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