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