WKContentView should just use InitializeWebKit2()
[WebKit-https.git] / Source / WebKit2 / UIProcess / API / ios / WKContentView.mm
1 /*
2  * Copyright (C) 2013 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 "WKContentViewInternal.h"
28
29 #import "PageClientImplIOS.h"
30 #import "RemoteLayerTreeDrawingAreaProxy.h"
31 #import "WebKit2Initialize.h"
32 #import "WKBrowsingContextControllerInternal.h"
33 #import "WKBrowsingContextGroupPrivate.h"
34 #import "WKGeolocationProviderIOS.h"
35 #import "WKInteractionView.h"
36 #import "WKProcessGroupInternal.h"
37 #import "WebContext.h"
38 #import "WebFrameProxy.h"
39 #import "WebPageGroup.h"
40 #import "WebSystemInterface.h"
41 #import <UIKit/UIWindow_Private.h>
42 #import <WebCore/ViewportArguments.h>
43 #import <wtf/RetainPtr.h>
44
45 using namespace WebCore;
46 using namespace WebKit;
47
48 @implementation WKContentView {
49     std::unique_ptr<PageClientImpl> _pageClient;
50     RefPtr<WebPageProxy> _page;
51
52     RetainPtr<UIView> _rootContentView;
53     RetainPtr<WKInteractionView> _interactionView;
54 }
55
56 - (id)initWithCoder:(NSCoder *)coder
57 {
58     // FIXME: Implement.
59     [self release];
60     return nil;
61 }
62
63 - (id)initWithFrame:(CGRect)frame processGroup:(WKProcessGroup *)processGroup browsingContextGroup:(WKBrowsingContextGroup *)browsingContextGroup
64 {
65     if (!(self = [super initWithFrame:frame]))
66         return nil;
67
68     [self _commonInitializationWithContextRef:processGroup._contextRef pageGroupRef:browsingContextGroup._pageGroupRef relatedToPage:nullptr];
69     return self;
70 }
71
72 - (void)dealloc
73 {
74     _page->close();
75
76     WebContext::statistics().wkViewCount--;
77
78     [super dealloc];
79 }
80
81 - (void)willMoveToWindow:(UIWindow *)newWindow
82 {
83     NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
84     UIWindow *window = self.window;
85
86     if (window)
87         [defaultCenter removeObserver:self name:UIWindowDidMoveToScreenNotification object:window];
88
89     if (newWindow)
90         [defaultCenter addObserver:self selector:@selector(_windowDidMoveToScreenNotification:) name:UIWindowDidMoveToScreenNotification object:newWindow];
91 }
92
93 - (void)didMoveToWindow
94 {
95     if (self.window)
96         [self _updateForScreen:self.window.screen];
97     _page->viewStateDidChange(ViewState::IsInWindow);
98 }
99
100 - (WKBrowsingContextController *)browsingContextController
101 {
102     return wrapper(*_page);
103 }
104
105 - (WKContentType)contentType
106 {
107     if (_page->mainFrame()->mimeType() == "text/plain")
108         return WKContentType::PlainText;
109     else if (_page->mainFrame()->isDisplayingStandaloneImageDocument())
110         return WKContentType::Image;
111     return WKContentType::Standard;
112 }
113
114 - (void)setMinimumSize:(CGSize)size
115 {
116     _page->drawingArea()->setSize(IntSize(size), IntSize(), IntSize());
117 }
118
119 - (void)setViewportSize:(CGSize)size
120 {
121     _page->setFixedLayoutSize(IntSize(size));
122 }
123
124 - (void)didScrollTo:(CGPoint)contentOffset
125 {
126     _page->didFinishScrolling(contentOffset);
127 }
128
129 - (void)didZoomToScale:(CGFloat)scale
130 {
131     _page->didFinishZooming(scale);
132 }
133
134 #pragma mark Internal
135
136 - (void)_commonInitializationWithContextRef:(WKContextRef)contextRef pageGroupRef:(WKPageGroupRef)pageGroupRef relatedToPage:(WKPageRef)relatedPage
137 {
138     // FIXME: This should not be necessary, find why hit testing does not work otherwise.
139     // <rdar://problem/12287363>
140     self.backgroundColor = [UIColor blackColor];
141
142     InitializeWebKit2();
143     RunLoop::initializeMainRunLoop();
144
145     _pageClient = std::make_unique<PageClientImpl>(self);
146     _page = toImpl(contextRef)->createWebPage(*_pageClient, toImpl(pageGroupRef), toImpl(relatedPage));
147     _page->initializeWebPage();
148     _page->setIntrinsicDeviceScaleFactor([UIScreen mainScreen].scale);
149     _page->setUseFixedLayout(true);
150
151     WebContext::statistics().wkViewCount++;
152
153     _rootContentView = adoptNS([[UIView alloc] init]);
154     [[_rootContentView layer] setMasksToBounds:NO];
155     [_rootContentView setUserInteractionEnabled:NO];
156
157     [self addSubview:_rootContentView.get()];
158
159     _interactionView = adoptNS([[WKInteractionView alloc] init]);
160     [_interactionView setPage:_page];
161     [self addSubview:_interactionView.get()];
162 }
163
164 - (void)_windowDidMoveToScreenNotification:(NSNotification *)notification
165 {
166     ASSERT(notification.object == self.window);
167
168     UIScreen *screen = notification.userInfo[UIWindowNewScreenUserInfoKey];
169     [self _updateForScreen:screen];
170 }
171
172 - (void)_updateForScreen:(UIScreen *)screen
173 {
174     ASSERT(screen);
175     _page->setIntrinsicDeviceScaleFactor(screen.scale);
176 }
177
178 #pragma mark PageClientImpl methods
179
180 - (std::unique_ptr<DrawingAreaProxy>)_createDrawingAreaProxy
181 {
182     return std::make_unique<RemoteLayerTreeDrawingAreaProxy>(_page.get());
183 }
184
185 - (void)_processDidCrash
186 {
187     // FIXME: Implement.
188 }
189
190 - (void)_didRelaunchProcess
191 {
192     // FIXME: Implement.
193 }
194
195 - (void)_didCommitLoadForMainFrame
196 {
197     if ([_delegate respondsToSelector:@selector(contentViewDidCommitLoadForMainFrame:)])
198         [_delegate contentViewDidCommitLoadForMainFrame:self];
199 }
200
201 - (void)_didChangeContentSize:(CGSize)contentsSize
202 {
203     [self setBounds:{CGPointZero, contentsSize}];
204     [_interactionView setFrame:CGRectMake(0, 0, contentsSize.width, contentsSize.height)];
205     [_rootContentView setFrame:CGRectMake(0, 0, contentsSize.width, contentsSize.height)];
206
207     if ([_delegate respondsToSelector:@selector(contentView:contentsSizeDidChange:)])
208         [_delegate contentView:self contentsSizeDidChange:contentsSize];
209 }
210
211 - (void)_didReceiveMobileDocTypeForMainFrame
212 {
213     if ([_delegate respondsToSelector:@selector(contentViewDidReceiveMobileDocType:)])
214         [_delegate contentViewDidReceiveMobileDocType:self];
215 }
216
217 - (void)_didChangeViewportArguments:(const WebCore::ViewportArguments&)arguments
218 {
219     if ([_delegate respondsToSelector:@selector(contentView:didChangeViewportArgumentsSize:initialScale:minimumScale:maximumScale:allowsUserScaling:)])
220         [_delegate contentView:self didChangeViewportArgumentsSize:CGSizeMake(arguments.width, arguments.height) initialScale:arguments.zoom minimumScale:arguments.minZoom maximumScale:arguments.maxZoom allowsUserScaling:arguments.userZoom];
221 }
222
223 - (void)_didGetTapHighlightForRequest:(uint64_t)requestID color:(const Color&)color quads:(const Vector<FloatQuad>&)highlightedQuads topLeftRadius:(const IntSize&)topLeftRadius topRightRadius:(const IntSize&)topRightRadius bottomLeftRadius:(const IntSize&)bottomLeftRadius bottomRightRadius:(const IntSize&)bottomRightRadius
224 {
225     [_interactionView _didGetTapHighlightForRequest:requestID color:color quads:highlightedQuads topLeftRadius:topLeftRadius topRightRadius:topRightRadius bottomLeftRadius:bottomLeftRadius bottomRightRadius:bottomRightRadius];
226 }
227
228 - (void)_setAcceleratedCompositingRootLayer:(CALayer *)rootLayer
229 {
230     [[_rootContentView layer] setSublayers:@[rootLayer]];
231 }
232
233 // FIXME: change the name. Leave it for now to make it easier to refer to the UIKit implementation.
234 - (void)_startAssistingNode
235 {
236     [_interactionView _startAssistingNode];
237 }
238
239 - (void)_stopAssistingNode
240 {
241     [_interactionView _stopAssistingNode];
242 }
243
244 - (void)_selectionChanged
245 {
246     [_interactionView _selectionChanged];
247 }
248
249 - (BOOL)_interpretKeyEvent:(WebIOSEvent *)theEvent isCharEvent:(BOOL)isCharEvent
250 {
251     return [_interactionView _interpretKeyEvent:theEvent isCharEvent:isCharEvent];
252 }
253
254 - (void)_decidePolicyForGeolocationRequestFromOrigin:(WebSecurityOrigin&)origin frame:(WebFrameProxy&)frame request:(GeolocationPermissionRequestProxy&)permissionRequest
255 {
256     [[wrapper(_page->process().context()) _geolocationProvider] decidePolicyForGeolocationRequestFromOrigin:toAPI(&origin) frame:toAPI(&frame) request:toAPI(&permissionRequest) window:[self window]];
257 }
258
259 @end
260
261 @implementation WKContentView (Private)
262
263 - (WKPageRef)_pageRef
264 {
265     return toAPI(_page.get());
266 }
267
268 - (id)initWithFrame:(CGRect)frame contextRef:(WKContextRef)contextRef pageGroupRef:(WKPageGroupRef)pageGroupRef
269 {
270     return [self initWithFrame:frame contextRef:contextRef pageGroupRef:pageGroupRef relatedToPage:nullptr];
271 }
272
273 - (id)initWithFrame:(CGRect)frame contextRef:(WKContextRef)contextRef pageGroupRef:(WKPageGroupRef)pageGroupRef relatedToPage:(WKPageRef)relatedPage
274 {
275     if (!(self = [super initWithFrame:frame]))
276         return nil;
277
278     [self _commonInitializationWithContextRef:contextRef pageGroupRef:pageGroupRef relatedToPage:relatedPage];
279     return self;
280 }
281
282 @end