009c1f746ade1d9e7531158b0e1ada83800d8da1
[WebKit-https.git] / Tools / MiniBrowser / mac / SettingsController.m
1 /*
2  * Copyright (C) 2014 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
31 static NSString * const defaultURL = @"http://www.webkit.org/";
32 static NSString * const DefaultURLPreferenceKey = @"DefaultURL";
33
34 static NSString * const UseWebKit2ByDefaultPreferenceKey = @"UseWebKit2ByDefault";
35 static NSString * const LayerBordersVisiblePreferenceKey = @"LayerBordersVisible";
36 static NSString * const SimpleLineLayoutDebugBordersEnabledPreferenceKey = @"SimpleLineLayoutDebugBordersEnabled";
37 static NSString * const TiledScrollingIndicatorVisiblePreferenceKey = @"TiledScrollingIndicatorVisible";
38
39 static NSString * const NonFastScrollableRegionOverlayVisiblePreferenceKey = @"NonFastScrollableRegionOverlayVisible";
40 static NSString * const WheelEventHandlerRegionOverlayVisiblePreferenceKey = @"WheelEventHandlerRegionOverlayVisible";
41
42 static NSString * const UseTransparentWindowsPreferenceKey = @"UseTransparentWindows";
43 static NSString * const UsePaginatedModePreferenceKey = @"UsePaginatedMode";
44 static NSString * const EnableSubPixelCSSOMMetricsPreferenceKey = @"EnableSubPixelCSSOMMetrics";
45
46 // This default name intentionally overlaps with the key that WebKit2 checks when creating a view.
47 static NSString * const UseRemoteLayerTreeDrawingAreaPreferenceKey = @"WebKit2UseRemoteLayerTreeDrawingArea";
48
49 typedef NS_ENUM(NSInteger, DebugOverylayMenuItemTag) {
50     NonFastScrollableRegionOverlayTag = 100,
51     WheelEventHandlerRegionOverlayTag
52 };
53
54 @implementation SettingsController
55
56 @synthesize menu=_menu;
57
58 + (instancetype)shared
59 {
60     static SettingsController *sharedSettingsController;
61     static dispatch_once_t onceToken;
62     dispatch_once(&onceToken, ^{
63         sharedSettingsController = [[super alloc] init];
64     });
65
66     return sharedSettingsController;
67 }
68
69 - (NSMenu *)menu
70 {
71     if (!_menu)
72         [self _populateMenu];
73
74     return _menu;
75 }
76
77 - (void)_addItemWithTitle:(NSString *)title action:(SEL)action indented:(BOOL)indented
78 {
79     NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:title action:action keyEquivalent:@""];
80     [item setTarget:self];
81     if (indented)
82         [item setIndentationLevel:1];
83     [_menu addItem:item];
84     [item release];
85 }
86
87 - (void)_addHeaderWithTitle:(NSString *)title
88 {
89     [_menu addItem:[NSMenuItem separatorItem]];
90     [_menu addItem:[[[NSMenuItem alloc] initWithTitle:title action:nil keyEquivalent:@""] autorelease]];
91 }
92
93 - (void)_populateMenu
94 {
95     _menu = [[NSMenu alloc] initWithTitle:@"Settings"];
96
97     [self _addItemWithTitle:@"Use WebKit2 By Default" action:@selector(toggleUseWebKit2ByDefault:) indented:NO];
98
99     [_menu addItem:[NSMenuItem separatorItem]];
100
101     [self _addItemWithTitle:@"Use Transparent Windows" action:@selector(toggleUseTransparentWindows:) indented:NO];
102     [self _addItemWithTitle:@"Use Paginated Mode" action:@selector(toggleUsePaginatedMode:) indented:NO];
103     [self _addItemWithTitle:@"Show Layer Borders" action:@selector(toggleShowLayerBorders:) indented:NO];
104     [self _addItemWithTitle:@"Show Simple Line Layout Borders" action:@selector(toggleSimpleLineLayoutDebugBordersEnabled:) indented:NO];
105
106     [self _addHeaderWithTitle:@"WebKit2-only Settings"];
107
108     [self _addItemWithTitle:@"Show Tiled Scrolling Indicator" action:@selector(toggleShowTiledScrollingIndicator:) indented:YES];
109     [self _addItemWithTitle:@"Use UI-Side Compositing" action:@selector(toggleUseUISideCompositing:) indented:YES];
110
111     NSMenuItem *debugOverlaysSubmenuItem = [[NSMenuItem alloc] initWithTitle:@"Debug Overlays" action:nil keyEquivalent:@""];
112     NSMenu *debugOverlaysMenu = [[NSMenu alloc] initWithTitle:@"Debug Overlays"];
113     [debugOverlaysSubmenuItem setSubmenu:debugOverlaysMenu];
114
115     NSMenuItem *nonFastScrollableRegionItem = [[NSMenuItem alloc] initWithTitle:@"Non-fast Scrollable Region" action:@selector(toggleDebugOverlay:) keyEquivalent:@""];
116     [nonFastScrollableRegionItem setTag:NonFastScrollableRegionOverlayTag];
117     [nonFastScrollableRegionItem setTarget:self];
118     [debugOverlaysMenu addItem:[nonFastScrollableRegionItem autorelease]];
119
120     NSMenuItem *wheelEventHandlerRegionItem = [[NSMenuItem alloc] initWithTitle:@"Wheel Event Handler Region" action:@selector(toggleDebugOverlay:) keyEquivalent:@""];
121     [wheelEventHandlerRegionItem setTag:WheelEventHandlerRegionOverlayTag];
122     [wheelEventHandlerRegionItem setTarget:self];
123     [debugOverlaysMenu addItem:[wheelEventHandlerRegionItem autorelease]];
124     [debugOverlaysMenu release];
125     
126     [_menu addItem:debugOverlaysSubmenuItem];
127     [debugOverlaysSubmenuItem release];
128
129     [self _addHeaderWithTitle:@"WebKit1-only Settings"];
130     [self _addItemWithTitle:@"Enable Subpixel CSSOM Metrics" action:@selector(toggleEnableSubPixelCSSOMMetrics:) indented:YES];
131 }
132
133 - (BOOL)validateMenuItem:(NSMenuItem *)menuItem
134 {
135     SEL action = [menuItem action];
136
137     if (action == @selector(toggleUseWebKit2ByDefault:))
138         [menuItem setState:[self useWebKit2ByDefault] ? NSOnState : NSOffState];
139     else if (action == @selector(toggleUseTransparentWindows:))
140         [menuItem setState:[self useTransparentWindows] ? NSOnState : NSOffState];
141     else if (action == @selector(toggleUsePaginatedMode:))
142         [menuItem setState:[self usePaginatedMode] ? NSOnState : NSOffState];
143     else if (action == @selector(toggleShowLayerBorders:))
144         [menuItem setState:[self layerBordersVisible] ? NSOnState : NSOffState];
145     else if (action == @selector(toggleSimpleLineLayoutDebugBordersEnabled:))
146         [menuItem setState:[self simpleLineLayoutDebugBordersEnabled] ? NSOnState : NSOffState];
147     else if (action == @selector(toggleShowTiledScrollingIndicator:))
148         [menuItem setState:[self tiledScrollingIndicatorVisible] ? NSOnState : NSOffState];
149     else if (action == @selector(toggleUseUISideCompositing:))
150         [menuItem setState:[self useUISideCompositing] ? NSOnState : NSOffState];
151     else if (action == @selector(toggleEnableSubPixelCSSOMMetrics:))
152         [menuItem setState:[self subPixelCSSOMMetricsEnabled] ? NSOnState : NSOffState];
153     else if (action == @selector(toggleDebugOverlay:))
154         [menuItem setState:[self debugOverlayVisible:menuItem] ? NSOnState : NSOffState];
155
156     return YES;
157 }
158
159 - (void)_toggleBooleanDefault:(NSString *)defaultName
160 {
161     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
162     [defaults setBool:![defaults boolForKey:defaultName] forKey:defaultName];
163
164     [(BrowserAppDelegate *)[[NSApplication sharedApplication] delegate] didChangeSettings];
165 }
166
167 - (void)toggleUseWebKit2ByDefault:(id)sender
168 {
169     [self _toggleBooleanDefault:UseWebKit2ByDefaultPreferenceKey];
170 }
171
172 - (BOOL)useWebKit2ByDefault
173 {
174     return [[NSUserDefaults standardUserDefaults] boolForKey:UseWebKit2ByDefaultPreferenceKey];
175 }
176
177 - (void)toggleUseTransparentWindows:(id)sender
178 {
179     [self _toggleBooleanDefault:UseTransparentWindowsPreferenceKey];
180 }
181
182 - (BOOL)useTransparentWindows
183 {
184     return [[NSUserDefaults standardUserDefaults] boolForKey:UseTransparentWindowsPreferenceKey];
185 }
186
187 - (void)toggleUsePaginatedMode:(id)sender
188 {
189     [self _toggleBooleanDefault:UsePaginatedModePreferenceKey];
190 }
191
192 - (BOOL)usePaginatedMode
193 {
194     return [[NSUserDefaults standardUserDefaults] boolForKey:UsePaginatedModePreferenceKey];
195 }
196
197 - (void)toggleUseUISideCompositing:(id)sender
198 {
199     [self _toggleBooleanDefault:UseRemoteLayerTreeDrawingAreaPreferenceKey];
200 }
201
202 - (BOOL)useUISideCompositing
203 {
204     return [[NSUserDefaults standardUserDefaults] boolForKey:UseRemoteLayerTreeDrawingAreaPreferenceKey];
205 }
206
207 - (void)toggleShowLayerBorders:(id)sender
208 {
209     [self _toggleBooleanDefault:LayerBordersVisiblePreferenceKey];
210 }
211
212 - (BOOL)layerBordersVisible
213 {
214     return [[NSUserDefaults standardUserDefaults] boolForKey:LayerBordersVisiblePreferenceKey];
215 }
216
217 - (void)toggleSimpleLineLayoutDebugBordersEnabled:(id)sender
218 {
219     [self _toggleBooleanDefault:SimpleLineLayoutDebugBordersEnabledPreferenceKey];
220 }
221
222 - (BOOL)simpleLineLayoutDebugBordersEnabled
223 {
224     return [[NSUserDefaults standardUserDefaults] boolForKey:SimpleLineLayoutDebugBordersEnabledPreferenceKey];
225 }
226
227 - (void)toggleShowTiledScrollingIndicator:(id)sender
228 {
229     [self _toggleBooleanDefault:TiledScrollingIndicatorVisiblePreferenceKey];
230 }
231
232 - (BOOL)tiledScrollingIndicatorVisible
233 {
234     return [[NSUserDefaults standardUserDefaults] boolForKey:TiledScrollingIndicatorVisiblePreferenceKey];
235 }
236
237 - (void)toggleEnableSubPixelCSSOMMetrics:(id)sender
238 {
239     [self _toggleBooleanDefault:EnableSubPixelCSSOMMetricsPreferenceKey];
240 }
241
242 - (BOOL)subPixelCSSOMMetricsEnabled
243 {
244     return [[NSUserDefaults standardUserDefaults] boolForKey:EnableSubPixelCSSOMMetricsPreferenceKey];
245 }
246
247 - (BOOL)nonFastScrollableRegionOverlayVisible
248 {
249     return [[NSUserDefaults standardUserDefaults] boolForKey:NonFastScrollableRegionOverlayVisiblePreferenceKey];
250 }
251
252 - (BOOL)wheelEventHandlerRegionOverlayVisible
253 {
254     return [[NSUserDefaults standardUserDefaults] boolForKey:WheelEventHandlerRegionOverlayVisiblePreferenceKey];
255 }
256
257 - (NSString *)preferenceKeyForRegionOverlayTag:(NSUInteger)tag
258 {
259     switch (tag) {
260     case NonFastScrollableRegionOverlayTag:
261         return NonFastScrollableRegionOverlayVisiblePreferenceKey;
262
263     case WheelEventHandlerRegionOverlayTag:
264         return WheelEventHandlerRegionOverlayVisiblePreferenceKey;
265     }
266     return nil;
267 }
268
269 - (void)toggleDebugOverlay:(id)sender
270 {
271     NSString *preferenceKey = [self preferenceKeyForRegionOverlayTag:[sender tag]];
272     if (preferenceKey)
273         [self _toggleBooleanDefault:preferenceKey];
274 }
275
276 - (BOOL)debugOverlayVisible:(NSMenuItem *)menuItem
277 {
278     NSString *preferenceKey = [self preferenceKeyForRegionOverlayTag:[menuItem tag]];
279     if (preferenceKey)
280         return [[NSUserDefaults standardUserDefaults] boolForKey:preferenceKey];
281
282     return NO;
283 }
284
285 - (NSString *)defaultURL
286 {
287     NSString *customDefaultURL = [[NSUserDefaults standardUserDefaults] stringForKey:DefaultURLPreferenceKey];
288     if (customDefaultURL)
289         return customDefaultURL;
290     return defaultURL;
291 }
292
293 @end