Inform clients when editable image attachment backing data changes
authortimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 30 Nov 2018 06:31:04 +0000 (06:31 +0000)
committertimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 30 Nov 2018 06:31:04 +0000 (06:31 +0000)
https://bugs.webkit.org/show_bug.cgi?id=192206
<rdar://problem/46350277>

Reviewed by Wenson Hsieh.

Source/WebKit:

* UIProcess/API/Cocoa/APIAttachmentCocoa.mm:
(API::Attachment::invalidateGeneratedFileWrapper):
* UIProcess/API/Cocoa/WKUIDelegatePrivate.h:
* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _didInvalidateDataForAttachment:]):
* UIProcess/API/Cocoa/WKWebViewInternal.h:
* UIProcess/Cocoa/PageClientImplCocoa.h:
* UIProcess/Cocoa/PageClientImplCocoa.mm:
(WebKit::PageClientImplCocoa::didInvalidateDataForAttachment):
* UIProcess/PageClient.h:
(WebKit::PageClient::didInvalidateDataForAttachment):
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::didInvalidateDataForAttachment):
* UIProcess/WebPageProxy.h:
Plumb file-wrapper-invalidation through from APIAttachment to WKUIDelegate.

Tools:

* TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
* TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm:
(-[AttachmentUpdateObserver init]):
(-[AttachmentUpdateObserver dataInvalidated]):
(-[AttachmentUpdateObserver _webView:didInvalidateDataForAttachment:]):
(TestWebKitAPI::ObserveAttachmentUpdatesForScope::expectAttachmentInvalidation):
(webViewForTestingAttachments):
(TestWebKitAPI::forEachViewInHierarchy):
(TestWebKitAPI::findEditableImageCanvas):
(TestWebKitAPI::drawSquareInEditableImage):
(TestWebKitAPI::TEST):
* TestWebKitAPI/ios/PencilKitTestSPI.h: Added.
Add a test ensuring that we get an invalidation callback when an editable image is changed.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@238726 268f45cc-cd09-0410-ab3c-d52691b4dbfc

14 files changed:
Source/WebKit/ChangeLog
Source/WebKit/UIProcess/API/Cocoa/APIAttachmentCocoa.mm
Source/WebKit/UIProcess/API/Cocoa/WKUIDelegatePrivate.h
Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
Source/WebKit/UIProcess/API/Cocoa/WKWebViewInternal.h
Source/WebKit/UIProcess/Cocoa/PageClientImplCocoa.h
Source/WebKit/UIProcess/Cocoa/PageClientImplCocoa.mm
Source/WebKit/UIProcess/PageClient.h
Source/WebKit/UIProcess/WebPageProxy.cpp
Source/WebKit/UIProcess/WebPageProxy.h
Tools/ChangeLog
Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj
Tools/TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm
Tools/TestWebKitAPI/ios/PencilKitTestSPI.h [new file with mode: 0644]

index b191b25..ad765ed 100644 (file)
@@ -1,3 +1,27 @@
+2018-11-29  Tim Horton  <timothy_horton@apple.com>
+
+        Inform clients when editable image attachment backing data changes
+        https://bugs.webkit.org/show_bug.cgi?id=192206
+        <rdar://problem/46350277>
+
+        Reviewed by Wenson Hsieh.
+
+        * UIProcess/API/Cocoa/APIAttachmentCocoa.mm:
+        (API::Attachment::invalidateGeneratedFileWrapper):
+        * UIProcess/API/Cocoa/WKUIDelegatePrivate.h:
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _didInvalidateDataForAttachment:]):
+        * UIProcess/API/Cocoa/WKWebViewInternal.h:
+        * UIProcess/Cocoa/PageClientImplCocoa.h:
+        * UIProcess/Cocoa/PageClientImplCocoa.mm:
+        (WebKit::PageClientImplCocoa::didInvalidateDataForAttachment):
+        * UIProcess/PageClient.h:
+        (WebKit::PageClient::didInvalidateDataForAttachment):
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::didInvalidateDataForAttachment):
+        * UIProcess/WebPageProxy.h:
+        Plumb file-wrapper-invalidation through from APIAttachment to WKUIDelegate.
+
 2018-11-29  Eric Carlson  <eric.carlson@apple.com>
 
         [MediaStream] DeviceIdHashSaltStorage should use iframe and top level documents
