bd2b8fdfc17c604589ff10d875982109ffe0d182
[WebKit-https.git] / Source / WebKit / UIProcess / ios / WKPDFView.mm
1 /*
2  * Copyright (C) 2018 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #import "config.h"
27 #import "WKPDFView.h"
28
29 #if ENABLE(WKPDFVIEW)
30
31 #import "WKWebViewInternal.h"
32 #import "WeakObjCPtr.h"
33 #import "WebPageProxy.h"
34 #import <PDFKit/PDFHostViewController.h>
35 #import <wtf/MainThread.h>
36 #import <wtf/RetainPtr.h>
37
38 @interface WKPDFView () <PDFHostViewControllerDelegate>
39 @end
40
41 @implementation WKPDFView {
42     CGSize _overlaidAccessoryViewsInset;
43     RetainPtr<NSData> _data;
44     RetainPtr<NSString> _suggestedFilename;
45     RetainPtr<PDFHostViewController> _hostViewController;
46     RetainPtr<UIView> _fixedOverlayView;
47     RetainPtr<UIView> _pageNumberIndicator;
48     WebKit::WeakObjCPtr<WKWebView> _webView;
49 }
50
51 - (void)dealloc
52 {
53     [[_hostViewController view] removeFromSuperview];
54     [_pageNumberIndicator removeFromSuperview];
55     [super dealloc];
56 }
57
58 - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
59 {
60     return [_hostViewController gestureRecognizerShouldBegin:gestureRecognizer];
61 }
62
63 #pragma mark WKWebViewContentProvider
64
65 - (instancetype)web_initWithFrame:(CGRect)frame webView:(WKWebView *)webView
66 {
67     if (!(self = [super initWithFrame:frame webView:webView]))
68         return nil;
69
70     self.backgroundColor = UIColor.grayColor;
71     webView.scrollView.backgroundColor = UIColor.grayColor;
72
73     _webView = webView;
74     return self;
75 }
76
77 - (void)web_setContentProviderData:(NSData *)data suggestedFilename:(NSString *)filename
78 {
79     _data = adoptNS([data copy]);
80     _suggestedFilename = adoptNS([filename copy]);
81
82     [PDFHostViewController createHostView:^(PDFHostViewController * _Nullable hostViewController) {
83         ASSERT(isMainThread());
84
85         WKWebView *webView = _webView.getAutoreleased();
86         if (!webView)
87             return;
88
89         if (!hostViewController)
90             return;
91         _hostViewController = hostViewController;
92
93         UIView *hostView = hostViewController.view;
94         hostView.frame = webView.bounds;
95         hostView.backgroundColor = UIColor.grayColor;
96
97         UIScrollView *scrollView = webView.scrollView;
98         [self removeFromSuperview];
99         [scrollView addSubview:hostView];
100
101         _pageNumberIndicator = hostViewController.pageNumberIndicator;
102         [_fixedOverlayView addSubview:_pageNumberIndicator.get()];
103
104         hostViewController.delegate = self;
105         [hostViewController setDocumentData:_data.get() withScrollView:scrollView];
106     } forExtensionIdentifier:nil];
107 }
108
109 - (CGPoint)_offsetForPageNumberIndicator
110 {
111     WKWebView *webView = _webView.getAutoreleased();
112     if (!webView)
113         return CGPointZero;
114
115     UIEdgeInsets insets = UIEdgeInsetsAdd(webView._computedUnobscuredSafeAreaInset, webView._computedObscuredInset, UIRectEdgeAll);
116     return CGPointMake(insets.left, insets.top + _overlaidAccessoryViewsInset.height);
117 }
118
119 - (void)_movePageNumberIndicatorToPoint:(CGPoint)point animated:(BOOL)animated
120 {
121     void (^setFrame)() = ^{
122         static const CGFloat margin = 20;
123         const CGRect frame = { CGPointMake(point.x + margin, point.y + margin), [_pageNumberIndicator frame].size };
124         [_pageNumberIndicator setFrame:frame];
125     };
126
127     if (animated) {
128         static const NSTimeInterval duration = 0.3;
129         [UIView animateWithDuration:duration animations:setFrame];
130         return;
131     }
132
133     setFrame();
134 }
135
136 - (void)_updateLayoutAnimated:(BOOL)animated
137 {
138     [_hostViewController updatePDFViewLayout];
139     [self _movePageNumberIndicatorToPoint:self._offsetForPageNumberIndicator animated:animated];
140 }
141
142 - (void)web_setMinimumSize:(CGSize)size
143 {
144     self.frame = { self.frame.origin, size };
145     [self _updateLayoutAnimated:NO];
146 }
147
148 - (void)web_setOverlaidAccessoryViewsInset:(CGSize)inset
149 {
150     _overlaidAccessoryViewsInset = inset;
151     [self _updateLayoutAnimated:YES];
152 }
153
154 - (void)web_computedContentInsetDidChange
155 {
156     [self _updateLayoutAnimated:NO];
157 }
158
159 - (void)web_setFixedOverlayView:(UIView *)fixedOverlayView
160 {
161     _fixedOverlayView = fixedOverlayView;
162 }
163
164 - (void)web_didSameDocumentNavigation:(WKSameDocumentNavigationType)navigationType
165 {
166     // FIXME: Implement page number navigations.
167 }
168
169 - (void)web_countStringMatches:(NSString *)string options:(_WKFindOptions)options maxCount:(NSUInteger)maxCount
170 {
171     // FIXME: Implement find-in-page.
172 }
173
174 - (void)web_findString:(NSString *)string options:(_WKFindOptions)options maxCount:(NSUInteger)maxCount
175 {
176     // FIXME: Implement find-in-page.
177 }
178
179 - (void)web_hideFindUI
180 {
181     // FIXME: Implement find-in-page.
182 }
183
184 - (UIView *)web_contentView
185 {
186     return _hostViewController ? [_hostViewController view] : self;
187 }
188
189 - (void)web_scrollViewDidScroll:(UIScrollView *)scrollView
190 {
191     [_hostViewController updatePDFViewLayout];
192 }
193
194 - (void)web_scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view
195 {
196     [_hostViewController updatePDFViewLayout];
197 }
198
199 - (void)web_scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale
200 {
201     [_hostViewController updatePDFViewLayout];
202 }
203
204 - (void)web_scrollViewDidZoom:(UIScrollView *)scrollView
205 {
206     [_hostViewController updatePDFViewLayout];
207 }
208
209 - (NSData *)web_dataRepresentation
210 {
211     return _data.get();
212 }
213
214 - (NSString *)web_suggestedFilename
215 {
216     return _suggestedFilename.get();
217 }
218
219 - (BOOL)web_isBackground
220 {
221     return self.isBackground;
222 }
223
224 @end
225
226 #endif // ENABLE(WKPDFVIEW)