<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[211852] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/211852">211852</a></dd>
<dt>Author</dt> <dd>wenson_hsieh@apple.com</dd>
<dt>Date</dt> <dd>2017-02-07 17:47:31 -0800 (Tue, 07 Feb 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>WebItemProviderPasteboard should use -registerLoadHandlersToItemProvider: when creating a new UIItemProvider
https://bugs.webkit.org/show_bug.cgi?id=167918
&lt;rdar://problem/30382347&gt;

Reviewed by Tim Horton.

Adopts SPI in WebItemProviderPasteboard for object types that the platform knows how to serialize. Since we use
-createObjectOfClass: to initialize data when reading off of the pasteboard, we need to match the format that
objects conforming to UIItemProviderReading will expect. Thus, for all given objects that conform to
UIItemProviderWriting, we have them register themselves to the item provider.

We register other UTI types due to the fact that PlatformPasteboardIOS does not care about the specific
pasteboard used. This should not be necessary, however, since data written to the WebItemProviderPasteboard
should never need to be read by an actual UIPasteboard. This will be refactored in a future patch to add a
special type of WebItemProviderPasteboard-aware PlatformPasteboard.

Also fixes some reference counting issues in WebItemProviderPasteboard by changing the array of _itemProviders
to be a RetainPtr.

* platform/ios/WebItemProviderPasteboard.mm:
(-[WebItemProviderPasteboard init]):
(-[WebItemProviderPasteboard pasteboardTypes]):
(-[WebItemProviderPasteboard itemProviders]):
(-[WebItemProviderPasteboard setItemProviders:]):
(-[WebItemProviderPasteboard numberOfItems]):
(-[WebItemProviderPasteboard setItems:]):
(-[WebItemProviderPasteboard valuesForPasteboardType:inItemSet:]):
(-[WebItemProviderPasteboard itemProviderAtIndex:]):
(-[WebItemProviderPasteboard dealloc]): Deleted.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformiosWebItemProviderPasteboardmm">trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (211851 => 211852)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2017-02-08 01:25:42 UTC (rev 211851)
+++ trunk/Source/WebCore/ChangeLog        2017-02-08 01:47:31 UTC (rev 211852)
</span><span class="lines">@@ -1,3 +1,35 @@
</span><ins>+2017-02-07  Wenson Hsieh  &lt;wenson_hsieh@apple.com&gt;
+
+        WebItemProviderPasteboard should use -registerLoadHandlersToItemProvider: when creating a new UIItemProvider
+        https://bugs.webkit.org/show_bug.cgi?id=167918
+        &lt;rdar://problem/30382347&gt;
+
+        Reviewed by Tim Horton.
+
+        Adopts SPI in WebItemProviderPasteboard for object types that the platform knows how to serialize. Since we use
+        -createObjectOfClass: to initialize data when reading off of the pasteboard, we need to match the format that
+        objects conforming to UIItemProviderReading will expect. Thus, for all given objects that conform to
+        UIItemProviderWriting, we have them register themselves to the item provider.
+
+        We register other UTI types due to the fact that PlatformPasteboardIOS does not care about the specific
+        pasteboard used. This should not be necessary, however, since data written to the WebItemProviderPasteboard
+        should never need to be read by an actual UIPasteboard. This will be refactored in a future patch to add a
+        special type of WebItemProviderPasteboard-aware PlatformPasteboard.
+
+        Also fixes some reference counting issues in WebItemProviderPasteboard by changing the array of _itemProviders
+        to be a RetainPtr.
+
+        * platform/ios/WebItemProviderPasteboard.mm:
+        (-[WebItemProviderPasteboard init]):
+        (-[WebItemProviderPasteboard pasteboardTypes]):
+        (-[WebItemProviderPasteboard itemProviders]):
+        (-[WebItemProviderPasteboard setItemProviders:]):
+        (-[WebItemProviderPasteboard numberOfItems]):
+        (-[WebItemProviderPasteboard setItems:]):
+        (-[WebItemProviderPasteboard valuesForPasteboardType:inItemSet:]):
+        (-[WebItemProviderPasteboard itemProviderAtIndex:]):
+        (-[WebItemProviderPasteboard dealloc]): Deleted.
+
</ins><span class="cx"> 2017-02-06  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         WebContent process repeatedly jetsams on BuzzFeed's Another Round page
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformiosWebItemProviderPasteboardmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.mm (211851 => 211852)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.mm        2017-02-08 01:25:42 UTC (rev 211851)
+++ trunk/Source/WebCore/platform/ios/WebItemProviderPasteboard.mm        2017-02-08 01:47:31 UTC (rev 211852)
</span><span class="lines">@@ -34,6 +34,8 @@
</span><span class="cx"> #import &lt;MobileCoreServices/MobileCoreServices.h&gt;
</span><span class="cx"> #import &lt;UIKit/UIColor.h&gt;
</span><span class="cx"> #import &lt;UIKit/UIImage.h&gt;
</span><ins>+#import &lt;UIKit/UIItemProviderWriting.h&gt;
+#import &lt;wtf/RetainPtr.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> SOFT_LINK_FRAMEWORK(UIKit)
</span><span class="cx"> SOFT_LINK_CLASS(UIKit, UIColor)
</span><span class="lines">@@ -76,7 +78,9 @@
</span><span class="cx"> 
</span><span class="cx"> @end
</span><span class="cx"> 
</span><del>-@implementation WebItemProviderPasteboard
</del><ins>+@implementation WebItemProviderPasteboard {
+    RetainPtr&lt;NSArray&gt; _itemProviders;
+}
</ins><span class="cx"> 
</span><span class="cx"> + (instancetype)sharedInstance
</span><span class="cx"> {
</span><span class="lines">@@ -91,7 +95,7 @@
</span><span class="cx"> - (instancetype)init
</span><span class="cx"> {
</span><span class="cx">     if (self = [super init]) {
</span><del>-        _itemProviders = [[NSArray alloc] init];
</del><ins>+        _itemProviders = adoptNS([[NSArray alloc] init]);
</ins><span class="cx">         _changeCount = 0;
</span><span class="cx">         _pendingOperationCount = 0;
</span><span class="cx">     }
</span><span class="lines">@@ -98,49 +102,65 @@
</span><span class="cx">     return self;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-- (void)dealloc
-{
-    [super dealloc];
-    [_itemProviders release];
-}
-
</del><span class="cx"> - (NSArray&lt;NSString *&gt; *)pasteboardTypes
</span><span class="cx"> {
</span><span class="cx">     NSMutableSet&lt;NSString *&gt; *allTypes = [NSMutableSet set];
</span><del>-    for (UIItemProvider *provider in _itemProviders)
</del><ins>+    for (UIItemProvider *provider in _itemProviders.get())
</ins><span class="cx">         [allTypes addObjectsFromArray:provider.registeredTypeIdentifiers];
</span><span class="cx">     return allTypes.allObjects;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (NSArray&lt;UIItemProvider *&gt; *)itemProviders
+{
+    return _itemProviders.get();
+}
+
</ins><span class="cx"> - (void)setItemProviders:(NSArray&lt;UIItemProvider *&gt; *)itemProviders
</span><span class="cx"> {
</span><span class="cx">     itemProviders = itemProviders ?: [NSArray array];
</span><span class="cx">     if (_itemProviders == itemProviders || [_itemProviders isEqualToArray:itemProviders])
</span><span class="cx">         return;
</span><del>-    _itemProviders = [itemProviders copy];
</del><ins>+
+    _itemProviders = itemProviders;
</ins><span class="cx">     _changeCount++;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (NSInteger)numberOfItems
</span><span class="cx"> {
</span><del>-    return _itemProviders.count;
</del><ins>+    return [_itemProviders count];
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (void)setItems:(NSArray *)items
</span><span class="cx"> {
</span><del>-    NSMutableArray *providers = [[NSMutableArray alloc] init];
</del><ins>+    NSMutableArray *providers = [NSMutableArray array];
</ins><span class="cx">     for (NSDictionary *item in items) {
</span><span class="cx">         if (!item.count)
</span><span class="cx">             continue;
</span><del>-        UIItemProvider *itemProvider = [[getUIItemProviderClass() alloc] init];
-        for (NSString *typeIdentifier in item) {
</del><ins>+        RetainPtr&lt;UIItemProvider&gt; itemProvider = adoptNS([[getUIItemProviderClass() alloc] init]);
+        RetainPtr&lt;NSMutableDictionary&gt; itemRepresentationsCopy = adoptNS([item mutableCopy]);
+        // First, let the platform write all the default object types it can recognize, such as NSString and NSURL.
+        for (NSString *typeIdentifier in [itemRepresentationsCopy allKeys]) {
+            id representingObject = [itemRepresentationsCopy objectForKey:typeIdentifier];
+            if (![representingObject conformsToProtocol:@protocol(UIItemProviderWriting)])
+                continue;
+
+            id &lt;UIItemProviderWriting&gt; objectToWrite = (id &lt;UIItemProviderWriting&gt;)representingObject;
+            if (![objectToWrite.writableTypeIdentifiersForItemProvider containsObject:typeIdentifier])
+                continue;
+
+            [itemRepresentationsCopy removeObjectForKey:typeIdentifier];
+            [objectToWrite registerLoadHandlersToItemProvider:itemProvider.get()];
+        }
+
+        // Secondly, WebKit uses some custom type representations and/or type identifiers, so we need to write these as well.
+        for (NSString *typeIdentifier in itemRepresentationsCopy.get()) {
</ins><span class="cx">             [itemProvider registerDataRepresentationForTypeIdentifier:typeIdentifier options:nil loadHandler:^NSProgress *(UIItemProviderDataLoadCompletionBlock completionBlock)
</span><span class="cx">             {
</span><del>-                completionBlock(item[typeIdentifier], nil);
</del><ins>+                completionBlock([itemRepresentationsCopy objectForKey:typeIdentifier], nil);
</ins><span class="cx">                 return [NSProgress discreteProgressWithTotalUnitCount:100];
</span><span class="cx">             }];
</span><span class="cx">         }
</span><del>-        [providers addObject:itemProvider];
</del><ins>+        [providers addObject:itemProvider.get()];
</ins><span class="cx">     }
</span><span class="cx">     _changeCount++;
</span><span class="cx">     _itemProviders = providers;
</span><span class="lines">@@ -174,7 +194,7 @@
</span><span class="cx">         if (isColorType(pasteboardType) &amp;&amp; [self _tryToCreateAndAppendObjectOfClass:[getUIColorClass() class] toArray:values usingProvider:provider])
</span><span class="cx">             return;
</span><span class="cx"> 
</span><del>-        if (isImageType(pasteboardType) &amp;&amp; [self _tryToCreateAndAppendObjectOfClass:[NSString class] toArray:values usingProvider:provider])
</del><ins>+        if (isImageType(pasteboardType) &amp;&amp; [self _tryToCreateAndAppendObjectOfClass:[getUIImageClass() class] toArray:values usingProvider:provider])
</ins><span class="cx">             return;
</span><span class="cx"> 
</span><span class="cx">         if (isURLType(pasteboardType) &amp;&amp; [self _tryToCreateAndAppendObjectOfClass:[NSURL class] toArray:values usingProvider:provider])
</span><span class="lines">@@ -210,7 +230,7 @@
</span><span class="cx"> 
</span><span class="cx"> - (UIItemProvider *)itemProviderAtIndex:(NSInteger)index
</span><span class="cx"> {
</span><del>-    return 0 &lt;= index &amp;&amp; index &lt; (NSInteger)_itemProviders.count ? _itemProviders[index] : nil;
</del><ins>+    return 0 &lt;= index &amp;&amp; index &lt; (NSInteger)[_itemProviders count] ? [_itemProviders objectAtIndex:index] : nil;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (BOOL)hasPendingOperation
</span></span></pre>
</div>
</div>

</body>
</html>