index 6255af0..29ec69a 100644 (file)
@@ -64,6 +64,7 @@ void Attachment::invalidateGeneratedFileWrapper()
 {
     ASSERT(m_fileWrapperGenerator);
     m_fileWrapper = nil;
+    m_webPage->didInvalidateDataForAttachment(*this);
 }
 
 WTF::String Attachment::mimeType() const
@@ -193,6 +194,7 @@ void Attachment::setFileWrapperGenerator(Function<RetainPtr<NSFileWrapper>(void)
 {
     m_fileWrapperGenerator = WTFMove(fileWrapperGenerator);
     m_fileWrapper = nil;
+    m_webPage->didInvalidateDataForAttachment(*this);
 }
 
 } // namespace API
index 81861bc..997468c 100644 (file)
@@ -116,6 +116,7 @@ struct UIEdgeInsets;
 
 - (void)_webView:(WKWebView *)webView didRemoveAttachment:(_WKAttachment *)attachment WK_API_AVAILABLE(macosx(10.13.4), ios(11.3));
 - (void)_webView:(WKWebView *)webView didInsertAttachment:(_WKAttachment *)attachment withSource:(NSString *)source WK_API_AVAILABLE(macosx(10.14), ios(12.0));
+- (void)_webView:(WKWebView *)webView didInvalidateDataForAttachment:(_WKAttachment *)attachment WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 - (void)_webView:(WKWebView *)webView didResignInputElementStrongPasswordAppearanceWithUserInfo:(id <NSSecureCoding>)userInfo WK_API_AVAILABLE(macosx(10.14), ios(12.0));
 
index d9fca4d..8814342 100644 (file)
@@ -1314,6 +1314,13 @@ static NSDictionary *dictionaryRepresentationForEditorState(const WebKit::Editor
         [uiDelegate _webView:self didRemoveAttachment:wrapper(attachment)];
 }
 
+- (void)_didInvalidateDataForAttachment:(API::Attachment&)attachment
+{
+    id <WKUIDelegatePrivate> uiDelegate = (id <WKUIDelegatePrivate>)self.UIDelegate;
+    if ([uiDelegate respondsToSelector:@selector(_webView:didInvalidateDataForAttachment:)])
+        [uiDelegate _webView:self didInvalidateDataForAttachment:wrapper(attachment)];
+}
+
 #endif // ENABLE(ATTACHMENT_ELEMENT)
 
 #pragma mark iOS-specific methods
index 71e291f..b065b35 100644 (file)
@@ -181,6 +181,7 @@ class URL;
 #if ENABLE(ATTACHMENT_ELEMENT)
 - (void)_didRemoveAttachment:(API::Attachment&)attachment;
 - (void)_didInsertAttachment:(API::Attachment&)attachment withSource:(NSString *)source;
+- (void)_didInvalidateDataForAttachment:(API::Attachment&)attachment;
 #endif
 
 - (void)_showSafeBrowsingWarning:(const WebKit::SafeBrowsingWarning&)warning completionHandler:(CompletionHandler<void(Variant<WebKit::ContinueUnsafeLoad, WebCore::URL>&&)>&&)completionHandler;
index 83948d8..7b4a2da 100644 (file)
@@ -46,6 +46,7 @@ public:
 #if ENABLE(ATTACHMENT_ELEMENT)
     void didInsertAttachment(API::Attachment&, const String& source) final;
     void didRemoveAttachment(API::Attachment&) final;
