Make Legacy EME API controlled by RuntimeEnabled setting.
[WebKit-https.git] / Source / WebKit2 / UIProcess / API / Cocoa / WKWebViewConfiguration.mm
1 /*
2  * Copyright (C) 2014-2016 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 "VersionChecks.h"
33 #import "WKPreferences.h"
34 #import "WKProcessPool.h"
35 #import "WKUserContentController.h"
36 #import "WKWebView.h"
37 #import "WKWebViewContentProviderRegistry.h"
38 #import "WeakObjCPtr.h"
39 #import "WebKit2Initialize.h"
40 #import "_WKVisitedLinkStore.h"
41 #import "_WKWebsiteDataStoreInternal.h"
42 #import <WebCore/RuntimeApplicationChecks.h>
43 #import <WebCore/Settings.h>
44 #import <WebCore/URLParser.h>
45 #import <wtf/RetainPtr.h>
46
47 #if PLATFORM(IOS)
48 #import "UIKitSPI.h"
49 #import <WebCore/Device.h>
50 #endif
51
52 using namespace WebCore;
53
54 template<typename T> class LazyInitialized {
55 public:
56     typedef typename WTF::GetPtrHelper<T>::PtrType PtrType;
57
58     template<typename F>
59     PtrType get(F&& f)
60     {
61         if (!m_isInitialized) {
62             m_value = f();
63             m_isInitialized = true;
64         }
65
66         return m_value.get();
67     }
68
69     void set(PtrType t)
70     {
71         m_value = t;
72         m_isInitialized = true;
73     }
74
75     void set(T&& t)
76     {
77         m_value = WTFMove(t);
78         m_isInitialized = true;
79     }
80
81     PtrType peek()
82     {
83         return m_value.get();
84     }
85
86 private:
87     bool m_isInitialized = false;
88     T m_value;
89 };
90
91 #if PLATFORM(IOS)
92
93 static _WKDragLiftDelay toDragLiftDelay(NSUInteger value)
94 {
95     if (value == _WKDragLiftDelayMedium)
96         return _WKDragLiftDelayMedium;
97     if (value == _WKDragLiftDelayLong)
98         return _WKDragLiftDelayLong;
99     return _WKDragLiftDelayShort;
100 }
101
102 #endif
103
104 @implementation WKWebViewConfiguration {
105     LazyInitialized<RetainPtr<WKProcessPool>> _processPool;
106     LazyInitialized<RetainPtr<WKPreferences>> _preferences;
107     LazyInitialized<RetainPtr<WKUserContentController>> _userContentController;
108     LazyInitialized<RetainPtr<_WKVisitedLinkStore>> _visitedLinkStore;
109     LazyInitialized<RetainPtr<WKWebsiteDataStore>> _websiteDataStore;
110     WebKit::WeakObjCPtr<WKWebView> _relatedWebView;
111     WebKit::WeakObjCPtr<WKWebView> _alternateWebViewForNavigationGestures;
112     RetainPtr<NSString> _groupIdentifier;
113     LazyInitialized<RetainPtr<NSString>> _applicationNameForUserAgent;
114     LazyInitialized<RetainPtr<NSMutableDictionary<NSString *, id <WKURLSchemeHandler>>>> _urlSchemeHandlers;
115     NSTimeInterval _incrementalRenderingSuppressionTimeout;
116     BOOL _treatsSHA1SignedCertificatesAsInsecure;
117     BOOL _respectsImageOrientation;
118     BOOL _printsBackgrounds;
119     BOOL _allowsJavaScriptMarkup;
120     BOOL _convertsPositionStyleOnCopy;
121     BOOL _allowsMetaRefresh;
122     BOOL _allowUniversalAccessFromFileURLs;
123
124 #if PLATFORM(IOS)
125     LazyInitialized<RetainPtr<WKWebViewContentProviderRegistry>> _contentProviderRegistry;
126     BOOL _alwaysRunsAtForegroundPriority;
127     BOOL _allowsInlineMediaPlayback;
128     BOOL _inlineMediaPlaybackRequiresPlaysInlineAttribute;
129     BOOL _allowsInlineMediaPlaybackAfterFullscreen;
130     BOOL _allowsBlockSelection;
131     _WKDragLiftDelay _dragLiftDelay;
132 #endif
133
134     BOOL _invisibleAutoplayNotPermitted;
135     BOOL _mediaDataLoadsAutomatically;
136     BOOL _attachmentElementEnabled;
137     BOOL _mainContentUserGestureOverrideEnabled;
138
139 #if PLATFORM(MAC)
140     BOOL _showsURLsInToolTips;
141     BOOL _serviceControlsEnabled;
142     BOOL _imageControlsEnabled;
143     BOOL _requiresUserActionForEditingControlsManager;
144 #endif
145     BOOL _initialCapitalizationEnabled;
146     BOOL _waitsForPaintAfterViewDidMoveToWindow;
147     BOOL _controlledByAutomation;
148
149 #if ENABLE(APPLE_PAY)
150     BOOL _applePayEnabled;
151 #endif
152     BOOL _needsStorageAccessFromFileURLsQuirk;
153     BOOL _legacyEncryptedMediaAPIEnabled;
154
155     RetainPtr<NSString> _overrideContentSecurityPolicy;
156     RetainPtr<NSString> _mediaContentTypesRequiringHardwareSupport;
157 }
158
159 - (instancetype)init
160 {
161     if (!(self = [super init]))
162         return nil;
163
164     WebKit::InitializeWebKit2();
165
166 #if PLATFORM(IOS)
167     _allowsPictureInPictureMediaPlayback = YES;
168     _allowsInlineMediaPlayback = WebCore::deviceClass() == MGDeviceClassiPad;
169     _inlineMediaPlaybackRequiresPlaysInlineAttribute = !_allowsInlineMediaPlayback;
170     _allowsInlineMediaPlaybackAfterFullscreen = !_allowsInlineMediaPlayback;
171     _mediaDataLoadsAutomatically = NO;
172     if (WebKit::linkedOnOrAfter(WebKit::SDKVersion::FirstWithMediaTypesRequiringUserActionForPlayback))
173         _mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeAudio;
174     else
175         _mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeAll;
176     _ignoresViewportScaleLimits = NO;
177     _legacyEncryptedMediaAPIEnabled = NO;
178 #else
179     _mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
180     _mediaDataLoadsAutomatically = YES;
181     _userInterfaceDirectionPolicy = WKUserInterfaceDirectionPolicyContent;
182     _legacyEncryptedMediaAPIEnabled = YES;
183 #endif
184     _mainContentUserGestureOverrideEnabled = NO;
185     _invisibleAutoplayNotPermitted = NO;
186     _attachmentElementEnabled = NO;
187
188 #if PLATFORM(IOS)
189     _respectsImageOrientation = YES;
190     _printsBackgrounds = YES;
191 #endif
192
193 #if PLATFORM(MAC)
194     _printsBackgrounds = NO;
195     _respectsImageOrientation = NO;
196     _showsURLsInToolTips = NO;
197     _serviceControlsEnabled = NO;
198     _imageControlsEnabled = NO;
199     _requiresUserActionForEditingControlsManager = NO;
200 #endif
201     _initialCapitalizationEnabled = YES;
202     _waitsForPaintAfterViewDidMoveToWindow = YES;
203
204 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
205     _allowsAirPlayForMediaPlayback = YES;
206 #endif
207
208     _incrementalRenderingSuppressionTimeout = 5;
209     _allowsJavaScriptMarkup = YES;
210     _convertsPositionStyleOnCopy = NO;
211     _allowsMetaRefresh = YES;
212     _allowUniversalAccessFromFileURLs = NO;
213     _treatsSHA1SignedCertificatesAsInsecure = YES;
214     _needsStorageAccessFromFileURLsQuirk = YES;
215
216 #if PLATFORM(IOS)
217     _selectionGranularity = WKSelectionGranularityDynamic;
218     _allowsBlockSelection = [[NSUserDefaults standardUserDefaults] boolForKey:@"WebKitDebugAllowBlockSelection"];
219     _dragLiftDelay = toDragLiftDelay([[NSUserDefaults standardUserDefaults] integerForKey:@"WebKitDebugDragLiftDelay"]);
220 #endif
221
222     _mediaContentTypesRequiringHardwareSupport = Settings::defaultMediaContentTypesRequiringHardwareSupport();
223
224     return self;
225 }
226
227 - (NSString *)description
228 {
229     return [NSString stringWithFormat:@"<%@: %p; processPool = %@; preferences = %@>", NSStringFromClass(self.class), self, self.processPool, self.preferences];
230 }
231
232 // FIXME: Encode the process pool, user content controller and website data store.
233
234 - (void)encodeWithCoder:(NSCoder *)coder
235 {
236     [coder encodeObject:self.processPool forKey:@"processPool"];
237     [coder encodeObject:self.preferences forKey:@"preferences"];
238     [coder encodeObject:self.userContentController forKey:@"userContentController"];
239     [coder encodeObject:self.websiteDataStore forKey:@"websiteDataStore"];
240
241     [coder encodeBool:self.suppressesIncrementalRendering forKey:@"suppressesIncrementalRendering"];
242     [coder encodeObject:self.applicationNameForUserAgent forKey:@"applicationNameForUserAgent"];
243     [coder encodeBool:self.allowsAirPlayForMediaPlayback forKey:@"allowsAirPlayForMediaPlayback"];
244
245 #if PLATFORM(IOS)
246     [coder encodeInteger:self.dataDetectorTypes forKey:@"dataDetectorTypes"];
247     [coder encodeBool:self.allowsInlineMediaPlayback forKey:@"allowsInlineMediaPlayback"];
248     [coder encodeBool:self._allowsInlineMediaPlaybackAfterFullscreen forKey:@"allowsInlineMediaPlaybackAfterFullscreen"];
249     [coder encodeBool:self.mediaTypesRequiringUserActionForPlayback forKey:@"mediaTypesRequiringUserActionForPlayback"];
250     [coder encodeInteger:self.selectionGranularity forKey:@"selectionGranularity"];
251     [coder encodeBool:self.allowsPictureInPictureMediaPlayback forKey:@"allowsPictureInPictureMediaPlayback"];
252     [coder encodeBool:self.ignoresViewportScaleLimits forKey:@"ignoresViewportScaleLimits"];
253     [coder encodeInteger:self._dragLiftDelay forKey:@"dragLiftDelay"];
254 #else
255     [coder encodeInteger:self.userInterfaceDirectionPolicy forKey:@"userInterfaceDirectionPolicy"];
256 #endif
257 }
258
259 - (instancetype)initWithCoder:(NSCoder *)coder
260 {
261     if (!(self = [self init]))
262         return nil;
263
264     self.processPool = [coder decodeObjectForKey:@"processPool"];
265     self.preferences = [coder decodeObjectForKey:@"preferences"];
266     self.userContentController = [coder decodeObjectForKey:@"userContentController"];
267     self.websiteDataStore = [coder decodeObjectForKey:@"websiteDataStore"];
268
269     self.suppressesIncrementalRendering = [coder decodeBoolForKey:@"suppressesIncrementalRendering"];
270     self.applicationNameForUserAgent = [coder decodeObjectForKey:@"applicationNameForUserAgent"];
271     self.allowsAirPlayForMediaPlayback = [coder decodeBoolForKey:@"allowsAirPlayForMediaPlayback"];
272
273 #if PLATFORM(IOS)
274     self.dataDetectorTypes = [coder decodeIntegerForKey:@"dataDetectorTypes"];
275     self.allowsInlineMediaPlayback = [coder decodeBoolForKey:@"allowsInlineMediaPlayback"];
276     self._allowsInlineMediaPlaybackAfterFullscreen = [coder decodeBoolForKey:@"allowsInlineMediaPlaybackAfterFullscreen"];
277     self.mediaTypesRequiringUserActionForPlayback = [coder decodeBoolForKey:@"mediaTypesRequiringUserActionForPlayback"];
278     self.selectionGranularity = static_cast<WKSelectionGranularity>([coder decodeIntegerForKey:@"selectionGranularity"]);
279     self.allowsPictureInPictureMediaPlayback = [coder decodeBoolForKey:@"allowsPictureInPictureMediaPlayback"];
280     self.ignoresViewportScaleLimits = [coder decodeBoolForKey:@"ignoresViewportScaleLimits"];
281     self._dragLiftDelay = toDragLiftDelay([coder decodeIntegerForKey:@"dragLiftDelay"]);
282 #else
283     auto userInterfaceDirectionPolicyCandidate = static_cast<WKUserInterfaceDirectionPolicy>([coder decodeIntegerForKey:@"userInterfaceDirectionPolicy"]);
284     if (userInterfaceDirectionPolicyCandidate == WKUserInterfaceDirectionPolicyContent || userInterfaceDirectionPolicyCandidate == WKUserInterfaceDirectionPolicySystem)
285         self.userInterfaceDirectionPolicy = userInterfaceDirectionPolicyCandidate;
286 #endif
287
288     return self;
289 }
290
291 - (id)copyWithZone:(NSZone *)zone
292 {
293     WKWebViewConfiguration *configuration = [(WKWebViewConfiguration *)[[self class] allocWithZone:zone] init];
294
295     configuration.processPool = self.processPool;
296     configuration.preferences = self.preferences;
297     configuration.userContentController = self.userContentController;
298     configuration.websiteDataStore = self.websiteDataStore;
299     configuration._visitedLinkStore = self._visitedLinkStore;
300     configuration._relatedWebView = _relatedWebView.get().get();
301     configuration._alternateWebViewForNavigationGestures = _alternateWebViewForNavigationGestures.get().get();
302     configuration->_treatsSHA1SignedCertificatesAsInsecure = _treatsSHA1SignedCertificatesAsInsecure;
303 #if PLATFORM(IOS)
304     configuration._contentProviderRegistry = self._contentProviderRegistry;
305 #endif
306
307     configuration->_suppressesIncrementalRendering = self->_suppressesIncrementalRendering;
308     configuration.applicationNameForUserAgent = self.applicationNameForUserAgent;
309
310     configuration->_respectsImageOrientation = self->_respectsImageOrientation;
311     configuration->_printsBackgrounds = self->_printsBackgrounds;
312     configuration->_incrementalRenderingSuppressionTimeout = self->_incrementalRenderingSuppressionTimeout;
313     configuration->_allowsJavaScriptMarkup = self->_allowsJavaScriptMarkup;
314     configuration->_convertsPositionStyleOnCopy = self->_convertsPositionStyleOnCopy;
315     configuration->_allowsMetaRefresh = self->_allowsMetaRefresh;
316     configuration->_allowUniversalAccessFromFileURLs = self->_allowUniversalAccessFromFileURLs;
317
318     configuration->_invisibleAutoplayNotPermitted = self->_invisibleAutoplayNotPermitted;
319     configuration->_mediaDataLoadsAutomatically = self->_mediaDataLoadsAutomatically;
320     configuration->_attachmentElementEnabled = self->_attachmentElementEnabled;
321     configuration->_mediaTypesRequiringUserActionForPlayback = self->_mediaTypesRequiringUserActionForPlayback;
322     configuration->_mainContentUserGestureOverrideEnabled = self->_mainContentUserGestureOverrideEnabled;
323     configuration->_initialCapitalizationEnabled = self->_initialCapitalizationEnabled;
324     configuration->_waitsForPaintAfterViewDidMoveToWindow = self->_waitsForPaintAfterViewDidMoveToWindow;
325     configuration->_controlledByAutomation = self->_controlledByAutomation;
326
327 #if PLATFORM(IOS)
328     configuration->_allowsInlineMediaPlayback = self->_allowsInlineMediaPlayback;
329     configuration->_allowsInlineMediaPlaybackAfterFullscreen = self->_allowsInlineMediaPlaybackAfterFullscreen;
330     configuration->_inlineMediaPlaybackRequiresPlaysInlineAttribute = self->_inlineMediaPlaybackRequiresPlaysInlineAttribute;
331     configuration->_allowsPictureInPictureMediaPlayback = self->_allowsPictureInPictureMediaPlayback;
332     configuration->_alwaysRunsAtForegroundPriority = _alwaysRunsAtForegroundPriority;
333     configuration->_selectionGranularity = self->_selectionGranularity;
334     configuration->_allowsBlockSelection = self->_allowsBlockSelection;
335     configuration->_ignoresViewportScaleLimits = self->_ignoresViewportScaleLimits;
336     configuration->_dragLiftDelay = self->_dragLiftDelay;
337 #endif
338 #if PLATFORM(MAC)
339     configuration->_userInterfaceDirectionPolicy = self->_userInterfaceDirectionPolicy;
340     configuration->_showsURLsInToolTips = self->_showsURLsInToolTips;
341     configuration->_serviceControlsEnabled = self->_serviceControlsEnabled;
342     configuration->_imageControlsEnabled = self->_imageControlsEnabled;
343     configuration->_requiresUserActionForEditingControlsManager = self->_requiresUserActionForEditingControlsManager;
344 #endif
345 #if ENABLE(DATA_DETECTION) && PLATFORM(IOS)
346     configuration->_dataDetectorTypes = self->_dataDetectorTypes;
347 #endif
348 #if ENABLE(WIRELESS_TARGET_PLAYBACK)
349     configuration->_allowsAirPlayForMediaPlayback = self->_allowsAirPlayForMediaPlayback;
350 #endif
351 #if ENABLE(APPLE_PAY)
352     configuration->_applePayEnabled = self->_applePayEnabled;
353 #endif
354     configuration->_needsStorageAccessFromFileURLsQuirk = self->_needsStorageAccessFromFileURLsQuirk;
355     configuration->_overrideContentSecurityPolicy = adoptNS([self->_overrideContentSecurityPolicy copyWithZone:zone]);
356
357     configuration->_urlSchemeHandlers.set(adoptNS([self._urlSchemeHandlers mutableCopyWithZone:zone]));
358     configuration->_mediaContentTypesRequiringHardwareSupport = adoptNS([self._mediaContentTypesRequiringHardwareSupport copyWithZone:zone]);
359     configuration->_legacyEncryptedMediaAPIEnabled = self->_legacyEncryptedMediaAPIEnabled;
360
361     return configuration;
362 }
363
364 - (WKProcessPool *)processPool
365 {
366     return _processPool.get([] { return adoptNS([[WKProcessPool alloc] init]); });
367 }
368
369 - (void)setProcessPool:(WKProcessPool *)processPool
370 {
371     _processPool.set(processPool);
372 }
373
374 - (WKPreferences *)preferences
375 {
376     return _preferences.get([] { return adoptNS([[WKPreferences alloc] init]); });
377 }
378
379 - (void)setPreferences:(WKPreferences *)preferences
380 {
381     _preferences.set(preferences);
382 }
383
384 - (WKUserContentController *)userContentController
385 {
386     return _userContentController.get([] { return adoptNS([[WKUserContentController alloc] init]); });
387 }
388
389 - (void)setUserContentController:(WKUserContentController *)userContentController
390 {
391     _userContentController.set(userContentController);
392 }
393
394 - (WKWebsiteDataStore *)websiteDataStore
395 {
396     return _websiteDataStore.get([] { return [WKWebsiteDataStore defaultDataStore]; });
397 }
398
399 - (void)setWebsiteDataStore:(WKWebsiteDataStore *)websiteDataStore
400 {
401     _websiteDataStore.set(websiteDataStore);
402 }
403
404 static NSString *defaultApplicationNameForUserAgent()
405 {
406 #if PLATFORM(IOS)
407     return [@"Mobile/" stringByAppendingString:[UIDevice currentDevice].buildVersion];
408 #else
409     return nil;
410 #endif
411 }
412
413 - (NSString *)applicationNameForUserAgent
414 {
415     return _applicationNameForUserAgent.get([] { return defaultApplicationNameForUserAgent(); });
416 }
417
418 - (void)setApplicationNameForUserAgent:(NSString *)applicationNameForUserAgent
419 {
420     _applicationNameForUserAgent.set(adoptNS([applicationNameForUserAgent copy]));
421 }
422
423 - (_WKVisitedLinkStore *)_visitedLinkStore
424 {
425     return _visitedLinkStore.get([] { return adoptNS([[_WKVisitedLinkStore alloc] init]); });
426 }
427
428 - (void)_setVisitedLinkStore:(_WKVisitedLinkStore *)visitedLinkStore
429 {
430     _visitedLinkStore.set(visitedLinkStore);
431 }
432
433 - (void)setURLSchemeHandler:(id <WKURLSchemeHandler>)urlSchemeHandler forURLScheme:(NSString *)urlScheme
434 {
435     auto *urlSchemeHandlers = _urlSchemeHandlers.get([] { return adoptNS([[NSMutableDictionary alloc] init]); });
436
437     if ([WKWebView handlesURLScheme:urlScheme])
438         [NSException raise:NSInvalidArgumentException format:@"'%@' is a URL scheme that WKWebView handles natively", urlScheme];
439
440     auto canonicalScheme = WebCore::URLParser::maybeCanonicalizeScheme(urlScheme);
441     if (!canonicalScheme)
442         [NSException raise:NSInvalidArgumentException format:@"'%@' is not a valid URL scheme", urlScheme];
443
444     if ([urlSchemeHandlers objectForKey:(NSString *)canonicalScheme.value()])
445         [NSException raise:NSInvalidArgumentException format:@"URL scheme '%@' already has a registered URL scheme handler", urlScheme];
446
447     [urlSchemeHandlers setObject:urlSchemeHandler forKey:(NSString *)canonicalScheme.value()];
448 }
449
450 - (nullable id <WKURLSchemeHandler>)urlSchemeHandlerForURLScheme:(NSString *)urlScheme
451 {
452     auto canonicalScheme = WebCore::URLParser::maybeCanonicalizeScheme(urlScheme);
453     if (!canonicalScheme)
454         return nil;
455
456     auto *urlSchemeHandlers = _urlSchemeHandlers.get([] { return adoptNS([[NSMutableDictionary alloc] init]); });
457     return [urlSchemeHandlers objectForKey:(NSString *)canonicalScheme.value()];
458 }
459
460 #pragma clang diagnostic push
461 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
462
463 - (_WKWebsiteDataStore *)_websiteDataStore
464 {
465     return self.websiteDataStore ? adoptNS([[_WKWebsiteDataStore alloc] initWithDataStore:self.websiteDataStore]).autorelease() : nullptr;
466 }
467
468 - (void)_setWebsiteDataStore:(_WKWebsiteDataStore *)websiteDataStore
469 {
470     self.websiteDataStore = websiteDataStore ? websiteDataStore->_dataStore.get() : nullptr;
471 }
472
473 #pragma clang diagnostic pop
474
475 - (NSMutableDictionary<NSString *, id <WKURLSchemeHandler>> *)_urlSchemeHandlers
476 {
477     return _urlSchemeHandlers.get([] { return adoptNS([[NSMutableDictionary alloc] init]); });
478 }
479
480 #if PLATFORM(IOS)
481 - (WKWebViewContentProviderRegistry *)_contentProviderRegistry
482 {
483     return _contentProviderRegistry.get([] { return adoptNS([[WKWebViewContentProviderRegistry alloc] init]); });
484 }
485
486 - (void)_setContentProviderRegistry:(WKWebViewContentProviderRegistry *)registry
487 {
488     _contentProviderRegistry.set(registry);
489 }
490 #endif
491
492 - (void)_validate
493 {
494     if (!self.processPool)
495         [NSException raise:NSInvalidArgumentException format:@"configuration.processPool is nil"];
496
497     if (!self.preferences)
498         [NSException raise:NSInvalidArgumentException format:@"configuration.preferences is nil"];
499
500     if (!self.userContentController)
501         [NSException raise:NSInvalidArgumentException format:@"configuration.userContentController is nil"];
502
503     if (!self.websiteDataStore)
504         [NSException raise:NSInvalidArgumentException format:@"configuration.websiteDataStore is nil"];
505
506     if (!self._visitedLinkStore)
507         [NSException raise:NSInvalidArgumentException format:@"configuration._visitedLinkStore is nil"];
508
509 #if PLATFORM(IOS)
510     if (!self._contentProviderRegistry)
511         [NSException raise:NSInvalidArgumentException format:@"configuration._contentProviderRegistry is nil"];
512 #endif
513 }
514
515 @end
516
517 @implementation WKWebViewConfiguration (WKPrivate)
518
519 - (WKWebView *)_relatedWebView
520 {
521     return _relatedWebView.getAutoreleased();
522 }
523
524 - (void)_setRelatedWebView:(WKWebView *)relatedWebView
525 {
526     _relatedWebView = relatedWebView;
527 }
528
529 - (WKWebView *)_alternateWebViewForNavigationGestures
530 {
531     return _alternateWebViewForNavigationGestures.getAutoreleased();
532 }
533
534 - (void)_setAlternateWebViewForNavigationGestures:(WKWebView *)alternateView
535 {
536     _alternateWebViewForNavigationGestures = alternateView;
537 }
538
539 - (NSString *)_groupIdentifier
540 {
541     return _groupIdentifier.get();
542 }
543
544 - (void)_setGroupIdentifier:(NSString *)groupIdentifier
545 {
546     _groupIdentifier = groupIdentifier;
547 }
548
549 - (BOOL)_treatsSHA1SignedCertificatesAsInsecure
550 {
551     return _treatsSHA1SignedCertificatesAsInsecure;
552 }
553
554 - (void)_setTreatsSHA1SignedCertificatesAsInsecure:(BOOL)insecure
555 {
556     _treatsSHA1SignedCertificatesAsInsecure = insecure;
557 }
558
559 - (BOOL)_respectsImageOrientation
560 {
561     return _respectsImageOrientation;
562 }
563
564 - (void)_setRespectsImageOrientation:(BOOL)respectsImageOrientation
565 {
566     _respectsImageOrientation = respectsImageOrientation;
567 }
568
569 - (BOOL)_printsBackgrounds
570 {
571     return _printsBackgrounds;
572 }
573
574 - (void)_setPrintsBackgrounds:(BOOL)printsBackgrounds
575 {
576     _printsBackgrounds = printsBackgrounds;
577 }
578
579 - (NSTimeInterval)_incrementalRenderingSuppressionTimeout
580 {
581     return _incrementalRenderingSuppressionTimeout;
582 }
583
584 - (void)_setIncrementalRenderingSuppressionTimeout:(NSTimeInterval)incrementalRenderingSuppressionTimeout
585 {
586     _incrementalRenderingSuppressionTimeout = incrementalRenderingSuppressionTimeout;
587 }
588
589 - (BOOL)_allowsJavaScriptMarkup
590 {
591     return _allowsJavaScriptMarkup;
592 }
593
594 - (void)_setAllowsJavaScriptMarkup:(BOOL)allowsJavaScriptMarkup
595 {
596     _allowsJavaScriptMarkup = allowsJavaScriptMarkup;
597 }
598
599 - (BOOL)_allowUniversalAccessFromFileURLs
600 {
601     return _allowUniversalAccessFromFileURLs;
602 }
603
604 - (void)_setAllowUniversalAccessFromFileURLs:(BOOL)allowUniversalAccessFromFileURLs
605 {
606     _allowUniversalAccessFromFileURLs = allowUniversalAccessFromFileURLs;
607 }
608
609 - (BOOL)_convertsPositionStyleOnCopy
610 {
611     return _convertsPositionStyleOnCopy;
612 }
613
614 - (void)_setConvertsPositionStyleOnCopy:(BOOL)convertsPositionStyleOnCopy
615 {
616     _convertsPositionStyleOnCopy = convertsPositionStyleOnCopy;
617 }
618
619 - (BOOL)_allowsMetaRefresh
620 {
621     return _allowsMetaRefresh;
622 }
623
624 - (void)_setAllowsMetaRefresh:(BOOL)allowsMetaRefresh
625 {
626     _allowsMetaRefresh = allowsMetaRefresh;
627 }
628
629 #if PLATFORM(IOS)
630 - (BOOL)_alwaysRunsAtForegroundPriority
631 {
632     return _alwaysRunsAtForegroundPriority;
633 }
634
635 - (void)_setAlwaysRunsAtForegroundPriority:(BOOL)alwaysRunsAtForegroundPriority
636 {
637     _alwaysRunsAtForegroundPriority = alwaysRunsAtForegroundPriority;
638 }
639
640 - (BOOL)_inlineMediaPlaybackRequiresPlaysInlineAttribute
641 {
642     return _inlineMediaPlaybackRequiresPlaysInlineAttribute;
643 }
644
645 - (void)_setInlineMediaPlaybackRequiresPlaysInlineAttribute:(BOOL)requires
646 {
647     _inlineMediaPlaybackRequiresPlaysInlineAttribute = requires;
648 }
649
650 - (BOOL)_allowsInlineMediaPlaybackAfterFullscreen
651 {
652     return _allowsInlineMediaPlaybackAfterFullscreen;
653 }
654
655 - (void)_setAllowsInlineMediaPlaybackAfterFullscreen:(BOOL)allows
656 {
657     _allowsInlineMediaPlaybackAfterFullscreen = allows;
658 }
659
660 - (BOOL)_allowsBlockSelection
661 {
662     return _allowsBlockSelection;
663 }
664
665 - (void)_setAllowsBlockSelection:(BOOL)allowsBlockSelection
666 {
667     _allowsBlockSelection = allowsBlockSelection;
668 }
669
670 - (_WKDragLiftDelay)_dragLiftDelay
671 {
672     return _dragLiftDelay;
673 }
674
675 - (void)_setDragLiftDelay:(_WKDragLiftDelay)dragLiftDelay
676 {
677     _dragLiftDelay = dragLiftDelay;
678 }
679 #endif // PLATFORM(IOS)
680
681 - (BOOL)_invisibleAutoplayNotPermitted
682 {
683     return _invisibleAutoplayNotPermitted;
684 }
685
686 - (void)_setInvisibleAutoplayNotPermitted:(BOOL)notPermitted
687 {
688     _invisibleAutoplayNotPermitted = notPermitted;
689 }
690
691 - (BOOL)_mediaDataLoadsAutomatically
692 {
693     return _mediaDataLoadsAutomatically;
694 }
695
696 - (void)_setMediaDataLoadsAutomatically:(BOOL)mediaDataLoadsAutomatically
697 {
698     _mediaDataLoadsAutomatically = mediaDataLoadsAutomatically;
699 }
700
701 - (BOOL)_attachmentElementEnabled
702 {
703     return _attachmentElementEnabled;
704 }
705
706 - (void)_setAttachmentElementEnabled:(BOOL)attachmentElementEnabled
707 {
708     _attachmentElementEnabled = attachmentElementEnabled;
709 }
710
711 - (BOOL)_requiresUserActionForVideoPlayback
712 {
713     return self.mediaTypesRequiringUserActionForPlayback & WKAudiovisualMediaTypeVideo;
714 }
715
716 - (void)_setRequiresUserActionForVideoPlayback:(BOOL)requiresUserActionForVideoPlayback
717 {
718     if (requiresUserActionForVideoPlayback)
719         self.mediaTypesRequiringUserActionForPlayback |= WKAudiovisualMediaTypeVideo;
720     else
721         self.mediaTypesRequiringUserActionForPlayback &= ~WKAudiovisualMediaTypeVideo;
722 }
723
724 - (BOOL)_requiresUserActionForAudioPlayback
725 {
726     return self.mediaTypesRequiringUserActionForPlayback & WKAudiovisualMediaTypeAudio;
727 }
728
729 - (void)_setRequiresUserActionForAudioPlayback:(BOOL)requiresUserActionForAudioPlayback
730 {
731     if (requiresUserActionForAudioPlayback)
732         self.mediaTypesRequiringUserActionForPlayback |= WKAudiovisualMediaTypeAudio;
733     else
734         self.mediaTypesRequiringUserActionForPlayback &= ~WKAudiovisualMediaTypeAudio;
735 }
736
737 - (BOOL)_mainContentUserGestureOverrideEnabled
738 {
739     return _mainContentUserGestureOverrideEnabled;
740 }
741
742 - (void)_setMainContentUserGestureOverrideEnabled:(BOOL)mainContentUserGestureOverrideEnabled
743 {
744     _mainContentUserGestureOverrideEnabled = mainContentUserGestureOverrideEnabled;
745 }
746
747 - (BOOL)_initialCapitalizationEnabled
748 {
749     return _initialCapitalizationEnabled;
750 }
751
752 - (void)_setInitialCapitalizationEnabled:(BOOL)initialCapitalizationEnabled
753 {
754     _initialCapitalizationEnabled = initialCapitalizationEnabled;
755 }
756
757 - (BOOL)_waitsForPaintAfterViewDidMoveToWindow
758 {
759     return _waitsForPaintAfterViewDidMoveToWindow;
760 }
761
762 - (void)_setWaitsForPaintAfterViewDidMoveToWindow:(BOOL)shouldSynchronize
763 {
764     _waitsForPaintAfterViewDidMoveToWindow = shouldSynchronize;
765 }
766
767 - (BOOL)_isControlledByAutomation
768 {
769     return _controlledByAutomation;
770 }
771
772 - (void)_setControlledByAutomation:(BOOL)controlledByAutomation
773 {
774     _controlledByAutomation = controlledByAutomation;
775 }
776
777 #if PLATFORM(MAC)
778 - (BOOL)_showsURLsInToolTips
779 {
780     return _showsURLsInToolTips;
781 }
782
783 - (void)_setShowsURLsInToolTips:(BOOL)showsURLsInToolTips
784 {
785     _showsURLsInToolTips = showsURLsInToolTips;
786 }
787
788 - (BOOL)_serviceControlsEnabled
789 {
790     return _serviceControlsEnabled;
791 }
792
793 - (void)_setServiceControlsEnabled:(BOOL)serviceControlsEnabled
794 {
795     _serviceControlsEnabled = serviceControlsEnabled;
796 }
797
798 - (BOOL)_imageControlsEnabled
799 {
800     return _imageControlsEnabled;
801 }
802
803 - (void)_setImageControlsEnabled:(BOOL)imageControlsEnabled
804 {
805     _imageControlsEnabled = imageControlsEnabled;
806 }
807
808 - (BOOL)_requiresUserActionForEditingControlsManager
809 {
810     return _requiresUserActionForEditingControlsManager;
811 }
812
813 - (void)_setRequiresUserActionForEditingControlsManager:(BOOL)requiresUserAction
814 {
815     _requiresUserActionForEditingControlsManager = requiresUserAction;
816 }
817
818 #endif // PLATFORM(MAC)
819
820 - (BOOL)_applePayEnabled
821 {
822 #if ENABLE(APPLE_PAY)
823     return _applePayEnabled;
824 #else
825     return NO;
826 #endif
827 }
828
829 - (void)_setApplePayEnabled:(BOOL)applePayEnabled
830 {
831 #if ENABLE(APPLE_PAY)
832     _applePayEnabled = applePayEnabled;
833 #endif
834 }
835
836 - (BOOL)_needsStorageAccessFromFileURLsQuirk
837 {
838     return _needsStorageAccessFromFileURLsQuirk;
839 }
840
841 - (void)_setNeedsStorageAccessFromFileURLsQuirk:(BOOL)needsLocalStorageQuirk
842 {
843     _needsStorageAccessFromFileURLsQuirk = needsLocalStorageQuirk;
844 }
845
846 - (NSString *)_overrideContentSecurityPolicy
847 {
848     return _overrideContentSecurityPolicy.get();
849 }
850
851 - (void)_setOverrideContentSecurityPolicy:(NSString *)overrideContentSecurityPolicy
852 {
853     _overrideContentSecurityPolicy = adoptNS([overrideContentSecurityPolicy copy]);
854 }
855
856 - (NSString *)_mediaContentTypesRequiringHardwareSupport
857 {
858     return _mediaContentTypesRequiringHardwareSupport.get();
859 }
860
861 - (void)_setMediaContentTypesRequiringHardwareSupport:(NSString *)mediaContentTypesRequiringHardwareSupport
862 {
863     _mediaContentTypesRequiringHardwareSupport = adoptNS([mediaContentTypesRequiringHardwareSupport copy]);
864 }
865
866 - (void)_setLegacyEncryptedMediaAPIEnabled:(BOOL)enabled
867 {
868     _legacyEncryptedMediaAPIEnabled = enabled;
869 }
870
871 - (BOOL)_legacyEncryptedMediaAPIEnabled
872 {
873     return _legacyEncryptedMediaAPIEnabled;
874 }
875
876 @end
877
878 @implementation WKWebViewConfiguration (WKDeprecated)
879
880 #if PLATFORM(IOS)
881 - (BOOL)mediaPlaybackAllowsAirPlay
882 {
883     return self.allowsAirPlayForMediaPlayback;
884 }
885
886 - (void)setMediaPlaybackAllowsAirPlay:(BOOL)allowed
887 {
888     self.allowsAirPlayForMediaPlayback = allowed;
889 }
890
891 - (BOOL)mediaPlaybackRequiresUserAction
892 {
893     return self.requiresUserActionForMediaPlayback;
894 }
895
896 - (void)setMediaPlaybackRequiresUserAction:(BOOL)required
897 {
898     self.requiresUserActionForMediaPlayback = required;
899 }
900
901 - (BOOL)requiresUserActionForMediaPlayback
902 {
903     return self.mediaTypesRequiringUserActionForPlayback == WKAudiovisualMediaTypeAll;
904 }
905
906 - (void)setRequiresUserActionForMediaPlayback:(BOOL)requiresUserActionForMediaPlayback
907 {
908     self.mediaTypesRequiringUserActionForPlayback = requiresUserActionForMediaPlayback ? WKAudiovisualMediaTypeAll : WKAudiovisualMediaTypeNone;
909 }
910
911 #endif // PLATFORM(IOS)
912
913 @end
914
915 @implementation WKWebViewConfiguration (WKBinaryCompatibilityWithIOS10)
916
917 -(_WKVisitedLinkStore *)_visitedLinkProvider
918 {
919     return self._visitedLinkStore;
920 }
921
922 - (void)_setVisitedLinkProvider:(_WKVisitedLinkStore *)visitedLinkProvider
923 {
924     self._visitedLinkStore = visitedLinkProvider;
925 }
926
927 @end
928
929 #endif // WK_API_ENABLED