Replace WTF::move with WTFMove
[WebKit-https.git] / Source / WebKit2 / UIProcess / API / Cocoa / WKWebViewConfiguration.mm
1 /*
2  * Copyright (C) 2014, 2015 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 "WKWebViewConfigurationInternal.h"
28
29 #if WK_API_ENABLED
30
31 #import "APIPageConfiguration.h"
32 #import "WKPreferences.h"
33 #import "WKProcessPool.h"
34 #import "WKUserContentController.h"
35 #import "WKWebViewContentProviderRegistry.h"
36 #import "WeakObjCPtr.h"
37 #import "_WKVisitedLinkProvider.h"
38 #import "_WKWebsiteDataStoreInternal.h"
39 #import <wtf/RetainPtr.h>
40
41 #if PLATFORM(IOS)
42 #import "UIKitSPI.h"
43 #import <WebCore/Device.h>
44 #endif
45
46 template<typename T> class LazyInitialized {
47 public:
48     typedef typename WTF::GetPtrHelper<T>::PtrType PtrType;
49
50     template<typename F>
51     PtrType get(F&& f)
52     {
53         if (!m_isInitialized) {
54             m_value = f();
55             m_isInitialized = true;
56         }
57
58         return m_value.get();
59     }
60
61     void set(PtrType t)
62     {
63         m_value = t;
64         m_isInitialized = true;
65     }
66
67     void set(T&& t)
68     {
69         m_value = WTFMove(t);
70         m_isInitialized = true;
71     }
72
73     PtrType peek()
74     {
75         return m_value.get();
76     }
77
78 private:
79     bool m_isInitialized = false;
80     T m_value;
81 };
82
83 @implementation WKWebViewConfiguration {
84     LazyInitialized<RetainPtr<WKProcessPool>> _processPool;
85     LazyInitialized<RetainPtr<WKPreferences>> _preferences;
86     LazyInitialized<RetainPtr<WKUserContentController>> _userContentController;
87     LazyInitialized<RetainPtr<_WKVisitedLinkStore>> _visitedLinkStore;
88     LazyInitialized<RetainPtr<WKWebsiteDataStore>> _websiteDataStore;
89     WebKit::WeakObjCPtr<WKWebView> _relatedWebView;
90     WebKit::WeakObjCPtr<WKWebView> _alternateWebViewForNavigationGestures;
91     BOOL _treatsSHA1SignedCertificatesAsInsecure;
92     RetainPtr<NSString> _groupIdentifier;
93     LazyInitialized<RetainPtr<NSString>> _applicationNameForUserAgent;
94     BOOL _respectsImageOrientation;
95     BOOL _printsBackgrounds;
96     CGFloat _incrementalRenderingSuppressionTimeout;
97     BOOL _allowsJavaScriptMarkup;
98     BOOL _convertsPositionStyleOnCopy;
99     BOOL _allowsMetaRefresh;
100
101 #if PLATFORM(IOS)
102     LazyInitialized<RetainPtr<WKWebViewContentProviderRegistry>> _contentProviderRegistry;
103     BOOL _alwaysRunsAtForegroundPriority;
104     BOOL _allowsInlineMediaPlayback;
105     BOOL _inlineMediaPlaybackRequiresPlaysInlineAttribute;
106     BOOL _invisibleAutoplayNotPermitted;
107     BOOL _mediaDataLoadsAutomatically;
108     BOOL _requiresUserActionForAudioPlayback;
109 #endif
110 #if PLATFORM(MAC)
111     BOOL _showsURLsInToolTips;
112     BOOL _serviceControlsEnabled;
113     BOOL _imageControlsEnabled;
114 #endif
115 }
116
117 - (instancetype)init
118 {
119     if (!(self = [super init]))
120         return nil;
121     
122 #if PLATFORM(IOS)
123     _requiresUserActionForMediaPlayback = YES;
124     _requiresUserActionForAudioPlayback = YES;
125     _allowsPictureInPictureMediaPlayback = YES;
126     _allowsInlineMediaPlayback = WebCore::deviceClass() == MGDeviceClassiPad;
127     _inlineMediaPlaybackRequiresPlaysInlineAttribute = !_allowsInlineMediaPlayback;
128     _invisibleAutoplayNotPermitted = YES;
129     _mediaDataLoadsAutomatically = NO;
130     _respectsImageOrientation = YES;
131     _printsBackgrounds = YES;
132 #endif
133
134 #if PLATFORM(MAC)
135     _printsBackgrounds = NO;
136     _respectsImageOrientation = NO;
137     _showsURLsInToolTips = NO;
138     _serviceControlsEnabled = NO;
139     _imageControlsEnabled = NO;
140 #endif
141
142 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
143     _allowsAirPlayForMediaPlayback = YES;
144 #endif
145
146     _incrementalRenderingSuppressionTimeout = 5;
147     _allowsJavaScriptMarkup = YES;
148     _convertsPositionStyleOnCopy = NO;
149     _allowsMetaRefresh = YES;
150
151     return self;
152 }
153
154 - (NSString *)description
155 {
156     return [NSString stringWithFormat:@"<%@: %p; processPool = %@; preferences = %@>", NSStringFromClass(self.class), self, self.processPool, self.preferences];
157 }
158
159 - (id)copyWithZone:(NSZone *)zone
160 {
161     WKWebViewConfiguration *configuration = [(WKWebViewConfiguration *)[[self class] allocWithZone:zone] init];
162
163     configuration.processPool = self.processPool;
164     configuration.preferences = self.preferences;
165     configuration.userContentController = self.userContentController;
166     configuration.websiteDataStore = self.websiteDataStore;
167     configuration._visitedLinkStore = self._visitedLinkStore;
168     configuration._relatedWebView = _relatedWebView.get().get();
169     configuration._alternateWebViewForNavigationGestures = _alternateWebViewForNavigationGestures.get().get();
170     configuration->_treatsSHA1SignedCertificatesAsInsecure = _treatsSHA1SignedCertificatesAsInsecure;
171 #if PLATFORM(IOS)
172     configuration._contentProviderRegistry = self._contentProviderRegistry;
173 #endif
174
175     configuration->_suppressesIncrementalRendering = self->_suppressesIncrementalRendering;
176     configuration.applicationNameForUserAgent = self.applicationNameForUserAgent;
177
178     configuration->_respectsImageOrientation = self->_respectsImageOrientation;
179     configuration->_printsBackgrounds = self->_printsBackgrounds;
180     configuration->_incrementalRenderingSuppressionTimeout = self->_incrementalRenderingSuppressionTimeout;
181     configuration->_allowsJavaScriptMarkup = self->_allowsJavaScriptMarkup;
182     configuration->_convertsPositionStyleOnCopy = self->_convertsPositionStyleOnCopy;
183     configuration->_allowsMetaRefresh = self->_allowsMetaRefresh;
184
185 #if PLATFORM(IOS)
186     configuration->_allowsInlineMediaPlayback = self->_allowsInlineMediaPlayback;
187     configuration->_inlineMediaPlaybackRequiresPlaysInlineAttribute = self->_inlineMediaPlaybackRequiresPlaysInlineAttribute;
188     configuration->_invisibleAutoplayNotPermitted = self->_invisibleAutoplayNotPermitted;
189     configuration->_mediaDataLoadsAutomatically = self->_mediaDataLoadsAutomatically;
190     configuration->_allowsPictureInPictureMediaPlayback = self->_allowsPictureInPictureMediaPlayback;
191     configuration->_alwaysRunsAtForegroundPriority = _alwaysRunsAtForegroundPriority;
192     configuration->_requiresUserActionForMediaPlayback = self->_requiresUserActionForMediaPlayback;
193     configuration->_requiresUserActionForAudioPlayback = self->_requiresUserActionForAudioPlayback;
194     configuration->_selectionGranularity = self->_selectionGranularity;
195 #endif
196 #if PLATFORM(MAC)
197     configuration->_showsURLsInToolTips = self->_showsURLsInToolTips;
198     configuration->_serviceControlsEnabled = self->_serviceControlsEnabled;
199     configuration->_imageControlsEnabled = self->_imageControlsEnabled;
200 #endif
201 #if ENABLE(WIRELESS_TARGET_PLAYBACK)
202     configuration->_allowsAirPlayForMediaPlayback = self->_allowsAirPlayForMediaPlayback;
203 #endif
204
205     return configuration;
206 }
207
208 - (WKProcessPool *)processPool
209 {
210     return _processPool.get([] { return adoptNS([[WKProcessPool alloc] init]); });
211 }
212
213 - (void)setProcessPool:(WKProcessPool *)processPool
214 {
215     _processPool.set(processPool);
216 }
217
218 - (WKPreferences *)preferences
219 {
220     return _preferences.get([] { return adoptNS([[WKPreferences alloc] init]); });
221 }
222
223 - (void)setPreferences:(WKPreferences *)preferences
224 {
225     _preferences.set(preferences);
226 }
227
228 - (WKUserContentController *)userContentController
229 {
230     return _userContentController.get([] { return adoptNS([[WKUserContentController alloc] init]); });
231 }
232
233 - (void)setUserContentController:(WKUserContentController *)userContentController
234 {
235     _userContentController.set(userContentController);
236 }
237
238 - (WKWebsiteDataStore *)websiteDataStore
239 {
240     return _websiteDataStore.get([] { return [WKWebsiteDataStore defaultDataStore]; });
241 }
242
243 - (void)setWebsiteDataStore:(WKWebsiteDataStore *)websiteDataStore
244 {
245     _websiteDataStore.set(websiteDataStore);
246 }
247
248 static NSString *defaultApplicationNameForUserAgent()
249 {
250 #if PLATFORM(IOS)
251     return [@"Mobile/" stringByAppendingString:[UIDevice currentDevice].buildVersion];
252 #else
253     return nil;
254 #endif
255 }
256
257 - (NSString *)applicationNameForUserAgent
258 {
259     return _applicationNameForUserAgent.get([] { return defaultApplicationNameForUserAgent(); });
260 }
261
262 - (void)setApplicationNameForUserAgent:(NSString *)applicationNameForUserAgent
263 {
264     _applicationNameForUserAgent.set(adoptNS([applicationNameForUserAgent copy]));
265 }
266
267 - (_WKVisitedLinkStore *)_visitedLinkStore
268 {
269     return _visitedLinkStore.get([] { return adoptNS([[_WKVisitedLinkStore alloc] init]); });
270 }
271
272 - (void)_setVisitedLinkStore:(_WKVisitedLinkStore *)visitedLinkStore
273 {
274     _visitedLinkStore.set(visitedLinkStore);
275 }
276
277 #pragma clang diagnostic push
278 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
279
280 - (_WKWebsiteDataStore *)_websiteDataStore
281 {
282     return self.websiteDataStore ? adoptNS([[_WKWebsiteDataStore alloc] initWithDataStore:self.websiteDataStore]).autorelease() : nullptr;
283 }
284
285 - (void)_setWebsiteDataStore:(_WKWebsiteDataStore *)websiteDataStore
286 {
287     self.websiteDataStore = websiteDataStore ? websiteDataStore->_dataStore.get() : nullptr;
288 }
289
290 -(_WKVisitedLinkProvider *)_visitedLinkProvider
291 {
292     return (_WKVisitedLinkProvider *)self._visitedLinkStore;
293 }
294
295 - (void)_setVisitedLinkProvider:(_WKVisitedLinkProvider *)_visitedLinkProvider
296 {
297     self._visitedLinkStore = _visitedLinkProvider;
298 }
299
300 #pragma clang diagnostic pop
301
302 #if PLATFORM(IOS)
303 - (WKWebViewContentProviderRegistry *)_contentProviderRegistry
304 {
305     return _contentProviderRegistry.get([] { return adoptNS([[WKWebViewContentProviderRegistry alloc] init]); });
306 }
307
308 - (void)_setContentProviderRegistry:(WKWebViewContentProviderRegistry *)registry
309 {
310     _contentProviderRegistry.set(registry);
311 }
312 #endif
313
314 - (void)_validate
315 {
316     if (!self.processPool)
317         [NSException raise:NSInvalidArgumentException format:@"configuration.processPool is nil"];
318
319     if (!self.preferences)
320         [NSException raise:NSInvalidArgumentException format:@"configuration.preferences is nil"];
321
322     if (!self.userContentController)
323         [NSException raise:NSInvalidArgumentException format:@"configuration.userContentController is nil"];
324
325     if (!self.websiteDataStore)
326         [NSException raise:NSInvalidArgumentException format:@"configuration.websiteDataStore is nil"];
327
328     if (!self._visitedLinkStore)
329         [NSException raise:NSInvalidArgumentException format:@"configuration._visitedLinkStore is nil"];
330
331 #if PLATFORM(IOS)
332     if (!self._contentProviderRegistry)
333         [NSException raise:NSInvalidArgumentException format:@"configuration._contentProviderRegistry is nil"];
334 #endif
335 }
336
337 @end
338
339 @implementation WKWebViewConfiguration (WKPrivate)
340
341 - (WKWebView *)_relatedWebView
342 {
343     return _relatedWebView.getAutoreleased();
344 }
345
346 - (void)_setRelatedWebView:(WKWebView *)relatedWebView
347 {
348     _relatedWebView = relatedWebView;
349 }
350
351 - (WKWebView *)_alternateWebViewForNavigationGestures
352 {
353     return _alternateWebViewForNavigationGestures.getAutoreleased();
354 }
355
356 - (void)_setAlternateWebViewForNavigationGestures:(WKWebView *)alternateView
357 {
358     _alternateWebViewForNavigationGestures = alternateView;
359 }
360
361 - (NSString *)_groupIdentifier
362 {
363     return _groupIdentifier.get();
364 }
365
366 - (void)_setGroupIdentifier:(NSString *)groupIdentifier
367 {
368     _groupIdentifier = groupIdentifier;
369 }
370
371 - (BOOL)_treatsSHA1SignedCertificatesAsInsecure
372 {
373     return _treatsSHA1SignedCertificatesAsInsecure;
374 }
375
376 - (void)_setTreatsSHA1SignedCertificatesAsInsecure:(BOOL)insecure
377 {
378     _treatsSHA1SignedCertificatesAsInsecure = insecure;
379 }
380
381 - (BOOL)_respectsImageOrientation
382 {
383     return _respectsImageOrientation;
384 }
385
386 - (void)_setRespectsImageOrientation:(BOOL)respectsImageOrientation
387 {
388     _respectsImageOrientation = respectsImageOrientation;
389 }
390
391 - (BOOL)_printsBackgrounds
392 {
393     return _printsBackgrounds;
394 }
395
396 - (void)_setPrintsBackgrounds:(BOOL)printsBackgrounds
397 {
398     _printsBackgrounds = printsBackgrounds;
399 }
400
401 - (CGFloat)_incrementalRenderingSuppressionTimeout
402 {
403     return _incrementalRenderingSuppressionTimeout;
404 }
405
406 - (void)_setIncrementalRenderingSuppressionTimeout:(CGFloat)incrementalRenderingSuppressionTimeout
407 {
408     _incrementalRenderingSuppressionTimeout = incrementalRenderingSuppressionTimeout;
409 }
410
411 - (BOOL)_allowsJavaScriptMarkup
412 {
413     return _allowsJavaScriptMarkup;
414 }
415
416 - (void)_setAllowsJavaScriptMarkup:(BOOL)allowsJavaScriptMarkup
417 {
418     _allowsJavaScriptMarkup = allowsJavaScriptMarkup;
419 }
420
421 - (BOOL)_convertsPositionStyleOnCopy
422 {
423     return _convertsPositionStyleOnCopy;
424 }
425
426 - (void)_setConvertsPositionStyleOnCopy:(BOOL)convertsPositionStyleOnCopy
427 {
428     _convertsPositionStyleOnCopy = convertsPositionStyleOnCopy;
429 }
430
431 - (BOOL)_allowsMetaRefresh
432 {
433     return _allowsMetaRefresh;
434 }
435
436 - (void)_setAllowsMetaRefresh:(BOOL)allowsMetaRefresh
437 {
438     _allowsMetaRefresh = allowsMetaRefresh;
439 }
440
441 #if PLATFORM(IOS)
442 - (BOOL)_alwaysRunsAtForegroundPriority
443 {
444     return _alwaysRunsAtForegroundPriority;
445 }
446
447 - (void)_setAlwaysRunsAtForegroundPriority:(BOOL)alwaysRunsAtForegroundPriority
448 {
449     _alwaysRunsAtForegroundPriority = alwaysRunsAtForegroundPriority;
450 }
451
452 - (BOOL)_inlineMediaPlaybackRequiresPlaysInlineAttribute
453 {
454     return _inlineMediaPlaybackRequiresPlaysInlineAttribute;
455 }
456
457 - (void)_setInlineMediaPlaybackRequiresPlaysInlineAttribute:(BOOL)requires
458 {
459     _inlineMediaPlaybackRequiresPlaysInlineAttribute = requires;
460 }
461
462 - (BOOL)_invisibleAutoplayNotPermitted
463 {
464     return _invisibleAutoplayNotPermitted;
465 }
466
467 - (void)_setInvisibleAutoplayNotPermitted:(BOOL)notPermitted
468 {
469     _invisibleAutoplayNotPermitted = notPermitted;
470 }
471
472 - (BOOL)_mediaDataLoadsAutomatically
473 {
474     return _mediaDataLoadsAutomatically;
475 }
476
477 - (void)_setMediaDataLoadsAutomatically:(BOOL)mediaDataLoadsAutomatically
478 {
479     _mediaDataLoadsAutomatically = mediaDataLoadsAutomatically;
480 }
481
482 - (BOOL)_requiresUserActionForAudioPlayback
483 {
484     return _requiresUserActionForAudioPlayback;
485 }
486
487 - (void)_setRequiresUserActionForAudioPlayback:(BOOL)requiresUserActionForAudioPlayback
488 {
489     _requiresUserActionForAudioPlayback = requiresUserActionForAudioPlayback;
490 }
491
492 #endif // PLATFORM(IOS)
493
494 #if PLATFORM(MAC)
495 - (BOOL)_showsURLsInToolTips
496 {
497     return _showsURLsInToolTips;
498 }
499
500 - (void)_setShowsURLsInToolTips:(BOOL)showsURLsInToolTips
501 {
502     _showsURLsInToolTips = showsURLsInToolTips;
503 }
504
505 - (BOOL)_serviceControlsEnabled
506 {
507     return _serviceControlsEnabled;
508 }
509
510 - (void)_setServiceControlsEnabled:(BOOL)serviceControlsEnabled
511 {
512     _serviceControlsEnabled = serviceControlsEnabled;
513 }
514
515 - (BOOL)_imageControlsEnabled
516 {
517     return _imageControlsEnabled;
518 }
519
520 - (void)_setImageControlsEnabled:(BOOL)imageControlsEnabled
521 {
522     _imageControlsEnabled = imageControlsEnabled;
523 }
524 #endif // PLATFORM(MAC)
525
526 @end
527
528 @implementation WKWebViewConfiguration (WKDeprecated)
529
530 #if PLATFORM(IOS)
531 - (BOOL)mediaPlaybackAllowsAirPlay
532 {
533     return self.allowsAirPlayForMediaPlayback;
534 }
535
536 - (void)setMediaPlaybackAllowsAirPlay:(BOOL)allowed
537 {
538     self.allowsAirPlayForMediaPlayback = allowed;
539 }
540
541 - (BOOL)mediaPlaybackRequiresUserAction
542 {
543     return self.requiresUserActionForMediaPlayback;
544 }
545
546 - (void)setMediaPlaybackRequiresUserAction:(BOOL)required
547 {
548     self.requiresUserActionForMediaPlayback = required;
549 }
550 #endif // PLATFORM(IOS)
551
552 @end
553
554 #endif // WK_API_ENABLED