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