+    void didInvalidateDataForAttachment(API::Attachment&) final;
     NSFileWrapper *allocFileWrapperInstance() const final;
     NSSet *serializableFileWrapperClasses() const final;
 #endif
index efe4e81..07f02c3 100644 (file)
@@ -66,6 +66,15 @@ void PageClientImplCocoa::didRemoveAttachment(API::Attachment& attachment)
 #endif
 }
 
+void PageClientImplCocoa::didInvalidateDataForAttachment(API::Attachment& attachment)
+{
+#if WK_API_ENABLED
+    [m_webView _didInvalidateDataForAttachment:attachment];
+#else
+    UNUSED_PARAM(attachment);
+#endif
+}
+
 NSFileWrapper *PageClientImplCocoa::allocFileWrapperInstance() const
 {
 #if WK_API_ENABLED
index 7defa40..ee852b2 100644 (file)
@@ -454,6 +454,7 @@ public:
 #if ENABLE(ATTACHMENT_ELEMENT)
     virtual void didInsertAttachment(API::Attachment&, const String& source) { }
     virtual void didRemoveAttachment(API::Attachment&) { }
+    virtual void didInvalidateDataForAttachment(API::Attachment&) { }
 #if PLATFORM(COCOA)
     virtual NSFileWrapper *allocFileWrapperInstance() const { return nullptr; }
     virtual NSSet *serializableFileWrapperClasses() const { return nullptr; }
index c791eab..5ffb2bf 100644 (file)
@@ -8115,6 +8115,11 @@ void WebPageProxy::serializedAttachmentDataForIdentifiers(const Vector<String>&
     }
 }
 
