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