diff --git a/blink/renderer/bindings/generated_in_modules.gni b/blink/renderer/bindings/generated_in_modules.gni index 173262dbd53c..938b099d2a1f 100644 --- a/blink/renderer/bindings/generated_in_modules.gni +++ b/blink/renderer/bindings/generated_in_modules.gni @@ -227,8 +227,6 @@ generated_dictionary_sources_in_modules = [ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_channel_splitter_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_client_query_options.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_client_query_options.h", - "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_clipboard_item_options.cc", - "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_clipboard_item_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_clipboard_permission_descriptor.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_clipboard_permission_descriptor.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_close_event_init.cc", diff --git a/blink/renderer/bindings/idl_in_modules.gni b/blink/renderer/bindings/idl_in_modules.gni index 04e31813d634..66e021717ccc 100644 --- a/blink/renderer/bindings/idl_in_modules.gni +++ b/blink/renderer/bindings/idl_in_modules.gni @@ -107,7 +107,6 @@ static_idl_files_in_modules = get_path_info( "//third_party/blink/renderer/modules/canvas/offscreencanvas2d/offscreen_canvas_rendering_context_2d.idl", "//third_party/blink/renderer/modules/clipboard/clipboard.idl", "//third_party/blink/renderer/modules/clipboard/clipboard_item.idl", - "//third_party/blink/renderer/modules/clipboard/clipboard_item_options.idl", "//third_party/blink/renderer/modules/clipboard/navigator_clipboard.idl", "//third_party/blink/renderer/modules/compression/compression_stream.idl", "//third_party/blink/renderer/modules/compression/decompression_stream.idl", diff --git a/blink/renderer/core/testing/mock_clipboard_host.cc b/blink/renderer/core/testing/mock_clipboard_host.cc index 0f0b30abfd67..96b43043bf19 100644 --- a/blink/renderer/core/testing/mock_clipboard_host.cc +++ b/blink/renderer/core/testing/mock_clipboard_host.cc @@ -10,6 +10,7 @@ #include "third_party/blink/public/common/tokens/tokens.h" #include "third_party/blink/renderer/platform/graphics/color_behavior.h" #include "third_party/blink/renderer/platform/image-encoders/image_encoder.h" +#include "third_party/blink/renderer/platform/wtf/text/string_builder.h" #include "third_party/skia/include/core/SkBitmap.h" namespace blink { @@ -40,9 +41,7 @@ void MockClipboardHost::GetSequenceNumber( std::move(callback).Run(sequence_number_); } -void MockClipboardHost::ReadAvailableTypes( - mojom::ClipboardBuffer clipboard_buffer, - ReadAvailableTypesCallback callback) { +Vector MockClipboardHost::ReadStandardFormatNames() { Vector types; if (!plain_text_.IsEmpty()) types.push_back("text/plain"); @@ -56,7 +55,14 @@ void MockClipboardHost::ReadAvailableTypes( CHECK(!base::Contains(types, it.key)); types.push_back(it.key); } - std::move(callback).Run(types); + return types; +} + +void MockClipboardHost::ReadAvailableTypes( + mojom::ClipboardBuffer clipboard_buffer, + ReadAvailableTypesCallback callback) { + Vector types = ReadStandardFormatNames(); + std::move(callback).Run(std::move(types)); } void MockClipboardHost::IsFormatAvailable( @@ -173,10 +179,10 @@ void MockClipboardHost::CommitWrite() { void MockClipboardHost::ReadAvailableCustomAndStandardFormats( ReadAvailableCustomAndStandardFormatsCallback callback) { - Vector format_names; + Vector format_names = ReadStandardFormatNames(); for (const auto& item : unsanitized_custom_data_map_) format_names.emplace_back(item.key); - std::move(callback).Run(format_names); + std::move(callback).Run(std::move(format_names)); } void MockClipboardHost::ReadUnsanitizedCustomFormat( @@ -199,7 +205,9 @@ void MockClipboardHost::WriteUnsanitizedCustomFormat( // Simulate the underlying platform copying this data. Vector data_copy(base::saturated_cast(data.size()), *data.data()); - unsanitized_custom_data_map_.Set(format, data_copy); + // Append the "web " prefix since it is removed by the clipboard writer during + // write. + unsanitized_custom_data_map_.Set("web " + format, std::move(data_copy)); } #if BUILDFLAG(IS_MAC) diff --git a/blink/renderer/core/testing/mock_clipboard_host.h b/blink/renderer/core/testing/mock_clipboard_host.h index 73d3fac44cbf..74ac69d20546 100644 --- a/blink/renderer/core/testing/mock_clipboard_host.h +++ b/blink/renderer/core/testing/mock_clipboard_host.h @@ -67,6 +67,7 @@ class MockClipboardHost : public mojom::blink::ClipboardHost { #if BUILDFLAG(IS_MAC) void WriteStringToFindPboard(const String& text) override; #endif + Vector ReadStandardFormatNames(); mojo::ReceiverSet receivers_; ClipboardSequenceNumberToken sequence_number_; diff --git a/blink/renderer/modules/clipboard/DEPS b/blink/renderer/modules/clipboard/DEPS index d6391a348599..4dc7b35d1024 100644 --- a/blink/renderer/modules/clipboard/DEPS +++ b/blink/renderer/modules/clipboard/DEPS @@ -1,5 +1,6 @@ include_rules = [ "+mojo/public/cpp/base/big_buffer.h", + "+net/base/mime_util.h", "+third_party/blink/renderer/core/clipboard", "-third_party/blink/renderer/modules", "+third_party/blink/renderer/modules/event_modules.h", diff --git a/blink/renderer/modules/clipboard/clipboard.cc b/blink/renderer/modules/clipboard/clipboard.cc index f08ebfcd1b76..50175b125973 100644 --- a/blink/renderer/modules/clipboard/clipboard.cc +++ b/blink/renderer/modules/clipboard/clipboard.cc @@ -6,11 +6,11 @@ #include #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" -#include "third_party/blink/renderer/bindings/modules/v8/v8_clipboard_item_options.h" #include "third_party/blink/renderer/core/event_target_names.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/frame/navigator.h" #include "third_party/blink/renderer/modules/clipboard/clipboard_promise.h" +#include "ui/base/clipboard/clipboard_constants.h" namespace blink { @@ -29,13 +29,7 @@ Clipboard* Clipboard::clipboard(Navigator& navigator) { Clipboard::Clipboard(Navigator& navigator) : Supplement(navigator) {} ScriptPromise Clipboard::read(ScriptState* script_state) { - return read(script_state, ClipboardItemOptions::Create()); -} - -ScriptPromise Clipboard::read(ScriptState* script_state, - ClipboardItemOptions* options) { - return ClipboardPromise::CreateForRead(GetExecutionContext(), script_state, - options); + return ClipboardPromise::CreateForRead(GetExecutionContext(), script_state); } ScriptPromise Clipboard::readText(ScriptState* script_state) { @@ -63,6 +57,16 @@ ExecutionContext* Clipboard::GetExecutionContext() const { return GetSupplementable()->DomWindow(); } +// static +String Clipboard::ParseWebCustomFormat(const String& format) { + String web_custom_format; + if (format.StartsWith(ui::kWebClipboardFormatPrefix)) { + web_custom_format = format.Substring( + static_cast(std::strlen(ui::kWebClipboardFormatPrefix))); + } + return web_custom_format; +} + void Clipboard::Trace(Visitor* visitor) const { EventTargetWithInlineData::Trace(visitor); Supplement::Trace(visitor); diff --git a/blink/renderer/modules/clipboard/clipboard.h b/blink/renderer/modules/clipboard/clipboard.h index 8e2d168b8bba..8b66d4585361 100644 --- a/blink/renderer/modules/clipboard/clipboard.h +++ b/blink/renderer/modules/clipboard/clipboard.h @@ -13,7 +13,6 @@ namespace blink { -class ClipboardItemOptions; class Navigator; class ScriptState; @@ -30,7 +29,6 @@ class Clipboard : public EventTargetWithInlineData, Clipboard& operator=(const Clipboard&) = delete; ScriptPromise read(ScriptState*); - ScriptPromise read(ScriptState*, ClipboardItemOptions*); ScriptPromise readText(ScriptState*); ScriptPromise write(ScriptState*, const HeapVector>&); @@ -40,6 +38,8 @@ class Clipboard : public EventTargetWithInlineData, const AtomicString& InterfaceName() const override; ExecutionContext* GetExecutionContext() const override; + static String ParseWebCustomFormat(const String& format); + void Trace(Visitor*) const override; }; diff --git a/blink/renderer/modules/clipboard/clipboard.idl b/blink/renderer/modules/clipboard/clipboard.idl index 01d0dac998d4..0f90bb027560 100644 --- a/blink/renderer/modules/clipboard/clipboard.idl +++ b/blink/renderer/modules/clipboard/clipboard.idl @@ -12,11 +12,6 @@ CallWith=ScriptState ] Promise> read(); - [MeasureAs=AsyncClipboardAPIRead, - CallWith=ScriptState, - RuntimeEnabled=ClipboardCustomFormats - ] Promise> read(ClipboardItemOptions options); - [MeasureAs=AsyncClipboardAPIReadText, CallWith=ScriptState ] Promise readText(); diff --git a/blink/renderer/modules/clipboard/clipboard_item.cc b/blink/renderer/modules/clipboard/clipboard_item.cc index cac082816898..9c94308e4b04 100644 --- a/blink/renderer/modules/clipboard/clipboard_item.cc +++ b/blink/renderer/modules/clipboard/clipboard_item.cc @@ -4,21 +4,22 @@ #include "third_party/blink/renderer/modules/clipboard/clipboard_item.h" +#include "net/base/mime_util.h" #include "third_party/blink/public/common/features.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" -#include "third_party/blink/renderer/bindings/modules/v8/v8_clipboard_item_options.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" +#include "third_party/blink/renderer/modules/clipboard/clipboard.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" +#include "third_party/blink/renderer/platform/wtf/text/string_builder.h" +#include "ui/base/clipboard/clipboard_constants.h" namespace blink { // static ClipboardItem* ClipboardItem::Create( const HeapVector>& items, - const ClipboardItemOptions* options, ExceptionState& exception_state) { - DCHECK(options); // Check that incoming dictionary isn't empty. If it is, it's possible that // Javascript bindings implicitly converted an Object (like a ScriptPromise) // into {}, an empty dictionary. @@ -26,18 +27,38 @@ ClipboardItem* ClipboardItem::Create( exception_state.ThrowTypeError("Empty dictionary argument"); return nullptr; } - return MakeGarbageCollected(items, options); + return MakeGarbageCollected(items); } ClipboardItem::ClipboardItem( - const HeapVector>& items, - const ClipboardItemOptions* options) - : items_(items) { - DCHECK(items_.size()); - if (options->hasUnsanitized()) { - for (const auto& unsanitized_item : options->unsanitized()) { - custom_format_items_.push_back(unsanitized_item); + const HeapVector>& items) { + DCHECK(items.size()); + for (const auto& item : items) { + String web_custom_format = Clipboard::ParseWebCustomFormat(item.first); + if (!web_custom_format.IsEmpty()) { + // Types with "web " prefix are special, so we do some level of MIME type + // parsing here to get a valid web custom format type. + // We want to ensure that the string after removing the "web " prefix is + // a valid MIME type. + // e.g. "web text/html" is a web custom MIME type & "text/html" is a + // well-known MIME type. Removing the "web " prefix makes it hard to + // differentiate between the two. + std::string web_top_level_mime_type; + std::string web_mime_sub_type; + if (net::ParseMimeTypeWithoutParameter(web_custom_format.Utf8(), + &web_top_level_mime_type, + &web_mime_sub_type)) { + String web_custom_format_string = String::Format( + "%s%s/%s", ui::kWebClipboardFormatPrefix, + web_top_level_mime_type.c_str(), web_mime_sub_type.c_str()); + items_.emplace_back(web_custom_format_string, item.second); + custom_format_items_.push_back(web_custom_format_string); + continue; + } } + // Any arbitrary type can be added to ClipboardItem, but there may not be + // any read/write support for that type. + items_.push_back(item); } } @@ -54,9 +75,8 @@ ScriptPromise ClipboardItem::getType(ScriptState* script_state, const String& type, ExceptionState& exception_state) const { for (const auto& item : items_) { - if (type == item.first) { + if (type == item.first) return item.second; - } } exception_state.ThrowDOMException(DOMExceptionCode::kNotFoundError, diff --git a/blink/renderer/modules/clipboard/clipboard_item.h b/blink/renderer/modules/clipboard/clipboard_item.h index c665606a8bb6..a4fc528c080f 100644 --- a/blink/renderer/modules/clipboard/clipboard_item.h +++ b/blink/renderer/modules/clipboard/clipboard_item.h @@ -12,7 +12,6 @@ namespace blink { class ScriptState; -class ClipboardItemOptions; class ClipboardItem final : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); @@ -20,12 +19,10 @@ class ClipboardItem final : public ScriptWrappable { public: static ClipboardItem* Create( const HeapVector>& items, - const ClipboardItemOptions* options, ExceptionState& exception_state); explicit ClipboardItem( - const HeapVector>& items, - const ClipboardItemOptions* options); + const HeapVector>& items); Vector types() const; ScriptPromise getType(ScriptState* script_state, const String& type, @@ -35,7 +32,7 @@ class ClipboardItem final : public ScriptWrappable { return items_; } - // Returns the custom formats passed to direct option. + // Returns the custom formats that have a "web " prefix. const Vector& CustomFormats() const { return custom_format_items_; } void Trace(Visitor*) const override; diff --git a/blink/renderer/modules/clipboard/clipboard_item.idl b/blink/renderer/modules/clipboard/clipboard_item.idl index 3a8a2664339b..9a5029084e76 100644 --- a/blink/renderer/modules/clipboard/clipboard_item.idl +++ b/blink/renderer/modules/clipboard/clipboard_item.idl @@ -8,8 +8,7 @@ SecureContext, Exposed=Window ] interface ClipboardItem { - [RaisesException] constructor(record> items, - optional ClipboardItemOptions options = {}); + [RaisesException] constructor(record> items); readonly attribute FrozenArray types; [ diff --git a/blink/renderer/modules/clipboard/clipboard_item_options.idl b/blink/renderer/modules/clipboard/clipboard_item_options.idl deleted file mode 100644 index c1e12134f667..000000000000 --- a/blink/renderer/modules/clipboard/clipboard_item_options.idl +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// https://w3c.github.io/clipboard-apis/#clipboard-interface - -dictionary ClipboardItemOptions { - [RuntimeEnabled=ClipboardCustomFormats] sequence unsanitized; -}; \ No newline at end of file diff --git a/blink/renderer/modules/clipboard/clipboard_promise.cc b/blink/renderer/modules/clipboard/clipboard_promise.cc index 307e408b319a..d398e4ba09f4 100644 --- a/blink/renderer/modules/clipboard/clipboard_promise.cc +++ b/blink/renderer/modules/clipboard/clipboard_promise.cc @@ -15,7 +15,6 @@ #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/bindings/core/v8/script_function.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" -#include "third_party/blink/renderer/bindings/modules/v8/v8_clipboard_item_options.h" #include "third_party/blink/renderer/core/clipboard/clipboard_mime_types.h" #include "third_party/blink/renderer/core/clipboard/system_clipboard.h" #include "third_party/blink/renderer/core/dom/document.h" @@ -115,16 +114,14 @@ class ClipboardPromise::BlobPromiseResolverFunction final // static ScriptPromise ClipboardPromise::CreateForRead(ExecutionContext* context, - ScriptState* script_state, - ClipboardItemOptions* options) { + ScriptState* script_state) { if (!script_state->ContextIsValid()) return ScriptPromise(); ClipboardPromise* clipboard_promise = MakeGarbageCollected(context, script_state); clipboard_promise->GetTaskRunner()->PostTask( - FROM_HERE, - WTF::Bind(&ClipboardPromise::HandleRead, - WrapPersistent(clipboard_promise), WrapPersistent(options))); + FROM_HERE, WTF::Bind(&ClipboardPromise::HandleRead, + WrapPersistent(clipboard_promise))); return clipboard_promise->script_promise_resolver_->Promise(); } @@ -215,22 +212,10 @@ void ClipboardPromise::WriteNextRepresentation() { wtf_size_t item_index = custom_format_items_.Find(type); if (item_index != kNotFound) { clipboard_writer_ = - ClipboardWriter::Create(local_frame->GetSystemClipboard(), type, this, - /*is_custom_format_type*/ true); - if (ClipboardWriter::IsValidType(type, /*is_custom_format_type*/ false)) { - // Decrement `clipboard_representation_index_` & remove the format from - // the `custom_format_items_` so we can redo the write, but this time, it - // will write a sanitized version of the format using the "standard" - // format writer. Standard formats include text/html, text/plain, - // text/rtf, image/png, text/uri-list & image/svg+xml. - // https://github.com/w3c/editing/blob/gh-pages/docs/clipboard-pickling/explainer.md#pickled-version-for-sanitized-formats - custom_format_items_.EraseAt(item_index); - clipboard_representation_index_--; - } + ClipboardWriter::Create(local_frame->GetSystemClipboard(), type, this); } else { clipboard_writer_ = - ClipboardWriter::Create(local_frame->GetSystemClipboard(), type, this, - /*is_custom_format_type*/ false); + ClipboardWriter::Create(local_frame->GetSystemClipboard(), type, this); } clipboard_writer_->WriteToSystem(blob); } @@ -245,22 +230,19 @@ void ClipboardPromise::RejectFromReadOrDecodeFailure() { clipboard_item_data_[clipboard_representation_index_].first + ".")); } -void ClipboardPromise::HandleRead(ClipboardItemOptions* options) { +void ClipboardPromise::HandleRead() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (options->hasUnsanitized()) { - for (const auto& unsanitized_item : options->unsanitized()) { - custom_format_items_.push_back(unsanitized_item); - } - } RequestPermission(mojom::blink::PermissionName::CLIPBOARD_READ, - !custom_format_items_.IsEmpty(), + /*allow_without_sanitization=*/ + RuntimeEnabledFeatures::ClipboardCustomFormatsEnabled(), WTF::Bind(&ClipboardPromise::HandleReadWithPermission, WrapPersistent(this))); } void ClipboardPromise::HandleReadText() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - RequestPermission(mojom::blink::PermissionName::CLIPBOARD_READ, false, + RequestPermission(mojom::blink::PermissionName::CLIPBOARD_READ, + /*allow_without_sanitization=*/false, WTF::Bind(&ClipboardPromise::HandleReadTextWithPermission, WrapPersistent(this))); } @@ -299,16 +281,18 @@ void ClipboardPromise::HandleWrite( DCHECK(RuntimeEnabledFeatures::ClipboardCustomFormatsEnabled() || custom_format_items_.IsEmpty()); - RequestPermission(mojom::blink::PermissionName::CLIPBOARD_WRITE, - !custom_format_items_.IsEmpty(), - WTF::Bind(&ClipboardPromise::HandleWriteWithPermission, - WrapPersistent(this))); + RequestPermission( + mojom::blink::PermissionName::CLIPBOARD_WRITE, + /*allow_without_sanitization=*/!custom_format_items_.IsEmpty(), + WTF::Bind(&ClipboardPromise::HandleWriteWithPermission, + WrapPersistent(this))); } void ClipboardPromise::HandleWriteText(const String& data) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); plain_text_ = data; - RequestPermission(mojom::blink::PermissionName::CLIPBOARD_WRITE, false, + RequestPermission(mojom::blink::PermissionName::CLIPBOARD_WRITE, + /*allow_without_sanitization=*/false, WTF::Bind(&ClipboardPromise::HandleWriteTextWithPermission, WrapPersistent(this))); } @@ -324,7 +308,7 @@ void ClipboardPromise::HandleReadWithPermission(PermissionStatus status) { } SystemClipboard* system_clipboard = GetLocalFrame()->GetSystemClipboard(); - if (!custom_format_items_.IsEmpty()) { + if (RuntimeEnabledFeatures::ClipboardCustomFormatsEnabled()) { system_clipboard->ReadAvailableCustomAndStandardFormats(WTF::Bind( &ClipboardPromise::OnReadAvailableFormatNames, WrapPersistent(this))); return; @@ -343,9 +327,6 @@ void ClipboardPromise::ResolveRead() { return; } - ClipboardItemOptions* options = ClipboardItemOptions::Create(); - options->setUnsanitized(custom_format_items_); - ScriptState::Scope scope(script_state_); HeapVector> items; items.ReserveInitialCapacity(clipboard_item_data_.size()); @@ -356,7 +337,7 @@ void ClipboardPromise::ResolveRead() { items.emplace_back(item.first, promise); } HeapVector> clipboard_items = { - MakeGarbageCollected(items, options)}; + MakeGarbageCollected(items)}; script_promise_resolver_->Resolve(clipboard_items); } @@ -368,8 +349,7 @@ void ClipboardPromise::OnReadAvailableFormatNames( clipboard_item_data_.ReserveInitialCapacity(format_names.size()); for (const String& format_name : format_names) { - if (ClipboardWriter::IsValidType( - format_name, base::Contains(custom_format_items_, format_name))) { + if (ClipboardWriter::IsValidType(format_name)) { clipboard_item_data_.emplace_back(format_name, /* Placeholder value. */ nullptr); } @@ -390,8 +370,7 @@ void ClipboardPromise::ReadNextRepresentation() { clipboard_item_data_[clipboard_representation_index_].first; ClipboardReader* clipboard_reader = ClipboardReader::Create( - GetLocalFrame()->GetSystemClipboard(), format_name, this, - base::Contains(custom_format_items_, format_name)); + GetLocalFrame()->GetSystemClipboard(), format_name, this); if (!clipboard_reader) { OnRead(nullptr); return; @@ -469,8 +448,7 @@ void ClipboardPromise::HandleWriteWithPermission(PermissionStatus status) { const String& type = type_and_promise_to_blob.first; clipboard_item_types_.emplace_back(type); promise_list.emplace_back(type_and_promise_to_blob.second); - bool is_valid_custom_format = base::Contains(custom_format_items_, type); - if (!ClipboardWriter::IsValidType(type, is_valid_custom_format)) { + if (!ClipboardWriter::IsValidType(type)) { script_promise_resolver_->Reject(MakeGarbageCollected( DOMExceptionCode::kNotAllowedError, "Type " + type + " not supported on write.")); @@ -559,7 +537,8 @@ void ClipboardPromise::RequestPermission( LocalFrame::HasTransientUserActivation(GetLocalFrame()); base::UmaHistogramBoolean("Blink.Clipboard.HasTransientUserActivation", has_transient_user_activation); - if (!custom_format_items_.IsEmpty() && !has_transient_user_activation) { + if (RuntimeEnabledFeatures::ClipboardCustomFormatsEnabled() && + !has_transient_user_activation) { script_promise_resolver_->Reject(MakeGarbageCollected( DOMExceptionCode::kSecurityError, "Must be handling a user gesture to use custom clipboard")); @@ -586,7 +565,8 @@ void ClipboardPromise::RequestPermission( // Check permission, and query if necessary. // See crbug.com/795929 for moving this check into the Browser process. permission_service_->RequestPermission(std::move(permission_descriptor), - false, std::move(callback)); + /*user_gesture*/ false, + std::move(callback)); } LocalFrame* ClipboardPromise::GetLocalFrame() const { diff --git a/blink/renderer/modules/clipboard/clipboard_promise.h b/blink/renderer/modules/clipboard/clipboard_promise.h index 28c51842d25e..ceee63ad6239 100644 --- a/blink/renderer/modules/clipboard/clipboard_promise.h +++ b/blink/renderer/modules/clipboard/clipboard_promise.h @@ -31,9 +31,7 @@ class ClipboardPromise final : public GarbageCollected, public ExecutionContextLifecycleObserver { public: // Creates promise to execute Clipboard API functions off the main thread. - static ScriptPromise CreateForRead(ExecutionContext*, - ScriptState*, - ClipboardItemOptions*); + static ScriptPromise CreateForRead(ExecutionContext*, ScriptState*); static ScriptPromise CreateForReadText(ExecutionContext*, ScriptState*); static ScriptPromise CreateForWrite(ExecutionContext*, ScriptState*, @@ -70,7 +68,7 @@ class ClipboardPromise final : public GarbageCollected, void WriteNextRepresentation(); // Checks Read/Write permission (interacting with PermissionService). - void HandleRead(ClipboardItemOptions*); + void HandleRead(); void HandleReadText(); void HandleWrite(HeapVector>*); void HandleWriteText(const String&); diff --git a/blink/renderer/modules/clipboard/clipboard_reader.cc b/blink/renderer/modules/clipboard/clipboard_reader.cc index c37ee70d5723..19a3a84c83a8 100644 --- a/blink/renderer/modules/clipboard/clipboard_reader.cc +++ b/blink/renderer/modules/clipboard/clipboard_reader.cc @@ -12,6 +12,7 @@ #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/web_feature.h" #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h" +#include "third_party/blink/renderer/modules/clipboard/clipboard.h" #include "third_party/blink/renderer/modules/clipboard/clipboard_promise.h" #include "third_party/blink/renderer/modules/clipboard/clipboard_writer.h" #include "third_party/blink/renderer/platform/image-encoders/image_encoder.h" @@ -305,12 +306,14 @@ class ClipboardCustomFormatReader final : public ClipboardReader { // static ClipboardReader* ClipboardReader::Create(SystemClipboard* system_clipboard, const String& mime_type, - ClipboardPromise* promise, - bool is_custom_format_type) { - DCHECK(ClipboardWriter::IsValidType(mime_type, is_custom_format_type)); - // If this is a custom format then read the unsanitized version. - if (is_custom_format_type && - RuntimeEnabledFeatures::ClipboardCustomFormatsEnabled()) { + ClipboardPromise* promise) { + DCHECK(ClipboardWriter::IsValidType(mime_type)); + // If this is a web custom format then read the unsanitized version. + if (RuntimeEnabledFeatures::ClipboardCustomFormatsEnabled() && + !Clipboard::ParseWebCustomFormat(mime_type).IsNull()) { + // We read the custom MIME type that has the "web " prefix. + // These MIME types are found in the web custom format map written by + // native applications. return MakeGarbageCollected( system_clipboard, promise, mime_type); } diff --git a/blink/renderer/modules/clipboard/clipboard_reader.h b/blink/renderer/modules/clipboard/clipboard_reader.h index abbf2dce60bb..1e123431acab 100644 --- a/blink/renderer/modules/clipboard/clipboard_reader.h +++ b/blink/renderer/modules/clipboard/clipboard_reader.h @@ -43,8 +43,7 @@ class ClipboardReader : public GarbageCollected { // ClipboardWriter::IsValidType() must return true for `mime_type`. static ClipboardReader* Create(SystemClipboard* system_clipboard, const String& mime_type, - ClipboardPromise* promise, - bool is_custom_format_type); + ClipboardPromise* promise); virtual ~ClipboardReader(); // Reads from the system clipboard and encodes on a background thread. diff --git a/blink/renderer/modules/clipboard/clipboard_writer.cc b/blink/renderer/modules/clipboard/clipboard_writer.cc index 9ef088c9ff90..aa8421a6c4a4 100644 --- a/blink/renderer/modules/clipboard/clipboard_writer.cc +++ b/blink/renderer/modules/clipboard/clipboard_writer.cc @@ -15,6 +15,7 @@ #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/web_feature.h" #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h" +#include "third_party/blink/renderer/modules/clipboard/clipboard.h" #include "third_party/blink/renderer/platform/image-decoders/image_decoder.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h" @@ -23,6 +24,7 @@ #include "third_party/blink/renderer/platform/wtf/cross_thread_copier_skia.h" #include "third_party/blink/renderer/platform/wtf/cross_thread_functional.h" #include "third_party/blink/renderer/platform/wtf/wtf.h" +#include "ui/base/clipboard/clipboard_constants.h" namespace blink { @@ -258,13 +260,17 @@ class ClipboardCustomFormatWriter final : public ClipboardWriter { // static ClipboardWriter* ClipboardWriter::Create(SystemClipboard* system_clipboard, const String& mime_type, - ClipboardPromise* promise, - bool is_custom_format_type) { - DCHECK(ClipboardWriter::IsValidType(mime_type, is_custom_format_type)); - if (is_custom_format_type && - RuntimeEnabledFeatures::ClipboardCustomFormatsEnabled()) { + ClipboardPromise* promise) { + DCHECK(ClipboardWriter::IsValidType(mime_type)); + if (RuntimeEnabledFeatures::ClipboardCustomFormatsEnabled() && + !Clipboard::ParseWebCustomFormat(mime_type).IsEmpty()) { + // We write the custom MIME type without the "web " prefix into the web + // custom format map so native applications don't have to add any string + // parsing logic to read format from clipboard. return MakeGarbageCollected( - system_clipboard, promise, mime_type); + system_clipboard, promise, + mime_type.Substring( + static_cast(std::strlen(ui::kWebClipboardFormatPrefix)))); } if (mime_type == kMimeTypeImagePng) { return MakeGarbageCollected(system_clipboard, @@ -299,11 +305,10 @@ ClipboardWriter::~ClipboardWriter() { } // static -bool ClipboardWriter::IsValidType(const String& type, - bool is_custom_format_type) { - if (is_custom_format_type) { - return RuntimeEnabledFeatures::ClipboardCustomFormatsEnabled() && - type.length() < mojom::blink::ClipboardHost::kMaxFormatSize; +bool ClipboardWriter::IsValidType(const String& type) { + if (RuntimeEnabledFeatures::ClipboardCustomFormatsEnabled() && + !Clipboard::ParseWebCustomFormat(type).IsEmpty()) { + return type.length() < mojom::blink::ClipboardHost::kMaxFormatSize; } if (type == kMimeTypeImageSvg) return RuntimeEnabledFeatures::ClipboardSvgEnabled(); diff --git a/blink/renderer/modules/clipboard/clipboard_writer.h b/blink/renderer/modules/clipboard/clipboard_writer.h index 278f10426d03..97776968405f 100644 --- a/blink/renderer/modules/clipboard/clipboard_writer.h +++ b/blink/renderer/modules/clipboard/clipboard_writer.h @@ -57,8 +57,7 @@ class ClipboardWriter : public GarbageCollected, // IsValidType() must return true on types passed into `mime_type`. static ClipboardWriter* Create(SystemClipboard* system_clipboard, const String& mime_type, - ClipboardPromise* promise, - bool is_custom_format_type); + ClipboardPromise* promise); ~ClipboardWriter() override; @@ -70,7 +69,7 @@ class ClipboardWriter : public GarbageCollected, // IsValidType() is used for both ClipboardWriter and ClipboardReader, as read // and write currently support the same types. If this changes in the future, // please create separate IsValidType functions. - static bool IsValidType(const String& mime_type, bool is_custom_format_type); + static bool IsValidType(const String& mime_type); // Begins the sequence of writing the Blob to the system clipbaord. void WriteToSystem(Blob* blob); diff --git a/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py b/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py index a835d91c7941..e6f5913fd9f2 100755 --- a/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py +++ b/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py @@ -1734,6 +1734,12 @@ 'base::Value', ], }, + { + 'paths': ['third_party/blink/renderer/modules/clipboard/'], + 'allowed': [ + 'net::ParseMimeTypeWithoutParameter', + ], + }, ] diff --git a/blink/web_tests/clipboard/async-clipboard/async-custom-format-write-read.tentative.https.html b/blink/web_tests/clipboard/async-clipboard/async-custom-format-write-read.tentative.https.html index 779722ea6bd9..507de149bcd4 100644 --- a/blink/web_tests/clipboard/async-clipboard/async-custom-format-write-read.tentative.https.html +++ b/blink/web_tests/clipboard/async-clipboard/async-custom-format-write-read.tentative.https.html @@ -13,10 +13,9 @@ 'use strict'; async function customFormatWriteBeforeTest() { - const format = 'text/customformat'; + const format = 'web text/customformat'; const blob = new Blob(['CustomFormatClipboardDisabled'], {type: format}); - const clipboardItem = new ClipboardItem( - {[format]: blob}, {unsanitized: [format]}); + const clipboardItem = new ClipboardItem({[format]: blob}); await waitForUserActivation(); await navigator.clipboard.write([clipboardItem]); } @@ -32,20 +31,18 @@ // message when the ClipboardCustomFormats flag isn't enabled. await customFormatWriteBeforeTest(); const dataToWrite = 'Test text.'; - const format = 'text/plain'; + const format = 'web text/plain'; const blobInput = new Blob([dataToWrite], {type: format}); // Blob types are automatically converted to lower-case. assert_equals(blobInput.type, format.toLowerCase()); - const clipboardItemInput = new ClipboardItem( - {[format]: blobInput}, {unsanitized: [format]}); + const clipboardItemInput = new ClipboardItem({[format]: blobInput}); await waitForUserActivation(); await navigator.clipboard.write([clipboardItemInput]); // Items should be readable on a system clipboard after custom format write. await waitForUserActivation(); - const clipboardItems = await navigator.clipboard.read( - {unsanitized: [format]}); + const clipboardItems = await navigator.clipboard.read(); assert_equals(clipboardItems.length, 1); const clipboardItem = clipboardItems[0]; assert_true(clipboardItem instanceof ClipboardItem); @@ -55,9 +52,9 @@ const data = await (new Response(blobOutput)).text(); assert_equals(data, dataToWrite); - // These examples use native text formats, so these formats should be + // These examples use web custom text format, so this format shouldn't be // accessible as text. const textOutput = await navigator.clipboard.readText(); - assert_equals(textOutput, dataToWrite); -}, 'Verify write and read clipboard given custom formats as input'); + assert_not_equals(textOutput, dataToWrite); +}, 'Verify write and read clipboard given web custom format as input'); diff --git a/blink/web_tests/clipboard/async-clipboard/async-custom-formats-write-read.tentative.https.html b/blink/web_tests/clipboard/async-clipboard/async-custom-formats-write-read.tentative.https.html index b5609563762c..0f5505e152dc 100644 --- a/blink/web_tests/clipboard/async-clipboard/async-custom-formats-write-read.tentative.https.html +++ b/blink/web_tests/clipboard/async-clipboard/async-custom-formats-write-read.tentative.https.html @@ -16,24 +16,18 @@ await PermissionsHelper.setPermission('clipboard-read-write', 'granted'); await PermissionsHelper.setPermission('clipboard-sanitized-write', 'granted'); - const format1 = 'application/x-custom-format-clipboard-test-format-1'; - const format2 = 'application/x-custom-format-clipboard-test-format-2'; + const format1 = 'web application/x-custom-format-clipboard-test-format-1'; + const format2 = 'web application/x-custom-format-clipboard-test-format-2'; const blobInput1 = new Blob(['input data 1'], {type: format1}); const blobInput2 = new Blob(['input data 2'], {type: format2}); const clipboardItemInput = new ClipboardItem( - {[format1]: blobInput1, [format2]: blobInput2}, - {unsanitized: [format1, format2]}); + {[format1]: blobInput1, [format2]: blobInput2}); await waitForUserActivation(); await navigator.clipboard.write([clipboardItemInput]); - // Items may not be readable on the sanitized clipboard after custom format write. - await promise_rejects_dom(t, 'DataError', - navigator.clipboard.read()); - // Items should be readable on a custom format clipboard after custom format write. await waitForUserActivation(); - const clipboardItems = await navigator.clipboard.read( - {unsanitized: [format1, format2]}); + const clipboardItems = await navigator.clipboard.read(); assert_equals(clipboardItems.length, 1); const clipboardItem = clipboardItems[0]; assert_true(clipboardItem instanceof ClipboardItem); @@ -42,12 +36,12 @@ const blobOutput1 = await clipboardItem.getType(format1); assert_equals(blobOutput1.type, format1); - const data1 = await (new Response(blobOutput1)).text(); + const data1 = await blobOutput1.text(); assert_equals(data1, 'input data 1'); const blobOutput2 = await clipboardItem.getType(format2); assert_equals(blobOutput2.type, format2); - const data2 = await (new Response(blobOutput2)).text(); + const data2 = await blobOutput2.text(); assert_equals(data2, 'input data 2'); }, 'Verify write and read clipboard given 2 platform-neutral custom format inputs'); diff --git a/blink/web_tests/clipboard/async-clipboard/async-navigator-clipboard-basics.https.html b/blink/web_tests/clipboard/async-clipboard/async-navigator-clipboard-basics.https.html index 02b503fd70c0..ef2bc8cbcc83 100644 --- a/blink/web_tests/clipboard/async-clipboard/async-navigator-clipboard-basics.https.html +++ b/blink/web_tests/clipboard/async-clipboard/async-navigator-clipboard-basics.https.html @@ -2,9 +2,13 @@ Async Clipboard input type validation tests +Body needed for test_driver.click() + + + + - + - \ No newline at end of file diff --git a/blink/web_tests/external/wpt/clipboard-apis/async-custom-formats-write-read.tentative.https.html b/blink/web_tests/external/wpt/clipboard-apis/async-custom-formats-write-read.tentative.https.html index b6c368f75bc2..77991ec98aa0 100644 --- a/blink/web_tests/external/wpt/clipboard-apis/async-custom-formats-write-read.tentative.https.html +++ b/blink/web_tests/external/wpt/clipboard-apis/async-custom-formats-write-read.tentative.https.html @@ -14,26 +14,19 @@ promise_test(async t => { await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); - const format1 = 'application/x-custom-format-clipboard-test-format-1'; - const format2 = 'application/x-custom-format-clipboard-test-format-2'; + const format1 = 'web application/x-custom-format-clipboard-test-format-1'; + const format2 = 'web application/x-custom-format-clipboard-test-format-2'; const blobInput1 = new Blob(['input data 1'], {type: format1}); const blobInput2 = new Blob(['input data 2'], {type: format2}); const clipboardItemInput = new ClipboardItem( - {[format1]: blobInput1, [format2]: blobInput2}, - {unsanitized: [format1, format2]}); + {[format1]: blobInput1, [format2]: blobInput2}); await waitForUserActivation(); await navigator.clipboard.write([clipboardItemInput]); - // Items may not be readable on the sanitized clipboard after custom format - // write. - await promise_rejects_dom(t, 'DataError', - navigator.clipboard.read()); - // Items should be readable on a custom format clipboard after custom format // write. await waitForUserActivation(); - const clipboardItems = await navigator.clipboard.read( - {unsanitized: [format1, format2]}); + const clipboardItems = await navigator.clipboard.read(); assert_equals(clipboardItems.length, 1); const clipboardItem = clipboardItems[0]; assert_true(clipboardItem instanceof ClipboardItem); @@ -58,15 +51,44 @@ const customFormatArray = []; const customFormatMap = {}; for (let i = 0; i <= 100; i++) { - customFormatArray.push("CustomFormat" + i); + customFormatArray.push("web text/CustomFormat" + i); const blobInput = new Blob(['input data'], {type: customFormatArray[i]}); customFormatMap[customFormatArray[i]] = blobInput; } - const clipboardItemInput = new ClipboardItem(customFormatMap, - {unsanitized: customFormatArray}); + const clipboardItemInput = new ClipboardItem(customFormatMap); await waitForUserActivation(); await promise_rejects_dom(t, 'NotAllowedError', navigator.clipboard.write([clipboardItemInput])); }, 'navigator.clipboard.write() fails for more than 100 custom formats'); +promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + + const format1 = 'application/x-custom-format-clipboard-test-format-1'; + const format2 = 'application/x-custom-format-clipboard-test-format-2'; + const blobInput1 = new Blob(['input data 1'], {type: format1}); + const blobInput2 = new Blob(['input data 2'], {type: format2}); + const clipboardItemInput = new ClipboardItem( + {[format1]: blobInput1, [format2]: blobInput2}); + await waitForUserActivation(); + await promise_rejects_dom(t, 'NotAllowedError', + navigator.clipboard.write([clipboardItemInput])); +}, 'navigator.clipboard.write() fails for custom formats without web prefix'); + +promise_test(async t => { + await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); + await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); + + const format1 = 'web '; + const format2 = 'web a'; + const blobInput1 = new Blob(['input data 1'], {type: format1}); + const blobInput2 = new Blob(['input data 2'], {type: format2}); + const clipboardItemInput = new ClipboardItem( + {[format1]: blobInput1, [format2]: blobInput2}); + await waitForUserActivation(); + await promise_rejects_dom(t, 'NotAllowedError', + navigator.clipboard.write([clipboardItemInput])); +}, 'navigator.clipboard.write() fails for custom formats with web prefix, but invalid MIME types'); + diff --git a/blink/web_tests/external/wpt/clipboard-apis/async-html-script-removal.https.html b/blink/web_tests/external/wpt/clipboard-apis/async-html-script-removal.https.html index 90dc44c9db20..44c11add8551 100644 --- a/blink/web_tests/external/wpt/clipboard-apis/async-html-script-removal.https.html +++ b/blink/web_tests/external/wpt/clipboard-apis/async-html-script-removal.https.html @@ -4,10 +4,12 @@ Async Clipboard write ([text/html ClipboardItem]) -> readHtml (and remove scripts) tests +Body needed for test_driver.click() + + +Body needed for test_driver.click()

@@ -27,6 +29,7 @@ await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); await test_driver.click(button); + await waitForUserActivation(); const items = await navigator.clipboard.read(); const htmlBlob = await items[0].getType("text/html"); const html = await htmlBlob.text(); @@ -38,3 +41,4 @@ assert_false(loadObserved, 'Should not observe resource loading'); }); + diff --git a/blink/web_tests/external/wpt/clipboard-apis/async-navigator-clipboard-read-sanitize.https.html b/blink/web_tests/external/wpt/clipboard-apis/async-navigator-clipboard-read-sanitize.https.html index 9e0ab2ee740f..cc1836753478 100644 --- a/blink/web_tests/external/wpt/clipboard-apis/async-navigator-clipboard-read-sanitize.https.html +++ b/blink/web_tests/external/wpt/clipboard-apis/async-navigator-clipboard-read-sanitize.https.html @@ -7,7 +7,9 @@ + +Body needed for test_driver.click()