+void WebPageProxy::didInvalidateDataForAttachment(API::Attachment& attachment)
+{
+    pageClient().didInvalidateDataForAttachment(attachment);
+}
+
 WebPageProxy::ShouldUpdateAttachmentAttributes WebPageProxy::willUpdateAttachmentAttributes(const API::Attachment& attachment)
 {
 #if HAVE(PENCILKIT)
index 0ae1fbb..b72b006 100644 (file)
@@ -1370,6 +1370,7 @@ public:
     void updateAttachmentAttributes(const API::Attachment&, Function<void(CallbackBase::Error)>&&);
     void serializedAttachmentDataForIdentifiers(const Vector<String>&, Vector<WebCore::SerializedAttachmentData>&);
     void registerAttachmentIdentifier(const String&);
+    void didInvalidateDataForAttachment(API::Attachment&);
 
     enum class ShouldUpdateAttachmentAttributes : bool { No, Yes };
     ShouldUpdateAttachmentAttributes willUpdateAttachmentAttributes(const API::Attachment&);
index 2a468ac..73d6f2f 100644 (file)
@@ -1,3 +1,25 @@
+2018-11-29  Tim Horton  <timothy_horton@apple.com>
+
+        Inform clients when editable image attachment backing data changes
+        https://bugs.webkit.org/show_bug.cgi?id=192206
+        <rdar://problem/46350277>
+
+        Reviewed by Wenson Hsieh.
+
+        * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+        * TestWebKitAPI/Tests/WebKitCocoa/WKAttachmentTests.mm:
+        (-[AttachmentUpdateObserver init]):
+        (-[AttachmentUpdateObserver dataInvalidated]):
+        (-[AttachmentUpdateObserver _webView:didInvalidateDataForAttachment:]):
+        (TestWebKitAPI::ObserveAttachmentUpdatesForScope::expectAttachmentInvalidation):
+        (webViewForTestingAttachments):
+        (TestWebKitAPI::forEachViewInHierarchy):
+        (TestWebKitAPI::findEditableImageCanvas):
+        (TestWebKitAPI::drawSquareInEditableImage):
+        (TestWebKitAPI::TEST):
+        * TestWebKitAPI/ios/PencilKitTestSPI.h: Added.
+        Add a test ensuring that we get an invalidation callback when an editable image is changed.
+
 2018-11-29  Fujii Hironori  <Hironori.Fujii@sony.com>
 
         REGRESSION(r238445)[Buildbot] Unknown builder 'GTK Linux 32-bit Release' in scheduler 'trunk'
index 11d6478..8e2a4e3 100644 (file)
                2D21FE581F04642800B58E7D /* WKPDFViewStablePresentationUpdateCallback.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKPDFViewStablePresentationUpdateCallback.mm; sourceTree = "<group>"; };
                2D4CF8BC1D8360CC0001CE8D /* WKThumbnailView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WKThumbnailView.mm; path = WebKit/WKThumbnailView.mm; sourceTree = "<group>"; };
                2D51A0C51C8BF00400765C45 /* DOMHTMLVideoElementWrapper.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DOMHTMLVideoElementWrapper.mm; sourceTree = "<group>"; };
+               2D61EC3021B0B75C00A7D1CB /* PencilKitTestSPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PencilKitTestSPI.h; sourceTree = "<group>"; };
                2D640B5417875DFF00BFAF99 /* ScrollPinningBehaviors.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollPinningBehaviors.cpp; sourceTree = "<group>"; };
                2D8104CB1BEC13E70020DA46 /* FindInPage.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FindInPage.mm; sourceTree = "<group>"; };
                2D838B1E1EEF3A5B009B980E /* WKContentViewEditingActions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKContentViewEditingActions.mm; sourceTree = "<group>"; };
                        children = (
                                F4D4F3B41E4E2BCB00BB2767 /* DragAndDropSimulatorIOS.mm */,
                                2E7765CC16C4D80A00BA2BB1 /* mainIOS.mm */,
+                               2D61EC3021B0B75C00A7D1CB /* PencilKitTestSPI.h */,
                                F4517B652054C49500C26721 /* TestWKWebViewController.h */,
                                F4517B662054C49500C26721 /* TestWKWebViewController.mm */,
                                F493247C1F44DF8D006F4336 /* UIKitSPI.h */,
                                F45B63FE1F19D410009D38B9 /* ActionSheetTests.mm in Sources */,
                                37E7DD641EA06FF2009B396D /* AdditionalReadAccessAllowedURLs.mm in Sources */,
                                55A817FC218100E00004A39A /* AdditionalSupportedImageTypes.mm in Sources */,
-                               637281A721AE1386009E0DE6 /* DownloadProgress.mm in Sources */,
                                7A909A7D1D877480007E10F8 /* AffineTransform.cpp in Sources */,
                                A1DF74321C41B65800A2F4D0 /* AlwaysRevalidatedURLSchemes.mm in Sources */,
                                2DE71AFE1D49C0BD00904094 /* AnimatedResize.mm in Sources */,
                                518EE51820A78CE200E024F3 /* DoubleDefersLoading.mm in Sources */,
                                7CCE7F231A411AF600447C4C /* Download.mm in Sources */,
                                7CCE7EEE1A411AE600447C4C /* DownloadDecideDestinationCrash.cpp in Sources */,
+                               637281A721AE1386009E0DE6 /* DownloadProgress.mm in Sources */,
                                F4D4F3B61E4E2BCB00BB2767 /* DragAndDropSimulatorIOS.mm in Sources */,
                                F46128B7211C8ED500D9FADB /* DragAndDropSimulatorMac.mm in Sources */,
                                F46128D7211E489C00D9FADB /* DragAndDropTests.mm in Sources */,
index d48f43e..048b907 100644 (file)
@@ -26,6 +26,7 @@
 #import "config.h"
 
 #import "DragAndDropSimulator.h"
+#import "PencilKitTestSPI.h"
 #import "PlatformUtilities.h"
 #import "TestNavigationDelegate.h"
 #import "TestWKWebView.h"
 @interface AttachmentUpdateObserver : NSObject <WKUIDelegatePrivate>
 @property (nonatomic, readonly) NSArray *inserted;
 @property (nonatomic, readonly) NSArray *removed;
+@property (nonatomic, readonly) NSArray *dataInvalidated;
 @end
 
 @implementation AttachmentUpdateObserver {
     RetainPtr<NSMutableArray<_WKAttachment *>> _inserted;
     RetainPtr<NSMutableArray<_WKAttachment *>> _removed;
+    RetainPtr<NSMutableArray<_WKAttachment *>> _dataInvalidated;
     RetainPtr<NSMutableDictionary<NSString *, NSString *>> _identifierToSourceMap;
 }
 
@@ -60,6 +63,7 @@
     if (self = [super init]) {
         _inserted = adoptNS([[NSMutableArray alloc] init]);
         _removed = adoptNS([[NSMutableArray alloc] init]);
+        _dataInvalidated = adoptNS([[NSMutableArray alloc] init]);
         _identifierToSourceMap = adoptNS([[NSMutableDictionary alloc] init]);
     }
     return self;
     return _removed.get();
 }
 
