200ae9d57278e3c315ae392460dc61af359d9340
[WebKit-https.git] / Tools / WebEditingTester / AppDelegate.m
1 /*
2  * Copyright (C) 2015 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 "AppDelegate.h"
27
28 #import "CannedContent.h"
29 #import "EditingOperations.h"
30 #import "WK1WebDocumentController.h"
31 #import "WK2WebDocumentController.h"
32 #import <WebKit/WKBrowsingContextController.h>
33
34 static NSString * const UseWebKit2ByDefaultPreferenceKey = @"UseWebKit2ByDefault";
35
36 @implementation WebEditingAppDelegate {
37     Class _openingDocumentController;
38 }
39
40 - (id)init
41 {
42     self = [super init];
43     if (self)
44         _webDocuments = [[NSMutableSet alloc] init];
45     
46     return self;
47 }
48
49 - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
50 {
51     [NSURLProtocol registerClass:[CannedContent class]];
52     [WKBrowsingContextController registerSchemeForCustomProtocol:@"canned"];
53
54     [self newEditor:self];
55     [self _updateNewWindowKeyEquivalents];
56 }
57
58 - (IBAction)newEditor:(id)sender
59 {
60     Class controllerClass;
61
62     if (sender == self)
63         controllerClass = self._defaultWebDocumentControllerClass;
64     else if (sender == _newWebKit2EditorItem)
65         controllerClass = [WK2WebDocumentController class];
66     else if (sender == _newWebKit1EditorItem)
67         controllerClass = [WK1WebDocumentController class];
68     
69     WebDocumentController *controller = [[controllerClass alloc] init];
70     [[controller window] makeKeyAndOrderFront:sender];
71     [_webDocuments addObject:controller];
72     [controller loadHTMLString:[WebDocumentController defaultEditingSource]];
73 }
74
75 - (IBAction)showOperations:(id)sender
76 {
77     static BOOL initialized = NO;
78
79     if (!initialized) {
80         NSFont *font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSMiniControlSize]];
81         NSDictionary *attributes = [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName];
82         NSArray *operations = editingOperations();
83         
84         float maxWidth = 0;
85         for (NSString *operationName in operations)
86             maxWidth = MAX(maxWidth, [operationName sizeWithAttributes:attributes].width);
87
88         maxWidth += 24;
89         
90         unsigned long columnHeight = (operations.count + 2) / 3;
91         
92         NSView *superview = [_operationsPanel contentView];
93         
94         [_operationsPanel setContentSize:NSMakeSize(3 * maxWidth, columnHeight * 16 + 1)];
95         
96         float firstY = NSMaxY([superview frame]) - 1;
97         float y = firstY;
98         float x = 0;
99         for (NSString *operationName in operations) {
100             y -= 16;
101             if (y < 0) {
102                 y = firstY - 16;
103                 x += maxWidth;
104             }
105             NSButton *button = [[NSButton alloc] initWithFrame:NSMakeRect(x, y, maxWidth, 16)];
106             [button setBezelStyle:NSRoundedBezelStyle];
107             [button.cell setControlSize:NSMiniControlSize];
108             [button setFont:font];
109             [button setTitle:operationName];
110             [button setAction:NSSelectorFromString(operationName)];
111             [superview addSubview:button];
112         }
113         
114         [_operationsPanel center];
115         [_operationsPanel setFloatingPanel:YES];
116         [_operationsPanel setBecomesKeyOnlyIfNeeded:YES];
117         initialized = YES;
118     }
119
120     [_operationsPanel orderFront:nil];
121 }
122
123 - (Class)_defaultWebDocumentControllerClass
124 {
125     return self.useWebKit2ByDefault ? [WK2WebDocumentController class] : [WK1WebDocumentController class];
126 }
127
128 - (BOOL)useWebKit2ByDefault
129 {
130     return [[NSUserDefaults standardUserDefaults] boolForKey:UseWebKit2ByDefaultPreferenceKey];
131 }
132
133 - (IBAction)toggleUseWebKit2ByDefault:(id)sender
134 {
135     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
136     [defaults setBool:![defaults boolForKey:UseWebKit2ByDefaultPreferenceKey] forKey:UseWebKit2ByDefaultPreferenceKey];
137     [self _updateNewWindowKeyEquivalents];
138 }
139
140 - (BOOL)validateMenuItem:(NSMenuItem *)menuItem
141 {
142     SEL action = [menuItem action];
143     
144     if (action == @selector(toggleUseWebKit2ByDefault:))
145         [menuItem setState:[self useWebKit2ByDefault] ? NSOnState : NSOffState];
146     
147     return YES;
148 }
149
150 - (void)_openDocumentWithWebKit1:(id)sender
151 {
152     _openingDocumentController = [WK1WebDocumentController class];
153 }
154
155 - (void)_openDocumentWithWebKit2:(id)sender
156 {
157     _openingDocumentController = [WK2WebDocumentController class];
158 }
159
160 - (IBAction)openDocument:(id)sender
161 {
162     _openingDocumentController = self._defaultWebDocumentControllerClass;
163
164     NSButtonCell *radioButtonPrototype = [[NSButtonCell alloc] init];
165     radioButtonPrototype.buttonType = NSRadioButton;
166
167     NSMatrix *openPanelAccessoryView = [[NSMatrix alloc] initWithFrame:NSZeroRect mode:NSRadioModeMatrix prototype:radioButtonPrototype numberOfRows:2 numberOfColumns:1];
168     openPanelAccessoryView.autorecalculatesCellSize = YES;
169     openPanelAccessoryView.autosizesCells = YES;
170     NSArray *cells = openPanelAccessoryView.cells;
171     [[cells objectAtIndex:0] setTitle:@"Open with WebKit1"];
172     [[cells objectAtIndex:0] setAction:@selector(_openDocumentWithWebKit1:)];
173     [[cells objectAtIndex:0] setState:!self.useWebKit2ByDefault];
174     [[cells objectAtIndex:1] setTitle:@"Open with WebKit2"];
175     [[cells objectAtIndex:1] setAction:@selector(_openDocumentWithWebKit2:)];
176     [[cells objectAtIndex:1] setState:self.useWebKit2ByDefault];
177     [openPanelAccessoryView sizeToFit];
178
179     NSOpenPanel *panel = [NSOpenPanel openPanel];
180     [panel setAccessoryView:openPanelAccessoryView];
181
182     [panel beginWithCompletionHandler:^(NSInteger result) {
183         if (result != NSFileHandlingPanelOKButton)
184             return;
185
186         NSURL *URL = panel.URLs.lastObject;
187         [self application:[NSApplication sharedApplication] openFile:URL.path];
188         _openingDocumentController = nil;
189     }];
190 }
191
192 - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
193 {
194     Class controllerClass = _openingDocumentController ? _openingDocumentController : self._defaultWebDocumentControllerClass;
195     WebDocumentController *controller = [[controllerClass alloc] init];
196     [controller.window makeKeyAndOrderFront:nil];
197     [_webDocuments addObject:controller];
198     [controller loadHTMLString:[NSString stringWithContentsOfFile:filename encoding:NSUTF8StringEncoding error:nil]];
199     return YES;
200 }
201
202 - (void)_updateNewWindowKeyEquivalents
203 {
204     if (self.useWebKit2ByDefault) {
205         [_newWebKit1EditorItem setKeyEquivalentModifierMask:NSCommandKeyMask | NSAlternateKeyMask];
206         [_newWebKit2EditorItem setKeyEquivalentModifierMask:NSCommandKeyMask];
207     } else {
208         [_newWebKit1EditorItem setKeyEquivalentModifierMask:NSCommandKeyMask];
209         [_newWebKit2EditorItem setKeyEquivalentModifierMask:NSCommandKeyMask | NSAlternateKeyMask];
210     }
211 }
212
213 - (void)performTextFinderAction:(id)sender
214 {
215     id keyWindowDelegate = [NSApplication sharedApplication].keyWindow.delegate;
216     if (![keyWindowDelegate isKindOfClass:[WebDocumentController class]])
217         return;
218     [(WebDocumentController *)keyWindowDelegate performTextFinderAction:sender];
219 }
220
221 @end