diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-05-20 09:47:09 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-06-07 11:15:42 +0000 |
commit | 189d4fd8fad9e3c776873be51938cd31a42b6177 (patch) | |
tree | 6497caeff5e383937996768766ab3bb2081a40b2 /chromium/third_party/blink/renderer/core/html | |
parent | 8bc75099d364490b22f43a7ce366b366c08f4164 (diff) | |
download | qtwebengine-chromium-189d4fd8fad9e3c776873be51938cd31a42b6177.tar.gz |
BASELINE: Update Chromium to 90.0.4430.221
Change-Id: Iff4d9d18d2fcf1a576f3b1f453010f744a232920
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer/core/html')
300 files changed, 4750 insertions, 6966 deletions
diff --git a/chromium/third_party/blink/renderer/core/html/DIR_METADATA b/chromium/third_party/blink/renderer/core/html/DIR_METADATA new file mode 100644 index 00000000000..b7acf25f76d --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/DIR_METADATA @@ -0,0 +1,5 @@ +monorail { + component: "Blink>HTML" +} + +team_email: "dom-dev@chromium.org" diff --git a/chromium/third_party/blink/renderer/core/html/OWNERS b/chromium/third_party/blink/renderer/core/html/OWNERS index 472b0c7cf86..e69de29bb2d 100644 --- a/chromium/third_party/blink/renderer/core/html/OWNERS +++ b/chromium/third_party/blink/renderer/core/html/OWNERS @@ -1,2 +0,0 @@ -# TEAM: dom-dev@chromium.org -# COMPONENT: Blink>HTML diff --git a/chromium/third_party/blink/renderer/core/html/aria_properties.json5 b/chromium/third_party/blink/renderer/core/html/aria_properties.json5 index b57f304ddc0..496f9a32ea6 100644 --- a/chromium/third_party/blink/renderer/core/html/aria_properties.json5 +++ b/chromium/third_party/blink/renderer/core/html/aria_properties.json5 @@ -128,10 +128,16 @@ enum: ["ascending", "descending", "none", "other"], type: "token" }, + { + name: "aria-touchpassthrough", + type: "boolean", + runtimeEnabled: "AriaTouchPassthrough" + }, {name: "aria-valuemax", type: "decimal"}, {name: "aria-valuemin", type: "decimal"}, {name: "aria-valuenow", type: "decimal"}, {name: "aria-valuetext", type: "string"}, + {name: "aria-virtualcontent", type: "string"}, ], roles: [ { diff --git a/chromium/third_party/blink/renderer/core/html/battery_savings.h b/chromium/third_party/blink/renderer/core/html/battery_savings.h new file mode 100644 index 00000000000..5519b37da7a --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/battery_savings.h @@ -0,0 +1,24 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_BATTERY_SAVINGS_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_BATTERY_SAVINGS_H_ + +namespace blink { + +// These are constants for the various keywords allowed for the battery-savings +// meta element. For instance: +// +// <meta name="battery-savings" content="allow-reduced-framerate"> +// These constants are bits which can be combined. +enum BatterySavings { + kAllowReducedFrameRate = 1 << 0, + kAllowReducedScriptSpeed = 1 << 1, +}; + +using BatterySavingsFlags = unsigned; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_BATTERY_SAVINGS_H_ diff --git a/chromium/third_party/blink/renderer/core/html/build.gni b/chromium/third_party/blink/renderer/core/html/build.gni index 2c41552f9d0..cc30e361483 100644 --- a/chromium/third_party/blink/renderer/core/html/build.gni +++ b/chromium/third_party/blink/renderer/core/html/build.gni @@ -7,6 +7,7 @@ blink_core_sources_html = [ "anchor_element_metrics.h", "anchor_element_metrics_sender.cc", "anchor_element_metrics_sender.h", + "battery_savings.h", "canvas/canvas_async_blob_creator.cc", "canvas/canvas_async_blob_creator.h", "canvas/canvas_context_creation_attributes_core.cc", @@ -32,6 +33,8 @@ blink_core_sources_html = [ "canvas/ukm_parameters.h", "collection_items_cache.h", "collection_type.h", + "conversion_measurement_parsing.cc", + "conversion_measurement_parsing.h", "cross_origin_attribute.cc", "cross_origin_attribute.h", "custom/ce_reactions_scope.cc", @@ -55,49 +58,10 @@ blink_core_sources_html = [ "custom/custom_element_registry.h", "custom/custom_element_upgrade_sorter.cc", "custom/custom_element_upgrade_sorter.h", + "custom/custom_state_set.cc", + "custom/custom_state_set.h", "custom/element_internals.cc", "custom/element_internals.h", - "custom/v0_custom_element.cc", - "custom/v0_custom_element.h", - "custom/v0_custom_element_async_import_microtask_queue.cc", - "custom/v0_custom_element_async_import_microtask_queue.h", - "custom/v0_custom_element_callback_invocation.cc", - "custom/v0_custom_element_callback_invocation.h", - "custom/v0_custom_element_callback_queue.cc", - "custom/v0_custom_element_callback_queue.h", - "custom/v0_custom_element_definition.cc", - "custom/v0_custom_element_definition.h", - "custom/v0_custom_element_descriptor.h", - "custom/v0_custom_element_descriptor_hash.h", - "custom/v0_custom_element_exception.cc", - "custom/v0_custom_element_exception.h", - "custom/v0_custom_element_lifecycle_callbacks.h", - "custom/v0_custom_element_microtask_dispatcher.cc", - "custom/v0_custom_element_microtask_dispatcher.h", - "custom/v0_custom_element_microtask_import_step.cc", - "custom/v0_custom_element_microtask_import_step.h", - "custom/v0_custom_element_microtask_queue_base.cc", - "custom/v0_custom_element_microtask_queue_base.h", - "custom/v0_custom_element_microtask_resolution_step.cc", - "custom/v0_custom_element_microtask_resolution_step.h", - "custom/v0_custom_element_microtask_run_queue.cc", - "custom/v0_custom_element_microtask_run_queue.h", - "custom/v0_custom_element_microtask_step.h", - "custom/v0_custom_element_observer.cc", - "custom/v0_custom_element_observer.h", - "custom/v0_custom_element_processing_stack.cc", - "custom/v0_custom_element_processing_stack.h", - "custom/v0_custom_element_processing_step.h", - "custom/v0_custom_element_registration_context.cc", - "custom/v0_custom_element_registration_context.h", - "custom/v0_custom_element_registry.cc", - "custom/v0_custom_element_registry.h", - "custom/v0_custom_element_scheduler.cc", - "custom/v0_custom_element_scheduler.h", - "custom/v0_custom_element_sync_microtask_queue.cc", - "custom/v0_custom_element_sync_microtask_queue.h", - "custom/v0_custom_element_upgrade_candidate_map.cc", - "custom/v0_custom_element_upgrade_candidate_map.h", "document_all_name_collection.cc", "document_all_name_collection.h", "document_name_collection.cc", @@ -202,6 +166,8 @@ blink_core_sources_html = [ "forms/html_output_element.h", "forms/html_select_element.cc", "forms/html_select_element.h", + "forms/html_select_menu_element.cc", + "forms/html_select_menu_element.h", "forms/html_text_area_element.cc", "forms/html_text_area_element.h", "forms/image_input_type.cc", @@ -294,8 +260,6 @@ blink_core_sources_html = [ "html_br_element.h", "html_collection.cc", "html_collection.h", - "html_content_element.cc", - "html_content_element.h", "html_data_element.cc", "html_data_element.h", "html_details_element.cc", @@ -378,6 +342,8 @@ blink_core_sources_html = [ "html_picture_element.h", "html_plugin_element.cc", "html_plugin_element.h", + "html_popup_element.cc", + "html_popup_element.h", "html_pre_element.cc", "html_pre_element.h", "html_progress_element.cc", @@ -390,8 +356,6 @@ blink_core_sources_html = [ "html_ruby_element.h", "html_script_element.cc", "html_script_element.h", - "html_shadow_element.cc", - "html_shadow_element.h", "html_slot_element.cc", "html_slot_element.h", "html_source_element.cc", @@ -470,6 +434,8 @@ blink_core_sources_html = [ "list_item_ordinal.h", "loading_attribute.cc", "loading_attribute.h", + "media/audio_output_device_controller.cc", + "media/audio_output_device_controller.h", "media/autoplay_policy.cc", "media/autoplay_policy.h", "media/autoplay_uma_helper.cc", @@ -706,7 +672,6 @@ blink_core_tests_html = [ "forms/step_range_test.cc", "forms/text_control_element_test.cc", "forms/type_ahead_test.cc", - "html_content_element_test.cc", "html_dimension_test.cc", "html_element_test.cc", "html_embed_element_test.cc", diff --git a/chromium/third_party/blink/renderer/core/html/canvas/DIR_METADATA b/chromium/third_party/blink/renderer/core/html/canvas/DIR_METADATA new file mode 100644 index 00000000000..4ae95d48d73 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/canvas/DIR_METADATA @@ -0,0 +1,5 @@ +monorail { + component: "Blink>Canvas" +} + +team_email: "paint-dev@chromium.org" diff --git a/chromium/third_party/blink/renderer/core/html/canvas/OWNERS b/chromium/third_party/blink/renderer/core/html/canvas/OWNERS index 5ef87b1aa3f..1e563633b29 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/OWNERS +++ b/chromium/third_party/blink/renderer/core/html/canvas/OWNERS @@ -1,4 +1 @@ fserb@chromium.org - -# TEAM: paint-dev@chromium.org -# COMPONENT: Blink>Canvas 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 3e078d42692..aae43a337bc 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 @@ -86,24 +86,23 @@ void RecordIdleTaskStatusHistogram( void RecordInitiateEncodingTimeHistogram(ImageEncodingMimeType mime_type, base::TimeDelta elapsed_time) { - // TODO(crbug.com/983261) Change this to use UmaHistogramMicrosecondsTimes. if (mime_type == kMimeTypePng) { - UmaHistogramMicrosecondsTimesUnderTenMilliseconds( - "Blink.Canvas.ToBlob.InitiateEncodingDelay.PNG", elapsed_time); + UmaHistogramMicrosecondsTimes( + "Blink.Canvas.ToBlob.InitialEncodingDelay.PNG", elapsed_time); } else if (mime_type == kMimeTypeJpeg) { - UmaHistogramMicrosecondsTimesUnderTenMilliseconds( - "Blink.Canvas.ToBlob.InitiateEncodingDelay.JPEG", elapsed_time); + UmaHistogramMicrosecondsTimes( + "Blink.Canvas.ToBlob.InitialEncodingDelay.JPEG", elapsed_time); } } void RecordCompleteEncodingTimeHistogram(ImageEncodingMimeType mime_type, base::TimeDelta elapsed_time) { if (mime_type == kMimeTypePng) { - UmaHistogramMicrosecondsTimesUnderTenMilliseconds( - "Blink.Canvas.ToBlob.CompleteEncodingDelay.PNG", elapsed_time); + UmaHistogramMicrosecondsTimes("Blink.Canvas.ToBlob.TotalEncodingDelay.PNG", + elapsed_time); } else if (mime_type == kMimeTypeJpeg) { - UmaHistogramMicrosecondsTimesUnderTenMilliseconds( - "Blink.Canvas.ToBlob.CompleteEncodingDelay.JPEG", elapsed_time); + UmaHistogramMicrosecondsTimes("Blink.Canvas.ToBlob.TotalEncodingDelay.JPEG", + elapsed_time); } } @@ -205,12 +204,15 @@ CanvasAsyncBlobCreator::CanvasAsyncBlobCreator( } // For kHTMLCanvasToBlobCallback and kOffscreenCanvasConvertToBlobPromise - // to-blob function types, we color convert to sRGB and do not tag the image - // with any color space info. + // to-blob function types, we keep the color space of the image and save + // it in the info if color management is enabled; otherwise, we color convert + // to sRGB and do not tag the image with any color space info. // For kHTMLCanvasConvertToBlobPromise to-blob function type, we color // covnert to the requested color space and pixel format. if (function_type_ != kHTMLCanvasConvertToBlobPromise) { - if (skia_image->colorSpace()) { + bool isColorManagementEnabled = + RuntimeEnabledFeatures::CanvasColorManagementEnabled(); + if (skia_image->colorSpace() && !isColorManagementEnabled) { image_ = image_->ConvertToColorSpace( SkColorSpace::MakeSRGB(), GetColorTypeForConversion(skia_image->colorType())); @@ -218,10 +220,10 @@ CanvasAsyncBlobCreator::CanvasAsyncBlobCreator( } if (skia_image->peekPixels(&src_data_)) { - src_data_.setColorSpace(nullptr); static_bitmap_image_loaded_ = true; + if (!isColorManagementEnabled) + src_data_.setColorSpace(nullptr); } - DCHECK(!src_data_.colorSpace()); } else { sk_sp<SkColorSpace> blob_color_space = BlobColorSpaceToSkColorSpace(encode_options_->colorSpace()); diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_image_source.h b/chromium/third_party/blink/renderer/core/html/canvas/canvas_image_source.h index b1954a1880b..c6fe16f9638 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_image_source.h +++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_image_source.h @@ -65,6 +65,7 @@ class CORE_EXPORT CanvasImageSource { virtual bool IsSVGSource() const { return false; } virtual bool IsImageBitmap() const { return false; } virtual bool IsOffscreenCanvas() const { return false; } + virtual bool IsVideoFrame() const { return false; } virtual FloatSize ElementSize(const FloatSize& default_object_size, const RespectImageOrientationEnum) const = 0; diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc b/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc index e165fcf0f54..5906a3ac051 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc +++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc @@ -40,52 +40,8 @@ CanvasRenderingContext::CanvasRenderingContext( CanvasRenderingContextHost* host, const CanvasContextCreationAttributesCore& attrs) : host_(host), - color_params_(CanvasColorSpace::kSRGB, - CanvasColorParams::GetNativeCanvasPixelFormat(), - kNonOpaque), - creation_attributes_(attrs) { - if (creation_attributes_.pixel_format == kF16CanvasPixelFormatName) - color_params_.SetCanvasPixelFormat(CanvasPixelFormat::kF16); - - if (creation_attributes_.color_space == kRec2020CanvasColorSpaceName) - color_params_.SetCanvasColorSpace(CanvasColorSpace::kRec2020); - else if (creation_attributes_.color_space == kP3CanvasColorSpaceName) - color_params_.SetCanvasColorSpace(CanvasColorSpace::kP3); - - if (!creation_attributes_.alpha) - color_params_.SetOpacityMode(kOpaque); - - // Make creation_attributes_ reflect the effective color_space and - // pixel_format rather than the requested one. - creation_attributes_.color_space = ColorSpaceAsString(); - creation_attributes_.pixel_format = PixelFormatAsString(); -} - -WTF::String CanvasRenderingContext::ColorSpaceAsString() const { - switch (color_params_.ColorSpace()) { - case CanvasColorSpace::kSRGB: - return kSRGBCanvasColorSpaceName; - case CanvasColorSpace::kRec2020: - return kRec2020CanvasColorSpaceName; - case CanvasColorSpace::kP3: - return kP3CanvasColorSpaceName; - }; - CHECK(false); - return ""; -} - -WTF::String CanvasRenderingContext::PixelFormatAsString() const { - switch (color_params_.PixelFormat()) { - case CanvasPixelFormat::kRGBA8: - return kRGBA8CanvasPixelFormatName; - case CanvasPixelFormat::kF16: - return kF16CanvasPixelFormatName; - case CanvasPixelFormat::kBGRA8: - return kBGRA8CanvasPixelFormatName; - }; - CHECK(false); - return ""; -} + color_params_(attrs.color_space, attrs.pixel_format, attrs.alpha), + creation_attributes_(attrs) {} void CanvasRenderingContext::Dispose() { StopListeningForDidProcessTask(); @@ -141,6 +97,22 @@ void CanvasRenderingContext::RecordUKMCanvasRenderingAPI( } } +void CanvasRenderingContext::RecordUKMCanvasDrawnToRenderingAPI( + CanvasRenderingAPI canvasRenderingAPI) { + DCHECK(Host()); + const auto& ukm_params = Host()->GetUkmParameters(); + if (Host()->IsOffscreenCanvas()) { + ukm::builders::ClientRenderingAPI(ukm_params.source_id) + .SetOffscreenCanvas_RenderingContextDrawnTo( + static_cast<int>(canvasRenderingAPI)) + .Record(ukm_params.ukm_recorder); + } else { + ukm::builders::ClientRenderingAPI(ukm_params.source_id) + .SetCanvas_RenderingContextDrawnTo(static_cast<int>(canvasRenderingAPI)) + .Record(ukm_params.ukm_recorder); + } +} + CanvasRenderingContext::ContextType CanvasRenderingContext::ContextTypeFromId( const String& id) { if (id == "2d") 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 cc030d990d2..ef4f222ccaf 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h +++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h @@ -46,14 +46,6 @@ class CanvasImageSource; class HTMLCanvasElement; class ImageBitmap; -constexpr const char* kSRGBCanvasColorSpaceName = "srgb"; -constexpr const char* kRec2020CanvasColorSpaceName = "rec2020"; -constexpr const char* kP3CanvasColorSpaceName = "p3"; - -constexpr const char* kRGBA8CanvasPixelFormatName = "uint8"; -constexpr const char* kBGRA8CanvasPixelFormatName = "uint8"; -constexpr const char* kF16CanvasPixelFormatName = "float16"; - class CORE_EXPORT CanvasRenderingContext : public ScriptWrappable, public Thread::TaskObserver { USING_PRE_FINALIZER(CanvasRenderingContext, Dispose); @@ -90,16 +82,17 @@ class CORE_EXPORT CanvasRenderingContext : public ScriptWrappable, }; void RecordUKMCanvasRenderingAPI(CanvasRenderingAPI canvasRenderingAPI); + void RecordUKMCanvasDrawnToRenderingAPI( + CanvasRenderingAPI canvasRenderingAPI); static ContextType ContextTypeFromId(const String& id); static ContextType ResolveContextTypeAliases(ContextType); CanvasRenderingContextHost* Host() const { return host_; } - WTF::String ColorSpaceAsString() const; - WTF::String PixelFormatAsString() const; - - const CanvasColorParams& ColorParams() const { return color_params_; } + const CanvasColorParams& CanvasRenderingContextColorParams() const { + return color_params_; + } virtual scoped_refptr<StaticBitmapImage> GetImage() = 0; virtual ContextType GetContextType() const = 0; @@ -186,7 +179,7 @@ class CORE_EXPORT CanvasRenderingContext : public ScriptWrappable, virtual bool Is3d() const { return false; } virtual bool UsingSwapChain() const { return false; } virtual void SetFilterQuality(SkFilterQuality) { NOTREACHED(); } - virtual void Reshape(int width, int height) { NOTREACHED(); } + virtual void Reshape(int width, int height) {} virtual void MarkLayerComposited() { NOTREACHED(); } virtual sk_sp<SkData> PaintRenderingResultsToDataArray(SourceDrawingBuffer) { NOTREACHED(); 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 174e887bb27..fd548d85896 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 @@ -48,7 +48,7 @@ CanvasRenderingContextHost::CreateTransparentImage(const IntSize& size) const { return nullptr; CanvasColorParams color_params = CanvasColorParams(); if (RenderingContext()) - color_params = RenderingContext()->ColorParams(); + color_params = RenderingContext()->CanvasRenderingContextColorParams(); SkImageInfo info = SkImageInfo::Make( size.Width(), size.Height(), color_params.GetSkColorType(), kPremul_SkAlphaType, color_params.GetSkColorSpace()); @@ -115,6 +115,8 @@ void CanvasRenderingContextHost::CreateCanvasResourceProvider3D() { : nullptr; std::unique_ptr<CanvasResourceProvider> provider; + const CanvasResourceParams resource_params = + ColorParams().GetAsResourceParams(); if (SharedGpuContext::IsGpuCompositingEnabled() && LowLatencyEnabled()) { // If LowLatency is enabled, we need a resource that is able to perform well @@ -126,7 +128,7 @@ void CanvasRenderingContextHost::CreateCanvasResourceProvider3D() { // try a passthrough provider. DCHECK(LowLatencyEnabled()); provider = CanvasResourceProvider::CreatePassThroughProvider( - Size(), FilterQuality(), ColorParams(), + Size(), FilterQuality(), resource_params, SharedGpuContext::ContextProviderWrapper(), dispatcher, RenderingContext()->IsOriginTopLeft()); } @@ -141,7 +143,7 @@ void CanvasRenderingContextHost::CreateCanvasResourceProvider3D() { gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE; } provider = CanvasResourceProvider::CreateSharedImageProvider( - Size(), FilterQuality(), ColorParams(), + Size(), FilterQuality(), resource_params, CanvasResourceProvider::ShouldInitialize::kCallClear, SharedGpuContext::ContextProviderWrapper(), RasterMode::kGPU, RenderingContext()->IsOriginTopLeft(), shared_image_usage_flags); @@ -155,7 +157,7 @@ void CanvasRenderingContextHost::CreateCanvasResourceProvider3D() { shared_image_usage_flags |= gpu::SHARED_IMAGE_USAGE_SCANOUT; } provider = CanvasResourceProvider::CreateSharedImageProvider( - Size(), FilterQuality(), ColorParams(), + Size(), FilterQuality(), resource_params, CanvasResourceProvider::ShouldInitialize::kCallClear, SharedGpuContext::ContextProviderWrapper(), RasterMode::kGPU, RenderingContext()->IsOriginTopLeft(), shared_image_usage_flags); @@ -166,12 +168,12 @@ void CanvasRenderingContextHost::CreateCanvasResourceProvider3D() { // provider. if (!provider) { provider = CanvasResourceProvider::CreateSharedBitmapProvider( - Size(), FilterQuality(), ColorParams(), + Size(), FilterQuality(), resource_params, CanvasResourceProvider::ShouldInitialize::kCallClear, dispatcher); } if (!provider) { provider = CanvasResourceProvider::CreateBitmapProvider( - Size(), FilterQuality(), ColorParams(), + Size(), FilterQuality(), resource_params, CanvasResourceProvider::ShouldInitialize::kCallClear); } @@ -193,6 +195,8 @@ void CanvasRenderingContextHost::CreateCanvasResourceProvider2D( : nullptr; std::unique_ptr<CanvasResourceProvider> provider; + const CanvasResourceParams resource_params = + ColorParams().GetAsResourceParams(); const bool use_gpu = hint == RasterModeHint::kPreferGPU && ShouldAccelerate2dContext(); // It is important to not use the context's IsOriginTopLeft() here @@ -205,7 +209,7 @@ void CanvasRenderingContextHost::CreateCanvasResourceProvider2D( // SwapChain if possible. if (base::FeatureList::IsEnabled(features::kLowLatencyCanvas2dSwapChain)) { provider = CanvasResourceProvider::CreateSwapChainProvider( - Size(), FilterQuality(), ColorParams(), + Size(), FilterQuality(), resource_params, CanvasResourceProvider::ShouldInitialize::kCallClear, SharedGpuContext::ContextProviderWrapper(), dispatcher, is_origin_top_left); @@ -223,7 +227,7 @@ void CanvasRenderingContextHost::CreateCanvasResourceProvider2D( gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE; } provider = CanvasResourceProvider::CreateSharedImageProvider( - Size(), FilterQuality(), ColorParams(), + Size(), FilterQuality(), resource_params, CanvasResourceProvider::ShouldInitialize::kCallClear, SharedGpuContext::ContextProviderWrapper(), RasterMode::kGPU, is_origin_top_left, shared_image_usage_flags); @@ -236,7 +240,7 @@ void CanvasRenderingContextHost::CreateCanvasResourceProvider2D( if (RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled()) shared_image_usage_flags |= gpu::SHARED_IMAGE_USAGE_SCANOUT; provider = CanvasResourceProvider::CreateSharedImageProvider( - Size(), FilterQuality(), ColorParams(), + Size(), FilterQuality(), resource_params, CanvasResourceProvider::ShouldInitialize::kCallClear, SharedGpuContext::ContextProviderWrapper(), RasterMode::kGPU, is_origin_top_left, shared_image_usage_flags); @@ -244,7 +248,7 @@ void CanvasRenderingContextHost::CreateCanvasResourceProvider2D( const uint32_t shared_image_usage_flags = gpu::SHARED_IMAGE_USAGE_DISPLAY | gpu::SHARED_IMAGE_USAGE_SCANOUT; provider = CanvasResourceProvider::CreateSharedImageProvider( - Size(), FilterQuality(), ColorParams(), + Size(), FilterQuality(), resource_params, CanvasResourceProvider::ShouldInitialize::kCallClear, SharedGpuContext::ContextProviderWrapper(), RasterMode::kCPU, is_origin_top_left, shared_image_usage_flags); @@ -255,12 +259,12 @@ void CanvasRenderingContextHost::CreateCanvasResourceProvider2D( // provider. if (!provider) { provider = CanvasResourceProvider::CreateSharedBitmapProvider( - Size(), FilterQuality(), ColorParams(), + Size(), FilterQuality(), resource_params, CanvasResourceProvider::ShouldInitialize::kCallClear, dispatcher); } if (!provider) { provider = CanvasResourceProvider::CreateBitmapProvider( - Size(), FilterQuality(), ColorParams(), + Size(), FilterQuality(), resource_params, CanvasResourceProvider::ShouldInitialize::kCallClear); } @@ -280,7 +284,7 @@ void CanvasRenderingContextHost::CreateCanvasResourceProvider2D( CanvasColorParams CanvasRenderingContextHost::ColorParams() const { if (RenderingContext()) - return RenderingContext()->ColorParams(); + return RenderingContext()->CanvasRenderingContextColorParams(); return CanvasColorParams(); } 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 4489838b4ed..1e3ed7bc5c6 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 @@ -114,6 +114,10 @@ constexpr int kDefaultCanvasHeight = 150; constexpr int kUndefinedQualityValue = -1.0; constexpr int kMinimumAccelerated2dCanvasSize = 128 * 129; +// A default size used for canvas memory allocation when canvas size is greater +// than 2^20. +constexpr uint32_t kMaximumCanvasSize = 2 << 20; + } // namespace HTMLCanvasElement::HTMLCanvasElement(Document& document) @@ -138,9 +142,10 @@ HTMLCanvasElement::~HTMLCanvasElement() { } void HTMLCanvasElement::Dispose() { - if (OffscreenCanvasFrame()) { - ReleaseOffscreenCanvasFrame(); - } + // We need to record metrics before we dispose of anything + if (context_) + UMA_HISTOGRAM_BOOLEAN("Blink.Canvas.HasRendered", bool(ResourceProvider())); + // It's possible that the placeholder frame has been disposed but its ID still // exists. Make sure that it gets unregistered here UnregisterPlaceholderCanvas(); @@ -150,12 +155,8 @@ void HTMLCanvasElement::Dispose() { DiscardResourceProvider(); if (context_) { - UMA_HISTOGRAM_BOOLEAN("Blink.Canvas.HasRendered", bool(ResourceProvider())); - if (context_->Host()) { - UMA_HISTOGRAM_BOOLEAN("Blink.Canvas.IsComposited", - context_->IsComposited()); + if (context_->Host()) context_->DetachHost(); - } context_ = nullptr; } @@ -286,9 +287,9 @@ CanvasRenderingContext* HTMLCanvasElement::GetCanvasRenderingContext( auto* old_contents_cc_layer = ContentsCcLayer(); auto* result = GetCanvasRenderingContextInternal(type, attributes); + Document& doc = GetDocument(); if (IdentifiabilityStudySettings::Get()->ShouldSample( IdentifiableSurface::Type::kCanvasRenderingContext)) { - Document& doc = GetDocument(); IdentifiabilityMetricBuilder(doc.UkmSourceID()) .Set(IdentifiableSurface::FromTypeAndToken( IdentifiableSurface::Type::kCanvasRenderingContext, @@ -296,6 +297,10 @@ CanvasRenderingContext* HTMLCanvasElement::GetCanvasRenderingContext( !!result) .Record(doc.UkmRecorder()); } + if (attributes.color_space != kSRGBCanvasColorSpaceName || + attributes.pixel_format != kUint8CanvasPixelFormatName) { + UseCounter::Count(doc, WebFeature::kCanvasUseColorSpace); + } if (ContentsCcLayer() != old_contents_cc_layer) OnContentsCcLayerChanged(); @@ -377,10 +382,16 @@ CanvasRenderingContext* HTMLCanvasElement::GetCanvasRenderingContextInternal( } if (context_->CreationAttributes().desynchronized) { - CreateLayer(); + if (!CreateLayer()) + return nullptr; SetNeedsUnbufferedInputEvents(true); frame_dispatcher_ = std::make_unique<CanvasResourceDispatcher>( - nullptr, surface_layer_bridge_->GetFrameSinkId().client_id(), + nullptr, + GetPage() + ->GetPageScheduler() + ->GetAgentGroupScheduler() + .CompositorTaskRunner(), + surface_layer_bridge_->GetFrameSinkId().client_id(), surface_layer_bridge_->GetFrameSinkId().sink_id(), CanvasResourceDispatcher::kInvalidPlaceholderCanvasId, size_); // We don't actually need the begin frame signal when in low latency mode, @@ -469,6 +480,12 @@ void HTMLCanvasElement::DidDraw() { void HTMLCanvasElement::PreFinalizeFrame() { RecordCanvasSizeToUMA(size_); + // PreFinalizeFrame indicates the end of a script task that may have rendered + // into the canvas, now is a good time to unlock cache entries. + auto* resource_provider = ResourceProvider(); + if (resource_provider) + resource_provider->ReleaseLockedImages(); + // Low-latency 2d canvases produce their frames after the resource gets single // buffered. if (LowLatencyEnabled() && !dirty_rect_.IsEmpty() && @@ -1060,6 +1077,32 @@ void HTMLCanvasElement::toBlob(V8BlobCallback* callback, } } +bool HTMLCanvasElement::IsPresentationAttribute( + const QualifiedName& name) const { + if (name == html_names::kWidthAttr || name == html_names::kHeightAttr) + return true; + return HTMLElement::IsPresentationAttribute(name); +} + +void HTMLCanvasElement::CollectStyleForPresentationAttribute( + const QualifiedName& name, + const AtomicString& value, + MutableCSSPropertyValueSet* style) { + if (name == html_names::kWidthAttr) { + if (FastHasAttribute(html_names::kHeightAttr)) { + const AtomicString& height = FastGetAttribute(html_names::kHeightAttr); + ApplyAspectRatioToStyle(value, height, style); + } + } else if (name == html_names::kHeightAttr) { + if (FastHasAttribute(html_names::kWidthAttr)) { + const AtomicString& width = FastGetAttribute(html_names::kWidthAttr); + ApplyAspectRatioToStyle(width, value, style); + } + } else { + HTMLElement::CollectStyleForPresentationAttribute(name, value, style); + } +} + void HTMLCanvasElement::AddListener(CanvasDrawListener* listener) { listeners_.insert(listener); } @@ -1100,9 +1143,8 @@ bool HTMLCanvasElement::ShouldAccelerate() const { return false; // The command line flag --disable-accelerated-2d-canvas toggles this option - if (!RuntimeEnabledFeatures::Accelerated2dCanvasEnabled()) { + if (!RuntimeEnabledFeatures::Accelerated2dCanvasEnabled()) return false; - } // Webview crashes with accelerated small canvases (crbug.com/1004304) // Experimenting to see if this still causes crashes (crbug.com/1136603) @@ -1393,7 +1435,7 @@ ScriptPromise HTMLCanvasElement::CreateImageBitmap( void HTMLCanvasElement::SetOffscreenCanvasResource( scoped_refptr<CanvasResource> image, - unsigned resource_id) { + viz::ResourceId resource_id) { OffscreenCanvasPlaceholder::SetOffscreenCanvasResource(std::move(image), resource_id); SetSize(OffscreenCanvasFrame()->Size()); @@ -1484,20 +1526,23 @@ String HTMLCanvasElement::GetIdFromControl(const Element* element) { return String(); } -void HTMLCanvasElement::CreateLayer() { +bool HTMLCanvasElement::CreateLayer() { DCHECK(!surface_layer_bridge_); LocalFrame* frame = GetDocument().GetFrame(); // We do not design transferControlToOffscreen() for frame-less HTML canvas. - if (frame) { - surface_layer_bridge_ = std::make_unique<::blink::SurfaceLayerBridge>( - frame->GetPage()->GetChromeClient().GetFrameSinkId(frame), - ::blink::SurfaceLayerBridge::ContainsVideo::kNo, this, - base::NullCallback()); - // Creates a placeholder layer first before Surface is created. - surface_layer_bridge_->CreateSolidColorLayer(); - // This may cause the canvas to be composited. - SetNeedsCompositingUpdate(); - } + if (!frame) + return false; + + surface_layer_bridge_ = std::make_unique<::blink::SurfaceLayerBridge>( + frame->GetPage()->GetChromeClient().GetFrameSinkId(frame), + ::blink::SurfaceLayerBridge::ContainsVideo::kNo, this, + base::NullCallback()); + // Creates a placeholder layer first before Surface is created. + surface_layer_bridge_->CreateSolidColorLayer(); + // This may cause the canvas to be composited. + SetNeedsCompositingUpdate(); + + return true; } void HTMLCanvasElement::OnWebLayerUpdated() { @@ -1539,12 +1584,15 @@ void HTMLCanvasElement::UpdateMemoryUsage() { const int bytes_per_pixel = ColorParams().BytesPerPixel(); intptr_t gpu_memory_usage = 0; + uint32_t canvas_width = std::min(kMaximumCanvasSize, width()); + uint32_t canvas_height = std::min(kMaximumCanvasSize, height()); + if (gpu_buffer_count) { // Switch from cpu mode to gpu mode base::CheckedNumeric<intptr_t> checked_usage = gpu_buffer_count * bytes_per_pixel; - checked_usage *= width(); - checked_usage *= height(); + checked_usage *= canvas_width; + checked_usage *= canvas_height; gpu_memory_usage = checked_usage.ValueOrDefault(std::numeric_limits<intptr_t>::max()); } @@ -1553,8 +1601,8 @@ void HTMLCanvasElement::UpdateMemoryUsage() { // in all cases. base::CheckedNumeric<intptr_t> checked_usage = non_gpu_buffer_count * bytes_per_pixel; - checked_usage *= width(); - checked_usage *= height(); + checked_usage *= canvas_width; + checked_usage *= canvas_height; checked_usage += gpu_memory_usage; intptr_t externally_allocated_memory = checked_usage.ValueOrDefault(std::numeric_limits<intptr_t>::max()); @@ -1607,8 +1655,22 @@ void HTMLCanvasElement::ReplaceExisting2dLayerBridge( // TODO(jochin): Consider using ResourceProvider()->RestoreBackBuffer() here // to avoid all of this clip stack manipulation. - if (image) - canvas2d_bridge_->DrawFullImage(image->PaintImageForCurrentFrame()); + if (image) { + auto paint_image = image->PaintImageForCurrentFrame(); + if (!canvas2d_bridge_->IsAccelerated() && paint_image.IsTextureBacked()) { + // If new bridge is unaccelrated we must read back |paint_image| here. + // DrawFullImage will record the image and potentially raster on a worker + // thread, but texture backed PaintImages can't be used on a different + // thread. + auto sk_image = paint_image.GetSwSkImage(); + auto content_id = paint_image.GetContentIdForFrame(0); + auto builder = + cc::PaintImageBuilder::WithProperties(std::move(paint_image)) + .set_image(sk_image, content_id); + paint_image = builder.TakePaintImage(); + } + canvas2d_bridge_->DrawFullImage(paint_image); + } RestoreCanvasMatrixClipStack(canvas); canvas2d_bridge_->DidRestoreCanvasMatrixClipStack(canvas); 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 1d7efdc4ded..79de50a0338 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 @@ -141,9 +141,16 @@ class CORE_EXPORT HTMLCanvasElement final return toBlob(callback, mime_type, ScriptValue(), exception_state); } + bool IsPresentationAttribute(const QualifiedName&) const final; + void CollectStyleForPresentationAttribute(const QualifiedName&, + const AtomicString&, + MutableCSSPropertyValueSet*) final; + // Used for canvas capture. void AddListener(CanvasDrawListener*); void RemoveListener(CanvasDrawListener*); + // Derived from OffscreenCanvasPlaceholder. + bool HasCanvasCapture() const final { return !listeners_.IsEmpty(); } // Used for rendering void DidDraw(const FloatRect&) override; @@ -234,7 +241,7 @@ class CORE_EXPORT HTMLCanvasElement final // OffscreenCanvasPlaceholder implementation. void SetOffscreenCanvasResource(scoped_refptr<CanvasResource>, - unsigned resource_id) override; + viz::ResourceId resource_id) override; void Trace(Visitor*) const override; void SetResourceProviderForTesting(std::unique_ptr<CanvasResourceProvider>, @@ -261,7 +268,7 @@ class CORE_EXPORT HTMLCanvasElement final ::blink::SurfaceLayerBridge* SurfaceLayerBridge() const { return surface_layer_bridge_.get(); } - void CreateLayer(); + bool CreateLayer(); void DetachContext() override { context_ = nullptr; } diff --git a/chromium/third_party/blink/renderer/core/html/canvas/image_data.cc b/chromium/third_party/blink/renderer/core/html/canvas/image_data.cc index 5e8683287c1..d2bbbae8bf8 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/image_data.cc +++ b/chromium/third_party/blink/renderer/core/html/canvas/image_data.cc @@ -34,137 +34,154 @@ #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h" #include "third_party/blink/renderer/platform/graphics/color_behavior.h" -#include "third_party/skia/include/third_party/skcms/skcms.h" #include "v8/include/v8.h" namespace blink { -// Please note that all the number "4" in the file means number of channels -// required to describe a pixel, namely, red, green, blue and alpha. -namespace { - -bool RaiseDOMExceptionAndReturnFalse(ExceptionState* exception_state, - DOMExceptionCode exception_code, - const char* message) { - if (exception_state) - exception_state->ThrowDOMException(exception_code, message); - return false; -} - -} // namespace - -bool ImageData::ValidateConstructorArguments( - const unsigned& param_flags, - const IntSize* size, - const unsigned& width, - const unsigned& height, - const NotShared<DOMArrayBufferView> data, - const ImageDataColorSettings* color_settings, - ExceptionState* exception_state) { - // We accept all the combinations of colorSpace and storageFormat in an - // ImageDataColorSettings to be stored in an ImageData. Therefore, we don't - // check the color settings in this function. +ImageData* ImageData::ValidateAndCreate( + unsigned width, + base::Optional<unsigned> height, + base::Optional<NotShared<DOMArrayBufferView>> data, + const ImageDataSettings* input_settings, + ExceptionState& exception_state, + uint32_t flags) { + IntSize size; + if ((flags & RequireCanvasColorManagement && + !RuntimeEnabledFeatures::CanvasColorManagementEnabled())) { + exception_state.ThrowTypeError("Overload resolution failed."); + return nullptr; + } - if ((param_flags & kParamWidth) && !width) { - return RaiseDOMExceptionAndReturnFalse( - exception_state, DOMExceptionCode::kIndexSizeError, + if (!width) { + exception_state.ThrowDOMException( + DOMExceptionCode::kIndexSizeError, "The source width is zero or not a number."); + return nullptr; } - - if ((param_flags & kParamHeight) && !height) { - return RaiseDOMExceptionAndReturnFalse( - exception_state, DOMExceptionCode::kIndexSizeError, - "The source height is zero or not a number."); + size.SetWidth(width); + if (height) { + if (!*height) { + exception_state.ThrowDOMException( + DOMExceptionCode::kIndexSizeError, + "The source height is zero or not a number."); + return nullptr; + } + size.SetHeight(*height); } - if (param_flags & (kParamWidth | kParamHeight)) { - base::CheckedNumeric<unsigned> data_size = - ImageData::StorageFormatBytesPerPixel( - kUint8ClampedArrayStorageFormatName); - if (color_settings) { - data_size = ImageData::StorageFormatBytesPerPixel( - color_settings->storageFormat()); - } - data_size *= width; - data_size *= height; - if (!data_size.IsValid()) { - return RaiseDOMExceptionAndReturnFalse( - exception_state, DOMExceptionCode::kIndexSizeError, - "The requested image size exceeds the supported range."); - } + // Populate the ImageDataSettings to use based on |input_settings|. + ImageDataSettings* settings = ImageDataSettings::Create(); + if (input_settings) { + settings->setColorSpace(input_settings->colorSpace()); + settings->setStorageFormat(input_settings->storageFormat()); + } - if (data_size.ValueOrDie() > v8::TypedArray::kMaxLength) { - if (exception_state) { - exception_state->ThrowRangeError( - "Out of memory at ImageData creation."); + // Ensure the size does not overflow. + unsigned size_in_elements = 0; + { + // Please note that the number "4" in the means number of channels required + // to describe a pixel, namely, red, green, blue and alpha. + base::CheckedNumeric<unsigned> size_in_elements_checked = 4; + size_in_elements_checked *= size.Width(); + size_in_elements_checked *= size.Height(); + if (!(flags & ValidateAndCreateFlags::Context2DErrorMode)) { + if (!size_in_elements_checked.IsValid()) { + exception_state.ThrowDOMException( + DOMExceptionCode::kIndexSizeError, + "The requested image size exceeds the supported range."); + return nullptr; } - return false; } + if (!size_in_elements_checked.IsValid() || + size_in_elements_checked.ValueOrDie() > v8::TypedArray::kMaxLength) { + exception_state.ThrowRangeError("Out of memory at ImageData creation."); + return nullptr; + } + size_in_elements = size_in_elements_checked.ValueOrDie(); } - unsigned data_length = 0; - if (param_flags & kParamData) { + // If |data| is provided, ensure it is a reasonable format, and that it can + // work with |size|. Update |settings| to reflect |data|'s format. + if (data) { DCHECK(data); - if (data->GetType() != DOMArrayBufferView::ViewType::kTypeUint8Clamped && - data->GetType() != DOMArrayBufferView::ViewType::kTypeUint16 && - data->GetType() != DOMArrayBufferView::ViewType::kTypeFloat32) { - return RaiseDOMExceptionAndReturnFalse( - exception_state, DOMExceptionCode::kNotSupportedError, - "The input data type is not supported."); + switch ((*data)->GetType()) { + case DOMArrayBufferView::ViewType::kTypeUint8Clamped: + settings->setStorageFormat(kUint8ClampedArrayStorageFormatName); + break; + case DOMArrayBufferView::ViewType::kTypeUint16: + settings->setStorageFormat(kUint16ArrayStorageFormatName); + break; + case DOMArrayBufferView::ViewType::kTypeFloat32: + settings->setStorageFormat(kFloat32ArrayStorageFormatName); + break; + default: + exception_state.ThrowDOMException( + DOMExceptionCode::kNotSupportedError, + "The input data type is not supported."); + return nullptr; } - static_assert( std::numeric_limits<unsigned>::max() >= std::numeric_limits<uint32_t>::max(), "We use UINT32_MAX as the upper bound of the input size and expect " "that the result fits into an `unsigned`."); - if (!base::CheckedNumeric<uint32_t>(data->byteLength()) - .AssignIfValid(&data_length)) { - return RaiseDOMExceptionAndReturnFalse( - exception_state, DOMExceptionCode::kNotSupportedError, + + unsigned data_length_in_bytes = 0; + if (!base::CheckedNumeric<uint32_t>((*data)->byteLength()) + .AssignIfValid(&data_length_in_bytes)) { + exception_state.ThrowDOMException( + DOMExceptionCode::kNotSupportedError, "The input data is too large. The maximum size is 4294967295."); + return nullptr; } - if (!data_length) { - return RaiseDOMExceptionAndReturnFalse( - exception_state, DOMExceptionCode::kInvalidStateError, - "The input data has zero elements."); + if (!data_length_in_bytes) { + exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, + "The input data has zero elements."); + return nullptr; } - data_length /= data->TypeSize(); - if (data_length % 4) { - return RaiseDOMExceptionAndReturnFalse( - exception_state, DOMExceptionCode::kInvalidStateError, + + const unsigned data_length_in_elements = + data_length_in_bytes / (*data)->TypeSize(); + if (data_length_in_elements % 4) { + exception_state.ThrowDOMException( + DOMExceptionCode::kInvalidStateError, "The input data length is not a multiple of 4."); + return nullptr; } - if ((param_flags & kParamWidth) && (data_length / 4) % width) { - return RaiseDOMExceptionAndReturnFalse( - exception_state, DOMExceptionCode::kIndexSizeError, + const unsigned data_length_in_pixels = data_length_in_elements / 4; + if (data_length_in_pixels % width) { + exception_state.ThrowDOMException( + DOMExceptionCode::kIndexSizeError, "The input data length is not a multiple of (4 * width)."); + return nullptr; } - if ((param_flags & kParamWidth) && (param_flags & kParamHeight) && - height != data_length / (4 * width)) - return RaiseDOMExceptionAndReturnFalse( - exception_state, DOMExceptionCode::kIndexSizeError, - "The input data length is not equal to (4 * width * height)."); + const unsigned expected_height = data_length_in_pixels / width; + if (height) { + if (*height != expected_height) { + exception_state.ThrowDOMException( + DOMExceptionCode::kIndexSizeError, + "The input data length is not equal to (4 * width * height)."); + return nullptr; + } + } else { + size.SetHeight(expected_height); + } } - if (param_flags & kParamSize) { - if (size->Width() <= 0 || size->Height() <= 0) - return false; - base::CheckedNumeric<unsigned> data_size = 4; - data_size *= size->Width(); - data_size *= size->Height(); - if (!data_size.IsValid() || - data_size.ValueOrDie() > v8::TypedArray::kMaxLength) - return false; - if (param_flags & kParamData) { - if (data_size.ValueOrDie() > data_length) - return false; - } + NotShared<DOMArrayBufferView> allocated_data; + if (!data) { + ImageDataStorageFormat storage_format = + GetImageDataStorageFormat(settings->storageFormat()); + allocated_data = AllocateAndValidateDataArray( + size_in_elements, storage_format, &exception_state); + if (!allocated_data) + return nullptr; } - return true; + return MakeGarbageCollected<ImageData>(size, data ? *data : allocated_data, + settings); } NotShared<DOMArrayBufferView> ImageData::AllocateAndValidateDataArray( @@ -204,333 +221,11 @@ NotShared<DOMArrayBufferView> ImageData::AllocateAndValidateDataArray( return data_array; } -NotShared<DOMUint8ClampedArray> ImageData::AllocateAndValidateUint8ClampedArray( - const unsigned& length, - ExceptionState* exception_state) { - NotShared<DOMUint8ClampedArray> buffer_view; - buffer_view = AllocateAndValidateDataArray( - length, kUint8ClampedArrayStorageFormat, exception_state); - return buffer_view; -} - -NotShared<DOMUint16Array> ImageData::AllocateAndValidateUint16Array( - const unsigned& length, - ExceptionState* exception_state) { - NotShared<DOMUint16Array> buffer_view; - buffer_view = AllocateAndValidateDataArray(length, kUint16ArrayStorageFormat, - exception_state); - return buffer_view; -} - -NotShared<DOMFloat32Array> ImageData::AllocateAndValidateFloat32Array( - const unsigned& length, - ExceptionState* exception_state) { - NotShared<DOMFloat32Array> buffer_view; - buffer_view = AllocateAndValidateDataArray(length, kFloat32ArrayStorageFormat, - exception_state); - return buffer_view; -} - -ImageData* ImageData::Create(const IntSize& size, - const ImageDataColorSettings* color_settings) { - if (!ValidateConstructorArguments(kParamSize, &size, 0, 0, - NotShared<DOMArrayBufferView>(), - color_settings)) - return nullptr; - ImageDataStorageFormat storage_format = kUint8ClampedArrayStorageFormat; - if (color_settings) { - storage_format = - ImageData::GetImageDataStorageFormat(color_settings->storageFormat()); - } - NotShared<DOMArrayBufferView> data_array = - AllocateAndValidateDataArray(4 * static_cast<unsigned>(size.Width()) * - static_cast<unsigned>(size.Height()), - storage_format); - return data_array - ? MakeGarbageCollected<ImageData>(size, data_array, color_settings) - : nullptr; -} - -ImageDataColorSettings* CanvasColorParamsToImageDataColorSettings( - const CanvasColorParams& color_params) { - ImageDataColorSettings* color_settings = ImageDataColorSettings::Create(); - switch (color_params.ColorSpace()) { - case CanvasColorSpace::kSRGB: - color_settings->setColorSpace(kSRGBCanvasColorSpaceName); - break; - case CanvasColorSpace::kRec2020: - color_settings->setColorSpace(kRec2020CanvasColorSpaceName); - break; - case CanvasColorSpace::kP3: - color_settings->setColorSpace(kP3CanvasColorSpaceName); - break; - } - color_settings->setStorageFormat(kUint8ClampedArrayStorageFormatName); - if (color_params.PixelFormat() == CanvasPixelFormat::kF16) - color_settings->setStorageFormat(kFloat32ArrayStorageFormatName); - return color_settings; -} - -ImageData* ImageData::Create(const IntSize& size, - const CanvasColorParams& color_params) { - ImageDataColorSettings* color_settings = - CanvasColorParamsToImageDataColorSettings(color_params); - return ImageData::Create(size, color_settings); -} - -ImageData* ImageData::Create(const IntSize& size, - CanvasColorSpace color_space, - ImageDataStorageFormat storage_format) { - ImageDataColorSettings* color_settings = ImageDataColorSettings::Create(); - switch (color_space) { - case CanvasColorSpace::kSRGB: - color_settings->setColorSpace(kSRGBCanvasColorSpaceName); - break; - case CanvasColorSpace::kRec2020: - color_settings->setColorSpace(kRec2020CanvasColorSpaceName); - break; - case CanvasColorSpace::kP3: - color_settings->setColorSpace(kP3CanvasColorSpaceName); - break; - } - - switch (storage_format) { - case kUint8ClampedArrayStorageFormat: - color_settings->setStorageFormat(kUint8ClampedArrayStorageFormatName); - break; - case kUint16ArrayStorageFormat: - color_settings->setStorageFormat(kUint16ArrayStorageFormatName); - break; - case kFloat32ArrayStorageFormat: - color_settings->setStorageFormat(kFloat32ArrayStorageFormatName); - break; - } - - return ImageData::Create(size, color_settings); -} - -ImageData* ImageData::Create(const IntSize& size, - NotShared<DOMArrayBufferView> data_array, - const ImageDataColorSettings* color_settings) { - if (!ImageData::ValidateConstructorArguments( - kParamSize | kParamData, &size, 0, 0, data_array, color_settings)) - return nullptr; - return MakeGarbageCollected<ImageData>(size, data_array, color_settings); -} - -ImageData* ImageData::Create(scoped_refptr<StaticBitmapImage> image, - AlphaDisposition alpha_disposition) { - PaintImage paint_image = image->PaintImageForCurrentFrame(); - DCHECK(paint_image); - SkImageInfo image_info = image->PaintImageForCurrentFrame().GetSkImageInfo(); - CanvasColorParams color_params(image_info); - if (image_info.alphaType() != kOpaque_SkAlphaType) { - if (alpha_disposition == kPremultiplyAlpha) { - image_info = image_info.makeAlphaType(kPremul_SkAlphaType); - } else if (alpha_disposition == kUnpremultiplyAlpha) { - image_info = image_info.makeAlphaType(kUnpremul_SkAlphaType); - } - } - - ImageData* image_data = Create(image->Size(), color_params); - if (!image_data) - return nullptr; - - ImageDataArray data = image_data->data(); - SkColorType color_type = image_info.colorType(); - bool create_f32_image_data = (color_type == kRGBA_1010102_SkColorType || - color_type == kRGB_101010x_SkColorType || - color_type == kRGBA_F16_SkColorType || - color_type == kRGBA_F32_SkColorType); - - if (!create_f32_image_data) { - if (color_type == kR16G16B16A16_unorm_SkColorType) { - image_info = image_info.makeColorType(kR16G16B16A16_unorm_SkColorType); - paint_image.readPixels(image_info, data.GetAsUint16Array()->Data(), - image_info.minRowBytes(), 0, 0); - } else { - image_info = image_info.makeColorType(kRGBA_8888_SkColorType); - paint_image.readPixels(image_info, data.GetAsUint8ClampedArray()->Data(), - image_info.minRowBytes(), 0, 0); - } - } else { - image_info = image_info.makeColorType(kRGBA_F32_SkColorType); - paint_image.readPixels(image_info, data.GetAsFloat32Array()->Data(), - image_info.minRowBytes(), 0, 0); - } - return image_data; -} - -ImageData* ImageData::Create(unsigned width, - unsigned height, - ExceptionState& exception_state) { - if (!ImageData::ValidateConstructorArguments( - kParamWidth | kParamHeight, nullptr, width, height, - NotShared<DOMArrayBufferView>(), nullptr, &exception_state)) - return nullptr; - - NotShared<DOMUint8ClampedArray> byte_array = - AllocateAndValidateUint8ClampedArray( - ImageData::StorageFormatBytesPerPixel( - kUint8ClampedArrayStorageFormat) * - width * height, - &exception_state); - return byte_array ? MakeGarbageCollected<ImageData>(IntSize(width, height), - byte_array) - : nullptr; -} - -ImageData* ImageData::Create(NotShared<DOMUint8ClampedArray> data, - unsigned width, - ExceptionState& exception_state) { - if (!ImageData::ValidateConstructorArguments(kParamData | kParamWidth, - nullptr, width, 0, data, nullptr, - &exception_state)) - return nullptr; - - unsigned height = base::checked_cast<unsigned>(data->length()) / (width * 4); - return MakeGarbageCollected<ImageData>(IntSize(width, height), data); -} - -ImageData* ImageData::Create(NotShared<DOMUint8ClampedArray> data, - unsigned width, - unsigned height, - ExceptionState& exception_state) { - if (!ImageData::ValidateConstructorArguments( - kParamData | kParamWidth | kParamHeight, nullptr, width, height, data, - nullptr, &exception_state)) - return nullptr; - - return MakeGarbageCollected<ImageData>(IntSize(width, height), data); -} - -ImageData* ImageData::Create(NotShared<DOMUint16Array> data, - unsigned width, - ExceptionState& exception_state) { - if (!ImageData::ValidateConstructorArguments(kParamData | kParamWidth, - nullptr, width, 0, data, nullptr, - &exception_state)) - return nullptr; - unsigned height = base::checked_cast<unsigned>(data->length()) / - (width * ImageData::StorageFormatBytesPerPixel( - kUint16ArrayStorageFormatName)); - ImageDataColorSettings* image_setting = ImageDataColorSettings::Create(); - image_setting->setStorageFormat(kUint16ArrayStorageFormatName); - return MakeGarbageCollected<ImageData>(IntSize(width, height), data, - image_setting); -} - -ImageData* ImageData::Create(NotShared<DOMUint16Array> data, - unsigned width, - unsigned height, - ExceptionState& exception_state) { - if (!ImageData::ValidateConstructorArguments( - kParamData | kParamWidth | kParamHeight, nullptr, width, height, data, - nullptr, &exception_state)) - return nullptr; - - ImageDataColorSettings* image_setting = ImageDataColorSettings::Create(); - image_setting->setStorageFormat(kUint16ArrayStorageFormatName); - return MakeGarbageCollected<ImageData>(IntSize(width, height), data, - image_setting); -} - -ImageData* ImageData::Create(NotShared<DOMFloat32Array> data, - unsigned width, - ExceptionState& exception_state) { - if (!ImageData::ValidateConstructorArguments(kParamData | kParamWidth, - nullptr, width, 0, data, nullptr, - &exception_state)) - return nullptr; - - unsigned height = base::checked_cast<unsigned>(data->length()) / - (width * ImageData::StorageFormatBytesPerPixel( - kFloat32ArrayStorageFormatName)); - ImageDataColorSettings* image_setting = ImageDataColorSettings::Create(); - image_setting->setStorageFormat(kFloat32ArrayStorageFormatName); - return MakeGarbageCollected<ImageData>(IntSize(width, height), data, - image_setting); -} - -ImageData* ImageData::Create(NotShared<DOMFloat32Array> data, - unsigned width, - unsigned height, - ExceptionState& exception_state) { - if (!ImageData::ValidateConstructorArguments( - kParamData | kParamWidth | kParamHeight, nullptr, width, height, data, - nullptr, &exception_state)) - return nullptr; - - ImageDataColorSettings* image_setting = ImageDataColorSettings::Create(); - image_setting->setStorageFormat(kFloat32ArrayStorageFormatName); - return MakeGarbageCollected<ImageData>(IntSize(width, height), data, - image_setting); -} - -ImageData* ImageData::CreateImageData( - unsigned width, - unsigned height, - const ImageDataColorSettings* color_settings, - ExceptionState& exception_state) { - if (!ImageData::ValidateConstructorArguments( - kParamWidth | kParamHeight, nullptr, width, height, - NotShared<DOMArrayBufferView>(), color_settings, &exception_state)) - return nullptr; - - ImageDataStorageFormat storage_format = - ImageData::GetImageDataStorageFormat(color_settings->storageFormat()); - NotShared<DOMArrayBufferView> buffer_view = AllocateAndValidateDataArray( - 4 * width * height, storage_format, &exception_state); - - if (!buffer_view) - return nullptr; - - return MakeGarbageCollected<ImageData>(IntSize(width, height), buffer_view, - color_settings); -} - -ImageData* ImageData::CreateImageData(ImageDataArray& data, - unsigned width, - unsigned height, - ImageDataColorSettings* color_settings, - ExceptionState& exception_state) { - NotShared<DOMArrayBufferView> buffer_view; - - // When pixels data is provided, we need to override the storage format of - // ImageDataColorSettings with the one that matches the data type of the - // pixels. - String storage_format_name; - - if (data.IsUint8ClampedArray()) { - buffer_view = data.GetAsUint8ClampedArray(); - storage_format_name = kUint8ClampedArrayStorageFormatName; - } else if (data.IsUint16Array()) { - buffer_view = data.GetAsUint16Array(); - storage_format_name = kUint16ArrayStorageFormatName; - } else if (data.IsFloat32Array()) { - buffer_view = data.GetAsFloat32Array(); - storage_format_name = kFloat32ArrayStorageFormatName; - } else { - NOTREACHED(); - } - - if (color_settings->storageFormat() != storage_format_name) - color_settings->setStorageFormat(storage_format_name); - - if (!ImageData::ValidateConstructorArguments( - kParamData | kParamWidth | kParamHeight, nullptr, width, height, - buffer_view, color_settings, &exception_state)) - return nullptr; - - return MakeGarbageCollected<ImageData>(IntSize(width, height), buffer_view, - color_settings); -} - // This function accepts size (0, 0) and always returns the ImageData in // "srgb" color space and "uint8" storage format. ImageData* ImageData::CreateForTest(const IntSize& size) { base::CheckedNumeric<unsigned> data_size = - ImageData::StorageFormatBytesPerPixel(kUint8ClampedArrayStorageFormat); + StorageFormatBytesPerPixel(kUint8ClampedArrayStorageFormat); data_size *= size.Width(); data_size *= size.Height(); if (!data_size.IsValid() || @@ -547,65 +242,17 @@ ImageData* ImageData::CreateForTest(const IntSize& size) { // This function is called from unit tests, and all the parameters are supposed // to be validated on the call site. -ImageData* ImageData::CreateForTest( - const IntSize& size, - NotShared<DOMArrayBufferView> buffer_view, - const ImageDataColorSettings* color_settings) { - return MakeGarbageCollected<ImageData>(size, buffer_view, color_settings); -} - -// Crops ImageData to the intersect of its size and the given rectangle. If the -// intersection is empty or it cannot create the cropped ImageData it returns -// nullptr. This function leaves the source ImageData intact. When crop_rect -// covers all the ImageData, a copy of the ImageData is returned. -// TODO (zakerinasab): crbug.com/774484: As a rule of thumb ImageData belongs to -// the user and its state should not change unless directly modified by the -// user. Therefore, we should be able to remove the extra copy and return a -// "cropped view" on the source ImageData object. -ImageData* ImageData::CropRect(const IntRect& crop_rect, bool flip_y) { - IntRect src_rect(IntPoint(), size_); - const IntRect dst_rect = Intersection(src_rect, crop_rect); - if (dst_rect.IsEmpty()) - return nullptr; - - unsigned data_size = 4 * dst_rect.Width() * dst_rect.Height(); - NotShared<DOMArrayBufferView> buffer_view = AllocateAndValidateDataArray( - data_size, - ImageData::GetImageDataStorageFormat(color_settings_->storageFormat())); - if (!buffer_view) - return nullptr; - - if (src_rect == dst_rect && !flip_y) { - std::memcpy(buffer_view->BufferBase()->Data(), BufferBase()->Data(), - data_size * buffer_view->TypeSize()); - } else { - unsigned data_type_size = - ImageData::StorageFormatBytesPerPixel(color_settings_->storageFormat()); - int src_index = (dst_rect.X() + dst_rect.Y() * src_rect.Width()) * 4; - int dst_index = 0; - if (flip_y) - dst_index = (dst_rect.Height() - 1) * dst_rect.Width() * 4; - int src_row_stride = src_rect.Width() * 4; - int dst_row_stride = flip_y ? -dst_rect.Width() * 4 : dst_rect.Width() * 4; - for (int i = 0; i < dst_rect.Height(); i++) { - std::memcpy(static_cast<char*>(buffer_view->BufferBase()->Data()) + - dst_index / 4 * data_type_size, - static_cast<char*>(BufferBase()->Data()) + - src_index / 4 * data_type_size, - dst_rect.Width() * data_type_size); - src_index += src_row_stride; - dst_index += dst_row_stride; - } - } - return MakeGarbageCollected<ImageData>(dst_rect.Size(), buffer_view, - color_settings_); +ImageData* ImageData::CreateForTest(const IntSize& size, + NotShared<DOMArrayBufferView> buffer_view, + const ImageDataSettings* settings) { + return MakeGarbageCollected<ImageData>(size, buffer_view, settings); } ScriptPromise ImageData::CreateImageBitmap(ScriptState* script_state, base::Optional<IntRect> crop_rect, const ImageBitmapOptions* options, ExceptionState& exception_state) { - if (BufferBase()->IsDetached()) { + if (IsBufferBaseDetached()) { exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError, "The source data has been detached."); return ScriptPromise(); @@ -641,18 +288,6 @@ v8::Local<v8::Object> ImageData::AssociateWithWrapper( return wrapper; } -CanvasColorSpace ImageData::GetCanvasColorSpace( - const String& color_space_name) { - if (color_space_name == kSRGBCanvasColorSpaceName) - return CanvasColorSpace::kSRGB; - if (color_space_name == kRec2020CanvasColorSpaceName) - return CanvasColorSpace::kRec2020; - if (color_space_name == kP3CanvasColorSpaceName) - return CanvasColorSpace::kP3; - NOTREACHED(); - return CanvasColorSpace::kSRGB; -} - String ImageData::CanvasColorSpaceName(CanvasColorSpace color_space) { switch (color_space) { case CanvasColorSpace::kSRGB: @@ -679,7 +314,13 @@ ImageDataStorageFormat ImageData::GetImageDataStorageFormat( return kUint8ClampedArrayStorageFormat; } -ImageDataStorageFormat ImageData::GetImageDataStorageFormat() { +CanvasColorSpace ImageData::GetCanvasColorSpace() const { + if (!RuntimeEnabledFeatures::CanvasColorManagementEnabled()) + return CanvasColorSpace::kSRGB; + return CanvasColorSpaceFromName(settings_->colorSpace()); +} + +ImageDataStorageFormat ImageData::GetImageDataStorageFormat() const { if (data_u16_) return kUint16ArrayStorageFormat; if (data_f32_) @@ -713,192 +354,38 @@ unsigned ImageData::StorageFormatBytesPerPixel( return 1; } -NotShared<DOMArrayBufferView> -ImageData::ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat( - ArrayBufferContents& content, - CanvasPixelFormat pixel_format, - ImageDataStorageFormat storage_format) { - if (!content.DataLength()) - return NotShared<DOMArrayBufferView>(); - - if (pixel_format == CanvasColorParams::GetNativeCanvasPixelFormat() && - storage_format == kUint8ClampedArrayStorageFormat) { - DOMArrayBuffer* array_buffer = DOMArrayBuffer::Create(content); - return NotShared<DOMArrayBufferView>(DOMUint8ClampedArray::Create( - array_buffer, 0, array_buffer->ByteLength())); - } - - skcms_PixelFormat src_format = skcms_PixelFormat_RGBA_8888; - unsigned num_pixels = content.DataLength() / 4; - if (pixel_format == CanvasPixelFormat::kF16) { - src_format = skcms_PixelFormat_RGBA_hhhh; - num_pixels /= 2; - } - skcms_AlphaFormat alpha_format = skcms_AlphaFormat_Unpremul; - - if (storage_format == kUint8ClampedArrayStorageFormat) { - NotShared<DOMUint8ClampedArray> u8_array = - AllocateAndValidateUint8ClampedArray(num_pixels * 4); - if (!u8_array) - return NotShared<DOMArrayBufferView>(); - bool data_transform_successful = skcms_Transform( - content.Data(), src_format, alpha_format, nullptr, u8_array->Data(), - skcms_PixelFormat_RGBA_8888, alpha_format, nullptr, num_pixels); - DCHECK(data_transform_successful); - return u8_array; - } - - if (storage_format == kUint16ArrayStorageFormat) { - NotShared<DOMUint16Array> u16_array = - AllocateAndValidateUint16Array(num_pixels * 4); - if (!u16_array) - return NotShared<DOMArrayBufferView>(); - bool data_transform_successful = skcms_Transform( - content.Data(), src_format, alpha_format, nullptr, u16_array->Data(), - skcms_PixelFormat_RGBA_16161616LE, alpha_format, nullptr, num_pixels); - DCHECK(data_transform_successful); - return u16_array; - } - - NotShared<DOMFloat32Array> f32_array = - AllocateAndValidateFloat32Array(num_pixels * 4); - if (!f32_array) - return NotShared<DOMArrayBufferView>(); - bool data_transform_successful = skcms_Transform( - content.Data(), src_format, alpha_format, nullptr, f32_array->Data(), - skcms_PixelFormat_RGBA_ffff, alpha_format, nullptr, num_pixels); - DCHECK(data_transform_successful); - return f32_array; -} - -DOMArrayBufferBase* ImageData::BufferBase() const { +bool ImageData::IsBufferBaseDetached() const { if (data_.IsUint8ClampedArray()) - return data_.GetAsUint8ClampedArray()->BufferBase(); + return data_.GetAsUint8ClampedArray()->BufferBase()->IsDetached(); if (data_.IsUint16Array()) - return data_.GetAsUint16Array()->BufferBase(); + return data_.GetAsUint16Array()->BufferBase()->IsDetached(); if (data_.IsFloat32Array()) - return data_.GetAsFloat32Array()->BufferBase(); - return nullptr; -} - -CanvasColorParams ImageData::GetCanvasColorParams() { - if (!RuntimeEnabledFeatures::CanvasColorManagementEnabled()) - return CanvasColorParams(); - CanvasColorSpace color_space = - ImageData::GetCanvasColorSpace(color_settings_->colorSpace()); - return CanvasColorParams( - color_space, - color_settings_->storageFormat() != kUint8ClampedArrayStorageFormatName - ? CanvasPixelFormat::kF16 - : CanvasColorParams::GetNativeCanvasPixelFormat(), - kNonOpaque); + return data_.GetAsFloat32Array()->BufferBase()->IsDetached(); + return false; } -SkImageInfo ImageData::GetSkImageInfo() { - SkColorType color_type = kN32_SkColorType; - if (data_u16_) { +SkPixmap ImageData::GetSkPixmap() const { + CHECK(!IsBufferBaseDetached()); + SkColorType color_type = kRGBA_8888_SkColorType; + const void* data = nullptr; + if (data_.IsUint8ClampedArray()) { + color_type = kRGBA_8888_SkColorType; + data = data_.GetAsUint8ClampedArray()->Data(); + } else if (data_.IsUint16Array()) { color_type = kR16G16B16A16_unorm_SkColorType; - } else if (data_f32_) { + data = data_.GetAsUint16Array()->Data(); + } else if (data_.IsFloat32Array()) { color_type = kRGBA_F32_SkColorType; + data = data_.GetAsFloat32Array()->Data(); } - return SkImageInfo::Make(width(), height(), color_type, - kUnpremul_SkAlphaType); -} - -bool ImageData::ImageDataInCanvasColorSettings( - CanvasColorSpace canvas_color_space, - CanvasPixelFormat canvas_pixel_format, - unsigned char* converted_pixels, - DataU8ColorType u8_color_type, - const IntRect* src_rect, - const AlphaDisposition alpha_disposition) { - if (data_.IsNull()) - return false; - - CanvasColorParams canvas_color_params = - CanvasColorParams(canvas_color_space, canvas_pixel_format, kNonOpaque); - - unsigned char* src_data = static_cast<unsigned char*>(BufferBase()->Data()); - - ImageDataStorageFormat storage_format = GetImageDataStorageFormat(); - - skcms_PixelFormat src_pixel_format = skcms_PixelFormat_RGBA_8888; - if (data_u16_) - src_pixel_format = skcms_PixelFormat_RGBA_16161616LE; - else if (data_f32_) - src_pixel_format = skcms_PixelFormat_RGBA_ffff; - - skcms_PixelFormat dst_pixel_format = skcms_PixelFormat_RGBA_8888; - if (canvas_pixel_format == CanvasPixelFormat::kF16) { - dst_pixel_format = skcms_PixelFormat_RGBA_hhhh; - } -#if SK_PMCOLOR_BYTE_ORDER(B, G, R, A) - else if (canvas_pixel_format == - CanvasColorParams::GetNativeCanvasPixelFormat() && - u8_color_type == kN32ColorType) { - dst_pixel_format = skcms_PixelFormat_BGRA_8888; - } -#endif - - skcms_AlphaFormat src_alpha_format = skcms_AlphaFormat_Unpremul; - skcms_AlphaFormat dst_alpha_format = skcms_AlphaFormat_Unpremul; - if (alpha_disposition == kPremultiplyAlpha) - dst_alpha_format = skcms_AlphaFormat_PremulAsEncoded; - - skcms_ICCProfile* src_profile_ptr = nullptr; - skcms_ICCProfile* dst_profile_ptr = nullptr; - skcms_ICCProfile src_profile, dst_profile; - GetCanvasColorParams().GetSkColorSpace()->toProfile(&src_profile); - canvas_color_params.GetSkColorSpace()->toProfile(&dst_profile); - // If the profiles are similar, we better leave them as nullptr, since - // skcms_Transform() only checks for profile pointer equality for the fast - // path. - if (!skcms_ApproximatelyEqualProfiles(&src_profile, &dst_profile)) { - src_profile_ptr = &src_profile; - dst_profile_ptr = &dst_profile; - } - - const IntRect* crop_rect = nullptr; - if (src_rect && *src_rect != IntRect(IntPoint(), Size())) - crop_rect = src_rect; - - // If only a portion of ImageData is required for canvas, we run the transform - // for every line. - if (crop_rect) { - unsigned bytes_per_pixel = - ImageData::StorageFormatBytesPerPixel(storage_format); - unsigned src_index = - (crop_rect->X() + crop_rect->Y() * width()) * bytes_per_pixel; - unsigned dst_index = 0; - unsigned src_row_stride = width() * bytes_per_pixel; - unsigned dst_row_stride = - crop_rect->Width() * canvas_color_params.BytesPerPixel(); - bool data_transform_successful = true; - - for (int i = 0; data_transform_successful && i < crop_rect->Height(); i++) { - data_transform_successful = skcms_Transform( - src_data + src_index, src_pixel_format, src_alpha_format, - src_profile_ptr, converted_pixels + dst_index, dst_pixel_format, - dst_alpha_format, dst_profile_ptr, crop_rect->Width()); - DCHECK(data_transform_successful); - src_index += src_row_stride; - dst_index += dst_row_stride; - } - return data_transform_successful; - } - - base::CheckedNumeric<uint32_t> area = size_.Area(); - if (!area.IsValid()) - return false; - bool data_transform_successful = - skcms_Transform(src_data, src_pixel_format, src_alpha_format, - src_profile_ptr, converted_pixels, dst_pixel_format, - dst_alpha_format, dst_profile_ptr, area.ValueOrDie()); - return data_transform_successful; + SkImageInfo info = + SkImageInfo::Make(width(), height(), color_type, kUnpremul_SkAlphaType, + CanvasColorSpaceToSkColorSpace(GetCanvasColorSpace())); + return SkPixmap(info, data, info.minRowBytes()); } void ImageData::Trace(Visitor* visitor) const { - visitor->Trace(color_settings_); + visitor->Trace(settings_); visitor->Trace(data_); visitor->Trace(data_u8_); visitor->Trace(data_u16_); @@ -908,8 +395,8 @@ void ImageData::Trace(Visitor* visitor) const { ImageData::ImageData(const IntSize& size, NotShared<DOMArrayBufferView> data, - const ImageDataColorSettings* color_settings) - : size_(size), color_settings_(ImageDataColorSettings::Create()) { + const ImageDataSettings* settings) + : size_(size), settings_(ImageDataSettings::Create()) { DCHECK_GE(size.Width(), 0); DCHECK_GE(size.Height(), 0); DCHECK(data); @@ -918,23 +405,17 @@ ImageData::ImageData(const IntSize& size, data_u16_.Clear(); data_f32_.Clear(); - if (color_settings) { - color_settings_->setColorSpace(color_settings->colorSpace()); - color_settings_->setStorageFormat(color_settings->storageFormat()); + if (settings) { + settings_->setColorSpace(settings->colorSpace()); + settings_->setStorageFormat(settings->storageFormat()); } ImageDataStorageFormat storage_format = - GetImageDataStorageFormat(color_settings_->storageFormat()); - - // TODO (zakerinasab): crbug.com/779570 - // The default color space for ImageData with U16/F32 data should be - // extended-srgb color space. It is temporarily set to linear-rgb, which is - // not correct, but fixes crbug.com/779419. - + GetImageDataStorageFormat(settings_->storageFormat()); switch (storage_format) { case kUint8ClampedArrayStorageFormat: - DCHECK(data->GetType() == - DOMArrayBufferView::ViewType::kTypeUint8Clamped); + DCHECK_EQ(data->GetType(), + DOMArrayBufferView::ViewType::kTypeUint8Clamped); data_u8_ = data; DCHECK(data_u8_); data_.SetUint8ClampedArray(data_u8_); @@ -944,7 +425,7 @@ ImageData::ImageData(const IntSize& size, break; case kUint16ArrayStorageFormat: - DCHECK(data->GetType() == DOMArrayBufferView::ViewType::kTypeUint16); + DCHECK_EQ(data->GetType(), DOMArrayBufferView::ViewType::kTypeUint16); data_u16_ = data; DCHECK(data_u16_); data_.SetUint16Array(data_u16_); @@ -954,7 +435,7 @@ ImageData::ImageData(const IntSize& size, break; case kFloat32ArrayStorageFormat: - DCHECK(data->GetType() == DOMArrayBufferView::ViewType::kTypeFloat32); + DCHECK_EQ(data->GetType(), DOMArrayBufferView::ViewType::kTypeFloat32); data_f32_ = data; DCHECK(data_f32_); data_.SetFloat32Array(data_f32_); diff --git a/chromium/third_party/blink/renderer/core/html/canvas/image_data.h b/chromium/third_party/blink/renderer/core/html/canvas/image_data.h index 66d026c6ff8..f6aad266f89 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/image_data.h +++ b/chromium/third_party/blink/renderer/core/html/canvas/image_data.h @@ -31,7 +31,7 @@ #include "base/numerics/checked_math.h" #include "third_party/blink/renderer/bindings/core/v8/uint8_clamped_array_or_uint16_array_or_float32_array.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_image_data_color_settings.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_image_data_settings.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h" #include "third_party/blink/renderer/core/imagebitmap/image_bitmap_source.h" @@ -53,13 +53,6 @@ class ImageBitmapOptions; typedef Uint8ClampedArrayOrUint16ArrayOrFloat32Array ImageDataArray; -enum ConstructorParams { - kParamSize = 1, - kParamWidth = 1 << 1, - kParamHeight = 1 << 2, - kParamData = 1 << 3, -}; - constexpr const char* kUint8ClampedArrayStorageFormatName = "uint8"; constexpr const char* kUint16ArrayStorageFormatName = "uint16"; constexpr const char* kFloat32ArrayStorageFormatName = "float32"; @@ -69,75 +62,130 @@ class CORE_EXPORT ImageData final : public ScriptWrappable, DEFINE_WRAPPERTYPEINFO(); public: - static ImageData* Create(const IntSize&, - const ImageDataColorSettings* = nullptr); - static ImageData* Create(const IntSize&, const CanvasColorParams&); - static ImageData* Create(const IntSize&, - CanvasColorSpace, - ImageDataStorageFormat); - static ImageData* Create(const IntSize&, - NotShared<DOMArrayBufferView>, - const ImageDataColorSettings* = nullptr); - static ImageData* Create(scoped_refptr<StaticBitmapImage>, - AlphaDisposition = kDontChangeAlpha); - - static ImageData* Create(unsigned width, unsigned height, ExceptionState&); - static ImageData* Create(NotShared<DOMUint8ClampedArray>, + // Constructor that takes width, height, and an optional ImageDataSettings. + static ImageData* Create(unsigned width, + unsigned height, + ExceptionState& exception_state) { + return ValidateAndCreate(width, height, base::nullopt, nullptr, + exception_state); + } + static ImageData* Create(unsigned width, + unsigned height, + const ImageDataSettings* settings, + ExceptionState& exception_state) { + return ValidateAndCreate(width, height, base::nullopt, settings, + exception_state, RequireCanvasColorManagement); + } + + // Constructor that takes Uint8ClampedArray, width, optional height, and + // optional ImageDataSettings. + static ImageData* Create(NotShared<DOMUint8ClampedArray> data, unsigned width, - ExceptionState&); - static ImageData* Create(NotShared<DOMUint8ClampedArray>, + ExceptionState& exception_state) { + return ValidateAndCreate(width, base::nullopt, data, nullptr, + exception_state); + } + static ImageData* Create(NotShared<DOMUint8ClampedArray> data, unsigned width, unsigned height, - ExceptionState&); - static ImageData* Create(NotShared<DOMUint16Array>, + ExceptionState& exception_state) { + return ValidateAndCreate(width, height, data, nullptr, exception_state); + } + static ImageData* Create(NotShared<DOMUint8ClampedArray> data, unsigned width, - ExceptionState&); - static ImageData* Create(NotShared<DOMUint16Array>, + unsigned height, + const ImageDataSettings* settings, + ExceptionState& exception_state) { + return ValidateAndCreate(width, height, data, settings, exception_state, + RequireCanvasColorManagement); + } + + // Constructor that takes DOMUint16Array, width, optional height, and optional + // ImageDataSettings. + static ImageData* Create(NotShared<DOMUint16Array> data, + unsigned width, + ExceptionState& exception_state) { + return ValidateAndCreate(width, base::nullopt, data, nullptr, + exception_state, RequireCanvasColorManagement); + } + static ImageData* Create(NotShared<DOMUint16Array> data, unsigned width, unsigned height, - ExceptionState&); - static ImageData* Create(NotShared<DOMFloat32Array>, + ExceptionState& exception_state) { + return ValidateAndCreate(width, height, data, nullptr, exception_state, + RequireCanvasColorManagement); + } + static ImageData* Create(NotShared<DOMUint16Array> data, unsigned width, - ExceptionState&); - static ImageData* Create(NotShared<DOMFloat32Array>, + unsigned height, + const ImageDataSettings* settings, + ExceptionState& exception_state) { + return ValidateAndCreate(width, height, data, settings, exception_state, + RequireCanvasColorManagement); + } + + // Constructor that takes DOMFloat32Array, width, optional height, and + // optional ImageDataSettings. + static ImageData* Create(NotShared<DOMFloat32Array> data, + unsigned width, + ExceptionState& exception_state) { + return ValidateAndCreate(width, base::nullopt, data, nullptr, + exception_state, RequireCanvasColorManagement); + } + static ImageData* Create(NotShared<DOMFloat32Array> data, unsigned width, unsigned height, - ExceptionState&); - - static ImageData* CreateImageData(unsigned width, - unsigned height, - const ImageDataColorSettings*, - ExceptionState&); - static ImageData* CreateImageData(ImageDataArray&, - unsigned width, - unsigned height, - ImageDataColorSettings*, - ExceptionState&); - - ImageDataColorSettings* getColorSettings() { return color_settings_; } + ExceptionState& exception_state) { + return ValidateAndCreate(width, height, data, nullptr, exception_state, + RequireCanvasColorManagement); + } + static ImageData* Create(NotShared<DOMFloat32Array> data, + unsigned width, + unsigned height, + const ImageDataSettings* settings, + ExceptionState& exception_state) { + return ValidateAndCreate(width, height, data, settings, exception_state, + RequireCanvasColorManagement); + } + + // ValidateAndCreate is the common path that all ImageData creation code + // should call directly. The other Create functions are to be called only by + // generated code. + enum ValidateAndCreateFlags { + None = 0x0, + // When a too-large ImageData is created using a constructor, it has + // historically thrown an IndexSizeError. When created through a 2D + // canvas, it has historically thrown a RangeError. This flag will + // trigger the RangeError path. + Context2DErrorMode = 0x1, + // Constructors in IDL files cannot specify RuntimeEnabled restrictions. + // This argument is passed by Create functions that should require that the + // CanvasColorManagement feature be enabled. + RequireCanvasColorManagement = 0x2, + }; + static ImageData* ValidateAndCreate( + unsigned width, + base::Optional<unsigned> height, + base::Optional<NotShared<DOMArrayBufferView>> data, + const ImageDataSettings* settings, + ExceptionState& exception_state, + uint32_t flags = 0); + + ImageDataSettings* getSettings() { return settings_; } static ImageData* CreateForTest(const IntSize&); static ImageData* CreateForTest(const IntSize&, NotShared<DOMArrayBufferView>, - const ImageDataColorSettings* = nullptr); + const ImageDataSettings* = nullptr); ImageData(const IntSize&, NotShared<DOMArrayBufferView>, - const ImageDataColorSettings* = nullptr); - - ImageData* CropRect(const IntRect&, bool flip_y = false); + const ImageDataSettings* = nullptr); - ImageDataStorageFormat GetImageDataStorageFormat(); - static CanvasColorSpace GetCanvasColorSpace(const String&); static String CanvasColorSpaceName(CanvasColorSpace); static ImageDataStorageFormat GetImageDataStorageFormat(const String&); static unsigned StorageFormatBytesPerPixel(const String&); static unsigned StorageFormatBytesPerPixel(ImageDataStorageFormat); - static NotShared<DOMArrayBufferView> - ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat( - ArrayBufferContents&, - CanvasPixelFormat, - ImageDataStorageFormat); IntSize Size() const { return size_; } int width() const { return size_.Width(); } @@ -147,22 +195,12 @@ class CORE_EXPORT ImageData final : public ScriptWrappable, const ImageDataArray& data() const { return data_; } void data(ImageDataArray& result) { result = data_; } - DOMArrayBufferBase* BufferBase() const; - CanvasColorParams GetCanvasColorParams(); - SkImageInfo GetSkImageInfo(); - - // DataU8ColorType param specifies if the converted pixels in uint8 pixel - // format should respect the "native" 32bit ARGB format of Skia's blitters. - // For example, if ImageDataInCanvasColorSettings() is called to fill an - // ImageBuffer, kRGBAColorType should be used. If the converted pixels are - // used to create an ImageBitmap, kN32ColorType should be used. - bool ImageDataInCanvasColorSettings( - CanvasColorSpace, - CanvasPixelFormat, - unsigned char* converted_pixels, - DataU8ColorType, - const IntRect* = nullptr, - const AlphaDisposition = kUnpremultiplyAlpha); + bool IsBufferBaseDetached() const; + CanvasColorSpace GetCanvasColorSpace() const; + ImageDataStorageFormat GetImageDataStorageFormat() const; + + // Return an SkPixmap that references this data directly. + SkPixmap GetSkPixmap() const; // ImageBitmapSource implementation IntSize BitmapSourceSize() const override { return size_; } @@ -178,18 +216,9 @@ class CORE_EXPORT ImageData final : public ScriptWrappable, const WrapperTypeInfo*, v8::Local<v8::Object> wrapper) override; - static bool ValidateConstructorArguments( - const unsigned&, - const IntSize* = nullptr, - const unsigned& = 0, - const unsigned& = 0, - const NotShared<DOMArrayBufferView> = NotShared<DOMArrayBufferView>(), - const ImageDataColorSettings* = nullptr, - ExceptionState* = nullptr); - private: IntSize size_; - Member<ImageDataColorSettings> color_settings_; + Member<ImageDataSettings> settings_; ImageDataArray data_; NotShared<DOMUint8ClampedArray> data_u8_; NotShared<DOMUint16Array> data_u16_; @@ -199,18 +228,6 @@ class CORE_EXPORT ImageData final : public ScriptWrappable, const unsigned&, ImageDataStorageFormat, ExceptionState* = nullptr); - - static NotShared<DOMUint8ClampedArray> AllocateAndValidateUint8ClampedArray( - const unsigned&, - ExceptionState* = nullptr); - - static NotShared<DOMUint16Array> AllocateAndValidateUint16Array( - const unsigned&, - ExceptionState* = nullptr); - - static NotShared<DOMFloat32Array> AllocateAndValidateFloat32Array( - const unsigned&, - ExceptionState* = nullptr); }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/canvas/image_data.idl b/chromium/third_party/blink/renderer/core/html/canvas/image_data.idl index 2ec2035d6cb..07cb4737629 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/image_data.idl +++ b/chromium/third_party/blink/renderer/core/html/canvas/image_data.idl @@ -35,9 +35,11 @@ typedef (Uint8ClampedArray or Uint16Array or Float32Array) ImageDataArray; Exposed=(Window,Worker), Serializable ] interface ImageData { - [RaisesException] constructor(unsigned long sw, unsigned long sh); - [RaisesException] constructor(Uint8ClampedArray data, unsigned long sw, optional unsigned long sh); - [RuntimeEnabled=CanvasColorManagement] ImageDataColorSettings getColorSettings(); + [RaisesException] constructor(unsigned long sw, unsigned long sh, optional ImageDataSettings settings); + [RaisesException] constructor(Uint8ClampedArray data, unsigned long sw, optional unsigned long sh, optional ImageDataSettings settings); + [RaisesException] constructor(Uint16Array data, unsigned long sw, optional unsigned long sh, optional ImageDataSettings settings); + [RaisesException] constructor(Float32Array data, unsigned long sw, optional unsigned long sh, optional ImageDataSettings settings); + [RuntimeEnabled=CanvasColorManagement] ImageDataSettings getSettings(); readonly attribute unsigned long width; readonly attribute unsigned long height; diff --git a/chromium/third_party/blink/renderer/core/html/canvas/image_data_color_settings.idl b/chromium/third_party/blink/renderer/core/html/canvas/image_data_settings.idl index 917e0e182c8..ad08837ea08 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/image_data_color_settings.idl +++ b/chromium/third_party/blink/renderer/core/html/canvas/image_data_settings.idl @@ -7,7 +7,7 @@ enum CanvasColorSpace { "srgb", // default "rec2020", - "p3", + "display-p3", }; enum ImageDataStorageFormat { @@ -16,7 +16,7 @@ enum ImageDataStorageFormat { "float32", }; -dictionary ImageDataColorSettings { +dictionary ImageDataSettings { CanvasColorSpace colorSpace = "srgb"; ImageDataStorageFormat storageFormat = "uint8"; }; diff --git a/chromium/third_party/blink/renderer/core/html/canvas/image_data_test.cc b/chromium/third_party/blink/renderer/core/html/canvas/image_data_test.cc index cddff59d6dd..13ca54e9456 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/image_data_test.cc +++ b/chromium/third_party/blink/renderer/core/html/canvas/image_data_test.cc @@ -27,501 +27,6 @@ TEST_F(ImageDataTest, CreateImageDataTooBig) { } } -// This test verifies the correct behavior of ImageData member function used -// to convert pixels data from canvas pixel format to image data storage -// format. This function is used in BaseRenderingContext2D::getImageData. -TEST_F(ImageDataTest, - TestConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat) { - // Source pixels in RGBA32 - unsigned char rgba32_pixels[] = {255, 0, 0, 255, // Red - 0, 0, 0, 0, // Transparent - 255, 192, 128, 64, // Decreasing values - 93, 117, 205, 11}; // Random values - const unsigned kNumColorComponents = 16; - float f32_pixels[kNumColorComponents]; - for (unsigned i = 0; i < kNumColorComponents; i++) - f32_pixels[i] = rgba32_pixels[i] / 255.0; - - const unsigned kNumPixels = kNumColorComponents / 4; - - // Source pixels in F16 - unsigned char f16_pixels[kNumColorComponents * 2]; - EXPECT_TRUE(skcms_Transform(f32_pixels, skcms_PixelFormat_RGBA_ffff, - skcms_AlphaFormat_Unpremul, nullptr, f16_pixels, - skcms_PixelFormat_RGBA_hhhh, - skcms_AlphaFormat_Unpremul, nullptr, 4)); - - // Source pixels in U16 - uint16_t u16_pixels[kNumColorComponents]; - for (unsigned i = 0; i < kNumColorComponents; i++) - u16_pixels[i] = f32_pixels[i] * 65535.0; - - // Creating ArrayBufferContents objects. We need two buffers for RGBA32 data - // because - // CanvasPixelFormat::kRGBA8->kUint8ClampedArrayStorageFormat - // consumes the input data parameter. - ArrayBufferContents contents_rgba32(kNumColorComponents, 1, - ArrayBufferContents::kNotShared, - ArrayBufferContents::kDontInitialize); - std::memcpy(contents_rgba32.Data(), rgba32_pixels, kNumColorComponents); - - ArrayBufferContents contents_rgba32_2; - contents_rgba32.CopyTo(contents_rgba32_2); - - ArrayBufferContents contents_f16(kNumColorComponents * 2, 1, - ArrayBufferContents::kNotShared, - ArrayBufferContents::kDontInitialize); - std::memcpy(contents_f16.Data(), f16_pixels, kNumColorComponents * 2); - - // Testing CanvasPixelFormat::kRGBA8-> - // kUint8ClampedArrayStorageFormat - NotShared<DOMArrayBufferView> data( - ImageData::ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat( - contents_rgba32, CanvasPixelFormat::kRGBA8, - kUint8ClampedArrayStorageFormat)); - DCHECK(data->GetType() == DOMArrayBufferView::ViewType::kTypeUint8Clamped); - ColorCorrectionTestUtils::CompareColorCorrectedPixels( - data->BaseAddress(), rgba32_pixels, kNumPixels, kPixelFormat_8888, - kAlphaUnmultiplied, kNoUnpremulRoundTripTolerance); - - // Testing CanvasPixelFormat::kRGBA8-> - // kUint16ArrayStorageFormat - data = ImageData::ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat( - contents_rgba32_2, CanvasPixelFormat::kRGBA8, kUint16ArrayStorageFormat); - DCHECK(data->GetType() == DOMArrayBufferView::ViewType::kTypeUint16); - ColorCorrectionTestUtils::CompareColorCorrectedPixels( - data->BaseAddress(), u16_pixels, kNumPixels, kPixelFormat_16161616, - kAlphaUnmultiplied, kUnpremulRoundTripTolerance); - // Testing CanvasPixelFormat::kRGBA8 -> - // kFloat32ArrayStorageFormat - data = ImageData::ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat( - contents_rgba32_2, CanvasPixelFormat::kRGBA8, kFloat32ArrayStorageFormat); - DCHECK(data->GetType() == DOMArrayBufferView::ViewType::kTypeFloat32); - ColorCorrectionTestUtils::CompareColorCorrectedPixels( - data->BaseAddress(), f32_pixels, kNumPixels, kPixelFormat_ffff, - kAlphaUnmultiplied, kUnpremulRoundTripTolerance); - - // Testing CanvasPixelFormat::kF16 -> kUint8ClampedArrayStorageFormat - data = ImageData::ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat( - contents_f16, CanvasPixelFormat::kF16, kUint8ClampedArrayStorageFormat); - DCHECK(data->GetType() == DOMArrayBufferView::ViewType::kTypeUint8Clamped); - ColorCorrectionTestUtils::CompareColorCorrectedPixels( - data->BaseAddress(), rgba32_pixels, kNumPixels, kPixelFormat_8888, - kAlphaUnmultiplied, kNoUnpremulRoundTripTolerance); - - // Testing CanvasPixelFormat::kF16 -> kUint16ArrayStorageFormat - data = ImageData::ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat( - contents_f16, CanvasPixelFormat::kF16, kUint16ArrayStorageFormat); - DCHECK(data->GetType() == DOMArrayBufferView::ViewType::kTypeUint16); - ColorCorrectionTestUtils::CompareColorCorrectedPixels( - data->BaseAddress(), u16_pixels, kNumPixels, kPixelFormat_16161616, - kAlphaUnmultiplied, kUnpremulRoundTripTolerance); - - // Testing CanvasPixelFormat::kF16 -> kFloat32ArrayStorageFormat - data = ImageData::ConvertPixelsFromCanvasPixelFormatToImageDataStorageFormat( - contents_f16, CanvasPixelFormat::kF16, kFloat32ArrayStorageFormat); - DCHECK(data->GetType() == DOMArrayBufferView::ViewType::kTypeFloat32); - ColorCorrectionTestUtils::CompareColorCorrectedPixels( - data->BaseAddress(), f32_pixels, kNumPixels, kPixelFormat_ffff, - kAlphaUnmultiplied, kUnpremulRoundTripTolerance); -} - -// This test verifies the correct behavior of ImageData member function used -// to convert image data from image data storage format to canvas pixel format. -// This function is used in BaseRenderingContext2D::putImageData. -TEST_F(ImageDataTest, TestGetImageDataInCanvasColorSettings) { - unsigned num_image_data_color_spaces = 3; - CanvasColorSpace image_data_color_spaces[] = { - CanvasColorSpace::kSRGB, - CanvasColorSpace::kRec2020, - CanvasColorSpace::kP3, - }; - - unsigned num_image_data_storage_formats = 3; - ImageDataStorageFormat image_data_storage_formats[] = { - kUint8ClampedArrayStorageFormat, kUint16ArrayStorageFormat, - kFloat32ArrayStorageFormat, - }; - - unsigned num_canvas_color_settings = 3; - CanvasColorSpace canvas_color_spaces[] = { - CanvasColorSpace::kSRGB, - CanvasColorSpace::kSRGB, - CanvasColorSpace::kRec2020, - CanvasColorSpace::kP3, - }; - - CanvasPixelFormat canvas_pixel_formats[] = { - CanvasPixelFormat::kRGBA8, CanvasPixelFormat::kF16, - CanvasPixelFormat::kF16, CanvasPixelFormat::kF16, - }; - - // As cross checking the output of Skia color space covnersion API is not in - // the scope of this unit test, we do turn-around tests here. To do so, we - // create an ImageData with the selected color space and storage format, - // convert it to the target canvas color space and pixel format by calling - // ImageData::imageDataInCanvasColorSettings(), and then convert it back - // to the source image data color space and Float32 storage format by calling - // ImageData::convertPixelsFromCanvasPixelFormatToImageDataStorageFormat(). - // We expect to get the same image data as we started with. - - // Source pixels in RGBA32, unpremul - uint8_t u8_pixels[] = {255, 0, 0, 255, // Red - 0, 0, 0, 0, // Transparent - 255, 192, 128, 64, // Decreasing values - 93, 117, 205, 11}; // Random values - size_t data_length = 16; - - uint16_t* u16_pixels = new uint16_t[data_length]; - for (size_t i = 0; i < data_length; i++) - u16_pixels[i] = u8_pixels[i] * 257; - - float* f32_pixels = new float[data_length]; - for (size_t i = 0; i < data_length; i++) - f32_pixels[i] = u8_pixels[i] / 255.0; - - NotShared<DOMUint8ClampedArray> data_u8( - DOMUint8ClampedArray::Create(u8_pixels, data_length)); - DCHECK(data_u8); - EXPECT_EQ(data_length, data_u8->length()); - NotShared<DOMUint16Array> data_u16( - DOMUint16Array::Create(u16_pixels, data_length)); - DCHECK(data_u16); - EXPECT_EQ(data_length, data_u16->length()); - NotShared<DOMFloat32Array> data_f32( - DOMFloat32Array::Create(f32_pixels, data_length)); - DCHECK(data_f32); - EXPECT_EQ(data_length, data_f32->length()); - - ImageData* image_data = nullptr; - ImageDataColorSettings* color_settings = ImageDataColorSettings::Create(); - - // At most two bytes are needed for output per color component. - std::unique_ptr<uint8_t[]> pixels_converted_manually( - new uint8_t[data_length * 2]()); - std::unique_ptr<uint8_t[]> pixels_converted_in_image_data( - new uint8_t[data_length * 2]()); - - // Loop through different possible combinations of image data color space and - // storage formats and create the respective test image data objects. - for (unsigned i = 0; i < num_image_data_color_spaces; i++) { - color_settings->setColorSpace( - ImageData::CanvasColorSpaceName(image_data_color_spaces[i])); - - for (unsigned j = 0; j < num_image_data_storage_formats; j++) { - NotShared<DOMArrayBufferView> data_array; - switch (image_data_storage_formats[j]) { - case kUint8ClampedArrayStorageFormat: - data_array = data_u8; - color_settings->setStorageFormat(kUint8ClampedArrayStorageFormatName); - break; - case kUint16ArrayStorageFormat: - data_array = data_u16; - color_settings->setStorageFormat(kUint16ArrayStorageFormatName); - break; - case kFloat32ArrayStorageFormat: - data_array = data_f32; - color_settings->setStorageFormat(kFloat32ArrayStorageFormatName); - break; - default: - NOTREACHED(); - } - - image_data = - ImageData::CreateForTest(IntSize(2, 2), data_array, color_settings); - - for (unsigned k = 0; k < num_canvas_color_settings; k++) { - // Convert the original data used to create ImageData to the - // canvas color space and canvas pixel format. - EXPECT_TRUE( - ColorCorrectionTestUtils:: - ConvertPixelsToColorSpaceAndPixelFormatForTest( - data_array->BaseAddress(), data_length, - image_data_color_spaces[i], image_data_storage_formats[j], - canvas_color_spaces[k], canvas_pixel_formats[k], - pixels_converted_manually, kPixelFormat_hhhh)); - - // Convert the image data to the color settings of the canvas. - EXPECT_TRUE(image_data->ImageDataInCanvasColorSettings( - canvas_color_spaces[k], canvas_pixel_formats[k], - pixels_converted_in_image_data.get(), kRGBAColorType)); - - // Compare the converted pixels - ColorCorrectionTestUtils::CompareColorCorrectedPixels( - pixels_converted_manually.get(), - pixels_converted_in_image_data.get(), - static_cast<int>(image_data->Size().Area()), - (canvas_pixel_formats[k] == CanvasPixelFormat::kRGBA8) - ? kPixelFormat_8888 - : kPixelFormat_hhhh, - kAlphaUnmultiplied, kUnpremulRoundTripTolerance); - } - } - } - delete[] u16_pixels; - delete[] f32_pixels; -} - -// This test examines ImageData::Create(StaticBitmapImage) -TEST_F(ImageDataTest, TestCreateImageDataFromStaticBitmapImage) { - const unsigned kNumColorComponents = 16; - const unsigned kNumPixels = kNumColorComponents / 4; - const unsigned kWidth = 2; - const unsigned kHeight = 2; - - // Preparing source pixels - uint8_t expected_u8_pixels_unpremul[] = { - 255, 0, 0, 255, // Red - 0, 0, 0, 0, // Transparent - 255, 192, 128, 64, // Decreasing values - 93, 117, 205, 41}; // Random values - - uint8_t expected_u8_pixels_premul[kNumColorComponents]; - uint16_t expected_f16_pixels_unpremul[kNumColorComponents]; - uint16_t expected_f16_pixels_premul[kNumColorComponents]; - float expected_f32_pixels_unpremul[kNumColorComponents]; - float expected_f32_pixels_premul[kNumColorComponents]; - - auto prepareSourcePixels = [&expected_u8_pixels_unpremul, &kNumPixels]( - auto buffer, bool is_premul, - auto pixel_format) { - EXPECT_TRUE(skcms_Transform( - expected_u8_pixels_unpremul, skcms_PixelFormat_RGBA_8888, - skcms_AlphaFormat_Unpremul, nullptr, buffer, pixel_format, - is_premul ? skcms_AlphaFormat_PremulAsEncoded - : skcms_AlphaFormat_Unpremul, - nullptr, kNumPixels)); - }; - - prepareSourcePixels(expected_u8_pixels_premul, true, - skcms_PixelFormat_RGBA_8888); - prepareSourcePixels(expected_f16_pixels_unpremul, false, - skcms_PixelFormat_RGBA_hhhh); - prepareSourcePixels(expected_f16_pixels_premul, true, - skcms_PixelFormat_RGBA_hhhh); - prepareSourcePixels(expected_f32_pixels_unpremul, false, - skcms_PixelFormat_RGBA_ffff); - prepareSourcePixels(expected_f32_pixels_premul, true, - skcms_PixelFormat_RGBA_ffff); - - auto contents_u8_premul = - SkData::MakeWithoutCopy(expected_u8_pixels_premul, kNumColorComponents); - auto contents_u8_unpremul = - SkData::MakeWithoutCopy(expected_u8_pixels_unpremul, kNumColorComponents); - auto contents_f16_premul = SkData::MakeWithoutCopy(expected_f16_pixels_premul, - kNumColorComponents * 2); - auto contents_f16_unpremul = SkData::MakeWithoutCopy( - expected_f16_pixels_unpremul, kNumColorComponents * 2); - - // Preparing StaticBitmapImage objects - auto info_u8_premul = SkImageInfo::Make( - kWidth, kHeight, kRGBA_8888_SkColorType, kPremul_SkAlphaType); - auto info_u8_unpremul = info_u8_premul.makeAlphaType(kUnpremul_SkAlphaType); - auto info_f16_premul = info_u8_premul.makeColorType(kRGBA_F16_SkColorType) - .makeColorSpace(SkColorSpace::MakeSRGBLinear()); - auto info_f16_unpremul = info_f16_premul.makeAlphaType(kUnpremul_SkAlphaType); - - auto image_u8_premul = - StaticBitmapImage::Create(contents_u8_premul, info_u8_premul); - auto image_u8_unpremul = - StaticBitmapImage::Create(contents_u8_unpremul, info_u8_unpremul); - auto image_f16_premul = - StaticBitmapImage::Create(contents_f16_premul, info_f16_premul); - auto image_f16_unpremul = - StaticBitmapImage::Create(contents_f16_unpremul, info_f16_unpremul); - - // Creating ImageData objects - ImageData* actual_image_data_u8[4]; - ImageData* actual_image_data_f32[4]; - // u8 premul - actual_image_data_u8[0] = ImageData::Create(image_u8_premul); - actual_image_data_u8[1] = - ImageData::Create(image_u8_unpremul, kPremultiplyAlpha); - // u8 unpremul - actual_image_data_u8[2] = ImageData::Create(image_u8_unpremul); - actual_image_data_u8[3] = - ImageData::Create(image_u8_premul, kUnpremultiplyAlpha); - - // ImageData does not support half float storage. Therefore, ImageData - // objects that are created from half-float backed StaticBitmapImage objects - // will contain float 32 data items. - - // f32 premul - actual_image_data_f32[0] = ImageData::Create(image_f16_premul); - actual_image_data_f32[1] = - ImageData::Create(image_f16_unpremul, kPremultiplyAlpha); - // f32 unpremul - actual_image_data_f32[2] = ImageData::Create(image_f16_unpremul); - actual_image_data_f32[3] = - ImageData::Create(image_f16_premul, kUnpremultiplyAlpha); - - // Associating expected color component arrays - uint8_t* expected_pixel_arrays_u8[4] = { - expected_u8_pixels_premul, expected_u8_pixels_premul, - expected_u8_pixels_unpremul, expected_u8_pixels_unpremul}; - float* expected_pixel_arrays_f32[4] = { - expected_f32_pixels_premul, expected_f32_pixels_premul, - expected_f32_pixels_unpremul, expected_f32_pixels_unpremul}; - - // Comparing ImageData with the source StaticBitmapImage - for (unsigned i = 0; i < 4; i++) { - ColorCorrectionTestUtils::CompareColorCorrectedPixels( - expected_pixel_arrays_u8[i], - actual_image_data_u8[i]->BufferBase()->Data(), kNumPixels, - kPixelFormat_8888, kAlphaUnmultiplied, kUnpremulRoundTripTolerance); - } - - for (unsigned i = 0; i < 4; i++) { - ColorCorrectionTestUtils::CompareColorCorrectedPixels( - expected_pixel_arrays_f32[i], - actual_image_data_f32[i]->BufferBase()->Data(), kNumPixels, - kPixelFormat_ffff, kAlphaUnmultiplied, kUnpremulRoundTripTolerance); - } -} - -// This test examines ImageData::CropRect() -TEST_F(ImageDataTest, TestCropRect) { - const int num_image_data_storage_formats = 3; - ImageDataStorageFormat image_data_storage_formats[] = { - kUint8ClampedArrayStorageFormat, kUint16ArrayStorageFormat, - kFloat32ArrayStorageFormat, - }; - String image_data_storage_format_names[] = { - kUint8ClampedArrayStorageFormatName, kUint16ArrayStorageFormatName, - kFloat32ArrayStorageFormatName, - }; - - // Source pixels - unsigned width = 20; - unsigned height = 20; - size_t data_length = width * height * 4; - uint8_t* u8_pixels = new uint8_t[data_length]; - uint16_t* u16_pixels = new uint16_t[data_length]; - float* f32_pixels = new float[data_length]; - - // Test scenarios - const int num_test_cases = 14; - const IntRect crop_rects[14] = { - IntRect(3, 4, 5, 6), IntRect(3, 4, 5, 6), IntRect(10, 10, 20, 20), - IntRect(10, 10, 20, 20), IntRect(0, 0, 20, 20), IntRect(0, 0, 20, 20), - IntRect(0, 0, 10, 10), IntRect(0, 0, 10, 10), IntRect(0, 0, 10, 0), - IntRect(0, 0, 0, 10), IntRect(10, 0, 10, 10), IntRect(0, 10, 10, 10), - IntRect(0, 5, 20, 15), IntRect(0, 5, 20, 15)}; - const bool crop_flips[14] = {true, false, true, false, true, false, true, - false, false, false, false, false, true, false}; - - // Fill the pixels with numbers related to their positions - unsigned set_value = 0; - unsigned expected_value = 0; - float fexpected_value = 0; - unsigned index = 0, row_index = 0; - for (unsigned i = 0; i < height; i++) - for (unsigned j = 0; j < width; j++) - for (unsigned k = 0; k < 4; k++) { - index = i * width * 4 + j * 4 + k; - set_value = (i + 1) * (j + 1) * (k + 1); - u8_pixels[index] = set_value % 255; - u16_pixels[index] = (set_value * 257) % 65535; - f32_pixels[index] = (set_value % 255) / 255.0f; - } - - // Create ImageData objects - - NotShared<DOMUint8ClampedArray> data_u8( - DOMUint8ClampedArray::Create(u8_pixels, data_length)); - DCHECK(data_u8); - EXPECT_EQ(data_length, data_u8->length()); - NotShared<DOMUint16Array> data_u16( - DOMUint16Array::Create(u16_pixels, data_length)); - DCHECK(data_u16); - EXPECT_EQ(data_length, data_u16->length()); - NotShared<DOMFloat32Array> data_f32( - DOMFloat32Array::Create(f32_pixels, data_length)); - DCHECK(data_f32); - EXPECT_EQ(data_length, data_f32->length()); - - ImageData* image_data = nullptr; - ImageData* cropped_image_data = nullptr; - - bool test_passed = true; - for (int i = 0; i < num_image_data_storage_formats; i++) { - NotShared<DOMArrayBufferView> data_array; - if (image_data_storage_formats[i] == kUint8ClampedArrayStorageFormat) - data_array = data_u8; - else if (image_data_storage_formats[i] == kUint16ArrayStorageFormat) - data_array = data_u16; - else - data_array = data_f32; - - ImageDataColorSettings* color_settings = ImageDataColorSettings::Create(); - color_settings->setStorageFormat(image_data_storage_format_names[i]); - image_data = ImageData::CreateForTest(IntSize(width, height), data_array, - color_settings); - for (int j = 0; j < num_test_cases; j++) { - // Test the size of the cropped image data - IntRect src_rect(IntPoint(), image_data->Size()); - IntRect crop_rect = Intersection(src_rect, crop_rects[j]); - - cropped_image_data = image_data->CropRect(crop_rects[j], crop_flips[j]); - if (crop_rect.IsEmpty()) { - EXPECT_FALSE(cropped_image_data); - continue; - } - EXPECT_TRUE(cropped_image_data->Size() == crop_rect.Size()); - - // Test the content - for (int k = 0; k < crop_rect.Height(); k++) - for (int m = 0; m < crop_rect.Width(); m++) - for (int n = 0; n < 4; n++) { - row_index = crop_flips[j] ? (crop_rect.Height() - k - 1) : k; - index = - row_index * cropped_image_data->Size().Width() * 4 + m * 4 + n; - expected_value = - (k + crop_rect.Y() + 1) * (m + crop_rect.X() + 1) * (n + 1); - if (image_data_storage_formats[i] == - kUint8ClampedArrayStorageFormat) - expected_value %= 255; - else if (image_data_storage_formats[i] == kUint16ArrayStorageFormat) - expected_value = (expected_value * 257) % 65535; - else - fexpected_value = (expected_value % 255) / 255.0f; - - if (image_data_storage_formats[i] == - kUint8ClampedArrayStorageFormat) { - if (cropped_image_data->data() - .GetAsUint8ClampedArray() - ->Data()[index] != expected_value) { - test_passed = false; - break; - } - } else if (image_data_storage_formats[i] == - kUint16ArrayStorageFormat) { - if (cropped_image_data->data() - .GetAsUint16Array() - .View() - ->Data()[index] != expected_value) { - test_passed = false; - break; - } - } else { - if (cropped_image_data->data() - .GetAsFloat32Array() - .View() - ->Data()[index] != fexpected_value) { - test_passed = false; - break; - } - } - } - EXPECT_TRUE(test_passed); - } - } - - delete[] u8_pixels; - delete[] u16_pixels; - delete[] f32_pixels; -} - TEST_F(ImageDataTest, ImageDataTooBigToAllocateDoesNotCrash) { ImageData* image_data = ImageData::CreateForTest( IntSize(1, (v8::TypedArray::kMaxLength / 4) + 1)); diff --git a/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.cc b/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.cc index 33a77ea25c4..b3d0a644387 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.cc +++ b/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.cc @@ -120,6 +120,18 @@ IntSize ImageElementBase::BitmapSourceSize() const { return image->IntrinsicSize(kDoNotRespectImageOrientation); } +static bool HasDimensionsForImage(SVGImage* svg_image, + base::Optional<IntRect> crop_rect, + const ImageBitmapOptions* options) { + if (!svg_image->ConcreteObjectSize(FloatSize()).IsEmpty()) + return true; + if (crop_rect) + return true; + if (options->hasResizeWidth() && options->hasResizeHeight()) + return true; + return false; +} + ScriptPromise ImageElementBase::CreateImageBitmap( ScriptState* script_state, base::Optional<IntRect> crop_rect, @@ -132,11 +144,20 @@ ScriptPromise ImageElementBase::CreateImageBitmap( "No image can be retrieved from the provided element."); return ScriptPromise(); } - Image* image = image_content->GetImage(); - if (auto* svg_image = DynamicTo<SVGImage>(image)) { - if (!svg_image->HasIntrinsicDimensions() && - (!crop_rect && - (!options->hasResizeWidth() || !options->hasResizeHeight()))) { + if (options->hasResizeWidth() && options->resizeWidth() == 0) { + exception_state.ThrowDOMException( + DOMExceptionCode::kInvalidStateError, + "The resize width dimension is equal to 0."); + return ScriptPromise(); + } + if (options->hasResizeHeight() && options->resizeHeight() == 0) { + exception_state.ThrowDOMException( + DOMExceptionCode::kInvalidStateError, + "The resize width dimension is equal to 0."); + return ScriptPromise(); + } + if (auto* svg_image = DynamicTo<SVGImage>(image_content->GetImage())) { + if (!HasDimensionsForImage(svg_image, crop_rect, options)) { exception_state.ThrowDOMException( DOMExceptionCode::kInvalidStateError, "The image element contains an SVG image without intrinsic " @@ -170,9 +191,4 @@ Image::ImageDecodingMode ImageElementBase::GetDecodingModeForPainting( return decoding_mode_; } -RespectImageOrientationEnum ImageElementBase::RespectImageOrientation() const { - return LayoutObject::ShouldRespectImageOrientation( - GetElement().GetLayoutObject()); -} - } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.h b/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.h index 88f23ca7565..b88e837d1a9 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.h +++ b/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.h @@ -60,11 +60,6 @@ class CORE_EXPORT ImageElementBase : public CanvasImageSource, // Used with HTMLImageElement and SVGImageElement types. Image::ImageDecodingMode GetDecodingModeForPainting(PaintImage::Id); - // Return the image orientation setting from the layout object, if available. - // In the absence of a layout object, kRespectImageOrientation will be - // returned. - RespectImageOrientationEnum RespectImageOrientation() const; - protected: Image::ImageDecodingMode decoding_mode_ = Image::ImageDecodingMode::kUnspecifiedDecode; diff --git a/chromium/third_party/blink/renderer/core/html/conversion_measurement_parsing.cc b/chromium/third_party/blink/renderer/core/html/conversion_measurement_parsing.cc new file mode 100644 index 00000000000..a2165c74e5e --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/conversion_measurement_parsing.cc @@ -0,0 +1,148 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/html/conversion_measurement_parsing.h" + +#include "base/time/time.h" +#include "third_party/blink/public/mojom/devtools/console_message.mojom-blink.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_impression_params.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" +#include "third_party/blink/renderer/core/execution_context/security_context.h" +#include "third_party/blink/renderer/core/frame/frame.h" +#include "third_party/blink/renderer/core/frame/local_dom_window.h" +#include "third_party/blink/renderer/core/frame/web_feature.h" +#include "third_party/blink/renderer/core/html/html_anchor_element.h" +#include "third_party/blink/renderer/core/html_names.h" +#include "third_party/blink/renderer/core/inspector/console_message.h" +#include "third_party/blink/renderer/platform/instrumentation/use_counter.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" +#include "third_party/blink/renderer/platform/weborigin/security_origin.h" + +namespace blink { + +namespace { + +base::Optional<WebImpression> GetImpression( + ExecutionContext* execution_context, + const String& impression_data_string, + const String& conversion_destination_string, + const base::Optional<String>& reporting_origin_string, + base::Optional<uint64_t> impression_expiry_milliseconds) { + if (!RuntimeEnabledFeatures::ConversionMeasurementEnabled(execution_context)) + return base::nullopt; + + if (!execution_context->IsFeatureEnabled( + mojom::blink::FeaturePolicyFeature::kConversionMeasurement)) { + String message = + "The 'conversion-measurement' feature policy must be enabled to " + "declare an impression."; + execution_context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( + mojom::blink::ConsoleMessageSource::kOther, + mojom::blink::ConsoleMessageLevel::kError, message)); + return base::nullopt; + } + + // Conversion measurement is only allowed when both the frame and the main + // frame (if different) have a secure origin. + LocalFrame* frame = nullptr; + if (auto* window = DynamicTo<LocalDOMWindow>(execution_context)) { + frame = window->GetFrame(); + } else { + return base::nullopt; + } + + const Frame& main_frame = frame->Tree().Top(); + if (!main_frame.GetSecurityContext() + ->GetSecurityOrigin() + ->IsPotentiallyTrustworthy()) { + return base::nullopt; + } + + if (!frame->IsMainFrame() && !frame->GetSecurityContext() + ->GetSecurityOrigin() + ->IsPotentiallyTrustworthy()) { + return base::nullopt; + } + + scoped_refptr<const SecurityOrigin> conversion_destination = + SecurityOrigin::CreateFromString(conversion_destination_string); + if (!conversion_destination->IsPotentiallyTrustworthy()) + return base::nullopt; + + bool impression_data_is_valid = false; + uint64_t impression_data = + impression_data_string.ToUInt64Strict(&impression_data_is_valid); + + // Provide a default of 0 if the impression data was not valid. + impression_data = impression_data_is_valid ? impression_data : 0UL; + + // Reporting origin is an optional attribute. Reporting origins must be + // secure. + base::Optional<WebSecurityOrigin> reporting_origin; + if (reporting_origin_string) { + reporting_origin = + SecurityOrigin::CreateFromString(*reporting_origin_string); + + if (!reporting_origin->IsPotentiallyTrustworthy()) + return base::nullopt; + } + + base::Optional<base::TimeDelta> expiry; + if (impression_expiry_milliseconds) + expiry = base::TimeDelta::FromMilliseconds(*impression_expiry_milliseconds); + + UseCounter::Count(execution_context, + mojom::blink::WebFeature::kConversionAPIAll); + UseCounter::Count(execution_context, + mojom::blink::WebFeature::kImpressionRegistration); + + return WebImpression{conversion_destination, reporting_origin, + impression_data, expiry}; +} + +} // namespace + +base::Optional<WebImpression> GetImpressionForAnchor( + HTMLAnchorElement* element) { + base::Optional<uint64_t> expiry; + if (element->hasAttribute(html_names::kImpressionexpiryAttr)) { + bool expiry_is_valid = false; + uint64_t expiry_milliseconds = + element->FastGetAttribute(html_names::kImpressionexpiryAttr) + .GetString() + .ToUInt64Strict(&expiry_is_valid); + if (expiry_is_valid) + expiry = expiry_milliseconds; + } + + DCHECK(element->hasAttribute(html_names::kConversiondestinationAttr)); + DCHECK(element->hasAttribute(html_names::kImpressiondataAttr)); + + return GetImpression( + element->GetExecutionContext(), + element->FastGetAttribute(html_names::kImpressiondataAttr).GetString(), + element->FastGetAttribute(html_names::kConversiondestinationAttr) + .GetString(), + element->hasAttribute(html_names::kReportingoriginAttr) + ? base::make_optional( + element->FastGetAttribute(html_names::kReportingoriginAttr) + .GetString()) + : base::nullopt, + expiry); +} + +base::Optional<WebImpression> GetImpressionForParams( + ExecutionContext* execution_context, + const ImpressionParams* params) { + return GetImpression(execution_context, params->impressionData(), + params->conversionDestination(), + params->hasReportingOrigin() + ? base::make_optional(params->reportingOrigin()) + : base::nullopt, + params->hasImpressionExpiry() + ? base::make_optional(params->impressionExpiry()) + : base::nullopt); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/conversion_measurement_parsing.h b/chromium/third_party/blink/renderer/core/html/conversion_measurement_parsing.h new file mode 100644 index 00000000000..82e4c04c632 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/conversion_measurement_parsing.h @@ -0,0 +1,35 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CONVERSION_MEASUREMENT_PARSING_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CONVERSION_MEASUREMENT_PARSING_H_ + +#include <stdint.h> +#include <memory> + +#include "base/optional.h" +#include "third_party/blink/public/platform/web_impression.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" + +namespace blink { + +class ExecutionContext; +class HTMLAnchorElement; +class ImpressionParams; + +// Returns the WebImpression struct with all data declared by impression +// related attributes on |element|. If the impression attributes do not contain +// allowed values, base::nullopt is returned. +base::Optional<WebImpression> GetImpressionForAnchor( + HTMLAnchorElement* element); + +// Same as GetImpressionForAnchor(), but gets an impression specified by an +// ImpressionParams dictionary associated with a window.open call. +base::Optional<WebImpression> GetImpressionForParams( + ExecutionContext* execution_context, + const ImpressionParams* params); + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CONVERSION_MEASUREMENT_PARSING_H_ diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element.cc b/chromium/third_party/blink/renderer/core/html/custom/custom_element.cc index 7e121c6c15a..88c244e0cd5 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/custom_element.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element.cc @@ -12,8 +12,6 @@ #include "third_party/blink/renderer/core/html/custom/custom_element_reaction_factory.h" #include "third_party/blink/renderer/core/html/custom/custom_element_reaction_stack.h" #include "third_party/blink/renderer/core/html/custom/custom_element_registry.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.h" #include "third_party/blink/renderer/core/html/html_element.h" #include "third_party/blink/renderer/core/html/html_unknown_element.h" #include "third_party/blink/renderer/core/html_element_factory.h" @@ -144,8 +142,7 @@ HTMLElement* CustomElement::CreateCustomElement(Document& document, document, tag_name, flags, g_null_atom)); } -// Step 7 of https://dom.spec.whatwg.org/#concept-create-element in -// addition to Custom Element V0 handling. +// Step 7 of https://dom.spec.whatwg.org/#concept-create-element template <CustomElement::CreateUUCheckLevel level> Element* CustomElement::CreateUncustomizedOrUndefinedElementTemplate( Document& document, @@ -157,29 +154,11 @@ Element* CustomElement::CreateUncustomizedOrUndefinedElementTemplate( DCHECK(ShouldCreateCustomElement(tag_name)) << tag_name; } - Element* element; - if (RuntimeEnabledFeatures::CustomElementsV0Enabled()) { - if (V0CustomElement::IsValidName(tag_name.LocalName()) && - document.RegistrationContext()) { - element = document.RegistrationContext()->CreateCustomTagElement( - document, tag_name); - } else { - element = document.CreateRawElement(tag_name, flags); - if (level == kCheckAll && !is_value.IsNull()) { - element->SetIsValue(is_value); - if (flags.IsCustomElementsV0()) { - V0CustomElementRegistrationContext::SetTypeExtension(element, - is_value); - } - } - } - } else { - // 7.1. Let interface be the element interface for localName and namespace. - // 7.2. Set result to a new element that implements interface, with ... - element = document.CreateRawElement(tag_name, flags); - if (level == kCheckAll && !is_value.IsNull()) - element->SetIsValue(is_value); - } + // 7.1. Let interface be the element interface for localName and namespace. + // 7.2. Set result to a new element that implements interface, with ... + Element* element = document.CreateRawElement(tag_name, flags); + if (level == kCheckAll && !is_value.IsNull()) + element->SetIsValue(is_value); // 7.3. If namespace is the HTML namespace, and either localName is a // valid custom element name or is is non-null, then set result’s diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_definition_test.cc b/chromium/third_party/blink/renderer/core/html/custom/custom_element_definition_test.cc index 404a9472907..87469ef7065 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_definition_test.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_definition_test.cc @@ -34,12 +34,11 @@ TEST(CustomElementDefinitionTest, upgrade_clearsReactionQueueOnFailure) { << "sanity check: this element should be ready to upgrade"; { CEReactionsScope reactions; - HeapVector<Member<Command>>* commands = - MakeGarbageCollected<HeapVector<Member<Command>>>(); - commands->push_back(MakeGarbageCollected<Unreached>( + HeapVector<Member<Command>> commands; + commands.push_back(MakeGarbageCollected<Unreached>( "upgrade failure should clear the reaction queue")); reactions.EnqueueToCurrentQueue( - element, *MakeGarbageCollected<TestReaction>(commands)); + element, *MakeGarbageCollected<TestReaction>(std::move(commands))); ConstructorFails definition(CustomElementDescriptor("a-a", "a-a")); definition.Upgrade(element); } @@ -53,12 +52,11 @@ TEST(CustomElementDefinitionTest, EXPECT_EQ(CustomElementState::kUndefined, element.GetCustomElementState()) << "sanity check: this element should be ready to upgrade"; ResetCustomElementReactionStackForTest reset_reaction_stack; - HeapVector<Member<Command>>* commands = - MakeGarbageCollected<HeapVector<Member<Command>>>(); - commands->push_back(MakeGarbageCollected<Unreached>( + HeapVector<Member<Command>> commands; + commands.push_back(MakeGarbageCollected<Unreached>( "upgrade failure should clear the reaction queue")); reset_reaction_stack.Stack().EnqueueToBackupQueue( - element, *MakeGarbageCollected<TestReaction>(commands)); + element, *MakeGarbageCollected<TestReaction>(std::move(commands))); ConstructorFails definition(CustomElementDescriptor("a-a", "a-a")); definition.Upgrade(element); EXPECT_EQ(CustomElementState::kFailed, element.GetCustomElementState()) diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_queue.cc b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_queue.cc index 1e78556eabe..6570895bbc8 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_queue.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_queue.cc @@ -32,9 +32,8 @@ void CustomElementReactionQueue::InvokeReactions(Element& element) { reactions_[index_++] = nullptr; reaction->Invoke(element); } - // Unlike V0CustomElementsCallbackQueue, reactions are always - // inserted by steps which bump the global element queue. This - // means we do not need queue "owner" guards. + // Reactions are always inserted by steps which bump the global element queue. + // This means we do not need queue "owner" guards. // https://html.spec.whatwg.org/C/#custom-element-reactions Clear(); } diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_queue_test.cc b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_queue_test.cc index 4f3c7506adf..7703104e3e7 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_queue_test.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_queue_test.cc @@ -18,10 +18,9 @@ TEST(CustomElementReactionQueueTest, invokeReactions_one) { Vector<char> log; CustomElementReactionQueue* queue = MakeGarbageCollected<CustomElementReactionQueue>(); - HeapVector<Member<Command>>* commands = - MakeGarbageCollected<HeapVector<Member<Command>>>(); - commands->push_back(MakeGarbageCollected<Log>('a', log)); - queue->Add(*MakeGarbageCollected<TestReaction>(commands)); + HeapVector<Member<Command>> commands; + commands.push_back(MakeGarbageCollected<Log>('a', log)); + queue->Add(*MakeGarbageCollected<TestReaction>(std::move(commands))); Element* test_element = CreateElement(AtomicString("my-element")); queue->InvokeReactions(*test_element); EXPECT_EQ(log, Vector<char>({'a'})) @@ -33,22 +32,19 @@ TEST(CustomElementReactionQueueTest, invokeReactions_many) { CustomElementReactionQueue* queue = MakeGarbageCollected<CustomElementReactionQueue>(); { - HeapVector<Member<Command>>* commands = - MakeGarbageCollected<HeapVector<Member<Command>>>(); - commands->push_back(MakeGarbageCollected<Log>('a', log)); - queue->Add(*MakeGarbageCollected<TestReaction>(commands)); + HeapVector<Member<Command>> commands; + commands.push_back(MakeGarbageCollected<Log>('a', log)); + queue->Add(*MakeGarbageCollected<TestReaction>(std::move(commands))); } { - HeapVector<Member<Command>>* commands = - MakeGarbageCollected<HeapVector<Member<Command>>>(); - commands->push_back(MakeGarbageCollected<Log>('b', log)); - queue->Add(*MakeGarbageCollected<TestReaction>(commands)); + HeapVector<Member<Command>> commands; + commands.push_back(MakeGarbageCollected<Log>('b', log)); + queue->Add(*MakeGarbageCollected<TestReaction>(std::move(commands))); } { - HeapVector<Member<Command>>* commands = - MakeGarbageCollected<HeapVector<Member<Command>>>(); - commands->push_back(MakeGarbageCollected<Log>('c', log)); - queue->Add(*MakeGarbageCollected<TestReaction>(commands)); + HeapVector<Member<Command>> commands; + commands.push_back(MakeGarbageCollected<Log>('c', log)); + queue->Add(*MakeGarbageCollected<TestReaction>(std::move(commands))); } Element* test_element = CreateElement(AtomicString("my-element")); queue->InvokeReactions(*test_element); @@ -61,27 +57,24 @@ TEST(CustomElementReactionQueueTest, invokeReactions_recursive) { CustomElementReactionQueue* queue = MakeGarbageCollected<CustomElementReactionQueue>(); - HeapVector<Member<Command>>* third_commands = - MakeGarbageCollected<HeapVector<Member<Command>>>(); - third_commands->push_back(MakeGarbageCollected<Log>('c', log)); - third_commands->push_back(MakeGarbageCollected<Recurse>(queue)); - CustomElementReaction* third = - MakeGarbageCollected<TestReaction>(third_commands); // "Empty" recursion + HeapVector<Member<Command>> third_commands; + third_commands.push_back(MakeGarbageCollected<Log>('c', log)); + third_commands.push_back(MakeGarbageCollected<Recurse>(queue)); + CustomElementReaction* third = MakeGarbageCollected<TestReaction>( + std::move(third_commands)); // "Empty" recursion - HeapVector<Member<Command>>* second_commands = - MakeGarbageCollected<HeapVector<Member<Command>>>(); - second_commands->push_back(MakeGarbageCollected<Log>('b', log)); - second_commands->push_back(MakeGarbageCollected<Enqueue>(queue, third)); + HeapVector<Member<Command>> second_commands; + second_commands.push_back(MakeGarbageCollected<Log>('b', log)); + second_commands.push_back(MakeGarbageCollected<Enqueue>(queue, third)); CustomElementReaction* second = MakeGarbageCollected<TestReaction>( - second_commands); // Unwinds one level of recursion + std::move(second_commands)); // Unwinds one level of recursion - HeapVector<Member<Command>>* first_commands = - MakeGarbageCollected<HeapVector<Member<Command>>>(); - first_commands->push_back(MakeGarbageCollected<Log>('a', log)); - first_commands->push_back(MakeGarbageCollected<Enqueue>(queue, second)); - first_commands->push_back(MakeGarbageCollected<Recurse>(queue)); + HeapVector<Member<Command>> first_commands; + first_commands.push_back(MakeGarbageCollected<Log>('a', log)); + first_commands.push_back(MakeGarbageCollected<Enqueue>(queue, second)); + first_commands.push_back(MakeGarbageCollected<Recurse>(queue)); CustomElementReaction* first = MakeGarbageCollected<TestReaction>( - first_commands); // Non-empty recursion + std::move(first_commands)); // Non-empty recursion queue->Add(*first); Element* test_element = CreateElement(AtomicString("my-element")); @@ -96,24 +89,21 @@ TEST(CustomElementReactionQueueTest, clear_duringInvoke) { MakeGarbageCollected<CustomElementReactionQueue>(); { - HeapVector<Member<Command>>* commands = - MakeGarbageCollected<HeapVector<Member<Command>>>(); - commands->push_back(MakeGarbageCollected<Log>('a', log)); - queue->Add(*MakeGarbageCollected<TestReaction>(commands)); + HeapVector<Member<Command>> commands; + commands.push_back(MakeGarbageCollected<Log>('a', log)); + queue->Add(*MakeGarbageCollected<TestReaction>(std::move(commands))); } { - HeapVector<Member<Command>>* commands = - MakeGarbageCollected<HeapVector<Member<Command>>>(); - commands->push_back(MakeGarbageCollected<Call>(WTF::Bind( + HeapVector<Member<Command>> commands; + commands.push_back(MakeGarbageCollected<Call>(WTF::Bind( [](CustomElementReactionQueue* queue, Element&) { queue->Clear(); }, WrapPersistent(queue)))); - queue->Add(*MakeGarbageCollected<TestReaction>(commands)); + queue->Add(*MakeGarbageCollected<TestReaction>(std::move(commands))); } { - HeapVector<Member<Command>>* commands = - MakeGarbageCollected<HeapVector<Member<Command>>>(); - commands->push_back(MakeGarbageCollected<Log>('b', log)); - queue->Add(*MakeGarbageCollected<TestReaction>(commands)); + HeapVector<Member<Command>> commands; + commands.push_back(MakeGarbageCollected<Log>('b', log)); + queue->Add(*MakeGarbageCollected<TestReaction>(std::move(commands))); } Element* test_element = CreateElement(AtomicString("my-element")); diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack_test.cc b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack_test.cc index b3a8d86dab5..a515720ba83 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack_test.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack_test.cc @@ -21,11 +21,11 @@ TEST(CustomElementReactionStackTest, one) { CustomElementReactionStack* stack = MakeGarbageCollected<CustomElementReactionStack>(); stack->Push(); - HeapVector<Member<Command>>* commands = - MakeGarbageCollected<HeapVector<Member<Command>>>(); - commands->push_back(MakeGarbageCollected<Log>('a', log)); - stack->EnqueueToCurrentQueue(*CreateElement("a"), - *MakeGarbageCollected<TestReaction>(commands)); + HeapVector<Member<Command>> commands; + commands.push_back(MakeGarbageCollected<Log>('a', log)); + stack->EnqueueToCurrentQueue( + *CreateElement("a"), + *MakeGarbageCollected<TestReaction>(std::move(commands))); stack->PopInvokingReactions(); EXPECT_EQ(log, Vector<char>({'a'})) @@ -39,18 +39,18 @@ TEST(CustomElementReactionStackTest, multipleElements) { MakeGarbageCollected<CustomElementReactionStack>(); stack->Push(); { - HeapVector<Member<Command>>* commands = - MakeGarbageCollected<HeapVector<Member<Command>>>(); - commands->push_back(MakeGarbageCollected<Log>('a', log)); - stack->EnqueueToCurrentQueue(*CreateElement("a"), - *MakeGarbageCollected<TestReaction>(commands)); + HeapVector<Member<Command>> commands; + commands.push_back(MakeGarbageCollected<Log>('a', log)); + stack->EnqueueToCurrentQueue( + *CreateElement("a"), + *MakeGarbageCollected<TestReaction>(std::move(commands))); } { - HeapVector<Member<Command>>* commands = - MakeGarbageCollected<HeapVector<Member<Command>>>(); - commands->push_back(MakeGarbageCollected<Log>('b', log)); - stack->EnqueueToCurrentQueue(*CreateElement("a"), - *MakeGarbageCollected<TestReaction>(commands)); + HeapVector<Member<Command>> commands; + commands.push_back(MakeGarbageCollected<Log>('b', log)); + stack->EnqueueToCurrentQueue( + *CreateElement("a"), + *MakeGarbageCollected<TestReaction>(std::move(commands))); } stack->PopInvokingReactions(); @@ -64,11 +64,11 @@ TEST(CustomElementReactionStackTest, popTopEmpty) { CustomElementReactionStack* stack = MakeGarbageCollected<CustomElementReactionStack>(); stack->Push(); - HeapVector<Member<Command>>* commands = - MakeGarbageCollected<HeapVector<Member<Command>>>(); - commands->push_back(MakeGarbageCollected<Log>('a', log)); - stack->EnqueueToCurrentQueue(*CreateElement("a"), - *MakeGarbageCollected<TestReaction>(commands)); + HeapVector<Member<Command>> commands; + commands.push_back(MakeGarbageCollected<Log>('a', log)); + stack->EnqueueToCurrentQueue( + *CreateElement("a"), + *MakeGarbageCollected<TestReaction>(std::move(commands))); stack->Push(); stack->PopInvokingReactions(); @@ -83,19 +83,19 @@ TEST(CustomElementReactionStackTest, popTop) { MakeGarbageCollected<CustomElementReactionStack>(); stack->Push(); { - HeapVector<Member<Command>>* commands = - MakeGarbageCollected<HeapVector<Member<Command>>>(); - commands->push_back(MakeGarbageCollected<Log>('a', log)); - stack->EnqueueToCurrentQueue(*CreateElement("a"), - *MakeGarbageCollected<TestReaction>(commands)); + HeapVector<Member<Command>> commands; + commands.push_back(MakeGarbageCollected<Log>('a', log)); + stack->EnqueueToCurrentQueue( + *CreateElement("a"), + *MakeGarbageCollected<TestReaction>(std::move(commands))); } stack->Push(); { - HeapVector<Member<Command>>* commands = - MakeGarbageCollected<HeapVector<Member<Command>>>(); - commands->push_back(MakeGarbageCollected<Log>('b', log)); - stack->EnqueueToCurrentQueue(*CreateElement("a"), - *MakeGarbageCollected<TestReaction>(commands)); + HeapVector<Member<Command>> commands; + commands.push_back(MakeGarbageCollected<Log>('b', log)); + stack->EnqueueToCurrentQueue( + *CreateElement("a"), + *MakeGarbageCollected<TestReaction>(std::move(commands))); } stack->PopInvokingReactions(); @@ -112,25 +112,23 @@ TEST(CustomElementReactionStackTest, requeueingDoesNotReorderElements) { MakeGarbageCollected<CustomElementReactionStack>(); stack->Push(); { - HeapVector<Member<Command>>* commands = - MakeGarbageCollected<HeapVector<Member<Command>>>(); - commands->push_back(MakeGarbageCollected<Log>('a', log)); - stack->EnqueueToCurrentQueue(element, - *MakeGarbageCollected<TestReaction>(commands)); + HeapVector<Member<Command>> commands; + commands.push_back(MakeGarbageCollected<Log>('a', log)); + stack->EnqueueToCurrentQueue( + element, *MakeGarbageCollected<TestReaction>(std::move(commands))); } { - HeapVector<Member<Command>>* commands = - MakeGarbageCollected<HeapVector<Member<Command>>>(); - commands->push_back(MakeGarbageCollected<Log>('z', log)); - stack->EnqueueToCurrentQueue(*CreateElement("a"), - *MakeGarbageCollected<TestReaction>(commands)); + HeapVector<Member<Command>> commands; + commands.push_back(MakeGarbageCollected<Log>('z', log)); + stack->EnqueueToCurrentQueue( + *CreateElement("a"), + *MakeGarbageCollected<TestReaction>(std::move(commands))); } { - HeapVector<Member<Command>>* commands = - MakeGarbageCollected<HeapVector<Member<Command>>>(); - commands->push_back(MakeGarbageCollected<Log>('b', log)); - stack->EnqueueToCurrentQueue(element, - *MakeGarbageCollected<TestReaction>(commands)); + HeapVector<Member<Command>> commands; + commands.push_back(MakeGarbageCollected<Log>('b', log)); + stack->EnqueueToCurrentQueue( + element, *MakeGarbageCollected<TestReaction>(std::move(commands))); } stack->PopInvokingReactions(); @@ -147,33 +145,31 @@ TEST(CustomElementReactionStackTest, oneReactionQueuePerElement) { MakeGarbageCollected<CustomElementReactionStack>(); stack->Push(); { - HeapVector<Member<Command>>* commands = - MakeGarbageCollected<HeapVector<Member<Command>>>(); - commands->push_back(MakeGarbageCollected<Log>('a', log)); - stack->EnqueueToCurrentQueue(element, - *MakeGarbageCollected<TestReaction>(commands)); + HeapVector<Member<Command>> commands; + commands.push_back(MakeGarbageCollected<Log>('a', log)); + stack->EnqueueToCurrentQueue( + element, *MakeGarbageCollected<TestReaction>(std::move(commands))); } { - HeapVector<Member<Command>>* commands = - MakeGarbageCollected<HeapVector<Member<Command>>>(); - commands->push_back(MakeGarbageCollected<Log>('z', log)); - stack->EnqueueToCurrentQueue(*CreateElement("a"), - *MakeGarbageCollected<TestReaction>(commands)); + HeapVector<Member<Command>> commands; + commands.push_back(MakeGarbageCollected<Log>('z', log)); + stack->EnqueueToCurrentQueue( + *CreateElement("a"), + *MakeGarbageCollected<TestReaction>(std::move(commands))); } stack->Push(); { - HeapVector<Member<Command>>* commands = - MakeGarbageCollected<HeapVector<Member<Command>>>(); - commands->push_back(MakeGarbageCollected<Log>('y', log)); - stack->EnqueueToCurrentQueue(*CreateElement("a"), - *MakeGarbageCollected<TestReaction>(commands)); + HeapVector<Member<Command>> commands; + commands.push_back(MakeGarbageCollected<Log>('y', log)); + stack->EnqueueToCurrentQueue( + *CreateElement("a"), + *MakeGarbageCollected<TestReaction>(std::move(commands))); } { - HeapVector<Member<Command>>* commands = - MakeGarbageCollected<HeapVector<Member<Command>>>(); - commands->push_back(MakeGarbageCollected<Log>('b', log)); - stack->EnqueueToCurrentQueue(element, - *MakeGarbageCollected<TestReaction>(commands)); + HeapVector<Member<Command>> commands; + commands.push_back(MakeGarbageCollected<Log>('b', log)); + stack->EnqueueToCurrentQueue( + element, *MakeGarbageCollected<TestReaction>(std::move(commands))); } stack->PopInvokingReactions(); @@ -219,15 +215,14 @@ TEST(CustomElementReactionStackTest, enqueueFromReaction) { MakeGarbageCollected<CustomElementReactionStack>(); stack->Push(); { - HeapVector<Member<Command>>* subcommands = - MakeGarbageCollected<HeapVector<Member<Command>>>(); - subcommands->push_back(MakeGarbageCollected<Log>('a', log)); - HeapVector<Member<Command>>* commands = - MakeGarbageCollected<HeapVector<Member<Command>>>(); - commands->push_back(MakeGarbageCollected<EnqueueToStack>( - stack, element, MakeGarbageCollected<TestReaction>(subcommands))); - stack->EnqueueToCurrentQueue(element, - *MakeGarbageCollected<TestReaction>(commands)); + HeapVector<Member<Command>> subcommands; + subcommands.push_back(MakeGarbageCollected<Log>('a', log)); + HeapVector<Member<Command>> commands; + commands.push_back(MakeGarbageCollected<EnqueueToStack>( + stack, element, + MakeGarbageCollected<TestReaction>(std::move(subcommands)))); + stack->EnqueueToCurrentQueue( + element, *MakeGarbageCollected<TestReaction>(std::move(commands))); } stack->PopInvokingReactions(); diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_test_helpers.h b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_test_helpers.h index ee3a1291d03..a9417d1f27b 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_test_helpers.h +++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_test_helpers.h @@ -107,23 +107,23 @@ class Enqueue : public Command { class TestReaction : public CustomElementReaction { public: - TestReaction(HeapVector<Member<Command>>* commands) + explicit TestReaction(HeapVector<Member<Command>>&& commands) : CustomElementReaction( *MakeGarbageCollected<TestCustomElementDefinition>( CustomElementDescriptor("mock-element", "mock-element"))), - commands_(commands) {} + commands_(std::move(commands)) {} ~TestReaction() override = default; void Trace(Visitor* visitor) const override { CustomElementReaction::Trace(visitor); visitor->Trace(commands_); } void Invoke(Element& element) override { - for (auto& command : *commands_) + for (auto& command : commands_) command->Run(element); } private: - Member<HeapVector<Member<Command>>> commands_; + HeapVector<Member<Command>> commands_; DISALLOW_COPY_AND_ASSIGN(TestReaction); }; diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.cc b/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.cc index 55380bb760c..29196fe5e89 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.cc @@ -25,7 +25,6 @@ #include "third_party/blink/renderer/core/html/custom/custom_element_descriptor.h" #include "third_party/blink/renderer/core/html/custom/custom_element_reaction_stack.h" #include "third_party/blink/renderer/core/html/custom/custom_element_upgrade_sorter.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.h" #include "third_party/blink/renderer/core/html_element_type_helpers.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" @@ -78,19 +77,12 @@ bool ThrowIfValidName(const AtomicString& name, CustomElementRegistry::CustomElementRegistry(const LocalDOMWindow* owner) : element_definition_is_running_(false), owner_(owner), - v0_(MakeGarbageCollected<V0RegistrySet>()), upgrade_candidates_(MakeGarbageCollected<UpgradeCandidateMap>()), - reaction_stack_(&CustomElementReactionStack::Current()) { - Document* document = owner->document(); - if (V0CustomElementRegistrationContext* v0 = - document ? document->RegistrationContext() : nullptr) - Entangle(v0); -} + reaction_stack_(&CustomElementReactionStack::Current()) {} void CustomElementRegistry::Trace(Visitor* visitor) const { visitor->Trace(definitions_); visitor->Trace(owner_); - visitor->Trace(v0_); visitor->Trace(upgrade_candidates_); visitor->Trace(when_defined_promise_map_); visitor->Trace(reaction_stack_); @@ -124,7 +116,7 @@ CustomElementDefinition* CustomElementRegistry::DefineInternal( if (ThrowIfInvalidName(name, allow_embedder_names, exception_state)) return nullptr; - if (NameIsDefined(name) || V0NameIsDefined(name)) { + if (NameIsDefined(name)) { exception_state.ThrowDOMException( DOMExceptionCode::kNotSupportedError, "the name \"" + name + "\" has already been used with this registry"); @@ -265,19 +257,6 @@ bool CustomElementRegistry::NameIsDefined(const AtomicString& name) const { return name_id_map_.Contains(name); } -void CustomElementRegistry::Entangle(V0CustomElementRegistrationContext* v0) { - v0_->insert(v0); - v0->SetV1(this); -} - -bool CustomElementRegistry::V0NameIsDefined(const AtomicString& name) { - for (const auto& v0 : *v0_) { - if (v0->NameIsDefined(name)) - return true; - } - return false; -} - CustomElementDefinition* CustomElementRegistry::DefinitionForName( const AtomicString& name) const { return DefinitionForId(name_id_map_.at(name)); @@ -295,7 +274,7 @@ void CustomElementRegistry::AddCandidate(Element& candidate) { if (!is.IsNull()) name = is; } - if (NameIsDefined(name) || V0NameIsDefined(name)) + if (NameIsDefined(name)) return; UpgradeCandidateMap::iterator it = upgrade_candidates_->find(name); UpgradeCandidateSet* set; diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.h b/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.h index 9f4d9ef6145..9f268126991 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.h +++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.h @@ -27,7 +27,6 @@ class LocalDOMWindow; class ScriptPromiseResolver; class ScriptState; class ScriptValue; -class V0CustomElementRegistrationContext; class V8CustomElementConstructor; class CORE_EXPORT CustomElementRegistry final : public ScriptWrappable { @@ -60,8 +59,6 @@ class CORE_EXPORT CustomElementRegistry final : public ScriptWrappable { ExceptionState&); void upgrade(Node* root); - void Entangle(V0CustomElementRegistrationContext*); - void Trace(Visitor*) const override; private: @@ -71,8 +68,6 @@ class CORE_EXPORT CustomElementRegistry final : public ScriptWrappable { const ElementDefinitionOptions*, ExceptionState&); - bool V0NameIsDefined(const AtomicString& name); - void CollectCandidates(const CustomElementDescriptor&, HeapVector<Member<Element>>*); @@ -86,10 +81,6 @@ class CORE_EXPORT CustomElementRegistry final : public ScriptWrappable { Member<const LocalDOMWindow> owner_; - using V0RegistrySet = - HeapHashSet<WeakMember<V0CustomElementRegistrationContext>>; - Member<V0RegistrySet> v0_; - using UpgradeCandidateSet = HeapHashSet<WeakMember<Element>>; using UpgradeCandidateMap = HeapHashMap<AtomicString, Member<UpgradeCandidateSet>>; 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 144566b51d2..bb79bb06c8e 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 @@ -6,7 +6,7 @@ [Exposed=Window] interface CustomElementRegistry { - [CallWith=ScriptState, CEReactions, CustomElementCallbacks, RaisesException, MeasureAs=CustomElementRegistryDefine] void define(DOMString name, CustomElementConstructor constructor, optional ElementDefinitionOptions options = {}); + [CallWith=ScriptState, CEReactions, RaisesException, MeasureAs=CustomElementRegistryDefine] void define(DOMString name, CustomElementConstructor constructor, optional ElementDefinitionOptions options = {}); any get(DOMString name); [CallWith=ScriptState,RaisesException] Promise<void> whenDefined(DOMString name); [CEReactions] void upgrade(Node root); diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_test.cc b/chromium/third_party/blink/renderer/core/html/custom/custom_element_test.cc index d28b73f5cbc..f82edbd61ac 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_test.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_test.cc @@ -165,16 +165,14 @@ TEST(CustomElementTest, StateByParser) { struct { const char* id; CustomElementState state; - Element::V0CustomElementState v0state; } parser_data[] = { - {"div", CustomElementState::kUncustomized, Element::kV0NotCustomElement}, - {"v1v0", CustomElementState::kUndefined, Element::kV0WaitingForUpgrade}, - {"v0", CustomElementState::kUncustomized, Element::kV0WaitingForUpgrade}, + {"div", CustomElementState::kUncustomized}, + {"v1v0", CustomElementState::kUndefined}, + {"v0", CustomElementState::kUncustomized}, }; for (const auto& data : parser_data) { Element* element = document.getElementById(data.id); EXPECT_EQ(data.state, element->GetCustomElementState()) << data.id; - EXPECT_EQ(data.v0state, element->GetV0CustomElementState()) << data.id; } } @@ -182,35 +180,27 @@ TEST(CustomElementTest, StateByCreateElement) { struct { const char* name; CustomElementState state; - Element::V0CustomElementState v0state; } create_element_data[] = { - {"div", CustomElementState::kUncustomized, Element::kV0NotCustomElement}, - {"a-a", CustomElementState::kUndefined, Element::kV0WaitingForUpgrade}, - // TODO(pdr): <font-face> should be V0NotCustomElement as per the spec, - // but was regressed to be V0WaitingForUpgrade in - // http://crrev.com/656913006 - {"font-face", CustomElementState::kUncustomized, - Element::kV0WaitingForUpgrade}, - {"_-X", CustomElementState::kUncustomized, Element::kV0WaitingForUpgrade}, + {"div", CustomElementState::kUncustomized}, + {"a-a", CustomElementState::kUndefined}, + {"font-face", CustomElementState::kUncustomized}, + {"_-X", CustomElementState::kUncustomized}, }; auto page_holder = std::make_unique<DummyPageHolder>(); Document& document = page_holder->GetDocument(); for (const auto& data : create_element_data) { Element* element = document.CreateElementForBinding(data.name); EXPECT_EQ(data.state, element->GetCustomElementState()) << data.name; - EXPECT_EQ(data.v0state, element->GetV0CustomElementState()) << data.name; element = document.createElementNS(html_names::xhtmlNamespaceURI, data.name, ASSERT_NO_EXCEPTION); EXPECT_EQ(data.state, element->GetCustomElementState()) << data.name; - EXPECT_EQ(data.v0state, element->GetV0CustomElementState()) << data.name; element = document.createElementNS(svg_names::kNamespaceURI, data.name, ASSERT_NO_EXCEPTION); EXPECT_EQ(CustomElementState::kUncustomized, element->GetCustomElementState()) << data.name; - EXPECT_EQ(data.v0state, element->GetV0CustomElementState()) << data.name; } } diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_state_set.cc b/chromium/third_party/blink/renderer/core/html/custom/custom_state_set.cc new file mode 100644 index 00000000000..0a17d3656ef --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/custom/custom_state_set.cc @@ -0,0 +1,123 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use 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/custom/custom_state_set.h" + +#include "third_party/blink/renderer/core/css/css_selector.h" +#include "third_party/blink/renderer/core/css/parser/css_parser_idioms.h" +#include "third_party/blink/renderer/core/dom/element.h" + +namespace blink { + +CustomStateSet::CustomStateSet(Element& element) : element_(element) {} + +void CustomStateSet::Trace(Visitor* visitor) const { + visitor->Trace(element_); + ScriptWrappable::Trace(visitor); +} + +void CustomStateSet::add(const String& value, ExceptionState& exception_state) { + // https://wicg.github.io/custom-state-pseudo-class/#dom-customstateset-add + + // 1. If value does not match to <dashed-ident>, then throw a "SyntaxError" + // DOMException. + if (!value.StartsWith("--")) { + exception_state.ThrowDOMException( + DOMExceptionCode::kSyntaxError, + "The specified value '" + value + "' must start with '--'."); + return; + } + for (wtf_size_t i = 2; i < value.length(); ++i) { + if (IsNameCodePoint(value[i])) + continue; + exception_state.ThrowDOMException( + DOMExceptionCode::kSyntaxError, + "The specified value '" + value + + "' must match to <dashed-ident> production. '" + value[i] + + "' is invalid."); + return; + } + + // 2. Invoke the default add operation, which the setlike<DOMString> would + // have if CustomStateSet interface had no add(value) operation, with value + // argument. + set_.insert(value); + + InvalidateStyle(); +} + +uint32_t CustomStateSet::size() const { + return set_.size(); +} + +void CustomStateSet::clearForBinding(ScriptState*, ExceptionState&) { + set_.clear(); + InvalidateStyle(); +} + +bool CustomStateSet::deleteForBinding(ScriptState*, + const String& value, + ExceptionState&) { + auto iter = set_.find(value); + if (iter == set_.cend()) + return false; + set_.erase(iter); + InvalidateStyle(); + return true; +} + +bool CustomStateSet::hasForBinding(ScriptState*, + const String& value, + ExceptionState&) const { + return Has(value); +} + +bool CustomStateSet::Has(const String& value) const { + return set_.Contains(value); +} + +class CustomStateIterationSource : public CustomStateSet::IterationSource { + public: + explicit CustomStateIterationSource(CustomStateSet& states) + : states_(states), iterator_(states.set_.begin()) {} + + void Trace(Visitor* visitor) const override { + visitor->Trace(states_); + CustomStateSet::IterationSource::Trace(visitor); + } + + bool Next(ScriptState*, + String& out_key, + String& out_value, + ExceptionState&) override { + if (iterator_ == states_->set_.end()) + return false; + String value = *iterator_; + ++iterator_; + out_key = value; + out_value = value; + return true; + } + + private: + Member<CustomStateSet> states_; + LinkedHashSet<String>::const_iterator iterator_; +}; + +CustomStateSet::IterationSource* CustomStateSet::StartIteration( + ScriptState*, + ExceptionState&) { + return MakeGarbageCollected<CustomStateIterationSource>(*this); +} + +void CustomStateSet::InvalidateStyle() const { + // TOOD(tkent): The following line invalidates all of rulesets with any + // custom state pseudo classes though we should invalidate only rulesets + // with the updated state ideally. We can improve style resolution + // performance in documents with various custom state pseudo classes by + // having blink::InvalidationSet for each of states. + element_->PseudoStateChanged(CSSSelector::kPseudoState); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_state_set.h b/chromium/third_party/blink/renderer/core/html/custom/custom_state_set.h new file mode 100644 index 00000000000..f1e37908c6a --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/custom/custom_state_set.h @@ -0,0 +1,47 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use 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_CUSTOM_CUSTOM_STATE_SET_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_CUSTOM_STATE_SET_H_ + +#include "third_party/blink/renderer/bindings/core/v8/iterable.h" +#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" + +namespace blink { + +class Element; + +// This class is an implementation of 'CustomStateSet' IDL interface. +class CustomStateSet final : public ScriptWrappable, + public SetlikeIterable<String> { + DEFINE_WRAPPERTYPEINFO(); + + public: + explicit CustomStateSet(Element& element); + void Trace(Visitor* visitor) const override; + + // IDL bindings: + void add(const String& value, ExceptionState& exception_state); + uint32_t size() const; + void clearForBinding(ScriptState*, ExceptionState&); + bool deleteForBinding(ScriptState*, const String& value, ExceptionState&); + bool hasForBinding(ScriptState*, const String& value, ExceptionState&) const; + + bool Has(const String& value) const; + + private: + // blink::Iterable override: + IterationSource* StartIteration(ScriptState* state, ExceptionState&) override; + + void InvalidateStyle() const; + + Member<Element> element_; + LinkedHashSet<String> set_; + + friend class CustomStateIterationSource; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_CUSTOM_STATE_SET_H_ diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_state_set.idl b/chromium/third_party/blink/renderer/core/html/custom/custom_state_set.idl new file mode 100644 index 00000000000..5d9abe0decf --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/custom/custom_state_set.idl @@ -0,0 +1,13 @@ +// Copyright 2021 The Chromium 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/custom-state-pseudo-class/#customstateset +[ + Exposed=Window, + RuntimeEnabled=CustomStatePseudoClass +] +interface CustomStateSet { + setlike<DOMString>; + [RaisesException] void add(DOMString key); +}; diff --git a/chromium/third_party/blink/renderer/core/html/custom/element_internals.cc b/chromium/third_party/blink/renderer/core/html/custom/element_internals.cc index f579182ddd4..b0d64cbaf84 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/element_internals.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/element_internals.cc @@ -6,11 +6,11 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_validity_state_flags.h" #include "third_party/blink/renderer/core/accessibility/ax_object_cache.h" -#include "third_party/blink/renderer/core/dom/dom_token_list.h" #include "third_party/blink/renderer/core/dom/node_lists_node_data.h" #include "third_party/blink/renderer/core/fileapi/file.h" #include "third_party/blink/renderer/core/html/custom/custom_element.h" #include "third_party/blink/renderer/core/html/custom/custom_element_registry.h" +#include "third_party/blink/renderer/core/html/custom/custom_state_set.h" #include "third_party/blink/renderer/core/html/forms/form_controller.h" #include "third_party/blink/renderer/core/html/forms/form_data.h" #include "third_party/blink/renderer/core/html/forms/html_form_element.h" @@ -32,20 +32,6 @@ bool IsValidityStateFlagsValid(const ValidityStateFlags* flags) { } } // anonymous namespace -class CustomStatesTokenList : public DOMTokenList { - public: - CustomStatesTokenList(Element& element) - : DOMTokenList(element, g_null_name) {} - - AtomicString value() const override { return TokenSet().SerializeToString(); } - - void setValue(const AtomicString& new_value) override { - DidUpdateAttributeValue(value(), new_value); - // Should we have invalidation set for each of state tokens? - GetElement().PseudoStateChanged(CSSSelector::kPseudoState); - } -}; - ElementInternals::ElementInternals(HTMLElement& target) : target_(target) { } @@ -228,14 +214,14 @@ LabelsNodeList* ElementInternals::labels(ExceptionState& exception_state) { return Target().labels(); } -DOMTokenList* ElementInternals::states() { +CustomStateSet* ElementInternals::states() { if (!custom_states_) - custom_states_ = MakeGarbageCollected<CustomStatesTokenList>(Target()); + custom_states_ = MakeGarbageCollected<CustomStateSet>(Target()); return custom_states_; } bool ElementInternals::HasState(const AtomicString& state) const { - return custom_states_ && custom_states_->contains(state); + return custom_states_ && custom_states_->Has(state); } ShadowRoot* ElementInternals::shadowRoot() const { diff --git a/chromium/third_party/blink/renderer/core/html/custom/element_internals.h b/chromium/third_party/blink/renderer/core/html/custom/element_internals.h index 695e1e8b2f0..ce10aa81441 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/element_internals.h +++ b/chromium/third_party/blink/renderer/core/html/custom/element_internals.h @@ -14,7 +14,7 @@ namespace blink { -class DOMTokenList; +class CustomStateSet; class HTMLElement; class ValidityStateFlags; @@ -50,7 +50,7 @@ class CORE_EXPORT ElementInternals : public ScriptWrappable, bool checkValidity(ExceptionState& exception_state); bool reportValidity(ExceptionState& exception_state); LabelsNodeList* labels(ExceptionState& exception_state); - DOMTokenList* states(); + CustomStateSet* states(); bool HasState(const AtomicString& state) const; @@ -107,7 +107,7 @@ class CORE_EXPORT ElementInternals : public ScriptWrappable, Member<ValidityStateFlags> validity_flags_; Member<Element> validation_anchor_; - Member<DOMTokenList> custom_states_; + Member<CustomStateSet> custom_states_; HashMap<QualifiedName, AtomicString> accessibility_semantics_map_; diff --git a/chromium/third_party/blink/renderer/core/html/custom/element_internals.idl b/chromium/third_party/blink/renderer/core/html/custom/element_internals.idl index 8333dbd36f2..6140f3086b4 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/element_internals.idl +++ b/chromium/third_party/blink/renderer/core/html/custom/element_internals.idl @@ -25,8 +25,9 @@ interface ElementInternals { [RaisesException] readonly attribute NodeList labels; // Custom state - // https://github.com/w3c/webcomponents/blob/gh-pages/proposals/custom-states-and-state-pseudo-class.md - [RuntimeEnabled=CustomStatePseudoClass] readonly attribute DOMTokenList states; + // https://wicg.github.io/custom-state-pseudo-class/#dom-elementinternals-states + [RuntimeEnabled=CustomStatePseudoClass, MeasureAs=ElementInternalsStates] + readonly attribute CustomStateSet states; // Access to shadowRoot from custom elements. See crbug.com/1042130 and // https://github.com/w3c/webcomponents/issues/871#issuecomment-672082936 diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element.cc deleted file mode 100644 index 3b91ebaa6a9..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element.cc +++ /dev/null @@ -1,150 +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 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/html/custom/v0_custom_element.h" - -#include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/dom/element.h" -#include "third_party/blink/renderer/core/frame/web_feature.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_run_queue.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_observer.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_scheduler.h" -#include "third_party/blink/renderer/core/html_names.h" -#include "third_party/blink/renderer/core/mathml_names.h" -#include "third_party/blink/renderer/core/svg_names.h" -#include "third_party/blink/renderer/platform/instrumentation/use_counter.h" - -namespace blink { - -V0CustomElementMicrotaskImportStep* V0CustomElement::DidCreateImport( - HTMLImportChild* import) { - return V0CustomElementScheduler::ScheduleImport(import); -} - -void V0CustomElement::DidFinishLoadingImport(Document& tree_root) { - tree_root.CustomElementMicrotaskRunQueue()->RequestDispatchIfNeeded(); -} - -static inline bool IsValidNCName(const AtomicString& name) { - if (kNotFound != name.find(':')) - return false; - - if (!name.GetString().Is8Bit()) { - const UChar32 c = name.Characters16()[0]; - // These characters comes under CombiningChar in NCName and according to - // NCName only BaseChar and Ideodgraphic can come as first chars. - // Also these characters come under Letter_Other in UnicodeData, thats - // why they pass as valid document name. - if (c == 0x0B83 || c == 0x0F88 || c == 0x0F89 || c == 0x0F8A || c == 0x0F8B) - return false; - } - - return Document::IsValidName(name.GetString()); -} - -bool V0CustomElement::IsValidName(const AtomicString& name) { - if (kNotFound != name.find('-')) { - DEFINE_STATIC_LOCAL(Vector<AtomicString>, reserved_names, ()); - if (reserved_names.IsEmpty()) { - // FIXME(crbug.com/426605): We should be able to remove this. - reserved_names.push_back(mathml_names::kAnnotationXmlTag.LocalName()); - } - - if (kNotFound == reserved_names.Find(name)) - return IsValidNCName(name); - } - - return false; -} - -void V0CustomElement::Define(Element* element, - V0CustomElementDefinition* definition) { - switch (element->GetV0CustomElementState()) { - case Element::kV0NotCustomElement: - case Element::kV0Upgraded: - NOTREACHED(); - break; - - case Element::kV0WaitingForUpgrade: - UseCounter::Count( - element->GetDocument(), - definition->Descriptor().IsTypeExtension() - ? WebFeature::kV0CustomElementsCreateTypeExtensionElement - : WebFeature::kV0CustomElementsCreateCustomTagElement); - element->V0SetCustomElementDefinition(definition); - V0CustomElementScheduler::ScheduleCallback( - definition->Callbacks(), element, - V0CustomElementLifecycleCallbacks::kCreatedCallback); - break; - } -} - -void V0CustomElement::AttributeDidChange(Element* element, - const AtomicString& name, - const AtomicString& old_value, - const AtomicString& new_value) { - DCHECK_EQ(element->GetV0CustomElementState(), Element::kV0Upgraded); - V0CustomElementScheduler::ScheduleAttributeChangedCallback( - element->GetV0CustomElementDefinition()->Callbacks(), element, name, - old_value, new_value); -} - -void V0CustomElement::DidAttach(Element* element, const Document& document) { - DCHECK_EQ(element->GetV0CustomElementState(), Element::kV0Upgraded); - if (!document.domWindow()) - return; - V0CustomElementScheduler::ScheduleCallback( - element->GetV0CustomElementDefinition()->Callbacks(), element, - V0CustomElementLifecycleCallbacks::kAttachedCallback); -} - -void V0CustomElement::DidDetach(Element* element, const Document& document) { - DCHECK_EQ(element->GetV0CustomElementState(), Element::kV0Upgraded); - if (!document.domWindow()) - return; - V0CustomElementScheduler::ScheduleCallback( - element->GetV0CustomElementDefinition()->Callbacks(), element, - V0CustomElementLifecycleCallbacks::kDetachedCallback); -} - -void V0CustomElement::WasDestroyed(Element* element) { - switch (element->GetV0CustomElementState()) { - case Element::kV0NotCustomElement: - NOTREACHED(); - break; - - case Element::kV0WaitingForUpgrade: - case Element::kV0Upgraded: - V0CustomElementObserver::NotifyElementWasDestroyed(element); - break; - } -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element.h deleted file mode 100644 index 0c3e255a3ae..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element.h +++ /dev/null @@ -1,73 +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 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_HTML_CUSTOM_V0_CUSTOM_ELEMENT_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_H_ - -#include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_definition.h" -#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" -#include "third_party/blink/renderer/platform/wtf/hash_map.h" -#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" -#include "third_party/blink/renderer/platform/wtf/vector.h" - -namespace blink { - -class V0CustomElementMicrotaskImportStep; -class Document; -class HTMLImportChild; - -class CORE_EXPORT V0CustomElement { - STATIC_ONLY(V0CustomElement); - - public: - static bool IsValidName(const AtomicString& name); - - // API to notify of document-level changes - static V0CustomElementMicrotaskImportStep* DidCreateImport(HTMLImportChild*); - static void DidFinishLoadingImport(Document& tree_root); - - // API for registration contexts - static void Define(Element*, V0CustomElementDefinition*); - - // API for Element to kick off changes - - static void AttributeDidChange(Element*, - const AtomicString& name, - const AtomicString& old_value, - const AtomicString& new_value); - static void DidAttach(Element*, const Document&); - static void DidDetach(Element*, const Document&); - static void WasDestroyed(Element*); -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_H_ diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_async_import_microtask_queue.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_async_import_microtask_queue.cc deleted file mode 100644 index 0a57915451e..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_async_import_microtask_queue.cc +++ /dev/null @@ -1,53 +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: - * - * 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 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/html/custom/v0_custom_element_async_import_microtask_queue.h" - -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_import_step.h" - -namespace blink { - -void V0CustomElementAsyncImportMicrotaskQueue::Enqueue( - V0CustomElementMicrotaskStep* step) { - queue_.push_back(step); -} - -void V0CustomElementAsyncImportMicrotaskQueue::DoDispatch() { - HeapVector<Member<V0CustomElementMicrotaskStep>> remaining; - - for (auto& step : queue_) { - if (V0CustomElementMicrotaskStep::kProcessing == step->Process()) - remaining.push_back(step.Release()); - } - - queue_.swap(remaining); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_async_import_microtask_queue.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_async_import_microtask_queue.h deleted file mode 100644 index 5f64134f5fa..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_async_import_microtask_queue.h +++ /dev/null @@ -1,51 +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: - * - * 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 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_HTML_CUSTOM_V0_CUSTOM_ELEMENT_ASYNC_IMPORT_MICROTASK_QUEUE_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_ASYNC_IMPORT_MICROTASK_QUEUE_H_ - -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_queue_base.h" - -namespace blink { - -class V0CustomElementAsyncImportMicrotaskQueue - : public V0CustomElementMicrotaskQueueBase { - public: - V0CustomElementAsyncImportMicrotaskQueue() = default; - - void Enqueue(V0CustomElementMicrotaskStep*); - - private: - void DoDispatch() override; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_ASYNC_IMPORT_MICROTASK_QUEUE_H_ diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_invocation.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_invocation.cc deleted file mode 100644 index 47cb0add209..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_invocation.cc +++ /dev/null @@ -1,153 +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 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/html/custom/v0_custom_element_callback_invocation.h" - -#include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/dom/element.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_scheduler.h" - -namespace blink { - -class AttachedDetachedInvocation final - : public V0CustomElementCallbackInvocation { - public: - AttachedDetachedInvocation( - V0CustomElementLifecycleCallbacks*, - V0CustomElementLifecycleCallbacks::CallbackType which); - - private: - void Dispatch(Element*) override; - - V0CustomElementLifecycleCallbacks::CallbackType which_; -}; - -AttachedDetachedInvocation::AttachedDetachedInvocation( - V0CustomElementLifecycleCallbacks* callbacks, - V0CustomElementLifecycleCallbacks::CallbackType which) - : V0CustomElementCallbackInvocation(callbacks), which_(which) { - DCHECK(which_ == V0CustomElementLifecycleCallbacks::kAttachedCallback || - which_ == V0CustomElementLifecycleCallbacks::kDetachedCallback); -} - -void AttachedDetachedInvocation::Dispatch(Element* element) { - switch (which_) { - case V0CustomElementLifecycleCallbacks::kAttachedCallback: - Callbacks()->Attached(element); - break; - case V0CustomElementLifecycleCallbacks::kDetachedCallback: - Callbacks()->Detached(element); - break; - default: - NOTREACHED(); - } -} - -class AttributeChangedInvocation final - : public V0CustomElementCallbackInvocation { - public: - AttributeChangedInvocation(V0CustomElementLifecycleCallbacks*, - const AtomicString& name, - const AtomicString& old_value, - const AtomicString& new_value); - - private: - void Dispatch(Element*) override; - - AtomicString name_; - AtomicString old_value_; - AtomicString new_value_; -}; - -AttributeChangedInvocation::AttributeChangedInvocation( - V0CustomElementLifecycleCallbacks* callbacks, - const AtomicString& name, - const AtomicString& old_value, - const AtomicString& new_value) - : V0CustomElementCallbackInvocation(callbacks), - name_(name), - old_value_(old_value), - new_value_(new_value) {} - -void AttributeChangedInvocation::Dispatch(Element* element) { - Callbacks()->AttributeChanged(element, name_, old_value_, new_value_); -} - -class CreatedInvocation final : public V0CustomElementCallbackInvocation { - public: - explicit CreatedInvocation(V0CustomElementLifecycleCallbacks* callbacks) - : V0CustomElementCallbackInvocation(callbacks) {} - - private: - void Dispatch(Element*) override; - bool IsCreatedCallback() const override { return true; } -}; - -void CreatedInvocation::Dispatch(Element* element) { - if (element->isConnected() && element->GetDocument().domWindow()) - V0CustomElementScheduler::ScheduleCallback( - Callbacks(), element, - V0CustomElementLifecycleCallbacks::kAttachedCallback); - Callbacks()->Created(element); -} - -V0CustomElementCallbackInvocation* -V0CustomElementCallbackInvocation::CreateInvocation( - V0CustomElementLifecycleCallbacks* callbacks, - V0CustomElementLifecycleCallbacks::CallbackType which) { - switch (which) { - case V0CustomElementLifecycleCallbacks::kCreatedCallback: - return MakeGarbageCollected<CreatedInvocation>(callbacks); - - case V0CustomElementLifecycleCallbacks::kAttachedCallback: - case V0CustomElementLifecycleCallbacks::kDetachedCallback: - return MakeGarbageCollected<AttachedDetachedInvocation>(callbacks, which); - default: - NOTREACHED(); - return nullptr; - } -} - -V0CustomElementCallbackInvocation* -V0CustomElementCallbackInvocation::CreateAttributeChangedInvocation( - V0CustomElementLifecycleCallbacks* callbacks, - const AtomicString& name, - const AtomicString& old_value, - const AtomicString& new_value) { - return MakeGarbageCollected<AttributeChangedInvocation>(callbacks, name, - old_value, new_value); -} - -void V0CustomElementCallbackInvocation::Trace(Visitor* visitor) const { - visitor->Trace(callbacks_); - V0CustomElementProcessingStep::Trace(visitor); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_invocation.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_invocation.h deleted file mode 100644 index 3250a3a330e..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_invocation.h +++ /dev/null @@ -1,69 +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 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_HTML_CUSTOM_V0_CUSTOM_ELEMENT_CALLBACK_INVOCATION_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_CALLBACK_INVOCATION_H_ - -#include "base/macros.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_lifecycle_callbacks.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_processing_step.h" -#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" - -namespace blink { - -class V0CustomElementCallbackInvocation : public V0CustomElementProcessingStep { - public: - static V0CustomElementCallbackInvocation* CreateInvocation( - V0CustomElementLifecycleCallbacks*, - V0CustomElementLifecycleCallbacks::CallbackType); - static V0CustomElementCallbackInvocation* CreateAttributeChangedInvocation( - V0CustomElementLifecycleCallbacks*, - const AtomicString& name, - const AtomicString& old_value, - const AtomicString& new_value); - - protected: - V0CustomElementCallbackInvocation( - V0CustomElementLifecycleCallbacks* callbacks) - : callbacks_(callbacks) {} - - V0CustomElementLifecycleCallbacks* Callbacks() { return callbacks_.Get(); } - - void Trace(Visitor*) const override; - - private: - Member<V0CustomElementLifecycleCallbacks> callbacks_; - - DISALLOW_COPY_AND_ASSIGN(V0CustomElementCallbackInvocation); -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_CALLBACK_INVOCATION_H_ diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_queue.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_queue.cc deleted file mode 100644 index 0a9718ddad8..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_queue.cc +++ /dev/null @@ -1,76 +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 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/html/custom/v0_custom_element_callback_queue.h" - -#include "third_party/blink/renderer/core/dom/shadow_root.h" - -namespace blink { - -V0CustomElementCallbackQueue::V0CustomElementCallbackQueue(Element* element) - : element_(element), owner_(-1), index_(0), in_created_callback_(false) {} - -bool V0CustomElementCallbackQueue::ProcessInElementQueue( - ElementQueueId caller) { - DCHECK(!in_created_callback_); - bool did_work = false; - - // Never run custom element callbacks in UA shadow roots since that would - // leak the UA root and it's elements into the page. - ShadowRoot* shadow_root = element_->ContainingShadowRoot(); - if (!shadow_root || !shadow_root->IsUserAgent()) { - while (index_ < queue_.size() && Owner() == caller) { - in_created_callback_ = queue_[index_]->IsCreatedCallback(); - - // dispatch() may cause recursion which steals this callback - // queue and reenters processInQueue. owner() == caller - // detects this recursion and cedes processing. - queue_[index_++]->Dispatch(element_.Get()); - in_created_callback_ = false; - did_work = true; - } - } - - if (Owner() == caller && index_ == queue_.size()) { - // This processInQueue exhausted the queue; shrink it. - index_ = 0; - queue_.resize(0); - owner_ = -1; - } - - return did_work; -} - -void V0CustomElementCallbackQueue::Trace(Visitor* visitor) const { - visitor->Trace(element_); - visitor->Trace(queue_); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_queue.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_queue.h deleted file mode 100644 index 22290f77bd3..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_queue.h +++ /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: - * - * 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 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_HTML_CUSTOM_V0_CUSTOM_ELEMENT_CALLBACK_QUEUE_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_CALLBACK_QUEUE_H_ - -#include "base/macros.h" -#include "third_party/blink/renderer/core/dom/element.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_processing_step.h" -#include "third_party/blink/renderer/platform/heap/handle.h" -#include "third_party/blink/renderer/platform/wtf/vector.h" - -namespace blink { - -// FIXME: Rename this because it contains resolution and upgrade as -// well as callbacks. -class V0CustomElementCallbackQueue - : public GarbageCollected<V0CustomElementCallbackQueue> { - public: - explicit V0CustomElementCallbackQueue(Element*); - - typedef int ElementQueueId; - ElementQueueId Owner() const { return owner_; } - - void SetOwner(ElementQueueId new_owner) { - // ElementCallbackQueues only migrate towards the top of the - // processing stack. - DCHECK_GE(new_owner, owner_); - owner_ = new_owner; - } - - bool ProcessInElementQueue(ElementQueueId); - - void Append(V0CustomElementProcessingStep* invocation) { - queue_.push_back(invocation); - } - bool InCreatedCallback() const { return in_created_callback_; } - - void Trace(Visitor*) const; - - private: - Member<Element> element_; - HeapVector<Member<V0CustomElementProcessingStep>> queue_; - ElementQueueId owner_; - wtf_size_t index_; - bool in_created_callback_; - - DISALLOW_COPY_AND_ASSIGN(V0CustomElementCallbackQueue); -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_CALLBACK_QUEUE_H_ diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_definition.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_definition.cc deleted file mode 100644 index 1795303dde1..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_definition.cc +++ /dev/null @@ -1,44 +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/html/custom/v0_custom_element_definition.h" - -namespace blink { - -V0CustomElementDefinition::V0CustomElementDefinition( - const V0CustomElementDescriptor& descriptor, - V0CustomElementLifecycleCallbacks* callbacks) - : descriptor_(descriptor), callbacks_(callbacks) {} - -void V0CustomElementDefinition::Trace(Visitor* visitor) const { - visitor->Trace(callbacks_); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_definition.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_definition.h deleted file mode 100644 index a5af9378ace..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_definition.h +++ /dev/null @@ -1,59 +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_HTML_CUSTOM_V0_CUSTOM_ELEMENT_DEFINITION_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_DEFINITION_H_ - -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_descriptor.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_lifecycle_callbacks.h" - -namespace blink { - -class V0CustomElementDefinition final - : public GarbageCollected<V0CustomElementDefinition> { - public: - V0CustomElementDefinition(const V0CustomElementDescriptor&, - V0CustomElementLifecycleCallbacks*); - - const V0CustomElementDescriptor& Descriptor() const { return descriptor_; } - V0CustomElementLifecycleCallbacks* Callbacks() const { - return callbacks_.Get(); - } - - void Trace(Visitor*) const; - - private: - V0CustomElementDescriptor descriptor_; - Member<V0CustomElementLifecycleCallbacks> callbacks_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_DEFINITION_H_ diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_descriptor.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_descriptor.h deleted file mode 100644 index dd98203b257..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_descriptor.h +++ /dev/null @@ -1,93 +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_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_DESCRIPTOR_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_DESCRIPTOR_H_ - -#include "third_party/blink/renderer/platform/heap/handle.h" -#include "third_party/blink/renderer/platform/wtf/hash_table_deleted_value_type.h" -#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" - -namespace blink { - -struct V0CustomElementDescriptorHash; - -// A Custom Element descriptor is everything necessary to match a -// Custom Element instance to a definition. -class V0CustomElementDescriptor { - DISALLOW_NEW(); - - public: - V0CustomElementDescriptor(const AtomicString& type, - const AtomicString& namespace_uri, - const AtomicString& local_name) - : type_(type), namespace_uri_(namespace_uri), local_name_(local_name) {} - - V0CustomElementDescriptor() = default; - ~V0CustomElementDescriptor() = default; - - // Specifies whether the custom element is in the HTML or SVG - // namespace. - const AtomicString& NamespaceURI() const { return namespace_uri_; } - - // The tag name. - const AtomicString& LocalName() const { return local_name_; } - - // The name of the definition. For custom tags, this is the tag - // name and the same as "localName". For type extensions, this is - // the value of the "is" attribute. - const AtomicString& GetType() const { return type_; } - - bool IsTypeExtension() const { return type_ != local_name_; } - - bool operator==(const V0CustomElementDescriptor& other) const { - return type_ == other.type_ && local_name_ == other.local_name_ && - namespace_uri_ == other.namespace_uri_; - } - - private: - friend struct WTF::HashTraits<blink::V0CustomElementDescriptor>; - AtomicString type_; - AtomicString namespace_uri_; - AtomicString local_name_; -}; - -} // namespace blink - -namespace WTF { - -template <> -struct DefaultHash<blink::V0CustomElementDescriptor> { - typedef blink::V0CustomElementDescriptorHash Hash; -}; - -} // namespace WTF - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_DESCRIPTOR_H_ diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_descriptor_hash.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_descriptor_hash.h deleted file mode 100644 index 103ffc488a3..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_descriptor_hash.h +++ /dev/null @@ -1,82 +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_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_DESCRIPTOR_HASH_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_DESCRIPTOR_HASH_H_ - -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_descriptor.h" -#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" -#include "third_party/blink/renderer/platform/wtf/hash_functions.h" -#include "third_party/blink/renderer/platform/wtf/hash_traits.h" -#include "third_party/blink/renderer/platform/wtf/text/atomic_string_hash.h" - -namespace blink { - -struct V0CustomElementDescriptorHash { - STATIC_ONLY(V0CustomElementDescriptorHash); - static unsigned GetHash(const V0CustomElementDescriptor& descriptor) { - return WTF::HashInts( - AtomicStringHash::GetHash(descriptor.GetType()), - WTF::HashInts(AtomicStringHash::GetHash(descriptor.NamespaceURI()), - AtomicStringHash::GetHash(descriptor.LocalName()))); - } - - static bool Equal(const V0CustomElementDescriptor& a, - const V0CustomElementDescriptor& b) { - return a == b; - } - - static const bool safe_to_compare_to_empty_or_deleted = true; -}; - -} // namespace blink - -namespace WTF { - -template <> -struct HashTraits<blink::V0CustomElementDescriptor> - : SimpleClassHashTraits<blink::V0CustomElementDescriptor> { - STATIC_ONLY(HashTraits); - static const bool kEmptyValueIsZero = - HashTraits<AtomicString>::kEmptyValueIsZero; - - static bool IsDeletedValue(const blink::V0CustomElementDescriptor& value) { - return HashTraits<AtomicString>::IsDeletedValue(value.type_); - } - - static void ConstructDeletedValue(blink::V0CustomElementDescriptor& slot, - bool zero_value) { - HashTraits<AtomicString>::ConstructDeletedValue(slot.type_, zero_value); - } -}; - -} // namespace WTF - -#endif // V0CustomElementDescriptorHash diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_exception.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_exception.cc deleted file mode 100644 index d321126ef9f..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_exception.cc +++ /dev/null @@ -1,116 +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 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/html/custom/v0_custom_element_exception.h" - -#include "base/notreached.h" -#include "third_party/blink/renderer/platform/bindings/exception_state.h" - -namespace blink { - -String V0CustomElementException::Preamble(const AtomicString& type) { - return "Registration failed for type '" + type + "'. "; -} - -void V0CustomElementException::ThrowException(Reason reason, - const AtomicString& type, - ExceptionState& exception_state) { - switch (reason) { - case kCannotRegisterFromExtension: - exception_state.ThrowDOMException( - DOMExceptionCode::kNotSupportedError, - Preamble(type) + "Elements cannot be registered from extensions."); - return; - - case kConstructorPropertyNotConfigurable: - exception_state.ThrowDOMException( - DOMExceptionCode::kNotSupportedError, - Preamble(type) + - "Prototype constructor property is not configurable."); - return; - - case kContextDestroyedCheckingPrototype: - exception_state.ThrowDOMException( - DOMExceptionCode::kInvalidStateError, - Preamble(type) + "The context is no longer valid."); - return; - - case kContextDestroyedCreatingCallbacks: - exception_state.ThrowDOMException( - DOMExceptionCode::kInvalidStateError, - Preamble(type) + "The context is no longer valid."); - return; - - case kContextDestroyedRegisteringDefinition: - exception_state.ThrowDOMException( - DOMExceptionCode::kInvalidStateError, - Preamble(type) + "The context is no longer valid."); - return; - - case kExtendsIsInvalidName: - exception_state.ThrowDOMException( - DOMExceptionCode::kNotSupportedError, - Preamble(type) + - "The tag name specified in 'extends' is not a valid tag name."); - return; - - case kExtendsIsCustomElementName: - exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError, - Preamble(type) + - "The tag name specified in " - "'extends' is a custom element " - "name. Use inheritance instead."); - return; - - case kInvalidName: - exception_state.ThrowDOMException( - DOMExceptionCode::kSyntaxError, - Preamble(type) + "The type name is invalid."); - return; - - case kPrototypeInUse: - exception_state.ThrowDOMException( - DOMExceptionCode::kNotSupportedError, - Preamble(type) + - "The prototype is already in-use as " - "an interface prototype object."); - return; - - case kTypeAlreadyRegistered: - exception_state.ThrowDOMException( - DOMExceptionCode::kNotSupportedError, - Preamble(type) + "A type with that name is already registered."); - return; - } - - NOTREACHED(); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_exception.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_exception.h deleted file mode 100644 index 2727385ca95..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_exception.h +++ /dev/null @@ -1,67 +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 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_HTML_CUSTOM_V0_CUSTOM_ELEMENT_EXCEPTION_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_EXCEPTION_H_ - -#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" -#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" -#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" - -namespace blink { - -class ExceptionState; - -class V0CustomElementException { - STATIC_ONLY(V0CustomElementException); - - public: - enum Reason { - kCannotRegisterFromExtension, - kConstructorPropertyNotConfigurable, - kContextDestroyedCheckingPrototype, - kContextDestroyedCreatingCallbacks, - kContextDestroyedRegisteringDefinition, - kExtendsIsInvalidName, - kExtendsIsCustomElementName, - kInvalidName, - kPrototypeInUse, - kTypeAlreadyRegistered - }; - - static void ThrowException(Reason, const AtomicString& type, ExceptionState&); - - private: - static String Preamble(const AtomicString& type); -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_EXCEPTION_H_ diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_lifecycle_callbacks.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_lifecycle_callbacks.h deleted file mode 100644 index 06190fc0ea2..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_lifecycle_callbacks.h +++ /dev/null @@ -1,76 +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_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_LIFECYCLE_CALLBACKS_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_LIFECYCLE_CALLBACKS_H_ - -#include "third_party/blink/renderer/platform/heap/handle.h" -#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" - -namespace blink { - -class Element; - -class V0CustomElementLifecycleCallbacks - : public GarbageCollected<V0CustomElementLifecycleCallbacks> { - public: - virtual ~V0CustomElementLifecycleCallbacks() = default; - - enum CallbackType { - kNone = 0, - kCreatedCallback = 1 << 0, - kAttachedCallback = 1 << 1, - kDetachedCallback = 1 << 2, - kAttributeChangedCallback = 1 << 3 - }; - - bool HasCallback(CallbackType type) const { return callback_type_ & type; } - - virtual void Created(Element*) = 0; - virtual void Attached(Element*) = 0; - virtual void Detached(Element*) = 0; - virtual void AttributeChanged(Element*, - const AtomicString& name, - const AtomicString& old_value, - const AtomicString& new_value) = 0; - - virtual void Trace(Visitor* visitor) const {} - - protected: - explicit V0CustomElementLifecycleCallbacks(CallbackType type) - : callback_type_(type) {} - - private: - CallbackType callback_type_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_LIFECYCLE_CALLBACKS_H_ diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_dispatcher.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_dispatcher.cc deleted file mode 100644 index 1c781204b72..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_dispatcher.cc +++ /dev/null @@ -1,83 +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/html/custom/v0_custom_element_microtask_dispatcher.h" - -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_callback_queue.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_processing_stack.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_scheduler.h" -#include "third_party/blink/renderer/platform/bindings/microtask.h" -#include "third_party/blink/renderer/platform/heap/persistent.h" - -namespace blink { - -static const V0CustomElementCallbackQueue::ElementQueueId kMicrotaskQueueId = 0; - -V0CustomElementMicrotaskDispatcher::V0CustomElementMicrotaskDispatcher() - : has_scheduled_microtask_(false), phase_(kQuiescent) {} - -V0CustomElementMicrotaskDispatcher& -V0CustomElementMicrotaskDispatcher::Instance() { - DEFINE_STATIC_LOCAL( - Persistent<V0CustomElementMicrotaskDispatcher>, instance, - (MakeGarbageCollected<V0CustomElementMicrotaskDispatcher>())); - return *instance; -} - -void V0CustomElementMicrotaskDispatcher::Enqueue( - V0CustomElementCallbackQueue* queue) { - EnsureMicrotaskScheduledForElementQueue(); - queue->SetOwner(kMicrotaskQueueId); - elements_.push_back(queue); -} - -void V0CustomElementMicrotaskDispatcher:: - EnsureMicrotaskScheduledForElementQueue() { - DCHECK(phase_ == kQuiescent || phase_ == kResolving); - EnsureMicrotaskScheduled(); -} - -void V0CustomElementMicrotaskDispatcher::EnsureMicrotaskScheduled() { - if (!has_scheduled_microtask_) { - Microtask::EnqueueMicrotask(WTF::Bind(&Dispatch)); - has_scheduled_microtask_ = true; - } -} - -void V0CustomElementMicrotaskDispatcher::Dispatch() { - Instance().DoDispatch(); -} - -void V0CustomElementMicrotaskDispatcher::DoDispatch() { - DCHECK(IsMainThread()); - - DCHECK(phase_ == kQuiescent); - DCHECK(has_scheduled_microtask_); - has_scheduled_microtask_ = false; - - // Finishing microtask work deletes all - // V0CustomElementCallbackQueues. Being in a callback delivery scope - // implies those queues could still be in use. - SECURITY_DCHECK(!V0CustomElementProcessingStack::InCallbackDeliveryScope()); - - phase_ = kResolving; - - phase_ = kDispatchingCallbacks; - for (const auto& element : elements_) { - // Created callback may enqueue an attached callback. - V0CustomElementProcessingStack::CallbackDeliveryScope scope; - element->ProcessInElementQueue(kMicrotaskQueueId); - } - - elements_.clear(); - V0CustomElementScheduler::MicrotaskDispatcherDidFinish(); - phase_ = kQuiescent; -} - -void V0CustomElementMicrotaskDispatcher::Trace(Visitor* visitor) const { - visitor->Trace(elements_); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_dispatcher.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_dispatcher.h deleted file mode 100644 index 0eed206c421..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_dispatcher.h +++ /dev/null @@ -1,46 +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_HTML_CUSTOM_V0_CUSTOM_ELEMENT_MICROTASK_DISPATCHER_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_MICROTASK_DISPATCHER_H_ - -#include "base/macros.h" -#include "third_party/blink/renderer/platform/heap/handle.h" -#include "third_party/blink/renderer/platform/wtf/vector.h" - -namespace blink { - -class V0CustomElementCallbackQueue; - -class V0CustomElementMicrotaskDispatcher final - : public GarbageCollected<V0CustomElementMicrotaskDispatcher> { - public: - static V0CustomElementMicrotaskDispatcher& Instance(); - - V0CustomElementMicrotaskDispatcher(); - - void Enqueue(V0CustomElementCallbackQueue*); - - bool ElementQueueIsEmpty() { return elements_.IsEmpty(); } - - void Trace(Visitor*) const; - - private: - void EnsureMicrotaskScheduledForElementQueue(); - void EnsureMicrotaskScheduled(); - - static void Dispatch(); - void DoDispatch(); - - bool has_scheduled_microtask_; - enum { kQuiescent, kResolving, kDispatchingCallbacks } phase_; - - HeapVector<Member<V0CustomElementCallbackQueue>> elements_; - - DISALLOW_COPY_AND_ASSIGN(V0CustomElementMicrotaskDispatcher); -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_MICROTASK_DISPATCHER_H_ diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_import_step.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_import_step.cc deleted file mode 100644 index fcf21c00af0..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_import_step.cc +++ /dev/null @@ -1,88 +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 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/html/custom/v0_custom_element_microtask_import_step.h" - -#include <stdio.h> -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_dispatcher.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_sync_microtask_queue.h" -#include "third_party/blink/renderer/core/html/imports/html_import_child.h" -#include "third_party/blink/renderer/core/html/imports/html_import_loader.h" - -namespace blink { - -V0CustomElementMicrotaskImportStep::V0CustomElementMicrotaskImportStep( - HTMLImportChild* import) - : import_(import), queue_(import->Loader()->MicrotaskQueue()) {} - -V0CustomElementMicrotaskImportStep::~V0CustomElementMicrotaskImportStep() = - default; - -void V0CustomElementMicrotaskImportStep::Invalidate() { - queue_ = MakeGarbageCollected<V0CustomElementSyncMicrotaskQueue>(); - import_.Clear(); -} - -bool V0CustomElementMicrotaskImportStep::ShouldWaitForImport() const { - return import_ && !import_->Loader()->IsDone(); -} - -void V0CustomElementMicrotaskImportStep::DidUpgradeAllCustomElements() { - DCHECK(queue_); - if (import_) - import_->DidFinishUpgradingCustomElements(); -} - -V0CustomElementMicrotaskStep::Result -V0CustomElementMicrotaskImportStep::Process() { - queue_->Dispatch(); - if (!queue_->IsEmpty() || ShouldWaitForImport()) - return kProcessing; - - DidUpgradeAllCustomElements(); - return kFinishedProcessing; -} - -void V0CustomElementMicrotaskImportStep::Trace(Visitor* visitor) const { - visitor->Trace(import_); - visitor->Trace(queue_); - V0CustomElementMicrotaskStep::Trace(visitor); -} - -#if !defined(NDEBUG) -void V0CustomElementMicrotaskImportStep::Show(unsigned indent) { - fprintf(stderr, "%*sImport(wait=%d sync=%d, url=%s)\n", indent, "", - ShouldWaitForImport(), import_ && import_->IsSync(), - import_ ? import_->Url().GetString().Utf8().c_str() : "null"); - queue_->Show(indent + 1); -} -#endif - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_import_step.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_import_step.h deleted file mode 100644 index 566af67cfb2..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_import_step.h +++ /dev/null @@ -1,76 +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 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_HTML_CUSTOM_V0_CUSTOM_ELEMENT_MICROTASK_IMPORT_STEP_H_ -#define 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_microtask_step.h" -#include "third_party/blink/renderer/platform/heap/handle.h" - -namespace blink { - -class V0CustomElementSyncMicrotaskQueue; -class HTMLImportChild; - -// Processes the Custom Elements in an HTML Import. This is a -// composite step which processes the Custom Elements created by -// parsing the import, and its sub-imports. -// -// This step blocks further Custom Element microtask processing if its -// import isn't "ready" (finished parsing and running script.) -class V0CustomElementMicrotaskImportStep final - : public V0CustomElementMicrotaskStep { - public: - explicit V0CustomElementMicrotaskImportStep(HTMLImportChild*); - ~V0CustomElementMicrotaskImportStep() override; - - // API for HTML Imports - void Invalidate(); - void ImportDidFinishLoading(); - - void Trace(Visitor*) const override; - - private: - void DidUpgradeAllCustomElements(); - bool ShouldWaitForImport() const; - - // V0CustomElementMicrotaskStep - Result Process() final; - -#if !defined(NDEBUG) - void Show(unsigned indent) override; -#endif - WeakMember<HTMLImportChild> import_; - Member<V0CustomElementSyncMicrotaskQueue> queue_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_MICROTASK_IMPORT_STEP_H_ diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_queue_base.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_queue_base.cc deleted file mode 100644 index 25efaad36df..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_queue_base.cc +++ /dev/null @@ -1,33 +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/html/custom/v0_custom_element_microtask_queue_base.h" - -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.h" - -namespace blink { - -void V0CustomElementMicrotaskQueueBase::Dispatch() { - CHECK(!in_dispatch_); - in_dispatch_ = true; - DoDispatch(); - in_dispatch_ = false; -} - -void V0CustomElementMicrotaskQueueBase::Trace(Visitor* visitor) const { - visitor->Trace(queue_); -} - -#if !defined(NDEBUG) -void V0CustomElementMicrotaskQueueBase::Show(unsigned indent) { - for (const auto& step : queue_) { - if (step) - step->Show(indent); - else - fprintf(stderr, "%*snull\n", indent, ""); - } -} -#endif - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_queue_base.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_queue_base.h deleted file mode 100644 index da4c6f039b6..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_queue_base.h +++ /dev/null @@ -1,41 +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_HTML_CUSTOM_V0_CUSTOM_ELEMENT_MICROTASK_QUEUE_BASE_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_MICROTASK_QUEUE_BASE_H_ - -#include "base/macros.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_step.h" -#include "third_party/blink/renderer/platform/heap/handle.h" -#include "third_party/blink/renderer/platform/wtf/vector.h" - -namespace blink { - -class V0CustomElementMicrotaskQueueBase - : public GarbageCollected<V0CustomElementMicrotaskQueueBase> { - public: - virtual ~V0CustomElementMicrotaskQueueBase() = default; - - bool IsEmpty() const { return queue_.IsEmpty(); } - void Dispatch(); - - void Trace(Visitor*) const; - -#if !defined(NDEBUG) - void Show(unsigned indent); -#endif - - protected: - V0CustomElementMicrotaskQueueBase() : in_dispatch_(false) {} - virtual void DoDispatch() = 0; - - HeapVector<Member<V0CustomElementMicrotaskStep>> queue_; - bool in_dispatch_; - - DISALLOW_COPY_AND_ASSIGN(V0CustomElementMicrotaskQueueBase); -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_MICROTASK_QUEUE_BASE_H_ diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.cc deleted file mode 100644 index f0a9f551f81..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.cc +++ /dev/null @@ -1,66 +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 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/html/custom/v0_custom_element_microtask_resolution_step.h" - -#include "third_party/blink/renderer/core/dom/element.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.h" - -namespace blink { - -V0CustomElementMicrotaskResolutionStep::V0CustomElementMicrotaskResolutionStep( - V0CustomElementRegistrationContext* context, - Element* element, - const V0CustomElementDescriptor& descriptor) - : context_(context), element_(element), descriptor_(descriptor) {} - -V0CustomElementMicrotaskResolutionStep:: - ~V0CustomElementMicrotaskResolutionStep() = default; - -V0CustomElementMicrotaskStep::Result -V0CustomElementMicrotaskResolutionStep::Process() { - context_->Resolve(element_.Get(), descriptor_); - return V0CustomElementMicrotaskStep::kFinishedProcessing; -} - -void V0CustomElementMicrotaskResolutionStep::Trace(Visitor* visitor) const { - visitor->Trace(context_); - visitor->Trace(element_); - V0CustomElementMicrotaskStep::Trace(visitor); -} - -#if !defined(NDEBUG) -void V0CustomElementMicrotaskResolutionStep::Show(unsigned indent) { - fprintf(stderr, "%*sResolution: ", indent, ""); - element_->outerHTML().Show(); -} -#endif - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.h deleted file mode 100644 index 5288b6f9562..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.h +++ /dev/null @@ -1,67 +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 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_HTML_CUSTOM_V0_CUSTOM_ELEMENT_MICROTASK_RESOLUTION_STEP_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_MICROTASK_RESOLUTION_STEP_H_ - -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_descriptor.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_step.h" -#include "third_party/blink/renderer/platform/heap/handle.h" - -namespace blink { - -class V0CustomElementRegistrationContext; -class Element; - -class V0CustomElementMicrotaskResolutionStep final - : public V0CustomElementMicrotaskStep { - public: - V0CustomElementMicrotaskResolutionStep(V0CustomElementRegistrationContext*, - Element*, - const V0CustomElementDescriptor&); - ~V0CustomElementMicrotaskResolutionStep() override; - - void Trace(Visitor*) const override; - - private: - Result Process() override; - -#if !defined(NDEBUG) - void Show(unsigned indent) override; -#endif - - Member<V0CustomElementRegistrationContext> context_; - Member<Element> element_; - V0CustomElementDescriptor descriptor_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_MICROTASK_RESOLUTION_STEP_H_ diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_run_queue.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_run_queue.cc deleted file mode 100644 index 20a96fef1b0..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_run_queue.cc +++ /dev/null @@ -1,61 +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/html/custom/v0_custom_element_microtask_run_queue.h" - -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_async_import_microtask_queue.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_sync_microtask_queue.h" -#include "third_party/blink/renderer/core/html/imports/html_import_loader.h" -#include "third_party/blink/renderer/platform/bindings/microtask.h" -#include "third_party/blink/renderer/platform/heap/persistent.h" - -namespace blink { - -V0CustomElementMicrotaskRunQueue::V0CustomElementMicrotaskRunQueue() - : sync_queue_(MakeGarbageCollected<V0CustomElementSyncMicrotaskQueue>()), - async_queue_( - MakeGarbageCollected<V0CustomElementAsyncImportMicrotaskQueue>()), - dispatch_is_pending_(false) {} - -void V0CustomElementMicrotaskRunQueue::Enqueue( - HTMLImportLoader* parent_loader, - V0CustomElementMicrotaskStep* step, - bool import_is_sync) { - if (import_is_sync) { - if (parent_loader) - parent_loader->MicrotaskQueue()->Enqueue(step); - else - sync_queue_->Enqueue(step); - } else { - async_queue_->Enqueue(step); - } - - RequestDispatchIfNeeded(); -} - -void V0CustomElementMicrotaskRunQueue::RequestDispatchIfNeeded() { - if (dispatch_is_pending_ || IsEmpty()) - return; - Microtask::EnqueueMicrotask(WTF::Bind( - &V0CustomElementMicrotaskRunQueue::Dispatch, WrapWeakPersistent(this))); - dispatch_is_pending_ = true; -} - -void V0CustomElementMicrotaskRunQueue::Trace(Visitor* visitor) const { - visitor->Trace(sync_queue_); - visitor->Trace(async_queue_); -} - -void V0CustomElementMicrotaskRunQueue::Dispatch() { - dispatch_is_pending_ = false; - sync_queue_->Dispatch(); - if (sync_queue_->IsEmpty()) - async_queue_->Dispatch(); -} - -bool V0CustomElementMicrotaskRunQueue::IsEmpty() const { - return sync_queue_->IsEmpty() && async_queue_->IsEmpty(); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_run_queue.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_run_queue.h deleted file mode 100644 index d6e3a8a6d06..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_run_queue.h +++ /dev/null @@ -1,40 +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_HTML_CUSTOM_V0_CUSTOM_ELEMENT_MICROTASK_RUN_QUEUE_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_MICROTASK_RUN_QUEUE_H_ - -#include "third_party/blink/renderer/platform/heap/handle.h" - -namespace blink { - -class V0CustomElementSyncMicrotaskQueue; -class V0CustomElementAsyncImportMicrotaskQueue; -class V0CustomElementMicrotaskStep; -class HTMLImportLoader; - -class V0CustomElementMicrotaskRunQueue - : public GarbageCollected<V0CustomElementMicrotaskRunQueue> { - public: - V0CustomElementMicrotaskRunQueue(); - - void Enqueue(HTMLImportLoader* parent_loader, - V0CustomElementMicrotaskStep*, - bool import_is_sync); - void RequestDispatchIfNeeded(); - bool IsEmpty() const; - - void Trace(Visitor*) const; - - private: - void Dispatch(); - - Member<V0CustomElementSyncMicrotaskQueue> sync_queue_; - Member<V0CustomElementAsyncImportMicrotaskQueue> async_queue_; - bool dispatch_is_pending_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_MICROTASK_RUN_QUEUE_H_ diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_step.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_step.h deleted file mode 100644 index 3da59d78f1e..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_step.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2013 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 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 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_HTML_CUSTOM_V0_CUSTOM_ELEMENT_MICROTASK_STEP_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_MICROTASK_STEP_H_ - -#include "base/macros.h" -#include "third_party/blink/renderer/platform/heap/handle.h" - -namespace blink { - -class V0CustomElementMicrotaskStep - : public GarbageCollected<V0CustomElementMicrotaskStep> { - public: - V0CustomElementMicrotaskStep() = default; - virtual ~V0CustomElementMicrotaskStep() = default; - - enum Result { kProcessing, kFinishedProcessing }; - - virtual Result Process() = 0; - - virtual void Trace(Visitor* visitor) const {} - -#if !defined(NDEBUG) - virtual void Show(unsigned indent) = 0; -#endif - - DISALLOW_COPY_AND_ASSIGN(V0CustomElementMicrotaskStep); -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_MICROTASK_STEP_H_ diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_observer.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_observer.cc deleted file mode 100644 index a450e7667cf..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_observer.cc +++ /dev/null @@ -1,67 +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 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/html/custom/v0_custom_element_observer.h" - -#include "third_party/blink/renderer/core/dom/element.h" -#include "third_party/blink/renderer/platform/heap/persistent.h" - -namespace blink { - -// Maps elements to the observer watching them. At most one per -// element at a time. -typedef HeapHashMap<WeakMember<Element>, Member<V0CustomElementObserver>> - ElementObserverMap; - -static ElementObserverMap& ElementObservers() { - DEFINE_STATIC_LOCAL(Persistent<ElementObserverMap>, map, - (MakeGarbageCollected<ElementObserverMap>())); - return *map; -} - -void V0CustomElementObserver::NotifyElementWasDestroyed(Element* element) { - ElementObserverMap::iterator it = ElementObservers().find(element); - if (it == ElementObservers().end()) - return; - it->value->ElementWasDestroyed(element); -} - -void V0CustomElementObserver::Observe(Element* element) { - ElementObserverMap::AddResult result = - ElementObservers().insert(element, this); - DCHECK(result.is_new_entry); -} - -void V0CustomElementObserver::Unobserve(Element* element) { - V0CustomElementObserver* observer = ElementObservers().Take(element); - DCHECK_EQ(observer, this); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_observer.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_observer.h deleted file mode 100644 index c05ea7ddc78..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_observer.h +++ /dev/null @@ -1,62 +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 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_HTML_CUSTOM_V0_CUSTOM_ELEMENT_OBSERVER_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_OBSERVER_H_ - -#include "third_party/blink/renderer/platform/heap/handle.h" -#include "third_party/blink/renderer/platform/wtf/hash_map.h" - -namespace blink { - -class Element; - -class V0CustomElementObserver - : public GarbageCollected<V0CustomElementObserver> { - public: - virtual ~V0CustomElementObserver() = default; - - // API for CustomElement to kick off notifications - static void NotifyElementWasDestroyed(Element*); - - virtual void Trace(Visitor* visitor) const {} - - protected: - V0CustomElementObserver() = default; - - void Observe(Element*); - void Unobserve(Element*); - - virtual void ElementWasDestroyed(Element* element) { Unobserve(element); } -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_OBSERVER_H_ diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.cc deleted file mode 100644 index 627a3773747..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.cc +++ /dev/null @@ -1,99 +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 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/html/custom/v0_custom_element_processing_stack.h" - -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_callback_queue.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_scheduler.h" -#include "third_party/blink/renderer/platform/heap/persistent.h" - -namespace blink { - -wtf_size_t V0CustomElementProcessingStack::element_queue_start_ = 0; - -// The base of the stack has a null sentinel value. -wtf_size_t V0CustomElementProcessingStack::element_queue_end_ = kNumSentinels; - -V0CustomElementProcessingStack& V0CustomElementProcessingStack::Instance() { - DEFINE_STATIC_LOCAL(Persistent<V0CustomElementProcessingStack>, instance, - (MakeGarbageCollected<V0CustomElementProcessingStack>())); - return *instance; -} - -// Dispatches callbacks when popping the processing stack. -void V0CustomElementProcessingStack::ProcessElementQueueAndPop() { - Instance().ProcessElementQueueAndPop(element_queue_start_, - element_queue_end_); -} - -void V0CustomElementProcessingStack::ProcessElementQueueAndPop(wtf_size_t start, - wtf_size_t end) { - DCHECK(IsMainThread()); - V0CustomElementCallbackQueue::ElementQueueId this_queue = - CurrentElementQueue(); - - for (wtf_size_t i = start; i < end; ++i) { - { - // The created callback may schedule entered document - // callbacks. - CallbackDeliveryScope delivery_scope; - flattened_processing_stack_[i]->ProcessInElementQueue(this_queue); - } - - DCHECK_EQ(start, element_queue_start_); - DCHECK_EQ(end, element_queue_end_); - } - - // Pop the element queue from the processing stack - flattened_processing_stack_.resize(start); - element_queue_end_ = start; - - if (element_queue_start_ == kNumSentinels) - V0CustomElementScheduler::CallbackDispatcherDidFinish(); -} - -void V0CustomElementProcessingStack::Enqueue( - V0CustomElementCallbackQueue* callback_queue) { - DCHECK(InCallbackDeliveryScope()); - - if (callback_queue->Owner() == CurrentElementQueue()) - return; - - callback_queue->SetOwner(CurrentElementQueue()); - - flattened_processing_stack_.push_back(callback_queue); - ++element_queue_end_; -} - -void V0CustomElementProcessingStack::Trace(Visitor* visitor) const { - visitor->Trace(flattened_processing_stack_); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.h deleted file mode 100644 index c932c36806d..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.h +++ /dev/null @@ -1,109 +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 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_HTML_CUSTOM_V0_CUSTOM_ELEMENT_PROCESSING_STACK_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_PROCESSING_STACK_H_ - -#include "base/macros.h" -#include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_callback_queue.h" -#include "third_party/blink/renderer/platform/wtf/vector.h" - -namespace blink { - -class CORE_EXPORT V0CustomElementProcessingStack - : public GarbageCollected<V0CustomElementProcessingStack> { - public: - // This is stack allocated in many DOM callbacks. Make it cheap. - class CallbackDeliveryScope { - STACK_ALLOCATED(); - - public: - CallbackDeliveryScope() : saved_element_queue_start_(element_queue_start_) { - element_queue_start_ = element_queue_end_; - } - - ~CallbackDeliveryScope() { - if (element_queue_start_ != element_queue_end_) - ProcessElementQueueAndPop(); - element_queue_start_ = saved_element_queue_start_; - } - - private: - wtf_size_t saved_element_queue_start_; - }; - - static bool InCallbackDeliveryScope() { return element_queue_start_; } - - V0CustomElementProcessingStack() { - // Add a null element as a sentinel. This makes it possible to - // identify elements queued when there is no - // CallbackDeliveryScope active. Also, if the processing stack - // is popped when empty, this sentinel will cause a null deref - // crash. - V0CustomElementCallbackQueue* sentinel = nullptr; - for (wtf_size_t i = 0; i < kNumSentinels; i++) - flattened_processing_stack_.push_back(sentinel); - DCHECK_EQ(element_queue_end_, flattened_processing_stack_.size()); - } - - static V0CustomElementProcessingStack& Instance(); - void Enqueue(V0CustomElementCallbackQueue*); - - void Trace(Visitor*) const; - - private: - // The start of the element queue on the top of the processing - // stack. An offset into Instance().flattened_processing_stack_. - static wtf_size_t element_queue_start_; - - // The end of the element queue on the top of the processing - // stack. A cache of Instance().flattened_processing_stack_.size(). - static wtf_size_t element_queue_end_; - - static V0CustomElementCallbackQueue::ElementQueueId CurrentElementQueue() { - return V0CustomElementCallbackQueue::ElementQueueId(element_queue_start_); - } - - static void ProcessElementQueueAndPop(); - void ProcessElementQueueAndPop(wtf_size_t start, wtf_size_t end); - - // The processing stack, flattened. Element queues lower in the - // stack appear toward the head of the vector. The first element - // is a null sentinel value. - static const wtf_size_t kNumSentinels = 1; - HeapVector<Member<V0CustomElementCallbackQueue>> flattened_processing_stack_; - - DISALLOW_COPY_AND_ASSIGN(V0CustomElementProcessingStack); -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_PROCESSING_STACK_H_ diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_step.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_step.h deleted file mode 100644 index 23ff9aa87bb..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_step.h +++ /dev/null @@ -1,55 +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 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_HTML_CUSTOM_V0_CUSTOM_ELEMENT_PROCESSING_STEP_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_PROCESSING_STEP_H_ - -#include "base/macros.h" -#include "third_party/blink/renderer/platform/heap/handle.h" - -namespace blink { - -class V0CustomElementProcessingStep - : public GarbageCollected<V0CustomElementProcessingStep> { - public: - V0CustomElementProcessingStep() = default; - - virtual ~V0CustomElementProcessingStep() = default; - virtual void Dispatch(Element*) = 0; - virtual bool IsCreatedCallback() const { return false; } - - virtual void Trace(Visitor* visitor) const {} - - DISALLOW_COPY_AND_ASSIGN(V0CustomElementProcessingStep); -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_PROCESSING_STEP_H_ diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.cc deleted file mode 100644 index 07ba6362261..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.cc +++ /dev/null @@ -1,186 +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 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/html/custom/v0_custom_element_registration_context.h" - -#include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/dom/element.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_definition.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_scheduler.h" -#include "third_party/blink/renderer/core/html/html_element.h" -#include "third_party/blink/renderer/core/html/html_unknown_element.h" -#include "third_party/blink/renderer/core/html_names.h" -#include "third_party/blink/renderer/core/svg/svg_unknown_element.h" -#include "third_party/blink/renderer/core/svg_names.h" -#include "third_party/blink/renderer/platform/bindings/exception_state.h" -#include "third_party/blink/renderer/platform/heap/heap.h" - -namespace blink { - -V0CustomElementRegistrationContext::V0CustomElementRegistrationContext() - : candidates_(MakeGarbageCollected<V0CustomElementUpgradeCandidateMap>()) {} - -void V0CustomElementRegistrationContext::RegisterElement( - Document* document, - V0CustomElementConstructorBuilder* constructor_builder, - const AtomicString& type, - ExceptionState& exception_state) { - V0CustomElementDefinition* definition = registry_.RegisterElement( - document, constructor_builder, type, exception_state); - - if (!definition) - return; - - // Upgrade elements that were waiting for this definition. - V0CustomElementUpgradeCandidateMap::ElementSet* upgrade_candidates = - candidates_->TakeUpgradeCandidatesFor(definition->Descriptor()); - - if (!upgrade_candidates) - return; - - for (const auto& candidate : *upgrade_candidates) - V0CustomElement::Define(candidate, definition); -} - -Element* V0CustomElementRegistrationContext::CreateCustomTagElement( - Document& document, - const QualifiedName& tag_name) { - DCHECK(V0CustomElement::IsValidName(tag_name.LocalName())); - - Element* element; - - if (html_names::xhtmlNamespaceURI == tag_name.NamespaceURI()) { - element = MakeGarbageCollected<HTMLElement>(tag_name, document); - } else if (svg_names::kNamespaceURI == tag_name.NamespaceURI()) { - element = MakeGarbageCollected<SVGUnknownElement>(tag_name, document); - } else { - // XML elements are not custom elements, so return early. - return MakeGarbageCollected<Element>(tag_name, &document); - } - - element->SetV0CustomElementState(Element::kV0WaitingForUpgrade); - ResolveOrScheduleResolution(element, g_null_atom); - return element; -} - -void V0CustomElementRegistrationContext::DidGiveTypeExtension( - Element* element, - const AtomicString& type) { - ResolveOrScheduleResolution(element, type); -} - -void V0CustomElementRegistrationContext::ResolveOrScheduleResolution( - Element* element, - const AtomicString& type_extension) { - // If an element has a custom tag name it takes precedence over - // the "is" attribute (if any). - const AtomicString& type = V0CustomElement::IsValidName(element->localName()) - ? element->localName() - : type_extension; - DCHECK(!type.IsNull()); - - V0CustomElementDescriptor descriptor(type, element->namespaceURI(), - element->localName()); - DCHECK_EQ(element->GetV0CustomElementState(), Element::kV0WaitingForUpgrade); - - V0CustomElementScheduler::ResolveOrScheduleResolution(this, element, - descriptor); -} - -void V0CustomElementRegistrationContext::Resolve( - Element* element, - const V0CustomElementDescriptor& descriptor) { - V0CustomElementDefinition* definition = registry_.Find(descriptor); - if (definition) { - V0CustomElement::Define(element, definition); - } else { - DCHECK_EQ(element->GetV0CustomElementState(), - Element::kV0WaitingForUpgrade); - candidates_->Add(descriptor, element); - } -} - -void V0CustomElementRegistrationContext::SetIsAttributeAndTypeExtension( - Element* element, - const AtomicString& type) { - DCHECK(element); - DCHECK(!type.IsEmpty()); - element->setAttribute(html_names::kIsAttr, type); - SetTypeExtension(element, type); -} - -void V0CustomElementRegistrationContext::SetTypeExtension( - Element* element, - const AtomicString& type) { - if (!element->IsHTMLElement() && !element->IsSVGElement()) - return; - - V0CustomElementRegistrationContext* context = - element->GetDocument().RegistrationContext(); - if (!context) - return; - - if (element->IsV0CustomElement()) { - // This can happen if: - // 1. The element has a custom tag, which takes precedence over - // type extensions. - // 2. Undoing a command (eg ReplaceNodeWithSpan) recycles an - // element but tries to overwrite its attribute list. - return; - } - - // Custom tags take precedence over type extensions - DCHECK(!V0CustomElement::IsValidName(element->localName())); - - if (!V0CustomElement::IsValidName(type)) - return; - - element->SetV0CustomElementState(Element::kV0WaitingForUpgrade); - context->DidGiveTypeExtension(element, - element->GetDocument().ConvertLocalName(type)); -} - -bool V0CustomElementRegistrationContext::NameIsDefined( - const AtomicString& name) const { - return registry_.NameIsDefined(name); -} - -void V0CustomElementRegistrationContext::SetV1( - const CustomElementRegistry* v1) { - registry_.SetV1(v1); -} - -void V0CustomElementRegistrationContext::Trace(Visitor* visitor) const { - visitor->Trace(candidates_); - visitor->Trace(registry_); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.h deleted file mode 100644 index 9e7baee49de..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.h +++ /dev/null @@ -1,85 +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 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_HTML_CUSTOM_V0_CUSTOM_ELEMENT_REGISTRATION_CONTEXT_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_REGISTRATION_CONTEXT_H_ - -#include "third_party/blink/renderer/core/dom/qualified_name.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_descriptor.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_registry.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_upgrade_candidate_map.h" -#include "third_party/blink/renderer/platform/heap/handle.h" -#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" - -namespace blink { - -class CustomElementRegistry; - -class V0CustomElementRegistrationContext final - : public GarbageCollected<V0CustomElementRegistrationContext> { - public: - V0CustomElementRegistrationContext(); - ~V0CustomElementRegistrationContext() = default; - void DocumentWasDetached() { registry_.DocumentWasDetached(); } - - // Definitions - void RegisterElement(Document*, - V0CustomElementConstructorBuilder*, - const AtomicString& type, - ExceptionState&); - - Element* CreateCustomTagElement(Document&, const QualifiedName&); - static void SetIsAttributeAndTypeExtension(Element*, - const AtomicString& type); - static void SetTypeExtension(Element*, const AtomicString& type); - - void Resolve(Element*, const V0CustomElementDescriptor&); - - bool NameIsDefined(const AtomicString& name) const; - void SetV1(const CustomElementRegistry*); - - void Trace(Visitor*) const; - - // Instance creation - void DidGiveTypeExtension(Element*, const AtomicString& type); - - private: - void ResolveOrScheduleResolution(Element*, - const AtomicString& type_extension); - - V0CustomElementRegistry registry_; - - // Element creation - Member<V0CustomElementUpgradeCandidateMap> candidates_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_REGISTRATION_CONTEXT_H_ diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registry.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registry.cc deleted file mode 100644 index 9d4fb89945c..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registry.cc +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name of 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/html/custom/v0_custom_element_registry.h" - -#include "third_party/blink/renderer/bindings/core/v8/v0_custom_element_constructor_builder.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/web_feature.h" -#include "third_party/blink/renderer/core/html/custom/custom_element_registry.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_exception.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.h" -#include "third_party/blink/renderer/core/html_names.h" -#include "third_party/blink/renderer/core/svg_names.h" -#include "third_party/blink/renderer/platform/instrumentation/use_counter.h" - -namespace blink { - -V0CustomElementDefinition* V0CustomElementRegistry::RegisterElement( - Document* document, - V0CustomElementConstructorBuilder* constructor_builder, - const AtomicString& user_supplied_name, - ExceptionState& exception_state) { - AtomicString type = user_supplied_name.LowerASCII(); - - if (!constructor_builder->IsFeatureAllowed()) { - V0CustomElementException::ThrowException( - V0CustomElementException::kCannotRegisterFromExtension, type, - exception_state); - return nullptr; - } - - if (!V0CustomElement::IsValidName(type)) { - V0CustomElementException::ThrowException( - V0CustomElementException::kInvalidName, type, exception_state); - return nullptr; - } - - if (registered_type_names_.Contains(type) || V1NameIsDefined(type)) { - V0CustomElementException::ThrowException( - V0CustomElementException::kTypeAlreadyRegistered, type, - exception_state); - return nullptr; - } - - QualifiedName tag_name = QualifiedName::Null(); - if (!constructor_builder->ValidateOptions(type, tag_name, exception_state)) - return nullptr; - - DCHECK(tag_name.NamespaceURI() == html_names::xhtmlNamespaceURI || - tag_name.NamespaceURI() == svg_names::kNamespaceURI); - - DCHECK(!document_was_detached_); - - V0CustomElementLifecycleCallbacks* lifecycle_callbacks = - constructor_builder->CreateCallbacks(); - - // Consulting the constructor builder could execute script and - // kill the document. - if (document_was_detached_) { - V0CustomElementException::ThrowException( - V0CustomElementException::kContextDestroyedCreatingCallbacks, type, - exception_state); - return nullptr; - } - - const V0CustomElementDescriptor descriptor(type, tag_name.NamespaceURI(), - tag_name.LocalName()); - auto* definition = MakeGarbageCollected<V0CustomElementDefinition>( - descriptor, lifecycle_callbacks); - - if (!constructor_builder->CreateConstructor(document, definition, - exception_state)) - return nullptr; - - definitions_.insert(descriptor, definition); - registered_type_names_.insert(descriptor.GetType()); - - if (!constructor_builder->DidRegisterDefinition()) { - V0CustomElementException::ThrowException( - V0CustomElementException::kContextDestroyedRegisteringDefinition, type, - exception_state); - return nullptr; - } - - if (tag_name.NamespaceURI() == svg_names::kNamespaceURI) { - UseCounter::Count(document, - WebFeature::kV0CustomElementsRegisterSVGElement); - } else { - UseCounter::Count( - document, descriptor.IsTypeExtension() - ? WebFeature::kV0CustomElementsRegisterHTMLTypeExtension - : WebFeature::kV0CustomElementsRegisterHTMLCustomTag); - } - - return definition; -} - -V0CustomElementDefinition* V0CustomElementRegistry::Find( - const V0CustomElementDescriptor& descriptor) const { - return definitions_.at(descriptor); -} - -bool V0CustomElementRegistry::NameIsDefined(const AtomicString& name) const { - return registered_type_names_.Contains(name); -} - -void V0CustomElementRegistry::SetV1(const CustomElementRegistry* v1) { - DCHECK(!v1_.Get()); - v1_ = v1; -} - -bool V0CustomElementRegistry::V1NameIsDefined(const AtomicString& name) const { - return v1_.Get() && v1_->NameIsDefined(name); -} - -void V0CustomElementRegistry::Trace(Visitor* visitor) const { - visitor->Trace(definitions_); - visitor->Trace(v1_); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registry.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registry.h deleted file mode 100644 index 8f43354c6af..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registry.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name of 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_HTML_CUSTOM_V0_CUSTOM_ELEMENT_REGISTRY_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_REGISTRY_H_ - -#include "base/macros.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_definition.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_descriptor.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_descriptor_hash.h" -#include "third_party/blink/renderer/platform/wtf/hash_map.h" -#include "third_party/blink/renderer/platform/wtf/hash_set.h" -#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" -#include "third_party/blink/renderer/platform/wtf/text/atomic_string_hash.h" - -namespace blink { - -class CustomElementRegistry; -class ExceptionState; -class V0CustomElementConstructorBuilder; - -class V0CustomElementRegistry final { - DISALLOW_NEW(); - - public: - void Trace(Visitor*) const; - void DocumentWasDetached() { document_was_detached_ = true; } - - protected: - friend class V0CustomElementRegistrationContext; - - V0CustomElementRegistry() : document_was_detached_(false) {} - - V0CustomElementDefinition* RegisterElement( - Document*, - V0CustomElementConstructorBuilder*, - const AtomicString& name, - ExceptionState&); - V0CustomElementDefinition* Find(const V0CustomElementDescriptor&) const; - - bool NameIsDefined(const AtomicString& name) const; - void SetV1(const CustomElementRegistry*); - - private: - bool V1NameIsDefined(const AtomicString& name) const; - - typedef HeapHashMap<V0CustomElementDescriptor, - Member<V0CustomElementDefinition>> - DefinitionMap; - DefinitionMap definitions_; - HashSet<AtomicString> registered_type_names_; - Member<const CustomElementRegistry> v1_; - bool document_was_detached_; - - DISALLOW_COPY_AND_ASSIGN(V0CustomElementRegistry); -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_REGISTRY_H_ diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_scheduler.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_scheduler.cc deleted file mode 100644 index 91b860eba41..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_scheduler.cc +++ /dev/null @@ -1,169 +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 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/html/custom/v0_custom_element_scheduler.h" - -#include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/dom/element.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_callback_invocation.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_lifecycle_callbacks.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_dispatcher.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_microtask_resolution_step.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_run_queue.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_sync_microtask_queue.h" -#include "third_party/blink/renderer/core/html/imports/html_import_child.h" -#include "third_party/blink/renderer/core/html/imports/html_imports_controller.h" -#include "third_party/blink/renderer/platform/heap/heap.h" - -namespace blink { - -// FIXME: Consider moving the element's callback queue to ElementRareData. -typedef HeapHashMap<Member<Element>, Member<V0CustomElementCallbackQueue>> - ElementCallbackQueueMap; - -static ElementCallbackQueueMap& CallbackQueues() { - DEFINE_STATIC_LOCAL(Persistent<ElementCallbackQueueMap>, map, - (MakeGarbageCollected<ElementCallbackQueueMap>())); - return *map; -} - -static V0CustomElementCallbackQueue& EnsureCallbackQueue(Element* element) { - ElementCallbackQueueMap::ValueType* it = - CallbackQueues().insert(element, nullptr).stored_value; - if (!it->value) - it->value = MakeGarbageCollected<V0CustomElementCallbackQueue>(element); - return *it->value.Get(); -} - -// Finds or creates the callback queue for element. -static V0CustomElementCallbackQueue& ScheduleCallbackQueue(Element* element) { - V0CustomElementCallbackQueue& callback_queue = EnsureCallbackQueue(element); - if (callback_queue.InCreatedCallback()) { - // Don't move it. Authors use the createdCallback like a - // constructor. By not moving it, the createdCallback - // completes before any other callbacks are entered for this - // element. - return callback_queue; - } - - if (V0CustomElementProcessingStack::InCallbackDeliveryScope()) { - // The processing stack is active. - V0CustomElementProcessingStack::Instance().Enqueue(&callback_queue); - return callback_queue; - } - - V0CustomElementMicrotaskDispatcher::Instance().Enqueue(&callback_queue); - return callback_queue; -} - -void V0CustomElementScheduler::ScheduleCallback( - V0CustomElementLifecycleCallbacks* callbacks, - Element* element, - V0CustomElementLifecycleCallbacks::CallbackType type) { - DCHECK(type != V0CustomElementLifecycleCallbacks::kAttributeChangedCallback); - - if (!callbacks->HasCallback(type)) - return; - - V0CustomElementCallbackQueue& queue = ScheduleCallbackQueue(element); - queue.Append( - V0CustomElementCallbackInvocation::CreateInvocation(callbacks, type)); -} - -void V0CustomElementScheduler::ScheduleAttributeChangedCallback( - V0CustomElementLifecycleCallbacks* callbacks, - Element* element, - const AtomicString& name, - const AtomicString& old_value, - const AtomicString& new_value) { - if (!callbacks->HasCallback( - V0CustomElementLifecycleCallbacks::kAttributeChangedCallback)) - return; - - V0CustomElementCallbackQueue& queue = ScheduleCallbackQueue(element); - queue.Append( - V0CustomElementCallbackInvocation::CreateAttributeChangedInvocation( - callbacks, name, old_value, new_value)); -} - -void V0CustomElementScheduler::ResolveOrScheduleResolution( - V0CustomElementRegistrationContext* context, - Element* element, - const V0CustomElementDescriptor& descriptor) { - if (V0CustomElementProcessingStack::InCallbackDeliveryScope()) { - context->Resolve(element, descriptor); - return; - } - - Document& document = element->GetDocument(); - auto* step = MakeGarbageCollected<V0CustomElementMicrotaskResolutionStep>( - context, element, descriptor); - EnqueueMicrotaskStep(document, step); -} - -V0CustomElementMicrotaskImportStep* V0CustomElementScheduler::ScheduleImport( - HTMLImportChild* import) { - DCHECK(!import->HasFinishedLoading()); - DCHECK(import->Parent()); - - // Ownership of the new step is transferred to the parent - // processing step, or the base queue. - auto* step = MakeGarbageCollected<V0CustomElementMicrotaskImportStep>(import); - V0CustomElementMicrotaskImportStep* raw_step = step; - EnqueueMicrotaskStep(*(import->Parent()->GetDocument()), step, - import->IsSync()); - return raw_step; -} - -void V0CustomElementScheduler::EnqueueMicrotaskStep( - Document& document, - V0CustomElementMicrotaskStep* step, - bool import_is_sync) { - Document& tree_root = document.ImportsController() - ? *(document.ImportsController()->TreeRoot()) - : document; - tree_root.CustomElementMicrotaskRunQueue()->Enqueue(document.ImportLoader(), - step, import_is_sync); -} - -void V0CustomElementScheduler::CallbackDispatcherDidFinish() { - if (V0CustomElementMicrotaskDispatcher::Instance().ElementQueueIsEmpty()) - CallbackQueues().clear(); -} - -void V0CustomElementScheduler::MicrotaskDispatcherDidFinish() { - DCHECK(!V0CustomElementProcessingStack::InCallbackDeliveryScope()); - CallbackQueues().clear(); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_scheduler.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_scheduler.h deleted file mode 100644 index 68e0e6e1588..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_scheduler.h +++ /dev/null @@ -1,79 +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 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_HTML_CUSTOM_V0_CUSTOM_ELEMENT_SCHEDULER_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_SCHEDULER_H_ - -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_callback_queue.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_lifecycle_callbacks.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/text/atomic_string.h" - -namespace blink { - -class V0CustomElementDescriptor; -class V0CustomElementMicrotaskImportStep; -class V0CustomElementMicrotaskStep; -class V0CustomElementRegistrationContext; -class HTMLImportChild; - -class V0CustomElementScheduler final - : public GarbageCollected<V0CustomElementScheduler> { - public: - static void ScheduleCallback(V0CustomElementLifecycleCallbacks*, - Element*, - V0CustomElementLifecycleCallbacks::CallbackType); - static void ScheduleAttributeChangedCallback( - V0CustomElementLifecycleCallbacks*, - Element*, - const AtomicString& name, - const AtomicString& old_value, - const AtomicString& new_value); - - static void ResolveOrScheduleResolution(V0CustomElementRegistrationContext*, - Element*, - const V0CustomElementDescriptor&); - static V0CustomElementMicrotaskImportStep* ScheduleImport(HTMLImportChild*); - - static void MicrotaskDispatcherDidFinish(); - static void CallbackDispatcherDidFinish(); - - private: - V0CustomElementScheduler() = default; - - static void EnqueueMicrotaskStep(Document&, - V0CustomElementMicrotaskStep*, - bool import_is_sync = true); -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_SCHEDULER_H_ diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_sync_microtask_queue.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_sync_microtask_queue.cc deleted file mode 100644 index 8dab3026123..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_sync_microtask_queue.cc +++ /dev/null @@ -1,25 +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/html/custom/v0_custom_element_sync_microtask_queue.h" - -namespace blink { - -void V0CustomElementSyncMicrotaskQueue::Enqueue( - V0CustomElementMicrotaskStep* step) { - queue_.push_back(step); -} - -void V0CustomElementSyncMicrotaskQueue::DoDispatch() { - unsigned i; - - for (i = 0; i < queue_.size(); ++i) { - if (V0CustomElementMicrotaskStep::kProcessing == queue_[i]->Process()) - break; - } - - queue_.EraseAt(0, i); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_sync_microtask_queue.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_sync_microtask_queue.h deleted file mode 100644 index 884033c6dde..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_sync_microtask_queue.h +++ /dev/null @@ -1,25 +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_HTML_CUSTOM_V0_CUSTOM_ELEMENT_SYNC_MICROTASK_QUEUE_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_SYNC_MICROTASK_QUEUE_H_ - -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_queue_base.h" - -namespace blink { - -class V0CustomElementSyncMicrotaskQueue - : public V0CustomElementMicrotaskQueueBase { - public: - V0CustomElementSyncMicrotaskQueue() = default; - - void Enqueue(V0CustomElementMicrotaskStep*); - - private: - void DoDispatch() override; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_SYNC_MICROTASK_QUEUE_H_ diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_upgrade_candidate_map.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_upgrade_candidate_map.cc deleted file mode 100644 index 28c5c0fc581..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_upgrade_candidate_map.cc +++ /dev/null @@ -1,94 +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/core/html/custom/v0_custom_element_upgrade_candidate_map.h" - -#include "third_party/blink/renderer/core/dom/element.h" - -namespace blink { - -V0CustomElementUpgradeCandidateMap::~V0CustomElementUpgradeCandidateMap() = - default; - -void V0CustomElementUpgradeCandidateMap::Add( - const V0CustomElementDescriptor& descriptor, - Element* element) { - Observe(element); - - UpgradeCandidateMap::AddResult result = - upgrade_candidates_.insert(element, descriptor); - DCHECK(result.is_new_entry); - - UnresolvedDefinitionMap::iterator it = - unresolved_definitions_.find(descriptor); - ElementSet* elements; - if (it == unresolved_definitions_.end()) - elements = unresolved_definitions_ - .insert(descriptor, MakeGarbageCollected<ElementSet>()) - .stored_value->value.Get(); - else - elements = it->value.Get(); - elements->insert(element); -} - -void V0CustomElementUpgradeCandidateMap::ElementWasDestroyed(Element* element) { - V0CustomElementObserver::ElementWasDestroyed(element); - UpgradeCandidateMap::iterator candidate = upgrade_candidates_.find(element); - SECURITY_DCHECK(candidate != upgrade_candidates_.end()); - - UnresolvedDefinitionMap::iterator elements = - unresolved_definitions_.find(candidate->value); - SECURITY_DCHECK(elements != unresolved_definitions_.end()); - elements->value->erase(element); - upgrade_candidates_.erase(candidate); -} - -V0CustomElementUpgradeCandidateMap::ElementSet* -V0CustomElementUpgradeCandidateMap::TakeUpgradeCandidatesFor( - const V0CustomElementDescriptor& descriptor) { - ElementSet* candidates = unresolved_definitions_.Take(descriptor); - - if (!candidates) - return nullptr; - - for (const auto& candidate : *candidates) { - Unobserve(candidate); - upgrade_candidates_.erase(candidate); - } - return candidates; -} - -void V0CustomElementUpgradeCandidateMap::Trace(Visitor* visitor) const { - visitor->Trace(upgrade_candidates_); - visitor->Trace(unresolved_definitions_); - V0CustomElementObserver::Trace(visitor); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_upgrade_candidate_map.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_upgrade_candidate_map.h deleted file mode 100644 index ee0232f17cb..00000000000 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_upgrade_candidate_map.h +++ /dev/null @@ -1,74 +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_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_UPGRADE_CANDIDATE_MAP_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_UPGRADE_CANDIDATE_MAP_H_ - -#include "base/macros.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_descriptor.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_descriptor_hash.h" -#include "third_party/blink/renderer/core/html/custom/v0_custom_element_observer.h" -#include "third_party/blink/renderer/platform/wtf/hash_map.h" -#include "third_party/blink/renderer/platform/wtf/linked_hash_set.h" - -namespace blink { - -class V0CustomElementUpgradeCandidateMap final - : public V0CustomElementObserver { - public: - V0CustomElementUpgradeCandidateMap() = default; - ~V0CustomElementUpgradeCandidateMap() override; - - // API for V0CustomElementRegistrationContext to save and take candidates - - typedef HeapLinkedHashSet<WeakMember<Element>> ElementSet; - - void Add(const V0CustomElementDescriptor&, Element*); - ElementSet* TakeUpgradeCandidatesFor(const V0CustomElementDescriptor&); - - void Trace(Visitor*) const override; - - private: - void ElementWasDestroyed(Element*) override; - - typedef HeapHashMap<WeakMember<Element>, V0CustomElementDescriptor> - UpgradeCandidateMap; - UpgradeCandidateMap upgrade_candidates_; - - typedef HeapHashMap<V0CustomElementDescriptor, Member<ElementSet>> - UnresolvedDefinitionMap; - UnresolvedDefinitionMap unresolved_definitions_; - - DISALLOW_COPY_AND_ASSIGN(V0CustomElementUpgradeCandidateMap); -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CUSTOM_V0_CUSTOM_ELEMENT_UPGRADE_CANDIDATE_MAP_H_ diff --git a/chromium/third_party/blink/renderer/core/html/forms/DIR_METADATA b/chromium/third_party/blink/renderer/core/html/forms/DIR_METADATA new file mode 100644 index 00000000000..a682370216c --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/forms/DIR_METADATA @@ -0,0 +1,5 @@ +monorail { + component: "Blink>Forms" +} + +team_email: "dom-dev@chromium.org" diff --git a/chromium/third_party/blink/renderer/core/html/forms/OWNERS b/chromium/third_party/blink/renderer/core/html/forms/OWNERS index cbe63714987..e69f3656a7f 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/OWNERS +++ b/chromium/third_party/blink/renderer/core/html/forms/OWNERS @@ -1,6 +1,3 @@ keishi@chromium.org tkent@chromium.org masonfreed@chromium.org - -# TEAM: dom-dev@chromium.org -# COMPONENT: Blink>Forms 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 d13e518a241..b363ab086da 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 @@ -32,6 +32,7 @@ #include "third_party/blink/renderer/core/html/forms/base_checkable_input_type.h" #include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/dom/events/simulated_click_options.h" #include "third_party/blink/renderer/core/events/keyboard_event.h" #include "third_party/blink/renderer/core/frame/web_feature.h" #include "third_party/blink/renderer/core/html/forms/form_controller.h" @@ -87,11 +88,10 @@ bool BaseCheckableInputType::CanSetStringValue() const { // FIXME: Could share this with KeyboardClickableInputTypeView and // RangeInputType if we had a common base class. -void BaseCheckableInputType::AccessKeyAction(bool send_mouse_events) { - InputTypeView::AccessKeyAction(send_mouse_events); - - GetElement().DispatchSimulatedClick( - nullptr, send_mouse_events ? kSendMouseUpDownEvents : kSendNoEvents); +void BaseCheckableInputType::AccessKeyAction( + SimulatedClickCreationScope creation_scope) { + InputTypeView::AccessKeyAction(creation_scope); + GetElement().DispatchSimulatedClick(nullptr, creation_scope); } bool BaseCheckableInputType::MatchesDefaultPseudoClass() { @@ -121,4 +121,8 @@ bool BaseCheckableInputType::IsCheckable() { return true; } +void BaseCheckableInputType::HandleBlurEvent() { + GetElement().SetActive(false); +} + } // namespace blink 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 0e225e11560..ffe004840d0 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 @@ -31,6 +31,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_BASE_CHECKABLE_INPUT_TYPE_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_BASE_CHECKABLE_INPUT_TYPE_H_ +#include "third_party/blink/renderer/core/dom/events/simulated_click_options.h" #include "third_party/blink/renderer/core/html/forms/input_type.h" #include "third_party/blink/renderer/core/html/forms/input_type_view.h" @@ -42,6 +43,8 @@ class BaseCheckableInputType : public InputType, public InputTypeView { void Trace(Visitor*) const override; using InputType::GetElement; + void HandleBlurEvent() override; + protected: BaseCheckableInputType(HTMLInputElement& element) : InputType(element), @@ -59,7 +62,7 @@ class BaseCheckableInputType : public InputType, public InputTypeView { void AppendToFormData(FormData&) const final; void HandleKeypressEvent(KeyboardEvent&) final; bool CanSetStringValue() const final; - void AccessKeyAction(bool send_mouse_events) final; + void AccessKeyAction(SimulatedClickCreationScope creation_scope) final; bool MatchesDefaultPseudoClass() override; ValueMode GetValueMode() const override; void SetValue(const String&, diff --git a/chromium/third_party/blink/renderer/core/html/forms/base_text_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/base_text_input_type.cc index 0f838dc1992..200b2bd5a07 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/base_text_input_type.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/base_text_input_type.cc @@ -32,6 +32,11 @@ namespace blink { +void BaseTextInputType::Trace(Visitor* visitor) const { + visitor->Trace(regexp_); + TextFieldInputType::Trace(visitor); +} + BaseTextInputType::BaseTextInputType(HTMLInputElement& element) : TextFieldInputType(element) {} @@ -84,9 +89,9 @@ bool BaseTextInputType::PatternMismatch(const String& value) const { if (raw_pattern.IsNull() || value.IsEmpty()) return false; if (!regexp_ || pattern_for_regexp_ != raw_pattern) { - std::unique_ptr<ScriptRegexp> raw_regexp( - new ScriptRegexp(raw_pattern, kTextCaseSensitive, kMultilineDisabled, - ScriptRegexp::UTF16)); + ScriptRegexp* raw_regexp = MakeGarbageCollected<ScriptRegexp>( + raw_pattern, kTextCaseSensitive, kMultilineDisabled, + ScriptRegexp::UTF16); if (!raw_regexp->IsValid()) { GetElement().GetDocument().AddConsoleMessage( MakeGarbageCollected<ConsoleMessage>( @@ -95,13 +100,13 @@ bool BaseTextInputType::PatternMismatch(const String& value) const { "Pattern attribute value " + raw_pattern + " is not a valid regular expression: " + raw_regexp->ExceptionMessage())); - regexp_.reset(raw_regexp.release()); + regexp_ = raw_regexp; pattern_for_regexp_ = raw_pattern; return false; } String pattern = "^(?:" + raw_pattern + ")$"; - regexp_.reset(new ScriptRegexp(pattern, kTextCaseSensitive, - kMultilineDisabled, ScriptRegexp::UTF16)); + regexp_ = MakeGarbageCollected<ScriptRegexp>( + pattern, kTextCaseSensitive, kMultilineDisabled, ScriptRegexp::UTF16); pattern_for_regexp_ = raw_pattern; } else if (!regexp_->IsValid()) { return false; diff --git a/chromium/third_party/blink/renderer/core/html/forms/base_text_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/base_text_input_type.h index 9e820805e02..f75ae74d42d 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/base_text_input_type.h +++ b/chromium/third_party/blink/renderer/core/html/forms/base_text_input_type.h @@ -40,6 +40,9 @@ class ScriptRegexp; // Base of email, password, search, tel, text, and URL types. // They support maxlength, selection functions, and so on. class BaseTextInputType : public TextFieldInputType { + public: + void Trace(Visitor* visitor) const override; + protected: BaseTextInputType(HTMLInputElement&); ~BaseTextInputType() override; @@ -57,7 +60,7 @@ class BaseTextInputType : public TextFieldInputType { // regexp_ and pattern_for_regexp_ are mutable because they are kinds of // cache. - mutable std::unique_ptr<ScriptRegexp> regexp_; + mutable Member<ScriptRegexp> regexp_; mutable AtomicString pattern_for_regexp_; }; 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 7259f28988f..5ecc350d9a4 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 @@ -571,10 +571,12 @@ void DateTimeEditElement::BlurByOwner() { field->blur(); } -scoped_refptr<ComputedStyle> DateTimeEditElement::CustomStyleForLayoutObject() { - // FIXME: This is a kind of layout. We might want to introduce new - // layoutObject. - scoped_refptr<ComputedStyle> style = OriginalStyleForLayoutObject(); +scoped_refptr<ComputedStyle> DateTimeEditElement::CustomStyleForLayoutObject( + const StyleRecalcContext& style_recalc_context) { + // TODO(crbug.com/1181868): This is a kind of layout. We might want to + // introduce new LayoutObject. + scoped_refptr<ComputedStyle> style = + OriginalStyleForLayoutObject(style_recalc_context); float width = 0; for (Node* child = FieldsWrapperElement()->firstChild(); child; child = child->nextSibling()) { @@ -594,6 +596,7 @@ scoped_refptr<ComputedStyle> DateTimeEditElement::CustomStyleForLayoutObject() { } } style->SetWidth(Length::Fixed(ceilf(width))); + style->SetCustomStyleCallbackDependsOnFont(); return style; } 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 c2e7ab39c6e..0fcacc50303 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 @@ -139,7 +139,8 @@ class DateTimeEditElement final : public HTMLDivElement, void UpdateUIState(); // Element function. - scoped_refptr<ComputedStyle> CustomStyleForLayoutObject() override; + scoped_refptr<ComputedStyle> CustomStyleForLayoutObject( + const StyleRecalcContext&) override; bool IsDateTimeEditElement() const override; // DateTimeFieldElement::FieldOwner functions. diff --git a/chromium/third_party/blink/renderer/core/html/forms/email_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/email_input_type.cc index 06aa0bf6f14..4e574dade6d 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/email_input_type.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/email_input_type.cc @@ -57,9 +57,9 @@ static const int32_t kMaximumDomainNameLength = 255; // Use the same option as in url/url_canon_icu.cc static const int32_t kIdnaConversionOption = UIDNA_CHECK_BIDI; -std::unique_ptr<ScriptRegexp> EmailInputType::CreateEmailRegexp() { - return std::make_unique<ScriptRegexp>(kEmailPattern, - kTextCaseUnicodeInsensitive); +ScriptRegexp* EmailInputType::CreateEmailRegexp() { + return MakeGarbageCollected<ScriptRegexp>(kEmailPattern, + kTextCaseUnicodeInsensitive); } String EmailInputType::ConvertEmailAddressToASCII(const ScriptRegexp& regexp, diff --git a/chromium/third_party/blink/renderer/core/html/forms/email_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/email_input_type.h index 41970a04320..77eeeabda73 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/email_input_type.h +++ b/chromium/third_party/blink/renderer/core/html/forms/email_input_type.h @@ -44,7 +44,7 @@ class EmailInputType final : public BaseTextInputType { const String&); CORE_EXPORT static bool IsValidEmailAddress(const ScriptRegexp&, const String&); - CORE_EXPORT static std::unique_ptr<ScriptRegexp> CreateEmailRegexp(); + CORE_EXPORT static ScriptRegexp* CreateEmailRegexp(); private: void CountUsage() override; diff --git a/chromium/third_party/blink/renderer/core/html/forms/email_input_type_test.cc b/chromium/third_party/blink/renderer/core/html/forms/email_input_type_test.cc index b702e425cc4..6151a7379f8 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/email_input_type_test.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/email_input_type_test.cc @@ -12,8 +12,7 @@ namespace blink { namespace { void ExpectToSucceed(const String& source) { - std::unique_ptr<ScriptRegexp> email_regexp = - EmailInputType::CreateEmailRegexp(); + ScriptRegexp* email_regexp = EmailInputType::CreateEmailRegexp(); String result = EmailInputType::ConvertEmailAddressToASCII(*email_regexp, source); EXPECT_NE(source, result); @@ -21,8 +20,7 @@ void ExpectToSucceed(const String& source) { } void ExpectToFail(const String& source) { - std::unique_ptr<ScriptRegexp> email_regexp = - EmailInputType::CreateEmailRegexp(); + ScriptRegexp* email_regexp = EmailInputType::CreateEmailRegexp(); // Conversion failed. The resultant value might contains non-ASCII // characters, and not a valid email address. EXPECT_FALSE(EmailInputType::IsValidEmailAddress( diff --git a/chromium/third_party/blink/renderer/core/html/forms/external_popup_menu.cc b/chromium/third_party/blink/renderer/core/html/forms/external_popup_menu.cc index 99a12ecbf9f..2ef63564e4f 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/external_popup_menu.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/external_popup_menu.cc @@ -40,7 +40,7 @@ #include "third_party/blink/renderer/core/exported/web_view_impl.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" -#include "third_party/blink/renderer/core/frame/web_frame_widget_base.h" +#include "third_party/blink/renderer/core/frame/web_frame_widget_impl.h" #include "third_party/blink/renderer/core/frame/web_local_frame_impl.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" @@ -68,6 +68,7 @@ ExternalPopupMenu::~ExternalPopupMenu() = default; void ExternalPopupMenu::Trace(Visitor* visitor) const { visitor->Trace(owner_element_); visitor->Trace(local_frame_); + visitor->Trace(dispatch_event_timer_); visitor->Trace(receiver_); PopupMenu::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/forms/external_popup_menu.h b/chromium/third_party/blink/renderer/core/html/forms/external_popup_menu.h index 5965d566bbe..061b856044f 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/external_popup_menu.h +++ b/chromium/third_party/blink/renderer/core/html/forms/external_popup_menu.h @@ -90,7 +90,7 @@ class CORE_EXPORT ExternalPopupMenu final Member<HTMLSelectElement> owner_element_; Member<LocalFrame> local_frame_; std::unique_ptr<WebMouseEvent> synthetic_event_; - TaskRunnerTimer<ExternalPopupMenu> dispatch_event_timer_; + HeapTaskRunnerTimer<ExternalPopupMenu> dispatch_event_timer_; // The actual implementor of the show menu. HeapMojoReceiver<mojom::blink::PopupMenuClient, ExternalPopupMenu, diff --git a/chromium/third_party/blink/renderer/core/html/forms/hidden_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/hidden_input_type.cc index 76a13e9e3c5..02fd6492193 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/hidden_input_type.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/hidden_input_type.cc @@ -32,6 +32,7 @@ #include "third_party/blink/renderer/core/html/forms/hidden_input_type.h" #include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/dom/events/simulated_click_options.h" #include "third_party/blink/renderer/core/frame/web_feature.h" #include "third_party/blink/renderer/core/html/forms/form_controller.h" #include "third_party/blink/renderer/core/html/forms/form_data.h" @@ -73,7 +74,7 @@ LayoutObject* HiddenInputType::CreateLayoutObject(const ComputedStyle&, return nullptr; } -void HiddenInputType::AccessKeyAction(bool) {} +void HiddenInputType::AccessKeyAction(SimulatedClickCreationScope) {} bool HiddenInputType::LayoutObjectIsNeeded() { return false; diff --git a/chromium/third_party/blink/renderer/core/html/forms/hidden_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/hidden_input_type.h index 0bcf41149b1..b251c6d3687 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/hidden_input_type.h +++ b/chromium/third_party/blink/renderer/core/html/forms/hidden_input_type.h @@ -31,6 +31,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_HIDDEN_INPUT_TYPE_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_HIDDEN_INPUT_TYPE_H_ +#include "third_party/blink/renderer/core/dom/events/simulated_click_options.h" #include "third_party/blink/renderer/core/html/forms/input_type.h" #include "third_party/blink/renderer/core/html/forms/input_type_view.h" @@ -52,7 +53,7 @@ class HiddenInputType final : public InputType, private InputTypeView { bool SupportsValidation() const override; LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) const override; - void AccessKeyAction(bool send_mouse_events) override; + void AccessKeyAction(SimulatedClickCreationScope creation_scope) override; bool LayoutObjectIsNeeded() override; ValueMode GetValueMode() const override; bool IsInteractiveContent() const override { return false; } 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 c0b6a74c6af..4ef91c54288 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 @@ -26,6 +26,7 @@ #include "third_party/blink/renderer/core/html/forms/html_button_element.h" #include "third_party/blink/renderer/core/dom/attribute.h" +#include "third_party/blink/renderer/core/dom/events/simulated_click_options.h" #include "third_party/blink/renderer/core/events/keyboard_event.h" #include "third_party/blink/renderer/core/frame/web_feature.h" #include "third_party/blink/renderer/core/html/forms/form_data.h" @@ -154,11 +155,10 @@ void HTMLButtonElement::AppendToFormData(FormData& form_data) { form_data.AppendFromElement(GetName(), Value()); } -void HTMLButtonElement::AccessKeyAction(bool send_mouse_events) { +void HTMLButtonElement::AccessKeyAction( + SimulatedClickCreationScope creation_scope) { focus(); - - DispatchSimulatedClick( - nullptr, send_mouse_events ? kSendMouseUpDownEvents : kSendNoEvents); + DispatchSimulatedClick(nullptr, creation_scope); } bool HTMLButtonElement::IsURLAttribute(const Attribute& attribute) const { 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 c51020487ff..9326ef276be 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 @@ -24,6 +24,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_HTML_BUTTON_ELEMENT_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_HTML_BUTTON_ELEMENT_H_ +#include "third_party/blink/renderer/core/dom/events/simulated_click_options.h" #include "third_party/blink/renderer/core/html/forms/html_form_control_element.h" namespace blink { @@ -67,7 +68,7 @@ class HTMLButtonElement final : public HTMLFormControlElement { bool IsActivatedSubmit() const override; void SetActivatedSubmit(bool flag) override; - void AccessKeyAction(bool send_mouse_events) override; + void AccessKeyAction(SimulatedClickCreationScope creation_scope) override; bool IsURLAttribute(const Attribute&) const override; bool CanStartSelection() const override { return false; } diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_field_set_element.cc b/chromium/third_party/blink/renderer/core/html/forms/html_field_set_element.cc index b116574ff38..53c4cfbb6ea 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/html_field_set_element.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/html_field_set_element.cc @@ -135,10 +135,6 @@ LayoutBox* HTMLFieldSetElement::GetLayoutBoxForScrolling() const { return HTMLFormControlElement::GetLayoutBoxForScrolling(); } -bool HTMLFieldSetElement::TypeShouldForceLegacyLayout() const { - return !RuntimeEnabledFeatures::LayoutNGFieldsetEnabled(); -} - HTMLLegendElement* HTMLFieldSetElement::Legend() const { return Traversal<HTMLLegendElement>::FirstChild(*this); } diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_field_set_element.h b/chromium/third_party/blink/renderer/core/html/forms/html_field_set_element.h index b0538ed5af3..b5f62447fd1 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/html_field_set_element.h +++ b/chromium/third_party/blink/renderer/core/html/forms/html_field_set_element.h @@ -48,7 +48,6 @@ class CORE_EXPORT HTMLFieldSetElement final : public HTMLFormControlElement { bool SupportsFocus() const override; LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) override; LayoutBox* GetLayoutBoxForScrolling() const override; - bool TypeShouldForceLegacyLayout() const final; const AtomicString& FormControlType() const override; bool RecalcWillValidate() const override { return false; } bool MatchesValidityPseudoClasses() const final; diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_form_element.idl b/chromium/third_party/blink/renderer/core/html/forms/html_form_element.idl index aa4293e67b7..ad8ea3f30e6 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/html_form_element.idl +++ b/chromium/third_party/blink/renderer/core/html/forms/html_form_element.idl @@ -28,9 +28,9 @@ [CEReactions, Reflect=accept_charset] attribute DOMString acceptCharset; [CEReactions, URL] attribute USVString action; [CEReactions, Reflect, ReflectOnly=("on","off"), ReflectMissing="on", ReflectInvalid="on"] attribute DOMString autocomplete; - [CEReactions, CustomElementCallbacks] attribute DOMString enctype; - [CEReactions, CustomElementCallbacks] attribute DOMString encoding; - [CEReactions, CustomElementCallbacks] attribute DOMString method; + [CEReactions] attribute DOMString enctype; + [CEReactions] attribute DOMString encoding; + [CEReactions] attribute DOMString method; [CEReactions, Reflect] attribute DOMString name; [CEReactions, Reflect] attribute boolean noValidate; [CEReactions, Reflect] attribute DOMString target; @@ -43,7 +43,7 @@ [ImplementedAs=submitFromJavaScript] void submit(); [RaisesException] void requestSubmit(optional HTMLElement submitter); - [CEReactions, CustomElementCallbacks] void reset(); + [CEReactions] void reset(); boolean checkValidity(); boolean reportValidity(); }; 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 966621de256..ac733001009 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 @@ -41,10 +41,10 @@ #include "third_party/blink/renderer/core/css/style_change_reason.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/events/scoped_event_queue.h" +#include "third_party/blink/renderer/core/dom/events/simulated_click_options.h" #include "third_party/blink/renderer/core/dom/id_target_observer.h" #include "third_party/blink/renderer/core/dom/node_computed_style.h" #include "third_party/blink/renderer/core/dom/shadow_root.h" -#include "third_party/blink/renderer/core/dom/v0_insertion_point.h" #include "third_party/blink/renderer/core/editing/frame_selection.h" #include "third_party/blink/renderer/core/editing/spellcheck/spell_checker.h" #include "third_party/blink/renderer/core/events/before_text_inserted_event.h" @@ -596,7 +596,7 @@ void HTMLInputElement::SubtreeHasChanged() { input_type_view_->SubtreeHasChanged(); // When typing in an input field, childrenChanged is not called, so we need to // force the directionality check. - CalculateAndAdjustDirectionality(); + CalculateAndAdjustAutoDirectionality(this); } const AtomicString& HTMLInputElement::FormControlType() const { @@ -730,8 +730,9 @@ void HTMLInputElement::SetSelectionRangeForTesting( TextControlElement::setSelectionRangeForBinding(start, end); } -void HTMLInputElement::AccessKeyAction(bool send_mouse_events) { - input_type_view_->AccessKeyAction(send_mouse_events); +void HTMLInputElement::AccessKeyAction( + SimulatedClickCreationScope creation_scope) { + input_type_view_->AccessKeyAction(creation_scope); } bool HTMLInputElement::IsPresentationAttribute( @@ -759,11 +760,19 @@ void HTMLInputElement::CollectStyleForPresentationAttribute( if (input_type_->ShouldRespectAlignAttribute()) ApplyAlignmentAttributeToStyle(value, style); } else if (name == html_names::kWidthAttr) { - if (input_type_->ShouldRespectHeightAndWidthAttributes()) + if (input_type_->ShouldRespectHeightAndWidthAttributes()) { AddHTMLLengthToStyle(style, CSSPropertyID::kWidth, value); + const AtomicString& height = FastGetAttribute(html_names::kHeightAttr); + if (height) + ApplyAspectRatioToStyle(value, height, style); + } } else if (name == html_names::kHeightAttr) { - if (input_type_->ShouldRespectHeightAndWidthAttributes()) + if (input_type_->ShouldRespectHeightAndWidthAttributes()) { AddHTMLLengthToStyle(style, CSSPropertyID::kHeight, value); + const AtomicString& width = FastGetAttribute(html_names::kWidthAttr); + if (width) + ApplyAspectRatioToStyle(width, value, style); + } } else if (name == html_names::kBorderAttr && type() == input_type_names::kImage) { // FIXME: Remove type check. ApplyBorderAttributeToStyle(value, style); @@ -1127,8 +1136,12 @@ void HTMLInputElement::SetValueForUser(const String& value) { } void HTMLInputElement::SetSuggestedValue(const String& value) { - if (!input_type_->CanSetSuggestedValue()) + if (!input_type_->CanSetSuggestedValue()) { + // Clear the suggested value because it may have been set when + // `input_type_->CanSetSuggestedValue()` was true. + TextControlElement::SetSuggestedValue(String()); return; + } needs_to_update_view_value_ = true; TextControlElement::SetSuggestedValue(SanitizeValue(value)); SetNeedsStyleRecalc( @@ -1849,7 +1862,7 @@ bool HTMLInputElement::SupportsPlaceholder() const { } void HTMLInputElement::UpdatePlaceholderText() { - return input_type_view_->UpdatePlaceholderText(); + return input_type_view_->UpdatePlaceholderText(!SuggestedValue().IsEmpty()); } String HTMLInputElement::GetPlaceholderValue() const { @@ -2043,8 +2056,10 @@ bool HTMLInputElement::IsInteractiveContent() const { return input_type_->IsInteractiveContent(); } -scoped_refptr<ComputedStyle> HTMLInputElement::CustomStyleForLayoutObject() { - scoped_refptr<ComputedStyle> style = OriginalStyleForLayoutObject(); +scoped_refptr<ComputedStyle> HTMLInputElement::CustomStyleForLayoutObject( + const StyleRecalcContext& style_recalc_context) { + scoped_refptr<ComputedStyle> style = + OriginalStyleForLayoutObject(style_recalc_context); input_type_view_->CustomStyleForLayoutObject(*style); return style; } 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 77a311d2b22..d4ed4d88a51 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 @@ -31,6 +31,7 @@ #include "third_party/blink/renderer/bindings/core/v8/script_regexp.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/dom/create_element_flags.h" +#include "third_party/blink/renderer/core/dom/events/simulated_click_options.h" #include "third_party/blink/renderer/core/html/forms/file_chooser.h" #include "third_party/blink/renderer/core/html/forms/step_range.h" #include "third_party/blink/renderer/core/html/forms/text_control_element.h" @@ -388,7 +389,7 @@ class CORE_EXPORT HTMLInputElement bool CanStartSelection() const final; - void AccessKeyAction(bool send_mouse_events) final; + void AccessKeyAction(SimulatedClickCreationScope creation_scope) final; void ParseAttribute(const AttributeModificationParams&) override; bool IsPresentationAttribute(const QualifiedName&) const final; @@ -446,7 +447,8 @@ class CORE_EXPORT HTMLInputElement void AddToRadioButtonGroup(); void RemoveFromRadioButtonGroup(); - scoped_refptr<ComputedStyle> CustomStyleForLayoutObject() override; + scoped_refptr<ComputedStyle> CustomStyleForLayoutObject( + const StyleRecalcContext&) override; void DidRecalcStyle(const StyleRecalcChange) override; void MaybeReportPiiMetrics(); diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_input_element.idl b/chromium/third_party/blink/renderer/core/html/forms/html_input_element.idl index 48bb6afc2a6..1fdc1e13bde 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/html_input_element.idl +++ b/chromium/third_party/blink/renderer/core/html/forms/html_input_element.idl @@ -40,37 +40,37 @@ enum SelectionMode { "select", "start", "end", "preserve" }; // https://www.w3.org/Bugs/Public/show_bug.cgi?id=22682 attribute FileList? files; [CEReactions] attribute DOMString formAction; - [CEReactions, CustomElementCallbacks] attribute DOMString formEnctype; - [CEReactions, CustomElementCallbacks] attribute DOMString formMethod; + [CEReactions] attribute DOMString formEnctype; + [CEReactions] attribute DOMString formMethod; [CEReactions, Reflect] attribute boolean formNoValidate; [CEReactions, Reflect] attribute DOMString formTarget; - [CEReactions, CustomElementCallbacks] attribute unsigned long height; + [CEReactions] attribute unsigned long height; attribute boolean indeterminate; readonly attribute HTMLElement? list; [CEReactions, Reflect] attribute DOMString max; - [CEReactions, RaisesException=Setter, CustomElementCallbacks] attribute long maxLength; + [CEReactions, RaisesException=Setter] attribute long maxLength; [CEReactions, Reflect] attribute DOMString min; - [CEReactions, RaisesException=Setter, CustomElementCallbacks] attribute long minLength; + [CEReactions, RaisesException=Setter] attribute long minLength; [CEReactions, Reflect] attribute boolean multiple; [CEReactions, Reflect] attribute DOMString name; [CEReactions, Reflect] attribute DOMString pattern; [CEReactions, Reflect] attribute DOMString placeholder; [CEReactions, Reflect] attribute boolean readOnly; [CEReactions, Reflect] attribute boolean required; - [CEReactions, RaisesException=Setter, CustomElementCallbacks] attribute unsigned long size; + [CEReactions, RaisesException=Setter] attribute unsigned long size; [CEReactions, Reflect, URL] attribute DOMString src; [CEReactions, Reflect] attribute DOMString step; - [CEReactions, CustomElementCallbacks] attribute DOMString type; - [CEReactions, Reflect=value, CustomElementCallbacks] attribute DOMString defaultValue; - [CEReactions, RaisesException=Setter, CustomElementCallbacks] attribute [TreatNullAs=EmptyString] DOMString value; - [CEReactions, RaisesException=Setter, CustomElementCallbacks, CallWith=ScriptState] attribute object? valueAsDate; - [RaisesException=Setter, CustomElementCallbacks] attribute unrestricted double valueAsNumber; + [CEReactions] attribute DOMString type; + [CEReactions, Reflect=value] attribute DOMString defaultValue; + [CEReactions, RaisesException=Setter] attribute [TreatNullAs=EmptyString] DOMString value; + [CEReactions, RaisesException=Setter, CallWith=ScriptState] attribute object? valueAsDate; + [RaisesException=Setter] attribute unrestricted double valueAsNumber; // Note: The spec has valueLow and valueHigh for two-valued range controls. // https://www.w3.org/Bugs/Public/show_bug.cgi?id=13154 - [CEReactions, CustomElementCallbacks] attribute unsigned long width; + [CEReactions] attribute unsigned long width; - [RaisesException, CustomElementCallbacks] void stepUp(optional long n = 1); - [RaisesException, CustomElementCallbacks] void stepDown(optional long n = 1); + [RaisesException] void stepUp(optional long n = 1); + [RaisesException] void stepDown(optional long n = 1); readonly attribute boolean willValidate; readonly attribute ValidityState validity; 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 d8258f10792..1b30722decd 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 @@ -27,6 +27,7 @@ #include "third_party/blink/public/mojom/input/focus_type.mojom-blink.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/element_traversal.h" +#include "third_party/blink/renderer/core/dom/events/simulated_click_options.h" #include "third_party/blink/renderer/core/dom/focus_params.h" #include "third_party/blink/renderer/core/editing/editing_utilities.h" #include "third_party/blink/renderer/core/editing/frame_selection.h" @@ -249,11 +250,12 @@ void HTMLLabelElement::focus(const FocusParams& params) { } } -void HTMLLabelElement::AccessKeyAction(bool send_mouse_events) { +void HTMLLabelElement::AccessKeyAction( + SimulatedClickCreationScope creation_scope) { if (HTMLElement* element = control()) - element->AccessKeyAction(send_mouse_events); + element->AccessKeyAction(creation_scope); else - HTMLElement::AccessKeyAction(send_mouse_events); + HTMLElement::AccessKeyAction(creation_scope); } } // namespace blink 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 3e4fc40bea2..b57b74cd805 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 @@ -25,6 +25,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_HTML_LABEL_ELEMENT_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/html/html_element.h" namespace blink { @@ -44,7 +45,7 @@ class CORE_EXPORT HTMLLabelElement final : public HTMLElement { bool IsInInteractiveContent(Node*) const; bool IsInteractiveContent() const override; - void AccessKeyAction(bool send_mouse_events) override; + void AccessKeyAction(SimulatedClickCreationScope creation_scope) override; // Overridden to update the hover/active state of the corresponding control. void SetActive(bool active) override; 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 ea0b9c965c0..7ee9f4c8339 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 @@ -26,6 +26,7 @@ #include "third_party/blink/renderer/core/html/forms/html_opt_group_element.h" #include "third_party/blink/renderer/core/css/css_property_names.h" +#include "third_party/blink/renderer/core/dom/events/simulated_click_options.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_select_element.h" @@ -96,8 +97,7 @@ void HTMLOptGroupElement::ChildrenChanged(const ChildrenChange& change) { if (auto* option = DynamicTo<HTMLOptionElement>(change.sibling_changed)) select->OptionRemoved(*option); } else if (change.type == ChildrenChangeType::kAllChildrenRemoved) { - DCHECK(change.removed_nodes); - for (Node* node : *change.removed_nodes) { + for (Node* node : change.removed_nodes) { if (auto* option = DynamicTo<HTMLOptionElement>(node)) select->OptionRemoved(*option); } @@ -148,11 +148,14 @@ String HTMLOptGroupElement::DefaultToolTip() const { return String(); } -void HTMLOptGroupElement::AccessKeyAction(bool) { +void HTMLOptGroupElement::AccessKeyAction( + SimulatedClickCreationScope creation_scope) { HTMLSelectElement* select = OwnerSelectElement(); - // send to the parent to bring focus to the list box + // Send to the parent to bring focus to the list box. + // TODO(crbug.com/1176745): investigate why we don't care + // about creation scope. if (select && !select->IsFocused()) - select->AccessKeyAction(false); + select->AccessKeyAction(SimulatedClickCreationScope::kFromUserAgent); } void HTMLOptGroupElement::DidAddUserAgentShadowRoot(ShadowRoot& root) { 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 a03db9bb975..57a0fbf1043 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 @@ -25,6 +25,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_HTML_OPT_GROUP_ELEMENT_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/html/html_element.h" namespace blink { @@ -37,6 +38,7 @@ class CORE_EXPORT HTMLOptGroupElement final : public HTMLElement { public: explicit HTMLOptGroupElement(Document&); + ~HTMLOptGroupElement() override; bool IsDisabledFormControl() const override; String DefaultToolTip() const override; @@ -49,13 +51,11 @@ class CORE_EXPORT HTMLOptGroupElement final : public HTMLElement { static bool CanAssignToOptGroupSlot(const Node&); private: - ~HTMLOptGroupElement() override; - bool SupportsFocus() const override; void ChildrenChanged(const ChildrenChange& change) override; bool ChildrenChangedAllChildrenRemovedNeedsList() const override; void ParseAttribute(const AttributeModificationParams&) override; - void AccessKeyAction(bool send_mouse_events) override; + void AccessKeyAction(SimulatedClickCreationScope creation_scope) override; void DidAddUserAgentShadowRoot(ShadowRoot&) override; bool MatchesEnabledPseudoClass() const override; InsertionNotificationRequest InsertedInto(ContainerNode&) override; diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_option_element.cc b/chromium/third_party/blink/renderer/core/html/forms/html_option_element.cc index 2c22f9d040b..7575659e9c5 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 @@ -29,6 +29,7 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_mutation_observer_init.h" #include "third_party/blink/renderer/core/accessibility/ax_object_cache.h" #include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/dom/events/simulated_click_options.h" #include "third_party/blink/renderer/core/dom/mutation_observer.h" #include "third_party/blink/renderer/core/dom/node_computed_style.h" #include "third_party/blink/renderer/core/dom/node_traversal.h" @@ -173,7 +174,8 @@ void HTMLOptionElement::setText(const String& text) { select->setSelectedIndex(old_selected_index); } -void HTMLOptionElement::AccessKeyAction(bool) { +void HTMLOptionElement::AccessKeyAction(SimulatedClickCreationScope) { + // TODO(crbug.com/1176745): why creation_scope arg is not used at all? if (HTMLSelectElement* select = OwnerSelectElement()) select->SelectOptionByAccessKey(this); } 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 78a6f792afb..43c7f9df8ca 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 @@ -26,6 +26,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_HTML_OPTION_ELEMENT_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/html/html_element.h" namespace blink { @@ -54,6 +55,7 @@ class CORE_EXPORT HTMLOptionElement final : public HTMLElement { ExceptionState&); explicit HTMLOptionElement(Document&); + ~HTMLOptionElement() override; void Trace(Visitor* visitor) const override; // A text to be shown to users. The difference from |label()| is |label()| @@ -112,13 +114,11 @@ class CORE_EXPORT HTMLOptionElement final : public HTMLElement { void DidChangeTextContent(); private: - ~HTMLOptionElement() override; - bool SupportsFocus() const override; bool MatchesDefaultPseudoClass() const override; bool MatchesEnabledPseudoClass() const override; void ParseAttribute(const AttributeModificationParams&) override; - void AccessKeyAction(bool) override; + void AccessKeyAction(SimulatedClickCreationScope) override; void ChildrenChanged(const ChildrenChange&) 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 87e0b394958..4c2afcc1526 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 @@ -40,6 +40,7 @@ #include "third_party/blink/renderer/core/dom/attribute.h" #include "third_party/blink/renderer/core/dom/element_traversal.h" #include "third_party/blink/renderer/core/dom/events/scoped_event_queue.h" +#include "third_party/blink/renderer/core/dom/events/simulated_click_options.h" #include "third_party/blink/renderer/core/dom/node_computed_style.h" #include "third_party/blink/renderer/core/dom/node_lists_node_data.h" #include "third_party/blink/renderer/core/dom/node_traversal.h" @@ -391,10 +392,10 @@ void HTMLSelectElement::OptionElementChildrenChanged( } } -void HTMLSelectElement::AccessKeyAction(bool send_mouse_events) { +void HTMLSelectElement::AccessKeyAction( + SimulatedClickCreationScope creation_scope) { focus(); - DispatchSimulatedClick( - nullptr, send_mouse_events ? kSendMouseUpDownEvents : kSendNoEvents); + DispatchSimulatedClick(nullptr, creation_scope); } Element* HTMLSelectElement::namedItem(const AtomicString& name) { @@ -436,6 +437,8 @@ void HTMLSelectElement::SetOption(unsigned index, // Finally add the new element. EventQueueScope scope; add(element, before, exception_state); + if (exception_state.HadException()) + return; if (diff >= 0 && option->Selected()) OptionSelectionStateChanged(option, true); } @@ -709,8 +712,7 @@ void HTMLSelectElement::ChildrenChanged(const ChildrenChange& change) { OptionRemoved(child_option); } } else if (change.type == ChildrenChangeType::kAllChildrenRemoved) { - DCHECK(change.removed_nodes); - for (Node* node : *change.removed_nodes) { + for (Node* node : change.removed_nodes) { if (auto* option = DynamicTo<HTMLOptionElement>(node)) { OptionRemoved(*option); } else if (auto* optgroup = DynamicTo<HTMLOptGroupElement>(node)) { @@ -1109,7 +1111,7 @@ void HTMLSelectElement::TypeAheadFind(const KeyboardEvent& event) { void HTMLSelectElement::SelectOptionByAccessKey(HTMLOptionElement* option) { // First bring into focus the list box. if (!IsFocused()) - AccessKeyAction(false); + AccessKeyAction(SimulatedClickCreationScope::kFromUserAgent); if (!option || option->OwnerSelectElement() != this) return; 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 b9b87282849..807f104b7bf 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 @@ -30,6 +30,7 @@ #include "base/gtest_prod_util.h" #include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.h" #include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/dom/events/simulated_click_options.h" #include "third_party/blink/renderer/core/html/forms/html_form_control_element_with_state.h" #include "third_party/blink/renderer/core/html/forms/html_options_collection.h" #include "third_party/blink/renderer/core/html/forms/option_list.h" @@ -115,7 +116,7 @@ class CORE_EXPORT HTMLSelectElement final // We prefer |optionList()| to |listItems()|. const ListItems& GetListItems() const; - void AccessKeyAction(bool send_mouse_events) override; + void AccessKeyAction(SimulatedClickCreationScope creation_scope) override; void SelectOptionByAccessKey(HTMLOptionElement*); void SetOption(unsigned index, HTMLOptionElement*, ExceptionState&); diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_select_menu_element.cc b/chromium/third_party/blink/renderer/core/html/forms/html_select_menu_element.cc new file mode 100644 index 00000000000..de7842ab649 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/forms/html_select_menu_element.cc @@ -0,0 +1,348 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/html/forms/html_select_menu_element.h" + +#include "third_party/blink/renderer/core/dom/events/event.h" +#include "third_party/blink/renderer/core/dom/flat_tree_traversal.h" +#include "third_party/blink/renderer/core/dom/shadow_root.h" +#include "third_party/blink/renderer/core/dom/text.h" +#include "third_party/blink/renderer/core/frame/web_feature.h" +#include "third_party/blink/renderer/core/html/forms/html_button_element.h" +#include "third_party/blink/renderer/core/html/html_div_element.h" +#include "third_party/blink/renderer/core/html/html_popup_element.h" +#include "third_party/blink/renderer/core/html/html_slot_element.h" +#include "third_party/blink/renderer/core/inspector/console_message.h" +#include "third_party/blink/renderer/platform/instrumentation/use_counter.h" + +namespace blink { + +HTMLSelectMenuElement::HTMLSelectMenuElement(Document& document) + : HTMLElement(html_names::kSelectmenuTag, document) { + DCHECK(RuntimeEnabledFeatures::HTMLSelectMenuElementEnabled()); + DCHECK(RuntimeEnabledFeatures::HTMLPopupElementEnabled()); + UseCounter::Count(document, WebFeature::kSelectMenuElement); + + // TODO(crbug.com/1121840) This should really be a user-agent shadow root. + // But, these don't support name-based assignment (see + // ShouldAssignToCustomSlot). Perhaps names-based slot assignment can be added + // to user-agent shadows? See crbug.com/1179356. + AttachShadowRootInternal(ShadowRootType::kClosed); + + CreateShadowSubtree(); +} + +void HTMLSelectMenuElement::CreateShadowSubtree() { + DCHECK(IsShadowHost(this)); + + Document& document = this->GetDocument(); + + // TODO(crbug.com/1121840) Where to put the styles for the default elements in + // the shadow tree? We'd like to have them in the UA styles (html.css), but + // the -webkit pseudo-id selectors only work if this is a UA shadow DOM. We + // can't use a UA shadow DOMs because these don't currently support named + // slots. For now, just set the style attributes with raw inline strings, but + // we should be able to do something better than this. Probably the solution + // is to get named slots working in UA shadow DOM (crbug.com/1179356), and + // then we can switch to that and use the -webkit pseudo-id selectors. + + auto* button_slot = MakeGarbageCollected<HTMLSlotElement>(document); + slotchange_listener_ = + MakeGarbageCollected<HTMLSelectMenuElement::SlotChangeEventListener>( + this); + button_slot->addEventListener(event_type_names::kSlotchange, + slotchange_listener_, false); + button_slot->setAttribute(html_names::kNameAttr, kButtonPartName); + + button_part_ = MakeGarbageCollected<HTMLButtonElement>(document); + button_part_->setAttribute(html_names::kPartAttr, kButtonPartName); + button_part_->setAttribute(html_names::kStyleAttr, + R"CSS( + display: inline-flex; + align-items: center; + background-color: #ffffff; + padding: 0 0 0 3px; + border: 1px solid #767676; + border-radius: 2px; + cursor: default; + )CSS"); + button_part_listener_ = + MakeGarbageCollected<HTMLSelectMenuElement::ButtonPartEventListener>( + this); + button_part_->addEventListener(event_type_names::kClick, + button_part_listener_, false); + + selected_value_part_ = MakeGarbageCollected<HTMLDivElement>(document); + selected_value_part_->setAttribute(html_names::kPartAttr, + kSelectedValuePartName); + + auto* button_icon = MakeGarbageCollected<HTMLDivElement>(document); + button_icon->setAttribute(html_names::kStyleAttr, + R"CSS( + background-image: url( + 'data:image/svg+xml,\ + <svg width="20" height="14" viewBox="0 0 20 16" fill="none" xmlns="http://www.w3.org/2000/svg">\ + <path d="M4 6 L10 12 L 16 6" stroke="WindowText" stroke-width="3" stroke-linejoin="round"/>\ + </svg>'); + background-origin: content-box; + background-repeat: no-repeat; + background-size: contain; + height: 1.0em; + margin-inline-start: 4px; + opacity: 1; + outline: none; + padding-bottom: 2px; + padding-inline-start: 3px; + padding-inline-end: 3px; + padding-top: 2px; + width: 1.2em; + )CSS"); + + auto* listbox_slot = MakeGarbageCollected<HTMLSlotElement>(document); + listbox_slot->addEventListener(event_type_names::kSlotchange, + slotchange_listener_, false); + listbox_slot->setAttribute(html_names::kNameAttr, kListboxPartName); + + listbox_part_ = MakeGarbageCollected<HTMLPopupElement>(document); + listbox_part_->setAttribute(html_names::kPartAttr, kListboxPartName); + + auto* options_slot = MakeGarbageCollected<HTMLSlotElement>(document); + options_slot->addEventListener(event_type_names::kSlotchange, + slotchange_listener_, false); + + button_part_->AppendChild(selected_value_part_); + button_part_->AppendChild(button_icon); + + button_slot->AppendChild(button_part_); + + listbox_part_->appendChild(options_slot); + listbox_slot->appendChild(listbox_part_); + + this->GetShadowRoot()->AppendChild(button_slot); + this->GetShadowRoot()->AppendChild(listbox_slot); + + option_part_listener_ = + MakeGarbageCollected<HTMLSelectMenuElement::OptionPartEventListener>( + this); +} + +String HTMLSelectMenuElement::value() const { + if (selected_option_) { + return selected_option_->innerText(); + } + return ""; +} + +void HTMLSelectMenuElement::setValue(const String& value, bool send_events) { + // Find the option with innerText matching the given parameter and make it the + // current selection. + for (auto& option : option_parts_) { + if (option->innerText() == value) { + SetSelectedOption(option); + break; + } + } +} + +bool HTMLSelectMenuElement::IsOpen() const { + // TODO(crbug.com/1121840) listbox_part_ can be null if + // the author has filled the listbox slot without including + // a replacement listbox part. Instead of null checks like this, + // we should consider refusing to render the control at all if + // either of the key parts (button or listbox) are missing. + return listbox_part_ != nullptr && listbox_part_->open(); +} + +void HTMLSelectMenuElement::Open() { + if (listbox_part_ != nullptr && !IsOpen()) { + listbox_part_->show(); + } +} + +void HTMLSelectMenuElement::Close() { + if (listbox_part_ != nullptr && IsOpen()) { + listbox_part_->hide(); + } +} + +void HTMLSelectMenuElement::UpdatePartElements() { + Element* new_button_part = nullptr; + Element* new_selected_value_part = nullptr; + HTMLPopupElement* new_listbox_part = nullptr; + HeapLinkedHashSet<Member<Element>> new_option_parts; + + for (Node* node = FlatTreeTraversal::FirstChild(*this); node != nullptr; + node = FlatTreeTraversal::Next(*node, this)) { + // For all part types, if there are multiple candidates, choose the + // one that comes first in the flat tree traversal. + + auto* element = DynamicTo<Element>(node); + if (element == nullptr) { + continue; + } + + if (new_button_part == nullptr && + element->getAttribute(html_names::kPartAttr) == kButtonPartName) { + new_button_part = element; + } + + if (new_selected_value_part == nullptr && + element->getAttribute(html_names::kPartAttr) == + kSelectedValuePartName) { + new_selected_value_part = element; + } + + if (new_listbox_part == nullptr && + element->getAttribute(html_names::kPartAttr) == kListboxPartName) { + // TODO(crbug.com/1121840) Should we allow non-<popup> elements to be + // the listbox part? If so, how to manage open/closed state? + if (auto* popup_element = DynamicTo<HTMLPopupElement>(element)) { + new_listbox_part = popup_element; + } else { + GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( + mojom::blink::ConsoleMessageSource::kRendering, + mojom::blink::ConsoleMessageLevel::kWarning, + "Found non-<popup> element labeled as listbox under <selectmenu>, " + "but only a <popup> can be used for the <selectmenu>'s listbox " + "part.")); + } + } + + // The fact that this comes after the clauses for other parts + // means that an <option> element labeled as another part will + // be handled as the other part type. E.g. <option part="button"> + // will be treated as a button. + // TODO(crbug.com/1121840) Only include options that are inside the + // listbox, or allow them to be anywhere in the <selectmenu>? + if (element->getAttribute(html_names::kPartAttr) == kOptionPartName || + IsA<HTMLOptionElement>(element)) { + new_option_parts.insert(element); + } + } + + if (button_part_ != new_button_part) { + if (button_part_) { + button_part_->removeEventListener(event_type_names::kClick, + button_part_listener_, false); + } + if (new_button_part) { + new_button_part->addEventListener(event_type_names::kClick, + button_part_listener_, false); + } + button_part_ = new_button_part; + } + + selected_value_part_ = new_selected_value_part; + + listbox_part_ = new_listbox_part; + + bool updateSelectedOption = false; + for (auto& option : option_parts_) { + if (!new_option_parts.Contains(option)) { + option->removeEventListener(event_type_names::kClick, + option_part_listener_, false); + + if (option == selected_option_) { + updateSelectedOption = true; + } + + // TODO(crbug.com/1121840) Whenever we figure out how to set + // focusability properly (without using tabIndex), we should undo up + // those changes here for elements that are no longer option parts. + } + } + + for (auto& option : new_option_parts) { + if (!option_parts_.Contains(option)) { + option->addEventListener(event_type_names::kClick, option_part_listener_, + false); + + // TODO(crbug.com/1121840) We don't want to actually change the attribute, + // and if tabindex is already set we shouldn't override it. So we need to + // come up with something else here. + option->setTabIndex(-1); + } + } + + option_parts_ = new_option_parts; + if (updateSelectedOption || selected_option_ == nullptr) { + // If the currently selected option was removed, or if + // we didn't have a selected option previously, change the + // selection to the first option part, if there is one. + SetSelectedOption(option_parts_.size() > 0 ? option_parts_.front() + : nullptr); + } +} + +void HTMLSelectMenuElement::SetSelectedOption(Element* selected_option) { + if (selected_option_ == selected_option) + return; + + selected_option_ = selected_option; + UpdateSelectedValuePartContents(); +} + +void HTMLSelectMenuElement::UpdateSelectedValuePartContents() { + // Null-check here because the selected-value part is optional; the author + // might replace the button contents and not provide a selected-value part if + // they want to show something in the button other than the current value of + // the <selectmenu>. + if (selected_value_part_) { + selected_value_part_->setTextContent( + selected_option_ ? selected_option_->innerText() : ""); + } +} + +void HTMLSelectMenuElement::ButtonPartEventListener::Invoke(ExecutionContext*, + Event* event) { + if (event->type() == event_type_names::kClick && + !select_menu_element_->IsOpen()) { + select_menu_element_->Open(); + } +} + +void HTMLSelectMenuElement::OptionPartEventListener::Invoke(ExecutionContext*, + Event* event) { + if (event->type() == event_type_names::kClick) { + Element* target_element = + DynamicTo<Element>(event->currentTarget()->ToNode()); + DCHECK(target_element); + DCHECK(select_menu_element_->option_parts_.Contains(target_element)); + select_menu_element_->SetSelectedOption(target_element); + select_menu_element_->listbox_part_->hide(); + } +} + +void HTMLSelectMenuElement::SlotChangeEventListener::Invoke(ExecutionContext*, + Event* event) { + DCHECK_EQ(event->type(), event_type_names::kSlotchange); + // TODO(crbug.com/1121840) Slotchange doesn't fire when + // the children of slotted content change, so it isn't + // enough to do this here. We might need to set up mutation observers + // or something to watch for changes in addition or instead of the + // slotchange event. + // Also, if we want to match the select behavior, then we should be + // doing this update synchronously. See failing tests in + // external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-value.html + select_menu_element_->UpdatePartElements(); +} + +void HTMLSelectMenuElement::Trace(Visitor* visitor) const { + visitor->Trace(button_part_listener_); + visitor->Trace(option_part_listener_); + visitor->Trace(slotchange_listener_); + visitor->Trace(button_part_); + visitor->Trace(selected_value_part_); + visitor->Trace(listbox_part_); + visitor->Trace(option_parts_); + visitor->Trace(selected_option_); + HTMLElement::Trace(visitor); +} + +constexpr char HTMLSelectMenuElement::kButtonPartName[]; +constexpr char HTMLSelectMenuElement::kSelectedValuePartName[]; +constexpr char HTMLSelectMenuElement::kListboxPartName[]; +constexpr char HTMLSelectMenuElement::kOptionPartName[]; + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_select_menu_element.h b/chromium/third_party/blink/renderer/core/html/forms/html_select_menu_element.h new file mode 100644 index 00000000000..aa5d320997b --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/forms/html_select_menu_element.h @@ -0,0 +1,107 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_HTML_SELECT_MENU_ELEMENT_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_HTML_SELECT_MENU_ELEMENT_H_ + +#include "third_party/blink/renderer/core/dom/events/native_event_listener.h" +#include "third_party/blink/renderer/core/html/html_element.h" + +namespace blink { + +class Document; + +// The HTMLSelectMenuElement implements the <selectmenu> HTML element. +// The <selectmenu> element is similar to <select>, but allows site authors +// freedom to customize the element's appearance and shadow DOM structure. +// This feature is still under development, and is not part of the HTML +// standard. It can be enabled by passing +// --enable-blink-features=HTMLSelectMenuElement. See +// https://groups.google.com/u/1/a/chromium.org/g/blink-dev/c/9TcfjaOs5zg/m/WAiv6WpUAAAJ +// for more details. +class HTMLSelectMenuElement final : public HTMLElement { + DEFINE_WRAPPERTYPEINFO(); + + public: + explicit HTMLSelectMenuElement(Document&); + + String value() const; + void setValue(const String&, bool send_events = false); + + bool IsOpen() const; + + void Trace(Visitor*) const override; + + private: + void CreateShadowSubtree(); + void Open(); + void Close(); + void UpdatePartElements(); + void SetSelectedOption(Element* selected_option); + void UpdateSelectedValuePartContents(); + + class ButtonPartEventListener : public NativeEventListener { + public: + explicit ButtonPartEventListener(HTMLSelectMenuElement* select_menu_element) + : select_menu_element_(select_menu_element) {} + void Invoke(ExecutionContext*, Event*) override; + + void Trace(Visitor* visitor) const override { + visitor->Trace(select_menu_element_); + NativeEventListener::Trace(visitor); + } + + private: + Member<HTMLSelectMenuElement> select_menu_element_; + }; + + class OptionPartEventListener : public NativeEventListener { + public: + explicit OptionPartEventListener(HTMLSelectMenuElement* select_menu_element) + : select_menu_element_(select_menu_element) {} + void Invoke(ExecutionContext*, Event*) override; + + void Trace(Visitor* visitor) const override { + visitor->Trace(select_menu_element_); + NativeEventListener::Trace(visitor); + } + + private: + Member<HTMLSelectMenuElement> select_menu_element_; + }; + + class SlotChangeEventListener : public NativeEventListener { + public: + explicit SlotChangeEventListener(HTMLSelectMenuElement* select_menu_element) + : select_menu_element_(select_menu_element) {} + void Invoke(ExecutionContext*, Event*) override; + + void Trace(Visitor* visitor) const override { + visitor->Trace(select_menu_element_); + NativeEventListener::Trace(visitor); + } + + private: + Member<HTMLSelectMenuElement> select_menu_element_; + }; + + static constexpr char kButtonPartName[] = "button"; + static constexpr char kSelectedValuePartName[] = "selected-value"; + static constexpr char kListboxPartName[] = "listbox"; + static constexpr char kOptionPartName[] = "option"; + + Member<ButtonPartEventListener> button_part_listener_; + Member<OptionPartEventListener> option_part_listener_; + Member<SlotChangeEventListener> slotchange_listener_; + + Member<Element> button_part_; + Member<Element> selected_value_part_; + Member<HTMLPopupElement> listbox_part_; + HeapLinkedHashSet<Member<Element>> option_parts_; + Member<Element> selected_option_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_HTML_SELECT_MENU_ELEMENT_H_ diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_select_menu_element.idl b/chromium/third_party/blink/renderer/core/html/forms/html_select_menu_element.idl new file mode 100644 index 00000000000..b11883770f7 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/forms/html_select_menu_element.idl @@ -0,0 +1,12 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +[Exposed=Window,HTMLConstructor,RuntimeEnabled=HTMLSelectMenuElement] +interface HTMLSelectMenuElement : HTMLElement { + attribute DOMString value; + // TODO(crbug.com/1121840) Fill this out. + // Open question: do we want to replicate the interface of + // <select> as closely as possible? + // Or should we try to improve, simplify, or extend it? +}; 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 7cdf765f11f..0d857bc97f2 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 @@ -32,6 +32,7 @@ #include "third_party/blink/renderer/core/css_value_keywords.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/events/event.h" +#include "third_party/blink/renderer/core/dom/events/simulated_click_options.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/frame_selection.h" @@ -357,7 +358,7 @@ void HTMLTextAreaElement::SubtreeHasChanged() { // When typing in a textarea, childrenChanged is not called, so we need to // force the directionality check. - CalculateAndAdjustDirectionality(); + CalculateAndAdjustAutoDirectionality(this); DCHECK(GetDocument().IsActive()); GetDocument().GetPage()->GetChromeClient().DidChangeValueInTextField(*this); @@ -617,7 +618,7 @@ bool HTMLTextAreaElement::IsValidValue(const String& candidate) const { !TooShort(&candidate, kIgnoreDirtyFlag); } -void HTMLTextAreaElement::AccessKeyAction(bool) { +void HTMLTextAreaElement::AccessKeyAction(SimulatedClickCreationScope) { focus(); } @@ -646,6 +647,7 @@ void HTMLTextAreaElement::SetPlaceholderVisibility(bool visible) { void HTMLTextAreaElement::UpdatePlaceholderText() { HTMLElement* placeholder = PlaceholderElement(); const String placeholder_text = GetPlaceholderValue(); + const bool is_suggested_value = !SuggestedValue().IsEmpty(); if (placeholder_text.IsEmpty()) { if (placeholder) UserAgentShadowRoot()->RemoveChild(placeholder); @@ -662,6 +664,12 @@ void HTMLTextAreaElement::UpdatePlaceholderText() { IsPlaceholderVisible() ? CSSValueID::kBlock : CSSValueID::kNone, true); UserAgentShadowRoot()->InsertBefore(placeholder, InnerEditorElement()); } + if (is_suggested_value) { + placeholder->SetInlineStyleProperty(CSSPropertyID::kUserSelect, + CSSValueID::kNone, true); + } else { + placeholder->RemoveInlineStyleProperty(CSSPropertyID::kUserSelect); + } String normalized_value = placeholder_text; // https://html.spec.whatwg.org/multipage/form-elements.html#attr-textarea-placeholder ReplaceCRWithNewLine(normalized_value); 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 e518140906a..bb301489f2b 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 @@ -26,6 +26,7 @@ #include "base/gtest_prod_util.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/html/forms/text_control_element.h" namespace blink { @@ -128,7 +129,7 @@ class CORE_EXPORT HTMLTextAreaElement final : public TextControlElement { void UpdateFocusAppearanceWithOptions(SelectionBehaviorOnFocus, const FocusOptions*) override; - void AccessKeyAction(bool send_mouse_events) override; + void AccessKeyAction(SimulatedClickCreationScope creation_scope) override; bool MatchesReadOnlyPseudoClass() const override; bool MatchesReadWritePseudoClass() const 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 bf5ba5db832..6e5c35bab3b 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 @@ -188,7 +188,7 @@ unsigned ImageInputType::Height() const { HTMLImageLoader* image_loader = GetElement().ImageLoader(); if (image_loader && image_loader->GetContent()) { return image_loader->GetContent() - ->IntrinsicSize(LayoutObject::ShouldRespectImageOrientation(nullptr)) + ->IntrinsicSize(kRespectImageOrientation) .Height(); } } @@ -214,7 +214,7 @@ unsigned ImageInputType::Width() const { HTMLImageLoader* image_loader = GetElement().ImageLoader(); if (image_loader && image_loader->GetContent()) { return image_loader->GetContent() - ->IntrinsicSize(LayoutObject::ShouldRespectImageOrientation(nullptr)) + ->IntrinsicSize(kRespectImageOrientation) .Width(); } } 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 8819c8304c4..25d3b0a20c7 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 @@ -28,6 +28,7 @@ #include "third_party/blink/renderer/core/html/forms/input_type_view.h" +#include "third_party/blink/renderer/core/dom/events/simulated_click_options.h" #include "third_party/blink/renderer/core/dom/focus_params.h" #include "third_party/blink/renderer/core/dom/node_computed_style.h" #include "third_party/blink/renderer/core/dom/shadow_root.h" @@ -77,7 +78,7 @@ void InputTypeView::DispatchSimulatedClickIfActive(KeyboardEvent& event) const { event.SetDefaultHandled(); } -void InputTypeView::AccessKeyAction(bool) { +void InputTypeView::AccessKeyAction(SimulatedClickCreationScope) { GetElement().focus(FocusParams(SelectionBehaviorOnFocus::kReset, mojom::blink::FocusType::kNone, nullptr)); } @@ -188,7 +189,7 @@ bool InputTypeView::ShouldDrawCapsLockIndicator() const { void InputTypeView::UpdateClearButtonVisibility() {} -void InputTypeView::UpdatePlaceholderText() {} +void InputTypeView::UpdatePlaceholderText(bool) {} AXObject* InputTypeView::PopupRootAXObject() { return nullptr; @@ -202,7 +203,8 @@ FormControlState InputTypeView::SaveFormControlState() const { } void InputTypeView::RestoreFormControlState(const FormControlState& state) { - GetElement().setValue(state[0]); + GetElement().setValue(state[0], + TextFieldEventBehavior::kDispatchInputAndChangeEvent); } bool InputTypeView::IsDraggedSlider() const { 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 f2a5ed488ab..ebe7aaa1d08 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 @@ -37,6 +37,7 @@ #include "third_party/blink/public/mojom/input/focus_type.mojom-blink-forward.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/dom/events/event_dispatcher.h" +#include "third_party/blink/renderer/core/dom/events/simulated_click_options.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/text/text_direction.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" @@ -98,7 +99,7 @@ class CORE_EXPORT InputTypeView : public GarbageCollectedMixin { mojom::blink::FocusType); virtual void HandleBlurEvent(); virtual void HandleDOMActivateEvent(Event&); - virtual void AccessKeyAction(bool send_mouse_events); + virtual void AccessKeyAction(SimulatedClickCreationScope creation_scope); virtual void Blur(); void DispatchSimulatedClickIfActive(KeyboardEvent&) const; @@ -135,7 +136,7 @@ class CORE_EXPORT InputTypeView : public GarbageCollectedMixin { virtual void CapsLockStateMayHaveChanged(); virtual bool ShouldDrawCapsLockIndicator() const; virtual void UpdateClearButtonVisibility(); - virtual void UpdatePlaceholderText(); + virtual void UpdatePlaceholderText(bool is_suggested_value); virtual AXObject* PopupRootAXObject(); virtual void EnsureFallbackContent() {} virtual void EnsurePrimaryContent() {} diff --git a/chromium/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc b/chromium/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc index ec97640e577..b3a13907d2d 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc @@ -87,10 +87,11 @@ scoped_refptr<const ComputedStyle> StyleForHoveredScrollbarPart( if (part == kNoPart) return nullptr; scrollbar->SetHoveredPart(part); - scoped_refptr<const ComputedStyle> part_style = element.StyleForPseudoElement( - PseudoElementStyleRequest(target_id, To<CustomScrollbar>(scrollbar), - part), - style); + scoped_refptr<const ComputedStyle> part_style = + element.UncachedStyleForPseudoElement( + PseudoElementStyleRequest(target_id, To<CustomScrollbar>(scrollbar), + part), + style); return part_style; } @@ -99,7 +100,7 @@ scoped_refptr<const ComputedStyle> StyleForHoveredScrollbarPart( class PopupMenuCSSFontSelector : public CSSFontSelector, private FontSelectorClient { public: - PopupMenuCSSFontSelector(Document*, CSSFontSelector*); + PopupMenuCSSFontSelector(Document&, CSSFontSelector*); ~PopupMenuCSSFontSelector() override; // We don't override willUseFontData() for now because the old PopupListBox @@ -116,7 +117,7 @@ class PopupMenuCSSFontSelector : public CSSFontSelector, }; PopupMenuCSSFontSelector::PopupMenuCSSFontSelector( - Document* document, + Document& document, CSSFontSelector* owner_font_selector) : CSSFontSelector(document), owner_font_selector_(owner_font_selector) { owner_font_selector_->RegisterForInvalidationCallbacks(this); @@ -492,11 +493,11 @@ void InternalPopupMenu::AppendOwnerElementPseudoStyles( PagePopupClient::AddString(target + "{ \n", data); const CSSPropertyID serialize_targets[] = { - CSSPropertyID::kDisplay, CSSPropertyID::kBackgroundColor, - CSSPropertyID::kWidth, CSSPropertyID::kBorderBottom, - CSSPropertyID::kBorderLeft, CSSPropertyID::kBorderRight, - CSSPropertyID::kBorderTop, CSSPropertyID::kBorderRadius, - CSSPropertyID::kBoxShadow}; + CSSPropertyID::kDisplay, CSSPropertyID::kBackgroundColor, + CSSPropertyID::kWidth, CSSPropertyID::kBorderBottom, + CSSPropertyID::kBorderLeft, CSSPropertyID::kBorderRight, + CSSPropertyID::kBorderTop, CSSPropertyID::kBorderRadius, + CSSPropertyID::kBackgroundClip, CSSPropertyID::kBoxShadow}; for (CSSPropertyID id : serialize_targets) { PagePopupClient::AddString(SerializeComputedStyleForProperty(style, id), @@ -510,7 +511,7 @@ CSSFontSelector* InternalPopupMenu::CreateCSSFontSelector( Document& popup_document) { Document& owner_document = OwnerElement().GetDocument(); return MakeGarbageCollected<PopupMenuCSSFontSelector>( - &popup_document, owner_document.GetStyleEngine().GetFontSelector()); + popup_document, owner_document.GetStyleEngine().GetFontSelector()); } void InternalPopupMenu::SetValueAndClosePopup(int num_value, 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 ba8e4bb19f8..2392c425f74 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 @@ -31,6 +31,7 @@ #include "third_party/blink/renderer/core/html/forms/keyboard_clickable_input_type_view.h" +#include "third_party/blink/renderer/core/dom/events/simulated_click_options.h" #include "third_party/blink/renderer/core/events/keyboard_event.h" #include "third_party/blink/renderer/core/html/forms/html_input_element.h" @@ -67,10 +68,10 @@ void KeyboardClickableInputTypeView::HandleKeyupEvent(KeyboardEvent& event) { // FIXME: Could share this with BaseCheckableInputType and RangeInputType if we // had a common base class. -void KeyboardClickableInputTypeView::AccessKeyAction(bool send_mouse_events) { - InputTypeView::AccessKeyAction(send_mouse_events); - GetElement().DispatchSimulatedClick( - nullptr, send_mouse_events ? kSendMouseUpDownEvents : kSendNoEvents); +void KeyboardClickableInputTypeView::AccessKeyAction( + SimulatedClickCreationScope creation_scope) { + InputTypeView::AccessKeyAction(creation_scope); + GetElement().DispatchSimulatedClick(nullptr, creation_scope); } } // namespace blink 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 4fd91a6a78f..e01fe106f07 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 @@ -32,6 +32,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_KEYBOARD_CLICKABLE_INPUT_TYPE_VIEW_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/html/forms/input_type_view.h" namespace blink { @@ -46,7 +47,7 @@ class CORE_EXPORT KeyboardClickableInputTypeView : public InputTypeView { void HandleKeydownEvent(KeyboardEvent&) override; void HandleKeypressEvent(KeyboardEvent&) override; void HandleKeyupEvent(KeyboardEvent&) override; - void AccessKeyAction(bool send_mouse_events) override; + void AccessKeyAction(SimulatedClickCreationScope creation_scope) override; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/forms/menu_list_inner_element.cc b/chromium/third_party/blink/renderer/core/html/forms/menu_list_inner_element.cc index f96b288b259..90e3bcb8088 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/menu_list_inner_element.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/menu_list_inner_element.cc @@ -16,8 +16,8 @@ MenuListInnerElement::MenuListInnerElement(Document& document) SetHasCustomStyleCallbacks(); } -scoped_refptr<ComputedStyle> -MenuListInnerElement::CustomStyleForLayoutObject() { +scoped_refptr<ComputedStyle> MenuListInnerElement::CustomStyleForLayoutObject( + const StyleRecalcContext& style_recalc_context) { const ComputedStyle& parent_style = OwnerShadowHost()->ComputedStyleRef(); scoped_refptr<ComputedStyle> style = ComputedStyle::CreateAnonymousStyleWithDisplay(parent_style, diff --git a/chromium/third_party/blink/renderer/core/html/forms/menu_list_inner_element.h b/chromium/third_party/blink/renderer/core/html/forms/menu_list_inner_element.h index b3f7085cb59..0d8317af9c5 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/menu_list_inner_element.h +++ b/chromium/third_party/blink/renderer/core/html/forms/menu_list_inner_element.h @@ -14,7 +14,8 @@ class MenuListInnerElement : public HTMLDivElement { explicit MenuListInnerElement(Document& document); private: - scoped_refptr<ComputedStyle> CustomStyleForLayoutObject() override; + scoped_refptr<ComputedStyle> CustomStyleForLayoutObject( + const StyleRecalcContext&) override; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/forms/password_input_type_test.cc b/chromium/third_party/blink/renderer/core/html/forms/password_input_type_test.cc index 2ac6e83e0e6..1c2f3389f3e 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/password_input_type_test.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/password_input_type_test.cc @@ -71,8 +71,8 @@ TEST(PasswordInputTypeTest, DidEditFieldEvent) { TEST(PasswordInputTypeTest, DidEditFieldEventNotSentFromSecureContext) { auto page_holder = std::make_unique<DummyPageHolder>(IntSize(2000, 2000)); page_holder->GetFrame().Loader().CommitNavigation( - WebNavigationParams::CreateWithHTMLBuffer(SharedBuffer::Create(), - KURL("https://example.test")), + WebNavigationParams::CreateWithHTMLBufferForTesting( + SharedBuffer::Create(), KURL("https://example.test")), nullptr /* extra_data */); blink::test::RunPendingTasks(); MockInsecureInputService mock_service(page_holder->GetFrame()); diff --git a/chromium/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc b/chromium/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc index 1cdacdcbfab..2a4bbe5c47c 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc @@ -163,14 +163,6 @@ void RadioButtonGroup::Remove(HTMLInputElement* button) { // valid only if the group was invalid. button->SetNeedsValidityCheck(); } - - // Send notification to update AX attributes for AXObjects which radiobutton - // group has. - if (!members_.IsEmpty()) { - HTMLInputElement* input = members_.begin()->key; - if (AXObjectCache* cache = input->GetDocument().ExistingAXObjectCache()) - cache->RadiobuttonRemovedFromGroup(input); - } } void RadioButtonGroup::SetNeedsValidityCheckForAllButtons() { 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 c8b4880ee6a..0514ac5b6d8 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 @@ -158,7 +158,7 @@ void RadioInputType::HandleKeydownEvent(KeyboardEvent& event) { document.SetFocusedElement( input_element, FocusParams(SelectionBehaviorOnFocus::kRestore, mojom::blink::FocusType::kNone, nullptr)); - input_element->DispatchSimulatedClick(&event, kSendNoEvents); + input_element->DispatchSimulatedClick(&event); event.SetDefaultHandled(); return; } 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 5c3933f2150..f978b04e64b 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 @@ -36,6 +36,7 @@ #include "third_party/blink/renderer/core/accessibility/ax_object_cache.h" #include "third_party/blink/renderer/core/dom/events/scoped_event_queue.h" +#include "third_party/blink/renderer/core/dom/events/simulated_click_options.h" #include "third_party/blink/renderer/core/dom/node_computed_style.h" #include "third_party/blink/renderer/core/dom/shadow_root.h" #include "third_party/blink/renderer/core/events/keyboard_event.h" @@ -194,12 +195,8 @@ void RangeInputType::HandleKeydownEvent(KeyboardEvent& event) { std::max((step_range.Maximum() - step_range.Minimum()) / 10, step); TextDirection dir = TextDirection::kLtr; - bool is_vertical = false; if (GetElement().GetLayoutObject()) { dir = ComputedTextDirection(); - ControlPart part = - GetElement().GetLayoutObject()->Style()->EffectiveAppearance(); - is_vertical = part == kSliderVerticalPart; } Decimal new_value; @@ -208,19 +205,17 @@ void RangeInputType::HandleKeydownEvent(KeyboardEvent& event) { } else if (key == "ArrowDown") { new_value = current - step; } else if (key == "ArrowLeft") { - new_value = (is_vertical || dir == TextDirection::kRtl) ? current + step - : current - step; + new_value = dir == TextDirection::kRtl ? current + step : current - step; } else if (key == "ArrowRight") { - new_value = (is_vertical || dir == TextDirection::kRtl) ? current - step - : current + step; + new_value = dir == TextDirection::kRtl ? current - step : current + step; } else if (key == "PageUp") { new_value = current + big_step; } else if (key == "PageDown") { new_value = current - big_step; } else if (key == "Home") { - new_value = is_vertical ? step_range.Maximum() : step_range.Minimum(); + new_value = step_range.Minimum(); } else if (key == "End") { - new_value = is_vertical ? step_range.Minimum() : step_range.Maximum(); + new_value = step_range.Maximum(); } else { return; // Did not match any key binding. } @@ -255,14 +250,6 @@ void RangeInputType::CreateShadowSubtree() { GetElement().UserAgentShadowRoot()->AppendChild(container); } -bool RangeInputType::TypeShouldForceLegacyLayout() const { - if (RuntimeEnabledFeatures::LayoutNGForControlsEnabled()) - return false; - UseCounter::Count(GetElement().GetDocument(), - WebFeature::kLegacyLayoutBySlider); - return true; -} - LayoutObject* RangeInputType::CreateLayoutObject(const ComputedStyle& style, LegacyLayout legacy) const { // TODO(crbug.com/1131352): input[type=range] should not use @@ -283,11 +270,10 @@ String RangeInputType::Serialize(const Decimal& value) const { // FIXME: Could share this with KeyboardClickableInputTypeView and // BaseCheckableInputType if we had a common base class. -void RangeInputType::AccessKeyAction(bool send_mouse_events) { - InputTypeView::AccessKeyAction(send_mouse_events); - - GetElement().DispatchSimulatedClick( - nullptr, send_mouse_events ? kSendMouseUpDownEvents : kSendNoEvents); +void RangeInputType::AccessKeyAction( + SimulatedClickCreationScope creation_scope) { + InputTypeView::AccessKeyAction(creation_scope); + GetElement().DispatchSimulatedClick(nullptr, creation_scope); } void RangeInputType::SanitizeValueInResponseToMinOrMaxAttributeChange() { 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 0c22a327616..2dc25f5ee34 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 @@ -31,6 +31,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_RANGE_INPUT_TYPE_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_RANGE_INPUT_TYPE_H_ +#include "third_party/blink/renderer/core/dom/events/simulated_click_options.h" #include "third_party/blink/renderer/core/html/forms/input_type.h" #include "third_party/blink/renderer/core/html/forms/input_type_view.h" @@ -61,13 +62,12 @@ class RangeInputType final : public InputType, public InputTypeView { bool IsSteppable() const override; void HandleMouseDownEvent(MouseEvent&) override; void HandleKeydownEvent(KeyboardEvent&) override; - bool TypeShouldForceLegacyLayout() const override; LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) const override; void CreateShadowSubtree() override; Decimal ParseToNumber(const String&, const Decimal&) const override; String Serialize(const Decimal&) const override; - void AccessKeyAction(bool send_mouse_events) override; + void AccessKeyAction(SimulatedClickCreationScope creation_scope) override; void SanitizeValueInResponseToMinOrMaxAttributeChange() override; void StepAttributeChanged() override; void WarnIfValueIsInvalid(const String&) const override; diff --git a/chromium/third_party/blink/renderer/core/html/forms/resources/color_picker.css b/chromium/third_party/blink/renderer/core/html/forms/resources/color_picker.css index cb08889fcc1..401f06da483 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/resources/color_picker.css +++ b/chromium/third_party/blink/renderer/core/html/forms/resources/color_picker.css @@ -211,6 +211,14 @@ channel-label { format-toggler { border: 1px solid WindowText; } + format-toggler:hover, + input:hover { + border: 1px solid Highlight; + } + eye-dropper:hover { + border: 1px solid Highlight; + padding: 5px; + } } @media (prefers-color-scheme: dark) { diff --git a/chromium/third_party/blink/renderer/core/html/forms/resources/color_picker.js b/chromium/third_party/blink/renderer/core/html/forms/resources/color_picker.js index b3ee0ad7ae4..e076b6332e8 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/resources/color_picker.js +++ b/chromium/third_party/blink/renderer/core/html/forms/resources/color_picker.js @@ -1789,6 +1789,7 @@ class ChannelValueContainer extends HTMLInputElement { this.addEventListener('input', this.onValueChange_); this.addEventListener('blur', this.onBlur_); + this.addEventListener('focus', this.onFocus_); } get channelValue() { @@ -1851,13 +1852,12 @@ class ChannelValueContainer extends HTMLInputElement { if (value) { switch (this.colorChannel_) { case ColorChannel.HEX: - if (value.startsWith('#')) { + if (value.startsWith('#')) value = value.substr(1).toLowerCase(); - if (value.match(/^[0-9a-f]+$/)) { - // Ex. 'ffffff' => this.channelValue_ == 'ffffff' - // Ex. 'ff' => this.channelValue_ == '0000ff' - this.channelValue_ = ('000000' + value).slice(-6); - } + if (value.match(/^[0-9a-f]+$/)) { + // Ex. 'ffffff' => this.channelValue_ == 'ffffff' + // Ex. 'ff' => this.channelValue_ == '0000ff' + this.channelValue_ = ('000000' + value).slice(-6); } break; case ColorChannel.R: @@ -1874,11 +1874,10 @@ class ChannelValueContainer extends HTMLInputElement { break; case ColorChannel.S: case ColorChannel.L: - if (value.endsWith('%')) { + if (value.endsWith('%')) value = value.substring(0, value.length - 1); - if (value.match(/^\d+$/) && (0 <= value) && (value <= 100)) { - this.channelValue_ = Number(value); - } + if (value.match(/^\d+$/) && (0 <= value) && (value <= 100)) { + this.channelValue_ = Number(value); } break; } @@ -1909,6 +1908,10 @@ class ChannelValueContainer extends HTMLInputElement { break; } } + + onFocus_ = () => { + this.select(); + } } window.customElements.define( 'channel-value-container', ChannelValueContainer, {extends: 'input'}); diff --git a/chromium/third_party/blink/renderer/core/html/forms/resources/listPicker.js b/chromium/third_party/blink/renderer/core/html/forms/resources/listPicker.js index 1f936b10d3a..d292c47c997 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/resources/listPicker.js +++ b/chromium/third_party/blink/renderer/core/html/forms/resources/listPicker.js @@ -90,6 +90,7 @@ ListPicker.prototype._handleWindowMessage = function(event) { if (window.updateData.type === 'update') { this._config.baseStyle = window.updateData.baseStyle; this._config.children = window.updateData.children; + const prev_children_count = this._selectElement.children.length; this._update(); if (this._config.anchorRectInScreen.x !== window.updateData.anchorRectInScreen.x || @@ -98,9 +99,10 @@ ListPicker.prototype._handleWindowMessage = function(event) { this._config.anchorRectInScreen.width !== window.updateData.anchorRectInScreen.width || this._config.anchorRectInScreen.height !== - window.updateData.anchorRectInScreen.height) { - this._config.anchorRectInScreen = window.updateData.anchorRectInScreen; - this._fixWindowSize(); + window.updateData.anchorRectInScreen.height || + prev_children_count !== window.updateData.children.length) { + this._config.anchorRectInScreen = window.updateData.anchorRectInScreen; + this._fixWindowSize(); } } delete window.updateData; diff --git a/chromium/third_party/blink/renderer/core/html/forms/resources/validation_bubble.css b/chromium/third_party/blink/renderer/core/html/forms/resources/validation_bubble.css index 2403a75d86b..c923e021aa1 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/resources/validation_bubble.css +++ b/chromium/third_party/blink/renderer/core/html/forms/resources/validation_bubble.css @@ -134,6 +134,7 @@ grid-column: 2; margin-top: 3px; margin-bottom: 4px; + white-space: pre-line; } #sub-message { 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 e564c3261f6..914548d7304 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 @@ -162,4 +162,9 @@ bool SearchInputType::SupportsInputModeAttribute() const { return true; } +void SearchInputType::Trace(Visitor* visitor) const { + visitor->Trace(search_event_timer_); + BaseTextInputType::Trace(visitor); +} + } // namespace blink 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 dd1ff43512a..e9dccbf79ec 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 @@ -38,7 +38,9 @@ namespace blink { class SearchInputType final : public BaseTextInputType { public: - SearchInputType(HTMLInputElement&); + explicit SearchInputType(HTMLInputElement&); + + void Trace(Visitor*) const final; private: void CountUsage() override; @@ -56,7 +58,7 @@ class SearchInputType final : public BaseTextInputType { void StartSearchEventTimer(); void UpdateCancelButtonVisibility(); - TaskRunnerTimer<SearchInputType> search_event_timer_; + HeapTaskRunnerTimer<SearchInputType> search_event_timer_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/forms/select_type.cc b/chromium/third_party/blink/renderer/core/html/forms/select_type.cc index 2197db39872..3a02df56a8e 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/select_type.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/select_type.cc @@ -232,7 +232,7 @@ bool MenuListSelectType::DefaultEventHandler(const Event& event) { ->GetInputDeviceCapabilities() ->FiresTouchEvents(mouse_event->FromTouch()); select_->focus(FocusParams(SelectionBehaviorOnFocus::kRestore, - mojom::blink::FocusType::kNone, + mojom::blink::FocusType::kMouse, source_capabilities)); if (select_->GetLayoutObject() && !will_be_destroyed_ && !select_->IsDisabledFormControl()) { 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 8fbea89e7c5..21676c674ac 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 @@ -287,11 +287,13 @@ const AtomicString& SliderThumbElement::ShadowPseudoId() const { } } -scoped_refptr<ComputedStyle> SliderThumbElement::CustomStyleForLayoutObject() { +scoped_refptr<ComputedStyle> SliderThumbElement::CustomStyleForLayoutObject( + const StyleRecalcContext& style_recalc_context) { Element* host = OwnerShadowHost(); DCHECK(host); const ComputedStyle& host_style = host->ComputedStyleRef(); - scoped_refptr<ComputedStyle> style = OriginalStyleForLayoutObject(); + scoped_refptr<ComputedStyle> style = + OriginalStyleForLayoutObject(style_recalc_context); if (host_style.EffectiveAppearance() == kSliderVerticalPart) style->SetEffectiveAppearance(kSliderThumbVerticalPart); 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 069f438b7de..ff8635aacf2 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 @@ -63,7 +63,8 @@ class SliderThumbElement final : public HTMLDivElement { private: LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) override; - scoped_refptr<ComputedStyle> CustomStyleForLayoutObject() final; + scoped_refptr<ComputedStyle> CustomStyleForLayoutObject( + const StyleRecalcContext&) final; Element& CloneWithoutAttributesAndChildren(Document&) const override; bool IsDisabledFormControl() const override; bool MatchesReadOnlyPseudoClass() const 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 fe31397f04d..b70a2b407a0 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 @@ -223,6 +223,7 @@ bool SpinButtonElement::ShouldRespondToMouseEvents() { void SpinButtonElement::Trace(Visitor* visitor) const { visitor->Trace(spin_button_owner_); + visitor->Trace(repeating_timer_); HTMLDivElement::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/forms/spin_button_element.h b/chromium/third_party/blink/renderer/core/html/forms/spin_button_element.h index 482229a0f4c..b9828380e8b 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 @@ -95,7 +95,7 @@ class CORE_EXPORT SpinButtonElement final : public HTMLDivElement, bool capturing_; UpDownState up_down_state_; UpDownState press_starting_state_; - TaskRunnerTimer<SpinButtonElement> repeating_timer_; + HeapTaskRunnerTimer<SpinButtonElement> repeating_timer_; }; template <> 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 f06d2ab1bd7..4996197dee4 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 @@ -74,14 +74,13 @@ namespace { Position GetNextSoftBreak(const NGOffsetMapping& mapping, NGInlineCursor& cursor) { while (cursor) { - DCHECK(cursor.Current().IsLineBox()) << cursor.Current(); + DCHECK(cursor.Current().IsLineBox()) << cursor; const auto* break_token = cursor.Current().InlineBreakToken(); - DCHECK(break_token); cursor.MoveToNextLine(); // We don't need to emit a LF for the last line. if (!cursor) return Position(); - if (!break_token->IsForcedBreak()) + if (break_token && !break_token->IsForcedBreak()) return mapping.GetFirstPosition(break_token->TextOffset()); } return Position(); @@ -780,7 +779,7 @@ void TextControlElement::SelectionChanged(bool user_triggered) { return; const SelectionInDOMTree& selection = frame->Selection().GetSelectionInDOMTree(); - if (selection.Type() != kRangeSelection) + if (!selection.IsRange()) return; DispatchEvent(*Event::CreateBubble(event_type_names::kSelect)); } @@ -1047,10 +1046,8 @@ String TextControlElement::DirectionForFormData() const { return dir_attribute_value; if (EqualIgnoringASCIICase(dir_attribute_value, "auto")) { - bool is_auto; - TextDirection text_direction = - element->DirectionalityIfhasDirAutoAttribute(is_auto); - return text_direction == TextDirection::kRtl ? "rtl" : "ltr"; + return element->CachedDirectionality() == TextDirection::kRtl ? "rtl" + : "ltr"; } } 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 3c96c9cbce1..5d65533faac 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 @@ -281,7 +281,7 @@ struct DowncastTraits<TextControlElement> { TextControlElement* EnclosingTextControl(const Position&); TextControlElement* EnclosingTextControl(const PositionInFlatTree&); -TextControlElement* EnclosingTextControl(const Node*); +CORE_EXPORT TextControlElement* EnclosingTextControl(const Node*); } // namespace blink 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 763660b3805..220dd750c83 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 @@ -45,8 +45,8 @@ EditingViewPortElement::EditingViewPortElement(Document& document) setAttribute(html_names::kIdAttr, shadow_element_names::kIdEditingViewPort); } -scoped_refptr<ComputedStyle> -EditingViewPortElement::CustomStyleForLayoutObject() { +scoped_refptr<ComputedStyle> EditingViewPortElement::CustomStyleForLayoutObject( + const StyleRecalcContext&) { // FXIME: Move these styles to html.css. scoped_refptr<ComputedStyle> style = ComputedStyle::Create(); @@ -134,7 +134,8 @@ LayoutObject* TextControlInnerEditorElement::CreateLayoutObject( } scoped_refptr<ComputedStyle> -TextControlInnerEditorElement::CustomStyleForLayoutObject() { +TextControlInnerEditorElement::CustomStyleForLayoutObject( + const StyleRecalcContext&) { scoped_refptr<ComputedStyle> inner_editor_style = CreateInnerEditorStyle(); // Using StyleAdjuster::adjustComputedStyle updates unwanted style. We'd like // to apply only editing-related and alignment-related. 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 4be63f67adb..254b480c0f9 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 @@ -37,7 +37,8 @@ class EditingViewPortElement final : public HTMLDivElement { explicit EditingViewPortElement(Document&); protected: - scoped_refptr<ComputedStyle> CustomStyleForLayoutObject() override; + scoped_refptr<ComputedStyle> CustomStyleForLayoutObject( + const StyleRecalcContext&) override; private: bool TypeShouldForceLegacyLayout() const final; @@ -57,7 +58,8 @@ class TextControlInnerEditorElement final : public HTMLDivElement { private: LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) override; bool TypeShouldForceLegacyLayout() const final; - scoped_refptr<ComputedStyle> CustomStyleForLayoutObject() override; + scoped_refptr<ComputedStyle> CustomStyleForLayoutObject( + const StyleRecalcContext&) override; bool SupportsFocus() const override { return false; } bool is_visible_ = true; }; 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 c8606c31925..cea4e00d3d3 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 @@ -484,7 +484,7 @@ bool TextFieldInputType::ShouldRespectListAttribute() { return true; } -void TextFieldInputType::UpdatePlaceholderText() { +void TextFieldInputType::UpdatePlaceholderText(bool is_suggested_value) { if (!SupportsPlaceholder()) return; HTMLElement* placeholder = GetElement().PlaceholderElement(); @@ -512,6 +512,12 @@ void TextFieldInputType::UpdatePlaceholderText() { previous->parentNode()->InsertBefore(placeholder, previous); SECURITY_DCHECK(placeholder->parentNode() == previous->parentNode()); } + if (is_suggested_value) { + placeholder->SetInlineStyleProperty(CSSPropertyID::kUserSelect, + CSSValueID::kNone, true); + } else { + placeholder->RemoveInlineStyleProperty(CSSPropertyID::kUserSelect); + } placeholder->setTextContent(placeholder_text); } 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 4f24cb60993..e1877045d29 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 @@ -88,7 +88,7 @@ class TextFieldInputType : public InputType, bool ShouldSubmitImplicitly(const Event&) final; bool ShouldRespectListAttribute() override; void ListAttributeTargetChanged() override; - void UpdatePlaceholderText() final; + void UpdatePlaceholderText(bool is_suggested_value) final; void AppendToFormData(FormData&) const override; void SubtreeHasChanged() final; 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 81f0815d97e..b3ecda6a691 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 @@ -42,6 +42,7 @@ #include "third_party/blink/renderer/core/frame/settings.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/conversion_measurement_parsing.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/html_names.h" @@ -204,7 +205,7 @@ bool HTMLAnchorElement::HasActivationBehavior() const { } void HTMLAnchorElement::SetActive(bool active) { - if (HasEditableStyle(*this)) + if (active && HasEditableStyle(*this)) return; HTMLElement::SetActive(active); @@ -262,11 +263,6 @@ void HTMLAnchorElement::ParseAttribute( } } -void HTMLAnchorElement::AccessKeyAction(bool send_mouse_events) { - DispatchSimulatedClick( - nullptr, send_mouse_events ? kSendMouseUpDownEvents : kSendNoEvents); -} - bool HTMLAnchorElement::IsURLAttribute(const Attribute& attribute) const { return attribute.GetName().LocalName() == html_names::kHrefAttr || HTMLElement::IsURLAttribute(attribute); @@ -358,90 +354,6 @@ bool HTMLAnchorElement::HasImpression() const { hasAttribute(html_names::kConversiondestinationAttr); } -base::Optional<WebImpression> HTMLAnchorElement::GetImpressionForNavigation() - const { - DCHECK(HasImpression()); - - if (!RuntimeEnabledFeatures::ConversionMeasurementEnabled( - GetExecutionContext())) - return base::nullopt; - - if (!GetExecutionContext()->IsFeatureEnabled( - mojom::blink::FeaturePolicyFeature::kConversionMeasurement)) { - String message = - "The 'conversion-measurement' feature policy must be enabled to " - "declare an impression."; - GetExecutionContext()->AddConsoleMessage( - MakeGarbageCollected<ConsoleMessage>( - mojom::blink::ConsoleMessageSource::kOther, - mojom::blink::ConsoleMessageLevel::kError, message)); - return base::nullopt; - } - - // Conversion measurement is only allowed when both the frame and the main - // frame (if different) have a secure origin. - LocalFrame* frame = GetDocument().GetFrame(); - const Frame& main_frame = frame->Tree().Top(); - if (!main_frame.GetSecurityContext() - ->GetSecurityOrigin() - ->IsPotentiallyTrustworthy()) { - return base::nullopt; - } - if (!frame->IsMainFrame() && !frame->GetSecurityContext() - ->GetSecurityOrigin() - ->IsPotentiallyTrustworthy()) { - return base::nullopt; - } - - const AtomicString& conversion_destination_string = - FastGetAttribute(html_names::kConversiondestinationAttr); - scoped_refptr<const SecurityOrigin> conversion_destination = - SecurityOrigin::CreateFromString(conversion_destination_string); - if (!conversion_destination->IsPotentiallyTrustworthy()) - return base::nullopt; - - bool impression_data_is_valid = false; - uint64_t impression_data = FastGetAttribute(html_names::kImpressiondataAttr) - .GetString() - .HexToUInt64Strict(&impression_data_is_valid); - - // Provide a default of 0 if the impression data was not valid. - impression_data = impression_data_is_valid ? impression_data : 0UL; - - // Reporting origin is an optional attribute. Reporting origins must be - // secure. - base::Optional<WebSecurityOrigin> reporting_origin; - if (hasAttribute(html_names::kReportingoriginAttr)) { - const AtomicString& reporting_origin_string = - FastGetAttribute(html_names::kReportingoriginAttr); - reporting_origin = - SecurityOrigin::CreateFromString(reporting_origin_string); - - if (!reporting_origin->IsPotentiallyTrustworthy()) - return base::nullopt; - } - - // Impression expiry is an optional attribute. - base::Optional<base::TimeDelta> expiry; - if (hasAttribute(html_names::kImpressionexpiryAttr)) { - bool expiry_is_valid = false; - uint64_t expiry_milliseconds = - FastGetAttribute(html_names::kImpressionexpiryAttr) - .GetString() - .ToUInt64Strict(&expiry_is_valid); - if (expiry_is_valid) - expiry = base::TimeDelta::FromMilliseconds(expiry_milliseconds); - } - - UseCounter::Count(GetExecutionContext(), - mojom::blink::WebFeature::kConversionAPIAll); - UseCounter::Count(GetExecutionContext(), - mojom::blink::WebFeature::kImpressionRegistration); - - return WebImpression{conversion_destination, reporting_origin, - impression_data, expiry}; -} - void HTMLAnchorElement::SendPings(const KURL& destination_url) const { const AtomicString& ping_value = FastGetAttribute(html_names::kPingAttr); if (ping_value.IsNull() || !GetDocument().GetSettings() || @@ -551,12 +463,28 @@ void HTMLAnchorElement::HandleClick(Event& event) { } frame_request.SetTriggeringEventInfo( - event.isTrusted() ? TriggeringEventInfo::kFromTrustedEvent - : TriggeringEventInfo::kFromUntrustedEvent); + event.isTrusted() + ? mojom::blink::TriggeringEventInfo::kFromTrustedEvent + : mojom::blink::TriggeringEventInfo::kFromUntrustedEvent); frame_request.SetInputStartTime(event.PlatformTimeStamp()); frame->MaybeLogAdClickNavigation(); + if (request.HasUserGesture() && HasImpression()) { + // An impression must be attached prior to the + // FindOrCreateFrameForNavigation() call, as that call may result in + // performing a navigation if the call results in creating a new window with + // noopener set. + // At this time we don't know if the navigation will navigate a main frame + // or subframe. For example, a middle click on the anchor element will + // set `target_frame` to `frame`, but end up targeting a new window. + // Attach the impression regardless, the embedder will be able to drop + // impressions for subframe navigations. + base::Optional<WebImpression> impression = GetImpressionForAnchor(this); + if (impression) + frame_request.SetImpression(*impression); + } + Frame* target_frame = frame->Tree().FindOrCreateFrameForNavigation(frame_request, target).frame; @@ -571,14 +499,6 @@ void HTMLAnchorElement::HandleClick(Event& event) { WebFeature::kHTMLAnchorElementHrefTranslateAttribute); } - // Only attach impressions for main frame navigations. - if (target_frame && target_frame->IsMainFrame() && request.HasUserGesture() && - HasImpression()) { - base::Optional<WebImpression> impression = GetImpressionForNavigation(); - if (impression) - frame_request.SetImpression(*impression); - } - if (target_frame) target_frame->Navigate(frame_request, WebFrameLoadType::kStandard); } 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 e1478ded441..6b1a47372f2 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 @@ -101,11 +101,6 @@ class CORE_EXPORT HTMLAnchorElement : public HTMLElement, public DOMURLUtils { // determined by looking at the presence of required attributes. bool HasImpression() const; - // Returns the WebImpression struct with all data declared by impression - // related attributes on |this|. If the impression attributes do not contain - // allowed values, base::nullopt is returned. - base::Optional<WebImpression> GetImpressionForNavigation() const; - void SendPings(const KURL& destination_url) const; void Trace(Visitor*) const override; @@ -122,7 +117,6 @@ class CORE_EXPORT HTMLAnchorElement : public HTMLElement, public DOMURLUtils { void DefaultEventHandler(Event&) final; bool HasActivationBehavior() const override; void SetActive(bool active) final; - void AccessKeyAction(bool send_mouse_events) final; bool IsURLAttribute(const Attribute&) const final; bool HasLegalLinkAttribute(const QualifiedName&) const final; bool CanStartSelection() const final; diff --git a/chromium/third_party/blink/renderer/core/html/html_area_element.h b/chromium/third_party/blink/renderer/core/html/html_area_element.h index b51388818d9..863d4899300 100644 --- a/chromium/third_party/blink/renderer/core/html/html_area_element.h +++ b/chromium/third_party/blink/renderer/core/html/html_area_element.h @@ -39,6 +39,7 @@ class CORE_EXPORT HTMLAreaElement final : public HTMLAnchorElement { public: explicit HTMLAreaElement(Document&); + ~HTMLAreaElement() override; bool IsDefault() const { return shape_ == kDefault; } @@ -58,8 +59,6 @@ class CORE_EXPORT HTMLAreaElement final : public HTMLAnchorElement { HTMLImageElement* ImageElement() const; private: - ~HTMLAreaElement() override; - void ParseAttribute(const AttributeModificationParams&) override; bool IsKeyboardFocusable() const override; bool IsMouseFocusable() const override; diff --git a/chromium/third_party/blink/renderer/core/html/html_attribute_names.json5 b/chromium/third_party/blink/renderer/core/html/html_attribute_names.json5 index 7c7b7942aa3..c25150bece7 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 @@ -19,6 +19,7 @@ "allowfullscreen", "allowpaymentrequest", "alt", + "anchor", "archive", "as", "async", @@ -292,6 +293,7 @@ "sandbox", "scheme", "scope", + "scopes", "scrollamount", "scrolldelay", "scrolling", diff --git a/chromium/third_party/blink/renderer/core/html/html_content_element.cc b/chromium/third_party/blink/renderer/core/html/html_content_element.cc deleted file mode 100644 index de6e6c716d1..00000000000 --- a/chromium/third_party/blink/renderer/core/html/html_content_element.cc +++ /dev/null @@ -1,127 +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. - * * 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/html/html_content_element.h" - -#include "third_party/blink/renderer/core/css/parser/css_parser.h" -#include "third_party/blink/renderer/core/css/selector_checker.h" -#include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/dom/qualified_name.h" -#include "third_party/blink/renderer/core/dom/shadow_root.h" -#include "third_party/blink/renderer/core/dom/shadow_root_v0.h" -#include "third_party/blink/renderer/core/frame/web_feature.h" -#include "third_party/blink/renderer/core/html_names.h" -#include "third_party/blink/renderer/platform/heap/heap.h" -#include "third_party/blink/renderer/platform/instrumentation/use_counter.h" - -namespace blink { - -HTMLContentElement::HTMLContentElement(Document& document) - : V0InsertionPoint(html_names::kContentTag, document), - should_parse_select_(false), - is_valid_selector_(true) { - UseCounter::Count(document, WebFeature::kHTMLContentElement); -} - -HTMLContentElement::~HTMLContentElement() = default; - -void HTMLContentElement::Trace(Visitor* visitor) const { - V0InsertionPoint::Trace(visitor); -} - -void HTMLContentElement::ParseSelect() { - DCHECK(should_parse_select_); - - selector_list_ = CSSParser::ParseSelector( - MakeGarbageCollected<CSSParserContext>(GetDocument()), nullptr, select_); - should_parse_select_ = false; - is_valid_selector_ = ValidateSelect(); - if (!is_valid_selector_) - selector_list_ = CSSSelectorList(); -} - -void HTMLContentElement::ParseAttribute( - const AttributeModificationParams& params) { - if (params.name == html_names::kSelectAttr) { - if (ShadowRoot* root = ContainingShadowRoot()) { - if (!root->IsV1()) - root->V0().WillAffectSelector(); - } - should_parse_select_ = true; - select_ = params.new_value; - } else { - V0InsertionPoint::ParseAttribute(params); - } -} - -static inline bool IncludesDisallowedPseudoClass(const CSSSelector& selector) { - if (selector.GetPseudoType() == CSSSelector::kPseudoNot) { - const CSSSelector* sub_selector = selector.SelectorList()->First(); - return sub_selector->Match() == CSSSelector::kPseudoClass; - } - return selector.Match() == CSSSelector::kPseudoClass; -} - -bool HTMLContentElement::ValidateSelect() const { - DCHECK(!should_parse_select_); - - if (select_.IsNull() || select_.IsEmpty()) - return true; - - if (!selector_list_.IsValid()) - return false; - - for (const CSSSelector* selector = selector_list_.First(); selector; - selector = selector_list_.Next(*selector)) { - if (!selector->IsCompound()) - return false; - for (const CSSSelector* sub_selector = selector; sub_selector; - sub_selector = sub_selector->TagHistory()) { - if (IncludesDisallowedPseudoClass(*sub_selector)) - return false; - } - } - return true; -} - -// TODO(esprehn): element should really be const, but matching a selector is not -// const for some SelectorCheckingModes (mainly ResolvingStyle) where it sets -// dynamic restyle flags on elements. -bool HTMLContentElement::MatchSelector(Element& element) const { - SelectorChecker::Init init; - init.mode = SelectorChecker::kQueryingRules; - SelectorChecker checker(init); - SelectorChecker::SelectorCheckingContext context(&element); - for (const CSSSelector* selector = SelectorList().First(); selector; - selector = CSSSelectorList::Next(*selector)) { - context.selector = selector; - if (checker.Match(context)) - return true; - } - return false; -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/html_content_element.h b/chromium/third_party/blink/renderer/core/html/html_content_element.h deleted file mode 100644 index e57deb6040c..00000000000 --- a/chromium/third_party/blink/renderer/core/html/html_content_element.h +++ /dev/null @@ -1,99 +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_HTML_HTML_CONTENT_ELEMENT_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_CONTENT_ELEMENT_H_ - -#include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/css/css_selector_list.h" -#include "third_party/blink/renderer/core/dom/v0_insertion_point.h" -#include "third_party/blink/renderer/platform/heap/handle.h" - -namespace blink { - -class CORE_EXPORT HTMLContentElement final : public V0InsertionPoint { - DEFINE_WRAPPERTYPEINFO(); - - public: - HTMLContentElement(Document&); - ~HTMLContentElement() override; - - bool CanAffectSelector() const override { return true; } - - bool CanSelectNode(const HeapVector<Member<Node>, 32>& siblings, - int nth) const; - - const CSSSelectorList& SelectorList() const; - bool IsSelectValid() const; - - void Trace(Visitor*) const override; - - private: - void ParseAttribute(const AttributeModificationParams&) override; - - bool ValidateSelect() const; - void ParseSelect(); - - bool MatchSelector(Element&) const; - - bool should_parse_select_; - bool is_valid_selector_; - AtomicString select_; - CSSSelectorList selector_list_; -}; - -inline const CSSSelectorList& HTMLContentElement::SelectorList() const { - if (should_parse_select_) - const_cast<HTMLContentElement*>(this)->ParseSelect(); - return selector_list_; -} - -inline bool HTMLContentElement::IsSelectValid() const { - if (should_parse_select_) - const_cast<HTMLContentElement*>(this)->ParseSelect(); - return is_valid_selector_; -} - -inline bool HTMLContentElement::CanSelectNode( - const HeapVector<Member<Node>, 32>& siblings, - int nth) const { - if (select_.IsNull() || select_.IsEmpty()) - return true; - if (!IsSelectValid()) - return false; - auto* element = DynamicTo<Element>(siblings[nth].Get()); - if (!element) - return false; - return MatchSelector(*element); -} - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_CONTENT_ELEMENT_H_ diff --git a/chromium/third_party/blink/renderer/core/html/html_content_element.idl b/chromium/third_party/blink/renderer/core/html/html_content_element.idl deleted file mode 100644 index 609d07a68ac..00000000000 --- a/chromium/third_party/blink/renderer/core/html/html_content_element.idl +++ /dev/null @@ -1,34 +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. - */ - -// https://w3c.github.io/webcomponents/spec/shadow/#the-content-element - -[ - Exposed=Window -] interface HTMLContentElement : HTMLElement { - [Reflect] attribute DOMString select; - NodeList getDistributedNodes(); -}; diff --git a/chromium/third_party/blink/renderer/core/html/html_content_element_test.cc b/chromium/third_party/blink/renderer/core/html/html_content_element_test.cc deleted file mode 100644 index bbae3818cb4..00000000000 --- a/chromium/third_party/blink/renderer/core/html/html_content_element_test.cc +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/renderer/core/html/html_content_element.h" - -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/renderer/core/css/style_engine.h" -#include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/dom/node_computed_style.h" -#include "third_party/blink/renderer/core/dom/shadow_root.h" -#include "third_party/blink/renderer/core/testing/dummy_page_holder.h" - -namespace blink { - -class HTMLContentElementTest : public testing::Test { - protected: - void SetUp() final { - dummy_page_holder_ = std::make_unique<DummyPageHolder>(IntSize(800, 600)); - } - Document& GetDocument() { return dummy_page_holder_->GetDocument(); } - - private: - std::unique_ptr<DummyPageHolder> dummy_page_holder_; -}; - -TEST_F(HTMLContentElementTest, FallbackRecalcForReattach) { - GetDocument().body()->setInnerHTML(R"HTML( - <div id='host'></div> - )HTML"); - - Element* host = GetDocument().getElementById("host"); - ShadowRoot& root = host->CreateV0ShadowRootForTesting(); - GetDocument().View()->UpdateAllLifecyclePhasesForTest(); - - auto* content = GetDocument().CreateRawElement(html_names::kContentTag); - auto* fallback = GetDocument().CreateRawElement(html_names::kSpanTag); - content->AppendChild(fallback); - root.AppendChild(content); - - GetDocument().UpdateDistributionForLegacyDistributedNodes(); - GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInStyleRecalc); - GetDocument().GetStyleEngine().RecalcStyle(); - - EXPECT_TRUE(fallback->GetComputedStyle()); -} - -} // namespace blink 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 42c8395ef86..43a31f0925f 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 @@ -31,6 +31,7 @@ #include "third_party/blink/renderer/core/frame/web_feature.h" #include "third_party/blink/renderer/core/html/html_div_element.h" #include "third_party/blink/renderer/core/html/html_slot_element.h" +#include "third_party/blink/renderer/core/html/html_style_element.h" #include "third_party/blink/renderer/core/html/html_summary_element.h" #include "third_party/blink/renderer/core/html/shadow/details_marker_control.h" #include "third_party/blink/renderer/core/html/shadow/shadow_element_names.h" @@ -95,6 +96,22 @@ void HTMLDetailsElement::DidAddUserAgentShadowRoot(ShadowRoot& root) { content_slot->SetInlineStyleProperty(CSSPropertyID::kDisplay, CSSValueID::kNone); root.AppendChild(content_slot); + + if (RuntimeEnabledFeatures::SummaryListItemEnabled()) { + auto* default_summary_style = MakeGarbageCollected<HTMLStyleElement>( + GetDocument(), CreateElementFlags::ByCreateElement()); + default_summary_style->setTextContent(R"CSS( +:host summary { + display: list-item; + counter-increment: list-item 0; + list-style: disclosure-closed inside; +} +:host([open]) summary { + list-style-type: disclosure-open; +} +)CSS"); + root.AppendChild(default_summary_style); + } } Element* HTMLDetailsElement::FindMainSummary() const { @@ -134,6 +151,8 @@ void HTMLDetailsElement::ParseAttribute( CSSValueID::kNone); } + if (RuntimeEnabledFeatures::SummaryListItemEnabled()) + return; // Invalidate the LayoutDetailsMarker in order to turn the arrow signifying // if the details element is open or closed. Element* summary = FindMainSummary(); 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 4c6a5edac63..3882308da82 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 @@ -149,6 +149,9 @@ void HTMLDialogElement::show() { return; SetBooleanAttribute(html_names::kOpenAttr, true); + // Showing a <dialog> should hide all open popups. + GetDocument().HideAllPopupsUntil(nullptr); + // The layout must be updated here because setFocusForDialog calls // Element::isFocusable, which requires an up-to-date layout. GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kJavaScript); @@ -176,6 +179,9 @@ void HTMLDialogElement::showModal(ExceptionState& exception_state) { WebFeature::kShowModalForElementInFullscreenStack); } + // Showing a <dialog> should hide all open popups. + GetDocument().HideAllPopupsUntil(nullptr); + GetDocument().AddToTopLayer(this); SetBooleanAttribute(html_names::kOpenAttr, true); @@ -192,27 +198,9 @@ void HTMLDialogElement::showModal(ExceptionState& exception_state) { void HTMLDialogElement::RemovedFrom(ContainerNode& insertion_point) { HTMLElement::RemovedFrom(insertion_point); - - // TODO(671907): Calling UpdateDistributionForFlatTreeTraversal here is a - // workaround for https://crbug.com/895511. This shouldn't be done during DOM - // mutation. However, Shadow DOM v0 will be removed, at which point this call - // can be removed. - GetDocument().UpdateDistributionForFlatTreeTraversal(); - InertSubtreesChanged(GetDocument()); } -bool HTMLDialogElement::IsPresentationAttribute( - const QualifiedName& name) const { - // FIXME: Workaround for <https://bugs.webkit.org/show_bug.cgi?id=91058>: - // modifying an attribute for which there is an attribute selector in html.css - // sometimes does not trigger a style recalc. - if (name == html_names::kOpenAttr) - return true; - - return HTMLElement::IsPresentationAttribute(name); -} - void HTMLDialogElement::DefaultEventHandler(Event& event) { if (event.type() == event_type_names::kCancel) { close(); 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 8e6c8d8f9e6..605672be06b 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 @@ -33,7 +33,6 @@ namespace blink { class Document; class ExceptionState; -class QualifiedName; class HTMLDialogElement final : public HTMLElement { DEFINE_WRAPPERTYPEINFO(); @@ -54,7 +53,6 @@ class HTMLDialogElement final : public HTMLElement { } private: - bool IsPresentationAttribute(const QualifiedName&) const override; void DefaultEventHandler(Event&) override; void SetIsModal(bool is_modal); diff --git a/chromium/third_party/blink/renderer/core/html/html_document.cc b/chromium/third_party/blink/renderer/core/html/html_document.cc index bc709a11c85..fd08b664927 100644 --- a/chromium/third_party/blink/renderer/core/html/html_document.cc +++ b/chromium/third_party/blink/renderer/core/html/html_document.cc @@ -82,8 +82,7 @@ Document* HTMLDocument::CloneDocumentWithoutChildren() const { return MakeGarbageCollected<HTMLDocument>( DocumentInit::Create() .WithExecutionContext(GetExecutionContext()) - .WithURL(Url()) - .WithRegistrationContext(RegistrationContext())); + .WithURL(Url())); } // -------------------------------------------------------------------------- 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 47525bc3abe..af8ff43e6bf 100644 --- a/chromium/third_party/blink/renderer/core/html/html_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_element.cc @@ -42,11 +42,14 @@ #include "third_party/blink/renderer/core/dom/element_rare_data.h" #include "third_party/blink/renderer/core/dom/element_traversal.h" #include "third_party/blink/renderer/core/dom/events/event_listener.h" +#include "third_party/blink/renderer/core/dom/events/simulated_click_options.h" #include "third_party/blink/renderer/core/dom/flat_tree_traversal.h" #include "third_party/blink/renderer/core/dom/node_computed_style.h" #include "third_party/blink/renderer/core/dom/node_lists_node_data.h" #include "third_party/blink/renderer/core/dom/node_traversal.h" #include "third_party/blink/renderer/core/dom/shadow_root.h" +#include "third_party/blink/renderer/core/dom/slot_assignment.h" +#include "third_party/blink/renderer/core/dom/slot_assignment_recalc_forbidden_scope.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/editing/serializers/serialization.h" @@ -67,6 +70,7 @@ #include "third_party/blink/renderer/core/html/html_dimension.h" #include "third_party/blink/renderer/core/html/html_document.h" #include "third_party/blink/renderer/core/html/html_frame_owner_element.h" +#include "third_party/blink/renderer/core/html/html_slot_element.h" #include "third_party/blink/renderer/core/html/html_template_element.h" #include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h" #include "third_party/blink/renderer/core/html/shadow/shadow_element_names.h" @@ -140,6 +144,36 @@ bool IsEditable(const Node& node) { const WebFeature kNoWebFeature = static_cast<WebFeature>(0); +HTMLElement* GetParentForDirectionality(HTMLElement* element, + bool& needs_slot_assignment_recalc) { + if (element->IsPseudoElement()) + return DynamicTo<HTMLElement>(element->ParentOrShadowHostNode()); + + if (element->IsChildOfShadowHost()) { + ShadowRoot* root = element->ShadowRootOfParent(); + if (!root || !root->HasSlotAssignment()) + return nullptr; + + if (root->NeedsSlotAssignmentRecalc()) { + needs_slot_assignment_recalc = true; + return nullptr; + } + } + if (auto* parent_slot = ToHTMLSlotElementIfSupportsAssignmentOrNull( + element->parentElement())) { + ShadowRoot* root = parent_slot->ContainingShadowRoot(); + if (root->NeedsSlotAssignmentRecalc()) { + needs_slot_assignment_recalc = true; + return nullptr; + } + } + + // We should take care of all cases that would trigger a slot assignment + // recalc, and delay the check for later for a performance reason. + SlotAssignmentRecalcForbiddenScope forbid_slot_recalc(element->GetDocument()); + return DynamicTo<HTMLElement>(FlatTreeTraversal::ParentElement(*element)); +} + } // anonymous namespace String HTMLElement::DebugNodeName() const { @@ -711,6 +745,11 @@ void HTMLElement::AttributeChanged(const AttributeModificationParams& params) { if (params.name == html_names::kHiddenAttr && !params.new_value.IsNull()) { if (AdjustedFocusedElementInTreeScope() == this) blur(); + } else if (params.name == html_names::kSpellcheckAttr) { + if (GetDocument().GetFrame()) { + GetDocument().GetFrame()->GetSpellChecker().RespondToChangedEnablement( + *this, IsSpellCheckingEnabled()); + } } else if (params.name == html_names::kContenteditableAttr) { if (GetDocument().GetFrame()) { GetDocument() @@ -1037,13 +1076,11 @@ void HTMLElement::setSpellcheck(bool enable) { } void HTMLElement::click() { - DispatchSimulatedClick(nullptr, kSendNoEvents, - SimulatedClickCreationScope::kFromScript); + DispatchSimulatedClick(nullptr, SimulatedClickCreationScope::kFromScript); } -void HTMLElement::AccessKeyAction(bool send_mouse_events) { - DispatchSimulatedClick( - nullptr, send_mouse_events ? kSendMouseUpDownEvents : kSendNoEvents); +void HTMLElement::AccessKeyAction(SimulatedClickCreationScope creation_scope) { + DispatchSimulatedClick(nullptr, creation_scope); } String HTMLElement::title() const { @@ -1122,12 +1159,23 @@ HTMLFormElement* HTMLElement::FindFormAncestor() const { static inline bool ElementAffectsDirectionality(const Node* node) { auto* html_element = DynamicTo<HTMLElement>(node); return html_element && (IsA<HTMLBDIElement>(*html_element) || - html_element->FastHasAttribute(html_names::kDirAttr)); + IsValidDirAttribute(html_element->FastGetAttribute( + html_names::kDirAttr))); } void HTMLElement::ChildrenChanged(const ChildrenChange& change) { Element::ChildrenChanged(change); - AdjustDirectionalityIfNeededAfterChildrenChanged(change); + + if (GetDocument().IsDirAttributeDirty()) { + AdjustDirectionalityIfNeededAfterChildrenChanged(change); + + if (change.IsChildInsertion() && !SelfOrAncestorHasDirAutoAttribute()) { + auto* element = DynamicTo<HTMLElement>(change.sibling_changed); + if (element && !element->NeedsInheritDirectionalityFromParent() && + !ElementAffectsDirectionality(element)) + element->UpdateDirectionalityAndDescendant(CachedDirectionality()); + } + } } bool HTMLElement::HasDirectionAuto() const { @@ -1138,20 +1186,13 @@ bool HTMLElement::HasDirectionAuto() const { EqualIgnoringASCIICase(direction, "auto"); } -TextDirection HTMLElement::DirectionalityIfhasDirAutoAttribute( - bool& is_auto) const { - is_auto = HasDirectionAuto(); - if (!is_auto) - return TextDirection::kLtr; - return Directionality(); -} - -TextDirection HTMLElement::Directionality() const { +TextDirection HTMLElement::ResolveAutoDirectionality(bool& is_deferred, + Node* stay_within) const { + is_deferred = false; if (auto* input_element = DynamicTo<HTMLInputElement>(*this)) { bool has_strong_directionality; - TextDirection text_direction = DetermineDirectionality( - input_element->value(), &has_strong_directionality); - return text_direction; + return DetermineDirectionality(input_element->value(), + &has_strong_directionality); } Node* node = FlatTreeTraversal::FirstChild(*this); @@ -1163,16 +1204,28 @@ TextDirection HTMLElement::Directionality() const { (element && element->IsTextControl()) || (element && element->ShadowPseudoId() == shadow_element_names::kPseudoInputPlaceholder)) { - node = FlatTreeTraversal::NextSkippingChildren(*node, this); + node = FlatTreeTraversal::NextSkippingChildren(*node, stay_within); continue; } + if (auto* slot = ToHTMLSlotElementIfSupportsAssignmentOrNull(node)) { + ShadowRoot* root = slot->ContainingShadowRoot(); + // Defer to adjust the directionality to avoid recalcuating slot + // assignment in FlatTreeTraversal when updating slot. + // ResolveAutoDirectionality will be adjusted after recalculating its + // children. + if (root->NeedsSlotAssignmentRecalc()) { + is_deferred = true; + return TextDirection::kLtr; + } + } + // Skip elements with valid dir attribute if (auto* element_node = DynamicTo<Element>(node)) { AtomicString dir_attribute_value = element_node->FastGetAttribute(html_names::kDirAttr); if (IsValidDirAttribute(dir_attribute_value)) { - node = FlatTreeTraversal::NextSkippingChildren(*node, this); + node = FlatTreeTraversal::NextSkippingChildren(*node, stay_within); continue; } } @@ -1184,46 +1237,55 @@ TextDirection HTMLElement::Directionality() const { if (has_strong_directionality) return text_direction; } - node = FlatTreeTraversal::Next(*node, this); + node = FlatTreeTraversal::Next(*node, stay_within); } return TextDirection::kLtr; } -bool HTMLElement::SelfOrAncestorHasDirAutoAttribute() const { - // TODO(esprehn): Storing this state in the computed style is bad, we - // should be able to answer questions about the shape of the DOM and the - // text contained inside it without having style. - if (const ComputedStyle* style = GetComputedStyle()) - return style->SelfOrAncestorHasDirAutoAttribute(); - return false; -} - void HTMLElement::AdjustDirectionalityIfNeededAfterChildAttributeChanged( Element* child) { DCHECK(SelfOrAncestorHasDirAutoAttribute()); - const ComputedStyle* style = GetComputedStyle(); - if (style && style->Direction() != Directionality()) { + bool is_deferred; + TextDirection text_direction = ResolveAutoDirectionality(is_deferred, this); + if (CachedDirectionality() != text_direction && !is_deferred) { + SetCachedDirectionality(text_direction); + for (Element* element_to_adjust = this; element_to_adjust; element_to_adjust = FlatTreeTraversal::ParentElement(*element_to_adjust)) { if (ElementAffectsDirectionality(element_to_adjust)) { - element_to_adjust->SetNeedsStyleRecalc( - kLocalStyleChange, StyleChangeReasonForTracing::Create( - style_change_reason::kWritingModeChange)); + DynamicTo<HTMLElement>(element_to_adjust) + ->UpdateDirectionalityAndDescendant(text_direction); + + const ComputedStyle* style = GetComputedStyle(); + if (style && style->Direction() != text_direction) { + element_to_adjust->SetNeedsStyleRecalc( + kLocalStyleChange, StyleChangeReasonForTracing::Create( + style_change_reason::kWritingModeChange)); + } return; } } } } -void HTMLElement::CalculateAndAdjustDirectionality() { - TextDirection text_direction = Directionality(); - const ComputedStyle* style = GetComputedStyle(); - if (style && style->Direction() != text_direction) { - SetNeedsStyleRecalc(kLocalStyleChange, - StyleChangeReasonForTracing::Create( - style_change_reason::kWritingModeChange)); +bool HTMLElement::CalculateAndAdjustAutoDirectionality(Node* stay_within) { + bool is_deferred = false; + TextDirection text_direction = + ResolveAutoDirectionality(is_deferred, stay_within); + if (CachedDirectionality() != text_direction && !is_deferred) { + UpdateDirectionalityAndDescendant(text_direction); + + const ComputedStyle* style = GetComputedStyle(); + if (style && style->Direction() != text_direction) { + SetNeedsStyleRecalc(kLocalStyleChange, + StyleChangeReasonForTracing::Create( + style_change_reason::kWritingModeChange)); + return true; + } } + + return false; } void HTMLElement::AdjustDirectionalityIfNeededAfterChildrenChanged( @@ -1231,18 +1293,95 @@ void HTMLElement::AdjustDirectionalityIfNeededAfterChildrenChanged( if (!SelfOrAncestorHasDirAutoAttribute()) return; - UpdateDistributionForFlatTreeTraversal(); + Node* stay_within = nullptr; + bool has_strong_directionality; + if (change.type == ChildrenChangeType::kTextChanged) { + TextDirection old_text_direction = + DetermineDirectionality(change.old_text, &has_strong_directionality); + auto* character_data = DynamicTo<CharacterData>(change.sibling_changed); + DCHECK(character_data); + TextDirection new_text_direction = DetermineDirectionality( + character_data->data(), &has_strong_directionality); + if (old_text_direction == new_text_direction) + return; + stay_within = change.sibling_changed; + } else if (change.IsChildInsertion()) { + if (change.sibling_changed->IsTextNode()) { + TextDirection new_text_direction = + DetermineDirectionality(change.sibling_changed->textContent(true), + &has_strong_directionality); + if (!has_strong_directionality || + new_text_direction == CachedDirectionality()) + return; + } + stay_within = change.sibling_changed; + } + + UpdateDescendantHasDirAutoAttribute(true /* has_dir_auto */); for (Element* element_to_adjust = this; element_to_adjust; element_to_adjust = FlatTreeTraversal::ParentElement(*element_to_adjust)) { if (ElementAffectsDirectionality(element_to_adjust)) { - To<HTMLElement>(element_to_adjust)->CalculateAndAdjustDirectionality(); + if (To<HTMLElement>(element_to_adjust) + ->CalculateAndAdjustAutoDirectionality( + stay_within ? stay_within : element_to_adjust)) { + SetNeedsStyleRecalc(kLocalStyleChange, + StyleChangeReasonForTracing::Create( + style_change_reason::kPseudoClass)); + } + if (RuntimeEnabledFeatures::CSSPseudoDirEnabled()) + element_to_adjust->PseudoStateChanged(CSSSelector::kPseudoDir); return; } } } +void HTMLElement::AdjustCandidateDirectionalityForSlot( + HeapHashSet<Member<HTMLElement>> candidate_set) { + HeapHashSet<Member<HTMLElement>> directionality_set; + // Transfer a candidate directionality set to |directionality_set| to avoid + // the tree walk to the duplicated parent node for the directionality. + for (auto& element : candidate_set) { + if (!element->SelfOrAncestorHasDirAutoAttribute()) { + auto* parent = + DynamicTo<HTMLElement>(FlatTreeTraversal::ParentElement(*element)); + if (parent && !parent->NeedsInheritDirectionalityFromParent() && + element->NeedsInheritDirectionalityFromParent()) { + element->UpdateDirectionalityAndDescendant( + parent->CachedDirectionality()); + } + continue; + } + + for (auto* element_to_adjust = element.Get(); element_to_adjust; + element_to_adjust = DynamicTo<HTMLElement>( + FlatTreeTraversal::ParentElement(*element_to_adjust))) { + if (ElementAffectsDirectionality(element_to_adjust)) { + directionality_set.insert(element_to_adjust); + continue; + } + } + } + + for (auto& element : directionality_set) { + if (element->CalculateAndAdjustAutoDirectionality(element) && + RuntimeEnabledFeatures::CSSPseudoDirEnabled()) { + element->SetNeedsStyleRecalc(kLocalStyleChange, + StyleChangeReasonForTracing::Create( + style_change_reason::kPseudoClass)); + } + } +} + +void HTMLElement::AddCandidateDirectionalityForSlot() { + ShadowRoot* root = ShadowRootOfParent(); + if (!root || !root->HasSlotAssignment()) + return; + + root->GetSlotAssignment().GetCandidateDirectionality().insert(this); +} + Node::InsertionNotificationRequest HTMLElement::InsertedInto( ContainerNode& insertion_point) { // Process the superclass first to ensure that `InActiveDocument()` is @@ -1569,20 +1708,125 @@ Element* HTMLElement::unclosedOffsetParent() { return layout_object->OffsetParent(this); } +void HTMLElement::UpdateDescendantHasDirAutoAttribute(bool has_dir_auto) { + Node* node = FlatTreeTraversal::FirstChild(*this); + while (node) { + if (auto* element = DynamicTo<Element>(node)) { + AtomicString dir_attribute_value = + element->FastGetAttribute(html_names::kDirAttr); + if (IsValidDirAttribute(dir_attribute_value)) { + node = FlatTreeTraversal::NextSkippingChildren(*node, this); + continue; + } + + if (auto* slot = ToHTMLSlotElementIfSupportsAssignmentOrNull(node)) { + ShadowRoot* root = slot->ContainingShadowRoot(); + // Defer to adjust the directionality to avoid recalcuating slot + // assignment in FlatTreeTraversal when updating slot. + // Slot and its children will be updated after recalculating children. + if (root->NeedsSlotAssignmentRecalc()) { + root->SetNeedsDirAutoAttributeUpdate(true); + node = FlatTreeTraversal::NextSkippingChildren(*node, this); + continue; + } + } + + if (!has_dir_auto) { + if (!element->SelfOrAncestorHasDirAutoAttribute()) { + node = FlatTreeTraversal::NextSkippingChildren(*node, this); + continue; + } + element->ClearSelfOrAncestorHasDirAutoAttribute(); + } else { + if (element->SelfOrAncestorHasDirAutoAttribute()) { + node = FlatTreeTraversal::NextSkippingChildren(*node, this); + continue; + } + element->SetSelfOrAncestorHasDirAutoAttribute(); + } + } + node = FlatTreeTraversal::Next(*node, this); + } +} + +void HTMLElement::UpdateDirectionalityAndDescendant(TextDirection direction) { + SetCachedDirectionality(direction); + UpdateDescendantDirectionality(direction); +} + +void HTMLElement::UpdateDescendantDirectionality(TextDirection direction) { + Node* node = FlatTreeTraversal::FirstChild(*this); + while (node) { + if (IsA<HTMLElement>(node)) { + if (ElementAffectsDirectionality(node) || + node->CachedDirectionality() == direction) { + node = FlatTreeTraversal::NextSkippingChildren(*node, this); + continue; + } + node->SetCachedDirectionality(direction); + } + node = FlatTreeTraversal::Next(*node, this); + } +} + void HTMLElement::OnDirAttrChanged(const AttributeModificationParams& params) { // If an ancestor has dir=auto, and this node has the first character, // changes to dir attribute may affect the ancestor. - if (!CanParticipateInFlatTree()) + if (!IsValidDirAttribute(params.old_value) && + !IsValidDirAttribute(params.new_value)) return; - UpdateDistributionForFlatTreeTraversal(); - auto* parent = - DynamicTo<HTMLElement>(FlatTreeTraversal::ParentElement(*this)); - if (parent && parent->SelfOrAncestorHasDirAutoAttribute()) { - parent->AdjustDirectionalityIfNeededAfterChildAttributeChanged(this); + + GetDocument().SetDirAttributeDirty(); + + bool is_old_auto = SelfOrAncestorHasDirAutoAttribute(); + bool is_new_auto = HasDirectionAuto(); + bool needs_slot_assignment_recalc = false; + auto* parent = GetParentForDirectionality(this, needs_slot_assignment_recalc); + if (!is_old_auto || !is_new_auto) { + if (parent && parent->SelfOrAncestorHasDirAutoAttribute()) { + parent->AdjustDirectionalityIfNeededAfterChildAttributeChanged(this); + } + } + + if (is_old_auto && !is_new_auto) { + ClearSelfOrAncestorHasDirAutoAttribute(); + UpdateDescendantHasDirAutoAttribute(false /* has_dir_auto */); + } else if (!is_old_auto && is_new_auto) { + SetSelfOrAncestorHasDirAutoAttribute(); + UpdateDescendantHasDirAutoAttribute(true /* has_dir_auto */); + } + + if (is_new_auto) { + CalculateAndAdjustAutoDirectionality(this); + } else { + base::Optional<TextDirection> text_direction; + if (EqualIgnoringASCIICase(params.new_value, "ltr")) { + text_direction = TextDirection::kLtr; + } else if (EqualIgnoringASCIICase(params.new_value, "rtl")) { + text_direction = TextDirection::kRtl; + } + + if (!text_direction.has_value()) { + if (parent) { + text_direction = parent->CachedDirectionality(); + } else { + text_direction = TextDirection::kLtr; + } + } + + if (needs_slot_assignment_recalc) { + SetNeedsInheritDirectionalityFromParent(); + } else { + UpdateDirectionalityAndDescendant(*text_direction); + } } - if (EqualIgnoringASCIICase(params.new_value, "auto")) - CalculateAndAdjustDirectionality(); + if (RuntimeEnabledFeatures::CSSPseudoDirEnabled()) { + SetNeedsStyleRecalc( + kSubtreeStyleChange, + StyleChangeReasonForTracing::Create(style_change_reason::kPseudoClass)); + PseudoStateChanged(CSSSelector::kPseudoDir); + } } void HTMLElement::OnFormAttrChanged(const AttributeModificationParams& params) { @@ -1729,6 +1973,24 @@ void HTMLElement::FinishParsingChildren() { EnsureElementInternals().TakeStateAndRestore(); } +void HTMLElement::BeginParsingChildren() { + Element::BeginParsingChildren(); + + if (GetDocument().IsDirAttributeDirty()) { + if (HasDirectionAuto()) { + SetSelfOrAncestorHasDirAutoAttribute(); + } else if (!ElementAffectsDirectionality(this)) { + bool needs_slot_assignment_recalc = false; + auto* parent = + GetParentForDirectionality(this, needs_slot_assignment_recalc); + if (needs_slot_assignment_recalc) + SetNeedsInheritDirectionalityFromParent(); + else if (parent) + SetCachedDirectionality(parent->CachedDirectionality()); + } + } +} + } // namespace blink #ifndef NDEBUG 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 67e9e66e02f..fd1d50bcdfe 100644 --- a/chromium/third_party/blink/renderer/core/html/html_element.h +++ b/chromium/third_party/blink/renderer/core/html/html_element.h @@ -25,6 +25,7 @@ #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/dom/element.h" +#include "third_party/blink/renderer/core/dom/events/simulated_click_options.h" #include "third_party/blink/renderer/core/html/forms/labels_node_list.h" #include "third_party/blink/renderer/platform/text/text_direction.h" #include "third_party/blink/renderer/platform/wtf/casting.h" @@ -96,7 +97,7 @@ class CORE_EXPORT HTMLElement : public Element { void click(); - void AccessKeyAction(bool send_mouse_events) override; + void AccessKeyAction(SimulatedClickCreationScope creation_scope) override; bool ShouldSerializeEndTag() const; @@ -105,7 +106,6 @@ class CORE_EXPORT HTMLElement : public Element { HTMLFormElement* FindFormAncestor() const; bool HasDirectionAuto() const; - TextDirection DirectionalityIfhasDirAutoAttribute(bool& is_auto) const; virtual bool IsHTMLBodyElement() const { return false; } virtual bool IsHTMLFrameSetElement() const { return false; } @@ -153,6 +153,14 @@ class CORE_EXPORT HTMLElement : public Element { virtual FormAssociated* ToFormAssociatedOrNull() { return nullptr; } bool IsFormAssociatedCustomElement() const; + void AddCandidateDirectionalityForSlot(); + static void AdjustCandidateDirectionalityForSlot( + HeapHashSet<Member<HTMLElement>> candidate_set); + void UpdateDescendantHasDirAutoAttribute(bool has_dir_auto); + void UpdateDirectionalityAndDescendant(TextDirection direction); + void UpdateDescendantDirectionality(TextDirection direction); + void BeginParsingChildren() override; + protected: enum AllowPercentage { kDontAllowPercentageValues, kAllowPercentageValues }; enum AllowZero { kDontAllowZeroValues, kAllowZeroValues }; @@ -185,7 +193,7 @@ class CORE_EXPORT HTMLElement : public Element { unsigned ParseBorderWidthAttribute(const AtomicString&) const; void ChildrenChanged(const ChildrenChange&) override; - void CalculateAndAdjustDirectionality(); + bool CalculateAndAdjustAutoDirectionality(Node* stay_within); InsertionNotificationRequest InsertedInto(ContainerNode&) override; void RemovedFrom(ContainerNode& insertion_point) override; @@ -206,10 +214,11 @@ class CORE_EXPORT HTMLElement : public Element { DocumentFragment* TextToFragment(const String&, ExceptionState&); - bool SelfOrAncestorHasDirAutoAttribute() const; void AdjustDirectionalityIfNeededAfterChildAttributeChanged(Element* child); - void AdjustDirectionalityIfNeededAfterChildrenChanged(const ChildrenChange&); - TextDirection Directionality() const; + void AdjustDirectionalityIfNeededAfterChildrenChanged( + const ChildrenChange& change); + TextDirection ResolveAutoDirectionality(bool& is_deferred, + Node* stay_within) const; TranslateAttributeMode GetTranslateAttributeMode() const; diff --git a/chromium/third_party/blink/renderer/core/html/html_element.idl b/chromium/third_party/blink/renderer/core/html/html_element.idl index 4f751fec935..d231c479383 100644 --- a/chromium/third_party/blink/renderer/core/html/html_element.idl +++ b/chromium/third_party/blink/renderer/core/html/html_element.idl @@ -34,7 +34,7 @@ [RuntimeCallStatsCounter=HTMLElementClick] void click(); [CEReactions, RuntimeEnabled=InertAttribute, Reflect] attribute boolean inert; [CEReactions, Reflect] attribute DOMString accessKey; - [CEReactions, CustomElementCallbacks] attribute boolean draggable; + [CEReactions] attribute boolean draggable; [CEReactions] attribute boolean spellcheck; [Measure] attribute DOMString autocapitalize; @@ -42,7 +42,7 @@ // HTMLElement includes ElementContentEditable // https://html.spec.whatwg.org/C/#contenteditable - [CEReactions, CustomElementCallbacks, RaisesException=Setter] attribute DOMString contentEditable; + [CEReactions, RaisesException=Setter] attribute DOMString contentEditable; [RuntimeEnabled=EnterKeyHintAttribute, CEReactions, Reflect, ReflectOnly=("enter","done","go","next","previous","search","send")] attribute DOMString enterKeyHint; [ImplementedAs=isContentEditableForBinding] readonly attribute boolean isContentEditable; [CEReactions, Reflect, ReflectOnly=("none","text","tel","url","email","numeric","decimal","search")] attribute DOMString inputMode; @@ -65,8 +65,8 @@ [Affects=Nothing, SameObject, PerWorldBindings, PutForwards=cssText] readonly attribute CSSStyleDeclaration style; // Non-standard APIs - [Affects=Nothing, CEReactions, CustomElementCallbacks, RaisesException=Setter, MeasureAs=HTMLElementInnerText] attribute ([TreatNullAs=EmptyString] DOMString or TrustedScript) innerText; - [Affects=Nothing, CEReactions, CustomElementCallbacks, RaisesException=Setter, MeasureAs=HTMLElementOuterText] attribute [TreatNullAs=EmptyString] DOMString outerText; + [Affects=Nothing, CEReactions, RaisesException=Setter, MeasureAs=HTMLElementInnerText] attribute ([TreatNullAs=EmptyString] DOMString or TrustedScript) innerText; + [Affects=Nothing, CEReactions, RaisesException=Setter, MeasureAs=HTMLElementOuterText] attribute [TreatNullAs=EmptyString] DOMString outerText; }; HTMLElement includes GlobalEventHandlers; 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 index a0f5c3cd5a0..b1552b3b260 100644 --- a/chromium/third_party/blink/renderer/core/html/html_element_test.cc +++ b/chromium/third_party/blink/renderer/core/html/html_element_test.cc @@ -5,8 +5,10 @@ #include "third_party/blink/renderer/core/html/html_element.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/core/dom/node_computed_style.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/frame/settings.h" +#include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/core/testing/core_unit_test_helper.h" namespace blink { @@ -246,4 +248,18 @@ TEST_F(HTMLElementTest, GetDocument().GetPage()->Animator().has_inline_style_mutation_for_test()); } +TEST_F(HTMLElementTest, DirAutoByChildChanged) { + ScopedCSSPseudoDirForTest scoped_feature(false); + + SetBodyInnerHTML("<div id='target' dir='auto'></div>"); + auto* element = GetDocument().getElementById("target"); + element->setTextContent(u"\u05D1"); + UpdateAllLifecyclePhasesForTest(); + EXPECT_EQ(element->GetComputedStyle()->Direction(), TextDirection::kRtl); + + element->RemoveChildren(); + UpdateAllLifecyclePhasesForTest(); + EXPECT_EQ(element->GetComputedStyle()->Direction(), TextDirection::kLtr); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/html_embed_element.cc b/chromium/third_party/blink/renderer/core/html/html_embed_element.cc index 0ea3c6f5107..35bc484d9c6 100644 --- a/chromium/third_party/blink/renderer/core/html/html_embed_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_embed_element.cc @@ -126,6 +126,9 @@ void HTMLEmbedElement::ParseAttribute( if (FastHasAttribute(html_names::kTypeAttr)) { SetNeedsPluginUpdate(true); ReattachOnPluginChangeIfNeeded(); + } else { + UseCounter::Count(GetDocument(), + WebFeature::kEmbedElementWithoutTypeSrcChanged); } } } else { 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 59fe1414910..cc54e54db47 100644 --- a/chromium/third_party/blink/renderer/core/html/html_frame_owner_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_frame_owner_element.cc @@ -20,7 +20,6 @@ #include "third_party/blink/renderer/core/html/html_frame_owner_element.h" -#include "services/network/public/cpp/features.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h" @@ -31,6 +30,7 @@ #include "third_party/blink/renderer/core/dom/events/event.h" #include "third_party/blink/renderer/core/dom/node_computed_style.h" #include "third_party/blink/renderer/core/events/current_input_event.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/exported/web_plugin_container_impl.h" #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h" @@ -54,6 +54,7 @@ #include "third_party/blink/renderer/core/timing/window_performance.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/heap/heap_allocator.h" +#include "third_party/blink/renderer/platform/instrumentation/resource_coordinator/renderer_resource_coordinator.h" #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" #include "third_party/blink/renderer/platform/network/network_state_notifier.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" @@ -84,7 +85,7 @@ bool DoesParentAllowLazyLoadingChildren(Document& document) { return containing_frame_owner->ShouldLazyLoadChildren(); } -bool IsFrameLazyLoadable(const ExecutionContext* context, +bool IsFrameLazyLoadable(ExecutionContext* context, const KURL& url, bool is_loading_attr_lazy, bool should_lazy_load_children) { @@ -99,6 +100,11 @@ bool IsFrameLazyLoadable(const ExecutionContext* context, if (!url.ProtocolIsInHTTPFamily()) return false; + // Do not lazyload frames when JavaScript is disabled, regardless of the + // `loading` attribute. + if (!context->CanExecuteScripts(kNotAboutToExecuteScript)) + return false; + if (is_loading_attr_lazy) return true; @@ -198,6 +204,12 @@ void HTMLFrameOwnerElement::SetContentFrame(Frame& frame) { DCHECK(!lazy_load_frame_observer_ || !lazy_load_frame_observer_->IsLazyLoadPending()); + DCHECK_NE(content_frame_, &frame); + auto* resource_coordinator = RendererResourceCoordinator::Get(); + if (content_frame_) + resource_coordinator->OnBeforeContentFrameDetached(*content_frame_, *this); + resource_coordinator->OnBeforeContentFrameAttached(frame, *this); + content_frame_ = &frame; // Invalidate compositing inputs, because a remote frame child can cause the @@ -226,6 +238,9 @@ void HTMLFrameOwnerElement::ClearContentFrame() { CancelPendingLazyLoad(); DCHECK_EQ(content_frame_->Owner(), this); + RendererResourceCoordinator::Get()->OnBeforeContentFrameDetached( + *content_frame_, *this); + content_frame_ = nullptr; for (ContainerNode* node = this; node; node = node->ParentOrShadowHostNode()) @@ -385,9 +400,6 @@ void HTMLFrameOwnerElement::FrameOwnerPropertiesChanged() { } void HTMLFrameOwnerElement::CSPAttributeChanged() { - if (!base::FeatureList::IsEnabled(network::features::kOutOfBlinkCSPEE)) - return; - // Don't notify about updates if ContentFrame() is null, for example when // the subframe hasn't been created yet; or if we are in the middle of // swapping one frame for another, in which case the final state @@ -397,8 +409,14 @@ void HTMLFrameOwnerElement::CSPAttributeChanged() { String fake_header = "HTTP/1.1 200 OK\nContent-Security-Policy: " + RequiredCsp(); + // ParseHeaders needs a url to resolve report endpoints and for matching the + // keyword 'self'. However, the csp attribute does not allow report + // endpoints. Moreover, in the csp attribute, 'self' should not match the + // owner's url, but rather the frame src url. This is taken care by the + // Content-Security-Policy Embedded Enforcement algorithm, implemented in the + // AncestorThrottle. That's why we pass an empty url here. network::mojom::blink::ParsedHeadersPtr parsed_headers = - ParseHeaders(fake_header, GetDocument().Url()); + ParseHeaders(fake_header, KURL()); DCHECK_LE(parsed_headers->content_security_policy.size(), 1u); 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 158a4bcf59c..eda50e4275a 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 @@ -74,7 +74,7 @@ class CORE_EXPORT HTMLFrameOwnerElement : public HTMLElement, return embedded_content_view_; } - void SetColorScheme(mojom::ColorScheme); + void SetColorScheme(mojom::blink::ColorScheme); class PluginDisposeSuspendScope { STACK_ALLOCATED(); @@ -118,7 +118,7 @@ class CORE_EXPORT HTMLFrameOwnerElement : public HTMLElement, bool AllowFullscreen() const override { return false; } bool AllowPaymentRequest() const override { return false; } bool IsDisplayNone() const override { return !embedded_content_view_; } - mojom::ColorScheme GetColorScheme() const override; + mojom::blink::ColorScheme GetColorScheme() const override; AtomicString RequiredCsp() const override { return g_null_atom; } bool ShouldLazyLoadChildren() const final; @@ -138,9 +138,6 @@ class CORE_EXPORT HTMLFrameOwnerElement : public HTMLElement, HTMLFrameOwnerElement(const QualifiedName& tag_name, Document&); void SetSandboxFlags(network::mojom::blink::WebSandboxFlags); - void SetAllowedToDownload(bool allowed) { - frame_policy_.allowed_to_download = allowed; - } void SetDisallowDocumentAccesss(bool disallowed); bool LoadOrRedirectSubframe(const KURL&, 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 bf337b75fd2..9017e5ff468 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 @@ -262,7 +262,7 @@ void HTMLFrameSetElement::DefaultEventHandler(Event& evt) { auto* mouse_event = DynamicTo<MouseEvent>(evt); if (mouse_event && !noresize_ && GetLayoutObject() && GetLayoutObject()->IsFrameSet()) { - if (ToLayoutFrameSet(GetLayoutObject())->UserResize(*mouse_event)) { + if (To<LayoutFrameSet>(GetLayoutObject())->UserResize(*mouse_event)) { evt.SetDefaultHandled(); return; } @@ -281,8 +281,13 @@ Node::InsertionNotificationRequest HTMLFrameSetElement::InsertedInto( } void HTMLFrameSetElement::WillRecalcStyle(const StyleRecalcChange) { if (NeedsStyleRecalc() && GetLayoutObject()) { - GetLayoutObject()->SetNeedsLayoutAndFullPaintInvalidation( - layout_invalidation_reason::kStyleChange); + if (GetForceReattachLayoutTree()) { + // Adding a frameset to the top layer for fullscreen forces a reattach. + SetNeedsReattachLayoutTree(); + } else { + GetLayoutObject()->SetNeedsLayoutAndFullPaintInvalidation( + layout_invalidation_reason::kStyleChange); + } ClearNeedsStyleRecalc(); } } 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 a36767291bc..5b800502911 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 @@ -39,8 +39,6 @@ #include "third_party/blink/renderer/core/feature_policy/iframe_policy.h" #include "third_party/blink/renderer/core/fetch/trust_token_issuance_authorization.h" #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" -#include "third_party/blink/renderer/core/frame/deprecation.h" -#include "third_party/blink/renderer/core/frame/sandbox_flags.h" #include "third_party/blink/renderer/core/html/html_document.h" #include "third_party/blink/renderer/core/html/trust_token_attribute_parsing.h" #include "third_party/blink/renderer/core/html_names.h" @@ -154,8 +152,6 @@ void HTMLIFrameElement::ParseAttribute( FrameOwnerPropertiesChanged(); } else if (name == html_names::kSandboxAttr) { sandbox_->DidUpdateAttributeValue(params.old_value, value); - bool feature_policy_for_sandbox = - RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled(); network::mojom::blink::WebSandboxFlags current_flags = network::mojom::blink::WebSandboxFlags::kNone; @@ -178,29 +174,7 @@ void HTMLIFrameElement::ParseAttribute( parsed.error_message))); } } - SetAllowedToDownload( - (current_flags & network::mojom::blink::WebSandboxFlags::kDownloads) == - network::mojom::blink::WebSandboxFlags::kNone); - // With FeaturePolicyForSandbox, sandbox flags are represented as part of - // the container policies. However, not all sandbox flags are yet converted - // and for now the residue will stay around in the stored flags. - // (see https://crbug.com/812381). - network::mojom::blink::WebSandboxFlags sandbox_to_set = current_flags; - sandbox_flags_converted_to_feature_policies_ = - network::mojom::blink::WebSandboxFlags::kNone; - if (feature_policy_for_sandbox && - current_flags != network::mojom::blink::WebSandboxFlags::kNone) { - // Residue sandbox which will not be mapped to feature policies. - sandbox_to_set = - GetSandboxFlagsNotImplementedAsFeaturePolicy(current_flags); - // The part of sandbox which will be mapped to feature policies. - sandbox_flags_converted_to_feature_policies_ = - current_flags & ~sandbox_to_set; - } - SetSandboxFlags(sandbox_to_set); - if (RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()) - UpdateContainerPolicy(); - + SetSandboxFlags(current_flags); UseCounter::Count(GetDocument(), WebFeature::kSandboxViaIFrame); } else if (name == html_names::kReferrerpolicyAttr) { referrer_policy_ = network::mojom::ReferrerPolicy::kDefault; @@ -233,35 +207,19 @@ void HTMLIFrameElement::ParseAttribute( UpdateContainerPolicy(); } } else if (name == html_names::kCspAttr) { - if (base::FeatureList::IsEnabled(network::features::kOutOfBlinkCSPEE)) { - if (value.Contains('\n') || value.Contains('\r') || value.Contains(',')) { - required_csp_ = g_null_atom; - GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( - mojom::blink::ConsoleMessageSource::kOther, - mojom::blink::ConsoleMessageLevel::kError, - "'csp' attribute is invalid: " + value)); - return; - } - if (required_csp_ != value) { - required_csp_ = value; - CSPAttributeChanged(); - UseCounter::Count(GetDocument(), WebFeature::kIFrameCSPAttribute); - } - } else { - if (!ContentSecurityPolicy::IsValidCSPAttr( - value.GetString(), GetDocument().RequiredCSP().GetString())) { - required_csp_ = g_null_atom; - GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( - mojom::blink::ConsoleMessageSource::kOther, - mojom::blink::ConsoleMessageLevel::kError, - "'csp' attribute is not a valid policy: " + value)); - return; - } - if (required_csp_ != value) { - required_csp_ = value; - FrameOwnerPropertiesChanged(); - UseCounter::Count(GetDocument(), WebFeature::kIFrameCSPAttribute); - } + if (value && (value.Contains('\n') || value.Contains('\r') || + !MatchesTheSerializedCSPGrammar(value.GetString()))) { + required_csp_ = g_null_atom; + GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( + mojom::blink::ConsoleMessageSource::kOther, + mojom::blink::ConsoleMessageLevel::kError, + "'csp' attribute is invalid: " + value)); + return; + } + if (required_csp_ != value) { + required_csp_ = value; + CSPAttributeChanged(); + UseCounter::Count(GetDocument(), WebFeature::kIFrameCSPAttribute); } } else if (name == html_names::kAllowAttr) { if (allow_ != value) { @@ -271,11 +229,6 @@ void HTMLIFrameElement::ParseAttribute( UseCounter::Count(GetDocument(), WebFeature::kFeaturePolicyAllowAttribute); } - if (value.Contains(',')) { - Deprecation::CountDeprecation( - GetDocument().GetExecutionContext(), - WebFeature::kCommaSeparatorInAllowAttribute); - } } } else if (name == html_names::kDisallowdocumentaccessAttr && RuntimeEnabledFeatures::DisallowDocumentAccessEnabled()) { @@ -289,6 +242,7 @@ void HTMLIFrameElement::ParseAttribute( UpdateRequiredPolicy(); } } else if (name == html_names::kTrusttokenAttr) { + UseCounter::Count(GetDocument(), WebFeature::kTrustTokenIframe); trust_token_ = value; } else { // Websites picked up a Chromium article that used this non-specified @@ -369,32 +323,8 @@ ParsedFeaturePolicy HTMLIFrameElement::ConstructContainerPolicy() const { ParsedFeaturePolicy container_policy = FeaturePolicyParser::ParseAttribute( allow_, self_origin, src_origin, logger, GetExecutionContext()); - // Next, process sandbox flags. These all only take effect if a corresponding - // policy does *not* exist in the allow attribute's value. - if (RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()) { - // If the frame is sandboxed at all, then warn if feature policy attributes - // will override the sandbox attributes. - if ((sandbox_flags_converted_to_feature_policies_ & - network::mojom::blink::WebSandboxFlags::kNavigation) != - network::mojom::blink::WebSandboxFlags::kNone) { - for (const auto& pair : SandboxFlagsWithFeaturePolicies()) { - if ((sandbox_flags_converted_to_feature_policies_ & pair.first) != - network::mojom::blink::WebSandboxFlags::kNone && - IsFeatureDeclared(pair.second, container_policy)) { - logger.Warn(String::Format( - "Allow and Sandbox attributes both mention '%s'. Allow will take " - "precedence.", - GetNameForFeature(pair.second).Utf8().c_str())); - } - } - } - ApplySandboxFlagsToParsedFeaturePolicy( - sandbox_flags_converted_to_feature_policies_, container_policy); - } - - // Finally, process the allow* attribuets. Like sandbox attributes, they only - // take effect if the corresponding feature is not present in the allow - // attribute's value. + // Process the allow* attributes. These only take effect if the corresponding + // feature is not present in the allow attribute's value. // If allowfullscreen attribute is present and no fullscreen policy is set, // enable the feature for all origins. @@ -449,24 +379,8 @@ Node::InsertionNotificationRequest HTMLIFrameElement::InsertedInto( HTMLFrameElementBase::InsertedInto(insertion_point); auto* html_doc = DynamicTo<HTMLDocument>(GetDocument()); - if (html_doc && insertion_point.IsInDocumentTree()) { + if (html_doc && insertion_point.IsInDocumentTree()) html_doc->AddNamedItem(name_); - if (!base::FeatureList::IsEnabled(network::features::kOutOfBlinkCSPEE) && - !ContentSecurityPolicy::IsValidCSPAttr( - required_csp_, GetDocument().RequiredCSP().GetString())) { - if (!required_csp_.IsEmpty()) { - GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( - mojom::ConsoleMessageSource::kOther, - mojom::ConsoleMessageLevel::kError, - "'csp' attribute is not a valid policy: " + required_csp_)); - } - if (required_csp_ != GetDocument().RequiredCSP()) { - required_csp_ = GetDocument().RequiredCSP(); - FrameOwnerPropertiesChanged(); - UseCounter::Count(GetDocument(), WebFeature::kIFrameCSPAttribute); - } - } - } LogAddElementIfIsolatedWorldAndInDocument("iframe", html_names::kSrcAttr); return result; } 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 7a27189bf89..0e1623f07bd 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 @@ -61,11 +61,6 @@ class CORE_EXPORT HTMLIFrameElement final return mojom::blink::FrameOwnerElementType::kIframe; } - network::mojom::blink::WebSandboxFlags - sandbox_flags_converted_to_feature_policies() const { - return sandbox_flags_converted_to_feature_policies_; - } - private: void SetCollapsed(bool) override; @@ -107,12 +102,6 @@ class CORE_EXPORT HTMLIFrameElement final bool collapsed_by_client_; Member<HTMLIFrameElementSandbox> sandbox_; Member<DOMFeaturePolicy> policy_; - // This represents a subset of sandbox flags set through 'sandbox' attribute - // that will be converted to feature policies as part of the container - // policies. - network::mojom::blink::WebSandboxFlags - sandbox_flags_converted_to_feature_policies_ = - network::mojom::blink::WebSandboxFlags::kNone; network::mojom::ReferrerPolicy referrer_policy_; }; diff --git a/chromium/third_party/blink/renderer/core/html/html_iframe_element_sandbox.cc b/chromium/third_party/blink/renderer/core/html/html_iframe_element_sandbox.cc index 2340322f86a..af5ae9b0320 100644 --- a/chromium/third_party/blink/renderer/core/html/html_iframe_element_sandbox.cc +++ b/chromium/third_party/blink/renderer/core/html/html_iframe_element_sandbox.cc @@ -33,10 +33,6 @@ const char* const kSupportedSandboxTokens[] = { constexpr char kStorageAccessAPISandboxToken[] = "allow-storage-access-by-user-activation"; -// TODO(crbug.com/1042130): move this into |kSupportedSandboxTokens| when the -// feature flag is enabled by default. -constexpr char kDeclarativeShadowDom[] = "allow-declarative-shadow-dom"; - bool IsTokenSupported(const AtomicString& token) { for (const char* supported_token : kSupportedSandboxTokens) { if (token == supported_token) @@ -51,14 +47,6 @@ bool IsTokenSupported(const AtomicString& token) { return true; } - // If Declarative Shadow DOM is enabled, allow the sandbox flag. - // TODO(crbug.com/1145605): This won't work for origin trial enabled iframe - // documents, because there's no ExecutionContext here. - if (RuntimeEnabledFeatures::DeclarativeShadowDOMEnabledByRuntimeFlag() && - (token == kDeclarativeShadowDom)) { - return true; - } - return false; } diff --git a/chromium/third_party/blink/renderer/core/html/html_iframe_element_test.cc b/chromium/third_party/blink/renderer/core/html/html_iframe_element_test.cc index f7ed45ffef0..32d553b87a5 100644 --- a/chromium/third_party/blink/renderer/core/html/html_iframe_element_test.cc +++ b/chromium/third_party/blink/renderer/core/html/html_iframe_element_test.cc @@ -17,8 +17,6 @@ namespace blink { -constexpr size_t expected_number_of_sandbox_features = 9; - class HTMLIFrameElementTest : public testing::Test { public: scoped_refptr<const SecurityOrigin> GetOriginForFeaturePolicy( @@ -192,83 +190,6 @@ TEST_F(HTMLIFrameElementTest, AllowAttributeContainerPolicy) { container_policy2[1].allowed_origins.begin()->Serialize()); } -// Sandboxing an iframe should result in a container policy with an item for -// each sandbox feature -TEST_F(HTMLIFrameElementTest, SandboxAttributeContainerPolicy) { - ASSERT_TRUE(RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()); - - frame_element_->setAttribute(html_names::kSandboxAttr, ""); - frame_element_->UpdateContainerPolicyForTests(); - - const ParsedFeaturePolicy& container_policy = - frame_element_->GetFramePolicy().container_policy; - - EXPECT_EQ(expected_number_of_sandbox_features, container_policy.size()); -} - -// Test that the allow attribute on a sandboxed frame results in a container -// policy which is restricted to a unique origin. -TEST_F(HTMLIFrameElementTest, CrossOriginSandboxAttributeContainerPolicy) { - ASSERT_TRUE(RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()); - - frame_element_->setAttribute(html_names::kSrcAttr, "http://example.net/"); - frame_element_->setAttribute(html_names::kAllowAttr, "fullscreen"); - frame_element_->setAttribute(html_names::kSandboxAttr, ""); - frame_element_->UpdateContainerPolicyForTests(); - - const ParsedFeaturePolicy& container_policy = - frame_element_->GetFramePolicy().container_policy; - - EXPECT_EQ(expected_number_of_sandbox_features + 1, container_policy.size()); - const auto& container_policy_item = - std::find_if(container_policy.begin(), container_policy.end(), - [](const auto& declaration) { - return declaration.feature == - mojom::blink::FeaturePolicyFeature::kFullscreen; - }); - EXPECT_NE(container_policy_item, container_policy.end()) - << "Fullscreen feature not found in container policy"; - - const ParsedFeaturePolicyDeclaration item = *container_policy_item; - EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kFullscreen, item.feature); - EXPECT_FALSE(item.matches_all_origins); - EXPECT_TRUE(item.matches_opaque_src); - EXPECT_EQ(0UL, item.allowed_origins.size()); -} - -// Test that the allow attribute on a sandboxed frame with the allow-same-origin -// flag results in a container policy which is restricted to the origin of the -// containing document. -TEST_F(HTMLIFrameElementTest, SameOriginSandboxAttributeContainerPolicy) { - ASSERT_TRUE(RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()); - - frame_element_->setAttribute(html_names::kSrcAttr, "http://example.net/"); - frame_element_->setAttribute(html_names::kAllowAttr, "fullscreen"); - frame_element_->setAttribute(html_names::kSandboxAttr, "allow-same-origin"); - frame_element_->UpdateContainerPolicyForTests(); - - const ParsedFeaturePolicy& container_policy = - frame_element_->GetFramePolicy().container_policy; - - EXPECT_EQ(expected_number_of_sandbox_features + 1, container_policy.size()); - const auto& container_policy_item = - std::find_if(container_policy.begin(), container_policy.end(), - [](const auto& declaration) { - return declaration.feature == - mojom::blink::FeaturePolicyFeature::kFullscreen; - }); - EXPECT_NE(container_policy_item, container_policy.end()) - << "Fullscreen feature not found in container policy"; - - const ParsedFeaturePolicyDeclaration item = *container_policy_item; - EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kFullscreen, item.feature); - EXPECT_FALSE(item.matches_all_origins); - EXPECT_FALSE(item.matches_opaque_src); - EXPECT_EQ(1UL, item.allowed_origins.size()); - EXPECT_FALSE(item.allowed_origins.begin()->opaque()); - EXPECT_EQ("http://example.net", item.allowed_origins.begin()->Serialize()); -} - // Test the ConstructContainerPolicy method when no attributes are set on the // iframe element. TEST_F(HTMLIFrameElementTest, ConstructEmptyContainerPolicy) { @@ -403,26 +324,4 @@ TEST_F(HTMLIFrameElementSimTest, AllowAttributeParsingError) { << ConsoleMessages().front(); } -TEST_F(HTMLIFrameElementSimTest, CommaSeparatorIsDeprecated) { - EXPECT_FALSE( - GetDocument().Loader()->GetUseCounterHelper().HasRecordedMeasurement( - WebFeature::kCommaSeparatorInAllowAttribute)); - SimRequest main_resource("https://example.com", "text/html"); - LoadURL("https://example.com"); - main_resource.Complete(R"( - <iframe - allow="fullscreen, geolocation"></iframe> - )"); - - EXPECT_EQ(ConsoleMessages().size(), 1u) - << "Comma separator in allow attribute should log a deprecation message " - "to the console."; - EXPECT_TRUE(ConsoleMessages().front().Contains("5740835259809792")) - << "Console message should mention the chromestatus entry."; - - EXPECT_TRUE( - GetDocument().Loader()->GetUseCounterHelper().HasRecordedMeasurement( - WebFeature::kCommaSeparatorInAllowAttribute)); -} - } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/html_image_element.cc b/chromium/third_party/blink/renderer/core/html/html_image_element.cc index 3ee7b73923c..2dd7e1dfd9b 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 @@ -108,6 +108,7 @@ HTMLImageElement::HTMLImageElement(Document& document, bool created_by_parser) !GetExecutionContext()->IsFeatureEnabled( mojom::blink::DocumentPolicyFeature::kUnsizedMedia)), is_legacy_format_or_unoptimized_image_(false), + is_ad_related_(false), referrer_policy_(network::mojom::ReferrerPolicy::kDefault) { SetHasCustomStyleCallbacks(); } @@ -197,6 +198,39 @@ void HTMLImageElement::CollectStyleForPresentationAttribute( } } +void HTMLImageElement::CollectExtraStyleForPresentationAttribute( + MutableCSSPropertyValueSet* style) { + if (!source_) + return; + + const AtomicString& width = source_->FastGetAttribute(html_names::kWidthAttr); + const AtomicString& height = + source_->FastGetAttribute(html_names::kHeightAttr); + if (!width && !height) + return; + + if (width) { + AddHTMLLengthToStyle(style, CSSPropertyID::kWidth, width); + } else { + AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kWidth, + CSSValueID::kAuto); + } + + if (height) { + AddHTMLLengthToStyle(style, CSSPropertyID::kHeight, height); + } else { + AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kHeight, + CSSValueID::kAuto); + } + + if (width && height) { + ApplyAspectRatioToStyle(width, height, style); + } else { + AddPropertyToPresentationAttributeStyle(style, CSSPropertyID::kAspectRatio, + CSSValueID::kAuto); + } +} + const AtomicString HTMLImageElement::ImageSourceURL() const { return best_fit_image_url_.IsNull() ? FastGetAttribute(html_names::kSrcAttr) : best_fit_image_url_; @@ -343,6 +377,13 @@ String HTMLImageElement::AltText() const { return FastGetAttribute(html_names::kTitleAttr); } +void HTMLImageElement::InvalidateAttributeMapping() { + EnsureUniqueElementData().SetPresentationAttributeStyleIsDirty(true); + SetNeedsStyleRecalc(kLocalStyleChange, + StyleChangeReasonForTracing::Create( + style_change_reason::kPictureSourceChanged)); +} + bool HTMLImageElement::SupportedImageType( const String& type, const HashSet<String>* disabled_image_types) { @@ -461,6 +502,7 @@ Node::InsertionNotificationRequest HTMLImageElement::InsertedInto( if (GetDocument().IsActive() && was_added_to_picture_parent) { ImageCandidate candidate = FindBestFitImageFromPictureParent(); if (!candidate.IsEmpty()) { + InvalidateAttributeMapping(); SetBestFitURLAndDPRFromImageCandidate(candidate); image_was_modified = true; } @@ -475,6 +517,7 @@ Node::InsertionNotificationRequest HTMLImageElement::InsertedInto( } void HTMLImageElement::RemovedFrom(ContainerNode& insertion_point) { + InvalidateAttributeMapping(); if (!form_ || NodeTraversal::HighestAncestorOrSelf(*form_.Get()) != NodeTraversal::HighestAncestorOrSelf(*this)) ResetFormOwner(); @@ -501,9 +544,7 @@ unsigned HTMLImageElement::width() { // if the image is available, use its width if (ImageResourceContent* image_content = GetImageLoader().GetContent()) { - return image_content - ->IntrinsicSize(LayoutObject::ShouldRespectImageOrientation(nullptr)) - .Width(); + return image_content->IntrinsicSize(kRespectImageOrientation).Width(); } } @@ -525,9 +566,7 @@ unsigned HTMLImageElement::height() { // if the image is available, use its height if (ImageResourceContent* image_content = GetImageLoader().GetContent()) { - return image_content - ->IntrinsicSize(LayoutObject::ShouldRespectImageOrientation(nullptr)) - .Height(); + return image_content->IntrinsicSize(kRespectImageOrientation).Height(); } } @@ -755,7 +794,10 @@ void HTMLImageElement::SelectSourceURL( ImageLoader::UpdateFromElementBehavior behavior) { if (!GetDocument().IsActive()) return; + // TODO(crbug.com/1175295): Remove this CHECK once the investigation is done. + CHECK(GetDocument().GetExecutionContext()); + HTMLSourceElement* old_source = source_; ImageCandidate candidate = FindBestFitImageFromPictureParent(); if (candidate.IsEmpty()) { candidate = BestFitSourceForImageAttributes( @@ -763,6 +805,8 @@ void HTMLImageElement::SelectSourceURL( FastGetAttribute(html_names::kSrcAttr), FastGetAttribute(html_names::kSrcsetAttr), &GetDocument()); } + if (old_source != source_) + InvalidateAttributeMapping(); AtomicString old_url = best_fit_image_url_; SetBestFitURLAndDPRFromImageCandidate(candidate); @@ -848,13 +892,15 @@ void HTMLImageElement::SetLayoutDisposition( SetForceReattachLayoutTree(); } -scoped_refptr<ComputedStyle> HTMLImageElement::CustomStyleForLayoutObject() { +scoped_refptr<ComputedStyle> HTMLImageElement::CustomStyleForLayoutObject( + const StyleRecalcContext& style_recalc_context) { switch (layout_disposition_) { case LayoutDisposition::kPrimaryContent: // Fall through. case LayoutDisposition::kCollapsed: - return OriginalStyleForLayoutObject(); + return OriginalStyleForLayoutObject(style_recalc_context); case LayoutDisposition::kFallbackContent: { - scoped_refptr<ComputedStyle> style = OriginalStyleForLayoutObject(); + scoped_refptr<ComputedStyle> style = + OriginalStyleForLayoutObject(style_recalc_context); HTMLImageFallbackHelper::CustomStyleForAltText(*this, *style); return style; } 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 35dfdaacb76..3d6b773a7ff 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 @@ -181,6 +181,8 @@ class CORE_EXPORT HTMLImageElement final void SetIsAdRelated() { is_ad_related_ = true; } bool IsAdRelated() const override { return is_ad_related_; } + void InvalidateAttributeMapping(); + static bool SupportedImageType(const String& type, const HashSet<String>* disabled_image_types); @@ -204,7 +206,8 @@ class CORE_EXPORT HTMLImageElement final void DidMoveToNewDocument(Document& old_document) override; void DidAddUserAgentShadowRoot(ShadowRoot&) override; - scoped_refptr<ComputedStyle> CustomStyleForLayoutObject() override; + scoped_refptr<ComputedStyle> CustomStyleForLayoutObject( + const StyleRecalcContext&) override; private: bool AreAuthorShadowsAllowed() const override { return false; } @@ -215,6 +218,12 @@ class CORE_EXPORT HTMLImageElement final const QualifiedName&, const AtomicString&, MutableCSSPropertyValueSet*) override; + // For mapping attributes from the <source> element, if any. + bool HasExtraStyleForPresentationAttribute() const override { + return source_; + } + void CollectExtraStyleForPresentationAttribute( + MutableCSSPropertyValueSet*) override; void SetLayoutDisposition(LayoutDisposition, bool force_reattach = false); void AttachLayoutTree(AttachContext&) override; @@ -259,13 +268,12 @@ class CORE_EXPORT HTMLImageElement final // policies. When any policy is violated, the image should be rendered as a // placeholder image. bool is_legacy_format_or_unoptimized_image_ : 1; + bool is_ad_related_ : 1; network::mojom::ReferrerPolicy referrer_policy_; std::unique_ptr<LazyLoadImageObserver::VisibleLoadTimeMetrics> visible_load_time_metrics_; - - bool is_ad_related_ = false; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/html_li_element.cc b/chromium/third_party/blink/renderer/core/html/html_li_element.cc index b69d9524afb..f1bab3c76ad 100644 --- a/chromium/third_party/blink/renderer/core/html/html_li_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_li_element.cc @@ -22,6 +22,7 @@ #include "third_party/blink/renderer/core/html/html_li_element.h" +#include "third_party/blink/renderer/core/css/css_custom_ident_value.h" #include "third_party/blink/renderer/core/css/css_property_names.h" #include "third_party/blink/renderer/core/css_value_keywords.h" #include "third_party/blink/renderer/core/dom/document.h" @@ -41,26 +42,24 @@ bool HTMLLIElement::IsPresentationAttribute(const QualifiedName& name) const { return HTMLElement::IsPresentationAttribute(name); } -CSSValueID ListTypeToCSSValueID(const AtomicString& value) { +AtomicString ListTypeAttributeToStyleName(const AtomicString& value) { if (value == "a") - return CSSValueID::kLowerAlpha; + return "lower-alpha"; if (value == "A") - return CSSValueID::kUpperAlpha; + return "upper-alpha"; if (value == "i") - return CSSValueID::kLowerRoman; + return "lower-roman"; if (value == "I") - return CSSValueID::kUpperRoman; + return "upper-roman"; if (value == "1") - return CSSValueID::kDecimal; + return "decimal"; if (EqualIgnoringASCIICase(value, "disc")) - return CSSValueID::kDisc; + return "disc"; if (EqualIgnoringASCIICase(value, "circle")) - return CSSValueID::kCircle; + return "circle"; if (EqualIgnoringASCIICase(value, "square")) - return CSSValueID::kSquare; - if (EqualIgnoringASCIICase(value, "none")) - return CSSValueID::kNone; - return CSSValueID::kInvalid; + return "square"; + return g_null_atom; } void HTMLLIElement::CollectStyleForPresentationAttribute( @@ -68,10 +67,16 @@ void HTMLLIElement::CollectStyleForPresentationAttribute( const AtomicString& value, MutableCSSPropertyValueSet* style) { if (name == html_names::kTypeAttr) { - CSSValueID type_value = ListTypeToCSSValueID(value); - if (IsValidCSSValueID(type_value)) { + if (EqualIgnoringASCIICase(value, "none")) { AddPropertyToPresentationAttributeStyle( - style, CSSPropertyID::kListStyleType, type_value); + style, CSSPropertyID::kListStyleType, CSSValueID::kNone); + } else { + AtomicString list_style_type_name = ListTypeAttributeToStyleName(value); + if (!list_style_type_name.IsNull()) { + AddPropertyToPresentationAttributeStyle( + style, CSSPropertyID::kListStyleType, + *MakeGarbageCollected<CSSCustomIdentValue>(list_style_type_name)); + } } } else { HTMLElement::CollectStyleForPresentationAttribute(name, value, style); @@ -91,7 +96,6 @@ void HTMLLIElement::AttachLayoutTree(AttachContext& context) { HTMLElement::AttachLayoutTree(context); if (ListItemOrdinal* ordinal = ListItemOrdinal::Get(*this)) { - DCHECK(!GetDocument().ChildNeedsDistributionRecalc()); ParseValue(FastGetAttribute(html_names::kValueAttr), ordinal); } } diff --git a/chromium/third_party/blink/renderer/core/html/html_link_element.cc b/chromium/third_party/blink/renderer/core/html/html_link_element.cc index 9aee0c76a43..c4d2416e8c0 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 @@ -25,6 +25,8 @@ #include "third_party/blink/renderer/core/html/html_link_element.h" +#include <utility> + #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/public/platform/web_icon_sizes_parser.h" #include "third_party/blink/public/platform/web_prescient_networking.h" @@ -53,6 +55,23 @@ namespace blink { +namespace { + +void ParseUrlsListValue(const AtomicString& value, HashSet<KURL>& url_hash) { + // Parse the attribute value as a space-separated list of urls + SpaceSplitString urls(value); + url_hash.clear(); + url_hash.ReserveCapacityForSize(SafeCast<wtf_size_t>(urls.size())); + for (wtf_size_t i = 0; i < urls.size(); ++i) { + KURL url = LinkWebBundle::ParseResourceUrl(urls[i]); + if (url.IsValid()) { + url_hash.insert(std::move(url)); + } + } +} + +} // namespace + HTMLLinkElement::HTMLLinkElement(Document& document, const CreateElementFlags flags) : HTMLElement(html_names::kLinkTag, document), @@ -64,6 +83,8 @@ HTMLLinkElement::HTMLLinkElement(Document& document, resources_( MakeGarbageCollected<DOMTokenList>(*this, html_names::kResourcesAttr)), + scopes_( + MakeGarbageCollected<DOMTokenList>(*this, html_names::kScopesAttr)), created_by_parser_(flags.IsCreatedByParser()) {} HTMLLinkElement::~HTMLLinkElement() = default; @@ -134,9 +155,6 @@ void HTMLLinkElement::ParseAttribute( } else if (name == html_names::kMediaAttr) { media_ = value.LowerASCII(); Process(); - } else if (name == html_names::kScopeAttr) { - scope_ = value; - Process(); } else if (name == html_names::kIntegrityAttr) { integrity_ = value; } else if (name == html_names::kImportanceAttr && @@ -145,21 +163,14 @@ void HTMLLinkElement::ParseAttribute( UseCounter::Count(GetDocument(), WebFeature::kPriorityHints); importance_ = value; } else if (name == html_names::kResourcesAttr && - RuntimeEnabledFeatures::SubresourceWebBundlesEnabled( - GetExecutionContext())) { + LinkWebBundle::IsFeatureEnabled(GetExecutionContext())) { resources_->DidUpdateAttributeValue(params.old_value, value); - - // Parse the attribute value as a space-separated list of urls - SpaceSplitString urls(value); - valid_resource_urls_.clear(); - valid_resource_urls_.ReserveCapacityForSize( - SafeCast<wtf_size_t>(urls.size())); - for (wtf_size_t i = 0; i < urls.size(); ++i) { - KURL url = LinkWebBundle::ParseResourceUrl(urls[i]); - if (url.IsValid()) { - valid_resource_urls_.insert(std::move(url)); - } - } + ParseUrlsListValue(value, valid_resource_urls_); + Process(); + } else if (name == html_names::kScopesAttr && + LinkWebBundle::IsFeatureEnabled(GetExecutionContext())) { + scopes_->DidUpdateAttributeValue(params.old_value, value); + ParseUrlsListValue(value, valid_scope_urls_); Process(); } else if (name == html_names::kDisabledAttr) { UseCounter::Count(GetDocument(), WebFeature::kHTMLLinkElementDisabled); @@ -220,9 +231,11 @@ bool HTMLLinkElement::LoadLink(const LinkLoadParameters& params) { void HTMLLinkElement::LoadStylesheet(const LinkLoadParameters& params, const WTF::TextEncoding& charset, FetchParameters::DeferOption defer_option, - ResourceClient* link_client) { + ResourceClient* link_client, + RenderBlockingBehavior render_blocking) { return link_loader_->LoadStylesheet(params, localName(), charset, - defer_option, GetDocument(), link_client); + defer_option, GetDocument(), link_client, + render_blocking); } LinkResource* HTMLLinkElement::LinkResourceToProcess() { @@ -245,8 +258,7 @@ LinkResource* HTMLLinkElement::LinkResourceToProcess() { link_ = MakeGarbageCollected<LinkImport>(this); } else if (rel_attribute_.IsWebBundle()) { // Only create a webbundle link when SubresourceWebBundles are enabled. - if (!RuntimeEnabledFeatures::SubresourceWebBundlesEnabled( - GetExecutionContext())) { + if (!LinkWebBundle::IsFeatureEnabled(GetExecutionContext())) { return nullptr; } link_ = MakeGarbageCollected<LinkWebBundle>(this); @@ -363,23 +375,6 @@ void HTMLLinkElement::LinkLoadingErrored() { DispatchEvent(*Event::Create(event_type_names::kError)); } -void HTMLLinkElement::DidStartLinkPrerender() { - DispatchEvent(*Event::Create(event_type_names::kWebkitprerenderstart)); -} - -void HTMLLinkElement::DidStopLinkPrerender() { - DispatchEvent(*Event::Create(event_type_names::kWebkitprerenderstop)); -} - -void HTMLLinkElement::DidSendLoadForLinkPrerender() { - DispatchEvent(*Event::Create(event_type_names::kWebkitprerenderload)); -} - -void HTMLLinkElement::DidSendDOMContentLoadedForLinkPrerender() { - DispatchEvent( - *Event::Create(event_type_names::kWebkitprerenderdomcontentloaded)); -} - scoped_refptr<base::SingleThreadTaskRunner> HTMLLinkElement::GetLoadingTaskRunner() { return GetDocument().GetTaskRunner(TaskType::kNetworking); @@ -414,10 +409,9 @@ void HTMLLinkElement::ScheduleEvent() { .GetTaskRunner(TaskType::kDOMManipulation) ->PostTask( FROM_HERE, - WTF::Bind(&HTMLLinkElement::DispatchPendingEvent, - WrapPersistent(this), - WTF::Passed(std::make_unique<IncrementLoadEventDelayCount>( - GetDocument())))); + WTF::Bind( + &HTMLLinkElement::DispatchPendingEvent, WrapPersistent(this), + std::make_unique<IncrementLoadEventDelayCount>(GetDocument()))); } void HTMLLinkElement::StartLoadingDynamicSheet() { @@ -481,12 +475,17 @@ DOMTokenList* HTMLLinkElement::resources() const { return resources_.Get(); } +DOMTokenList* HTMLLinkElement::scopes() const { + return scopes_.Get(); +} + void HTMLLinkElement::Trace(Visitor* visitor) const { visitor->Trace(link_); visitor->Trace(sizes_); visitor->Trace(link_loader_); visitor->Trace(rel_list_); visitor->Trace(resources_); + visitor->Trace(scopes_); HTMLElement::Trace(visitor); LinkLoaderClient::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/html_link_element.h b/chromium/third_party/blink/renderer/core/html/html_link_element.h index d7231b65599..4cd11864713 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 @@ -69,7 +69,6 @@ class CORE_EXPORT HTMLLinkElement final : public HTMLElement, DOMTokenList& relList() const { return static_cast<DOMTokenList&>(*rel_list_); } - String Scope() const { return scope_; } const AtomicString& GetType() const; @@ -99,10 +98,12 @@ class CORE_EXPORT HTMLLinkElement final : public HTMLElement, // IDL method. DOMTokenList* resources() const; + DOMTokenList* scopes() const; const HashSet<KURL>& ValidResourceUrls() const { return valid_resource_urls_; } + const HashSet<KURL>& ValidScopeUrls() const { return valid_scope_urls_; } void ScheduleEvent(); @@ -115,7 +116,8 @@ class CORE_EXPORT HTMLLinkElement final : public HTMLElement, void LoadStylesheet(const LinkLoadParameters&, const WTF::TextEncoding&, FetchParameters::DeferOption, - ResourceClient*); + ResourceClient*, + RenderBlockingBehavior render_blocking); bool IsAlternate() const { // TODO(crbug.com/1087043): Remove this if() condition once the feature has // landed and no compat issues are reported. @@ -162,10 +164,6 @@ class CORE_EXPORT HTMLLinkElement final : public HTMLElement, // From LinkLoaderClient void LinkLoaded() override; void LinkLoadingErrored() override; - void DidStartLinkPrerender() override; - void DidStopLinkPrerender() override; - void DidSendLoadForLinkPrerender() override; - void DidSendDOMContentLoadedForLinkPrerender() override; scoped_refptr<base::SingleThreadTaskRunner> GetLoadingTaskRunner() override; Member<LinkResource> link_; @@ -181,9 +179,10 @@ class CORE_EXPORT HTMLLinkElement final : public HTMLElement, Vector<gfx::Size> icon_sizes_; Member<RelList> rel_list_; LinkRelAttribute rel_attribute_; - String scope_; Member<DOMTokenList> resources_; HashSet<KURL> valid_resource_urls_; + Member<DOMTokenList> scopes_; + HashSet<KURL> valid_scope_urls_; bool created_by_parser_; }; diff --git a/chromium/third_party/blink/renderer/core/html/html_link_element.idl b/chromium/third_party/blink/renderer/core/html/html_link_element.idl index 80a95e7ac4c..5856df7c67b 100644 --- a/chromium/third_party/blink/renderer/core/html/html_link_element.idl +++ b/chromium/third_party/blink/renderer/core/html/html_link_element.idl @@ -58,5 +58,6 @@ // Subresource loading with Web Bundles // https://github.com/WICG/webpackage/blob/master/explainers/subresource-loading.md // crbug.com/1082020 - [RuntimeEnabled=SubresourceWebBundles, PutForwards=value] readonly attribute DOMTokenList resources; + [RuntimeEnabled=SubresourceWebBundles, PutForwards=value, SecureContext] readonly attribute DOMTokenList resources; + [RuntimeEnabled=SubresourceWebBundles, PutForwards=value, SecureContext] readonly attribute DOMTokenList scopes; }; 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 fd0b909f61e..ac2d2fd38b3 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 @@ -39,6 +39,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/platform/heap/heap.h" +#include "third_party/blink/renderer/platform/weborigin/security_policy.h" #include "third_party/blink/renderer/platform/wtf/text/string_to_number.h" namespace blink { @@ -589,26 +590,17 @@ void HTMLMetaElement::ProcessContent() { UseCounter::Count(&GetDocument(), WebFeature::kHTMLMetaElementReferrerPolicyOutsideHead); } - bool comma_in_content_value = false; - if (content_value.Contains(',')) { - comma_in_content_value = true; - UseCounter::Count( - &GetDocument(), - WebFeature::kHTMLMetaElementReferrerPolicyMultipleTokens); - } - GetExecutionContext()->ParseAndSetReferrerPolicy( - content_value, true /* support legacy keywords */, - /*from_meta_tag_with_list_of_policies=*/ - comma_in_content_value); + GetExecutionContext()->ParseAndSetReferrerPolicy(content_value, + kPolicySourceMetaTag); if (base::FeatureList::IsEnabled(blink::features::kPolicyContainer)) { LocalFrame* frame = GetDocument().GetFrame(); // If frame is null, this document is not attached to a frame, hence it - // has no Policy Container, so we ignore the next step. This function will + // has no PolicyContainer, so we ignore the next step. This function will // run again anyway, should this document or this element be attached to a // frame. if (frame) { - GetDocument().GetFrame()->GetPolicyContainer()->UpdateReferrerPolicy( + frame->GetPolicyContainer()->UpdateReferrerPolicy( GetExecutionContext()->GetReferrerPolicy()); } } @@ -649,4 +641,4 @@ const AtomicString& HTMLMetaElement::HttpEquiv() const { const AtomicString& HTMLMetaElement::GetName() const { return FastGetAttribute(html_names::kNameAttr); } -} +} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/html_meta_element_test.cc b/chromium/third_party/blink/renderer/core/html/html_meta_element_test.cc index f2ac9d6711d..c317a16fdde 100644 --- a/chromium/third_party/blink/renderer/core/html/html_meta_element_test.cc +++ b/chromium/third_party/blink/renderer/core/html/html_meta_element_test.cc @@ -13,6 +13,7 @@ #include "third_party/blink/renderer/core/css/style_engine.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/node_computed_style.h" +#include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/core/frame/viewport_data.h" #include "third_party/blink/renderer/core/html/html_head_element.h" @@ -244,12 +245,21 @@ TEST_F(HTMLMetaElementTest, ColorSchemeForcedDarkeningAndMQ) { } TEST_F(HTMLMetaElementTest, ReferrerPolicyWithoutContent) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature(features::kPolicyContainer); + + MockPolicyContainerHost policy_container_host; + GetFrame().SetPolicyContainer(std::make_unique<PolicyContainer>( + policy_container_host.BindNewEndpointAndPassDedicatedRemote(), + mojom::blink::PolicyContainerPolicies::New())); + EXPECT_CALL(policy_container_host, + SetReferrerPolicy(network::mojom::ReferrerPolicy::kStrictOrigin)); + GetDocument().head()->setInnerHTML(R"HTML( <meta name="referrer" content="strict-origin"> <meta name="referrer" > )HTML"); - EXPECT_EQ(network::mojom::ReferrerPolicy::kStrictOrigin, - GetDocument().GetReferrerPolicy()); + policy_container_host.FlushForTesting(); } TEST_F(HTMLMetaElementTest, ReferrerPolicyUpdatesPolicyContainer) { @@ -262,7 +272,7 @@ TEST_F(HTMLMetaElementTest, ReferrerPolicyUpdatesPolicyContainer) { policy_container_host.BindNewEndpointAndPassDedicatedRemote(); auto policy_container = std::make_unique<PolicyContainer>( std::move(stub_policy_container_remote), - mojom::blink::PolicyContainerDocumentPolicies::New()); + mojom::blink::PolicyContainerPolicies::New()); GetFrame().SetPolicyContainer(std::move(policy_container)); EXPECT_CALL(policy_container_host, diff --git a/chromium/third_party/blink/renderer/core/html/html_meter_element.h b/chromium/third_party/blink/renderer/core/html/html_meter_element.h index 620f2cbf7fc..ab6ddfc4294 100644 --- a/chromium/third_party/blink/renderer/core/html/html_meter_element.h +++ b/chromium/third_party/blink/renderer/core/html/html_meter_element.h @@ -33,6 +33,7 @@ class CORE_EXPORT HTMLMeterElement final : public HTMLElement { public: explicit HTMLMeterElement(Document&); + ~HTMLMeterElement() override; enum GaugeRegion { kGaugeRegionOptimum, @@ -66,8 +67,6 @@ class CORE_EXPORT HTMLMeterElement final : public HTMLElement { void Trace(Visitor*) const override; private: - ~HTMLMeterElement() override; - bool AreAuthorShadowsAllowed() const override { return false; } bool IsLabelable() const override { return true; } diff --git a/chromium/third_party/blink/renderer/core/html/html_no_embed_element.cc b/chromium/third_party/blink/renderer/core/html/html_no_embed_element.cc index 3f453f98bd9..691a6d389a7 100644 --- a/chromium/third_party/blink/renderer/core/html/html_no_embed_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_no_embed_element.cc @@ -42,8 +42,7 @@ HTMLNoEmbedElement::HTMLNoEmbedElement(Document& document) bool HTMLNoEmbedElement::LayoutObjectIsNeeded( const ComputedStyle& style) const { - if (GetDocument().GetFrame()->Loader().AllowPlugins( - kNotAboutToInstantiatePlugin)) + if (GetDocument().GetFrame()->Loader().AllowPlugins()) return false; return Element::LayoutObjectIsNeeded(style); } diff --git a/chromium/third_party/blink/renderer/core/html/html_object_element.cc b/chromium/third_party/blink/renderer/core/html/html_object_element.cc index 142d13904fd..2f29f9134c5 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 @@ -55,8 +55,6 @@ HTMLObjectElement::HTMLObjectElement(Document& document, EnsureUserAgentShadowRoot(); } -inline HTMLObjectElement::~HTMLObjectElement() = default; - void HTMLObjectElement::Trace(Visitor* visitor) const { ListedElement::Trace(visitor); HTMLPlugInElement::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/core/html/html_object_element.h b/chromium/third_party/blink/renderer/core/html/html_object_element.h index 23a896a7065..45065ee7121 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 @@ -44,7 +44,7 @@ class CORE_EXPORT HTMLObjectElement final : public HTMLPlugInElement, public: HTMLObjectElement(Document&, const CreateElementFlags); - ~HTMLObjectElement() override; + ~HTMLObjectElement() override = default; void Trace(Visitor*) const override; // Returns attributes that should be checked against Trusted Types diff --git a/chromium/third_party/blink/renderer/core/html/html_olist_element.cc b/chromium/third_party/blink/renderer/core/html/html_olist_element.cc index 48581eb8040..ad05ff09971 100644 --- a/chromium/third_party/blink/renderer/core/html/html_olist_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_olist_element.cc @@ -22,8 +22,8 @@ #include "third_party/blink/renderer/core/html/html_olist_element.h" +#include "third_party/blink/renderer/core/css/css_custom_ident_value.h" #include "third_party/blink/renderer/core/css/css_property_names.h" -#include "third_party/blink/renderer/core/css_value_keywords.h" #include "third_party/blink/renderer/core/html/list_item_ordinal.h" #include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h" #include "third_party/blink/renderer/core/html_names.h" @@ -54,19 +54,24 @@ void HTMLOListElement::CollectStyleForPresentationAttribute( if (name == html_names::kTypeAttr) { if (value == "a") { AddPropertyToPresentationAttributeStyle( - style, CSSPropertyID::kListStyleType, CSSValueID::kLowerAlpha); + style, CSSPropertyID::kListStyleType, + *MakeGarbageCollected<CSSCustomIdentValue>("lower-alpha")); } else if (value == "A") { AddPropertyToPresentationAttributeStyle( - style, CSSPropertyID::kListStyleType, CSSValueID::kUpperAlpha); + style, CSSPropertyID::kListStyleType, + *MakeGarbageCollected<CSSCustomIdentValue>("upper-alpha")); } else if (value == "i") { AddPropertyToPresentationAttributeStyle( - style, CSSPropertyID::kListStyleType, CSSValueID::kLowerRoman); + style, CSSPropertyID::kListStyleType, + *MakeGarbageCollected<CSSCustomIdentValue>("lower-roman")); } else if (value == "I") { AddPropertyToPresentationAttributeStyle( - style, CSSPropertyID::kListStyleType, CSSValueID::kUpperRoman); + style, CSSPropertyID::kListStyleType, + *MakeGarbageCollected<CSSCustomIdentValue>("upper-roman")); } else if (value == "1") { AddPropertyToPresentationAttributeStyle( - style, CSSPropertyID::kListStyleType, CSSValueID::kDecimal); + style, CSSPropertyID::kListStyleType, + *MakeGarbageCollected<CSSCustomIdentValue>("decimal")); } } else { HTMLElement::CollectStyleForPresentationAttribute(name, value, style); @@ -102,7 +107,6 @@ void HTMLOListElement::setStart(int start) { void HTMLOListElement::UpdateItemValues() { if (!GetLayoutObject()) return; - UpdateDistributionForFlatTreeTraversal(); ListItemOrdinal::InvalidateAllItemsForOrderedList(this); } diff --git a/chromium/third_party/blink/renderer/core/html/html_or_foreign_element.idl b/chromium/third_party/blink/renderer/core/html/html_or_foreign_element.idl index a49710e81fa..486da823b35 100644 --- a/chromium/third_party/blink/renderer/core/html/html_or_foreign_element.idl +++ b/chromium/third_party/blink/renderer/core/html/html_or_foreign_element.idl @@ -10,7 +10,7 @@ interface mixin HTMLOrForeignElement { [CEReactions] attribute DOMString nonce; [CEReactions, Reflect] attribute boolean autofocus; - [Affects=Nothing, CEReactions, CustomElementCallbacks] attribute long tabIndex; + [Affects=Nothing, CEReactions] attribute long tabIndex; void focus(optional FocusOptions options = {}); void blur(); }; 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 d6a71246fe7..8b96d350041 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 @@ -27,6 +27,15 @@ void HTMLPictureElement::SourceOrMediaChanged() { } } +void HTMLPictureElement::SourceAttributeChanged() { + for (HTMLImageElement* image_element = + Traversal<HTMLImageElement>::FirstChild(*this); + image_element; image_element = Traversal<HTMLImageElement>::NextSibling( + *image_element)) { + image_element->InvalidateAttributeMapping(); + } +} + void HTMLPictureElement::RemoveListenerFromSourceChildren() { for (HTMLSourceElement* source_element = Traversal<HTMLSourceElement>::FirstChild(*this); 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 65fe13e7cf7..48dee7b5f39 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 @@ -16,6 +16,7 @@ class HTMLPictureElement final : public HTMLElement { explicit HTMLPictureElement(Document&); void SourceOrMediaChanged(); + void SourceAttributeChanged(); void RemoveListenerFromSourceChildren(); void AddListenerToSourceChildren(); 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 675f683a392..02f9782ab4f 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 @@ -132,7 +132,7 @@ HTMLPlugInElement::HTMLPlugInElement( if (auto* context = doc.GetExecutionContext()) { context->GetScheduler()->RegisterStickyFeature( SchedulingPolicy::Feature::kContainsPlugins, - {SchedulingPolicy::RecordMetricsForBackForwardCache()}); + {SchedulingPolicy::DisableBackForwardCache()}); } } @@ -646,7 +646,7 @@ bool HTMLPlugInElement::LoadPlugin(const KURL& url, return false; LocalFrame* frame = GetDocument().GetFrame(); - if (!frame->Loader().AllowPlugins(kAboutToInstantiatePlugin)) + if (!frame->Loader().AllowPlugins()) return false; auto* layout_object = GetLayoutEmbeddedObject(); @@ -712,8 +712,7 @@ bool HTMLPlugInElement::AllowedToLoadObject(const KURL& url, AtomicString declared_mime_type = FastGetAttribute(html_names::kTypeAttr); auto* csp = GetExecutionContext()->GetContentSecurityPolicy(); - if (!csp->AllowObjectFromSource(url) || - !csp->AllowPluginType(mime_type, declared_mime_type, url)) { + if (!csp->AllowObjectFromSource(url)) { if (auto* layout_object = GetLayoutEmbeddedObject()) { plugin_is_available_ = false; layout_object->SetPluginAvailability( @@ -799,8 +798,10 @@ void HTMLPlugInElement::UpdateServiceTypeIfEmpty() { } } -scoped_refptr<ComputedStyle> HTMLPlugInElement::CustomStyleForLayoutObject() { - scoped_refptr<ComputedStyle> style = OriginalStyleForLayoutObject(); +scoped_refptr<ComputedStyle> HTMLPlugInElement::CustomStyleForLayoutObject( + const StyleRecalcContext& style_recalc_context) { + scoped_refptr<ComputedStyle> style = + OriginalStyleForLayoutObject(style_recalc_context); if (IsImageType() && !GetLayoutObject() && style && LayoutObjectIsNeeded(*style)) { if (!image_loader_) 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 7fb6e7bb01a..3512c61bf42 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 @@ -172,7 +172,8 @@ class CORE_EXPORT HTMLPlugInElement bool IsFocusableStyle() const final; bool IsKeyboardFocusable() const final; void DidAddUserAgentShadowRoot(ShadowRoot&) final; - scoped_refptr<ComputedStyle> CustomStyleForLayoutObject() final; + scoped_refptr<ComputedStyle> CustomStyleForLayoutObject( + const StyleRecalcContext&) final; // HTMLElement overrides: bool HasCustomFocusLogic() const override; diff --git a/chromium/third_party/blink/renderer/core/html/html_popup_element.cc b/chromium/third_party/blink/renderer/core/html/html_popup_element.cc new file mode 100644 index 00000000000..c7654c925f2 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/html_popup_element.cc @@ -0,0 +1,148 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use 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_popup_element.h" + +#include "third_party/blink/renderer/core/css/style_change_reason.h" +#include "third_party/blink/renderer/core/dom/events/event.h" +#include "third_party/blink/renderer/core/events/keyboard_event.h" +#include "third_party/blink/renderer/core/frame/web_feature.h" +#include "third_party/blink/renderer/platform/instrumentation/use_counter.h" + +namespace blink { + +HTMLPopupElement::HTMLPopupElement(Document& document) + : HTMLElement(html_names::kPopupTag, document), open_(false) { + DCHECK(RuntimeEnabledFeatures::HTMLPopupElementEnabled()); + UseCounter::Count(document, WebFeature::kPopupElement); +} + + +void HTMLPopupElement::MarkStyleDirty() { + SetNeedsStyleRecalc(kLocalStyleChange, + StyleChangeReasonForTracing::Create( + style_change_reason::kPopupVisibilityChange)); +} + +bool HTMLPopupElement::open() const { + return open_; +} + +void HTMLPopupElement::hide() { + if (!open_) + return; + GetDocument().HideAllPopupsUntil(this); + PopPopupElement(this); + open_ = false; + PseudoStateChanged(CSSSelector::kPseudoPopupOpen); + MarkStyleDirty(); + ScheduleHideEvent(); +} + +void HTMLPopupElement::ScheduleHideEvent() { + Event* event = Event::Create(event_type_names::kHide); + event->SetTarget(this); + GetDocument().EnqueueAnimationFrameEvent(event); +} + +void HTMLPopupElement::show() { + if (open_ || !isConnected()) + return; + + // Only hide popups up to the anchor element's nearest shadow-including + // ancestor popup element. + HTMLPopupElement* parent_popup = nullptr; + if (Element* anchor = AnchorElement()) { + for (Node* ancestor = anchor; ancestor; + ancestor = ancestor->ParentOrShadowHostNode()) { + if (HTMLPopupElement* ancestor_popup = + DynamicTo<HTMLPopupElement>(ancestor)) { + parent_popup = ancestor_popup; + break; + } + } + } + GetDocument().HideAllPopupsUntil(parent_popup); + open_ = true; + PseudoStateChanged(CSSSelector::kPseudoPopupOpen); + PushNewPopupElement(this); + MarkStyleDirty(); +} + +void HTMLPopupElement::PushNewPopupElement(HTMLPopupElement* popup) { + auto& stack = GetDocument().PopupElementStack(); + DCHECK(!stack.Contains(popup)); + stack.push_back(popup); + GetDocument().AddToTopLayer(popup); +} + +void HTMLPopupElement::PopPopupElement(HTMLPopupElement* popup) { + auto& stack = GetDocument().PopupElementStack(); + DCHECK(stack.back() == popup); + stack.pop_back(); + GetDocument().RemoveFromTopLayer(popup); +} + +HTMLPopupElement* HTMLPopupElement::TopmostPopupElement() { + auto& stack = GetDocument().PopupElementStack(); + return stack.IsEmpty() ? nullptr : stack.back(); +} + +Element* HTMLPopupElement::AnchorElement() const { + const AtomicString& anchor_id = FastGetAttribute(html_names::kAnchorAttr); + if (anchor_id.IsNull()) + return nullptr; + if (!IsInTreeScope()) + return nullptr; + if (Element* anchor = GetTreeScope().getElementById(anchor_id)) + return anchor; + return nullptr; +} + +void HTMLPopupElement::HandleLightDismiss(const Event& event) { + auto* target_node = event.target()->ToNode(); + if (!target_node) + return; + auto& document = target_node->GetDocument(); + DCHECK(document.PopupShowing()); + const AtomicString& event_type = event.type(); + if (event_type == event_type_names::kClick) { + // We need to walk up from the clicked element to see if there + // is a parent popup, or the anchor for a popup. There can be + // multiple popups for a single anchor element, but we will + // stop on any of them. Therefore, just store the popup that + // is highest (last) on the popup stack for each anchor. + HeapHashMap<Member<const Element>, Member<const HTMLPopupElement>> anchors; + for (auto popup : document.PopupElementStack()) { + if (auto* anchor = popup->AnchorElement()) { + anchors.Set(anchor, popup); + } + } + const HTMLPopupElement* closest_popup_parent = nullptr; + for (Node* current_node = target_node; current_node; + current_node = current_node->parentNode()) { + if (auto* popup = DynamicTo<HTMLPopupElement>(current_node)) { + closest_popup_parent = popup; + break; + } + Element* current_element = DynamicTo<Element>(current_node); + if (current_element && anchors.Contains(current_element)) { + closest_popup_parent = anchors.at(current_element); + break; + } + } + document.HideAllPopupsUntil(closest_popup_parent); + } else if (event_type == event_type_names::kKeydown) { + const KeyboardEvent* key_event = DynamicTo<KeyboardEvent>(event); + if (key_event && key_event->key() == "Escape") { + // Escape key just pops the topmost <popup> off the stack. + document.HideTopmostPopupElement(); + } + } else if (event_type == event_type_names::kScroll) { + // Close all popups upon scroll. + document.HideAllPopupsUntil(nullptr); + } +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/html_popup_element.h b/chromium/third_party/blink/renderer/core/html/html_popup_element.h new file mode 100644 index 00000000000..f374a7c4d92 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/html_popup_element.h @@ -0,0 +1,48 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use 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_HTML_POPUP_ELEMENT_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_POPUP_ELEMENT_H_ + +#include "third_party/blink/renderer/core/html/html_element.h" +#include "third_party/blink/renderer/platform/geometry/layout_unit.h" + +namespace blink { + +class Document; + +// The HTMLPopupElement implements the <popup> HTML element. The popup element +// can be used to construct a topmost popup dialog. This feature is still +// under development, and is not part of the HTML standard. It can be enabled +// by passing --enable-blink-features=HTMLPopupElement. See +// https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/Popup/explainer.md +// for more details. +class HTMLPopupElement final : public HTMLElement { + DEFINE_WRAPPERTYPEINFO(); + + public: + explicit HTMLPopupElement(Document&); + + bool open() const; + void hide(); + void show(); + + Element* AnchorElement() const; + + static void HandleLightDismiss(const Event&); + + private: + void ScheduleHideEvent(); + void MarkStyleDirty(); + + void PushNewPopupElement(HTMLPopupElement*); + void PopPopupElement(HTMLPopupElement*); + HTMLPopupElement* TopmostPopupElement(); + + bool open_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_POPUP_ELEMENT_H_ diff --git a/chromium/third_party/blink/renderer/core/html/html_popup_element.idl b/chromium/third_party/blink/renderer/core/html/html_popup_element.idl new file mode 100644 index 00000000000..06d07b8a955 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/html_popup_element.idl @@ -0,0 +1,11 @@ +// Copyright 2021 The Chromium 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/MicrosoftEdge/MSEdgeExplainers/blob/main/Popup/explainer.md +[Exposed=Window,HTMLConstructor,RuntimeEnabled=HTMLPopupElement] +interface HTMLPopupElement : HTMLElement { + [CEReactions] readonly attribute boolean open; + [CEReactions, Measure] void show(); + [CEReactions, Measure] void hide(); +}; diff --git a/chromium/third_party/blink/renderer/core/html/html_progress_element.h b/chromium/third_party/blink/renderer/core/html/html_progress_element.h index 61bce3bfc06..756bf256eaa 100644 --- a/chromium/third_party/blink/renderer/core/html/html_progress_element.h +++ b/chromium/third_party/blink/renderer/core/html/html_progress_element.h @@ -37,6 +37,7 @@ class CORE_EXPORT HTMLProgressElement final : public HTMLElement { static const double kInvalidPosition; explicit HTMLProgressElement(Document&); + ~HTMLProgressElement() override; double value() const; void setValue(double); @@ -51,8 +52,6 @@ class CORE_EXPORT HTMLProgressElement final : public HTMLElement { void Trace(Visitor*) const override; private: - ~HTMLProgressElement() override; - bool AreAuthorShadowsAllowed() const override { return false; } bool ShouldAppearIndeterminate() const override; bool IsLabelable() const override { return true; } 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 692566bb50f..f6afbac3ed5 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 @@ -107,9 +107,10 @@ void HTMLScriptElement::ParseAttribute( Node::InsertionNotificationRequest HTMLScriptElement::InsertedInto( ContainerNode& insertion_point) { if (insertion_point.isConnected() && HasSourceAttribute() && - !ScriptLoader::IsValidScriptTypeAndLanguage( + ScriptLoader::GetScriptTypeAtPrepare( TypeAttributeValue(), LanguageAttributeValue(), - ScriptLoader::kDisallowLegacyTypeInTypeAttribute)) { + ScriptLoader::kDisallowLegacyTypeInTypeAttribute) == + ScriptLoader::ScriptTypeAtPrepare::kInvalid) { UseCounter::Count(GetDocument(), WebFeature::kScriptElementWithInvalidTypeHasSrc); } @@ -294,7 +295,7 @@ void HTMLScriptElement::DispatchErrorEvent() { void HTMLScriptElement::SetScriptElementForBinding( HTMLScriptElementOrSVGScriptElement& element) { - if (!IsInV1ShadowTree()) + if (!IsInShadowTree()) element.SetHTMLScriptElement(this); } diff --git a/chromium/third_party/blink/renderer/core/html/html_shadow_element.cc b/chromium/third_party/blink/renderer/core/html/html_shadow_element.cc deleted file mode 100644 index 7f91cb8cda8..00000000000 --- a/chromium/third_party/blink/renderer/core/html/html_shadow_element.cc +++ /dev/null @@ -1,51 +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/html/html_shadow_element.h" - -#include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/dom/shadow_root.h" -#include "third_party/blink/renderer/core/frame/web_feature.h" -#include "third_party/blink/renderer/core/html_names.h" -#include "third_party/blink/renderer/core/inspector/console_message.h" -#include "third_party/blink/renderer/platform/instrumentation/use_counter.h" - -namespace blink { - -class Document; - -HTMLShadowElement::HTMLShadowElement(Document& document) - : V0InsertionPoint(html_names::kShadowTag, document) { - UseCounter::Count(document, WebFeature::kHTMLShadowElement); -} - -HTMLShadowElement::~HTMLShadowElement() = default; - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/html_shadow_element.h b/chromium/third_party/blink/renderer/core/html/html_shadow_element.h deleted file mode 100644 index b804cf41f5f..00000000000 --- a/chromium/third_party/blink/renderer/core/html/html_shadow_element.h +++ /dev/null @@ -1,49 +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_HTML_HTML_SHADOW_ELEMENT_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_SHADOW_ELEMENT_H_ - -#include "third_party/blink/renderer/core/dom/v0_insertion_point.h" -#include "third_party/blink/renderer/platform/wtf/forward.h" - -namespace blink { - -class HTMLShadowElement final : public V0InsertionPoint { - DEFINE_WRAPPERTYPEINFO(); - - public: - explicit HTMLShadowElement(Document&); - ~HTMLShadowElement() override; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_SHADOW_ELEMENT_H_ diff --git a/chromium/third_party/blink/renderer/core/html/html_shadow_element.idl b/chromium/third_party/blink/renderer/core/html/html_shadow_element.idl deleted file mode 100644 index 1939442db51..00000000000 --- a/chromium/third_party/blink/renderer/core/html/html_shadow_element.idl +++ /dev/null @@ -1,37 +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. - */ - -// https://w3c.github.io/webcomponents/spec/shadow/#the-shadow-element - -[ - Exposed=Window -] interface HTMLShadowElement : HTMLElement { - NodeList getDistributedNodes(); -}; 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 2981d044c68..4044a4ae761 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 @@ -224,7 +224,7 @@ void HTMLSlotElement::assign(HeapVector<Member<Node>> nodes, if (candidates_changed) { assigned_nodes_candidates_.Swap(candidates); - ContainingShadowRoot()->GetSlotAssignment().SetNeedsAssignmentRecalc(); + SetShadowRootNeedsAssignmentRecalc(); DidSlotChange(SlotChangeType::kSignalSlotChangeEvent); } } @@ -357,9 +357,20 @@ void HTMLSlotElement::AttachLayoutTree(AttachContext& context) { void HTMLSlotElement::DetachLayoutTree(bool performing_reattach) { if (SupportsAssignment()) { + auto* host = OwnerShadowHost(); const HeapVector<Member<Node>>& flat_tree_children = assigned_nodes_; for (auto& node : flat_tree_children) { - if (node->GetDocument() == GetDocument()) + // Don't detach the assigned node if the node is no longer a child of the + // host. + // + // 1. It's no long a direct flat-tree child of this slot. + // 2. It was already detached when removed from the host. + // 3. It might already have been inserted in a different part of the DOM, + // or a new document tree and been attached. + // 4. It might have been marked style-dirty in its new location and + // calling DetachLayoutTree here would have incorrectly cleared those + // dirty bits. + if (host == node->parentNode()) node->DetachLayoutTree(performing_reattach); } } @@ -382,7 +393,7 @@ void HTMLSlotElement::AttributeChanged( const AttributeModificationParams& params) { if (params.name == html_names::kNameAttr) { if (ShadowRoot* root = ContainingShadowRoot()) { - if (root->IsV1() && params.old_value != params.new_value) { + if (params.old_value != params.new_value) { root->GetSlotAssignment().DidRenameSlot( NormalizeSlotName(params.old_value), *this); } @@ -397,7 +408,6 @@ Node::InsertionNotificationRequest HTMLSlotElement::InsertedInto( if (SupportsAssignment()) { ShadowRoot* root = ContainingShadowRoot(); DCHECK(root); - DCHECK(root->IsV1()); if (root == insertion_point.ContainingShadowRoot()) { // This slot is inserted into the same tree of |insertion_point| root->DidAddSlot(*this); @@ -420,13 +430,14 @@ 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 - // shadow tree. An inclusive shadow-including ancestor of the shadow host was - // originally removed from its parent. + // shadow tree. An inclusive shadow-including ancestor of the shadow host + // was originally removed from its parent. See slot s2 below. // 2. Or (this slot is not in a tree scope), this slot's inclusive - // ancestor was orginally removed from its parent (== insertion point). This - // slot and the originally removed node was in the same tree before removal. + // ancestor was orginally removed from its parent (== insertion point). + // This slot and the originally removed node was in the same tree before + // removal. See slot s1 below. - // For exmaple, given the following trees, (srN: = shadow root, sN: = slot) + // For example, given the following trees, (srN: = shadow root, sN: = slot) // a // |- b --sr1 // |- c |--d @@ -455,7 +466,7 @@ void HTMLSlotElement::RemovedFrom(ContainerNode& insertion_point) { // We don't need to clear |assigned_nodes_| here. That's an important // optimization. } - } else if (insertion_point.IsInV1ShadowTree()) { + } else if (insertion_point.IsInShadowTree()) { // 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). @@ -470,12 +481,13 @@ void HTMLSlotElement::RemovedFrom(ContainerNode& insertion_point) { } void HTMLSlotElement::RecalcStyleForSlotChildren( - const StyleRecalcChange change) { + const StyleRecalcChange change, + const StyleRecalcContext& style_recalc_context) { for (auto& node : flat_tree_children_) { if (!change.TraverseChild(*node)) continue; if (auto* element = DynamicTo<Element>(node.Get())) - element->RecalcStyle(change); + element->RecalcStyle(change, style_recalc_context); else if (auto* text_node = DynamicTo<Text>(node.Get())) text_node->RecalcTextStyle(change); } @@ -568,7 +580,7 @@ void HTMLSlotElement::DidSlotChangeAfterRemovedFromShadowTree() { void HTMLSlotElement::DidSlotChangeAfterRenaming() { DCHECK(SupportsAssignment()); EnqueueSlotChangeEvent(); - SetNeedsDistributionRecalcWillBeSetNeedsAssignmentRecalc(); + SetShadowRootNeedsAssignmentRecalc(); CheckSlotChange(SlotChangeType::kSuppressSlotChangeEvent); } @@ -682,8 +694,7 @@ void HTMLSlotElement::NotifySlottedNodesOfFlatTreeChangeNaive( } } -void HTMLSlotElement:: - SetNeedsDistributionRecalcWillBeSetNeedsAssignmentRecalc() { +void HTMLSlotElement::SetShadowRootNeedsAssignmentRecalc() { ContainingShadowRoot()->GetSlotAssignment().SetNeedsAssignmentRecalc(); } @@ -691,7 +702,7 @@ void HTMLSlotElement::DidSlotChange(SlotChangeType slot_change_type) { DCHECK(SupportsAssignment()); if (slot_change_type == SlotChangeType::kSignalSlotChangeEvent) EnqueueSlotChangeEvent(); - SetNeedsDistributionRecalcWillBeSetNeedsAssignmentRecalc(); + SetShadowRootNeedsAssignmentRecalc(); // Check slotchange recursively since this slotchange may cause another // slotchange. CheckSlotChange(SlotChangeType::kSuppressSlotChangeEvent); @@ -701,7 +712,7 @@ void HTMLSlotElement::CheckFallbackAfterInsertedIntoShadowTree() { DCHECK(SupportsAssignment()); if (HasSlotableChild()) { // We use kSuppress here because a slotchange event shouldn't be - // dispatched if a slot being inserted don't get any assigned + // dispatched if a slot being inserted doesn't get any assigned // node, but has a slotable child, according to DOM Standard. DidSlotChange(SlotChangeType::kSuppressSlotChangeEvent); } @@ -740,14 +751,19 @@ void HTMLSlotElement::EnqueueSlotChangeEvent() { bool HTMLSlotElement::HasAssignedNodesSlow() const { ShadowRoot* root = ContainingShadowRoot(); - DCHECK(root); - DCHECK(root->IsV1()); + DCHECK(root) << "This should only be called on slots inside a shadow tree"; SlotAssignment& assignment = root->GetSlotAssignment(); if (assignment.FindSlotByName(GetName()) != this) return false; return assignment.FindHostChildBySlotName(GetName()); } +void HTMLSlotElement::ChildrenChanged(const ChildrenChange& change) { + HTMLElement::ChildrenChanged(change); + if (SupportsAssignment()) + SetShadowRootNeedsAssignmentRecalc(); +} + void HTMLSlotElement::Trace(Visitor* visitor) const { visitor->Trace(assigned_nodes_); visitor->Trace(flat_tree_children_); 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 2e0b527ac04..ee2e2b5be9e 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 @@ -91,7 +91,7 @@ class CORE_EXPORT HTMLSlotElement final : public HTMLElement { // dirty. e.g. To detect a slotchange event in DOM mutations. bool HasAssignedNodesSlow() const; - bool SupportsAssignment() const { return IsInV1ShadowTree(); } + bool SupportsAssignment() const { return IsInShadowTree(); } void CheckFallbackAfterInsertedIntoShadowTree(); void CheckFallbackAfterRemovedFromShadowTree(); @@ -104,7 +104,8 @@ class CORE_EXPORT HTMLSlotElement final : public HTMLElement { static AtomicString NormalizeSlotName(const AtomicString&); - void RecalcStyleForSlotChildren(const StyleRecalcChange); + void RecalcStyleForSlotChildren(const StyleRecalcChange, + const StyleRecalcContext&); // For User-Agent Shadow DOM static const AtomicString& UserAgentCustomAssignSlotName(); @@ -124,6 +125,8 @@ class CORE_EXPORT HTMLSlotElement final : public HTMLElement { InsertionNotificationRequest InsertedInto(ContainerNode&) final; void RemovedFrom(ContainerNode&) final; + void ChildrenChanged(const ChildrenChange&) override; + void EnqueueSlotChangeEvent(); bool HasSlotableChild() const; @@ -138,7 +141,7 @@ class CORE_EXPORT HTMLSlotElement final : public HTMLElement { const HeapVector<Member<Node>>& old_slotted, const HeapVector<Member<Node>>& new_slotted); - void SetNeedsDistributionRecalcWillBeSetNeedsAssignmentRecalc(); + void SetShadowRootNeedsAssignmentRecalc(); bool CheckNodesValidity(HeapVector<Member<Node>> nodes, ExceptionState&); // SlotAssignnment:recalc runs in tree order. Update to assigned order. 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 b3e2f46957b..c2765fb2553 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 @@ -161,6 +161,17 @@ bool HTMLSourceElement::MediaQueryMatches() const { return media_query_list_->matches(); } +void HTMLSourceElement::AttributeChanged( + const AttributeModificationParams& params) { + const QualifiedName& name = params.name; + if (name == html_names::kWidthAttr || name == html_names::kHeightAttr) { + if (auto* picture = DynamicTo<HTMLPictureElement>(parentElement())) + picture->SourceAttributeChanged(); + } + + HTMLElement::AttributeChanged(params); +} + bool HTMLSourceElement::IsURLAttribute(const Attribute& attribute) const { return attribute.GetName() == html_names::kSrcAttr || HTMLElement::IsURLAttribute(attribute); 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 2c461edcaf6..83fafd8759b 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 @@ -62,6 +62,7 @@ class HTMLSourceElement final : public HTMLElement { InsertionNotificationRequest InsertedInto(ContainerNode&) override; void RemovedFrom(ContainerNode&) override; + void AttributeChanged(const AttributeModificationParams&) override; bool IsURLAttribute(const Attribute&) const override; void ParseAttribute(const AttributeModificationParams&) override; diff --git a/chromium/third_party/blink/renderer/core/html/html_source_element.idl b/chromium/third_party/blink/renderer/core/html/html_source_element.idl index 1e122bbc18b..88adafc43d8 100644 --- a/chromium/third_party/blink/renderer/core/html/html_source_element.idl +++ b/chromium/third_party/blink/renderer/core/html/html_source_element.idl @@ -35,4 +35,6 @@ [CEReactions, Reflect] attribute USVString srcset; [CEReactions, Reflect] attribute DOMString sizes; [CEReactions, Reflect] attribute DOMString media; + [CEReactions, Reflect] attribute unsigned long width; + [CEReactions, Reflect] attribute unsigned long height; }; 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 1fb65d80835..031497fbd7b 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 @@ -49,7 +49,7 @@ void HTMLStyleElement::ParseAttribute( GetDocument().IsActive() && sheet_) { sheet_->SetMediaQueries( MediaQuerySet::Create(params.new_value, GetExecutionContext())); - GetDocument().GetStyleEngine().MediaQueriesChangedInScope(GetTreeScope()); + GetDocument().GetStyleEngine().SetNeedsActiveStyleUpdate(GetTreeScope()); } else if (params.name == html_names::kTypeAttr) { HTMLElement::ParseAttribute(params); StyleElement::ChildrenChanged(*this); @@ -129,11 +129,10 @@ void HTMLStyleElement::NotifyLoadedSheetAndAllCriticalSubresources( .GetTaskRunner(TaskType::kNetworking) ->PostTask( FROM_HERE, - WTF::Bind(&HTMLStyleElement::DispatchPendingEvent, - WrapPersistent(this), - WTF::Passed(std::make_unique<IncrementLoadEventDelayCount>( - GetDocument())), - is_load_event)); + WTF::Bind( + &HTMLStyleElement::DispatchPendingEvent, WrapPersistent(this), + std::make_unique<IncrementLoadEventDelayCount>(GetDocument()), + is_load_event)); } bool HTMLStyleElement::disabled() const { 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 aa9c582e7ea..953846bcf79 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 @@ -38,8 +38,10 @@ namespace blink { HTMLSummaryElement::HTMLSummaryElement(Document& document) : HTMLElement(html_names::kSummaryTag, document) { - SetHasCustomStyleCallbacks(); - EnsureUserAgentShadowRoot(); + if (!RuntimeEnabledFeatures::SummaryListItemEnabled()) { + SetHasCustomStyleCallbacks(); + EnsureUserAgentShadowRoot(); + } } LayoutObject* HTMLSummaryElement::CreateLayoutObject(const ComputedStyle& style, @@ -57,6 +59,7 @@ LayoutObject* HTMLSummaryElement::CreateLayoutObject(const ComputedStyle& style, } void HTMLSummaryElement::DidAddUserAgentShadowRoot(ShadowRoot& root) { + DCHECK(!RuntimeEnabledFeatures::SummaryListItemEnabled()); auto* marker_control = MakeGarbageCollected<DetailsMarkerControl>(GetDocument()); marker_control->SetIdAttribute(shadow_element_names::kIdDetailsMarker); @@ -73,6 +76,7 @@ HTMLDetailsElement* HTMLSummaryElement::DetailsElement() const { } Element* HTMLSummaryElement::MarkerControl() { + DCHECK(!RuntimeEnabledFeatures::SummaryListItemEnabled()); return EnsureUserAgentShadowRoot().getElementById( shadow_element_names::kIdDetailsMarker); } @@ -161,6 +165,7 @@ bool HTMLSummaryElement::WillRespondToMouseClickEvents() { } void HTMLSummaryElement::WillRecalcStyle(const StyleRecalcChange) { + DCHECK(!RuntimeEnabledFeatures::SummaryListItemEnabled()); if (GetForceReattachLayoutTree() && IsMainSummary()) { if (Element* marker = MarkerControl()) { marker->SetNeedsStyleRecalc( diff --git a/chromium/third_party/blink/renderer/core/html/html_table_col_element.cc b/chromium/third_party/blink/renderer/core/html/html_table_col_element.cc index 4ccc1ed2c2f..911cddebf40 100644 --- a/chromium/third_party/blink/renderer/core/html/html_table_col_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_table_col_element.cc @@ -71,7 +71,7 @@ void HTMLTableColElement::ParseAttribute( } else if (params.name == html_names::kWidthAttr) { if (!params.new_value.IsEmpty()) { if (GetLayoutObject() && GetLayoutObject()->IsLayoutTableCol()) { - LayoutTableCol* col = ToLayoutTableCol(GetLayoutObject()); + auto* col = To<LayoutBox>(GetLayoutObject()); int new_width = Width().ToInt(); if (new_width != col->Size().Width()) { col->SetNeedsLayoutAndIntrinsicWidthsRecalcAndFullPaintInvalidation( diff --git a/chromium/third_party/blink/renderer/core/html/html_table_element.h b/chromium/third_party/blink/renderer/core/html/html_table_element.h index 7cfaf43a8a5..57c7834c2e5 100644 --- a/chromium/third_party/blink/renderer/core/html/html_table_element.h +++ b/chromium/third_party/blink/renderer/core/html/html_table_element.h @@ -42,6 +42,7 @@ class CORE_EXPORT HTMLTableElement final : public HTMLElement { public: explicit HTMLTableElement(Document&); + ~HTMLTableElement() override; HTMLTableCaptionElement* caption() const; void setCaption(HTMLTableCaptionElement*, ExceptionState&); @@ -76,8 +77,6 @@ class CORE_EXPORT HTMLTableElement final : public HTMLElement { void Trace(Visitor*) const override; private: - ~HTMLTableElement() override; - void ParseAttribute(const AttributeModificationParams&) override; bool IsPresentationAttribute(const QualifiedName&) const override; void CollectStyleForPresentationAttribute( 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 b85be229135..bd31d2feb6f 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 @@ -113,10 +113,6 @@ interfaceName: "HTMLUnknownElement", }, { - name: "content", - interfaceName: "HTMLContentElement", - }, - { name: "data", interfaceName: "HTMLDataElement", }, @@ -342,10 +338,6 @@ interfaceHeaderDir: "third_party/blink/renderer/core/html/forms", }, { - name: "shadow", - interfaceName: "HTMLShadowElement", - }, - { name: "p", interfaceName: "HTMLParagraphElement", }, @@ -359,6 +351,11 @@ interfaceName: "HTMLElement", }, { + name: "popup", + interfaceName: "HTMLPopupElement", + runtimeEnabled: "HTMLPopupElement", + }, + { name: "portal", interfaceName: "HTMLPortalElement", interfaceHeaderDir: "third_party/blink/renderer/core/html/portal", @@ -419,6 +416,12 @@ interfaceHeaderDir: "third_party/blink/renderer/core/html/forms", }, { + name: "selectmenu", + interfaceName: "HTMLSelectMenuElement", + runtimeEnabled: "HTMLSelectMenuElement", + interfaceHeaderDir: "third_party/blink/renderer/core/html/forms", + }, + { name: "slot", interfaceName: "HTMLSlotElement", }, diff --git a/chromium/third_party/blink/renderer/core/html/html_ulist_element.cc b/chromium/third_party/blink/renderer/core/html/html_ulist_element.cc index bf0d71a2525..2eba42ecc53 100644 --- a/chromium/third_party/blink/renderer/core/html/html_ulist_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_ulist_element.cc @@ -22,6 +22,7 @@ #include "third_party/blink/renderer/core/html/html_ulist_element.h" +#include "third_party/blink/renderer/core/css/css_custom_ident_value.h" #include "third_party/blink/renderer/core/css/css_property_names.h" #include "third_party/blink/renderer/core/css_value_keywords.h" #include "third_party/blink/renderer/core/html_names.h" @@ -45,13 +46,16 @@ void HTMLUListElement::CollectStyleForPresentationAttribute( if (name == html_names::kTypeAttr) { if (EqualIgnoringASCIICase(value, "disc")) { AddPropertyToPresentationAttributeStyle( - style, CSSPropertyID::kListStyleType, CSSValueID::kDisc); + style, CSSPropertyID::kListStyleType, + *MakeGarbageCollected<CSSCustomIdentValue>("disc")); } else if (EqualIgnoringASCIICase(value, "circle")) { AddPropertyToPresentationAttributeStyle( - style, CSSPropertyID::kListStyleType, CSSValueID::kCircle); + style, CSSPropertyID::kListStyleType, + *MakeGarbageCollected<CSSCustomIdentValue>("circle")); } else if (EqualIgnoringASCIICase(value, "square")) { AddPropertyToPresentationAttributeStyle( - style, CSSPropertyID::kListStyleType, CSSValueID::kSquare); + style, CSSPropertyID::kListStyleType, + *MakeGarbageCollected<CSSCustomIdentValue>("square")); } else if (EqualIgnoringASCIICase(value, "none")) { AddPropertyToPresentationAttributeStyle( style, CSSPropertyID::kListStyleType, CSSValueID::kNone); diff --git a/chromium/third_party/blink/renderer/core/html/html_view_source_document.cc b/chromium/third_party/blink/renderer/core/html/html_view_source_document.cc index 797ff5d125b..0b4d0a6a273 100644 --- a/chromium/third_party/blink/renderer/core/html/html_view_source_document.cc +++ b/chromium/third_party/blink/renderer/core/html/html_view_source_document.cc @@ -24,8 +24,15 @@ #include "third_party/blink/renderer/core/html/html_view_source_document.h" +#include "third_party/blink/public/strings/grit/blink_strings.h" #include "third_party/blink/renderer/core/css/css_value_id_mappings.h" +#include "third_party/blink/renderer/core/dom/events/event.h" +#include "third_party/blink/renderer/core/dom/events/native_event_listener.h" #include "third_party/blink/renderer/core/dom/text.h" +#include "third_party/blink/renderer/core/events/mouse_event.h" +#include "third_party/blink/renderer/core/html/forms/html_form_element.h" +#include "third_party/blink/renderer/core/html/forms/html_input_element.h" +#include "third_party/blink/renderer/core/html/forms/html_label_element.h" #include "third_party/blink/renderer/core/html/html_anchor_element.h" #include "third_party/blink/renderer/core/html/html_base_element.h" #include "third_party/blink/renderer/core/html/html_body_element.h" @@ -41,9 +48,32 @@ #include "third_party/blink/renderer/core/html/parser/html_view_source_parser.h" #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/platform/heap/heap.h" +#include "third_party/blink/renderer/platform/text/platform_locale.h" namespace blink { +class ViewSourceEventListener : public NativeEventListener { + public: + ViewSourceEventListener(HTMLTableElement* table, HTMLInputElement* checkbox) + : table_(table), checkbox_(checkbox) {} + + void Invoke(ExecutionContext*, Event* event) override { + DCHECK_EQ(event->type(), event_type_names::kChange); + table_->setAttribute(html_names::kClassAttr, + checkbox_->checked() ? "line-wrap" : ""); + } + + void Trace(Visitor* visitor) const override { + visitor->Trace(table_); + visitor->Trace(checkbox_); + NativeEventListener::Trace(visitor); + } + + private: + Member<HTMLTableElement> table_; + Member<HTMLInputElement> checkbox_; +}; + HTMLViewSourceDocument::HTMLViewSourceDocument(const DocumentInit& initializer) : HTMLDocument(initializer), type_(initializer.GetMimeType()) { SetIsViewSource(true); @@ -76,6 +106,34 @@ void HTMLViewSourceDocument::CreateContainingTable() { table->ParserAppendChild(tbody_); current_ = tbody_; line_number_ = 0; + + // Create a checkbox to control line wrapping. + auto* checkbox = + MakeGarbageCollected<HTMLInputElement>(*this, CreateElementFlags()); + checkbox->setAttribute(html_names::kTypeAttr, "checkbox"); + checkbox->addEventListener( + event_type_names::kChange, + MakeGarbageCollected<ViewSourceEventListener>(table, checkbox), + /*use_capture=*/false); + auto* label = MakeGarbageCollected<HTMLLabelElement>(*this); + label->ParserAppendChild( + Text::Create(*this, WTF::AtomicString(Locale::DefaultLocale().QueryString( + IDS_VIEW_SOURCE_LINE_WRAP)))); + label->setAttribute(html_names::kClassAttr, "line-wrap-control"); + label->ParserAppendChild(checkbox); + // Add the checkbox to a form with autocomplete=off, to avoid form + // restoration from changing the value of the checkbox. + auto* form = MakeGarbageCollected<HTMLFormElement>(*this); + form->setAttribute(html_names::kAutocompleteAttr, "off"); + form->ParserAppendChild(label); + auto* tr = MakeGarbageCollected<HTMLTableRowElement>(*this); + auto* td = + MakeGarbageCollected<HTMLTableCellElement>(html_names::kTdTag, *this); + td->setAttribute(html_names::kColspanAttr, "2"); + td->setAttribute(html_names::kClassAttr, "line-wrap-cell"); + td->ParserAppendChild(form); + tr->ParserAppendChild(td); + tbody_->ParserAppendChild(tr); } void HTMLViewSourceDocument::AddSource(const String& source, HTMLToken& token) { diff --git a/chromium/third_party/blink/renderer/core/html/html_view_source_document_test.cc b/chromium/third_party/blink/renderer/core/html/html_view_source_document_test.cc index 81106688b61..5a507e73c2d 100644 --- a/chromium/third_party/blink/renderer/core/html/html_view_source_document_test.cc +++ b/chromium/third_party/blink/renderer/core/html/html_view_source_document_test.cc @@ -39,7 +39,11 @@ TEST_F(HTMLViewSourceDocumentTest, ViewSource1) { GetDocument().documentElement()->outerHTML(), "<html><head></head><body><div " "class=\"line-gutter-backdrop\"></div><table><tbody><tr><td " - "class=\"line-number\" value=\"1\"></td><td " + "colspan=\"2\" class=\"line-wrap-cell\"><form " + "autocomplete=\"off\"><label " + "class=\"line-wrap-control\"><input " + "type=\"checkbox\"></label></form>" + "</td></tr><tr><td class=\"line-number\" value=\"1\"></td><td " "class=\"line-content\"><br></td></tr><tr><td class=\"line-number\" " "value=\"2\"></td><td class=\"line-content\"> <span " "class=\"html-doctype\"><!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML " @@ -92,7 +96,11 @@ TEST_F(HTMLViewSourceDocumentTest, ViewSource2) { GetDocument().documentElement()->outerHTML(), "<html><head></head><body><div " "class=\"line-gutter-backdrop\"></div><table><tbody><tr><td " - "class=\"line-number\" value=\"1\"></td><td " + "colspan=\"2\" class=\"line-wrap-cell\"><form " + "autocomplete=\"off\"><label " + "class=\"line-wrap-control\"><input " + "type=\"checkbox\"></label></form>" + "</td></tr><tr><td class=\"line-number\" value=\"1\"></td><td " "class=\"line-content\"><br></td></tr><tr><td class=\"line-number\" " "value=\"2\"></td><td class=\"line-content\"> <span " "class=\"html-tag\"><script></span></td></tr><tr><td " @@ -144,7 +152,11 @@ TEST_F(HTMLViewSourceDocumentTest, ViewSource3) { GetDocument().documentElement()->outerHTML(), "<html><head></head><body><div " "class=\"line-gutter-backdrop\"></div><table><tbody><tr><td " - "class=\"line-number\" value=\"1\"></td><td " + "colspan=\"2\" class=\"line-wrap-cell\"><form " + "autocomplete=\"off\"><label " + "class=\"line-wrap-control\"><input " + "type=\"checkbox\"></label></form>" + "</td></tr><tr><td class=\"line-number\" value=\"1\"></td><td " "class=\"line-content\"><br></td></tr><tr><td class=\"line-number\" " "value=\"2\"></td><td class=\"line-content\"> <span " "class=\"html-tag\"><head></span><span class=\"html-tag\"><base " @@ -209,7 +221,11 @@ TEST_F(HTMLViewSourceDocumentTest, ViewSource4) { GetDocument().documentElement()->outerHTML(), "<html><head></head><body><div " "class=\"line-gutter-backdrop\"></div><table><tbody><tr><td " - "class=\"line-number\" value=\"1\"></td><td " + "colspan=\"2\" class=\"line-wrap-cell\"><form " + "autocomplete=\"off\"><label " + "class=\"line-wrap-control\"><input " + "type=\"checkbox\"></label></form>" + "</td></tr><tr><td class=\"line-number\" value=\"1\"></td><td " "class=\"line-content\"><br></td></tr><tr><td class=\"line-number\" " "value=\"2\"></td><td class=\"line-content\"> <span " "class=\"html-tag\"><HEAD></span><span class=\"html-tag\"><BASE " @@ -277,7 +293,11 @@ TEST_F(HTMLViewSourceDocumentTest, ViewSource5) { GetDocument().documentElement()->outerHTML(), "<html><head></head><body><div " "class=\"line-gutter-backdrop\"></div><table><tbody><tr><td " - "class=\"line-number\" value=\"1\"></td><td " + "colspan=\"2\" class=\"line-wrap-cell\"><form " + "autocomplete=\"off\"><label " + "class=\"line-wrap-control\"><input " + "type=\"checkbox\"></label></form>" + "</td></tr><tr><td class=\"line-number\" value=\"1\"></td><td " "class=\"line-content\"><br></td></tr><tr><td class=\"line-number\" " "value=\"2\"></td><td class=\"line-content\"><br></td></tr><tr><td " "class=\"line-number\" value=\"3\"></td><td " @@ -309,8 +329,12 @@ TEST_F(HTMLViewSourceDocumentTest, ViewSource6) { std::string expected_beginning( "<html><head></head><body><div " "class=\"line-gutter-backdrop\"></div><table><tbody><tr><td " - "class=\"line-number\" value=\"1\"></td><td class=\"line-content\"> " - " "); + "colspan=\"2\" class=\"line-wrap-cell\"><form " + "autocomplete=\"off\"><label " + "class=\"line-wrap-control\"><input " + "type=\"checkbox\"></label></form>" + "</td></tr><tr><td class=\"line-number\" value=\"1\">" + "</td><td class=\"line-content\"> "); std::string expected_ending( " <span class=\"html-tag\"><b></span>A<span " "class=\"html-tag\"></b></span> <span " @@ -325,7 +349,11 @@ TEST_F(HTMLViewSourceDocumentTest, ViewSource7) { EXPECT_EQ(GetDocument().documentElement()->outerHTML(), "<html><head></head><body><div " "class=\"line-gutter-backdrop\"></div><table><tbody><tr><td " - "class=\"line-number\" value=\"1\"></td><td " + "colspan=\"2\" class=\"line-wrap-cell\"><form " + "autocomplete=\"off\"><label " + "class=\"line-wrap-control\"><input " + "type=\"checkbox\"></label></form>" + "</td></tr><tr><td class=\"line-number\" value=\"1\"></td><td " "class=\"line-content\">1234567<span " "class=\"html-end-of-file\"></span></td></tr></tbody></table></" "body></html>"); @@ -347,7 +375,11 @@ TEST_F(HTMLViewSourceDocumentTest, ViewSource8) { GetDocument().documentElement()->outerHTML(), "<html><head></head><body><div " "class=\"line-gutter-backdrop\"></div><table><tbody><tr><td " - "class=\"line-number\" value=\"1\"></td><td " + "colspan=\"2\" class=\"line-wrap-cell\"><form " + "autocomplete=\"off\"><label " + "class=\"line-wrap-control\"><input " + "type=\"checkbox\"></label></form></td></tr>" + "<tr><td class=\"line-number\" value=\"1\"></td><td " "class=\"line-content\"><br></td></tr><tr><td class=\"line-number\" " "value=\"2\"></td><td class=\"line-content\"> <span " "class=\"html-doctype\"><!DOCTYPE html></span></td></tr><tr><td " @@ -414,7 +446,11 @@ TEST_F(HTMLViewSourceDocumentTest, ViewSource9) { GetDocument().documentElement()->outerHTML(), "<html><head></head><body><div " "class=\"line-gutter-backdrop\"></div><table><tbody><tr><td " - "class=\"line-number\" value=\"1\"></td><td " + "colspan=\"2\" class=\"line-wrap-cell\"><form " + "autocomplete=\"off\"><label " + "class=\"line-wrap-control\"><input " + "type=\"checkbox\"></label></form>" + "</td></tr><tr><td class=\"line-number\" value=\"1\"></td><td " "class=\"line-content\"><br></td></tr><tr><td class=\"line-number\" " "value=\"2\"></td><td class=\"line-content\"> <span " "class=\"html-doctype\"><!DOCTYPE html></span></td></tr><tr><td " @@ -445,7 +481,11 @@ TEST_F(HTMLViewSourceDocumentTest, IncompleteToken) { GetDocument().documentElement()->outerHTML(), "<html><head></head><body><div " "class=\"line-gutter-backdrop\"></div><table><tbody><tr><td " - "class=\"line-number\" value=\"1\"></td><td " + "colspan=\"2\" class=\"line-wrap-cell\"><form " + "autocomplete=\"off\"><label " + "class=\"line-wrap-control\"><input " + "type=\"checkbox\"></label></form>" + "</td></tr><tr><td class=\"line-number\" value=\"1\"></td><td " "class=\"line-content\"><br></td></tr><tr><td class=\"line-number\" " "value=\"2\"></td><td class=\"line-content\"> Incomplete token " "test</td></tr><tr><td class=\"line-number\" value=\"3\"></td><td " @@ -467,7 +507,12 @@ TEST_F(HTMLViewSourceDocumentTest, UnfinishedTextarea) { GetDocument().documentElement()->outerHTML(), "<html><head></head><body><div " "class=\"line-gutter-backdrop\"></div><table><tbody><tr><td " - "class=\"line-number\" value=\"1\"></td><td class=\"line-content\"><span " + "colspan=\"2\" class=\"line-wrap-cell\"><form " + "autocomplete=\"off\"><label " + "class=\"line-wrap-control\"><input " + "type=\"checkbox\"></label></form>" + "</td></tr><tr><td class=\"line-number\" value=\"1\"></td>" + "<td class=\"line-content\"><span " "class=\"html-tag\"><textarea></span>foobar in " "textarea</td></tr><tr><td class=\"line-number\" value=\"2\"></td><td " "class=\"line-content\"> <span " @@ -482,7 +527,12 @@ TEST_F(HTMLViewSourceDocumentTest, UnfinishedScript) { GetDocument().documentElement()->outerHTML(), "<html><head></head><body><div " "class=\"line-gutter-backdrop\"></div><table><tbody><tr><td " - "class=\"line-number\" value=\"1\"></td><td class=\"line-content\"><span " + "colspan=\"2\" class=\"line-wrap-cell\"><form " + "autocomplete=\"off\"><label " + "class=\"line-wrap-control\"><input " + "type=\"checkbox\"></label></form>" + "</td></tr><tr><td class=\"line-number\" value=\"1\"></td>" + "<td class=\"line-content\"><span " "class=\"html-tag\"><script></span>foobar in " "script</td></tr><tr><td class=\"line-number\" value=\"2\"></td><td " "class=\"line-content\"> <span " 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 ac7aad3cf3d..bffd533d270 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,9 +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/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" #include "third_party/blink/renderer/core/html/imports/html_import_child_client.h" #include "third_party/blink/renderer/core/html/imports/html_import_loader.h" #include "third_party/blink/renderer/core/html/imports/html_import_tree_root.h" @@ -64,12 +61,10 @@ void HTMLImportChild::OwnerInserted() { } void HTMLImportChild::DidShareLoader() { - CreateCustomElementMicrotaskStepIfNeeded(); StateWillChange(); } void HTMLImportChild::DidStartLoading() { - CreateCustomElementMicrotaskStepIfNeeded(); } void HTMLImportChild::DidFinish() { @@ -79,16 +74,13 @@ void HTMLImportChild::DidFinish() { void HTMLImportChild::DidFinishLoading() { StateWillChange(); - V0CustomElement::DidFinishLoadingImport(*(Root()->GetDocument())); } void HTMLImportChild::DidFinishUpgradingCustomElements() { StateWillChange(); - custom_element_microtask_step_.Clear(); } void HTMLImportChild::Dispose() { - InvalidateCustomElementMicrotaskStep(); if (Parent()) Parent()->RemoveChild(this); @@ -118,26 +110,10 @@ void HTMLImportChild::StateDidChange() { DidFinish(); } -void HTMLImportChild::InvalidateCustomElementMicrotaskStep() { - if (!custom_element_microtask_step_) - return; - custom_element_microtask_step_->Invalidate(); - custom_element_microtask_step_.Clear(); -} - -void HTMLImportChild::CreateCustomElementMicrotaskStepIfNeeded() { - DCHECK(!custom_element_microtask_step_); - - if (!HasFinishedLoading() && !FormsCycle()) { - custom_element_microtask_step_ = V0CustomElement::DidCreateImport(this); - } -} - bool HTMLImportChild::HasFinishedLoading() const { DCHECK(loader_); - return loader_->IsDone() && loader_->MicrotaskQueue()->IsEmpty() && - !custom_element_microtask_step_; + return loader_->IsDone(); } HTMLImportLoader* HTMLImportChild::Loader() const { @@ -168,14 +144,11 @@ void HTMLImportChild::Normalize() { for (HTMLImportChild* child = ToHTMLImportChild(FirstChild()); child; child = ToHTMLImportChild(child->Next())) { - if (child->FormsCycle()) - child->InvalidateCustomElementMicrotaskStep(); child->Normalize(); } } void HTMLImportChild::Trace(Visitor* visitor) const { - visitor->Trace(custom_element_microtask_step_); visitor->Trace(loader_); visitor->Trace(client_); HTMLImport::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/core/html/imports/html_import_child.h b/chromium/third_party/blink/renderer/core/html/imports/html_import_child.h index 7ba5533b9e5..016723d0fbf 100644 --- a/chromium/third_party/blink/renderer/core/html/imports/html_import_child.h +++ b/chromium/third_party/blink/renderer/core/html/imports/html_import_child.h @@ -37,7 +37,6 @@ namespace blink { -class V0CustomElementMicrotaskImportStep; class HTMLImportLoader; class HTMLImportChildClient; class HTMLLinkElement; @@ -83,7 +82,6 @@ class HTMLImportChild final : public HTMLImport { void InvalidateCustomElementMicrotaskStep(); KURL url_; - WeakMember<V0CustomElementMicrotaskImportStep> custom_element_microtask_step_; Member<HTMLImportLoader> loader_; Member<HTMLImportChildClient> client_; }; diff --git a/chromium/third_party/blink/renderer/core/html/imports/html_import_loader.cc b/chromium/third_party/blink/renderer/core/html/imports/html_import_loader.cc index 71e96eca7be..1a4f6f31d9e 100644 --- a/chromium/third_party/blink/renderer/core/html/imports/html_import_loader.cc +++ b/chromium/third_party/blink/renderer/core/html/imports/html_import_loader.cc @@ -34,7 +34,6 @@ #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/html/custom/v0_custom_element_sync_microtask_queue.h" #include "third_party/blink/renderer/core/html/html_document.h" #include "third_party/blink/renderer/core/html/imports/html_import_child.h" #include "third_party/blink/renderer/core/html/imports/html_imports_controller.h" @@ -44,10 +43,7 @@ namespace blink { HTMLImportLoader::HTMLImportLoader(HTMLImportsController* controller) - : controller_(controller), - state_(kStateLoading), - microtask_queue_( - MakeGarbageCollected<V0CustomElementSyncMicrotaskQueue>()) {} + : controller_(controller), state_(kStateLoading) {} HTMLImportLoader::~HTMLImportLoader() = default; @@ -101,7 +97,6 @@ HTMLImportLoader::State HTMLImportLoader::StartWritingAndParsing( DocumentInit::Create() .WithImportsController(controller_) .WithExecutionContext(tree_root->GetExecutionContext()) - .WithRegistrationContext(tree_root->RegistrationContext()) .WithURL(response.CurrentRequestUrl())); document_->OpenForNavigation( RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled() @@ -202,15 +197,10 @@ bool HTMLImportLoader::ShouldBlockScriptExecution() const { return FirstImport()->GetState().ShouldBlockScriptExecution(); } -V0CustomElementSyncMicrotaskQueue* HTMLImportLoader::MicrotaskQueue() const { - return microtask_queue_; -} - void HTMLImportLoader::Trace(Visitor* visitor) const { visitor->Trace(controller_); visitor->Trace(imports_); visitor->Trace(document_); - visitor->Trace(microtask_queue_); DocumentParserClient::Trace(visitor); RawResourceClient::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/imports/html_import_loader.h b/chromium/third_party/blink/renderer/core/html/imports/html_import_loader.h index 5bde9c7458d..27e4d7e1a6b 100644 --- a/chromium/third_party/blink/renderer/core/html/imports/html_import_loader.h +++ b/chromium/third_party/blink/renderer/core/html/imports/html_import_loader.h @@ -39,7 +39,6 @@ namespace blink { -class V0CustomElementSyncMicrotaskQueue; class Document; class HTMLImportChild; class HTMLImportsController; @@ -83,8 +82,6 @@ class HTMLImportLoader final : public GarbageCollected<HTMLImportLoader>, // loading. Called by Document::DidRemoveAllPendingStylesheets. void DidRemoveAllPendingStylesheets(); - V0CustomElementSyncMicrotaskQueue* MicrotaskQueue() const; - void Trace(Visitor*) const override; private: @@ -113,7 +110,6 @@ class HTMLImportLoader final : public GarbageCollected<HTMLImportLoader>, HeapVector<Member<HTMLImportChild>> imports_; State state_; Member<Document> document_; - Member<V0CustomElementSyncMicrotaskQueue> microtask_queue_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/imports/html_import_tree_root.cc b/chromium/third_party/blink/renderer/core/html/imports/html_import_tree_root.cc index f21358abc74..7e139f33f83 100644 --- a/chromium/third_party/blink/renderer/core/html/imports/html_import_tree_root.cc +++ b/chromium/third_party/blink/renderer/core/html/imports/html_import_tree_root.cc @@ -79,6 +79,7 @@ void HTMLImportTreeRoot::RecalcTimerFired(TimerBase*) { void HTMLImportTreeRoot::Trace(Visitor* visitor) const { visitor->Trace(document_); + visitor->Trace(recalc_timer_); visitor->Trace(imports_); HTMLImport::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/imports/html_import_tree_root.h b/chromium/third_party/blink/renderer/core/html/imports/html_import_tree_root.h index 02a484bcae1..c3ede3da15c 100644 --- a/chromium/third_party/blink/renderer/core/html/imports/html_import_tree_root.h +++ b/chromium/third_party/blink/renderer/core/html/imports/html_import_tree_root.h @@ -42,7 +42,7 @@ class HTMLImportTreeRoot final : public HTMLImport, public NameClient { void RecalcTimerFired(TimerBase*); Member<Document> document_; - TaskRunnerTimer<HTMLImportTreeRoot> recalc_timer_; + HeapTaskRunnerTimer<HTMLImportTreeRoot> recalc_timer_; // List of import which has been loaded or being loaded. typedef HeapVector<Member<HTMLImportChild>> ImportList; 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 02d907ee889..1128a3ff94a 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 @@ -23,7 +23,6 @@ #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/geometry/length.h" -#include "third_party/blink/renderer/platform/heap/visitor.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_request.h" #include "third_party/blink/renderer/platform/network/network_state_notifier.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" @@ -254,9 +253,9 @@ void LazyLoadFrameObserver::RecordMetricsOnVisibilityChanged( if (time_when_first_load_finished_.is_null() && !is_initially_above_the_fold_) { // Note: If the WebEffectiveConnectionType enum ever gets out of sync with - // net::EffectiveConnectionType, then this will have to be updated to record - // the sample in terms of net::EffectiveConnectionType instead of - // WebEffectiveConnectionType. + // mojom::blink::EffectiveConnectionType, then this will have to be updated + // to record the sample in terms of mojom::blink::EffectiveConnectionType + // instead of WebEffectiveConnectionType. UMA_HISTOGRAM_ENUMERATION( "Blink.VisibleBeforeLoaded.LazyLoadEligibleFrames.BelowTheFold", GetNetworkStateNotifier().EffectiveType()); 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 d27af3e6c0d..32ba218265b 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 @@ -11,6 +11,7 @@ #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" +#include "third_party/blink/renderer/platform/heap/visitor.h" namespace blink { @@ -18,7 +19,6 @@ class IntersectionObserver; class IntersectionObserverEntry; class HTMLFrameOwnerElement; class ResourceRequestHead; -class Visitor; class LazyLoadFrameObserver final : public GarbageCollected<LazyLoadFrameObserver> { diff --git a/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.cc b/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.cc index ecdfd944ccf..61b2779fffc 100644 --- a/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.cc +++ b/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.cc @@ -311,9 +311,9 @@ void LazyLoadImageObserver::OnVisibilityChanged( visible_load_time_metrics.time_when_first_visible = base::TimeTicks::Now(); if (visible_load_time_metrics.time_when_first_load_finished.is_null()) { // Note: If the WebEffectiveConnectionType enum ever gets out of sync - // with net::EffectiveConnectionType, then both the AboveTheFold and - // BelowTheFold histograms here will have to be updated to record the - // sample in terms of net::EffectiveConnectionType instead of + // with mojom::blink::EffectiveConnectionType, then both the AboveTheFold + // and BelowTheFold histograms here will have to be updated to record the + // sample in terms of mojom::blink::EffectiveConnectionType instead of // WebEffectiveConnectionType. if (visible_load_time_metrics.is_initially_intersecting) { UMA_HISTOGRAM_ENUMERATION( diff --git a/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.h b/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.h index 5d236775714..7f19c88202a 100644 --- a/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.h +++ b/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.h @@ -8,6 +8,7 @@ #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" +#include "third_party/blink/renderer/platform/heap/visitor.h" namespace blink { @@ -16,7 +17,6 @@ class Element; class HTMLImageElement; class IntersectionObserver; class IntersectionObserverEntry; -class Visitor; class LazyLoadImageObserver final : public GarbageCollected<LazyLoadImageObserver> { diff --git a/chromium/third_party/blink/renderer/core/html/link_style.cc b/chromium/third_party/blink/renderer/core/html/link_style.cc index b5da461825b..6b9590207c7 100644 --- a/chromium/third_party/blink/renderer/core/html/link_style.cc +++ b/chromium/third_party/blink/renderer/core/html/link_style.cc @@ -38,19 +38,13 @@ LinkStyle::LinkStyle(HTMLLinkElement* owner) : LinkResource(owner), disabled_state_(kUnset), pending_sheet_type_(kNone), + render_blocking_behavior_(RenderBlockingBehavior::kUnset), loading_(false), fired_load_(false), loaded_sheet_(false) {} LinkStyle::~LinkStyle() = default; -enum StyleSheetCacheStatus { - kStyleSheetNewEntry, - kStyleSheetInDiskCache, - kStyleSheetInMemoryCache, - kStyleSheetCacheStatusCount, -}; - void LinkStyle::NotifyFinished(Resource* resource) { if (!owner_->isConnected()) { // While the stylesheet is asynchronously loading, the owner can be @@ -63,7 +57,7 @@ void LinkStyle::NotifyFinished(Resource* resource) { return; } - CSSStyleSheetResource* cached_style_sheet = ToCSSStyleSheetResource(resource); + auto* cached_style_sheet = To<CSSStyleSheetResource>(resource); // See the comment in pending_script.cc about why this check is necessary // here, instead of in the resource fetcher. https://crbug.com/500701. if ((!cached_style_sheet->ErrorOccurred() && @@ -88,7 +82,9 @@ void LinkStyle::NotifyFinished(Resource* resource) { auto* parser_context = MakeGarbageCollected<CSSParserContext>( GetDocument(), cached_style_sheet->GetResponse().ResponseUrl(), cached_style_sheet->GetResponse().IsCorsSameOrigin(), - cached_style_sheet->GetReferrerPolicy(), cached_style_sheet->Encoding()); + Referrer(cached_style_sheet->GetResponse().ResponseUrl(), + cached_style_sheet->GetReferrerPolicy()), + cached_style_sheet->Encoding()); if (cached_style_sheet->GetResourceRequest().IsAdResource()) { parser_context->SetIsAdRelated(); } @@ -105,6 +101,7 @@ void LinkStyle::NotifyFinished(Resource* resource) { loading_ = false; parsed_sheet->CheckLoaded(); + parsed_sheet->SetRenderBlocking(render_blocking_behavior_); return; } @@ -121,6 +118,7 @@ void LinkStyle::NotifyFinished(Resource* resource) { if (owner_->IsInDocumentTree()) SetSheetTitle(owner_->title()); + style_sheet->SetRenderBlocking(render_blocking_behavior_); style_sheet->ParseAuthorStyleSheet(cached_style_sheet); loading_ = false; @@ -286,20 +284,31 @@ LinkStyle::LoadReturnValue LinkStyle::LoadStylesheetIfNeeded( media_query_matches = evaluator.Eval(*media); } + bool is_in_body = owner_->IsDescendantOf(owner_->GetDocument().body()); + // Don't hold up layout tree construction and script execution on // stylesheets that are not needed for the layout at the moment. - bool blocking = media_query_matches && !owner_->IsAlternate() && - owner_->IsCreatedByParser(); - AddPendingSheet(blocking ? kBlocking : kNonBlocking); + bool critical_style = media_query_matches && !owner_->IsAlternate(); + bool render_blocking = critical_style && owner_->IsCreatedByParser(); + + AddPendingSheet(render_blocking ? kBlocking : kNonBlocking); // Load stylesheets that are not needed for the layout immediately with low // priority. When the link element is created by scripts, load the // stylesheets asynchronously but in high priority. FetchParameters::DeferOption defer_option = - !media_query_matches || owner_->IsAlternate() ? FetchParameters::kLazyLoad - : FetchParameters::kNoDefer; - - owner_->LoadStylesheet(params, charset, defer_option, this); + !critical_style ? FetchParameters::kLazyLoad : FetchParameters::kNoDefer; + + render_blocking_behavior_ = + !critical_style + ? RenderBlockingBehavior::kNonBlocking + : (render_blocking + ? (is_in_body ? RenderBlockingBehavior::kInBodyParserBlocking + : RenderBlockingBehavior::kBlocking) + : RenderBlockingBehavior::kNonBlockingDynamic); + + owner_->LoadStylesheet(params, charset, defer_option, this, + render_blocking_behavior_); if (loading_ && !GetResource()) { // Fetch() synchronous failure case. diff --git a/chromium/third_party/blink/renderer/core/html/link_style.h b/chromium/third_party/blink/renderer/core/html/link_style.h index 6175160db76..06c5b3bb55b 100644 --- a/chromium/third_party/blink/renderer/core/html/link_style.h +++ b/chromium/third_party/blink/renderer/core/html/link_style.h @@ -9,7 +9,6 @@ #include "third_party/blink/renderer/core/dom/node.h" #include "third_party/blink/renderer/core/html/link_resource.h" #include "third_party/blink/renderer/core/loader/resource/css_style_sheet_resource.h" -#include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_client.h" #include "third_party/blink/renderer/platform/wtf/forward.h" @@ -75,6 +74,7 @@ class LinkStyle final : public LinkResource, ResourceClient { Member<CSSStyleSheet> sheet_; DisabledState disabled_state_; PendingSheetType pending_sheet_type_; + RenderBlockingBehavior render_blocking_behavior_; StyleEngineContext style_engine_context_; bool explicitly_enabled_; bool loading_; diff --git a/chromium/third_party/blink/renderer/core/html/link_web_bundle.cc b/chromium/third_party/blink/renderer/core/html/link_web_bundle.cc index a23b873e304..2524815ff95 100644 --- a/chromium/third_party/blink/renderer/core/html/link_web_bundle.cc +++ b/chromium/third_party/blink/renderer/core/html/link_web_bundle.cc @@ -4,12 +4,15 @@ #include "third_party/blink/renderer/core/html/link_web_bundle.h" +#include "base/unguessable_token.h" +#include "services/network/public/mojom/web_bundle_handle.mojom-blink.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h" #include "third_party/blink/public/mojom/web_feature/web_feature.mojom-blink.h" #include "third_party/blink/public/web/web_local_frame.h" #include "third_party/blink/public/web/web_local_frame_client.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/local_frame_client.h" +#include "third_party/blink/renderer/core/html/cross_origin_attribute.h" #include "third_party/blink/renderer/core/html/html_link_element.h" #include "third_party/blink/renderer/core/inspector/console_message.h" #include "third_party/blink/renderer/core/loader/threadable_loader.h" @@ -18,40 +21,54 @@ #include "third_party/blink/renderer/platform/loader/cors/cors.h" #include "third_party/blink/renderer/platform/loader/fetch/bytes_consumer.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h" -#include "third_party/blink/renderer/platform/loader/fetch/url_loader/web_bundle_subresource_loader.h" +#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h" namespace blink { -// WebBundleLoader is responsible for loading a WebBundle resource. class WebBundleLoader : public GarbageCollected<WebBundleLoader>, - public ThreadableLoaderClient { + public ThreadableLoaderClient, + public network::mojom::WebBundleHandle { public: WebBundleLoader(LinkWebBundle& link_web_bundle, Document& document, - const KURL& url) + const KURL& url, + CrossOriginAttributeValue cross_origin_attribute_value) : link_web_bundle_(&link_web_bundle), url_(url), - security_origin_(SecurityOrigin::Create(url)) { - blink::CrossVariantMojoReceiver< - network::mojom::URLLoaderFactoryInterfaceBase> - receiver(loader_factory_.BindNewPipeAndPassReceiver()); - document.GetFrame() - ->Client() - ->GetWebFrame() - ->Client() - ->MaybeProxyURLLoaderFactory(&receiver); - pending_factory_receiver_ = std::move(receiver); - + security_origin_(SecurityOrigin::Create(url)), + web_bundle_token_(base::UnguessableToken::Create()) { ResourceRequest request(url); request.SetUseStreamOnResponse(true); // TODO(crbug.com/1082020): Revisit these once the fetch and process the // linked resource algorithm [1] for <link rel=webbundle> is defined. // [1] // https://html.spec.whatwg.org/multipage/semantics.html#fetch-and-process-the-linked-resource - request.SetRequestContext(mojom::blink::RequestContextType::SUBRESOURCE); + request.SetRequestContext( + mojom::blink::RequestContextType::SUBRESOURCE_WEBBUNDLE); + + // https://github.com/WICG/webpackage/blob/main/explainers/subresource-loading.md#requests-mode-and-credentials-mode request.SetMode(network::mojom::blink::RequestMode::kCors); - request.SetCredentialsMode(network::mojom::blink::CredentialsMode::kOmit); + switch (cross_origin_attribute_value) { + case kCrossOriginAttributeNotSet: + case kCrossOriginAttributeAnonymous: + request.SetCredentialsMode( + network::mojom::CredentialsMode::kSameOrigin); + break; + case kCrossOriginAttributeUseCredentials: + request.SetCredentialsMode(network::mojom::CredentialsMode::kInclude); + break; + } + request.SetRequestDestination( + network::mojom::RequestDestination::kWebBundle); + request.SetPriority(ResourceLoadPriority::kHigh); + + mojo::PendingRemote<network::mojom::WebBundleHandle> web_bundle_handle; + web_bundle_handles_.Add(this, + web_bundle_handle.InitWithNewPipeAndPassReceiver()); + request.SetWebBundleTokenParams(ResourceRequestHead::WebBundleTokenParams( + url_, web_bundle_token_, std::move(web_bundle_handle))); ExecutionContext* execution_context = document.GetExecutionContext(); ResourceLoaderOptions resource_loader_options( @@ -70,70 +87,64 @@ class WebBundleLoader : public GarbageCollected<WebBundleLoader>, bool HasLoaded() const { return !failed_; } - mojo::PendingRemote<network::mojom::blink::URLLoaderFactory> - GetURLLoaderFactory() { - mojo::PendingRemote<network::mojom::blink::URLLoaderFactory> factory_clone; - loader_factory_->Clone(factory_clone.InitWithNewPipeAndPassReceiver()); - return factory_clone; - } - // ThreadableLoaderClient - void DidReceiveResponse(uint64_t, const ResourceResponse& response) override { - if (!cors::IsOkStatus(response.HttpStatusCode())) - failed_ = true; - // TODO(crbug.com/1082020): Check response headers, as spec'ed in - // https://wicg.github.io/webpackage/draft-yasskin-wpack-bundled-exchanges.html#name-serving-constraints. - } - void DidStartLoadingResponseBody(BytesConsumer& consumer) override { - DCHECK(pending_factory_receiver_); - CreateWebBundleSubresourceLoaderFactory( - std::move(pending_factory_receiver_), consumer.DrainAsDataPipe(), - ConvertToBaseRepeatingCallback( - CrossThreadBindRepeating(&WebBundleLoader::OnWebBundleError, - WrapCrossThreadWeakPersistent(this)))); + // Drain |consumer| so that DidFinishLoading is surely called later. + consumer.DrainAsDataPipe(); } - - void DidFinishLoading(uint64_t) override { link_web_bundle_->NotifyLoaded(); } void DidFail(const ResourceError&) override { DidFailInternal(); } void DidFailRedirectCheck() override { DidFailInternal(); } + // network::mojom::WebBundleHandle + void Clone(mojo::PendingReceiver<network::mojom::WebBundleHandle> receiver) + override { + web_bundle_handles_.Add(this, std::move(receiver)); + } + void OnWebBundleError(network::mojom::WebBundleErrorType type, + const std::string& message) override { + link_web_bundle_->OnWebBundleError(url_.ElidedString() + ": " + + message.c_str()); + } + void OnWebBundleLoadFinished(bool success) override { + if (failed_) + return; + failed_ = !success; + link_web_bundle_->NotifyLoaded(); + } + const KURL& url() const { return url_; } scoped_refptr<SecurityOrigin> GetSecurityOrigin() const { return security_origin_; } + const base::UnguessableToken& WebBundleToken() const { + return web_bundle_token_; + } private: void DidFailInternal() { - if (pending_factory_receiver_) { - // If we haven't create a WebBundleSubresourceLoaderFactory, create it - // with an empty bundle body so that requests to - // |pending_factory_receiver_| are processed (and fail). - CreateWebBundleSubresourceLoaderFactory( - std::move(pending_factory_receiver_), - mojo::ScopedDataPipeConsumerHandle(), base::DoNothing()); - } + if (failed_) + return; failed_ = true; link_web_bundle_->NotifyLoaded(); } - void OnWebBundleError(WebBundleErrorType type, const String& message) { - // TODO(crbug.com/1082020): Dispatch "error" event on metadata parse error. - // Simply setting |failed_| here does not work because DidFinishLoading() - // may already be called. - link_web_bundle_->OnWebBundleError(url_.ElidedString() + ": " + message); - } - Member<LinkWebBundle> link_web_bundle_; Member<ThreadableLoader> loader_; - mojo::Remote<network::mojom::blink::URLLoaderFactory> loader_factory_; - mojo::PendingReceiver<network::mojom::blink::URLLoaderFactory> - pending_factory_receiver_; bool failed_ = false; KURL url_; scoped_refptr<SecurityOrigin> security_origin_; + base::UnguessableToken web_bundle_token_; + // we need ReceiverSet here because WebBundleHandle is cloned when + // ResourceRequest is copied. + mojo::ReceiverSet<network::mojom::WebBundleHandle> web_bundle_handles_; }; +// static +bool LinkWebBundle::IsFeatureEnabled(const ExecutionContext* context) { + return context && context->IsSecureContext() && + RuntimeEnabledFeatures::SubresourceWebBundlesEnabled(context); +} + LinkWebBundle::LinkWebBundle(HTMLLinkElement* owner) : LinkResource(owner) { UseCounter::Count(owner_->GetDocument().GetExecutionContext(), WebFeature::kSubresourceWebBundles); @@ -172,9 +183,32 @@ void LinkWebBundle::Process() { if (!resource_fetcher) return; + // We don't support crossorigin= attribute's dynamic change. It seems + // other types of link elements doesn't support that too. See + // HTMLlinkElement::ParseAttribute, which doesn't call Process() for + // crossorigin= attribute change. if (!bundle_loader_ || bundle_loader_->url() != owner_->Href()) { + if (resource_fetcher->ShouldBeLoadedFromWebBundle(owner_->Href())) { + // This can happen when a requested bundle is a nested bundle. + // + // clang-format off + // Example: + // <link rel="webbundle" href=".../nested-main.wbn" resources=".../nested-sub.wbn"> + // <link rel="webbundle" href=".../nested-sub.wbn" resources="..."> + // clang-format on + if (bundle_loader_) { + resource_fetcher->RemoveSubresourceWebBundle(*this); + bundle_loader_ = nullptr; + } + NotifyLoaded(); + OnWebBundleError("A nested bundle is not supported: " + + owner_->Href().ElidedString()); + return; + } bundle_loader_ = MakeGarbageCollected<WebBundleLoader>( - *this, owner_->GetDocument(), owner_->Href()); + *this, owner_->GetDocument(), owner_->Href(), + GetCrossOriginAttributeValue( + owner_->FastGetAttribute(html_names::kCrossoriginAttr))); } resource_fetcher->AddSubresourceWebBundle(*this); @@ -199,8 +233,12 @@ void LinkWebBundle::OwnerRemoved() { } bool LinkWebBundle::CanHandleRequest(const KURL& url) const { - if (!owner_ || !owner_->ValidResourceUrls().Contains(url)) + if (!url.IsValid()) + return false; + if (!ResourcesOrScopesMatch(url)) return false; + if (url.Protocol() == "urn") + return true; DCHECK(bundle_loader_); if (!bundle_loader_->GetSecurityOrigin()->IsSameOriginWith( SecurityOrigin::Create(url).get())) { @@ -220,10 +258,16 @@ bool LinkWebBundle::CanHandleRequest(const KURL& url) const { return true; } -mojo::PendingRemote<network::mojom::blink::URLLoaderFactory> -LinkWebBundle::GetURLLoaderFactory() { - DCHECK(bundle_loader_); - return bundle_loader_->GetURLLoaderFactory(); +bool LinkWebBundle::ResourcesOrScopesMatch(const KURL& url) const { + if (!owner_) + return false; + if (owner_->ValidResourceUrls().Contains(url)) + return true; + for (const auto& scope : owner_->ValidScopeUrls()) { + if (url.GetString().StartsWith(scope.GetString())) + return true; + } + return false; } String LinkWebBundle::GetCacheIdentifier() const { @@ -231,6 +275,16 @@ String LinkWebBundle::GetCacheIdentifier() const { return bundle_loader_->url().GetString(); } +const KURL& LinkWebBundle::GetBundleUrl() const { + DCHECK(bundle_loader_); + return bundle_loader_->url(); +} + +const base::UnguessableToken& LinkWebBundle::WebBundleToken() const { + DCHECK(bundle_loader_); + return bundle_loader_->WebBundleToken(); +} + // static KURL LinkWebBundle::ParseResourceUrl(const AtomicString& str) { // The implementation is almost copy and paste from ParseExchangeURL() defined @@ -246,10 +300,10 @@ KURL LinkWebBundle::ParseResourceUrl(const AtomicString& str) { !url.Pass().IsEmpty()) return KURL(); - // For now, we allow only http: and https: schemes in Web Bundle URLs. + // For now, we allow only http:, https: and urn: schemes in Web Bundle URLs. // TODO(crbug.com/966753): Revisit this once // https://github.com/WICG/webpackage/issues/468 is resolved. - if (!url.ProtocolIsInHTTPFamily()) + if (!url.ProtocolIsInHTTPFamily() && !url.ProtocolIs("urn")) return KURL(); return url; diff --git a/chromium/third_party/blink/renderer/core/html/link_web_bundle.h b/chromium/third_party/blink/renderer/core/html/link_web_bundle.h index dcfa286be4c..303cd6cdb1a 100644 --- a/chromium/third_party/blink/renderer/core/html/link_web_bundle.h +++ b/chromium/third_party/blink/renderer/core/html/link_web_bundle.h @@ -12,6 +12,10 @@ #include "third_party/blink/renderer/platform/loader/fetch/subresource_web_bundle.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" +namespace base { +class UnguessableToken; +} + namespace blink { class WebBundleLoader; @@ -22,6 +26,8 @@ class WebBundleLoader; class CORE_EXPORT LinkWebBundle final : public LinkResource, public SubresourceWebBundle { public: + static bool IsFeatureEnabled(const ExecutionContext*); + explicit LinkWebBundle(HTMLLinkElement* owner); ~LinkWebBundle() override; @@ -41,9 +47,9 @@ class CORE_EXPORT LinkWebBundle final : public LinkResource, // SubresourceWebBundle overrides: bool CanHandleRequest(const KURL& url) const override; - mojo::PendingRemote<network::mojom::blink::URLLoaderFactory> - GetURLLoaderFactory() override; String GetCacheIdentifier() const override; + const KURL& GetBundleUrl() const override; + const base::UnguessableToken& WebBundleToken() const override; // Parse the given |str| as a url. If |str| doesn't meet the criteria which // WebBundles specification requires, this returns invalid empty KURL as an @@ -53,6 +59,8 @@ class CORE_EXPORT LinkWebBundle final : public LinkResource, static KURL ParseResourceUrl(const AtomicString& str); private: + bool ResourcesOrScopesMatch(const KURL& url) const; + Member<WebBundleLoader> bundle_loader_; }; diff --git a/chromium/third_party/blink/renderer/core/html/link_web_bundle_test.cc b/chromium/third_party/blink/renderer/core/html/link_web_bundle_test.cc index 2d22d4bd180..32ac196e7bb 100644 --- a/chromium/third_party/blink/renderer/core/html/link_web_bundle_test.cc +++ b/chromium/third_party/blink/renderer/core/html/link_web_bundle_test.cc @@ -7,6 +7,8 @@ #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/dom_token_list.h" #include "third_party/blink/renderer/core/html/html_link_element.h" +#include "third_party/blink/renderer/core/testing/sim/sim_request.h" +#include "third_party/blink/renderer/core/testing/sim/sim_test.h" namespace blink { @@ -18,7 +20,9 @@ void TestParseResourceUrl(const AtomicString& url, bool is_valid) { } // namespace -TEST(LinkWebBundleTest, ParseResourceUrl) { +class LinkWebBundleTest : public SimTest {}; + +TEST_F(LinkWebBundleTest, ParseResourceUrl) { TestParseResourceUrl("https://test.example.com/", true); TestParseResourceUrl("http://test.example.com/", true); TestParseResourceUrl("https://user@test.example.com/", false); @@ -28,10 +32,13 @@ TEST(LinkWebBundleTest, ParseResourceUrl) { TestParseResourceUrl("file:///test.html", false); } -TEST(LinkWebBundleTest, ResourcesAttribute) { - auto* document = Document::CreateForTest(); - auto* link = - MakeGarbageCollected<HTMLLinkElement>(*document, CreateElementFlags()); +TEST_F(LinkWebBundleTest, ResourcesAttribute) { + SimRequest request("https://example.com/test.html", "text/html"); + LoadURL("https://example.com/test.html"); + request.Complete("<!DOCTYPE html>"); + + auto* link = MakeGarbageCollected<HTMLLinkElement>(GetDocument(), + CreateElementFlags()); DOMTokenList* resources = link->resources(); EXPECT_EQ(g_null_atom, resources->value()); diff --git a/chromium/third_party/blink/renderer/core/html/list_item_ordinal.cc b/chromium/third_party/blink/renderer/core/html/list_item_ordinal.cc index 1fb038cc305..1317bbda431 100644 --- a/chromium/third_party/blink/renderer/core/html/list_item_ordinal.cc +++ b/chromium/third_party/blink/renderer/core/html/list_item_ordinal.cc @@ -4,8 +4,9 @@ #include "third_party/blink/renderer/core/html/list_item_ordinal.h" -#include "base/numerics/clamped_math.h" +#include "base/numerics/safe_conversions.h" #include "third_party/blink/renderer/core/dom/layout_tree_builder_traversal.h" +#include "third_party/blink/renderer/core/dom/node_computed_style.h" #include "third_party/blink/renderer/core/html/html_olist_element.h" #include "third_party/blink/renderer/core/layout/layout_list_item.h" #include "third_party/blink/renderer/core/layout/ng/list/layout_ng_list_item.h" @@ -74,7 +75,6 @@ ListItemOrdinal::NodeAndOrdinal ListItemOrdinal::NextListItem( const Node* current = item ? item : list_node; DCHECK(current); - DCHECK(!current->GetDocument().ChildNeedsDistributionRecalc()); current = LayoutTreeBuilderTraversal::Next(*current, list_node); while (current) { @@ -102,7 +102,6 @@ ListItemOrdinal::NodeAndOrdinal ListItemOrdinal::PreviousListItem( const Node* item) { const Node* current = item; DCHECK(current); - DCHECK(!current->GetDocument().ChildNeedsDistributionRecalc()); for (current = LayoutTreeBuilderTraversal::Previous(*current, list_node); current && current != list_node; current = LayoutTreeBuilderTraversal::Previous(*current, list_node)) { @@ -145,19 +144,27 @@ int ListItemOrdinal::CalcValue(const Node& item_node) const { Node* list = EnclosingList(&item_node); auto* o_list_element = DynamicTo<HTMLOListElement>(list); - int value_step = 1; - if (o_list_element && o_list_element->IsReversed()) - value_step = -1; + const bool is_reversed = o_list_element && o_list_element->IsReversed(); + int value_step = is_reversed ? -1 : 1; + if (const auto* style = item_node.GetComputedStyle()) { + const auto directives = + style->GetCounterDirectives(AtomicString("list-item")); + if (directives.IsSet()) + return directives.CombinedValue(); + if (directives.IsIncrement()) + value_step = directives.CombinedValue(); + } + int64_t base_value = 0; // FIXME: This recurses to a possible depth of the length of the list. // That's not good -- we need to change this to an iterative algorithm. - if (NodeAndOrdinal previous = PreviousListItem(list, &item_node)) - return base::ClampAdd(previous.ordinal->Value(*previous.node), value_step); - - if (o_list_element) - return o_list_element->StartConsideringItemCount(); - - return 1; + if (NodeAndOrdinal previous = PreviousListItem(list, &item_node)) { + base_value = previous.ordinal->Value(*previous.node); + } else if (o_list_element) { + base_value = o_list_element->StartConsideringItemCount(); + base_value += (is_reversed ? 1 : -1); + } + return base::saturated_cast<int>(base_value + value_step); } int ListItemOrdinal::Value(const Node& item_node) const { @@ -249,10 +256,8 @@ void ListItemOrdinal::InvalidateAllItemsForOrderedList( // TODO(layout-dev): We should use layout tree traversal instead of flat tree // traversal to invalidate ordinal number cache since lite items in unassigned // slots don't have cached value. See http://crbug.com/844277 for details. -void ListItemOrdinal::ItemInsertedOrRemoved( - const LayoutObject* layout_list_item) { - // If distribution recalc is needed, updateListMarkerNumber will be re-invoked - // after distribution is calculated. +void ListItemOrdinal::ItemUpdated(const LayoutObject* layout_list_item, + UpdateType type) { const Node* item_node = layout_list_item->GetNode(); if (item_node->GetDocument().IsSlotAssignmentOrLegacyDistributionDirty()) return; @@ -264,7 +269,8 @@ void ListItemOrdinal::ItemInsertedOrRemoved( bool is_list_reversed = false; if (auto* o_list_element = DynamicTo<HTMLOListElement>(list_node)) { - o_list_element->ItemCountChanged(); + if (type == kInsertedOrRemoved) + o_list_element->ItemCountChanged(); is_list_reversed = o_list_element->IsReversed(); } @@ -276,7 +282,22 @@ void ListItemOrdinal::ItemInsertedOrRemoved( if (list_node->NeedsReattachLayoutTree()) return; + if (type == kCounterStyle) { + ListItemOrdinal* ordinal = Get(*item_node); + DCHECK(ordinal); + ordinal->InvalidateSelf(*item_node); + } InvalidateOrdinalsAfter(is_list_reversed, list_node, item_node); } +void ListItemOrdinal::ItemInsertedOrRemoved( + const LayoutObject* layout_list_item) { + ItemUpdated(layout_list_item, kInsertedOrRemoved); +} + +void ListItemOrdinal::ItemCounterStyleUpdated( + const LayoutObject& layout_list_item) { + ItemUpdated(&layout_list_item, kCounterStyle); +} + } // namespace blink 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 01d3cafd768..1042afaf1c2 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 @@ -51,6 +51,8 @@ class CORE_EXPORT ListItemOrdinal { // Invalidate items that are affected by an insertion or a removal. static void ItemInsertedOrRemoved(const LayoutObject*); + // Invalidate items that are affected by counter style update. + static void ItemCounterStyleUpdated(const LayoutObject&); private: enum ValueType { kNeedsUpdate, kUpdated, kExplicit }; @@ -82,6 +84,8 @@ class CORE_EXPORT ListItemOrdinal { static void InvalidateOrdinalsAfter(bool is_reversed, const Node* list_node, const Node* item_node); + enum UpdateType { kInsertedOrRemoved, kCounterStyle }; + static void ItemUpdated(const LayoutObject*, UpdateType type); mutable int value_ = 0; mutable unsigned type_ : 2; // ValueType diff --git a/chromium/third_party/blink/renderer/core/html/media/DEPS b/chromium/third_party/blink/renderer/core/html/media/DEPS index 18abf950027..a8906ade4a0 100644 --- a/chromium/third_party/blink/renderer/core/html/media/DEPS +++ b/chromium/third_party/blink/renderer/core/html/media/DEPS @@ -1,4 +1,14 @@ include_rules = [ "+media/base/logging_override_if_enabled.h", + "+media/base/media_content_type.h", "+media/base/media_switches.h", + "+media/base/video_frame.h", + "+media/mojo/mojom/media_player.mojom-blink.h", ] + +specific_include_rules = { + # Tests need to wait to check mojo messages are correctly sent. + "html_media_element_test\.cc": [ + "+base/run_loop.h", + ], +} diff --git a/chromium/third_party/blink/renderer/core/html/media/DIR_METADATA b/chromium/third_party/blink/renderer/core/html/media/DIR_METADATA new file mode 100644 index 00000000000..33fee42126b --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/media/DIR_METADATA @@ -0,0 +1,5 @@ +monorail { + component: "Blink>Media" +} + +team_email: "media-dev@chromium.org" diff --git a/chromium/third_party/blink/renderer/core/html/media/OWNERS b/chromium/third_party/blink/renderer/core/html/media/OWNERS index 3d20d5d3962..2d282460822 100644 --- a/chromium/third_party/blink/renderer/core/html/media/OWNERS +++ b/chromium/third_party/blink/renderer/core/html/media/OWNERS @@ -1,4 +1 @@ mlamouri@chromium.org - -# TEAM: media-dev@chromium.org -# COMPONENT: Blink>Media diff --git a/chromium/third_party/blink/renderer/core/html/media/audio_output_device_controller.cc b/chromium/third_party/blink/renderer/core/html/media/audio_output_device_controller.cc new file mode 100644 index 00000000000..3a762f42161 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/media/audio_output_device_controller.cc @@ -0,0 +1,35 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/html/media/audio_output_device_controller.h" + +namespace blink { + +// static +const char AudioOutputDeviceController::kSupplementName[] = + "AudioOutputDeviceController"; + +// static +AudioOutputDeviceController* AudioOutputDeviceController::From( + HTMLMediaElement& element) { + return Supplement<HTMLMediaElement>::From<AudioOutputDeviceController>( + element); +} + +void AudioOutputDeviceController::Trace(Visitor* visitor) const { + Supplement<HTMLMediaElement>::Trace(visitor); +} + +AudioOutputDeviceController::AudioOutputDeviceController( + HTMLMediaElement& element) + : Supplement<HTMLMediaElement>(element) {} + +// static +void AudioOutputDeviceController::ProvideTo( + HTMLMediaElement& element, + AudioOutputDeviceController* controller) { + Supplement<HTMLMediaElement>::ProvideTo(element, controller); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/media/audio_output_device_controller.h b/chromium/third_party/blink/renderer/core/html/media/audio_output_device_controller.h new file mode 100644 index 00000000000..1bbb2e76906 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/media/audio_output_device_controller.h @@ -0,0 +1,34 @@ +// Copyright 2021 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_AUDIO_OUTPUT_DEVICE_CONTROLLER_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_AUDIO_OUTPUT_DEVICE_CONTROLLER_H_ + +#include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/html/media/html_media_element.h" +#include "third_party/blink/renderer/platform/supplementable.h" + +namespace blink { + +class CORE_EXPORT AudioOutputDeviceController + : public Supplement<HTMLMediaElement> { + public: + static const char kSupplementName[]; + + static AudioOutputDeviceController* From(HTMLMediaElement&); + + virtual void SetSinkId(const String&) = 0; + + void Trace(Visitor*) const override; + + protected: + explicit AudioOutputDeviceController(HTMLMediaElement&); + + // To be called by the implementation to register itself. + static void ProvideTo(HTMLMediaElement&, AudioOutputDeviceController*); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_AUDIO_OUTPUT_DEVICE_CONTROLLER_H_ 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 98169739f2d..c5aaff6418f 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 @@ -323,7 +323,9 @@ String AutoplayPolicy::GetPlayErrorMessage() const { } bool AutoplayPolicy::WasAutoplayInitiated() const { - DCHECK(autoplay_initiated_.has_value()); + if (!autoplay_initiated_.has_value()) + return false; + return *autoplay_initiated_; } 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 4ab449a7ca0..d5aefd079bf 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 @@ -36,11 +36,14 @@ #include "base/metrics/histogram_functions.h" #include "base/time/time.h" #include "media/base/logging_override_if_enabled.h" +#include "media/base/media_content_type.h" #include "media/base/media_switches.h" +#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" #include "third_party/blink/public/common/privacy_budget/identifiability_metric_builder.h" #include "third_party/blink/public/common/privacy_budget/identifiability_study_settings.h" #include "third_party/blink/public/common/privacy_budget/identifiable_surface.h" #include "third_party/blink/public/common/widget/screen_info.h" +#include "third_party/blink/public/mojom/frame/user_activation_notification_type.mojom-shared.h" #include "third_party/blink/public/platform/modules/mediastream/web_media_stream.h" #include "third_party/blink/public/platform/modules/remoteplayback/web_remote_playback_client.h" #include "third_party/blink/public/platform/platform.h" @@ -53,6 +56,7 @@ #include "third_party/blink/renderer/bindings/core/v8/script_controller.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/core_initializer.h" +#include "third_party/blink/renderer/core/core_probes_inl.h" #include "third_party/blink/renderer/core/css/media_list.h" #include "third_party/blink/renderer/core/dom/attribute.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" @@ -68,9 +72,11 @@ #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/picture_in_picture_controller.h" #include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/core/fullscreen/fullscreen.h" #include "third_party/blink/renderer/core/html/html_source_element.h" +#include "third_party/blink/renderer/core/html/media/audio_output_device_controller.h" #include "third_party/blink/renderer/core/html/media/autoplay_policy.h" #include "third_party/blink/renderer/core/html/media/html_media_element_controls_list.h" #include "third_party/blink/renderer/core/html/media/media_controls.h" @@ -531,7 +537,10 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tag_name, remote_playback_client_(nullptr), media_controls_(nullptr), controls_list_(MakeGarbageCollected<HTMLMediaElementControlsList>(this)), - lazy_load_intersection_observer_(nullptr) { + lazy_load_intersection_observer_(nullptr), + media_player_host_remote_(GetExecutionContext()), + media_player_observer_remote_set_(GetExecutionContext()), + media_player_receiver_set_(this, GetExecutionContext()) { DVLOG(1) << "HTMLMediaElement(" << *this << ")"; LocalFrame* frame = document.GetFrame(); @@ -1319,6 +1328,17 @@ void HTMLMediaElement::StartPlayerLoad() { OnWebMediaPlayerCreated(); + // Setup the communication channels between the renderer and browser processes + // via the MediaPlayer and MediaPlayerObserver mojo interfaces. + DCHECK(media_player_receiver_set_.empty()); + mojo::PendingAssociatedRemote<media::mojom::blink::MediaPlayer> + media_player_remote; + BindMediaPlayerReceiver( + media_player_remote.InitWithNewEndpointAndPassReceiver()); + + GetMediaPlayerHostRemote().OnMediaPlayerAdded( + std::move(media_player_remote), web_media_player_->GetDelegateId()); + if (GetLayoutObject()) GetLayoutObject()->SetShouldDoFullPaintInvalidation(); // Make sure if we create/re-create the WebMediaPlayer that we update our @@ -1334,7 +1354,11 @@ void HTMLMediaElement::StartPlayerLoad() { web_media_player_->RequestRemotePlaybackDisabled( FastHasAttribute(html_names::kDisableremoteplaybackAttr)); - auto load_timing = web_media_player_->Load(GetLoadType(), source, CorsMode()); + bool is_cache_disabled = false; + probe::IsCacheDisabled(GetDocument().GetExecutionContext(), + &is_cache_disabled); + auto load_timing = web_media_player_->Load(GetLoadType(), source, CorsMode(), + is_cache_disabled); if (load_timing == WebMediaPlayer::LoadTiming::kDeferred) { // Deferred media loading is not part of the spec, but intuition is that // this should not hold up the Window's "load" event (similar to user @@ -1443,6 +1467,18 @@ bool HTMLMediaElement::PausedWhenVisible() const { !GetWebMediaPlayer()->PausedWhenHidden(); } +void HTMLMediaElement::DidAudioOutputSinkChanged( + const String& hashed_device_id) { + for (auto& observer : media_player_observer_remote_set_) + observer->OnAudioOutputSinkChanged(hashed_device_id); +} + +void HTMLMediaElement::AddMediaPlayerObserverForTesting( + mojo::PendingAssociatedRemote<media::mojom::blink::MediaPlayerObserver> + observer) { + AddMediaPlayerObserver(std::move(observer)); +} + bool HTMLMediaElement::TextTracksAreReady() const { // 4.8.12.11.1 Text track model // ... @@ -1928,6 +1964,8 @@ void HTMLMediaElement::SetReadyState(ReadyState state) { jumped = true; } + web_media_player_->SetAutoplayInitiated(true); + UpdateLayoutObject(); } @@ -3438,11 +3476,6 @@ void HTMLMediaElement::DurationChanged(double duration, bool request_seek) { Seek(duration); } -void HTMLMediaElement::RequestSeek(double time) { - // The player is the source of this seek request. - setCurrentTime(time); -} - bool HTMLMediaElement::HasRemoteRoutes() const { // TODO(mlamouri): used by MediaControlsPainter; should be refactored out. return RemotePlaybackClient() && @@ -3644,7 +3677,13 @@ void HTMLMediaElement:: if (web_media_player_) { audio_source_provider_.Wrap(nullptr); web_media_player_.reset(); + + // The lifetime of the mojo endpoints are tied to the WebMediaPlayer's, so + // we need to reset those as well. + media_player_receiver_set_.Clear(); + media_player_observer_remote_set_.Clear(); } + OnWebMediaPlayerCleared(); } void HTMLMediaElement::ClearMediaPlayer() { @@ -4082,13 +4121,33 @@ bool HTMLMediaElement::IsInteractiveContent() const { return FastHasAttribute(html_names::kControlsAttr); } +void HTMLMediaElement::BindMediaPlayerReceiver( + mojo::PendingAssociatedReceiver<media::mojom::blink::MediaPlayer> + receiver) { + mojo::ReceiverId receiver_id = media_player_receiver_set_.Add( + std::move(receiver), + GetDocument().GetTaskRunner(TaskType::kInternalMedia)); + + media_player_receiver_set_.set_disconnect_handler(WTF::BindRepeating( + [](HTMLMediaElement* html_media_element, mojo::ReceiverId receiver_id) { + html_media_element->media_player_receiver_set_.Remove(receiver_id); + }, + WrapWeakPersistent(this), receiver_id)); +} + void HTMLMediaElement::Trace(Visitor* visitor) const { visitor->Trace(audio_source_node_); + visitor->Trace(load_timer_); + visitor->Trace(progress_event_timer_); + visitor->Trace(playback_progress_timer_); + visitor->Trace(audio_tracks_timer_); + visitor->Trace(removed_from_document_timer_); visitor->Trace(played_time_ranges_); visitor->Trace(async_event_queue_); visitor->Trace(error_); visitor->Trace(current_source_node_); visitor->Trace(next_child_node_to_consider_); + visitor->Trace(deferred_load_timer_); visitor->Trace(media_source_tracer_); visitor->Trace(audio_tracks_); visitor->Trace(video_tracks_); @@ -4104,6 +4163,9 @@ void HTMLMediaElement::Trace(Visitor* visitor) const { visitor->Trace(media_controls_); visitor->Trace(controls_list_); visitor->Trace(lazy_load_intersection_observer_); + visitor->Trace(media_player_host_remote_); + visitor->Trace(media_player_observer_remote_set_); + visitor->Trace(media_player_receiver_set_); Supplementable<HTMLMediaElement>::Trace(visitor); HTMLElement::Trace(visitor); ExecutionContextLifecycleStateObserver::Trace(visitor); @@ -4247,7 +4309,10 @@ void HTMLMediaElement::OnRemovedFromDocumentTimerFired(TimerBase*) { if (InActiveDocument()) return; - PauseInternal(); + // Video should not pause when playing in Picture-in-Picture and subsequently + // removed from the Document. + if (!PictureInPictureController::IsElementInPictureInPicture(this)) + PauseInternal(); } void HTMLMediaElement::AudioSourceProviderImpl::Wrap( @@ -4335,17 +4400,142 @@ bool HTMLMediaElement::WasAutoplayInitiated() { return autoplay_policy_->WasAutoplayInitiated(); } +void HTMLMediaElement::ResumePlayback() { + autoplay_policy_->EnsureAutoplayInitiatedSet(); + PlayInternal(); +} + +void HTMLMediaElement::PausePlayback() { + PauseInternal(); +} + +void HTMLMediaElement::DidPlayerStartPlaying() { + for (auto& observer : media_player_observer_remote_set_) + observer->OnMediaPlaying(); +} + +void HTMLMediaElement::DidPlayerPaused(bool stream_ended) { + for (auto& observer : media_player_observer_remote_set_) + observer->OnMediaPaused(stream_ended); +} + +void HTMLMediaElement::DidPlayerMutedStatusChange(bool muted) { + for (auto& observer : media_player_observer_remote_set_) + observer->OnMutedStatusChanged(muted); +} + +void HTMLMediaElement::DidMediaMetadataChange( + bool has_audio, + bool has_video, + media::MediaContentType media_content_type) { + for (auto& observer : media_player_observer_remote_set_) + observer->OnMediaMetadataChanged(has_audio, has_video, media_content_type); +} + +void HTMLMediaElement::DidPlayerMediaPositionStateChange( + double playback_rate, + base::TimeDelta duration, + base::TimeDelta position) { + for (auto& observer : media_player_observer_remote_set_) { + observer->OnMediaPositionStateChanged( + media_session::mojom::blink::MediaPosition::New( + playback_rate, duration, position, base::TimeTicks::Now())); + } +} + +void HTMLMediaElement::DidDisableAudioOutputSinkChanges() { + for (auto& observer : media_player_observer_remote_set_) + observer->OnAudioOutputSinkChangingDisabled(); +} + +void HTMLMediaElement::DidPlayerSizeChange(const gfx::Size& size) { + for (auto& observer : media_player_observer_remote_set_) + observer->OnMediaSizeChanged(size); +} + +void HTMLMediaElement::DidBufferUnderflow() { + for (auto& observer : media_player_observer_remote_set_) + observer->OnBufferUnderflow(); +} + +void HTMLMediaElement::DidSeek() { + // Send the seek updates to the browser process only once per second. + if (last_seek_update_time_.is_null() || + (base::TimeTicks::Now() - last_seek_update_time_ >= + base::TimeDelta::FromSeconds(1))) { + last_seek_update_time_ = base::TimeTicks::Now(); + for (auto& observer : media_player_observer_remote_set_) + observer->OnSeek(); + } +} + +media::mojom::blink::MediaPlayerHost& +HTMLMediaElement::GetMediaPlayerHostRemote() { + // It is an error to call this before having access to the document's frame. + DCHECK(GetDocument().GetFrame()); + if (!media_player_host_remote_.is_bound()) { + GetDocument() + .GetFrame() + ->GetRemoteNavigationAssociatedInterfaces() + ->GetInterface(media_player_host_remote_.BindNewEndpointAndPassReceiver( + GetDocument().GetTaskRunner(TaskType::kInternalMedia))); + } + return *media_player_host_remote_.get(); +} + +void HTMLMediaElement::AddMediaPlayerObserver( + mojo::PendingAssociatedRemote<media::mojom::blink::MediaPlayerObserver> + observer) { + media_player_observer_remote_set_.Add( + std::move(observer), + GetDocument().GetTaskRunner(TaskType::kInternalMedia)); + + media_player_observer_remote_set_.set_disconnect_handler(WTF::BindRepeating( + [](HTMLMediaElement* html_media_element, + mojo::RemoteSetElementId remote_id) { + html_media_element->media_player_observer_remote_set_.Remove(remote_id); + }, + WrapWeakPersistent(this))); +} + void HTMLMediaElement::RequestPlay() { + LocalFrame* frame = GetDocument().GetFrame(); + if (frame) { + LocalFrame::NotifyUserActivation( + frame, mojom::blink::UserActivationNotificationType::kInteraction); + } autoplay_policy_->EnsureAutoplayInitiatedSet(); PlayInternal(); } -void HTMLMediaElement::RequestPause() { +void HTMLMediaElement::RequestPause(bool triggered_by_user) { + if (triggered_by_user) { + LocalFrame* frame = GetDocument().GetFrame(); + if (frame) { + LocalFrame::NotifyUserActivation( + frame, mojom::blink::UserActivationNotificationType::kInteraction); + } + } PauseInternal(); } -void HTMLMediaElement::RequestMuted(bool muted) { - setMuted(muted); +void HTMLMediaElement::RequestSeekForward(base::TimeDelta seek_time) { + double seconds = seek_time.InSecondsF(); + DCHECK_GE(seconds, 0) << "Attempted to seek by a negative number of seconds"; + setCurrentTime(currentTime() + seconds); +} + +void HTMLMediaElement::RequestSeekBackward(base::TimeDelta seek_time) { + double seconds = seek_time.InSecondsF(); + DCHECK_GE(seconds, 0) << "Attempted to seek by a negative number of seconds"; + setCurrentTime(currentTime() - seconds); +} + +void HTMLMediaElement::SetAudioSinkId(const String& sink_id) { + auto* audio_output_controller = AudioOutputDeviceController::From(*this); + DCHECK(audio_output_controller); + + audio_output_controller->SetSinkId(sink_id); } bool HTMLMediaElement::MediaShouldBeOpaque() const { 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 8d1149fc950..0424d5d2b8e 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 @@ -30,7 +30,9 @@ #include <memory> #include "base/optional.h" +#include "base/time/time.h" #include "base/timer/elapsed_timer.h" +#include "media/mojo/mojom/media_player.mojom-blink.h" #include "third_party/blink/public/common/media/display_type.h" #include "third_party/blink/public/platform/web_media_player_client.h" #include "third_party/blink/public/platform/webaudiosourceprovider_impl.h" @@ -44,16 +46,24 @@ #include "third_party/blink/renderer/platform/audio/audio_source_provider.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/media/web_audio_source_provider_client.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_receiver_set.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote.h" +#include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote_set.h" #include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h" #include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h" #include "third_party/blink/renderer/platform/supplementable.h" #include "third_party/blink/renderer/platform/timer.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" +#include "third_party/blink/renderer/platform/wtf/threading_primitives.h" namespace cc { class Layer; } +namespace media { +enum class MediaContentType; +} // namespace media + namespace blink { class AudioSourceProviderClient; @@ -88,6 +98,7 @@ class CORE_EXPORT HTMLMediaElement public Supplementable<HTMLMediaElement>, public ActiveScriptWrappable<HTMLMediaElement>, public ExecutionContextLifecycleStateObserver, + public media::mojom::blink::MediaPlayer, private WebMediaPlayerClient { DEFINE_WRAPPERTYPEINFO(); USING_PRE_FINALIZER(HTMLMediaElement, Dispose); @@ -113,6 +124,12 @@ class CORE_EXPORT HTMLMediaElement // for the given document. static void OnMediaControlsEnabledChange(Document*); + // Binds |pending_receiver| and adds it to |media_player_receiver_set_|. Also + // called from other Blink classes (e.g. PictureInPictureControllerImpl). + void BindMediaPlayerReceiver( + mojo::PendingAssociatedReceiver<media::mojom::blink::MediaPlayer> + pending_receiver); + void Trace(Visitor*) const override; WebMediaPlayer* GetWebMediaPlayer() const { return web_media_player_.get(); } @@ -336,8 +353,15 @@ class CORE_EXPORT HTMLMediaElement // becomes visible again. bool PausedWhenVisible() const; + void DidAudioOutputSinkChanged(const String& hashed_device_id); + void SetCcLayerForTesting(cc::Layer* layer) { SetCcLayer(layer); } + // Required by tests set mock receivers to check that messages are delivered. + void AddMediaPlayerObserverForTesting( + mojo::PendingAssociatedRemote<media::mojom::blink::MediaPlayerObserver> + observer); + bool IsShowPosterFlagSet() const { return show_poster_flag_; } protected: @@ -348,6 +372,15 @@ class CORE_EXPORT HTMLMediaElement ~HTMLMediaElement() override; void Dispose(); + // Returns a constant reference to the HeapMojoAssociatedRemoteSet holding all + // the bound remotes for the media::mojom::blink::MediaPlayerObserver + // interface. Needed to allow sending messages directly from + // HTMLMediaElement's subclasses. + const HeapMojoAssociatedRemoteSet<media::mojom::blink::MediaPlayerObserver>& + GetMediaPlayerObserverRemoteSet() { + return media_player_observer_remote_set_; + } + void ParseAttribute(const AttributeModificationParams&) override; void FinishParsingChildren() final; bool IsURLAttribute(const Attribute&) const override; @@ -369,14 +402,16 @@ class CORE_EXPORT HTMLMediaElement // Called after the creation of |web_media_player_|. virtual void OnWebMediaPlayerCreated() {} + virtual void OnWebMediaPlayerCleared() {} void UpdateLayoutObject(); private: // Friend class for testing. friend class ContextMenuControllerTest; - friend class VideoWakeLockTest; + friend class HTMLMediaElementTest; friend class PictureInPictureControllerTest; + friend class VideoWakeLockTest; bool HasPendingActivityInternal() const; @@ -433,7 +468,6 @@ class CORE_EXPORT HTMLMediaElement void AddTextTrack(WebInbandTextTrack*) final; void RemoveTextTrack(WebInbandTextTrack*) final; void MediaSourceOpened(WebMediaSource*) final; - void RequestSeek(double) final; void RemotePlaybackCompatibilityChanged(const WebURL&, bool is_compatible) final; void OnBecamePersistentVideo(bool) override {} @@ -450,11 +484,39 @@ class CORE_EXPORT HTMLMediaElement gfx::ColorSpace TargetColorSpace() override; bool WasAutoplayInitiated() override; bool IsInAutoPIP() const override { return false; } - void RequestPlay() final; - void RequestPause() final; - void RequestMuted(bool muted) final; + void ResumePlayback() final; + void PausePlayback() final; + void DidPlayerStartPlaying() override; + void DidPlayerPaused(bool stream_ended) override; + void DidPlayerMutedStatusChange(bool muted) override; + void DidMediaMetadataChange( + bool has_audio, + bool has_video, + media::MediaContentType media_content_type) override; + void DidPlayerMediaPositionStateChange(double playback_rate, + base::TimeDelta duration, + base::TimeDelta position) override; + void DidDisableAudioOutputSinkChanges() override; + void DidPlayerSizeChange(const gfx::Size& size) override; + void DidBufferUnderflow() override; + void DidSeek() override; + + // Returns a reference to the mojo remote for the MediaPlayerHost interface, + // requesting it first from the BrowserInterfaceBroker if needed. It is an + // error to call this method before having access to the document's frame. + media::mojom::blink::MediaPlayerHost& GetMediaPlayerHostRemote(); + + // media::mojom::MediaPlayer implementation. + void AddMediaPlayerObserver( + mojo::PendingAssociatedRemote<media::mojom::blink::MediaPlayerObserver> + observer) override; + void RequestPlay() override; + void RequestPause(bool triggered_by_user) override; + void RequestSeekForward(base::TimeDelta seek_time) override; + void RequestSeekBackward(base::TimeDelta seek_time) override; void RequestEnterPictureInPicture() override {} void RequestExitPictureInPicture() override {} + void SetAudioSinkId(const String&) override; void LoadTimerFired(TimerBase*); void ProgressEventTimerFired(TimerBase*); @@ -571,11 +633,11 @@ class CORE_EXPORT HTMLMediaElement Features GetFeatures() override; - TaskRunnerTimer<HTMLMediaElement> load_timer_; - TaskRunnerTimer<HTMLMediaElement> progress_event_timer_; - TaskRunnerTimer<HTMLMediaElement> playback_progress_timer_; - TaskRunnerTimer<HTMLMediaElement> audio_tracks_timer_; - TaskRunnerTimer<HTMLMediaElement> removed_from_document_timer_; + HeapTaskRunnerTimer<HTMLMediaElement> load_timer_; + HeapTaskRunnerTimer<HTMLMediaElement> progress_event_timer_; + HeapTaskRunnerTimer<HTMLMediaElement> playback_progress_timer_; + HeapTaskRunnerTimer<HTMLMediaElement> audio_tracks_timer_; + HeapTaskRunnerTimer<HTMLMediaElement> removed_from_document_timer_; Member<TimeRanges> played_time_ranges_; Member<EventQueue> async_event_queue_; @@ -632,7 +694,7 @@ class CORE_EXPORT HTMLMediaElement kExecuteOnStopDelayingLoadEventTask }; DeferredLoadState deferred_load_state_; - TaskRunnerTimer<HTMLMediaElement> deferred_load_timer_; + HeapTaskRunnerTimer<HTMLMediaElement> deferred_load_timer_; std::unique_ptr<WebMediaPlayer> web_media_player_; cc::Layer* cc_layer_; @@ -685,6 +747,9 @@ class CORE_EXPORT HTMLMediaElement // playback raters other than 1.0. bool preserves_pitch_ = true; + // Keeps track of when the player seek event was sent to the browser process. + base::TimeTicks last_seek_update_time_; + Member<AudioTrackList> audio_tracks_; Member<VideoTrackList> video_tracks_; Member<TextTrackList> text_tracks_; @@ -771,6 +836,22 @@ class CORE_EXPORT HTMLMediaElement Member<HTMLMediaElementControlsList> controls_list_; Member<IntersectionObserver> lazy_load_intersection_observer_; + + HeapMojoAssociatedRemote<media::mojom::blink::MediaPlayerHost> + media_player_host_remote_; + + // Multiple objects outside of the renderer process can register as observers, + // so we need to store the remotes in a set here. + HeapMojoAssociatedRemoteSet<media::mojom::blink::MediaPlayerObserver> + media_player_observer_remote_set_; + + // A receiver set is needed here as there will be different objects in the + // browser communicating with this object. This is done this way to avoid + // routing everything through a single class (e.g. RFHI) and to keep this + // logic contained inside MediaPlayer-related classes. + HeapMojoAssociatedReceiverSet<media::mojom::blink::MediaPlayer, + HTMLMediaElement> + media_player_receiver_set_; }; template <> diff --git a/chromium/third_party/blink/renderer/core/html/media/html_media_element_test.cc b/chromium/third_party/blink/renderer/core/html/media/html_media_element_test.cc index f1e5dba46ed..0c4ad27a6be 100644 --- a/chromium/third_party/blink/renderer/core/html/media/html_media_element_test.cc +++ b/chromium/third_party/blink/renderer/core/html/media/html_media_element_test.cc @@ -4,7 +4,10 @@ #include "third_party/blink/renderer/core/html/media/html_media_element.h" +#include "base/run_loop.h" #include "base/test/gtest_util.h" +#include "media/base/media_content_type.h" +#include "media/mojo/mojom/media_player.mojom-blink.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/mojom/autoplay/autoplay.mojom-blink.h" @@ -26,6 +29,7 @@ #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" #include "third_party/blink/renderer/platform/wtf/vector.h" +#include "ui/gfx/geometry/size.h" using ::testing::_; using ::testing::AnyNumber; @@ -50,11 +54,12 @@ class MockWebMediaPlayer : public EmptyWebMediaPlayer { MOCK_METHOD1(SetLatencyHint, void(double)); MOCK_METHOD1(EnabledAudioTracksChanged, void(const WebVector<TrackId>&)); MOCK_METHOD1(SelectedVideoTrackChanged, void(TrackId*)); - MOCK_METHOD3( + MOCK_METHOD4( Load, WebMediaPlayer::LoadTiming(LoadType load_type, const blink::WebMediaPlayerSource& source, - CorsMode cors_mode)); + CorsMode cors_mode, + bool is_cache_disabled)); MOCK_CONST_METHOD0(DidLazyLoad, bool()); MOCK_METHOD0(GetSrcAfterRedirects, GURL()); @@ -77,6 +82,122 @@ class WebMediaStubLocalFrameClient : public EmptyLocalFrameClient { std::unique_ptr<WebMediaPlayer> player_; }; +// Helper class that provides an implementation of the MediaPlayerObserver mojo +// interface to allow checking that messages sent over mojo are received with +// the right values in the other end. +// +// Note this relies on HTMLMediaElement::AddMediaPlayerObserverForTesting() to +// provide the HTMLMediaElement instance owned by the test with a valid mojo +// remote, that will be bound to the mojo receiver provided by this class +// instead of the real one used in production that would be owned by +// MediaSessionController instead. +class MockMediaPlayerObserverReceiverForTesting + : public media::mojom::blink::MediaPlayerObserver { + public: + struct OnMetadataChangedResult { + bool has_audio; + bool has_video; + media::MediaContentType media_content_type; + }; + + explicit MockMediaPlayerObserverReceiverForTesting( + HTMLMediaElement* html_media_element) { + // Bind the remote to the receiver, so that we can intercept incoming + // messages sent via the different methods that use the remote. + html_media_element->AddMediaPlayerObserverForTesting( + receiver_.BindNewEndpointAndPassDedicatedRemote()); + } + + // Needs to be called from tests after invoking a method from the MediaPlayer + // mojo interface, so that we have enough time to process the message. + void WaitUntilReceivedMessage() { + run_loop_ = std::make_unique<base::RunLoop>(); + run_loop_->Run(); + run_loop_.reset(); + } + + // media::mojom::blink::MediaPlayerObserver implementation. + void OnMediaPlaying() override { + received_media_playing_ = true; + run_loop_->Quit(); + } + + void OnMediaPaused(bool stream_ended) override { + received_media_paused_stream_ended_ = stream_ended; + run_loop_->Quit(); + } + + void OnMutedStatusChanged(bool muted) override { + received_muted_status_type_ = muted; + run_loop_->Quit(); + } + + void OnMediaMetadataChanged(bool has_audio, + bool has_video, + media::MediaContentType content_type) override { + // struct OnMetadataChangedResult result{has_audio, has_video, + // content_type}; + received_metadata_changed_result_ = + OnMetadataChangedResult{has_audio, has_video, content_type}; + run_loop_->Quit(); + } + + void OnMediaPositionStateChanged( + ::media_session::mojom::blink::MediaPositionPtr) override {} + + void OnMediaEffectivelyFullscreenChanged( + blink::WebFullscreenVideoStatus status) override {} + + void OnMediaSizeChanged(const gfx::Size& size) override { + received_media_size_ = size; + run_loop_->Quit(); + } + + void OnPictureInPictureAvailabilityChanged(bool available) override {} + + void OnAudioOutputSinkChanged(const WTF::String& hashed_device_id) override {} + + void OnAudioOutputSinkChangingDisabled() override {} + + void OnBufferUnderflow() override { + received_buffer_underflow_ = true; + run_loop_->Quit(); + } + + void OnSeek() override {} + + // Getters used from HTMLMediaElementTest. + bool received_media_playing() const { return received_media_playing_; } + + const base::Optional<bool>& received_media_paused_stream_ended() const { + return received_media_paused_stream_ended_; + } + + const base::Optional<bool>& received_muted_status() const { + return received_muted_status_type_; + } + + const base::Optional<OnMetadataChangedResult>& + received_metadata_changed_result() const { + return received_metadata_changed_result_; + } + + gfx::Size received_media_size() const { return received_media_size_; } + + bool received_buffer_underflow() const { return received_buffer_underflow_; } + + private: + std::unique_ptr<base::RunLoop> run_loop_; + mojo::AssociatedReceiver<media::mojom::blink::MediaPlayerObserver> receiver_{ + this}; + bool received_media_playing_{false}; + base::Optional<bool> received_media_paused_stream_ended_; + base::Optional<bool> received_muted_status_type_; + base::Optional<OnMetadataChangedResult> received_metadata_changed_result_; + gfx::Size received_media_size_{0, 0}; + bool received_buffer_underflow_{false}; +}; + enum class MediaTestParam { kAudio, kVideo }; } // namespace @@ -96,7 +217,7 @@ class HTMLMediaElementTest : public testing::TestWithParam<MediaTestParam> { EXPECT_CALL(*mock_media_player, HasVideo()).WillRepeatedly(Return(true)); EXPECT_CALL(*mock_media_player, Duration()).WillRepeatedly(Return(1.0)); EXPECT_CALL(*mock_media_player, CurrentTime()).WillRepeatedly(Return(0)); - EXPECT_CALL(*mock_media_player, Load(_, _, _)) + EXPECT_CALL(*mock_media_player, Load(_, _, _, _)) .Times(AnyNumber()) .WillRepeatedly(Return(WebMediaPlayer::LoadTiming::kImmediate)); EXPECT_CALL(*mock_media_player, DidLazyLoad).WillRepeatedly(Return(false)); @@ -118,6 +239,9 @@ class HTMLMediaElementTest : public testing::TestWithParam<MediaTestParam> { media_ = MakeGarbageCollected<HTMLVideoElement>( dummy_page_holder_->GetDocument()); } + + media_player_observer_receiver_ = + std::make_unique<MockMediaPlayerObserverReceiverForTesting>(Media()); } HTMLMediaElement* Media() const { return media_.Get(); } @@ -161,12 +285,81 @@ class HTMLMediaElementTest : public testing::TestWithParam<MediaTestParam> { return dummy_page_holder_->GetFrame().DomWindow(); } + protected: + // Helpers to call MediaPlayerObserver mojo methods and check their results. + void NotifyMediaPlaying() { + media_->DidPlayerStartPlaying(); + media_player_observer_receiver_->WaitUntilReceivedMessage(); + } + + bool ReceivedMessageMediaPlaying() { + return media_player_observer_receiver_->received_media_playing(); + } + + void NotifyMediaPaused(bool stream_ended) { + media_->DidPlayerPaused(stream_ended); + media_player_observer_receiver_->WaitUntilReceivedMessage(); + } + + bool ReceivedMessageMediaPaused(bool stream_ended) { + return media_player_observer_receiver_ + ->received_media_paused_stream_ended() == stream_ended; + } + + void NotifyMutedStatusChange(bool muted) { + media_->DidPlayerMutedStatusChange(muted); + media_player_observer_receiver_->WaitUntilReceivedMessage(); + } + + bool ReceivedMessageMutedStatusChange(bool muted) { + return media_player_observer_receiver_->received_muted_status() == muted; + } + + void NotifyMediaMetadataChanged(bool has_audio, + bool has_video, + media::MediaContentType media_content_type) { + media_->DidMediaMetadataChange(has_audio, has_video, media_content_type); + media_player_observer_receiver_->WaitUntilReceivedMessage(); + } + + bool ReceivedMessageMediaMetadataChanged( + bool has_audio, + bool has_video, + media::MediaContentType media_content_type) { + const auto& result = + media_player_observer_receiver_->received_metadata_changed_result(); + return result->has_audio == has_audio && result->has_video == has_video && + result->media_content_type == media_content_type; + } + + void NotifyMediaSizeChange(const gfx::Size& size) { + media_->DidPlayerSizeChange(size); + media_player_observer_receiver_->WaitUntilReceivedMessage(); + } + + bool ReceivedMessageMediaSizeChange(const gfx::Size& size) { + return media_player_observer_receiver_->received_media_size() == size; + } + + void NotifyBufferUnderflowEvent() { + media_->DidBufferUnderflow(); + media_player_observer_receiver_->WaitUntilReceivedMessage(); + } + + bool ReceivedMessageBufferUnderflowEvent() { + return media_player_observer_receiver_->received_buffer_underflow(); + } + private: std::unique_ptr<DummyPageHolder> dummy_page_holder_; Persistent<HTMLMediaElement> media_; // Owned by WebMediaStubLocalFrameClient. MockWebMediaPlayer* media_player_; + + // Used to check that mojo messages are received in the other end. + std::unique_ptr<MockMediaPlayerObserverReceiverForTesting> + media_player_observer_receiver_; }; INSTANTIATE_TEST_SUITE_P(Audio, @@ -466,7 +659,7 @@ TEST_P(HTMLMediaElementTest, // WebMediaPlayer will signal that it will defer loading to some later time. testing::Mock::VerifyAndClearExpectations(MockMediaPlayer()); - EXPECT_CALL(*MockMediaPlayer(), Load(_, _, _)) + EXPECT_CALL(*MockMediaPlayer(), Load(_, _, _, _)) .WillOnce(Return(WebMediaPlayer::LoadTiming::kDeferred)); // Window's 'load' event starts out "delayed". @@ -484,7 +677,7 @@ TEST_P(HTMLMediaElementTest, ImmediateMediaPlayerLoadDoesDelayWindowLoadEvent) { Media()->SetSrc(SrcSchemeToURL(TestURLScheme::kHttp)); // WebMediaPlayer will signal that it will do the load immediately. - EXPECT_CALL(*MockMediaPlayer(), Load(_, _, _)) + EXPECT_CALL(*MockMediaPlayer(), Load(_, _, _, _)) .WillOnce(Return(WebMediaPlayer::LoadTiming::kImmediate)); // Window's 'load' event starts out "delayed". @@ -552,7 +745,9 @@ TEST_P(HTMLMediaElementTest, GcMarkingNoAllocWebTimeRanges) { ThreadState::NoAllocationScope no_allocation_scope(thread_state); EXPECT_FALSE(thread_state->IsAllocationAllowed()); // Use of TimeRanges is not allowed during GC marking (crbug.com/970150) - EXPECT_DCHECK_DEATH(MakeGarbageCollected<TimeRanges>(0, 0)); +#if DCHECK_IS_ON() + EXPECT_DEATH_IF_SUPPORTED(MakeGarbageCollected<TimeRanges>(0, 0), ""); +#endif // DCHECK_IS_ON() // Instead of using TimeRanges, WebTimeRanges can be used without GC Vector<WebTimeRanges> ranges; ranges.emplace_back(); @@ -793,4 +988,54 @@ TEST_P(HTMLMediaElementTest, ShowPosterFlag_FalseAfterPlayBeforeReady) { EXPECT_FALSE(Media()->IsShowPosterFlagSet()); } +TEST_P(HTMLMediaElementTest, SendMediaPlayingToObserver) { + NotifyMediaPlaying(); + EXPECT_TRUE(ReceivedMessageMediaPlaying()); +} + +TEST_P(HTMLMediaElementTest, SendMediaPausedToObserver) { + NotifyMediaPaused(true); + EXPECT_TRUE(ReceivedMessageMediaPaused(true)); + + NotifyMediaPaused(false); + EXPECT_TRUE(ReceivedMessageMediaPaused(false)); +} + +TEST_P(HTMLMediaElementTest, SendMutedStatusChangeToObserver) { + NotifyMutedStatusChange(true); + EXPECT_TRUE(ReceivedMessageMutedStatusChange(true)); + + NotifyMutedStatusChange(false); + EXPECT_TRUE(ReceivedMessageMutedStatusChange(false)); +} + +TEST_P(HTMLMediaElementTest, SendMediaMetadataChangedToObserver) { + bool has_audio = false; + bool has_video = true; + media::MediaContentType media_content_type = + media::MediaContentType::Transient; + + NotifyMediaMetadataChanged(has_audio, has_video, media_content_type); + EXPECT_TRUE(ReceivedMessageMediaMetadataChanged(has_audio, has_video, + media_content_type)); + // Change values and test again. + has_audio = true; + has_video = false; + media_content_type = media::MediaContentType::OneShot; + NotifyMediaMetadataChanged(has_audio, has_video, media_content_type); + EXPECT_TRUE(ReceivedMessageMediaMetadataChanged(has_audio, has_video, + media_content_type)); +} + +TEST_P(HTMLMediaElementTest, SendMediaSizeChangeToObserver) { + const gfx::Size kTestMediaSizeChangedValue(16, 9); + NotifyMediaSizeChange(kTestMediaSizeChangedValue); + EXPECT_TRUE(ReceivedMessageMediaSizeChange(kTestMediaSizeChangedValue)); +} + +TEST_P(HTMLMediaElementTest, SendBufferOverflowToObserver) { + NotifyBufferUnderflowEvent(); + EXPECT_TRUE(ReceivedMessageBufferUnderflowEvent()); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/media/html_video_element.cc b/chromium/third_party/blink/renderer/core/html/media/html_video_element.cc index da233001ac4..550f35b0b75 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 @@ -30,6 +30,7 @@ #include "base/callback_helpers.h" #include "base/metrics/histogram_functions.h" #include "cc/paint/paint_canvas.h" +#include "media/base/video_frame.h" #include "third_party/blink/public/mojom/feature_policy/feature_policy_feature.mojom-blink.h" #include "third_party/blink/public/platform/web_fullscreen_video_status.h" #include "third_party/blink/renderer/bindings/core/v8/v8_fullscreen_options.h" @@ -57,9 +58,10 @@ #include "third_party/blink/renderer/core/layout/layout_video.h" #include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/loader/document_loader.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/gpu/shared_gpu_context.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" +#include "third_party/blink/renderer/platform/graphics/video_frame_image_util.h" #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/web_test_support.h" @@ -177,12 +179,19 @@ void HTMLVideoElement::CollectStyleForPresentationAttribute( const QualifiedName& name, const AtomicString& value, MutableCSSPropertyValueSet* style) { - if (name == html_names::kWidthAttr) + if (name == html_names::kWidthAttr) { AddHTMLLengthToStyle(style, CSSPropertyID::kWidth, value); - else if (name == html_names::kHeightAttr) + const AtomicString& height = FastGetAttribute(html_names::kHeightAttr); + if (height) + ApplyAspectRatioToStyle(value, height, style); + } else if (name == html_names::kHeightAttr) { AddHTMLLengthToStyle(style, CSSPropertyID::kHeight, value); - else + const AtomicString& width = FastGetAttribute(html_names::kWidthAttr); + if (width) + ApplyAspectRatioToStyle(width, value, style); + } else { HTMLMediaElement::CollectStyleForPresentationAttribute(name, value, style); + } } bool HTMLVideoElement::IsPresentationAttribute( @@ -259,8 +268,8 @@ void HTMLVideoElement::UpdatePictureInPictureAvailability() { if (!web_media_player_) return; - web_media_player_->OnPictureInPictureAvailabilityChanged( - SupportsPictureInPicture()); + for (auto& observer : GetMediaPlayerObserverRemoteSet()) + observer->OnPictureInPictureAvailabilityChanged(SupportsPictureInPicture()); } // TODO(zqzhang): this callback could be used to hide native controls instead of @@ -358,12 +367,20 @@ void HTMLVideoElement::OnLoadFinished() { UpdatePictureInPictureAvailability(); } -void HTMLVideoElement::PaintCurrentFrame( - cc::PaintCanvas* canvas, - const IntRect& dest_rect, - const PaintFlags* flags, - int already_uploaded_id, - WebMediaPlayer::VideoFrameUploadMetadata* out_metadata) const { +void HTMLVideoElement::RequestEnterPictureInPicture() { + PictureInPictureController::From(GetDocument()) + .EnterPictureInPicture(this, nullptr /* promise */, + nullptr /* options */); +} + +void HTMLVideoElement::RequestExitPictureInPicture() { + PictureInPictureController::From(GetDocument()) + .ExitPictureInPicture(this, nullptr); +} + +void HTMLVideoElement::PaintCurrentFrame(cc::PaintCanvas* canvas, + const IntRect& dest_rect, + const PaintFlags* flags) const { if (!GetWebMediaPlayer()) return; @@ -376,81 +393,7 @@ void HTMLVideoElement::PaintCurrentFrame( media_flags.setBlendMode(SkBlendMode::kSrc); } - GetWebMediaPlayer()->Paint(canvas, dest_rect, media_flags, - already_uploaded_id, out_metadata); -} - -bool HTMLVideoElement::CopyVideoTextureToPlatformTexture( - 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()->CopyVideoTextureToPlatformTexture( - gl, target, texture, internal_format, format, type, level, - 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, - gpu::gles2::GLES2Interface* gl, - GLuint texture, - GLint level, - GLint internalformat, - GLenum format, - GLenum type, - GLint xoffset, - GLint yoffset, - GLint zoffset, - bool flip_y, - bool premultiply_alpha) { - if (!GetWebMediaPlayer()) - return false; - return GetWebMediaPlayer()->TexImageImpl( - function_id, target, gl, texture, level, internalformat, format, type, - xoffset, yoffset, zoffset, flip_y, premultiply_alpha); -} - -bool HTMLVideoElement::PrepareVideoFrameForWebGL( - gpu::gles2::GLES2Interface* gl, - GLenum target, - GLuint texture, - int already_uploaded_id, - WebMediaPlayer::VideoFrameUploadMetadata* out_metadata) { - if (!GetWebMediaPlayer()) - return false; - return GetWebMediaPlayer()->PrepareVideoFrameForWebGL( - gl, target, texture, already_uploaded_id, out_metadata); + GetWebMediaPlayer()->Paint(canvas, dest_rect, media_flags); } bool HTMLVideoElement::HasAvailableVideoFrame() const { @@ -565,28 +508,53 @@ KURL HTMLVideoElement::PosterImageURL() const { return GetDocument().CompleteURL(url); } -scoped_refptr<Image> HTMLVideoElement::GetSourceImageForCanvas( - SourceImageStatus* status, - const FloatSize&) { - if (!HasAvailableVideoFrame()) { - *status = kInvalidSourceImageStatus; - return nullptr; +bool HTMLVideoElement::IsDefaultPosterImageURL() const { + return ImageSourceURL() == default_poster_url_; +} + +scoped_refptr<StaticBitmapImage> HTMLVideoElement::CreateStaticBitmapImage( + bool allow_accelerated_images) { + media::PaintCanvasVideoRenderer* video_renderer = nullptr; + scoped_refptr<media::VideoFrame> media_video_frame; + if (auto* wmp = GetWebMediaPlayer()) { + media_video_frame = wmp->GetCurrentFrame(); + video_renderer = wmp->GetPaintCanvasVideoRenderer(); } - IntSize intrinsic_size(videoWidth(), videoHeight()); - // TODO(fserb): this should not be default software. - std::unique_ptr<CanvasResourceProvider> resource_provider = - CanvasResourceProvider::CreateBitmapProvider( - intrinsic_size, kLow_SkFilterQuality, CanvasColorParams(), - CanvasResourceProvider::ShouldInitialize::kNo); - if (!resource_provider) { - *status = kInvalidSourceImageStatus; + if (!media_video_frame || !video_renderer) return nullptr; + + const auto intrinsic_size = IntSize(media_video_frame->natural_size()); + if (!resource_provider_ || + allow_accelerated_images != resource_provider_->IsAccelerated() || + intrinsic_size != resource_provider_->Size()) { + viz::RasterContextProvider* raster_context_provider = nullptr; + if (allow_accelerated_images) { + if (auto wrapper = SharedGpuContext::ContextProviderWrapper()) { + if (auto* context_provider = wrapper->ContextProvider()) + raster_context_provider = context_provider->RasterContextProvider(); + } + } + // Providing a null |raster_context_provider| creates a software provider. + resource_provider_ = CreateResourceProviderForVideoFrame( + intrinsic_size, raster_context_provider); + if (!resource_provider_) + return nullptr; } - PaintCurrentFrame(resource_provider->Canvas(), - IntRect(IntPoint(0, 0), intrinsic_size), nullptr); - scoped_refptr<Image> snapshot = resource_provider->Snapshot(); + const auto dest_rect = gfx::Rect(media_video_frame->natural_size()); + auto image = CreateImageFromVideoFrame(std::move(media_video_frame), + /*allow_zero_copy_images=*/true, + resource_provider_.get(), + video_renderer, dest_rect); + image->SetOriginClean(!WouldTaintOrigin()); + return image; +} + +scoped_refptr<Image> HTMLVideoElement::GetSourceImageForCanvas( + SourceImageStatus* status, + const FloatSize&) { + scoped_refptr<Image> snapshot = CreateStaticBitmapImage(); if (!snapshot) { *status = kInvalidSourceImageStatus; return nullptr; @@ -672,17 +640,6 @@ bool HTMLVideoElement::IsInAutoPIP() const { return is_auto_picture_in_picture_; } -void HTMLVideoElement::RequestEnterPictureInPicture() { - PictureInPictureController::From(GetDocument()) - .EnterPictureInPicture(this, nullptr /* promise */, - nullptr /* options */); -} - -void HTMLVideoElement::RequestExitPictureInPicture() { - PictureInPictureController::From(GetDocument()) - .ExitPictureInPicture(this, nullptr); -} - void HTMLVideoElement::OnPictureInPictureStateChange() { if (GetDisplayType() != DisplayType::kPictureInPicture || IsInAutoPIP()) { return; @@ -726,6 +683,9 @@ void HTMLVideoElement::SetIsEffectivelyFullscreen( is_effectively_fullscreen_ = status != blink::WebFullscreenVideoStatus::kNotEffectivelyFullscreen; if (GetWebMediaPlayer()) { + for (auto& observer : GetMediaPlayerObserverRemoteSet()) + observer->OnMediaEffectivelyFullscreenChanged(status); + GetWebMediaPlayer()->SetIsEffectivelyFullscreen(status); GetWebMediaPlayer()->OnDisplayTypeChanged(GetDisplayType()); } @@ -780,6 +740,13 @@ void HTMLVideoElement::OnWebMediaPlayerCreated() { } } +void HTMLVideoElement::OnWebMediaPlayerCleared() { + if (RuntimeEnabledFeatures::RequestVideoFrameCallbackEnabled()) { + if (auto* vfc_requester = VideoFrameCallbackRequester::From(*this)) + vfc_requester->OnWebMediaPlayerCleared(); + } +} + void HTMLVideoElement::AttributeChanged( const AttributeModificationParams& params) { HTMLElement::AttributeChanged(params); 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 0c87312aff6..a7af2fc68c0 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 @@ -33,20 +33,16 @@ #include "third_party/blink/renderer/core/html/media/html_media_element.h" #include "third_party/blink/renderer/core/imagebitmap/image_bitmap_source.h" #include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h" +#include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h" #include "third_party/khronos/GLES2/gl2.h" -namespace gpu { -namespace gles2 { -class GLES2Interface; -} -} // namespace gpu - namespace blink { class ImageBitmapOptions; class IntersectionObserverEntry; class MediaCustomControlsFullscreenDetector; class MediaRemotingInterstitial; class PictureInPictureInterstitial; +class StaticBitmapImage; class VideoWakeLock; class CORE_EXPORT HTMLVideoElement final @@ -93,68 +89,26 @@ class CORE_EXPORT HTMLVideoElement final // Used by canvas to gain raw pixel access // // PaintFlags is optional. If unspecified, its blend mode defaults to kSrc. - void PaintCurrentFrame( - cc::PaintCanvas*, - const IntRect&, - const cc::PaintFlags*, - int already_uploaded_id = kNoAlreadyUploadedFrame, - WebMediaPlayer::VideoFrameUploadMetadata* out_metadata = nullptr) const; - - // Used by WebGL to do GPU-GPU texture copy if possible. - bool CopyVideoTextureToPlatformTexture( - 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 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, - GLenum target, - gpu::gles2::GLES2Interface*, - GLuint texture, - GLint level, - GLint internalformat, - GLenum format, - GLenum type, - GLint xoffset, - GLint yoffset, - GLint zoffset, - bool flip_y, - bool premultiply_alpha); - - // Used by WebGL to do GPU_GPU texture sharing if possible. - bool PrepareVideoFrameForWebGL( - gpu::gles2::GLES2Interface*, - GLenum target, - GLuint texture, - int already_uploaded_id, - WebMediaPlayer::VideoFrameUploadMetadata* out_metadata); + void PaintCurrentFrame(cc::PaintCanvas*, + const IntRect&, + const cc::PaintFlags*) const; bool HasAvailableVideoFrame() const; KURL PosterImageURL() const override; + // Returns whether the current poster image URL is the default for the + // document. + // TODO(1190335): Remove this once default poster image URL is removed. + bool IsDefaultPosterImageURL() const; + + // Helper for GetSourceImageForCanvas() and other external callers who want a + // StaticBitmapImage of the current VideoFrame. If |allow_accelerated_images| + // is set to false a software backed CanvasResourceProvider will be used to + // produce the StaticBitmapImage. + scoped_refptr<StaticBitmapImage> CreateStaticBitmapImage( + bool allow_accelerated_images = true); + // CanvasImageSource implementation scoped_refptr<Image> GetSourceImageForCanvas(SourceImageStatus*, const FloatSize&) override; @@ -188,8 +142,6 @@ class CORE_EXPORT HTMLVideoElement final void MediaRemotingStopped(int error_code) final; DisplayType GetDisplayType() const final; bool IsInAutoPIP() const final; - void RequestEnterPictureInPicture() final; - void RequestExitPictureInPicture() final; void OnPictureInPictureStateChange() final; // Used by the PictureInPictureController as callback when the video element @@ -208,6 +160,7 @@ class CORE_EXPORT HTMLVideoElement final RegisteredEventListener&) override; void OnWebMediaPlayerCreated() final; + void OnWebMediaPlayerCleared() final; void AttributeChanged(const AttributeModificationParams& params) override; @@ -236,6 +189,12 @@ class CORE_EXPORT HTMLVideoElement final void OnPlay() final; void OnLoadStarted() final; void OnLoadFinished() final; + + // Video-specific overrides for part of the media::mojom::MediaPlayer + // interface, fully implemented in the parent class HTMLMediaElement. + void RequestEnterPictureInPicture() final; + void RequestExitPictureInPicture() final; + void DidMoveToNewDocument(Document& old_document) override; void UpdatePictureInPictureAvailability(); @@ -276,6 +235,10 @@ class CORE_EXPORT HTMLVideoElement final // True, if the video element occupies most of the viewport. bool mostly_filling_viewport_ : 1; + + // Used to fulfill blink::Image requests (CreateImage(), + // GetSourceImageForCanvas(), etc). Created on demand. + std::unique_ptr<CanvasResourceProvider> resource_provider_; }; } // namespace blink 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 54643ff90e1..1e345abb5e4 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 @@ -10,6 +10,7 @@ #include "third_party/blink/public/common/media/display_type.h" #include "third_party/blink/public/platform/web_fullscreen_video_status.h" #include "third_party/blink/renderer/core/dom/shadow_root.h" +#include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/core/html/media/html_media_test_helper.h" #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/layout/layout_box_model_object.h" @@ -202,4 +203,31 @@ TEST_F(HTMLVideoElementTest, AutoPIPExitPIPTest) { test::RunPendingTasks(); } +// TODO(1190335): Remove this once we no longer support "default poster image" +// Blink embedders (such as Webview) can set the default poster image for a +// video using `blink::Settings`. In some cases we still need to distinguish +// between a "real" poster image and the default poster image. +TEST_F(HTMLVideoElementTest, DefaultPosterImage) { + String const kDefaultPosterImage = "http://www.example.com/foo.jpg"; + + // Override the default poster image + GetDocument().GetSettings()->SetDefaultVideoPosterURL(kDefaultPosterImage); + + // Need to create a new video element, since + // `HTMLVideoElement::default_poster_url_` is set upon construction. + auto* video = MakeGarbageCollected<HTMLVideoElement>(GetDocument()); + GetDocument().body()->appendChild(video); + + // Assert that video element (without an explicitly set poster image url) has + // the same poster image URL as what we just set. + EXPECT_TRUE(video->IsDefaultPosterImageURL()); + EXPECT_EQ(kDefaultPosterImage, video->PosterImageURL()); + + // Set the poster image of the video to something + video->setAttribute(html_names::kPosterAttr, + "http://www.example.com/bar.jpg"); + EXPECT_FALSE(video->IsDefaultPosterImageURL()); + EXPECT_NE(kDefaultPosterImage, video->PosterImageURL()); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/media/media_remoting_interstitial.cc b/chromium/third_party/blink/renderer/core/html/media/media_remoting_interstitial.cc index 8fa88c6d7e9..920ea2e042d 100644 --- a/chromium/third_party/blink/renderer/core/html/media/media_remoting_interstitial.cc +++ b/chromium/third_party/blink/renderer/core/html/media/media_remoting_interstitial.cc @@ -155,6 +155,7 @@ void MediaRemotingInterstitial::OnPosterImageChanged() { } void MediaRemotingInterstitial::Trace(Visitor* visitor) const { + visitor->Trace(toggle_interstitial_timer_); visitor->Trace(video_element_); visitor->Trace(background_image_); visitor->Trace(cast_icon_); diff --git a/chromium/third_party/blink/renderer/core/html/media/media_remoting_interstitial.h b/chromium/third_party/blink/renderer/core/html/media/media_remoting_interstitial.h index 8ccf4baa726..466719bd4ea 100644 --- a/chromium/third_party/blink/renderer/core/html/media/media_remoting_interstitial.h +++ b/chromium/third_party/blink/renderer/core/html/media/media_remoting_interstitial.h @@ -65,7 +65,7 @@ class MediaRemotingInterstitial final : public HTMLDivElement { }; State state_ = HIDDEN; - TaskRunnerTimer<MediaRemotingInterstitial> toggle_interstitial_timer_; + HeapTaskRunnerTimer<MediaRemotingInterstitial> toggle_interstitial_timer_; Member<HTMLVideoElement> video_element_; Member<HTMLImageElement> background_image_; Member<HTMLDivElement> cast_icon_; 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 5627a70f441..da2d1feb143 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 @@ -175,6 +175,7 @@ void PictureInPictureInterstitial::OnPosterImageChanged() { void PictureInPictureInterstitial::Trace(Visitor* visitor) const { visitor->Trace(resize_observer_); + visitor->Trace(interstitial_timer_); visitor->Trace(video_element_); visitor->Trace(background_image_); visitor->Trace(message_element_); 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 85aae77812d..397804aaf04 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 @@ -61,7 +61,7 @@ class PictureInPictureInterstitial final : public HTMLDivElement { // necessary. Member<ResizeObserver> resize_observer_; - TaskRunnerTimer<PictureInPictureInterstitial> interstitial_timer_; + HeapTaskRunnerTimer<PictureInPictureInterstitial> interstitial_timer_; Member<HTMLVideoElement> video_element_; Member<HTMLImageElement> background_image_; Member<HTMLDivElement> message_element_; diff --git a/chromium/third_party/blink/renderer/core/html/media/video_auto_fullscreen_test.cc b/chromium/third_party/blink/renderer/core/html/media/video_auto_fullscreen_test.cc index 51b1214a909..93fb7c565c9 100644 --- a/chromium/third_party/blink/renderer/core/html/media/video_auto_fullscreen_test.cc +++ b/chromium/third_party/blink/renderer/core/html/media/video_auto_fullscreen_test.cc @@ -53,12 +53,14 @@ class VideoAutoFullscreenFrameHost : public FakeLocalFrameHost { class VideoAutoFullscreenFrameClient : public frame_test_helpers::TestWebFrameClient { public: - WebMediaPlayer* CreateMediaPlayer(const WebMediaPlayerSource&, - WebMediaPlayerClient*, - blink::MediaInspectorContext*, - WebMediaPlayerEncryptedMediaClient*, - WebContentDecryptionModule*, - const WebString& sink_id) final { + WebMediaPlayer* CreateMediaPlayer( + const WebMediaPlayerSource&, + WebMediaPlayerClient*, + blink::MediaInspectorContext*, + WebMediaPlayerEncryptedMediaClient*, + WebContentDecryptionModule*, + const WebString& sink_id, + const cc::LayerTreeSettings& settings) final { return new EmptyWebMediaPlayer(); } }; diff --git a/chromium/third_party/blink/renderer/core/html/media/video_frame_callback_requester.h b/chromium/third_party/blink/renderer/core/html/media/video_frame_callback_requester.h index e47484cfefa..0a411483aff 100644 --- a/chromium/third_party/blink/renderer/core/html/media/video_frame_callback_requester.h +++ b/chromium/third_party/blink/renderer/core/html/media/video_frame_callback_requester.h @@ -28,6 +28,7 @@ class CORE_EXPORT VideoFrameCallbackRequester void Trace(Visitor*) const override; virtual void OnWebMediaPlayerCreated() = 0; + virtual void OnWebMediaPlayerCleared() = 0; virtual void OnRequestVideoFrameCallback() = 0; protected: diff --git a/chromium/third_party/blink/renderer/core/html/media/video_wake_lock_test.cc b/chromium/third_party/blink/renderer/core/html/media/video_wake_lock_test.cc index 62f79d46479..623c2851bdd 100644 --- a/chromium/third_party/blink/renderer/core/html/media/video_wake_lock_test.cc +++ b/chromium/third_party/blink/renderer/core/html/media/video_wake_lock_test.cc @@ -5,6 +5,8 @@ #include "third_party/blink/renderer/core/html/media/video_wake_lock.h" #include "cc/layers/layer.h" +#include "media/mojo/mojom/media_player.mojom-blink.h" +#include "mojo/public/cpp/bindings/pending_associated_remote.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" #include "mojo/public/cpp/bindings/receiver.h" @@ -63,6 +65,7 @@ class VideoWakeLockPictureInPictureService void StartSession( uint32_t, + mojo::PendingAssociatedRemote<media::mojom::blink::MediaPlayer>, const base::Optional<viz::SurfaceId>&, const gfx::Size&, bool, diff --git a/chromium/third_party/blink/renderer/core/html/parser/DIR_METADATA b/chromium/third_party/blink/renderer/core/html/parser/DIR_METADATA new file mode 100644 index 00000000000..18fa0a67843 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/parser/DIR_METADATA @@ -0,0 +1,5 @@ +monorail { + component: "Blink>HTML>Parser" +} + +team_email: "loading-dev@chromium.org" diff --git a/chromium/third_party/blink/renderer/core/html/parser/OWNERS b/chromium/third_party/blink/renderer/core/html/parser/OWNERS index 2812e39384d..c0b826f5f62 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/OWNERS +++ b/chromium/third_party/blink/renderer/core/html/parser/OWNERS @@ -2,6 +2,3 @@ csharrison@chromium.org kouhei@chromium.org masonfreed@chromium.org yoavweiss@chromium.org - -# TEAM: loading-dev@chromium.org -# COMPONENT: Blink>HTML>Parser diff --git a/chromium/third_party/blink/renderer/core/html/parser/background_html_parser.cc b/chromium/third_party/blink/renderer/core/html/parser/background_html_parser.cc index 6bc906f027b..0e429069e9c 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/background_html_parser.cc +++ b/chromium/third_party/blink/renderer/core/html/parser/background_html_parser.cc @@ -186,7 +186,7 @@ void BackgroundHTMLParser::MarkEndOfFile() { } void BackgroundHTMLParser::PumpTokenizer() { - TRACE_EVENT0("loading", "BackgroundHTMLParser::pumpTokenizer"); + TRACE_EVENT0("loading", "BackgroundHTMLParser::PumpTokenizer"); HTMLTreeBuilderSimulator::SimulatedToken simulated_token = HTMLTreeBuilderSimulator::kOtherToken; @@ -245,9 +245,6 @@ void BackgroundHTMLParser::EnqueueTokenizedChunk() { return; auto chunk = std::make_unique<HTMLDocumentParser::TokenizedChunk>(); - TRACE_EVENT_WITH_FLOW0("blink,loading", - "BackgroundHTMLParser::sendTokensToMainThread", - chunk.get(), TRACE_EVENT_FLAG_FLOW_OUT); chunk->preloads.swap(pending_preloads_); if (viewport_description_.has_value()) 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 a521cfe2a91..99f25715af3 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 @@ -47,13 +47,16 @@ void CSSPreloadScanner::Reset() { } template <typename Char> -void CSSPreloadScanner::ScanCommon(const Char* begin, - const Char* end, - const SegmentedString& source, - PreloadRequestStream& requests, - const KURL& predicted_base_element_url) { +void CSSPreloadScanner::ScanCommon( + const Char* begin, + const Char* end, + const SegmentedString& source, + PreloadRequestStream& requests, + const KURL& predicted_base_element_url, + const PreloadRequest::ExclusionInfo* exclusion_info) { requests_ = &requests; predicted_base_element_url_ = &predicted_base_element_url; + exclusion_info_ = exclusion_info; for (const Char* it = begin; it != end && state_ != kDoneParsingImportRules; ++it) @@ -64,29 +67,34 @@ void CSSPreloadScanner::ScanCommon(const Char* begin, requests_ = nullptr; predicted_base_element_url_ = nullptr; + exclusion_info_ = nullptr; } -void CSSPreloadScanner::Scan(const HTMLToken::DataVector& data, - const SegmentedString& source, - PreloadRequestStream& requests, - const KURL& predicted_base_element_url) { +void CSSPreloadScanner::Scan( + const HTMLToken::DataVector& data, + const SegmentedString& source, + PreloadRequestStream& requests, + const KURL& predicted_base_element_url, + const PreloadRequest::ExclusionInfo* exclusion_info) { ScanCommon(data.data(), data.data() + data.size(), source, requests, - predicted_base_element_url); + predicted_base_element_url, exclusion_info); } -void CSSPreloadScanner::Scan(const String& tag_name, - const SegmentedString& source, - PreloadRequestStream& requests, - const KURL& predicted_base_element_url) { +void CSSPreloadScanner::Scan( + const String& tag_name, + const SegmentedString& source, + PreloadRequestStream& requests, + const KURL& predicted_base_element_url, + const PreloadRequest::ExclusionInfo* exclusion_info) { if (tag_name.Is8Bit()) { const LChar* begin = tag_name.Characters8(); ScanCommon(begin, begin + tag_name.length(), source, requests, - predicted_base_element_url); + predicted_base_element_url, exclusion_info); return; } const UChar* begin = tag_name.Characters16(); ScanCommon(begin, begin + tag_name.length(), source, requests, - predicted_base_element_url); + predicted_base_element_url, exclusion_info); } void CSSPreloadScanner::SetReferrerPolicy( @@ -252,7 +260,7 @@ void CSSPreloadScanner::EmitRule(const SegmentedString& source) { fetch_initiator_type_names::kCSS, position, url, *predicted_base_element_url_, ResourceType::kCSSStyleSheet, referrer_policy_, PreloadRequest::kBaseUrlIsReferrer, - ResourceFetcher::kImageNotImageSet); + ResourceFetcher::kImageNotImageSet, exclusion_info_); if (request) { // FIXME: Should this be including the charset in the preload request? requests_->push_back(std::move(request)); 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 c937d06520d..fc8019935da 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 @@ -48,11 +48,13 @@ class CSSPreloadScanner { void Scan(const HTMLToken::DataVector&, const SegmentedString&, PreloadRequestStream&, - const KURL&); + const KURL&, + const PreloadRequest::ExclusionInfo*); void Scan(const String&, const SegmentedString&, PreloadRequestStream&, - const KURL&); + const KURL&, + const PreloadRequest::ExclusionInfo*); void SetReferrerPolicy(network::mojom::ReferrerPolicy); @@ -75,7 +77,8 @@ class CSSPreloadScanner { const Char* end, const SegmentedString&, PreloadRequestStream&, - const KURL&); + const KURL&, + const PreloadRequest::ExclusionInfo*); inline void Tokenize(UChar, const SegmentedString&); void EmitRule(const SegmentedString&); @@ -92,6 +95,7 @@ class CSSPreloadScanner { // Below members only non-null during scan() PreloadRequestStream* requests_ = nullptr; const KURL* predicted_base_element_url_ = nullptr; + const PreloadRequest::ExclusionInfo* exclusion_info_; DISALLOW_COPY_AND_ASSIGN(CSSPreloadScanner); }; diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_construction_site.cc b/chromium/third_party/blink/renderer/core/html/parser/html_construction_site.cc index 870c7f51762..5c1866b4730 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_construction_site.cc +++ b/chromium/third_party/blink/renderer/core/html/parser/html_construction_site.cc @@ -803,8 +803,6 @@ void HTMLConstructionSite::InsertTextNode(const StringView& string, if (ShouldFosterParent()) FindFosterSite(dummy_task); - // TODO(crbug.com/1070669): This can likely be removed, because it is already - // handled in Insert(). if (auto* template_element = DynamicTo<HTMLTemplateElement>(*dummy_task.parent)) { // If the Document was detached in the middle of parsing, the template diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_document_parser.cc b/chromium/third_party/blink/renderer/core/html/parser/html_document_parser.cc index 3a26bd51713..bcb138e4437 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_document_parser.cc +++ b/chromium/third_party/blink/renderer/core/html/parser/html_document_parser.cc @@ -89,6 +89,7 @@ constexpr int kDefaultMaxTokenizationBudget = 250; class EndIfDelayedForbiddenScope; class ShouldCompleteScope; +class AttemptToEndForbiddenScope; // This class encapsulates the internal state needed for synchronous foreground // HTML parsing (e.g. if HTMLDocumentParser::PumpTokenizer yields, this class @@ -97,6 +98,7 @@ class HTMLDocumentParserState : public GarbageCollected<HTMLDocumentParserState> { friend EndIfDelayedForbiddenScope; friend ShouldCompleteScope; + friend AttemptToEndForbiddenScope; public: // Keeps track of whether the parser needs to complete tokenization work, @@ -131,7 +133,10 @@ class HTMLDocumentParserState meta_csp_state_(MetaCSPTokenState::kNotSeen), mode_(mode), end_if_delayed_forbidden_(0), - should_complete_(0) {} + should_complete_(0), + should_attempt_to_end_on_eof_(0), + needs_link_header_dispatch_(true), + have_seen_first_byte_(false) {} void Trace(Visitor* v) const {} @@ -153,6 +158,27 @@ class HTMLDocumentParserState } } + bool NeedsLinkHeaderPreloadsDispatch() const { + return needs_link_header_dispatch_; + } + void DispatchedLinkHeaderPreloads() { needs_link_header_dispatch_ = false; } + + bool HaveSeenFirstByte() const { return have_seen_first_byte_; } + void SetHaveSeenFirstByte() { have_seen_first_byte_ = true; } + + // Keeps track of whether Document::Finish has been called whilst parsing + // asynchronously. ShouldAttemptToEndOnEOF() means that the parser should + // close when there's no more input. + bool ShouldAttemptToEndOnEOF() const { + return should_attempt_to_end_on_eof_ > 0; + } + void SetAttemptToEndOnEOF() { + // This method should only be called from ::Finish. + should_attempt_to_end_on_eof_++; + // Should only ever call ::Finish once. + DCHECK(should_attempt_to_end_on_eof_ < 2); + } + bool ShouldEndIfDelayed() const { return end_if_delayed_forbidden_ == 0; } bool ShouldComplete() const { return should_complete_ || GetMode() != kAllowDeferredParsing; @@ -185,6 +211,11 @@ class HTMLDocumentParserState DCHECK_GE(end_if_delayed_forbidden_, 0); } + void EnterAttemptToEndForbidden() { + DCHECK(should_attempt_to_end_on_eof_ > 0); + should_attempt_to_end_on_eof_ = 0; + } + void EnterShouldComplete() { should_complete_++; } void ExitShouldComplete() { should_complete_--; @@ -196,6 +227,11 @@ class HTMLDocumentParserState ParserSynchronizationPolicy mode_; int end_if_delayed_forbidden_; int should_complete_; + // Set to non-zero if Document::Finish has been called and we're operating + // asynchronously. + int should_attempt_to_end_on_eof_; + bool needs_link_header_dispatch_; + bool have_seen_first_byte_; }; class EndIfDelayedForbiddenScope { @@ -212,6 +248,19 @@ class EndIfDelayedForbiddenScope { HTMLDocumentParserState* state_; }; +class AttemptToEndForbiddenScope { + STACK_ALLOCATED(); + + public: + explicit AttemptToEndForbiddenScope(HTMLDocumentParserState* state) + : state_(state) { + state_->EnterAttemptToEndForbidden(); + } + + private: + HTMLDocumentParserState* state_; +}; + class ShouldCompleteScope { STACK_ALLOCATED(); @@ -283,36 +332,42 @@ class ScopedYieldTimer { }; HTMLDocumentParser::HTMLDocumentParser(HTMLDocument& document, - ParserSynchronizationPolicy sync_policy) - : HTMLDocumentParser(document, kAllowScriptingContent, sync_policy) { + ParserSynchronizationPolicy sync_policy, + ParserPrefetchPolicy prefetch_policy) + : HTMLDocumentParser(document, + kAllowScriptingContent, + sync_policy, + prefetch_policy) { script_runner_ = HTMLParserScriptRunner::Create(ReentryPermit(), &document, this); // Allow declarative shadow DOM for the document parser, if not explicitly // disabled. - bool allow_shadow_root = document.GetDeclarativeShadowRootAllowState() != - Document::DeclarativeShadowRootAllowState::kDeny; + bool include_shadow_roots = document.GetDeclarativeShadowRootAllowState() != + Document::DeclarativeShadowRootAllowState::kDeny; tree_builder_ = MakeGarbageCollected<HTMLTreeBuilder>( - this, document, kAllowScriptingContent, options_, allow_shadow_root); + this, document, kAllowScriptingContent, options_, include_shadow_roots); } HTMLDocumentParser::HTMLDocumentParser( DocumentFragment* fragment, Element* context_element, - ParserContentPolicy parser_content_policy) + ParserContentPolicy parser_content_policy, + ParserPrefetchPolicy parser_prefetch_policy) : HTMLDocumentParser(fragment->GetDocument(), parser_content_policy, - kForceSynchronousParsing) { + kForceSynchronousParsing, + parser_prefetch_policy) { // Allow declarative shadow DOM for the fragment parser only if explicitly // enabled. - bool allow_shadow_root = + bool include_shadow_roots = fragment->GetDocument().GetDeclarativeShadowRootAllowState() == Document::DeclarativeShadowRootAllowState::kAllow; // No script_runner_ in fragment parser. tree_builder_ = MakeGarbageCollected<HTMLTreeBuilder>( this, fragment, context_element, parser_content_policy, options_, - allow_shadow_root); + include_shadow_roots); // For now document fragment parsing never reports errors. bool report_errors = false; @@ -331,7 +386,8 @@ int GetMaxTokenizationBudget() { HTMLDocumentParser::HTMLDocumentParser(Document& document, ParserContentPolicy content_policy, - ParserSynchronizationPolicy sync_policy) + ParserSynchronizationPolicy sync_policy, + ParserPrefetchPolicy prefetch_policy) : ScriptableDocumentParser(document, content_policy), options_(&document), reentry_permit_(HTMLParserReentryPermit::Create()), @@ -400,7 +456,8 @@ HTMLDocumentParser::HTMLDocumentParser(Document& document, !document.IsPrefetchOnly()) return; - preloader_ = MakeGarbageCollected<HTMLResourcePreloader>(document); + if (prefetch_policy == kAllowPrefetching) + preloader_ = MakeGarbageCollected<HTMLResourcePreloader>(document); } HTMLDocumentParser::~HTMLDocumentParser() = default; @@ -552,6 +609,10 @@ void HTMLDocumentParser::PumpTokenizerIfPossible() { if (yielded) { DCHECK(!task_runner_state_->ShouldComplete()); SchedulePumpTokenizer(); + } else if (task_runner_state_->ShouldAttemptToEndOnEOF()) { + // Fall into this branch if ::Finish has been previously called and we've + // just finished asynchronously parsing everything. + AttemptToEnd(); } else if (task_runner_state_->ShouldEndIfDelayed()) { // If we did not exceed the budget or parsed everything there was to // parse, check if we should complete the document. @@ -596,17 +657,20 @@ void HTMLDocumentParser::RunScriptsForPausedTreeBuilder() { CheckIfBlockingStylesheetAdded(); } -bool HTMLDocumentParser::CanTakeNextToken() { +HTMLDocumentParser::NextTokenStatus HTMLDocumentParser::CanTakeNextToken() { if (IsStopped()) - return false; + return NoTokens; // If we're paused waiting for a script, we try to execute scripts before // continuing. - if (tree_builder_->HasParserBlockingScript()) + auto ret = HaveTokens; + if (tree_builder_->HasParserBlockingScript()) { RunScriptsForPausedTreeBuilder(); + ret = HaveTokensAfterScript; + } if (IsStopped() || IsPaused()) - return false; - return true; + return NoTokens; + return ret; } void HTMLDocumentParser::EnqueueTokenizedChunk( @@ -775,9 +839,8 @@ void HTMLDocumentParser::DiscardSpeculationsAndResumeFrom( DCHECK(checkpoint->unparsed_input.IsSafeToSendToAnotherThread()); loading_task_runner_->PostTask( - FROM_HERE, - WTF::Bind(&BackgroundHTMLParser::ResumeFrom, background_parser_, - WTF::Passed(std::move(checkpoint)))); + FROM_HERE, WTF::Bind(&BackgroundHTMLParser::ResumeFrom, + background_parser_, std::move(checkpoint))); } size_t HTMLDocumentParser::ProcessTokenizedChunkFromBackgroundParser( @@ -959,7 +1022,22 @@ bool HTMLDocumentParser::PumpTokenizer() { bool should_yield = false; int budget = max_tokenization_budget_; - while (CanTakeNextToken() && !should_yield) { + while (!should_yield) { + const auto next_token_status = CanTakeNextToken(); + if (next_token_status == NoTokens) { + // No tokens left to process in this pump, so break + break; + } else if (next_token_status == HaveTokensAfterScript && + task_runner_state_->HaveExitedHeader()) { + // Just executed a parser-blocking script in the body (which is usually + // very expensive), so expire the budget, yield, and permit paint if + // needed. + budget = 0; + if (!should_run_until_completion) { + should_yield = true; + break; + } + } { RUNTIME_CALL_TIMER_SCOPE( V8PerIsolateData::MainThreadIsolate(), @@ -1226,31 +1304,29 @@ void HTMLDocumentParser::Append(const String& input_source) { return; preload_scanner_->AppendToEnd(source); - ScanAndPreload(preload_scanner_.get()); + if (preloader_) { + // TODO(Richard.Townsend@arm.com): add test coverage of this branch. + // The crash in crbug.com/1166786 indicates that text documents are being + // speculatively prefetched. + ScanAndPreload(preload_scanner_.get()); + } // Return after the preload scanner, do not actually parse the document. return; } - if (preload_scanner_) { - if (input_.Current().IsEmpty() && !IsPaused()) { - // We have parsed until the end of the current input and so are now - // moving ahead of the preload scanner. Clear the scanner so we know to - // scan starting from the current input point if we block again. - preload_scanner_.reset(); - } else { - preload_scanner_->AppendToEnd(source); - if (preloader_) { - if (!task_runner_state_->IsSynchronous() || IsPaused()) { - // Should scan and preload if the parser's paused and operating - // synchronously, or if the parser's operating in an asynchronous - // mode. - ScanAndPreload(preload_scanner_.get()); - } - } + if (preload_scanner_ && preloader_) { + preload_scanner_->AppendToEnd(source); + if (task_runner_state_->GetMode() == kAllowDeferredParsing && + (IsPaused() || !task_runner_state_->HaveSeenFirstByte())) { + // Should scan and preload if the parser's paused waiting for a resource, + // or if we're starting a document for the first time (we want to at least + // prefetch anything that's in the <head> section). + ScanAndPreload(preload_scanner_.get()); } } input_.AppendToEnd(source); + task_runner_state_->SetHaveSeenFirstByte(); if (InPumpSession()) { // We've gotten data off the network in a nested write. We don't want to @@ -1306,7 +1382,11 @@ void HTMLDocumentParser::AttemptToEnd() { // an external script to load, we can't finish parsing quite yet. TRACE_EVENT1("blink", "HTMLDocumentParser::AttemptToEnd", "parser", (void*)this); - + DCHECK(task_runner_state_->ShouldAttemptToEndOnEOF()); + AttemptToEndForbiddenScope should_not_attempt_to_end(task_runner_state_); + // We should only be in this state once after calling Finish. + // If there are pending scripts, future control flow should pass to + // EndIfDelayed. if (ShouldDelayEnd()) { end_was_delayed_ = true; return; @@ -1367,10 +1447,11 @@ void HTMLDocumentParser::Finish() { if (!input_.HaveSeenEndOfFile()) input_.MarkEndOfFile(); + // If there's any deferred work remaining, signal that we + // want to end the document once all work's complete. + task_runner_state_->SetAttemptToEndOnEOF(); if (task_runner_state_->IsScheduled() && !GetDocument()->IsPrefetchOnly()) { - // If there's any deferred work remaining, synchronously pump the tokenizer - // one last time to make sure that everything's added to the document. - PumpTokenizerIfPossible(); + return; } AttemptToEnd(); @@ -1595,7 +1676,7 @@ void HTMLDocumentParser::AppendBytes(const char* data, size_t length) { loading_task_runner_->PostTask( FROM_HERE, WTF::Bind(&BackgroundHTMLParser::AppendRawBytesFromMainThread, - background_parser_, WTF::Passed(std::move(buffer)))); + background_parser_, std::move(buffer))); return; } @@ -1634,7 +1715,7 @@ void HTMLDocumentParser::SetDecoder( if (have_background_parser_) { loading_task_runner_->PostTask( FROM_HERE, WTF::Bind(&BackgroundHTMLParser::SetDecoder, - background_parser_, WTF::Passed(TakeDecoder()))); + background_parser_, TakeDecoder())); } } @@ -1672,8 +1753,38 @@ void HTMLDocumentParser::ScanAndPreload(HTMLPreloadScanner* scanner) { TRACE_EVENT0("blink", "HTMLDocumentParser::ScanAndPreload"); DCHECK(preloader_); bool seen_csp_meta_tag = false; - PreloadRequestStream requests = scanner->Scan( - GetDocument()->ValidBaseElementURL(), nullptr, seen_csp_meta_tag); + base::Optional<ViewportDescription> viewport_description; + PreloadRequestStream requests = + scanner->Scan(GetDocument()->ValidBaseElementURL(), &viewport_description, + seen_csp_meta_tag); + // Make sure that the viewport is up-to-date, so that the correct viewport + // dimensions will be fed to the background parser and preload scanner. + if (GetDocument()->Loader() && + task_runner_state_->GetMode() == kAllowDeferredParsing) { + if (viewport_description.has_value()) { + GetDocument()->GetStyleEngine().UpdateViewport(); + } + if (task_runner_state_->NeedsLinkHeaderPreloadsDispatch()) { + if (GetDocument()->Loader()->GetPrefetchedSignedExchangeManager()) { + TRACE_EVENT0("blink", + "HTMLDocumentParser::DispatchSignedExchangeManager"); + // Link header preloads for prefetched signed exchanges won't be started + // until StartPrefetchedLinkHeaderPreloads() is called. See the header + // comment of PrefetchedSignedExchangeManager. + GetDocument() + ->Loader() + ->GetPrefetchedSignedExchangeManager() + ->StartPrefetchedLinkHeaderPreloads(); + } else { + TRACE_EVENT0("blink", "HTMLDocumentParser::DispatchLinkHeaderPreloads"); + GetDocument()->Loader()->DispatchLinkHeaderPreloads( + base::OptionalOrNullptr(viewport_description), + PreloadHelper::kOnlyLoadMedia); + } + task_runner_state_->DispatchedLinkHeaderPreloads(); + } + } + task_runner_state_->SetSeenCSPMetaTag(seen_csp_meta_tag); for (auto& request : requests) { queued_preloads_.push_back(std::move(request)); diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_document_parser.h b/chromium/third_party/blink/renderer/core/html/parser/html_document_parser.h index cac43e4b796..97ebb884b7f 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_document_parser.h +++ b/chromium/third_party/blink/renderer/core/html/parser/html_document_parser.h @@ -67,6 +67,13 @@ class HTMLResourcePreloader; class HTMLTreeBuilder; class HTMLDocumentParserState; +enum ParserPrefetchPolicy { + // Indicates that prefetches/preloads should happen for this document type. + kAllowPrefetching, + // Indicates that prefetches are forbidden for this document type. + kDisallowPrefetching +}; + // TODO(https://crbug.com/1049898): These are only exposed to make it possible // to delete an expired histogram. The test should be rewritten to test at a // different level, so it won't have to make assertions about internal state. @@ -78,10 +85,13 @@ class CORE_EXPORT HTMLDocumentParser : public ScriptableDocumentParser, USING_PRE_FINALIZER(HTMLDocumentParser, Dispose); public: - HTMLDocumentParser(HTMLDocument&, ParserSynchronizationPolicy); + HTMLDocumentParser(HTMLDocument&, + ParserSynchronizationPolicy, + ParserPrefetchPolicy prefetch_policy = kAllowPrefetching); HTMLDocumentParser(DocumentFragment*, Element* context_element, - ParserContentPolicy); + ParserContentPolicy, + ParserPrefetchPolicy prefetch_policy = kAllowPrefetching); ~HTMLDocumentParser() override; void Trace(Visitor*) const override; @@ -156,7 +166,10 @@ class CORE_EXPORT HTMLDocumentParser : public ScriptableDocumentParser, private: HTMLDocumentParser(Document&, ParserContentPolicy, - ParserSynchronizationPolicy); + ParserSynchronizationPolicy, + ParserPrefetchPolicy); + + enum NextTokenStatus { NoTokens, HaveTokens, HaveTokensAfterScript }; // DocumentParser void Detach() final; @@ -194,7 +207,7 @@ class CORE_EXPORT HTMLDocumentParser : public ScriptableDocumentParser, bool*); void PumpPendingSpeculations(); - bool CanTakeNextToken(); + NextTokenStatus CanTakeNextToken(); bool PumpTokenizer(); void PumpTokenizerIfPossible(); void DeferredPumpTokenizerIfPossible(); @@ -228,7 +241,7 @@ class CORE_EXPORT HTMLDocumentParser : public ScriptableDocumentParser, std::unique_ptr<HTMLPreloadScanner> CreatePreloadScanner( TokenPreloadScanner::ScannerType); - // Let the given HTMLPreloadScanner scan the input it has, and then preloads + // Let the given HTMLPreloadScanner scan the input it has, and then preload // resources using the resulting PreloadRequests and |preloader_|. void ScanAndPreload(HTMLPreloadScanner*); void FetchQueuedPreloads(); diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_document_parser_test.cc b/chromium/third_party/blink/renderer/core/html/parser/html_document_parser_test.cc index e699b87eb66..6724f0702f4 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_document_parser_test.cc +++ b/chromium/third_party/blink/renderer/core/html/parser/html_document_parser_test.cc @@ -9,7 +9,7 @@ #include "third_party/blink/renderer/core/html/html_document.h" #include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h" #include "third_party/blink/renderer/core/html/parser/text_resource_decoder_builder.h" -#include "third_party/blink/renderer/core/loader/prerenderer_client.h" +#include "third_party/blink/renderer/core/loader/no_state_prefetch_client.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/testing/unit_test_helpers.h" @@ -18,10 +18,11 @@ namespace blink { namespace { -class MockPrerendererClient : public PrerendererClient { +class MockNoStatePrefetchClient : public NoStatePrefetchClient { public: - MockPrerendererClient(Page& page, bool is_prefetch_only) - : PrerendererClient(page, nullptr), is_prefetch_only_(is_prefetch_only) {} + MockNoStatePrefetchClient(Page& page, bool is_prefetch_only) + : NoStatePrefetchClient(page, nullptr), + is_prefetch_only_(is_prefetch_only) {} private: bool IsPrefetchOnly() override { return is_prefetch_only_; } @@ -117,9 +118,9 @@ TEST_P(HTMLDocumentParserTest, HasNoPendingWorkAfterDetach) { TEST_P(HTMLDocumentParserTest, AppendPrefetch) { auto& document = To<HTMLDocument>(GetDocument()); - ProvidePrerendererClientTo( - *document.GetPage(), - MakeGarbageCollected<MockPrerendererClient>(*document.GetPage(), true)); + ProvideNoStatePrefetchClientTo( + *document.GetPage(), MakeGarbageCollected<MockNoStatePrefetchClient>( + *document.GetPage(), true)); EXPECT_TRUE(document.IsPrefetchOnly()); HTMLDocumentParser* parser = CreateParser(document); @@ -151,7 +152,8 @@ TEST_P(HTMLDocumentParserTest, AppendNoPrefetch) { // The bytes are forwarded to the tokenizer. HTMLParserScriptRunnerHost* script_runner_host = parser->AsHTMLParserScriptRunnerHostForTesting(); - EXPECT_FALSE(script_runner_host->HasPreloadScanner()); + EXPECT_EQ(script_runner_host->HasPreloadScanner(), + testing::get<0>(GetParam()) == kAllowDeferredParsing); EXPECT_EQ(HTMLTokenizer::kTagNameState, parser->Tokenizer()->GetState()); // Cancel any pending work to make sure that RuntimeFeatures DCHECKs do not // fire. diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_parser_metrics_test.cc b/chromium/third_party/blink/renderer/core/html/parser/html_parser_metrics_test.cc index 7f797d2b3f9..5b9871da14c 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_parser_metrics_test.cc +++ b/chromium/third_party/blink/renderer/core/html/parser/html_parser_metrics_test.cc @@ -16,9 +16,7 @@ namespace blink { class HTMLParserMetricsTest : public testing::Test { public: - HTMLParserMetricsTest() { - helper_.Initialize(nullptr, nullptr, nullptr, nullptr); - } + HTMLParserMetricsTest() { helper_.Initialize(nullptr, nullptr, nullptr); } ~HTMLParserMetricsTest() override = default; 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 39dd6aaa788..b3427793dfd 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 @@ -47,6 +47,7 @@ #include "third_party/blink/renderer/core/html/html_image_element.h" #include "third_party/blink/renderer/core/html/html_meta_element.h" #include "third_party/blink/renderer/core/html/link_rel_attribute.h" +#include "third_party/blink/renderer/core/html/link_web_bundle.h" #include "third_party/blink/renderer/core/html/loading_attribute.h" #include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h" #include "third_party/blink/renderer/core/html/parser/html_srcset_parser.h" @@ -69,20 +70,22 @@ namespace blink { -static bool Match(const StringImpl* impl, const QualifiedName& q_name) { +namespace { + +bool Match(const StringImpl* impl, const QualifiedName& q_name) { return impl == q_name.LocalName().Impl(); } -static bool Match(const AtomicString& name, const QualifiedName& q_name) { +bool Match(const AtomicString& name, const QualifiedName& q_name) { DCHECK(IsMainThread()); return q_name.LocalName() == name; } -static bool Match(const String& name, const QualifiedName& q_name) { +bool Match(const String& name, const QualifiedName& q_name) { return ThreadSafeMatch(name, q_name); } -static const StringImpl* TagImplFor(const HTMLToken::DataVector& data) { +const StringImpl* TagImplFor(const HTMLToken::DataVector& data) { AtomicString tag_name(data); const StringImpl* result = tag_name.Impl(); if (result->IsStatic()) @@ -90,14 +93,14 @@ static const StringImpl* TagImplFor(const HTMLToken::DataVector& data) { return nullptr; } -static const StringImpl* TagImplFor(const String& tag_name) { +const StringImpl* TagImplFor(const String& tag_name) { const StringImpl* result = tag_name.Impl(); if (result->IsStatic()) return result; return nullptr; } -static String InitiatorFor(const StringImpl* tag_impl) { +String InitiatorFor(const StringImpl* tag_impl) { DCHECK(tag_impl); if (Match(tag_impl, html_names::kImgTag)) return html_names::kImgTag.LocalName(); @@ -113,8 +116,8 @@ static String InitiatorFor(const StringImpl* tag_impl) { return g_empty_string; } -static bool MediaAttributeMatches(const MediaValuesCached& media_values, - const String& attribute_value) { +bool MediaAttributeMatches(const MediaValuesCached& media_values, + const String& attribute_value) { // Since this is for preload scanning only, ExecutionContext-based origin // trials for media queries are not needed. scoped_refptr<MediaQuerySet> media_queries = @@ -123,6 +126,20 @@ static bool MediaAttributeMatches(const MediaValuesCached& media_values, return media_query_evaluator.Eval(*media_queries); } +void ParseWebBundleUrlsAndFillHash(const AtomicString& value, + HashSet<KURL>& url_hash) { + // Parse the attribute value as a space-separated list of urls + SpaceSplitString urls(value); + for (wtf_size_t i = 0; i < urls.size(); ++i) { + KURL url = LinkWebBundle::ParseResourceUrl(urls[i]); + if (url.IsValid()) { + url_hash.insert(std::move(url)); + } + } +} + +} // namespace + class TokenPreloadScanner::StartTagScanner { STACK_ALLOCATED(); @@ -139,6 +156,7 @@ class TokenPreloadScanner::StartTagScanner { link_is_preload_(false), link_is_modulepreload_(false), link_is_import_(false), + link_is_webbundle_(false), matched_(true), input_is_image_(false), nomodule_attribute_value_(false), @@ -152,6 +170,7 @@ class TokenPreloadScanner::StartTagScanner { referrer_policy_set_(false), referrer_policy_(network::mojom::ReferrerPolicy::kDefault), integrity_attr_set_(false), + is_async_(false), integrity_features_(features), loading_attr_value_(LoadingAttributeValue::kAuto), width_attr_dimension_type_( @@ -226,12 +245,32 @@ class TokenPreloadScanner::StartTagScanner { } } + bool MaybeUpdateExclusionInfo( + const KURL& document_url, + scoped_refptr<const PreloadRequest::ExclusionInfo>& exclusion_info) { + if (!IsLinkRelWebBundle()) + return false; + HashSet<KURL> scopes; + HashSet<KURL> resources; + if (exclusion_info) { + scopes = exclusion_info->scopes(); + resources = exclusion_info->resources(); + } + ParseWebBundleUrlsAndFillHash(scopes_attribute_value_, scopes); + ParseWebBundleUrlsAndFillHash(resources_attribute_value_, resources); + exclusion_info = base::MakeRefCounted<PreloadRequest::ExclusionInfo>( + document_url, std::move(scopes), std::move(resources)); + return true; + } + std::unique_ptr<PreloadRequest> CreatePreloadRequest( const KURL& predicted_base_url, const SegmentedString& source, const ClientHintsPreferences& client_hints_preferences, const PictureData& picture_data, - const CachedDocumentParameters& document_parameters) { + const CachedDocumentParameters& document_parameters, + const PreloadRequest::ExclusionInfo* exclusion_info, + bool treat_links_as_in_body) { PreloadRequest::RequestType request_type = PreloadRequest::kRequestTypePreload; base::Optional<ResourceType> type; @@ -283,13 +322,15 @@ class TokenPreloadScanner::StartTagScanner { auto request = PreloadRequest::CreateIfNeeded( InitiatorFor(tag_impl_), position, url_to_load_, predicted_base_url, type.value(), referrer_policy, PreloadRequest::kDocumentIsReferrer, - is_image_set, resource_width, client_hints_preferences, request_type); + is_image_set, exclusion_info, resource_width, client_hints_preferences, + request_type); if (!request) return nullptr; - if ((Match(tag_impl_, html_names::kScriptTag) && - type_attribute_value_ == "module") || - IsLinkRelModulePreload()) { + bool is_module = (type_attribute_value_ == "module"); + bool is_script = Match(tag_impl_, html_names::kScriptTag); + if ((is_script && is_module) || IsLinkRelModulePreload()) { + is_module = true; request->SetScriptType(mojom::blink::ScriptType::kModule); } @@ -299,6 +340,22 @@ class TokenPreloadScanner::StartTagScanner { request->SetCharset(Charset()); request->SetDefer(defer_); + RenderBlockingBehavior render_blocking_behavior = + RenderBlockingBehavior::kUnset; + if (is_script && (is_module || defer_ == FetchParameters::kLazyLoad)) { + render_blocking_behavior = + is_async_ ? RenderBlockingBehavior::kPotentiallyBlocking + : RenderBlockingBehavior::kNonBlocking; + } else if (is_script || type == ResourceType::kCSSStyleSheet) { + // CSS here is render blocking, as non blocking doesn't get preloaded. + // JS here is a blocking one, as others would've been caught by the + // previous condition. + render_blocking_behavior = + treat_links_as_in_body ? RenderBlockingBehavior::kInBodyParserBlocking + : RenderBlockingBehavior::kBlocking; + } + request->SetRenderBlockingBehavior(render_blocking_behavior); + if (type == ResourceType::kImage && Match(tag_impl_, html_names::kImgTag) && IsLazyLoadImageDeferable(document_parameters)) { return nullptr; @@ -332,6 +389,7 @@ class TokenPreloadScanner::StartTagScanner { } else if (Match(attribute_name, html_names::kNonceAttr)) { SetNonce(attribute_value); } else if (Match(attribute_name, html_names::kAsyncAttr)) { + is_async_ = true; SetDefer(FetchParameters::kLazyLoad); } else if (Match(attribute_name, html_names::kDeferAttr)) { SetDefer(FetchParameters::kLazyLoad); @@ -437,6 +495,7 @@ class TokenPreloadScanner::StartTagScanner { link_is_preload_ = rel.IsLinkPreload(); link_is_modulepreload_ = rel.IsModulePreload(); link_is_import_ = rel.IsImport(); + link_is_webbundle_ = rel.IsWebBundle(); } else if (Match(attribute_name, html_names::kMediaAttr)) { matched_ &= MediaAttributeMatches(*media_values_, attribute_value); } else if (Match(attribute_name, html_names::kCrossoriginAttr)) { @@ -467,6 +526,10 @@ class TokenPreloadScanner::StartTagScanner { Match(attribute_name, html_names::kImportanceAttr) && priority_hints_origin_trial_enabled_) { SetImportance(attribute_value); + } else if (Match(attribute_name, html_names::kScopesAttr)) { + scopes_attribute_value_ = AtomicString(attribute_value); + } else if (Match(attribute_name, html_names::kResourcesAttr)) { + resources_attribute_value_ = AtomicString(attribute_value); } } @@ -630,6 +693,10 @@ class TokenPreloadScanner::StartTagScanner { !url_to_load_.IsEmpty(); } + bool IsLinkRelWebBundle() const { + return Match(tag_impl_, html_names::kLinkTag) && link_is_webbundle_; + } + bool ShouldPreloadLink(base::Optional<ResourceType>& type) const { if (link_is_style_sheet_) { return type_attribute_value_.IsEmpty() || @@ -669,21 +736,24 @@ class TokenPreloadScanner::StartTagScanner { if (Match(tag_impl_, html_names::kInputTag) && !input_is_image_) return false; if (Match(tag_impl_, html_names::kScriptTag)) { - mojom::blink::ScriptType script_type = mojom::blink::ScriptType::kClassic; - bool is_import_map = false; - if (!ScriptLoader::IsValidScriptTypeAndLanguage( + ScriptLoader::ScriptTypeAtPrepare script_type = + ScriptLoader::GetScriptTypeAtPrepare( type_attribute_value_, language_attribute_value_, - ScriptLoader::kAllowLegacyTypeInTypeAttribute, &script_type, - &is_import_map)) { - return false; - } - if (is_import_map) { - // External import maps are not yet supported. https://crbug.com/922212 - return false; - } - if (ScriptLoader::BlockForNoModule(script_type, - nomodule_attribute_value_)) { - return false; + ScriptLoader::kAllowLegacyTypeInTypeAttribute); + switch (script_type) { + case ScriptLoader::ScriptTypeAtPrepare::kInvalid: + return false; + + case ScriptLoader::ScriptTypeAtPrepare::kImportMap: + // TODO(crbug.com/922212): External import maps are not yet supported. + return false; + + case ScriptLoader::ScriptTypeAtPrepare::kClassic: + case ScriptLoader::ScriptTypeAtPrepare::kModule: + if (ScriptLoader::BlockForNoModule(script_type, + nomodule_attribute_value_)) { + return false; + } } } return true; @@ -717,7 +787,7 @@ class TokenPreloadScanner::StartTagScanner { void SetDefer(FetchParameters::DeferOption defer) { defer_ = defer; } - bool Defer() const { return defer_; } + bool Defer() const { return defer_ != FetchParameters::kNoDefer; } const StringImpl* tag_impl_; String url_to_load_; @@ -728,6 +798,7 @@ class TokenPreloadScanner::StartTagScanner { bool link_is_preload_; bool link_is_modulepreload_; bool link_is_import_; + bool link_is_webbundle_; bool matched_; bool input_is_image_; String img_src_url_; @@ -735,6 +806,8 @@ class TokenPreloadScanner::StartTagScanner { String as_attribute_value_; String type_attribute_value_; String language_attribute_value_; + AtomicString scopes_attribute_value_; + AtomicString resources_attribute_value_; bool nomodule_attribute_value_; float source_size_; bool source_size_set_; @@ -747,6 +820,7 @@ class TokenPreloadScanner::StartTagScanner { bool referrer_policy_set_; network::mojom::ReferrerPolicy referrer_policy_; bool integrity_attr_set_; + bool is_async_; IntegrityMetadataSet integrity_metadata_; SubresourceIntegrity::IntegrityFeatures integrity_features_; LoadingAttributeValue loading_attr_value_; @@ -769,6 +843,8 @@ TokenPreloadScanner::TokenPreloadScanner( in_style_(false), in_picture_(false), in_script_(false), + seen_body_(false), + seen_img_(false), template_count_(0), document_parameters_(std::move(document_parameters)), media_values_( @@ -787,7 +863,8 @@ TokenPreloadScanner::~TokenPreloadScanner() = default; TokenPreloadScannerCheckpoint TokenPreloadScanner::CreateCheckpoint() { TokenPreloadScannerCheckpoint checkpoint = checkpoints_.size(); checkpoints_.push_back(Checkpoint(predicted_base_element_url_, in_style_, - in_script_, template_count_)); + in_script_, template_count_, + exclusion_info_)); return checkpoint; } @@ -799,6 +876,7 @@ void TokenPreloadScanner::RewindTo( predicted_base_element_url_ = checkpoint.predicted_base_element_url; in_style_ = checkpoint.in_style; template_count_ = checkpoint.template_count; + exclusion_info_ = checkpoint.exclusion_info; did_rewind_ = true; in_script_ = checkpoint.in_script; @@ -903,7 +981,7 @@ void TokenPreloadScanner::ScanCommon( case HTMLToken::kCharacter: { if (in_style_) { css_scanner_.Scan(token.Data(), source, requests, - predicted_base_element_url_); + predicted_base_element_url_, exclusion_info_.get()); } return; } @@ -931,13 +1009,13 @@ void TokenPreloadScanner::ScanCommon( return; } case HTMLToken::kStartTag: { - if (template_count_) - return; const StringImpl* tag_impl = TagImplFor(token.Data()); if (Match(tag_impl, html_names::kTemplateTag)) { ++template_count_; return; } + if (template_count_) + return; if (Match(tag_impl, html_names::kStyleTag)) { in_style_ = true; return; @@ -978,7 +1056,11 @@ void TokenPreloadScanner::ScanCommon( media_values_.Get(), &css_scanner_, viewport); } - if (Match(tag_impl, html_names::kPictureTag)) { + if (Match(tag_impl, html_names::kBodyTag)) { + seen_body_ = true; + } else if (Match(tag_impl, html_names::kImgTag)) { + seen_img_ = true; + } else if (Match(tag_impl, html_names::kPictureTag)) { in_picture_ = true; picture_data_ = PictureData(); return; @@ -995,6 +1077,13 @@ void TokenPreloadScanner::ScanCommon( scanner_type_, priority_hints_origin_trial_enabled_, &document_parameters_->disabled_image_types); scanner.ProcessAttributes(token.Attributes()); + + if (scanner.MaybeUpdateExclusionInfo(document_url_, exclusion_info_)) { + // This means the tag is <link rel=webbundle>. We don't preload the + // web bundle request. + return; + } + // TODO(yoav): ViewportWidth is currently racy and might be zero in some // cases, at least in tests. That problem will go away once // ParseHTMLOnMainThread lands and MediaValuesCached is eliminated. @@ -1002,7 +1091,8 @@ void TokenPreloadScanner::ScanCommon( scanner.HandlePictureSourceURL(picture_data_); std::unique_ptr<PreloadRequest> request = scanner.CreatePreloadRequest( predicted_base_element_url_, source, client_hints_preferences_, - picture_data_, *document_parameters_); + picture_data_, *document_parameters_, exclusion_info_.get(), + seen_img_ || seen_body_); if (request) { requests.push_back(std::move(request)); } diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner.h b/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner.h index abcff2db478..f0a57694aa2 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner.h +++ b/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner.h @@ -119,19 +119,23 @@ class TokenPreloadScanner { void UpdatePredictedBaseURL(const Token&); struct Checkpoint { - Checkpoint(const KURL& predicted_base_element_url, - bool in_style, - bool in_script, - size_t template_count) + Checkpoint( + const KURL& predicted_base_element_url, + bool in_style, + bool in_script, + size_t template_count, + scoped_refptr<const PreloadRequest::ExclusionInfo> exclusion_info) : predicted_base_element_url(predicted_base_element_url), in_style(in_style), in_script(in_script), - template_count(template_count) {} + template_count(template_count), + exclusion_info(std::move(exclusion_info)) {} KURL predicted_base_element_url; bool in_style; bool in_script; size_t template_count; + scoped_refptr<const PreloadRequest::ExclusionInfo> exclusion_info; }; struct PictureData { @@ -145,9 +149,12 @@ class TokenPreloadScanner { CSSPreloadScanner css_scanner_; const KURL document_url_; KURL predicted_base_element_url_; + scoped_refptr<const PreloadRequest::ExclusionInfo> exclusion_info_; bool in_style_; bool in_picture_; bool in_script_; + bool seen_body_; + bool seen_img_; PictureData picture_data_; size_t template_count_; std::unique_ptr<CachedDocumentParameters> document_parameters_; diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner_fuzzer.cc b/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner_fuzzer.cc index d75792bdf0b..82c51b5c430 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner_fuzzer.cc +++ b/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner_fuzzer.cc @@ -2,6 +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/public/mojom/webpreferences/web_preferences.mojom-blink.h" #include "third_party/blink/renderer/core/css/media_values_cached.h" #include "third_party/blink/renderer/core/html/html_document.h" #include "third_party/blink/renderer/core/html/parser/html_document_parser.h" @@ -56,7 +57,7 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { media_data.device_pixel_ratio = 2.0; media_data.color_bits_per_component = 24; media_data.monochrome_bits_per_component = 0; - media_data.primary_pointer_type = ui::POINTER_TYPE_FINE; + media_data.primary_pointer_type = mojom::blink::PointerType::kPointerFineType; media_data.default_font_size = 16; media_data.three_d_enabled = true; media_data.media_type = media_type_names::kScreen; 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 63a23ad4bfc..4bd6fb08d90 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 @@ -232,7 +232,7 @@ class HTMLPreloadScannerTest : public PageTestBase { data.device_pixel_ratio = 2.0; data.color_bits_per_component = 24; data.monochrome_bits_per_component = 0; - data.primary_pointer_type = ui::POINTER_TYPE_FINE; + data.primary_pointer_type = mojom::blink::PointerType::kPointerFineType; data.default_font_size = 16; data.three_d_enabled = true; data.media_type = media_type_names::kScreen; @@ -1488,4 +1488,32 @@ TEST_F(HTMLPreloadScannerTest, CSSImportWithSemicolonInUrl) { Test(test); } +// https://crbug.com/1181291 +TEST_F(HTMLPreloadScannerTest, TemplateInteractions) { + PreloadScannerTestCase test_cases[] = { + {"http://example.test", "<template><img src='bla.gif'></template>", + nullptr, "http://example.test/", ResourceType::kImage, 0}, + {"http://example.test", + "<template><template><img src='bla.gif'></template></template>", nullptr, + "http://example.test/", ResourceType::kImage, 0}, + {"http://example.test", + "<template><template></template><img src='bla.gif'></template>", nullptr, + "http://example.test/", ResourceType::kImage, 0}, + {"http://example.test", + "<template><template></template><script " + "src='test.js'></script></template>", + nullptr, "http://example.test/", ResourceType::kScript, 0}, + {"http://example.test", + "<template><template></template><link rel=preload as=fetch " + "href=bla></template>", + nullptr, "http://example.test/", ResourceType::kRaw, 0}, + {"http://example.test", + "<template><template></template><link rel='stylesheet' href='sheet.css' " + "type='text/css'></template>", + nullptr, "http://example.test/", ResourceType::kCSSStyleSheet, 0}, + }; + for (const auto& test : test_cases) + Test(test); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader_test.cc b/chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader_test.cc index 4b5fa934609..afb03ba1a3d 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader_test.cc +++ b/chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader_test.cc @@ -59,8 +59,8 @@ class HTMLResourcePreloaderTest : public PageTestBase { String(), TextPosition(), test_case.url, KURL(test_case.base_url), ResourceType::kImage, network::mojom::ReferrerPolicy(), PreloadRequest::kDocumentIsReferrer, ResourceFetcher::kImageNotImageSet, - FetchParameters::ResourceWidth(), ClientHintsPreferences(), - PreloadRequest::kRequestTypePreconnect); + nullptr /* exclusion_info */, FetchParameters::ResourceWidth(), + ClientHintsPreferences(), PreloadRequest::kRequestTypePreconnect); DCHECK(preload_request); if (test_case.is_cors) preload_request->SetCrossOrigin(kCrossOriginAttributeAnonymous); diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder.cc b/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder.cc index 77abc99de36..4f7b9218954 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder.cc +++ b/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder.cc @@ -233,13 +233,13 @@ HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, Document& document, ParserContentPolicy parser_content_policy, const HTMLParserOptions& options, - bool allow_shadow_root) + bool include_shadow_roots) : frameset_ok_(true), tree_(parser->ReentryPermit(), document, parser_content_policy), insertion_mode_(kInitialMode), original_insertion_mode_(kInitialMode), should_skip_leading_newline_(false), - allow_shadow_root_(allow_shadow_root), + include_shadow_roots_(include_shadow_roots), parser_(parser), script_to_process_start_position_(UninitializedPositionValue1()), options_(options) {} @@ -249,12 +249,12 @@ HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, Element* context_element, ParserContentPolicy parser_content_policy, const HTMLParserOptions& options, - bool allow_shadow_root) + bool include_shadow_roots) : HTMLTreeBuilder(parser, fragment->GetDocument(), parser_content_policy, options, - allow_shadow_root) { + include_shadow_roots) { DCHECK(IsMainThread()); DCHECK(context_element); tree_.InitFragmentParsing(fragment, context_element); @@ -898,33 +898,50 @@ void HTMLTreeBuilder::ProcessStartTagForInBody(AtomicHTMLToken* token) { tree_.InsertHTMLElement(token); } +namespace { +DeclarativeShadowRootType DeclarativeShadowRootTypeFromToken( + AtomicHTMLToken* token, + const Document& document, + bool include_shadow_roots) { + if (!RuntimeEnabledFeatures::DeclarativeShadowDOMEnabled( + document.GetExecutionContext())) { + return DeclarativeShadowRootType::kNone; + } + Attribute* type_attribute = + token->GetAttributeItem(html_names::kShadowrootAttr); + if (!type_attribute) + return DeclarativeShadowRootType::kNone; + + if (!include_shadow_roots) { + document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( + mojom::blink::ConsoleMessageSource::kOther, + mojom::blink::ConsoleMessageLevel::kWarning, + "Found declarative shadowroot attribute on a template, but declarative " + "Shadow DOM has not been enabled by includeShadowRoots.")); + return DeclarativeShadowRootType::kNone; + } + + String shadow_mode = type_attribute->Value(); + if (EqualIgnoringASCIICase(shadow_mode, "open")) + return DeclarativeShadowRootType::kOpen; + if (EqualIgnoringASCIICase(shadow_mode, "closed")) + return DeclarativeShadowRootType::kClosed; + + document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( + mojom::blink::ConsoleMessageSource::kOther, + mojom::blink::ConsoleMessageLevel::kWarning, + "Invalid declarative shadowroot attribute value \"" + shadow_mode + + "\". Valid values include \"open\" and \"closed\".")); + return DeclarativeShadowRootType::kNone; +} +} // namespace + void HTMLTreeBuilder::ProcessTemplateStartTag(AtomicHTMLToken* token) { tree_.ActiveFormattingElements()->AppendMarker(); - - DeclarativeShadowRootType declarative_shadow_root_type( - DeclarativeShadowRootType::kNone); - if (RuntimeEnabledFeatures::DeclarativeShadowDOMEnabled( - tree_.CurrentNode()->GetExecutionContext()) && - allow_shadow_root_) { - if (Attribute* type_attribute = - token->GetAttributeItem(html_names::kShadowrootAttr)) { - String shadow_mode = type_attribute->Value(); - if (EqualIgnoringASCIICase(shadow_mode, "open")) { - declarative_shadow_root_type = DeclarativeShadowRootType::kOpen; - } else if (EqualIgnoringASCIICase(shadow_mode, "closed")) { - declarative_shadow_root_type = DeclarativeShadowRootType::kClosed; - } else { - tree_.OwnerDocumentForCurrentNode().AddConsoleMessage( - MakeGarbageCollected<ConsoleMessage>( - mojom::blink::ConsoleMessageSource::kOther, - mojom::blink::ConsoleMessageLevel::kWarning, - "Invalid declarative shadowroot attribute value \"" + - shadow_mode + - "\". Valid values include \"open\" and \"closed\".")); - } - } - } - tree_.InsertHTMLTemplateElement(token, declarative_shadow_root_type); + tree_.InsertHTMLTemplateElement( + token, + DeclarativeShadowRootTypeFromToken( + token, tree_.OwnerDocumentForCurrentNode(), include_shadow_roots_)); frameset_ok_ = false; template_insertion_modes_.push_back(kTemplateContentsMode); SetInsertionMode(kTemplateContentsMode); diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder.h b/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder.h index ee8ff98b952..38135b60775 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder.h +++ b/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder.h @@ -55,13 +55,13 @@ class HTMLTreeBuilder final : public GarbageCollected<HTMLTreeBuilder> { Document&, ParserContentPolicy, const HTMLParserOptions&, - bool allow_shadow_root); + bool include_shadow_roots); HTMLTreeBuilder(HTMLDocumentParser*, DocumentFragment*, Element* context_element, ParserContentPolicy, const HTMLParserOptions&, - bool allow_shadow_root); + bool include_shadow_roots); ~HTMLTreeBuilder(); void Trace(Visitor*) const; @@ -248,7 +248,7 @@ class HTMLTreeBuilder final : public GarbageCollected<HTMLTreeBuilder> { bool should_skip_leading_newline_; - const bool allow_shadow_root_; + const bool include_shadow_roots_; // We access parser because HTML5 spec requires that we be able to change the // state of the tokenizer from within parser actions. We also need it to track diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder_simulator.cc b/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder_simulator.cc index ea11a426b6c..b0f1fa862b1 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder_simulator.cc +++ b/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder_simulator.cc @@ -171,9 +171,10 @@ HTMLTreeBuilderSimulator::SimulatedToken HTMLTreeBuilderSimulator::Simulate( language_attribute_value = item->Value(); } - if (ScriptLoader::IsValidScriptTypeAndLanguage( + if (ScriptLoader::GetScriptTypeAtPrepare( type_attribute_value, language_attribute_value, - ScriptLoader::kAllowLegacyTypeInTypeAttribute)) { + ScriptLoader::kAllowLegacyTypeInTypeAttribute) != + ScriptLoader::ScriptTypeAtPrepare::kInvalid) { simulated_token = kValidScriptStart; } } else if (ThreadSafeMatch(tag_name, html_names::kLinkTag)) { 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 8318f626709..73c57ab7c84 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 @@ -23,6 +23,30 @@ namespace blink { +PreloadRequest::ExclusionInfo::ExclusionInfo(const KURL& document_url, + HashSet<KURL> scopes, + HashSet<KURL> resources) + : document_url_(document_url), + scopes_(std::move(scopes)), + resources_(std::move(resources)) {} + +PreloadRequest::ExclusionInfo::~ExclusionInfo() = default; + +bool PreloadRequest::ExclusionInfo::ShouldExclude( + const KURL& base_url, + const String& resource_url) const { + if (resources_.IsEmpty() && scopes_.IsEmpty()) + return false; + KURL url = KURL(base_url.IsEmpty() ? document_url_ : base_url, resource_url); + if (resources_.Contains(url)) + return true; + for (const auto& scope : scopes_) { + if (url.GetString().StartsWith(scope.GetString())) + return true; + } + return false; +} + KURL PreloadRequest::CompleteURL(Document* document) { if (!base_url_.IsEmpty()) return document->CompleteURLWithOverride(resource_url_, base_url_); @@ -39,6 +63,7 @@ std::unique_ptr<PreloadRequest> PreloadRequest::CreateIfNeeded( const network::mojom::ReferrerPolicy referrer_policy, ReferrerSource referrer_source, ResourceFetcher::IsImageSet is_image_set, + const ExclusionInfo* exclusion_info, const FetchParameters::ResourceWidth& resource_width, const ClientHintsPreferences& client_hints_preferences, RequestType request_type) { @@ -50,6 +75,10 @@ std::unique_ptr<PreloadRequest> PreloadRequest::CreateIfNeeded( ProtocolIs(resource_url, "data")) { return nullptr; } + + if (exclusion_info && exclusion_info->ShouldExclude(base_url, resource_url)) + return nullptr; + return base::WrapUnique(new PreloadRequest( initiator_name, initiator_position, resource_url, base_url, resource_type, resource_width, client_hints_preferences, request_type, referrer_policy, @@ -100,6 +129,7 @@ Resource* PreloadRequest::Start(Document* document) { DCHECK_EQ(resource_type_, ResourceType::kScript); params.SetCrossOriginAccessControl( origin, ScriptLoader::ModuleScriptCredentialsMode(cross_origin_)); + params.SetModuleScript(); } else if (cross_origin_ != kCrossOriginAttributeNotSet) { params.SetCrossOriginAccessControl(origin, cross_origin_); } @@ -132,10 +162,11 @@ Resource* PreloadRequest::Start(Document* document) { params.SetSpeculativePreloadType(speculative_preload_type); if (resource_type_ == ResourceType::kScript) { - MaybeDisallowFetchForDocWrittenScript(params, *document); // We intentionally ignore the returned value, because we don't resend // the async request to the blocked script here. + MaybeDisallowFetchForDocWrittenScript(params, *document); } + params.SetRenderBlockingBehavior(render_blocking_behavior_); return PreloadHelper::StartPreload(resource_type_, params, *document); } 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 bb277995bb5..8f0d11c50f5 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 @@ -31,6 +31,31 @@ class CORE_EXPORT PreloadRequest { USING_FAST_MALLOC(PreloadRequest); public: + class CORE_EXPORT ExclusionInfo : public RefCounted<ExclusionInfo> { + USING_FAST_MALLOC(ExclusionInfo); + + public: + ExclusionInfo(const KURL& document_url, + HashSet<KURL> scopes, + HashSet<KURL> resources); + virtual ~ExclusionInfo(); + + // Disallow copy and assign. + ExclusionInfo(const ExclusionInfo&) = delete; + ExclusionInfo& operator=(const ExclusionInfo&) = delete; + + const KURL& document_url() const { return document_url_; } + const HashSet<KURL>& scopes() const { return scopes_; } + const HashSet<KURL>& resources() const { return resources_; } + + bool ShouldExclude(const KURL& base_url, const String& resource_url) const; + + private: + const KURL document_url_; + const HashSet<KURL> scopes_; + const HashSet<KURL> resources_; + }; + enum RequestType { kRequestTypePreload, kRequestTypePreconnect, @@ -48,6 +73,7 @@ class CORE_EXPORT PreloadRequest { const network::mojom::ReferrerPolicy referrer_policy, ReferrerSource referrer_source, ResourceFetcher::IsImageSet is_image_set, + const ExclusionInfo* exclusion_info, const FetchParameters::ResourceWidth& resource_width = FetchParameters::ResourceWidth(), const ClientHintsPreferences& client_hints_preferences = @@ -113,6 +139,11 @@ class CORE_EXPORT PreloadRequest { return is_image_set_ == ResourceFetcher::kImageIsImageSet; } + void SetRenderBlockingBehavior( + RenderBlockingBehavior render_blocking_behavior) { + render_blocking_behavior_ = render_blocking_behavior; + } + private: PreloadRequest(const String& initiator_name, const TextPosition& initiator_position, @@ -162,6 +193,8 @@ class CORE_EXPORT PreloadRequest { const network::mojom::ReferrerPolicy referrer_policy_; const ReferrerSource referrer_source_; IntegrityMetadataSet integrity_metadata_; + RenderBlockingBehavior render_blocking_behavior_ = + RenderBlockingBehavior::kUnset; bool from_insertion_scanner_; const ResourceFetcher::IsImageSet is_image_set_; bool is_lazy_load_image_enabled_; diff --git a/chromium/third_party/blink/renderer/core/html/parser/text_document_parser.cc b/chromium/third_party/blink/renderer/core/html/parser/text_document_parser.cc index 173287e38a1..9b87078dbf6 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/text_document_parser.cc +++ b/chromium/third_party/blink/renderer/core/html/parser/text_document_parser.cc @@ -32,7 +32,7 @@ namespace blink { TextDocumentParser::TextDocumentParser(HTMLDocument& document, ParserSynchronizationPolicy sync_policy) - : HTMLDocumentParser(document, sync_policy), + : HTMLDocumentParser(document, sync_policy, kDisallowPrefetching), have_inserted_fake_pre_element_(false) {} TextDocumentParser::~TextDocumentParser() = default; 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 b6b83eb6fb9..bee0df0123a 100644 --- a/chromium/third_party/blink/renderer/core/html/plugin_document.cc +++ b/chromium/third_party/blink/renderer/core/html/plugin_document.cc @@ -95,8 +95,7 @@ void PluginDocumentParser::CreateDocumentStructure() { return; // FIXME: Why does this check settings? - if (!frame->GetSettings() || - !frame->Loader().AllowPlugins(kNotAboutToInstantiatePlugin)) + if (!frame->GetSettings() || !frame->Loader().AllowPlugins()) return; auto* root_element = MakeGarbageCollected<HTMLHtmlElement>(*GetDocument()); @@ -190,7 +189,7 @@ PluginDocument::PluginDocument(const DocumentInit& initializer) LockCompatibilityMode(); GetExecutionContext()->GetScheduler()->RegisterStickyFeature( SchedulingPolicy::Feature::kContainsPlugins, - {SchedulingPolicy::RecordMetricsForBackForwardCache()}); + {SchedulingPolicy::DisableBackForwardCache()}); } DocumentParser* PluginDocument::CreateParser() { diff --git a/chromium/third_party/blink/renderer/core/html/portal/DIR_METADATA b/chromium/third_party/blink/renderer/core/html/portal/DIR_METADATA new file mode 100644 index 00000000000..1e4fe50104b --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/portal/DIR_METADATA @@ -0,0 +1,3 @@ +monorail { + component: "Blink>Portals" +} diff --git a/chromium/third_party/blink/renderer/core/html/portal/OWNERS b/chromium/third_party/blink/renderer/core/html/portal/OWNERS index 5ca25353465..15decd27f75 100644 --- a/chromium/third_party/blink/renderer/core/html/portal/OWNERS +++ b/chromium/third_party/blink/renderer/core/html/portal/OWNERS @@ -2,5 +2,3 @@ adithyas@chromium.org jbroman@chromium.org lfg@chromium.org mcnee@chromium.org - -# COMPONENT: Blink>Portals diff --git a/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.cc b/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.cc index 5116a6911ec..b554a4c9021 100644 --- a/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.cc +++ b/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.cc @@ -63,7 +63,7 @@ HTMLPortalElement::HTMLPortalElement( feature_handle_for_scheduler_( document.GetExecutionContext()->GetScheduler()->RegisterFeature( SchedulingPolicy::Feature::kPortal, - {SchedulingPolicy::RecordMetricsForBackForwardCache()})) { + {SchedulingPolicy::DisableBackForwardCache()})) { if (remote_portal) { DCHECK(portal_token); was_just_adopted_ = true; @@ -335,19 +335,7 @@ ScriptPromise HTMLPortalElement::activate(ScriptState* script_state, void HTMLPortalElement::postMessage(ScriptState* script_state, const ScriptValue& message, - const String& target_origin, - const HeapVector<ScriptValue>& transfer, - ExceptionState& exception_state) { - WindowPostMessageOptions* options = WindowPostMessageOptions::Create(); - options->setTargetOrigin(target_origin); - if (!transfer.IsEmpty()) - options->setTransfer(transfer); - postMessage(script_state, message, options, exception_state); -} - -void HTMLPortalElement::postMessage(ScriptState* script_state, - const ScriptValue& message, - const WindowPostMessageOptions* options, + const PostMessageOptions* options, ExceptionState& exception_state) { if (!CheckPortalsEnabledOrThrow(exception_state) || !GetExecutionContext()) return; diff --git a/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.h b/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.h index a2c1d190da5..37e6bab3729 100644 --- a/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.h +++ b/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.h @@ -23,6 +23,7 @@ namespace blink { class Document; class PortalActivateOptions; class PortalContents; +class PostMessageOptions; class ScriptState; // The HTMLPortalElement implements the <portal> HTML element. The portal @@ -54,12 +55,7 @@ class CORE_EXPORT HTMLPortalElement : public HTMLFrameOwnerElement { ScriptPromise activate(ScriptState*, PortalActivateOptions*, ExceptionState&); void postMessage(ScriptState* script_state, const ScriptValue& message, - const String& target_origin, - const HeapVector<ScriptValue>& transfer, - ExceptionState& exception_state); - void postMessage(ScriptState* script_state, - const ScriptValue& message, - const WindowPostMessageOptions* options, + const PostMessageOptions* options, ExceptionState& exception_state); EventListener* onmessage(); void setOnmessage(EventListener* listener); diff --git a/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.idl b/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.idl index 2a0d7a796b8..132f816161a 100644 --- a/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.idl +++ b/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.idl @@ -10,9 +10,7 @@ interface HTMLPortalElement : HTMLElement { [CEReactions, Reflect, ReflectOnly=("","no-referrer","origin","no-referrer-when-downgrade","origin-when-cross-origin","unsafe-url"), ReflectMissing="", ReflectInvalid=""] attribute DOMString referrerPolicy; [CallWith=ScriptState, RaisesException, Measure] Promise<void> activate(optional PortalActivateOptions options = {}); - [CallWith=ScriptState, RaisesException, Measure] void postMessage(any message, USVString targetOrigin, - optional sequence<object> transfer = []); - [CallWith=ScriptState, RaisesException, Measure] void postMessage(any message, optional WindowPostMessageOptions options = {}); + [CallWith=ScriptState, RaisesException, Measure] void postMessage(any message, optional PostMessageOptions options = {}); attribute EventHandler onmessage; attribute EventHandler onmessageerror; diff --git a/chromium/third_party/blink/renderer/core/html/portal/portal_host.cc b/chromium/third_party/blink/renderer/core/html/portal/portal_host.cc index 38bf87a7de9..69e423f1cfc 100644 --- a/chromium/third_party/blink/renderer/core/html/portal/portal_host.cc +++ b/chromium/third_party/blink/renderer/core/html/portal/portal_host.cc @@ -60,19 +60,7 @@ void PortalHost::OnPortalActivated() { void PortalHost::postMessage(ScriptState* script_state, const ScriptValue& message, - const String& target_origin, - HeapVector<ScriptValue>& transfer, - ExceptionState& exception_state) { - WindowPostMessageOptions* options = WindowPostMessageOptions::Create(); - options->setTargetOrigin(target_origin); - if (!transfer.IsEmpty()) - options->setTransfer(transfer); - postMessage(script_state, message, options, exception_state); -} - -void PortalHost::postMessage(ScriptState* script_state, - const ScriptValue& message, - const WindowPostMessageOptions* options, + const PostMessageOptions* options, ExceptionState& exception_state) { if (!DOMWindowPortalHost::ShouldExposePortalHost(*GetSupplementable())) { exception_state.ThrowDOMException( diff --git a/chromium/third_party/blink/renderer/core/html/portal/portal_host.h b/chromium/third_party/blink/renderer/core/html/portal/portal_host.h index 0db0aaa8fa5..fa40d4aef79 100644 --- a/chromium/third_party/blink/renderer/core/html/portal/portal_host.h +++ b/chromium/third_party/blink/renderer/core/html/portal/portal_host.h @@ -18,7 +18,7 @@ class ExecutionContext; class LocalDOMWindow; class ScriptValue; class SecurityOrigin; -class WindowPostMessageOptions; +class PostMessageOptions; class CORE_EXPORT PortalHost : public EventTargetWithInlineData, public Supplement<LocalDOMWindow> { @@ -43,12 +43,7 @@ class CORE_EXPORT PortalHost : public EventTargetWithInlineData, // idl implementation void postMessage(ScriptState* script_state, const ScriptValue& message, - const String& target_origin, - HeapVector<ScriptValue>& transfer, - ExceptionState& exception_state); - void postMessage(ScriptState* script_state, - const ScriptValue& message, - const WindowPostMessageOptions* options, + const PostMessageOptions* options, ExceptionState& exception_state); EventListener* onmessage(); void setOnmessage(EventListener* listener); diff --git a/chromium/third_party/blink/renderer/core/html/portal/portal_host.idl b/chromium/third_party/blink/renderer/core/html/portal/portal_host.idl index df5205486cd..14a3694ba8e 100644 --- a/chromium/third_party/blink/renderer/core/html/portal/portal_host.idl +++ b/chromium/third_party/blink/renderer/core/html/portal/portal_host.idl @@ -6,10 +6,8 @@ [Exposed=Window, RuntimeEnabled=Portals] interface PortalHost : EventTarget { - [RaisesException, CallWith=ScriptState, Measure] void postMessage(any message, USVString targetOrigin, - optional sequence<object> transfer = []); [RaisesException, CallWith=ScriptState, Measure] void postMessage(any message, - optional WindowPostMessageOptions options = {}); + optional PostMessageOptions options = {}); attribute EventHandler onmessage; attribute EventHandler onmessageerror; diff --git a/chromium/third_party/blink/renderer/core/html/rel_list.cc b/chromium/third_party/blink/renderer/core/html/rel_list.cc index 6b70a346592..47061caf65a 100644 --- a/chromium/third_party/blink/renderer/core/html/rel_list.cc +++ b/chromium/third_party/blink/renderer/core/html/rel_list.cc @@ -7,6 +7,7 @@ #include "third_party/blink/renderer/core/dom/element.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/html/html_element.h" +#include "third_party/blink/renderer/core/html/link_web_bundle.h" #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/origin_trials/origin_trials.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" @@ -54,8 +55,7 @@ bool RelList::ValidateTokenValue(const AtomicString& token_value, token_value == "allowed-alt-sxg") { return true; } - if (RuntimeEnabledFeatures::SubresourceWebBundlesEnabled( - GetElement().GetExecutionContext()) && + if (LinkWebBundle::IsFeatureEnabled(GetElement().GetExecutionContext()) && token_value == "webbundle") { return true; } diff --git a/chromium/third_party/blink/renderer/core/html/resources/android.css b/chromium/third_party/blink/renderer/core/html/resources/android.css index b6ee01f4569..de2953abe98 100644 --- a/chromium/third_party/blink/renderer/core/html/resources/android.css +++ b/chromium/third_party/blink/renderer/core/html/resources/android.css @@ -56,7 +56,7 @@ input[type="month" i], input[type="time" i], input[type="week" i] { align-items: center; - -webkit-appearance: menulist; /* AutoAppearanceFor() should match to this. */ + appearance: auto; background-color: ButtonFace; border: 1px solid #a9a9a9; display: -webkit-inline-flex; diff --git a/chromium/third_party/blink/renderer/core/html/resources/controls_refresh.css b/chromium/third_party/blink/renderer/core/html/resources/controls_refresh.css index 4f2dc364099..1fb64c41d0c 100644 --- a/chromium/third_party/blink/renderer/core/html/resources/controls_refresh.css +++ b/chromium/third_party/blink/renderer/core/html/resources/controls_refresh.css @@ -22,16 +22,16 @@ textarea { border-color: -internal-light-dark(#767676, #858585); } -a:-webkit-any-link:focus { +a:-webkit-any-link:focus-visible { outline-offset: 1px; } -input:focus, textarea:focus, select:focus { +input:focus-visible, textarea:focus-visible, select:focus-visible { outline-offset: 0; } -input[type="checkbox" i]:focus, -input[type="radio" i]:focus { +input[type="checkbox" i]:focus-visible, +input[type="radio" i]:focus-visible { outline-offset: 2px; } @@ -55,6 +55,7 @@ textarea:disabled { input:disabled, textarea:disabled { background-color: -internal-light-dark(rgba(239, 239, 239, 0.3), rgba(59, 59, 59, 0.3)); + color: -internal-light-dark(default, rgba(255, 255, 255, 0.6)); } select:disabled { @@ -80,7 +81,7 @@ input[type="file" i]:disabled::-webkit-file-upload-button, button:disabled { background-color: -internal-light-dark(rgba(239, 239, 239, 0.3), rgba(19, 1, 1, 0.3)); border-color: -internal-light-dark(rgba(118, 118, 118, 0.3), rgba(195, 195, 195, 0.3)); - color: -internal-light-dark(rgba(16, 16, 16, 0.3), white); + color: -internal-light-dark(rgba(16, 16, 16, 0.3), rgba(255, 255, 255, 0.3)); } input[type="password" i]::-internal-reveal { @@ -162,10 +163,10 @@ input[type="week" i]::-webkit-calendar-picker-indicator { width: 1.2em; } -input[type="date" i]::-webkit-calendar-picker-indicator:focus, -input[type="datetime-local" i]::-webkit-calendar-picker-indicator:focus, -input[type="month" i]::-webkit-calendar-picker-indicator:focus, -input[type="week" i]::-webkit-calendar-picker-indicator:focus { +input[type="date" i]::-webkit-calendar-picker-indicator:focus-visible, +input[type="datetime-local" i]::-webkit-calendar-picker-indicator:focus-visible, +input[type="month" i]::-webkit-calendar-picker-indicator:focus-visible, +input[type="week" i]::-webkit-calendar-picker-indicator:focus-visible { outline: solid 2px -webkit-focus-ring-color; outline-offset: -2px; } @@ -186,7 +187,7 @@ input[type="time" i]::-webkit-calendar-picker-indicator { width: 1.05em; } -input[type="time" i]::-webkit-calendar-picker-indicator:focus { +input[type="time" i]::-webkit-calendar-picker-indicator:focus-visible { outline: solid 2px -webkit-focus-ring-color; outline-offset: -2px; } @@ -235,15 +236,15 @@ select:-internal-list-box option:checked:disabled:hover { color: -internal-light-dark(gray, #aaa) !important; } -input::-webkit-datetime-edit-ampm-field:focus, -input::-webkit-datetime-edit-day-field:focus, -input::-webkit-datetime-edit-hour-field:focus, -input::-webkit-datetime-edit-millisecond-field:focus, -input::-webkit-datetime-edit-minute-field:focus, -input::-webkit-datetime-edit-month-field:focus, -input::-webkit-datetime-edit-second-field:focus, -input::-webkit-datetime-edit-week-field:focus, -input::-webkit-datetime-edit-year-field:focus { +input::-webkit-datetime-edit-ampm-field:focus-visible, +input::-webkit-datetime-edit-day-field:focus-visible, +input::-webkit-datetime-edit-hour-field:focus-visible, +input::-webkit-datetime-edit-millisecond-field:focus-visible, +input::-webkit-datetime-edit-minute-field:focus-visible, +input::-webkit-datetime-edit-month-field:focus-visible, +input::-webkit-datetime-edit-second-field:focus-visible, +input::-webkit-datetime-edit-week-field:focus-visible, +input::-webkit-datetime-edit-year-field:focus-visible { background-color: -internal-light-dark(highlight, #99C8FF); color: -internal-light-dark(highlighttext, #000000); outline: none; @@ -259,4 +260,4 @@ input::-webkit-datetime-edit-millisecond-field[disabled], input::-webkit-datetime-edit-minute-field[disabled], input::-webkit-datetime-edit-second-field[disabled] { color: -internal-light-dark(GrayText, #000000); -}
\ No newline at end of file +} diff --git a/chromium/third_party/blink/renderer/core/html/resources/forced_colors.css b/chromium/third_party/blink/renderer/core/html/resources/forced_colors.css index b2124b35f89..ce30cebc8c4 100644 --- a/chromium/third_party/blink/renderer/core/html/resources/forced_colors.css +++ b/chromium/third_party/blink/renderer/core/html/resources/forced_colors.css @@ -15,37 +15,38 @@ */ @media ua-forced-colors { - html { - color: CanvasText; - fill: currentColor; - } - - :focus { - outline-color: Highlight; + :focus-visible { + -internal-forced-outline-color: Highlight; } a:link, a:-webkit-any-link:active { - color: LinkText; + -internal-forced-color: LinkText; } a:visited { - color: VisitedText; + -internal-forced-color: VisitedText; } fieldset { - border-color: CanvasText; + -internal-forced-border-color: CanvasText; + } + + mark { + -internal-forced-background-color: yellow; + -internal-forced-color: black; } ::placeholder { - color: GrayText; + -internal-forced-color: GrayText; } input, textarea { background-color: Canvas; - border-color: ButtonText; - color: CanvasText; + -internal-forced-background-color: Canvas; + -internal-forced-border-color: ButtonText; + -internal-forced-color: CanvasText; } input:hover, @@ -53,7 +54,7 @@ input[type="file"]:hover::-webkit-file-upload-button, input:focus, textarea:focus { - border-color: Highlight; + -internal-forced-border-color: Highlight; } input[type="text"]:disabled, @@ -70,27 +71,30 @@ input[type="datetime-local"]:disabled, textarea:disabled { background-color: ButtonFace; - border-color: GrayText; - color: GrayText; + -internal-forced-background-color: ButtonFace; + -internal-forced-border-color: GrayText; + -internal-forced-color: GrayText; } input::-webkit-calendar-picker-indicator { background-color: ButtonFace; - color: ButtonText; - } - - input::-webkit-datetime-edit-ampm-field:focus, - input::-webkit-datetime-edit-day-field:focus, - input::-webkit-datetime-edit-hour-field:focus, - input::-webkit-datetime-edit-millisecond-field:focus, - input::-webkit-datetime-edit-minute-field:focus, - input::-webkit-datetime-edit-month-field:focus, - input::-webkit-datetime-edit-second-field:focus, - input::-webkit-datetime-edit-week-field:focus, - input::-webkit-datetime-edit-year-field:focus { + -internal-forced-background-color: ButtonFace; + -internal-forced-color: ButtonText; + } + + input::-webkit-datetime-edit-ampm-field:focus-visible, + input::-webkit-datetime-edit-day-field:focus-visible, + input::-webkit-datetime-edit-hour-field:focus-visible, + input::-webkit-datetime-edit-millisecond-field:focus-visible, + input::-webkit-datetime-edit-minute-field:focus-visible, + input::-webkit-datetime-edit-month-field:focus-visible, + input::-webkit-datetime-edit-second-field:focus-visible, + input::-webkit-datetime-edit-week-field:focus-visible, + input::-webkit-datetime-edit-year-field:focus-visible { background-color: Highlight; - color: HighlightText; outline: none; + -internal-forced-background-color: Highlight; + -internal-forced-color: HighlightText; } input[type="color"]:disabled { @@ -110,9 +114,10 @@ input[type="submit"], input[type="reset"], input[type="file"]::-webkit-file-upload-button { - border-color: ButtonText; background-color: ButtonFace; - color: ButtonText; + -internal-forced-background-color: ButtonFace; + -internal-forced-border-color: ButtonText; + -internal-forced-color: ButtonText; } button:hover, @@ -123,25 +128,26 @@ input[type="button"]:focus, input[type="submit"]:focus, input[type="reset"]:focus { - border-color: Highlight; + -internal-forced-border-color: Highlight; } button:disabled, input[type="button"]:disabled, input[type="submit"]:disabled, input[type="reset"]:disabled { - border-color: GrayText; - color: GrayText; + -internal-forced-border-color: GrayText; + -internal-forced-color: GrayText; } /* same color as hyperlinks */ details summary { - color: LinkText; + -internal-forced-color: LinkText; } select:-internal-list-box { background-color: Canvas !important; - border-color: ButtonText; + -internal-forced-background-color: Canvas !important; + -internal-forced-border-color: ButtonText; } /* option disabled */ @@ -150,6 +156,7 @@ select:-internal-list-box:disabled option, select:-internal-list-box:disabled option:hover { background-color: Canvas !important; + -internal-forced-background-color: Canvas !important; color: GrayText !important; } @@ -185,51 +192,57 @@ select { background-color: Canvas; - border-color: CanvasText; - color: CanvasText; + -internal-forced-background-color: Canvas; + -internal-forced-border-color: CanvasText; + -internal-forced-color: CanvasText; } select:not(:-internal-list-box) { background-color: Canvas; + -internal-forced-background-color: Canvas; } select:hover { - border-color: Highlight; + -internal-forced-border-color: Highlight; } select:focus { - border-color: Highlight; + -internal-forced-border-color: Highlight; } select:disabled { - border-color: GrayText; - color: GrayText; opacity: 1; + -internal-forced-border-color: GrayText; + -internal-forced-color: GrayText; } meter::-webkit-meter-bar { background-color: ButtonFace; - border-color: CanvasText; + -internal-forced-background-color: ButtonFace; + -internal-forced-border-color: CanvasText; } meter::-webkit-meter-even-less-good-value, meter::-webkit-meter-optimum-value, meter::-webkit-meter-suboptimum-value { background-color: Highlight; + -internal-forced-background-color: Highlight; } input:-internal-autofill-previewed, textarea:-internal-autofill-previewed, select:-internal-autofill-previewed { - color: CanvasText !important; background-color: Canvas !important; + -internal-forced-background-color: Canvas !important; + -internal-forced-color: CanvasText !important; } input:-internal-autofill-selected, textarea:-internal-autofill-selected, select:-internal-autofill-selected { - color: CanvasText !important; background-color: Canvas !important; + -internal-forced-background-color: Canvas !important; + -internal-forced-color: CanvasText !important; } } diff --git a/chromium/third_party/blink/renderer/core/html/resources/html.css b/chromium/third_party/blink/renderer/core/html/resources/html.css index da6f733ac6f..c98a0f6c11b 100644 --- a/chromium/third_party/blink/renderer/core/html/resources/html.css +++ b/chromium/third_party/blink/renderer/core/html/resources/html.css @@ -150,6 +150,32 @@ video { object-fit: contain; } +video:-webkit-full-page-media { + margin: auto; + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + max-height: 100%; + max-width: 100%; +} + +audio:not([controls]) { + display: none !important; +} + +/** TODO(crbug.com/985623): Remove these hard-coded audio tag size. + * This fixed audio tag width/height leads to fail the wpt tests below. + * crbug.com/955170 external/wpt/css/css-contain/contain-size-replaced-003a.html + * crbug.com/955163 external/wpt/css/css-contain/contain-size-replaced-003b.html + * crbug.com/955163 external/wpt/css/css-contain/contain-size-replaced-003c.html + */ +audio { + width: 300px; + height: 54px; +} + /* heading elements */ h1 { @@ -424,7 +450,7 @@ input[type="hidden" i] { } input { - -webkit-appearance: textfield; /* AutoAppearanceFor() should match to this. */ + appearance: auto; padding: 1px; background-color: -internal-light-dark(white, black); border: 2px inset; @@ -433,7 +459,7 @@ input { } input[type="search" i] { - -webkit-appearance: searchfield; /* AutoAppearanceFor() should match to this. */ + appearance: auto; box-sizing: border-box; } @@ -500,7 +526,7 @@ select { } textarea { - -webkit-appearance: textarea; /* AutoAppearanceFor() should match to this. */ + appearance: auto; background-color: -internal-light-dark(white, black); border: 1px solid; column-count: initial !important; @@ -557,7 +583,7 @@ input[type="password" i]::-internal-input-suggested { } input[type="hidden" i], input[type="image" i], input[type="file" i] { - -webkit-appearance: initial; /* AutoAppearanceFor() should match to this. */ + appearance: none; padding: initial; background-color: initial; border: initial; @@ -582,7 +608,7 @@ input[type="image" i] { input:-internal-autofill-previewed, textarea:-internal-autofill-previewed, select:-internal-autofill-previewed { - -webkit-appearance:menulist-button; + appearance: menulist-button; background-color: #E8F0FE !important; background-image:none !important; color: -internal-light-dark(black, white) !important; @@ -591,7 +617,7 @@ select:-internal-autofill-previewed { input:-internal-autofill-selected, textarea:-internal-autofill-selected, select:-internal-autofill-selected { - -webkit-appearance:menulist-button; + appearance: menulist-button; background-color: #E8F0FE !important; background-image:none !important; color: -internal-light-dark(black, white) !important; @@ -633,7 +659,7 @@ input[type="button" i], input[type="submit" i], input[type="reset" i], input[typ } input[type="range" i] { - -webkit-appearance: slider-horizontal; /* AutoAppearanceFor() should match to this. */ + appearance: auto; padding: initial; border: initial; margin: 2px; @@ -755,7 +781,7 @@ input[type="color" i]::-webkit-color-swatch { } input[type="color" i][list] { - -webkit-appearance: menulist; /* AutoAppearanceFor() should match to this. */ + appearance: auto; width: 88px; height: 23px } @@ -812,7 +838,7 @@ input[readonly]::-webkit-calendar-picker-indicator { } select { - -webkit-appearance: menulist; /* AutoAppearanceFor() should match to this. */ + appearance: auto; box-sizing: border-box; align-items: center; border: 1px solid; @@ -828,7 +854,7 @@ select:not(:-internal-list-box) { } select:-internal-list-box { - -webkit-appearance: listbox; /* AutoAppearanceFor() should match to this. */ + appearance: auto; align-items: flex-start; border: 1px inset gray; border-radius: initial; @@ -847,7 +873,7 @@ option { font-weight: normal; display: block; padding: 0 2px 1px 2px; - white-space: pre; + white-space: nowrap; min-height: 1.2em; } @@ -885,11 +911,24 @@ select:-internal-list-box hr { margin-block-end: 0; } -select:-internal-list-box:focus option:-internal-multi-select-focus { +select:-internal-list-box:focus-visible option:-internal-multi-select-focus { outline: auto 1px -webkit-focus-ring-color; outline-offset: -1px; } +/* selectmenu */ + +/* TODO(crbug.com/1121840) It's deliberate for now that this provides styles +for <option> but not other element types with part="option". Could this +be a mechanism for allowing authors to specify their own styles for +option parts by using e.g. <div part="option">, while authors that +want the default styles can instead just use <option>? */ +selectmenu option:hover { + background-color: lightgray; + cursor: default; + user-select: none; +} + output { display: inline; } @@ -1053,31 +1092,31 @@ nobr { box-shadow: none !important } -:focus { +:focus-visible { outline: auto 1px -webkit-focus-ring-color } -html:focus, body:focus { +html:focus-visible, body:focus-visible { outline: none } -embed:focus, iframe:focus, object:focus { +embed:focus-visible, iframe:focus-visible, object:focus-visible { outline: none } -input:focus, textarea:focus, select:focus { +input:focus-visible, textarea:focus-visible, select:focus-visible { outline-offset: -2px } -input[type="button" i]:focus, -input[type="checkbox" i]:focus, -input[type="file" i]:focus, -input[type="hidden" i]:focus, -input[type="image" i]:focus, -input[type="radio" i]:focus, -input[type="reset" i]:focus, -input[type="submit" i]:focus, -input[type="file" i]:focus::-webkit-file-upload-button { +input[type="button" i]:focus-visible, +input[type="checkbox" i]:focus-visible, +input[type="file" i]:focus-visible, +input[type="hidden" i]:focus-visible, +input[type="image" i]:focus-visible, +input[type="radio" i]:focus-visible, +input[type="reset" i]:focus-visible, +input[type="submit" i]:focus-visible, +input[type="file" i]:focus-visible::-webkit-file-upload-button { outline-offset: 0 } @@ -1204,6 +1243,26 @@ dialog::backdrop { background: rgba(0,0,0,0.1) } +popup:not(:-internal-popup-open) { + display: none !important; +} +popup { + display: block; + position: fixed; + top: 0; + left: 0; + /* The rest here is copied from dialog, perhaps these shouldn't + apply to popup. At least the background color is nice, because + it obscures the backdrop. And the foreground color/border + help to set off the popup from the rest of the page. */ + width: fit-content; + height: fit-content; + border: 1px solid; + padding: 1em; + background: -internal-light-dark(white, black); + color: -internal-light-dark(black, white); +} + slot { display: contents; } diff --git a/chromium/third_party/blink/renderer/core/html/resources/images/time_icon.svg b/chromium/third_party/blink/renderer/core/html/resources/images/time_icon.svg index 71a94c0ba2c..d9c2206df46 100644 --- a/chromium/third_party/blink/renderer/core/html/resources/images/time_icon.svg +++ b/chromium/third_party/blink/renderer/core/html/resources/images/time_icon.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24"><path fill="WindowText" d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"/><path d="M0 0h24v24H0z" fill="none"/><path d="M12.5 7H11v6l5.25 3.15.75-1.23-4.5-2.67z"/></svg>
\ No newline at end of file +<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24"><path fill="WindowText" d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"/><path d="M0 0h24v24H0z" fill="none"/><path fill="WindowText" d="M12.5 7H11v6l5.25 3.15.75-1.23-4.5-2.67z"/></svg>
\ No newline at end of file diff --git a/chromium/third_party/blink/renderer/core/html/resources/input_multiple_fields.css b/chromium/third_party/blink/renderer/core/html/resources/input_multiple_fields.css index d0591f61232..a42f7837204 100644 --- a/chromium/third_party/blink/renderer/core/html/resources/input_multiple_fields.css +++ b/chromium/third_party/blink/renderer/core/html/resources/input_multiple_fields.css @@ -56,7 +56,7 @@ input::-webkit-datetime-edit-year-field { padding: 1px; } -/* Remove focus ring from fields and use highlight color */ +/* Use highlight color. */ input::-webkit-datetime-edit-ampm-field:focus, input::-webkit-datetime-edit-day-field:focus, input::-webkit-datetime-edit-hour-field:focus, @@ -68,7 +68,6 @@ input::-webkit-datetime-edit-week-field:focus, input::-webkit-datetime-edit-year-field:focus { background-color: highlight; color: highlighttext; - outline: none; } input::-webkit-datetime-edit-year-field[disabled], diff --git a/chromium/third_party/blink/renderer/core/html/resources/mac.css b/chromium/third_party/blink/renderer/core/html/resources/mac.css index 1e1677ba858..bcf5cfa0ea1 100644 --- a/chromium/third_party/blink/renderer/core/html/resources/mac.css +++ b/chromium/third_party/blink/renderer/core/html/resources/mac.css @@ -42,6 +42,6 @@ button { box-shadow: none !important } -:focus { +:focus-visible { outline: auto 5px -webkit-focus-ring-color } diff --git a/chromium/third_party/blink/renderer/core/html/shadow/progress_shadow_element.cc b/chromium/third_party/blink/renderer/core/html/shadow/progress_shadow_element.cc index f1cea3811d9..7cd7a66e29c 100644 --- a/chromium/third_party/blink/renderer/core/html/shadow/progress_shadow_element.cc +++ b/chromium/third_party/blink/renderer/core/html/shadow/progress_shadow_element.cc @@ -44,9 +44,10 @@ HTMLProgressElement* ProgressShadowElement::ProgressElement() const { return To<HTMLProgressElement>(OwnerShadowHost()); } -scoped_refptr<ComputedStyle> -ProgressShadowElement::CustomStyleForLayoutObject() { - scoped_refptr<ComputedStyle> style = OriginalStyleForLayoutObject(); +scoped_refptr<ComputedStyle> ProgressShadowElement::CustomStyleForLayoutObject( + const StyleRecalcContext& style_recalc_context) { + scoped_refptr<ComputedStyle> style = + OriginalStyleForLayoutObject(style_recalc_context); const ComputedStyle* progress_style = ProgressElement()->GetComputedStyle(); DCHECK(progress_style); if (progress_style->HasEffectiveAppearance()) diff --git a/chromium/third_party/blink/renderer/core/html/shadow/progress_shadow_element.h b/chromium/third_party/blink/renderer/core/html/shadow/progress_shadow_element.h index aab050ec608..3f5c1f9a234 100644 --- a/chromium/third_party/blink/renderer/core/html/shadow/progress_shadow_element.h +++ b/chromium/third_party/blink/renderer/core/html/shadow/progress_shadow_element.h @@ -45,7 +45,8 @@ class ProgressShadowElement : public HTMLDivElement { private: HTMLProgressElement* ProgressElement() const; - scoped_refptr<ComputedStyle> CustomStyleForLayoutObject() override; + scoped_refptr<ComputedStyle> CustomStyleForLayoutObject( + const StyleRecalcContext&) override; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/shadow/progress_shadow_element_test.cc b/chromium/third_party/blink/renderer/core/html/shadow/progress_shadow_element_test.cc index a9e1e36542b..4e8c0ec11f5 100644 --- a/chromium/third_party/blink/renderer/core/html/shadow/progress_shadow_element_test.cc +++ b/chromium/third_party/blink/renderer/core/html/shadow/progress_shadow_element_test.cc @@ -44,7 +44,8 @@ TEST_F(ProgressShadowElementTest, LayoutObjectIsNeeded) { GetDocument().GetStyleEngine().RecalcStyle(); EXPECT_TRUE(shadow_element->GetComputedStyle()); - scoped_refptr<ComputedStyle> style = shadow_element->StyleForLayoutObject(); + scoped_refptr<ComputedStyle> style = + shadow_element->StyleForLayoutObject(StyleRecalcContext()); EXPECT_TRUE(shadow_element->LayoutObjectIsNeeded(*style)); } diff --git a/chromium/third_party/blink/renderer/core/html/shadow/shadow_element_names.json5 b/chromium/third_party/blink/renderer/core/html/shadow/shadow_element_names.json5 index e97b4ca6d03..daebf310885 100644 --- a/chromium/third_party/blink/renderer/core/html/shadow/shadow_element_names.json5 +++ b/chromium/third_party/blink/renderer/core/html/shadow/shadow_element_names.json5 @@ -53,7 +53,7 @@ Symbol: "kIdSearchClearButton", }, { - name: "passwrod-reveal", + name: "password-reveal", Symbol: "kIdPasswordRevealButton", }, { @@ -90,6 +90,10 @@ Symbol: "kPseudoInputPlaceholder", }, { + name: "-webkit-file-upload-button", + Symbol: "kPseudoFileUploadButton", + }, + { name: "-internal-input-suggested", Symbol: "kPseudoInternalInputSuggested", }, diff --git a/chromium/third_party/blink/renderer/core/html/shadow/shadow_element_utils.cc b/chromium/third_party/blink/renderer/core/html/shadow/shadow_element_utils.cc index 27b11ad59f8..805cadfa6f0 100644 --- a/chromium/third_party/blink/renderer/core/html/shadow/shadow_element_utils.cc +++ b/chromium/third_party/blink/renderer/core/html/shadow/shadow_element_utils.cc @@ -28,6 +28,16 @@ bool IsSliderThumb(const Node* node) { shadow_pseudo == shadow_element_names::kPseudoSliderThumb; } +bool IsTextControlContainer(const Node* node) { + const auto* element = DynamicTo<Element>(node); + if (!element || !element->IsInUserAgentShadowRoot()) + return false; + if (!IsTextControl(element->OwnerShadowHost())) + return false; + return element->GetIdAttribute() == + shadow_element_names::kIdTextFieldContainer; +} + bool IsTextControlPlaceholder(const Node* node) { const auto* element = DynamicTo<Element>(node); if (!element || !element->IsInUserAgentShadowRoot()) diff --git a/chromium/third_party/blink/renderer/core/html/shadow/shadow_element_utils.h b/chromium/third_party/blink/renderer/core/html/shadow/shadow_element_utils.h index 8be28138276..44d9635df2b 100644 --- a/chromium/third_party/blink/renderer/core/html/shadow/shadow_element_utils.h +++ b/chromium/third_party/blink/renderer/core/html/shadow/shadow_element_utils.h @@ -12,6 +12,7 @@ class Node; bool IsSliderContainer(const Element& elmenet); bool IsSliderThumb(const Node* node); +bool IsTextControlContainer(const Node* node); bool IsTextControlPlaceholder(const Node* node); } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/subresource_redirect_test.cc b/chromium/third_party/blink/renderer/core/html/subresource_redirect_test.cc index 8be019cdb05..8fa652c3c01 100644 --- a/chromium/third_party/blink/renderer/core/html/subresource_redirect_test.cc +++ b/chromium/third_party/blink/renderer/core/html/subresource_redirect_test.cc @@ -4,11 +4,13 @@ #include <tuple> +#include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/frame/web_local_frame_impl.h" +#include "third_party/blink/renderer/core/loader/subresource_redirect_util.h" #include "third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h" #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/core/style/style_image.h" @@ -57,17 +59,52 @@ class SubresourceRedirectSimTest GetDocument().UpdateStyleAndLayoutTree(); } + // Loads the main page resource and then loads the given image in the page. + void LoadMainResourceAndImage(const String& html_body, + const String& img_url) { + SimRequest image_resource(img_url, "image/png"); + LoadMainResource(html_body); + + if (!is_lazyload_image_enabled()) + image_resource.Complete(ReadTestImage()); + + Compositor().BeginFrame(); + test::RunPendingTasks(); + + if (is_lazyload_image_enabled()) { + // Scroll down until the image is visible. + GetDocument().View()->LayoutViewport()->SetScrollOffset( + ScrollOffset(0, 10000), mojom::blink::ScrollType::kProgrammatic); + Compositor().BeginFrame(); + test::RunPendingTasks(); + image_resource.Complete(ReadTestImage()); + } + } + + // Verifies previews state for the fetched request URL. + void VerifySubresourceRedirectPreviewsState( + const String& url, + bool is_subresource_redirect_allowed) { + PreviewsState previews_state = GetDocument() + .Fetcher() + ->CachedResource(KURL(url)) + ->GetResourceRequest() + .GetPreviewsState(); + EXPECT_EQ(is_subresource_redirect_allowed, + (previews_state & PreviewsTypes::kSubresourceRedirectOn) != 0); + } + ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test_; ScopedAutomaticLazyImageLoadingForTest scoped_automatic_lazy_image_loading_for_test_; base::test::ScopedFeatureList scoped_feature_list_; + base::HistogramTester histogram_tester_; }; // This test verifies subresource redirect previews state based on different // states of SaveData, LazyLoad, SubresourceRedirect features. TEST_P(SubresourceRedirectSimTest, CSSBackgroundImage) { - SimRequest image_resource("https://example.com/img.png", "image/png"); - LoadMainResource(R"HTML( + LoadMainResourceAndImage(R"HTML( <style> #deferred_image { height:200px; @@ -76,33 +113,159 @@ TEST_P(SubresourceRedirectSimTest, CSSBackgroundImage) { </style> <div style='height:10000px;'></div> <div id="deferred_image"></div> - )HTML"); + )HTML", + "https://example.com/img.png"); - if (!is_lazyload_image_enabled()) - image_resource.Complete(ReadTestImage()); - - Compositor().BeginFrame(); - test::RunPendingTasks(); + // Subresource redirect previews bit should be set only if SaveData and + // SubresourceRedirect feature are enabled. + VerifySubresourceRedirectPreviewsState( + "https://example.com/img.png", + is_save_data_enabled() && is_subresource_redirect_enabled()); +} - if (is_lazyload_image_enabled()) { - // Scroll down until the background image is visible. - GetDocument().View()->LayoutViewport()->SetScrollOffset( - ScrollOffset(0, 10000), mojom::blink::ScrollType::kProgrammatic); - Compositor().BeginFrame(); - test::RunPendingTasks(); - image_resource.Complete(ReadTestImage()); - } +TEST_P(SubresourceRedirectSimTest, ImgElement) { + LoadMainResourceAndImage(R"HTML( + <body> + <img src='https://example.com/img.png' loading='lazy'/> + </body> + )HTML", + "https://example.com/img.png"); - PreviewsState previews_state = - GetDocument() - .Fetcher() - ->CachedResource(KURL("https://example.com/img.png")) - ->GetResourceRequest() - .GetPreviewsState(); // Subresource redirect previews bit should be set only if SaveData and // SubresourceRedirect feature are enabled. - EXPECT_EQ(is_save_data_enabled() && is_subresource_redirect_enabled(), - (previews_state & PreviewsTypes::kSubresourceRedirectOn) != 0); + VerifySubresourceRedirectPreviewsState( + "https://example.com/img.png", + is_save_data_enabled() && is_subresource_redirect_enabled()); + + histogram_tester_.ExpectTotalCount("SubresourceRedirect.Blink.Ineligibility", + 0); +} + +TEST_P(SubresourceRedirectSimTest, JavascriptCreatedSameOriginImage) { + LoadMainResourceAndImage(R"HTML( + <body> + <div></div> + <script> + var img = document.createElement("img"); + img.loading = 'lazy'; + img.src = 'https://example.com/img.png'; + document.getElementsByTagName('div')[0].appendChild(img); + </script> + </body> + )HTML", + "https://example.com/img.png"); + + VerifySubresourceRedirectPreviewsState("https://example.com/img.png", false); + + if (is_save_data_enabled() && is_subresource_redirect_enabled()) { + histogram_tester_.ExpectUniqueSample( + "SubresourceRedirect.Blink.Ineligibility", + BlinkSubresourceRedirectIneligibility::kJavascriptCreatedSameOrigin, + is_lazyload_image_enabled() ? 2 : 1); + } else { + histogram_tester_.ExpectTotalCount( + "SubresourceRedirect.Blink.Ineligibility", 0); + } +} + +TEST_P(SubresourceRedirectSimTest, JavascriptCreatedCrossOriginImage) { + LoadMainResourceAndImage(R"HTML( + <body> + <div></div> + <script> + var img = document.createElement("img"); + img.loading = 'lazy'; + img.src = 'https://differentorigin.com/img.png'; + document.getElementsByTagName('div')[0].appendChild(img); + </script> + </body> + )HTML", + "https://differentorigin.com/img.png"); + + VerifySubresourceRedirectPreviewsState("https://differentorigin.com/img.png", + false); + + if (is_save_data_enabled() && is_subresource_redirect_enabled()) { + histogram_tester_.ExpectUniqueSample( + "SubresourceRedirect.Blink.Ineligibility", + BlinkSubresourceRedirectIneligibility::kJavascriptCreatedCrossOrigin, + is_lazyload_image_enabled() ? 2 : 1); + } else { + histogram_tester_.ExpectTotalCount( + "SubresourceRedirect.Blink.Ineligibility", 0); + } +} + +TEST_P(SubresourceRedirectSimTest, ImgElementWithCrossOriginAttribute) { + LoadMainResourceAndImage(R"HTML( + <body> + <img src='https://example.com/img.png' loading='lazy' crossorigin='anonymous'/> + </body> + )HTML", + "https://example.com/img.png"); + + VerifySubresourceRedirectPreviewsState("https://example.com/img.png", false); + + if (is_save_data_enabled() && is_subresource_redirect_enabled()) { + histogram_tester_.ExpectUniqueSample( + "SubresourceRedirect.Blink.Ineligibility", + BlinkSubresourceRedirectIneligibility::kCrossOriginAttributeSet, + is_lazyload_image_enabled() ? 2 : 1); + } else { + histogram_tester_.ExpectTotalCount( + "SubresourceRedirect.Blink.Ineligibility", 0); + } +} + +TEST_P(SubresourceRedirectSimTest, + RestrictedByContentSecurityPolicyDefaultSrc) { + LoadMainResourceAndImage(R"HTML( + <head> + <meta http-equiv="Content-Security-Policy" content="default-src 'self'"> + </head> + <body> + <img src='https://example.com/img.png' loading='lazy'/> + </body> + )HTML", + "https://example.com/img.png"); + + VerifySubresourceRedirectPreviewsState("https://example.com/img.png", false); + + if (is_save_data_enabled() && is_subresource_redirect_enabled()) { + histogram_tester_.ExpectUniqueSample( + "SubresourceRedirect.Blink.Ineligibility", + BlinkSubresourceRedirectIneligibility:: + kContentSecurityPolicyDefaultSrcRestricted, + is_lazyload_image_enabled() ? 2 : 1); + } else { + histogram_tester_.ExpectTotalCount( + "SubresourceRedirect.Blink.Ineligibility", 0); + } +} + +TEST_P(SubresourceRedirectSimTest, RestrictedByContentSecurityPolicyImgSrc) { + LoadMainResourceAndImage(R"HTML( + <head> + <meta http-equiv="Content-Security-Policy" content="img-src 'self'"> + </head> + <body> + <img src='https://example.com/img.png' loading='lazy'/> + </body> + )HTML", + "https://example.com/img.png"); + + VerifySubresourceRedirectPreviewsState("https://example.com/img.png", false); + + if (is_save_data_enabled() && is_subresource_redirect_enabled()) { + histogram_tester_.ExpectUniqueSample( + "SubresourceRedirect.Blink.Ineligibility", + BlinkSubresourceRedirectIneligibility:: + kContentSecurityPolicyImgSrcRestricted, + is_lazyload_image_enabled() ? 2 : 1); + } else { + histogram_tester_.ExpectTotalCount( + "SubresourceRedirect.Blink.Ineligibility", 0); + } } INSTANTIATE_TEST_SUITE_P( diff --git a/chromium/third_party/blink/renderer/core/html/track/DIR_METADATA b/chromium/third_party/blink/renderer/core/html/track/DIR_METADATA new file mode 100644 index 00000000000..ea2b83774ac --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/track/DIR_METADATA @@ -0,0 +1,3 @@ +monorail { + component: "Blink>Media>Track" +} diff --git a/chromium/third_party/blink/renderer/core/html/track/OWNERS b/chromium/third_party/blink/renderer/core/html/track/OWNERS index 05096386007..068ec2721b0 100644 --- a/chromium/third_party/blink/renderer/core/html/track/OWNERS +++ b/chromium/third_party/blink/renderer/core/html/track/OWNERS @@ -1,5 +1,3 @@ foolip@chromium.org fs@opera.com srirama.m@samsung.com - -# COMPONENT: Blink>Media>Track diff --git a/chromium/third_party/blink/renderer/core/html/track/cue_timeline.cc b/chromium/third_party/blink/renderer/core/html/track/cue_timeline.cc index a8c2f0b4542..171ad5b8c19 100644 --- a/chromium/third_party/blink/renderer/core/html/track/cue_timeline.cc +++ b/chromium/third_party/blink/renderer/core/html/track/cue_timeline.cc @@ -422,7 +422,7 @@ CueTimeline::IgnoreUpdateScope CueTimeline::BeginIgnoreUpdateScope() { return scope; } -void CueTimeline::EndIgnoreUpdateScope(util::PassKey<IgnoreUpdateScope>, +void CueTimeline::EndIgnoreUpdateScope(base::PassKey<IgnoreUpdateScope>, IgnoreUpdateScope const& scope) { DCHECK(ignore_update_); --ignore_update_; @@ -543,6 +543,8 @@ void CueTimeline::DidMoveToNewDocument(Document& /*old_document*/) { void CueTimeline::Trace(Visitor* visitor) const { visitor->Trace(media_element_); + visitor->Trace(cue_event_timer_); + visitor->Trace(cue_timestamp_event_timer_); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/track/cue_timeline.h b/chromium/third_party/blink/renderer/core/html/track/cue_timeline.h index e84973bc7ca..dad9ce9f138 100644 --- a/chromium/third_party/blink/renderer/core/html/track/cue_timeline.h +++ b/chromium/third_party/blink/renderer/core/html/track/cue_timeline.h @@ -6,7 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_TRACK_CUE_TIMELINE_H_ #include "base/optional.h" -#include "base/util/type_safety/pass_key.h" +#include "base/types/pass_key.h" #include "third_party/blink/renderer/core/html/track/text_track_cue.h" #include "third_party/blink/renderer/core/html/track/vtt/vtt_cue.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -39,7 +39,7 @@ class CueTimeline final : public GarbageCollected<CueTimeline> { public: ~IgnoreUpdateScope() { DCHECK(cue_timeline_); - cue_timeline_->EndIgnoreUpdateScope(util::PassKey<IgnoreUpdateScope>(), + cue_timeline_->EndIgnoreUpdateScope(base::PassKey<IgnoreUpdateScope>(), *this); } @@ -68,7 +68,7 @@ class CueTimeline final : public GarbageCollected<CueTimeline> { bool InsideIgnoreUpdateScope() const { return ignore_update_ > 0; } IgnoreUpdateScope BeginIgnoreUpdateScope(); - void EndIgnoreUpdateScope(util::PassKey<IgnoreUpdateScope>, + void EndIgnoreUpdateScope(base::PassKey<IgnoreUpdateScope>, IgnoreUpdateScope const& scope); void DidMoveToNewDocument(Document& old_document); @@ -100,11 +100,11 @@ class CueTimeline final : public GarbageCollected<CueTimeline> { // Timer data for cue events (start, end) base::Optional<double> next_cue_event_; - TaskRunnerTimer<CueTimeline> cue_event_timer_; + HeapTaskRunnerTimer<CueTimeline> cue_event_timer_; // Timer data for cue timestamps // https://w3c.github.io/webvtt/#ref-for-webvtt-timestamp-6 - TaskRunnerTimer<CueTimeline> cue_timestamp_event_timer_; + HeapTaskRunnerTimer<CueTimeline> cue_timestamp_event_timer_; int ignore_update_; bool update_requested_while_ignoring_; 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 248c3ebb6da..0dd80f19dcf 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 @@ -343,6 +343,7 @@ HTMLMediaElement* HTMLTrackElement::MediaElement() const { void HTMLTrackElement::Trace(Visitor* visitor) const { visitor->Trace(track_); visitor->Trace(loader_); + visitor->Trace(load_timer_); HTMLElement::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/track/html_track_element.h b/chromium/third_party/blink/renderer/core/html/track/html_track_element.h index c3f391ae30a..9c207bbb083 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 @@ -42,6 +42,7 @@ class HTMLTrackElement final : public HTMLElement, public: explicit HTMLTrackElement(Document&); + ~HTMLTrackElement() override; const AtomicString& kind(); void setKind(const AtomicString&); @@ -55,8 +56,6 @@ class HTMLTrackElement final : public HTMLElement, void Trace(Visitor*) const override; private: - ~HTMLTrackElement() override; - void ParseAttribute(const AttributeModificationParams&) override; InsertionNotificationRequest InsertedInto(ContainerNode&) override; @@ -83,7 +82,7 @@ class HTMLTrackElement final : public HTMLElement, Member<LoadableTextTrack> track_; Member<TextTrackLoader> loader_; - TaskRunnerTimer<HTMLTrackElement> load_timer_; + HeapTaskRunnerTimer<HTMLTrackElement> load_timer_; KURL url_; }; diff --git a/chromium/third_party/blink/renderer/core/html/track/track_base.h b/chromium/third_party/blink/renderer/core/html/track/track_base.h index 055fe6e79db..70e673ed75f 100644 --- a/chromium/third_party/blink/renderer/core/html/track/track_base.h +++ b/chromium/third_party/blink/renderer/core/html/track/track_base.h @@ -70,10 +70,6 @@ class CORE_EXPORT TrackBase : public Supplementable<TrackBase> { Member<HTMLMediaElement> media_element_; }; -#define DEFINE_TRACK_TYPE_CASTS(thisType, predicate) \ - DEFINE_TYPE_CASTS(thisType, TrackBase, track, track->GetType() == predicate, \ - track.GetType() == predicate) - } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_TRACK_TRACK_BASE_H_ diff --git a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_parser.cc b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_parser.cc index 727caa18bac..351917da340 100644 --- a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_parser.cc +++ b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_parser.cc @@ -244,9 +244,8 @@ VTTParser::ParseState VTTParser::CollectRegionSettings(const String& line) { VTTParser::ParseState VTTParser::CollectStyleSheet(const String& line) { if (line.IsEmpty() || line.Contains("-->")) { auto* parser_context = MakeGarbageCollected<CSSParserContext>( - *document_, NullURL(), true /* origin_clean */, - document_->GetReferrerPolicy(), UTF8Encoding(), - CSSParserContext::kLiveProfile, + *document_, NullURL(), true /* origin_clean */, Referrer(), + UTF8Encoding(), CSSParserContext::kLiveProfile, ResourceFetchRestriction::kOnlyDataUrls); auto* style_sheet_contents = MakeGarbageCollected<StyleSheetContents>(parser_context); diff --git a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.cc b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.cc index d551daa9dea..8ff5c053965 100644 --- a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.cc +++ b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.cc @@ -422,6 +422,7 @@ void VTTRegion::ScrollTimerFired(TimerBase*) { void VTTRegion::Trace(Visitor* visitor) const { visitor->Trace(cue_container_); visitor->Trace(region_display_tree_); + visitor->Trace(scroll_timer_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.h b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.h index 87dadf7ad56..04a0ea0e3f9 100644 --- a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.h +++ b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.h @@ -132,7 +132,7 @@ class VTTRegion final : public ScriptWrappable { // soon as the animation for rolling out one line has finished, but // currently it is used also for non-scrolling regions to use a single // code path. - TaskRunnerTimer<VTTRegion> scroll_timer_; + HeapTaskRunnerTimer<VTTRegion> scroll_timer_; }; } // namespace blink |