@@ -29,6 +31,7 @@ await test_driver.set_permission({name: 'clipboard-read'}, 'granted'); await test_driver.click(button); + await waitForUserActivation(); const items = await navigator.clipboard.read(); const htmlBlob = await items[0].getType("text/html"); const html = await htmlBlob.text(); @@ -42,3 +45,4 @@ assert_false(testFailed); }); + diff --git a/blink/web_tests/external/wpt/clipboard-apis/async-promise-write-blobs-read-blobs.https.html b/blink/web_tests/external/wpt/clipboard-apis/async-promise-write-blobs-read-blobs.https.html index e4b93c7c5ffb..12184c92e077 100644 --- a/blink/web_tests/external/wpt/clipboard-apis/async-promise-write-blobs-read-blobs.https.html +++ b/blink/web_tests/external/wpt/clipboard-apis/async-promise-write-blobs-read-blobs.https.html @@ -4,10 +4,12 @@ Async Clipboard write blobs -> read blobs with promise tests +Body needed for test_driver.click() + + diff --git a/blink/web_tests/external/wpt/clipboard-apis/async-unsanitized-plaintext-formats-write-read.tentative.https.html b/blink/web_tests/external/wpt/clipboard-apis/async-unsanitized-plaintext-formats-write-read.tentative.https.html index f44ed22618e2..1c5638ca0a5f 100644 --- a/blink/web_tests/external/wpt/clipboard-apis/async-unsanitized-plaintext-formats-write-read.tentative.https.html +++ b/blink/web_tests/external/wpt/clipboard-apis/async-unsanitized-plaintext-formats-write-read.tentative.https.html @@ -18,32 +18,35 @@ await test_driver.set_permission({name: 'clipboard-write'}, 'granted'); const dataToWrite = 'Test text.'; - const format = 'text/plain'; + const format1 = 'web text/plain'; + const format2 = 'text/plain'; - const blobInput = new Blob([dataToWrite], {type: format}); + const blobInput1 = new Blob([dataToWrite], {type: format1}); + const blobInput2 = new Blob([dataToWrite], {type: format2}); // Blob types are automatically converted to lower-case. - assert_equals(blobInput.type, format.toLowerCase()); + assert_equals(blobInput1.type, format1.toLowerCase()); + assert_equals(blobInput2.type, format2.toLowerCase()); const clipboardItemInput = new ClipboardItem( - {[format]: blobInput}, {unsanitized: [format]}); + {[format1]: blobInput1, [format2]: blobInput2}); await waitForUserActivation(); await navigator.clipboard.write([clipboardItemInput]); // Items should be readable on a system clipboard after custom format write. await waitForUserActivation(); - const clipboardItems = await navigator.clipboard.read( - {unsanitized: [format]}); + const clipboardItems = await navigator.clipboard.read(); assert_equals(clipboardItems.length, 1); const clipboardItem = clipboardItems[0]; assert_true(clipboardItem instanceof ClipboardItem); - const blobOutput = await clipboardItem.getType(format); - assert_equals(blobOutput.type, format); - const data = await (new Response(blobOutput)).text(); - assert_equals(data, dataToWrite); + const blobOutput1 = await clipboardItem.getType(format1); + assert_equals(blobOutput1.type, format1); + const data1 = await (new Response(blobOutput1)).text(); + assert_equals(data1, dataToWrite); // These examples use native text formats, so these formats should be // accessible as text. + await waitForUserActivation(); const textOutput = await navigator.clipboard.readText(); assert_equals(textOutput, dataToWrite); -}, 'Verify write and read unsanitized content to the clipboard given standard format as input'); +}, 'Verify write and read unsanitized content to the clipboard given standard and custom formats as input'); diff --git a/blink/web_tests/external/wpt/clipboard-apis/async-write-blobs-read-blobs.https.html b/blink/web_tests/external/wpt/clipboard-apis/async-write-blobs-read-blobs.https.html index 50d23a9c3625..8bec558b2b2d 100644 --- a/blink/web_tests/external/wpt/clipboard-apis/async-write-blobs-read-blobs.https.html +++ b/blink/web_tests/external/wpt/clipboard-apis/async-write-blobs-read-blobs.https.html @@ -4,10 +4,12 @@ Async Clipboard write blobs -> read blobs tests +Body needed for test_driver.click() + + + +Body needed for test_driver.click()

