Add simple line layout toggle to MiniBrowser
[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 CreateEditorByDefaultPreferenceKey = @"CreateEditorByDefault";
41 static NSString * const LayerBordersVisiblePreferenceKey = @"LayerBordersVisible";
42 static NSString * const SimpleLineLayoutEnabledPreferenceKey = @"SimpleLineLayoutEnabled";
43 static NSString * const SimpleLineLayoutDebugBordersEnabledPreferenceKey = @"SimpleLineLayoutDebugBordersEnabled";
44 static NSString * const TiledScrollingIndicatorVisiblePreferenceKey = @"TiledScrollingIndicatorVisible";
45 static NSString * const ReserveSpaceForBannersPreferenceKey = @"ReserveSpaceForBanners";
46
47 static NSString * const ResourceUsageOverlayVisiblePreferenceKey = @"ResourceUsageOverlayVisible";
48 static NSString * const LoadsAllSiteIconsKey = @"LoadsAllSiteIcons";
49 static NSString * const UsesGameControllerFrameworkKey = @"UsesGameControllerFramework";
50 static NSString * const IncrementalRenderingSuppressedPreferenceKey = @"IncrementalRenderingSuppressed";
51 static NSString * const AcceleratedDrawingEnabledPreferenceKey = @"AcceleratedDrawingEnabled";
52 static NSString * const DisplayListDrawingEnabledPreferenceKey = @"DisplayListDrawingEnabled";
53 static NSString * const ResourceLoadStatisticsEnabledPreferenceKey = @"ResourceLoadStatisticsEnabled";
54
55 static NSString * const NonFastScrollableRegionOverlayVisiblePreferenceKey = @"NonFastScrollableRegionOverlayVisible";
56 static NSString * const WheelEventHandlerRegionOverlayVisiblePreferenceKey = @"WheelEventHandlerRegionOverlayVisible";
57
58 static NSString * const UseTransparentWindowsPreferenceKey = @"UseTransparentWindows";
59 static NSString * const UsePaginatedModePreferenceKey = @"UsePaginatedMode";
60 static NSString * const EnableSubPixelCSSOMMetricsPreferenceKey = @"EnableSubPixelCSSOMMetrics";
61
62 static NSString * const VisualViewportEnabledPreferenceKey = @"VisualViewportEnabled";
63 static NSString * const LargeImageAsyncDecodingEnabledPreferenceKey = @"LargeImageAsyncDecodingEnabled";
64 static NSString * const AnimatedImageAsyncDecodingEnabledPreferenceKey = @"AnimatedImageAsyncDecodingEnabled";
65
66 // This default name intentionally overlaps with the key that WebKit2 checks when creating a view.
67 static NSString * const UseRemoteLayerTreeDrawingAreaPreferenceKey = @"WebKit2UseRemoteLayerTreeDrawingArea";
68
69 static NSString * const PerWindowWebProcessesDisabledKey = @"PerWindowWebProcessesDisabled";
70 static NSString * const NetworkCacheSpeculativeRevalidationDisabledKey = @"NetworkCacheSpeculativeRevalidationDisabled";
71
72 typedef NS_ENUM(NSInteger, DebugOverylayMenuItemTag) {
73     NonFastScrollableRegionOverlayTag = 100,
74     WheelEventHandlerRegionOverlayTag,
75 #if WK_API_ENABLED
76     ExperimentalFeatureTag,
77 #endif
78 };
79
80 @implementation SettingsController
81
82 @synthesize menu=_menu;
83
84 + (instancetype)shared
85 {
86     static SettingsController *sharedSettingsController;
87     static dispatch_once_t onceToken;
88     dispatch_once(&onceToken, ^{
89         sharedSettingsController = [[super alloc] init];
90     });
91
92     return sharedSettingsController;
93 }
94
95 - (NSMenu *)menu
96 {
97     if (!_menu)
98         [self _populateMenu];
99
100     return _menu;
101 }
102
103 - (void)_addItemWithTitle:(NSString *)title action:(SEL)action indented:(BOOL)indented
104 {
105     NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:title action:action keyEquivalent:@""];
106     [item setTarget:self];
107     if (indented)
108         [item setIndentationLevel:1];
109     [_menu addItem:item];
110     [item release];
111 }
112
113 - (void)_addHeaderWithTitle:(NSString *)title
114 {
115     [_menu addItem:[NSMenuItem separatorItem]];
116     [_menu addItem:[[[NSMenuItem alloc] initWithTitle:title action:nil keyEquivalent:@""] autorelease]];
117 }
118
119 - (void)_populateMenu
120 {
121     _menu = [[NSMenu alloc] initWithTitle:@"Settings"];
122
123     [self _addItemWithTitle:@"Use WebKit2 By Default" action:@selector(toggleUseWebKit2ByDefault:) indented:NO];
124     [self _addItemWithTitle:@"Create Editor By Default" action:@selector(toggleCreateEditorByDefault:) indented:NO];
125     [self _addItemWithTitle:@"Set Default URL to Current URL" action:@selector(setDefaultURLToCurrentURL:) indented:NO];
126
127     [_menu addItem:[NSMenuItem separatorItem]];
128
129     [self _addItemWithTitle:@"Use Transparent Windows" action:@selector(toggleUseTransparentWindows:) indented:NO];
130     [self _addItemWithTitle:@"Use Paginated Mode" action:@selector(toggleUsePaginatedMode:) indented:NO];
131     [self _addItemWithTitle:@"Show Layer Borders" action:@selector(toggleShowLayerBorders:) indented:NO];
132     [self _addItemWithTitle:@"Disable Simple Line Layout" action:@selector(toggleSimpleLineLayoutEnabled:) indented:NO];
133     [self _addItemWithTitle:@"Show Simple Line Layout Borders" action:@selector(toggleSimpleLineLayoutDebugBordersEnabled:) indented:NO];
134     [self _addItemWithTitle:@"Suppress Incremental Rendering in New Windows" action:@selector(toggleIncrementalRenderingSuppressed:) indented:NO];
135     [self _addItemWithTitle:@"Enable Accelerated Drawing" action:@selector(toggleAcceleratedDrawingEnabled:) indented:NO];
136     [self _addItemWithTitle:@"Enable Display List Drawing" action:@selector(toggleDisplayListDrawingEnabled:) indented:NO];
137     [self _addItemWithTitle:@"Enable Visual Viewport" action:@selector(toggleVisualViewportEnabled:) indented:NO];
138     [self _addItemWithTitle:@"Enable Resource Load Statistics" action:@selector(toggleResourceLoadStatisticsEnabled:) indented:NO];
139     [self _addItemWithTitle:@"Enable Large Image Async Decoding" action:@selector(toggleLargeImageAsyncDecodingEnabled:) indented:NO];
140     [self _addItemWithTitle:@"Enable Animated Image Async Decoding" action:@selector(toggleAnimatedImageAsyncDecodingEnabled:) indented:NO];
141
142     [self _addHeaderWithTitle:@"WebKit2-only Settings"];
143
144     [self _addItemWithTitle:@"Reserve Space For Banners" action:@selector(toggleReserveSpaceForBanners:) indented:YES];
145     [self _addItemWithTitle:@"Show Tiled Scrolling Indicator" action:@selector(toggleShowTiledScrollingIndicator:) indented:YES];
146     [self _addItemWithTitle:@"Use UI-Side Compositing" action:@selector(toggleUseUISideCompositing:) indented:YES];
147     [self _addItemWithTitle:@"Disable Per-Window Web Processes" action:@selector(togglePerWindowWebProcessesDisabled:) indented:YES];
148     [self _addItemWithTitle:@"Show Resource Usage Overlay" action:@selector(toggleShowResourceUsageOverlay:) indented:YES];
149     [self _addItemWithTitle:@"Load All Site Icons Per-Page" action:@selector(toggleLoadsAllSiteIcons:) indented:YES];
150     [self _addItemWithTitle:@"Use GameController.framework on macOS (Restart required)" action:@selector(toggleUsesGameControllerFramework:) indented:YES];
151     [self _addItemWithTitle:@"Disable network cache speculative revalidation" action:@selector(toggleNetworkCacheSpeculativeRevalidationDisabled:) indented:YES];
152
153     NSMenuItem *debugOverlaysSubmenuItem = [[NSMenuItem alloc] initWithTitle:@"Debug Overlays" action:nil keyEquivalent:@""];
154     NSMenu *debugOverlaysMenu = [[NSMenu alloc] initWithTitle:@"Debug Overlays"];
155     [debugOverlaysSubmenuItem setSubmenu:debugOverlaysMenu];
156
157     NSMenuItem *nonFastScrollableRegionItem = [[NSMenuItem alloc] initWithTitle:@"Non-fast Scrollable Region" action:@selector(toggleDebugOverlay:) keyEquivalent:@""];
158     [nonFastScrollableRegionItem setTag:NonFastScrollableRegionOverlayTag];
159     [nonFastScrollableRegionItem setTarget:self];
160     [debugOverlaysMenu addItem:[nonFastScrollableRegionItem autorelease]];
161
162     NSMenuItem *wheelEventHandlerRegionItem = [[NSMenuItem alloc] initWithTitle:@"Wheel Event Handler Region" action:@selector(toggleDebugOverlay:) keyEquivalent:@""];
163     [wheelEventHandlerRegionItem setTag:WheelEventHandlerRegionOverlayTag];
164     [wheelEventHandlerRegionItem setTarget:self];
165     [debugOverlaysMenu addItem:[wheelEventHandlerRegionItem autorelease]];
166     [debugOverlaysMenu release];
167     
168     [_menu addItem:debugOverlaysSubmenuItem];
169     [debugOverlaysSubmenuItem release];
170
171 #if WK_API_ENABLED
172     NSMenuItem *experimentalFeaturesSubmenuItem = [[NSMenuItem alloc] initWithTitle:@"Experimental Features" action:nil keyEquivalent:@""];
173     NSMenu *experimentalFeaturesMenu = [[NSMenu alloc] initWithTitle:@"Experimental Features"];
174     [experimentalFeaturesSubmenuItem setSubmenu:experimentalFeaturesMenu];
175
176     NSArray<_WKExperimentalFeature *> *features = [WKPreferences _experimentalFeatures];
177
178     for (_WKExperimentalFeature *feature in features) {
179         NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:feature.name action:@selector(toggleExperimentalFeature:) keyEquivalent:@""];
180         item.toolTip = feature.details;
181         item.representedObject = feature;
182
183         [item setTag:ExperimentalFeatureTag];
184         [item setTarget:self];
185         [experimentalFeaturesMenu addItem:[item autorelease]];
186     }
187
188     [_menu addItem:experimentalFeaturesSubmenuItem];
189     [experimentalFeaturesSubmenuItem release];
190 #endif // WK_API_ENABLED
191
192     [self _addHeaderWithTitle:@"WebKit1-only Settings"];
193     [self _addItemWithTitle:@"Enable Subpixel CSSOM Metrics" action:@selector(toggleEnableSubPixelCSSOMMetrics:) indented:YES];
194 }
195
196 - (BOOL)validateMenuItem:(NSMenuItem *)menuItem
197 {
198     SEL action = [menuItem action];
199
200     if (action == @selector(toggleUseWebKit2ByDefault:))
201         [menuItem setState:[self useWebKit2ByDefault] ? NSOnState : NSOffState];
202     else if (action == @selector(toggleCreateEditorByDefault:))
203         [menuItem setState:[self createEditorByDefault] ? NSOnState : NSOffState];
204     else if (action == @selector(toggleUseTransparentWindows:))
205         [menuItem setState:[self useTransparentWindows] ? NSOnState : NSOffState];
206     else if (action == @selector(toggleUsePaginatedMode:))
207         [menuItem setState:[self usePaginatedMode] ? NSOnState : NSOffState];
208     else if (action == @selector(toggleShowLayerBorders:))
209         [menuItem setState:[self layerBordersVisible] ? NSOnState : NSOffState];
210     else if (action == @selector(toggleSimpleLineLayoutEnabled:))
211         [menuItem setState:[self simpleLineLayoutEnabled] ? NSOffState : NSOnState];
212     else if (action == @selector(toggleSimpleLineLayoutDebugBordersEnabled:))
213         [menuItem setState:[self simpleLineLayoutDebugBordersEnabled] ? NSOnState : NSOffState];
214     else if (action == @selector(toggleIncrementalRenderingSuppressed:))
215         [menuItem setState:[self incrementalRenderingSuppressed] ? NSOnState : NSOffState];
216     else if (action == @selector(toggleAcceleratedDrawingEnabled:))
217         [menuItem setState:[self acceleratedDrawingEnabled] ? NSOnState : NSOffState];
218     else if (action == @selector(toggleDisplayListDrawingEnabled:))
219         [menuItem setState:[self displayListDrawingEnabled] ? NSOnState : NSOffState];
220     else if (action == @selector(toggleResourceLoadStatisticsEnabled:))
221         [menuItem setState:[self resourceLoadStatisticsEnabled] ? NSOnState : NSOffState];
222     else if (action == @selector(toggleLargeImageAsyncDecodingEnabled:))
223         [menuItem setState:[self largeImageAsyncDecodingEnabled] ? NSOnState : NSOffState];
224     else if (action == @selector(toggleAnimatedImageAsyncDecodingEnabled:))
225         [menuItem setState:[self animatedImageAsyncDecodingEnabled] ? NSOnState : NSOffState];
226     else if (action == @selector(toggleVisualViewportEnabled:))
227         [menuItem setState:[self visualViewportEnabled] ? NSOnState : NSOffState];
228     else if (action == @selector(toggleReserveSpaceForBanners:))
229         [menuItem setState:[self isSpaceReservedForBanners] ? NSOnState : NSOffState];
230     else if (action == @selector(toggleShowTiledScrollingIndicator:))
231         [menuItem setState:[self tiledScrollingIndicatorVisible] ? NSOnState : NSOffState];
232     else if (action == @selector(toggleShowResourceUsageOverlay:))
233         [menuItem setState:[self resourceUsageOverlayVisible] ? NSOnState : NSOffState];
234     else if (action == @selector(toggleLoadsAllSiteIcons:))
235         [menuItem setState:[self loadsAllSiteIcons] ? NSOnState : NSOffState];
236     else if (action == @selector(toggleUsesGameControllerFramework:))
237         [menuItem setState:[self usesGameControllerFramework] ? NSOnState : NSOffState];
238     else if (action == @selector(toggleNetworkCacheSpeculativeRevalidationDisabled:))
239         [menuItem setState:[self networkCacheSpeculativeRevalidationDisabled] ? NSOnState : NSOffState];
240     else if (action == @selector(toggleUseUISideCompositing:))
241         [menuItem setState:[self useUISideCompositing] ? NSOnState : NSOffState];
242     else if (action == @selector(togglePerWindowWebProcessesDisabled:))
243         [menuItem setState:[self perWindowWebProcessesDisabled] ? NSOnState : NSOffState];
244     else if (action == @selector(toggleEnableSubPixelCSSOMMetrics:))
245         [menuItem setState:[self subPixelCSSOMMetricsEnabled] ? NSOnState : NSOffState];
246     else if (action == @selector(toggleDebugOverlay:))
247         [menuItem setState:[self debugOverlayVisible:menuItem] ? NSOnState : NSOffState];
248
249 #if WK_API_ENABLED
250     if (menuItem.tag == ExperimentalFeatureTag) {
251         _WKExperimentalFeature *feature = menuItem.representedObject;
252         [menuItem setState:[defaultPreferences() _isEnabledForFeature:feature] ? NSOnState : NSOffState];
253     }
254 #endif
255
256     return YES;
257 }
258
259 - (void)_toggleBooleanDefault:(NSString *)defaultName
260 {
261     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
262     [defaults setBool:![defaults boolForKey:defaultName] forKey:defaultName];
263
264     [(BrowserAppDelegate *)[[NSApplication sharedApplication] delegate] didChangeSettings];
265 }
266
267 - (void)toggleUseWebKit2ByDefault:(id)sender
268 {
269     [self _toggleBooleanDefault:UseWebKit2ByDefaultPreferenceKey];
270 }
271
272 - (BOOL)useWebKit2ByDefault
273 {
274     return [[NSUserDefaults standardUserDefaults] boolForKey:UseWebKit2ByDefaultPreferenceKey];
275 }
276
277 - (void)toggleCreateEditorByDefault:(id)sender
278 {
279     [self _toggleBooleanDefault:CreateEditorByDefaultPreferenceKey];
280 }
281
282 - (BOOL)createEditorByDefault
283 {
284     return [[NSUserDefaults standardUserDefaults] boolForKey:CreateEditorByDefaultPreferenceKey];
285 }
286
287 - (void)toggleUseTransparentWindows:(id)sender
288 {
289     [self _toggleBooleanDefault:UseTransparentWindowsPreferenceKey];
290 }
291
292 - (BOOL)useTransparentWindows
293 {
294     return [[NSUserDefaults standardUserDefaults] boolForKey:UseTransparentWindowsPreferenceKey];
295 }
296
297 - (void)toggleUsePaginatedMode:(id)sender
298 {
299     [self _toggleBooleanDefault:UsePaginatedModePreferenceKey];
300 }
301
302 - (BOOL)usePaginatedMode
303 {
304     return [[NSUserDefaults standardUserDefaults] boolForKey:UsePaginatedModePreferenceKey];
305 }
306
307 - (void)toggleUseUISideCompositing:(id)sender
308 {
309     [self _toggleBooleanDefault:UseRemoteLayerTreeDrawingAreaPreferenceKey];
310 }
311
312 - (BOOL)useUISideCompositing
313 {
314     return [[NSUserDefaults standardUserDefaults] boolForKey:UseRemoteLayerTreeDrawingAreaPreferenceKey];
315 }
316
317 - (void)togglePerWindowWebProcessesDisabled:(id)sender
318 {
319     NSAlert *alert = [[NSAlert alloc] init];
320     [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?"];
321     [alert setInformativeText:@"This requires quitting and relaunching MiniBrowser. I'll do the quitting. You will have to do the relaunching."];
322     [alert addButtonWithTitle:@"Switch and Quit"];
323     [alert addButtonWithTitle:@"Cancel"];
324
325     if ([alert runModal] != NSAlertFirstButtonReturn)
326         return;
327
328     [self _toggleBooleanDefault:PerWindowWebProcessesDisabledKey];
329     [NSApp terminate:self];
330 }
331
332 - (BOOL)perWindowWebProcessesDisabled
333 {
334     return [[NSUserDefaults standardUserDefaults] boolForKey:PerWindowWebProcessesDisabledKey];
335 }
336
337 - (void)toggleIncrementalRenderingSuppressed:(id)sender
338 {
339     [self _toggleBooleanDefault:IncrementalRenderingSuppressedPreferenceKey];
340 }
341
342 - (BOOL)incrementalRenderingSuppressed
343 {
344     return [[NSUserDefaults standardUserDefaults] boolForKey:IncrementalRenderingSuppressedPreferenceKey];
345 }
346
347 - (void)toggleShowLayerBorders:(id)sender
348 {
349     [self _toggleBooleanDefault:LayerBordersVisiblePreferenceKey];
350 }
351
352 - (BOOL)layerBordersVisible
353 {
354     return [[NSUserDefaults standardUserDefaults] boolForKey:LayerBordersVisiblePreferenceKey];
355 }
356
357 - (void)toggleSimpleLineLayoutEnabled:(id)sender
358 {
359     [self _toggleBooleanDefault:SimpleLineLayoutEnabledPreferenceKey];
360 }
361
362 - (BOOL)simpleLineLayoutEnabled
363 {
364     return [[NSUserDefaults standardUserDefaults] boolForKey:SimpleLineLayoutEnabledPreferenceKey];
365 }
366
367 - (void)toggleSimpleLineLayoutDebugBordersEnabled:(id)sender
368 {
369     [self _toggleBooleanDefault:SimpleLineLayoutDebugBordersEnabledPreferenceKey];
370 }
371
372 - (BOOL)simpleLineLayoutDebugBordersEnabled
373 {
374     return [[NSUserDefaults standardUserDefaults] boolForKey:SimpleLineLayoutDebugBordersEnabledPreferenceKey];
375 }
376
377 - (void)toggleAcceleratedDrawingEnabled:(id)sender
378 {
379     [self _toggleBooleanDefault:AcceleratedDrawingEnabledPreferenceKey];
380 }
381
382 - (BOOL)acceleratedDrawingEnabled
383 {
384     return [[NSUserDefaults standardUserDefaults] boolForKey:AcceleratedDrawingEnabledPreferenceKey];
385 }
386
387 - (void)toggleDisplayListDrawingEnabled:(id)sender
388 {
389     [self _toggleBooleanDefault:DisplayListDrawingEnabledPreferenceKey];
390 }
391
392 - (BOOL)displayListDrawingEnabled
393 {
394     return [[NSUserDefaults standardUserDefaults] boolForKey:DisplayListDrawingEnabledPreferenceKey];
395 }
396
397 - (void)toggleReserveSpaceForBanners:(id)sender
398 {
399     [self _toggleBooleanDefault:ReserveSpaceForBannersPreferenceKey];
400 }
401
402 - (void)toggleShowTiledScrollingIndicator:(id)sender
403 {
404     [self _toggleBooleanDefault:TiledScrollingIndicatorVisiblePreferenceKey];
405 }
406
407 - (void)toggleShowResourceUsageOverlay:(id)sender
408 {
409     [self _toggleBooleanDefault:ResourceUsageOverlayVisiblePreferenceKey];
410 }
411
412 - (BOOL)loadsAllSiteIcons
413 {
414     return [[NSUserDefaults standardUserDefaults] boolForKey:LoadsAllSiteIconsKey];
415 }
416
417 - (void)toggleLoadsAllSiteIcons:(id)sender
418 {
419     [self _toggleBooleanDefault:LoadsAllSiteIconsKey];
420 }
421
422 - (BOOL)usesGameControllerFramework
423 {
424     return [[NSUserDefaults standardUserDefaults] boolForKey:UsesGameControllerFrameworkKey];
425 }
426
427 - (void)toggleUsesGameControllerFramework:(id)sender
428 {
429     [self _toggleBooleanDefault:UsesGameControllerFrameworkKey];
430 }
431
432 - (BOOL)networkCacheSpeculativeRevalidationDisabled
433 {
434     return [[NSUserDefaults standardUserDefaults] boolForKey:NetworkCacheSpeculativeRevalidationDisabledKey];
435 }
436
437 - (void)toggleNetworkCacheSpeculativeRevalidationDisabled:(id)sender
438 {
439     [self _toggleBooleanDefault:NetworkCacheSpeculativeRevalidationDisabledKey];
440 }
441
442 - (BOOL)isSpaceReservedForBanners
443 {
444     return [[NSUserDefaults standardUserDefaults] boolForKey:ReserveSpaceForBannersPreferenceKey];
445 }
446
447 - (BOOL)tiledScrollingIndicatorVisible
448 {
449     return [[NSUserDefaults standardUserDefaults] boolForKey:TiledScrollingIndicatorVisiblePreferenceKey];
450 }
451
452 - (BOOL)resourceUsageOverlayVisible
453 {
454     return [[NSUserDefaults standardUserDefaults] boolForKey:ResourceUsageOverlayVisiblePreferenceKey];
455 }
456
457 - (void)toggleResourceLoadStatisticsEnabled:(id)sender
458 {
459     [self _toggleBooleanDefault:ResourceLoadStatisticsEnabledPreferenceKey];
460 }
461
462 - (BOOL)visualViewportEnabled
463 {
464     return [[NSUserDefaults standardUserDefaults] boolForKey:VisualViewportEnabledPreferenceKey];
465 }
466
467 - (void)toggleVisualViewportEnabled:(id)sender
468 {
469     [self _toggleBooleanDefault:VisualViewportEnabledPreferenceKey];
470 }
471
472 - (BOOL)resourceLoadStatisticsEnabled
473 {
474     return [[NSUserDefaults standardUserDefaults] boolForKey:ResourceLoadStatisticsEnabledPreferenceKey];
475 }
476
477 - (void)toggleLargeImageAsyncDecodingEnabled:(id)sender
478 {
479     [self _toggleBooleanDefault:LargeImageAsyncDecodingEnabledPreferenceKey];
480 }
481
482 - (BOOL)largeImageAsyncDecodingEnabled
483 {
484     return [[NSUserDefaults standardUserDefaults] boolForKey:LargeImageAsyncDecodingEnabledPreferenceKey];
485 }
486
487 - (void)toggleAnimatedImageAsyncDecodingEnabled:(id)sender
488 {
489     [self _toggleBooleanDefault:AnimatedImageAsyncDecodingEnabledPreferenceKey];
490 }
491
492 - (BOOL)animatedImageAsyncDecodingEnabled
493 {
494     return [[NSUserDefaults standardUserDefaults] boolForKey:AnimatedImageAsyncDecodingEnabledPreferenceKey];
495 }
496
497 - (void)toggleEnableSubPixelCSSOMMetrics:(id)sender
498 {
499     [self _toggleBooleanDefault:EnableSubPixelCSSOMMetricsPreferenceKey];
500 }
501
502 - (BOOL)subPixelCSSOMMetricsEnabled
503 {
504     return [[NSUserDefaults standardUserDefaults] boolForKey:EnableSubPixelCSSOMMetricsPreferenceKey];
505 }
506
507 - (BOOL)nonFastScrollableRegionOverlayVisible
508 {
509     return [[NSUserDefaults standardUserDefaults] boolForKey:NonFastScrollableRegionOverlayVisiblePreferenceKey];
510 }
511
512 - (BOOL)wheelEventHandlerRegionOverlayVisible
513 {
514     return [[NSUserDefaults standardUserDefaults] boolForKey:WheelEventHandlerRegionOverlayVisiblePreferenceKey];
515 }
516
517 - (NSString *)preferenceKeyForRegionOverlayTag:(NSUInteger)tag
518 {
519     switch (tag) {
520     case NonFastScrollableRegionOverlayTag:
521         return NonFastScrollableRegionOverlayVisiblePreferenceKey;
522
523     case WheelEventHandlerRegionOverlayTag:
524         return WheelEventHandlerRegionOverlayVisiblePreferenceKey;
525     }
526     return nil;
527 }
528
529 - (void)toggleDebugOverlay:(id)sender
530 {
531     NSString *preferenceKey = [self preferenceKeyForRegionOverlayTag:[sender tag]];
532     if (preferenceKey)
533         [self _toggleBooleanDefault:preferenceKey];
534 }
535
536 #if WK_API_ENABLED
537 - (void)toggleExperimentalFeature:(id)sender
538 {
539     _WKExperimentalFeature *feature = ((NSMenuItem *)sender).representedObject;
540     WKPreferences *preferences = defaultPreferences();
541
542     BOOL currentlyEnabled = [preferences _isEnabledForFeature:feature];
543     [preferences _setEnabled:!currentlyEnabled forFeature:feature];
544
545     [[NSUserDefaults standardUserDefaults] setBool:!currentlyEnabled forKey:feature.key];
546 }
547 #endif
548
549 - (BOOL)debugOverlayVisible:(NSMenuItem *)menuItem
550 {
551     NSString *preferenceKey = [self preferenceKeyForRegionOverlayTag:[menuItem tag]];
552     if (preferenceKey)
553         return [[NSUserDefaults standardUserDefaults] boolForKey:preferenceKey];
554
555     return NO;
556 }
557
558 - (NSString *)defaultURL
559 {
560     NSString *customDefaultURL = [[NSUserDefaults standardUserDefaults] stringForKey:DefaultURLPreferenceKey];
561     if (customDefaultURL)
562         return customDefaultURL;
563     return defaultURL;
564 }
565
566 - (void)setDefaultURLToCurrentURL:(id)sender
567 {
568     NSWindowController *windowController = [[NSApp keyWindow] windowController];
569     NSString *customDefaultURL = nil;
570
571     if ([windowController isKindOfClass:[BrowserWindowController class]])
572         customDefaultURL = [[(BrowserWindowController *)windowController currentURL] absoluteString];
573
574     if (customDefaultURL)
575         [[NSUserDefaults standardUserDefaults] setObject:customDefaultURL forKey:DefaultURLPreferenceKey];
576 }
577
578 @end