+- (NSArray<_WKAttachment *> *)dataInvalidated
+{
+    return _dataInvalidated.get();
+}
+
 - (NSString *)sourceForIdentifier:(NSString *)identifier
 {
     return [_identifierToSourceMap objectForKey:identifier];
     [_removed addObject:attachment];
 }
 
+- (void)_webView:(WKWebView *)webView didInvalidateDataForAttachment:(_WKAttachment *)attachment
+{
+    [_dataInvalidated addObject:attachment];
+}
+
 @end
 
 namespace TestWebKitAPI {
@@ -126,6 +140,14 @@ public:
         EXPECT_TRUE(insertedAttachmentsMatch);
     }
 
+    void expectAttachmentInvalidation(NSArray<_WKAttachment *> *dataInvalidated)
+    {
+        BOOL invalidatedAttachmentsMatch = [[NSSet setWithArray:observer().dataInvalidated] isEqual:[NSSet setWithArray:dataInvalidated]];
+        if (!invalidatedAttachmentsMatch)
+            NSLog(@"Expected attachments with invalidated data: %@ to match %@.", observer().dataInvalidated, dataInvalidated);
+        EXPECT_TRUE(invalidatedAttachmentsMatch);
+    }
+
     void expectSourceForIdentifier(NSString *expectedSource, NSString *identifier)
     {
         NSString *observedSource = [observer() sourceForIdentifier:identifier];
@@ -153,6 +175,7 @@ static NSString *attachmentEditingTestMarkup = @"<meta name='viewport' content='
 static RetainPtr<TestWKWebView> webViewForTestingAttachments(CGSize webViewSize, WKWebViewConfiguration *configuration)
 {
     configuration._attachmentElementEnabled = YES;
+    configuration._editableImagesEnabled = YES;
     WKPreferencesSetCustomPasteboardDataEnabled((__bridge WKPreferencesRef)[configuration preferences], YES);
 
     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, webViewSize.width, webViewSize.height) configuration:configuration]);
@@ -1778,6 +1801,76 @@ TEST(WKAttachmentTestsIOS, DragAttachmentInsertedAsData)
     [dragAndDropSimulator endDataTransfer];
 }
 
