diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/core/html')
390 files changed, 3571 insertions, 2017 deletions
diff --git a/chromium/third_party/blink/renderer/core/html/BUILD.gn b/chromium/third_party/blink/renderer/core/html/BUILD.gn index 76cfc6e1dd6..a02c6372002 100644 --- a/chromium/third_party/blink/renderer/core/html/BUILD.gn +++ b/chromium/third_party/blink/renderer/core/html/BUILD.gn @@ -32,6 +32,7 @@ blink_core_sources("html") { "canvas/image_element_base.h", "canvas/text_metrics.cc", "canvas/text_metrics.h", + "canvas/ukm_parameters.h", "collection_items_cache.h", "collection_type.h", "cross_origin_attribute.cc", @@ -464,6 +465,8 @@ blink_core_sources("html") { "link_resource.h", "link_style.cc", "link_style.h", + "link_web_bundle.cc", + "link_web_bundle.h", "list_item_ordinal.cc", "list_item_ordinal.h", "loading_attribute.cc", @@ -670,6 +673,7 @@ blink_core_tests("unit_tests") { "lazy_load_image_observer_test.cc", "link_element_loading_test.cc", "link_rel_attribute_test.cc", + "link_web_bundle_test.cc", "media/autoplay_uma_helper_test.cc", "media/html_media_element_event_listeners_test.cc", "media/html_media_element_test.cc", @@ -695,6 +699,7 @@ blink_core_tests("unit_tests") { "parser/html_tokenizer_test.cc", "parser/html_tree_builder_simulator_test.cc", "parser/html_view_source_parser_test.cc", + "parser/text_resource_decoder_builder_test.cc", "parser/text_resource_decoder_test.cc", "portal/html_portal_element_test.cc", "shadow/progress_shadow_element_test.cc", diff --git a/chromium/third_party/blink/renderer/core/html/anchor_element_metrics_sender.cc b/chromium/third_party/blink/renderer/core/html/anchor_element_metrics_sender.cc index 6b73d04db1c..2f0b8b68de7 100644 --- a/chromium/third_party/blink/renderer/core/html/anchor_element_metrics_sender.cc +++ b/chromium/third_party/blink/renderer/core/html/anchor_element_metrics_sender.cc @@ -98,7 +98,7 @@ AnchorElementMetricsSender::GetAnchorElements() const { return anchor_elements_; } -void AnchorElementMetricsSender::Trace(Visitor* visitor) { +void AnchorElementMetricsSender::Trace(Visitor* visitor) const { visitor->Trace(anchor_elements_); visitor->Trace(metrics_host_); Supplement<Document>::Trace(visitor); @@ -113,7 +113,7 @@ bool AnchorElementMetricsSender::AssociateInterface() { if (!document->GetFrame()) return false; - document->GetBrowserInterfaceBroker().GetInterface( + document->GetFrame()->GetBrowserInterfaceBroker().GetInterface( metrics_host_.BindNewPipeAndPassReceiver( document->GetExecutionContext()->GetTaskRunner( TaskType::kInternalDefault))); diff --git a/chromium/third_party/blink/renderer/core/html/anchor_element_metrics_sender.h b/chromium/third_party/blink/renderer/core/html/anchor_element_metrics_sender.h index d421c1ba7c5..4b8dde7475c 100644 --- a/chromium/third_party/blink/renderer/core/html/anchor_element_metrics_sender.h +++ b/chromium/third_party/blink/renderer/core/html/anchor_element_metrics_sender.h @@ -63,7 +63,7 @@ class CORE_EXPORT AnchorElementMetricsSender final // Returns the stored |anchor_elements_|. const HeapHashSet<Member<HTMLAnchorElement>>& GetAnchorElements() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // Associates |metrics_host_| with the IPC interface if not already, so it can diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.cc b/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.cc index fbe1cc5eb3e..44dc498b064 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.cc +++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.cc @@ -8,6 +8,9 @@ #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "build/build_config.h" +#include "third_party/blink/public/common/privacy_budget/identifiability_metric_builder.h" +#include "third_party/blink/public/common/privacy_budget/identifiability_metrics.h" +#include "third_party/blink/public/common/privacy_budget/identifiability_study_participation.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/core/dom/document.h" @@ -146,6 +149,7 @@ CanvasAsyncBlobCreator::CanvasAsyncBlobCreator( ToBlobFunctionType function_type, base::TimeTicks start_time, ExecutionContext* context, + base::Optional<UkmParameters> ukm_params, ScriptPromiseResolver* resolver) : CanvasAsyncBlobCreator(image, options, @@ -153,6 +157,7 @@ CanvasAsyncBlobCreator::CanvasAsyncBlobCreator( nullptr, start_time, context, + ukm_params, resolver) {} CanvasAsyncBlobCreator::CanvasAsyncBlobCreator( @@ -162,6 +167,7 @@ CanvasAsyncBlobCreator::CanvasAsyncBlobCreator( V8BlobCallback* callback, base::TimeTicks start_time, ExecutionContext* context, + base::Optional<UkmParameters> ukm_params, ScriptPromiseResolver* resolver) : fail_encoder_initialization_for_test_(false), enforce_idle_encoding_for_test_(false), @@ -174,6 +180,7 @@ CanvasAsyncBlobCreator::CanvasAsyncBlobCreator( callback_(callback), script_promise_resolver_(resolver) { DCHECK(image); + DCHECK(context); mime_type_ = ImageEncoderUtils::ToEncodingMimeType( encode_options_->type(), @@ -467,6 +474,8 @@ void CanvasAsyncBlobCreator::CreateBlobAndReturnResult() { WrapPersistent(result_blob))); } + RecordIdentifiabilityMetric(); + RecordScaledDurationHistogram(mime_type_, base::TimeTicks::Now() - start_time_, image_->width(), image_->height()); @@ -474,6 +483,36 @@ void CanvasAsyncBlobCreator::CreateBlobAndReturnResult() { Dispose(); } +void CanvasAsyncBlobCreator::RecordIdentifiabilityMetric() { + if (!ukm_params_.has_value() || !IsUserInIdentifiabilityStudy()) + return; + // Creating this ImageDataBuffer has some overhead, namely getting the SkImage + // and computing the pixmap. + // We need the StaticBitmapImage to be deleted on the same thread on which it + // was created, so we use the same TaskType here in order to get the same + // TaskRunner. + context_->GetTaskRunner(TaskType::kCanvasBlobSerialization) + ->PostTask( + FROM_HERE, + WTF::Bind( + [](scoped_refptr<StaticBitmapImage> image, + UkmParameters ukm_params) { + std::unique_ptr<ImageDataBuffer> data_buffer = + ImageDataBuffer::Create(image); + if (!data_buffer) + return; + blink::IdentifiabilityMetricBuilder(ukm_params.source_id) + .Set(blink::IdentifiableSurface::FromTypeAndInput( + blink::IdentifiableSurface::Type::kCanvasReadback, + 0), + blink::IdentifiabilityDigestOfBytes( + base::make_span(data_buffer->Pixels(), + data_buffer->ComputeByteSize()))) + .Record(ukm_params.ukm_recorder); + }, + image_, ukm_params_.value())); +} + void CanvasAsyncBlobCreator::CreateNullAndReturnResult() { RecordIdleTaskStatusHistogram(idle_task_status_); if (function_type_ == kHTMLCanvasToBlobCallback) { @@ -604,7 +643,7 @@ void CanvasAsyncBlobCreator::PostDelayedTaskToCurrentThread( base::TimeDelta::FromMillisecondsD(delay_ms)); } -void CanvasAsyncBlobCreator::Trace(Visitor* visitor) { +void CanvasAsyncBlobCreator::Trace(Visitor* visitor) const { visitor->Trace(context_); visitor->Trace(encode_options_); visitor->Trace(callback_); @@ -615,7 +654,7 @@ sk_sp<SkColorSpace> CanvasAsyncBlobCreator::BlobColorSpaceToSkColorSpace( String blob_color_space) { skcms_Matrix3x3 gamut = SkNamedGamut::kSRGB; if (blob_color_space == kDisplayP3ImageColorSpaceName) - gamut = SkNamedGamut::kDCIP3; + gamut = SkNamedGamut::kDisplayP3; else if (blob_color_space == kRec2020ImageColorSpaceName) gamut = SkNamedGamut::kRec2020; return SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, gamut); diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.h b/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.h index 9a2c289975a..1a97de918e0 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.h +++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator.h @@ -8,11 +8,14 @@ #include <memory> #include "base/location.h" +#include "base/optional.h" #include "base/single_thread_task_runner.h" +#include "services/metrics/public/cpp/ukm_recorder.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/bindings/core/v8/v8_blob_callback.h" #include "third_party/blink/renderer/bindings/core/v8/v8_image_encode_options.h" #include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/html/canvas/ukm_parameters.h" #include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h" #include "third_party/blink/renderer/platform/geometry/int_size.h" #include "third_party/blink/renderer/platform/graphics/graphics_types.h" @@ -60,6 +63,7 @@ class CORE_EXPORT CanvasAsyncBlobCreator ToBlobFunctionType function_type, base::TimeTicks start_time, ExecutionContext*, + base::Optional<UkmParameters> ukm_params, ScriptPromiseResolver*); CanvasAsyncBlobCreator(scoped_refptr<StaticBitmapImage>, const ImageEncodeOptions*, @@ -67,6 +71,7 @@ class CORE_EXPORT CanvasAsyncBlobCreator V8BlobCallback*, base::TimeTicks start_time, ExecutionContext*, + base::Optional<UkmParameters> ukm_params, ScriptPromiseResolver* = nullptr); virtual ~CanvasAsyncBlobCreator(); @@ -74,7 +79,7 @@ class CORE_EXPORT CanvasAsyncBlobCreator virtual void SignalTaskSwitchInStartTimeoutEventForTesting() {} virtual void SignalTaskSwitchInCompleteTimeoutEventForTesting() {} - virtual void Trace(Visitor*); + virtual void Trace(Visitor*) const; static sk_sp<SkColorSpace> BlobColorSpaceToSkColorSpace( String blob_color_space); @@ -132,6 +137,8 @@ class CORE_EXPORT CanvasAsyncBlobCreator // Used for HTMLCanvasElement only Member<V8BlobCallback> callback_; + base::Optional<UkmParameters> ukm_params_; + // Used for OffscreenCanvas only Member<ScriptPromiseResolver> script_promise_resolver_; @@ -147,6 +154,8 @@ class CORE_EXPORT CanvasAsyncBlobCreator void IdleTaskStartTimeoutEvent(double quality); void IdleTaskCompleteTimeoutEvent(); + + void RecordIdentifiabilityMetric(); }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator_test.cc b/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator_test.cc index 32388eb43c1..c68359ce45b 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator_test.cc +++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_async_blob_creator_test.cc @@ -35,6 +35,7 @@ class MockCanvasAsyncBlobCreator : public CanvasAsyncBlobCreator { nullptr, base::TimeTicks(), document->GetExecutionContext(), + base::make_optional<UkmParameters>(), nullptr) { if (fail_encoder_initialization) fail_encoder_initialization_for_test_ = true; @@ -129,7 +130,6 @@ class CanvasAsyncBlobCreatorTest : public PageTestBase { void TearDown() override; private: - Persistent<MockCanvasAsyncBlobCreator> async_blob_creator_; }; @@ -248,7 +248,8 @@ TEST_F(CanvasAsyncBlobCreatorTest, ColorManagedConvertToBlob) { color_space_params.push_back(std::pair<sk_sp<SkColorSpace>, SkColorType>( SkColorSpace::MakeSRGBLinear(), kRGBA_F16_SkColorType)); color_space_params.push_back(std::pair<sk_sp<SkColorSpace>, SkColorType>( - SkColorSpace::MakeRGB(SkNamedTransferFn::kLinear, SkNamedGamut::kDCIP3), + SkColorSpace::MakeRGB(SkNamedTransferFn::kLinear, + SkNamedGamut::kDisplayP3), kRGBA_F16_SkColorType)); color_space_params.push_back(std::pair<sk_sp<SkColorSpace>, SkColorType>( SkColorSpace::MakeRGB(SkNamedTransferFn::kLinear, SkNamedGamut::kRec2020), @@ -263,7 +264,8 @@ TEST_F(CanvasAsyncBlobCreatorTest, ColorManagedConvertToBlob) { kDisplayP3ImageColorSpaceName, kRec2020ImageColorSpaceName}; std::list<String> blob_pixel_formats = { - kRGBA8ImagePixelFormatName, kRGBA16ImagePixelFormatName, + kRGBA8ImagePixelFormatName, + kRGBA16ImagePixelFormatName, }; // Maximum differences are both observed locally with @@ -294,7 +296,8 @@ TEST_F(CanvasAsyncBlobCreatorTest, ColorManagedConvertToBlob) { source_bitmap_image, options, CanvasAsyncBlobCreator::ToBlobFunctionType:: kHTMLCanvasConvertToBlobPromise, - base::TimeTicks(), GetFrame().DomWindow(), nullptr); + base::TimeTicks(), GetFrame().DomWindow(), + base::make_optional<UkmParameters>(), nullptr); ASSERT_TRUE(async_blob_creator->EncodeImageForConvertToBlobTest()); sk_sp<SkData> sk_data = SkData::MakeWithCopy( @@ -325,4 +328,4 @@ TEST_F(CanvasAsyncBlobCreatorTest, ColorManagedConvertToBlob) { } } } -} +} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h b/chromium/third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h index 774eb849294..946dd195908 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h +++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_context_creation_attributes_core.h @@ -32,6 +32,8 @@ class CORE_EXPORT CanvasContextCreationAttributesCore { bool preserve_drawing_buffer = false; String power_preference = "default"; bool stencil = false; + // Help to determine whether to use GPU or CPU for the canvas. + bool will_read_frequently = false; bool xr_compatible = false; }; diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache.cc b/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache.cc index c86e35e067b..f24674961d0 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache.cc +++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache.cc @@ -153,7 +153,7 @@ void CanvasFontCache::PruneAll() { fonts_resolved_using_default_style_.clear(); } -void CanvasFontCache::Trace(Visitor* visitor) { +void CanvasFontCache::Trace(Visitor* visitor) const { visitor->Trace(fetched_fonts_); visitor->Trace(document_); } diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache.h b/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache.h index 2fd9b9fa15a..9e6b4a82d0f 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache.h +++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache.h @@ -34,7 +34,7 @@ class CORE_EXPORT CanvasFontCache final void PruneAll(); unsigned size(); - virtual void Trace(Visitor*); + virtual void Trace(Visitor*) const; static unsigned MaxFonts(); unsigned HardMaxFonts(); diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache_test.cc b/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache_test.cc index 9a34c10bdfe..c41cbb8ec3f 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache_test.cc +++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_font_cache_test.cc @@ -36,7 +36,7 @@ CanvasRenderingContext* CanvasFontCacheTest::Context2D() const { // If the following check fails, perhaps you forgot to call createContext // in your test? EXPECT_NE(nullptr, CanvasElement().RenderingContext()); - EXPECT_TRUE(CanvasElement().RenderingContext()->Is2d()); + EXPECT_TRUE(CanvasElement().RenderingContext()->IsRenderingContext2D()); return CanvasElement().RenderingContext(); } diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_image_source.h b/chromium/third_party/blink/renderer/core/html/canvas/canvas_image_source.h index 8e8782b0461..b1954a1880b 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_image_source.h +++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_image_source.h @@ -50,7 +50,6 @@ enum SourceImageStatus { class CORE_EXPORT CanvasImageSource { public: virtual scoped_refptr<Image> GetSourceImageForCanvas(SourceImageStatus*, - AccelerationHint, const FloatSize&) = 0; // IMPORTANT: Result must be independent of whether destinationContext is diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc b/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc index 2793b17d823..50af5f3158d 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc +++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.cc @@ -43,20 +43,13 @@ CanvasRenderingContext::CanvasRenderingContext( CanvasColorParams::GetNativeCanvasPixelFormat(), kNonOpaque), creation_attributes_(attrs) { - // Supported color spaces and pixel formats: sRGB in uint8, e-sRGB in f16, - // linear sRGB and p3 and rec2020 with linear gamma transfer function in f16. - // For wide gamut color spaces, user must explicitly request half float - // storage. Otherwise, we fall back to sRGB in uint8. Invalid requests fall - // back to sRGB in uint8 too. - if (creation_attributes_.pixel_format == kF16CanvasPixelFormatName) { + if (creation_attributes_.pixel_format == kF16CanvasPixelFormatName) color_params_.SetCanvasPixelFormat(CanvasPixelFormat::kF16); - if (creation_attributes_.color_space == kLinearRGBCanvasColorSpaceName) - color_params_.SetCanvasColorSpace(CanvasColorSpace::kLinearRGB); - if (creation_attributes_.color_space == kRec2020CanvasColorSpaceName) - color_params_.SetCanvasColorSpace(CanvasColorSpace::kRec2020); - else if (creation_attributes_.color_space == kP3CanvasColorSpaceName) - color_params_.SetCanvasColorSpace(CanvasColorSpace::kP3); - } + + if (creation_attributes_.color_space == kRec2020CanvasColorSpaceName) + color_params_.SetCanvasColorSpace(CanvasColorSpace::kRec2020); + else if (creation_attributes_.color_space == kP3CanvasColorSpaceName) + color_params_.SetCanvasColorSpace(CanvasColorSpace::kP3); if (!creation_attributes_.alpha) color_params_.SetOpacityMode(kOpaque); @@ -71,8 +64,6 @@ WTF::String CanvasRenderingContext::ColorSpaceAsString() const { switch (color_params_.ColorSpace()) { case CanvasColorSpace::kSRGB: return kSRGBCanvasColorSpaceName; - case CanvasColorSpace::kLinearRGB: - return kLinearRGBCanvasColorSpaceName; case CanvasColorSpace::kRec2020: return kRec2020CanvasColorSpaceName; case CanvasColorSpace::kP3: @@ -177,7 +168,7 @@ bool CanvasRenderingContext::WouldTaintOrigin(CanvasImageSource* image_source) { return image_source->WouldTaintOrigin(); } -void CanvasRenderingContext::Trace(Visitor* visitor) { +void CanvasRenderingContext::Trace(Visitor* visitor) const { visitor->Trace(host_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h b/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h index e14dd738e8c..dc2b3ba2bbf 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h +++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context.h @@ -46,7 +46,6 @@ class HTMLCanvasElement; class ImageBitmap; constexpr const char* kSRGBCanvasColorSpaceName = "srgb"; -constexpr const char* kLinearRGBCanvasColorSpaceName = "linear-rgb"; constexpr const char* kRec2020CanvasColorSpaceName = "rec2020"; constexpr const char* kP3CanvasColorSpaceName = "p3"; @@ -88,7 +87,7 @@ class CORE_EXPORT CanvasRenderingContext : public ScriptWrappable, const CanvasColorParams& ColorParams() const { return color_params_; } - virtual scoped_refptr<StaticBitmapImage> GetImage(AccelerationHint) = 0; + virtual scoped_refptr<StaticBitmapImage> GetImage() = 0; virtual ContextType GetContextType() const = 0; virtual bool IsComposited() const = 0; virtual bool IsAccelerated() const = 0; @@ -151,7 +150,7 @@ class CORE_EXPORT CanvasRenderingContext : public ScriptWrappable, void WillProcessTask(const base::PendingTask&, bool) final {} // Canvas2D-specific interface - virtual bool Is2d() const { return false; } + virtual bool IsRenderingContext2D() const { return false; } virtual void RestoreCanvasMatrixClipStack(cc::PaintCanvas*) const {} virtual void Reset() {} virtual void ClearRect(double x, double y, double width, double height) {} @@ -201,9 +200,11 @@ class CORE_EXPORT CanvasRenderingContext : public ScriptWrappable, return creation_attributes_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; virtual void Stop() = 0; + virtual uint64_t IdentifiabilityTextDigest() { return 0; } + protected: CanvasRenderingContext(CanvasRenderingContextHost*, const CanvasContextCreationAttributesCore&); diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc b/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc index 1ef7b373945..466d0eb0199 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc +++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc @@ -22,8 +22,10 @@ namespace blink { -CanvasRenderingContextHost::CanvasRenderingContextHost(HostType host_type) - : host_type_(host_type) {} +CanvasRenderingContextHost::CanvasRenderingContextHost( + HostType host_type, + base::Optional<UkmParameters> ukm_params) + : host_type_(host_type), ukm_params_(ukm_params) {} void CanvasRenderingContextHost::RecordCanvasSizeToUMA(const IntSize& size) { if (did_record_canvas_size_to_uma_) @@ -78,23 +80,23 @@ bool CanvasRenderingContextHost::Is3d() const { return RenderingContext() && RenderingContext()->Is3d(); } -bool CanvasRenderingContextHost::Is2d() const { - return RenderingContext() && RenderingContext()->Is2d(); +bool CanvasRenderingContextHost::IsRenderingContext2D() const { + return RenderingContext() && RenderingContext()->IsRenderingContext2D(); } CanvasResourceProvider* CanvasRenderingContextHost::GetOrCreateCanvasResourceProvider( - AccelerationHint hint) { + RasterModeHint hint) { return GetOrCreateCanvasResourceProviderImpl(hint); } CanvasResourceProvider* CanvasRenderingContextHost::GetOrCreateCanvasResourceProviderImpl( - AccelerationHint hint) { + RasterModeHint hint) { if (!ResourceProvider() && !did_fail_to_create_resource_provider_) { if (IsValidImageSize(Size())) { if (Is3d()) { - CreateCanvasResourceProvider3D(hint); + CreateCanvasResourceProvider3D(); } else { CreateCanvasResourceProvider2D(hint); } @@ -105,56 +107,69 @@ CanvasRenderingContextHost::GetOrCreateCanvasResourceProviderImpl( return ResourceProvider(); } -void CanvasRenderingContextHost::CreateCanvasResourceProvider3D( - AccelerationHint hint) { +void CanvasRenderingContextHost::CreateCanvasResourceProvider3D() { DCHECK(Is3d()); - uint8_t presentation_mode = CanvasResourceProvider::kDefaultPresentationMode; - if (RuntimeEnabledFeatures::WebGLImageChromiumEnabled()) { - presentation_mode |= - CanvasResourceProvider::kAllowImageChromiumPresentationMode; - } - if (RenderingContext() && RenderingContext()->UsingSwapChain()) { - DCHECK(LowLatencyEnabled()); - // Allow swap chain presentation only if 3d context is using a swap - // chain since we'll be importing it as a passthrough texture. - presentation_mode |= - CanvasResourceProvider::kAllowSwapChainPresentationMode; - } - std::unique_ptr<CanvasResourceProvider> provider; base::WeakPtr<CanvasResourceDispatcher> dispatcher = GetOrCreateResourceDispatcher() ? GetOrCreateResourceDispatcher()->GetWeakPtr() : nullptr; - if (SharedGpuContext::IsGpuCompositingEnabled()) { - CanvasResourceProvider::ResourceUsage usage; - if (LowLatencyEnabled() && RenderingContext()) { - // Allow swap chain presentation only if 3d context is using a swap - // chain since we'll be importing it as a passthrough texture. - usage = CanvasResourceProvider::ResourceUsage:: - kAcceleratedDirect3DResourceUsage; - } else { - usage = CanvasResourceProvider::ResourceUsage:: - kAcceleratedCompositedResourceUsage; + + std::unique_ptr<CanvasResourceProvider> provider; + + if (SharedGpuContext::IsGpuCompositingEnabled() && LowLatencyEnabled()) { + // If LowLatency is enabled, we need a resource that is able to perform well + // in such mode. It will first try a PassThrough provider and, if that is + // not possible, it will try a SharedImage with the appropriate flags. + if ((RenderingContext() && RenderingContext()->UsingSwapChain()) || + RuntimeEnabledFeatures::WebGLImageChromiumEnabled()) { + // If either SwapChain is enabled or WebGLImage mode is enabled, we can + // try a passthrough provider. + DCHECK(LowLatencyEnabled()); + provider = CanvasResourceProvider::CreatePassThroughProvider( + Size(), SharedGpuContext::ContextProviderWrapper(), FilterQuality(), + ColorParams(), RenderingContext()->IsOriginTopLeft(), + std::move(dispatcher)); } - provider = CanvasResourceProvider::Create( - Size(), usage, SharedGpuContext::ContextProviderWrapper(), - 0 /* msaa_sample_count */, FilterQuality(), ColorParams(), - presentation_mode, std::move(dispatcher), - RenderingContext()->IsOriginTopLeft()); - } else { - // Here it should try a SoftwareCompositedResourceUsage, but as - // SharedGpuCOntext::IsGpuCompositingEnabled() is false and that being true - // is a requirement to try and create a SharedImageProvider if - // SoftwareCompositeResourceUsage is used, it will go straight ahead to a - // fallback SharedBitmap and then to a Bitmap provider - provider = CanvasResourceProvider::CreateSharedBitmapProvider( - Size(), SharedGpuContext::ContextProviderWrapper(), FilterQuality(), - ColorParams(), std::move(dispatcher)); if (!provider) { - provider = CanvasResourceProvider::CreateBitmapProvider( - Size(), FilterQuality(), ColorParams()); + // If PassThrough failed, try a SharedImage with usage display enabled, + // and if WebGLImageChromium is enabled, add concurrent read write and + // usage scanout (overlay). + uint32_t shared_image_usage_flags = gpu::SHARED_IMAGE_USAGE_DISPLAY; + if (RuntimeEnabledFeatures::WebGLImageChromiumEnabled()) { + shared_image_usage_flags |= gpu::SHARED_IMAGE_USAGE_SCANOUT; + shared_image_usage_flags |= + gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE; + } + provider = CanvasResourceProvider::CreateSharedImageProvider( + Size(), SharedGpuContext::ContextProviderWrapper(), FilterQuality(), + ColorParams(), RenderingContext()->IsOriginTopLeft(), + RasterMode::kGPU, shared_image_usage_flags); } + } else if (SharedGpuContext::IsGpuCompositingEnabled()) { + // If there is no LawLatency mode, and GPU is enabled, will try a GPU + // SharedImage that should support Usage Display and probably Usage Canbout + // if WebGLImageChromium is enabled. + uint32_t shared_image_usage_flags = gpu::SHARED_IMAGE_USAGE_DISPLAY; + if (RuntimeEnabledFeatures::WebGLImageChromiumEnabled()) { + shared_image_usage_flags |= gpu::SHARED_IMAGE_USAGE_SCANOUT; + } + provider = CanvasResourceProvider::CreateSharedImageProvider( + Size(), SharedGpuContext::ContextProviderWrapper(), FilterQuality(), + ColorParams(), RenderingContext()->IsOriginTopLeft(), RasterMode::kGPU, + shared_image_usage_flags); + } + + // If either of the other modes failed and / or it was not possible to do, we + // will backup with a SharedBitmap, and if that was not possible with a Bitmap + // provider. + if (!provider) { + provider = CanvasResourceProvider::CreateSharedBitmapProvider( + Size(), FilterQuality(), ColorParams(), std::move(dispatcher)); + } + if (!provider) { + provider = CanvasResourceProvider::CreateBitmapProvider( + Size(), FilterQuality(), ColorParams()); } ReplaceResourceProvider(std::move(provider)); @@ -167,95 +182,74 @@ void CanvasRenderingContextHost::CreateCanvasResourceProvider3D( } void CanvasRenderingContextHost::CreateCanvasResourceProvider2D( - AccelerationHint hint) { - DCHECK(Is2d()); - const bool want_acceleration = - hint == kPreferAcceleration && ShouldAccelerate2dContext(); - + RasterModeHint hint) { + DCHECK(IsRenderingContext2D()); base::WeakPtr<CanvasResourceDispatcher> dispatcher = GetOrCreateResourceDispatcher() ? GetOrCreateResourceDispatcher()->GetWeakPtr() : nullptr; - uint8_t presentation_mode = CanvasResourceProvider::kDefaultPresentationMode; - bool composited_mode = false; - // Allow GMB image resources if the runtime feature is enabled or if - // we want to use it for low latency mode. - if (RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled() || - (base::FeatureList::IsEnabled( - features::kLowLatencyCanvas2dImageChromium) && - LowLatencyEnabled() && want_acceleration)) { - presentation_mode |= - CanvasResourceProvider::kAllowImageChromiumPresentationMode; - composited_mode = true; - } - if (base::FeatureList::IsEnabled(features::kLowLatencyCanvas2dSwapChain) && - LowLatencyEnabled() && want_acceleration) { - presentation_mode |= - CanvasResourceProvider::kAllowSwapChainPresentationMode; - } - - bool try_swap_chain = false; - - CanvasResourceProvider::ResourceUsage usage; - if (want_acceleration) { - if (LowLatencyEnabled()) { - // Allow swap chains only if the runtime feature is enabled and we're - // in low latency mode too. - usage = CanvasResourceProvider::ResourceUsage:: - kAcceleratedDirect2DResourceUsage; - try_swap_chain = true; - } else { - usage = CanvasResourceProvider::ResourceUsage:: - kAcceleratedCompositedResourceUsage; - } - } else { - usage = - CanvasResourceProvider::ResourceUsage::kSoftwareCompositedResourceUsage; - } std::unique_ptr<CanvasResourceProvider> provider; + const bool use_gpu = + hint == RasterModeHint::kPreferGPU && ShouldAccelerate2dContext(); // It is important to not use the context's IsOriginTopLeft() here // because that denotes the current state and could change after the // new resource provider is created e.g. due to switching between // unaccelerated and accelerated modes during tab switching. - const bool is_origin_top_left = !want_acceleration || LowLatencyEnabled(); - - // First try to be optimized for displaying on screen. In the case we are - // hardware compositing, we also try to enable the usage of the image as - // scanout buffer (overlay) - uint32_t shared_image_usage_flags = gpu::SHARED_IMAGE_USAGE_DISPLAY; - if (composited_mode) - shared_image_usage_flags |= gpu::SHARED_IMAGE_USAGE_SCANOUT; - - if (try_swap_chain) { - // Swap Chain is used for low latency. - provider = CanvasResourceProvider::Create( - Size(), usage, SharedGpuContext::ContextProviderWrapper(), - GetMSAASampleCountFor2dContext(), FilterQuality(), ColorParams(), - presentation_mode, std::move(dispatcher), is_origin_top_left); - } else if (want_acceleration) { + const bool is_origin_top_left = !use_gpu || LowLatencyEnabled(); + if (use_gpu && LowLatencyEnabled()) { + // If we can use the gpu and low latency is enabled, we will try to use a + // SwapChain if possible. + if (base::FeatureList::IsEnabled(features::kLowLatencyCanvas2dSwapChain)) { + provider = CanvasResourceProvider::CreateSwapChainProvider( + Size(), SharedGpuContext::ContextProviderWrapper(), FilterQuality(), + ColorParams(), is_origin_top_left, std::move(dispatcher)); + } + // If SwapChain failed or it was not possible, we will try a SharedImage + // with a set of flags trying to add Usage Display and Usage Scanout and + // Concurrent Read and Write if possible. + if (!provider) { + uint32_t shared_image_usage_flags = gpu::SHARED_IMAGE_USAGE_DISPLAY; + if (RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled() || + base::FeatureList::IsEnabled( + features::kLowLatencyCanvas2dImageChromium)) { + shared_image_usage_flags |= gpu::SHARED_IMAGE_USAGE_SCANOUT; + shared_image_usage_flags |= + gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE; + } + provider = CanvasResourceProvider::CreateSharedImageProvider( + Size(), SharedGpuContext::ContextProviderWrapper(), FilterQuality(), + ColorParams(), is_origin_top_left, RasterMode::kGPU, + shared_image_usage_flags); + } + } else if (use_gpu) { + // First try to be optimized for displaying on screen. In the case we are + // hardware compositing, we also try to enable the usage of the image as + // scanout buffer (overlay) + uint32_t shared_image_usage_flags = gpu::SHARED_IMAGE_USAGE_DISPLAY; + if (RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled()) + shared_image_usage_flags |= gpu::SHARED_IMAGE_USAGE_SCANOUT; provider = CanvasResourceProvider::CreateSharedImageProvider( Size(), SharedGpuContext::ContextProviderWrapper(), FilterQuality(), - ColorParams(), is_origin_top_left, - CanvasResourceProvider::RasterMode::kGPU, shared_image_usage_flags); - } else if (composited_mode) { + ColorParams(), is_origin_top_left, RasterMode::kGPU, + shared_image_usage_flags); + } else if (RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled()) { + const uint32_t shared_image_usage_flags = + gpu::SHARED_IMAGE_USAGE_DISPLAY | gpu::SHARED_IMAGE_USAGE_SCANOUT; provider = CanvasResourceProvider::CreateSharedImageProvider( Size(), SharedGpuContext::ContextProviderWrapper(), FilterQuality(), - ColorParams(), is_origin_top_left, - CanvasResourceProvider::RasterMode::kCPU, shared_image_usage_flags); + ColorParams(), is_origin_top_left, RasterMode::kCPU, + shared_image_usage_flags); } - if (!provider && !try_swap_chain) { - // If the sharedImage Provider creation above failed, we try a - // SharedBitmap Provider before falling back to a Bitmap Provider + // If either of the other modes failed and / or it was not possible to do, we + // will backup with a SharedBitmap, and if that was not possible with a Bitmap + // provider. + if (!provider) { provider = CanvasResourceProvider::CreateSharedBitmapProvider( - Size(), SharedGpuContext::ContextProviderWrapper(), FilterQuality(), - ColorParams(), std::move(dispatcher)); + Size(), FilterQuality(), ColorParams(), std::move(dispatcher)); } - - if (!provider && !try_swap_chain) { - // If any of the above Create was able to create a valid provider, a - // BitmapProvider will be created here. + if (!provider) { provider = CanvasResourceProvider::CreateBitmapProvider( Size(), FilterQuality(), ColorParams()); } @@ -323,7 +317,7 @@ ScriptPromise CanvasRenderingContextHost::convertToBlob( base::TimeTicks start_time = base::TimeTicks::Now(); scoped_refptr<StaticBitmapImage> image_bitmap = - RenderingContext()->GetImage(kPreferNoAcceleration); + RenderingContext()->GetImage(); if (image_bitmap) { auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); CanvasAsyncBlobCreator::ToBlobFunctionType function_type = @@ -334,7 +328,7 @@ ScriptPromise CanvasRenderingContextHost::convertToBlob( } auto* async_creator = MakeGarbageCollected<CanvasAsyncBlobCreator>( image_bitmap, options, function_type, start_time, - ExecutionContext::From(script_state), resolver); + ExecutionContext::From(script_state), ukm_params_, resolver); async_creator->ScheduleAsyncBlobCreation(options->quality()); return resolver->Promise(); } diff --git a/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.h b/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.h index 0716b939ac8..6ffb6efe5b4 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.h +++ b/chromium/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.h @@ -5,11 +5,14 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CANVAS_CANVAS_RENDERING_CONTEXT_HOST_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CANVAS_CANVAS_RENDERING_CONTEXT_HOST_H_ +#include "base/optional.h" +#include "services/metrics/public/cpp/ukm_recorder.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/dom/events/event_dispatcher.h" #include "third_party/blink/renderer/core/dom/events/event_target.h" #include "third_party/blink/renderer/core/html/canvas/canvas_image_source.h" +#include "third_party/blink/renderer/core/html/canvas/ukm_parameters.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/geometry/float_rect.h" @@ -37,7 +40,8 @@ class CORE_EXPORT CanvasRenderingContextHost : public CanvasResourceHost, kCanvasHost, kOffscreenCanvasHost, }; - CanvasRenderingContextHost(HostType host_type); + CanvasRenderingContextHost(HostType host_type, + base::Optional<UkmParameters> ukm_params); void RecordCanvasSizeToUMA(const IntSize&); @@ -72,7 +76,6 @@ class CORE_EXPORT CanvasRenderingContextHost : public CanvasResourceHost, virtual FontSelector* GetFontSelector() = 0; virtual bool ShouldAccelerate2dContext() const = 0; - virtual unsigned GetMSAASampleCountFor2dContext() const = 0; virtual bool IsNeutered() const { return false; } @@ -94,28 +97,31 @@ class CORE_EXPORT CanvasRenderingContextHost : public CanvasResourceHost, // Partial CanvasResourceHost implementation void RestoreCanvasMatrixClipStack(cc::PaintCanvas*) const final; CanvasResourceProvider* GetOrCreateCanvasResourceProviderImpl( - AccelerationHint hint) final; + RasterModeHint hint) final; CanvasResourceProvider* GetOrCreateCanvasResourceProvider( - AccelerationHint hint) override; + RasterModeHint hint) override; bool Is3d() const; - bool Is2d() const; + bool IsRenderingContext2D() const; CanvasColorParams ColorParams() const; // blink::CanvasImageSource bool IsOffscreenCanvas() const override; + base::Optional<UkmParameters> ukm_parameters() { return ukm_params_; } + protected: ~CanvasRenderingContextHost() override {} scoped_refptr<StaticBitmapImage> CreateTransparentImage(const IntSize&) const; - void CreateCanvasResourceProvider2D(AccelerationHint hint); - void CreateCanvasResourceProvider3D(AccelerationHint hint); + void CreateCanvasResourceProvider2D(RasterModeHint hint); + void CreateCanvasResourceProvider3D(); bool did_fail_to_create_resource_provider_ = false; bool did_record_canvas_size_to_uma_ = false; HostType host_type_ = kNone; + base::Optional<UkmParameters> ukm_params_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc b/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc index a5b05b93340..b19802cfa60 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc +++ b/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.cc @@ -42,6 +42,10 @@ #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/common/privacy_budget/identifiability_metric_builder.h" #include "third_party/blink/public/common/privacy_budget/identifiability_metrics.h" +#include "third_party/blink/public/common/privacy_budget/identifiability_study_participation.h" +#include "third_party/blink/public/common/thread_safe_browser_interface_broker_proxy.h" +#include "third_party/blink/public/mojom/gpu/gpu.mojom-blink.h" +#include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/public/resources/grit/blink_image_resources.h" #include "third_party/blink/renderer/bindings/core/v8/script_controller.h" @@ -82,7 +86,6 @@ #include "third_party/blink/renderer/core/paint/paint_timing.h" #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" -#include "third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h" #include "third_party/blink/renderer/platform/graphics/canvas_resource_dispatcher.h" #include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h" #include "third_party/blink/renderer/platform/graphics/graphics_layer.h" @@ -115,7 +118,9 @@ HTMLCanvasElement::HTMLCanvasElement(Document& document) ExecutionContextLifecycleObserver(GetExecutionContext()), PageVisibilityObserver(document.GetPage()), CanvasRenderingContextHost( - CanvasRenderingContextHost::HostType::kCanvasHost), + CanvasRenderingContextHost::HostType::kCanvasHost, + base::make_optional<UkmParameters>( + {document.UkmRecorder(), document.UkmSourceID()})), size_(kDefaultCanvasWidth, kDefaultCanvasHeight), context_creation_was_blocked_(false), ignore_reset_(false), @@ -177,8 +182,8 @@ void HTMLCanvasElement::ParseAttribute( LayoutObject* HTMLCanvasElement::CreateLayoutObject(const ComputedStyle& style, LegacyLayout legacy) { - LocalFrame* frame = GetDocument().GetFrame(); - if (frame && GetDocument().CanExecuteScripts(kNotAboutToExecuteScript)) { + if (GetExecutionContext() && + GetExecutionContext()->CanExecuteScripts(kNotAboutToExecuteScript)) { // Allocation of a layout object indicates that the canvas doesn't // have display:none set, so is conceptually being displayed. if (context_) { @@ -256,8 +261,7 @@ void HTMLCanvasElement::RegisterRenderingContextFactory( void HTMLCanvasElement::RecordIdentifiabilityMetric( const blink::IdentifiableSurface& surface, int64_t value) const { - blink::IdentifiabilityMetricBuilder( - base::UkmSourceId::FromInt64(GetDocument().UkmSourceID())) + blink::IdentifiabilityMetricBuilder(GetDocument().UkmSourceID()) .Set(surface, value) .Record(GetDocument().UkmRecorder()); } @@ -285,11 +289,14 @@ CanvasRenderingContext* HTMLCanvasElement::GetCanvasRenderingContextInternal( // Log the aliased context type used. if (!context_) { - RecordIdentifiabilityMetric( - blink::IdentifiableSurface::FromTypeAndInput( - blink::IdentifiableSurface::Type::kWebFeature, - static_cast<uint64_t>(blink::WebFeature::kCanvasRenderingContext)), - blink::IdentifiabilityDigestHelper(context_type)); + if (IsUserInIdentifiabilityStudy()) { + RecordIdentifiabilityMetric( + blink::IdentifiableSurface::FromTypeAndInput( + blink::IdentifiableSurface::Type::kWebFeature, + static_cast<uint64_t>( + blink::WebFeature::kCanvasRenderingContext)), + blink::IdentifiabilityDigestHelper(context_type)); + } UMA_HISTOGRAM_ENUMERATION("Blink.Canvas.ContextType", context_type); } @@ -344,7 +351,7 @@ CanvasRenderingContext* HTMLCanvasElement::GetCanvasRenderingContextInternal( EVisibility::kVisible); } - if (Is2d() && !context_->CreationAttributes().alpha) { + if (IsRenderingContext2D() && !context_->CreationAttributes().alpha) { // In the alpha false case, canvas is initially opaque, so we need to // trigger an invalidation. DidDraw(); @@ -367,7 +374,7 @@ CanvasRenderingContext* HTMLCanvasElement::GetCanvasRenderingContextInternal( // A 2D context does not know before lazy creation whether or not it is // direct composited. The Canvas2DLayerBridge will handle this - if (!Is2d()) + if (!IsRenderingContext2D()) SetNeedsCompositingUpdate(); return context_.Get(); @@ -377,12 +384,6 @@ ScriptPromise HTMLCanvasElement::convertToBlob( ScriptState* script_state, const ImageEncodeOptions* options, ExceptionState& exception_state) { - RecordIdentifiabilityMetric( - blink::IdentifiableSurface::FromTypeAndInput( - blink::IdentifiableSurface::Type::kCanvasReadback, - context_ ? context_->GetContextType() - : CanvasRenderingContext::kContextTypeUnknown), - 0); return CanvasRenderingContextHost::convertToBlob(script_state, options, exception_state); } @@ -415,12 +416,11 @@ bool HTMLCanvasElement::IsWebGL2Enabled() const { bool HTMLCanvasElement::IsWebGLBlocked() const { Document& document = GetDocument(); - LocalFrame* frame = document.GetFrame(); - if (!frame) - return false; - bool blocked = false; - frame->GetLocalFrameHostRemote().Are3DAPIsBlocked(&blocked); + mojo::Remote<mojom::blink::GpuDataManager> gpu_data_manager; + Platform::Current()->GetBrowserInterfaceBroker()->GetInterface( + gpu_data_manager.BindNewPipeAndPassReceiver()); + gpu_data_manager->Are3DAPIsBlockedForUrl(document.Url(), &blocked); return blocked; } @@ -430,7 +430,7 @@ void HTMLCanvasElement::DidDraw(const FloatRect& rect) { canvas_is_clear_ = false; if (GetLayoutObject() && !LowLatencyEnabled()) GetLayoutObject()->SetShouldCheckForPaintInvalidation(); - if (Is2d() && context_->ShouldAntialias() && GetPage() && + if (IsRenderingContext2D() && context_->ShouldAntialias() && GetPage() && GetPage()->DeviceScaleFactorDeprecated() > 1.0f) { FloatRect inflated_rect = rect; inflated_rect.Inflate(1); @@ -438,7 +438,7 @@ void HTMLCanvasElement::DidDraw(const FloatRect& rect) { } else { dirty_rect_.Unite(rect); } - if (Is2d() && canvas2d_bridge_) + if (IsRenderingContext2D() && canvas2d_bridge_) canvas2d_bridge_->DidDraw(rect); } @@ -458,7 +458,7 @@ void HTMLCanvasElement::PreFinalizeFrame() { // Low-latency 2d canvases produce their frames after the resource gets single // buffered. if (LowLatencyEnabled() && !dirty_rect_.IsEmpty() && - GetOrCreateCanvasResourceProvider(kPreferAcceleration)) { + GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU)) { // TryEnableSingleBuffering() the first time we FinalizeFrame(). This is // a nop if already single buffered or if single buffering is unsupported. ResourceProvider()->TryEnableSingleBuffering(); @@ -467,7 +467,7 @@ void HTMLCanvasElement::PreFinalizeFrame() { void HTMLCanvasElement::PostFinalizeFrame() { if (LowLatencyEnabled() && !dirty_rect_.IsEmpty() && - GetOrCreateCanvasResourceProvider(kPreferAcceleration)) { + GetOrCreateCanvasResourceProvider(RasterModeHint::kPreferGPU)) { const base::TimeTicks start_time = base::TimeTicks::Now(); const scoped_refptr<CanvasResource> canvas_resource = ResourceProvider()->ProduceCanvasResource(); @@ -502,7 +502,7 @@ void HTMLCanvasElement::DisableAcceleration( if (unaccelerated_bridge_used_for_testing) bridge = std::move(unaccelerated_bridge_used_for_testing); else - bridge = CreateUnaccelerated2dBuffer(); + bridge = Create2DLayerBridge(RasterMode::kCPU); if (bridge && canvas2d_bridge_) ReplaceExisting2dLayerBridge(std::move(bridge)); @@ -535,7 +535,7 @@ void HTMLCanvasElement::DoDeferredPaintInvalidation() { } } - if (Is2d()) { + if (IsRenderingContext2D()) { FloatRect src_rect(0, 0, Size().Width(), Size().Height()); dirty_rect_.Intersect(src_rect); @@ -613,7 +613,7 @@ void HTMLCanvasElement::Reset() { h = kDefaultCanvasHeight; } - if (Is2d()) { + if (IsRenderingContext2D()) { context_->Reset(); origin_clean_ = true; } @@ -623,7 +623,7 @@ void HTMLCanvasElement::Reset() { // If the size of an existing buffer matches, we can just clear it instead of // reallocating. This optimization is only done for 2D canvases for now. - if (had_resource_provider && old_size == new_size && Is2d()) { + if (had_resource_provider && old_size == new_size && IsRenderingContext2D()) { if (!canvas_is_clear_) { canvas_is_clear_ = true; if (canvas2d_bridge_) @@ -682,7 +682,7 @@ void HTMLCanvasElement::NotifyListenersCanvasChanged() { if (listener_needs_new_frame_capture) { SourceImageStatus status; scoped_refptr<StaticBitmapImage> source_image = - GetSourceImageForCanvasInternal(&status, kPreferNoAcceleration); + GetSourceImageForCanvasInternal(&status); if (status != kNormalSourceImageStatus) return; for (CanvasDrawListener* listener : listeners_) { @@ -708,6 +708,12 @@ static std::pair<blink::Image*, float> BrokenCanvas(float device_scale_factor) { return std::make_pair(broken_canvas_lo_res, 1); } +static SkFilterQuality FilterQualityFromStyle(const ComputedStyle* style) { + if (style && style->ImageRendering() == EImageRendering::kPixelated) + return kNone_SkFilterQuality; + return kLow_SkFilterQuality; +} + SkFilterQuality HTMLCanvasElement::FilterQuality() const { if (!isConnected()) return kLow_SkFilterQuality; @@ -718,23 +724,21 @@ SkFilterQuality HTMLCanvasElement::FilterQuality() const { HTMLCanvasElement* non_const_this = const_cast<HTMLCanvasElement*>(this); style = non_const_this->EnsureComputedStyle(); } - return (style && style->ImageRendering() == EImageRendering::kPixelated) - ? kNone_SkFilterQuality - : kLow_SkFilterQuality; + return FilterQualityFromStyle(style); } bool HTMLCanvasElement::LowLatencyEnabled() const { return !!frame_dispatcher_; } -void HTMLCanvasElement::UpdateFilterQuality() { +void HTMLCanvasElement::UpdateFilterQuality(SkFilterQuality filter_quality) { if (IsOffscreenCanvasRegistered()) - UpdateOffscreenCanvasFilterQuality(FilterQuality()); + UpdateOffscreenCanvasFilterQuality(filter_quality); if (context_ && Is3d()) - context_->SetFilterQuality(FilterQuality()); + context_->SetFilterQuality(filter_quality); else if (canvas2d_bridge_) - canvas2d_bridge_->UpdateFilterQuality(); + canvas2d_bridge_->SetFilterQuality(filter_quality); } // In some instances we don't actually want to paint to the parent layer @@ -828,7 +832,7 @@ void HTMLCanvasElement::PaintInternal(GraphicsContext& context, FloatRect src_rect = FloatRect(FloatPoint(), FloatSize(Size())); scoped_refptr<StaticBitmapImage> snapshot = canvas2d_bridge_ - ? canvas2d_bridge_->NewImageSnapshot(kPreferAcceleration) + ? canvas2d_bridge_->NewImageSnapshot() : (ResourceProvider() ? ResourceProvider()->Snapshot() : nullptr); if (snapshot) { // GraphicsContext cannot handle gpu resource serialization. @@ -857,7 +861,7 @@ void HTMLCanvasElement::SetSurfaceSize(const IntSize& size) { size_ = size; did_fail_to_create_resource_provider_ = false; DiscardResourceProvider(); - if (Is2d() && context_->isContextLost()) + if (IsRenderingContext2D() && context_->isContextLost()) context_->DidSetSurfaceSize(); if (frame_dispatcher_) frame_dispatcher_->Reshape(size_); @@ -869,8 +873,7 @@ const AtomicString HTMLCanvasElement::ImageSourceURL() const { } scoped_refptr<StaticBitmapImage> HTMLCanvasElement::Snapshot( - SourceDrawingBuffer source_buffer, - AccelerationHint hint) const { + SourceDrawingBuffer source_buffer) const { if (size_.IsEmpty()) return nullptr; @@ -900,11 +903,11 @@ scoped_refptr<StaticBitmapImage> HTMLCanvasElement::Snapshot( image_bitmap = StaticBitmapImage::Create(std::move(pixel_data), info); } } - } else if (canvas2d_bridge_) { // 2D Canvas - DCHECK(Is2d()); - image_bitmap = canvas2d_bridge_->NewImageSnapshot(hint); + } else if (canvas2d_bridge_) { + DCHECK(IsRenderingContext2D()); + image_bitmap = canvas2d_bridge_->NewImageSnapshot(); } else if (context_) { // Bitmap renderer canvas - image_bitmap = context_->GetImage(hint); + image_bitmap = context_->GetImage(); } if (!image_bitmap) @@ -924,8 +927,7 @@ String HTMLCanvasElement::ToDataURLInternal( ImageEncoderUtils::ToEncodingMimeType( mime_type, ImageEncoderUtils::kEncodeReasonToDataURL); - scoped_refptr<StaticBitmapImage> image_bitmap = - Snapshot(source_buffer, kPreferNoAcceleration); + scoped_refptr<StaticBitmapImage> image_bitmap = Snapshot(source_buffer); if (image_bitmap) { std::unique_ptr<ImageDataBuffer> data_buffer = ImageDataBuffer::Create(image_bitmap); @@ -958,12 +960,22 @@ String HTMLCanvasElement::ToDataURLInternal( // Currently we only support three encoding types. NOTREACHED(); } - RecordIdentifiabilityMetric( - blink::IdentifiableSurface::FromTypeAndInput( - blink::IdentifiableSurface::Type::kCanvasReadback, - context_ ? context_->GetContextType() - : CanvasRenderingContext::kContextTypeUnknown), - 0); + if (IsUserInIdentifiabilityStudy()) { + const uint64_t context_digest = + context_ ? context_->IdentifiabilityTextDigest() : 0; + const uint64_t canvas_digest = + ResourceProvider() ? ResourceProvider()->GetIdentifiabilityDigest() + : 0; + const uint64_t context_type = + context_ ? context_->GetContextType() + : CanvasRenderingContext::kContextTypeUnknown; + const uint64_t final_digest = + ((context_digest ^ canvas_digest) << 4) | context_type; + RecordIdentifiabilityMetric( + blink::IdentifiableSurface::FromTypeAndInput( + blink::IdentifiableSurface::Type::kCanvasReadback, final_digest), + blink::IdentifiabilityDigestOfBytes(data_url.Span8())); + } return data_url; } @@ -996,6 +1008,9 @@ void HTMLCanvasElement::toBlob(V8BlobCallback* callback, return; } + if (!GetExecutionContext()) + return; + if (!IsPaintable()) { // If the canvas element's bitmap has no pixels GetDocument() @@ -1019,23 +1034,26 @@ void HTMLCanvasElement::toBlob(V8BlobCallback* callback, mime_type, ImageEncoderUtils::kEncodeReasonToBlobCallback); CanvasAsyncBlobCreator* async_creator = nullptr; - scoped_refptr<StaticBitmapImage> image_bitmap = - Snapshot(kBackBuffer, kPreferNoAcceleration); + scoped_refptr<StaticBitmapImage> image_bitmap = Snapshot(kBackBuffer); if (image_bitmap) { auto* options = ImageEncodeOptions::Create(); options->setType(ImageEncodingMimeTypeName(encoding_mime_type)); async_creator = MakeGarbageCollected<CanvasAsyncBlobCreator>( image_bitmap, options, CanvasAsyncBlobCreator::kHTMLCanvasToBlobCallback, callback, start_time, - GetExecutionContext()); + GetExecutionContext(), + base::make_optional<UkmParameters>( + {GetDocument().UkmRecorder(), GetDocument().UkmSourceID()})); } - RecordIdentifiabilityMetric( - blink::IdentifiableSurface::FromTypeAndInput( - blink::IdentifiableSurface::Type::kCanvasReadback, - context_ ? context_->GetContextType() - : CanvasRenderingContext::kContextTypeUnknown), - 0); + if (IsUserInIdentifiabilityStudy()) { + RecordIdentifiabilityMetric( + blink::IdentifiableSurface::FromTypeAndInput( + blink::IdentifiableSurface::Type::kCanvasReadback, + context_ ? context_->GetContextType() + : CanvasRenderingContext::kContextTypeUnknown), + 0); + } if (async_creator) { async_creator->ScheduleAsyncBlobCreation(quality); @@ -1067,7 +1085,7 @@ bool HTMLCanvasElement::OriginClean() const { } bool HTMLCanvasElement::ShouldAccelerate2dContext() const { - return ShouldAccelerate(kNormalAccelerationCriteria); + return ShouldAccelerate(); } CanvasResourceDispatcher* HTMLCanvasElement::GetOrCreateResourceDispatcher() { @@ -1083,8 +1101,8 @@ bool HTMLCanvasElement::PushFrame(scoped_refptr<CanvasResource> image, return false; } -bool HTMLCanvasElement::ShouldAccelerate(AccelerationCriteria criteria) const { - if (context_ && !Is2d()) +bool HTMLCanvasElement::ShouldAccelerate() const { + if (context_ && !IsRenderingContext2D()) return false; // The command line flag --disable-accelerated-2d-canvas toggles this option @@ -1121,35 +1139,19 @@ bool HTMLCanvasElement::ShouldAccelerate(AccelerationCriteria criteria) const { return context_provider_wrapper->Utils()->Accelerated2DCanvasFeatureEnabled(); } -unsigned HTMLCanvasElement::GetMSAASampleCountFor2dContext() const { - if (!GetDocument().GetSettings()) - return 0; - return GetDocument().GetSettings()->GetAccelerated2dCanvasMSAASampleCount(); -} - -std::unique_ptr<Canvas2DLayerBridge> -HTMLCanvasElement::CreateAccelerated2dBuffer() { - auto surface = std::make_unique<Canvas2DLayerBridge>( - Size(), Canvas2DLayerBridge::kEnableAcceleration, ColorParams()); +std::unique_ptr<Canvas2DLayerBridge> HTMLCanvasElement::Create2DLayerBridge( + RasterMode raster_mode) { + auto surface = + std::make_unique<Canvas2DLayerBridge>(Size(), raster_mode, ColorParams()); if (!surface->IsValid()) return nullptr; return surface; } -std::unique_ptr<Canvas2DLayerBridge> -HTMLCanvasElement::CreateUnaccelerated2dBuffer() { - auto surface = std::make_unique<Canvas2DLayerBridge>( - Size(), Canvas2DLayerBridge::kDisableAcceleration, ColorParams()); - if (surface->IsValid()) - return surface; - - return nullptr; -} - void HTMLCanvasElement::SetCanvas2DLayerBridgeInternal( std::unique_ptr<Canvas2DLayerBridge> external_canvas2d_bridge) { - DCHECK(Is2d() && !canvas2d_bridge_); + DCHECK(IsRenderingContext2D() && !canvas2d_bridge_); did_fail_to_create_resource_provider_ = true; if (!IsValidImageSize(Size())) @@ -1159,10 +1161,19 @@ void HTMLCanvasElement::SetCanvas2DLayerBridgeInternal( if (external_canvas2d_bridge->IsValid()) canvas2d_bridge_ = std::move(external_canvas2d_bridge); } else { - if (ShouldAccelerate(kNormalAccelerationCriteria)) - canvas2d_bridge_ = CreateAccelerated2dBuffer(); - if (!canvas2d_bridge_) - canvas2d_bridge_ = CreateUnaccelerated2dBuffer(); + // If the canvas meets the criteria to use accelerated-GPU rendering, and + // the user signals that the canvas will not be read frequently through + // getImageData, which is a slow operation with GPU, the canvas will try to + // use accelerated-GPU rendering. + // If any of the two conditions fails, or if the creation of accelerated + // resource provider fails, the canvas will fallback to CPU rendering. + if (ShouldAccelerate() && + !context_->CreationAttributes().will_read_frequently) { + canvas2d_bridge_ = Create2DLayerBridge(RasterMode::kGPU); + } + if (!canvas2d_bridge_) { + canvas2d_bridge_ = Create2DLayerBridge(RasterMode::kCPU); + } } if (!canvas2d_bridge_) @@ -1177,25 +1188,16 @@ void HTMLCanvasElement::SetCanvas2DLayerBridgeInternal( did_fail_to_create_resource_provider_ = false; UpdateMemoryUsage(); - // Enabling MSAA overrides a request to disable antialiasing. This is true - // regardless of whether the rendering mode is accelerated or not. For - // consistency, we don't want to apply AA in accelerated canvases but not in - // unaccelerated canvases. - if (!GetMSAASampleCountFor2dContext() && GetDocument().GetSettings() && - !GetDocument().GetSettings()->GetAntialiased2dCanvasEnabled()) { - context_->SetShouldAntialias(false); - } - if (context_) SetNeedsCompositingUpdate(); } void HTMLCanvasElement::NotifyGpuContextLost() { - if (Is2d()) + if (IsRenderingContext2D()) context_->LoseContext(CanvasRenderingContext::kRealLostContext); } -void HTMLCanvasElement::Trace(Visitor* visitor) { +void HTMLCanvasElement::Trace(Visitor* visitor) const { visitor->Trace(listeners_); visitor->Trace(context_); ExecutionContextLifecycleObserver::Trace(visitor); @@ -1204,7 +1206,7 @@ void HTMLCanvasElement::Trace(Visitor* visitor) { } Canvas2DLayerBridge* HTMLCanvasElement::GetOrCreateCanvas2DLayerBridge() { - DCHECK(Is2d()); + DCHECK(IsRenderingContext2D()); if (!canvas2d_bridge_ && !did_fail_to_create_resource_provider_) { SetCanvas2DLayerBridgeInternal(nullptr); if (did_fail_to_create_resource_provider_ && !Size().IsEmpty()) @@ -1249,6 +1251,7 @@ void HTMLCanvasElement::ContextDestroyed() { void HTMLCanvasElement::StyleDidChange(const ComputedStyle* old_style, const ComputedStyle& new_style) { + UpdateFilterQuality(FilterQualityFromStyle(&new_style)); if (context_) context_->StyleDidChange(old_style, new_style); } @@ -1269,9 +1272,9 @@ void HTMLCanvasElement::DidMoveToNewDocument(Document& old_document) { void HTMLCanvasElement::WillDrawImageTo2DContext(CanvasImageSource* source) { if (SharedGpuContext::AllowSoftwareToAcceleratedCanvasUpgrade() && source->IsAccelerated() && GetOrCreateCanvas2DLayerBridge() && - !canvas2d_bridge_->IsAccelerated() && - ShouldAccelerate(kIgnoreResourceLimitCriteria)) { - std::unique_ptr<Canvas2DLayerBridge> surface = CreateAccelerated2dBuffer(); + !canvas2d_bridge_->IsAccelerated() && ShouldAccelerate()) { + std::unique_ptr<Canvas2DLayerBridge> surface = + Create2DLayerBridge(RasterMode::kGPU); if (surface) { ReplaceExisting2dLayerBridge(std::move(surface)); SetNeedsCompositingUpdate(); @@ -1281,14 +1284,12 @@ void HTMLCanvasElement::WillDrawImageTo2DContext(CanvasImageSource* source) { scoped_refptr<Image> HTMLCanvasElement::GetSourceImageForCanvas( SourceImageStatus* status, - AccelerationHint hint, const FloatSize&) { - return GetSourceImageForCanvasInternal(status, hint); + return GetSourceImageForCanvasInternal(status); } scoped_refptr<StaticBitmapImage> -HTMLCanvasElement::GetSourceImageForCanvasInternal(SourceImageStatus* status, - AccelerationHint hint) { +HTMLCanvasElement::GetSourceImageForCanvasInternal(SourceImageStatus* status) { if (!width() || !height()) { *status = kZeroSizeCanvasSourceImageStatus; return nullptr; @@ -1312,7 +1313,7 @@ HTMLCanvasElement::GetSourceImageForCanvasInternal(SourceImageStatus* status, if (HasImageBitmapContext()) { *status = kNormalSourceImageStatus; - scoped_refptr<StaticBitmapImage> result = context_->GetImage(hint); + scoped_refptr<StaticBitmapImage> result = context_->GetImage(); if (!result) result = GetTransparentImage(); *status = result ? kNormalSourceImageStatus : kInvalidSourceImageStatus; @@ -1332,7 +1333,7 @@ HTMLCanvasElement::GetSourceImageForCanvasInternal(SourceImageStatus* status, else image = GetTransparentImage(); } else { - image = RenderingContext()->GetImage(hint); + image = RenderingContext()->GetImage(); if (!image) image = GetTransparentImage(); } @@ -1352,7 +1353,7 @@ FloatSize HTMLCanvasElement::ElementSize( const FloatSize&, const RespectImageOrientationEnum) const { if (context_ && HasImageBitmapContext()) { - scoped_refptr<Image> image = context_->GetImage(kPreferNoAcceleration); + scoped_refptr<Image> image = context_->GetImage(); if (image) return FloatSize(image->width(), image->height()); return FloatSize(0, 0); @@ -1458,7 +1459,7 @@ bool HTMLCanvasElement::IsSupportedInteractiveCanvasFallback( HitTestCanvasResult* HTMLCanvasElement::GetControlAndIdIfHitRegionExists( const PhysicalOffset& location) { - if (Is2d()) + if (IsRenderingContext2D()) return context_->GetControlAndIdIfHitRegionExists(location); return MakeGarbageCollected<HitTestCanvasResult>(String(), nullptr); } @@ -1505,7 +1506,7 @@ void HTMLCanvasElement::UpdateMemoryUsage() { int non_gpu_buffer_count = 0; int gpu_buffer_count = 0; - if (!Is2d() && !Is3d()) + if (!IsRenderingContext2D() && !Is3d()) return; if (ResourceProvider()) { non_gpu_buffer_count++; @@ -1525,7 +1526,7 @@ void HTMLCanvasElement::UpdateMemoryUsage() { intptr_t gpu_memory_usage = 0; if (gpu_buffer_count) { - // Switch from non-acceleration mode to acceleration mode + // Switch from cpu mode to gpu mode base::CheckedNumeric<intptr_t> checked_usage = gpu_buffer_count * bytes_per_pixel; checked_usage *= width(); @@ -1553,22 +1554,40 @@ void HTMLCanvasElement::UpdateMemoryUsage() { void HTMLCanvasElement::ReplaceExisting2dLayerBridge( std::unique_ptr<Canvas2DLayerBridge> new_layer_bridge) { scoped_refptr<StaticBitmapImage> image; + std::unique_ptr<Canvas2DLayerBridge> old_layer_bridge; if (canvas2d_bridge_) { - image = canvas2d_bridge_->NewImageSnapshot(kPreferNoAcceleration); + image = canvas2d_bridge_->NewImageSnapshot(); // image can be null if allocation failed in which case we should just // abort the surface switch to retain the old surface which is still // functional. if (!image) return; + old_layer_bridge = std::move(canvas2d_bridge_); + // Removing connection between old_layer_bridge and CanvasResourceHost; + // otherwise, the CanvasResourceHost checks for the old one before + // assigning the new canvas layer bridge. + old_layer_bridge->SetCanvasResourceHost(nullptr); } ReplaceResourceProvider(nullptr); canvas2d_bridge_ = std::move(new_layer_bridge); canvas2d_bridge_->SetCanvasResourceHost(this); + // If PaintCanvas cannot be get from the new layer bridge, revert the + // replacement. cc::PaintCanvas* canvas = canvas2d_bridge_->GetPaintCanvas(); - // Paint canvas automatically has the clip re-applied. Since image already - // contains clip, it needs to be drawn before the clip stack is re-applied. - // Remove clip from canvas and restore it after the image is drawn. + if (!canvas) { + if (old_layer_bridge) { + canvas2d_bridge_ = std::move(old_layer_bridge); + canvas2d_bridge_->SetCanvasResourceHost(this); + } + return; + } + + // After validating paint canvas on new layer bridge, removes the clip from + // the canvas. Since clips is automatically applied to paint canvas, the image + // already contains clip and the image needs to be drawn before the clip stack + // is re-applied, it needs to remove clip from canvas and restore it after the + // image is drawn. canvas->restoreToCount(1); canvas->save(); @@ -1584,9 +1603,9 @@ void HTMLCanvasElement::ReplaceExisting2dLayerBridge( } CanvasResourceProvider* HTMLCanvasElement::GetOrCreateCanvasResourceProvider( - AccelerationHint hint) { - if (Is2d()) - return GetOrCreateCanvas2DLayerBridge()->GetOrCreateResourceProvider(hint); + RasterModeHint hint) { + if (IsRenderingContext2D()) + return GetOrCreateCanvas2DLayerBridge()->GetOrCreateResourceProvider(); return CanvasRenderingContextHost::GetOrCreateCanvasResourceProvider(hint); } diff --git a/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.h b/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.h index e36e9a211ab..2aa3fe0864f 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.h +++ b/chromium/third_party/blink/renderer/core/html/canvas/html_canvas_element.h @@ -45,6 +45,7 @@ #include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h" #include "third_party/blink/renderer/platform/geometry/float_rect.h" #include "third_party/blink/renderer/platform/geometry/int_size.h" +#include "third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h" #include "third_party/blink/renderer/platform/graphics/canvas_resource_host.h" #include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h" #include "third_party/blink/renderer/platform/graphics/graphics_types.h" @@ -86,11 +87,11 @@ typedef CanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextO #endif // This contains the information of HTML Canvas Element, -// There are four different types of context this HTML Canvas can contain. +// There are four different types of rendering context this HTML Canvas can own. // It can be a 3D Context (WebGL or WebGL2), 2D Context, -// BitmapRenderingContext or it can have no context (Offscreencanvas). +// BitmapRenderingContext or it can have no context (Offscreen placeholder). // To check the no context case is good to check if there is a placeholder. -// For 3D and 2D contexts there are Is3D or Is2D functions. +// For 3D and 2D contexts there are Is3D or IsRenderingContext2D functions. // The remaining case is BitmaprenderingContext. // // TODO (juanmihd): Study if a refactor of context could help in simplifying @@ -155,7 +156,6 @@ class CORE_EXPORT HTMLCanvasElement final void DidDraw(const FloatRect&) override; void DidDraw() override; - void UpdateFilterQuality(); void Paint(GraphicsContext&, const PhysicalRect&, bool flatten_composited_layers); @@ -202,7 +202,6 @@ class CORE_EXPORT HTMLCanvasElement final // CanvasImageSource implementation scoped_refptr<Image> GetSourceImageForCanvas(SourceImageStatus*, - AccelerationHint, const FloatSize&) override; bool WouldTaintOrigin() const override; FloatSize ElementSize(const FloatSize&, @@ -221,11 +220,10 @@ class CORE_EXPORT HTMLCanvasElement final void SetNeedsCompositingUpdate() override; void UpdateMemoryUsage() override; bool ShouldAccelerate2dContext() const override; - unsigned GetMSAASampleCountFor2dContext() const override; SkFilterQuality FilterQuality() const override; bool LowLatencyEnabled() const override; CanvasResourceProvider* GetOrCreateCanvasResourceProvider( - AccelerationHint hint) override; + RasterModeHint hint) override; bool IsPrinting() const override; void DisableAcceleration(std::unique_ptr<Canvas2DLayerBridge> @@ -241,7 +239,7 @@ class CORE_EXPORT HTMLCanvasElement final // OffscreenCanvasPlaceholder implementation. void SetOffscreenCanvasResource(scoped_refptr<CanvasResource>, unsigned resource_id) override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void SetResourceProviderForTesting(std::unique_ptr<CanvasResourceProvider>, std::unique_ptr<Canvas2DLayerBridge>, @@ -300,8 +298,7 @@ class CORE_EXPORT HTMLCanvasElement final needs_unbuffered_input_ = value; } - scoped_refptr<StaticBitmapImage> Snapshot(SourceDrawingBuffer, - AccelerationHint) const; + scoped_refptr<StaticBitmapImage> Snapshot(SourceDrawingBuffer) const; // Returns the cc layer containing the contents. It's the cc layer of // SurfaceLayerBridge() or RenderingContext(), or nullptr if the canvas is not @@ -323,17 +320,14 @@ class CORE_EXPORT HTMLCanvasElement final int64_t value) const; void PaintInternal(GraphicsContext&, const PhysicalRect&); + void UpdateFilterQuality(SkFilterQuality filter_quality); using ContextFactoryVector = Vector<std::unique_ptr<CanvasRenderingContextFactory>>; static ContextFactoryVector& RenderingContextFactories(); static CanvasRenderingContextFactory* GetRenderingContextFactory(int); - enum AccelerationCriteria { - kNormalAccelerationCriteria, - kIgnoreResourceLimitCriteria, - }; - bool ShouldAccelerate(AccelerationCriteria) const; + bool ShouldAccelerate() const; void ParseAttribute(const AttributeModificationParams&) override; LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) override; @@ -341,8 +335,8 @@ class CORE_EXPORT HTMLCanvasElement final void Reset(); - std::unique_ptr<Canvas2DLayerBridge> CreateAccelerated2dBuffer(); - std::unique_ptr<Canvas2DLayerBridge> CreateUnaccelerated2dBuffer(); + std::unique_ptr<Canvas2DLayerBridge> Create2DLayerBridge( + RasterMode raster_mode); void SetCanvas2DLayerBridgeInternal(std::unique_ptr<Canvas2DLayerBridge>); void SetSurfaceSize(const IntSize&); @@ -365,8 +359,7 @@ class CORE_EXPORT HTMLCanvasElement final const CanvasContextCreationAttributesCore&); scoped_refptr<StaticBitmapImage> GetSourceImageForCanvasInternal( - SourceImageStatus*, - AccelerationHint); + SourceImageStatus*); void OnContentsCcLayerChanged(); diff --git a/chromium/third_party/blink/renderer/core/html/canvas/image_data.cc b/chromium/third_party/blink/renderer/core/html/canvas/image_data.cc index 099510256d3..e8bb23291fc 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/image_data.cc +++ b/chromium/third_party/blink/renderer/core/html/canvas/image_data.cc @@ -254,9 +254,6 @@ ImageDataColorSettings* CanvasColorParamsToImageDataColorSettings( case CanvasColorSpace::kSRGB: color_settings->setColorSpace(kSRGBCanvasColorSpaceName); break; - case CanvasColorSpace::kLinearRGB: - color_settings->setColorSpace(kLinearRGBCanvasColorSpaceName); - break; case CanvasColorSpace::kRec2020: color_settings->setColorSpace(kRec2020CanvasColorSpaceName); break; @@ -285,9 +282,6 @@ ImageData* ImageData::Create(const IntSize& size, case CanvasColorSpace::kSRGB: color_settings->setColorSpace(kSRGBCanvasColorSpaceName); break; - case CanvasColorSpace::kLinearRGB: - color_settings->setColorSpace(kLinearRGBCanvasColorSpaceName); - break; case CanvasColorSpace::kRec2020: color_settings->setColorSpace(kRec2020CanvasColorSpaceName); break; @@ -604,8 +598,6 @@ CanvasColorSpace ImageData::GetCanvasColorSpace( const String& color_space_name) { if (color_space_name == kSRGBCanvasColorSpaceName) return CanvasColorSpace::kSRGB; - if (color_space_name == kLinearRGBCanvasColorSpaceName) - return CanvasColorSpace::kLinearRGB; if (color_space_name == kRec2020CanvasColorSpaceName) return CanvasColorSpace::kRec2020; if (color_space_name == kP3CanvasColorSpaceName) @@ -618,8 +610,6 @@ String ImageData::CanvasColorSpaceName(CanvasColorSpace color_space) { switch (color_space) { case CanvasColorSpace::kSRGB: return kSRGBCanvasColorSpaceName; - case CanvasColorSpace::kLinearRGB: - return kLinearRGBCanvasColorSpaceName; case CanvasColorSpace::kRec2020: return kRec2020CanvasColorSpaceName; case CanvasColorSpace::kP3: @@ -848,7 +838,7 @@ bool ImageData::ImageDataInCanvasColorSettings( return data_transform_successful; } -void ImageData::Trace(Visitor* visitor) { +void ImageData::Trace(Visitor* visitor) const { visitor->Trace(color_settings_); visitor->Trace(data_); visitor->Trace(data_u16_); diff --git a/chromium/third_party/blink/renderer/core/html/canvas/image_data.h b/chromium/third_party/blink/renderer/core/html/canvas/image_data.h index 4101d0fa9b2..5a5e0da97a2 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/image_data.h +++ b/chromium/third_party/blink/renderer/core/html/canvas/image_data.h @@ -158,7 +158,7 @@ class CORE_EXPORT ImageData final : public ScriptWrappable, const ImageBitmapOptions*, ExceptionState&) override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; WARN_UNUSED_RESULT v8::Local<v8::Object> AssociateWithWrapper( v8::Isolate*, diff --git a/chromium/third_party/blink/renderer/core/html/canvas/image_data_color_settings.idl b/chromium/third_party/blink/renderer/core/html/canvas/image_data_color_settings.idl index e8fc5ced5c1..917e0e182c8 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/image_data_color_settings.idl +++ b/chromium/third_party/blink/renderer/core/html/canvas/image_data_color_settings.idl @@ -6,7 +6,6 @@ enum CanvasColorSpace { "srgb", // default - "linear-rgb", "rec2020", "p3", }; diff --git a/chromium/third_party/blink/renderer/core/html/canvas/image_data_test.cc b/chromium/third_party/blink/renderer/core/html/canvas/image_data_test.cc index 15db4684f74..dd867b4cdde 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/image_data_test.cc +++ b/chromium/third_party/blink/renderer/core/html/canvas/image_data_test.cc @@ -133,7 +133,6 @@ TEST_F(ImageDataTest, TestGetImageDataInCanvasColorSettings) { unsigned num_image_data_color_spaces = 3; CanvasColorSpace image_data_color_spaces[] = { CanvasColorSpace::kSRGB, - CanvasColorSpace::kLinearRGB, CanvasColorSpace::kRec2020, CanvasColorSpace::kP3, }; @@ -144,17 +143,17 @@ TEST_F(ImageDataTest, TestGetImageDataInCanvasColorSettings) { kFloat32ArrayStorageFormat, }; - unsigned num_canvas_color_settings = 4; + unsigned num_canvas_color_settings = 3; CanvasColorSpace canvas_color_spaces[] = { - CanvasColorSpace::kSRGB, CanvasColorSpace::kSRGB, - CanvasColorSpace::kLinearRGB, CanvasColorSpace::kRec2020, + CanvasColorSpace::kSRGB, + CanvasColorSpace::kSRGB, + CanvasColorSpace::kRec2020, CanvasColorSpace::kP3, }; CanvasPixelFormat canvas_pixel_formats[] = { CanvasPixelFormat::kRGBA8, CanvasPixelFormat::kF16, CanvasPixelFormat::kF16, CanvasPixelFormat::kF16, - CanvasPixelFormat::kF16, }; // As cross checking the output of Skia color space covnersion API is not in diff --git a/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.cc b/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.cc index 33076248c58..d0bbfde754b 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.cc +++ b/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.cc @@ -47,7 +47,6 @@ bool ImageElementBase::IsImageElement() const { scoped_refptr<Image> ImageElementBase::GetSourceImageForCanvas( SourceImageStatus* status, - AccelerationHint, const FloatSize& default_object_size) { ImageResourceContent* image_content = CachedImage(); if (!GetImageLoader().ImageComplete() || !image_content) { diff --git a/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.h b/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.h index 05a08421d22..88f23ca7565 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.h +++ b/chromium/third_party/blink/renderer/core/html/canvas/image_element_base.h @@ -33,7 +33,6 @@ class CORE_EXPORT ImageElementBase : public CanvasImageSource, ExceptionState&) override; scoped_refptr<Image> GetSourceImageForCanvas(SourceImageStatus*, - AccelerationHint, const FloatSize&) override; bool WouldTaintOrigin() const override; diff --git a/chromium/third_party/blink/renderer/core/html/canvas/text_metrics.cc b/chromium/third_party/blink/renderer/core/html/canvas/text_metrics.cc index bdbc4c5a9f9..d3fadad089c 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/text_metrics.cc +++ b/chromium/third_party/blink/renderer/core/html/canvas/text_metrics.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/core/html/canvas/text_metrics.h" #include "third_party/blink/renderer/bindings/core/v8/v8_baselines.h" +#include "third_party/blink/renderer/core/layout/ng/inline/ng_bidi_paragraph.h" #include "third_party/blink/renderer/platform/fonts/character_range.h" namespace blink { @@ -38,7 +39,7 @@ float TextMetrics::GetFontBaseline(const TextBaseline& text_baseline, return 0; } -void TextMetrics::Trace(Visitor* visitor) { +void TextMetrics::Trace(Visitor* visitor) const { visitor->Trace(baselines_); ScriptWrappable::Trace(visitor); } @@ -63,20 +64,56 @@ void TextMetrics::Update(const Font& font, if (!font_data) return; + // TODO(kojii): Need to figure out the desired behavior of |advances| when + // bidi reorder occurs. TextRun text_run( text, /* xpos */ 0, /* expansion */ 0, TextRun::kAllowTrailingExpansion | TextRun::kForbidLeadingExpansion, direction, false); text_run.SetNormalizeSpace(true); - FloatRect bbox = font.BoundingBox(text_run); - const FontMetrics& font_metrics = font_data->GetFontMetrics(); - advances_ = font.IndividualCharacterAdvances(text_run); // x direction - width_ = bbox.Width(); + // Run bidi algorithm on the given text. Step 5 of: + // https://html.spec.whatwg.org/multipage/canvas.html#text-preparation-algorithm FloatRect glyph_bounds; - double real_width = font.Width(text_run, nullptr, &glyph_bounds); + String text16 = text; + text16.Ensure16Bit(); + NGBidiParagraph bidi; + bidi.SetParagraph(text16, direction); + NGBidiParagraph::Runs runs; + bidi.GetLogicalRuns(text16, &runs); + float xpos = 0; + for (const auto& run : runs) { + // Measure each run. + TextRun text_run( + StringView(text, run.start, run.Length()), xpos, /* expansion */ 0, + TextRun::kAllowTrailingExpansion | TextRun::kForbidLeadingExpansion, + run.Direction(), /* directional_override */ false); + text_run.SetNormalizeSpace(true); + FloatRect run_glyph_bounds; + float run_width = font.Width(text_run, nullptr, &run_glyph_bounds); + + // Accumulate the position and the glyph bounding box. + run_glyph_bounds.Move(xpos, 0); + glyph_bounds.Unite(run_glyph_bounds); + xpos += run_width; + } + double real_width = xpos; +#if DCHECK_IS_ON() + // This DCHECK is for limited time only; to use |glyph_bounds| instead of + // |BoundingBox| and make sure they are compatible. + if (runs.size() == 1 && direction == runs[0].Direction()) { + FloatRect bbox = font.BoundingBox(text_run); + // |GetCharacterRange|, the underlying function of |BoundingBox|, clamps + // negative |MaxY| to 0. This is unintentional, and that we are not copying + // the behavior. + DCHECK_EQ(bbox.Y(), std::min(glyph_bounds.Y(), .0f)); + DCHECK_EQ(bbox.MaxY(), std::max(glyph_bounds.MaxY(), .0f)); + DCHECK_EQ(bbox.Width(), real_width); + } +#endif + width_ = real_width; float dx = 0.0f; if (align == kCenterTextAlign) @@ -89,13 +126,14 @@ void TextMetrics::Update(const Font& font, actual_bounding_box_right_ = glyph_bounds.MaxX() - dx; // y direction + const FontMetrics& font_metrics = font_data->GetFontMetrics(); const float ascent = font_metrics.FloatAscent(); const float descent = font_metrics.FloatDescent(); const float baseline_y = GetFontBaseline(baseline, *font_data); font_bounding_box_ascent_ = ascent - baseline_y; font_bounding_box_descent_ = descent + baseline_y; - actual_bounding_box_ascent_ = -bbox.Y() - baseline_y; - actual_bounding_box_descent_ = bbox.MaxY() + baseline_y; + actual_bounding_box_ascent_ = -glyph_bounds.Y() - baseline_y; + actual_bounding_box_descent_ = glyph_bounds.MaxY() + baseline_y; em_height_ascent_ = font_data->EmHeightAscent() - baseline_y; em_height_descent_ = font_data->EmHeightDescent() + baseline_y; diff --git a/chromium/third_party/blink/renderer/core/html/canvas/text_metrics.h b/chromium/third_party/blink/renderer/core/html/canvas/text_metrics.h index 2a3529a53e7..74625069b36 100644 --- a/chromium/third_party/blink/renderer/core/html/canvas/text_metrics.h +++ b/chromium/third_party/blink/renderer/core/html/canvas/text_metrics.h @@ -62,7 +62,7 @@ class CORE_EXPORT TextMetrics final : public ScriptWrappable { static float GetFontBaseline(const TextBaseline&, const SimpleFontData&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void Update(const Font&, diff --git a/chromium/third_party/blink/renderer/core/html/canvas/ukm_parameters.h b/chromium/third_party/blink/renderer/core/html/canvas/ukm_parameters.h new file mode 100644 index 00000000000..fad8e38b0aa --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/canvas/ukm_parameters.h @@ -0,0 +1,20 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CANVAS_UKM_PARAMETERS_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CANVAS_UKM_PARAMETERS_H_ + +#include "services/metrics/public/cpp/ukm_recorder.h" +#include "services/metrics/public/cpp/ukm_source_id.h" + +namespace blink { + +struct UkmParameters { + ukm::UkmRecorder* ukm_recorder; + ukm::SourceId source_id; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_CANVAS_UKM_PARAMETERS_H_ diff --git a/chromium/third_party/blink/renderer/core/html/collection_items_cache.h b/chromium/third_party/blink/renderer/core/html/collection_items_cache.h index c311e300c62..2617e33ed7c 100644 --- a/chromium/third_party/blink/renderer/core/html/collection_items_cache.h +++ b/chromium/third_party/blink/renderer/core/html/collection_items_cache.h @@ -47,7 +47,7 @@ class CollectionItemsCache : public CollectionIndexCache<Collection, NodeType> { CollectionItemsCache(); ~CollectionItemsCache(); - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(cached_list_); Base::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element.cc b/chromium/third_party/blink/renderer/core/html/custom/custom_element.cc index eeca328bf00..4992ea23f77 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/custom_element.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element.cc @@ -158,7 +158,8 @@ Element* CustomElement::CreateUncustomizedOrUndefinedElementTemplate( } Element* element; - if (RuntimeEnabledFeatures::CustomElementsV0Enabled(&document)) { + if (RuntimeEnabledFeatures::CustomElementsV0Enabled( + document.GetExecutionContext())) { if (V0CustomElement::IsValidName(tag_name.LocalName()) && document.RegistrationContext()) { element = document.RegistrationContext()->CreateCustomTagElement( diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_definition.cc b/chromium/third_party/blink/renderer/core/html/custom/custom_element_definition.cc index 3c4b80f4433..75d40046346 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_definition.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_definition.cc @@ -40,7 +40,7 @@ CustomElementDefinition::CustomElementDefinition( CustomElementDefinition::~CustomElementDefinition() = default; -void CustomElementDefinition::Trace(Visitor* visitor) { +void CustomElementDefinition::Trace(Visitor* visitor) const { visitor->Trace(construction_stack_); visitor->Trace(default_style_sheets_); } diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_definition.h b/chromium/third_party/blink/renderer/core/html/custom/custom_element_definition.h index 4df21e145c3..26b288b56ce 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_definition.h +++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_definition.h @@ -42,7 +42,7 @@ class CORE_EXPORT CustomElementDefinition virtual ~CustomElementDefinition(); - virtual void Trace(Visitor*); + virtual void Trace(Visitor*) const; const char* NameInHeapSnapshot() const override { return "CustomElementDefinition"; } diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction.cc b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction.cc index dd88199be20..e7d7109daa4 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction.cc @@ -12,7 +12,7 @@ CustomElementReaction::CustomElementReaction( CustomElementDefinition& definition) : definition_(definition) {} -void CustomElementReaction::Trace(Visitor* visitor) { +void CustomElementReaction::Trace(Visitor* visitor) const { visitor->Trace(definition_); } diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction.h b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction.h index d3f60588e0c..59c30538f23 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction.h +++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction.h @@ -22,7 +22,7 @@ class CORE_EXPORT CustomElementReaction virtual void Invoke(Element&) = 0; - virtual void Trace(Visitor*); + virtual void Trace(Visitor*) const; protected: Member<CustomElementDefinition> definition_; diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_factory.cc b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_factory.cc index 859dd263529..b0a62d6677e 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_factory.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_factory.cc @@ -79,7 +79,7 @@ class CustomElementAdoptedCallbackReaction final DCHECK(definition.HasAdoptedCallback()); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(old_owner_); visitor->Trace(new_owner_); CustomElementReaction::Trace(visitor); @@ -138,7 +138,7 @@ class CustomElementFormAssociatedCallbackReaction final DCHECK(definition.HasFormAssociatedCallback()); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(form_); CustomElementReaction::Trace(visitor); } @@ -206,7 +206,7 @@ class CustomElementFormStateRestoreCallbackReaction final DCHECK(mode == "restore" || mode == "autocomplete"); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(value_); CustomElementReaction::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_queue.cc b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_queue.cc index 0f7c3ea14c1..1e78556eabe 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_queue.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_queue.cc @@ -14,7 +14,7 @@ CustomElementReactionQueue::CustomElementReactionQueue() : index_(0u) {} CustomElementReactionQueue::~CustomElementReactionQueue() = default; -void CustomElementReactionQueue::Trace(Visitor* visitor) { +void CustomElementReactionQueue::Trace(Visitor* visitor) const { visitor->Trace(reactions_); } diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_queue.h b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_queue.h index 34dfc38337b..383236bc063 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_queue.h +++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_queue.h @@ -20,7 +20,7 @@ class CORE_EXPORT CustomElementReactionQueue final CustomElementReactionQueue(); ~CustomElementReactionQueue(); - void Trace(Visitor*); + void Trace(Visitor*) const; void Add(CustomElementReaction&); void InvokeReactions(Element&); diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack.cc b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack.cc index 990283baa64..828b7c84da8 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack.cc @@ -28,7 +28,7 @@ Persistent<CustomElementReactionStack>& GetCustomElementReactionStack() { CustomElementReactionStack::CustomElementReactionStack() = default; -void CustomElementReactionStack::Trace(Visitor* visitor) { +void CustomElementReactionStack::Trace(Visitor* visitor) const { visitor->Trace(map_); visitor->Trace(stack_); visitor->Trace(backup_queue_); diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack.h b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack.h index 9b10239b270..44b6a986005 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack.h +++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack.h @@ -23,7 +23,7 @@ class CORE_EXPORT CustomElementReactionStack final public: CustomElementReactionStack(); - void Trace(Visitor*); + void Trace(Visitor*) const; const char* NameInHeapSnapshot() const override { return "CustomElementReactionStack"; } diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack_test.cc b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack_test.cc index 7bfb1712cfe..b3a8d86dab5 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack_test.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_stack_test.cc @@ -192,7 +192,7 @@ class EnqueueToStack : public Command { CustomElementReaction* reaction) : stack_(stack), element_(element), reaction_(reaction) {} ~EnqueueToStack() override = default; - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { Command::Trace(visitor); visitor->Trace(stack_); visitor->Trace(element_); diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_test_helpers.h b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_test_helpers.h index 6450df0d6ec..ee3a1291d03 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_test_helpers.h +++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_reaction_test_helpers.h @@ -26,7 +26,7 @@ class Command : public GarbageCollected<Command> { public: Command() = default; virtual ~Command() = default; - virtual void Trace(Visitor* visitor) {} + virtual void Trace(Visitor* visitor) const {} virtual void Run(Element&) = 0; DISALLOW_COPY_AND_ASSIGN(Command); @@ -74,7 +74,7 @@ class Recurse : public Command { public: Recurse(CustomElementReactionQueue* queue) : queue_(queue) {} ~Recurse() override = default; - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { Command::Trace(visitor); visitor->Trace(queue_); } @@ -91,7 +91,7 @@ class Enqueue : public Command { Enqueue(CustomElementReactionQueue* queue, CustomElementReaction* reaction) : queue_(queue), reaction_(reaction) {} ~Enqueue() override = default; - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { Command::Trace(visitor); visitor->Trace(queue_); visitor->Trace(reaction_); @@ -113,7 +113,7 @@ class TestReaction : public CustomElementReaction { CustomElementDescriptor("mock-element", "mock-element"))), commands_(commands) {} ~TestReaction() override = default; - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { CustomElementReaction::Trace(visitor); visitor->Trace(commands_); } diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.cc b/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.cc index f1579312558..1bf7934ec3d 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.cc @@ -87,7 +87,7 @@ CustomElementRegistry::CustomElementRegistry(const LocalDOMWindow* owner) Entangle(v0); } -void CustomElementRegistry::Trace(Visitor* visitor) { +void CustomElementRegistry::Trace(Visitor* visitor) const { visitor->Trace(definitions_); visitor->Trace(owner_); visitor->Trace(v0_); diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.h b/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.h index 3c959f93747..9f4d9ef6145 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.h +++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry.h @@ -62,7 +62,7 @@ class CORE_EXPORT CustomElementRegistry final : public ScriptWrappable { void Entangle(V0CustomElementRegistrationContext*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: CustomElementDefinition* DefineInternal(ScriptState*, diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry_test.cc b/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry_test.cc index c50d69d521f..2696ad7e5f9 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry_test.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_registry_test.cc @@ -78,7 +78,7 @@ TEST_F(CustomElementRegistryTest, Element* element = CreateElement("a-a").InDocument(&GetDocument()); Registry().AddCandidate(*element); - auto* other_document = MakeGarbageCollected<HTMLDocument>(); + auto* other_document = HTMLDocument::CreateForTest(); other_document->AppendChild(element); EXPECT_EQ(other_document, element->ownerDocument()) << "sanity: another document should have adopted an element on append"; @@ -173,7 +173,7 @@ class LogUpgradeDefinition : public TestCustomElementDefinition { }, {}) {} - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { TestCustomElementDefinition::Trace(visitor); visitor->Trace(element_); visitor->Trace(adopted_); @@ -205,7 +205,7 @@ class LogUpgradeDefinition : public TestCustomElementDefinition { Member<Document> old_owner_; Member<Document> new_owner_; - void Trace(Visitor* visitor) { + void Trace(Visitor* visitor) const { visitor->Trace(old_owner_); visitor->Trace(new_owner_); } @@ -398,7 +398,7 @@ TEST_F(CustomElementRegistryTest, adoptedCallback) { static_cast<LogUpgradeDefinition*>(Registry().DefinitionForName("a-a")); definition->Clear(); - auto* other_document = MakeGarbageCollected<HTMLDocument>(); + auto* other_document = HTMLDocument::CreateForTest(); { CEReactionsScope reactions; other_document->adoptNode(element, ASSERT_NO_EXCEPTION); diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_test_helpers.h b/chromium/third_party/blink/renderer/core/html/custom/custom_element_test_helpers.h index 915324b0e8b..03a18e0f77b 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_test_helpers.h +++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_test_helpers.h @@ -154,7 +154,7 @@ class CreateElement { operator Element*() const { Document* document = document_; if (!document) - document = MakeGarbageCollected<HTMLDocument>(); + document = HTMLDocument::CreateForTest(); NonThrowableExceptionState no_exceptions; Element* element = document->CreateElement( QualifiedName(g_null_atom, local_name_, namespace_uri_), diff --git a/chromium/third_party/blink/renderer/core/html/custom/custom_element_upgrade_sorter_test.cc b/chromium/third_party/blink/renderer/core/html/custom/custom_element_upgrade_sorter_test.cc index f82ce78f372..924c2b38c7c 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/custom_element_upgrade_sorter_test.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/custom_element_upgrade_sorter_test.cc @@ -43,7 +43,7 @@ TEST_F(CustomElementUpgradeSorterTest, inOtherDocument_notInSet) { Element* element = GetDocument().CreateElementForBinding( "a-a", StringOrElementCreationOptions(), no_exceptions); - auto* other_document = MakeGarbageCollected<HTMLDocument>(); + auto* other_document = HTMLDocument::CreateForTest(); other_document->AppendChild(element); EXPECT_EQ(other_document, element->ownerDocument()) << "sanity: another document should have adopted an element on append"; diff --git a/chromium/third_party/blink/renderer/core/html/custom/element_internals.cc b/chromium/third_party/blink/renderer/core/html/custom/element_internals.cc index 731e5ebcad3..e879e1fbb08 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/element_internals.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/element_internals.cc @@ -49,7 +49,7 @@ class CustomStatesTokenList : public DOMTokenList { ElementInternals::ElementInternals(HTMLElement& target) : target_(target) { } -void ElementInternals::Trace(Visitor* visitor) { +void ElementInternals::Trace(Visitor* visitor) const { visitor->Trace(target_); visitor->Trace(value_); visitor->Trace(state_); diff --git a/chromium/third_party/blink/renderer/core/html/custom/element_internals.h b/chromium/third_party/blink/renderer/core/html/custom/element_internals.h index 18519174b08..4f2effbb1e7 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/element_internals.h +++ b/chromium/third_party/blink/renderer/core/html/custom/element_internals.h @@ -25,7 +25,7 @@ class CORE_EXPORT ElementInternals : public ScriptWrappable, public: ElementInternals(HTMLElement& target); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; HTMLElement& Target() const { return *target_; } void DidUpgrade(); diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element.cc index 08aa4240504..3b91ebaa6a9 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element.cc @@ -48,8 +48,8 @@ V0CustomElementMicrotaskImportStep* V0CustomElement::DidCreateImport( return V0CustomElementScheduler::ScheduleImport(import); } -void V0CustomElement::DidFinishLoadingImport(Document& master) { - master.CustomElementMicrotaskRunQueue()->RequestDispatchIfNeeded(); +void V0CustomElement::DidFinishLoadingImport(Document& tree_root) { + tree_root.CustomElementMicrotaskRunQueue()->RequestDispatchIfNeeded(); } static inline bool IsValidNCName(const AtomicString& name) { diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element.h index 3fffa8901fd..0c3e255a3ae 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element.h +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element.h @@ -52,7 +52,7 @@ class CORE_EXPORT V0CustomElement { // API to notify of document-level changes static V0CustomElementMicrotaskImportStep* DidCreateImport(HTMLImportChild*); - static void DidFinishLoadingImport(Document& master); + static void DidFinishLoadingImport(Document& tree_root); // API for registration contexts static void Define(Element*, V0CustomElementDefinition*); diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_invocation.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_invocation.cc index 8550ba58cb0..47cb0add209 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_invocation.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_invocation.cc @@ -145,7 +145,7 @@ V0CustomElementCallbackInvocation::CreateAttributeChangedInvocation( old_value, new_value); } -void V0CustomElementCallbackInvocation::Trace(Visitor* visitor) { +void V0CustomElementCallbackInvocation::Trace(Visitor* visitor) const { visitor->Trace(callbacks_); V0CustomElementProcessingStep::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_invocation.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_invocation.h index 23e40003a9d..3250a3a330e 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_invocation.h +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_invocation.h @@ -56,7 +56,7 @@ class V0CustomElementCallbackInvocation : public V0CustomElementProcessingStep { V0CustomElementLifecycleCallbacks* Callbacks() { return callbacks_.Get(); } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<V0CustomElementLifecycleCallbacks> callbacks_; diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_queue.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_queue.cc index 4bdeeaee120..0a9718ddad8 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_queue.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_queue.cc @@ -68,7 +68,7 @@ bool V0CustomElementCallbackQueue::ProcessInElementQueue( return did_work; } -void V0CustomElementCallbackQueue::Trace(Visitor* visitor) { +void V0CustomElementCallbackQueue::Trace(Visitor* visitor) const { visitor->Trace(element_); visitor->Trace(queue_); } diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_queue.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_queue.h index 2ab98cd078f..22290f77bd3 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_queue.h +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_callback_queue.h @@ -63,7 +63,7 @@ class V0CustomElementCallbackQueue } bool InCreatedCallback() const { return in_created_callback_; } - void Trace(Visitor*); + void Trace(Visitor*) const; private: Member<Element> element_; diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_definition.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_definition.cc index e8b8a80ae74..1795303dde1 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_definition.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_definition.cc @@ -37,7 +37,7 @@ V0CustomElementDefinition::V0CustomElementDefinition( V0CustomElementLifecycleCallbacks* callbacks) : descriptor_(descriptor), callbacks_(callbacks) {} -void V0CustomElementDefinition::Trace(Visitor* visitor) { +void V0CustomElementDefinition::Trace(Visitor* visitor) const { visitor->Trace(callbacks_); } diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_definition.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_definition.h index 79b5530aac3..a5af9378ace 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_definition.h +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_definition.h @@ -47,7 +47,7 @@ class V0CustomElementDefinition final return callbacks_.Get(); } - void Trace(Visitor*); + void Trace(Visitor*) const; private: V0CustomElementDescriptor descriptor_; diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_exception.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_exception.cc index e199eaadd23..d321126ef9f 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_exception.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_exception.cc @@ -30,6 +30,7 @@ #include "third_party/blink/renderer/core/html/custom/v0_custom_element_exception.h" +#include "base/notreached.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_lifecycle_callbacks.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_lifecycle_callbacks.h index ea4407a710e..06190fc0ea2 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_lifecycle_callbacks.h +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_lifecycle_callbacks.h @@ -61,7 +61,7 @@ class V0CustomElementLifecycleCallbacks const AtomicString& old_value, const AtomicString& new_value) = 0; - virtual void Trace(Visitor* visitor) {} + virtual void Trace(Visitor* visitor) const {} protected: explicit V0CustomElementLifecycleCallbacks(CallbackType type) diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_dispatcher.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_dispatcher.cc index fe023ce0db4..1c781204b72 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_dispatcher.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_dispatcher.cc @@ -76,7 +76,7 @@ void V0CustomElementMicrotaskDispatcher::DoDispatch() { phase_ = kQuiescent; } -void V0CustomElementMicrotaskDispatcher::Trace(Visitor* visitor) { +void V0CustomElementMicrotaskDispatcher::Trace(Visitor* visitor) const { visitor->Trace(elements_); } diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_dispatcher.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_dispatcher.h index 9aa1567285a..0eed206c421 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_dispatcher.h +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_dispatcher.h @@ -24,7 +24,7 @@ class V0CustomElementMicrotaskDispatcher final bool ElementQueueIsEmpty() { return elements_.IsEmpty(); } - void Trace(Visitor*); + void Trace(Visitor*) const; private: void EnsureMicrotaskScheduledForElementQueue(); diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_import_step.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_import_step.cc index f4025118dc0..fcf21c00af0 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_import_step.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_import_step.cc @@ -70,7 +70,7 @@ V0CustomElementMicrotaskImportStep::Process() { return kFinishedProcessing; } -void V0CustomElementMicrotaskImportStep::Trace(Visitor* visitor) { +void V0CustomElementMicrotaskImportStep::Trace(Visitor* visitor) const { visitor->Trace(import_); visitor->Trace(queue_); V0CustomElementMicrotaskStep::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_import_step.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_import_step.h index c4c7efb9f29..566af67cfb2 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_import_step.h +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_import_step.h @@ -55,7 +55,7 @@ class V0CustomElementMicrotaskImportStep final void Invalidate(); void ImportDidFinishLoading(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void DidUpgradeAllCustomElements(); diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_queue_base.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_queue_base.cc index f043853f4df..25efaad36df 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_queue_base.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_queue_base.cc @@ -15,7 +15,7 @@ void V0CustomElementMicrotaskQueueBase::Dispatch() { in_dispatch_ = false; } -void V0CustomElementMicrotaskQueueBase::Trace(Visitor* visitor) { +void V0CustomElementMicrotaskQueueBase::Trace(Visitor* visitor) const { visitor->Trace(queue_); } diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_queue_base.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_queue_base.h index 8855eee71d8..da4c6f039b6 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_queue_base.h +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_queue_base.h @@ -20,7 +20,7 @@ class V0CustomElementMicrotaskQueueBase bool IsEmpty() const { return queue_.IsEmpty(); } void Dispatch(); - void Trace(Visitor*); + void Trace(Visitor*) const; #if !defined(NDEBUG) void Show(unsigned indent); diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.cc index 22b212dbb61..f0a9f551f81 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.cc @@ -50,7 +50,7 @@ V0CustomElementMicrotaskResolutionStep::Process() { return V0CustomElementMicrotaskStep::kFinishedProcessing; } -void V0CustomElementMicrotaskResolutionStep::Trace(Visitor* visitor) { +void V0CustomElementMicrotaskResolutionStep::Trace(Visitor* visitor) const { visitor->Trace(context_); visitor->Trace(element_); V0CustomElementMicrotaskStep::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.h index 2d28a2dcb85..5288b6f9562 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.h +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_resolution_step.h @@ -48,7 +48,7 @@ class V0CustomElementMicrotaskResolutionStep final const V0CustomElementDescriptor&); ~V0CustomElementMicrotaskResolutionStep() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Result Process() override; diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_run_queue.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_run_queue.cc index 5bc637f3a4c..20a96fef1b0 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_run_queue.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_run_queue.cc @@ -42,7 +42,7 @@ void V0CustomElementMicrotaskRunQueue::RequestDispatchIfNeeded() { dispatch_is_pending_ = true; } -void V0CustomElementMicrotaskRunQueue::Trace(Visitor* visitor) { +void V0CustomElementMicrotaskRunQueue::Trace(Visitor* visitor) const { visitor->Trace(sync_queue_); visitor->Trace(async_queue_); } diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_run_queue.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_run_queue.h index b46ba996068..d6e3a8a6d06 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_run_queue.h +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_run_queue.h @@ -25,7 +25,7 @@ class V0CustomElementMicrotaskRunQueue void RequestDispatchIfNeeded(); bool IsEmpty() const; - void Trace(Visitor*); + void Trace(Visitor*) const; private: void Dispatch(); diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_step.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_step.h index 27f49c78ef0..3da59d78f1e 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_step.h +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_microtask_step.h @@ -46,7 +46,7 @@ class V0CustomElementMicrotaskStep virtual Result Process() = 0; - virtual void Trace(Visitor* visitor) {} + virtual void Trace(Visitor* visitor) const {} #if !defined(NDEBUG) virtual void Show(unsigned indent) = 0; diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_observer.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_observer.h index 1c95d5febcd..c05ea7ddc78 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_observer.h +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_observer.h @@ -46,7 +46,7 @@ class V0CustomElementObserver // API for CustomElement to kick off notifications static void NotifyElementWasDestroyed(Element*); - virtual void Trace(Visitor* visitor) {} + virtual void Trace(Visitor* visitor) const {} protected: V0CustomElementObserver() = default; diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.cc index 63e9648790b..627a3773747 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.cc @@ -92,7 +92,7 @@ void V0CustomElementProcessingStack::Enqueue( ++element_queue_end_; } -void V0CustomElementProcessingStack::Trace(Visitor* visitor) { +void V0CustomElementProcessingStack::Trace(Visitor* visitor) const { visitor->Trace(flattened_processing_stack_); } diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.h index 62717b7e79e..c932c36806d 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.h +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.h @@ -77,7 +77,7 @@ class CORE_EXPORT V0CustomElementProcessingStack static V0CustomElementProcessingStack& Instance(); void Enqueue(V0CustomElementCallbackQueue*); - void Trace(Visitor*); + void Trace(Visitor*) const; private: // The start of the element queue on the top of the processing diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_step.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_step.h index 64e2314be3e..23ff9aa87bb 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_step.h +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_processing_step.h @@ -45,7 +45,7 @@ class V0CustomElementProcessingStep virtual void Dispatch(Element*) = 0; virtual bool IsCreatedCallback() const { return false; } - virtual void Trace(Visitor* visitor) {} + virtual void Trace(Visitor* visitor) const {} DISALLOW_COPY_AND_ASSIGN(V0CustomElementProcessingStep); }; diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.cc index fa37f647b30..07ba6362261 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.cc @@ -178,7 +178,7 @@ void V0CustomElementRegistrationContext::SetV1( registry_.SetV1(v1); } -void V0CustomElementRegistrationContext::Trace(Visitor* visitor) { +void V0CustomElementRegistrationContext::Trace(Visitor* visitor) const { visitor->Trace(candidates_); visitor->Trace(registry_); } diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.h index b810d5c081a..9e7baee49de 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.h +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.h @@ -65,7 +65,7 @@ class V0CustomElementRegistrationContext final bool NameIsDefined(const AtomicString& name) const; void SetV1(const CustomElementRegistry*); - void Trace(Visitor*); + void Trace(Visitor*) const; // Instance creation void DidGiveTypeExtension(Element*, const AtomicString& type); diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registry.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registry.cc index c613e26f294..9d4fb89945c 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registry.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registry.cc @@ -141,7 +141,7 @@ bool V0CustomElementRegistry::V1NameIsDefined(const AtomicString& name) const { return v1_.Get() && v1_->NameIsDefined(name); } -void V0CustomElementRegistry::Trace(Visitor* visitor) { +void V0CustomElementRegistry::Trace(Visitor* visitor) const { visitor->Trace(definitions_); visitor->Trace(v1_); } diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registry.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registry.h index 477589e2fdf..8f43354c6af 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registry.h +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_registry.h @@ -51,7 +51,7 @@ class V0CustomElementRegistry final { DISALLOW_NEW(); public: - void Trace(Visitor*); + void Trace(Visitor*) const; void DocumentWasDetached() { document_was_detached_ = true; } protected: diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_scheduler.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_scheduler.cc index 7e9edadcea2..91b860eba41 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_scheduler.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_scheduler.cc @@ -149,11 +149,11 @@ void V0CustomElementScheduler::EnqueueMicrotaskStep( Document& document, V0CustomElementMicrotaskStep* step, bool import_is_sync) { - Document& master = document.ImportsController() - ? *(document.ImportsController()->Master()) - : document; - master.CustomElementMicrotaskRunQueue()->Enqueue(document.ImportLoader(), - step, import_is_sync); + Document& tree_root = document.ImportsController() + ? *(document.ImportsController()->TreeRoot()) + : document; + tree_root.CustomElementMicrotaskRunQueue()->Enqueue(document.ImportLoader(), + step, import_is_sync); } void V0CustomElementScheduler::CallbackDispatcherDidFinish() { diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_upgrade_candidate_map.cc b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_upgrade_candidate_map.cc index ee4ffdbb92e..28c5c0fc581 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_upgrade_candidate_map.cc +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_upgrade_candidate_map.cc @@ -85,7 +85,7 @@ V0CustomElementUpgradeCandidateMap::TakeUpgradeCandidatesFor( return candidates; } -void V0CustomElementUpgradeCandidateMap::Trace(Visitor* visitor) { +void V0CustomElementUpgradeCandidateMap::Trace(Visitor* visitor) const { visitor->Trace(upgrade_candidates_); visitor->Trace(unresolved_definitions_); V0CustomElementObserver::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_upgrade_candidate_map.h b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_upgrade_candidate_map.h index b91c4ab656b..ee0232f17cb 100644 --- a/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_upgrade_candidate_map.h +++ b/chromium/third_party/blink/renderer/core/html/custom/v0_custom_element_upgrade_candidate_map.h @@ -53,7 +53,7 @@ class V0CustomElementUpgradeCandidateMap final void Add(const V0CustomElementDescriptor&, Element*); ElementSet* TakeUpgradeCandidatesFor(const V0CustomElementDescriptor&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void ElementWasDestroyed(Element*) override; diff --git a/chromium/third_party/blink/renderer/core/html/forms/base_button_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/base_button_input_type.cc index 793b040d25e..170107b5c91 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/base_button_input_type.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/base_button_input_type.cc @@ -45,7 +45,7 @@ namespace blink { BaseButtonInputType::BaseButtonInputType(HTMLInputElement& element) : InputType(element), KeyboardClickableInputTypeView(element) {} -void BaseButtonInputType::Trace(Visitor* visitor) { +void BaseButtonInputType::Trace(Visitor* visitor) const { KeyboardClickableInputTypeView::Trace(visitor); InputType::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/forms/base_button_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/base_button_input_type.h index b048c471560..a4a409e6c2f 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/base_button_input_type.h +++ b/chromium/third_party/blink/renderer/core/html/forms/base_button_input_type.h @@ -42,7 +42,7 @@ class BaseButtonInputType : public InputType, USING_GARBAGE_COLLECTED_MIXIN(BaseButtonInputType); public: - void Trace(Visitor*) override; + void Trace(Visitor*) const override; using InputType::GetElement; protected: diff --git a/chromium/third_party/blink/renderer/core/html/forms/base_checkable_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/base_checkable_input_type.cc index 93da5c3d371..d13e518a241 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/base_checkable_input_type.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/base_checkable_input_type.cc @@ -42,7 +42,7 @@ namespace blink { -void BaseCheckableInputType::Trace(Visitor* visitor) { +void BaseCheckableInputType::Trace(Visitor* visitor) const { InputTypeView::Trace(visitor); InputType::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/forms/base_checkable_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/base_checkable_input_type.h index d9696d33e8b..4fc9dec87d3 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/base_checkable_input_type.h +++ b/chromium/third_party/blink/renderer/core/html/forms/base_checkable_input_type.h @@ -41,7 +41,7 @@ class BaseCheckableInputType : public InputType, public InputTypeView { USING_GARBAGE_COLLECTED_MIXIN(BaseCheckableInputType); public: - void Trace(Visitor*) override; + void Trace(Visitor*) const override; using InputType::GetElement; protected: diff --git a/chromium/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.cc b/chromium/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.cc index d7eab0be39e..cfc7dc21375 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.cc @@ -47,7 +47,7 @@ ChooserOnlyTemporalInputTypeView::~ChooserOnlyTemporalInputTypeView() { DCHECK(!date_time_chooser_); } -void ChooserOnlyTemporalInputTypeView::Trace(Visitor* visitor) { +void ChooserOnlyTemporalInputTypeView::Trace(Visitor* visitor) const { visitor->Trace(input_type_); visitor->Trace(date_time_chooser_); InputTypeView::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.h b/chromium/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.h index 5e6f0b64d04..86d74e64c87 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.h +++ b/chromium/third_party/blink/renderer/core/html/forms/chooser_only_temporal_input_type_view.h @@ -44,7 +44,7 @@ class ChooserOnlyTemporalInputTypeView final public: ChooserOnlyTemporalInputTypeView(HTMLInputElement&, BaseTemporalInputType&); ~ChooserOnlyTemporalInputTypeView() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void CloseDateTimeChooser(); diff --git a/chromium/third_party/blink/renderer/core/html/forms/chooser_resource_loader.cc b/chromium/third_party/blink/renderer/core/html/forms/chooser_resource_loader.cc index 466a24b1082..61f4faf8d04 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/chooser_resource_loader.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/chooser_resource_loader.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/core/html/forms/chooser_resource_loader.h" +#include "base/notreached.h" #include "build/build_config.h" #include "third_party/blink/public/resources/grit/blink_resources.h" #include "third_party/blink/renderer/platform/data_resource_helper.h" diff --git a/chromium/third_party/blink/renderer/core/html/forms/clear_button_element.cc b/chromium/third_party/blink/renderer/core/html/forms/clear_button_element.cc index ee7210927ea..953e576733a 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/clear_button_element.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/clear_button_element.cc @@ -73,7 +73,7 @@ bool ClearButtonElement::IsClearButtonElement() const { return true; } -void ClearButtonElement::Trace(Visitor* visitor) { +void ClearButtonElement::Trace(Visitor* visitor) const { visitor->Trace(clear_button_owner_); HTMLDivElement::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/forms/clear_button_element.h b/chromium/third_party/blink/renderer/core/html/forms/clear_button_element.h index bcedfe36f09..c2ab150daf8 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/clear_button_element.h +++ b/chromium/third_party/blink/renderer/core/html/forms/clear_button_element.h @@ -45,7 +45,7 @@ class ClearButtonElement final : public HTMLDivElement { void RemoveClearButtonOwner() { clear_button_owner_ = nullptr; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void DetachLayoutTree(bool performing_reattach) override; diff --git a/chromium/third_party/blink/renderer/core/html/forms/color_chooser.h b/chromium/third_party/blink/renderer/core/html/forms/color_chooser.h index 051e20a4bdd..07a22f69960 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/color_chooser.h +++ b/chromium/third_party/blink/renderer/core/html/forms/color_chooser.h @@ -43,7 +43,7 @@ class CORE_EXPORT ColorChooser : public GarbageCollectedMixin { public: ColorChooser(); virtual ~ColorChooser(); - void Trace(Visitor* visitor) override {} + void Trace(Visitor* visitor) const override {} // Call to update the selection in the UI. Used to reflect value changes made // by JS. diff --git a/chromium/third_party/blink/renderer/core/html/forms/color_chooser_client.h b/chromium/third_party/blink/renderer/core/html/forms/color_chooser_client.h index 292e216ff7a..bf1f4190be7 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/color_chooser_client.h +++ b/chromium/third_party/blink/renderer/core/html/forms/color_chooser_client.h @@ -46,7 +46,7 @@ class Element; class CORE_EXPORT ColorChooserClient : public GarbageCollectedMixin { public: virtual ~ColorChooserClient(); - void Trace(Visitor* visitor) override {} + void Trace(Visitor* visitor) const override {} // Called when a color is chosen by the user in the ColorChooser UI. virtual void DidChooseColor(const Color&) = 0; diff --git a/chromium/third_party/blink/renderer/core/html/forms/color_chooser_popup_ui_controller.cc b/chromium/third_party/blink/renderer/core/html/forms/color_chooser_popup_ui_controller.cc index 5dc4c58a213..27ad8e3dd86 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/color_chooser_popup_ui_controller.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/color_chooser_popup_ui_controller.cc @@ -63,7 +63,7 @@ ColorChooserPopupUIController::~ColorChooserPopupUIController() { DCHECK(!popup_); } -void ColorChooserPopupUIController::Trace(Visitor* visitor) { +void ColorChooserPopupUIController::Trace(Visitor* visitor) const { visitor->Trace(chrome_client_); visitor->Trace(eye_dropper_chooser_); ColorChooserUIController::Trace(visitor); @@ -102,7 +102,9 @@ void ColorChooserPopupUIController::WriteColorPickerDocument( client_->ElementRectRelativeToViewport(), frame_->View()); PagePopupClient::AddString( - "<!DOCTYPE html><head><meta charset='UTF-8'><style>\n", data); + "<!DOCTYPE html><head><meta charset='UTF-8'><meta name='color-scheme' " + "content='light dark'><style>\n", + data); data->Append(ChooserResourceLoader::GetPickerCommonStyleSheet()); data->Append(ChooserResourceLoader::GetColorPickerStyleSheet()); PagePopupClient::AddString( @@ -161,7 +163,9 @@ void ColorChooserPopupUIController::WriteColorSuggestionPickerDocument( client_->ElementRectRelativeToViewport(), frame_->View()); PagePopupClient::AddString( - "<!DOCTYPE html><head><meta charset='UTF-8'><style>\n", data); + "<!DOCTYPE html><head><meta charset='UTF-8'><meta name='color-scheme' " + "content='light dark'><style>\n", + data); data->Append(ChooserResourceLoader::GetPickerCommonStyleSheet()); data->Append(ChooserResourceLoader::GetColorSuggestionPickerStyleSheet()); if (features::IsFormControlsRefreshEnabled()) @@ -225,6 +229,7 @@ void ColorChooserPopupUIController::SetValue(const String& value) { void ColorChooserPopupUIController::DidClosePopup() { popup_ = nullptr; + eye_dropper_chooser_.reset(); if (!chooser_) EndChooser(); diff --git a/chromium/third_party/blink/renderer/core/html/forms/color_chooser_popup_ui_controller.h b/chromium/third_party/blink/renderer/core/html/forms/color_chooser_popup_ui_controller.h index 0984c237224..62be6d5aee9 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/color_chooser_popup_ui_controller.h +++ b/chromium/third_party/blink/renderer/core/html/forms/color_chooser_popup_ui_controller.h @@ -48,7 +48,7 @@ class CORE_EXPORT ColorChooserPopupUIController final ChromeClient*, blink::ColorChooserClient*); ~ColorChooserPopupUIController() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // ColorChooserUIController functions: void OpenUI() override; diff --git a/chromium/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.cc b/chromium/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.cc index 8bce77ac6c3..e94e4ff79df 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.cc @@ -44,7 +44,7 @@ ColorChooserUIController::ColorChooserUIController( ColorChooserUIController::~ColorChooserUIController() = default; -void ColorChooserUIController::Trace(Visitor* visitor) { +void ColorChooserUIController::Trace(Visitor* visitor) const { visitor->Trace(receiver_); visitor->Trace(frame_); visitor->Trace(client_); diff --git a/chromium/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.h b/chromium/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.h index bccebbd339f..dbc461c9ef3 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.h +++ b/chromium/third_party/blink/renderer/core/html/forms/color_chooser_ui_controller.h @@ -50,7 +50,7 @@ class CORE_EXPORT ColorChooserUIController public: ColorChooserUIController(LocalFrame*, blink::ColorChooserClient*); ~ColorChooserUIController() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void Dispose(); diff --git a/chromium/third_party/blink/renderer/core/html/forms/color_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/color_input_type.cc index 75a2290469c..5a0bd274f8e 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/color_input_type.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/color_input_type.cc @@ -80,7 +80,7 @@ ColorInputType::ColorInputType(HTMLInputElement& element) ColorInputType::~ColorInputType() = default; -void ColorInputType::Trace(Visitor* visitor) { +void ColorInputType::Trace(Visitor* visitor) const { visitor->Trace(chooser_); KeyboardClickableInputTypeView::Trace(visitor); ColorChooserClient::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/core/html/forms/color_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/color_input_type.h index 2e75cb058aa..e315fa14095 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/color_input_type.h +++ b/chromium/third_party/blink/renderer/core/html/forms/color_input_type.h @@ -47,7 +47,7 @@ class ColorInputType final : public InputType, public: explicit ColorInputType(HTMLInputElement&); ~ColorInputType() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; using InputType::GetElement; // ColorChooserClient implementation. diff --git a/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser.h b/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser.h index 07cbacb625f..19416be49e2 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser.h +++ b/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser.h @@ -84,7 +84,7 @@ class CORE_EXPORT DateTimeChooser : public GarbageCollected<DateTimeChooser> { // Returns a root AXObject in the DateTimeChooser if it's available. virtual AXObject* RootAXObject() = 0; - virtual void Trace(Visitor* visitor) {} + virtual void Trace(Visitor* visitor) const {} }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser_client.h b/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser_client.h index 7c65f22c8f8..d69e3911637 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser_client.h +++ b/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser_client.h @@ -42,7 +42,7 @@ class Element; class CORE_EXPORT DateTimeChooserClient : public GarbageCollectedMixin { public: virtual ~DateTimeChooserClient(); - void Trace(Visitor* visitor) override {} + void Trace(Visitor* visitor) const override {} virtual Element& OwnerElement() const = 0; // Called when user picked a value. diff --git a/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.cc b/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.cc index ca0dababf14..186015ed290 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.cc @@ -69,7 +69,7 @@ DateTimeChooserImpl::DateTimeChooserImpl( DateTimeChooserImpl::~DateTimeChooserImpl() = default; -void DateTimeChooserImpl::Trace(Visitor* visitor) { +void DateTimeChooserImpl::Trace(Visitor* visitor) const { visitor->Trace(frame_); visitor->Trace(client_); DateTimeChooser::Trace(visitor); @@ -125,7 +125,7 @@ void DateTimeChooserImpl::WriteDocument(SharedBuffer* data) { AddString( "<!DOCTYPE html><head><meta charset='UTF-8'><meta name='color-scheme' " - "content='light,dark'><style>\n", + "content='light dark'><style>\n", data); data->Append(ChooserResourceLoader::GetPickerCommonStyleSheet()); diff --git a/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.h b/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.h index 22bca47ad27..698916d4773 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.h +++ b/chromium/third_party/blink/renderer/core/html/forms/date_time_chooser_impl.h @@ -55,7 +55,7 @@ class CORE_EXPORT DateTimeChooserImpl final : public DateTimeChooser, void EndChooser() override; AXObject* RootAXObject() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // PagePopupClient functions: diff --git a/chromium/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc b/chromium/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc index a22fc3b2088..841b8313117 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/date_time_edit_element.cc @@ -540,7 +540,7 @@ DateTimeEditElement::DateTimeEditElement(Document& document, DateTimeEditElement::~DateTimeEditElement() = default; -void DateTimeEditElement::Trace(Visitor* visitor) { +void DateTimeEditElement::Trace(Visitor* visitor) const { visitor->Trace(fields_); visitor->Trace(edit_control_owner_); HTMLDivElement::Trace(visitor); @@ -847,6 +847,13 @@ bool DateTimeEditElement::HasFocusedField() { return FocusedFieldIndex() != kInvalidFieldIndex; } +void PopulateOnlyYearMonthDay(const DateComponents& date, + DateTimeFieldsState& date_time_fields_state) { + date_time_fields_state.SetYear(date.FullYear()); + date_time_fields_state.SetMonth(date.Month() + 1); + date_time_fields_state.SetDayOfMonth(date.MonthDay()); +} + void DateTimeEditElement::SetOnlyYearMonthDay(const DateComponents& date) { DCHECK_EQ(date.GetType(), DateComponents::kDate); @@ -854,20 +861,13 @@ void DateTimeEditElement::SetOnlyYearMonthDay(const DateComponents& date) { return; DateTimeFieldsState date_time_fields_state = ValueAsDateTimeFieldsState(); - date_time_fields_state.SetYear(date.FullYear()); - date_time_fields_state.SetMonth(date.Month() + 1); - date_time_fields_state.SetDayOfMonth(date.MonthDay()); + PopulateOnlyYearMonthDay(date, date_time_fields_state); SetValueAsDateTimeFieldsState(date_time_fields_state); edit_control_owner_->EditControlValueChanged(); } -void DateTimeEditElement::SetOnlyTime(const DateComponents& date) { - DCHECK_EQ(date.GetType(), DateComponents::kTime); - - if (!edit_control_owner_) - return; - - DateTimeFieldsState date_time_fields_state = ValueAsDateTimeFieldsState(); +void PopulateOnlyTime(const DateComponents& date, + DateTimeFieldsState& date_time_fields_state) { date_time_fields_state.SetHour(date.Hour() % 12 ? date.Hour() % 12 : 12); date_time_fields_state.SetMinute(date.Minute()); date_time_fields_state.SetSecond(date.Second()); @@ -875,6 +875,34 @@ void DateTimeEditElement::SetOnlyTime(const DateComponents& date) { date_time_fields_state.SetAMPM(date.Hour() >= 12 ? DateTimeFieldsState::kAMPMValuePM : DateTimeFieldsState::kAMPMValueAM); +} + +void DateTimeEditElement::SetOnlyTime(const DateComponents& date) { + DCHECK_EQ(date.GetType(), DateComponents::kTime); + + if (!edit_control_owner_) + return; + + DateTimeFieldsState date_time_fields_state = ValueAsDateTimeFieldsState(); + PopulateOnlyTime(date, date_time_fields_state); + SetValueAsDateTimeFieldsState(date_time_fields_state); + edit_control_owner_->EditControlValueChanged(); +} + +void PopulateDateTimeLocal(const DateComponents& date, + DateTimeFieldsState& date_time_fields_state) { + PopulateOnlyYearMonthDay(date, date_time_fields_state); + PopulateOnlyTime(date, date_time_fields_state); +} + +void DateTimeEditElement::SetDateTimeLocal(const DateComponents& date) { + DCHECK_EQ(date.GetType(), DateComponents::kDateTimeLocal); + + if (!edit_control_owner_) + return; + + DateTimeFieldsState date_time_fields_state = ValueAsDateTimeFieldsState(); + PopulateDateTimeLocal(date, date_time_fields_state); SetValueAsDateTimeFieldsState(date_time_fields_state); edit_control_owner_->EditControlValueChanged(); } diff --git a/chromium/third_party/blink/renderer/core/html/forms/date_time_edit_element.h b/chromium/third_party/blink/renderer/core/html/forms/date_time_edit_element.h index b241d8d00df..2b34f4a6ecb 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/date_time_edit_element.h +++ b/chromium/third_party/blink/renderer/core/html/forms/date_time_edit_element.h @@ -85,7 +85,7 @@ class DateTimeEditElement final : public HTMLDivElement, DateTimeEditElement(Document&, EditControlOwner&); ~DateTimeEditElement() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void AddField(DateTimeFieldElement*); bool AnyEditableFieldsHaveValues() const; @@ -107,6 +107,7 @@ class DateTimeEditElement final : public HTMLDivElement, void SetValueAsDateTimeFieldsState(const DateTimeFieldsState&); void SetOnlyYearMonthDay(const DateComponents&); void SetOnlyTime(const DateComponents&); + void SetDateTimeLocal(const DateComponents&); void StepDown(); void StepUp(); String Value() const; diff --git a/chromium/third_party/blink/renderer/core/html/forms/date_time_field_element.cc b/chromium/third_party/blink/renderer/core/html/forms/date_time_field_element.cc index 43011524c79..bad44bbb995 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/date_time_field_element.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/date_time_field_element.cc @@ -48,7 +48,7 @@ DateTimeFieldElement::DateTimeFieldElement(Document& document, DateTimeField type) : HTMLSpanElement(document), field_owner_(&field_owner), type_(type) {} -void DateTimeFieldElement::Trace(Visitor* visitor) { +void DateTimeFieldElement::Trace(Visitor* visitor) const { visitor->Trace(field_owner_); HTMLSpanElement::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/forms/date_time_field_element.h b/chromium/third_party/blink/renderer/core/html/forms/date_time_field_element.h index 80abb99baa9..ba6b356d6d7 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/date_time_field_element.h +++ b/chromium/third_party/blink/renderer/core/html/forms/date_time_field_element.h @@ -88,7 +88,7 @@ class DateTimeFieldElement : public HTMLSpanElement { virtual void StepUp() = 0; virtual String Value() const = 0; virtual String VisibleValue() const = 0; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; DateTimeField Type() const; static float ComputeTextWidth(const ComputedStyle&, const String&); diff --git a/chromium/third_party/blink/renderer/core/html/forms/external_date_time_chooser.cc b/chromium/third_party/blink/renderer/core/html/forms/external_date_time_chooser.cc index 8ad4132abe3..59f7092213d 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/external_date_time_chooser.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/external_date_time_chooser.cc @@ -39,25 +39,25 @@ namespace blink { -static ui::mojom::TextInputType ToTextInputType(const AtomicString& source) { +static ui::TextInputType ToTextInputType(const AtomicString& source) { if (source == input_type_names::kDate) - return ui::mojom::TextInputType::DATE; + return ui::TextInputType::TEXT_INPUT_TYPE_DATE; if (source == input_type_names::kDatetime) - return ui::mojom::TextInputType::TIME; + return ui::TextInputType::TEXT_INPUT_TYPE_TIME; if (source == input_type_names::kDatetimeLocal) - return ui::mojom::TextInputType::DATE_TIME_LOCAL; + return ui::TextInputType::TEXT_INPUT_TYPE_DATE_TIME_LOCAL; if (source == input_type_names::kMonth) - return ui::mojom::TextInputType::MONTH; + return ui::TextInputType::TEXT_INPUT_TYPE_MONTH; if (source == input_type_names::kTime) - return ui::mojom::TextInputType::TIME; + return ui::TextInputType::TEXT_INPUT_TYPE_TIME; if (source == input_type_names::kWeek) - return ui::mojom::TextInputType::WEEK; - return ui::mojom::TextInputType::NONE; + return ui::TextInputType::TEXT_INPUT_TYPE_WEEK; + return ui::TextInputType::TEXT_INPUT_TYPE_NONE; } ExternalDateTimeChooser::~ExternalDateTimeChooser() = default; -void ExternalDateTimeChooser::Trace(Visitor* visitor) { +void ExternalDateTimeChooser::Trace(Visitor* visitor) const { visitor->Trace(date_time_chooser_); visitor->Trace(client_); DateTimeChooser::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/core/html/forms/external_date_time_chooser.h b/chromium/third_party/blink/renderer/core/html/forms/external_date_time_chooser.h index af6ff3007cf..4a21bafce46 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/external_date_time_chooser.h +++ b/chromium/third_party/blink/renderer/core/html/forms/external_date_time_chooser.h @@ -40,7 +40,7 @@ class CORE_EXPORT ExternalDateTimeChooser final : public DateTimeChooser { public: explicit ExternalDateTimeChooser(DateTimeChooserClient*); ~ExternalDateTimeChooser() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // |frame| must not be null. void OpenDateTimeChooser(LocalFrame* frame, const DateTimeChooserParameters&); diff --git a/chromium/third_party/blink/renderer/core/html/forms/external_date_time_chooser_test.cc b/chromium/third_party/blink/renderer/core/html/forms/external_date_time_chooser_test.cc index 4f705495a9b..52d4599de62 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/external_date_time_chooser_test.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/external_date_time_chooser_test.cc @@ -34,7 +34,7 @@ class TestDateTimeChooserClient final explicit TestDateTimeChooserClient(Element* element) : element_(element) {} ~TestDateTimeChooserClient() override {} - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(element_); visitor->Trace(date_time_chooser_); DateTimeChooserClient::Trace(visitor); @@ -62,7 +62,7 @@ class TestDateTimeChooserClient final // when it's called twice because |client_| was already nullptr. TEST_F(ExternalDateTimeChooserTest, EndChooserShouldNotCrash) { ScopedInputMultipleFieldsUIForTest input_multiple_fields_ui(false); - auto* document = MakeGarbageCollected<Document>(); + auto* document = Document::CreateForTest(); auto* element = document->CreateRawElement(html_names::kInputTag); auto* client = MakeGarbageCollected<TestDateTimeChooserClient>(element); auto* external_date_time_chooser = diff --git a/chromium/third_party/blink/renderer/core/html/forms/external_popup_menu.cc b/chromium/third_party/blink/renderer/core/html/forms/external_popup_menu.cc index 25090b9a149..6cd24053348 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/external_popup_menu.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/external_popup_menu.cc @@ -65,7 +65,7 @@ ExternalPopupMenu::ExternalPopupMenu(LocalFrame& frame, ExternalPopupMenu::~ExternalPopupMenu() = default; -void ExternalPopupMenu::Trace(Visitor* visitor) { +void ExternalPopupMenu::Trace(Visitor* visitor) const { visitor->Trace(owner_element_); visitor->Trace(local_frame_); visitor->Trace(receiver_); @@ -145,8 +145,9 @@ void ExternalPopupMenu::Show() { } void ExternalPopupMenu::DispatchEvent(TimerBase*) { - WebLocalFrameImpl::FromFrame(local_frame_->LocalFrameRoot()) - ->FrameWidgetImpl() + static_cast<WebWidget*>( + WebLocalFrameImpl::FromFrame(local_frame_->LocalFrameRoot()) + ->FrameWidgetImpl()) ->HandleInputEvent( blink::WebCoalescedInputEvent(*synthetic_event_, ui::LatencyInfo())); synthetic_event_.reset(); @@ -268,10 +269,7 @@ void ExternalPopupMenu::GetPopupMenuInfo( } popup_item->enabled = !item_element.IsDisabledFormControl(); const ComputedStyle& style = *owner_element.ItemComputedStyle(item_element); - popup_item->text_direction = - style.Direction() == TextDirection::kLtr - ? mojo_base::mojom::blink::TextDirection::LEFT_TO_RIGHT - : mojo_base::mojom::blink::TextDirection::RIGHT_TO_LEFT; + popup_item->text_direction = ToBaseTextDirection(style.Direction()); popup_item->has_text_direction_override = IsOverride(style.GetUnicodeBidi()); menu_items->push_back(std::move(popup_item)); diff --git a/chromium/third_party/blink/renderer/core/html/forms/external_popup_menu.h b/chromium/third_party/blink/renderer/core/html/forms/external_popup_menu.h index c5429e05b96..5965d566bbe 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/external_popup_menu.h +++ b/chromium/third_party/blink/renderer/core/html/forms/external_popup_menu.h @@ -69,7 +69,7 @@ class CORE_EXPORT ExternalPopupMenu final static int ToPopupMenuItemIndex(int index, HTMLSelectElement&); static int ToExternalPopupMenuItemIndex(int index, HTMLSelectElement&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // PopupMenu methods: diff --git a/chromium/third_party/blink/renderer/core/html/forms/file_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/file_input_type.cc index c6b772fcd4e..1a679c96be4 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/file_input_type.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/file_input_type.cc @@ -75,7 +75,7 @@ FileInputType::FileInputType(HTMLInputElement& element) KeyboardClickableInputTypeView(element), file_list_(MakeGarbageCollected<FileList>()) {} -void FileInputType::Trace(Visitor* visitor) { +void FileInputType::Trace(Visitor* visitor) const { visitor->Trace(file_list_); KeyboardClickableInputTypeView::Trace(visitor); InputType::Trace(visitor); @@ -195,7 +195,7 @@ void FileInputType::HandleDOMActivateEvent(Event& event) { params.requestor = document.Url(); UseCounter::Count( - document, document.IsSecureContext() + document, GetElement().GetExecutionContext()->IsSecureContext() ? WebFeature::kInputTypeFileSecureOriginOpenChooser : WebFeature::kInputTypeFileInsecureOriginOpenChooser); chrome_client->OpenFileChooser(document.GetFrame(), NewFileChooser(params)); @@ -320,11 +320,11 @@ FileList* FileInputType::CreateFileList(const FileChooserFileInfoList& files, } void FileInputType::CountUsage() { - Document* document = &GetElement().GetDocument(); - if (document->IsSecureContext()) - UseCounter::Count(*document, WebFeature::kInputTypeFileInsecureOrigin); + ExecutionContext* context = GetElement().GetExecutionContext(); + if (context->IsSecureContext()) + UseCounter::Count(context, WebFeature::kInputTypeFileInsecureOrigin); else - UseCounter::Count(*document, WebFeature::kInputTypeFileSecureOrigin); + UseCounter::Count(context, WebFeature::kInputTypeFileSecureOrigin); } void FileInputType::CreateShadowSubtree() { diff --git a/chromium/third_party/blink/renderer/core/html/forms/file_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/file_input_type.h index 425bf6b8226..8300e6bf3de 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/file_input_type.h +++ b/chromium/third_party/blink/renderer/core/html/forms/file_input_type.h @@ -53,7 +53,7 @@ class CORE_EXPORT FileInputType final : public InputType, public: FileInputType(HTMLInputElement&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; using InputType::GetElement; static Vector<String> FilesFromFormControlState(const FormControlState&); static FileList* CreateFileList(const FileChooserFileInfoList& files, diff --git a/chromium/third_party/blink/renderer/core/html/forms/file_input_type_test.cc b/chromium/third_party/blink/renderer/core/html/forms/file_input_type_test.cc index ebbb62c3b57..f2ff1ab6c92 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/file_input_type_test.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/file_input_type_test.cc @@ -63,7 +63,7 @@ TEST(FileInputTypeTest, createFileList) { } TEST(FileInputTypeTest, ignoreDroppedNonNativeFiles) { - auto* document = MakeGarbageCollected<Document>(); + auto* document = Document::CreateForTest(); auto* input = MakeGarbageCollected<HTMLInputElement>(*document, CreateElementFlags()); InputType* file_input = MakeGarbageCollected<FileInputType>(*input); @@ -97,7 +97,7 @@ TEST(FileInputTypeTest, ignoreDroppedNonNativeFiles) { } TEST(FileInputTypeTest, setFilesFromPaths) { - auto* document = MakeGarbageCollected<Document>(); + auto* document = Document::CreateForTest(); auto* input = MakeGarbageCollected<HTMLInputElement>(*document, CreateElementFlags()); InputType* file_input = MakeGarbageCollected<FileInputType>(*input); @@ -156,4 +156,44 @@ TEST(FileInputTypeTest, DropTouchesNoPopupOpeningObserver) { // UnregisterPopupOpeningObserver() was not called. } +TEST(FileInputTypeTest, BeforePseudoCrash) { + std::unique_ptr<DummyPageHolder> page_holder = + std::make_unique<DummyPageHolder>(IntSize(800, 600)); + Document& doc = page_holder->GetDocument(); + doc.documentElement()->setInnerHTML(R"HTML( +<style> +.c6 { + zoom: 0.01; +} + +.c6::first-letter { + position: fixed; + border-style: groove; +} + +.c6::before { + content: 'c6'; +} + +.c7 { + zoom: 0.1; +} + +.c7::first-letter { + position: fixed; + border-style: groove; +} + +.c7::before { + content: 'c7'; +} + +</style> +<input type=file class=c6> +<input type=file class=c7> +)HTML"); + doc.View()->UpdateAllLifecyclePhases(DocumentUpdateReason::kTest); + // The test passes if no CHECK failures and no null pointer dereferences. +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/forms/form_controller.cc b/chromium/third_party/blink/renderer/core/html/forms/form_controller.cc index 681786d2c40..bdec179ac44 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/form_controller.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/form_controller.cc @@ -334,7 +334,7 @@ class FormKeyGenerator final : public GarbageCollected<FormKeyGenerator> { public: FormKeyGenerator() = default; - void Trace(Visitor* visitor) { visitor->Trace(form_to_key_map_); } + void Trace(Visitor* visitor) const { visitor->Trace(form_to_key_map_); } const AtomicString& FormKey(const ListedElement&); void WillDeleteForm(HTMLFormElement*); @@ -427,7 +427,7 @@ void FormKeyGenerator::WillDeleteForm(HTMLFormElement* form) { DocumentState::DocumentState(Document& document) : document_(document) {} -void DocumentState::Trace(Visitor* visitor) { +void DocumentState::Trace(Visitor* visitor) const { visitor->Trace(document_); visitor->Trace(control_list_); } @@ -499,7 +499,7 @@ FormController::FormController(Document& document) FormController::~FormController() = default; -void FormController::Trace(Visitor* visitor) { +void FormController::Trace(Visitor* visitor) const { visitor->Trace(document_); visitor->Trace(document_state_); visitor->Trace(form_key_generator_); diff --git a/chromium/third_party/blink/renderer/core/html/forms/form_controller.h b/chromium/third_party/blink/renderer/core/html/forms/form_controller.h index d0d93844a8c..da0c9b63069 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/form_controller.h +++ b/chromium/third_party/blink/renderer/core/html/forms/form_controller.h @@ -82,7 +82,7 @@ using SavedFormStateMap = class CORE_EXPORT DocumentState final : public GarbageCollected<DocumentState> { public: DocumentState(Document& document); - void Trace(Visitor*); + void Trace(Visitor*) const; using ControlList = HeapVector<Member<ListedElement>, 64>; void InvalidateControlList(); @@ -100,7 +100,7 @@ class CORE_EXPORT FormController final public: FormController(Document& document); ~FormController(); - void Trace(Visitor*); + void Trace(Visitor*) const; void InvalidateStatefulFormControlList(); // This should be called only by Document::FormElementsState(). diff --git a/chromium/third_party/blink/renderer/core/html/forms/form_controller_test.cc b/chromium/third_party/blink/renderer/core/html/forms/form_controller_test.cc index e54eefa6018..49990a51e9c 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/form_controller_test.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/form_controller_test.cc @@ -16,7 +16,7 @@ namespace blink { TEST(DocumentStateTest, ToStateVectorConnected) { - auto& doc = *MakeGarbageCollected<Document>(); + auto& doc = *Document::CreateForTest(); Element* html = doc.CreateRawElement(html_names::kHTMLTag); doc.appendChild(html); Node* body = html->appendChild(doc.CreateRawElement(html_names::kBodyTag)); diff --git a/chromium/third_party/blink/renderer/core/html/forms/form_data.cc b/chromium/third_party/blink/renderer/core/html/forms/form_data.cc index 1918cac770a..1eb941afd6e 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/form_data.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/form_data.cc @@ -71,7 +71,7 @@ class FormDataIterationSource final return true; } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(form_data_); PairIterable<String, FormDataEntryValue>::IterationSource::Trace(visitor); } @@ -111,7 +111,7 @@ FormData* FormData::Create(HTMLFormElement* form, return MakeGarbageCollected<FormData>(*form_data); } -void FormData::Trace(Visitor* visitor) { +void FormData::Trace(Visitor* visitor) const { visitor->Trace(entries_); ScriptWrappable::Trace(visitor); } @@ -340,7 +340,7 @@ FormData::Entry::Entry(const String& name, Blob* blob, const String& filename) << "'name' should be a USVString."; } -void FormData::Entry::Trace(Visitor* visitor) { +void FormData::Entry::Trace(Visitor* visitor) const { visitor->Trace(blob_); } diff --git a/chromium/third_party/blink/renderer/core/html/forms/form_data.h b/chromium/third_party/blink/renderer/core/html/forms/form_data.h index 4ebb24e3bc1..432592529c6 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/form_data.h +++ b/chromium/third_party/blink/renderer/core/html/forms/form_data.h @@ -66,7 +66,7 @@ class CORE_EXPORT FormData final // doesn't clone entries in it because they are immutable. FormData(const FormData& form_data); FormData(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // FormData IDL interface. void append(const String& name, const String& value); @@ -123,7 +123,7 @@ class FormData::Entry final : public GarbageCollected<FormData::Entry> { public: Entry(const String& name, const String& value); Entry(const String& name, Blob* blob, const String& filename); - void Trace(Visitor*); + void Trace(Visitor*) const; bool IsString() const { return !blob_; } bool isFile() const { return blob_; } diff --git a/chromium/third_party/blink/renderer/core/html/forms/form_data_event.cc b/chromium/third_party/blink/renderer/core/html/forms/form_data_event.cc index 3e1d9bf0d70..6f5fac010fd 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/form_data_event.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/form_data_event.cc @@ -32,7 +32,7 @@ FormDataEvent* FormDataEvent::Create(const AtomicString& type, return MakeGarbageCollected<FormDataEvent>(type, event_init); } -void FormDataEvent::Trace(Visitor* visitor) { +void FormDataEvent::Trace(Visitor* visitor) const { visitor->Trace(form_data_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/forms/form_data_event.h b/chromium/third_party/blink/renderer/core/html/forms/form_data_event.h index 3d0682353e3..6a0c1adef61 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/form_data_event.h +++ b/chromium/third_party/blink/renderer/core/html/forms/form_data_event.h @@ -22,7 +22,7 @@ class FormDataEvent : public Event { FormDataEvent(FormData& form_data); FormDataEvent(const AtomicString& type, const FormDataEventInit* event_init); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; FormData* formData() const { return form_data_; } diff --git a/chromium/third_party/blink/renderer/core/html/forms/hidden_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/hidden_input_type.cc index f8fef662ad8..76a13e9e3c5 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/hidden_input_type.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/hidden_input_type.cc @@ -46,7 +46,7 @@ void HiddenInputType::CountUsage() { UseCounter::Count(GetElement().GetDocument(), WebFeature::kInputTypeHidden); } -void HiddenInputType::Trace(Visitor* visitor) { +void HiddenInputType::Trace(Visitor* visitor) const { InputTypeView::Trace(visitor); InputType::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/forms/hidden_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/hidden_input_type.h index 5e211f67c15..1dd0ed6f47e 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/hidden_input_type.h +++ b/chromium/third_party/blink/renderer/core/html/forms/hidden_input_type.h @@ -43,7 +43,7 @@ class HiddenInputType final : public InputType, private InputTypeView { HiddenInputType(HTMLInputElement& element) : InputType(element), InputTypeView(element) {} - void Trace(Visitor*) override; + void Trace(Visitor*) const override; using InputType::GetElement; private: diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element.cc b/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element.cc index 7ef8db7a852..2afea2e1228 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element.cc @@ -53,7 +53,7 @@ HTMLFormControlElement::HTMLFormControlElement(const QualifiedName& tag_name, HTMLFormControlElement::~HTMLFormControlElement() = default; -void HTMLFormControlElement::Trace(Visitor* visitor) { +void HTMLFormControlElement::Trace(Visitor* visitor) const { ListedElement::Trace(visitor); HTMLElement::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element.h b/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element.h index 62c7a77395e..cdf5b4831bc 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element.h +++ b/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element.h @@ -47,7 +47,7 @@ class CORE_EXPORT HTMLFormControlElement : public HTMLElement, public: ~HTMLFormControlElement() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; String formAction() const; void setFormAction(const AtomicString&); diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element_test.cc b/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element_test.cc index db9caa6e8b2..32c40dd71cb 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element_test.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/html_form_control_element_test.cc @@ -45,7 +45,7 @@ class MockFormValidationMessageClient void DocumentDetached(const Document&) override {} void DidChangeFocusTo(const Element*) override {} void WillBeDestroyed() override {} - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(anchor_); ValidationMessageClient::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_form_controls_collection.cc b/chromium/third_party/blink/renderer/core/html/forms/html_form_controls_collection.cc index 6be7461d61c..86e78a22572 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/html_form_controls_collection.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/html_form_controls_collection.cc @@ -221,7 +221,7 @@ void HTMLFormControlsCollection::SupportedPropertyNames(Vector<String>& names) { } } -void HTMLFormControlsCollection::Trace(Visitor* visitor) { +void HTMLFormControlsCollection::Trace(Visitor* visitor) const { visitor->Trace(cached_element_); HTMLCollection::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_form_controls_collection.h b/chromium/third_party/blink/renderer/core/html/forms/html_form_controls_collection.h index 684265f7b26..b85bc929905 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/html_form_controls_collection.h +++ b/chromium/third_party/blink/renderer/core/html/forms/html_form_controls_collection.h @@ -54,7 +54,7 @@ class HTMLFormControlsCollection final : public HTMLCollection { HTMLElement* namedItem(const AtomicString& name) const override; void namedGetter(const AtomicString& name, RadioNodeListOrElement&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void UpdateIdNameCache() const override; diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_form_element.cc b/chromium/third_party/blink/renderer/core/html/forms/html_form_element.cc index 7c149fb0f92..74e1751c345 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/html_form_element.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/html_form_element.cc @@ -87,7 +87,7 @@ HTMLFormElement::HTMLFormElement(Document& document) HTMLFormElement::~HTMLFormElement() = default; -void HTMLFormElement::Trace(Visitor* visitor) { +void HTMLFormElement::Trace(Visitor* visitor) const { visitor->Trace(past_names_map_); visitor->Trace(radio_button_group_scope_); visitor->Trace(listed_elements_); @@ -514,6 +514,11 @@ void HTMLFormElement::ScheduleFormSubmission( // Cancel pending javascript url navigations for the target frame. This new // form submission should take precedence over them. target_local_frame->GetDocument()->CancelPendingJavaScriptUrls(); + + // Cancel any pre-existing attempt to navigate the target frame which was + // already sent to the browser process so this form submission will take + // precedence over it. + target_local_frame->Loader().CancelClientNavigation(); } target_frame->ScheduleFormSubmission(scheduler, form_submission); diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_form_element.h b/chromium/third_party/blink/renderer/core/html/forms/html_form_element.h index 620c05a3cc9..44e0c202fda 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/html_form_element.h +++ b/chromium/third_party/blink/renderer/core/html/forms/html_form_element.h @@ -46,7 +46,7 @@ class CORE_EXPORT HTMLFormElement final : public HTMLElement { public: explicit HTMLFormElement(Document&); ~HTMLFormElement() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; HTMLFormControlsCollection* elements(); void GetNamedElements(const AtomicString&, HeapVector<Member<Element>>&); diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_input_element.cc b/chromium/third_party/blink/renderer/core/html/forms/html_input_element.cc index d5a4f05446e..31676cf8670 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/html_input_element.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/html_input_element.cc @@ -91,7 +91,7 @@ class ListAttributeTargetObserver : public IdTargetObserver { public: ListAttributeTargetObserver(const AtomicString& id, HTMLInputElement*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void IdTargetChanged() override; private: @@ -135,7 +135,7 @@ HTMLInputElement::HTMLInputElement(Document& document, } } -void HTMLInputElement::Trace(Visitor* visitor) { +void HTMLInputElement::Trace(Visitor* visitor) const { visitor->Trace(input_type_); visitor->Trace(input_type_view_); visitor->Trace(list_attribute_target_observer_); @@ -775,8 +775,8 @@ void HTMLInputElement::ParseAttribute( SetNeedsStyleRecalc( kSubtreeStyleChange, StyleChangeReasonForTracing::FromAttribute(html_names::kValueAttr)); + needs_to_update_view_value_ = true; } - needs_to_update_view_value_ = true; SetNeedsValidityCheck(); input_type_->WarnIfValueIsInvalidAndElementIsVisible(value); input_type_->InRangeChanged(); @@ -1833,7 +1833,7 @@ ListAttributeTargetObserver::ListAttributeTargetObserver( id), element_(element) {} -void ListAttributeTargetObserver::Trace(Visitor* visitor) { +void ListAttributeTargetObserver::Trace(Visitor* visitor) const { visitor->Trace(element_); IdTargetObserver::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_input_element.h b/chromium/third_party/blink/renderer/core/html/forms/html_input_element.h index e2b0b44ab88..ec5959ab37f 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/html_input_element.h +++ b/chromium/third_party/blink/renderer/core/html/forms/html_input_element.h @@ -59,7 +59,7 @@ class CORE_EXPORT HTMLInputElement public: HTMLInputElement(Document&, const CreateElementFlags); ~HTMLInputElement() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; bool HasPendingActivity() const final; diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_input_element_test.cc b/chromium/third_party/blink/renderer/core/html/forms/html_input_element_test.cc index baa2c174681..3132d8f878a 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/html_input_element_test.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/html_input_element_test.cc @@ -89,14 +89,14 @@ TEST_F(HTMLInputElementTest, create) { EXPECT_NE(nullptr, input->UserAgentShadowRoot()); input = MakeGarbageCollected<HTMLInputElement>( - GetDocument(), CreateElementFlags::ByParser()); + GetDocument(), CreateElementFlags::ByParser(&GetDocument())); EXPECT_EQ(nullptr, input->UserAgentShadowRoot()); input->ParserSetAttributes(Vector<Attribute>()); EXPECT_NE(nullptr, input->UserAgentShadowRoot()); } TEST_F(HTMLInputElementTest, NoAssertWhenMovedInNewDocument) { - auto* document_without_frame = MakeGarbageCollected<Document>(); + auto* document_without_frame = Document::CreateForTest(); EXPECT_EQ(nullptr, document_without_frame->GetPage()); auto* html = MakeGarbageCollected<HTMLHtmlElement>(*document_without_frame); html->AppendChild( diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_option_element.cc b/chromium/third_party/blink/renderer/core/html/forms/html_option_element.cc index bce8b9e77da..c69ab0b118c 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/html_option_element.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/html_option_element.cc @@ -26,8 +26,10 @@ #include "third_party/blink/renderer/core/html/forms/html_option_element.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_mutation_observer_init.h" #include "third_party/blink/renderer/core/accessibility/ax_object_cache.h" #include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/dom/mutation_observer.h" #include "third_party/blink/renderer/core/dom/node_computed_style.h" #include "third_party/blink/renderer/core/dom/node_traversal.h" #include "third_party/blink/renderer/core/dom/shadow_root.h" @@ -44,6 +46,37 @@ namespace blink { +class OptionTextObserver : public MutationObserver::Delegate { + public: + explicit OptionTextObserver(HTMLOptionElement& option) + : option_(option), observer_(MutationObserver::Create(this)) { + MutationObserverInit* init = MutationObserverInit::Create(); + init->setCharacterData(true); + init->setChildList(true); + init->setSubtree(true); + observer_->observe(option_, init, ASSERT_NO_EXCEPTION); + } + + ExecutionContext* GetExecutionContext() const override { + return option_->GetExecutionContext(); + } + + void Deliver(const MutationRecordVector& records, + MutationObserver&) override { + option_->DidChangeTextContent(); + } + + void Trace(Visitor* visitor) const override { + visitor->Trace(option_); + visitor->Trace(observer_); + MutationObserver::Delegate::Trace(visitor); + } + + private: + Member<HTMLOptionElement> option_; + Member<MutationObserver> observer_; +}; + HTMLOptionElement::HTMLOptionElement(Document& document) : HTMLElement(html_names::kOptionTag, document), is_selected_(false) { EnsureUserAgentShadowRoot(); @@ -81,6 +114,11 @@ HTMLOptionElement* HTMLOptionElement::CreateForJSConstructor( return element; } +void HTMLOptionElement::Trace(Visitor* visitor) const { + visitor->Trace(text_observer_); + HTMLElement::Trace(visitor); +} + bool HTMLOptionElement::SupportsFocus() const { HTMLSelectElement* select = OwnerSelectElement(); if (select && select->UsesMenuList()) @@ -280,6 +318,15 @@ void HTMLOptionElement::SetDirty(bool value) { void HTMLOptionElement::ChildrenChanged(const ChildrenChange& change) { HTMLElement::ChildrenChanged(change); + DidChangeTextContent(); + + // If an element is inserted, We need to use MutationObserver to detect + // textContent changes. + if (change.type == ChildrenChangeType::kElementInserted && !text_observer_) + text_observer_ = MakeGarbageCollected<OptionTextObserver>(*this); +} + +void HTMLOptionElement::DidChangeTextContent() { if (HTMLDataListElement* data_list = OwnerDataListElement()) data_list->OptionElementChildrenChanged(); else if (HTMLSelectElement* select = OwnerSelectElement()) diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_option_element.h b/chromium/third_party/blink/renderer/core/html/forms/html_option_element.h index e895c8546f8..78a6f792afb 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/html_option_element.h +++ b/chromium/third_party/blink/renderer/core/html/forms/html_option_element.h @@ -33,6 +33,7 @@ namespace blink { class ExceptionState; class HTMLDataListElement; class HTMLSelectElement; +class OptionTextObserver; class CORE_EXPORT HTMLOptionElement final : public HTMLElement { DEFINE_WRAPPERTYPEINFO(); @@ -53,6 +54,7 @@ class CORE_EXPORT HTMLOptionElement final : public HTMLElement { ExceptionState&); explicit HTMLOptionElement(Document&); + void Trace(Visitor* visitor) const override; // A text to be shown to users. The difference from |label()| is |label()| // returns an empty string if |label| content attribute is empty. @@ -102,10 +104,13 @@ class CORE_EXPORT HTMLOptionElement final : public HTMLElement { bool IsMultiSelectFocused() const; void SetWasOptionInsertedCalled(bool flag) { - was_option_inserted_called_ = true; + was_option_inserted_called_ = flag; } bool WasOptionInsertedCalled() const { return was_option_inserted_called_; } + // Callback for OptionTextObserver. + void DidChangeTextContent(); + private: ~HTMLOptionElement() override; @@ -122,6 +127,8 @@ class CORE_EXPORT HTMLOptionElement final : public HTMLElement { void UpdateLabel(); + Member<OptionTextObserver> text_observer_; + // Represents 'selectedness'. // https://html.spec.whatwg.org/C/#concept-option-selectedness bool is_selected_; diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_output_element.cc b/chromium/third_party/blink/renderer/core/html/forms/html_output_element.cc index f5da9a76bd8..7404831437e 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/html_output_element.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/html_output_element.cc @@ -116,7 +116,7 @@ void HTMLOutputElement::setDefaultValue(const String& value) { setTextContent(value); } -void HTMLOutputElement::Trace(Visitor* visitor) { +void HTMLOutputElement::Trace(Visitor* visitor) const { visitor->Trace(tokens_); HTMLFormControlElement::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_output_element.h b/chromium/third_party/blink/renderer/core/html/forms/html_output_element.h index 58155db1465..6385fe3c19a 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/html_output_element.h +++ b/chromium/third_party/blink/renderer/core/html/forms/html_output_element.h @@ -55,7 +55,7 @@ class CORE_EXPORT HTMLOutputElement final : public HTMLFormControlElement { return is_default_value_mode_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void ParseAttribute(const AttributeModificationParams&) override; diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_output_element_test.cc b/chromium/third_party/blink/renderer/core/html/forms/html_output_element_test.cc index bd7c8df0d5d..7a6a561b7b9 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/html_output_element_test.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/html_output_element_test.cc @@ -14,7 +14,7 @@ namespace blink { TEST(HTMLLinkElementSizesAttributeTest, setHTMLForProperty_updatesForAttribute) { - auto* document = MakeGarbageCollected<Document>(); + auto* document = Document::CreateForTest(); auto* element = MakeGarbageCollected<HTMLOutputElement>(*document); EXPECT_EQ(g_null_atom, element->FastGetAttribute(html_names::kForAttr)); element->htmlFor()->setValue(" strawberry "); @@ -22,7 +22,7 @@ TEST(HTMLLinkElementSizesAttributeTest, } TEST(HTMLOutputElementTest, setForAttribute_updatesHTMLForPropertyValue) { - auto* document = MakeGarbageCollected<Document>(); + auto* document = Document::CreateForTest(); auto* element = MakeGarbageCollected<HTMLOutputElement>(*document); DOMTokenList* for_tokens = element->htmlFor(); EXPECT_EQ(g_null_atom, for_tokens->value()); diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_select_element.cc b/chromium/third_party/blink/renderer/core/html/forms/html_select_element.cc index bf5514858c6..80e83795058 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/html_select_element.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/html_select_element.cc @@ -50,7 +50,6 @@ #include "third_party/blink/renderer/core/html/forms/html_form_element.h" #include "third_party/blink/renderer/core/html/forms/html_opt_group_element.h" #include "third_party/blink/renderer/core/html/forms/html_option_element.h" -#include "third_party/blink/renderer/core/html/forms/menu_list_inner_element.h" #include "third_party/blink/renderer/core/html/forms/select_type.h" #include "third_party/blink/renderer/core/html/html_hr_element.h" #include "third_party/blink/renderer/core/html/html_slot_element.h" @@ -230,9 +229,7 @@ int HTMLSelectElement::ActiveSelectionEndListIndex() const { } HTMLOptionElement* HTMLSelectElement::ActiveSelectionEnd() const { - if (active_selection_end_) - return active_selection_end_.Get(); - return LastSelectedOption(); + return select_type_->ActiveSelectionEnd(); } void HTMLSelectElement::add( @@ -512,25 +509,6 @@ void HTMLSelectElement::SelectAll() { select_type_->SelectAll(); } -void HTMLSelectElement::SetActiveSelectionAnchor(HTMLOptionElement* option) { - active_selection_anchor_ = option; - select_type_->SaveListboxActiveSelection(); -} - -void HTMLSelectElement::SetActiveSelectionEnd(HTMLOptionElement* option) { - active_selection_end_ = option; -} - -void HTMLSelectElement::ScrollToSelection() { - if (!IsFinishedParsingChildren()) - return; - if (UsesMenuList()) - return; - select_type_->ScrollToOption(ActiveSelectionEnd()); - if (AXObjectCache* cache = GetDocument().ExistingAXObjectCache()) - cache->ListboxActiveIndexChanged(this); -} - const HTMLSelectElement::ListItems& HTMLSelectElement::GetListItems() const { if (should_recalc_list_items_) { RecalcListItems(); @@ -789,10 +767,6 @@ void HTMLSelectElement::OptionRemoved(HTMLOptionElement& option) { if (last_on_change_option_ == &option) last_on_change_option_.Clear(); select_type_->OptionRemoved(option); - if (active_selection_anchor_ == &option) - active_selection_anchor_.Clear(); - if (active_selection_end_ == &option) - active_selection_end_.Clear(); if (suggested_option_ == &option) SetSuggestedOption(nullptr); if (option.Selected()) @@ -846,18 +820,6 @@ void HTMLSelectElement::SelectOption(HTMLOptionElement* element, if (flags & kDeselectOtherOptionsFlag) should_update_popup |= DeselectItemsWithoutValidation(element); - // We should update active selection after finishing OPTION state change - // because setActiveSelectionAnchorIndex() stores OPTION's selection state. - if (element) { - // setActiveSelectionAnchor is O(N). - if (!active_selection_anchor_ || !IsMultiple() || - flags & kDeselectOtherOptionsFlag) - SetActiveSelectionAnchor(element); - if (!active_selection_end_ || !IsMultiple() || - flags & kDeselectOtherOptionsFlag) - SetActiveSelectionEnd(element); - } - select_type_->DidSelectOption(element, flags, should_update_popup); NotifyFormStateChanged(); @@ -1169,10 +1131,8 @@ void HTMLSelectElement::SelectOptionByAccessKey(HTMLOptionElement* option) { SelectOption(option, flags); } option->SetDirty(true); - if (UsesMenuList()) - return; select_type_->ListBoxOnChange(); - ScrollToSelection(); + select_type_->ScrollToSelection(); } unsigned HTMLSelectElement::length() const { @@ -1209,11 +1169,9 @@ bool HTMLSelectElement::IsInteractiveContent() const { return true; } -void HTMLSelectElement::Trace(Visitor* visitor) { +void HTMLSelectElement::Trace(Visitor* visitor) const { visitor->Trace(list_items_); visitor->Trace(last_on_change_option_); - visitor->Trace(active_selection_anchor_); - visitor->Trace(active_selection_end_); visitor->Trace(suggested_option_); visitor->Trace(select_type_); HTMLFormControlElementWithState::Trace(visitor); @@ -1241,30 +1199,15 @@ void HTMLSelectElement::UpdateUserAgentShadowTree(ShadowRoot& root) { will_be_removed->remove(); } } - if (UsesMenuList()) { - Element* inner_element = - MakeGarbageCollected<MenuListInnerElement>(GetDocument()); - inner_element->setAttribute(html_names::kAriaHiddenAttr, "true"); - // Make sure InnerElement() always has a Text node. - inner_element->appendChild(Text::Create(GetDocument(), g_empty_string)); - root.insertBefore(inner_element, root.firstChild()); - } + select_type_->CreateShadowSubtree(root); } Element& HTMLSelectElement::InnerElement() const { - DCHECK(UsesMenuList()); - auto* inner_element = DynamicTo<Element>(UserAgentShadowRoot()->firstChild()); - DCHECK(inner_element); - return *inner_element; + return select_type_->InnerElement(); } HTMLOptionElement* HTMLSelectElement::SpatialNavigationFocusedOption() { - if (!IsSpatialNavigationEnabled(GetDocument().GetFrame())) - return nullptr; - HTMLOptionElement* focused_option = ActiveSelectionEnd(); - if (!focused_option) - focused_option = select_type_->FirstSelectableOption(); - return focused_option; + return select_type_->SpatialNavigationFocusedOption(); } String HTMLSelectElement::ItemText(const Element& element) const { @@ -1418,9 +1361,12 @@ void HTMLSelectElement::CloneNonAttributePropertiesFrom( void HTMLSelectElement::ChangeRendering() { select_type_->DidDetachLayoutTree(); + bool old_uses_menu_list = UsesMenuList(); UpdateUsesMenuList(); - select_type_->WillBeDestroyed(); - select_type_ = SelectType::Create(*this); + if (UsesMenuList() != old_uses_menu_list) { + select_type_->WillBeDestroyed(); + select_type_ = SelectType::Create(*this); + } if (!InActiveDocument()) return; // TODO(futhark): SetForceReattachLayoutTree() should be the correct way to diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_select_element.h b/chromium/third_party/blink/renderer/core/html/forms/html_select_element.h index eb28983c7ad..86570a11d94 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/html_select_element.h +++ b/chromium/third_party/blink/renderer/core/html/forms/html_select_element.h @@ -122,14 +122,10 @@ class CORE_EXPORT HTMLSelectElement final Element* namedItem(const AtomicString& name); HTMLOptionElement* item(unsigned index); - void ScrollToSelection(); - bool CanSelectAll() const; void SelectAll(); int ActiveSelectionEndListIndex() const; HTMLOptionElement* ActiveSelectionEnd() const; - void SetActiveSelectionAnchor(HTMLOptionElement*); - void SetActiveSelectionEnd(HTMLOptionElement*); // For use in the implementation of HTMLOptionElement. void OptionSelectionStateChanged(HTMLOptionElement*, bool option_is_selected); @@ -179,7 +175,7 @@ class CORE_EXPORT HTMLSelectElement final bool HasNonInBodyInsertionMode() const override { return true; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void CloneNonAttributePropertiesFrom(const Element&, CloneChildrenFlag) override; @@ -285,8 +281,6 @@ class CORE_EXPORT HTMLSelectElement final TypeAhead type_ahead_; unsigned size_; Member<HTMLOptionElement> last_on_change_option_; - Member<HTMLOptionElement> active_selection_anchor_; - Member<HTMLOptionElement> active_selection_end_; Member<HTMLOptionElement> suggested_option_; bool uses_menu_list_ = true; bool is_multiple_; diff --git a/chromium/third_party/blink/renderer/core/html/forms/html_select_element_test.cc b/chromium/third_party/blink/renderer/core/html/forms/html_select_element_test.cc index 9a0133c5b2d..2c7624c15f2 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/html_select_element_test.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/html_select_element_test.cc @@ -394,8 +394,13 @@ TEST_F(HTMLSelectElementTest, PreviousSelectableOption) { TEST_F(HTMLSelectElementTest, ActiveSelectionEndAfterOptionRemoval) { SetHtmlInnerHTML( - "<select><optgroup><option selected>o1</option></optgroup></select>"); + "<select size=4>" + "<optgroup><option selected>o1</option></optgroup></select>"); auto* select = To<HTMLSelectElement>(GetDocument().body()->firstChild()); + // ActiveSelectionEnd*() work only in the listbox mode, which Android + // doesn't have. + if (select->UsesMenuList()) + return; auto* option = To<HTMLOptionElement>(select->firstChild()->firstChild()); EXPECT_EQ(1, select->ActiveSelectionEndListIndex()); select->firstChild()->removeChild(option); diff --git a/chromium/third_party/blink/renderer/core/html/forms/image_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/image_input_type.cc index 53abd4c58ba..27f89ccb231 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/image_input_type.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/image_input_type.cc @@ -38,6 +38,7 @@ #include "third_party/blink/renderer/core/layout/adjust_for_absolute_zoom.h" #include "third_party/blink/renderer/core/layout/layout_block_flow.h" #include "third_party/blink/renderer/core/layout/layout_image.h" +#include "third_party/blink/renderer/core/layout/layout_inline.h" #include "third_party/blink/renderer/core/layout/layout_object_factory.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" @@ -110,8 +111,12 @@ bool ImageInputType::TypeShouldForceLegacyLayout() const { LayoutObject* ImageInputType::CreateLayoutObject(const ComputedStyle& style, LegacyLayout legacy) const { - if (use_fallback_content_) + if (use_fallback_content_) { + if (style.Display() == EDisplay::kInline) + return new LayoutInline(&GetElement()); + return LayoutObjectFactory::CreateBlockFlow(GetElement(), style, legacy); + } LayoutImage* image = new LayoutImage(&GetElement()); image->SetImageResource(MakeGarbageCollected<LayoutImageResource>()); return image; diff --git a/chromium/third_party/blink/renderer/core/html/forms/input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/input_type.cc index dbe99ae5e5b..c3f2bd721f5 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/input_type.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/input_type.cc @@ -77,113 +77,44 @@ namespace blink { -using InputTypeFactoryFunction = InputType* (*)(HTMLInputElement&); -using InputTypeFactoryMap = HashMap<AtomicString, InputTypeFactoryFunction>; - -static std::unique_ptr<InputTypeFactoryMap> CreateInputTypeFactoryMap() { - std::unique_ptr<InputTypeFactoryMap> map = - std::make_unique<InputTypeFactoryMap>(); - map->insert(input_type_names::kButton, - [](HTMLInputElement& element) -> InputType* { - return MakeGarbageCollected<ButtonInputType>(element); - }); - map->insert(input_type_names::kCheckbox, - [](HTMLInputElement& element) -> InputType* { - return MakeGarbageCollected<CheckboxInputType>(element); - }); - map->insert(input_type_names::kColor, - [](HTMLInputElement& element) -> InputType* { - return MakeGarbageCollected<ColorInputType>(element); - }); - map->insert(input_type_names::kDate, - [](HTMLInputElement& element) -> InputType* { - return MakeGarbageCollected<DateInputType>(element); - }); - map->insert(input_type_names::kDatetimeLocal, - [](HTMLInputElement& element) -> InputType* { - return MakeGarbageCollected<DateTimeLocalInputType>(element); - }); - map->insert(input_type_names::kEmail, - [](HTMLInputElement& element) -> InputType* { - return MakeGarbageCollected<EmailInputType>(element); - }); - map->insert(input_type_names::kFile, - [](HTMLInputElement& element) -> InputType* { - return MakeGarbageCollected<FileInputType>(element); - }); - map->insert(input_type_names::kHidden, - [](HTMLInputElement& element) -> InputType* { - return MakeGarbageCollected<HiddenInputType>(element); - }); - map->insert(input_type_names::kImage, - [](HTMLInputElement& element) -> InputType* { - return MakeGarbageCollected<ImageInputType>(element); - }); - map->insert(input_type_names::kMonth, - [](HTMLInputElement& element) -> InputType* { - return MakeGarbageCollected<MonthInputType>(element); - }); - map->insert(input_type_names::kNumber, - [](HTMLInputElement& element) -> InputType* { - return MakeGarbageCollected<NumberInputType>(element); - }); - map->insert(input_type_names::kPassword, - [](HTMLInputElement& element) -> InputType* { - return MakeGarbageCollected<PasswordInputType>(element); - }); - map->insert(input_type_names::kRadio, - [](HTMLInputElement& element) -> InputType* { - return MakeGarbageCollected<RadioInputType>(element); - }); - map->insert(input_type_names::kRange, - [](HTMLInputElement& element) -> InputType* { - return MakeGarbageCollected<RangeInputType>(element); - }); - map->insert(input_type_names::kReset, - [](HTMLInputElement& element) -> InputType* { - return MakeGarbageCollected<ResetInputType>(element); - }); - map->insert(input_type_names::kSearch, - [](HTMLInputElement& element) -> InputType* { - return MakeGarbageCollected<SearchInputType>(element); - }); - map->insert(input_type_names::kSubmit, - [](HTMLInputElement& element) -> InputType* { - return MakeGarbageCollected<SubmitInputType>(element); - }); - map->insert(input_type_names::kTel, - [](HTMLInputElement& element) -> InputType* { - return MakeGarbageCollected<TelephoneInputType>(element); - }); - map->insert(input_type_names::kTime, - [](HTMLInputElement& element) -> InputType* { - return MakeGarbageCollected<TimeInputType>(element); - }); - map->insert(input_type_names::kUrl, - [](HTMLInputElement& element) -> InputType* { - return MakeGarbageCollected<URLInputType>(element); - }); - map->insert(input_type_names::kWeek, - [](HTMLInputElement& element) -> InputType* { - return MakeGarbageCollected<WeekInputType>(element); - }); - // No need to register "text" because it is the default type. - return map; -} - -static const InputTypeFactoryMap* FactoryMap() { - static const InputTypeFactoryMap* factory_map = - CreateInputTypeFactoryMap().release(); - return factory_map; -} +// Listed once to avoid any discrepancy between InputType::Create and +// InputType::NormalizeTypeName. +// +// No need to register "text" because it is the default type. +#define INPUT_TYPES(INPUT_TYPE) \ + INPUT_TYPE(kButton, ButtonInputType) \ + INPUT_TYPE(kCheckbox, CheckboxInputType) \ + INPUT_TYPE(kColor, ColorInputType) \ + INPUT_TYPE(kDate, DateInputType) \ + INPUT_TYPE(kDatetimeLocal, DateTimeLocalInputType) \ + INPUT_TYPE(kEmail, EmailInputType) \ + INPUT_TYPE(kFile, FileInputType) \ + INPUT_TYPE(kHidden, HiddenInputType) \ + INPUT_TYPE(kImage, ImageInputType) \ + INPUT_TYPE(kMonth, MonthInputType) \ + INPUT_TYPE(kNumber, NumberInputType) \ + INPUT_TYPE(kPassword, PasswordInputType) \ + INPUT_TYPE(kRadio, RadioInputType) \ + INPUT_TYPE(kRange, RangeInputType) \ + INPUT_TYPE(kReset, ResetInputType) \ + INPUT_TYPE(kSearch, SearchInputType) \ + INPUT_TYPE(kSubmit, SubmitInputType) \ + INPUT_TYPE(kTel, TelephoneInputType) \ + INPUT_TYPE(kTime, TimeInputType) \ + INPUT_TYPE(kUrl, URLInputType) \ + INPUT_TYPE(kWeek, WeekInputType) InputType* InputType::Create(HTMLInputElement& element, const AtomicString& type_name) { - InputTypeFactoryFunction factory = - type_name.IsEmpty() ? nullptr : FactoryMap()->at(type_name); - if (factory) { - return factory(element); - } + if (type_name.IsEmpty()) + return MakeGarbageCollected<TextInputType>(element); + +#define INPUT_TYPE_FACTORY(input_type, class_name) \ + if (type_name == input_type_names::input_type) \ + return MakeGarbageCollected<class_name>(element); + INPUT_TYPES(INPUT_TYPE_FACTORY) +#undef INPUT_TYPE_FACTORY + return MakeGarbageCollected<TextInputType>(element); } @@ -191,14 +122,21 @@ const AtomicString& InputType::NormalizeTypeName( const AtomicString& type_name) { if (type_name.IsEmpty()) return input_type_names::kText; - InputTypeFactoryMap::const_iterator it = - FactoryMap()->find(type_name.LowerASCII()); - return it == FactoryMap()->end() ? input_type_names::kText : it->key; + + AtomicString type_name_lower = type_name.LowerASCII(); + +#define NORMALIZE_INPUT_TYPE(input_type, class_name) \ + if (type_name_lower == input_type_names::input_type) \ + return input_type_names::input_type; + INPUT_TYPES(NORMALIZE_INPUT_TYPE) +#undef NORMALIZE_INPUT_TYPE + + return input_type_names::kText; } InputType::~InputType() = default; -void InputType::Trace(Visitor* visitor) { +void InputType::Trace(Visitor* visitor) const { visitor->Trace(element_); } diff --git a/chromium/third_party/blink/renderer/core/html/forms/input_type.h b/chromium/third_party/blink/renderer/core/html/forms/input_type.h index 45ec3898704..3f0c23264ac 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/input_type.h +++ b/chromium/third_party/blink/renderer/core/html/forms/input_type.h @@ -57,7 +57,7 @@ class CORE_EXPORT InputType : public GarbageCollected<InputType> { static InputType* Create(HTMLInputElement&, const AtomicString&); static const AtomicString& NormalizeTypeName(const AtomicString&); virtual ~InputType(); - virtual void Trace(Visitor*); + virtual void Trace(Visitor*) const; virtual InputTypeView* CreateView() = 0; virtual const AtomicString& FormControlType() const = 0; diff --git a/chromium/third_party/blink/renderer/core/html/forms/input_type_view.cc b/chromium/third_party/blink/renderer/core/html/forms/input_type_view.cc index 336cea6892e..6667c015c14 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/input_type_view.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/input_type_view.cc @@ -40,7 +40,7 @@ namespace blink { InputTypeView::~InputTypeView() = default; -void InputTypeView::Trace(Visitor* visitor) { +void InputTypeView::Trace(Visitor* visitor) const { visitor->Trace(element_); } @@ -202,7 +202,7 @@ bool InputTypeView::HasBadInput() const { return false; } -void ClickHandlingState::Trace(Visitor* visitor) { +void ClickHandlingState::Trace(Visitor* visitor) const { visitor->Trace(checked_radio_button); EventDispatchHandlingState::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/forms/input_type_view.h b/chromium/third_party/blink/renderer/core/html/forms/input_type_view.h index cba7ed4d453..1fc760298fc 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/input_type_view.h +++ b/chromium/third_party/blink/renderer/core/html/forms/input_type_view.h @@ -59,7 +59,7 @@ class MouseEvent; class ClickHandlingState final : public EventDispatchHandlingState { public: - void Trace(Visitor*) override; + void Trace(Visitor*) const override; bool checked; bool indeterminate; @@ -72,7 +72,7 @@ class ClickHandlingState final : public EventDispatchHandlingState { class CORE_EXPORT InputTypeView : public GarbageCollectedMixin { public: virtual ~InputTypeView(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; virtual bool SizeShouldIncludeDecoration(int default_size, int& preferred_size) const; diff --git a/chromium/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc b/chromium/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc index 411650375cf..d818498078c 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/internal_popup_menu.cc @@ -65,7 +65,7 @@ class PopupMenuCSSFontSelector : public CSSFontSelector, scoped_refptr<FontData> GetFontData(const FontDescription&, const AtomicString&) override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void FontsNeedUpdate(FontSelector*, FontInvalidationReason) override; @@ -93,7 +93,7 @@ void PopupMenuCSSFontSelector::FontsNeedUpdate(FontSelector* font_selector, DispatchInvalidationCallbacks(reason); } -void PopupMenuCSSFontSelector::Trace(Visitor* visitor) { +void PopupMenuCSSFontSelector::Trace(Visitor* visitor) const { visitor->Trace(owner_font_selector_); CSSFontSelector::Trace(visitor); FontSelectorClient::Trace(visitor); @@ -207,7 +207,7 @@ InternalPopupMenu::~InternalPopupMenu() { DCHECK(!popup_); } -void InternalPopupMenu::Trace(Visitor* visitor) { +void InternalPopupMenu::Trace(Visitor* visitor) const { visitor->Trace(chrome_client_); visitor->Trace(owner_element_); PopupMenu::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/core/html/forms/internal_popup_menu.h b/chromium/third_party/blink/renderer/core/html/forms/internal_popup_menu.h index ccd7c5f5304..b9eec5394fd 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/internal_popup_menu.h +++ b/chromium/third_party/blink/renderer/core/html/forms/internal_popup_menu.h @@ -27,7 +27,7 @@ class CORE_EXPORT InternalPopupMenu final : public PopupMenu, public: InternalPopupMenu(ChromeClient*, HTMLSelectElement&); ~InternalPopupMenu() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void Update(bool force_update) override; diff --git a/chromium/third_party/blink/renderer/core/html/forms/listed_element.cc b/chromium/third_party/blink/renderer/core/html/forms/listed_element.cc index 5bfc398d3bb..a55a83f6742 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/listed_element.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/listed_element.cc @@ -55,7 +55,7 @@ class FormAttributeTargetObserver : public IdTargetObserver { public: FormAttributeTargetObserver(const AtomicString& id, ListedElement*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void IdTargetChanged() override; private: @@ -74,7 +74,7 @@ ListedElement::~ListedElement() { // We can't call setForm here because it contains virtual calls. } -void ListedElement::Trace(Visitor* visitor) { +void ListedElement::Trace(Visitor* visitor) const { visitor->Trace(form_attribute_target_observer_); visitor->Trace(form_); visitor->Trace(validity_state_); @@ -703,7 +703,7 @@ FormAttributeTargetObserver::FormAttributeTargetObserver(const AtomicString& id, id), element_(element) {} -void FormAttributeTargetObserver::Trace(Visitor* visitor) { +void FormAttributeTargetObserver::Trace(Visitor* visitor) const { visitor->Trace(element_); IdTargetObserver::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/forms/listed_element.h b/chromium/third_party/blink/renderer/core/html/forms/listed_element.h index 1d3c8f53346..bd6071b5303 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/listed_element.h +++ b/chromium/third_party/blink/renderer/core/html/forms/listed_element.h @@ -170,7 +170,7 @@ class CORE_EXPORT ListedElement : public GarbageCollectedMixin { // This should be called in Element::FinishParsingChildren() override. void TakeStateAndRestore(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: ListedElement(); diff --git a/chromium/third_party/blink/renderer/core/html/forms/menu_list_inner_element.cc b/chromium/third_party/blink/renderer/core/html/forms/menu_list_inner_element.cc index abd197d33c8..f96b288b259 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/menu_list_inner_element.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/menu_list_inner_element.cc @@ -33,6 +33,16 @@ MenuListInnerElement::CustomStyleForLayoutObject() { style->SetTextOverflow(parent_style.TextOverflow()); style->SetUserModify(EUserModify::kReadOnly); + if (style->LineHeight() == ComputedStyleInitialValues::InitialLineHeight()) { + // line-height should be consistent with MenuListIntrinsicBlockSize() + // in layout_box.cc. + const SimpleFontData* font_data = style->GetFont().PrimaryFont(); + if (font_data) + style->SetLineHeight(Length::Fixed(font_data->GetFontMetrics().Height())); + else + style->SetLineHeight(Length::Fixed(style->FontSize())); + } + // Use margin:auto instead of align-items:center to get safe centering, i.e. // when the content overflows, treat it the same as align-items: flex-start. // But we only do that for the cases where html.css would otherwise use diff --git a/chromium/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc b/chromium/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc index f204c7d2228..8476f173821 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.cc @@ -294,6 +294,11 @@ void MultipleFieldsTemporalInputTypeView::PickerIndicatorChooseValue( if (input_type_->FormControlType() == input_type_names::kTime) { if (date.ParseTime(value, 0, end) && end == value.length()) edit->SetOnlyTime(date); + } else if (features::IsFormControlsRefreshEnabled() && + input_type_->FormControlType() == + input_type_names::kDatetimeLocal) { + if (date.ParseDateTimeLocal(value, 0, end) && end == value.length()) + edit->SetDateTimeLocal(date); } else { if (date.ParseDate(value, 0, end) && end == value.length()) edit->SetOnlyYearMonthDay(date); @@ -354,7 +359,7 @@ MultipleFieldsTemporalInputTypeView::MultipleFieldsTemporalInputTypeView( MultipleFieldsTemporalInputTypeView::~MultipleFieldsTemporalInputTypeView() = default; -void MultipleFieldsTemporalInputTypeView::Trace(Visitor* visitor) { +void MultipleFieldsTemporalInputTypeView::Trace(Visitor* visitor) const { visitor->Trace(input_type_); InputTypeView::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.h b/chromium/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.h index 2f4522ade10..01acc92336b 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.h +++ b/chromium/third_party/blink/renderer/core/html/forms/multiple_fields_temporal_input_type_view.h @@ -56,7 +56,7 @@ class MultipleFieldsTemporalInputTypeView final MultipleFieldsTemporalInputTypeView(HTMLInputElement&, BaseTemporalInputType&); ~MultipleFieldsTemporalInputTypeView() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; String RawValue() const override; diff --git a/chromium/third_party/blink/renderer/core/html/forms/option_list_test.cc b/chromium/third_party/blink/renderer/core/html/forms/option_list_test.cc index 71941a49f9e..a1f98089e6d 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/option_list_test.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/option_list_test.cc @@ -23,7 +23,7 @@ AtomicString Id(const HTMLOptionElement* option) { class OptionListTest : public testing::Test { protected: void SetUp() override { - auto* document = MakeGarbageCollected<HTMLDocument>(); + auto* document = HTMLDocument::CreateForTest(); auto* select = MakeGarbageCollected<HTMLSelectElement>(*document); document->AppendChild(select); select_ = select; diff --git a/chromium/third_party/blink/renderer/core/html/forms/picker_indicator_element.cc b/chromium/third_party/blink/renderer/core/html/forms/picker_indicator_element.cc index e9e58542693..07623a20ded 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/picker_indicator_element.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/picker_indicator_element.cc @@ -190,7 +190,7 @@ void PickerIndicatorElement::DidNotifySubtreeInsertionsToDocument() { this->picker_indicator_owner_->AriaRoleForPickerIndicator())); } -void PickerIndicatorElement::Trace(Visitor* visitor) { +void PickerIndicatorElement::Trace(Visitor* visitor) const { visitor->Trace(picker_indicator_owner_); visitor->Trace(chooser_); HTMLDivElement::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/core/html/forms/picker_indicator_element.h b/chromium/third_party/blink/renderer/core/html/forms/picker_indicator_element.h index 4aa8b3237f8..c92e4fd7906 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/picker_indicator_element.h +++ b/chromium/third_party/blink/renderer/core/html/forms/picker_indicator_element.h @@ -59,7 +59,7 @@ class PickerIndicatorElement final : public HTMLDivElement, PickerIndicatorElement(Document&, PickerIndicatorOwner&); ~PickerIndicatorElement() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void OpenPopup(); void ClosePopup(); diff --git a/chromium/third_party/blink/renderer/core/html/forms/popup_menu.h b/chromium/third_party/blink/renderer/core/html/forms/popup_menu.h index af7e1aa3b63..0bb4cb9222d 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/popup_menu.h +++ b/chromium/third_party/blink/renderer/core/html/forms/popup_menu.h @@ -29,7 +29,7 @@ namespace blink { class PopupMenu : public GarbageCollected<PopupMenu> { public: virtual ~PopupMenu() = default; - virtual void Trace(Visitor* visitor) {} + virtual void Trace(Visitor* visitor) const {} virtual void Show() = 0; virtual void Hide() = 0; enum UpdateReason { diff --git a/chromium/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc b/chromium/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc index 9191f0d96a3..1cdacdcbfab 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/radio_button_group_scope.cc @@ -41,7 +41,7 @@ class RadioButtonGroup : public GarbageCollected<RadioButtonGroup> { bool Contains(HTMLInputElement*) const; unsigned size() const; - void Trace(Visitor*); + void Trace(Visitor*) const; private: void SetNeedsValidityCheckForAllButtons(); @@ -189,7 +189,7 @@ unsigned RadioButtonGroup::size() const { return members_.size(); } -void RadioButtonGroup::Trace(Visitor* visitor) { +void RadioButtonGroup::Trace(Visitor* visitor) const { visitor->Trace(members_); visitor->Trace(checked_button_); } @@ -289,7 +289,7 @@ void RadioButtonGroupScope::RemoveButton(HTMLInputElement* element) { } } -void RadioButtonGroupScope::Trace(Visitor* visitor) { +void RadioButtonGroupScope::Trace(Visitor* visitor) const { visitor->Trace(name_to_group_map_); } diff --git a/chromium/third_party/blink/renderer/core/html/forms/radio_button_group_scope.h b/chromium/third_party/blink/renderer/core/html/forms/radio_button_group_scope.h index a6ba8d9f217..f739c99b1bc 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/radio_button_group_scope.h +++ b/chromium/third_party/blink/renderer/core/html/forms/radio_button_group_scope.h @@ -36,7 +36,7 @@ class RadioButtonGroupScope { public: RadioButtonGroupScope(); - void Trace(Visitor*); + void Trace(Visitor*) const; void AddButton(HTMLInputElement*); void UpdateCheckedState(HTMLInputElement*); void RequiredAttributeChanged(HTMLInputElement*); diff --git a/chromium/third_party/blink/renderer/core/html/forms/range_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/range_input_type.cc index 253ea5a28d3..3111ce0d95a 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/range_input_type.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/range_input_type.cc @@ -76,7 +76,7 @@ RangeInputType::RangeInputType(HTMLInputElement& element) InputTypeView(element), tick_mark_values_dirty_(true) {} -void RangeInputType::Trace(Visitor* visitor) { +void RangeInputType::Trace(Visitor* visitor) const { InputTypeView::Trace(visitor); InputType::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/forms/range_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/range_input_type.h index 013379890dc..98010d92176 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/range_input_type.h +++ b/chromium/third_party/blink/renderer/core/html/forms/range_input_type.h @@ -45,7 +45,7 @@ class RangeInputType final : public InputType, public InputTypeView { public: explicit RangeInputType(HTMLInputElement&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; using InputType::GetElement; private: diff --git a/chromium/third_party/blink/renderer/core/html/forms/resources/calendar_picker_refresh.css b/chromium/third_party/blink/renderer/core/html/forms/resources/calendar_picker_refresh.css index 69a6fc615e6..f72ea7e1c3f 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/resources/calendar_picker_refresh.css +++ b/chromium/third_party/blink/renderer/core/html/forms/resources/calendar_picker_refresh.css @@ -255,6 +255,19 @@ body { fill: GrayText; } + .month-popup-button, + .month-popup-button:hover, + .month-popup-button:disabled { + background-color: Canvas; + color: CanvasText; + forced-color-adjust: none; + opacity: 1.0; + } + + .month-popup-button:disabled { + color: GrayText !important; + } + .month-popup-button polygon { fill: WindowText !important; } @@ -370,3 +383,128 @@ body { forced-color-adjust: none; } } + +@media (prefers-color-scheme: dark) { + .calendar-picker { + background-color: #4a4a4a; + color:#ffffff; + } + + .calendar-table-header-view { + background-color: #4a4a4a; + } + + .calendar-navigation-button { + background-color: #4a4a4a; + color: #ffffff; + } + + .calendar-navigation-button:hover { + background-color: rgba(195, 195, 195, 0.3); + } + + .calendar-navigation-button:disabled { + background-color: #4a4a4a; + } + + .month-popup-button:disabled { + background-color: #4a4a4a; + color: rgba(255, 255, 255, 0.3); + } + + .day-cell { + background-color: #4a4a4a; + color: rgba(255, 255, 255, 0.6); + } + + .day-cell.current-month { + color: #ffffff; + } + + .month-button:hover { + background-color: rgba(195, 195, 195, 0.3); + } + + :not(.week-picker) > .calendar-table-view > .scroll-view > .scroll-view-content + > .calendar-row-cell > .day-cell:not(.selected):hover { + background-color: rgba(195, 195, 195, 0.3); + } + + .week-picker .calendar-row-cell:hover + .day-cell:not(.selected):not(.disabled):not(:nth-child(2)), + .week-picker .calendar-row-cell:hover + .calendar-row-cell + .day-cell:not(.selected):not(.disabled):nth-child(2), + .calendar-row-cell:hover .week-number-cell:not(.selected):not(.disabled) { + background-color: rgba(195, 195, 195, 0.3); + } + + .day-cell.selected, + .month-button.selected, + .week-number-cell.selected { + background-color: rgba(195, 195, 195, 0.5); + color: #FFFFFF; + } + + .day-cell.disabled, + .day-cell.disabled.today, + .month-button[aria-disabled="true"], + .week-number-cell.disabled { + background-color: #4a4a4a; + color: rgba(255, 255, 255, 0.3); + } + + .today-button-refresh:hover { + background-color: rgba(195, 195, 195, 0.3); + } + + .today-button-refresh:disabled { + background-color: #4a4a4a; + color: rgba(255, 255, 255, 0.3); + } + + .year-list-cell .label { + background-color: #4a4a4a; + color: #ffffff; + } + + body { + background-color: #4a4a4a; + } + + .month-popup-button, + .month-popup-button:hover, + .month-popup-button:disabled { + color: #ffffff; + } + + .scrubby-scroll-bar { + background-color: #4a4a4a; + border-left: 1px solid #4a4a4a; + } + + .scrubby-scroll-thumb { + background-color: #d8d8d8; + } + + .calendar-navigation-button path { + fill: #ffffff; + } + + .month-popup-button polygon { + fill: #ffffff; + } + + .month-popup-button:disabled polygon { + fill: #ffffff; + } + + .year-list-cell .month-chooser { + background-color: #4a4a4a; + } + + .month-button { + background-color: #4a4a4a; + color: #ffffff; + } + +} diff --git a/chromium/third_party/blink/renderer/core/html/forms/resources/color_picker.css b/chromium/third_party/blink/renderer/core/html/forms/resources/color_picker.css index 467b28893ee..25638da7926 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/resources/color_picker.css +++ b/chromium/third_party/blink/renderer/core/html/forms/resources/color_picker.css @@ -45,9 +45,15 @@ hue-slider { } eye-dropper { + background-image: -webkit-image-set(url(eye_dropper_icon.svg) 1x); + background-origin: content-box; + background-repeat: no-repeat; + background-size: contain; border-radius: 2px; + box-sizing: border-box; height: 32px; margin-left: 2%; + padding: 6px; position: relative; width: 32px; } @@ -64,14 +70,6 @@ eye-dropper.selected { background-color: #CECECE; } -eye-dropper > svg { - height: 16px; - left: 25%; - position: absolute; - top: 25%; - width: 16px; -} - color-viewer { border: 1px solid rgba(0, 0, 0, 0.19); border-radius: 50%; @@ -213,4 +211,27 @@ channel-label { format-toggler { border: 1px solid WindowText; } -}
\ No newline at end of file +} + +@media (prefers-color-scheme: dark) { + color-picker { + background: #4A4A4A; + color: #FFFFFF; + border: 1px solid #000000; + } + + format-toggler:hover { + background-color: #545454; + } + + input { + background: #4A4A4A; + color: #FFFFFF; + border: 1px solid #FFFFFF; + } + + .up-down-icon path { + fill: #FFFFFF; + } + + }
\ No newline at end of file diff --git a/chromium/third_party/blink/renderer/core/html/forms/resources/color_picker.js b/chromium/third_party/blink/renderer/core/html/forms/resources/color_picker.js index c2c2366c838..27a78541e93 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/resources/color_picker.js +++ b/chromium/third_party/blink/renderer/core/html/forms/resources/color_picker.js @@ -811,56 +811,6 @@ class EyeDropper extends HTMLElement { } this.setAttribute('tabIndex', 0); - this.innerHTML = - '<svg width="16" height="16" viewBox="0 0 16 16" fill="none" ' + - 'xmlns="http://www.w3.org/2000/svg"><path d="M13.7344 0C14.0469 0 ' + - '14.3411 0.0598958 14.6172 0.179688C14.8932 0.299479 15.1328 ' + - '0.460938 15.3359 0.664062C15.5391 0.867188 15.7005 1.10677 15.8203 ' + - '1.38281C15.9401 1.65885 16 1.95312 16 2.26562C16 2.56771 15.9427 ' + - '2.85938 15.8281 3.14062C15.7135 3.41667 15.5495 3.66146 15.3359 ' + - '3.875L13.4609 5.75C13.6328 5.91667 13.7656 6.10677 13.8594 ' + - '6.32031C13.9531 6.52865 14 6.75521 14 7C14 7.23958 13.9531 7.46354 ' + - '13.8594 7.67188C13.7708 7.88021 13.6432 8.06771 13.4766 ' + - '8.23438L12.25 9.46094L11 8.20312L4.71094 14.4922L4.50781 ' + - '14.5C4.24219 14.5104 4.01302 14.5547 3.82031 14.6328C3.63281 ' + - '14.7109 3.46615 14.8073 3.32031 14.9219C3.17969 15.0312 3.04948 ' + - '15.1484 2.92969 15.2734C2.8151 15.3984 2.69271 15.5156 2.5625 ' + - '15.625C2.43229 15.7344 2.28906 15.8255 2.13281 15.8984C1.97656 ' + - '15.9661 1.78646 16 1.5625 16C1.34896 16 1.14583 15.9583 0.953125 ' + - '15.875C0.765625 15.7917 0.601562 15.6797 0.460938 15.5391C0.320312 ' + - '15.3984 0.208333 15.2344 0.125 15.0469C0.0416667 14.8542 0 14.651 0 ' + - '14.4375C0 14.2135 0.0338542 14.0234 0.101562 13.8672C0.174479 ' + - '13.7057 0.265625 13.5625 0.375 13.4375C0.484375 13.3073 0.601562 ' + - '13.1849 0.726562 13.0703C0.851562 12.9505 0.96875 12.8203 1.07812 ' + - '12.6797C1.19271 12.5339 1.28906 12.3672 1.36719 12.1797C1.44531 ' + - '11.9922 1.48958 11.763 1.5 11.4922L1.50781 11.2891L7.79688 ' + - '5L6.53906 3.75L7.76562 2.52344C7.93229 2.35677 8.11979 2.22917 ' + - '8.32812 2.14062C8.53646 2.04688 8.76042 2 9 2C9.24479 2 9.47135 ' + - '2.04688 9.67969 2.14062C9.89323 2.23438 10.0833 2.36719 10.25 ' + - '2.53906L12.125 0.664062C12.3385 0.450521 12.5833 0.286458 12.8594 ' + - '0.171875C13.1406 0.0572917 13.4323 0 13.7344 0ZM10.2891 7.5L8.5 ' + - '5.71094L2.49219 11.7188C2.46615 11.9844 2.41667 12.2214 2.34375 ' + - '12.4297C2.27083 12.638 2.17708 12.8333 2.0625 13.0156C1.94792 ' + - '13.1927 1.8125 13.3646 1.65625 13.5312C1.50521 13.6927 1.34115 ' + - '13.8646 1.16406 14.0469C1.05469 14.1562 1 14.2891 1 14.4453C1 ' + - '14.5964 1.05469 14.7266 1.16406 14.8359C1.27344 14.9453 1.40365 15 ' + - '1.55469 15C1.71094 15 1.84375 14.9453 1.95312 14.8359C2.13542 ' + - '14.6589 2.3099 14.4948 2.47656 14.3438C2.64323 14.1875 2.8151 ' + - '14.0521 2.99219 13.9375C3.16927 13.8229 3.36198 13.7292 3.57031 ' + - '13.6562C3.77865 13.5833 4.01562 13.5339 4.28125 13.5078L10.2891 ' + - '7.5ZM14.625 3.16406C14.875 2.91406 15 2.61719 15 2.27344C15 2.10156 ' + - '14.9661 1.9375 14.8984 1.78125C14.8307 1.625 14.7396 1.48958 14.625 ' + - '1.375C14.5104 1.26042 14.375 1.16927 14.2188 1.10156C14.0625 ' + - '1.03385 13.8984 1 13.7266 1C13.3828 1 13.0859 1.125 12.8359 ' + - '1.375L10.25 3.95312L9.51562 3.21875C9.36979 3.07292 9.19792 3 9 ' + - '3C8.89062 3 8.78646 3.02604 8.6875 3.07812C8.59375 3.13021 8.5026 ' + - '3.19531 8.41406 3.27344C8.33073 3.35156 8.25 3.4349 8.17188 ' + - '3.52344C8.09375 3.60677 8.02083 3.68229 7.95312 3.75L12.25 ' + - '8.04688L12.7812 7.51562C12.9271 7.36979 13 7.19792 13 7C13 6.89583 ' + - '12.9792 6.80208 12.9375 6.71875C12.901 6.63021 12.8464 6.54948 ' + - '12.7734 6.47656L12.0469 5.75L14.625 3.16406Z" fill="WindowText"/> ' + - '</svg>'; - this.addEventListener('click', this.onClick_); this.addEventListener('keydown', this.onKeyDown_); } @@ -1982,7 +1932,7 @@ class FormatToggler extends HTMLElement { this.upDownIcon_ = document.createElement('span'); this.upDownIcon_.setAttribute('id', 'up-down-icon'); this.upDownIcon_.innerHTML = - '<svg width="6" height="8" viewBox="0 0 6 8" fill="none" ' + + '<svg class="up-down-icon" width="6" height="8" viewBox="0 0 6 8" fill="none" ' + 'xmlns="http://www.w3.org/2000/svg"><path d="M1.18359 ' + '3.18359L0.617188 2.61719L3 0.234375L5.38281 2.61719L4.81641 ' + '3.18359L3 1.36719L1.18359 3.18359ZM4.81641 4.81641L5.38281 ' + diff --git a/chromium/third_party/blink/renderer/core/html/forms/resources/eye_dropper_icon.svg b/chromium/third_party/blink/renderer/core/html/forms/resources/eye_dropper_icon.svg new file mode 100644 index 00000000000..20d39973b8b --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/forms/resources/eye_dropper_icon.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 0 24 24" width="20"><path d="M0 0h24v24H0z" fill="none"/><path fill="WindowText" d="M20.71 5.63l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-3.12 3.12-1.93-1.91-1.41 1.41 1.42 1.42L3 16.25V21h4.75l8.92-8.92 1.42 1.42 1.41-1.41-1.92-1.92 3.12-3.12c.4-.4.4-1.03.01-1.42zM6.92 19L5 17.08l8.06-8.06 1.92 1.92L6.92 19z"/></svg>
\ No newline at end of file diff --git a/chromium/third_party/blink/renderer/core/html/forms/resources/suggestionPicker.css b/chromium/third_party/blink/renderer/core/html/forms/resources/suggestionPicker.css index 011130295f3..30837f148de 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/resources/suggestionPicker.css +++ b/chromium/third_party/blink/renderer/core/html/forms/resources/suggestionPicker.css @@ -82,13 +82,18 @@ } @media (forced-colors: active) { - .suggestion-list-entry:focus { + .controls-refresh .suggestion-list-entry:focus { background-color: Highlight !important; - color: Window !important; forced-color-adjust: none; } - .suggestion-list-entry:focus .label { - color: Window !important; + .controls-refresh .suggestion-list-entry:focus .label, + .controls-refresh .suggestion-list-entry:focus .title { + color: HighlightText !important; + } + + .controls-refresh .suggestion-list-entry .label, + .controls-refresh .suggestion-list-entry .title { + color: WindowText !important; } } diff --git a/chromium/third_party/blink/renderer/core/html/forms/resources/time_picker.css b/chromium/third_party/blink/renderer/core/html/forms/resources/time_picker.css index 2a460119fea..0205061c648 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/resources/time_picker.css +++ b/chromium/third_party/blink/renderer/core/html/forms/resources/time_picker.css @@ -82,3 +82,23 @@ border-color: WindowText; } } + +@media (prefers-color-scheme: dark) { + .time-picker { + background: #4a4a4a; + border: 1px solid #bfbfbf; + } + + .time-cell { + color: #ffffff; + } + + .time-cell:hover { + background-color: rgba(195, 195, 195, 0.3); + } + + .time-cell.selected { + background-color: rgba(195, 195, 195, 0.5); + color: #FFFFFF; + } +} diff --git a/chromium/third_party/blink/renderer/core/html/forms/select_type.cc b/chromium/third_party/blink/renderer/core/html/forms/select_type.cc index 6048bc713fc..a2770356481 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/select_type.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/select_type.cc @@ -36,6 +36,7 @@ #include "third_party/blink/renderer/core/dom/mutation_observer.h" #include "third_party/blink/renderer/core/dom/mutation_record.h" #include "third_party/blink/renderer/core/dom/node_computed_style.h" +#include "third_party/blink/renderer/core/dom/text.h" #include "third_party/blink/renderer/core/events/gesture_event.h" #include "third_party/blink/renderer/core/events/keyboard_event.h" #include "third_party/blink/renderer/core/events/mouse_event.h" @@ -43,6 +44,7 @@ #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/html/forms/html_form_element.h" #include "third_party/blink/renderer/core/html/forms/html_select_element.h" +#include "third_party/blink/renderer/core/html/forms/menu_list_inner_element.h" #include "third_party/blink/renderer/core/html/forms/popup_menu.h" #include "third_party/blink/renderer/core/input/event_handler.h" #include "third_party/blink/renderer/core/input/input_device_capabilities.h" @@ -72,7 +74,7 @@ HTMLOptionElement* EventTargetOption(const Event& event) { class MenuListSelectType final : public SelectType { public: explicit MenuListSelectType(HTMLSelectElement& select) : SelectType(select) {} - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; bool DefaultEventHandler(const Event& event) override; void DidSelectOption(HTMLOptionElement* element, @@ -92,6 +94,8 @@ class MenuListSelectType final : public SelectType { } void MaximumOptionWidthMightBeChanged() const override; + void CreateShadowSubtree(ShadowRoot& root) override; + Element& InnerElement() const override; void ShowPopup() override; void HidePopup() override; void PopupDidHide() override; @@ -121,7 +125,7 @@ class MenuListSelectType final : public SelectType { bool snav_arrow_key_selection_ = false; }; -void MenuListSelectType::Trace(Visitor* visitor) { +void MenuListSelectType::Trace(Visitor* visitor) const { visitor->Trace(popup_); visitor->Trace(popup_updater_); SelectType::Trace(visitor); @@ -292,6 +296,22 @@ bool MenuListSelectType::HandlePopupOpenKeyboardEvent() { return true; } +void MenuListSelectType::CreateShadowSubtree(ShadowRoot& root) { + Document& doc = select_->GetDocument(); + Element* inner_element = MakeGarbageCollected<MenuListInnerElement>(doc); + inner_element->setAttribute(html_names::kAriaHiddenAttr, "true"); + // Make sure InnerElement() always has a Text node. + inner_element->appendChild(Text::Create(doc, g_empty_string)); + root.insertBefore(inner_element, root.firstChild()); +} + +Element& MenuListSelectType::InnerElement() const { + auto* inner_element = + DynamicTo<Element>(select_->UserAgentShadowRoot()->firstChild()); + DCHECK(inner_element); + return *inner_element; +} + void MenuListSelectType::ShowPopup() { if (PopupIsVisible()) return; @@ -365,7 +385,7 @@ void MenuListSelectType::DidSelectOption( if (PopupIsVisible() && should_update_popup) popup_->UpdateFromElement(PopupMenu::kBySelectionChange); - SelectType::DidSelectOption(element, flags, should_update_popup); + select_->SetNeedsValidityCheck(); if (should_dispatch_events) { select_->DispatchInputEvent(); @@ -577,7 +597,7 @@ class PopupUpdater : public MutationObserver::Delegate { void Dispose() { observer_->disconnect(); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(select_type_); visitor->Trace(select_); visitor->Trace(observer_); @@ -613,13 +633,19 @@ void MenuListSelectType::DidMutateSubtree() { class ListBoxSelectType final : public SelectType { public: explicit ListBoxSelectType(HTMLSelectElement& select) : SelectType(select) {} - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; bool DefaultEventHandler(const Event& event) override; + void DidSelectOption(HTMLOptionElement* element, + HTMLSelectElement::SelectOptionFlags flags, + bool should_update_popup) override; void OptionRemoved(HTMLOptionElement& option) override; void DidBlur() override; void DidSetSuggestedOption(HTMLOptionElement* option) override; void SaveLastSelection() override; + HTMLOptionElement* SpatialNavigationFocusedOption() override; + HTMLOptionElement* ActiveSelectionEnd() const override; + void ScrollToSelection() override; void ScrollToOption(HTMLOptionElement* option) override; void SelectAll() override; void SaveListboxActiveSelection() override; @@ -641,17 +667,23 @@ class ListBoxSelectType final : public SelectType { void UpdateSelectedState(HTMLOptionElement* clicked_option, SelectionMode mode); void UpdateListBoxSelection(bool deselect_other_options, bool scroll = true); + void SetActiveSelectionAnchor(HTMLOptionElement*); + void SetActiveSelectionEnd(HTMLOptionElement*); void ScrollToOptionTask(); Vector<bool> cached_state_for_active_selection_; Vector<bool> last_on_change_selection_; Member<HTMLOptionElement> option_to_scroll_to_; + Member<HTMLOptionElement> active_selection_anchor_; + Member<HTMLOptionElement> active_selection_end_; bool is_in_non_contiguous_selection_ = false; bool active_selection_state_ = false; }; -void ListBoxSelectType::Trace(Visitor* visitor) { +void ListBoxSelectType::Trace(Visitor* visitor) const { visitor->Trace(option_to_scroll_to_); + visitor->Trace(active_selection_anchor_); + visitor->Trace(active_selection_end_); SelectType::Trace(visitor); } @@ -733,14 +765,14 @@ bool ListBoxSelectType::DefaultEventHandler(const Event& event) { if (!select_->IsDisabledFormControl()) { if (select_->is_multiple_) { // Only extend selection if there is something selected. - if (!select_->active_selection_anchor_) + if (!active_selection_anchor_) return false; - select_->SetActiveSelectionEnd(option); + SetActiveSelectionEnd(option); UpdateListBoxSelection(false); } else { - select_->SetActiveSelectionAnchor(option); - select_->SetActiveSelectionEnd(option); + SetActiveSelectionAnchor(option); + SetActiveSelectionEnd(option); UpdateListBoxSelection(true); } } @@ -769,7 +801,7 @@ bool ListBoxSelectType::DefaultEventHandler(const Event& event) { bool handled = false; HTMLOptionElement* end_option = nullptr; - if (!select_->active_selection_end_) { + if (!active_selection_end_) { // Initialize the end index if (key == "ArrowDown" || key == "PageDown") { HTMLOptionElement* start_option = select_->LastSelectedOption(); @@ -793,19 +825,18 @@ bool ListBoxSelectType::DefaultEventHandler(const Event& event) { } else { // Set the end index based on the current end index. if (key == "ArrowDown") { - end_option = NextSelectableOption(select_->active_selection_end_.Get()); + end_option = NextSelectableOption(active_selection_end_); handled = true; } else if (key == "ArrowUp") { - end_option = - PreviousSelectableOption(select_->active_selection_end_.Get()); + end_option = PreviousSelectableOption(active_selection_end_); handled = true; } else if (key == "PageDown") { - end_option = NextSelectableOptionPageAway( - select_->active_selection_end_.Get(), kSkipForwards); + end_option = + NextSelectableOptionPageAway(active_selection_end_, kSkipForwards); handled = true; } else if (key == "PageUp") { - end_option = NextSelectableOptionPageAway( - select_->active_selection_end_.Get(), kSkipBackwards); + end_option = + NextSelectableOptionPageAway(active_selection_end_, kSkipBackwards); handled = true; } } @@ -821,7 +852,7 @@ bool ListBoxSelectType::DefaultEventHandler(const Event& event) { // Check if the selection moves to the boundary. if (key == "ArrowLeft" || key == "ArrowRight" || ((key == "ArrowDown" || key == "ArrowUp") && - end_option == select_->active_selection_end_)) + end_option == active_selection_end_)) return false; } @@ -833,9 +864,9 @@ bool ListBoxSelectType::DefaultEventHandler(const Event& event) { #endif if (select_->is_multiple_ && keyboard_event->keyCode() == ' ' && - is_control_key && select_->active_selection_end_) { + is_control_key && active_selection_end_) { // Use ctrl+space to toggle selection change. - ToggleSelection(*select_->active_selection_end_); + ToggleSelection(*active_selection_end_); return true; } @@ -845,7 +876,7 @@ bool ListBoxSelectType::DefaultEventHandler(const Event& event) { // selection. SaveLastSelection(); - select_->SetActiveSelectionEnd(end_option); + SetActiveSelectionEnd(end_option); is_in_non_contiguous_selection_ = select_->is_multiple_ && is_control_key; bool select_new_item = @@ -858,10 +889,10 @@ bool ListBoxSelectType::DefaultEventHandler(const Event& event) { // other options, then set the anchor index equal to the end index. bool deselect_others = !select_->is_multiple_ || (!keyboard_event->shiftKey() && select_new_item); - if (!select_->active_selection_anchor_ || deselect_others) { + if (!active_selection_anchor_ || deselect_others) { if (deselect_others) select_->DeselectItemsWithoutValidation(); - select_->SetActiveSelectionAnchor(select_->active_selection_end_.Get()); + SetActiveSelectionAnchor(active_selection_end_.Get()); } ScrollToOption(end_option); @@ -872,7 +903,7 @@ bool ListBoxSelectType::DefaultEventHandler(const Event& event) { } UpdateMultiSelectFocus(); } else { - select_->ScrollToSelection(); + ScrollToSelection(); } return true; @@ -893,7 +924,7 @@ bool ListBoxSelectType::DefaultEventHandler(const Event& event) { } else if (select_->is_multiple_ && key_code == ' ' && (IsSpatialNavigationEnabled(select_->GetDocument().GetFrame()) || is_in_non_contiguous_selection_)) { - HTMLOptionElement* option = select_->active_selection_end_; + HTMLOptionElement* option = active_selection_end_; // If there's no active selection, // act as if "ArrowDown" had been pressed. if (!option) @@ -909,9 +940,34 @@ bool ListBoxSelectType::DefaultEventHandler(const Event& event) { return false; } +void ListBoxSelectType::DidSelectOption( + HTMLOptionElement* element, + HTMLSelectElement::SelectOptionFlags flags, + bool should_update_popup) { + // We should update active selection after finishing OPTION state change + // because SetActiveSelectionAnchor() stores OPTION's selection state. + if (element) { + const bool is_single = !select_->IsMultiple(); + const bool deselect_other_options = + flags & HTMLSelectElement::kDeselectOtherOptionsFlag; + // SetActiveSelectionAnchor is O(N). + if (!active_selection_anchor_ || is_single || deselect_other_options) + SetActiveSelectionAnchor(element); + if (!active_selection_end_ || is_single || deselect_other_options) + SetActiveSelectionEnd(element); + } + + ScrollToSelection(); + select_->SetNeedsValidityCheck(); +} + void ListBoxSelectType::OptionRemoved(HTMLOptionElement& option) { if (option_to_scroll_to_ == &option) option_to_scroll_to_.Clear(); + if (active_selection_anchor_ == &option) + active_selection_anchor_.Clear(); + if (active_selection_end_ == &option) + active_selection_end_.Clear(); } void ListBoxSelectType::DidBlur() { @@ -939,11 +995,42 @@ void ListBoxSelectType::UpdateMultiSelectFocus() { for (auto* const option : select_->GetOptionList()) { if (option->IsDisabledFormControl() || !option->GetLayoutObject()) continue; - bool is_focused = (option == select_->active_selection_end_) && - is_in_non_contiguous_selection_; + bool is_focused = + (option == active_selection_end_) && is_in_non_contiguous_selection_; option->SetMultiSelectFocusedState(is_focused); } - select_->ScrollToSelection(); + ScrollToSelection(); +} + +HTMLOptionElement* ListBoxSelectType::SpatialNavigationFocusedOption() { + if (!IsSpatialNavigationEnabled(select_->GetDocument().GetFrame())) + return nullptr; + if (HTMLOptionElement* option = ActiveSelectionEnd()) + return option; + return FirstSelectableOption(); +} + +void ListBoxSelectType::SetActiveSelectionAnchor(HTMLOptionElement* option) { + active_selection_anchor_ = option; + SaveListboxActiveSelection(); +} + +void ListBoxSelectType::SetActiveSelectionEnd(HTMLOptionElement* option) { + active_selection_end_ = option; +} + +HTMLOptionElement* ListBoxSelectType::ActiveSelectionEnd() const { + if (active_selection_end_) + return active_selection_end_; + return select_->LastSelectedOption(); +} + +void ListBoxSelectType::ScrollToSelection() { + if (!select_->IsFinishedParsingChildren()) + return; + ScrollToOption(ActiveSelectionEnd()); + if (AXObjectCache* cache = select_->GetDocument().ExistingAXObjectCache()) + cache->ListboxActiveIndexChanged(select_); } void ListBoxSelectType::ScrollToOption(HTMLOptionElement* option) { @@ -997,8 +1084,8 @@ void ListBoxSelectType::SelectAll() { SaveLastSelection(); active_selection_state_ = true; - select_->SetActiveSelectionAnchor(NextSelectableOption(nullptr)); - select_->SetActiveSelectionEnd(PreviousSelectableOption(nullptr)); + SetActiveSelectionAnchor(NextSelectableOption(nullptr)); + SetActiveSelectionEnd(PreviousSelectableOption(nullptr)); UpdateListBoxSelection(false, false); ListBoxOnChange(); @@ -1060,9 +1147,8 @@ void ListBoxSelectType::UpdateSelectedState(HTMLOptionElement* clicked_option, // If the anchor hasn't been set, and we're doing kDeselectOthers or kRange, // then initialize the anchor to the first selected OPTION. - if (!select_->active_selection_anchor_ && - mode != SelectionMode::kNotChangeOthers) - select_->SetActiveSelectionAnchor(select_->SelectedOption()); + if (!active_selection_anchor_ && mode != SelectionMode::kNotChangeOthers) + SetActiveSelectionAnchor(select_->SelectedOption()); // Set the selection state of the clicked OPTION. if (!clicked_option->IsDisabledFormControl()) { @@ -1073,18 +1159,18 @@ void ListBoxSelectType::UpdateSelectedState(HTMLOptionElement* clicked_option, // If there was no selectedIndex() for the previous initialization, or if // we're doing kDeselectOthers, or kNotChangeOthers (using cmd or ctrl), // then initialize the anchor OPTION to the clicked OPTION. - if (!select_->active_selection_anchor_ || mode != SelectionMode::kRange) - select_->SetActiveSelectionAnchor(clicked_option); + if (!active_selection_anchor_ || mode != SelectionMode::kRange) + SetActiveSelectionAnchor(clicked_option); - select_->SetActiveSelectionEnd(clicked_option); + SetActiveSelectionEnd(clicked_option); UpdateListBoxSelection(mode != SelectionMode::kNotChangeOthers); } void ListBoxSelectType::UpdateListBoxSelection(bool deselect_other_options, bool scroll) { DCHECK(select_->GetLayoutObject()); - HTMLOptionElement* const anchor_option = select_->active_selection_anchor_; - HTMLOptionElement* const end_option = select_->active_selection_end_; + HTMLOptionElement* const anchor_option = active_selection_anchor_; + HTMLOptionElement* const end_option = active_selection_end_; const int anchor_index = anchor_option ? anchor_option->index() : -1; const int end_index = end_option ? end_option->index() : -1; const int start = std::min(anchor_index, end_index); @@ -1113,7 +1199,7 @@ void ListBoxSelectType::UpdateListBoxSelection(bool deselect_other_options, UpdateMultiSelectFocus(); select_->SetNeedsValidityCheck(); if (scroll) - select_->ScrollToSelection(); + ScrollToSelection(); select_->NotifyFormStateChanged(); } @@ -1191,17 +1277,10 @@ void SelectType::WillBeDestroyed() { will_be_destroyed_ = true; } -void SelectType::Trace(Visitor* visitor) { +void SelectType::Trace(Visitor* visitor) const { visitor->Trace(select_); } -void SelectType::DidSelectOption(HTMLOptionElement*, - HTMLSelectElement::SelectOptionFlags, - bool) { - select_->ScrollToSelection(); - select_->SetNeedsValidityCheck(); -} - void SelectType::OptionRemoved(HTMLOptionElement& option) {} void SelectType::DidDetachLayoutTree() {} @@ -1224,6 +1303,17 @@ const ComputedStyle* SelectType::OptionStyle() const { void SelectType::MaximumOptionWidthMightBeChanged() const {} +HTMLOptionElement* SelectType::SpatialNavigationFocusedOption() { + return nullptr; +} + +HTMLOptionElement* SelectType::ActiveSelectionEnd() const { + NOTREACHED(); + return nullptr; +} + +void SelectType::ScrollToSelection() {} + void SelectType::ScrollToOption(HTMLOptionElement* option) {} void SelectType::SelectAll() { @@ -1238,6 +1328,15 @@ void SelectType::ListBoxOnChange() {} void SelectType::ClearLastOnChangeSelection() {} +void SelectType::CreateShadowSubtree(ShadowRoot& root) {} + +Element& SelectType::InnerElement() const { + NOTREACHED(); + // Returning select_ doesn't make sense, but we need to return an element + // to compile this source. This function must not be called. + return *select_; +} + void SelectType::ShowPopup() { NOTREACHED(); } diff --git a/chromium/third_party/blink/renderer/core/html/forms/select_type.h b/chromium/third_party/blink/renderer/core/html/forms/select_type.h index e6eb23d62d9..e49dad8e0ba 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/select_type.h +++ b/chromium/third_party/blink/renderer/core/html/forms/select_type.h @@ -19,14 +19,14 @@ class SelectType : public GarbageCollected<SelectType> { // of |select|. static SelectType* Create(HTMLSelectElement& select); void WillBeDestroyed(); - virtual void Trace(Visitor* visitor); + virtual void Trace(Visitor* visitor) const; // Returns true if the event is handled. virtual bool DefaultEventHandler(const Event& event) = 0; virtual void DidSelectOption(HTMLOptionElement* element, HTMLSelectElement::SelectOptionFlags flags, - bool should_update_popup); + bool should_update_popup) = 0; virtual void OptionRemoved(HTMLOptionElement& option); virtual void DidBlur() = 0; @@ -46,6 +46,9 @@ class SelectType : public GarbageCollected<SelectType> { virtual const ComputedStyle* OptionStyle() const; virtual void MaximumOptionWidthMightBeChanged() const; + virtual HTMLOptionElement* SpatialNavigationFocusedOption(); + virtual HTMLOptionElement* ActiveSelectionEnd() const; + virtual void ScrollToSelection(); virtual void ScrollToOption(HTMLOptionElement* option); virtual void SelectAll(); virtual void SaveListboxActiveSelection(); @@ -55,6 +58,8 @@ class SelectType : public GarbageCollected<SelectType> { // This is for ListBoxes. virtual void ClearLastOnChangeSelection(); + virtual void CreateShadowSubtree(ShadowRoot& root); + virtual Element& InnerElement() const; virtual void ShowPopup(); virtual void HidePopup(); virtual void PopupDidHide(); diff --git a/chromium/third_party/blink/renderer/core/html/forms/slider_thumb_element.h b/chromium/third_party/blink/renderer/core/html/forms/slider_thumb_element.h index cc4dd4d78f1..8ad31ff0604 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/slider_thumb_element.h +++ b/chromium/third_party/blink/renderer/core/html/forms/slider_thumb_element.h @@ -59,6 +59,7 @@ class SliderThumbElement final : public HTMLDivElement { HTMLInputElement* HostInput() const; void SetPositionFromPoint(const LayoutPoint&); void StopDragging(); + bool IsSliderThumbElement() const override { return true; } private: LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) override; diff --git a/chromium/third_party/blink/renderer/core/html/forms/spin_button_element.cc b/chromium/third_party/blink/renderer/core/html/forms/spin_button_element.cc index bb7179bb155..6172e243b67 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/spin_button_element.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/spin_button_element.cc @@ -221,7 +221,7 @@ bool SpinButtonElement::ShouldRespondToMouseEvents() { spin_button_owner_->ShouldSpinButtonRespondToMouseEvents(); } -void SpinButtonElement::Trace(Visitor* visitor) { +void SpinButtonElement::Trace(Visitor* visitor) const { visitor->Trace(spin_button_owner_); HTMLDivElement::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/forms/spin_button_element.h b/chromium/third_party/blink/renderer/core/html/forms/spin_button_element.h index 65f3284f0c7..b725e5f0608 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/spin_button_element.h +++ b/chromium/third_party/blink/renderer/core/html/forms/spin_button_element.h @@ -74,7 +74,7 @@ class CORE_EXPORT SpinButtonElement final : public HTMLDivElement, void ForwardEvent(Event&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void DetachLayoutTree(bool performing_reattach) override; diff --git a/chromium/third_party/blink/renderer/core/html/forms/step_range.cc b/chromium/third_party/blink/renderer/core/html/forms/step_range.cc index b4bcb5d9ebc..833df98498d 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/step_range.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/step_range.cc @@ -21,6 +21,7 @@ #include "third_party/blink/renderer/core/html/forms/step_range.h" #include <float.h> +#include "base/notreached.h" #include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h" #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" diff --git a/chromium/third_party/blink/renderer/core/html/forms/submit_event.cc b/chromium/third_party/blink/renderer/core/html/forms/submit_event.cc index 04c84a91404..0ec3ad14202 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/submit_event.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/submit_event.cc @@ -20,7 +20,7 @@ SubmitEvent* SubmitEvent::Create(const AtomicString& type, return MakeGarbageCollected<SubmitEvent>(type, event_init); } -void SubmitEvent::Trace(Visitor* visitor) { +void SubmitEvent::Trace(Visitor* visitor) const { visitor->Trace(submitter_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/forms/submit_event.h b/chromium/third_party/blink/renderer/core/html/forms/submit_event.h index 2e242d3a791..29552813e42 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/submit_event.h +++ b/chromium/third_party/blink/renderer/core/html/forms/submit_event.h @@ -20,7 +20,7 @@ class SubmitEvent : public Event { const SubmitEventInit* event_init); SubmitEvent(const AtomicString& type, const SubmitEventInit* event_init); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; HTMLElement* submitter() const { return submitter_.Get(); } const AtomicString& InterfaceName() const override; diff --git a/chromium/third_party/blink/renderer/core/html/forms/text_control_element.cc b/chromium/third_party/blink/renderer/core/html/forms/text_control_element.cc index 69211bb4443..076f2215ccc 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/text_control_element.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/text_control_element.cc @@ -1048,7 +1048,7 @@ const String& TextControlElement::SuggestedValue() const { return suggested_value_; } -void TextControlElement::Trace(Visitor* visitor) { +void TextControlElement::Trace(Visitor* visitor) const { visitor->Trace(inner_editor_); HTMLFormControlElementWithState::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/forms/text_control_element.h b/chromium/third_party/blink/renderer/core/html/forms/text_control_element.h index 740cab80101..fce400feef1 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/text_control_element.h +++ b/chromium/third_party/blink/renderer/core/html/forms/text_control_element.h @@ -151,7 +151,7 @@ class CORE_EXPORT TextControlElement : public HTMLFormControlElementWithState { virtual void SetSuggestedValue(const String& value); const String& SuggestedValue() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; ETextOverflow ValueForTextOverflow() const; diff --git a/chromium/third_party/blink/renderer/core/html/forms/text_field_input_type.cc b/chromium/third_party/blink/renderer/core/html/forms/text_field_input_type.cc index 07164ddc329..c82f3dc9f98 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/text_field_input_type.cc +++ b/chromium/third_party/blink/renderer/core/html/forms/text_field_input_type.cc @@ -108,7 +108,7 @@ TextFieldInputType::TextFieldInputType(HTMLInputElement& element) TextFieldInputType::~TextFieldInputType() = default; -void TextFieldInputType::Trace(Visitor* visitor) { +void TextFieldInputType::Trace(Visitor* visitor) const { InputTypeView::Trace(visitor); InputType::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/forms/text_field_input_type.h b/chromium/third_party/blink/renderer/core/html/forms/text_field_input_type.h index 0e7994ca51a..8040fb31b77 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/text_field_input_type.h +++ b/chromium/third_party/blink/renderer/core/html/forms/text_field_input_type.h @@ -45,7 +45,7 @@ class TextFieldInputType : public InputType, USING_GARBAGE_COLLECTED_MIXIN(TextFieldInputType); public: - void Trace(Visitor*) override; + void Trace(Visitor*) const override; using InputType::GetElement; String RawValue() const override; diff --git a/chromium/third_party/blink/renderer/core/html/forms/validity_state.h b/chromium/third_party/blink/renderer/core/html/forms/validity_state.h index df9283cd474..73453e61f04 100644 --- a/chromium/third_party/blink/renderer/core/html/forms/validity_state.h +++ b/chromium/third_party/blink/renderer/core/html/forms/validity_state.h @@ -36,7 +36,7 @@ class ValidityState final : public ScriptWrappable { public: explicit ValidityState(ListedElement* control) : control_(control) {} - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(control_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/html_anchor_element.cc b/chromium/third_party/blink/renderer/core/html/html_anchor_element.cc index 3c913396405..981526ac0d3 100644 --- a/chromium/third_party/blink/renderer/core/html/html_anchor_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_anchor_element.cc @@ -418,6 +418,11 @@ base::Optional<WebImpression> HTMLAnchorElement::GetImpressionForNavigation() expiry = base::TimeDelta::FromMilliseconds(expiry_milliseconds); } + UseCounter::Count(GetExecutionContext(), + mojom::blink::WebFeature::kConversionAPIAll); + UseCounter::Count(GetExecutionContext(), + mojom::blink::WebFeature::kImpressionRegistration); + return WebImpression{conversion_destination, reporting_origin, impression_data, expiry}; } @@ -437,7 +442,7 @@ void HTMLAnchorElement::SendPings(const KURL& destination_url) const { ping_value.Contains('\t')) && ping_value.Contains('<')) { Deprecation::CountDeprecation( - GetDocument(), WebFeature::kCanRequestURLHTTPContainingNewline); + GetExecutionContext(), WebFeature::kCanRequestURLHTTPContainingNewline); return; } @@ -531,7 +536,7 @@ void HTMLAnchorElement::HandleClick(Event& event) { // If hrefTranslate is enabled and set restrict processing it // to same frame or navigations with noopener set. - if (RuntimeEnabledFeatures::HrefTranslateEnabled(&GetDocument()) && + if (RuntimeEnabledFeatures::HrefTranslateEnabled(GetExecutionContext()) && FastHasAttribute(html_names::kHreftranslateAttr) && (target_frame == frame || frame_request.GetWindowFeatures().noopener)) { frame_request.SetHrefTranslate( @@ -541,8 +546,9 @@ void HTMLAnchorElement::HandleClick(Event& event) { } // Only attach impressions for main frame navigations. - if (RuntimeEnabledFeatures::ConversionMeasurementEnabled() && target_frame && - target_frame->IsMainFrame() && request.HasUserGesture() && + if (RuntimeEnabledFeatures::ConversionMeasurementEnabled( + GetExecutionContext()) && + target_frame && target_frame->IsMainFrame() && request.HasUserGesture() && HasImpression()) { base::Optional<WebImpression> impression = GetImpressionForNavigation(); if (impression) @@ -593,7 +599,7 @@ Node::InsertionNotificationRequest HTMLAnchorElement::InsertedInto( return request; } -void HTMLAnchorElement::Trace(Visitor* visitor) { +void HTMLAnchorElement::Trace(Visitor* visitor) const { visitor->Trace(rel_list_); HTMLElement::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/html_anchor_element.h b/chromium/third_party/blink/renderer/core/html/html_anchor_element.h index a76f6ce870c..7685ce72caa 100644 --- a/chromium/third_party/blink/renderer/core/html/html_anchor_element.h +++ b/chromium/third_party/blink/renderer/core/html/html_anchor_element.h @@ -103,7 +103,7 @@ class CORE_EXPORT HTMLAnchorElement : public HTMLElement, public DOMURLUtils { void SendPings(const KURL& destination_url) const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: void ParseAttribute(const AttributeModificationParams&) override; diff --git a/chromium/third_party/blink/renderer/core/html/html_attribute_names.json5 b/chromium/third_party/blink/renderer/core/html/html_attribute_names.json5 index f73ebeab331..7c7b7942aa3 100644 --- a/chromium/third_party/blink/renderer/core/html/html_attribute_names.json5 +++ b/chromium/third_party/blink/renderer/core/html/html_attribute_names.json5 @@ -233,7 +233,6 @@ "onportalactivate", "onprogress", "onratechange", - "onrendersubtreeactivation", "onreset", "onresize", "onscroll", @@ -283,6 +282,7 @@ "rel", "reportingorigin", "required", + "resources", "rev", "reversed", "role", @@ -330,6 +330,7 @@ "version", "vlink", "vspace", + "virtualkeyboardpolicy", "webkitdirectory", "width", "wrap", diff --git a/chromium/third_party/blink/renderer/core/html/html_body_element.cc b/chromium/third_party/blink/renderer/core/html/html_body_element.cc index f7bd4b515e7..3c45bacd725 100644 --- a/chromium/third_party/blink/renderer/core/html/html_body_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_body_element.cc @@ -66,8 +66,8 @@ void HTMLBodyElement::CollectStyleForPresentationAttribute( if (!url.IsEmpty()) { CSSImageValue* image_value = MakeGarbageCollected<CSSImageValue>( url, GetDocument().CompleteURL(url), - Referrer(GetDocument().OutgoingReferrer(), - GetDocument().GetReferrerPolicy()), + Referrer(GetExecutionContext()->OutgoingReferrer(), + GetExecutionContext()->GetReferrerPolicy()), OriginClean::kTrue, false /* is_ad_related */); image_value->SetInitiator(localName()); style->SetProperty( @@ -215,7 +215,7 @@ void HTMLBodyElement::ParseAttribute( GetDocument().SetWindowAttributeEventListener( event_type_names::kLanguagechange, CreateAttributeEventListener(GetDocument().GetFrame(), name, value)); - } else if (RuntimeEnabledFeatures::PortalsEnabled(&GetDocument()) && + } else if (RuntimeEnabledFeatures::PortalsEnabled(GetExecutionContext()) && name == html_names::kOnportalactivateAttr) { GetDocument().SetWindowAttributeEventListener( event_type_names::kPortalactivate, diff --git a/chromium/third_party/blink/renderer/core/html/html_collection.cc b/chromium/third_party/blink/renderer/core/html/html_collection.cc index 384f50b80a4..d839a92aa47 100644 --- a/chromium/third_party/blink/renderer/core/html/html_collection.cc +++ b/chromium/third_party/blink/renderer/core/html/html_collection.cc @@ -544,7 +544,7 @@ void HTMLCollection::NamedItems(const AtomicString& name, HTMLCollection::NamedItemCache::NamedItemCache() = default; -void HTMLCollection::Trace(Visitor* visitor) { +void HTMLCollection::Trace(Visitor* visitor) const { visitor->Trace(named_item_cache_); visitor->Trace(collection_items_cache_); ScriptWrappable::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/core/html/html_collection.h b/chromium/third_party/blink/renderer/core/html/html_collection.h index 3f12118654e..c4ad29a2e2d 100644 --- a/chromium/third_party/blink/renderer/core/html/html_collection.h +++ b/chromium/third_party/blink/renderer/core/html/html_collection.h @@ -114,7 +114,7 @@ class CORE_EXPORT HTMLCollection : public ScriptWrappable, Iterator begin() const { return Iterator(this); } Iterator end() const { return Iterator::CreateEnd(this); } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: class NamedItemCache final : public GarbageCollected<NamedItemCache> { @@ -142,7 +142,7 @@ class CORE_EXPORT HTMLCollection : public ScriptWrappable, AddElementToMap(name_cache_, name, element); } - void Trace(Visitor* visitor) { + void Trace(Visitor* visitor) const { visitor->Trace(id_cache_); visitor->Trace(name_cache_); } diff --git a/chromium/third_party/blink/renderer/core/html/html_content_element.cc b/chromium/third_party/blink/renderer/core/html/html_content_element.cc index 2f120a42fc5..2834d6c1063 100644 --- a/chromium/third_party/blink/renderer/core/html/html_content_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_content_element.cc @@ -48,7 +48,7 @@ HTMLContentElement::HTMLContentElement(Document& document) HTMLContentElement::~HTMLContentElement() = default; -void HTMLContentElement::Trace(Visitor* visitor) { +void HTMLContentElement::Trace(Visitor* visitor) const { V0InsertionPoint::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/html_content_element.h b/chromium/third_party/blink/renderer/core/html/html_content_element.h index 83db8015a5f..e57deb6040c 100644 --- a/chromium/third_party/blink/renderer/core/html/html_content_element.h +++ b/chromium/third_party/blink/renderer/core/html/html_content_element.h @@ -53,7 +53,7 @@ class CORE_EXPORT HTMLContentElement final : public V0InsertionPoint { const CSSSelectorList& SelectorList() const; bool IsSelectValid() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void ParseAttribute(const AttributeModificationParams&) override; diff --git a/chromium/third_party/blink/renderer/core/html/html_document.cc b/chromium/third_party/blink/renderer/core/html/html_document.cc index fa3d053df00..c3dd77c6550 100644 --- a/chromium/third_party/blink/renderer/core/html/html_document.cc +++ b/chromium/third_party/blink/renderer/core/html/html_document.cc @@ -74,10 +74,14 @@ HTMLDocument::HTMLDocument(const DocumentInit& initializer, HTMLDocument::~HTMLDocument() = default; +HTMLDocument* HTMLDocument::CreateForTest() { + return MakeGarbageCollected<HTMLDocument>(DocumentInit::Create().ForTest()); +} + Document* HTMLDocument::CloneDocumentWithoutChildren() const { return MakeGarbageCollected<HTMLDocument>( DocumentInit::Create() - .WithContextDocument(ContextDocument()) + .WithExecutionContext(GetExecutionContext()) .WithOwnerDocument(const_cast<HTMLDocument*>(this)) .WithURL(Url()) .WithRegistrationContext(RegistrationContext())); diff --git a/chromium/third_party/blink/renderer/core/html/html_document.h b/chromium/third_party/blink/renderer/core/html/html_document.h index fa4c536df01..daf28cad782 100644 --- a/chromium/third_party/blink/renderer/core/html/html_document.h +++ b/chromium/third_party/blink/renderer/core/html/html_document.h @@ -35,10 +35,12 @@ class CORE_EXPORT HTMLDocument : public Document { public: explicit HTMLDocument( - const DocumentInit& = DocumentInit::Create(), + const DocumentInit&, DocumentClassFlags extended_document_classes = kDefaultDocumentClass); ~HTMLDocument() override; + static HTMLDocument* CreateForTest(); + void AddNamedItem(const AtomicString& name); void RemoveNamedItem(const AtomicString& name); bool HasNamedItem(const AtomicString& name); diff --git a/chromium/third_party/blink/renderer/core/html/html_element.cc b/chromium/third_party/blink/renderer/core/html/html_element.cc index 8e246cb080b..c090f12f9fa 100644 --- a/chromium/third_party/blink/renderer/core/html/html_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_element.cc @@ -502,8 +502,6 @@ AttributeTriggers* HTMLElement::TriggersForAttributeName( nullptr}, {html_names::kOnratechangeAttr, kNoWebFeature, event_type_names::kRatechange, nullptr}, - {html_names::kOnrendersubtreeactivationAttr, kNoWebFeature, - event_type_names::kRendersubtreeactivation, nullptr}, {html_names::kOnresetAttr, kNoWebFeature, event_type_names::kReset, nullptr}, {html_names::kOnresizeAttr, kNoWebFeature, event_type_names::kResize, diff --git a/chromium/third_party/blink/renderer/core/html/html_element.idl b/chromium/third_party/blink/renderer/core/html/html_element.idl index 9a806233e18..4f751fec935 100644 --- a/chromium/third_party/blink/renderer/core/html/html_element.idl +++ b/chromium/third_party/blink/renderer/core/html/html_element.idl @@ -47,6 +47,11 @@ [ImplementedAs=isContentEditableForBinding] readonly attribute boolean isContentEditable; [CEReactions, Reflect, ReflectOnly=("none","text","tel","url","email","numeric","decimal","search")] attribute DOMString inputMode; + // Explainers: + // https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/master/VirtualKeyboardPolicy/explainer.md + // https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/master/VirtualKeyboardAPI/explainer.md + [RuntimeEnabled=VirtualKeyboard, CEReactions, Reflect, ReflectOnly=("auto","manual")] attribute DOMString virtualKeyboardPolicy; + // CSSOM View Module // https://drafts.csswg.org/cssom-view/#extensions-to-the-htmlelement-interface [Affects=Nothing, PerWorldBindings, ImplementedAs=unclosedOffsetParent] readonly attribute Element? offsetParent; diff --git a/chromium/third_party/blink/renderer/core/html/html_frame_element.cc b/chromium/third_party/blink/renderer/core/html/html_frame_element.cc index a55bde6e05b..1770a962b27 100644 --- a/chromium/third_party/blink/renderer/core/html/html_frame_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_frame_element.cc @@ -75,8 +75,7 @@ void HTMLFrameElement::ParseAttribute( } } -ParsedFeaturePolicy HTMLFrameElement::ConstructContainerPolicy( - Vector<String>*) const { +ParsedFeaturePolicy HTMLFrameElement::ConstructContainerPolicy() const { // Frame elements are not allowed to enable the fullscreen feature. Add an // empty allowlist for the fullscreen feature so that the framed content is // unable to use the API, regardless of origin. diff --git a/chromium/third_party/blink/renderer/core/html/html_frame_element.h b/chromium/third_party/blink/renderer/core/html/html_frame_element.h index 30f604c98a7..2ea9ed35660 100644 --- a/chromium/third_party/blink/renderer/core/html/html_frame_element.h +++ b/chromium/third_party/blink/renderer/core/html/html_frame_element.h @@ -41,8 +41,7 @@ class CORE_EXPORT HTMLFrameElement final : public HTMLFrameElementBase { bool NoResize() const; - ParsedFeaturePolicy ConstructContainerPolicy( - Vector<String>* /* messages */) const override; + ParsedFeaturePolicy ConstructContainerPolicy() const override; mojom::blink::FrameOwnerElementType OwnerType() const final { return mojom::blink::FrameOwnerElementType::kFrame; diff --git a/chromium/third_party/blink/renderer/core/html/html_frame_element_base.cc b/chromium/third_party/blink/renderer/core/html/html_frame_element_base.cc index ac51562aefa..cd96dbb9677 100644 --- a/chromium/third_party/blink/renderer/core/html/html_frame_element_base.cc +++ b/chromium/third_party/blink/renderer/core/html/html_frame_element_base.cc @@ -67,7 +67,7 @@ bool HTMLFrameElementBase::IsURLAllowed() const { // frame. NB: This check can be invoked without any JS on the stack for some // parser operations. In such case, we use the origin of the frame element's // containing document as the caller context. - v8::Isolate* isolate = GetDocument().GetIsolate(); + v8::Isolate* isolate = GetExecutionContext()->GetIsolate(); LocalDOMWindow* accessing_window = isolate->InContext() ? CurrentDOMWindow(isolate) : GetDocument().domWindow(); @@ -96,15 +96,12 @@ void HTMLFrameElementBase::OpenURL(bool replace_current_item) { // URL at this point, *and* the base URL is a data URL, assume |url_| was // relative and give a warning. if (!url.IsValid() && GetDocument().BaseURL().ProtocolIsData()) { - if (LocalDOMWindow* window = GetDocument().ExecutingWindow()) { - if (LocalFrame* frame = window->GetFrame()) { - frame->Console().AddMessage(MakeGarbageCollected<ConsoleMessage>( + GetExecutionContext()->AddConsoleMessage( + MakeGarbageCollected<ConsoleMessage>( mojom::ConsoleMessageSource::kRendering, mojom::ConsoleMessageLevel::kWarning, "Invalid relative frame source URL (" + url_ + ") within data URL.")); - } - } } LoadOrRedirectSubframe(url, frame_name_, replace_current_item); } diff --git a/chromium/third_party/blink/renderer/core/html/html_frame_element_test.cc b/chromium/third_party/blink/renderer/core/html/html_frame_element_test.cc index 8545ba9e64f..f44e9d6c371 100644 --- a/chromium/third_party/blink/renderer/core/html/html_frame_element_test.cc +++ b/chromium/third_party/blink/renderer/core/html/html_frame_element_test.cc @@ -21,6 +21,7 @@ TEST_F(HTMLFrameElementTest, DefaultContainerPolicy) { const KURL document_url("http://example.com"); DocumentInit init = DocumentInit::Create() + .ForTest() .WithInitiatorOrigin(SecurityOrigin::Create(document_url)) .WithURL(document_url); auto* document = MakeGarbageCollected<Document>(init); diff --git a/chromium/third_party/blink/renderer/core/html/html_frame_owner_element.cc b/chromium/third_party/blink/renderer/core/html/html_frame_owner_element.cc index 08ae305ad65..c1c4dc67f9c 100644 --- a/chromium/third_party/blink/renderer/core/html/html_frame_owner_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_frame_owner_element.cc @@ -279,13 +279,13 @@ void HTMLFrameOwnerElement::SetSandboxFlags( frame_policy_.sandbox_flags = flags; // Recalculate the container policy in case the allow-same-origin flag has // changed. - frame_policy_.container_policy = ConstructContainerPolicy(nullptr); + frame_policy_.container_policy = ConstructContainerPolicy(); // Don't notify about updates if ContentFrame() is null, for example when // the subframe hasn't been created yet. if (ContentFrame()) { - GetDocument().GetFrame()->Client()->DidChangeFramePolicy(ContentFrame(), - frame_policy_); + GetDocument().GetFrame()->GetLocalFrameHostRemote().DidChangeFramePolicy( + ContentFrame()->GetFrameToken(), frame_policy_); } } @@ -294,8 +294,8 @@ void HTMLFrameOwnerElement::SetDisallowDocumentAccesss(bool disallowed) { // Don't notify about updates if ContentFrame() is null, for example when // the subframe hasn't been created yet. if (ContentFrame()) { - GetDocument().GetFrame()->Client()->DidChangeFramePolicy(ContentFrame(), - frame_policy_); + GetDocument().GetFrame()->GetLocalFrameHostRemote().DidChangeFramePolicy( + ContentFrame()->GetFrameToken(), frame_policy_); } } @@ -311,18 +311,18 @@ void HTMLFrameOwnerElement::DisposePluginSoon(WebPluginContainerImpl* plugin) { plugin->Dispose(); } -void HTMLFrameOwnerElement::UpdateContainerPolicy(Vector<String>* messages) { - frame_policy_.container_policy = ConstructContainerPolicy(messages); +void HTMLFrameOwnerElement::UpdateContainerPolicy() { + frame_policy_.container_policy = ConstructContainerPolicy(); // Don't notify about updates if ContentFrame() is null, for example when // the subframe hasn't been created yet. if (ContentFrame()) { - GetDocument().GetFrame()->Client()->DidChangeFramePolicy(ContentFrame(), - frame_policy_); + GetDocument().GetFrame()->GetLocalFrameHostRemote().DidChangeFramePolicy( + ContentFrame()->GetFrameToken(), frame_policy_); } } void HTMLFrameOwnerElement::UpdateRequiredPolicy() { - const auto* frame = GetDocument().GetFrame(); + auto* frame = GetDocument().GetFrame(); DocumentPolicy::FeatureState new_required_policy = frame ? DocumentPolicy::MergeFeatureState( @@ -334,13 +334,14 @@ void HTMLFrameOwnerElement::UpdateRequiredPolicy() { frame_policy_.required_document_policy.clear(); for (auto i = new_required_policy.begin(), last = new_required_policy.end(); i != last;) { - if (!DisabledByOriginTrial(i->first, &GetDocument())) + if (!DisabledByOriginTrial(i->first, GetExecutionContext())) frame_policy_.required_document_policy.insert(*i); ++i; } if (ContentFrame()) { - frame->Client()->DidChangeFramePolicy(ContentFrame(), frame_policy_); + frame->GetLocalFrameHostRemote().DidChangeFramePolicy( + ContentFrame()->GetFrameToken(), frame_policy_); } } @@ -473,13 +474,10 @@ bool HTMLFrameOwnerElement::LoadOrRedirectSubframe( // Update the |should_lazy_load_children_| value according to the "loading" // attribute immediately, so that it still gets respected even if the "src" // attribute gets parsed in ParseAttribute() before the "loading" attribute - // does. Note that when the *feature policy* for "lazyload" is disabled, the - // attribute value loading="eager" is ignored (i.e., interpreted as - // "auto" instead). + // does. if (should_lazy_load_children_ && EqualIgnoringASCIICase(FastGetAttribute(html_names::kLoadingAttr), - "eager") && - !GetDocument().IsLazyLoadPolicyEnforced()) { + "eager")) { should_lazy_load_children_ = false; } @@ -511,7 +509,7 @@ bool HTMLFrameOwnerElement::LoadOrRedirectSubframe( return false; if (GetDocument().GetFrame()->GetPage()->SubframeCount() >= - Page::kMaxNumberOfFrames) + Page::MaxNumberOfFrames()) return false; LocalFrame* child_frame = @@ -535,13 +533,8 @@ bool HTMLFrameOwnerElement::LoadOrRedirectSubframe( if (IsPlugin()) request.SetSkipServiceWorker(true); - // When the feature policy "loading-frame-default-eager" is disabled in - // the document, loading attribute value "auto" (or unset/invalid values) will - // also be interpreted as "lazy". const auto& loading_attr = FastGetAttribute(html_names::kLoadingAttr); - bool loading_lazy_set = EqualIgnoringASCIICase(loading_attr, "lazy") || - (IsLoadingFrameDefaultEagerEnforced() && - !EqualIgnoringASCIICase(loading_attr, "eager")); + bool loading_lazy_set = EqualIgnoringASCIICase(loading_attr, "lazy"); if (!lazy_load_frame_observer_ && IsFrameLazyLoadable(GetDocument(), url, loading_lazy_set, @@ -585,11 +578,7 @@ bool HTMLFrameOwnerElement::ShouldLazyLoadChildren() const { void HTMLFrameOwnerElement::ParseAttribute( const AttributeModificationParams& params) { if (params.name == html_names::kLoadingAttr) { - // Note that when the *feature policy* for "lazyload" is disabled, the - // attribute value loading="eager" is ignored (i.e., interpreted as - // "auto" instead). - if (EqualIgnoringASCIICase(params.new_value, "eager") && - !GetDocument().IsLazyLoadPolicyEnforced()) { + if (EqualIgnoringASCIICase(params.new_value, "eager")) { UseCounter::Count(GetDocument(), WebFeature::kLazyLoadFrameLoadingAttributeEager); should_lazy_load_children_ = false; @@ -606,21 +595,25 @@ void HTMLFrameOwnerElement::ParseAttribute( } } -void HTMLFrameOwnerElement::FrameCrossOriginToParentFrameChanged() { - if (base::FeatureList::IsEnabled( - blink::features::kCompositeCrossOriginIframes)) { - SetNeedsCompositingUpdate(); - } -} - void HTMLFrameOwnerElement::SetEmbeddingToken( const base::UnguessableToken& embedding_token) { - DCHECK(content_frame_); - DCHECK(content_frame_->IsRemoteFrame()); + DCHECK(ContentFrame()); embedding_token_ = embedding_token; } -void HTMLFrameOwnerElement::Trace(Visitor* visitor) { +const base::Optional<base::UnguessableToken>& +HTMLFrameOwnerElement::GetEmbeddingToken() const { + return embedding_token_; +} + +bool HTMLFrameOwnerElement::IsAdRelated() const { + if (!content_frame_) + return false; + + return content_frame_->IsAdSubframe(); +} + +void HTMLFrameOwnerElement::Trace(Visitor* visitor) const { visitor->Trace(content_frame_); visitor->Trace(embedded_content_view_); visitor->Trace(lazy_load_frame_observer_); @@ -628,10 +621,4 @@ void HTMLFrameOwnerElement::Trace(Visitor* visitor) { FrameOwner::Trace(visitor); } -bool HTMLFrameOwnerElement::IsLoadingFrameDefaultEagerEnforced() const { - return RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled() && - !GetDocument().IsFeatureEnabled( - mojom::blink::FeaturePolicyFeature::kLoadingFrameDefaultEager); -} - } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/html_frame_owner_element.h b/chromium/third_party/blink/renderer/core/html/html_frame_owner_element.h index 17b942a129d..c893f03da2d 100644 --- a/chromium/third_party/blink/renderer/core/html/html_frame_owner_element.h +++ b/chromium/third_party/blink/renderer/core/html/html_frame_owner_element.h @@ -76,8 +76,6 @@ class CORE_EXPORT HTMLFrameOwnerElement : public HTMLElement, return embedded_content_view_; } - void FrameCrossOriginToParentFrameChanged(); - class PluginDisposeSuspendScope { STACK_ALLOCATED(); @@ -131,11 +129,11 @@ class CORE_EXPORT HTMLFrameOwnerElement : public HTMLElement, void ParseAttribute(const AttributeModificationParams&) override; void SetEmbeddingToken(const base::UnguessableToken& token); - const base::Optional<base::UnguessableToken>& GetEmbeddingToken() const { - return embedding_token_; - } + const base::Optional<base::UnguessableToken>& GetEmbeddingToken() const; - void Trace(Visitor*) override; + bool IsAdRelated() const override; + + void Trace(Visitor*) const override; protected: HTMLFrameOwnerElement(const QualifiedName& tag_name, Document&); @@ -166,12 +164,11 @@ class CORE_EXPORT HTMLFrameOwnerElement : public HTMLElement, // Return a feature policy container policy for this frame, based on the // frame attributes and the effective origin specified in the frame // attributes. - virtual ParsedFeaturePolicy ConstructContainerPolicy( - Vector<String>* /* messages */) const = 0; + virtual ParsedFeaturePolicy ConstructContainerPolicy() const = 0; // Update the container policy and notify the frame loader client of any // changes. - void UpdateContainerPolicy(Vector<String>* messages = nullptr); + void UpdateContainerPolicy(); // Return a document policy required policy for this frame, based on the // frame attributes. @@ -202,8 +199,6 @@ class CORE_EXPORT HTMLFrameOwnerElement : public HTMLElement, return network::mojom::ReferrerPolicy::kDefault; } - bool IsLoadingFrameDefaultEagerEnforced() const; - Member<Frame> content_frame_; Member<EmbeddedContentView> embedded_content_view_; FramePolicy frame_policy_; diff --git a/chromium/third_party/blink/renderer/core/html/html_frame_set_element.cc b/chromium/third_party/blink/renderer/core/html/html_frame_set_element.cc index 5239ea86169..755fd9c497e 100644 --- a/chromium/third_party/blink/renderer/core/html/html_frame_set_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_frame_set_element.cc @@ -202,7 +202,7 @@ void HTMLFrameSetElement::ParseAttribute( GetDocument().SetWindowAttributeEventListener( event_type_names::kLanguagechange, CreateAttributeEventListener(GetDocument().GetFrame(), name, value)); - } else if (RuntimeEnabledFeatures::PortalsEnabled(&GetDocument()) && + } else if (RuntimeEnabledFeatures::PortalsEnabled(GetExecutionContext()) && name == html_names::kOnportalactivateAttr) { GetDocument().SetWindowAttributeEventListener( event_type_names::kPortalactivate, diff --git a/chromium/third_party/blink/renderer/core/html/html_html_element.cc b/chromium/third_party/blink/renderer/core/html/html_html_element.cc index 34c9578ef53..929a82ab6a6 100644 --- a/chromium/third_party/blink/renderer/core/html/html_html_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_html_element.cc @@ -79,10 +79,11 @@ void HTMLHtmlElement::MaybeSetupApplicationCache() { const AtomicString& manifest = FastGetAttribute(html_names::kManifestAttr); if (RuntimeEnabledFeatures::RestrictAppCacheToSecureContextsEnabled() && - !GetDocument().IsSecureContext()) { + !GetExecutionContext()->IsSecureContext()) { if (!manifest.IsEmpty()) { Deprecation::CountDeprecation( - GetDocument(), WebFeature::kApplicationCacheAPIInsecureOrigin); + GetExecutionContext(), + WebFeature::kApplicationCacheAPIInsecureOrigin); } return; } diff --git a/chromium/third_party/blink/renderer/core/html/html_iframe_element.cc b/chromium/third_party/blink/renderer/core/html/html_iframe_element.cc index 742e867f733..960f6e5235f 100644 --- a/chromium/third_party/blink/renderer/core/html/html_iframe_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_iframe_element.cc @@ -58,7 +58,7 @@ HTMLIFrameElement::HTMLIFrameElement(Document& document) sandbox_(MakeGarbageCollected<HTMLIFrameElementSandbox>(this)), referrer_policy_(network::mojom::ReferrerPolicy::kDefault) {} -void HTMLIFrameElement::Trace(Visitor* visitor) { +void HTMLIFrameElement::Trace(Visitor* visitor) const { visitor->Trace(sandbox_); visitor->Trace(policy_); HTMLFrameElementBase::Trace(visitor); @@ -196,17 +196,9 @@ void HTMLIFrameElement::ParseAttribute( current_flags & ~sandbox_to_set; } SetSandboxFlags(sandbox_to_set); - if (RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()) { - Vector<String> messages; - UpdateContainerPolicy(&messages); - if (!messages.IsEmpty()) { - for (const String& message : messages) { - GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( - mojom::ConsoleMessageSource::kOther, - mojom::ConsoleMessageLevel::kWarning, message)); - } - } - } + if (RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()) + UpdateContainerPolicy(); + UseCounter::Count(GetDocument(), WebFeature::kSandboxViaIFrame); } else if (name == html_names::kReferrerpolicyAttr) { referrer_policy_ = network::mojom::ReferrerPolicy::kDefault; @@ -256,19 +248,15 @@ void HTMLIFrameElement::ParseAttribute( } else if (name == html_names::kAllowAttr) { if (allow_ != value) { allow_ = value; - Vector<String> messages; - UpdateContainerPolicy(&messages); - if (!messages.IsEmpty()) { - for (const String& message : messages) { - GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( - mojom::ConsoleMessageSource::kOther, - mojom::ConsoleMessageLevel::kWarning, message)); - } - } + UpdateContainerPolicy(); if (!value.IsEmpty()) { UseCounter::Count(GetDocument(), WebFeature::kFeaturePolicyAllowAttribute); } + if (value.Contains(',')) { + UseCounter::Count(GetDocument(), + WebFeature::kCommaSeparatorInAllowAttribute); + } } } else if (name == html_names::kDisallowdocumentaccessAttr && RuntimeEnabledFeatures::DisallowDocumentAccessEnabled()) { @@ -311,7 +299,7 @@ void HTMLIFrameElement::ParseAttribute( DocumentPolicy::FeatureState HTMLIFrameElement::ConstructRequiredPolicy() const { - if (!RuntimeEnabledFeatures::DocumentPolicyEnabled(&GetDocument())) + if (!RuntimeEnabledFeatures::DocumentPolicyEnabled(GetExecutionContext())) return {}; if (!required_policy_.IsEmpty()) { @@ -348,29 +336,30 @@ DocumentPolicy::FeatureState HTMLIFrameElement::ConstructRequiredPolicy() return new_required_policy.feature_state; } -ParsedFeaturePolicy HTMLIFrameElement::ConstructContainerPolicy( - Vector<String>* messages) const { +ParsedFeaturePolicy HTMLIFrameElement::ConstructContainerPolicy() const { scoped_refptr<const SecurityOrigin> src_origin = GetOriginForFeaturePolicy(); scoped_refptr<const SecurityOrigin> self_origin = GetDocument().GetSecurityOrigin(); + PolicyParserMessageBuffer logger; + // Start with the allow attribute ParsedFeaturePolicy container_policy = FeaturePolicyParser::ParseAttribute( - allow_, self_origin, src_origin, messages, &GetDocument()); + allow_, self_origin, src_origin, logger, GetExecutionContext()); // Next, process sandbox flags. These all only take effect if a corresponding // policy does *not* exist in the allow attribute's value. if (RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()) { // If the frame is sandboxed at all, then warn if feature policy attributes // will override the sandbox attributes. - if (messages && (sandbox_flags_converted_to_feature_policies_ & - network::mojom::blink::WebSandboxFlags::kNavigation) != - network::mojom::blink::WebSandboxFlags::kNone) { + if ((sandbox_flags_converted_to_feature_policies_ & + network::mojom::blink::WebSandboxFlags::kNavigation) != + network::mojom::blink::WebSandboxFlags::kNone) { for (const auto& pair : SandboxFlagsWithFeaturePolicies()) { if ((sandbox_flags_converted_to_feature_policies_ & pair.first) != network::mojom::blink::WebSandboxFlags::kNone && IsFeatureDeclared(pair.second, container_policy)) { - messages->push_back(String::Format( + logger.Warn(String::Format( "Allow and Sandbox attributes both mention '%s'. Allow will take " "precedence.", GetNameForFeature(pair.second).Utf8().c_str())); @@ -390,8 +379,8 @@ ParsedFeaturePolicy HTMLIFrameElement::ConstructContainerPolicy( if (AllowFullscreen()) { bool policy_changed = AllowFeatureEverywhereIfNotPresent( mojom::blink::FeaturePolicyFeature::kFullscreen, container_policy); - if (!policy_changed && messages) { - messages->push_back( + if (!policy_changed) { + logger.Warn( "Allow attribute will take precedence over 'allowfullscreen'."); } } @@ -400,8 +389,8 @@ ParsedFeaturePolicy HTMLIFrameElement::ConstructContainerPolicy( if (AllowPaymentRequest()) { bool policy_changed = AllowFeatureEverywhereIfNotPresent( mojom::blink::FeaturePolicyFeature::kPayment, container_policy); - if (!policy_changed && messages) { - messages->push_back( + if (!policy_changed) { + logger.Warn( "Allow attribute will take precedence over 'allowpaymentrequest'."); } } @@ -411,6 +400,14 @@ ParsedFeaturePolicy HTMLIFrameElement::ConstructContainerPolicy( if (policy_) policy_->UpdateContainerPolicy(container_policy, src_origin); + for (const auto& message : logger.GetMessages()) { + GetDocument().AddConsoleMessage( + MakeGarbageCollected<ConsoleMessage>( + mojom::blink::ConsoleMessageSource::kOther, message.level, + message.content), + /* discard_duplicates */ true); + } + return container_policy; } @@ -504,13 +501,14 @@ HTMLIFrameElement::ConstructTrustTokenParams() const { network::mojom::blink::TrustTokenOperationType::kSigning; if (operation_requires_feature_policy && - (!GetDocument().IsFeatureEnabled( + (!GetExecutionContext()->IsFeatureEnabled( mojom::blink::FeaturePolicyFeature::kTrustTokenRedemption))) { - GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( - mojom::blink::ConsoleMessageSource::kOther, - mojom::blink::ConsoleMessageLevel::kError, - "Trust Tokens: Attempted redemption or signing without the " - "trust-token-redemption Feature Policy feature present.")); + GetExecutionContext()->AddConsoleMessage( + MakeGarbageCollected<ConsoleMessage>( + mojom::blink::ConsoleMessageSource::kOther, + mojom::blink::ConsoleMessageLevel::kError, + "Trust Tokens: Attempted redemption or signing without the " + "trust-token-redemption Feature Policy feature present.")); return nullptr; } diff --git a/chromium/third_party/blink/renderer/core/html/html_iframe_element.h b/chromium/third_party/blink/renderer/core/html/html_iframe_element.h index f5c1ee044bc..b9a0f527fbe 100644 --- a/chromium/third_party/blink/renderer/core/html/html_iframe_element.h +++ b/chromium/third_party/blink/renderer/core/html/html_iframe_element.h @@ -43,7 +43,7 @@ class CORE_EXPORT HTMLIFrameElement final USING_GARBAGE_COLLECTED_MIXIN(HTMLIFrameElement); public: - void Trace(Visitor*) override; + void Trace(Visitor*) const override; explicit HTMLIFrameElement(Document&); ~HTMLIFrameElement() override; @@ -55,8 +55,7 @@ class CORE_EXPORT HTMLIFrameElement final // Returns attributes that should be checked against Trusted Types const AttrNameToTrustedType& GetCheckedAttributeTypes() const override; - ParsedFeaturePolicy ConstructContainerPolicy( - Vector<String>* /* messages */) const override; + ParsedFeaturePolicy ConstructContainerPolicy() const override; DocumentPolicy::FeatureState ConstructRequiredPolicy() const override; mojom::blink::FrameOwnerElementType OwnerType() const final { diff --git a/chromium/third_party/blink/renderer/core/html/html_iframe_element.idl b/chromium/third_party/blink/renderer/core/html/html_iframe_element.idl index a2ec716d1ee..c087b4f1292 100644 --- a/chromium/third_party/blink/renderer/core/html/html_iframe_element.idl +++ b/chromium/third_party/blink/renderer/core/html/html_iframe_element.idl @@ -47,7 +47,7 @@ // Feature Policy [CEReactions, Reflect] attribute DOMString allow; // https://w3c.github.io/webappsec-feature-policy/#the-policy-object - [RuntimeEnabled=FeaturePolicyJavaScriptInterface] readonly attribute FeaturePolicy featurePolicy; + readonly attribute FeaturePolicy featurePolicy; // Document Policy [RuntimeEnabled=DocumentPolicy, CEReactions, Reflect] attribute DOMString policy; diff --git a/chromium/third_party/blink/renderer/core/html/html_iframe_element_test.cc b/chromium/third_party/blink/renderer/core/html/html_iframe_element_test.cc index 379168d4327..61171ac195f 100644 --- a/chromium/third_party/blink/renderer/core/html/html_iframe_element_test.cc +++ b/chromium/third_party/blink/renderer/core/html/html_iframe_element_test.cc @@ -276,7 +276,7 @@ TEST_F(HTMLIFrameElementTest, SameOriginSandboxAttributeContainerPolicy) { // iframe element. TEST_F(HTMLIFrameElementTest, ConstructEmptyContainerPolicy) { ParsedFeaturePolicy container_policy = - frame_element_->ConstructContainerPolicy(nullptr); + frame_element_->ConstructContainerPolicy(); EXPECT_EQ(0UL, container_policy.size()); } @@ -285,7 +285,7 @@ TEST_F(HTMLIFrameElementTest, ConstructEmptyContainerPolicy) { TEST_F(HTMLIFrameElementTest, ConstructContainerPolicy) { frame_element_->setAttribute(html_names::kAllowAttr, "payment; usb"); ParsedFeaturePolicy container_policy = - frame_element_->ConstructContainerPolicy(nullptr); + frame_element_->ConstructContainerPolicy(); EXPECT_EQ(2UL, container_policy.size()); EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kPayment, container_policy[0].feature); @@ -306,7 +306,7 @@ TEST_F(HTMLIFrameElementTest, ConstructContainerPolicyWithAllowFullscreen) { frame_element_->SetBooleanAttribute(html_names::kAllowfullscreenAttr, true); ParsedFeaturePolicy container_policy = - frame_element_->ConstructContainerPolicy(nullptr); + frame_element_->ConstructContainerPolicy(); EXPECT_EQ(1UL, container_policy.size()); EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kFullscreen, container_policy[0].feature); @@ -321,7 +321,7 @@ TEST_F(HTMLIFrameElementTest, ConstructContainerPolicyWithAllowPaymentRequest) { true); ParsedFeaturePolicy container_policy = - frame_element_->ConstructContainerPolicy(nullptr); + frame_element_->ConstructContainerPolicy(); EXPECT_EQ(2UL, container_policy.size()); EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kUsb, container_policy[0].feature); @@ -346,7 +346,7 @@ TEST_F(HTMLIFrameElementTest, ConstructContainerPolicyWithAllowAttributes) { true); ParsedFeaturePolicy container_policy = - frame_element_->ConstructContainerPolicy(nullptr); + frame_element_->ConstructContainerPolicy(); EXPECT_EQ(3UL, container_policy.size()); EXPECT_EQ(mojom::blink::FeaturePolicyFeature::kPayment, container_policy[0].feature); @@ -385,4 +385,41 @@ TEST_F(HTMLIFrameElementSimTest, PolicyAttributeParsingError) { } } +TEST_F(HTMLIFrameElementSimTest, AllowAttributeParsingError) { + SimRequest main_resource("https://example.com", "text/html"); + LoadURL("https://example.com"); + main_resource.Complete(R"( + <iframe + allow="bad-feature-name" + allowfullscreen + allowpayment + sandbox=""></iframe> + )"); + + EXPECT_EQ(ConsoleMessages().size(), 1u) + << "Allow attribute parsing should only generate console message once, " + "even though there might be multiple call to " + "FeaturePolicyParser::ParseAttribute."; + EXPECT_TRUE(ConsoleMessages().front().StartsWith("Unrecognized feature")) + << "Expect feature policy parser raising error for unrecognized feature " + "but got: " + << ConsoleMessages().front(); +} + +TEST_F(HTMLIFrameElementSimTest, CommaSeparatorIsCounted) { + EXPECT_FALSE( + GetDocument().Loader()->GetUseCounterHelper().HasRecordedMeasurement( + WebFeature::kCommaSeparatorInAllowAttribute)); + SimRequest main_resource("https://example.com", "text/html"); + LoadURL("https://example.com"); + main_resource.Complete(R"( + <iframe + allow="fullscreen, geolocation"></iframe> + )"); + + EXPECT_TRUE( + GetDocument().Loader()->GetUseCounterHelper().HasRecordedMeasurement( + WebFeature::kCommaSeparatorInAllowAttribute)); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/html_image_element.cc b/chromium/third_party/blink/renderer/core/html/html_image_element.cc index c54d6c04fa7..7ed7811b592 100644 --- a/chromium/third_party/blink/renderer/core/html/html_image_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_image_element.cc @@ -80,7 +80,7 @@ class HTMLImageElement::ViewportChangeListener final element_->NotifyViewportChanged(); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(element_); MediaQueryListListener::Trace(visitor); } @@ -103,8 +103,8 @@ HTMLImageElement::HTMLImageElement(Document& document, bool created_by_parser) element_created_by_parser_(created_by_parser), is_fallback_image_(false), is_default_overridden_intrinsic_size_( - !document.IsImageDocument() && - !document.IsFeatureEnabled( + !document.IsImageDocument() && GetExecutionContext() && + !GetExecutionContext()->IsFeatureEnabled( mojom::blink::DocumentPolicyFeature::kUnsizedMedia)), is_legacy_format_or_unoptimized_image_(false), referrer_policy_(network::mojom::ReferrerPolicy::kDefault) { @@ -113,7 +113,7 @@ HTMLImageElement::HTMLImageElement(Document& document, bool created_by_parser) HTMLImageElement::~HTMLImageElement() = default; -void HTMLImageElement::Trace(Visitor* visitor) { +void HTMLImageElement::Trace(Visitor* visitor) const { visitor->Trace(image_loader_); visitor->Trace(listener_); visitor->Trace(form_); @@ -287,11 +287,11 @@ void HTMLImageElement::ParseAttribute( UseCounter::Count(GetDocument(), WebFeature::kImageDecodingAttribute); decoding_mode_ = ParseImageDecodingMode(params.new_value); } else if (name == html_names::kLoadingAttr && - EqualIgnoringASCIICase(params.new_value, "eager") && - !GetDocument().IsLazyLoadPolicyEnforced()) { + EqualIgnoringASCIICase(params.new_value, "eager")) { GetImageLoader().LoadDeferredImage(referrer_policy_); } else if (name == html_names::kImportanceAttr && - RuntimeEnabledFeatures::PriorityHintsEnabled(&GetDocument())) { + RuntimeEnabledFeatures::PriorityHintsEnabled( + GetExecutionContext())) { // We only need to keep track of usage here, as the communication of the // |importance| attribute to the loading pipeline takes place in // ImageLoader. @@ -355,7 +355,7 @@ ImageCandidate HTMLImageElement::FindBestFitImageFromPictureParent() { continue; if (!source->FastGetAttribute(html_names::kSrcAttr).IsNull()) { - Deprecation::CountDeprecation(GetDocument(), + Deprecation::CountDeprecation(GetExecutionContext(), WebFeature::kPictureSourceSrc); } String srcset = source->FastGetAttribute(html_names::kSrcsetAttr); @@ -520,20 +520,20 @@ LayoutSize HTMLImageElement::DensityCorrectedIntrinsicDimensions() const { return LayoutSize(LayoutReplaced::kDefaultWidth, LayoutReplaced::kDefaultHeight); } - ImageResourceContent* image_resource = GetImageLoader().GetContent(); - if (!image_resource || !image_resource->HasImage()) + ImageResourceContent* image_content = GetImageLoader().GetContent(); + if (!image_content || !image_content->HasImage()) return LayoutSize(); float pixel_density = image_device_pixel_ratio_; - if (image_resource->HasDevicePixelRatioHeaderValue() && - image_resource->DevicePixelRatioHeaderValue() > 0) - pixel_density = 1 / image_resource->DevicePixelRatioHeaderValue(); + if (image_content->HasDevicePixelRatioHeaderValue() && + image_content->DevicePixelRatioHeaderValue() > 0) + pixel_density = 1 / image_content->DevicePixelRatioHeaderValue(); RespectImageOrientationEnum respect_image_orientation = LayoutObject::ShouldRespectImageOrientation(GetLayoutObject()); LayoutSize natural_size( - image_resource->IntrinsicSize(respect_image_orientation)); + image_content->IntrinsicSize(respect_image_orientation)); natural_size.Scale(pixel_density); return natural_size; } diff --git a/chromium/third_party/blink/renderer/core/html/html_image_element.h b/chromium/third_party/blink/renderer/core/html/html_image_element.h index 92800d28051..630301ef4f8 100644 --- a/chromium/third_party/blink/renderer/core/html/html_image_element.h +++ b/chromium/third_party/blink/renderer/core/html/html_image_element.h @@ -81,7 +81,7 @@ class CORE_EXPORT HTMLImageElement final HTMLImageElement(Document&, const CreateElementFlags); explicit HTMLImageElement(Document&, bool created_by_parser = false); ~HTMLImageElement() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; unsigned width(); unsigned height(); diff --git a/chromium/third_party/blink/renderer/core/html/html_image_fallback_helper.cc b/chromium/third_party/blink/renderer/core/html/html_image_fallback_helper.cc index 9d89a0001b7..905e78f76a3 100644 --- a/chromium/third_party/blink/renderer/core/html/html_image_fallback_helper.cc +++ b/chromium/third_party/blink/renderer/core/html/html_image_fallback_helper.cc @@ -21,15 +21,14 @@ namespace blink { -static bool NoImageSourceSpecified(const Element& element) { - return element.FastGetAttribute(html_names::kSrcAttr).IsEmpty(); -} - static bool ElementRepresentsNothing(const Element& element) { const auto& html_element = To<HTMLElement>(element); + // We source fallback content/alternative text from more than just the 'alt' + // attribute, so consider the element to represent text in those cases as + // well. bool alt_is_set = !html_element.AltText().IsNull(); bool alt_is_empty = alt_is_set && html_element.AltText().IsEmpty(); - bool src_is_set = !NoImageSourceSpecified(element); + bool src_is_set = !element.getAttribute(html_names::kSrcAttr).IsEmpty(); if (src_is_set && alt_is_empty) return true; return !src_is_set && (!alt_is_set || alt_is_empty); @@ -170,7 +169,8 @@ void HTMLImageFallbackHelper::CustomStyleForAltText(Element& element, bool image_has_intrinsic_dimensions = new_style.Width().IsSpecifiedOrIntrinsic() && new_style.Height().IsSpecifiedOrIntrinsic(); - bool image_has_no_alt_attribute = To<HTMLElement>(element).AltText().IsNull(); + bool image_has_no_alt_attribute = + element.getAttribute(html_names::kAltAttr).IsEmpty(); bool treat_as_replaced = image_has_intrinsic_dimensions && (element.GetDocument().InQuirksMode() || image_has_no_alt_attribute); diff --git a/chromium/third_party/blink/renderer/core/html/html_link_element.cc b/chromium/third_party/blink/renderer/core/html/html_link_element.cc index f5efe07788b..fc9633c5f75 100644 --- a/chromium/third_party/blink/renderer/core/html/html_link_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_link_element.cc @@ -41,6 +41,7 @@ #include "third_party/blink/renderer/core/html/cross_origin_attribute.h" #include "third_party/blink/renderer/core/html/imports/link_import.h" #include "third_party/blink/renderer/core/html/link_manifest.h" +#include "third_party/blink/renderer/core/html/link_web_bundle.h" #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/inspector/console_message.h" #include "third_party/blink/renderer/core/loader/link_loader.h" @@ -61,6 +62,9 @@ HTMLLinkElement::HTMLLinkElement(Document& document, referrer_policy_(network::mojom::ReferrerPolicy::kDefault), sizes_(MakeGarbageCollected<DOMTokenList>(*this, html_names::kSizesAttr)), rel_list_(MakeGarbageCollected<RelList>(this)), + resources_( + MakeGarbageCollected<DOMTokenList>(*this, + html_names::kResourcesAttr)), created_by_parser_(flags.IsCreatedByParser()) {} HTMLLinkElement::~HTMLLinkElement() = default; @@ -72,23 +76,22 @@ void HTMLLinkElement::ParseAttribute( if (name == html_names::kRelAttr) { rel_attribute_ = LinkRelAttribute(value); if (rel_attribute_.IsImport()) { - if (RuntimeEnabledFeatures::HTMLImportsEnabled(&GetDocument())) { - Deprecation::CountDeprecation(&GetDocument(), WebFeature::kHTMLImports); + if (RuntimeEnabledFeatures::HTMLImportsEnabled(GetExecutionContext())) { + Deprecation::CountDeprecation(GetExecutionContext(), + WebFeature::kHTMLImports); } else { // Show a warning that HTML Imports (<link rel=import>) were detected, // but HTML Imports have been disabled. Without this, the failure would // be silent. - if (LocalDOMWindow* window = GetDocument().ExecutingWindow()) { - if (LocalFrame* frame = window->GetFrame()) { - frame->Console().AddMessage(MakeGarbageCollected<ConsoleMessage>( - mojom::ConsoleMessageSource::kRendering, - mojom::ConsoleMessageLevel::kWarning, - "HTML Imports is deprecated and has now been removed as of " - "M80. See " - "https://www.chromestatus.com/features/5144752345317376 " - "and https://developers.google.com/web/updates/2019/07/" - "web-components-time-to-upgrade for more details.")); - } + if (auto* context = GetExecutionContext()) { + context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( + mojom::blink::ConsoleMessageSource::kRendering, + mojom::blink::ConsoleMessageLevel::kWarning, + "HTML Imports is deprecated and has now been removed as of " + "M80. See " + "https://www.chromestatus.com/features/5144752345317376 " + "and https://developers.google.com/web/updates/2019/07/" + "web-components-time-to-upgrade for more details.")); } } } @@ -138,15 +141,45 @@ void HTMLLinkElement::ParseAttribute( } else if (name == html_names::kIntegrityAttr) { integrity_ = value; } else if (name == html_names::kImportanceAttr && - RuntimeEnabledFeatures::PriorityHintsEnabled(&GetDocument())) { + RuntimeEnabledFeatures::PriorityHintsEnabled( + GetExecutionContext())) { UseCounter::Count(GetDocument(), WebFeature::kPriorityHints); importance_ = value; + } else if (name == html_names::kResourcesAttr && + RuntimeEnabledFeatures::SubresourceWebBundlesEnabled( + GetExecutionContext())) { + resources_->DidUpdateAttributeValue(params.old_value, value); + + // Parse the attribute value as a space-separated list of urls + SpaceSplitString urls(value); + valid_resource_urls_.clear(); + valid_resource_urls_.ReserveCapacityForSize( + SafeCast<wtf_size_t>(urls.size())); + for (wtf_size_t i = 0; i < urls.size(); ++i) { + KURL url = LinkWebBundle::ParseResourceUrl(urls[i]); + if (url.IsValid()) { + valid_resource_urls_.insert(std::move(url)); + } + } + Process(); } else if (name == html_names::kDisabledAttr) { UseCounter::Count(GetDocument(), WebFeature::kHTMLLinkElementDisabled); if (params.reason == AttributeModificationReason::kByParser) UseCounter::Count(GetDocument(), WebFeature::kHTMLLinkElementDisabledByParser); - if (LinkStyle* link = GetLinkStyle()) + // TODO(crbug.com/1087043): Remove this if() condition once the feature has + // landed and no compat issues are reported. + if (RuntimeEnabledFeatures::LinkDisabledNewSpecBehaviorEnabled( + GetExecutionContext())) { + LinkStyle* link = GetLinkStyle(); + if (!link) { + link = MakeGarbageCollected<LinkStyle>(this); + link_ = link; + } link->SetDisabledState(!value.IsNull()); + } else { + if (LinkStyle* link = GetLinkStyle()) + link->SetDisabledState(!value.IsNull()); + } } else { if (name == html_names::kTitleAttr) { if (LinkStyle* link = GetLinkStyle()) @@ -208,9 +241,16 @@ LinkResource* HTMLLinkElement::LinkResourceToProcess() { if (!link_) { if (rel_attribute_.IsImport()) { // Only create an import link when HTML imports are enabled. - if (!RuntimeEnabledFeatures::HTMLImportsEnabled(&GetDocument())) + if (!RuntimeEnabledFeatures::HTMLImportsEnabled(GetExecutionContext())) return nullptr; link_ = MakeGarbageCollected<LinkImport>(this); + } else if (rel_attribute_.IsWebBundle()) { + // Only create a webbundle link when SubresourceWebBundles are enabled. + if (!RuntimeEnabledFeatures::SubresourceWebBundlesEnabled( + GetExecutionContext())) { + return nullptr; + } + link_ = MakeGarbageCollected<LinkWebBundle>(this); } else if (rel_attribute_.IsManifest()) { link_ = MakeGarbageCollected<LinkManifest>(this); } else { @@ -438,11 +478,16 @@ DOMTokenList* HTMLLinkElement::sizes() const { return sizes_.Get(); } -void HTMLLinkElement::Trace(Visitor* visitor) { +DOMTokenList* HTMLLinkElement::resources() const { + return resources_.Get(); +} + +void HTMLLinkElement::Trace(Visitor* visitor) const { visitor->Trace(link_); visitor->Trace(sizes_); visitor->Trace(link_loader_); visitor->Trace(rel_list_); + visitor->Trace(resources_); HTMLElement::Trace(visitor); LinkLoaderClient::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/html_link_element.h b/chromium/third_party/blink/renderer/core/html/html_link_element.h index 9ba0c4ea32c..39a5e8c136c 100644 --- a/chromium/third_party/blink/renderer/core/html/html_link_element.h +++ b/chromium/third_party/blink/renderer/core/html/html_link_element.h @@ -38,6 +38,7 @@ #include "third_party/blink/renderer/core/html/rel_list.h" #include "third_party/blink/renderer/core/loader/link_loader_client.h" #include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h" +#include "third_party/blink/renderer/platform/wtf/hash_set.h" namespace blink { @@ -97,6 +98,13 @@ class CORE_EXPORT HTMLLinkElement final : public HTMLElement, DOMTokenList* sizes() const; + // IDL method. + DOMTokenList* resources() const; + + const HashSet<KURL>& ValidResourceUrls() const { + return valid_resource_urls_; + } + void ScheduleEvent(); // From LinkLoaderClient @@ -110,14 +118,21 @@ class CORE_EXPORT HTMLLinkElement final : public HTMLElement, FetchParameters::DeferOption, ResourceClient*); bool IsAlternate() const { - return GetLinkStyle()->IsUnset() && rel_attribute_.IsAlternate(); + // TODO(crbug.com/1087043): Remove this if() condition once the feature has + // landed and no compat issues are reported. + bool not_explicitly_enabled = + !GetLinkStyle()->IsExplicitlyEnabled() || + !RuntimeEnabledFeatures::LinkDisabledNewSpecBehaviorEnabled( + GetExecutionContext()); + return GetLinkStyle()->IsUnset() && rel_attribute_.IsAlternate() && + not_explicitly_enabled; } bool ShouldProcessStyle() { return LinkResourceToProcess() && GetLinkStyle(); } bool IsCreatedByParser() const { return created_by_parser_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: LinkStyle* GetLinkStyle() const; @@ -168,6 +183,8 @@ class CORE_EXPORT HTMLLinkElement final : public HTMLElement, Member<RelList> rel_list_; LinkRelAttribute rel_attribute_; String scope_; + Member<DOMTokenList> resources_; + HashSet<KURL> valid_resource_urls_; bool created_by_parser_; }; diff --git a/chromium/third_party/blink/renderer/core/html/html_link_element.idl b/chromium/third_party/blink/renderer/core/html/html_link_element.idl index f8908901496..776b99b9007 100644 --- a/chromium/third_party/blink/renderer/core/html/html_link_element.idl +++ b/chromium/third_party/blink/renderer/core/html/html_link_element.idl @@ -58,4 +58,9 @@ // Subresource Integrity // https://w3c.github.io/webappsec-subresource-integrity/#HTMLLinkElement [Reflect] attribute DOMString integrity; + + // Subresource loading with Web Bundles + // https://github.com/WICG/webpackage/blob/master/explainers/subresource-loading.md + // crbug.com/1082020 + [RuntimeEnabled=SubresourceWebBundles, PutForwards=value] readonly attribute DOMTokenList resources; }; diff --git a/chromium/third_party/blink/renderer/core/html/html_link_element_sizes_attribute_test.cc b/chromium/third_party/blink/renderer/core/html/html_link_element_sizes_attribute_test.cc index d4b821683cc..96454f83140 100644 --- a/chromium/third_party/blink/renderer/core/html/html_link_element_sizes_attribute_test.cc +++ b/chromium/third_party/blink/renderer/core/html/html_link_element_sizes_attribute_test.cc @@ -16,7 +16,7 @@ class HTMLLinkElementSizesAttributeTest : public testing::Test {}; TEST(HTMLLinkElementSizesAttributeTest, setSizesPropertyValue_updatesAttribute) { - auto* document = MakeGarbageCollected<Document>(); + auto* document = Document::CreateForTest(); auto* link = MakeGarbageCollected<HTMLLinkElement>(*document, CreateElementFlags()); DOMTokenList* sizes = link->sizes(); @@ -28,7 +28,7 @@ TEST(HTMLLinkElementSizesAttributeTest, TEST(HTMLLinkElementSizesAttributeTest, setSizesAttribute_updatesSizesPropertyValue) { - auto* document = MakeGarbageCollected<Document>(); + auto* document = Document::CreateForTest(); auto* link = MakeGarbageCollected<HTMLLinkElement>(*document, CreateElementFlags()); DOMTokenList* sizes = link->sizes(); diff --git a/chromium/third_party/blink/renderer/core/html/html_marquee_element.cc b/chromium/third_party/blink/renderer/core/html/html_marquee_element.cc index d12321171a9..9fc8c4e546a 100644 --- a/chromium/third_party/blink/renderer/core/html/html_marquee_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_marquee_element.cc @@ -88,7 +88,7 @@ class HTMLMarqueeElement::RequestAnimationFrameCallback final marquee_->ContinueAnimation(); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(marquee_); FrameRequestCallbackCollection::FrameCallback::Trace(visitor); } @@ -108,7 +108,7 @@ class HTMLMarqueeElement::AnimationFinished final : public NativeEventListener { marquee_->start(); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(marquee_); NativeEventListener::Trace(visitor); } @@ -486,7 +486,7 @@ AtomicString HTMLMarqueeElement::CreateTransform(double value) const { String::NumberToStringECMAScript(value) + "px)"; } -void HTMLMarqueeElement::Trace(Visitor* visitor) { +void HTMLMarqueeElement::Trace(Visitor* visitor) const { visitor->Trace(mover_); visitor->Trace(player_); HTMLElement::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/core/html/html_marquee_element.h b/chromium/third_party/blink/renderer/core/html/html_marquee_element.h index a9461edb73b..87013d57fb6 100644 --- a/chromium/third_party/blink/renderer/core/html/html_marquee_element.h +++ b/chromium/third_party/blink/renderer/core/html/html_marquee_element.h @@ -33,7 +33,7 @@ class HTMLMarqueeElement final : public HTMLElement { DEFINE_WRAPPERTYPEINFO(); public: - void Trace(Visitor*) override; + void Trace(Visitor*) const override; explicit HTMLMarqueeElement(Document&); diff --git a/chromium/third_party/blink/renderer/core/html/html_meta_element.cc b/chromium/third_party/blink/renderer/core/html/html_meta_element.cc index 853f518aeb3..3c332ec87a0 100644 --- a/chromium/third_party/blink/renderer/core/html/html_meta_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_meta_element.cc @@ -574,9 +574,19 @@ void HTMLMetaElement::ProcessContent() { if (EqualIgnoringASCIICase(name_value, "viewport")) { ProcessViewportContentAttribute(content_value, ViewportDescription::kViewportMeta); - } else if (EqualIgnoringASCIICase(name_value, "referrer")) { + } else if (EqualIgnoringASCIICase(name_value, "referrer") && + GetExecutionContext()) { UseCounter::Count(&GetDocument(), WebFeature::kHTMLMetaElementReferrerPolicy); + if (!IsDescendantOf(GetDocument().head())) { + UseCounter::Count(&GetDocument(), + WebFeature::kHTMLMetaElementReferrerPolicyOutsideHead); + } + if (content_value.Contains(',')) { + UseCounter::Count( + &GetDocument(), + WebFeature::kHTMLMetaElementReferrerPolicyMultipleTokens); + } GetExecutionContext()->ParseAndSetReferrerPolicy( content_value, true /* support legacy keywords */); } else if (EqualIgnoringASCIICase(name_value, "handheldfriendly") && diff --git a/chromium/third_party/blink/renderer/core/html/html_meter_element.cc b/chromium/third_party/blink/renderer/core/html/html_meter_element.cc index ada15e6ea4b..079257257b0 100644 --- a/chromium/third_party/blink/renderer/core/html/html_meter_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_meter_element.cc @@ -223,7 +223,7 @@ bool HTMLMeterElement::CanContainRangeEndPoint() const { return GetComputedStyle() && !GetComputedStyle()->HasEffectiveAppearance(); } -void HTMLMeterElement::Trace(Visitor* visitor) { +void HTMLMeterElement::Trace(Visitor* visitor) const { visitor->Trace(value_); HTMLElement::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/html_meter_element.h b/chromium/third_party/blink/renderer/core/html/html_meter_element.h index 3a6e50e713f..620f2cbf7fc 100644 --- a/chromium/third_party/blink/renderer/core/html/html_meter_element.h +++ b/chromium/third_party/blink/renderer/core/html/html_meter_element.h @@ -63,7 +63,7 @@ class CORE_EXPORT HTMLMeterElement final : public HTMLElement { bool CanContainRangeEndPoint() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: ~HTMLMeterElement() override; diff --git a/chromium/third_party/blink/renderer/core/html/html_no_script_element.cc b/chromium/third_party/blink/renderer/core/html/html_no_script_element.cc index 64ecf0c1c11..e2d87dc9e51 100644 --- a/chromium/third_party/blink/renderer/core/html/html_no_script_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_no_script_element.cc @@ -42,7 +42,7 @@ HTMLNoScriptElement::HTMLNoScriptElement(Document& document) bool HTMLNoScriptElement::LayoutObjectIsNeeded( const ComputedStyle& style) const { - if (GetDocument().CanExecuteScripts(kNotAboutToExecuteScript)) + if (GetExecutionContext()->CanExecuteScripts(kNotAboutToExecuteScript)) return false; return Element::LayoutObjectIsNeeded(style); } diff --git a/chromium/third_party/blink/renderer/core/html/html_object_element.cc b/chromium/third_party/blink/renderer/core/html/html_object_element.cc index 6a2465ce913..2f992e08868 100644 --- a/chromium/third_party/blink/renderer/core/html/html_object_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_object_element.cc @@ -58,7 +58,7 @@ HTMLObjectElement::HTMLObjectElement(Document& document, inline HTMLObjectElement::~HTMLObjectElement() = default; -void HTMLObjectElement::Trace(Visitor* visitor) { +void HTMLObjectElement::Trace(Visitor* visitor) const { ListedElement::Trace(visitor); HTMLPlugInElement::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/html_object_element.h b/chromium/third_party/blink/renderer/core/html/html_object_element.h index 6c14c233483..bbc9e3683ad 100644 --- a/chromium/third_party/blink/renderer/core/html/html_object_element.h +++ b/chromium/third_party/blink/renderer/core/html/html_object_element.h @@ -46,7 +46,7 @@ class CORE_EXPORT HTMLObjectElement final : public HTMLPlugInElement, public: HTMLObjectElement(Document&, const CreateElementFlags); ~HTMLObjectElement() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // Returns attributes that should be checked against Trusted Types const AttrNameToTrustedType& GetCheckedAttributeTypes() const override; diff --git a/chromium/third_party/blink/renderer/core/html/html_plugin_element.cc b/chromium/third_party/blink/renderer/core/html/html_plugin_element.cc index f1211b41033..bf2a8b47037 100644 --- a/chromium/third_party/blink/renderer/core/html/html_plugin_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_plugin_element.cc @@ -128,8 +128,8 @@ HTMLPlugInElement::HTMLPlugInElement( should_prefer_plug_ins_for_images_(prefer_plug_ins_for_images_option == kShouldPreferPlugInsForImages) { SetHasCustomStyleCallbacks(); - if (doc.GetScheduler()) { - doc.GetScheduler()->RegisterStickyFeature( + if (auto* context = doc.GetExecutionContext()) { + context->GetScheduler()->RegisterStickyFeature( SchedulingPolicy::Feature::kContainsPlugins, {SchedulingPolicy::RecordMetricsForBackForwardCache()}); } @@ -140,7 +140,7 @@ HTMLPlugInElement::~HTMLPlugInElement() { DCHECK(!is_delaying_load_event_); } -void HTMLPlugInElement::Trace(Visitor* visitor) { +void HTMLPlugInElement::Trace(Visitor* visitor) const { visitor->Trace(image_loader_); visitor->Trace(persisted_plugin_); HTMLFrameOwnerElement::Trace(visitor); @@ -272,8 +272,7 @@ bool HTMLPlugInElement::ShouldAccelerate() const { return plugin && plugin->CcLayer(); } -ParsedFeaturePolicy HTMLPlugInElement::ConstructContainerPolicy( - Vector<String>*) const { +ParsedFeaturePolicy HTMLPlugInElement::ConstructContainerPolicy() const { // Plugin elements (<object> and <embed>) are not allowed to enable the // fullscreen feature. Add an empty allowlist for the fullscreen feature so // that the nested browsing context is unable to use the API, regardless of @@ -725,7 +724,7 @@ bool HTMLPlugInElement::AllowedToLoadObject(const KURL& url, // is specified. return (!mime_type.IsEmpty() && url.IsEmpty()) || !MixedContentChecker::ShouldBlockFetch( - frame, mojom::RequestContextType::OBJECT, + frame, mojom::RequestContextType::OBJECT, url, ResourceRequest::RedirectStatus::kNoRedirect, url, /* devtools_id= */ base::nullopt); } diff --git a/chromium/third_party/blink/renderer/core/html/html_plugin_element.h b/chromium/third_party/blink/renderer/core/html/html_plugin_element.h index 56ffb6e89a6..58cd78b33b7 100644 --- a/chromium/third_party/blink/renderer/core/html/html_plugin_element.h +++ b/chromium/third_party/blink/renderer/core/html/html_plugin_element.h @@ -66,7 +66,7 @@ class CORE_EXPORT HTMLPlugInElement public: ~HTMLPlugInElement() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; bool IsPlugin() const final { return true; } @@ -99,8 +99,7 @@ class CORE_EXPORT HTMLPlugInElement bool ShouldAccelerate() const; - ParsedFeaturePolicy ConstructContainerPolicy( - Vector<String>* /* messages */) const override; + ParsedFeaturePolicy ConstructContainerPolicy() const override; bool IsImageType() const; HTMLImageLoader* ImageLoader() const { return image_loader_.Get(); } diff --git a/chromium/third_party/blink/renderer/core/html/html_plugin_element_test.cc b/chromium/third_party/blink/renderer/core/html/html_plugin_element_test.cc index 985076f427b..0e8b8147533 100644 --- a/chromium/third_party/blink/renderer/core/html/html_plugin_element_test.cc +++ b/chromium/third_party/blink/renderer/core/html/html_plugin_element_test.cc @@ -25,10 +25,6 @@ class TestPluginLocalFrameClient : public EmptyLocalFrameClient { int plugin_created_count() const { return plugin_created_count_; } private: - std::unique_ptr<WebURLLoaderFactory> CreateURLLoaderFactory() override { - return Platform::Current()->CreateDefaultURLLoaderFactory(); - } - WebPluginContainerImpl* CreatePlugin(HTMLPlugInElement& element, const KURL& url, const Vector<String>& param_names, diff --git a/chromium/third_party/blink/renderer/core/html/html_progress_element.cc b/chromium/third_party/blink/renderer/core/html/html_progress_element.cc index 054bc294414..3c9c804cead 100644 --- a/chromium/third_party/blink/renderer/core/html/html_progress_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_progress_element.cc @@ -147,7 +147,7 @@ bool HTMLProgressElement::ShouldAppearIndeterminate() const { return !IsDeterminate(); } -void HTMLProgressElement::Trace(Visitor* visitor) { +void HTMLProgressElement::Trace(Visitor* visitor) const { visitor->Trace(value_); HTMLElement::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/html_progress_element.h b/chromium/third_party/blink/renderer/core/html/html_progress_element.h index 1473489db2a..61bce3bfc06 100644 --- a/chromium/third_party/blink/renderer/core/html/html_progress_element.h +++ b/chromium/third_party/blink/renderer/core/html/html_progress_element.h @@ -48,7 +48,7 @@ class CORE_EXPORT HTMLProgressElement final : public HTMLElement { bool CanContainRangeEndPoint() const override { return false; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: ~HTMLProgressElement() override; diff --git a/chromium/third_party/blink/renderer/core/html/html_script_element.cc b/chromium/third_party/blink/renderer/core/html/html_script_element.cc index fd8290a81c4..756865b88ef 100644 --- a/chromium/third_party/blink/renderer/core/html/html_script_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_script_element.cc @@ -47,8 +47,7 @@ HTMLScriptElement::HTMLScriptElement(Document& document, const CreateElementFlags flags) : HTMLElement(html_names::kScriptTag, document), children_changed_by_api_(false), - loader_(InitializeScriptLoader(flags.IsCreatedByParser(), - flags.WasAlreadyStarted())) {} + loader_(InitializeScriptLoader(flags)) {} const AttrNameToTrustedType& HTMLScriptElement::GetCheckedAttributeTypes() const { @@ -94,7 +93,8 @@ void HTMLScriptElement::ParseAttribute( } else if (params.name == html_names::kAsyncAttr) { loader_->HandleAsyncAttribute(); } else if (params.name == html_names::kImportanceAttr && - RuntimeEnabledFeatures::PriorityHintsEnabled(&GetDocument())) { + RuntimeEnabledFeatures::PriorityHintsEnabled( + GetExecutionContext())) { // The only thing we need to do for the the importance attribute/Priority // Hints is count usage upon parsing. Processing the value happens when the // element loads. @@ -270,7 +270,7 @@ bool HTMLScriptElement::AllowInlineScriptForCSP( const AtomicString& nonce, const WTF::OrdinalNumber& context_line, const String& script_content) { - return GetDocument().GetContentSecurityPolicyForWorld()->AllowInline( + return GetExecutionContext()->GetContentSecurityPolicyForWorld()->AllowInline( ContentSecurityPolicy::InlineType::kScript, this, script_content, nonce, GetDocument().Url(), context_line); } @@ -309,7 +309,7 @@ Element& HTMLScriptElement::CloneWithoutAttributesAndChildren( return *factory.CreateElement(TagQName(), flags, IsValue()); } -void HTMLScriptElement::Trace(Visitor* visitor) { +void HTMLScriptElement::Trace(Visitor* visitor) const { visitor->Trace(loader_); HTMLElement::Trace(visitor); ScriptElementBase::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/core/html/html_script_element.h b/chromium/third_party/blink/renderer/core/html/html_script_element.h index 6315197c09a..ccafa59fc93 100644 --- a/chromium/third_party/blink/renderer/core/html/html_script_element.h +++ b/chromium/third_party/blink/renderer/core/html/html_script_element.h @@ -64,7 +64,7 @@ class CORE_EXPORT HTMLScriptElement final : public HTMLElement, Document& GetDocument() const override; ExecutionContext* GetExecutionContext() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void FinishParsingChildren() override; diff --git a/chromium/third_party/blink/renderer/core/html/html_script_element_test.cc b/chromium/third_party/blink/renderer/core/html/html_script_element_test.cc index 2ea58d2feea..c9c61cdd214 100644 --- a/chromium/third_party/blink/renderer/core/html/html_script_element_test.cc +++ b/chromium/third_party/blink/renderer/core/html/html_script_element_test.cc @@ -22,7 +22,7 @@ class HTMLScriptElementTest : public testing::Test { HTMLScriptElement* MakeScript() { HTMLScriptElement* script = To<HTMLScriptElement>( document().body()->AppendChild(MakeGarbageCollected<HTMLScriptElement>( - document(), CreateElementFlags::ByParser()))); + document(), CreateElementFlags::ByParser(&document())))); EXPECT_TRUE(script); return script; } diff --git a/chromium/third_party/blink/renderer/core/html/html_slot_element.cc b/chromium/third_party/blink/renderer/core/html/html_slot_element.cc index c0d3b990d97..d5231b5b194 100644 --- a/chromium/third_party/blink/renderer/core/html/html_slot_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_slot_element.cc @@ -746,7 +746,7 @@ bool HTMLSlotElement::HasAssignedNodesSlow() const { return assignment.FindHostChildBySlotName(GetName()); } -void HTMLSlotElement::Trace(Visitor* visitor) { +void HTMLSlotElement::Trace(Visitor* visitor) const { visitor->Trace(assigned_nodes_); visitor->Trace(flat_tree_children_); visitor->Trace(assigned_nodes_candidates_); diff --git a/chromium/third_party/blink/renderer/core/html/html_slot_element.h b/chromium/third_party/blink/renderer/core/html/html_slot_element.h index dab5c1f8416..2e0b527ac04 100644 --- a/chromium/third_party/blink/renderer/core/html/html_slot_element.h +++ b/chromium/third_party/blink/renderer/core/html/html_slot_element.h @@ -118,7 +118,7 @@ class CORE_EXPORT HTMLSlotElement final : public HTMLElement { void ClearAssignedNodesCandidates(); void RemoveAssignedNodeCandidate(Node&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: InsertionNotificationRequest InsertedInto(ContainerNode&) final; diff --git a/chromium/third_party/blink/renderer/core/html/html_source_element.cc b/chromium/third_party/blink/renderer/core/html/html_source_element.cc index c65bd23aebe..b3e2f46957b 100644 --- a/chromium/third_party/blink/renderer/core/html/html_source_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_source_element.cc @@ -49,7 +49,7 @@ class HTMLSourceElement::Listener final : public MediaQueryListListener { } void ClearElement() { element_ = nullptr; } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(element_); MediaQueryListListener::Trace(visitor); } @@ -184,7 +184,7 @@ void HTMLSourceElement::NotifyMediaQueryChanged() { picture->SourceOrMediaChanged(); } -void HTMLSourceElement::Trace(Visitor* visitor) { +void HTMLSourceElement::Trace(Visitor* visitor) const { visitor->Trace(media_query_list_); visitor->Trace(listener_); HTMLElement::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/core/html/html_source_element.h b/chromium/third_party/blink/renderer/core/html/html_source_element.h index 578e2eef779..2c461edcaf6 100644 --- a/chromium/third_party/blink/renderer/core/html/html_source_element.h +++ b/chromium/third_party/blink/renderer/core/html/html_source_element.h @@ -53,7 +53,7 @@ class HTMLSourceElement final : public HTMLElement { void RemoveMediaQueryListListener(); void AddMediaQueryListListener(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void DispatchPendingEvent(); diff --git a/chromium/third_party/blink/renderer/core/html/html_style_element.cc b/chromium/third_party/blink/renderer/core/html/html_style_element.cc index e49545b4d73..1fb65d80835 100644 --- a/chromium/third_party/blink/renderer/core/html/html_style_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_style_element.cc @@ -148,7 +148,7 @@ void HTMLStyleElement::setDisabled(bool set_disabled) { style_sheet->setDisabled(set_disabled); } -void HTMLStyleElement::Trace(Visitor* visitor) { +void HTMLStyleElement::Trace(Visitor* visitor) const { StyleElement::Trace(visitor); HTMLElement::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/html_style_element.h b/chromium/third_party/blink/renderer/core/html/html_style_element.h index e9c77140b26..56c3e51316e 100644 --- a/chromium/third_party/blink/renderer/core/html/html_style_element.h +++ b/chromium/third_party/blink/renderer/core/html/html_style_element.h @@ -44,7 +44,7 @@ class CORE_EXPORT HTMLStyleElement final : public HTMLElement, bool disabled() const; void setDisabled(bool); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // Always call this asynchronously because this can cause synchronous diff --git a/chromium/third_party/blink/renderer/core/html/html_table_element.cc b/chromium/third_party/blink/renderer/core/html/html_table_element.cc index b7693232ba2..7fbf2d4e948 100644 --- a/chromium/third_party/blink/renderer/core/html/html_table_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_table_element.cc @@ -329,8 +329,8 @@ void HTMLTableElement::CollectStyleForPresentationAttribute( WebFeature::kHTMLTableElementPresentationAttributeBackground); CSSImageValue* image_value = MakeGarbageCollected<CSSImageValue>( AtomicString(url), GetDocument().CompleteURL(url), - Referrer(GetDocument().OutgoingReferrer(), - GetDocument().GetReferrerPolicy()), + Referrer(GetExecutionContext()->OutgoingReferrer(), + GetExecutionContext()->GetReferrerPolicy()), OriginClean::kTrue, false /* is_ad_related */); style->SetProperty( CSSPropertyValue(GetCSSPropertyBackgroundImage(), *image_value)); @@ -633,7 +633,7 @@ const AtomicString& HTMLTableElement::Summary() const { return FastGetAttribute(html_names::kSummaryAttr); } -void HTMLTableElement::Trace(Visitor* visitor) { +void HTMLTableElement::Trace(Visitor* visitor) const { visitor->Trace(shared_cell_style_); HTMLElement::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/html_table_element.h b/chromium/third_party/blink/renderer/core/html/html_table_element.h index d3f59e00204..7cfaf43a8a5 100644 --- a/chromium/third_party/blink/renderer/core/html/html_table_element.h +++ b/chromium/third_party/blink/renderer/core/html/html_table_element.h @@ -73,7 +73,7 @@ class CORE_EXPORT HTMLTableElement final : public HTMLElement { bool HasNonInBodyInsertionMode() const override { return true; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: ~HTMLTableElement() override; diff --git a/chromium/third_party/blink/renderer/core/html/html_table_part_element.cc b/chromium/third_party/blink/renderer/core/html/html_table_part_element.cc index 5d04bf78b73..8b7d3c33156 100644 --- a/chromium/third_party/blink/renderer/core/html/html_table_part_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_table_part_element.cc @@ -62,8 +62,8 @@ void HTMLTablePartElement::CollectStyleForPresentationAttribute( WebFeature::kHTMLTableElementPresentationAttributeBackground); CSSImageValue* image_value = MakeGarbageCollected<CSSImageValue>( AtomicString(url), GetDocument().CompleteURL(url), - Referrer(GetDocument().OutgoingReferrer(), - GetDocument().GetReferrerPolicy()), + Referrer(GetExecutionContext()->OutgoingReferrer(), + GetExecutionContext()->GetReferrerPolicy()), OriginClean::kTrue, false /* is_ad_related */); style->SetProperty( CSSPropertyValue(GetCSSPropertyBackgroundImage(), *image_value)); diff --git a/chromium/third_party/blink/renderer/core/html/html_table_row_element_test.cc b/chromium/third_party/blink/renderer/core/html/html_table_row_element_test.cc index 8ccf5d44f08..84b43028542 100644 --- a/chromium/third_party/blink/renderer/core/html/html_table_row_element_test.cc +++ b/chromium/third_party/blink/renderer/core/html/html_table_row_element_test.cc @@ -16,14 +16,14 @@ namespace blink { // https://html.spec.whatwg.org/C/#dom-tr-rowindex TEST(HTMLTableRowElementTest, rowIndex_notInTable) { - auto* document = MakeGarbageCollected<Document>(); + auto* document = Document::CreateForTest(); auto* row = MakeGarbageCollected<HTMLTableRowElement>(*document); EXPECT_EQ(-1, row->rowIndex()) << "rows not in tables should have row index -1"; } TEST(HTMLTableRowElementTest, rowIndex_directChildOfTable) { - auto* document = MakeGarbageCollected<Document>(); + auto* document = Document::CreateForTest(); auto* table = MakeGarbageCollected<HTMLTableElement>(*document); auto* row = MakeGarbageCollected<HTMLTableRowElement>(*document); table->AppendChild(row); @@ -32,7 +32,7 @@ TEST(HTMLTableRowElementTest, rowIndex_directChildOfTable) { } TEST(HTMLTableRowElementTest, rowIndex_inUnrelatedElementInTable) { - auto* document = MakeGarbageCollected<Document>(); + auto* document = Document::CreateForTest(); auto* table = MakeGarbageCollected<HTMLTableElement>(*document); // Almost any element will do; what's pertinent is that this is not // THEAD, TBODY or TFOOT. diff --git a/chromium/third_party/blink/renderer/core/html/html_template_element.cc b/chromium/third_party/blink/renderer/core/html/html_template_element.cc index 25d817119e2..2cbed912ebc 100644 --- a/chromium/third_party/blink/renderer/core/html/html_template_element.cc +++ b/chromium/third_party/blink/renderer/core/html/html_template_element.cc @@ -46,7 +46,7 @@ HTMLTemplateElement::HTMLTemplateElement(Document& document) HTMLTemplateElement::~HTMLTemplateElement() = default; DocumentFragment* HTMLTemplateElement::ContentInternal() const { - if (!content_) + if (!content_ && GetExecutionContext()) content_ = MakeGarbageCollected<TemplateContentDocumentFragment>( GetDocument().EnsureTemplateDocument(), const_cast<HTMLTemplateElement*>(this)); @@ -66,7 +66,7 @@ DocumentFragment* HTMLTemplateElement::DeclarativeShadowContent() const { void HTMLTemplateElement::CloneNonAttributePropertiesFrom( const Element& source, CloneChildrenFlag flag) { - if (flag == CloneChildrenFlag::kSkip) + if (flag == CloneChildrenFlag::kSkip || !GetExecutionContext()) return; DCHECK_NE(flag, CloneChildrenFlag::kCloneWithShadows); auto& html_template_element = To<HTMLTemplateElement>(source); @@ -76,12 +76,12 @@ void HTMLTemplateElement::CloneNonAttributePropertiesFrom( void HTMLTemplateElement::DidMoveToNewDocument(Document& old_document) { HTMLElement::DidMoveToNewDocument(old_document); - if (!content_) + if (!content_ || !GetExecutionContext()) return; GetDocument().EnsureTemplateDocument().AdoptIfNeeded(*content_); } -void HTMLTemplateElement::Trace(Visitor* visitor) { +void HTMLTemplateElement::Trace(Visitor* visitor) const { visitor->Trace(content_); HTMLElement::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/html_template_element.h b/chromium/third_party/blink/renderer/core/html/html_template_element.h index 6cfc5b166af..5db37948794 100644 --- a/chromium/third_party/blink/renderer/core/html/html_template_element.h +++ b/chromium/third_party/blink/renderer/core/html/html_template_element.h @@ -53,7 +53,7 @@ class CORE_EXPORT HTMLTemplateElement final : public HTMLElement { bool HasNonInBodyInsertionMode() const override { return true; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; DocumentFragment* content() const; diff --git a/chromium/third_party/blink/renderer/core/html/html_view_source_document.cc b/chromium/third_party/blink/renderer/core/html/html_view_source_document.cc index c737b7b2675..c1f2ebb0e2c 100644 --- a/chromium/third_party/blink/renderer/core/html/html_view_source_document.cc +++ b/chromium/third_party/blink/renderer/core/html/html_view_source_document.cc @@ -335,7 +335,7 @@ int HTMLViewSourceDocument::AddSrcset(const String& source, return end; } -void HTMLViewSourceDocument::Trace(Visitor* visitor) { +void HTMLViewSourceDocument::Trace(Visitor* visitor) const { visitor->Trace(current_); visitor->Trace(tbody_); visitor->Trace(td_); diff --git a/chromium/third_party/blink/renderer/core/html/html_view_source_document.h b/chromium/third_party/blink/renderer/core/html/html_view_source_document.h index 87bf8b54dc8..7076c6186eb 100644 --- a/chromium/third_party/blink/renderer/core/html/html_view_source_document.h +++ b/chromium/third_party/blink/renderer/core/html/html_view_source_document.h @@ -40,7 +40,7 @@ class CORE_EXPORT HTMLViewSourceDocument final : public HTMLDocument { void AddSource(const String&, HTMLToken&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: DocumentParser* CreateParser() override; diff --git a/chromium/third_party/blink/renderer/core/html/image_document.cc b/chromium/third_party/blink/renderer/core/html/image_document.cc index 3ae208645a9..f33f26ed020 100644 --- a/chromium/third_party/blink/renderer/core/html/image_document.cc +++ b/chromium/third_party/blink/renderer/core/html/image_document.cc @@ -69,7 +69,7 @@ class ImageEventListener : public NativeEventListener { void Invoke(ExecutionContext*, Event*) override; - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(doc_); NativeEventListener::Trace(visitor); } @@ -99,7 +99,7 @@ class ImageDocumentParser : public RawDataDocumentParser { return To<ImageDocument>(RawDataDocumentParser::GetDocument()); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(image_resource_); RawDataDocumentParser::Trace(visitor); } @@ -562,7 +562,7 @@ bool ImageDocument::ShouldShrinkToFit() const { return GetFrame()->IsMainFrame() && !is_wrap_content_web_view; } -void ImageDocument::Trace(Visitor* visitor) { +void ImageDocument::Trace(Visitor* visitor) const { visitor->Trace(div_element_); visitor->Trace(image_element_); HTMLDocument::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/core/html/image_document.h b/chromium/third_party/blink/renderer/core/html/image_document.h index a9aa1335792..fec132d0867 100644 --- a/chromium/third_party/blink/renderer/core/html/image_document.h +++ b/chromium/third_party/blink/renderer/core/html/image_document.h @@ -52,7 +52,7 @@ class CORE_EXPORT ImageDocument final : public HTMLDocument { void UpdateTitle(); bool ShouldShrinkToFit() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: DocumentParser* CreateParser() override; diff --git a/chromium/third_party/blink/renderer/core/html/image_document_test.cc b/chromium/third_party/blink/renderer/core/html/image_document_test.cc index 1e7cc5c37bc..0c08423a3c8 100644 --- a/chromium/third_party/blink/renderer/core/html/image_document_test.cc +++ b/chromium/third_party/blink/renderer/core/html/image_document_test.cc @@ -19,6 +19,7 @@ #include "third_party/blink/renderer/core/testing/dummy_page_holder.h" #include "third_party/blink/renderer/core/testing/sim/sim_request.h" #include "third_party/blink/renderer/core/testing/sim/sim_test.h" +#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" namespace blink { @@ -83,8 +84,6 @@ class ImageDocumentTest : public testing::Test { void CreateDocumentWithoutLoadingImage(int view_width, int view_height); void CreateDocument(int view_width, int view_height); - DocumentParser* StartLoadingImage(); - void LoadImage(); ImageDocument& GetDocument() const; @@ -93,10 +92,14 @@ class ImageDocumentTest : public testing::Test { void SetPageZoom(float); void SetWindowToViewportScalingFactor(float); + void SetForceZeroLayoutHeight(bool); private: Persistent<WindowToViewportScalingChromeClient> chrome_client_; std::unique_ptr<DummyPageHolder> dummy_page_holder_; + float page_zoom_factor_ = 0.0f; + float viewport_scaling_factor_ = 0.0f; + base::Optional<bool> force_zero_layout_height_; }; void ImageDocumentTest::CreateDocumentWithoutLoadingImage(int view_width, @@ -109,19 +112,29 @@ void ImageDocumentTest::CreateDocumentWithoutLoadingImage(int view_width, dummy_page_holder_ = std::make_unique<DummyPageHolder>( IntSize(view_width, view_height), &page_clients); - LocalFrame& frame = dummy_page_holder_->GetFrame(); - frame.GetDocument()->Shutdown(); - DocumentInit init = - DocumentInit::Create() - .WithDocumentLoader(frame.Loader().GetDocumentLoader()) - .WithTypeFrom("image/jpeg"); - frame.DomWindow()->InstallNewDocument(init); - frame.GetDocument()->SetURL(KURL("http://www.example.com/image.jpg")); + if (page_zoom_factor_) + dummy_page_holder_->GetFrame().SetPageZoomFactor(page_zoom_factor_); + if (viewport_scaling_factor_) + chrome_client_->SetScalingFactor(viewport_scaling_factor_); + if (force_zero_layout_height_.has_value()) { + dummy_page_holder_->GetPage().GetSettings().SetForceZeroLayoutHeight( + force_zero_layout_height_.value()); + } + + auto params = std::make_unique<WebNavigationParams>(); + params->url = KURL("http://www.example.com/image.jpg"); + + const Vector<unsigned char>& data = JpegImage(); + WebNavigationParams::FillStaticResponse( + params.get(), "image/jpeg", "UTF-8", + base::make_span(reinterpret_cast<const char*>(data.data()), data.size())); + dummy_page_holder_->GetFrame().Loader().CommitNavigation(std::move(params), + nullptr); } void ImageDocumentTest::CreateDocument(int view_width, int view_height) { CreateDocumentWithoutLoadingImage(view_width, view_height); - LoadImage(); + blink::test::RunPendingTasks(); } ImageDocument& ImageDocumentTest::GetDocument() const { @@ -130,25 +143,23 @@ ImageDocument& ImageDocumentTest::GetDocument() const { return *image_document; } -DocumentParser* ImageDocumentTest::StartLoadingImage() { - DocumentParser* parser = GetDocument().ImplicitOpen( - ParserSynchronizationPolicy::kForceSynchronousParsing); - const Vector<unsigned char>& data = JpegImage(); - parser->AppendBytes(reinterpret_cast<const char*>(data.data()), data.size()); - return parser; -} - -void ImageDocumentTest::LoadImage() { - DocumentParser* parser = StartLoadingImage(); - parser->Finish(); -} - void ImageDocumentTest::SetPageZoom(float factor) { - dummy_page_holder_->GetFrame().SetPageZoomFactor(factor); + page_zoom_factor_ = factor; + if (dummy_page_holder_) + dummy_page_holder_->GetFrame().SetPageZoomFactor(factor); } void ImageDocumentTest::SetWindowToViewportScalingFactor(float factor) { - chrome_client_->SetScalingFactor(factor); + viewport_scaling_factor_ = factor; + if (chrome_client_) + chrome_client_->SetScalingFactor(factor); +} + +void ImageDocumentTest::SetForceZeroLayoutHeight(bool force) { + force_zero_layout_height_ = force; + if (dummy_page_holder_) { + dummy_page_holder_->GetPage().GetSettings().SetForceZeroLayoutHeight(force); + } } TEST_F(ImageDocumentTest, ImageLoad) { @@ -175,9 +186,8 @@ TEST_F(ImageDocumentTest, RestoreImageOnClick) { } TEST_F(ImageDocumentTest, InitialZoomDoesNotAffectScreenFit) { - CreateDocumentWithoutLoadingImage(20, 10); SetPageZoom(2.f); - LoadImage(); + CreateDocument(20, 10); EXPECT_EQ(10, ImageWidth()); EXPECT_EQ(10, ImageHeight()); GetDocument().ImageClicked(4, 4); @@ -198,17 +208,15 @@ TEST_F(ImageDocumentTest, ZoomingDoesNotChangeRelativeSize) { } TEST_F(ImageDocumentTest, ImageScalesDownWithDsf) { - CreateDocumentWithoutLoadingImage(20, 30); SetWindowToViewportScalingFactor(2.f); - LoadImage(); + CreateDocument(20, 30); EXPECT_EQ(10, ImageWidth()); EXPECT_EQ(10, ImageHeight()); } TEST_F(ImageDocumentTest, ImageNotCenteredWithForceZeroLayoutHeight) { - CreateDocumentWithoutLoadingImage(80, 70); - GetDocument().GetPage()->GetSettings().SetForceZeroLayoutHeight(true); - LoadImage(); + SetForceZeroLayoutHeight(true); + CreateDocument(80, 70); EXPECT_FALSE(GetDocument().ShouldShrinkToFit()); EXPECT_EQ(0, GetDocument().ImageElement()->OffsetLeft()); EXPECT_EQ(0, GetDocument().ImageElement()->OffsetTop()); @@ -217,9 +225,8 @@ TEST_F(ImageDocumentTest, ImageNotCenteredWithForceZeroLayoutHeight) { } TEST_F(ImageDocumentTest, ImageCenteredWithoutForceZeroLayoutHeight) { - CreateDocumentWithoutLoadingImage(80, 70); - GetDocument().GetPage()->GetSettings().SetForceZeroLayoutHeight(false); - LoadImage(); + SetForceZeroLayoutHeight(false); + CreateDocument(80, 70); EXPECT_TRUE(GetDocument().ShouldShrinkToFit()); EXPECT_EQ(15, GetDocument().ImageElement()->OffsetLeft()); EXPECT_EQ(10, GetDocument().ImageElement()->OffsetTop()); @@ -234,9 +241,8 @@ TEST_F(ImageDocumentTest, DomInteractive) { TEST_F(ImageDocumentTest, ImageSrcChangedBeforeFinish) { CreateDocumentWithoutLoadingImage(80, 70); - DocumentParser* parser = StartLoadingImage(); GetDocument().ImageElement()->removeAttribute(html_names::kSrcAttr); - parser->Finish(); + blink::test::RunPendingTasks(); } #if defined(OS_ANDROID) @@ -246,9 +252,8 @@ TEST_F(ImageDocumentTest, ImageSrcChangedBeforeFinish) { #endif TEST_F(ImageDocumentTest, MAYBE(ImageCenteredAtDeviceScaleFactor)) { - CreateDocumentWithoutLoadingImage(30, 30); SetWindowToViewportScalingFactor(1.5f); - LoadImage(); + CreateDocument(30, 30); EXPECT_TRUE(GetDocument().ShouldShrinkToFit()); GetDocument().ImageClicked(15, 27); diff --git a/chromium/third_party/blink/renderer/core/html/imports/README.md b/chromium/third_party/blink/renderer/core/html/imports/README.md index c31bf6d9d1d..35836d4c89a 100644 --- a/chromium/third_party/blink/renderer/core/html/imports/README.md +++ b/chromium/third_party/blink/renderer/core/html/imports/README.md @@ -13,7 +13,7 @@ HTML Imports form a tree: * The root of the tree is `HTMLImportTreeRoot`. * The `HTMLImportTreeRoot` is owned by `HTMLImportsController`, which is owned - by the master document as a `DocumentSupplement`. + by the tree_root document as a `DocumentSupplement`. * The non-root nodes are `HTMLImportChild`. They are all owned by `HTMLImporTreeRoot`. `LinkStyle` is wired into `HTMLImportChild` by implementing `HTMLImportChildClient` interface. diff --git a/chromium/third_party/blink/renderer/core/html/imports/html_import.h b/chromium/third_party/blink/renderer/core/html/imports/html_import.h index cc874f35d79..69741e2ea50 100644 --- a/chromium/third_party/blink/renderer/core/html/imports/html_import.h +++ b/chromium/third_party/blink/renderer/core/html/imports/html_import.h @@ -66,7 +66,7 @@ class HTMLImport : public GarbageCollected<HTMLImport>, virtual void StateWillChange() {} virtual void StateDidChange(); - virtual void Trace(Visitor* visitor) {} + virtual void Trace(Visitor* visitor) const {} protected: // Stating from most conservative state. diff --git a/chromium/third_party/blink/renderer/core/html/imports/html_import_child.cc b/chromium/third_party/blink/renderer/core/html/imports/html_import_child.cc index 301cb4a5ee8..ac7aad3cf3d 100644 --- a/chromium/third_party/blink/renderer/core/html/imports/html_import_child.cc +++ b/chromium/third_party/blink/renderer/core/html/imports/html_import_child.cc @@ -174,7 +174,7 @@ void HTMLImportChild::Normalize() { } } -void HTMLImportChild::Trace(Visitor* visitor) { +void HTMLImportChild::Trace(Visitor* visitor) const { visitor->Trace(custom_element_microtask_step_); visitor->Trace(loader_); visitor->Trace(client_); diff --git a/chromium/third_party/blink/renderer/core/html/imports/html_import_child.h b/chromium/third_party/blink/renderer/core/html/imports/html_import_child.h index e8265e3ea31..7ba5533b9e5 100644 --- a/chromium/third_party/blink/renderer/core/html/imports/html_import_child.h +++ b/chromium/third_party/blink/renderer/core/html/imports/html_import_child.h @@ -70,7 +70,7 @@ class HTMLImportChild final : public HTMLImport { HTMLImportLoader* Loader() const final; void StateWillChange() final; void StateDidChange() final; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void DidFinishLoading(); void DidFinishUpgradingCustomElements(); diff --git a/chromium/third_party/blink/renderer/core/html/imports/html_import_child_client.h b/chromium/third_party/blink/renderer/core/html/imports/html_import_child_client.h index 04525f82465..1b37fbb7828 100644 --- a/chromium/third_party/blink/renderer/core/html/imports/html_import_child_client.h +++ b/chromium/third_party/blink/renderer/core/html/imports/html_import_child_client.h @@ -45,7 +45,7 @@ class HTMLImportChildClient : public GarbageCollectedMixin { virtual void ImportChildWasDisposed(HTMLImportChild*) = 0; virtual bool IsSync() const = 0; virtual HTMLLinkElement* Link() = 0; - void Trace(Visitor* visitor) override {} + void Trace(Visitor* visitor) const override {} }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/imports/html_import_loader.cc b/chromium/third_party/blink/renderer/core/html/imports/html_import_loader.cc index a921505e787..b23f609a9a5 100644 --- a/chromium/third_party/blink/renderer/core/html/imports/html_import_loader.cc +++ b/chromium/third_party/blink/renderer/core/html/imports/html_import_loader.cc @@ -96,16 +96,21 @@ HTMLImportLoader::State HTMLImportLoader::StartWritingAndParsing( const ResourceResponse& response) { DCHECK(controller_); DCHECK(!imports_.IsEmpty()); - Document* master = controller_->Master(); + Document* tree_root = controller_->TreeRoot(); document_ = MakeGarbageCollected<HTMLDocument>( DocumentInit::Create() .WithImportsController(controller_) - .WithContextDocument(master->ContextDocument()) - .WithRegistrationContext(master->RegistrationContext()) - .WithContentSecurityPolicy(master->GetContentSecurityPolicy()) + .WithExecutionContext(tree_root->GetExecutionContext()) + .WithRegistrationContext(tree_root->RegistrationContext()) .WithURL(response.CurrentRequestUrl())); - document_->OpenForNavigation(kAllowAsynchronousParsing, response.MimeType(), - "UTF-8"); + // imports expect to be able to log CSP errors, which requires binding the CSP + // to a CSP delegate. + document_->BindContentSecurityPolicy(); + document_->OpenForNavigation( + RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled() + ? kAllowDeferredParsing + : kAllowAsynchronousParsing, + response.MimeType(), "UTF-8"); DocumentParser* parser = document_->Parser(); DCHECK(parser); @@ -204,7 +209,7 @@ V0CustomElementSyncMicrotaskQueue* HTMLImportLoader::MicrotaskQueue() const { return microtask_queue_; } -void HTMLImportLoader::Trace(Visitor* visitor) { +void HTMLImportLoader::Trace(Visitor* visitor) const { visitor->Trace(controller_); visitor->Trace(imports_); visitor->Trace(document_); diff --git a/chromium/third_party/blink/renderer/core/html/imports/html_import_loader.h b/chromium/third_party/blink/renderer/core/html/imports/html_import_loader.h index cbae34ab7f2..70d6505f3a6 100644 --- a/chromium/third_party/blink/renderer/core/html/imports/html_import_loader.h +++ b/chromium/third_party/blink/renderer/core/html/imports/html_import_loader.h @@ -87,7 +87,7 @@ class HTMLImportLoader final : public GarbageCollected<HTMLImportLoader>, V0CustomElementSyncMicrotaskQueue* MicrotaskQueue() const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // RawResourceClient overrides: diff --git a/chromium/third_party/blink/renderer/core/html/imports/html_import_tree_root.cc b/chromium/third_party/blink/renderer/core/html/imports/html_import_tree_root.cc index d88f5f79f8d..f21358abc74 100644 --- a/chromium/third_party/blink/renderer/core/html/imports/html_import_tree_root.cc +++ b/chromium/third_party/blink/renderer/core/html/imports/html_import_tree_root.cc @@ -77,7 +77,7 @@ void HTMLImportTreeRoot::RecalcTimerFired(TimerBase*) { HTMLImport::RecalcTreeState(this); } -void HTMLImportTreeRoot::Trace(Visitor* visitor) { +void HTMLImportTreeRoot::Trace(Visitor* visitor) const { visitor->Trace(document_); visitor->Trace(imports_); HTMLImport::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/core/html/imports/html_import_tree_root.h b/chromium/third_party/blink/renderer/core/html/imports/html_import_tree_root.h index 5bfb3fe17c2..02a484bcae1 100644 --- a/chromium/third_party/blink/renderer/core/html/imports/html_import_tree_root.h +++ b/chromium/third_party/blink/renderer/core/html/imports/html_import_tree_root.h @@ -33,7 +33,7 @@ class HTMLImportTreeRoot final : public HTMLImport, public NameClient { HTMLImportChild* Add(HTMLImportChild*); HTMLImportChild* Find(const KURL&) const; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; const char* NameInHeapSnapshot() const override { return "HTMLImportTreeRoot"; } diff --git a/chromium/third_party/blink/renderer/core/html/imports/html_imports_controller.cc b/chromium/third_party/blink/renderer/core/html/imports/html_imports_controller.cc index 4e9573b0311..84e47deda9b 100644 --- a/chromium/third_party/blink/renderer/core/html/imports/html_imports_controller.cc +++ b/chromium/third_party/blink/renderer/core/html/imports/html_imports_controller.cc @@ -42,8 +42,8 @@ namespace blink { -HTMLImportsController::HTMLImportsController(Document& master) - : root_(MakeGarbageCollected<HTMLImportTreeRoot>(&master)) {} +HTMLImportsController::HTMLImportsController(Document& tree_root) + : root_(MakeGarbageCollected<HTMLImportTreeRoot>(&tree_root)) {} void HTMLImportsController::Dispose() { // TODO(tkent): We copy loaders_ before iteration to avoid crashes. @@ -117,7 +117,7 @@ HTMLImportChild* HTMLImportsController::Load(const Document& parent_document, } scoped_refptr<const SecurityOrigin> security_origin = - Master()->GetSecurityOrigin(); + TreeRoot()->GetSecurityOrigin(); ResourceFetcher* fetcher = parent->GetDocument()->Fetcher(); if (parent->GetDocument()->ImportsController()) { @@ -137,7 +137,7 @@ HTMLImportChild* HTMLImportsController::Load(const Document& parent_document, return child; } -Document* HTMLImportsController::Master() const { +Document* HTMLImportsController::TreeRoot() const { return root_ ? root_->GetDocument() : nullptr; } @@ -159,7 +159,7 @@ HTMLImportLoader* HTMLImportsController::LoaderFor( return nullptr; } -void HTMLImportsController::Trace(Visitor* visitor) { +void HTMLImportsController::Trace(Visitor* visitor) const { visitor->Trace(root_); visitor->Trace(loaders_); } diff --git a/chromium/third_party/blink/renderer/core/html/imports/html_imports_controller.h b/chromium/third_party/blink/renderer/core/html/imports/html_imports_controller.h index ddb6933ec8b..7421c2a0573 100644 --- a/chromium/third_party/blink/renderer/core/html/imports/html_imports_controller.h +++ b/chromium/third_party/blink/renderer/core/html/imports/html_imports_controller.h @@ -60,13 +60,13 @@ class HTMLImportsController final HTMLImportChildClient*, FetchParameters&); - Document* Master() const; + Document* TreeRoot() const; wtf_size_t LoaderCount() const { return loaders_.size(); } HTMLImportLoader* LoaderAt(wtf_size_t i) const { return loaders_[i]; } HTMLImportLoader* LoaderFor(const Document&) const; - void Trace(Visitor*); + void Trace(Visitor*) const; void Dispose(); diff --git a/chromium/third_party/blink/renderer/core/html/imports/link_import.cc b/chromium/third_party/blink/renderer/core/html/imports/link_import.cc index 01ca5ecdf25..85aa9e01c88 100644 --- a/chromium/third_party/blink/renderer/core/html/imports/link_import.cc +++ b/chromium/third_party/blink/renderer/core/html/imports/link_import.cc @@ -128,7 +128,7 @@ void LinkImport::OwnerRemoved() { GetDocument().GetStyleEngine().HtmlImportAddedOrRemoved(); } -void LinkImport::Trace(Visitor* visitor) { +void LinkImport::Trace(Visitor* visitor) const { visitor->Trace(child_); HTMLImportChildClient::Trace(visitor); LinkResource::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/core/html/imports/link_import.h b/chromium/third_party/blink/renderer/core/html/imports/link_import.h index b6f1b8fcbc2..050903e0239 100644 --- a/chromium/third_party/blink/renderer/core/html/imports/link_import.h +++ b/chromium/third_party/blink/renderer/core/html/imports/link_import.h @@ -55,7 +55,7 @@ class LinkImport final : public LinkResource, public HTMLImportChildClient { void Process() final; LinkResourceType GetType() const final { return kImport; } bool HasLoaded() const final; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void OwnerInserted() final; void OwnerRemoved() final; diff --git a/chromium/third_party/blink/renderer/core/html/keywords.json5 b/chromium/third_party/blink/renderer/core/html/keywords.json5 index 411fc0bb7da..d1d3bae265f 100644 --- a/chromium/third_party/blink/renderer/core/html/keywords.json5 +++ b/chromium/third_party/blink/renderer/core/html/keywords.json5 @@ -90,5 +90,10 @@ "col", "rowgroup", "colgroup", + + // This mode corresponds to virtualkeyboardpolicy + // https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/master/VirtualKeyboardPolicy/explainer.md + "auto", + "manual", ], } diff --git a/chromium/third_party/blink/renderer/core/html/lazy_load_frame_observer.cc b/chromium/third_party/blink/renderer/core/html/lazy_load_frame_observer.cc index 24d34305f41..086f8f27796 100644 --- a/chromium/third_party/blink/renderer/core/html/lazy_load_frame_observer.cc +++ b/chromium/third_party/blink/renderer/core/html/lazy_load_frame_observer.cc @@ -382,7 +382,7 @@ void LazyLoadFrameObserver::RecordInitialDeferralAction( } } -void LazyLoadFrameObserver::Trace(Visitor* visitor) { +void LazyLoadFrameObserver::Trace(Visitor* visitor) const { visitor->Trace(element_); visitor->Trace(lazy_load_intersection_observer_); visitor->Trace(visibility_metrics_observer_); diff --git a/chromium/third_party/blink/renderer/core/html/lazy_load_frame_observer.h b/chromium/third_party/blink/renderer/core/html/lazy_load_frame_observer.h index d79cf667b74..bdc66dc4e7a 100644 --- a/chromium/third_party/blink/renderer/core/html/lazy_load_frame_observer.h +++ b/chromium/third_party/blink/renderer/core/html/lazy_load_frame_observer.h @@ -53,7 +53,7 @@ class LazyLoadFrameObserver final void LoadImmediately(); - void Trace(Visitor*); + void Trace(Visitor*) const; private: struct LazyLoadRequestInfo; diff --git a/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.cc b/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.cc index 67c244fa972..90f6f81c3db 100644 --- a/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.cc +++ b/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.cc @@ -335,7 +335,7 @@ bool LazyLoadImageObserver::IsFullyLoadableFirstKImageAndDecrementCount() { return false; } -void LazyLoadImageObserver::Trace(Visitor* visitor) { +void LazyLoadImageObserver::Trace(Visitor* visitor) const { visitor->Trace(lazy_load_intersection_observer_); visitor->Trace(visibility_metrics_observer_); } diff --git a/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.h b/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.h index 5b89cd988cd..5d236775714 100644 --- a/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.h +++ b/chromium/third_party/blink/renderer/core/html/lazy_load_image_observer.h @@ -49,7 +49,7 @@ class LazyLoadImageObserver final bool IsFullyLoadableFirstKImageAndDecrementCount(); - void Trace(Visitor*); + void Trace(Visitor*) const; private: void LoadIfNearViewport(const HeapVector<Member<IntersectionObserverEntry>>&); diff --git a/chromium/third_party/blink/renderer/core/html/link_rel_attribute.cc b/chromium/third_party/blink/renderer/core/html/link_rel_attribute.cc index c4d5fddf615..acdd00411e8 100644 --- a/chromium/third_party/blink/renderer/core/html/link_rel_attribute.cc +++ b/chromium/third_party/blink/renderer/core/html/link_rel_attribute.cc @@ -50,7 +50,8 @@ LinkRelAttribute::LinkRelAttribute() is_module_preload_(false), is_service_worker_(false), is_canonical_(false), - is_monetization_(false) {} + is_monetization_(false), + is_web_bundle_(false) {} LinkRelAttribute::LinkRelAttribute(const String& rel) : LinkRelAttribute() { if (rel.IsEmpty()) @@ -102,6 +103,8 @@ LinkRelAttribute::LinkRelAttribute(const String& rel) : LinkRelAttribute() { is_canonical_ = true; } else if (EqualIgnoringASCIICase(link_type, "monetization")) { is_monetization_ = true; + } else if (EqualIgnoringASCIICase(link_type, "webbundle")) { + is_web_bundle_ = true; } // Adding or removing a value here requires you to update // RelList::supportedTokens() diff --git a/chromium/third_party/blink/renderer/core/html/link_rel_attribute.h b/chromium/third_party/blink/renderer/core/html/link_rel_attribute.h index 309cbcb0078..37f6ebf2532 100644 --- a/chromium/third_party/blink/renderer/core/html/link_rel_attribute.h +++ b/chromium/third_party/blink/renderer/core/html/link_rel_attribute.h @@ -61,6 +61,7 @@ class CORE_EXPORT LinkRelAttribute { bool IsServiceWorker() const { return is_service_worker_; } bool IsCanonical() const { return is_canonical_; } bool IsMonetization() const { return is_monetization_; } + bool IsWebBundle() const { return is_web_bundle_; } private: mojom::blink::FaviconIconType icon_type_; @@ -78,6 +79,7 @@ class CORE_EXPORT LinkRelAttribute { bool is_service_worker_ : 1; bool is_canonical_ : 1; bool is_monetization_ : 1; + bool is_web_bundle_ : 1; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/link_rel_attribute_test.cc b/chromium/third_party/blink/renderer/core/html/link_rel_attribute_test.cc index c4a142ff0fa..5b6c3ba1ac4 100644 --- a/chromium/third_party/blink/renderer/core/html/link_rel_attribute_test.cc +++ b/chromium/third_party/blink/renderer/core/html/link_rel_attribute_test.cc @@ -43,7 +43,8 @@ static inline void TestLinkRelAttribute(const String& value, bool is_link_prerender, bool is_import = false, bool is_preconnect = false, - bool is_canonical = false) { + bool is_canonical = false, + bool is_web_bundle = false) { SCOPED_TRACE(value.Utf8()); LinkRelAttribute link_rel_attribute(value); ASSERT_EQ(is_style_sheet, link_rel_attribute.IsStyleSheet()); @@ -54,6 +55,7 @@ static inline void TestLinkRelAttribute(const String& value, ASSERT_EQ(is_import, link_rel_attribute.IsImport()); ASSERT_EQ(is_preconnect, link_rel_attribute.IsPreconnect()); ASSERT_EQ(is_canonical, link_rel_attribute.IsCanonical()); + ASSERT_EQ(is_web_bundle, link_rel_attribute.IsWebBundle()); } TEST(LinkRelAttributeTest, Constructor) { @@ -140,6 +142,12 @@ TEST(LinkRelAttributeTest, Constructor) { TestLinkRelAttribute("caNONiCAL", false, mojom::blink::FaviconIconType::kInvalid, false, false, false, false, false, true); + TestLinkRelAttribute("webbundle", false, + mojom::blink::FaviconIconType::kInvalid, false, false, + false, false, false, false, true); + TestLinkRelAttribute("wEbBundle", false, + mojom::blink::FaviconIconType::kInvalid, false, false, + false, false, false, false, true); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/link_resource.cc b/chromium/third_party/blink/renderer/core/html/link_resource.cc index c3b07b6bdaa..e7dd14f524e 100644 --- a/chromium/third_party/blink/renderer/core/html/link_resource.cc +++ b/chromium/third_party/blink/renderer/core/html/link_resource.cc @@ -47,7 +47,7 @@ bool LinkResource::ShouldLoadResource() const { } LocalFrame* LinkResource::LoadingFrame() const { - return owner_->GetDocument().MasterDocument().GetFrame(); + return owner_->GetDocument().TreeRootDocument().GetFrame(); } Document& LinkResource::GetDocument() { @@ -69,7 +69,7 @@ ExecutionContext* LinkResource::GetExecutionContext() { return owner_->GetExecutionContext(); } -void LinkResource::Trace(Visitor* visitor) { +void LinkResource::Trace(Visitor* visitor) const { visitor->Trace(owner_); } diff --git a/chromium/third_party/blink/renderer/core/html/link_resource.h b/chromium/third_party/blink/renderer/core/html/link_resource.h index c149a9dbee6..060124acb0e 100644 --- a/chromium/third_party/blink/renderer/core/html/link_resource.h +++ b/chromium/third_party/blink/renderer/core/html/link_resource.h @@ -59,7 +59,7 @@ class CORE_EXPORT LinkResource : public GarbageCollected<LinkResource> { virtual void OwnerInserted() {} virtual bool HasLoaded() const = 0; - virtual void Trace(Visitor*); + virtual void Trace(Visitor*) const; protected: void Load(); diff --git a/chromium/third_party/blink/renderer/core/html/link_style.cc b/chromium/third_party/blink/renderer/core/html/link_style.cc index ba9e774f8b2..5036ac1f0cb 100644 --- a/chromium/third_party/blink/renderer/core/html/link_style.cc +++ b/chromium/third_party/blink/renderer/core/html/link_style.cc @@ -202,6 +202,10 @@ void LinkStyle::RemovePendingSheet() { void LinkStyle::SetDisabledState(bool disabled) { LinkStyle::DisabledState old_disabled_state = disabled_state_; disabled_state_ = disabled ? kDisabled : kEnabledViaScript; + // Whenever the disabled attribute is removed, set the link element's + // explicitly enabled attribute to true. + if (!disabled) + explicitly_enabled_ = true; if (old_disabled_state == disabled_state_) return; @@ -231,8 +235,19 @@ void LinkStyle::SetDisabledState(bool disabled) { } if (sheet_) { - sheet_->setDisabled(disabled); - return; + // TODO(crbug.com/1087043): Remove this if() condition once the feature has + // landed and no compat issues are reported. + if (RuntimeEnabledFeatures::LinkDisabledNewSpecBehaviorEnabled( + GetExecutionContext())) { + DCHECK(disabled) + << "If link is being enabled, sheet_ shouldn't exist yet"; + ClearSheet(); + GetDocument().GetStyleEngine().SetNeedsActiveStyleUpdate( + owner_->GetTreeScope()); + return; + } else { + sheet_->setDisabled(disabled); + } } if (disabled_state_ == kEnabledViaScript && owner_->ShouldProcessStyle()) @@ -324,7 +339,7 @@ void LinkStyle::Process() { if (!GetDocument().GetSecurityOrigin()->CanDisplay(params.href)) return; if (!GetDocument().GetContentSecurityPolicy()->AllowImageFromSource( - params.href)) + params.href, params.href, RedirectStatus::kNoRedirect)) return; if (GetDocument().GetFrame()) GetDocument().GetFrame()->UpdateFaviconURL(); @@ -364,7 +379,7 @@ void LinkStyle::OwnerRemoved() { ClearSheet(); } -void LinkStyle::Trace(Visitor* visitor) { +void LinkStyle::Trace(Visitor* visitor) const { visitor->Trace(sheet_); LinkResource::Trace(visitor); ResourceClient::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/core/html/link_style.h b/chromium/third_party/blink/renderer/core/html/link_style.h index 5c56f2dd233..2b4df40e3fd 100644 --- a/chromium/third_party/blink/renderer/core/html/link_style.h +++ b/chromium/third_party/blink/renderer/core/html/link_style.h @@ -36,7 +36,7 @@ class LinkStyle final : public LinkResource, ResourceClient { void Process() override; void OwnerRemoved() override; bool HasLoaded() const override { return loaded_sheet_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void StartLoadingDynamicSheet(); void NotifyLoadedSheetAndAllCriticalSubresources( @@ -54,6 +54,8 @@ class LinkStyle final : public LinkResource, ResourceClient { } bool IsUnset() const { return disabled_state_ == kUnset; } + bool IsExplicitlyEnabled() const { return explicitly_enabled_; } + CSSStyleSheet* Sheet() const { return sheet_.Get(); } private: @@ -76,6 +78,7 @@ class LinkStyle final : public LinkResource, ResourceClient { DisabledState disabled_state_; PendingSheetType pending_sheet_type_; StyleEngineContext style_engine_context_; + bool explicitly_enabled_; bool loading_; bool fired_load_; bool loaded_sheet_; diff --git a/chromium/third_party/blink/renderer/core/html/link_web_bundle.cc b/chromium/third_party/blink/renderer/core/html/link_web_bundle.cc new file mode 100644 index 00000000000..630a103ca50 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/link_web_bundle.cc @@ -0,0 +1,49 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/html/link_web_bundle.h" + +namespace blink { + +LinkWebBundle::LinkWebBundle(HTMLLinkElement* owner) : LinkResource(owner) {} + +void LinkWebBundle::Process() { + // TODO(crbug.com/1082020): Implement this. +} + +LinkResource::LinkResourceType LinkWebBundle::GetType() const { + return kOther; +} + +bool LinkWebBundle::HasLoaded() const { + return false; +} + +void LinkWebBundle::OwnerRemoved() {} + +// static +KURL LinkWebBundle::ParseResourceUrl(const AtomicString& str) { + // The implementation is almost copy and paste from ParseExchangeURL() defined + // in services/data_decoder/web_bundle_parser.cc, replacing GURL with KURL. + + // TODO(hayato): Consider to support a relative URL. + KURL url(str); + if (!url.IsValid()) + return KURL(); + + // Exchange URL must not have a fragment or credentials. + if (url.HasFragmentIdentifier() || !url.User().IsEmpty() || + !url.Pass().IsEmpty()) + return KURL(); + + // For now, we allow only http: and https: schemes in Web Bundle URLs. + // TODO(crbug.com/966753): Revisit this once + // https://github.com/WICG/webpackage/issues/468 is resolved. + if (!url.ProtocolIsInHTTPFamily()) + return KURL(); + + return url; +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/link_web_bundle.h b/chromium/third_party/blink/renderer/core/html/link_web_bundle.h new file mode 100644 index 00000000000..9d786eddf40 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/link_web_bundle.h @@ -0,0 +1,37 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_LINK_WEB_BUNDLE_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_LINK_WEB_BUNDLE_H_ + +#include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/html/link_resource.h" +#include "third_party/blink/renderer/platform/weborigin/kurl.h" + +namespace blink { + +// LinkWebBundle is used in the Subresource loading with Web Bundles feature. +// See crbug.com/1082020 for details. +// A <link rel="webbundle" ...> element creates LinkWebBundle. +class CORE_EXPORT LinkWebBundle final : public LinkResource { + public: + explicit LinkWebBundle(HTMLLinkElement* owner); + ~LinkWebBundle() override = default; + + void Process() override; + LinkResourceType GetType() const override; + bool HasLoaded() const override; + void OwnerRemoved() override; + + // Parse the given |str| as a url. If |str| doesn't meet the criteria which + // WebBundles specification requires, this returns invalid empty KURL as an + // error. + // See + // https://wicg.github.io/webpackage/draft-yasskin-wpack-bundled-exchanges.html#name-parsing-the-index-section + static KURL ParseResourceUrl(const AtomicString& str); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_LINK_WEB_BUNDLE_H_ diff --git a/chromium/third_party/blink/renderer/core/html/link_web_bundle_test.cc b/chromium/third_party/blink/renderer/core/html/link_web_bundle_test.cc new file mode 100644 index 00000000000..2d22d4bd180 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/link_web_bundle_test.cc @@ -0,0 +1,85 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/html/link_web_bundle.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/dom/dom_token_list.h" +#include "third_party/blink/renderer/core/html/html_link_element.h" + +namespace blink { + +namespace { + +void TestParseResourceUrl(const AtomicString& url, bool is_valid) { + ASSERT_EQ(LinkWebBundle::ParseResourceUrl(url).IsValid(), is_valid); +} + +} // namespace + +TEST(LinkWebBundleTest, ParseResourceUrl) { + TestParseResourceUrl("https://test.example.com/", true); + TestParseResourceUrl("http://test.example.com/", true); + TestParseResourceUrl("https://user@test.example.com/", false); + TestParseResourceUrl("https://user:password@test.example.com/", false); + TestParseResourceUrl("https://test.example.com/#fragment", false); + TestParseResourceUrl("ftp://test.example.com/", false); + TestParseResourceUrl("file:///test.html", false); +} + +TEST(LinkWebBundleTest, ResourcesAttribute) { + auto* document = Document::CreateForTest(); + auto* link = + MakeGarbageCollected<HTMLLinkElement>(*document, CreateElementFlags()); + DOMTokenList* resources = link->resources(); + EXPECT_EQ(g_null_atom, resources->value()); + + link->setAttribute(html_names::kRelAttr, "webbundle"); + + // Valid url + link->setAttribute(html_names::kResourcesAttr, "https://test.example.com"); + EXPECT_EQ("https://test.example.com", resources->value()); + EXPECT_EQ(1u, link->ValidResourceUrls().size()); + EXPECT_TRUE( + link->ValidResourceUrls().Contains(KURL("https://test.example.com"))); + + // Invalid urls + link->setAttribute(html_names::kResourcesAttr, + "https://user:test.example.com"); + EXPECT_EQ("https://user:test.example.com", resources->value()); + EXPECT_TRUE(link->ValidResourceUrls().IsEmpty()); + + link->setAttribute(html_names::kResourcesAttr, + "https://:pass@test.example.com"); + EXPECT_TRUE(link->ValidResourceUrls().IsEmpty()); + + link->setAttribute(html_names::kResourcesAttr, + "https://test.example.com/#fragment"); + EXPECT_TRUE(link->ValidResourceUrls().IsEmpty()); + + // Spece-separated valid urls + link->setAttribute(html_names::kResourcesAttr, + "https://test1.example.com https://test2.example.com"); + EXPECT_EQ(2u, link->ValidResourceUrls().size()); + EXPECT_TRUE( + link->ValidResourceUrls().Contains(KURL("https://test1.example.com"))); + EXPECT_TRUE( + link->ValidResourceUrls().Contains(KURL("https://test2.example.com"))); + + // Space-separated valid and invalid urls + link->setAttribute(html_names::kResourcesAttr, + "https://test1.example.com https://user:test.example.com " + "https://test2.example.com"); + EXPECT_EQ( + "https://test1.example.com https://user:test.example.com " + "https://test2.example.com", + resources->value()); + EXPECT_EQ(2u, link->ValidResourceUrls().size()); + EXPECT_TRUE( + link->ValidResourceUrls().Contains(KURL("https://test1.example.com"))); + EXPECT_TRUE( + link->ValidResourceUrls().Contains(KURL("https://test2.example.com"))); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/media/autoplay_policy.cc b/chromium/third_party/blink/renderer/core/html/media/autoplay_policy.cc index f435e762221..b2a180e58a8 100644 --- a/chromium/third_party/blink/renderer/core/html/media/autoplay_policy.cc +++ b/chromium/third_party/blink/renderer/core/html/media/autoplay_policy.cc @@ -89,7 +89,8 @@ bool AutoplayPolicy::IsDocumentAllowedToPlay(const Document& document) { return false; bool feature_policy_enabled = - document.IsFeatureEnabled(mojom::blink::FeaturePolicyFeature::kAutoplay); + document.GetExecutionContext()->IsFeatureEnabled( + mojom::blink::FeaturePolicyFeature::kAutoplay); for (Frame* frame = document.GetFrame(); frame; frame = frame->Tree().Parent()) { @@ -343,6 +344,7 @@ void AutoplayPolicy::OnIntersectionChangedForAutoplay( if (ShouldAutoplay()) { element_->paused_ = false; + element_->SetShowPosterFlag(false); element_->ScheduleEvent(event_type_names::kPlay); element_->ScheduleNotifyPlaying(); @@ -361,11 +363,12 @@ void AutoplayPolicy::MaybeSetAutoplayInitiated() { autoplay_initiated_ = true; - const Document& document = element_->GetDocument(); bool feature_policy_enabled = - document.IsFeatureEnabled(mojom::blink::FeaturePolicyFeature::kAutoplay); + element_->GetExecutionContext() && + element_->GetExecutionContext()->IsFeatureEnabled( + mojom::blink::FeaturePolicyFeature::kAutoplay); - for (Frame* frame = document.GetFrame(); frame; + for (Frame* frame = element_->GetDocument().GetFrame(); frame; frame = frame->Tree().Parent()) { if (frame->HasStickyUserActivation() || frame->HadStickyUserActivationBeforeNavigation()) { @@ -385,7 +388,7 @@ bool AutoplayPolicy::ShouldAutoplay() { return element_->can_autoplay_ && element_->paused_ && element_->Autoplay(); } -void AutoplayPolicy::Trace(Visitor* visitor) { +void AutoplayPolicy::Trace(Visitor* visitor) const { visitor->Trace(element_); visitor->Trace(autoplay_intersection_observer_); visitor->Trace(autoplay_uma_helper_); diff --git a/chromium/third_party/blink/renderer/core/html/media/autoplay_policy.h b/chromium/third_party/blink/renderer/core/html/media/autoplay_policy.h index 683f8e176d7..f28bf5b8bba 100644 --- a/chromium/third_party/blink/renderer/core/html/media/autoplay_policy.h +++ b/chromium/third_party/blink/renderer/core/html/media/autoplay_policy.h @@ -111,7 +111,7 @@ class CORE_EXPORT AutoplayPolicy final // avoid false positives. void EnsureAutoplayInitiatedSet(); - virtual void Trace(Visitor*); + virtual void Trace(Visitor*) const; private: friend class AutoplayUmaHelper; diff --git a/chromium/third_party/blink/renderer/core/html/media/autoplay_uma_helper.cc b/chromium/third_party/blink/renderer/core/html/media/autoplay_uma_helper.cc index 44d1e8e0e39..78163e2cc42 100644 --- a/chromium/third_party/blink/renderer/core/html/media/autoplay_uma_helper.cc +++ b/chromium/third_party/blink/renderer/core/html/media/autoplay_uma_helper.cc @@ -297,7 +297,7 @@ bool AutoplayUmaHelper::ShouldListenToContextDestroyed() const { muted_video_offscreen_duration_intersection_observer_; } -void AutoplayUmaHelper::Trace(Visitor* visitor) { +void AutoplayUmaHelper::Trace(Visitor* visitor) const { NativeEventListener::Trace(visitor); ExecutionContextLifecycleObserver::Trace(visitor); visitor->Trace(element_); diff --git a/chromium/third_party/blink/renderer/core/html/media/autoplay_uma_helper.h b/chromium/third_party/blink/renderer/core/html/media/autoplay_uma_helper.h index 80c709bc43b..fddf6ab258c 100644 --- a/chromium/third_party/blink/renderer/core/html/media/autoplay_uma_helper.h +++ b/chromium/third_party/blink/renderer/core/html/media/autoplay_uma_helper.h @@ -59,7 +59,7 @@ class CORE_EXPORT AutoplayUmaHelper : public NativeEventListener, void Invoke(ExecutionContext*, Event*) override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: friend class MockAutoplayUmaHelper; diff --git a/chromium/third_party/blink/renderer/core/html/media/html_media_element.cc b/chromium/third_party/blink/renderer/core/html/media/html_media_element.cc index 2cce1250ded..1bcde9e6393 100644 --- a/chromium/third_party/blink/renderer/core/html/media/html_media_element.cc +++ b/chromium/third_party/blink/renderer/core/html/media/html_media_element.cc @@ -259,7 +259,7 @@ class AudioSourceProviderClientLockScope { STACK_ALLOCATED(); public: - AudioSourceProviderClientLockScope(HTMLMediaElement& element) + explicit AudioSourceProviderClientLockScope(HTMLMediaElement& element) : client_(element.AudioSourceNode()) { if (client_) client_->lock(); @@ -384,6 +384,11 @@ bool IsValidPlaybackRate(double rate) { return rate == 0.0 || (rate >= kMinRate && rate <= kMaxRate); } +std::ostream& operator<<(std::ostream& stream, + HTMLMediaElement const& media_element) { + return stream << static_cast<void const*>(&media_element); +} + } // anonymous namespace MIMETypeRegistry::SupportsType HTMLMediaElement::GetSupportsType( @@ -492,7 +497,6 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tag_name, this, &HTMLMediaElement::DeferredLoadTimerFired), cc_layer_(nullptr), - display_mode_(kUnknown), official_playback_position_(0), official_playback_position_needs_update_(true), fragment_end_time_(std::numeric_limits<double>::quiet_NaN()), @@ -505,6 +509,7 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tag_name, paused_(true), seeking_(false), paused_by_context_paused_(false), + show_poster_flag_(true), sent_stalled_event_(false), ignore_preload_none_(false), text_tracks_visible_(false), @@ -520,7 +525,7 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tag_name, media_controls_(nullptr), controls_list_(MakeGarbageCollected<HTMLMediaElementControlsList>(this)), lazy_load_intersection_observer_(nullptr) { - DVLOG(1) << "HTMLMediaElement(" << (void*)this << ")"; + DVLOG(1) << "HTMLMediaElement(" << *this << ")"; LocalFrame* frame = document.GetFrame(); if (frame) { @@ -535,7 +540,7 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tag_name, } HTMLMediaElement::~HTMLMediaElement() { - DVLOG(1) << "~HTMLMediaElement(" << (void*)this << ")"; + DVLOG(1) << "~HTMLMediaElement(" << *this << ")"; } void HTMLMediaElement::Dispose() { @@ -550,7 +555,7 @@ void HTMLMediaElement::Dispose() { } void HTMLMediaElement::DidMoveToNewDocument(Document& old_document) { - DVLOG(3) << "didMoveToNewDocument(" << (void*)this << ")"; + DVLOG(3) << "didMoveToNewDocument(" << *this << ")"; load_timer_.MoveToNewTaskRunner( GetDocument().GetTaskRunner(TaskType::kInternalMedia)); @@ -617,7 +622,7 @@ void HTMLMediaElement::ParseAttribute( const AttributeModificationParams& params) { const QualifiedName& name = params.name; if (name == html_names::kSrcAttr) { - DVLOG(2) << "parseAttribute(" << (void*)this + DVLOG(2) << "parseAttribute(" << *this << ", kSrcAttr, old=" << params.old_value << ", new=" << params.new_value << ")"; // Trigger a reload, as long as the 'src' attribute is present. @@ -697,7 +702,7 @@ LayoutObject* HTMLMediaElement::CreateLayoutObject(const ComputedStyle&, Node::InsertionNotificationRequest HTMLMediaElement::InsertedInto( ContainerNode& insertion_point) { - DVLOG(3) << "insertedInto(" << (void*)this << ", " << insertion_point << ")"; + DVLOG(3) << "insertedInto(" << *this << ", " << insertion_point << ")"; HTMLElement::InsertedInto(insertion_point); if (insertion_point.isConnected()) { @@ -717,7 +722,7 @@ void HTMLMediaElement::DidNotifySubtreeInsertionsToDocument() { } void HTMLMediaElement::RemovedFrom(ContainerNode& insertion_point) { - DVLOG(3) << "removedFrom(" << (void*)this << ", " << insertion_point << ")"; + DVLOG(3) << "removedFrom(" << *this << ", " << insertion_point << ")"; removed_from_document_timer_.StartOneShot(base::TimeDelta(), FROM_HERE); @@ -727,17 +732,16 @@ void HTMLMediaElement::RemovedFrom(ContainerNode& insertion_point) { void HTMLMediaElement::AttachLayoutTree(AttachContext& context) { HTMLElement::AttachLayoutTree(context); - if (GetLayoutObject()) - GetLayoutObject()->UpdateFromElement(); + UpdateLayoutObject(); } void HTMLMediaElement::DidRecalcStyle(const StyleRecalcChange change) { - if (!change.ReattachLayoutTree() && GetLayoutObject()) - GetLayoutObject()->UpdateFromElement(); + if (!change.ReattachLayoutTree()) + UpdateLayoutObject(); } void HTMLMediaElement::ScheduleTextTrackResourceLoad() { - DVLOG(3) << "scheduleTextTrackResourceLoad(" << (void*)this << ")"; + DVLOG(3) << "scheduleTextTrackResourceLoad(" << *this << ")"; pending_action_flags_ |= kLoadTextTrackResource; @@ -789,7 +793,7 @@ void HTMLMediaElement::SetSrc(const AtomicString& url) { } void HTMLMediaElement::SetSrcObject(MediaStreamDescriptor* src_object) { - DVLOG(1) << "setSrcObject(" << (void*)this << ")"; + DVLOG(1) << "setSrcObject(" << *this << ")"; src_object_ = src_object; InvokeLoadAlgorithm(); } @@ -816,14 +820,14 @@ String HTMLMediaElement::canPlayType(const String& mime_type) const { break; } - DVLOG(2) << "canPlayType(" << (void*)this << ", " << mime_type << ") -> " + DVLOG(2) << "canPlayType(" << *this << ", " << mime_type << ") -> " << can_play; return can_play; } void HTMLMediaElement::load() { - DVLOG(1) << "load(" << (void*)this << ")"; + DVLOG(1) << "load(" << *this << ")"; autoplay_policy_->TryUnlockingUserGesture(); @@ -831,12 +835,14 @@ void HTMLMediaElement::load() { InvokeLoadAlgorithm(); } +// Implements the "media element load algorithm" as defined by +// https://html.spec.whatwg.org/multipage/media.html#media-element-load-algorithm // TODO(srirama.m): Currently ignore_preload_none_ is reset before calling // invokeLoadAlgorithm() in all places except load(). Move it inside here // once microtask is implemented for "Await a stable state" step // in resource selection algorithm. void HTMLMediaElement::InvokeLoadAlgorithm() { - DVLOG(3) << "invokeLoadAlgorithm(" << (void*)this << ")"; + DVLOG(3) << "invokeLoadAlgorithm(" << *this << ")"; // Perform the cleanup required for the resource load algorithm to run. StopPeriodicTimers(); @@ -847,7 +853,6 @@ void HTMLMediaElement::InvokeLoadAlgorithm() { pending_action_flags_ &= ~kLoadMediaResource; sent_stalled_event_ = false; have_fired_loaded_data_ = false; - display_mode_ = kUnknown; autoplay_policy_->StopAutoplayMutedWhenVisible(); @@ -967,13 +972,13 @@ void HTMLMediaElement::InvokeLoadAlgorithm() { } void HTMLMediaElement::InvokeResourceSelectionAlgorithm() { - DVLOG(3) << "invokeResourceSelectionAlgorithm(" << (void*)this << ")"; + DVLOG(3) << "invokeResourceSelectionAlgorithm(" << *this << ")"; // The resource selection algorithm // 1 - Set the networkState to NETWORK_NO_SOURCE SetNetworkState(kNetworkNoSource); // 2 - Set the element's show poster flag to true - // TODO(srirama.m): Introduce show poster flag and update it as per spec + SetShowPosterFlag(true); played_time_ranges_ = MakeGarbageCollected<TimeRanges>(); @@ -1013,7 +1018,7 @@ void HTMLMediaElement::LoadInternal() { } void HTMLMediaElement::SelectMediaResource() { - DVLOG(3) << "selectMediaResource(" << (void*)this << ")"; + DVLOG(3) << "selectMediaResource(" << *this << ")"; enum Mode { kObject, kAttribute, kChildren, kNothing }; Mode mode = kNothing; @@ -1053,9 +1058,9 @@ void HTMLMediaElement::SelectMediaResource() { UseCounter::Count(GetDocument(), WebFeature::kHTMLMediaElementEmptyLoadWithFutureData); } - UpdateDisplayState(); + UpdateLayoutObject(); - DVLOG(3) << "selectMediaResource(" << (void*)this << "), nothing to load"; + DVLOG(3) << "selectMediaResource(" << *this << "), nothing to load"; return; } @@ -1070,18 +1075,17 @@ void HTMLMediaElement::SelectMediaResource() { switch (mode) { case kObject: LoadSourceFromObject(); - DVLOG(3) << "selectMediaResource(" << (void*)this + DVLOG(3) << "selectMediaResource(" << *this << ", using 'srcObject' attribute"; break; case kAttribute: LoadSourceFromAttribute(); - DVLOG(3) << "selectMediaResource(" << (void*)this + DVLOG(3) << "selectMediaResource(" << *this << "), using 'src' attribute url"; break; case kChildren: LoadNextSourceChild(); - DVLOG(3) << "selectMediaResource(" << (void*)this - << "), using source element"; + DVLOG(3) << "selectMediaResource(" << *this << "), using source element"; break; default: NOTREACHED(); @@ -1104,7 +1108,7 @@ void HTMLMediaElement::LoadSourceFromAttribute() { // If the src attribute's value is the empty string ... jump down to the // failed step below if (src_value.IsEmpty()) { - DVLOG(3) << "LoadSourceFromAttribute(" << (void*)this << "), empty 'src'"; + DVLOG(3) << "LoadSourceFromAttribute(" << *this << "), empty 'src'"; MediaLoadingFailed(WebMediaPlayer::kNetworkStateFormatError, BuildElementErrorMessage("Empty src attribute")); return; @@ -1145,8 +1149,8 @@ void HTMLMediaElement::LoadResource(const WebMediaPlayerSource& source, if (source.IsURL()) { url = source.GetAsURL(); DCHECK(IsSafeToLoadURL(url, kComplain)); - DVLOG(3) << "loadResource(" << (void*)this << ", " - << UrlForLoggingMedia(url) << ", " << content_type << ")"; + DVLOG(3) << "loadResource(" << *this << ", " << UrlForLoggingMedia(url) + << ", " << content_type << ")"; } LocalFrame* frame = GetDocument().GetFrame(); @@ -1176,15 +1180,11 @@ void HTMLMediaElement::LoadResource(const WebMediaPlayerSource& source, // until proved otherwise. RemotePlaybackCompatibilityChanged(current_src_, false); - DVLOG(3) << "loadResource(" << (void*)this << ") - current_src_ -> " + DVLOG(3) << "loadResource(" << *this << ") - current_src_ -> " << UrlForLoggingMedia(current_src_); StartProgressEventTimer(); - // Reset display mode to force a recalculation of what to show because we are - // resetting the player. - SetDisplayMode(kUnknown); - SetPlayerPreload(); DCHECK(!media_source_); @@ -1222,7 +1222,7 @@ void HTMLMediaElement::LoadResource(const WebMediaPlayerSource& source, // including MediaSource blob URLs. if (!source.IsMediaStream() && !url.ProtocolIs("blob") && EffectivePreloadType() == WebMediaPlayer::kPreloadNone) { - DVLOG(3) << "loadResource(" << (void*)this + DVLOG(3) << "loadResource(" << *this << ") : Delaying load because preload == 'none'"; DeferLoad(); } else { @@ -1235,13 +1235,6 @@ void HTMLMediaElement::LoadResource(const WebMediaPlayerSource& source, ? "Unable to load URL due to content type" : "Unable to attach MediaSource")); } - - // If there is no poster to display, allow the media engine to render video - // frames as soon as they are available. - UpdateDisplayState(); - - if (GetLayoutObject()) - GetLayoutObject()->UpdateFromElement(); } void HTMLMediaElement::StartPlayerLoad() { @@ -1324,6 +1317,8 @@ void HTMLMediaElement::StartPlayerLoad() { web_media_player_->SetLatencyHint(latencyHint()); + web_media_player_->SetPreservesPitch(preservesPitch()); + OnLoadStarted(); } @@ -1482,8 +1477,8 @@ void HTMLMediaElement::DisableAutomaticTextTrackSelection() { bool HTMLMediaElement::IsSafeToLoadURL(const KURL& url, InvalidURLAction action_if_invalid) { if (!url.IsValid()) { - DVLOG(3) << "isSafeToLoadURL(" << (void*)this << ", " - << UrlForLoggingMedia(url) << ") -> FALSE because url is invalid"; + DVLOG(3) << "isSafeToLoadURL(" << *this << ", " << UrlForLoggingMedia(url) + << ") -> FALSE because url is invalid"; return false; } @@ -1495,15 +1490,13 @@ bool HTMLMediaElement::IsSafeToLoadURL(const KURL& url, mojom::ConsoleMessageLevel::kError, "Not allowed to load local resource: " + url.ElidedString())); } - DVLOG(3) << "isSafeToLoadURL(" << (void*)this << ", " - << UrlForLoggingMedia(url) + DVLOG(3) << "isSafeToLoadURL(" << *this << ", " << UrlForLoggingMedia(url) << ") -> FALSE rejected by SecurityOrigin"; return false; } if (!GetDocument().GetContentSecurityPolicy()->AllowMediaFromSource(url)) { - DVLOG(3) << "isSafeToLoadURL(" << (void*)this << ", " - << UrlForLoggingMedia(url) + DVLOG(3) << "isSafeToLoadURL(" << *this << ", " << UrlForLoggingMedia(url) << ") -> rejected by Content Security Policy"; return false; } @@ -1533,27 +1526,27 @@ void HTMLMediaElement::StartProgressEventTimer() { } void HTMLMediaElement::WaitForSourceChange() { - DVLOG(3) << "waitForSourceChange(" << (void*)this << ")"; + DVLOG(3) << "waitForSourceChange(" << *this << ")"; StopPeriodicTimers(); load_state_ = kWaitingForSource; - // 6.17 - Waiting: Set the element's networkState attribute to the + // 17 - Waiting: Set the element's networkState attribute to the // NETWORK_NO_SOURCE value SetNetworkState(kNetworkNoSource); - // 6.18 - Set the element's delaying-the-load-event flag to false. This stops + // 18 - Set the element's show poster flag to true. + SetShowPosterFlag(true); + + // 19 - Set the element's delaying-the-load-event flag to false. This stops // delaying the load event. SetShouldDelayLoadEvent(false); - UpdateDisplayState(); - - if (GetLayoutObject()) - GetLayoutObject()->UpdateFromElement(); + UpdateLayoutObject(); } void HTMLMediaElement::NoneSupported(const String& input_message) { - DVLOG(3) << "NoneSupported(" << (void*)this << ", message='" << input_message + DVLOG(3) << "NoneSupported(" << *this << ", message='" << input_message << "')"; StopPeriodicTimers(); @@ -1579,7 +1572,7 @@ void HTMLMediaElement::NoneSupported(const String& input_message) { SetNetworkState(kNetworkNoSource); // 4 - Set the element's show poster flag to true. - UpdateDisplayState(); + SetShowPosterFlag(true); // 5 - Fire a simple event named error at the media element. ScheduleEvent(event_type_names::kError); @@ -1593,13 +1586,12 @@ void HTMLMediaElement::NoneSupported(const String& input_message) { // delaying the load event. SetShouldDelayLoadEvent(false); - if (GetLayoutObject()) - GetLayoutObject()->UpdateFromElement(); + UpdateLayoutObject(); } void HTMLMediaElement::MediaEngineError(MediaError* err) { DCHECK_GE(ready_state_, kHaveMetadata); - DVLOG(3) << "mediaEngineError(" << (void*)this << ", " + DVLOG(3) << "mediaEngineError(" << *this << ", " << static_cast<int>(err->code()) << ")"; // 1 - The user agent should cancel the fetching process. @@ -1625,7 +1617,7 @@ void HTMLMediaElement::MediaEngineError(MediaError* err) { } void HTMLMediaElement::CancelPendingEventsAndCallbacks() { - DVLOG(3) << "cancelPendingEventsAndCallbacks(" << (void*)this << ")"; + DVLOG(3) << "cancelPendingEventsAndCallbacks(" << *this << ")"; async_event_queue_->CancelAllEvents(); for (HTMLSourceElement* source = @@ -1640,8 +1632,8 @@ void HTMLMediaElement::NetworkStateChanged() { void HTMLMediaElement::MediaLoadingFailed(WebMediaPlayer::NetworkState error, const String& input_message) { - DVLOG(3) << "MediaLoadingFailed(" << (void*)this << ", " - << static_cast<int>(error) << ", message='" << input_message << "')"; + DVLOG(3) << "MediaLoadingFailed(" << *this << ", " << int{error} + << ", message='" << input_message << "')"; bool should_be_opaque = MediaShouldBeOpaque(); if (should_be_opaque) @@ -1662,7 +1654,7 @@ void HTMLMediaElement::MediaLoadingFailed(WebMediaPlayer::NetworkState error, if (current_source_node_) { current_source_node_->ScheduleErrorEvent(); } else { - DVLOG(3) << "mediaLoadingFailed(" << (void*)this + DVLOG(3) << "mediaLoadingFailed(" << *this << ") - error event not sent, <source> was removed"; } @@ -1675,11 +1667,11 @@ void HTMLMediaElement::MediaLoadingFailed(WebMediaPlayer::NetworkState error, ForgetResourceSpecificTracks(); if (HavePotentialSourceChild()) { - DVLOG(3) << "mediaLoadingFailed(" << (void*)this + DVLOG(3) << "mediaLoadingFailed(" << *this << ") - scheduling next <source>"; ScheduleNextSourceChild(); } else { - DVLOG(3) << "mediaLoadingFailed(" << (void*)this + DVLOG(3) << "mediaLoadingFailed(" << *this << ") - no more <source> elements, waiting"; WaitForSourceChange(); } @@ -1708,13 +1700,12 @@ void HTMLMediaElement::MediaLoadingFailed(WebMediaPlayer::NetworkState error, } } - UpdateDisplayState(); + UpdateLayoutObject(); } void HTMLMediaElement::SetNetworkState(WebMediaPlayer::NetworkState state) { - DVLOG(3) << "setNetworkState(" << (void*)this << ", " - << static_cast<int>(state) << ") - current state is " - << static_cast<int>(network_state_); + DVLOG(3) << "setNetworkState(" << *this << ", " << static_cast<int>(state) + << ") - current state is " << int{network_state_}; if (state == WebMediaPlayer::kNetworkStateEmpty) { // Just update the cached state and leave, we can't do anything. @@ -1762,7 +1753,7 @@ void HTMLMediaElement::ChangeNetworkStateFromLoadingToIdle() { SetNetworkState(kNetworkIdle); } else { // TODO(dalecurtis): Replace c-style casts in follow up patch. - DVLOG(1) << __func__ << "(" << (void*)this + DVLOG(1) << __func__ << "(" << *this << ") - Deferred network state change to idle for opaque media"; } } @@ -1772,8 +1763,8 @@ void HTMLMediaElement::ReadyStateChanged() { } void HTMLMediaElement::SetReadyState(ReadyState state) { - DVLOG(3) << "setReadyState(" << (void*)this << ", " << static_cast<int>(state) - << ") - current state is " << static_cast<int>(ready_state_); + DVLOG(3) << "setReadyState(" << *this << ", " << int{state} + << ") - current state is " << int{ready_state_}; // Set "wasPotentiallyPlaying" BEFORE updating ready_state_, // potentiallyPlaying() uses it @@ -1818,6 +1809,7 @@ void HTMLMediaElement::SetReadyState(ReadyState state) { frame, HasVideo() ? mojom::blink::RequestContextType::VIDEO : mojom::blink::RequestContextType::AUDIO, + current_src_, // Strictly speaking, this check is an approximation; a request could // have have redirected back to its original URL, for example. // However, the redirect status is only used to prevent leaking @@ -1903,12 +1895,9 @@ void HTMLMediaElement::SetReadyState(ReadyState state) { jumped = true; } - if (GetLayoutObject()) - GetLayoutObject()->UpdateFromElement(); + UpdateLayoutObject(); } - bool should_update_display_state = false; - bool is_potentially_playing = PotentiallyPlaying(); if (ready_state_ >= kHaveCurrentData && old_state < kHaveCurrentData && !have_fired_loaded_data_) { @@ -1918,7 +1907,6 @@ void HTMLMediaElement::SetReadyState(ReadyState state) { SetOfficialPlaybackPosition(CurrentPlaybackPosition()); have_fired_loaded_data_ = true; - should_update_display_state = true; ScheduleEvent(event_type_names::kLoadeddata); SetShouldDelayLoadEvent(false); @@ -1930,7 +1918,6 @@ void HTMLMediaElement::SetReadyState(ReadyState state) { ScheduleEvent(event_type_names::kCanplay); if (is_potentially_playing) ScheduleNotifyPlaying(); - should_update_display_state = true; } if (ready_state_ == kHaveEnoughData && old_state < kHaveEnoughData && @@ -1943,23 +1930,35 @@ void HTMLMediaElement::SetReadyState(ReadyState state) { if (autoplay_policy_->RequestAutoplayByAttribute()) { paused_ = false; + SetShowPosterFlag(false); ScheduleEvent(event_type_names::kPlay); ScheduleNotifyPlaying(); can_autoplay_ = false; } ScheduleEvent(event_type_names::kCanplaythrough); - - should_update_display_state = true; } - if (should_update_display_state) - UpdateDisplayState(); - UpdatePlayState(); GetCueTimeline().UpdateActiveCues(currentTime()); } +void HTMLMediaElement::SetShowPosterFlag(bool value) { + DVLOG(3) << "SetShowPosterFlag(" << *this << ", " << value + << ") - current state is " << show_poster_flag_; + + if (value == show_poster_flag_) + return; + + show_poster_flag_ = value; + UpdateLayoutObject(); +} + +void HTMLMediaElement::UpdateLayoutObject() { + if (GetLayoutObject()) + GetLayoutObject()->UpdateFromElement(); +} + void HTMLMediaElement::ProgressEventTimerFired(TimerBase*) { if (network_state_ != kNetworkLoading) return; @@ -1977,8 +1976,7 @@ void HTMLMediaElement::ProgressEventTimerFired(TimerBase*) { ScheduleEvent(event_type_names::kProgress); previous_progress_time_ = base::ElapsedTimer(); sent_stalled_event_ = false; - if (GetLayoutObject()) - GetLayoutObject()->UpdateFromElement(); + UpdateLayoutObject(); } else if (!media_source_ && previous_progress_time_->Elapsed() > kStalledNotificationInterval && @@ -1996,8 +1994,7 @@ void HTMLMediaElement::ProgressEventTimerFired(TimerBase*) { } void HTMLMediaElement::AddPlayedRange(double start, double end) { - DVLOG(3) << "addPlayedRange(" << (void*)this << ", " << start << ", " << end - << ")"; + DVLOG(3) << "addPlayedRange(" << *this << ", " << start << ", " << end << ")"; if (!played_time_ranges_) played_time_ranges_ = MakeGarbageCollected<TimeRanges>(); played_time_ranges_->Add(start, end); @@ -2057,13 +2054,16 @@ bool HTMLMediaElement::SupportsLoop() const { } void HTMLMediaElement::SetIgnorePreloadNone() { - DVLOG(3) << "setIgnorePreloadNone(" << (void*)this << ")"; + DVLOG(3) << "setIgnorePreloadNone(" << *this << ")"; ignore_preload_none_ = true; SetPlayerPreload(); } void HTMLMediaElement::Seek(double time) { - DVLOG(2) << "seek(" << (void*)this << ", " << time << ")"; + DVLOG(2) << "seek(" << *this << ", " << time << ")"; + + // 1 - Set the media element's show poster flag to false. + SetShowPosterFlag(false); // 2 - If the media element's readyState is HAVE_NOTHING, abort these steps. // FIXME: remove web_media_player_ check once we figure out how @@ -2105,7 +2105,7 @@ void HTMLMediaElement::Seek(double time) { // will never be cleared and we will never fire a 'seeked' event. double media_time = GetWebMediaPlayer()->MediaTimeForTimeValue(time); if (time != media_time) { - DVLOG(3) << "seek(" << (void*)this << ", " << time + DVLOG(3) << "seek(" << *this << ", " << time << ") - media timeline equivalent is " << media_time; time = media_time; } @@ -2134,13 +2134,14 @@ void HTMLMediaElement::Seek(double time) { // 11 - Set the current playback position to the given new playback position. GetWebMediaPlayer()->Seek(time); + GetWebMediaPlayer()->OnTimeUpdate(); // 14-17 are handled, if necessary, when the engine signals a readystate // change or otherwise satisfies seek completion and signals a time change. } void HTMLMediaElement::FinishSeek() { - DVLOG(3) << "finishSeek(" << (void*)this << ")"; + DVLOG(3) << "finishSeek(" << *this << ")"; // 14 - Set the seeking IDL attribute to false. seeking_ = false; @@ -2154,8 +2155,6 @@ void HTMLMediaElement::FinishSeek() { // 17 - Queue a task to fire a simple event named seeked at the element. ScheduleEvent(event_type_names::kSeeked); - - SetDisplayMode(kVideo); } HTMLMediaElement::ReadyState HTMLMediaElement::getReadyState() const { @@ -2244,7 +2243,7 @@ void HTMLMediaElement::SetOfficialPlaybackPosition(double position) const { std::isnan(duration()) ? position : std::min(duration(), position); if (official_playback_position_ != position) { - DVLOG(3) << "setOfficialPlaybackPosition(" << (void*)this + DVLOG(3) << "setOfficialPlaybackPosition(" << *this << ") position:" << position << " truncated to duration:" << official_playback_position_; } @@ -2269,7 +2268,7 @@ double HTMLMediaElement::currentTime() const { return default_playback_start_position_; if (seeking_) { - DVLOG(3) << "currentTime(" << (void*)this << ") - seeking, returning " + DVLOG(3) << "currentTime(" << *this << ") - seeking, returning " << last_seek_time_; return last_seek_time_; } @@ -2321,7 +2320,7 @@ double HTMLMediaElement::playbackRate() const { void HTMLMediaElement::setPlaybackRate(double rate, ExceptionState& exception_state) { - DVLOG(3) << "setPlaybackRate(" << (void*)this << ", " << rate << ")"; + DVLOG(3) << "setPlaybackRate(" << *this << ", " << rate << ")"; if (GetLoadType() == WebMediaPlayer::kLoadTypeMediaStream) return; @@ -2357,8 +2356,13 @@ void HTMLMediaElement::UpdatePlaybackRate() { // FIXME: remove web_media_player_ check once we figure out how // web_media_player_ is going out of sync with readystate. // web_media_player_ is cleared but readystate is not set to kHaveNothing. - if (web_media_player_ && PotentiallyPlaying()) - GetWebMediaPlayer()->SetRate(playbackRate()); + if (!web_media_player_) + return; + + if (PotentiallyPlaying()) + web_media_player_->SetRate(playbackRate()); + + web_media_player_->OnTimeUpdate(); } bool HTMLMediaElement::ended() const { @@ -2379,7 +2383,7 @@ String HTMLMediaElement::preload() const { } void HTMLMediaElement::setPreload(const AtomicString& preload) { - DVLOG(2) << "setPreload(" << (void*)this << ", " << preload << ")"; + DVLOG(2) << "setPreload(" << *this << ", " << preload << ")"; if (GetLoadType() == WebMediaPlayer::kLoadTypeMediaStream) return; setAttribute(html_names::kPreloadAttr, preload); @@ -2475,7 +2479,7 @@ ScriptPromise HTMLMediaElement::playForBindings(ScriptState* script_state) { } base::Optional<DOMExceptionCode> HTMLMediaElement::Play() { - DVLOG(2) << "play(" << (void*)this << ")"; + DVLOG(2) << "play(" << *this << ")"; base::Optional<DOMExceptionCode> exception_code = autoplay_policy_->RequestPlay(); @@ -2503,7 +2507,7 @@ base::Optional<DOMExceptionCode> HTMLMediaElement::Play() { } void HTMLMediaElement::PlayInternal() { - DVLOG(3) << "playInternal(" << (void*)this << ")"; + DVLOG(3) << "playInternal(" << *this << ")"; // Playback aborts any lazy loading. if (lazy_load_intersection_observer_) { @@ -2523,6 +2527,7 @@ void HTMLMediaElement::PlayInternal() { if (paused_) { paused_ = false; + SetShowPosterFlag(false); ScheduleEvent(event_type_names::kPlay); if (ready_state_ <= kHaveCurrentData) @@ -2542,14 +2547,14 @@ void HTMLMediaElement::PlayInternal() { } void HTMLMediaElement::pause() { - DVLOG(2) << "pause(" << (void*)this << ")"; + DVLOG(2) << "pause(" << *this << ")"; autoplay_policy_->StopAutoplayMutedWhenVisible(); PauseInternal(); } void HTMLMediaElement::PauseInternal() { - DVLOG(3) << "pauseInternal(" << (void*)this << ")"; + DVLOG(3) << "pauseInternal(" << *this << ")"; if (network_state_ == kNetworkEmpty) InvokeResourceSelectionAlgorithm(); @@ -2573,6 +2578,17 @@ void HTMLMediaElement::PauseInternal() { UpdatePlayState(); } +bool HTMLMediaElement::preservesPitch() const { + return preserves_pitch_; +} + +void HTMLMediaElement::setPreservesPitch(bool preserves_pitch) { + preserves_pitch_ = preserves_pitch; + + if (GetWebMediaPlayer()) + GetWebMediaPlayer()->SetPreservesPitch(preserves_pitch_); +} + double HTMLMediaElement::latencyHint() const { // Parse error will fallback to std::numeric_limits<double>::quiet_NaN() double seconds = GetFloatingPointAttribute(html_names::kLatencyhintAttr); @@ -2611,7 +2627,7 @@ bool HTMLMediaElement::Loop() const { } void HTMLMediaElement::SetLoop(bool b) { - DVLOG(3) << "setLoop(" << (void*)this << ", " << BoolString(b) << ")"; + DVLOG(3) << "setLoop(" << *this << ", " << BoolString(b) << ")"; SetBooleanAttribute(html_names::kLoopAttr, b); } @@ -2636,8 +2652,8 @@ bool HTMLMediaElement::ShouldShowControls( return true; } - LocalFrame* frame = GetDocument().GetFrame(); - if (frame && !GetDocument().CanExecuteScripts(kNotAboutToExecuteScript)) { + ExecutionContext* context = GetExecutionContext(); + if (context && !context->CanExecuteScripts(kNotAboutToExecuteScript)) { if (record_metrics == RecordMetricsBehavior::kDoRecord) RecordShowControlsUsage(this, MediaControlsShow::kNoScript); return true; @@ -2661,7 +2677,7 @@ double HTMLMediaElement::volume() const { } void HTMLMediaElement::setVolume(double vol, ExceptionState& exception_state) { - DVLOG(2) << "setVolume(" << (void*)this << ", " << vol << ")"; + DVLOG(2) << "setVolume(" << *this << ", " << vol << ")"; if (volume_ == vol) return; @@ -2707,7 +2723,7 @@ bool HTMLMediaElement::muted() const { } void HTMLMediaElement::setMuted(bool muted) { - DVLOG(2) << "setMuted(" << (void*)this << ", " << BoolString(muted) << ")"; + DVLOG(2) << "setMuted(" << *this << ", " << BoolString(muted) << ")"; if (muted_ == muted) return; @@ -2778,6 +2794,9 @@ void HTMLMediaElement::PlaybackProgressTimerFired(TimerBase*) { } void HTMLMediaElement::ScheduleTimeupdateEvent(bool periodic_event) { + if (web_media_player_) + web_media_player_->OnTimeUpdate(); + // Per spec, consult current playback position to check for changing time. double media_time = CurrentPlaybackPosition(); bool media_time_has_progressed = @@ -2812,7 +2831,7 @@ AudioTrackList& HTMLMediaElement::audioTracks() { } void HTMLMediaElement::AudioTrackChanged(AudioTrack* track) { - DVLOG(3) << "audioTrackChanged(" << (void*)this + DVLOG(3) << "audioTrackChanged(" << *this << ") trackId= " << String(track->id()) << " enabled=" << BoolString(track->enabled()); DCHECK(MediaTracksEnabledInternally()); @@ -2844,9 +2863,9 @@ WebMediaPlayer::TrackId HTMLMediaElement::AddAudioTrack( const WebString& language, bool enabled) { AtomicString kind_string = AudioKindToString(kind); - DVLOG(3) << "addAudioTrack(" << (void*)this << ", '" << (String)id << "', ' " - << (AtomicString)kind_string << "', '" << (String)label << "', '" - << (String)language << "', " << BoolString(enabled) << ")"; + DVLOG(3) << "addAudioTrack(" << *this << ", '" << String(id) << "', ' " + << kind_string << "', '" << String(label) << "', '" + << String(language) << "', " << BoolString(enabled) << ")"; auto* audio_track = MakeGarbageCollected<AudioTrack>(id, kind_string, label, language, enabled); @@ -2856,7 +2875,7 @@ WebMediaPlayer::TrackId HTMLMediaElement::AddAudioTrack( } void HTMLMediaElement::RemoveAudioTrack(WebMediaPlayer::TrackId track_id) { - DVLOG(3) << "removeAudioTrack(" << (void*)this << ")"; + DVLOG(3) << "removeAudioTrack(" << *this << ")"; audioTracks().Remove(track_id); } @@ -2866,8 +2885,7 @@ VideoTrackList& HTMLMediaElement::videoTracks() { } void HTMLMediaElement::SelectedVideoTrackChanged(VideoTrack* track) { - DVLOG(3) << "selectedVideoTrackChanged(" << (void*)this - << ") selectedTrackId=" + DVLOG(3) << "selectedVideoTrackChanged(" << *this << ") selectedTrackId=" << (track->selected() ? String(track->id()) : "none"); DCHECK(MediaTracksEnabledInternally()); @@ -2891,9 +2909,9 @@ WebMediaPlayer::TrackId HTMLMediaElement::AddVideoTrack( const WebString& language, bool selected) { AtomicString kind_string = VideoKindToString(kind); - DVLOG(3) << "addVideoTrack(" << (void*)this << ", '" << (String)id << "', '" - << (AtomicString)kind_string << "', '" << (String)label << "', '" - << (String)language << "', " << BoolString(selected) << ")"; + DVLOG(3) << "addVideoTrack(" << *this << ", '" << String(id) << "', '" + << kind_string << "', '" << String(label) << "', '" + << String(language) << "', " << BoolString(selected) << ")"; // If another track was selected (potentially by the user), leave it selected. if (selected && videoTracks().selectedIndex() != -1) @@ -2907,7 +2925,7 @@ WebMediaPlayer::TrackId HTMLMediaElement::AddVideoTrack( } void HTMLMediaElement::RemoveVideoTrack(WebMediaPlayer::TrackId track_id) { - DVLOG(3) << "removeVideoTrack(" << (void*)this << ")"; + DVLOG(3) << "removeVideoTrack(" << *this << ")"; videoTracks().Remove(track_id); } @@ -3045,7 +3063,7 @@ void HTMLMediaElement::DidAddTrackElement(HTMLTrackElement* track_element) { void HTMLMediaElement::DidRemoveTrackElement(HTMLTrackElement* track_element) { KURL url = track_element->GetNonEmptyURLAttribute(html_names::kSrcAttr); - DVLOG(3) << "didRemoveTrackElement(" << (void*)this << ") - 'src' is " + DVLOG(3) << "didRemoveTrackElement(" << *this << ") - 'src' is " << UrlForLoggingMedia(url); TextTrack* text_track = track_element->track(); @@ -3113,12 +3131,11 @@ KURL HTMLMediaElement::SelectNextSourceChild( // <source> elements. bool should_log = action_if_invalid != kDoNothing; if (should_log) - DVLOG(3) << "selectNextSourceChild(" << (void*)this << ")"; + DVLOG(3) << "selectNextSourceChild(" << *this << ")"; if (!next_child_node_to_consider_) { if (should_log) { - DVLOG(3) << "selectNextSourceChild(" << (void*)this - << ") -> 0x0000, \"\""; + DVLOG(3) << "selectNextSourceChild(" << *this << ") -> 0x0000, \"\""; } return KURL(); } @@ -3150,7 +3167,7 @@ KURL HTMLMediaElement::SelectNextSourceChild( const AtomicString& src_value = source->FastGetAttribute(html_names::kSrcAttr); if (should_log) { - DVLOG(3) << "selectNextSourceChild(" << (void*)this << ") - 'src' is " + DVLOG(3) << "selectNextSourceChild(" << *this << ") - 'src' is " << UrlForLoggingMedia(media_url); } if (src_value.IsEmpty()) @@ -3175,7 +3192,7 @@ KURL HTMLMediaElement::SelectNextSourceChild( type = MimeTypeFromDataURL(media_url); if (!type.IsEmpty()) { if (should_log) { - DVLOG(3) << "selectNextSourceChild(" << (void*)this << ") - 'type' is '" + DVLOG(3) << "selectNextSourceChild(" << *this << ") - 'type' is '" << type << "'"; } if (!GetSupportsType(ContentType(type))) @@ -3201,7 +3218,7 @@ KURL HTMLMediaElement::SelectNextSourceChild( } if (should_log) { - DVLOG(3) << "selectNextSourceChild(" << (void*)this << ") -> " + DVLOG(3) << "selectNextSourceChild(" << *this << ") -> " << current_source_node_.Get() << ", " << (can_use_source_element ? UrlForLoggingMedia(media_url) : ""); } @@ -3210,10 +3227,10 @@ KURL HTMLMediaElement::SelectNextSourceChild( } void HTMLMediaElement::SourceWasAdded(HTMLSourceElement* source) { - DVLOG(3) << "sourceWasAdded(" << (void*)this << ", " << source << ")"; + DVLOG(3) << "sourceWasAdded(" << *this << ", " << source << ")"; KURL url = source->GetNonEmptyURLAttribute(html_names::kSrcAttr); - DVLOG(3) << "sourceWasAdded(" << (void*)this << ") - 'src' is " + DVLOG(3) << "sourceWasAdded(" << *this << ") - 'src' is " << UrlForLoggingMedia(url); // We should only consider a <source> element when there is not src attribute @@ -3233,7 +3250,7 @@ void HTMLMediaElement::SourceWasAdded(HTMLSourceElement* source) { } if (current_source_node_ && source == current_source_node_->nextSibling()) { - DVLOG(3) << "sourceWasAdded(" << (void*)this + DVLOG(3) << "sourceWasAdded(" << *this << ") - <source> inserted immediately after current source"; // Ignore current |next_child_node_to_consider_| and consider |source|. next_child_node_to_consider_ = source; @@ -3265,10 +3282,10 @@ void HTMLMediaElement::SourceWasAdded(HTMLSourceElement* source) { } void HTMLMediaElement::SourceWasRemoved(HTMLSourceElement* source) { - DVLOG(3) << "sourceWasRemoved(" << (void*)this << ", " << source << ")"; + DVLOG(3) << "sourceWasRemoved(" << *this << ", " << source << ")"; KURL url = source->GetNonEmptyURLAttribute(html_names::kSrcAttr); - DVLOG(3) << "sourceWasRemoved(" << (void*)this << ") - 'src' is " + DVLOG(3) << "sourceWasRemoved(" << *this << ") - 'src' is " << UrlForLoggingMedia(url); if (source != current_source_node_ && source != next_child_node_to_consider_) @@ -3277,7 +3294,7 @@ void HTMLMediaElement::SourceWasRemoved(HTMLSourceElement* source) { if (source == next_child_node_to_consider_) { if (current_source_node_) next_child_node_to_consider_ = current_source_node_->nextSibling(); - DVLOG(3) << "sourceWasRemoved(" << (void*)this + DVLOG(3) << "sourceWasRemoved(" << *this << ") - next_child_node_to_consider_ set to " << next_child_node_to_consider_.Get(); } else if (source == current_source_node_) { @@ -3287,13 +3304,13 @@ void HTMLMediaElement::SourceWasRemoved(HTMLSourceElement* source) { // element is already inserted in a video or audio element will have no // effect. current_source_node_ = nullptr; - DVLOG(3) << "SourceWasRemoved(" << (void*)this + DVLOG(3) << "SourceWasRemoved(" << *this << ") - current_source_node_ set to 0"; } } void HTMLMediaElement::TimeChanged() { - DVLOG(3) << "timeChanged(" << (void*)this << ")"; + DVLOG(3) << "timeChanged(" << *this << ")"; GetCueTimeline().UpdateActiveCues(currentTime()); @@ -3335,7 +3352,7 @@ void HTMLMediaElement::TimeChanged() { } void HTMLMediaElement::DurationChanged() { - DVLOG(3) << "durationChanged(" << (void*)this << ")"; + DVLOG(3) << "durationChanged(" << *this << ")"; // durationChanged() is triggered by media player. CHECK(web_media_player_); @@ -3348,20 +3365,22 @@ void HTMLMediaElement::DurationChanged() { } void HTMLMediaElement::DurationChanged(double duration, bool request_seek) { - DVLOG(3) << "durationChanged(" << (void*)this << ", " << duration << ", " + DVLOG(3) << "durationChanged(" << *this << ", " << duration << ", " << BoolString(request_seek) << ")"; // Abort if duration unchanged. if (duration_ == duration) return; - DVLOG(3) << "durationChanged(" << (void*)this << ") : " << duration_ << " -> " + DVLOG(3) << "durationChanged(" << *this << ") : " << duration_ << " -> " << duration; duration_ = duration; ScheduleEvent(event_type_names::kDurationchange); - if (GetLayoutObject()) - GetLayoutObject()->UpdateFromElement(); + if (web_media_player_) + web_media_player_->OnTimeUpdate(); + + UpdateLayoutObject(); if (request_seek) Seek(duration); @@ -3406,20 +3425,19 @@ void HTMLMediaElement::Repaint() { if (cc_layer_) cc_layer_->SetNeedsDisplay(); - UpdateDisplayState(); + UpdateLayoutObject(); if (GetLayoutObject()) GetLayoutObject()->SetShouldDoFullPaintInvalidation(); } void HTMLMediaElement::SizeChanged() { - DVLOG(3) << "sizeChanged(" << (void*)this << ")"; + DVLOG(3) << "sizeChanged(" << *this << ")"; DCHECK(HasVideo()); // "resize" makes no sense in absence of video. if (ready_state_ > kHaveNothing && IsHTMLVideoElement()) ScheduleEvent(event_type_names::kResize); - if (GetLayoutObject()) - GetLayoutObject()->UpdateFromElement(); + UpdateLayoutObject(); } WebTimeRanges HTMLMediaElement::BufferedInternal() const { @@ -3510,7 +3528,7 @@ void HTMLMediaElement::UpdatePlayState() { bool is_playing = GetWebMediaPlayer() && !GetWebMediaPlayer()->Paused(); bool should_be_playing = PotentiallyPlaying(); - DVLOG(3) << "updatePlayState(" << (void*)this + DVLOG(3) << "updatePlayState(" << *this << ") - shouldBePlaying = " << BoolString(should_be_playing) << ", isPlaying = " << BoolString(is_playing); @@ -3518,8 +3536,6 @@ void HTMLMediaElement::UpdatePlayState() { was_always_muted_ = false; if (should_be_playing) { - SetDisplayMode(kVideo); - if (!is_playing) { // Set rate, muted before calling play in case they were set before the // media engine was setup. The media engine should just stash the rate @@ -3543,8 +3559,10 @@ void HTMLMediaElement::UpdatePlayState() { AddPlayedRange(last_seek_time_, time); } - if (GetLayoutObject()) - GetLayoutObject()->UpdateFromElement(); + UpdateLayoutObject(); + + if (web_media_player_) + web_media_player_->OnTimeUpdate(); } void HTMLMediaElement::StopPeriodicTimers() { @@ -3621,8 +3639,7 @@ void HTMLMediaElement::ContextDestroyed() { paused_ = true; seeking_ = false; - if (GetLayoutObject()) - GetLayoutObject()->UpdateFromElement(); + UpdateLayoutObject(); StopPeriodicTimers(); removed_from_document_timer_.Stop(); @@ -3631,7 +3648,7 @@ void HTMLMediaElement::ContextDestroyed() { bool HTMLMediaElement::HasPendingActivity() const { const auto result = HasPendingActivityInternal(); // TODO(dalecurtis): Replace c-style casts in followup patch. - DVLOG(3) << "HasPendingActivity(" << (void*)this << ") = " << result; + DVLOG(3) << "HasPendingActivity(" << *this << ") = " << result; return result; } @@ -3778,14 +3795,14 @@ TextTrackContainer& HTMLMediaElement::EnsureTextTrackContainer() { } void HTMLMediaElement::UpdateTextTrackDisplay() { - DVLOG(3) << "updateTextTrackDisplay(" << (void*)this << ")"; + DVLOG(3) << "updateTextTrackDisplay(" << *this << ")"; EnsureTextTrackContainer().UpdateDisplay( *this, TextTrackContainer::kDidNotStartExposingControls); } void HTMLMediaElement::MediaControlsDidBecomeVisible() { - DVLOG(3) << "mediaControlsDidBecomeVisible(" << (void*)this << ")"; + DVLOG(3) << "mediaControlsDidBecomeVisible(" << *this << ")"; // When the user agent starts exposing a user interface for a video element, // the user agent should run the rules for updating the text track rendering @@ -3862,7 +3879,7 @@ void HTMLMediaElement::SetShouldDelayLoadEvent(bool should_delay) { if (should_delay_load_event_ == should_delay) return; - DVLOG(3) << "setShouldDelayLoadEvent(" << (void*)this << ", " + DVLOG(3) << "setShouldDelayLoadEvent(" << *this << ", " << BoolString(should_delay) << ")"; should_delay_load_event_ = should_delay; @@ -3927,7 +3944,7 @@ CueTimeline& HTMLMediaElement::GetCueTimeline() { void HTMLMediaElement::ConfigureTextTrackDisplay() { DCHECK(text_tracks_); - DVLOG(3) << "configureTextTrackDisplay(" << (void*)this << ")"; + DVLOG(3) << "configureTextTrackDisplay(" << *this << ")"; if (processing_preference_change_) return; @@ -4001,7 +4018,7 @@ bool HTMLMediaElement::IsInteractiveContent() const { return FastHasAttribute(html_names::kControlsAttr); } -void HTMLMediaElement::Trace(Visitor* visitor) { +void HTMLMediaElement::Trace(Visitor* visitor) const { visitor->Trace(audio_source_node_); visitor->Trace(played_time_ranges_); visitor->Trace(async_event_queue_); @@ -4220,11 +4237,11 @@ void HTMLMediaElement::AudioClientImpl::SetFormat(uint32_t number_of_channels, client_->SetFormat(number_of_channels, sample_rate); } -void HTMLMediaElement::AudioClientImpl::Trace(Visitor* visitor) { +void HTMLMediaElement::AudioClientImpl::Trace(Visitor* visitor) const { visitor->Trace(client_); } -void HTMLMediaElement::AudioSourceProviderImpl::Trace(Visitor* visitor) { +void HTMLMediaElement::AudioSourceProviderImpl::Trace(Visitor* visitor) const { visitor->Trace(client_); } diff --git a/chromium/third_party/blink/renderer/core/html/media/html_media_element.h b/chromium/third_party/blink/renderer/core/html/media/html_media_element.h index 85851eb1cbc..f351646fcbc 100644 --- a/chromium/third_party/blink/renderer/core/html/media/html_media_element.h +++ b/chromium/third_party/blink/renderer/core/html/media/html_media_element.h @@ -108,7 +108,7 @@ class CORE_EXPORT HTMLMediaElement // for the given document. static void OnMediaControlsEnabledChange(Document*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; WebMediaPlayer* GetWebMediaPlayer() const { return web_media_player_.get(); } @@ -205,6 +205,8 @@ class CORE_EXPORT HTMLMediaElement void pause(); double latencyHint() const; void setLatencyHint(double); + bool preservesPitch() const; + void setPreservesPitch(bool); void FlingingStarted(); void FlingingStopped(); @@ -332,6 +334,8 @@ class CORE_EXPORT HTMLMediaElement void SetCcLayerForTesting(cc::Layer* layer) { SetCcLayer(layer); } + bool IsShowPosterFlagSet() const { return show_poster_flag_; } + protected: // Assert the correct order of the children in shadow dom when DCHECK is on. static void AssertShadowRootChildren(ShadowRoot&); @@ -359,13 +363,11 @@ class CORE_EXPORT HTMLMediaElement void DidMoveToNewDocument(Document& old_document) override; virtual KURL PosterImageURL() const { return KURL(); } - enum DisplayMode { kUnknown, kPoster, kVideo }; - DisplayMode GetDisplayMode() const { return display_mode_; } - virtual void SetDisplayMode(DisplayMode mode) { display_mode_ = mode; } - // Called after the creation of |web_media_player_|. virtual void OnWebMediaPlayerCreated() {} + void UpdateLayoutObject(); + private: // Friend class for testing. friend class ContextMenuControllerTest; @@ -394,11 +396,12 @@ class CORE_EXPORT HTMLMediaElement void ContextLifecycleStateChanged(mojom::FrameLifecycleState) override; void ContextDestroyed() override; - virtual void UpdateDisplayState() {} virtual void OnPlay() {} virtual void OnLoadStarted() {} virtual void OnLoadFinished() {} + void SetShowPosterFlag(bool value); + void SetReadyState(ReadyState); void SetNetworkState(WebMediaPlayer::NetworkState); @@ -624,8 +627,6 @@ class CORE_EXPORT HTMLMediaElement std::unique_ptr<WebMediaPlayer> web_media_player_; cc::Layer* cc_layer_; - DisplayMode display_mode_; - Member<MediaSource> media_source_; // Stores "official playback position", updated periodically from "current @@ -648,6 +649,7 @@ class CORE_EXPORT HTMLMediaElement bool paused_ : 1; bool seeking_ : 1; bool paused_by_context_paused_ : 1; + bool show_poster_flag_ : 1; // data has not been loaded since sending a "stalled" event bool sent_stalled_event_ : 1; @@ -662,6 +664,10 @@ class CORE_EXPORT HTMLMediaElement bool was_always_muted_ : 1; + // Whether or not |web_media_player_| should apply pitch adjustments at + // playback raters other than 1.0. + bool preserves_pitch_ = true; + Member<AudioTrackList> audio_tracks_; Member<VideoTrackList> video_tracks_; Member<TextTrackList> text_tracks_; @@ -693,7 +699,7 @@ class CORE_EXPORT HTMLMediaElement // WebAudioSourceProviderClient void SetFormat(uint32_t number_of_channels, float sample_rate) override; - void Trace(Visitor*); + void Trace(Visitor*) const; private: Member<AudioSourceProviderClient> client_; @@ -715,7 +721,7 @@ class CORE_EXPORT HTMLMediaElement void SetClient(AudioSourceProviderClient*) override; void ProvideInput(AudioBus*, uint32_t frames_to_process) override; - void Trace(Visitor*); + void Trace(Visitor*) const; private: scoped_refptr<WebAudioSourceProviderImpl> web_audio_source_provider_; diff --git a/chromium/third_party/blink/renderer/core/html/media/html_media_element.idl b/chromium/third_party/blink/renderer/core/html/media/html_media_element.idl index 3e38825ead2..4bc7fd9ccc6 100644 --- a/chromium/third_party/blink/renderer/core/html/media/html_media_element.idl +++ b/chromium/third_party/blink/renderer/core/html/media/html_media_element.idl @@ -76,6 +76,8 @@ enum CanPlayTypeResult { "" /* empty string */, "maybe", "probably" }; void pause(); [RuntimeEnabled=MediaLatencyHint, CEReactions] attribute double latencyHint; + [RuntimeEnabled=MediaPreservesPitch] + attribute boolean preservesPitch; // controls [CEReactions, Reflect] attribute boolean controls; diff --git a/chromium/third_party/blink/renderer/core/html/media/html_media_element_event_listeners_test.cc b/chromium/third_party/blink/renderer/core/html/media/html_media_element_event_listeners_test.cc index faeb17ce9f1..6c87cdee963 100644 --- a/chromium/third_party/blink/renderer/core/html/media/html_media_element_event_listeners_test.cc +++ b/chromium/third_party/blink/renderer/core/html/media/html_media_element_event_listeners_test.cc @@ -37,8 +37,10 @@ static constexpr base::TimeDelta kFakeMediaPlayerAutoIncrementTimeDelta = // exception of the mocked methods). class FakeWebMediaPlayer final : public EmptyWebMediaPlayer { public: - FakeWebMediaPlayer(WebMediaPlayerClient* client, Document* document) - : client_(client), document_(document) {} + FakeWebMediaPlayer(WebMediaPlayerClient* client, + ExecutionContext* context, + double duration) + : client_(client), context_(context), duration_(duration) {} MOCK_METHOD1(SetIsEffectivelyFullscreen, void(blink::WebFullscreenVideoStatus)); @@ -48,7 +50,7 @@ class FakeWebMediaPlayer final : public EmptyWebMediaPlayer { } // Establish a large so tests can attempt seeking. - double Duration() const override { return 1000000; } + double Duration() const override { return duration_; } WebTimeRanges Seekable() const override { WebTimeRange single_range[] = {WebTimeRange(0, Duration())}; @@ -64,6 +66,7 @@ class FakeWebMediaPlayer final : public EmptyWebMediaPlayer { } void Pause() override { playing_ = false; } bool Paused() const override { return !playing_; } + bool IsEnded() const override { return current_time_ == duration_; } void FinishSeek() { ASSERT_GE(last_seek_time_, 0); @@ -71,6 +74,8 @@ class FakeWebMediaPlayer final : public EmptyWebMediaPlayer { last_seek_time_ = -1; client_->TimeChanged(); + if (playing_) + ScheduleTimeIncrement(); } void SetAutoIncrementCurrentTime(bool auto_increment) { @@ -86,7 +91,7 @@ class FakeWebMediaPlayer final : public EmptyWebMediaPlayer { return; } - document_->GetTaskRunner(TaskType::kInternalMediaRealTime) + context_->GetTaskRunner(TaskType::kInternalMediaRealTime) ->PostDelayedTask(FROM_HERE, base::BindOnce(&FakeWebMediaPlayer::AutoTimeIncrement, base::Unretained(this)), @@ -101,19 +106,27 @@ class FakeWebMediaPlayer final : public EmptyWebMediaPlayer { scheduled_time_increment_ = false; current_time_ += kFakeMediaPlayerAutoIncrementTimeDelta.InSecondsF(); - ScheduleTimeIncrement(); + + // Notify the client if we've reached the end of the set duration + if (current_time_ >= duration_) { + current_time_ = duration_; + client_->TimeChanged(); + } else { + ScheduleTimeIncrement(); + } // Run V8 Microtasks (update OfficialPlaybackPosition) - Microtask::PerformCheckpoint(document_->GetIsolate()); + Microtask::PerformCheckpoint(context_->GetIsolate()); } WebMediaPlayerClient* client_; - WeakPersistent<Document> document_; + WeakPersistent<ExecutionContext> context_; mutable double current_time_ = 0; bool playing_ = false; bool auto_increment_current_time_ = false; bool scheduled_time_increment_ = false; double last_seek_time_ = -1; + const double duration_; }; class MediaStubLocalFrameClient : public EmptyLocalFrameClient { @@ -122,8 +135,16 @@ class MediaStubLocalFrameClient : public EmptyLocalFrameClient { HTMLMediaElement& element, const WebMediaPlayerSource&, WebMediaPlayerClient* client) override { - return std::make_unique<FakeWebMediaPlayer>(client, &element.GetDocument()); + return std::make_unique<FakeWebMediaPlayer>( + client, element.GetExecutionContext(), media_duration_); + } + + void SetMediaDuration(double media_duration) { + media_duration_ = media_duration; } + + private: + double media_duration_ = 1000000; }; using testing::_; @@ -140,19 +161,33 @@ class HTMLMediaElementEventListenersTest : public PageTestBase { } void DestroyDocument() { PageTestBase::TearDown(); } + HTMLVideoElement* Video() { return To<HTMLVideoElement>(GetDocument().QuerySelector("video")); } + FakeWebMediaPlayer* WebMediaPlayer() { return static_cast<FakeWebMediaPlayer*>(Video()->GetWebMediaPlayer()); } + + MediaStubLocalFrameClient* LocalFrameClient() { + return static_cast<MediaStubLocalFrameClient*>(GetFrame().Client()); + } + + void SetMediaDuration(double duration) { + LocalFrameClient()->SetMediaDuration(duration); + } + MediaControls* Controls() { return Video()->GetMediaControls(); } + void SimulateReadyState(HTMLMediaElement::ReadyState state) { Video()->SetReadyState(state); } + void SimulateNetworkState(HTMLMediaElement::NetworkState state) { Video()->SetNetworkState(state); } + MediaCustomControlsFullscreenDetector* FullscreenDetector() { return Video()->custom_controls_fullscreen_detector_; } @@ -406,4 +441,76 @@ TEST_F(HTMLMediaElementWithMockSchedulerTest, PeriodicTimeupdateAfterSeek) { platform()->RunUntilIdle(); } +TEST_F(HTMLMediaElementWithMockSchedulerTest, ShowPosterFlag_FalseAfterLoop) { + testing::InSequence dummy; + + // Adjust the duration of the media to something we can reasonably loop + SetMediaDuration(10.0); + + // Create a looping video with a source + GetDocument().body()->setInnerHTML( + "<video loop src=\"http://example.com\"></video>"); + platform()->RunUntilIdle(); + EXPECT_NE(WebMediaPlayer(), nullptr); + EXPECT_EQ(WebMediaPlayer()->Duration(), 10.0); + EXPECT_TRUE(Video()->Loop()); + + SimulateNetworkState(HTMLMediaElement::kNetworkIdle); + SimulateReadyState(HTMLMediaElement::kHaveEnoughData); + + // Simulate advancing playback time to enable periodic timeupdates. + WebMediaPlayer()->SetAutoIncrementCurrentTime(true); + Video()->Play(); + + // Ensure the 'seeking' and 'seeked' events are fired, so we know a loop + // occurred + auto* seeking_handler = MakeGarbageCollected<MockEventListener>(); + EXPECT_CALL(*seeking_handler, Invoke(_, _)).Times(1); + Video()->addEventListener(event_type_names::kSeeking, seeking_handler); + platform()->RunForPeriodSeconds(15); + testing::Mock::VerifyAndClearExpectations(seeking_handler); + + auto* seeked_handler = MakeGarbageCollected<MockEventListener>(); + EXPECT_CALL(*seeked_handler, Invoke(_, _)).Times(1); + Video()->addEventListener(event_type_names::kSeeked, seeked_handler); + WebMediaPlayer()->FinishSeek(); + platform()->RunUntilIdle(); + testing::Mock::VerifyAndClearExpectations(seeked_handler); + + // ShowPosterFlag should be false after looping + EXPECT_FALSE(Video()->IsShowPosterFlagSet()); +} + +TEST_F(HTMLMediaElementWithMockSchedulerTest, ShowPosterFlag_FalseAfterEnded) { + testing::InSequence dummy; + + // Adjust the duration of the media to something we can reach the end of + SetMediaDuration(10.0); + + // Create a video with a source + GetDocument().body()->setInnerHTML( + "<video src=\"http://example.com\"></video>"); + platform()->RunUntilIdle(); + EXPECT_NE(WebMediaPlayer(), nullptr); + EXPECT_EQ(WebMediaPlayer()->Duration(), 10.0); + + SimulateNetworkState(HTMLMediaElement::kNetworkIdle); + SimulateReadyState(HTMLMediaElement::kHaveEnoughData); + + // Simulate advancing playback time to enable periodic timeupdates. + WebMediaPlayer()->SetAutoIncrementCurrentTime(true); + Video()->Play(); + + // Ensure the 'ended' event is fired + auto* ended_handler = MakeGarbageCollected<MockEventListener>(); + Video()->addEventListener(event_type_names::kEnded, ended_handler); + + EXPECT_CALL(*ended_handler, Invoke(_, _)).Times(1); + platform()->RunForPeriodSeconds(15); + testing::Mock::VerifyAndClearExpectations(ended_handler); + + // ShowPosterFlag should be false even after ending + EXPECT_FALSE(Video()->IsShowPosterFlagSet()); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/media/html_media_element_test.cc b/chromium/third_party/blink/renderer/core/html/media/html_media_element_test.cc index 3fd83d9af3f..25bd257294c 100644 --- a/chromium/third_party/blink/renderer/core/html/media/html_media_element_test.cc +++ b/chromium/third_party/blink/renderer/core/html/media/html_media_element_test.cc @@ -38,6 +38,8 @@ namespace { class MockWebMediaPlayer : public EmptyWebMediaPlayer { public: + MOCK_METHOD0(OnTimeUpdate, void()); + MOCK_CONST_METHOD0(Seekable, WebTimeRanges()); MOCK_CONST_METHOD0(HasAudio, bool()); MOCK_CONST_METHOD0(HasVideo, bool()); MOCK_CONST_METHOD0(Duration, double()); @@ -88,6 +90,8 @@ class HTMLMediaElementTest : public testing::TestWithParam<MediaTestParam> { // Most tests do not care about this call, nor its return value. Those that // do will clear this expectation and set custom expectations/returns. + EXPECT_CALL(*mock_media_player, Seekable()) + .WillRepeatedly(Return(WebTimeRanges())); EXPECT_CALL(*mock_media_player, HasAudio()).WillRepeatedly(Return(true)); EXPECT_CALL(*mock_media_player, HasVideo()).WillRepeatedly(Return(true)); EXPECT_CALL(*mock_media_player, Duration()).WillRepeatedly(Return(1.0)); @@ -128,6 +132,8 @@ class HTMLMediaElementTest : public testing::TestWithParam<MediaTestParam> { bool CouldPlayIfEnoughData() { return Media()->CouldPlayIfEnoughData(); } + bool PotentiallyPlaying() { return Media()->PotentiallyPlaying(); } + bool ShouldDelayLoadEvent() { return Media()->should_delay_load_event_; } void SetReadyState(HTMLMediaElement::ReadyState state) { @@ -606,4 +612,177 @@ TEST_P(HTMLMediaElementTest, NoPendingActivityEvenIfBeforeMetadata) { EXPECT_TRUE(MediaShouldBeOpaque()); } +TEST_P(HTMLMediaElementTest, OnTimeUpdate_DurationChange) { + // Prepare the player. + Media()->SetSrc(SrcSchemeToURL(TestURLScheme::kHttp)); + test::RunPendingTasks(); + + // Change from no duration to 1s will trigger OnTimeUpdate(). + EXPECT_CALL(*MockMediaPlayer(), OnTimeUpdate()); + Media()->DurationChanged(1, false); + testing::Mock::VerifyAndClearExpectations(MockMediaPlayer()); + + // Change from 1s to 2s will trigger OnTimeUpdate(). + EXPECT_CALL(*MockMediaPlayer(), OnTimeUpdate()); + Media()->DurationChanged(2, false); + testing::Mock::VerifyAndClearExpectations(MockMediaPlayer()); + + // No duration change -> no OnTimeUpdate(). + Media()->DurationChanged(2, false); +} + +TEST_P(HTMLMediaElementTest, OnTimeUpdate_PlayPauseSetRate) { + // Prepare the player. + Media()->SetSrc(SrcSchemeToURL(TestURLScheme::kHttp)); + test::RunPendingTasks(); + + EXPECT_CALL(*MockMediaPlayer(), OnTimeUpdate()); + Media()->Play(); + testing::Mock::VerifyAndClearExpectations(MockMediaPlayer()); + + EXPECT_CALL(*MockMediaPlayer(), OnTimeUpdate()); + Media()->setPlaybackRate(0.5); + testing::Mock::VerifyAndClearExpectations(MockMediaPlayer()); + + EXPECT_CALL(*MockMediaPlayer(), OnTimeUpdate()).Times(testing::AtLeast(1)); + Media()->pause(); + testing::Mock::VerifyAndClearExpectations(MockMediaPlayer()); + + EXPECT_CALL(*MockMediaPlayer(), OnTimeUpdate()); + Media()->setPlaybackRate(1.5); + testing::Mock::VerifyAndClearExpectations(MockMediaPlayer()); + + EXPECT_CALL(*MockMediaPlayer(), OnTimeUpdate()); + Media()->Play(); +} + +TEST_P(HTMLMediaElementTest, OnTimeUpdate_ReadyState) { + // Prepare the player. + Media()->SetSrc(SrcSchemeToURL(TestURLScheme::kHttp)); + test::RunPendingTasks(); + + // The ready state affects the progress of media time, so the player should + // be kept informed. + EXPECT_CALL(*MockMediaPlayer(), GetSrcAfterRedirects) + .WillRepeatedly(Return(GURL())); + EXPECT_CALL(*MockMediaPlayer(), OnTimeUpdate()); + SetReadyState(HTMLMediaElement::kHaveCurrentData); + testing::Mock::VerifyAndClearExpectations(MockMediaPlayer()); + + EXPECT_CALL(*MockMediaPlayer(), OnTimeUpdate()); + SetReadyState(HTMLMediaElement::kHaveFutureData); +} + +TEST_P(HTMLMediaElementTest, OnTimeUpdate_Seeking) { + // Prepare the player and seekable ranges -- setCurrentTime()'s prerequisites. + WebTimeRanges seekable; + seekable.Add(0, 3); + EXPECT_CALL(*MockMediaPlayer(), Seekable).WillRepeatedly(Return(seekable)); + EXPECT_CALL(*MockMediaPlayer(), GetSrcAfterRedirects) + .WillRepeatedly(Return(GURL())); + EXPECT_CALL(*MockMediaPlayer(), OnTimeUpdate()); + Media()->SetSrc(SrcSchemeToURL(TestURLScheme::kHttp)); + test::RunPendingTasks(); + SetReadyState(HTMLMediaElement::kHaveCurrentData); + + EXPECT_CALL(*MockMediaPlayer(), OnTimeUpdate()); + Media()->setCurrentTime(1); + testing::Mock::VerifyAndClearExpectations(MockMediaPlayer()); + + EXPECT_CALL(*MockMediaPlayer(), Seekable).WillRepeatedly(Return(seekable)); + EXPECT_CALL(*MockMediaPlayer(), OnTimeUpdate()); + Media()->setCurrentTime(2); +} + +TEST_P(HTMLMediaElementTest, ShowPosterFlag_InitiallyTrue) { + // ShowPosterFlag should be true upon initialization + EXPECT_TRUE(Media()->IsShowPosterFlagSet()); + + Media()->SetSrc(SrcSchemeToURL(TestURLScheme::kHttp)); + test::RunPendingTasks(); + + EXPECT_TRUE(Media()->IsShowPosterFlagSet()); + + SetReadyState(HTMLMediaElement::kHaveEnoughData); + test::RunPendingTasks(); + + // ShowPosterFlag should still be true once video is ready to play + EXPECT_TRUE(Media()->IsShowPosterFlagSet()); +} + +TEST_P(HTMLMediaElementTest, ShowPosterFlag_FalseAfterPlay) { + Media()->SetSrc(SrcSchemeToURL(TestURLScheme::kHttp)); + test::RunPendingTasks(); + + SetReadyState(HTMLMediaElement::kHaveEnoughData); + test::RunPendingTasks(); + + Media()->Play(); + test::RunPendingTasks(); + + // ShowPosterFlag should be false once video is playing + ASSERT_FALSE(Media()->paused()); + EXPECT_FALSE(Media()->IsShowPosterFlagSet()); +} + +TEST_P(HTMLMediaElementTest, ShowPosterFlag_FalseAfterSeek) { + Media()->SetSrc(SrcSchemeToURL(TestURLScheme::kHttp)); + test::RunPendingTasks(); + + SetReadyState(HTMLMediaElement::kHaveEnoughData); + test::RunPendingTasks(); + + ASSERT_NE(Media()->duration(), 0.0); + Media()->setCurrentTime(Media()->duration() / 2); + test::RunPendingTasks(); + + EXPECT_FALSE(Media()->IsShowPosterFlagSet()); +} + +TEST_P(HTMLMediaElementTest, ShowPosterFlag_FalseAfterAutoPlay) { + Media()->SetSrc(SrcSchemeToURL(TestURLScheme::kHttp)); + test::RunPendingTasks(); + + Media()->SetBooleanAttribute(html_names::kAutoplayAttr, true); + test::RunPendingTasks(); + + SetReadyState(HTMLMediaElement::kHaveEnoughData); + test::RunPendingTasks(); + + ASSERT_TRUE(WasAutoplayInitiated()); + ASSERT_FALSE(Media()->paused()); + EXPECT_FALSE(Media()->IsShowPosterFlagSet()); +} + +TEST_P(HTMLMediaElementTest, ShowPosterFlag_FalseAfterPlayBeforeReady) { + Media()->SetSrc(SrcSchemeToURL(TestURLScheme::kHttp)); + + // Initially we have nothing, we're not playing, trying to play, and the 'show + // poster' flag is set + EXPECT_EQ(Media()->getReadyState(), HTMLMediaElement::kHaveNothing); + EXPECT_TRUE(Media()->paused()); + EXPECT_FALSE(PotentiallyPlaying()); + EXPECT_TRUE(Media()->IsShowPosterFlagSet()); + + // Attempt to begin playback + Media()->Play(); + test::RunPendingTasks(); + + // We still have no data, but we're not paused, and the 'show poster' flag is + // not set + EXPECT_EQ(Media()->getReadyState(), HTMLMediaElement::kHaveNothing); + EXPECT_FALSE(Media()->paused()); + EXPECT_FALSE(PotentiallyPlaying()); + EXPECT_FALSE(Media()->IsShowPosterFlagSet()); + + // Pretend we have data to begin playback + SetReadyState(HTMLMediaElement::kHaveFutureData); + + // We should have data, be playing, and the show poster flag should be unset + EXPECT_EQ(Media()->getReadyState(), HTMLMediaElement::kHaveFutureData); + EXPECT_FALSE(Media()->paused()); + EXPECT_TRUE(PotentiallyPlaying()); + EXPECT_FALSE(Media()->IsShowPosterFlagSet()); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/media/html_video_element.cc b/chromium/third_party/blink/renderer/core/html/media/html_video_element.cc index 4805e7e2afd..28327caae48 100644 --- a/chromium/third_party/blink/renderer/core/html/media/html_video_element.cc +++ b/chromium/third_party/blink/renderer/core/html/media/html_video_element.cc @@ -86,8 +86,8 @@ HTMLVideoElement::HTMLVideoElement(Document& document) in_overlay_fullscreen_video_(false), is_effectively_fullscreen_(false), is_default_overridden_intrinsic_size_( - !document.IsMediaDocument() && - !document.IsFeatureEnabled( + !document.IsMediaDocument() && GetExecutionContext() && + !GetExecutionContext()->IsFeatureEnabled( mojom::blink::DocumentPolicyFeature::kUnsizedMedia)), video_has_played_(false), mostly_filling_viewport_(false) { @@ -105,7 +105,7 @@ HTMLVideoElement::HTMLVideoElement(Document& document) UpdateStateIfNeeded(); } -void HTMLVideoElement::Trace(Visitor* visitor) { +void HTMLVideoElement::Trace(Visitor* visitor) const { visitor->Trace(image_loader_); visitor->Trace(custom_controls_fullscreen_detector_); visitor->Trace(wake_lock_); @@ -151,17 +151,25 @@ LayoutObject* HTMLVideoElement::CreateLayoutObject(const ComputedStyle&, void HTMLVideoElement::AttachLayoutTree(AttachContext& context) { HTMLMediaElement::AttachLayoutTree(context); + UpdatePosterImage(); +} + +void HTMLVideoElement::UpdatePosterImage() { + ImageResourceContent* image_content = nullptr; - UpdateDisplayState(); - if (ShouldDisplayPosterImage()) { + // Load the poster if set, |VideoLayout| will decide whether to draw it. + if (!PosterImageURL().IsEmpty()) { if (!image_loader_) image_loader_ = MakeGarbageCollected<HTMLImageLoader>(this); image_loader_->UpdateFromElement(); - if (GetLayoutObject()) { - ToLayoutImage(GetLayoutObject()) - ->ImageResource() - ->SetImageResource(image_loader_->GetContent()); - } + image_content = image_loader_->GetContent(); + } + + if (GetLayoutObject()) { + ToLayoutImage(GetLayoutObject()) + ->ImageResource() + ->SetImageResource(image_content); + UpdateLayoutObject(); } } @@ -187,25 +195,8 @@ bool HTMLVideoElement::IsPresentationAttribute( void HTMLVideoElement::ParseAttribute( const AttributeModificationParams& params) { if (params.name == html_names::kPosterAttr) { - // In case the poster attribute is set after playback, don't update the - // display state, post playback the correct state will be picked up. - if (GetDisplayMode() < kVideo || !HasAvailableVideoFrame()) { - // Force a poster recalc by setting display_mode_ to kUnknown directly - // before calling UpdateDisplayState. - HTMLMediaElement::SetDisplayMode(kUnknown); - UpdateDisplayState(); - } - if (!PosterImageURL().IsEmpty()) { - if (!image_loader_) - image_loader_ = MakeGarbageCollected<HTMLImageLoader>(this); - image_loader_->UpdateFromElement(ImageLoader::kUpdateIgnorePreviousError); - } else { - if (GetLayoutObject()) { - ToLayoutImage(GetLayoutObject()) - ->ImageResource() - ->SetImageResource(nullptr); - } - } + UpdatePosterImage(); + // Notify the player when the poster image URL changes. if (GetWebMediaPlayer()) GetWebMediaPlayer()->SetPoster(PosterImageURL()); @@ -264,25 +255,6 @@ const AtomicString HTMLVideoElement::ImageSourceURL() const { return default_poster_url_; } -void HTMLVideoElement::SetDisplayMode(DisplayMode mode) { - DisplayMode old_mode = GetDisplayMode(); - KURL poster = PosterImageURL(); - - if (!poster.IsEmpty()) { - // We have a poster path, but only show it until the user triggers display - // by playing or seeking and the media engine has something to display. - // Don't show the poster if there is a seek operation or the video has - // restarted because of loop attribute - if (mode == kVideo && old_mode == kPoster && !HasAvailableVideoFrame()) - return; - } - - HTMLMediaElement::SetDisplayMode(mode); - - if (GetLayoutObject() && GetDisplayMode() != old_mode) - GetLayoutObject()->UpdateFromElement(); -} - void HTMLVideoElement::UpdatePictureInPictureAvailability() { if (!web_media_player_) return; @@ -349,13 +321,6 @@ bool HTMLVideoElement::IsPersistent() const { return is_persistent_; } -void HTMLVideoElement::UpdateDisplayState() { - if (PosterImageURL().IsEmpty() || HasAvailableVideoFrame()) - SetDisplayMode(kVideo); - else if (GetDisplayMode() < kPoster) - SetDisplayMode(kPoster); -} - void HTMLVideoElement::OnPlay() { if (!video_has_played_) { video_has_played_ = true; @@ -598,7 +563,6 @@ KURL HTMLVideoElement::PosterImageURL() const { scoped_refptr<Image> HTMLVideoElement::GetSourceImageForCanvas( SourceImageStatus* status, - AccelerationHint, const FloatSize&) { if (!HasAvailableVideoFrame()) { *status = kInvalidSourceImageStatus; @@ -607,8 +571,6 @@ scoped_refptr<Image> HTMLVideoElement::GetSourceImageForCanvas( IntSize intrinsic_size(videoWidth(), videoHeight()); // TODO(fserb): this should not be default software. - // FIXME: Not sure if we should we be doing anything with the AccelerationHint - // argument here? Currently we use unacceleration mode. std::unique_ptr<CanvasResourceProvider> resource_provider = CanvasResourceProvider::CreateBitmapProvider( intrinsic_size, kLow_SkFilterQuality, CanvasColorParams()); @@ -654,7 +616,7 @@ ScriptPromise HTMLVideoElement::CreateImageBitmap( "The provided element has not retrieved data."); return ScriptPromise(); } - if (getReadyState() <= HTMLMediaElement::kHaveMetadata) { + if (!HasAvailableVideoFrame()) { exception_state.ThrowDOMException( DOMExceptionCode::kInvalidStateError, "The provided element's player has no current data."); @@ -771,6 +733,10 @@ void HTMLVideoElement::SetIsDominantVisibleContent(bool is_dominant) { auto* player = GetWebMediaPlayer(); if (player) player->BecameDominantVisibleContent(mostly_filling_viewport_); + + auto* local_frame_view = GetDocument().View(); + if (local_frame_view) + local_frame_view->NotifyVideoIsDominantVisibleStatus(this, is_dominant); } } diff --git a/chromium/third_party/blink/renderer/core/html/media/html_video_element.h b/chromium/third_party/blink/renderer/core/html/media/html_video_element.h index d8ce1f17a1a..f5375948ea1 100644 --- a/chromium/third_party/blink/renderer/core/html/media/html_video_element.h +++ b/chromium/third_party/blink/renderer/core/html/media/html_video_element.h @@ -53,12 +53,13 @@ class CORE_EXPORT HTMLVideoElement final public ImageBitmapSource, public Supplementable<HTMLVideoElement> { DEFINE_WRAPPERTYPEINFO(); + USING_GARBAGE_COLLECTED_MIXIN(HTMLVideoElement); public: static const int kNoAlreadyUploadedFrame = -1; - HTMLVideoElement(Document&); - void Trace(Visitor*) override; + explicit HTMLVideoElement(Document&); + void Trace(Visitor*) const override; bool HasPendingActivity() const final; @@ -149,15 +150,12 @@ class CORE_EXPORT HTMLVideoElement final int already_uploaded_id, WebMediaPlayer::VideoFrameUploadMetadata* out_metadata); - bool ShouldDisplayPosterImage() const { return GetDisplayMode() == kPoster; } - bool HasAvailableVideoFrame() const; KURL PosterImageURL() const override; // CanvasImageSource implementation scoped_refptr<Image> GetSourceImageForCanvas(SourceImageStatus*, - AccelerationHint, const FloatSize&) override; bool IsVideoElement() const override { return true; } bool WouldTaintOrigin() const override; @@ -201,13 +199,6 @@ class CORE_EXPORT HTMLVideoElement final void SetIsEffectivelyFullscreen(blink::WebFullscreenVideoStatus); void SetIsDominantVisibleContent(bool is_dominant); - void SetImageForTest(ImageResourceContent* content) { - if (!image_loader_) - image_loader_ = MakeGarbageCollected<HTMLImageLoader>(this); - image_loader_->SetImageForTest(content); - SetDisplayMode(kPoster); - } - VideoWakeLock* wake_lock_for_tests() const { return wake_lock_; } protected: @@ -231,6 +222,7 @@ class CORE_EXPORT HTMLVideoElement final bool LayoutObjectIsNeeded(const ComputedStyle&) const override; LayoutObject* CreateLayoutObject(const ComputedStyle&, LegacyLayout) override; void AttachLayoutTree(AttachContext&) override; + void UpdatePosterImage(); void ParseAttribute(const AttributeModificationParams&) override; bool IsPresentationAttribute(const QualifiedName&) const override; void CollectStyleForPresentationAttribute( @@ -240,12 +232,10 @@ class CORE_EXPORT HTMLVideoElement final bool IsURLAttribute(const Attribute&) const override; const AtomicString ImageSourceURL() const override; - void UpdateDisplayState() override; void OnPlay() final; void OnLoadStarted() final; void OnLoadFinished() final; void DidMoveToNewDocument(Document& old_document) override; - void SetDisplayMode(DisplayMode) override; void UpdatePictureInPictureAvailability(); diff --git a/chromium/third_party/blink/renderer/core/html/media/media_controls.cc b/chromium/third_party/blink/renderer/core/html/media/media_controls.cc index 4f735e0d753..ce1bfe739d4 100644 --- a/chromium/third_party/blink/renderer/core/html/media/media_controls.cc +++ b/chromium/third_party/blink/renderer/core/html/media/media_controls.cc @@ -48,7 +48,7 @@ HTMLMediaElement& MediaControls::MediaElement() const { return *media_element_; } -void MediaControls::Trace(Visitor* visitor) { +void MediaControls::Trace(Visitor* visitor) const { visitor->Trace(media_element_); } diff --git a/chromium/third_party/blink/renderer/core/html/media/media_controls.h b/chromium/third_party/blink/renderer/core/html/media/media_controls.h index 57c9b42217f..955dcbe5dba 100644 --- a/chromium/third_party/blink/renderer/core/html/media/media_controls.h +++ b/chromium/third_party/blink/renderer/core/html/media/media_controls.h @@ -77,7 +77,7 @@ class CORE_EXPORT MediaControls : public GarbageCollectedMixin { virtual HTMLDivElement* PanelElement() = 0; virtual void OnMediaControlsEnabledChange() = 0; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<HTMLMediaElement> media_element_; diff --git a/chromium/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.cc b/chromium/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.cc index 9955b98391a..ebc5ca05433 100644 --- a/chromium/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.cc +++ b/chromium/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.cc @@ -231,7 +231,7 @@ bool MediaCustomControlsFullscreenDetector::IsVideoOrParentFullscreen() { return fullscreen_element->contains(&VideoElement()); } -void MediaCustomControlsFullscreenDetector::Trace(Visitor* visitor) { +void MediaCustomControlsFullscreenDetector::Trace(Visitor* visitor) const { NativeEventListener::Trace(visitor); visitor->Trace(video_element_); visitor->Trace(viewport_intersection_observer_); diff --git a/chromium/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.h b/chromium/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.h index fcd75bfd8a9..570ce9c03b5 100644 --- a/chromium/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.h +++ b/chromium/third_party/blink/renderer/core/html/media/media_custom_controls_fullscreen_detector.h @@ -34,7 +34,7 @@ class CORE_EXPORT MediaCustomControlsFullscreenDetector final // EventListener implementation. void Invoke(ExecutionContext*, Event*) override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; void TriggerObservation(); private: diff --git a/chromium/third_party/blink/renderer/core/html/media/media_element_parser_helpers.cc b/chromium/third_party/blink/renderer/core/html/media/media_element_parser_helpers.cc index eb358a1d903..b358da2044d 100644 --- a/chromium/third_party/blink/renderer/core/html/media/media_element_parser_helpers.cc +++ b/chromium/third_party/blink/renderer/core/html/media/media_element_parser_helpers.cc @@ -18,7 +18,7 @@ void CheckUnsizedMediaViolation(const LayoutObject* layout_object, bool is_unsized = !style.LogicalWidth().IsSpecified() && !style.LogicalHeight().IsSpecified(); if (is_unsized) { - layout_object->GetDocument().IsFeatureEnabled( + layout_object->GetDocument().GetExecutionContext()->IsFeatureEnabled( mojom::blink::DocumentPolicyFeature::kUnsizedMedia, send_report ? ReportOptions::kReportOnFailure : ReportOptions::kDoNotReport); diff --git a/chromium/third_party/blink/renderer/core/html/media/media_remoting_interstitial.cc b/chromium/third_party/blink/renderer/core/html/media/media_remoting_interstitial.cc index 0024ef5fbc4..8fa88c6d7e9 100644 --- a/chromium/third_party/blink/renderer/core/html/media/media_remoting_interstitial.cc +++ b/chromium/third_party/blink/renderer/core/html/media/media_remoting_interstitial.cc @@ -154,7 +154,7 @@ void MediaRemotingInterstitial::OnPosterImageChanged() { GetVideoElement().FastGetAttribute(html_names::kPosterAttr)); } -void MediaRemotingInterstitial::Trace(Visitor* visitor) { +void MediaRemotingInterstitial::Trace(Visitor* visitor) const { visitor->Trace(video_element_); visitor->Trace(background_image_); visitor->Trace(cast_icon_); diff --git a/chromium/third_party/blink/renderer/core/html/media/media_remoting_interstitial.h b/chromium/third_party/blink/renderer/core/html/media/media_remoting_interstitial.h index 6457522a778..8ccf4baa726 100644 --- a/chromium/third_party/blink/renderer/core/html/media/media_remoting_interstitial.h +++ b/chromium/third_party/blink/renderer/core/html/media/media_remoting_interstitial.h @@ -47,7 +47,7 @@ class MediaRemotingInterstitial final : public HTMLDivElement { HTMLVideoElement& GetVideoElement() const { return *video_element_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: // Node override. diff --git a/chromium/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.cc b/chromium/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.cc index 40baab9412a..5627a70f441 100644 --- a/chromium/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.cc +++ b/chromium/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.cc @@ -47,7 +47,7 @@ class PictureInPictureInterstitial::VideoElementResizeObserverDelegate final interstitial_->NotifyElementSizeChanged(*entries[0]->contentRect()); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(interstitial_); ResizeObserver::Delegate::Trace(visitor); } @@ -173,7 +173,7 @@ void PictureInPictureInterstitial::OnPosterImageChanged() { GetVideoElement().FastGetAttribute(html_names::kPosterAttr)); } -void PictureInPictureInterstitial::Trace(Visitor* visitor) { +void PictureInPictureInterstitial::Trace(Visitor* visitor) const { visitor->Trace(resize_observer_); visitor->Trace(video_element_); visitor->Trace(background_image_); diff --git a/chromium/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.h b/chromium/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.h index deaaff75a85..85aae77812d 100644 --- a/chromium/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.h +++ b/chromium/third_party/blink/renderer/core/html/media/picture_in_picture_interstitial.h @@ -40,7 +40,7 @@ class PictureInPictureInterstitial final : public HTMLDivElement { void RemovedFrom(ContainerNode&) override; // Element: - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: class VideoElementResizeObserverDelegate; diff --git a/chromium/third_party/blink/renderer/core/html/media/remote_playback_controller.cc b/chromium/third_party/blink/renderer/core/html/media/remote_playback_controller.cc index 71f3d3c57b8..bb1cd102a2c 100644 --- a/chromium/third_party/blink/renderer/core/html/media/remote_playback_controller.cc +++ b/chromium/third_party/blink/renderer/core/html/media/remote_playback_controller.cc @@ -16,7 +16,7 @@ RemotePlaybackController* RemotePlaybackController::From( return Supplement<HTMLMediaElement>::From<RemotePlaybackController>(element); } -void RemotePlaybackController::Trace(Visitor* visitor) { +void RemotePlaybackController::Trace(Visitor* visitor) const { Supplement<HTMLMediaElement>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/media/remote_playback_controller.h b/chromium/third_party/blink/renderer/core/html/media/remote_playback_controller.h index 5bd208eb656..64eb54916ed 100644 --- a/chromium/third_party/blink/renderer/core/html/media/remote_playback_controller.h +++ b/chromium/third_party/blink/renderer/core/html/media/remote_playback_controller.h @@ -30,7 +30,7 @@ class CORE_EXPORT RemotePlaybackController virtual void AvailabilityChangedForTesting(bool screen_is_available) = 0; virtual void StateChangedForTesting(bool is_connected) = 0; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: explicit RemotePlaybackController(HTMLMediaElement&); diff --git a/chromium/third_party/blink/renderer/core/html/media/video_frame_callback_requester.cc b/chromium/third_party/blink/renderer/core/html/media/video_frame_callback_requester.cc index d0998e37e35..a27ed684da0 100644 --- a/chromium/third_party/blink/renderer/core/html/media/video_frame_callback_requester.cc +++ b/chromium/third_party/blink/renderer/core/html/media/video_frame_callback_requester.cc @@ -19,7 +19,7 @@ VideoFrameCallbackRequester* VideoFrameCallbackRequester::From( element); } -void VideoFrameCallbackRequester::Trace(Visitor* visitor) { +void VideoFrameCallbackRequester::Trace(Visitor* visitor) const { Supplement<HTMLVideoElement>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/media/video_frame_callback_requester.h b/chromium/third_party/blink/renderer/core/html/media/video_frame_callback_requester.h index 7f4dff1cb39..b5743ddcebb 100644 --- a/chromium/third_party/blink/renderer/core/html/media/video_frame_callback_requester.h +++ b/chromium/third_party/blink/renderer/core/html/media/video_frame_callback_requester.h @@ -27,7 +27,7 @@ class CORE_EXPORT VideoFrameCallbackRequester virtual ~VideoFrameCallbackRequester() = default; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; virtual void OnWebMediaPlayerCreated() = 0; virtual void OnRequestVideoFrameCallback() = 0; diff --git a/chromium/third_party/blink/renderer/core/html/media/video_wake_lock.cc b/chromium/third_party/blink/renderer/core/html/media/video_wake_lock.cc index 5ec06cd93ab..c90cede4b1f 100644 --- a/chromium/third_party/blink/renderer/core/html/media/video_wake_lock.cc +++ b/chromium/third_party/blink/renderer/core/html/media/video_wake_lock.cc @@ -64,7 +64,7 @@ void VideoWakeLock::OnVisibilityChanged( Update(); } -void VideoWakeLock::Trace(Visitor* visitor) { +void VideoWakeLock::Trace(Visitor* visitor) const { NativeEventListener::Trace(visitor); PageVisibilityObserver::Trace(visitor); ExecutionContextLifecycleStateObserver::Trace(visitor); @@ -117,6 +117,9 @@ bool VideoWakeLock::ShouldBeActive() const { bool page_visible = GetPage() && GetPage()->IsPageVisible(); bool in_picture_in_picture = PictureInPictureController::IsElementInPictureInPicture(&VideoElement()); + bool context_is_running = + VideoElement().GetExecutionContext() && + !VideoElement().GetExecutionContext()->IsContextPaused(); // The visibility requirements are met if one of the following is true: // - it's in Picture-in-Picture; @@ -135,8 +138,7 @@ bool VideoWakeLock::ShouldBeActive() const { return playing_ && visibility_requirements_met && remote_playback_state_ != mojom::blink::PresentationConnectionState::CONNECTED && - !(VideoElement().GetDocument().IsContextPaused() || - VideoElement().GetDocument().IsContextDestroyed()); + context_is_running; } void VideoWakeLock::EnsureWakeLockService() { diff --git a/chromium/third_party/blink/renderer/core/html/media/video_wake_lock.h b/chromium/third_party/blink/renderer/core/html/media/video_wake_lock.h index b042b0ca13c..c4e686b2620 100644 --- a/chromium/third_party/blink/renderer/core/html/media/video_wake_lock.h +++ b/chromium/third_party/blink/renderer/core/html/media/video_wake_lock.h @@ -40,7 +40,7 @@ class CORE_EXPORT VideoWakeLock final void ElementDidMoveToNewDocument(); - void Trace(Visitor*) final; + void Trace(Visitor*) const final; // EventListener implementation. void Invoke(ExecutionContext*, Event*) final; diff --git a/chromium/third_party/blink/renderer/core/html/media/video_wake_lock_test.cc b/chromium/third_party/blink/renderer/core/html/media/video_wake_lock_test.cc index 407b93e81fb..62f79d46479 100644 --- a/chromium/third_party/blink/renderer/core/html/media/video_wake_lock_test.cc +++ b/chromium/third_party/blink/renderer/core/html/media/video_wake_lock_test.cc @@ -102,7 +102,7 @@ class VideoWakeLockTest : public PageTestBase { nullptr, MakeGarbageCollected<VideoWakeLockFrameClient>( std::make_unique<VideoWakeLockMediaPlayer>())); - GetDocument().GetBrowserInterfaceBroker().SetBinderForTesting( + GetFrame().GetBrowserInterfaceBroker().SetBinderForTesting( mojom::blink::PictureInPictureService::Name_, WTF::BindRepeating(&VideoWakeLockPictureInPictureService::Bind, WTF::Unretained(&pip_service_))); @@ -117,7 +117,7 @@ class VideoWakeLockTest : public PageTestBase { } void TearDown() override { - GetDocument().GetBrowserInterfaceBroker().SetBinderForTesting( + GetFrame().GetBrowserInterfaceBroker().SetBinderForTesting( mojom::blink::PictureInPictureService::Name_, {}); PageTestBase::TearDown(); @@ -165,9 +165,7 @@ class VideoWakeLockTest : public PageTestBase { mojom::FrameLifecycleState::kRunning); } - void SimulateContextDestroyed() { - GetFrame().DomWindow()->NotifyContextDestroyed(); - } + void SimulateContextDestroyed() { GetFrame().DomWindow()->FrameDestroyed(); } void SimulateNetworkState(HTMLMediaElement::NetworkState network_state) { video_->SetNetworkState(network_state); diff --git a/chromium/third_party/blink/renderer/core/html/parser/BUILD.gn b/chromium/third_party/blink/renderer/core/html/parser/BUILD.gn index 43eb9f797d7..24c6c997ae8 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/BUILD.gn +++ b/chromium/third_party/blink/renderer/core/html/parser/BUILD.gn @@ -47,8 +47,6 @@ blink_core_sources("parser") { "html_preload_scanner.h", "html_resource_preloader.cc", "html_resource_preloader.h", - "html_source_tracker.cc", - "html_source_tracker.h", "html_srcset_parser.cc", "html_srcset_parser.h", "html_stack_item.h", @@ -76,12 +74,14 @@ blink_core_sources("parser") { "text_document_parser.h", "text_resource_decoder.cc", "text_resource_decoder.h", + "text_resource_decoder_builder.cc", + "text_resource_decoder_builder.h", ] # Optimizing the HTML parser for speed yields significant gains in performance # in parser-heavy scenarios. See https://crbug.com/787512. - # Windows builds already override the default optimization in core.gni. - if (!is_debug && !is_win) { + # All other platforms already override this in core.gni. + if (!is_debug && is_android) { configs -= [ "//build/config/compiler:default_optimization" ] configs += [ "//build/config/compiler:optimize_max" ] } diff --git a/chromium/third_party/blink/renderer/core/html/parser/atomic_html_token.h b/chromium/third_party/blink/renderer/core/html/parser/atomic_html_token.h index 6c1dcaa54c6..a70363c9e9c 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/atomic_html_token.h +++ b/chromium/third_party/blink/renderer/core/html/parser/atomic_html_token.h @@ -29,6 +29,7 @@ #include <memory> #include "base/macros.h" +#include "base/notreached.h" #include "third_party/blink/renderer/core/dom/attribute.h" #include "third_party/blink/renderer/core/html/parser/compact_html_token.h" #include "third_party/blink/renderer/core/html/parser/html_token.h" diff --git a/chromium/third_party/blink/renderer/core/html/parser/background_html_parser.h b/chromium/third_party/blink/renderer/core/html/parser/background_html_parser.h index de2b5d96511..34278f1e6df 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/background_html_parser.h +++ b/chromium/third_party/blink/renderer/core/html/parser/background_html_parser.h @@ -37,7 +37,6 @@ #include "third_party/blink/renderer/core/html/parser/compact_html_token.h" #include "third_party/blink/renderer/core/html/parser/html_parser_options.h" #include "third_party/blink/renderer/core/html/parser/html_preload_scanner.h" -#include "third_party/blink/renderer/core/html/parser/html_source_tracker.h" #include "third_party/blink/renderer/core/html/parser/html_tree_builder_simulator.h" #include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h" #include "third_party/blink/renderer/core/page/viewport_description.h" @@ -108,7 +107,6 @@ class BackgroundHTMLParser { void UpdateDocument(const String& decoded_data); BackgroundHTMLInputStream input_; - HTMLSourceTracker source_tracker_; std::unique_ptr<HTMLToken> token_; std::unique_ptr<HTMLTokenizer> tokenizer_; HTMLTreeBuilderSimulator tree_builder_simulator_; diff --git a/chromium/third_party/blink/renderer/core/html/parser/compact_html_token.cc b/chromium/third_party/blink/renderer/core/html/parser/compact_html_token.cc index 8291327ed58..b2d884a105b 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/compact_html_token.cc +++ b/chromium/third_party/blink/renderer/core/html/parser/compact_html_token.cc @@ -25,6 +25,7 @@ #include "third_party/blink/renderer/core/html/parser/compact_html_token.h" +#include "base/notreached.h" #include "third_party/blink/renderer/core/dom/qualified_name.h" #include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h" diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_construction_site.cc b/chromium/third_party/blink/renderer/core/html/parser/html_construction_site.cc index dc384962258..b7644d32558 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_construction_site.cc +++ b/chromium/third_party/blink/renderer/core/html/parser/html_construction_site.cc @@ -115,8 +115,13 @@ static inline void Insert(HTMLConstructionSiteTask& task) { // 3. If the adjusted insertion location is inside a template element, let it // instead be inside the template element's template contents, after its last // child (if any). - if (auto* template_element = DynamicTo<HTMLTemplateElement>(*task.parent)) + if (auto* template_element = DynamicTo<HTMLTemplateElement>(*task.parent)) { task.parent = template_element->TemplateContentForHTMLConstructionSite(); + // If the Document was detached in the middle of parsing, The template + // element won't be able to initialize its contents, so bail out. + if (!task.parent) + return; + } // https://html.spec.whatwg.org/C/#insert-a-foreign-element // 3.1, (3) Push (pop) an element queue @@ -390,7 +395,7 @@ HTMLConstructionSite::~HTMLConstructionSite() { DCHECK(pending_text_.IsEmpty()); } -void HTMLConstructionSite::Trace(Visitor* visitor) { +void HTMLConstructionSite::Trace(Visitor* visitor) const { visitor->Trace(document_); visitor->Trace(attachment_root_); visitor->Trace(head_); @@ -745,6 +750,9 @@ void HTMLConstructionSite::InsertFormattingElement(AtomicHTMLToken* token) { void HTMLConstructionSite::InsertScriptElement(AtomicHTMLToken* token) { CreateElementFlags flags; + bool should_be_parser_inserted = + parser_content_policy_ != + kAllowScriptingContentAndDoNotMarkAlreadyStarted; flags // http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#already-started // http://html5.org/specs/dom-parsing.html#dom-range-createcontextualfragment @@ -752,8 +760,8 @@ void HTMLConstructionSite::InsertScriptElement(AtomicHTMLToken* token) { // parser-inserted and already-started and later unmark them. However, we // short circuit that logic to avoid the subtree traversal to find script // elements since scripts can never see those flags or effects thereof. - .SetCreatedByParser(parser_content_policy_ != - kAllowScriptingContentAndDoNotMarkAlreadyStarted) + .SetCreatedByParser(should_be_parser_inserted, + should_be_parser_inserted ? document_ : nullptr) .SetAlreadyStarted(is_parsing_fragment_ && flags.IsCreatedByParser()); HTMLScriptElement* element = nullptr; if (const auto* is_attribute = token->GetAttributeItem(html_names::kIsAttr)) { @@ -799,8 +807,12 @@ void HTMLConstructionSite::InsertTextNode(const StringView& string, // handled in Insert(). if (auto* template_element = DynamicTo<HTMLTemplateElement>(*dummy_task.parent)) { - dummy_task.parent = - template_element->TemplateContentForHTMLConstructionSite(); + // If the Document was detached in the middle of parsing, the template + // element won't be able to initialize its contents. + if (auto* content = + template_element->TemplateContentForHTMLConstructionSite()) { + dummy_task.parent = content; + } } // Unclear when parent != case occurs. Somehow we insert text into two @@ -857,8 +869,8 @@ void HTMLConstructionSite::TakeAllChildren( } CreateElementFlags HTMLConstructionSite::GetCreateElementFlags() const { - return is_parsing_fragment_ ? CreateElementFlags::ByFragmentParser() - : CreateElementFlags::ByParser(); + return is_parsing_fragment_ ? CreateElementFlags::ByFragmentParser(document_) + : CreateElementFlags::ByParser(document_); } Document& HTMLConstructionSite::OwnerDocumentForCurrentNode() { @@ -867,8 +879,13 @@ Document& HTMLConstructionSite::OwnerDocumentForCurrentNode() { // used in those places. The spec needs to be updated to reflect this // behavior, and when that happens, a link to the spec should be placed here. if (auto* template_element = DynamicTo<HTMLTemplateElement>(*CurrentNode())) { - return template_element->TemplateContentForHTMLConstructionSite() - ->GetDocument(); + // If the Document was detached in the middle of parsing, The template + // element won't be able to initialize its contents. Fallback to the + // current node's document in that case.. + if (auto* content = + template_element->TemplateContentForHTMLConstructionSite()) { + return content->GetDocument(); + } } return CurrentNode()->GetDocument(); } @@ -884,7 +901,7 @@ CustomElementDefinition* HTMLConstructionSite::LookUpCustomElementDefinition( return nullptr; // "2. If document does not have a browsing context, return null." - LocalDOMWindow* window = document.ExecutingWindow(); + LocalDOMWindow* window = document.domWindow(); if (!window) return nullptr; @@ -950,7 +967,8 @@ Element* HTMLConstructionSite::CreateElement( // only partially construct themselves when created by the parser, but since // this is a custom element, we need a fully-constructed element here. element = definition->CreateElement( - document, tag_name, GetCreateElementFlags().SetCreatedByParser(false)); + document, tag_name, + GetCreateElementFlags().SetCreatedByParser(false, nullptr)); // "8. Append each attribute in the given token to element." We don't use // setAttributes here because the custom element constructor may have @@ -1145,7 +1163,7 @@ void HTMLConstructionSite::FosterParent(Node* node) { QueueTask(task); } -void HTMLConstructionSite::PendingText::Trace(Visitor* visitor) { +void HTMLConstructionSite::PendingText::Trace(Visitor* visitor) const { visitor->Trace(parent); visitor->Trace(next_child); } diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_construction_site.h b/chromium/third_party/blink/renderer/core/html/parser/html_construction_site.h index 6e40ad8438f..a1d6a3c6b37 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_construction_site.h +++ b/chromium/third_party/blink/renderer/core/html/parser/html_construction_site.h @@ -53,7 +53,7 @@ struct HTMLConstructionSiteTask { explicit HTMLConstructionSiteTask(Operation op) : operation(op), self_closing(false) {} - void Trace(Visitor* visitor) { + void Trace(Visitor* visitor) const { visitor->Trace(parent); visitor->Trace(next_child); visitor->Trace(child); @@ -112,7 +112,7 @@ class HTMLConstructionSite final { Document&, ParserContentPolicy); ~HTMLConstructionSite(); - void Trace(Visitor*); + void Trace(Visitor*) const; void InitFragmentParsing(DocumentFragment*, Element* context_element); @@ -328,7 +328,7 @@ class HTMLConstructionSite final { return string_builder.IsEmpty(); } - void Trace(Visitor*); + void Trace(Visitor*) const; Member<ContainerNode> parent; Member<Node> next_child; diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_document_parser.cc b/chromium/third_party/blink/renderer/core/html/parser/html_document_parser.cc index eb81ef312c7..35b5fd38340 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_document_parser.cc +++ b/chromium/third_party/blink/renderer/core/html/parser/html_document_parser.cc @@ -80,6 +80,96 @@ size_t GetDiscardedTokenCountForTesting() { return g_discarded_token_count_for_testing; } +// This sets the maximum number of tokens which the foreground HTML parser +// should try to process in one go. Lower values generally mean faster first +// paints, larger values delay first paint, but make sure it's closer to the +// final page. This value gives a good speedup, but may need to be tuned +// further. +constexpr int kMaxTokenizationBudget = 500; + +// This class encapsulates the internal state needed for synchronous foreground +// HTML parsing (e.g. if HTMLDocumentParser::PumpTokenizer yields, this class +// tracks what should be done after the pump completes.) +class HTMLDocumentParserState + : public GarbageCollected<HTMLDocumentParserState> { + public: + enum class DeferredParserState { + // Indicates that a tokenizer pump has either completed or hasn't been + // scheduled. + kNotScheduled, + // Indicates that a tokenizer pump is scheduled and hasn't completed yet. + kScheduled, + }; + + enum class MetaCSPTokenState { + // If we've seen a meta CSP token in an upcoming HTML chunk, then we need to + // defer any preloads until we've added the CSP token to the document and + // applied the Content Security Policy. + kSeen = 0, + // Indicates that there is no meta CSP token in the upcoming chunk. + kNotSeen = 1, + // Indicates that we've added the CSP token to the document and we can now + // fetch preloads. + kProcessed = 2, + // Indicates that it's too late to apply a Content-Security policy (because + // we've exited the header section.) + kUnenforceable = 3, + }; + + explicit HTMLDocumentParserState(ParserSynchronizationPolicy mode) + : state_(DeferredParserState::kNotScheduled), + meta_csp_state_(MetaCSPTokenState::kNotSeen), + mode_(mode), + end_if_delayed_(false), + should_complete_(false) {} + + void Trace(Visitor* v) const {} + + void SetState(DeferredParserState state) { state_ = state; } + DeferredParserState GetState() const { return state_; } + bool IsScheduled() const { return state_ == DeferredParserState::kScheduled; } + const char* GetStateAsString() const { + switch (state_) { + case DeferredParserState::kNotScheduled: + return "not_scheduled"; + case DeferredParserState::kScheduled: + return "scheduled"; + } + } + + void SetEndIfDelayed(bool value) { end_if_delayed_ = value; } + void SetShouldComplete(bool value) { should_complete_ = value; } + bool ShouldEndIfDelayed() const { return end_if_delayed_; } + bool ShouldComplete() const { return should_complete_; } + bool IsSynchronous() const { + return mode_ == ParserSynchronizationPolicy::kForceSynchronousParsing; + } + ParserSynchronizationPolicy GetMode() const { return mode_; } + + void SetSeenCSPMetaTag(const bool seen) { + if (meta_csp_state_ == MetaCSPTokenState::kUnenforceable) + return; + if (seen) + meta_csp_state_ = MetaCSPTokenState::kSeen; + else + meta_csp_state_ = MetaCSPTokenState::kNotSeen; + } + + void SetExitedHeader() { + meta_csp_state_ = MetaCSPTokenState::kUnenforceable; + } + bool HaveExitedHeader() const { + return meta_csp_state_ == MetaCSPTokenState::kUnenforceable; + } + + private: + DeferredParserState state_; + MetaCSPTokenState meta_csp_state_; + ParserSynchronizationPolicy mode_; + bool end_if_delayed_; + bool should_complete_; +}; + // This is a direct transcription of step 4 from: // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#fragment-case static HTMLTokenizer::State TokenizerStateForContextElement( @@ -169,20 +259,24 @@ HTMLDocumentParser::HTMLDocumentParser(Document& document, : ScriptableDocumentParser(document, content_policy), options_(&document), reentry_permit_(HTMLParserReentryPermit::Create()), - token_(sync_policy == kForceSynchronousParsing + token_(sync_policy != kAllowAsynchronousParsing ? std::make_unique<HTMLToken>() : nullptr), - tokenizer_(sync_policy == kForceSynchronousParsing + tokenizer_(sync_policy != kAllowAsynchronousParsing ? std::make_unique<HTMLTokenizer>(options_) : nullptr), - loading_task_runner_(document.GetTaskRunner(TaskType::kNetworking)), + loading_task_runner_(sync_policy == kForceSynchronousParsing + ? nullptr + : document.GetTaskRunner(TaskType::kNetworking)), parser_scheduler_(sync_policy == kAllowAsynchronousParsing ? MakeGarbageCollected<HTMLParserScheduler>( this, loading_task_runner_.get()) : nullptr), + task_runner_state_( + MakeGarbageCollected<HTMLDocumentParserState>(sync_policy)), pending_csp_meta_token_(nullptr), - should_use_threading_(sync_policy == kAllowAsynchronousParsing), + can_parse_asynchronously_(sync_policy == kAllowAsynchronousParsing), end_was_delayed_(false), have_background_parser_(false), pump_session_nesting_level_(0), @@ -190,10 +284,19 @@ HTMLDocumentParser::HTMLDocumentParser(Document& document, is_parsing_at_line_number_(false), tried_loading_link_headers_(false), added_pending_parser_blocking_stylesheet_(false), - is_waiting_for_stylesheets_(false) { - DCHECK(ShouldUseThreading() || (token_ && tokenizer_)); - // Threading is not allowed in prefetch mode. - DCHECK(!document.IsPrefetchOnly() || !ShouldUseThreading()); + is_waiting_for_stylesheets_(false), + scheduler_(sync_policy == kAllowDeferredParsing + ? Thread::Current()->Scheduler() + : nullptr) { + DCHECK(CanParseAsynchronously() || (token_ && tokenizer_)); + // Asynchronous parsing is not allowed in prefetch mode. + DCHECK(!document.IsPrefetchOnly() || !CanParseAsynchronously()); + + // It is permissible to request the background HTML parser whilst also using + // --enable-blink-features=ForceSynchronousHTMLParsing, but it's usually + // unintentional. To help flush out these cases, trigger a DCHECK. + DCHECK(!RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled() || + !CanParseAsynchronously()); // Report metrics for async document parsing only. The document // must be main frame to meet UKM requirements, and must have a high @@ -231,11 +334,12 @@ void HTMLDocumentParser::Dispose() { StopBackgroundParser(); } -void HTMLDocumentParser::Trace(Visitor* visitor) { +void HTMLDocumentParser::Trace(Visitor* visitor) const { visitor->Trace(tree_builder_); visitor->Trace(parser_scheduler_); visitor->Trace(script_runner_); visitor->Trace(preloader_); + visitor->Trace(task_runner_state_); ScriptableDocumentParser::Trace(visitor); HTMLParserScriptRunnerHost::Trace(visitor); } @@ -269,6 +373,8 @@ void HTMLDocumentParser::StopParsing() { parser_scheduler_->Detach(); parser_scheduler_.Clear(); } + task_runner_state_->SetState( + HTMLDocumentParserState::DeferredParserState::kNotScheduled); if (have_background_parser_) StopBackgroundParser(); } @@ -276,6 +382,8 @@ void HTMLDocumentParser::StopParsing() { // This kicks off "Once the user agent stops parsing" as described by: // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#the-end void HTMLDocumentParser::PrepareToStopParsing() { + TRACE_EVENT1("blink", "HTMLDocumentParser::PrepareToStopParsing", "parser", + (void*)this); // FIXME: It may not be correct to disable this for the background parser. // That means hasInsertionPoint() may not be correct in some cases. DCHECK(!HasInsertionPoint() || have_background_parser_); @@ -283,6 +391,7 @@ void HTMLDocumentParser::PrepareToStopParsing() { // NOTE: This pump should only ever emit buffered character tokens. if (tokenizer_ && !GetDocument()->IsPrefetchOnly()) { DCHECK(!have_background_parser_); + task_runner_state_->SetShouldComplete(true); PumpTokenizerIfPossible(); } @@ -310,12 +419,44 @@ bool HTMLDocumentParser::IsParsingFragment() const { return tree_builder_->IsParsingFragment(); } +void HTMLDocumentParser::DeferredPumpTokenizerIfPossible() { + // This method is called asynchronously, continues building the HTML document. + // This function should only be called when + // --enable-blink-features=ForceSynchronousHTMLParsing is available. + DCHECK(RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled()); + TRACE_EVENT2("blink", "HTMLDocumentParser::DeferredPumpTokenizerIfPossible", + "parser", (void*)this, "state", + task_runner_state_->GetStateAsString()); + + if (IsDetached()) + return; + + if (task_runner_state_->IsScheduled()) { + HTMLDocumentParser::PumpTokenizerIfPossible(); + } +} + void HTMLDocumentParser::PumpTokenizerIfPossible() { + // This method is called synchronously, builds the HTML document up to + // the current budget, and optionally completes. + TRACE_EVENT1("blink", "HTMLDocumentParser::PumpTokenizerIfPossible", "parser", + (void*)this); + + bool yielded = false; + const bool should_call_delay_end = task_runner_state_->ShouldEndIfDelayed(); CheckIfBlockingStylesheetAdded(); - if (IsStopped() || IsPaused()) - return; + if (!IsStopped() && !IsPaused()) { + yielded = PumpTokenizer(); + } - PumpTokenizer(); + if (!yielded) { + // If we did not exceed the budget or parsed everything there was to + // parse, check if we should complete the document. + if (should_call_delay_end) { + EndIfDelayed(); + } + task_runner_state_->SetShouldComplete(false); + } } bool HTMLDocumentParser::IsScheduledForUnpause() const { @@ -324,8 +465,9 @@ bool HTMLDocumentParser::IsScheduledForUnpause() const { // Used by HTMLParserScheduler void HTMLDocumentParser::ResumeParsingAfterYield() { - DCHECK(ShouldUseThreading()); + DCHECK(CanParseAsynchronously()); DCHECK(have_background_parser_); + DCHECK(!RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled()); ScopedYieldTimer(&yield_timer_, metrics_reporter_.get()); @@ -337,6 +479,8 @@ void HTMLDocumentParser::ResumeParsingAfterYield() { } void HTMLDocumentParser::RunScriptsForPausedTreeBuilder() { + TRACE_EVENT1("blink", "HTMLDocumentParser::RunScriptsForPausedTreeBuilder", + "parser", (void*)this); DCHECK(ScriptingContentIsAllowed(GetParserContentPolicy())); TextPosition script_start_position = TextPosition::BelowRangePosition(); @@ -363,6 +507,7 @@ bool HTMLDocumentParser::CanTakeNextToken() { void HTMLDocumentParser::EnqueueTokenizedChunk( std::unique_ptr<TokenizedChunk> chunk) { + DCHECK(!RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled()); TRACE_EVENT0("blink", "HTMLDocumentParser::EnqueueTokenizedChunk"); DCHECK(chunk); @@ -441,11 +586,13 @@ void HTMLDocumentParser::EnqueueTokenizedChunk( void HTMLDocumentParser::DidReceiveEncodingDataFromBackgroundParser( const DocumentEncodingData& data) { + DCHECK(!RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled()); GetDocument()->SetEncodingData(data); } void HTMLDocumentParser::ValidateSpeculations( std::unique_ptr<TokenizedChunk> chunk) { + DCHECK(!RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled()); DCHECK(chunk); // TODO(kouhei): We should simplify codepath here by disallowing // ValidateSpeculations @@ -494,6 +641,7 @@ void HTMLDocumentParser::DiscardSpeculationsAndResumeFrom( std::unique_ptr<TokenizedChunk> last_chunk_before_script, std::unique_ptr<HTMLToken> token, std::unique_ptr<HTMLTokenizer> tokenizer) { + DCHECK(!RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled()); // Clear back ref. background_parser_->ClearParser(); @@ -539,10 +687,11 @@ size_t HTMLDocumentParser::ProcessTokenizedChunkFromBackgroundParser( SECURITY_DCHECK(pump_speculations_session_nesting_level_ == 1); SECURITY_DCHECK(!InPumpSession()); + DCHECK(!RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled()); DCHECK(!IsParsingFragment()); DCHECK(!IsPaused()); DCHECK(!IsStopped()); - DCHECK(ShouldUseThreading()); + DCHECK(CanParseAsynchronously()); DCHECK(!tokenizer_); DCHECK(!token_); DCHECK(!last_chunk_before_pause_); @@ -619,6 +768,7 @@ void HTMLDocumentParser::PumpPendingSpeculations() { DCHECK(!IsStopped()); DCHECK(!IsScheduledForUnpause()); DCHECK(!InPumpSession()); + DCHECK(!RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled()); // FIXME: Here should never be reached when there is a blocking script, // but it happens in unknown scenarios. See https://crbug.com/440901 @@ -666,7 +816,7 @@ void HTMLDocumentParser::PumpPendingSpeculations() { } void HTMLDocumentParser::ForcePlaintextForTextDocument() { - if (ShouldUseThreading()) { + if (CanParseAsynchronously()) { // This method is called before any data is appended, so we have to start // the background parser ourselves. if (!have_background_parser_) @@ -679,7 +829,14 @@ void HTMLDocumentParser::ForcePlaintextForTextDocument() { tokenizer_->SetState(HTMLTokenizer::kPLAINTEXTState); } -void HTMLDocumentParser::PumpTokenizer() { +bool HTMLDocumentParser::PumpTokenizer() { + // If we're in kForceSynchronousParsing, always run until all available input + // is consumed. + bool should_run_until_completion = task_runner_state_->ShouldComplete() || + task_runner_state_->IsSynchronous(); + TRACE_EVENT2("blink", "HTMLDocumentParser::PumpTokenizer", "should_complete", + should_run_until_completion, "parser", (void*)this); + DCHECK(!GetDocument()->IsPrefetchOnly()); DCHECK(!IsStopped()); DCHECK(tokenizer_); @@ -694,20 +851,35 @@ void HTMLDocumentParser::PumpTokenizer() { // DidWriteHTML instead of WillWriteHTML. probe::ParseHTML probe(GetDocument(), this); - while (CanTakeNextToken()) { + bool should_yield = false; + int budget = kMaxTokenizationBudget; + + while (CanTakeNextToken() && !should_yield) { { RUNTIME_CALL_TIMER_SCOPE( V8PerIsolateData::MainThreadIsolate(), RuntimeCallStats::CounterId::kHTMLTokenizerNextToken); if (!tokenizer_->NextToken(input_.Current(), Token())) break; + budget--; } ConstructTreeFromHTMLToken(); + if (!should_run_until_completion && !IsPaused()) { + DCHECK_EQ(task_runner_state_->GetMode(), kAllowDeferredParsing); + should_yield = budget <= 0; + should_yield |= scheduler_->ShouldYieldForHighPriorityWork(); + should_yield &= task_runner_state_->HaveExitedHeader(); + } else { + should_yield = false; + } DCHECK(IsStopped() || Token().IsUninitialized()); } + task_runner_state_->SetState( + HTMLDocumentParserState::DeferredParserState::kNotScheduled); + if (IsStopped()) - return; + return false; // There should only be PendingText left since the tree-builder always flushes // the task queue before returning. In case that ever changes, crash. @@ -726,12 +898,35 @@ void HTMLDocumentParser::PumpTokenizer() { ScanAndPreload(preload_scanner_.get()); } } + + CHECK(!(should_yield && (task_runner_state_->ShouldComplete() || + task_runner_state_->IsSynchronous()))); + if (should_yield) { + TRACE_EVENT0("blink", "HTMLDocumentParser::ScheduleTokenizerPump"); + DCHECK(RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled()); + DCHECK(!should_run_until_completion); + loading_task_runner_->PostTask( + FROM_HERE, + WTF::Bind(&HTMLDocumentParser::DeferredPumpTokenizerIfPossible, + WrapPersistent(this))); + task_runner_state_->SetState( + HTMLDocumentParserState::DeferredParserState::kScheduled); + } + return should_yield; } void HTMLDocumentParser::ConstructTreeFromHTMLToken() { DCHECK(!GetDocument()->IsPrefetchOnly()); + AtomicHTMLToken atomic_token(Token()); + // Check whether we've exited the header. + if (!task_runner_state_->HaveExitedHeader()) { + if (GetDocument()->body()) { + task_runner_state_->SetExitedHeader(); + } + } + // We clear the token_ in case ConstructTreeFromAtomicToken // synchronously re-enters the parser. We don't clear the token immedately // for kCharacter tokens because the AtomicHTMLToken avoids copying the @@ -761,6 +956,7 @@ void HTMLDocumentParser::ConstructTreeFromHTMLToken() { void HTMLDocumentParser::ConstructTreeFromCompactHTMLToken( const CompactHTMLToken& compact_token) { DCHECK(!GetDocument()->IsPrefetchOnly()); + DCHECK(!RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled()); AtomicHTMLToken token(compact_token); tree_builder_->ConstructTree(&token); CheckIfBlockingStylesheetAdded(); @@ -779,8 +975,8 @@ void HTMLDocumentParser::insert(const String& source) { if (IsStopped()) return; - TRACE_EVENT1("blink", "HTMLDocumentParser::insert", "source_length", - source.length()); + TRACE_EVENT2("blink", "HTMLDocumentParser::insert", "source_length", + source.length(), "parser", (void*)this); if (!tokenizer_) { DCHECK(!InPumpSession()); @@ -792,6 +988,12 @@ void HTMLDocumentParser::insert(const String& source) { SegmentedString excluded_line_number_source(source); excluded_line_number_source.SetExcludeLineNumbers(); input_.InsertAtCurrentInsertionPoint(excluded_line_number_source); + + // Pump the the tokenizer to build the document from the given insert point. + // Should process everything available and not defer anything. + task_runner_state_->SetShouldComplete(true); + // Call EndIfDelayed manually at the end to maintain preload behaviour. + task_runner_state_->SetEndIfDelayed(false); PumpTokenizerIfPossible(); if (IsPaused()) { @@ -802,16 +1004,18 @@ void HTMLDocumentParser::insert(const String& source) { CreatePreloadScanner(TokenPreloadScanner::ScannerType::kInsertion); } insertion_preload_scanner_->AppendToEnd(source); - ScanAndPreload(insertion_preload_scanner_.get()); + if (preloader_) { + ScanAndPreload(insertion_preload_scanner_.get()); + } } - EndIfDelayed(); } void HTMLDocumentParser::StartBackgroundParser() { TRACE_EVENT0("blink,loading", "HTMLDocumentParser::StartBackgroundParser"); + DCHECK(!RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled()); DCHECK(!IsStopped()); - DCHECK(ShouldUseThreading()); + DCHECK(CanParseAsynchronously()); DCHECK(!have_background_parser_); DCHECK(GetDocument()); have_background_parser_ = true; @@ -839,7 +1043,8 @@ void HTMLDocumentParser::StartBackgroundParser() { // the status of the Priority Hints Origin Trial, and has no way of figuring // this out on its own. See https://crbug.com/821464. bool priority_hints_origin_trial_enabled = - RuntimeEnabledFeatures::PriorityHintsEnabled(GetDocument()); + RuntimeEnabledFeatures::PriorityHintsEnabled( + GetDocument()->GetExecutionContext()); background_parser_->Init( GetDocument()->Url(), @@ -849,8 +1054,9 @@ void HTMLDocumentParser::StartBackgroundParser() { } void HTMLDocumentParser::StopBackgroundParser() { - DCHECK(ShouldUseThreading()); + DCHECK(CanParseAsynchronously()); DCHECK(have_background_parser_); + DCHECK(!RuntimeEnabledFeatures::ForceSynchronousHTMLParsingEnabled()); have_background_parser_ = false; @@ -860,44 +1066,54 @@ void HTMLDocumentParser::StopBackgroundParser() { } void HTMLDocumentParser::Append(const String& input_source) { + TRACE_EVENT2("blink", "HTMLDocumentParser::append", "size", + input_source.length(), "parser", (void*)this); + if (IsStopped()) return; // We should never reach this point if we're using a parser thread, as // appendBytes() will directly ship the data to the thread. - DCHECK(!ShouldUseThreading()); + DCHECK(!CanParseAsynchronously()); - TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.debug"), - "HTMLDocumentParser::append", "size", input_source.length()); const SegmentedString source(input_source); + if (!preload_scanner_ && GetDocument()->Url().IsValid() && + (!task_runner_state_->IsSynchronous() || + GetDocument()->IsPrefetchOnly() || IsPaused())) { + // If we're operating with synchronous, budgeted foreground HTML parsing + // or using the background parser, need to create a preload scanner to + // make sure that parser-blocking Javascript requests are dispatched in + // plenty of time, which prevents unnecessary delays. + // When parsing without a budget (e.g. for HTML fragment parsing), it's + // additional overhead to scan the string unless the parser's already + // paused whilst executing a script. + preload_scanner_ = + CreatePreloadScanner(TokenPreloadScanner::ScannerType::kMainDocument); + } + if (GetDocument()->IsPrefetchOnly()) { // Do not prefetch if there is an appcache. if (GetDocument()->Loader()->GetResponse().AppCacheID() != 0) return; - if (!preload_scanner_) { - preload_scanner_ = - CreatePreloadScanner(TokenPreloadScanner::ScannerType::kMainDocument); - } - preload_scanner_->AppendToEnd(source); ScanAndPreload(preload_scanner_.get()); // Return after the preload scanner, do not actually parse the document. return; } - if (preload_scanner_) { if (input_.Current().IsEmpty() && !IsPaused()) { - // We have parsed until the end of the current input and so are now moving - // ahead of the preload scanner. Clear the scanner so we know to scan - // starting from the current input point if we block again. + // We have parsed until the end of the current input and so are now + // moving ahead of the preload scanner. Clear the scanner so we know to + // scan starting from the current input point if we block again. preload_scanner_.reset(); } else { preload_scanner_->AppendToEnd(source); - if (IsPaused()) + if (IsPaused() && preloader_) { ScanAndPreload(preload_scanner_.get()); + } } } @@ -910,9 +1126,9 @@ void HTMLDocumentParser::Append(const String& input_source) { return; } + // Schedule a tokenizer pump to process this new data. + task_runner_state_->SetEndIfDelayed(true); PumpTokenizerIfPossible(); - - EndIfDelayed(); } void HTMLDocumentParser::end() { @@ -942,9 +1158,16 @@ void HTMLDocumentParser::AttemptToRunDeferredScriptsAndEnd() { end(); } +bool HTMLDocumentParser::ShouldDelayEnd() const { + return InPumpSession() || IsPaused() || IsExecutingScript() || + task_runner_state_->IsScheduled(); +} + void HTMLDocumentParser::AttemptToEnd() { // finish() indicates we will not receive any more data. If we are waiting on // an external script to load, we can't finish parsing quite yet. + TRACE_EVENT1("blink", "HTMLDocumentParser::AttemptToEnd", "parser", + (void*)this); if (ShouldDelayEnd()) { end_was_delayed_ = true; @@ -954,6 +1177,9 @@ void HTMLDocumentParser::AttemptToEnd() { } void HTMLDocumentParser::EndIfDelayed() { + TRACE_EVENT1("blink", "HTMLDocumentParser::EndIfDelayed", "parser", + (void*)this); + task_runner_state_->SetEndIfDelayed(false); // If we've already been detached, don't bother ending. if (IsDetached()) return; @@ -975,8 +1201,8 @@ void HTMLDocumentParser::Finish() { return; // Empty documents never got an append() call, and thus have never started a - // background parser. In those cases, we ignore shouldUseThreading() and fall - // through to the non-threading case. + // background parser. In those cases, we ignore CanParseAsynchronously() and + // fall through to the synchronous case. if (have_background_parser_) { if (!input_.HaveSeenEndOfFile()) input_.CloseWithoutMarkingEndOfFile(); @@ -1000,6 +1226,13 @@ void HTMLDocumentParser::Finish() { if (!input_.HaveSeenEndOfFile()) input_.MarkEndOfFile(); + if (task_runner_state_->IsScheduled() && !GetDocument()->IsPrefetchOnly()) { + // If there's any deferred work remaining, synchronously pump the tokenizer + // one last time to make sure that everything's added to the document. + task_runner_state_->SetShouldComplete(true); + PumpTokenizerIfPossible(); + } + AttemptToEnd(); } @@ -1010,8 +1243,11 @@ bool HTMLDocumentParser::IsExecutingScript() const { } bool HTMLDocumentParser::IsParsingAtLineNumber() const { - return is_parsing_at_line_number_ && - ScriptableDocumentParser::IsParsingAtLineNumber(); + if (CanParseAsynchronously()) { + return is_parsing_at_line_number_ && + ScriptableDocumentParser::IsParsingAtLineNumber(); + } + return ScriptableDocumentParser::IsParsingAtLineNumber(); } OrdinalNumber HTMLDocumentParser::LineNumber() const { @@ -1055,6 +1291,18 @@ bool HTMLDocumentParser::IsWaitingForScripts() const { } void HTMLDocumentParser::ResumeParsingAfterPause() { + // This function runs after a parser-blocking script has completed. There are + // four possible cases: + // 1) Parsing with kForceSynchronousParsing, where there is no background + // parser and a tokenizer_'s defined. + // 2) Parsing with kAllowAsynchronousParsing, without a background parser. In + // this case, the document is usually being completed or parsing has + // otherwise stopped. + // 3) Parsing with kAllowAsynchronousParsing with a background parser. In this + // case, need to add any pending speculations to the document. + // 4) Parsing with kAllowDeferredParsing, with a tokenizer_. + TRACE_EVENT1("blink", "HTMLDocumentParser::ResumeParsingAfterPause", "parser", + (void*)this); DCHECK(!IsExecutingScript()); DCHECK(!IsPaused()); @@ -1062,7 +1310,7 @@ void HTMLDocumentParser::ResumeParsingAfterPause() { if (IsStopped() || IsPaused()) return; - if (have_background_parser_) { + if (have_background_parser_) { // Case 3) // If we paused in the middle of processing a token chunk, // deal with that before starting to pump. if (last_chunk_before_pause_) { @@ -1079,24 +1327,39 @@ void HTMLDocumentParser::ResumeParsingAfterPause() { insertion_preload_scanner_.reset(); if (tokenizer_) { + // Case 1) or 4): kForceSynchronousParsing, kAllowDeferredParsing. + // kForceSynchronousParsing must pump the tokenizer synchronously. + // kDeferredParsing could (theoretically) defer the tokenizer pump. + // TODO(Richard.Townsend@arm.com) investigate this. + task_runner_state_->SetEndIfDelayed(true); + task_runner_state_->SetShouldComplete(true); PumpTokenizerIfPossible(); + } else { + // Case 2): kAllowAsynchronousParsing, no background parser available + // (indicating possible Document shutdown). + EndIfDelayed(); } - EndIfDelayed(); } void HTMLDocumentParser::AppendCurrentInputStreamToPreloadScannerAndScan() { + TRACE_EVENT1( + "blink", + "HTMLDocumentParser::AppendCurrentInputStreamToPreloadScannerAndScan", + "parser", (void*)this); DCHECK(preload_scanner_); + DCHECK(preloader_); preload_scanner_->AppendToEnd(input_.Current()); ScanAndPreload(preload_scanner_.get()); } void HTMLDocumentParser::NotifyScriptLoaded(PendingScript* pending_script) { + TRACE_EVENT1("blink", "HTMLDocumentParser::NotifyScriptLoaded", "parser", + (void*)this); DCHECK(script_runner_); DCHECK(!IsExecutingScript()); scheduler::CooperativeSchedulingManager::AllowedStackScope - whitelisted_stack_scope( - scheduler::CooperativeSchedulingManager::Instance()); + allowed_stack_scope(scheduler::CooperativeSchedulingManager::Instance()); if (IsStopped()) { return; @@ -1113,6 +1376,8 @@ void HTMLDocumentParser::NotifyScriptLoaded(PendingScript* pending_script) { } void HTMLDocumentParser::ExecuteScriptsWaitingForResources() { + TRACE_EVENT0("blink", + "HTMLDocumentParser::ExecuteScriptsWaitingForResources"); if (IsStopped()) return; @@ -1168,18 +1433,21 @@ void HTMLDocumentParser::ParseDocumentFragment( } void HTMLDocumentParser::AppendBytes(const char* data, size_t length) { + TRACE_EVENT2("blink", "HTMLDocumentParser::appendBytes", "size", + (unsigned)length, "parser", (void*)this); + + DCHECK(Thread::MainThread()->IsCurrentThread()); + if (!length || IsStopped()) return; - if (ShouldUseThreading()) { + if (CanParseAsynchronously()) { if (!have_background_parser_) StartBackgroundParser(); std::unique_ptr<Vector<char>> buffer = std::make_unique<Vector<char>>(length); memcpy(buffer->data(), data, length); - TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.debug"), - "HTMLDocumentParser::appendBytes", "size", (unsigned)length); loading_task_runner_->PostTask( FROM_HERE, @@ -1192,15 +1460,16 @@ void HTMLDocumentParser::AppendBytes(const char* data, size_t length) { } void HTMLDocumentParser::Flush() { + TRACE_EVENT1("blink", "HTMLDocumentParser::Flush", "parser", (void*)this); // If we've got no decoder, we never received any data. if (IsDetached() || NeedsDecoder()) return; - if (ShouldUseThreading()) { + if (CanParseAsynchronously()) { // In some cases, flush() is called without any invocation of appendBytes. // Fallback to synchronous parsing in that case. if (!have_background_parser_) { - should_use_threading_ = false; + can_parse_asynchronously_ = false; token_ = std::make_unique<HTMLToken>(); tokenizer_ = std::make_unique<HTMLTokenizer>(options_); DecodedDataDocumentParser::Flush(); @@ -1257,20 +1526,26 @@ std::unique_ptr<HTMLPreloadScanner> HTMLDocumentParser::CreatePreloadScanner( } void HTMLDocumentParser::ScanAndPreload(HTMLPreloadScanner* scanner) { - if (!preloader_) - return; - + TRACE_EVENT0("blink", "HTMLDocumentParser::ScanAndPreload"); + DCHECK(preloader_); bool seen_csp_meta_tag = false; PreloadRequestStream requests = scanner->Scan( GetDocument()->ValidBaseElementURL(), nullptr, seen_csp_meta_tag); - preloader_->TakeAndPreload(requests); + task_runner_state_->SetSeenCSPMetaTag(seen_csp_meta_tag); + for (auto& request : requests) { + queued_preloads_.push_back(std::move(request)); + } + FetchQueuedPreloads(); } void HTMLDocumentParser::FetchQueuedPreloads() { DCHECK(preloader_); + TRACE_EVENT0("blink", "HTMLDocumentParser::FetchQueuedPreloads"); - if (pending_csp_meta_token_ || !GetDocument()->documentElement()) - return; + if (CanParseAsynchronously()) { + if (pending_csp_meta_token_ || !GetDocument()->documentElement()) + return; + } if (!queued_preloads_.IsEmpty()) preloader_->TakeAndPreload(queued_preloads_); diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_document_parser.h b/chromium/third_party/blink/renderer/core/html/parser/html_document_parser.h index ac73abc6eeb..42d58d5e4b6 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_document_parser.h +++ b/chromium/third_party/blink/renderer/core/html/parser/html_document_parser.h @@ -29,6 +29,7 @@ #include <memory> #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" +#include "base/single_thread_task_runner.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/dom/parser_content_policy.h" #include "third_party/blink/renderer/core/dom/scriptable_document_parser.h" @@ -37,7 +38,6 @@ #include "third_party/blink/renderer/core/html/parser/html_parser_options.h" #include "third_party/blink/renderer/core/html/parser/html_parser_reentry_permit.h" #include "third_party/blink/renderer/core/html/parser/html_preload_scanner.h" -#include "third_party/blink/renderer/core/html/parser/html_source_tracker.h" #include "third_party/blink/renderer/core/html/parser/html_token.h" #include "third_party/blink/renderer/core/html/parser/html_tokenizer.h" #include "third_party/blink/renderer/core/html/parser/html_tree_builder_simulator.h" @@ -46,6 +46,7 @@ #include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h" #include "third_party/blink/renderer/core/page/viewport_description.h" #include "third_party/blink/renderer/core/script/html_parser_script_runner_host.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/wtf/deque.h" #include "third_party/blink/renderer/platform/wtf/text/text_position.h" @@ -64,6 +65,7 @@ class HTMLParserScriptRunner; class HTMLPreloadScanner; class HTMLResourcePreloader; class HTMLTreeBuilder; +class HTMLDocumentParserState; // TODO(https://crbug.com/1049898): These are only exposed to make it possible // to delete an expired histogram. The test should be rewritten to test at a @@ -82,7 +84,7 @@ class CORE_EXPORT HTMLDocumentParser : public ScriptableDocumentParser, Element* context_element, ParserContentPolicy); ~HTMLDocumentParser() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // TODO(alexclarke): Remove when background parser goes away. void Dispose(); @@ -169,7 +171,7 @@ class CORE_EXPORT HTMLDocumentParser : public ScriptableDocumentParser, void NotifyScriptLoaded(PendingScript*) final; HTMLInputStream& InputStream() final { return input_; } bool HasPreloadScanner() const final { - return preload_scanner_.get() && !ShouldUseThreading(); + return preload_scanner_.get() && !CanParseAsynchronously(); } void AppendCurrentInputStreamToPreloadScannerAndScan() final; @@ -186,8 +188,9 @@ class CORE_EXPORT HTMLDocumentParser : public ScriptableDocumentParser, void PumpPendingSpeculations(); bool CanTakeNextToken(); - void PumpTokenizer(); + bool PumpTokenizer(); void PumpTokenizerIfPossible(); + void DeferredPumpTokenizerIfPossible(); void ConstructTreeFromHTMLToken(); void ConstructTreeFromCompactHTMLToken(const CompactHTMLToken&); @@ -199,15 +202,12 @@ class CORE_EXPORT HTMLDocumentParser : public ScriptableDocumentParser, void AttemptToRunDeferredScriptsAndEnd(); void end(); - bool ShouldUseThreading() const { return should_use_threading_; } + bool CanParseAsynchronously() const { return can_parse_asynchronously_; } bool IsParsingFragment() const; bool IsScheduledForUnpause() const; bool InPumpSession() const { return pump_session_nesting_level_ > 0; } - bool ShouldDelayEnd() const { - return InPumpSession() || IsPaused() || IsScheduledForUnpause() || - IsExecutingScript(); - } + bool ShouldDelayEnd() const; std::unique_ptr<HTMLPreloadScanner> CreatePreloadScanner( TokenPreloadScanner::ScannerType); @@ -234,7 +234,6 @@ class CORE_EXPORT HTMLDocumentParser : public ScriptableDocumentParser, scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner_; Member<HTMLParserScheduler> parser_scheduler_; - HTMLSourceTracker source_tracker_; TextPosition text_position_; // FIXME: last_chunk_before_pause_, tokenizer_, token_, and input_ should be @@ -247,6 +246,7 @@ class CORE_EXPORT HTMLDocumentParser : public ScriptableDocumentParser, // finalizer. base::WeakPtr<BackgroundHTMLParser> background_parser_; Member<HTMLResourcePreloader> preloader_; + Member<HTMLDocumentParserState> task_runner_state_; PreloadRequestStream queued_preloads_; // Metrics gathering and reporting @@ -262,9 +262,7 @@ class CORE_EXPORT HTMLDocumentParser : public ScriptableDocumentParser, // would require keeping track of token positions of preload requests. CompactHTMLToken* pending_csp_meta_token_; - TaskHandle resume_parsing_task_handle_; - - bool should_use_threading_; + bool can_parse_asynchronously_; bool end_was_delayed_; bool have_background_parser_; unsigned pump_session_nesting_level_; @@ -273,6 +271,7 @@ class CORE_EXPORT HTMLDocumentParser : public ScriptableDocumentParser, bool tried_loading_link_headers_; bool added_pending_parser_blocking_stylesheet_; bool is_waiting_for_stylesheets_; + ThreadScheduler* scheduler_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_document_parser_test.cc b/chromium/third_party/blink/renderer/core/html/parser/html_document_parser_test.cc index d74f07df6a4..9ebeb085475 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_document_parser_test.cc +++ b/chromium/third_party/blink/renderer/core/html/parser/html_document_parser_test.cc @@ -8,8 +8,8 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/core/html/html_document.h" #include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h" +#include "third_party/blink/renderer/core/html/parser/text_resource_decoder_builder.h" #include "third_party/blink/renderer/core/loader/prerenderer_client.h" -#include "third_party/blink/renderer/core/loader/text_resource_decoder_builder.h" #include "third_party/blink/renderer/core/testing/page_test_base.h" #include "third_party/blink/renderer/platform/heap/heap.h" diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_element_stack.cc b/chromium/third_party/blink/renderer/core/html/parser/html_element_stack.cc index a4a13996c81..61383ee77b1 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_element_stack.cc +++ b/chromium/third_party/blink/renderer/core/html/parser/html_element_stack.cc @@ -123,7 +123,7 @@ bool HTMLElementStack::ElementRecord::IsAbove(ElementRecord* other) const { return false; } -void HTMLElementStack::ElementRecord::Trace(Visitor* visitor) { +void HTMLElementStack::ElementRecord::Trace(Visitor* visitor) const { visitor->Trace(item_); visitor->Trace(next_); } @@ -541,7 +541,7 @@ HTMLElementStack::FurthestBlockForFormattingElement( return nullptr; } -void HTMLElementStack::Trace(Visitor* visitor) { +void HTMLElementStack::Trace(Visitor* visitor) const { visitor->Trace(top_); visitor->Trace(root_node_); visitor->Trace(head_element_); diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_element_stack.h b/chromium/third_party/blink/renderer/core/html/parser/html_element_stack.h index a433c82874c..8380d7c87ab 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_element_stack.h +++ b/chromium/third_party/blink/renderer/core/html/parser/html_element_stack.h @@ -60,7 +60,7 @@ class HTMLElementStack { ElementRecord* Next() const { return next_.Get(); } - void Trace(Visitor*); + void Trace(Visitor*) const; private: friend class HTMLElementStack; @@ -164,7 +164,7 @@ class HTMLElementStack { ContainerNode* RootNode() const; - void Trace(Visitor*); + void Trace(Visitor*) const; #ifndef NDEBUG void Show(); diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_entity_parser.cc b/chromium/third_party/blink/renderer/core/html/parser/html_entity_parser.cc index 2855991a54b..231cd4c52dc 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_entity_parser.cc +++ b/chromium/third_party/blink/renderer/core/html/parser/html_entity_parser.cc @@ -27,6 +27,7 @@ #include "third_party/blink/renderer/core/html/parser/html_entity_parser.h" +#include "base/notreached.h" #include "third_party/blink/renderer/core/html/parser/html_entity_search.h" #include "third_party/blink/renderer/core/html/parser/html_entity_table.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_formatting_element_list.h b/chromium/third_party/blink/renderer/core/html/parser/html_formatting_element_list.h index f9c4f2a13cb..bb2f43f327a 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_formatting_element_list.h +++ b/chromium/third_party/blink/renderer/core/html/parser/html_formatting_element_list.h @@ -75,7 +75,7 @@ class HTMLFormattingElementList { return !item_ ? !!element : item_->GetElement() != element; } - void Trace(Visitor* visitor) { visitor->Trace(item_); } + void Trace(Visitor* visitor) const { visitor->Trace(item_); } private: Member<HTMLStackItem> item_; @@ -120,7 +120,7 @@ class HTMLFormattingElementList { const Entry& at(wtf_size_t i) const { return entries_[i]; } Entry& at(wtf_size_t i) { return entries_[i]; } - void Trace(Visitor* visitor) { visitor->Trace(entries_); } + void Trace(Visitor* visitor) const { visitor->Trace(entries_); } #ifndef NDEBUG void Show(); diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_parser_idioms.cc b/chromium/third_party/blink/renderer/core/html/parser/html_parser_idioms.cc index 85a7b67b3c4..f66bbf0c583 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_parser_idioms.cc +++ b/chromium/third_party/blink/renderer/core/html/parser/html_parser_idioms.cc @@ -27,6 +27,7 @@ #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" +#include "third_party/blink/renderer/platform/wtf/text/character_visitor.h" #include "third_party/blink/renderer/platform/wtf/text/parsing_utilities.h" #include "third_party/blink/renderer/platform/wtf/text/string_hash.h" #include "third_party/blink/renderer/platform/wtf/text/string_to_number.h" @@ -36,47 +37,37 @@ namespace blink { -template <typename CharType> -static String StripLeadingAndTrailingHTMLSpaces(String string, - const CharType* characters, - unsigned length) { - unsigned num_leading_spaces = 0; - unsigned num_trailing_spaces = 0; - - for (; num_leading_spaces < length; ++num_leading_spaces) { - if (IsNotHTMLSpace<CharType>(characters[num_leading_spaces])) - break; - } +String StripLeadingAndTrailingHTMLSpaces(const String& string) { + unsigned length = string.length(); - if (num_leading_spaces == length) + if (!length) return string.IsNull() ? string : g_empty_atom.GetString(); - for (; num_trailing_spaces < length; ++num_trailing_spaces) { - if (IsNotHTMLSpace<CharType>(characters[length - num_trailing_spaces - 1])) - break; - } - - DCHECK_LT(num_leading_spaces + num_trailing_spaces, length); + return WTF::VisitCharacters(string, [&](const auto* chars, unsigned length) { + unsigned num_leading_spaces = 0; + unsigned num_trailing_spaces = 0; - if (!(num_leading_spaces | num_trailing_spaces)) - return string; + for (; num_leading_spaces < length; ++num_leading_spaces) { + if (IsNotHTMLSpace(chars[num_leading_spaces])) + break; + } - return string.Substring(num_leading_spaces, - length - (num_leading_spaces + num_trailing_spaces)); -} + if (num_leading_spaces == length) + return string.IsNull() ? string : g_empty_atom.GetString(); -String StripLeadingAndTrailingHTMLSpaces(const String& string) { - unsigned length = string.length(); + for (; num_trailing_spaces < length; ++num_trailing_spaces) { + if (IsNotHTMLSpace(chars[length - num_trailing_spaces - 1])) + break; + } - if (!length) - return string.IsNull() ? string : g_empty_atom.GetString(); + DCHECK_LT(num_leading_spaces + num_trailing_spaces, length); - if (string.Is8Bit()) - return StripLeadingAndTrailingHTMLSpaces<LChar>( - string, string.Characters8(), length); + if (!(num_leading_spaces | num_trailing_spaces)) + return string; - return StripLeadingAndTrailingHTMLSpaces<UChar>(string, string.Characters16(), - length); + return string.Substring(num_leading_spaces, length - (num_leading_spaces + + num_trailing_spaces)); + }); } String SerializeForNumberType(const Decimal& number) { @@ -159,22 +150,6 @@ template <typename CharacterType> static bool ParseHTMLIntegerInternal(const CharacterType* position, const CharacterType* end, int& value) { - // Step 4 - SkipWhile<CharacterType, IsHTMLSpace<CharacterType>>(position, end); - - // Step 5 - if (position == end) - return false; - DCHECK_LT(position, end); - - bool ok; - WTF::NumberParsingOptions options( - WTF::NumberParsingOptions::kAcceptTrailingGarbage | - WTF::NumberParsingOptions::kAcceptLeadingPlus); - int wtf_value = CharactersToInt(position, end - position, options, &ok); - if (ok) - value = wtf_value; - return ok; } // http://www.whatwg.org/specs/web-apps/current-work/#rules-for-parsing-integers @@ -182,46 +157,31 @@ bool ParseHTMLInteger(const String& input, int& value) { // Step 1 // Step 2 unsigned length = input.length(); - if (!length || input.Is8Bit()) { - const LChar* start = input.Characters8(); - return ParseHTMLIntegerInternal(start, start + length, value); - } + if (length == 0) + return false; - const UChar* start = input.Characters16(); - return ParseHTMLIntegerInternal(start, start + length, value); -} - -template <typename CharacterType> -static WTF::NumberParsingResult ParseHTMLNonNegativeIntegerInternal( - const CharacterType* position, - const CharacterType* end, - unsigned& value) { - // This function is an implementation of the following algorithm: - // https://html.spec.whatwg.org/C/#rules-for-parsing-non-negative-integers - // However, in order to support integers >= 2^31, we fold [1] into this. - // 'Step N' in the following comments refers to [1]. - // - // [1] - // https://html.spec.whatwg.org/C/#rules-for-parsing-integers - - // Step 4: Skip whitespace. - SkipWhile<CharacterType, IsHTMLSpace<CharacterType>>(position, end); - - // Step 5: If position is past the end of input, return an error. - if (position == end) - return WTF::NumberParsingResult::kError; - DCHECK_LT(position, end); - - WTF::NumberParsingResult result; - WTF::NumberParsingOptions options( - WTF::NumberParsingOptions::kAcceptTrailingGarbage | - WTF::NumberParsingOptions::kAcceptLeadingPlus | - WTF::NumberParsingOptions::kAcceptMinusZeroForUnsigned); - unsigned wtf_value = - CharactersToUInt(position, end - position, options, &result); - if (result == WTF::NumberParsingResult::kSuccess) - value = wtf_value; - return result; + return WTF::VisitCharacters( + input, [&](const auto* position, unsigned length) { + using CharacterType = std::decay_t<decltype(*position)>; + const auto* end = position + length; + + // Step 4 + SkipWhile<CharacterType, IsHTMLSpace<CharacterType>>(position, end); + + // Step 5 + if (position == end) + return false; + DCHECK_LT(position, end); + + bool ok; + WTF::NumberParsingOptions options( + WTF::NumberParsingOptions::kAcceptTrailingGarbage | + WTF::NumberParsingOptions::kAcceptLeadingPlus); + int wtf_value = CharactersToInt(position, end - position, options, &ok); + if (ok) + value = wtf_value; + return ok; + }); } static WTF::NumberParsingResult ParseHTMLNonNegativeIntegerInternal( @@ -230,13 +190,39 @@ static WTF::NumberParsingResult ParseHTMLNonNegativeIntegerInternal( unsigned length = input.length(); if (length == 0) return WTF::NumberParsingResult::kError; - if (input.Is8Bit()) { - const LChar* start = input.Characters8(); - return ParseHTMLNonNegativeIntegerInternal(start, start + length, value); - } - const UChar* start = input.Characters16(); - return ParseHTMLNonNegativeIntegerInternal(start, start + length, value); + return WTF::VisitCharacters( + input, [&](const auto* position, unsigned length) { + using CharacterType = std::decay_t<decltype(*position)>; + const auto* end = position + length; + + // This function is an implementation of the following algorithm: + // https://html.spec.whatwg.org/C/#rules-for-parsing-non-negative-integers + // However, in order to support integers >= 2^31, we fold [1] into this. + // 'Step N' in the following comments refers to [1]. + // + // [1] + // https://html.spec.whatwg.org/C/#rules-for-parsing-integers + + // Step 4: Skip whitespace. + SkipWhile<CharacterType, IsHTMLSpace<CharacterType>>(position, end); + + // Step 5: If position is past the end of input, return an error. + if (position == end) + return WTF::NumberParsingResult::kError; + DCHECK_LT(position, end); + + WTF::NumberParsingResult result; + WTF::NumberParsingOptions options( + WTF::NumberParsingOptions::kAcceptTrailingGarbage | + WTF::NumberParsingOptions::kAcceptLeadingPlus | + WTF::NumberParsingOptions::kAcceptMinusZeroForUnsigned); + unsigned wtf_value = + CharactersToUInt(position, end - position, options, &result); + if (result == WTF::NumberParsingResult::kSuccess) + value = wtf_value; + return result; + }); } // https://html.spec.whatwg.org/C/#rules-for-parsing-non-negative-integers @@ -281,32 +267,38 @@ static Vector<double> ParseHTMLListOfFloatingPointNumbersInternal( const CharacterType* position, const CharacterType* end) { Vector<double> numbers; - SkipWhile<CharacterType, IsSpaceOrDelimiter>(position, end); - - while (position < end) { - SkipWhile<CharacterType, IsNotSpaceDelimiterOrNumberStart>(position, end); - - const CharacterType* unparsed_number_start = position; - SkipUntil<CharacterType, IsSpaceOrDelimiter>(position, end); - - size_t parsed_length = 0; - double number = CharactersToDouble( - unparsed_number_start, position - unparsed_number_start, parsed_length); - numbers.push_back(CheckDoubleValue(number, parsed_length != 0, 0)); - - SkipWhile<CharacterType, IsSpaceOrDelimiter>(position, end); - } return numbers; } // https://html.spec.whatwg.org/C/#rules-for-parsing-a-list-of-floating-point-numbers Vector<double> ParseHTMLListOfFloatingPointNumbers(const String& input) { + Vector<double> numbers; unsigned length = input.length(); - if (!length || input.Is8Bit()) - return ParseHTMLListOfFloatingPointNumbersInternal( - input.Characters8(), input.Characters8() + length); - return ParseHTMLListOfFloatingPointNumbersInternal( - input.Characters16(), input.Characters16() + length); + if (!length) + return numbers; + + WTF::VisitCharacters(input, [&](const auto* position, unsigned length) { + using CharacterType = std::decay_t<decltype(*position)>; + const auto* end = position + length; + + SkipWhile<CharacterType, IsSpaceOrDelimiter>(position, end); + + while (position < end) { + SkipWhile<CharacterType, IsNotSpaceDelimiterOrNumberStart>(position, end); + + const CharacterType* unparsed_number_start = position; + SkipUntil<CharacterType, IsSpaceOrDelimiter>(position, end); + + size_t parsed_length = 0; + double number = + CharactersToDouble(unparsed_number_start, + position - unparsed_number_start, parsed_length); + numbers.push_back(CheckDoubleValue(number, parsed_length != 0, 0)); + + SkipWhile<CharacterType, IsSpaceOrDelimiter>(position, end); + } + }); + return numbers; } static const char kCharsetString[] = "charset"; diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_parser_options.cc b/chromium/third_party/blink/renderer/core/html/parser/html_parser_options.cc index a5c4119348f..1ca1e1b3152 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_parser_options.cc +++ b/chromium/third_party/blink/renderer/core/html/parser/html_parser_options.cc @@ -26,20 +26,22 @@ #include "third_party/blink/renderer/core/html/parser/html_parser_options.h" #include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" namespace blink { HTMLParserOptions::HTMLParserOptions(Document* document) { - if (!document || !document->GetFrame()) + auto* window = document ? document->domWindow() : nullptr; + if (!window) return; scripting_flag = (document->GetSettings()->GetParserScriptingFlagPolicy() == ParserScriptingFlagPolicy::kEnabled) || - document->CanExecuteScripts(kNotAboutToExecuteScript); + window->CanExecuteScripts(kNotAboutToExecuteScript); priority_hints_origin_trial_enabled = - RuntimeEnabledFeatures::PriorityHintsEnabled(document); + RuntimeEnabledFeatures::PriorityHintsEnabled(window); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_parser_scheduler.cc b/chromium/third_party/blink/renderer/core/html/parser/html_parser_scheduler.cc index 1559a1624ba..871214fd6b1 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_parser_scheduler.cc +++ b/chromium/third_party/blink/renderer/core/html/parser/html_parser_scheduler.cc @@ -51,7 +51,7 @@ HTMLParserScheduler::HTMLParserScheduler( HTMLParserScheduler::~HTMLParserScheduler() = default; -void HTMLParserScheduler::Trace(Visitor* visitor) { +void HTMLParserScheduler::Trace(Visitor* visitor) const { visitor->Trace(parser_); } diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_parser_scheduler.h b/chromium/third_party/blink/renderer/core/html/parser/html_parser_scheduler.h index 87d35d4a9f8..a477674e510 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_parser_scheduler.h +++ b/chromium/third_party/blink/renderer/core/html/parser/html_parser_scheduler.h @@ -66,7 +66,7 @@ class HTMLParserScheduler final : public GarbageCollected<HTMLParserScheduler> { void Detach(); // Clear active tasks if any. - void Trace(Visitor*); + void Trace(Visitor*) const; private: bool ShouldYield(const SpeculationsPumpSession&, bool starting_script) const; diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc b/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc index f80ec1268db..4a020714905 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc +++ b/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc @@ -295,13 +295,6 @@ class TokenPreloadScanner::StartTagScanner { request->SetCharset(Charset()); request->SetDefer(defer_); - LoadingAttrValue effective_loading_attr_value = loading_attr_value_; - // If the 'lazyload' feature policy is enforced, the attribute value - // loading='eager' is considered as 'auto'. - if (effective_loading_attr_value == LoadingAttrValue::kEager && - document_parameters.lazyload_policy_enforced) { - effective_loading_attr_value = LoadingAttrValue::kAuto; - } if (type == ResourceType::kImage && Match(tag_impl_, html_names::kImgTag) && IsLazyLoadImageDeferable(document_parameters)) { return nullptr; @@ -559,14 +552,7 @@ class TokenPreloadScanner::StartTagScanner { return false; } - // If the 'lazyload' feature policy is enforced, the attribute value - // loading='eager' is considered as 'auto'. - LoadingAttrValue effective_loading_attr_value = loading_attr_value_; - if (effective_loading_attr_value == LoadingAttrValue::kEager && - document_parameters.lazyload_policy_enforced) { - effective_loading_attr_value = LoadingAttrValue::kAuto; - } - switch (effective_loading_attr_value) { + switch (loading_attr_value_) { case LoadingAttrValue::kEager: return false; case LoadingAttrValue::kLazy: @@ -1114,7 +1100,6 @@ CachedDocumentParameters::CachedDocumentParameters(Document* document) { referrer_policy = document->GetReferrerPolicy(); integrity_features = SubresourceIntegrityHelper::GetFeatures(document->GetExecutionContext()); - lazyload_policy_enforced = document->IsLazyLoadPolicyEnforced(); if (document->Loader() && document->Loader()->GetFrame()) { lazy_load_image_setting = document->Loader()->GetFrame()->GetLazyLoadImageSetting(); diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner.h b/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner.h index 429b1495788..7a2549801d1 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner.h +++ b/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner.h @@ -67,7 +67,6 @@ struct CORE_EXPORT CachedDocumentParameters { bool viewport_meta_enabled; network::mojom::ReferrerPolicy referrer_policy; SubresourceIntegrity::IntegrityFeatures integrity_features; - bool lazyload_policy_enforced; LocalFrame::LazyLoadImageSetting lazy_load_image_setting; WeakPersistent<LazyLoadImageObserver> lazy_load_image_observer; }; diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc b/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc index a19d93de8d2..7c164f761b5 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc +++ b/chromium/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc @@ -11,6 +11,7 @@ #include "third_party/blink/public/platform/web_runtime_features.h" #include "third_party/blink/public/platform/web_url_loader_mock_factory.h" #include "third_party/blink/renderer/core/css/media_values_cached.h" +#include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/core/html/cross_origin_attribute.h" #include "third_party/blink/renderer/core/html/parser/html_parser_options.h" @@ -256,7 +257,7 @@ class HTMLPreloadScannerTest : public PageTestBase { kViewportEnabled); GetDocument().GetSettings()->SetDoHtmlPreloadScanning(preload_state == kPreloadEnabled); - GetDocument().SetReferrerPolicy(document_referrer_policy); + GetFrame().DomWindow()->SetReferrerPolicy(document_referrer_policy); scanner_ = std::make_unique<HTMLPreloadScanner>( options, document_url, std::make_unique<CachedDocumentParameters>(&GetDocument()), @@ -1225,7 +1226,6 @@ TEST_F(HTMLPreloadScannerTest, LazyLoadImage_DisabledForSmallImages) { ScopedRestrictAutomaticLazyImageLoadingToDataSaverForTest scoped_restrict_automatic_lazy_image_loading_to_data_saver_for_test( false); - GetDocument().GetSettings()->SetLazyLoadEnabled(true); RunSetUp(kViewportEnabled); LazyLoadImageTestCase test_cases[] = { {"<img src='foo.jpg'>", true}, @@ -1245,7 +1245,6 @@ TEST_F(HTMLPreloadScannerTest, LazyLoadImage_DisabledForSmallImages) { TEST_F(HTMLPreloadScannerTest, LazyLoadImage_FeatureDisabledWithAttribute) { ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test(false); - GetDocument().GetSettings()->SetLazyLoadEnabled(true); RunSetUp(kViewportEnabled); LazyLoadImageTestCase test_cases[] = { {"<img src='foo.jpg' loading='auto'>", false}, @@ -1264,7 +1263,6 @@ TEST_F(HTMLPreloadScannerTest, ScopedRestrictAutomaticLazyImageLoadingToDataSaverForTest scoped_restrict_automatic_lazy_image_loading_to_data_saver_for_test( false); - GetDocument().GetSettings()->SetLazyLoadEnabled(true); RunSetUp(kViewportEnabled); LazyLoadImageTestCase test_cases[] = { {"<img src='foo.jpg' loading='auto'>", true}, @@ -1282,7 +1280,6 @@ TEST_F(HTMLPreloadScannerTest, TEST_F(HTMLPreloadScannerTest, LazyLoadImage_FeatureExplicitEnabledWithAttribute) { ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test(true); - GetDocument().GetSettings()->SetLazyLoadEnabled(true); RunSetUp(kViewportEnabled); LazyLoadImageTestCase test_cases[] = { {"<img src='foo.jpg' loading='auto'>", false}, @@ -1302,7 +1299,6 @@ TEST_F(HTMLPreloadScannerTest, ScopedRestrictAutomaticLazyImageLoadingToDataSaverForTest scoped_restrict_automatic_lazy_image_loading_to_data_saver_for_test( false); - GetDocument().GetSettings()->SetLazyLoadEnabled(true); RunSetUp(kViewportEnabled); PreloadScannerTestCase test_cases[] = { {"http://example.test", "<img src='foo.jpg' height='20px' width='20px'>", @@ -1340,7 +1336,6 @@ TEST_F(HTMLPreloadScannerTest, LazyLoadImage_FeatureExplicitPreloadForLargeImages) { // Large images should not be preloaded, when loading is lazy. ScopedLazyImageLoadingForTest scoped_lazy_image_loading_for_test(true); - GetDocument().GetSettings()->SetLazyLoadEnabled(true); RunSetUp(kViewportEnabled); PreloadScannerTestCase test_cases[] = { {"http://example.test", @@ -1366,30 +1361,27 @@ TEST_F(HTMLPreloadScannerTest, Test(test_case); } +// TODO(domfarolino): Before merging, can we just delete this test, since we no +// longer have metadata fetching? TEST_F(HTMLPreloadScannerTest, LazyLoadImage_DisableMetadataFetch) { - GetDocument().GetSettings()->SetLazyLoadEnabled(true); struct TestCase { bool automatic_lazy_image_loading_enabled; const char* loading_attr_value; bool expected_is_preload; - // If preload happens, whether it is a fetch of placeholder or full image. - bool expected_is_placeholder_fetch; }; const TestCase test_cases[] = { - // The lazyload eligible cases should not trigger any preload when - // metadata fetch feature disabled, and trigger placeholder fetch if - // metadata fetch feature is active. - {false, "lazy", false, false}, - {true, "lazy", false, false}, - {true, "auto", false, false}, + // The lazyload eligible cases should not trigger a preload. + {false, "lazy", false}, + {true, "lazy", false}, + {true, "auto", false}, // Lazyload ineligible case. - {false, "auto", true, false}, + {false, "auto", true}, // Full image should be fetched when loading='eager' irrespective of - // automatic lazyload or metadata fetch feature states. - {false, "eager", true, false}, - {true, "eager", true, false}, + // automatic lazyload feature state. + {false, "eager", true}, + {true, "eager", true}, }; for (const auto& test_case : test_cases) { ScopedAutomaticLazyImageLoadingForTest @@ -1402,8 +1394,7 @@ TEST_F(HTMLPreloadScannerTest, LazyLoadImage_DisableMetadataFetch) { const std::string img_html = base::StringPrintf( "<img src='foo.jpg' loading='%s'>", test_case.loading_attr_value); if (test_case.expected_is_preload) { - LazyLoadImageTestCase test_preload = { - img_html.c_str(), test_case.expected_is_placeholder_fetch}; + LazyLoadImageTestCase test_preload = {img_html.c_str(), false}; Test(test_preload); } else { PreloadScannerTestCase test_no_preload = { @@ -1421,7 +1412,6 @@ TEST_F(HTMLPreloadScannerTest, ScopedRestrictAutomaticLazyImageLoadingToDataSaverForTest scoped_restrict_automatic_lazy_image_loading_to_data_saver_for_test( false); - GetDocument().GetSettings()->SetLazyLoadEnabled(true); GetDocument().GetSettings()->SetLazyImageFirstKFullyLoadUnknown(1); RunSetUp(kViewportEnabled); @@ -1438,7 +1428,6 @@ TEST_F(HTMLPreloadScannerTest, LazyLoadImage_FirstKImagesAppliesForAutomatic) { ScopedRestrictAutomaticLazyImageLoadingToDataSaverForTest scoped_restrict_automatic_lazy_image_loading_to_data_saver_for_test( false); - GetDocument().GetSettings()->SetLazyLoadEnabled(true); GetDocument().GetSettings()->SetLazyImageFirstKFullyLoadUnknown(1); RunSetUp(kViewportEnabled); @@ -1456,7 +1445,6 @@ TEST_F(HTMLPreloadScannerTest, ScopedRestrictAutomaticLazyImageLoadingToDataSaverForTest scoped_restrict_automatic_lazy_image_loading_to_data_saver_for_test( false); - GetDocument().GetSettings()->SetLazyLoadEnabled(true); GetDocument().GetSettings()->SetLazyImageFirstKFullyLoadUnknown(1); RunSetUp(kViewportEnabled); diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader.cc b/chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader.cc index 4a95b4a9b2f..0dca6283357 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader.cc +++ b/chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader.cc @@ -45,7 +45,7 @@ namespace blink { HTMLResourcePreloader::HTMLResourcePreloader(Document& document) : document_(document) {} -void HTMLResourcePreloader::Trace(Visitor* visitor) { +void HTMLResourcePreloader::Trace(Visitor* visitor) const { visitor->Trace(document_); } @@ -122,8 +122,7 @@ bool HTMLResourcePreloader::AllowPreloadRequest(PreloadRequest* preload) const { case ResourceType::kCSSStyleSheet: return true; case ResourceType::kFont: - return base::FeatureList::IsEnabled( - features::kLightweightNoStatePrefetch_FetchFonts); + return false; case ResourceType::kScript: // We might skip all script. if (GetFieldTrialParamByFeatureAsBool( diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader.h b/chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader.h index 263ead7891e..ef89b2a67b9 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader.h +++ b/chromium/third_party/blink/renderer/core/html/parser/html_resource_preloader.h @@ -46,7 +46,7 @@ class CORE_EXPORT HTMLResourcePreloader public: explicit HTMLResourcePreloader(Document&); - void Trace(Visitor*); + void Trace(Visitor*) const; protected: void Preload(std::unique_ptr<PreloadRequest>) override; diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_source_tracker.cc b/chromium/third_party/blink/renderer/core/html/parser/html_source_tracker.cc deleted file mode 100644 index 692440aa063..00000000000 --- a/chromium/third_party/blink/renderer/core/html/parser/html_source_tracker.cc +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2010 Adam Barth. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "third_party/blink/renderer/core/html/parser/html_source_tracker.h" - -#include "third_party/blink/renderer/core/html/parser/html_tokenizer.h" -#include "third_party/blink/renderer/platform/wtf/text/string_builder.h" - -namespace blink { - -HTMLSourceTracker::HTMLSourceTracker() : is_started_(false) {} - -void HTMLSourceTracker::Start(SegmentedString& current_input, - HTMLTokenizer* tokenizer, - HTMLToken& token) { - if (token.GetType() == HTMLToken::kUninitialized && !is_started_) { - previous_source_.Clear(); - if (NeedToCheckTokenizerBuffer(tokenizer) && - tokenizer->NumberOfBufferedCharacters()) - previous_source_ = tokenizer->BufferedCharacters(); - } else { - previous_source_.Append(current_source_); - } - - is_started_ = true; - current_source_ = current_input; - token.SetBaseOffset(current_source_.NumberOfCharactersConsumed() - - previous_source_.length()); -} - -void HTMLSourceTracker::end(SegmentedString& current_input, - HTMLTokenizer* tokenizer, - HTMLToken& token) { - is_started_ = false; - - cached_source_for_token_ = String(); - - // FIXME: This work should really be done by the HTMLTokenizer. - wtf_size_t number_of_buffered_characters = 0u; - if (NeedToCheckTokenizerBuffer(tokenizer)) { - number_of_buffered_characters = tokenizer->NumberOfBufferedCharacters(); - } - token.end(current_input.NumberOfCharactersConsumed() - - number_of_buffered_characters); -} - -String HTMLSourceTracker::SourceForToken(const HTMLToken& token) { - if (!cached_source_for_token_.IsEmpty()) - return cached_source_for_token_; - - wtf_size_t length; - if (token.GetType() == HTMLToken::kEndOfFile) { - // Consume the remainder of the input, omitting the null character we use to - // mark the end of the file. - length = previous_source_.length() + current_source_.length() - 1; - } else { - DCHECK(!token.StartIndex()); - length = static_cast<wtf_size_t>(token.EndIndex() - token.StartIndex()); - } - - StringBuilder source; - source.ReserveCapacity(length); - - size_t i = 0; - for (; i < length && !previous_source_.IsEmpty(); ++i) { - source.Append(previous_source_.CurrentChar()); - previous_source_.Advance(); - } - for (; i < length; ++i) { - DCHECK(!current_source_.IsEmpty()); - source.Append(current_source_.CurrentChar()); - current_source_.Advance(); - } - - cached_source_for_token_ = source.ToString(); - return cached_source_for_token_; -} - -bool HTMLSourceTracker::NeedToCheckTokenizerBuffer(HTMLTokenizer* tokenizer) { - HTMLTokenizer::State state = tokenizer->GetState(); - // The temporary buffer must not be used unconditionally, because in some - // states (e.g. ScriptDataDoubleEscapedStartState), data is appended to - // both the temporary buffer and the token itself. - return state == HTMLTokenizer::kDataState || - HTMLTokenizer::IsEndTagBufferingState(state); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_source_tracker.h b/chromium/third_party/blink/renderer/core/html/parser/html_source_tracker.h deleted file mode 100644 index 1e87b08935e..00000000000 --- a/chromium/third_party/blink/renderer/core/html/parser/html_source_tracker.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2010 Adam Barth. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_PARSER_HTML_SOURCE_TRACKER_H_ -#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_PARSER_HTML_SOURCE_TRACKER_H_ - -#include "base/macros.h" -#include "third_party/blink/renderer/core/html/parser/html_token.h" -#include "third_party/blink/renderer/platform/text/segmented_string.h" -#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" - -namespace blink { - -class HTMLTokenizer; - -class HTMLSourceTracker { - DISALLOW_NEW(); - - public: - HTMLSourceTracker(); - - // FIXME: Once we move "end" into HTMLTokenizer, rename "start" to - // something that makes it obvious that this method can be called multiple - // times. - void Start(SegmentedString&, HTMLTokenizer*, HTMLToken&); - void end(SegmentedString&, HTMLTokenizer*, HTMLToken&); - - String SourceForToken(const HTMLToken&); - - private: - bool NeedToCheckTokenizerBuffer(HTMLTokenizer*); - - SegmentedString previous_source_; - SegmentedString current_source_; - - String cached_source_for_token_; - - bool is_started_; - - DISALLOW_COPY_AND_ASSIGN(HTMLSourceTracker); -}; - -} // namespace blink - -#endif diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_srcset_parser.cc b/chromium/third_party/blink/renderer/core/html/parser/html_srcset_parser.cc index 7d3025bbee5..bdbda40d96d 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_srcset_parser.cc +++ b/chromium/third_party/blink/renderer/core/html/parser/html_srcset_parser.cc @@ -46,6 +46,7 @@ #include "third_party/blink/renderer/platform/json/json_values.h" #include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h" +#include "third_party/blink/renderer/platform/wtf/text/character_visitor.h" #include "third_party/blink/renderer/platform/wtf/text/parsing_utilities.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" #include "third_party/blink/renderer/platform/wtf/text/string_to_number.h" @@ -275,12 +276,10 @@ static bool ParseDescriptors(const String& attribute, DescriptorParsingResult& result, Document* document) { // FIXME: See if StringView can't be extended to replace DescriptorToken here. - if (attribute.Is8Bit()) { - return ParseDescriptors(attribute.Characters8(), descriptors, result, - document); - } - return ParseDescriptors(attribute.Characters16(), descriptors, result, - document); + return WTF::VisitCharacters( + attribute, [&](const auto* chars, unsigned length) { + return ParseDescriptors(chars, descriptors, result, document); + }); } // http://picture.responsiveimages.org/#parse-srcset-attr diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_stack_item.h b/chromium/third_party/blink/renderer/core/html/parser/html_stack_item.h index 3d7bc5aa4b3..9fcf4500e50 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_stack_item.h +++ b/chromium/third_party/blink/renderer/core/html/parser/html_stack_item.h @@ -205,7 +205,7 @@ class HTMLStackItem final : public GarbageCollected<HTMLStackItem> { tag_name == html_names::kWbrTag || tag_name == html_names::kXmpTag; } - void Trace(Visitor* visitor) { visitor->Trace(node_); } + void Trace(Visitor* visitor) const { visitor->Trace(node_); } private: Member<ContainerNode> node_; diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder.cc b/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder.cc index c6551c6cfea..2c24eee68fa 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder.cc +++ b/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder.cc @@ -33,6 +33,7 @@ #include "third_party/blink/renderer/core/dom/document_fragment.h" #include "third_party/blink/renderer/core/dom/element_traversal.h" #include "third_party/blink/renderer/core/dom/shadow_root.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/frame/web_feature.h" #include "third_party/blink/renderer/core/html/forms/html_form_control_element.h" #include "third_party/blink/renderer/core/html/forms/html_form_element.h" @@ -57,6 +58,7 @@ #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" #include "third_party/blink/renderer/platform/text/platform_locale.h" #include "third_party/blink/renderer/platform/wtf/text/character_names.h" +#include "third_party/blink/renderer/platform/wtf/text/character_visitor.h" namespace blink { @@ -165,10 +167,9 @@ class HTMLTreeBuilder::CharacterTokenBuffer { } void GiveRemainingTo(StringBuilder& recipient) { - if (characters_->Is8Bit()) - recipient.Append(characters_->Characters8() + current_, end_ - current_); - else - recipient.Append(characters_->Characters16() + current_, end_ - current_); + WTF::VisitCharacters(*characters_, [&](const auto* chars, unsigned length) { + recipient.Append(chars + current_, end_ - current_); + }); current_ = end_; } @@ -277,12 +278,12 @@ void HTMLTreeBuilder::FragmentParsingContext::Init(DocumentFragment* fragment, context_element, HTMLStackItem::kItemForContextElement); } -void HTMLTreeBuilder::FragmentParsingContext::Trace(Visitor* visitor) { +void HTMLTreeBuilder::FragmentParsingContext::Trace(Visitor* visitor) const { visitor->Trace(fragment_); visitor->Trace(context_element_stack_item_); } -void HTMLTreeBuilder::Trace(Visitor* visitor) { +void HTMLTreeBuilder::Trace(Visitor* visitor) const { visitor->Trace(fragment_context_); visitor->Trace(tree_); visitor->Trace(parser_); @@ -896,7 +897,8 @@ void HTMLTreeBuilder::ProcessTemplateStartTag(AtomicHTMLToken* token) { DeclarativeShadowRootType declarative_shadow_root_type( DeclarativeShadowRootType::kNone); - if (RuntimeEnabledFeatures::DeclarativeShadowDOMEnabled()) { + if (RuntimeEnabledFeatures::DeclarativeShadowDOMEnabled( + tree_.CurrentNode()->GetExecutionContext())) { if (Attribute* type_attribute = token->GetAttributeItem(html_names::kShadowrootAttr)) { String shadow_mode = type_attribute->Value(); @@ -942,7 +944,8 @@ bool HTMLTreeBuilder::ProcessTemplateEndTag(AtomicHTMLToken* token) { tree_.ActiveFormattingElements()->ClearToLastMarker(); template_insertion_modes_.pop_back(); ResetInsertionModeAppropriately(); - if (RuntimeEnabledFeatures::DeclarativeShadowDOMEnabled() && + if (RuntimeEnabledFeatures::DeclarativeShadowDOMEnabled( + shadow_host_stack_item->GetNode()->GetExecutionContext()) && template_stack_item) { DCHECK(template_stack_item->IsElementNode()); HTMLTemplateElement* template_element = @@ -951,29 +954,32 @@ bool HTMLTreeBuilder::ProcessTemplateEndTag(AtomicHTMLToken* token) { // attribute with the name "shadowroot" whose value was an ASCII // case-insensitive match for the strings "open" or "closed", then stop this // algorithm. - // 10. If the adjusted current node is the topmost element in the stack of - // open elements, then stop this algorithm. - if (template_element->IsDeclarativeShadowRoot() && - shadow_host_stack_item->GetNode() != tree_.OpenElements()->RootNode()) { - DCHECK(shadow_host_stack_item); - DCHECK(shadow_host_stack_item->IsElementNode()); - UseCounter::Count(shadow_host_stack_item->GetElement()->GetDocument(), - WebFeature::kDeclarativeShadowRoot); - bool delegates_focus = template_stack_item->GetAttributeItem( - html_names::kShadowrootdelegatesfocusAttr); - // TODO(crbug.com/1063157): Add an attribute for imperative slot - // assignment. - bool manual_slotting = false; - shadow_host_stack_item->GetElement()->AttachDeclarativeShadowRoot( - template_element, - template_element->GetDeclarativeShadowRootType() == - DeclarativeShadowRootType::kOpen - ? ShadowRootType::kOpen - : ShadowRootType::kClosed, - delegates_focus ? FocusDelegation::kDelegateFocus - : FocusDelegation::kNone, - manual_slotting ? SlotAssignmentMode::kManual - : SlotAssignmentMode::kAuto); + if (template_element->IsDeclarativeShadowRoot()) { + if (shadow_host_stack_item->GetNode() == + tree_.OpenElements()->RootNode()) { + // 10. If the adjusted current node is the topmost element in the stack + // of open elements, then stop this algorithm. + template_element->SetDeclarativeShadowRootType( + DeclarativeShadowRootType::kNone); + } else { + DCHECK(shadow_host_stack_item); + DCHECK(shadow_host_stack_item->IsElementNode()); + bool delegates_focus = template_stack_item->GetAttributeItem( + html_names::kShadowrootdelegatesfocusAttr); + // TODO(crbug.com/1063157): Add an attribute for imperative slot + // assignment. + bool manual_slotting = false; + shadow_host_stack_item->GetElement()->AttachDeclarativeShadowRoot( + template_element, + template_element->GetDeclarativeShadowRootType() == + DeclarativeShadowRootType::kOpen + ? ShadowRootType::kOpen + : ShadowRootType::kClosed, + delegates_focus ? FocusDelegation::kDelegateFocus + : FocusDelegation::kNone, + manual_slotting ? SlotAssignmentMode::kManual + : SlotAssignmentMode::kAuto); + } } } return true; diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder.h b/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder.h index 64dc15e3319..74c358cbc32 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder.h +++ b/chromium/third_party/blink/renderer/core/html/parser/html_tree_builder.h @@ -61,7 +61,7 @@ class HTMLTreeBuilder final : public GarbageCollected<HTMLTreeBuilder> { ParserContentPolicy, const HTMLParserOptions&); ~HTMLTreeBuilder(); - void Trace(Visitor*); + void Trace(Visitor*) const; const HTMLElementStack* OpenElements() const { return tree_.OpenElements(); } @@ -216,7 +216,7 @@ class HTMLTreeBuilder final : public GarbageCollected<HTMLTreeBuilder> { return context_element_stack_item_.Get(); } - void Trace(Visitor*); + void Trace(Visitor*) const; private: Member<DocumentFragment> fragment_; diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_view_source_parser.cc b/chromium/third_party/blink/renderer/core/html/parser/html_view_source_parser.cc index 15f8c4960d0..4d1bd538e0e 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_view_source_parser.cc +++ b/chromium/third_party/blink/renderer/core/html/parser/html_view_source_parser.cc @@ -26,10 +26,10 @@ #include "third_party/blink/renderer/core/html/parser/html_view_source_parser.h" #include <memory> -#include "third_party/blink/renderer/core/dom/dom_implementation.h" #include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h" #include "third_party/blink/renderer/core/html/parser/html_parser_options.h" #include "third_party/blink/renderer/core/html/parser/html_token.h" +#include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h" namespace blink { @@ -38,18 +38,18 @@ HTMLViewSourceParser::HTMLViewSourceParser(HTMLViewSourceDocument& document, : DecodedDataDocumentParser(document), tokenizer_( std::make_unique<HTMLTokenizer>(HTMLParserOptions(&document))) { - if (mime_type != "text/html" && !DOMImplementation::IsXMLMIMEType(mime_type)) + if (mime_type != "text/html" && !MIMETypeRegistry::IsXMLMIMEType(mime_type)) tokenizer_->SetState(HTMLTokenizer::kPLAINTEXTState); } void HTMLViewSourceParser::PumpTokenizer() { while (true) { - source_tracker_.Start(input_.Current(), tokenizer_.get(), token_); + StartTracker(input_.Current(), tokenizer_.get(), token_); if (!tokenizer_->NextToken(input_.Current(), token_)) return; - source_tracker_.end(input_.Current(), tokenizer_.get(), token_); + EndTracker(input_.Current(), tokenizer_.get(), token_); - GetDocument()->AddSource(source_tracker_.SourceForToken(token_), token_); + GetDocument()->AddSource(SourceForToken(token_), token_); // FIXME: The tokenizer should do this work for us. if (token_.GetType() == HTMLToken::kStartTag) @@ -75,4 +75,80 @@ void HTMLViewSourceParser::Finish() { } } +void HTMLViewSourceParser::StartTracker(SegmentedString& current_input, + HTMLTokenizer* tokenizer, + HTMLToken& token) { + if (token.GetType() == HTMLToken::kUninitialized && !tracker_is_started_) { + previous_source_.Clear(); + if (NeedToCheckTokenizerBuffer(tokenizer) && + tokenizer->NumberOfBufferedCharacters()) + previous_source_ = tokenizer->BufferedCharacters(); + } else { + previous_source_.Append(current_source_); + } + + tracker_is_started_ = true; + current_source_ = current_input; + token.SetBaseOffset(current_source_.NumberOfCharactersConsumed() - + previous_source_.length()); +} + +void HTMLViewSourceParser::EndTracker(SegmentedString& current_input, + HTMLTokenizer* tokenizer, + HTMLToken& token) { + tracker_is_started_ = false; + + cached_source_for_token_ = String(); + + // FIXME: This work should really be done by the HTMLTokenizer. + wtf_size_t number_of_buffered_characters = 0u; + if (NeedToCheckTokenizerBuffer(tokenizer)) { + number_of_buffered_characters = tokenizer->NumberOfBufferedCharacters(); + } + token.end(current_input.NumberOfCharactersConsumed() - + number_of_buffered_characters); +} + +String HTMLViewSourceParser::SourceForToken(const HTMLToken& token) { + if (!cached_source_for_token_.IsEmpty()) + return cached_source_for_token_; + + wtf_size_t length; + if (token.GetType() == HTMLToken::kEndOfFile) { + // Consume the remainder of the input, omitting the null character we use to + // mark the end of the file. + length = previous_source_.length() + current_source_.length() - 1; + } else { + DCHECK(!token.StartIndex()); + length = static_cast<wtf_size_t>(token.EndIndex() - token.StartIndex()); + } + + StringBuilder source; + source.ReserveCapacity(length); + + size_t i = 0; + for (; i < length && !previous_source_.IsEmpty(); ++i) { + source.Append(previous_source_.CurrentChar()); + previous_source_.Advance(); + } + for (; i < length; ++i) { + DCHECK(!current_source_.IsEmpty()); + source.Append(current_source_.CurrentChar()); + current_source_.Advance(); + } + + cached_source_for_token_ = source.ToString(); + return cached_source_for_token_; +} + +bool HTMLViewSourceParser::NeedToCheckTokenizerBuffer( + HTMLTokenizer* tokenizer) { + HTMLTokenizer::State state = tokenizer->GetState(); + // The temporary buffer must not be used unconditionally, because in some + // states (e.g. ScriptDataDoubleEscapedStartState), data is appended to + // both the temporary buffer and the token itself. + return state == HTMLTokenizer::kDataState || + HTMLTokenizer::IsEndTagBufferingState(state); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_view_source_parser.h b/chromium/third_party/blink/renderer/core/html/parser/html_view_source_parser.h index dc695308840..81febb2e076 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_view_source_parser.h +++ b/chromium/third_party/blink/renderer/core/html/parser/html_view_source_parser.h @@ -31,7 +31,6 @@ #include "third_party/blink/renderer/core/dom/decoded_data_document_parser.h" #include "third_party/blink/renderer/core/html/html_view_source_document.h" #include "third_party/blink/renderer/core/html/parser/html_input_stream.h" -#include "third_party/blink/renderer/core/html/parser/html_source_tracker.h" #include "third_party/blink/renderer/core/html/parser/html_tokenizer.h" namespace blink { @@ -56,10 +55,20 @@ class CORE_EXPORT HTMLViewSourceParser final void PumpTokenizer(); void UpdateTokenizerState(); + void StartTracker(SegmentedString&, HTMLTokenizer*, HTMLToken&); + void EndTracker(SegmentedString&, HTMLTokenizer*, HTMLToken&); + String SourceForToken(const HTMLToken&); + bool NeedToCheckTokenizerBuffer(HTMLTokenizer*); + HTMLInputStream input_; HTMLToken token_; - HTMLSourceTracker source_tracker_; std::unique_ptr<HTMLTokenizer> tokenizer_; + bool tracker_is_started_; + + SegmentedString previous_source_; + SegmentedString current_source_; + + String cached_source_for_token_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/parser/html_view_source_parser_test.cc b/chromium/third_party/blink/renderer/core/html/parser/html_view_source_parser_test.cc index 3bd21514f75..3b3a5594446 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/html_view_source_parser_test.cc +++ b/chromium/third_party/blink/renderer/core/html/parser/html_view_source_parser_test.cc @@ -17,7 +17,7 @@ namespace blink { TEST(HTMLViewSourceParserTest, DetachThenFinish_ShouldNotCrash) { String mime_type("text/html"); auto* document = MakeGarbageCollected<HTMLViewSourceDocument>( - DocumentInit::Create().WithTypeFrom(mime_type)); + DocumentInit::Create().ForTest().WithTypeFrom(mime_type)); auto* parser = MakeGarbageCollected<HTMLViewSourceParser>(*document, mime_type); // A client may detach the parser from the document. diff --git a/chromium/third_party/blink/renderer/core/html/parser/parser_synchronization_policy.h b/chromium/third_party/blink/renderer/core/html/parser/parser_synchronization_policy.h index e57d7071bc6..5283f13dd8e 100644 --- a/chromium/third_party/blink/renderer/core/html/parser/parser_synchronization_policy.h +++ b/chromium/third_party/blink/renderer/core/html/parser/parser_synchronization_policy.h @@ -5,6 +5,7 @@ namespace blink { enum ParserSynchronizationPolicy { kAllowAsynchronousParsing, + kAllowDeferredParsing, kForceSynchronousParsing, }; } diff --git a/chromium/third_party/blink/renderer/core/html/parser/text_resource_decoder_builder.cc b/chromium/third_party/blink/renderer/core/html/parser/text_resource_decoder_builder.cc new file mode 100644 index 00000000000..88a0b4e5b6f --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/parser/text_resource_decoder_builder.cc @@ -0,0 +1,173 @@ +/* + * 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/parser/text_resource_decoder_builder.h" + +#include <memory> + +#include "base/stl_util.h" +#include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/frame/local_frame.h" +#include "third_party/blink/renderer/core/frame/settings.h" +#include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h" +#include "third_party/blink/renderer/platform/weborigin/security_origin.h" + +namespace blink { + +static inline bool CanReferToParentFrameEncoding( + const LocalFrame* frame, + const LocalFrame* parent_frame) { + return parent_frame && + parent_frame->GetDocument()->GetSecurityOrigin()->CanAccess( + frame->GetDocument()->GetSecurityOrigin()); +} + +namespace { + +struct LegacyEncoding { + const char* domain; + const char* encoding; +}; + +static const LegacyEncoding kEncodings[] = { + {"au", "windows-1252"}, {"az", "ISO-8859-9"}, {"bd", "windows-1252"}, + {"bg", "windows-1251"}, {"br", "windows-1252"}, {"ca", "windows-1252"}, + {"ch", "windows-1252"}, {"cn", "GBK"}, {"cz", "windows-1250"}, + {"de", "windows-1252"}, {"dk", "windows-1252"}, {"ee", "windows-1256"}, + {"eg", "windows-1257"}, {"et", "windows-1252"}, {"fi", "windows-1252"}, + {"fr", "windows-1252"}, {"gb", "windows-1252"}, {"gr", "ISO-8859-7"}, + {"hk", "Big5"}, {"hr", "windows-1250"}, {"hu", "ISO-8859-2"}, + {"il", "windows-1255"}, {"ir", "windows-1257"}, {"is", "windows-1252"}, + {"it", "windows-1252"}, {"jp", "Shift_JIS"}, {"kr", "windows-949"}, + {"lt", "windows-1256"}, {"lv", "windows-1256"}, {"mk", "windows-1251"}, + {"nl", "windows-1252"}, {"no", "windows-1252"}, {"pl", "ISO-8859-2"}, + {"pt", "windows-1252"}, {"ro", "ISO-8859-2"}, {"rs", "windows-1251"}, + {"ru", "windows-1251"}, {"se", "windows-1252"}, {"si", "ISO-8859-2"}, + {"sk", "windows-1250"}, {"th", "windows-874"}, {"tr", "ISO-8859-9"}, + {"tw", "Big5"}, {"tz", "windows-1252"}, {"ua", "windows-1251"}, + {"us", "windows-1252"}, {"vn", "windows-1258"}, {"xa", "windows-1252"}, + {"xb", "windows-1257"}}; + +static const WTF::TextEncoding GetEncodingFromDomain(const KURL& url) { + Vector<String> tokens; + url.Host().Split(".", tokens); + if (!tokens.IsEmpty()) { + auto tld = tokens.back(); + for (size_t i = 0; i < base::size(kEncodings); i++) { + if (tld == kEncodings[i].domain) + return WTF::TextEncoding(kEncodings[i].encoding); + } + } + return WTF::TextEncoding(); +} + +TextResourceDecoderOptions::ContentType DetermineContentType( + const String& mime_type) { + if (EqualIgnoringASCIICase(mime_type, "text/css")) + return TextResourceDecoderOptions::kCSSContent; + if (EqualIgnoringASCIICase(mime_type, "text/html")) + return TextResourceDecoderOptions::kHTMLContent; + if (MIMETypeRegistry::IsXMLMIMEType(mime_type)) + return TextResourceDecoderOptions::kXMLContent; + return TextResourceDecoderOptions::kPlainTextContent; +} + +} // namespace + +std::unique_ptr<TextResourceDecoder> BuildTextResourceDecoderFor( + Document* document, + const AtomicString& mime_type, + const AtomicString& encoding) { + const WTF::TextEncoding encoding_from_domain = + GetEncodingFromDomain(document->Url()); + + LocalFrame* frame = document->GetFrame(); + LocalFrame* parent_frame = nullptr; + if (frame) + parent_frame = DynamicTo<LocalFrame>(frame->Tree().Parent()); + + // Set the hint encoding to the parent frame encoding only if the parent and + // the current frames share the security origin. We impose this condition + // because somebody can make a child frameg63 containing a carefully crafted + // html/javascript in one encoding that can be mistaken for hintEncoding (or + // related encoding) by an auto detector. When interpreted in the latter, it + // could be an attack vector. + // FIXME: This might be too cautious for non-7bit-encodings and we may + // consider relaxing this later after testing. + bool use_hint_encoding = + frame && CanReferToParentFrameEncoding(frame, parent_frame); + + std::unique_ptr<TextResourceDecoder> decoder; + if (frame && frame->GetSettings()) { + const WTF::TextEncoding default_encoding = + encoding_from_domain.IsValid() + ? encoding_from_domain + : WTF::TextEncoding( + frame->GetSettings()->GetDefaultTextEncodingName()); + // Disable autodetection for XML/JSON to honor the default encoding (UTF-8) + // for unlabelled documents. + if (MIMETypeRegistry::IsXMLMIMEType(mime_type)) { + decoder = + std::make_unique<TextResourceDecoder>(TextResourceDecoderOptions( + TextResourceDecoderOptions::kXMLContent, default_encoding)); + use_hint_encoding = false; + } else if (MIMETypeRegistry::IsJSONMimeType(mime_type)) { + decoder = + std::make_unique<TextResourceDecoder>(TextResourceDecoderOptions( + TextResourceDecoderOptions::kJSONContent, default_encoding)); + use_hint_encoding = false; + } else { + WTF::TextEncoding hint_encoding; + if (use_hint_encoding && + parent_frame->GetDocument()->EncodingWasDetectedHeuristically()) + hint_encoding = parent_frame->GetDocument()->Encoding(); + decoder = std::make_unique<TextResourceDecoder>( + TextResourceDecoderOptions::CreateWithAutoDetection( + DetermineContentType(mime_type), default_encoding, hint_encoding, + document->Url())); + } + } else { + decoder = std::make_unique<TextResourceDecoder>(TextResourceDecoderOptions( + DetermineContentType(mime_type), encoding_from_domain)); + } + DCHECK(decoder); + + if (!encoding.IsEmpty()) { + decoder->SetEncoding(WTF::TextEncoding(encoding.GetString()), + TextResourceDecoder::kEncodingFromHTTPHeader); + } else if (use_hint_encoding) { + decoder->SetEncoding(parent_frame->GetDocument()->Encoding(), + TextResourceDecoder::kEncodingFromParentFrame); + } + + return decoder; +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/parser/text_resource_decoder_builder.h b/chromium/third_party/blink/renderer/core/html/parser/text_resource_decoder_builder.h new file mode 100644 index 00000000000..5166dd59878 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/parser/text_resource_decoder_builder.h @@ -0,0 +1,49 @@ +/* + * 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_PARSER_TEXT_RESOURCE_DECODER_BUILDER_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_PARSER_TEXT_RESOURCE_DECODER_BUILDER_H_ + +#include <memory> +#include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h" +#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" + +namespace blink { + +class Document; + +CORE_EXPORT std::unique_ptr<TextResourceDecoder> BuildTextResourceDecoderFor( + Document*, + const AtomicString& mime_type, + const AtomicString& encoding); + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_PARSER_TEXT_RESOURCE_DECODER_BUILDER_H_ diff --git a/chromium/third_party/blink/renderer/core/html/parser/text_resource_decoder_builder_test.cc b/chromium/third_party/blink/renderer/core/html/parser/text_resource_decoder_builder_test.cc new file mode 100644 index 00000000000..aa529b353c1 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/parser/text_resource_decoder_builder_test.cc @@ -0,0 +1,47 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/html/parser/text_resource_decoder_builder.h" + +#include <memory> +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/core/testing/dummy_page_holder.h" + +namespace blink { + +static const WTF::TextEncoding DefaultEncodingForUrlAndContentType( + const char* url, + const char* content_type) { + auto page_holder = std::make_unique<DummyPageHolder>(IntSize(0, 0)); + Document& document = page_holder->GetDocument(); + document.SetURL(KURL(NullURL(), url)); + return BuildTextResourceDecoderFor(&document, content_type, g_null_atom) + ->Encoding(); +} + +static const WTF::TextEncoding DefaultEncodingForURL(const char* url) { + return DefaultEncodingForUrlAndContentType(url, "text/html"); +} + +TEST(TextResourceDecoderBuilderTest, defaultEncodingForJsonIsUTF8) { + EXPECT_EQ(WTF::TextEncoding("UTF-8"), + DefaultEncodingForUrlAndContentType( + "https://udarenieru.ru/1.2/dealers/", "application/json")); +} + +TEST(TextResourceDecoderBuilderTest, defaultEncodingComesFromTopLevelDomain) { + EXPECT_EQ(WTF::TextEncoding("Shift_JIS"), + DefaultEncodingForURL("http://tsubotaa.la.coocan.jp")); + EXPECT_EQ(WTF::TextEncoding("windows-1251"), + DefaultEncodingForURL("http://udarenieru.ru/index.php")); +} + +TEST(TextResourceDecoderBuilderTest, + NoCountryDomainURLDefaultsToLatin1Encoding) { + // Latin1 encoding is set in |TextResourceDecoder::defaultEncoding()|. + EXPECT_EQ(WTF::Latin1Encoding(), + DefaultEncodingForURL("http://arstechnica.com/about-us")); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/core/html/plugin_document.cc b/chromium/third_party/blink/renderer/core/html/plugin_document.cc index 5ff78584883..17d92892f3f 100644 --- a/chromium/third_party/blink/renderer/core/html/plugin_document.cc +++ b/chromium/third_party/blink/renderer/core/html/plugin_document.cc @@ -57,7 +57,7 @@ class PluginDocumentParser : public RawDataDocumentParser { embed_element_(nullptr), background_color_(background_color) {} - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(embed_element_); RawDataDocumentParser::Trace(visitor); } @@ -185,8 +185,8 @@ PluginDocument::PluginDocument(const DocumentInit& initializer) background_color_(initializer.GetPluginBackgroundColor()) { SetCompatibilityMode(kQuirksMode); LockCompatibilityMode(); - if (GetScheduler()) { - GetScheduler()->RegisterStickyFeature( + if (GetExecutionContext()) { + GetExecutionContext()->GetScheduler()->RegisterStickyFeature( SchedulingPolicy::Feature::kContainsPlugins, {SchedulingPolicy::RecordMetricsForBackForwardCache()}); } @@ -206,7 +206,7 @@ void PluginDocument::Shutdown() { HTMLDocument::Shutdown(); } -void PluginDocument::Trace(Visitor* visitor) { +void PluginDocument::Trace(Visitor* visitor) const { visitor->Trace(plugin_node_); HTMLDocument::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/plugin_document.h b/chromium/third_party/blink/renderer/core/html/plugin_document.h index d2faa0e365e..0b536cdcf1c 100644 --- a/chromium/third_party/blink/renderer/core/html/plugin_document.h +++ b/chromium/third_party/blink/renderer/core/html/plugin_document.h @@ -47,7 +47,7 @@ class CORE_EXPORT PluginDocument final : public HTMLDocument { void Shutdown() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: class BeforeUnloadEventListener; diff --git a/chromium/third_party/blink/renderer/core/html/portal/document_portals.cc b/chromium/third_party/blink/renderer/core/html/portal/document_portals.cc index bf53d46e18b..ba600abe02e 100644 --- a/chromium/third_party/blink/renderer/core/html/portal/document_portals.cc +++ b/chromium/third_party/blink/renderer/core/html/portal/document_portals.cc @@ -4,7 +4,9 @@ #include "third_party/blink/renderer/core/html/portal/document_portals.h" +#include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/html/portal/portal_contents.h" +#include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/platform/wtf/wtf_size_t.h" namespace blink { @@ -28,15 +30,26 @@ DocumentPortals::DocumentPortals(Document& document) void DocumentPortals::RegisterPortalContents(PortalContents* portal) { portals_.push_back(portal); + auto* frame = GetSupplementable()->GetFrame(); + if (!frame) + return; + if (auto* page = frame->GetPage()) + page->IncrementSubframeCount(); } void DocumentPortals::DeregisterPortalContents(PortalContents* portal) { wtf_size_t index = portals_.Find(portal); - if (index != WTF::kNotFound) + if (index != WTF::kNotFound) { portals_.EraseAt(index); + auto* frame = GetSupplementable()->GetFrame(); + if (!frame) + return; + if (auto* page = frame->GetPage()) + page->DecrementSubframeCount(); + } } -void DocumentPortals::Trace(Visitor* visitor) { +void DocumentPortals::Trace(Visitor* visitor) const { Supplement<Document>::Trace(visitor); visitor->Trace(portals_); visitor->Trace(activating_portal_); diff --git a/chromium/third_party/blink/renderer/core/html/portal/document_portals.h b/chromium/third_party/blink/renderer/core/html/portal/document_portals.h index 96b264aeb60..88fd72a4b09 100644 --- a/chromium/third_party/blink/renderer/core/html/portal/document_portals.h +++ b/chromium/third_party/blink/renderer/core/html/portal/document_portals.h @@ -52,7 +52,7 @@ class DocumentPortals final : public GarbageCollected<DocumentPortals>, explicit DocumentPortals(Document&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: HeapVector<Member<PortalContents>> portals_; diff --git a/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.cc b/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.cc index 6d3bc25c35c..536e983949d 100644 --- a/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.cc +++ b/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.cc @@ -41,6 +41,8 @@ #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" +#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/public/scheduling_policy.h" #include "third_party/blink/renderer/platform/weborigin/referrer.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" #include "third_party/blink/renderer/platform/weborigin/security_policy.h" @@ -54,7 +56,11 @@ HTMLPortalElement::HTMLPortalElement( mojo::PendingAssociatedRemote<mojom::blink::Portal> remote_portal, mojo::PendingAssociatedReceiver<mojom::blink::PortalClient> portal_client_receiver) - : HTMLFrameOwnerElement(html_names::kPortalTag, document) { + : HTMLFrameOwnerElement(html_names::kPortalTag, document), + feature_handle_for_scheduler_( + document.GetExecutionContext()->GetScheduler()->RegisterFeature( + SchedulingPolicy::Feature::kPortal, + {SchedulingPolicy::RecordMetricsForBackForwardCache()})) { if (remote_portal) { was_just_adopted_ = true; DCHECK(CanHaveGuestContents()) @@ -64,13 +70,12 @@ HTMLPortalElement::HTMLPortalElement( *this, portal_token, std::move(remote_portal), std::move(portal_client_receiver)); } - UseCounter::Count(document, WebFeature::kHTMLPortalElement); } HTMLPortalElement::~HTMLPortalElement() {} -void HTMLPortalElement::Trace(Visitor* visitor) { +void HTMLPortalElement::Trace(Visitor* visitor) const { HTMLFrameOwnerElement::Trace(visitor); visitor->Trace(portal_); } @@ -97,31 +102,53 @@ void HTMLPortalElement::PortalContentsWillBeDestroyed(PortalContents* portal) { portal_ = nullptr; } -bool HTMLPortalElement::CheckPortalsEnabledOrWarn() const { - Document& document = GetDocument(); - if (RuntimeEnabledFeatures::PortalsEnabled(&document)) +bool HTMLPortalElement::IsCurrentlyWithinFrameLimit() const { + auto* frame = GetDocument().GetFrame(); + if (!frame) + return false; + auto* page = frame->GetPage(); + if (!page) + return false; + return page->SubframeCount() < Page::MaxNumberOfFrames(); +} + +bool HTMLPortalElement::CheckWithinFrameLimitOrWarn() const { + if (IsCurrentlyWithinFrameLimit()) return true; - // TODO(jbroman): Consider linking to origin trial info if applicable. + Document& document = GetDocument(); document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( mojom::blink::ConsoleMessageSource::kRendering, mojom::blink::ConsoleMessageLevel::kWarning, + "An operation was prevented due to too many frames and portals present " + "on the page.")); + return false; +} + +bool HTMLPortalElement::CheckPortalsEnabledOrWarn() const { + ExecutionContext* context = GetExecutionContext(); + if (RuntimeEnabledFeatures::PortalsEnabled(context)) + return true; + + context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( + mojom::blink::ConsoleMessageSource::kRendering, + mojom::blink::ConsoleMessageLevel::kWarning, "An operation was prevented because a <portal> was moved to a document " - "where it is not enabled.")); + "where it is not enabled. See " + "https://www.chromium.org/blink/origin-trials/portals.")); return false; } bool HTMLPortalElement::CheckPortalsEnabledOrThrow( ExceptionState& exception_state) const { - Document& document = GetDocument(); - if (RuntimeEnabledFeatures::PortalsEnabled(&document)) + if (RuntimeEnabledFeatures::PortalsEnabled(GetExecutionContext())) return true; - // TODO(jbroman): Consider linking to origin trial info if applicable. exception_state.ThrowDOMException( DOMExceptionCode::kNotSupportedError, "An operation was prevented because a <portal> was moved to a document " - "where it is not enabled."); + "where it is not enabled. See " + "https://www.chromium.org/blink/origin-trials/portals."); return false; } @@ -141,6 +168,13 @@ HTMLPortalElement::GetGuestContentsEligibility() const { if (!is_top_level) return GuestContentsEligibility::kNotTopLevel; + // TODO(crbug.com/1051639): We need to find a long term solution to when/how + // portals should work in sandboxed documents. + if (GetDocument().GetSandboxFlags() != + network::mojom::blink::WebSandboxFlags::kNone) { + return GuestContentsEligibility::kSandboxed; + } + if (!GetDocument().Url().ProtocolIsInHTTPFamily()) return GuestContentsEligibility::kNotHTTPFamily; @@ -151,10 +185,16 @@ void HTMLPortalElement::Navigate() { if (!CheckPortalsEnabledOrWarn()) return; - if (portal_) { - portal_->Navigate(GetNonEmptyURLAttribute(html_names::kSrcAttr), - ReferrerPolicyAttribute()); - } + if (!CheckWithinFrameLimitOrWarn()) + return; + + auto url = GetNonEmptyURLAttribute(html_names::kSrcAttr); + + if (url.PotentiallyDanglingMarkup()) + return; + + if (portal_) + portal_->Navigate(url, ReferrerPolicyAttribute()); } namespace { @@ -238,6 +278,13 @@ ScriptPromise HTMLPortalElement::activate(ScriptState* script_state, "Cannot activate a portal that is inside another portal."); return ScriptPromise(); } + if (GetDocument().BeforeUnloadStarted()) { + exception_state.ThrowDOMException( + DOMExceptionCode::kInvalidStateError, + "Cannot activate portal while document is in beforeunload or has " + "started unloading."); + return ScriptPromise(); + } BlinkTransferableMessage data = ActivateDataAsMessage(script_state, options, exception_state); @@ -317,6 +364,9 @@ Node::InsertionNotificationRequest HTMLPortalElement::InsertedInto( if (!CheckPortalsEnabledOrWarn()) return result; + if (!CheckWithinFrameLimitOrWarn()) + return result; + if (!SubframeLoadingDisabler::CanLoadFrame(*this)) return result; @@ -331,6 +381,13 @@ Node::InsertionNotificationRequest HTMLPortalElement::InsertedInto( "Cannot use <portal> in a nested browsing context.")); return result; + case GuestContentsEligibility::kSandboxed: + GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( + mojom::ConsoleMessageSource::kRendering, + mojom::ConsoleMessageLevel::kWarning, + "Cannot use <portal> in a sandboxed browsing context.")); + return result; + case GuestContentsEligibility::kNotHTTPFamily: GetDocument().AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( mojom::ConsoleMessageSource::kRendering, diff --git a/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.h b/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.h index 1ec5984927d..5e9e05dec04 100644 --- a/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.h +++ b/chromium/third_party/blink/renderer/core/html/portal/html_portal_element.h @@ -14,6 +14,7 @@ #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/dom/node.h" #include "third_party/blink/renderer/core/html/html_frame_owner_element.h" +#include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h" #include "third_party/blink/renderer/platform/wtf/casting.h" namespace blink { @@ -43,7 +44,7 @@ class CORE_EXPORT HTMLPortalElement : public HTMLFrameOwnerElement { bool IsHTMLPortalElement() const final { return true; } // ScriptWrappable overrides. - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; // idl implementation. ScriptPromise activate(ScriptState*, PortalActivateOptions*, ExceptionState&); @@ -86,6 +87,15 @@ class CORE_EXPORT HTMLPortalElement : public HTMLFrameOwnerElement { bool CheckPortalsEnabledOrWarn() const; bool CheckPortalsEnabledOrThrow(ExceptionState&) const; + // Checks if, when inserted, we were beyond the frame limit. If so, we will + // disable navigating the portal and insertion (and will display a warning in + // the console). + bool CheckWithinFrameLimitOrWarn() const; + + // Checks that the number of frames and portals on the page are within the + // limit. + bool IsCurrentlyWithinFrameLimit() const; + enum class GuestContentsEligibility { // Can have a guest contents. kEligible, @@ -93,6 +103,9 @@ class CORE_EXPORT HTMLPortalElement : public HTMLFrameOwnerElement { // Ineligible as it is not top-level. kNotTopLevel, + // Ineligible as it is sandboxed. + kSandboxed, + // Ineligible as the host's protocol is not in the HTTP family. kNotHTTPFamily, @@ -120,7 +133,7 @@ class CORE_EXPORT HTMLPortalElement : public HTMLFrameOwnerElement { // HTMLFrameOwnerElement overrides void DisconnectContentFrame() override; - ParsedFeaturePolicy ConstructContainerPolicy(Vector<String>*) const override { + ParsedFeaturePolicy ConstructContainerPolicy() const override { return ParsedFeaturePolicy(); } void AttachLayoutTree(AttachContext& context) override; @@ -133,6 +146,11 @@ class CORE_EXPORT HTMLPortalElement : public HTMLFrameOwnerElement { // Temporarily set to keep this element alive after adoption. bool was_just_adopted_ = false; + + // Disable BackForwardCache when using the portal feature, because we do not + // handle the state inside the portal after putting the page in cache. + FrameOrWorkerScheduler::SchedulingAffectingFeatureHandle + feature_handle_for_scheduler_; }; // Type casting. Custom since adoption could lead to an HTMLPortalElement ending diff --git a/chromium/third_party/blink/renderer/core/html/portal/html_portal_element_test.cc b/chromium/third_party/blink/renderer/core/html/portal/html_portal_element_test.cc index c7904de4aaf..92e22391e3f 100644 --- a/chromium/third_party/blink/renderer/core/html/portal/html_portal_element_test.cc +++ b/chromium/third_party/blink/renderer/core/html/portal/html_portal_element_test.cc @@ -35,7 +35,8 @@ TEST_F(HTMLPortalElementTest, PortalsDisabledInDocument) { Document& document = GetDocument(); auto* portal = MakeGarbageCollected<HTMLPortalElement>(document); ScopedPortalsForTest disable_portals(false); - ASSERT_FALSE(RuntimeEnabledFeatures::PortalsEnabled(&document)); + ASSERT_FALSE( + RuntimeEnabledFeatures::PortalsEnabled(document.GetExecutionContext())); DummyExceptionStateForTesting exception_state; ScriptState* script_state = ToScriptStateForMainWorld(&GetFrame()); diff --git a/chromium/third_party/blink/renderer/core/html/portal/portal_activate_event.cc b/chromium/third_party/blink/renderer/core/html/portal/portal_activate_event.cc index 2e685353655..3aebb0c255e 100644 --- a/chromium/third_party/blink/renderer/core/html/portal/portal_activate_event.cc +++ b/chromium/third_party/blink/renderer/core/html/portal/portal_activate_event.cc @@ -105,7 +105,7 @@ ScriptValue PortalActivateEvent::data(ScriptState* script_state) { return ScriptValue(isolate, value); } -void PortalActivateEvent::Trace(Visitor* visitor) { +void PortalActivateEvent::Trace(Visitor* visitor) const { Event::Trace(visitor); visitor->Trace(document_); visitor->Trace(adopted_portal_); @@ -121,7 +121,8 @@ const AtomicString& PortalActivateEvent::InterfaceName() const { HTMLPortalElement* PortalActivateEvent::adoptPredecessor( ExceptionState& exception_state) { - if (!RuntimeEnabledFeatures::PortalsEnabled(document_)) { + if (!RuntimeEnabledFeatures::PortalsEnabled( + document_ ? document_->GetExecutionContext() : nullptr)) { exception_state.ThrowDOMException( DOMExceptionCode::kNotSupportedError, "Portals is not enabled in this document."); diff --git a/chromium/third_party/blink/renderer/core/html/portal/portal_activate_event.h b/chromium/third_party/blink/renderer/core/html/portal/portal_activate_event.h index 41d3a4e0c41..d72fc5f19f8 100644 --- a/chromium/third_party/blink/renderer/core/html/portal/portal_activate_event.h +++ b/chromium/third_party/blink/renderer/core/html/portal/portal_activate_event.h @@ -64,7 +64,7 @@ class CORE_EXPORT PortalActivateEvent : public Event { ~PortalActivateEvent() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // Event overrides const AtomicString& InterfaceName() const override; diff --git a/chromium/third_party/blink/renderer/core/html/portal/portal_contents.cc b/chromium/third_party/blink/renderer/core/html/portal/portal_contents.cc index 80f1404bc48..b077af9abca 100644 --- a/chromium/third_party/blink/renderer/core/html/portal/portal_contents.cc +++ b/chromium/third_party/blink/renderer/core/html/portal/portal_contents.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/core/html/portal/portal_contents.h" #include "base/compiler_specific.h" +#include "base/time/time.h" #include "third_party/blink/public/mojom/portal/portal.mojom-blink-forward.h" #include "third_party/blink/public/mojom/referrer.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" @@ -15,6 +16,8 @@ #include "third_party/blink/renderer/core/html/portal/html_portal_element.h" #include "third_party/blink/renderer/core/html/portal/portal_post_message_helper.h" #include "third_party/blink/renderer/core/inspector/console_message.h" +#include "third_party/blink/renderer/core/loader/document_load_timing.h" +#include "third_party/blink/renderer/core/loader/document_loader.h" #include "third_party/blink/renderer/core/messaging/blink_transferable_message.h" #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/platform/heap/heap.h" @@ -60,7 +63,7 @@ ScriptPromise PortalContents::Activate(ScriptState* script_state, // This object (and thus the Mojo connection it owns) remains alive while the // renderer awaits the response. remote_portal_->Activate( - std::move(data), + std::move(data), base::TimeTicks::Now(), WTF::Bind(&PortalContents::OnActivateResponse, WrapPersistent(this))); // Dissociate from the element. The element is expected to do the same. @@ -72,7 +75,7 @@ ScriptPromise PortalContents::Activate(ScriptState* script_state, void PortalContents::OnActivateResponse( mojom::blink::PortalActivateResult result) { auto reject = [&](DOMExceptionCode code, const char* message) { - if (GetDocument().IsContextDestroyed()) + if (!GetDocument().GetExecutionContext()) return; ScriptState* script_state = activate_resolver_->GetScriptState(); @@ -91,8 +94,8 @@ void PortalContents::OnActivateResponse( bool should_destroy_contents = false; switch (result) { case mojom::blink::PortalActivateResult::kPredecessorWasAdopted: - if (!GetDocument().IsContextDestroyed()) - GetDocument().GetPage()->SetInsidePortal(true); + if (auto* page = GetDocument().GetPage()) + page->SetInsidePortal(true); FALLTHROUGH; case mojom::blink::PortalActivateResult::kPredecessorWillUnload: activate_resolver_->Resolve(); @@ -154,10 +157,11 @@ void PortalContents::Navigate( return; } + ExecutionContext* context = GetDocument().GetExecutionContext(); if (referrer_policy_to_use == network::mojom::ReferrerPolicy::kDefault) - referrer_policy_to_use = GetDocument().GetReferrerPolicy(); + referrer_policy_to_use = context->GetReferrerPolicy(); Referrer referrer = SecurityPolicy::GenerateReferrer( - referrer_policy_to_use, url, GetDocument().OutgoingReferrer()); + referrer_policy_to_use, url, context->OutgoingReferrer()); auto mojo_referrer = mojom::blink::Referrer::New( KURL(NullURL(), referrer.referrer), referrer.referrer_policy); @@ -214,7 +218,7 @@ void PortalContents::DispatchLoadEvent() { GetDocument().CheckCompleted(); } -void PortalContents::Trace(Visitor* visitor) { +void PortalContents::Trace(Visitor* visitor) const { visitor->Trace(document_); visitor->Trace(portal_element_); visitor->Trace(activate_resolver_); diff --git a/chromium/third_party/blink/renderer/core/html/portal/portal_contents.h b/chromium/third_party/blink/renderer/core/html/portal/portal_contents.h index 82270a20191..2c63c8111a2 100644 --- a/chromium/third_party/blink/renderer/core/html/portal/portal_contents.h +++ b/chromium/third_party/blink/renderer/core/html/portal/portal_contents.h @@ -90,7 +90,7 @@ class PortalContents : public GarbageCollected<PortalContents>, const scoped_refptr<const SecurityOrigin>& target_origin) override; void DispatchLoadEvent() override; - void Trace(Visitor* visitor); + void Trace(Visitor* visitor) const; private: // Returns the document which controls the lifetime of this portal (usually, diff --git a/chromium/third_party/blink/renderer/core/html/portal/portal_host.cc b/chromium/third_party/blink/renderer/core/html/portal/portal_host.cc index 5758bd24cfb..10cbf0b3ddc 100644 --- a/chromium/third_party/blink/renderer/core/html/portal/portal_host.cc +++ b/chromium/third_party/blink/renderer/core/html/portal/portal_host.cc @@ -24,7 +24,7 @@ namespace blink { PortalHost::PortalHost(LocalDOMWindow& window) : Supplement<LocalDOMWindow>(window) {} -void PortalHost::Trace(Visitor* visitor) { +void PortalHost::Trace(Visitor* visitor) const { EventTargetWithInlineData::Trace(visitor); Supplement<LocalDOMWindow>::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/portal/portal_host.h b/chromium/third_party/blink/renderer/core/html/portal/portal_host.h index 49966b02916..ce127eb0872 100644 --- a/chromium/third_party/blink/renderer/core/html/portal/portal_host.h +++ b/chromium/third_party/blink/renderer/core/html/portal/portal_host.h @@ -28,7 +28,7 @@ class CORE_EXPORT PortalHost : public EventTargetWithInlineData, public: explicit PortalHost(LocalDOMWindow& window); - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; static const char kSupplementName[]; static PortalHost& From(LocalDOMWindow& window); diff --git a/chromium/third_party/blink/renderer/core/html/rel_list.cc b/chromium/third_party/blink/renderer/core/html/rel_list.cc index dc257118aa5..abe48f3c1c2 100644 --- a/chromium/third_party/blink/renderer/core/html/rel_list.cc +++ b/chromium/third_party/blink/renderer/core/html/rel_list.cc @@ -50,10 +50,20 @@ bool RelList::ValidateTokenValue(const AtomicString& token_value, return true; } if (RuntimeEnabledFeatures::SignedExchangeSubresourcePrefetchEnabled( - &GetElement().GetDocument()) && + GetElement().GetExecutionContext()) && token_value == "allowed-alt-sxg") { return true; } + if (RuntimeEnabledFeatures::SubresourceWebBundlesEnabled( + GetElement().GetExecutionContext()) && + token_value == "webbundle") { + return true; + } + if (RuntimeEnabledFeatures::MediaFeedsEnabled( + GetElement().GetExecutionContext()) || + token_value == "media-feed") { + return true; + } } else if ((GetElement().HasTagName(html_names::kATag) || GetElement().HasTagName(html_names::kAreaTag)) && SupportedTokensAnchorAndArea().Contains(token_value)) { diff --git a/chromium/third_party/blink/renderer/core/html/resources/controls_refresh.css b/chromium/third_party/blink/renderer/core/html/resources/controls_refresh.css index ccf1422fad5..d8de47f45ad 100644 --- a/chromium/third_party/blink/renderer/core/html/resources/controls_refresh.css +++ b/chromium/third_party/blink/renderer/core/html/resources/controls_refresh.css @@ -146,7 +146,7 @@ input[type="date" i]::-webkit-calendar-picker-indicator, input[type="datetime-local" i]::-webkit-calendar-picker-indicator, input[type="month" i]::-webkit-calendar-picker-indicator, input[type="week" i]::-webkit-calendar-picker-indicator { - background-image: -webkit-image-set(url(images/calendar_icon.svg) 1x); + background-image: -internal-light-dark(-webkit-image-set(url(images/calendar_icon.svg) 1x), -webkit-image-set(url(images/calendar_icon_white.svg) 1x)); background-origin: content-box; background-repeat: no-repeat; background-size: contain; diff --git a/chromium/third_party/blink/renderer/core/html/resources/forced_colors.css b/chromium/third_party/blink/renderer/core/html/resources/forced_colors.css index 8752b6d2fd4..47b2e5f7355 100644 --- a/chromium/third_party/blink/renderer/core/html/resources/forced_colors.css +++ b/chromium/third_party/blink/renderer/core/html/resources/forced_colors.css @@ -14,9 +14,8 @@ @namespace "http://www.w3.org/1999/xhtml" */ -@media forced-colors { - body { - background-color: Canvas; +@media ua-forced-colors { + html { color: CanvasText; fill: currentColor; } @@ -38,6 +37,10 @@ border-color: CanvasText; } + mark { + -internal-forced-background-color-rgb: yellow; + } + ::placeholder { color: GrayText; } @@ -73,11 +76,13 @@ background-color: ButtonFace; border-color: GrayText; color: GrayText; + -internal-forced-background-color-rgb: ButtonFace; } input::-webkit-calendar-picker-indicator { background-color: ButtonFace; color: ButtonText; + -internal-forced-background-color-rgb: ButtonFace; } input::-webkit-datetime-edit-ampm-field:focus, @@ -91,6 +96,7 @@ input::-webkit-datetime-edit-year-field:focus { background-color: Highlight; color: HighlightText; + -internal-forced-background-color-rgb: Highlight; outline: none; } @@ -114,6 +120,7 @@ border-color: ButtonText; background: ButtonFace; color: ButtonText; + -internal-forced-background-color-rgb: ButtonFace; } button:hover, @@ -164,6 +171,7 @@ background-color: Highlight !important; color: Canvas !important; forced-color-adjust: none; + -internal-forced-background-color-rgb: Highlight; } /* option both disabled and selected */ @@ -176,12 +184,14 @@ background-color: GrayText !important; color: Canvas !important; forced-color-adjust: none; + -internal-forced-background-color-rgb: GrayText; } select:-internal-list-box option:hover { background-color: Highlight !important; color: Canvas; forced-color-adjust: none; + -internal-forced-background-color-rgb: Highlight; } select { @@ -207,12 +217,14 @@ meter::-webkit-meter-bar { background: ButtonFace; border-color: CanvasText; + -internal-forced-background-color-rgb: ButtonFace; } meter::-webkit-meter-even-less-good-value, meter::-webkit-meter-optimum-value, meter::-webkit-meter-suboptimum-value { background: Highlight; + -internal-forced-background-color-rgb: Highlight; } input:-internal-autofill-previewed, diff --git a/chromium/third_party/blink/renderer/core/html/resources/images/calendar_icon_white.svg b/chromium/third_party/blink/renderer/core/html/resources/images/calendar_icon_white.svg new file mode 100644 index 00000000000..3f4b476a17c --- /dev/null +++ b/chromium/third_party/blink/renderer/core/html/resources/images/calendar_icon_white.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="16" height="15" viewBox="0 0 24 24"><path fill="#ffffff" d="M20 3h-1V1h-2v2H7V1H5v2H4c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 18H4V8h16v13z"/><path fill="none" d="M0 0h24v24H0z"/></svg>
\ No newline at end of file diff --git a/chromium/third_party/blink/renderer/core/html/shadow/details_marker_control.cc b/chromium/third_party/blink/renderer/core/html/shadow/details_marker_control.cc index 2e54345f6f7..a77981b2d28 100644 --- a/chromium/third_party/blink/renderer/core/html/shadow/details_marker_control.cc +++ b/chromium/third_party/blink/renderer/core/html/shadow/details_marker_control.cc @@ -31,13 +31,14 @@ #include "third_party/blink/renderer/core/html/shadow/details_marker_control.h" #include "third_party/blink/renderer/core/html/html_summary_element.h" +#include "third_party/blink/renderer/core/html/shadow/shadow_element_names.h" #include "third_party/blink/renderer/core/layout/layout_details_marker.h" namespace blink { DetailsMarkerControl::DetailsMarkerControl(Document& document) : HTMLDivElement(document) { - SetShadowPseudoId(AtomicString("-webkit-details-marker")); + SetShadowPseudoId(shadow_element_names::WebKitDetailsMarker()); } LayoutObject* DetailsMarkerControl::CreateLayoutObject(const ComputedStyle&, diff --git a/chromium/third_party/blink/renderer/core/html/shadow/shadow_element_names.cc b/chromium/third_party/blink/renderer/core/html/shadow/shadow_element_names.cc index ae955ffa21f..9c5d9509379 100644 --- a/chromium/third_party/blink/renderer/core/html/shadow/shadow_element_names.cc +++ b/chromium/third_party/blink/renderer/core/html/shadow/shadow_element_names.cc @@ -104,6 +104,11 @@ const AtomicString& TextFieldContainer() { return name; } +const AtomicString& WebKitDetailsMarker() { + DEFINE_STATIC_LOCAL(AtomicString, name, ("-webkit-details-marker")); + return name; +} + const AtomicString& FileUploadButton() { DEFINE_STATIC_LOCAL(AtomicString, name, ("file-upload-button")); return name; diff --git a/chromium/third_party/blink/renderer/core/html/shadow/shadow_element_names.h b/chromium/third_party/blink/renderer/core/html/shadow/shadow_element_names.h index 128f3ebd3de..fb459eff76c 100644 --- a/chromium/third_party/blink/renderer/core/html/shadow/shadow_element_names.h +++ b/chromium/third_party/blink/renderer/core/html/shadow/shadow_element_names.h @@ -40,6 +40,7 @@ namespace shadow_element_names { const AtomicString& DetailsContent(); const AtomicString& DetailsSummary(); +// An ID attribute value for a details marker. const AtomicString& DetailsMarker(); const AtomicString& DateTimeEdit(); CORE_EXPORT const AtomicString& SpinButton(); @@ -52,6 +53,8 @@ const AtomicString& PasswordRevealButton(); CORE_EXPORT const AtomicString& SliderThumb(); const AtomicString& SliderTrack(); const AtomicString& TextFieldContainer(); +// Pseudo element name ::-webkit-details-marker +const AtomicString& WebKitDetailsMarker(); const AtomicString& FileUploadButton(); const AtomicString& OptGroupLabel(); diff --git a/chromium/third_party/blink/renderer/core/html/subresource_redirect_test.cc b/chromium/third_party/blink/renderer/core/html/subresource_redirect_test.cc index e7f15117ddf..9a3422d7473 100644 --- a/chromium/third_party/blink/renderer/core/html/subresource_redirect_test.cc +++ b/chromium/third_party/blink/renderer/core/html/subresource_redirect_test.cc @@ -66,9 +66,6 @@ class SubresourceRedirectSimTest // This test verifies subresource redirect previews state based on different // states of SaveData, LazyLoad, SubresourceRedirect features. TEST_P(SubresourceRedirectSimTest, CSSBackgroundImage) { - WebView().GetPage()->GetSettings().SetLazyLoadEnabled( - is_lazyload_image_enabled()); - SimRequest image_resource("https://example.com/img.png", "image/png"); LoadMainResource(String::Format(R"HTML( <style> diff --git a/chromium/third_party/blink/renderer/core/html/track/audio_track.cc b/chromium/third_party/blink/renderer/core/html/track/audio_track.cc index 53484fa1333..9193f154912 100644 --- a/chromium/third_party/blink/renderer/core/html/track/audio_track.cc +++ b/chromium/third_party/blink/renderer/core/html/track/audio_track.cc @@ -22,7 +22,7 @@ AudioTrack::AudioTrack(const String& id, AudioTrack::~AudioTrack() = default; -void AudioTrack::Trace(Visitor* visitor) { +void AudioTrack::Trace(Visitor* visitor) const { ScriptWrappable::Trace(visitor); TrackBase::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/track/audio_track.h b/chromium/third_party/blink/renderer/core/html/track/audio_track.h index c267eef9f57..0ca1b445933 100644 --- a/chromium/third_party/blink/renderer/core/html/track/audio_track.h +++ b/chromium/third_party/blink/renderer/core/html/track/audio_track.h @@ -23,7 +23,7 @@ class CORE_EXPORT AudioTrack final : public ScriptWrappable, public TrackBase { const AtomicString& language, bool enabled); ~AudioTrack() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; bool enabled() const { return enabled_; } void setEnabled(bool); diff --git a/chromium/third_party/blink/renderer/core/html/track/audio_track_list.h b/chromium/third_party/blink/renderer/core/html/track/audio_track_list.h index 9e831d41179..fac6f1b337e 100644 --- a/chromium/third_party/blink/renderer/core/html/track/audio_track_list.h +++ b/chromium/third_party/blink/renderer/core/html/track/audio_track_list.h @@ -22,7 +22,7 @@ class CORE_EXPORT AudioTrackList final : public TrackListBase<AudioTrack> { // EventTarget const AtomicString& InterfaceName() const override; - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { TrackListBase<AudioTrack>::Trace(visitor); } }; diff --git a/chromium/third_party/blink/renderer/core/html/track/cue_timeline.cc b/chromium/third_party/blink/renderer/core/html/track/cue_timeline.cc index 590529d72a9..ae436e34f84 100644 --- a/chromium/third_party/blink/renderer/core/html/track/cue_timeline.cc +++ b/chromium/third_party/blink/renderer/core/html/track/cue_timeline.cc @@ -362,7 +362,7 @@ void CueTimeline::EndIgnoringUpdateRequests() { UpdateActiveCues(MediaElement().currentTime()); } -void CueTimeline::Trace(Visitor* visitor) { +void CueTimeline::Trace(Visitor* visitor) const { visitor->Trace(media_element_); } diff --git a/chromium/third_party/blink/renderer/core/html/track/cue_timeline.h b/chromium/third_party/blink/renderer/core/html/track/cue_timeline.h index cbfc68db7e8..76b59798188 100644 --- a/chromium/third_party/blink/renderer/core/html/track/cue_timeline.h +++ b/chromium/third_party/blink/renderer/core/html/track/cue_timeline.h @@ -47,7 +47,7 @@ class CueTimeline final : public GarbageCollected<CueTimeline> { const CueList& CurrentlyActiveCues() const { return currently_active_cues_; } - void Trace(Visitor*); + void Trace(Visitor*) const; private: HTMLMediaElement& MediaElement() const { return *media_element_; } diff --git a/chromium/third_party/blink/renderer/core/html/track/html_track_element.cc b/chromium/third_party/blink/renderer/core/html/track/html_track_element.cc index 67d538e5186..e461bbbad6e 100644 --- a/chromium/third_party/blink/renderer/core/html/track/html_track_element.cc +++ b/chromium/third_party/blink/renderer/core/html/track/html_track_element.cc @@ -338,7 +338,7 @@ HTMLMediaElement* HTMLTrackElement::MediaElement() const { return DynamicTo<HTMLMediaElement>(parentElement()); } -void HTMLTrackElement::Trace(Visitor* visitor) { +void HTMLTrackElement::Trace(Visitor* visitor) const { visitor->Trace(track_); visitor->Trace(loader_); HTMLElement::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/core/html/track/html_track_element.h b/chromium/third_party/blink/renderer/core/html/track/html_track_element.h index 4e66620f818..b7473220e0b 100644 --- a/chromium/third_party/blink/renderer/core/html/track/html_track_element.h +++ b/chromium/third_party/blink/renderer/core/html/track/html_track_element.h @@ -53,7 +53,7 @@ class HTMLTrackElement final : public HTMLElement, TextTrack* track(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: ~HTMLTrackElement() override; diff --git a/chromium/third_party/blink/renderer/core/html/track/loadable_text_track.cc b/chromium/third_party/blink/renderer/core/html/track/loadable_text_track.cc index 560607a0243..e932189035f 100644 --- a/chromium/third_party/blink/renderer/core/html/track/loadable_text_track.cc +++ b/chromium/third_party/blink/renderer/core/html/track/loadable_text_track.cc @@ -63,7 +63,7 @@ wtf_size_t LoadableTextTrack::TrackElementIndex() const { return index; } -void LoadableTextTrack::Trace(Visitor* visitor) { +void LoadableTextTrack::Trace(Visitor* visitor) const { visitor->Trace(track_element_); TextTrack::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/track/loadable_text_track.h b/chromium/third_party/blink/renderer/core/html/track/loadable_text_track.h index 87b69cdf8b0..1de1ed23456 100644 --- a/chromium/third_party/blink/renderer/core/html/track/loadable_text_track.h +++ b/chromium/third_party/blink/renderer/core/html/track/loadable_text_track.h @@ -49,7 +49,7 @@ class LoadableTextTrack final : public TextTrack { bool IsDefault() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<HTMLTrackElement> track_element_; diff --git a/chromium/third_party/blink/renderer/core/html/track/text_track.cc b/chromium/third_party/blink/renderer/core/html/track/text_track.cc index 703706b3b98..7e1f5852d6a 100644 --- a/chromium/third_party/blink/renderer/core/html/track/text_track.cc +++ b/chromium/third_party/blink/renderer/core/html/track/text_track.cc @@ -376,7 +376,7 @@ Node* TextTrack::Owner() const { return MediaElement(); } -void TextTrack::Trace(Visitor* visitor) { +void TextTrack::Trace(Visitor* visitor) const { visitor->Trace(cues_); visitor->Trace(active_cues_); visitor->Trace(track_list_); diff --git a/chromium/third_party/blink/renderer/core/html/track/text_track.h b/chromium/third_party/blink/renderer/core/html/track/text_track.h index e4459809417..f34193f77da 100644 --- a/chromium/third_party/blink/renderer/core/html/track/text_track.h +++ b/chromium/third_party/blink/renderer/core/html/track/text_track.h @@ -127,7 +127,7 @@ class CORE_EXPORT TextTrack : public EventTargetWithInlineData, const AtomicString& InterfaceName() const override; ExecutionContext* GetExecutionContext() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; const HeapVector<Member<CSSStyleSheet>>& GetCSSStyleSheets() const { return style_sheets_; diff --git a/chromium/third_party/blink/renderer/core/html/track/text_track_container.cc b/chromium/third_party/blink/renderer/core/html/track/text_track_container.cc index fccd0224a16..e2bb51a8bc5 100644 --- a/chromium/third_party/blink/renderer/core/html/track/text_track_container.cc +++ b/chromium/third_party/blink/renderer/core/html/track/text_track_container.cc @@ -55,7 +55,7 @@ class VideoElementResizeDelegate final : public ResizeObserver::Delegate { entries[0]->target()->GetLayoutObject()); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(text_track_container_); ResizeObserver::Delegate::Trace(visitor); } @@ -75,7 +75,7 @@ TextTrackContainer::TextTrackContainer(HTMLMediaElement& media_element) ObserveSizeChanges(*media_element_); } -void TextTrackContainer::Trace(Visitor* visitor) { +void TextTrackContainer::Trace(Visitor* visitor) const { visitor->Trace(media_element_); visitor->Trace(video_size_observer_); HTMLDivElement::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/core/html/track/text_track_container.h b/chromium/third_party/blink/renderer/core/html/track/text_track_container.h index 190f247449a..f5b110c0b10 100644 --- a/chromium/third_party/blink/renderer/core/html/track/text_track_container.h +++ b/chromium/third_party/blink/renderer/core/html/track/text_track_container.h @@ -55,7 +55,7 @@ class TextTrackContainer final : public HTMLDivElement { void UpdateDisplay(HTMLMediaElement&, ExposingControls); void UpdateDefaultFontSize(LayoutObject*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: bool IsTextTrackContainer() const override { return true; } diff --git a/chromium/third_party/blink/renderer/core/html/track/text_track_cue.cc b/chromium/third_party/blink/renderer/core/html/track/text_track_cue.cc index 08b901b75bd..d67cc93ba80 100644 --- a/chromium/third_party/blink/renderer/core/html/track/text_track_cue.cc +++ b/chromium/third_party/blink/renderer/core/html/track/text_track_cue.cc @@ -132,7 +132,7 @@ const AtomicString& TextTrackCue::InterfaceName() const { return event_target_names::kTextTrackCue; } -void TextTrackCue::Trace(Visitor* visitor) { +void TextTrackCue::Trace(Visitor* visitor) const { visitor->Trace(track_); EventTargetWithInlineData::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/track/text_track_cue.h b/chromium/third_party/blink/renderer/core/html/track/text_track_cue.h index 176febe7577..93acd32ef60 100644 --- a/chromium/third_party/blink/renderer/core/html/track/text_track_cue.h +++ b/chromium/third_party/blink/renderer/core/html/track/text_track_cue.h @@ -97,7 +97,7 @@ class TextTrackCue : public EventTargetWithInlineData { DEFINE_ATTRIBUTE_EVENT_LISTENER(enter, kEnter) DEFINE_ATTRIBUTE_EVENT_LISTENER(exit, kExit) - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: TextTrackCue(double start, double end); diff --git a/chromium/third_party/blink/renderer/core/html/track/text_track_cue_list.cc b/chromium/third_party/blink/renderer/core/html/track/text_track_cue_list.cc index 44bd640bd32..30b9b17dccf 100644 --- a/chromium/third_party/blink/renderer/core/html/track/text_track_cue_list.cc +++ b/chromium/third_party/blink/renderer/core/html/track/text_track_cue_list.cc @@ -139,7 +139,7 @@ void TextTrackCueList::ValidateCueIndexes() { first_invalid_index_ = list_.size(); } -void TextTrackCueList::Trace(Visitor* visitor) { +void TextTrackCueList::Trace(Visitor* visitor) const { visitor->Trace(list_); ScriptWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/track/text_track_cue_list.h b/chromium/third_party/blink/renderer/core/html/track/text_track_cue_list.h index 505136faed1..51266a732db 100644 --- a/chromium/third_party/blink/renderer/core/html/track/text_track_cue_list.h +++ b/chromium/third_party/blink/renderer/core/html/track/text_track_cue_list.h @@ -55,7 +55,7 @@ class TextTrackCueList final : public ScriptWrappable { } void ValidateCueIndexes(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: wtf_size_t FindInsertionIndex(const TextTrackCue*) const; diff --git a/chromium/third_party/blink/renderer/core/html/track/text_track_list.cc b/chromium/third_party/blink/renderer/core/html/track/text_track_list.cc index c5cfc997620..7393444b2ce 100644 --- a/chromium/third_party/blink/renderer/core/html/track/text_track_list.cc +++ b/chromium/third_party/blink/renderer/core/html/track/text_track_list.cc @@ -296,7 +296,7 @@ HTMLMediaElement* TextTrackList::Owner() const { return owner_; } -void TextTrackList::Trace(Visitor* visitor) { +void TextTrackList::Trace(Visitor* visitor) const { visitor->Trace(owner_); visitor->Trace(add_track_tracks_); visitor->Trace(element_tracks_); diff --git a/chromium/third_party/blink/renderer/core/html/track/text_track_list.h b/chromium/third_party/blink/renderer/core/html/track/text_track_list.h index fd1483dafc9..0d04e60d169 100644 --- a/chromium/third_party/blink/renderer/core/html/track/text_track_list.h +++ b/chromium/third_party/blink/renderer/core/html/track/text_track_list.h @@ -70,7 +70,7 @@ class CORE_EXPORT TextTrackList final : public EventTargetWithInlineData { bool HasShowingTracks(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void ScheduleTrackEvent(const AtomicString& event_name, TextTrack*); diff --git a/chromium/third_party/blink/renderer/core/html/track/track_base.cc b/chromium/third_party/blink/renderer/core/html/track/track_base.cc index 06186ff6f78..cffda8b41ef 100644 --- a/chromium/third_party/blink/renderer/core/html/track/track_base.cc +++ b/chromium/third_party/blink/renderer/core/html/track/track_base.cc @@ -48,7 +48,7 @@ TrackBase::TrackBase(WebMediaPlayer::TrackType type, TrackBase::~TrackBase() = default; -void TrackBase::Trace(Visitor* visitor) { +void TrackBase::Trace(Visitor* visitor) const { Supplementable<TrackBase>::Trace(visitor); visitor->Trace(media_element_); } diff --git a/chromium/third_party/blink/renderer/core/html/track/track_base.h b/chromium/third_party/blink/renderer/core/html/track/track_base.h index d752883ecb6..055fe6e79db 100644 --- a/chromium/third_party/blink/renderer/core/html/track/track_base.h +++ b/chromium/third_party/blink/renderer/core/html/track/track_base.h @@ -53,7 +53,7 @@ class CORE_EXPORT TrackBase : public Supplementable<TrackBase> { } HTMLMediaElement* MediaElement() const { return media_element_; } - void Trace(Visitor*) override; + void Trace(Visitor*) const override; protected: TrackBase(WebMediaPlayer::TrackType, diff --git a/chromium/third_party/blink/renderer/core/html/track/track_event.cc b/chromium/third_party/blink/renderer/core/html/track/track_event.cc index 24d0448c33c..e875488aeb0 100644 --- a/chromium/third_party/blink/renderer/core/html/track/track_event.cc +++ b/chromium/third_party/blink/renderer/core/html/track/track_event.cc @@ -79,7 +79,7 @@ void TrackEvent::track(VideoTrackOrAudioTrackOrTextTrack& return_value) { } } -void TrackEvent::Trace(Visitor* visitor) { +void TrackEvent::Trace(Visitor* visitor) const { visitor->Trace(track_); Event::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/track/track_event.h b/chromium/third_party/blink/renderer/core/html/track/track_event.h index 6810fe194e2..af6a98f9352 100644 --- a/chromium/third_party/blink/renderer/core/html/track/track_event.h +++ b/chromium/third_party/blink/renderer/core/html/track/track_event.h @@ -59,7 +59,7 @@ class CORE_EXPORT TrackEvent final : public Event { void track(VideoTrackOrAudioTrackOrTextTrack&); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<TrackBase> track_; diff --git a/chromium/third_party/blink/renderer/core/html/track/track_list_base.h b/chromium/third_party/blink/renderer/core/html/track/track_list_base.h index 27b4c3b8e0a..4827214252c 100644 --- a/chromium/third_party/blink/renderer/core/html/track/track_list_base.h +++ b/chromium/third_party/blink/renderer/core/html/track/track_list_base.h @@ -77,7 +77,7 @@ class TrackListBase : public EventTargetWithInlineData { ScheduleEvent(Event::Create(event_type_names::kChange)); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(tracks_); visitor->Trace(media_element_); EventTargetWithInlineData::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/core/html/track/video_track.cc b/chromium/third_party/blink/renderer/core/html/track/video_track.cc index ee63e7767c8..9fc8cc67b13 100644 --- a/chromium/third_party/blink/renderer/core/html/track/video_track.cc +++ b/chromium/third_party/blink/renderer/core/html/track/video_track.cc @@ -18,7 +18,7 @@ VideoTrack::VideoTrack(const String& id, VideoTrack::~VideoTrack() = default; -void VideoTrack::Trace(Visitor* visitor) { +void VideoTrack::Trace(Visitor* visitor) const { ScriptWrappable::Trace(visitor); TrackBase::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/track/video_track.h b/chromium/third_party/blink/renderer/core/html/track/video_track.h index a59fd126a47..69b051fba1b 100644 --- a/chromium/third_party/blink/renderer/core/html/track/video_track.h +++ b/chromium/third_party/blink/renderer/core/html/track/video_track.h @@ -23,7 +23,7 @@ class CORE_EXPORT VideoTrack final : public ScriptWrappable, public TrackBase { const AtomicString& language, bool selected); ~VideoTrack() override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; bool selected() const { return selected_; } void setSelected(bool); diff --git a/chromium/third_party/blink/renderer/core/html/track/video_track_list.h b/chromium/third_party/blink/renderer/core/html/track/video_track_list.h index 4fee375ea84..4cf6a0fdf95 100644 --- a/chromium/third_party/blink/renderer/core/html/track/video_track_list.h +++ b/chromium/third_party/blink/renderer/core/html/track/video_track_list.h @@ -24,7 +24,7 @@ class CORE_EXPORT VideoTrackList final : public TrackListBase<VideoTrack> { void TrackSelected(WebMediaPlayer::TrackId selected_track_id); - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { TrackListBase<VideoTrack>::Trace(visitor); } }; diff --git a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_cue.cc b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_cue.cc index 401575bfb08..42277379f7f 100644 --- a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_cue.cc +++ b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_cue.cc @@ -145,7 +145,7 @@ VTTCueBackgroundBox::VTTCueBackgroundBox(Document& document) SetShadowPseudoId(TextTrackCue::CueShadowPseudoId()); } -void VTTCueBackgroundBox::Trace(Visitor* visitor) { +void VTTCueBackgroundBox::Trace(Visitor* visitor) const { visitor->Trace(track_); HTMLDivElement::Trace(visitor); } @@ -1114,7 +1114,7 @@ Document& VTTCue::GetDocument() const { return cue_background_box_->GetDocument(); } -void VTTCue::Trace(Visitor* visitor) { +void VTTCue::Trace(Visitor* visitor) const { visitor->Trace(region_); visitor->Trace(vtt_node_tree_); visitor->Trace(cue_background_box_); diff --git a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_cue.h b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_cue.h index 0152de94d5d..c8aec42a505 100644 --- a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_cue.h +++ b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_cue.h @@ -80,7 +80,7 @@ class VTTCueBackgroundBox final : public HTMLDivElement { explicit VTTCueBackgroundBox(Document&); bool IsVTTCueBackgroundBox() const override { return true; } void SetTrack(TextTrack*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; const TextTrack* GetTrack() const { return track_; } @@ -172,7 +172,7 @@ class VTTCue final : public TextTrackCue { String ToString() const override; #endif - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Document& GetDocument() const; diff --git a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_element.cc b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_element.cc index ba0aef82404..d57e3602443 100644 --- a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_element.cc +++ b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_element.cc @@ -86,32 +86,32 @@ HTMLElement* VTTElement::CreateEquivalentHTMLElement(Document& document) { case kVTTNodeTypeClass: case kVTTNodeTypeLanguage: case kVTTNodeTypeVoice: - html_element = document.CreateRawElement(html_names::kSpanTag, - CreateElementFlags::ByParser()); + html_element = + document.CreateRawElement(html_names::kSpanTag, CreateElementFlags()); html_element->setAttribute(html_names::kTitleAttr, getAttribute(VoiceAttributeName())); html_element->setAttribute(html_names::kLangAttr, getAttribute(LangAttributeName())); break; case kVTTNodeTypeItalic: - html_element = document.CreateRawElement(html_names::kITag, - CreateElementFlags::ByParser()); + html_element = + document.CreateRawElement(html_names::kITag, CreateElementFlags()); break; case kVTTNodeTypeBold: - html_element = document.CreateRawElement(html_names::kBTag, - CreateElementFlags::ByParser()); + html_element = + document.CreateRawElement(html_names::kBTag, CreateElementFlags()); break; case kVTTNodeTypeUnderline: - html_element = document.CreateRawElement(html_names::kUTag, - CreateElementFlags::ByParser()); + html_element = + document.CreateRawElement(html_names::kUTag, CreateElementFlags()); break; case kVTTNodeTypeRuby: - html_element = document.CreateRawElement(html_names::kRubyTag, - CreateElementFlags::ByParser()); + html_element = + document.CreateRawElement(html_names::kRubyTag, CreateElementFlags()); break; case kVTTNodeTypeRubyText: - html_element = document.CreateRawElement(html_names::kRtTag, - CreateElementFlags::ByParser()); + html_element = + document.CreateRawElement(html_names::kRtTag, CreateElementFlags()); break; default: NOTREACHED(); @@ -137,7 +137,7 @@ void VTTElement::SetTrack(TextTrack* track) { track_ = track; } -void VTTElement::Trace(Visitor* visitor) { +void VTTElement::Trace(Visitor* visitor) const { visitor->Trace(track_); Element::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_element.h b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_element.h index 9d26b2e9165..f95165e7cdf 100644 --- a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_element.h +++ b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_element.h @@ -82,7 +82,7 @@ class VTTElement final : public Element { const TextTrack* GetTrack() const { return track_; } void SetTrack(TextTrack*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<TextTrack> track_; diff --git a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_parser.cc b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_parser.cc index 3d878c164b5..0b6e9b6b8b6 100644 --- a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_parser.cc +++ b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_parser.cc @@ -669,7 +669,7 @@ void VTTTreeBuilder::ConstructTreeFromToken(Document& document) { } } -void VTTParser::Trace(Visitor* visitor) { +void VTTParser::Trace(Visitor* visitor) const { visitor->Trace(document_); visitor->Trace(current_region_); visitor->Trace(client_); diff --git a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_parser.h b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_parser.h index 92355c84d39..b214f9303f6 100644 --- a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_parser.h +++ b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_parser.h @@ -54,7 +54,7 @@ class VTTParserClient : public GarbageCollectedMixin { virtual void NewCuesParsed() = 0; virtual void FileFailedToParse() = 0; - void Trace(Visitor* visitor) override {} + void Trace(Visitor* visitor) const override {} }; // Implementation of the WebVTT parser algorithm. @@ -114,7 +114,7 @@ class VTTParser final : public GarbageCollected<VTTParser> { // Transfers ownership of last parsed style sheets to caller. void GetNewStyleSheets(HeapVector<Member<CSSStyleSheet>>&); - void Trace(Visitor*); + void Trace(Visitor*) const; private: Member<Document> document_; diff --git a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.cc b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.cc index a7395d16272..d551daa9dea 100644 --- a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.cc +++ b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.cc @@ -419,7 +419,7 @@ void VTTRegion::ScrollTimerFired(TimerBase*) { DisplayLastVTTCueBox(); } -void VTTRegion::Trace(Visitor* visitor) { +void VTTRegion::Trace(Visitor* visitor) const { visitor->Trace(cue_container_); visitor->Trace(region_display_tree_); ScriptWrappable::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.h b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.h index 0adac94f793..87dadf7ad56 100644 --- a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.h +++ b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_region.h @@ -88,7 +88,7 @@ class VTTRegion final : public ScriptWrappable { void DisplayLastVTTCueBox(); void WillRemoveVTTCueBox(VTTCueBox*); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void PrepareRegionDisplayTree(); diff --git a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_tokenizer.cc b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_tokenizer.cc index 3483fa68061..9cee192afca 100644 --- a/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_tokenizer.cc +++ b/chromium/third_party/blink/renderer/core/html/track/vtt/vtt_tokenizer.cc @@ -30,6 +30,7 @@ #include "third_party/blink/renderer/core/html/track/vtt/vtt_tokenizer.h" +#include "base/notreached.h" #include "third_party/blink/renderer/core/html/parser/html_entity_parser.h" #include "third_party/blink/renderer/core/html/parser/markup_tokenizer_inlines.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" diff --git a/chromium/third_party/blink/renderer/core/html/trust_token_attribute_parsing.cc b/chromium/third_party/blink/renderer/core/html/trust_token_attribute_parsing.cc index 0724901f6f1..5f67023e60f 100644 --- a/chromium/third_party/blink/renderer/core/html/trust_token_attribute_parsing.cc +++ b/chromium/third_party/blink/renderer/core/html/trust_token_attribute_parsing.cc @@ -6,6 +6,7 @@ #include "services/network/public/mojom/trust_tokens.mojom-blink.h" #include "services/network/public/mojom/trust_tokens.mojom-shared.h" #include "third_party/blink/renderer/bindings/core/v8/v8_trust_token.h" +#include "third_party/blink/renderer/core/fetch/trust_token_to_mojom.h" #include "third_party/blink/renderer/platform/json/json_values.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" @@ -133,6 +134,14 @@ network::mojom::blink::TrustTokenParamsPtr TrustTokenParamsFromJson( } } + // |additionalSigningData| is optional. + if (JSONValue* additional_signing_data = + object->Get("additionalSigningData")) { + if (!additional_signing_data->AsString( + &ret->possibly_unsafe_additional_signing_data)) + return nullptr; + } + return ret; } diff --git a/chromium/third_party/blink/renderer/core/html/trust_token_attribute_parsing_test.cc b/chromium/third_party/blink/renderer/core/html/trust_token_attribute_parsing_test.cc index 75934f207ff..85721c02335 100644 --- a/chromium/third_party/blink/renderer/core/html/trust_token_attribute_parsing_test.cc +++ b/chromium/third_party/blink/renderer/core/html/trust_token_attribute_parsing_test.cc @@ -229,5 +229,15 @@ TEST(TrustTokenAttributeParsing, TypeUnsafeAdditionalSignedHeader) { ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json))); } +// Test that the parser requires that additionalSigningData be a string. +TEST(TrustTokenAttributeParsing, TypeUnsafeAdditionalSigningData) { + auto json = ParseJSON(R"( + { "type": "token-request", + "additionalSigningData": 15 } + )"); + ASSERT_TRUE(json); + ASSERT_FALSE(TrustTokenParamsFromJson(std::move(json))); +} + } // namespace internal } // namespace blink |