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