+#if HAVE(PENCILKIT)
+static BOOL forEachViewInHierarchy(UIView *view, void(^mapFunction)(UIView *subview, BOOL *stop))
+{
+    BOOL stop = NO;
+    mapFunction(view, &stop);
+    if (stop)
+        return YES;
+
+    for (UIView *subview in view.subviews) {
+        stop = forEachViewInHierarchy(subview, mapFunction);
+        if (stop)
+            break;
+    }
+    return stop;
+}
+
+static PKCanvasView *findEditableImageCanvas(WKWebView *webView)
+{
+    Class pkCanvasViewClass = NSClassFromString(@"PKCanvasView");
+    __block PKCanvasView *canvasView = nil;
+    forEachViewInHierarchy(webView.window, ^(UIView *subview, BOOL *stop) {
+        if (![subview isKindOfClass:pkCanvasViewClass])
+            return;
+
+        canvasView = (PKCanvasView *)subview;
+        *stop = YES;
+    });
+    return canvasView;
+}
+
+static void drawSquareInEditableImage(WKWebView *webView)
+{
+    Class pkDrawingClass = NSClassFromString(@"PKDrawing");
+    Class pkInkClass = NSClassFromString(@"PKInk");
+    Class pkStrokeClass = NSClassFromString(@"PKStroke");
+
+    PKCanvasView *canvasView = findEditableImageCanvas(webView);
+    RetainPtr<PKDrawing> drawing = canvasView.drawing ?: adoptNS([[pkDrawingClass alloc] init]);
+    RetainPtr<CGPathRef> path = adoptCF(CGPathCreateWithRect(CGRectMake(0, 0, 50, 50), NULL));
+    RetainPtr<PKInk> ink = [pkInkClass inkWithType:0 color:UIColor.greenColor weight:100.0];
+    RetainPtr<PKStroke> stroke = adoptNS([[pkStrokeClass alloc] _initWithPath:path.get() ink:ink.get() inputScale:1]);
+    [drawing _addStroke:stroke.get()];
+
+    [canvasView setDrawing:drawing.get()];
+}
+
+TEST(WKAttachmentTestsIOS, EditableImageAttachmentDataInvalidation)
+{
+    auto webView = webViewForTestingAttachments();
+
+    RetainPtr<_WKAttachment> attachment;
+
+    {
+        ObserveAttachmentUpdatesForScope observer(webView.get());
+        EXPECT_TRUE([webView _synchronouslyExecuteEditCommand:@"InsertEditableImage" argument:nil]);
+        EXPECT_EQ(observer.observer().inserted.count, 1LU);
+        attachment = observer.observer().inserted.firstObject;
+    }
+
+    [webView waitForNextPresentationUpdate];
+
+    {
+        ObserveAttachmentUpdatesForScope observer(webView.get());
+        drawSquareInEditableImage(webView.get());
+        observer.expectAttachmentInvalidation(@[ attachment.get() ]);
+    }
+}
+
+#endif // HAVE(PENCILKIT)
+
 #endif // PLATFORM(IOS_FAMILY)
 
 } // namespace TestWebKitAPI
diff --git a/Tools/TestWebKitAPI/ios/PencilKitTestSPI.h b/Tools/TestWebKitAPI/ios/PencilKitTestSPI.h
new file mode 100644 (file)
index 0000000..b58369f
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#import <wtf/Platform.h>
+
+#if HAVE(PENCILKIT)
+
+#if USE(APPLE_INTERNAL_SDK)
+
+#import <PencilKit/PencilKit.h>
+
+#import <PencilKit/PKDrawing_Private.h>
+#import <PencilKit/PKStroke_Private.h>
+
+#else
+
+typedef NSInteger PKInkType;
+
+@interface PKInk : NSObject
++ (PKInk *)inkWithType:(PKInkType)type color:(UIColor *)color weight:(CGFloat)weight;
+@end
+
+@interface PKStroke : NSObject
+- (id)_initWithPath:(CGPathRef)path ink:(PKInk *)ink inputScale:(CGFloat)inputScale;
+@end
+
+@interface PKDrawing : NSObject
+- (PKStroke *)_addStroke:(PKStroke *)stroke;
+@property (nonatomic, readonly) NSArray<PKStroke *> *_allStrokes;
+@end
+
+@interface PKCanvasView : UIView
+@property (nonatomic, copy) PKDrawing *drawing;
+@end
+
+#endif // USE(APPLE_INTERNAL_SDK)
+
+#endif // HAVE(PENCILKIT)