The bottom image should display the same image as the top image.

Original Image:

@@ -47,7 +49,9 @@ assert_equals(blobInput.type, 'image/png'); const clipboardItemInput = new ClipboardItem({'image/png' : blobInput}); + await waitForUserActivation(); await navigator.clipboard.write([clipboardItemInput]); + await waitForUserActivation(); const clipboardItems = await navigator.clipboard.read(); assert_equals(clipboardItems.length, 1); @@ -73,7 +77,9 @@ const invalidPngBlob = new Blob(['this text is not a valid png image'], {type: 'image/png'}); const clipboardItemInput = new ClipboardItem({'image/png' : invalidPngBlob}); + await waitForUserActivation(); await promise_rejects_dom(t, 'DataError', navigator.clipboard.write([clipboardItemInput])); }, 'Verify write error on malformed data [image/png ClipboardItem]'); + diff --git a/blink/web_tests/external/wpt/clipboard-apis/async-write-svg-read-svg.https.html b/blink/web_tests/external/wpt/clipboard-apis/async-write-svg-read-svg.https.html index 19c91597c111..42f6c547b297 100644 --- a/blink/web_tests/external/wpt/clipboard-apis/async-write-svg-read-svg.https.html +++ b/blink/web_tests/external/wpt/clipboard-apis/async-write-svg-read-svg.https.html @@ -4,10 +4,12 @@ Async Clipboard write ([image/svg+xml ClipboardItem]) -> read and write svg tests +Body needed for test_driver.click() + + + + - diff --git a/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-attribute-tentative.https.sub.html b/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-attribute-tentative.https.sub.html index 15d268426163..e812854b4c75 100644 --- a/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-attribute-tentative.https.sub.html +++ b/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-attribute-tentative.https.sub.html @@ -1,17 +1,19 @@ - +Body needed for test_driver.click() + - diff --git a/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-cross-origin-tentative.https.sub.html b/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-cross-origin-tentative.https.sub.html index 1b6f4929a19d..c371ea3b41cb 100644 --- a/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-cross-origin-tentative.https.sub.html +++ b/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy-cross-origin-tentative.https.sub.html @@ -1,10 +1,11 @@ - +Body needed for test_driver.click() + - diff --git a/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy.tentative.https.sub.html b/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy.tentative.https.sub.html index f8c5bcb129f9..552183cc67d4 100644 --- a/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy.tentative.https.sub.html +++ b/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-by-feature-policy.tentative.https.sub.html @@ -1,10 +1,11 @@ - +Body needed for test_driver.click() + - diff --git a/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-on-self-origin-by-feature-policy.tentative.https.sub.html b/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-on-self-origin-by-feature-policy.tentative.https.sub.html index 47aa6511ec59..17dc3628a772 100644 --- a/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-on-self-origin-by-feature-policy.tentative.https.sub.html +++ b/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-read/clipboard-read-enabled-on-self-origin-by-feature-policy.tentative.https.sub.html @@ -1,10 +1,11 @@ - +Body needed for test_driver.click() + - diff --git a/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-attribute-cross-origin-tentative.https.sub.html b/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-attribute-cross-origin-tentative.https.sub.html index c931bbbb89f3..e669c8fec491 100644 --- a/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-attribute-cross-origin-tentative.https.sub.html +++ b/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-attribute-cross-origin-tentative.https.sub.html @@ -1,10 +1,11 @@ - +Body needed for test_driver.click() + - diff --git a/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-attribute-tentative.https.sub.html b/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-attribute-tentative.https.sub.html index a2858c638e6c..b57dfe3dd288 100644 --- a/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-attribute-tentative.https.sub.html +++ b/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-attribute-tentative.https.sub.html @@ -1,17 +1,19 @@ - +Body needed for test_driver.click() + - diff --git a/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-cross-origin-tentative.https.sub.html b/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-cross-origin-tentative.https.sub.html index 0f3164d9b02a..6e7029cc789a 100644 --- a/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-cross-origin-tentative.https.sub.html +++ b/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy-cross-origin-tentative.https.sub.html @@ -1,10 +1,11 @@ - +Body needed for test_driver.click() + - diff --git a/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy.tentative.https.sub.html b/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy.tentative.https.sub.html index 1c6fc49a0566..ca97994c617d 100644 --- a/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy.tentative.https.sub.html +++ b/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-by-feature-policy.tentative.https.sub.html @@ -1,10 +1,11 @@ - +Body needed for test_driver.click() + - diff --git a/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-on-self-origin-by-feature-policy.tentative.https.sub.html b/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-on-self-origin-by-feature-policy.tentative.https.sub.html index 51db5a427d2b..5615a68ac55a 100644 --- a/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-on-self-origin-by-feature-policy.tentative.https.sub.html +++ b/blink/web_tests/external/wpt/clipboard-apis/feature-policy/clipboard-write/clipboard-write-enabled-on-self-origin-by-feature-policy.tentative.https.sub.html @@ -1,10 +1,11 @@ - +Body needed for test_driver.click() + - diff --git a/blink/web_tests/external/wpt/clipboard-apis/permissions/readText-denied.https.html b/blink/web_tests/external/wpt/clipboard-apis/permissions/readText-denied.https.html index 935f520e7de2..010f4ba21b95 100644 --- a/blink/web_tests/external/wpt/clipboard-apis/permissions/readText-denied.https.html +++ b/blink/web_tests/external/wpt/clipboard-apis/permissions/readText-denied.https.html @@ -2,15 +2,18 @@ navigator.clipboard.readText() fails when permission denied +Body needed for test_driver.click() + + \ No newline at end of file diff --git a/blink/web_tests/external/wpt/clipboard-apis/permissions/writeText-denied.https.html b/blink/web_tests/external/wpt/clipboard-apis/permissions/writeText-denied.https.html index 4d0530f0bc22..5fbcab411748 100644 --- a/blink/web_tests/external/wpt/clipboard-apis/permissions/writeText-denied.https.html +++ b/blink/web_tests/external/wpt/clipboard-apis/permissions/writeText-denied.https.html @@ -2,15 +2,18 @@ navigator.clipboard.writeText() fails when permission denied +Body needed for test_driver.click() + + \ No newline at end of file diff --git a/blink/web_tests/external/wpt/clipboard-apis/text-write-read/async-write-read.https.html b/blink/web_tests/external/wpt/clipboard-apis/text-write-read/async-write-read.https.html index a00c5b27a4d6..c46e5d431713 100644 --- a/blink/web_tests/external/wpt/clipboard-apis/text-write-read/async-write-read.https.html +++ b/blink/web_tests/external/wpt/clipboard-apis/text-write-read/async-write-read.https.html @@ -5,10 +5,12 @@ read ([text/plain ClipboardItem]) tests +Body needed for test_driver.click() + + + +