Expose a way for MiniBrowser to simulate header and footer banners
[WebKit-https.git] / Tools / MiniBrowser / mac / SettingsController.m
1 /*
2  * Copyright (C) 2014-2016 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #import "SettingsController.h"
27
28 #import "AppDelegate.h"
29 #import "BrowserWindowController.h"
30 #import <WebKit/WKPreferencesPrivate.h>
31
32 #if WK_API_ENABLED
33 #import <WebKit/_WKExperimentalFeature.h>
34 #endif
35
36 static NSString * const defaultURL = @"http://www.webkit.org/";
37 static NSString * const DefaultURLPreferenceKey = @"DefaultURL";
38
39 static NSString * const UseWebKit2ByDefaultPreferenceKey = @"UseWebKit2ByDefault";
40 static NSString * const LayerBordersVisiblePreferenceKey = @"LayerBordersVisible";
41 static NSString * const SimpleLineLayoutDebugBordersEnabledPreferenceKey = @"SimpleLineLayoutDebugBordersEnabled";
42 static NSString * const TiledScrollingIndicatorVisiblePreferenceKey = @"TiledScrollingIndicatorVisible";
43 static NSString * const ReserveSpaceForBannersPreferenceKey = @"ReserveSpaceForBanners";
44
45 static NSString * const ResourceUsageOverlayVisiblePreferenceKey = @"ResourceUsageOverlayVisible";
46 static NSString * const LoadsAllSiteIconsKey = @"LoadsAllSiteIcons";
47 static NSString * const UsesGameControllerFrameworkKey = @"UsesGameControllerFramework";
48 static NSString * const IncrementalRenderingSuppressedPreferenceKey = @"IncrementalRenderingSuppressed";
49 static NSString * const AcceleratedDrawingEnabledPreferenceKey = @"AcceleratedDrawingEnabled";
50 static NSString * const DisplayListDrawingEnabledPreferenceKey = @"DisplayListDrawingEnabled";
51 static NSString * const ResourceLoadStatisticsEnabledPreferenceKey = @"ResourceLoadStatisticsEnabled";
52
53 static NSString * const NonFastScrollableRegionOverlayVisiblePreferenceKey = @"NonFastScrollableRegionOverlayVisible";
54 static NSString * const WheelEventHandlerRegionOverlayVisiblePreferenceKey = @"WheelEventHandlerRegionOverlayVisible";
55
56 static NSString * const UseTransparentWindowsPreferenceKey = @"UseTransparentWindows";
57 static NSString * const UsePaginatedModePreferenceKey = @"UsePaginatedMode";
58 static NSString * const EnableSubPixelCSSOMMetricsPreferenceKey = @"EnableSubPixelCSSOMMetrics";
59
60 static NSString * const VisualViewportEnabledPreferenceKey = @"VisualViewportEnabled";
61 static NSString * const LargeImageAsyncDecodingEnabledPreferenceKey = @"LargeImageAsyncDecodingEnabled";
62 static NSString * const AnimatedImageAsyncDecodingEnabledPreferenceKey = @"AnimatedImageAsyncDecodingEnabled";
63
64 // This default name intentionally overlaps with the key that WebKit2 checks when creating a view.
65 static NSString * const UseRemoteLayerTreeDrawingAreaPreferenceKey = @"WebKit2UseRemoteLayerTreeDrawingArea";
66
67 static NSString * const PerWindowWebProcessesDisabledKey = @"PerWindowWebProcessesDisabled";
68 static NSString * const NetworkCacheSpeculativeRevalidationDisabledKey = @"NetworkCacheSpeculativeRevalidationDisabled";
69
70 typedef NS_ENUM(NSInteger, DebugOverylayMenuItemTag) {
71     NonFastScrollableRegionOverlayTag = 100,
72     WheelEventHandlerRegionOverlayTag,
73 #if WK_API_ENABLED
74     ExperimentalFeatureTag,
75 #endif
76 };
77
78 @implementation SettingsController
79
80 @synthesize menu=_menu;
81
82 + (instancetype)shared
83 {
84     static SettingsController *sharedSettingsController;
85     static dispatch_once_t onceToken;
86     dispatch_once(&onceToken, ^{
87         sharedSettingsController = [[super alloc] init];
88     });
89
90     return sharedSettingsController;
91 }
92
93 - (NSMenu *)menu
94 {
95     if (!_menu)
96         [self _populateMenu];
97
98     return _menu;
99 }
100
101 - (void)_addItemWithTitle:(NSString *)title action:(SEL)action indented:(BOOL)indented
102 {
103     NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:title action:action keyEquivalent:@""];
104     [item setTarget:self];
105     if (indented)
106         [item setIndentationLevel:1];
107     [_menu addItem:item];
108     [item release];
109 }
110
111 - (void)_addHeaderWithTitle:(NSString *)title
112 {
113     [_menu addItem:[NSMenuItem separatorItem]];
114     [_menu addItem:[[[NSMenuItem alloc] initWithTitle:title action:nil keyEquivalent:@""] autorelease]];
115 }
116
117 - (void)_populateMenu
118 {
119     _menu = [[NSMenu alloc] initWithTitle:@"Settings"];
120
121     [self _addItemWithTitle:@"Use WebKit2 By Default" action:@selector(toggleUseWebKit2ByDefault:) indented:NO];
122     [self _addItemWithTitle:@"Set Default URL to Current URL" action:@selector(setDefaultURLToCurrentURL:) indented:NO];
123
124     [_menu addItem:[NSMenuItem separatorItem]];
125
126     [self _addItemWithTitle:@"Use Transparent Windows" action:@selector(toggleUseTransparentWindows:) indented:NO];
127     [self _addItemWithTitle:@"Use Paginated Mode" action:@selector(toggleUsePaginatedMode:) indented:NO];
128     [self _addItemWithTitle:@"Show Layer Borders" action:@selector(toggleShowLayerBorders:) indented:NO];
129     [self _addItemWithTitle:@"Show Simple Line Layout Borders" action:@selector(toggleSimpleLineLayoutDebugBordersEnabled:) indented:NO];
130     [self _addItemWithTitle:@"Suppress Incremental Rendering in New Windows" action:@selector(toggleIncrementalRenderingSuppressed:) indented:NO];
131     [self _addItemWithTitle:@"Enable Accelerated Drawing" action:@selector(toggleAcceleratedDrawingEnabled:) indented:NO];
132     [self _addItemWithTitle:@"Enable Display List Drawing" action:@selector(toggleDisplayListDrawingEnabled:) indented:NO];
133     [self _addItemWithTitle:@"Enable Visual Viewport" action:@selector(toggleVisualViewportEnabled:) indented:NO];
134     [self _addItemWithTitle:@"Enable Resource Load Statistics" action:@selector(toggleResourceLoadStatisticsEnabled:) indented:NO];
135     [self _addItemWithTitle:@"Enable Large Image Async Decoding" action:@selector(toggleLargeImageAsyncDecodingEnabled:) indented:NO];
136     [self _addItemWithTitle:@"Enable Animated Image Async Decoding" action:@selector(toggleAnimatedImageAsyncDecodingEnabled:) indented:NO];
137
138     [self _addHeaderWithTitle:@"WebKit2-only Settings"];
139
140     [self _addItemWithTitle:@"Reserve Space For Banners" action:@selector(toggleReserveSpaceForBanners:) indented:YES];
141     [self _addItemWithTitle:@"Show Tiled Scrolling Indicator" action:@selector(toggleShowTiledScrollingIndicator:) indented:YES];
142     [self _addItemWithTitle:@"Use UI-Side Compositing" action:@selector(toggleUseUISideCompositing:) indented:YES];
143     [self _addItemWithTitle:@"Disable Per-Window Web Processes" action:@selector(togglePerWindowWebProcessesDisabled:) indented:YES];
144     [self _addItemWithTitle:@"Show Resource Usage Overlay" action:@selector(toggleShowResourceUsageOverlay:) indented:YES];
145     [self _addItemWithTitle:@"Load All Site Icons Per-Page" action:@selector(toggleLoadsAllSiteIcons:) indented:YES];
146     [self _addItemWithTitle:@"Use GameController.framework on macOS (Restart required)" action:@selector(toggleUsesGameControllerFramework:) indented:YES];
147     [self _addItemWithTitle:@"Disable network cache speculative revalidation" action:@selector(toggleNetworkCacheSpeculativeRevalidationDisabled:) indented:YES];
148
149     NSMenuItem *debugOverlaysSubmenuItem = [[NSMenuItem alloc] initWithTitle:@"Debug Overlays" action:nil keyEquivalent:@""];
150     NSMenu *debugOverlaysMenu = [[NSMenu alloc] initWithTitle:@"Debug Overlays"];
151     [debugOverlaysSubmenuItem setSubmenu:debugOverlaysMenu];
152
153     NSMenuItem *nonFastScrollableRegionItem = [[NSMenuItem alloc] initWithTitle:@"Non-fast Scrollable Region" action:@selector(toggleDebugOverlay:) keyEquivalent:@""];
154     [nonFastScrollableRegionItem setTag:NonFastScrollableRegionOverlayTag];
155     [nonFastScrollableRegionItem setTarget:self];
156     [debugOverlaysMenu addItem:[nonFastScrollableRegionItem autorelease]];
157
158     NSMenuItem *wheelEventHandlerRegionItem = [[NSMenuItem alloc] initWithTitle:@"Wheel Event Handler Region" action:@selector(toggleDebugOverlay:) keyEquivalent:@""];
159     [wheelEventHandlerRegionItem setTag:WheelEventHandlerRegionOverlayTag];
160     [wheelEventHandlerRegionItem setTarget:self];
161     [debugOverlaysMenu addItem:[wheelEventHandlerRegionItem autorelease]];
162     [debugOverlaysMenu release];
163     
164     [_menu addItem:debugOverlaysSubmenuItem];
165     [debugOverlaysSubmenuItem release];
166
167 #if WK_API_ENABLED
168     NSMenuItem *experimentalFeaturesSubmenuItem = [[NSMenuItem alloc] initWithTitle:@"Experimental Features" action:nil keyEquivalent:@""];
169     NSMenu *experimentalFeaturesMenu = [[NSMenu alloc] initWithTitle:@"Experimental Features"];
170     [experimentalFeaturesSubmenuItem setSubmenu:experimentalFeaturesMenu];
171
172     NSArray<_WKExperimentalFeature *> *features = [WKPreferences _experimentalFeatures];
173
174     for (_WKExperimentalFeature *feature in features) {
175         NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:feature.name action:@selector(toggleExperimentalFeature:) keyEquivalent:@""];
176         item.representedObject = feature;
177
178         [item setTag:ExperimentalFeatureTag];
179         [item setTarget:self];
180         [experimentalFeaturesMenu addItem:[item autorelease]];
181     }
182
183     [_menu addItem:experimentalFeaturesSubmenuItem];
184     [experimentalFeaturesSubmenuItem release];
185 #endif // WK_API_ENABLED
186
187     [self _addHeaderWithTitle:@"WebKit1-only Settings"];
188     [self _addItemWithTitle:@"Enable Subpixel CSSOM Metrics" action:@selector(toggleEnableSubPixelCSSOMMetrics:) indented:YES];
189 }
190
191 - (BOOL)validateMenuItem:(NSMenuItem *)menuItem
192 {
193     SEL action = [menuItem action];
194
195     if (action == @selector(toggleUseWebKit2ByDefault:))
196         [menuItem setState:[self useWebKit2ByDefault] ? NSOnState : NSOffState];
197     else if (action == @selector(toggleUseTransparentWindows:))
198         [menuItem setState:[self useTransparentWindows] ? NSOnState : NSOffState];
199     else if (action == @selector(toggleUsePaginatedMode:))
200         [menuItem setState:[self usePaginatedMode] ? NSOnState : NSOffState];
201     else if (action == @selector(toggleShowLayerBorders:))
202         [menuItem setState:[self layerBordersVisible] ? NSOnState : NSOffState];
203     else if (action == @selector(toggleSimpleLineLayoutDebugBordersEnabled:))
204         [menuItem setState:[self simpleLineLayoutDebugBordersEnabled] ? NSOnState : NSOffState];
205     else if (action == @selector(toggleIncrementalRenderingSuppressed:))
206         [menuItem setState:[self incrementalRenderingSuppressed] ? NSOnState : NSOffState];
207     else if (action == @selector(toggleAcceleratedDrawingEnabled:))
208         [menuItem setState:[self acceleratedDrawingEnabled] ? NSOnState : NSOffState];
209     else if (action == @selector(toggleDisplayListDrawingEnabled:))
210         [menuItem setState:[self displayListDrawingEnabled] ? NSOnState : NSOffState];
211     else if (action == @selector(toggleResourceLoadStatisticsEnabled:))
212         [menuItem setState:[self resourceLoadStatisticsEnabled] ? NSOnState : NSOffState];
213     else if (action == @selector(toggleLargeImageAsyncDecodingEnabled:))
214         [menuItem setState:[self largeImageAsyncDecodingEnabled] ? NSOnState : NSOffState];
215     else if (action == @selector(toggleAnimatedImageAsyncDecodingEnabled:))
216         [menuItem setState:[self animatedImageAsyncDecodingEnabled] ? NSOnState : NSOffState];
217     else if (action == @selector(toggleVisualViewportEnabled:))
218         [menuItem setState:[self visualViewportEnabled] ? NSOnState : NSOffState];
219     else if (action == @selector(toggleReserveSpaceForBanners:))
220         [menuItem setState:[self isSpaceReservedForBanners] ? NSOnState : NSOffState];
221     else if (action == @selector(toggleShowTiledScrollingIndicator:))
222         [menuItem setState:[self tiledScrollingIndicatorVisible] ? NSOnState : NSOffState];
223     else if (action == @selector(toggleShowResourceUsageOverlay:))
224         [menuItem setState:[self resourceUsageOverlayVisible] ? NSOnState : NSOffState];
225     else if (action == @selector(toggleLoadsAllSiteIcons:))
226         [menuItem setState:[self loadsAllSiteIcons] ? NSOnState : NSOffState];
227     else if (action == @selector(toggleUsesGameControllerFramework:))
228         [menuItem setState:[self usesGameControllerFramework] ? NSOnState : NSOffState];
229     else if (action == @selector(toggleNetworkCacheSpeculativeRevalidationDisabled:))
230         [menuItem setState:[self networkCacheSpeculativeRevalidationDisabled] ? NSOnState : NSOffState];
231     else if (action == @selector(toggleUseUISideCompositing:))
232         [menuItem setState:[self useUISideCompositing] ? NSOnState : NSOffState];
233     else if (action == @selector(togglePerWindowWebProcessesDisabled:))
234         [menuItem setState:[self perWindowWebProcessesDisabled] ? NSOnState : NSOffState];
235     else if (action == @selector(toggleEnableSubPixelCSSOMMetrics:))
236         [menuItem setState:[self subPixelCSSOMMetricsEnabled] ? NSOnState : NSOffState];
237     else if (action == @selector(toggleDebugOverlay:))
238         [menuItem setState:[self debugOverlayVisible:menuItem] ? NSOnState : NSOffState];
239
240 #if WK_API_ENABLED
241     if (menuItem.tag == ExperimentalFeatureTag) {
242         _WKExperimentalFeature *feature = menuItem.representedObject;
243         [menuItem setState:[defaultPreferences() _isEnabledForFeature:feature] ? NSOnState : NSOffState];
244     }
245 #endif
246
247     return YES;
248 }
249
250 - (void)_toggleBooleanDefault:(NSString *)defaultName
251 {
252     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
253     [defaults setBool:![defaults boolForKey:defaultName] forKey:defaultName];
254
255     [(BrowserAppDelegate *)[[NSApplication sharedApplication] delegate] didChangeSettings];
256 }
257
258 - (void)toggleUseWebKit2ByDefault:(id)sender
259 {
260     [self _toggleBooleanDefault:UseWebKit2ByDefaultPreferenceKey];
261 }
262
263 - (BOOL)useWebKit2ByDefault
264 {
265     return [[NSUserDefaults standardUserDefaults] boolForKey:UseWebKit2ByDefaultPreferenceKey];
266 }
267
268 - (void)toggleUseTransparentWindows:(id)sender
269 {
270     [self _toggleBooleanDefault:UseTransparentWindowsPreferenceKey];
271 }
272
273 - (BOOL)useTransparentWindows
274 {
275     return [[NSUserDefaults standardUserDefaults] boolForKey:UseTransparentWindowsPreferenceKey];
276 }
277
278 - (void)toggleUsePaginatedMode:(id)sender
279 {
280     [self _toggleBooleanDefault:UsePaginatedModePreferenceKey];
281 }
282
283 - (BOOL)usePaginatedMode
284 {
285     return [[NSUserDefaults standardUserDefaults] boolForKey:UsePaginatedModePreferenceKey];
286 }
287
288 - (void)toggleUseUISideCompositing:(id)sender
289 {
290     [self _toggleBooleanDefault:UseRemoteLayerTreeDrawingAreaPreferenceKey];
291 }
292
293 - (BOOL)useUISideCompositing
294 {
295     return [[NSUserDefaults standardUserDefaults] boolForKey:UseRemoteLayerTreeDrawingAreaPreferenceKey];
296 }
297
298 - (void)togglePerWindowWebProcessesDisabled:(id)sender
299 {
300     NSAlert *alert = [[NSAlert alloc] init];
301     [alert setMessageText:self.perWindowWebProcessesDisabled ? @"Are you sure you want to switch to per-window web processes?" : @"Are you sure you want to switch to a single web process?"];
302     [alert setInformativeText:@"This requires quitting and relaunching MiniBrowser. I'll do the quitting. You will have to do the relaunching."];
303     [alert addButtonWithTitle:@"Switch and Quit"];
304     [alert addButtonWithTitle:@"Cancel"];
305
306     if ([alert runModal] != NSAlertFirstButtonReturn)
307         return;
308
309     [self _toggleBooleanDefault:PerWindowWebProcessesDisabledKey];
310     [NSApp terminate:self];
311 }
312
313 - (BOOL)perWindowWebProcessesDisabled
314 {
315     return [[NSUserDefaults standardUserDefaults] boolForKey:PerWindowWebProcessesDisabledKey];
316 }
317
318 - (void)toggleIncrementalRenderingSuppressed:(id)sender
319 {
320     [self _toggleBooleanDefault:IncrementalRenderingSuppressedPreferenceKey];
321 }
322
323 - (BOOL)incrementalRenderingSuppressed
324 {
325     return [[NSUserDefaults standardUserDefaults] boolForKey:IncrementalRenderingSuppressedPreferenceKey];
326 }
327
328 - (void)toggleShowLayerBorders:(id)sender
329 {
330     [self _toggleBooleanDefault:LayerBordersVisiblePreferenceKey];
331 }
332
333 - (BOOL)layerBordersVisible
334 {
335     return [[NSUserDefaults standardUserDefaults] boolForKey:LayerBordersVisiblePreferenceKey];
336 }
337
338 - (void)toggleSimpleLineLayoutDebugBordersEnabled:(id)sender
339 {
340     [self _toggleBooleanDefault:SimpleLineLayoutDebugBordersEnabledPreferenceKey];
341 }
342
343 - (BOOL)simpleLineLayoutDebugBordersEnabled
344 {
345     return [[NSUserDefaults standardUserDefaults] boolForKey:SimpleLineLayoutDebugBordersEnabledPreferenceKey];
346 }
347
348 - (void)toggleAcceleratedDrawingEnabled:(id)sender
349 {
350     [self _toggleBooleanDefault:AcceleratedDrawingEnabledPreferenceKey];
351 }
352
353 - (BOOL)acceleratedDrawingEnabled
354 {
355     return [[NSUserDefaults standardUserDefaults] boolForKey:AcceleratedDrawingEnabledPreferenceKey];
356 }
357
358 - (void)toggleDisplayListDrawingEnabled:(id)sender
359 {
360     [self _toggleBooleanDefault:DisplayListDrawingEnabledPreferenceKey];
361 }
362
363 - (BOOL)displayListDrawingEnabled
364 {
365     return [[NSUserDefaults standardUserDefaults] boolForKey:DisplayListDrawingEnabledPreferenceKey];
366 }
367
368 - (void)toggleReserveSpaceForBanners:(id)sender
369 {
370     [self _toggleBooleanDefault:ReserveSpaceForBannersPreferenceKey];
371 }
372
373 - (void)toggleShowTiledScrollingIndicator:(id)sender
374 {
375     [self _toggleBooleanDefault:TiledScrollingIndicatorVisiblePreferenceKey];
376 }
377
378 - (void)toggleShowResourceUsageOverlay:(id)sender
379 {
380     [self _toggleBooleanDefault:ResourceUsageOverlayVisiblePreferenceKey];
381 }
382
383 - (BOOL)loadsAllSiteIcons
384 {
385     return [[NSUserDefaults standardUserDefaults] boolForKey:LoadsAllSiteIconsKey];
386 }
387
388 - (void)toggleLoadsAllSiteIcons:(id)sender
389 {
390     [self _toggleBooleanDefault:LoadsAllSiteIconsKey];
391 }
392
393 - (BOOL)usesGameControllerFramework
394 {
395     return [[NSUserDefaults standardUserDefaults] boolForKey:UsesGameControllerFrameworkKey];
396 }
397
398 - (void)toggleUsesGameControllerFramework:(id)sender
399 {
400     [self _toggleBooleanDefault:UsesGameControllerFrameworkKey];
401 }
402
403 - (BOOL)networkCacheSpeculativeRevalidationDisabled
404 {
405     return [[NSUserDefaults standardUserDefaults] boolForKey:NetworkCacheSpeculativeRevalidationDisabledKey];
406 }
407
408 - (void)toggleNetworkCacheSpeculativeRevalidationDisabled:(id)sender
409 {
410     [self _toggleBooleanDefault:NetworkCacheSpeculativeRevalidationDisabledKey];
411 }
412
413 - (BOOL)isSpaceReservedForBanners
414 {
415     return [[NSUserDefaults standardUserDefaults] boolForKey:ReserveSpaceForBannersPreferenceKey];
416 }
417
418 - (BOOL)tiledScrollingIndicatorVisible
419 {
420     return [[NSUserDefaults standardUserDefaults] boolForKey:TiledScrollingIndicatorVisiblePreferenceKey];
421 }
422
423 - (BOOL)resourceUsageOverlayVisible
424 {
425     return [[NSUserDefaults standardUserDefaults] boolForKey:ResourceUsageOverlayVisiblePreferenceKey];
426 }
427
428 - (void)toggleResourceLoadStatisticsEnabled:(id)sender
429 {
430     [self _toggleBooleanDefault:ResourceLoadStatisticsEnabledPreferenceKey];
431 }
432
433 - (BOOL)visualViewportEnabled
434 {
435     return [[NSUserDefaults standardUserDefaults] boolForKey:VisualViewportEnabledPreferenceKey];
436 }
437
438 - (void)toggleVisualViewportEnabled:(id)sender
439 {
440     [self _toggleBooleanDefault:VisualViewportEnabledPreferenceKey];
441 }
442
443 - (BOOL)resourceLoadStatisticsEnabled
444 {
445     return [[NSUserDefaults standardUserDefaults] boolForKey:ResourceLoadStatisticsEnabledPreferenceKey];
446 }
447
448 - (void)toggleLargeImageAsyncDecodingEnabled:(id)sender
449 {
450     [self _toggleBooleanDefault:LargeImageAsyncDecodingEnabledPreferenceKey];
451 }
452
453 - (BOOL)largeImageAsyncDecodingEnabled
454 {
455     return [[NSUserDefaults standardUserDefaults] boolForKey:LargeImageAsyncDecodingEnabledPreferenceKey];
456 }
457
458 - (void)toggleAnimatedImageAsyncDecodingEnabled:(id)sender
459 {
460     [self _toggleBooleanDefault:AnimatedImageAsyncDecodingEnabledPreferenceKey];
461 }
462
463 - (BOOL)animatedImageAsyncDecodingEnabled
464 {
465     return [[NSUserDefaults standardUserDefaults] boolForKey:AnimatedImageAsyncDecodingEnabledPreferenceKey];
466 }
467
468 - (void)toggleEnableSubPixelCSSOMMetrics:(id)sender
469 {
470     [self _toggleBooleanDefault:EnableSubPixelCSSOMMetricsPreferenceKey];
471 }
472
473 - (BOOL)subPixelCSSOMMetricsEnabled
474 {
475     return [[NSUserDefaults standardUserDefaults] boolForKey:EnableSubPixelCSSOMMetricsPreferenceKey];
476 }
477
478 - (BOOL)nonFastScrollableRegionOverlayVisible
479 {
480     return [[NSUserDefaults standardUserDefaults] boolForKey:NonFastScrollableRegionOverlayVisiblePreferenceKey];
481 }
482
483 - (BOOL)wheelEventHandlerRegionOverlayVisible
484 {
485     return [[NSUserDefaults standardUserDefaults] boolForKey:WheelEventHandlerRegionOverlayVisiblePreferenceKey];
486 }
487
488 - (NSString *)preferenceKeyForRegionOverlayTag:(NSUInteger)tag
489 {
490     switch (tag) {
491     case NonFastScrollableRegionOverlayTag:
492         return NonFastScrollableRegionOverlayVisiblePreferenceKey;
493
494     case WheelEventHandlerRegionOverlayTag:
495         return WheelEventHandlerRegionOverlayVisiblePreferenceKey;
496     }
497     return nil;
498 }
499
500 - (void)toggleDebugOverlay:(id)sender
501 {
502     NSString *preferenceKey = [self preferenceKeyForRegionOverlayTag:[sender tag]];
503     if (preferenceKey)
504         [self _toggleBooleanDefault:preferenceKey];
505 }
506
507 #if WK_API_ENABLED
508 - (void)toggleExperimentalFeature:(id)sender
509 {
510     _WKExperimentalFeature *feature = ((NSMenuItem *)sender).representedObject;
511     WKPreferences *preferences = defaultPreferences();
512
513     BOOL currentlyEnabled = [preferences _isEnabledForFeature:feature];
514     [preferences _setEnabled:!currentlyEnabled forFeature:feature];
515
516     [[NSUserDefaults standardUserDefaults] setBool:!currentlyEnabled forKey:feature.key];
517 }
518 #endif
519
520 - (BOOL)debugOverlayVisible:(NSMenuItem *)menuItem
521 {
522     NSString *preferenceKey = [self preferenceKeyForRegionOverlayTag:[menuItem tag]];
523     if (preferenceKey)
524         return [[NSUserDefaults standardUserDefaults] boolForKey:preferenceKey];
525
526     return NO;
527 }
528
529 - (NSString *)defaultURL
530 {
531     NSString *customDefaultURL = [[NSUserDefaults standardUserDefaults] stringForKey:DefaultURLPreferenceKey];
532     if (customDefaultURL)
533         return customDefaultURL;
534     return defaultURL;
535 }
536
537 - (void)setDefaultURLToCurrentURL:(id)sender
538 {
539     NSWindowController *windowController = [[NSApp keyWindow] windowController];
540     NSString *customDefaultURL = nil;
541
542     if ([windowController isKindOfClass:[BrowserWindowController class]])
543         customDefaultURL = [[(BrowserWindowController *)windowController currentURL] absoluteString];
544
545     if (customDefaultURL)
546         [[NSUserDefaults standardUserDefaults] setObject:customDefaultURL forKey:DefaultURLPreferenceKey];
547 }
548
549 @end