WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
203707
[Clipboard API] Add some infrastructure to resolve ClipboardItems into pasteboard data for writing
https://bugs.webkit.org/show_bug.cgi?id=203707
Summary
[Clipboard API] Add some infrastructure to resolve ClipboardItems into pasteb...
Wenson Hsieh
Reported
2019-10-31 17:24:02 PDT
Work towards supporting ClipboardItem.write().
Attachments
Patch
(33.96 KB, patch)
2019-10-31 21:46 PDT
,
Wenson Hsieh
no flags
Details
Formatted Diff
Diff
Fix GTK/WPE builds
(34.69 KB, patch)
2019-10-31 21:55 PDT
,
Wenson Hsieh
no flags
Details
Formatted Diff
Diff
Unified source build fix
(35.32 KB, patch)
2019-11-01 07:20 PDT
,
Wenson Hsieh
no flags
Details
Formatted Diff
Diff
Another build fix in MediaStreamTrack.cpp
(35.34 KB, patch)
2019-11-01 07:26 PDT
,
Wenson Hsieh
no flags
Details
Formatted Diff
Diff
Another build fix in MediaStreamTrack.cpp
(35.55 KB, patch)
2019-11-01 07:36 PDT
,
Wenson Hsieh
no flags
Details
Formatted Diff
Diff
v2
(18.23 KB, patch)
2019-11-07 18:56 PST
,
Wenson Hsieh
no flags
Details
Formatted Diff
Diff
FIX WPE/GTK builds
(18.37 KB, patch)
2019-11-07 19:05 PST
,
Wenson Hsieh
no flags
Details
Formatted Diff
Diff
v3
(18.55 KB, patch)
2019-11-08 10:05 PST
,
Wenson Hsieh
rniwa
: review+
Details
Formatted Diff
Diff
Patch for landing
(19.19 KB, patch)
2019-11-10 14:42 PST
,
Wenson Hsieh
commit-queue
: commit-queue-
Details
Formatted Diff
Diff
Patch for landing
(19.20 KB, patch)
2019-11-10 15:33 PST
,
Wenson Hsieh
no flags
Details
Formatted Diff
Diff
Show Obsolete
(8)
View All
Add attachment
proposed patch, testcase, etc.
Wenson Hsieh
Comment 1
2019-10-31 21:46:00 PDT
Comment hidden (obsolete)
Created
attachment 382551
[details]
Patch
Wenson Hsieh
Comment 2
2019-10-31 21:55:36 PDT
Comment hidden (obsolete)
Created
attachment 382552
[details]
Fix GTK/WPE builds
Wenson Hsieh
Comment 3
2019-11-01 07:20:57 PDT
Comment hidden (obsolete)
Created
attachment 382576
[details]
Unified source build fix
Wenson Hsieh
Comment 4
2019-11-01 07:26:53 PDT
Comment hidden (obsolete)
Created
attachment 382577
[details]
Another build fix in MediaStreamTrack.cpp
Wenson Hsieh
Comment 5
2019-11-01 07:36:33 PDT
Comment hidden (obsolete)
Created
attachment 382578
[details]
Another build fix in MediaStreamTrack.cpp
Ryosuke Niwa
Comment 6
2019-11-05 15:28:42 PST
Comment on
attachment 382578
[details]
Another build fix in MediaStreamTrack.cpp View in context:
https://bugs.webkit.org/attachment.cgi?id=382578&action=review
> Source/WebCore/ChangeLog:42 > + ClipboardItemDataCollector and ClipboardItem carry out these steps in parallel, so that for each pair of
"in parallel" is misleading because we don't have multiple threads here. Maybe asynchronously?
> Source/WebCore/Modules/async-clipboard/ClipboardItemBindingsDataSource.cpp:98 > +void ClipboardItemBindingsDataSource::collectDataForWriting(ClipboardItemDataCollector& collector)
Having dependency to ClipboardItemDataCollector is weird here. I think this function should take a lambda which takes the result instead.
> Source/WebCore/Modules/async-clipboard/ClipboardItemBindingsDataSource.cpp:105 > + collector->cancelDataCollection();
It's somewhat unclear why we'd have to clear other data collection. I think it's better to have more descriptive helper function like didReceiveBadItem() or didFailToResolveItem().
> Source/WebCore/Modules/async-clipboard/ClipboardItemDataCollector.cpp:68 > + ++m_pendingLoadResultCount;
This manual incrementing & decrementing seems super fragile. If we made the change to make collectDataForWriting take a lambda, we can increment & decrement the count in that single lambda.
> Source/WebCore/Modules/async-clipboard/ClipboardItemDataCollector.h:69 > + return PtrHash<ClipboardItem*>::hash(key.item.get()) + key.type.hash();
Please use DefaultHash<>::hash(std::pair<>(key.item, key.type)).
> Source/WebCore/Modules/async-clipboard/ClipboardItemDataCollector.h:90 > + class ClipboardItemBlobLoader : public RefCounted<ClipboardItemBlobLoader>, public FileReaderLoaderClient {
This class should be defined in the cpp file. You only need a decoration here.
> Source/WebCore/Modules/async-clipboard/ClipboardItemDataCollector.h:102 > + ClipboardItemBlobLoader(ClipboardItemDataCollector& collector, const LoadResultKey& loadResultKey, FileReaderLoader::ReadType readType)
Again, this loader should probably just take a lambda instead of having interdependency.
> Source/WebCore/Modules/async-clipboard/ClipboardItemDataCollector.h:124 > + RefPtr<ClipboardItemBlobLoader> loader;
It's very strange that m_loadResults contains loader.
> Source/WebCore/Modules/async-clipboard/ClipboardItemDataCollector.h:136 > + HashMap<LoadResultKey, LoadResult, LoadResultKeyHash, LoadResultKeyHashTrait> m_loadResults;
This map seems completely unnecessary. We can just keep accumulating results in a list then we can iterate them all to assign all the results in takePasteboardItemsFromResults.
Wenson Hsieh
Comment 7
2019-11-07 18:38:38 PST
Comment on
attachment 382578
[details]
Another build fix in MediaStreamTrack.cpp View in context:
https://bugs.webkit.org/attachment.cgi?id=382578&action=review
>> Source/WebCore/ChangeLog:42 >> + ClipboardItemDataCollector and ClipboardItem carry out these steps in parallel, so that for each pair of > > "in parallel" is misleading because we don't have multiple threads here. Maybe asynchronously?
Good point — changed the wording accordingly.
>> Source/WebCore/Modules/async-clipboard/ClipboardItemBindingsDataSource.cpp:98 >> +void ClipboardItemBindingsDataSource::collectDataForWriting(ClipboardItemDataCollector& collector) > > Having dependency to ClipboardItemDataCollector is weird here. > I think this function should take a lambda which takes the result instead.
Refactored so that collectDataForWriting() takes completion handlers.
>> Source/WebCore/Modules/async-clipboard/ClipboardItemBindingsDataSource.cpp:105 >> + collector->cancelDataCollection(); > > It's somewhat unclear why we'd have to clear other data collection. > I think it's better to have more descriptive helper function like didReceiveBadItem() or didFailToResolveItem().
Good point — I find didFailToResolveItem() to be a better name as well.
>> Source/WebCore/Modules/async-clipboard/ClipboardItemDataCollector.cpp:68 >> + ++m_pendingLoadResultCount; > > This manual incrementing & decrementing seems super fragile. > If we made the change to make collectDataForWriting take a lambda, > we can increment & decrement the count in that single lambda.
Done.
>> Source/WebCore/Modules/async-clipboard/ClipboardItemDataCollector.h:69 >> + return PtrHash<ClipboardItem*>::hash(key.item.get()) + key.type.hash(); > > Please use DefaultHash<>::hash(std::pair<>(key.item, key.type)).
Removed this custom hashable key altogether.
>> Source/WebCore/Modules/async-clipboard/ClipboardItemDataCollector.h:90 >> + class ClipboardItemBlobLoader : public RefCounted<ClipboardItemBlobLoader>, public FileReaderLoaderClient { > > This class should be defined in the cpp file. > You only need a decoration here.
Removed ClipboardItemBlobLoader.
>> Source/WebCore/Modules/async-clipboard/ClipboardItemDataCollector.h:102 >> + ClipboardItemBlobLoader(ClipboardItemDataCollector& collector, const LoadResultKey& loadResultKey, FileReaderLoader::ReadType readType) > > Again, this loader should probably just take a lambda instead of having interdependency.
Removed ClipboardItemBlobLoader.
>> Source/WebCore/Modules/async-clipboard/ClipboardItemDataCollector.h:124 >> + RefPtr<ClipboardItemBlobLoader> loader; > > It's very strange that m_loadResults contains loader.
Refactored this to avoid having a separate wrapper class around the loader.
>> Source/WebCore/Modules/async-clipboard/ClipboardItemDataCollector.h:136 >> + HashMap<LoadResultKey, LoadResult, LoadResultKeyHash, LoadResultKeyHashTrait> m_loadResults; > > This map seems completely unnecessary. We can just keep accumulating results in a list > then we can iterate them all to assign all the results in takePasteboardItemsFromResults.
Removed this map.
Wenson Hsieh
Comment 8
2019-11-07 18:56:25 PST
Comment hidden (obsolete)
Created
attachment 383102
[details]
v2
Wenson Hsieh
Comment 9
2019-11-07 19:05:11 PST
Comment hidden (obsolete)
Created
attachment 383105
[details]
FIX WPE/GTK builds
Ryosuke Niwa
Comment 10
2019-11-07 19:34:31 PST
Comment on
attachment 383105
[details]
FIX WPE/GTK builds View in context:
https://bugs.webkit.org/attachment.cgi?id=383105&action=review
> Source/WebCore/Modules/async-clipboard/ClipboardItemBindingsDataSource.cpp:224 > + // All clipboard types have been loaded; proceed to convert the loaded data into PasteboardCustomData.
Instead of having this comment, why don't we just rename canFinishCollectingDataForWriting to didFinishLoadingAllTypes?
> Source/WebCore/Modules/async-clipboard/ClipboardItemBindingsDataSource.cpp:243 > + // We've already extracted data from this loader.
Having a single callback which iterates over all FileReaderLoader whenever one type finishes loading seems awfully inefficient & cumbersome. We don't we create a struct like ClipboardItemType or something for each type, and then have each one of those objects be a FileReaderLoaderClient. The struct can then have a String & Ref<SharedBuffer> as members or a single variant member.
Wenson Hsieh
Comment 11
2019-11-07 19:45:00 PST
Comment on
attachment 383105
[details]
FIX WPE/GTK builds View in context:
https://bugs.webkit.org/attachment.cgi?id=383105&action=review
>> Source/WebCore/Modules/async-clipboard/ClipboardItemBindingsDataSource.cpp:224 >> + // All clipboard types have been loaded; proceed to convert the loaded data into PasteboardCustomData. > > Instead of having this comment, why don't we just rename canFinishCollectingDataForWriting to didFinishLoadingAllTypes?
The name didFinishLoadingAllTypes sounds too much like a delegate or client hook, so I think we should avoid that. How about `bool finishedLoadingAllTypes() const`.
>> Source/WebCore/Modules/async-clipboard/ClipboardItemBindingsDataSource.cpp:243 >> + // We've already extracted data from this loader. > > Having a single callback which iterates over all FileReaderLoader > whenever one type finishes loading seems awfully inefficient & cumbersome. > > We don't we create a struct like ClipboardItemType or something for each type, > and then have each one of those objects be a FileReaderLoaderClient. > > The struct can then have a String & Ref<SharedBuffer> as members or a single variant member.
This was what I did in my original patch, for this exact reason; I moved away from this to address your concerns about the resulting code being too complicated. I'll bring it back as `ClipboardItemType`.
Ryosuke Niwa
Comment 12
2019-11-07 19:52:19 PST
(In reply to Wenson Hsieh from
comment #11
)
> Comment on
attachment 383105
[details]
> FIX WPE/GTK builds > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=383105&action=review
> > >> Source/WebCore/Modules/async-clipboard/ClipboardItemBindingsDataSource.cpp:224 > >> + // All clipboard types have been loaded; proceed to convert the loaded data into PasteboardCustomData. > > > > Instead of having this comment, why don't we just rename canFinishCollectingDataForWriting to didFinishLoadingAllTypes? > > The name didFinishLoadingAllTypes sounds too much like a delegate or client > hook, so I think we should avoid that. How about `bool > finishedLoadingAllTypes() const`.
Sounds good.
> >> Source/WebCore/Modules/async-clipboard/ClipboardItemBindingsDataSource.cpp:243 > >> + // We've already extracted data from this loader. > > > > Having a single callback which iterates over all FileReaderLoader > > whenever one type finishes loading seems awfully inefficient & cumbersome. > > > > We don't we create a struct like ClipboardItemType or something for each type, > > and then have each one of those objects be a FileReaderLoaderClient. > > > > The struct can then have a String & Ref<SharedBuffer> as members or a single variant member. > > This was what I did in my original patch, for this exact reason; I moved > away from this to address your concerns about the resulting code being too > complicated.
Hm... maybe we're talking about each other. What I'm saying is that each type can have its own loader. But when it finishes loading, it doesn't need to look itself in a map, etc... Just hold onto that data, and notify ClipboardItem that it has completed loading all types. ClipboardItem can then notify Clipboard when it has gathered all types. All of this could be done via a completion handler instead of looking up a hash map & storing data in a central location, etc...
Wenson Hsieh
Comment 13
2019-11-08 10:05:36 PST
Created
attachment 383138
[details]
v3
Radar WebKit Bug Importer
Comment 14
2019-11-08 10:06:59 PST
<
rdar://problem/57025262
>
Ryosuke Niwa
Comment 15
2019-11-08 22:58:05 PST
Comment on
attachment 383138
[details]
v3 View in context:
https://bugs.webkit.org/attachment.cgi?id=383138&action=review
Very nice!
> Source/WebCore/Modules/async-clipboard/ClipboardItemBindingsDataSource.cpp:118 > + if (!--m_numberOfPendingClipboardTypes)
Hm... are we sure this completion handler can't be called after m_itemTypeLoaders.clear() had ran? Given this keeps item alive in lambda, there might be a race condition here. Perhaps we might want to either assert or check that item is still in m_itemTypeLoaders.
> Source/WebCore/Modules/async-clipboard/ClipboardItemBindingsDataSource.cpp:182 > + if (!clipboard) {
Can we add a static helper which gets RefPtr<document> so that we can consolidate these sanity checks into one?
> Source/WebCore/Modules/async-clipboard/ClipboardItemBindingsDataSource.h:56 > + static Ref<ClipboardItemType> create(const String& type, CompletionHandler<void()>&& completionHandler)
If this object takes a completion hander, I would call it ClipboardItemTypeLoader or something.
> Source/WebCore/Modules/async-clipboard/ClipboardItemBindingsDataSource.h:89 > + Vector<Ref<ClipboardItemType>> m_itemTypeLoaders;
Especially because this variable is called m_itemTypeLoaders.
Wenson Hsieh
Comment 16
2019-11-10 14:24:12 PST
Comment on
attachment 383138
[details]
v3 View in context:
https://bugs.webkit.org/attachment.cgi?id=383138&action=review
>> Source/WebCore/Modules/async-clipboard/ClipboardItemBindingsDataSource.cpp:118 >> + if (!--m_numberOfPendingClipboardTypes) > > Hm... are we sure this completion handler can't be called after m_itemTypeLoaders.clear() had ran? > Given this keeps item alive in lambda, there might be a race condition here. > Perhaps we might want to either assert or check that item is still in m_itemTypeLoaders.
I /think/ this is safe, because the only thing that hangs on to the item loader is ClipboardItemBindingsDataSource (the Ref to m_item is for the ClipboardItem, rather than the ClipboardItemTypeLoader). More assertions sounds like a good idea — I added these two: - Assert m_numberOfPendingClipboardTypes before decrementing it. - Assert that m_itemTypeLoaders contains the itemTypeLoader above when settling the promise. I’ll also be writing a layout test in the next patch to exercise this scenario (i.e. calling Clipboard.write(), and then calling it again before the previous write() has finished).
>> Source/WebCore/Modules/async-clipboard/ClipboardItemBindingsDataSource.cpp:182 >> + if (!clipboard) { > > Can we add a static helper which gets RefPtr<document> so that we can consolidate these sanity checks into one?
👍🏻 Added a new helper, and used it here.
>> Source/WebCore/Modules/async-clipboard/ClipboardItemBindingsDataSource.h:56 >> + static Ref<ClipboardItemType> create(const String& type, CompletionHandler<void()>&& completionHandler) > > If this object takes a completion hander, I would call it ClipboardItemTypeLoader or something.
Sounds good — renamed to ClipboardItemTypeLoader.
Wenson Hsieh
Comment 17
2019-11-10 14:42:05 PST
Comment hidden (obsolete)
Created
attachment 383249
[details]
Patch for landing
WebKit Commit Bot
Comment 18
2019-11-10 15:13:03 PST
Comment hidden (obsolete)
Comment on
attachment 383249
[details]
Patch for landing Rejecting
attachment 383249
[details]
from commit-queue. Failed to run "['/Volumes/Data/EWS/WebKit/Tools/Scripts/webkit-patch', '--status-host=webkit-queues.webkit.org', '--bot-id=webkit-cq-03', 'build', '--no-clean', '--no-update', '--build-style=release', '--port=mac']" exit_code: 2 cwd: /Volumes/Data/EWS/WebKit Last 5000 characters of output: -all-target-headers.hmap -iquote /Volumes/Data/EWS/WebKit/WebKitBuild/WebCore.build/Release/WebCore.build/WebCore-project-headers.hmap -I/Volumes/Data/EWS/WebKit/WebKitBuild/Release/include -IPAL -IForwardingHeaders -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/libxslt -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/libxml2 -I/Volumes/Data/EWS/WebKit/WebKitBuild/Release/DerivedSources/WebCore -I/Volumes/Data/EWS/WebKit/WebKitBuild/Release/usr/local/include -I/Volumes/Data/EWS/WebKit/WebKitBuild/Release/usr/local/include/WebKitAdditions -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/local/include/WebKitAdditions -I/Volumes/Data/EWS/WebKit/WebKitBuild/Release/usr/local/include/webrtc -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/local/include/webrtc -I/Volumes/Data/EWS/WebKit/WebKitBuild/Release/usr/local/include/webrtc/sdk/objc/Framework/Headers -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/local/include/webrtc/sdk/objc/Framework/Headers -I/Volumes/Data/EWS/WebKit/Source/WebCore -I/Volumes/Data/EWS/WebKit/WebKitBuild/WebCore.build/Release/WebCore.build/DerivedSources/x86_64 -I/Volumes/Data/EWS/WebKit/WebKitBuild/WebCore.build/Release/WebCore.build/DerivedSources -Wall -Wextra -Wcast-qual -Wchar-subscripts -Wextra-tokens -Wformat=2 -Winit-self -Wmissing-format-attribute -Wmissing-noreturn -Wpacked -Wpointer-arith -Wredundant-decls -Wundef -Wwrite-strings -Wexit-time-destructors -Wglobal-constructors -Wtautological-compare -Wimplicit-fallthrough -Wno-unknown-warning-option -F/Volumes/Data/EWS/WebKit/WebKitBuild/Release -iframework /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/System/Library/PrivateFrameworks -iframework /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/System/Library/Frameworks -isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/System/Library/Frameworks/System.framework/PrivateHeaders -include /Volumes/Data/EWS/WebKit/WebKitBuild/PrecompiledHeaders/WebCorePrefix-hesoptuqnbqggaewbsnjerkudzpe/WebCorePrefix.h -MMD -MT dependencies -MF /Volumes/Data/EWS/WebKit/WebKitBuild/WebCore.build/Release/WebCore.build/Objects-normal/x86_64/UnifiedSource29.d --serialize-diagnostics /Volumes/Data/EWS/WebKit/WebKitBuild/WebCore.build/Release/WebCore.build/Objects-normal/x86_64/UnifiedSource29.dia -c /Volumes/Data/EWS/WebKit/WebKitBuild/Release/DerivedSources/WebCore/unified-sources/UnifiedSource29.cpp -o /Volumes/Data/EWS/WebKit/WebKitBuild/WebCore.build/Release/WebCore.build/Objects-normal/x86_64/UnifiedSource29.o ** BUILD FAILED ** The following build commands failed: CompileC /Volumes/Data/EWS/WebKit/WebKitBuild/WebCore.build/Release/WebCore.build/Objects-normal/x86_64/UnifiedSource23.o /Volumes/Data/EWS/WebKit/WebKitBuild/Release/DerivedSources/WebCore/unified-sources/UnifiedSource23.cpp normal x86_64 c++ com.apple.compilers.llvm.clang.1_0.compiler (1 failure) Failed to run "['Tools/Scripts/build-webkit', '--release']" exit_code: 65 nt-decls -Wundef -Wwrite-strings -Wexit-time-destructors -Wglobal-constructors -Wtautological-compare -Wimplicit-fallthrough -Wno-unknown-warning-option -F/Volumes/Data/EWS/WebKit/WebKitBuild/Release -iframework /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/System/Library/PrivateFrameworks -iframework /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/System/Library/Frameworks -isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/System/Library/Frameworks/System.framework/PrivateHeaders -include /Volumes/Data/EWS/WebKit/WebKitBuild/PrecompiledHeaders/WebCorePrefix-hesoptuqnbqggaewbsnjerkudzpe/WebCorePrefix.h -MMD -MT dependencies -MF /Volumes/Data/EWS/WebKit/WebKitBuild/WebCore.build/Release/WebCore.build/Objects-normal/x86_64/UnifiedSource29.d --serialize-diagnostics /Volumes/Data/EWS/WebKit/WebKitBuild/WebCore.build/Release/WebCore.build/Objects-normal/x86_64/UnifiedSource29.dia -c /Volumes/Data/EWS/WebKit/WebKitBuild/Release/DerivedSources/WebCore/unified-sources/UnifiedSource29.cpp -o /Volumes/Data/EWS/WebKit/WebKitBuild/WebCore.build/Release/WebCore.build/Objects-normal/x86_64/UnifiedSource29.o ** BUILD FAILED ** The following build commands failed: CompileC /Volumes/Data/EWS/WebKit/WebKitBuild/WebCore.build/Release/WebCore.build/Objects-normal/x86_64/UnifiedSource23.o /Volumes/Data/EWS/WebKit/WebKitBuild/Release/DerivedSources/WebCore/unified-sources/UnifiedSource23.cpp normal x86_64 c++ com.apple.compilers.llvm.clang.1_0.compiler (1 failure) Full output:
https://webkit-queues.webkit.org/results/13236428
Wenson Hsieh
Comment 19
2019-11-10 15:33:28 PST
Created
attachment 383250
[details]
Patch for landing
WebKit Commit Bot
Comment 20
2019-11-10 16:16:54 PST
Comment on
attachment 383250
[details]
Patch for landing Clearing flags on attachment: 383250 Committed
r252315
: <
https://trac.webkit.org/changeset/252315
>
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug