WKR does not include my nick when commit-queue lands my patch
[WebKit-https.git] / Tools / MiniBrowser / mac / WK1BrowserWindowController.m
1 /*
2  * Copyright (C) 2010 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 "WK1BrowserWindowController.h"
27
28 #import "AppDelegate.h"
29 #import "SettingsController.h"
30 #import <WebKit/WebKit.h>
31 #import <WebKit/WebNSURLExtras.h>
32 #import <WebKit/WebPreferences.h>
33 #import <WebKit/WebPreferencesPrivate.h>
34 #import <WebKit/WebPreferenceKeysPrivate.h>
35 #import <WebKit/WebViewPrivate.h>
36
37 @interface WK1BrowserWindowController () <WebFrameLoadDelegate, WebPolicyDelegate, WebResourceLoadDelegate, WebUIDelegate>
38 @end
39
40 @implementation WK1BrowserWindowController
41
42 - (void)awakeFromNib
43 {
44     _webView = [[WebView alloc] initWithFrame:[containerView bounds] frameName:nil groupName:@"MiniBrowser"];
45     [_webView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
46
47     _webView.editable = self.isEditable;
48
49     [_webView setFrameLoadDelegate:self];
50     [_webView setUIDelegate:self];
51     [_webView setResourceLoadDelegate:self];
52     [_webView setPolicyDelegate:self];
53
54     [[WebPreferences standardPreferences] setFullScreenEnabled:YES];
55     [[WebPreferences standardPreferences] setDeveloperExtrasEnabled:YES];
56     [[WebPreferences standardPreferences] setImageControlsEnabled:YES];
57     [[WebPreferences standardPreferences] setServiceControlsEnabled:YES];
58     [[WebPreferences standardPreferences] setJavaScriptCanOpenWindowsAutomatically:YES];
59
60     [_webView _listenForLayoutMilestones:WebDidFirstLayout | WebDidFirstVisuallyNonEmptyLayout | WebDidHitRelevantRepaintedObjectsAreaThreshold];
61
62     [self didChangeSettings];
63
64     [containerView addSubview:_webView];
65 }
66
67 - (void)dealloc
68 {
69     [_webView setFrameLoadDelegate:nil];
70     [_webView setUIDelegate:nil];
71     [_webView setResourceLoadDelegate:nil];
72     [_webView release];
73
74     [super dealloc];
75 }
76
77 - (void)loadURLString:(NSString *)urlString
78 {
79     // FIXME: We shouldn't have to set the url text here.
80     [urlText setStringValue:urlString];
81     [self fetch:nil];
82 }
83
84 - (void)loadHTMLString:(NSString *)HTMLString
85 {
86     [_webView.mainFrame loadHTMLString:HTMLString baseURL:nil];
87 }
88
89 - (IBAction)fetch:(id)sender
90 {
91     [urlText setStringValue:[self addProtocolIfNecessary:[urlText stringValue]]];
92     NSURL *url = [NSURL _webkit_URLWithUserTypedString:urlText.stringValue];
93     [[_webView mainFrame] loadRequest:[NSURLRequest requestWithURL:url]];
94 }
95
96 - (IBAction)setPageScale:(id)sender
97 {
98     CGFloat scale = [self pageScaleForMenuItemTag:[sender tag]];
99     [_webView _scaleWebView:scale atOrigin:NSZeroPoint];
100 }
101
102 - (IBAction)setViewScale:(id)sender
103 {
104 }
105
106 - (IBAction)reload:(id)sender
107 {
108     [_webView reload:sender];
109 }
110
111 - (IBAction)forceRepaint:(id)sender
112 {
113     [_webView setNeedsDisplay:YES];
114 }
115
116 - (IBAction)goBack:(id)sender
117 {
118     [_webView goBack:sender];
119 }
120
121 - (IBAction)goForward:(id)sender
122 {
123     [_webView goForward:sender];
124 }
125
126 static BOOL areEssentiallyEqual(double a, double b)
127 {
128     double tolerance = 0.001;
129     return (fabs(a - b) <= tolerance);
130 }
131
132 - (BOOL)validateMenuItem:(NSMenuItem *)menuItem
133 {
134     SEL action = [menuItem action];
135
136     if (action == @selector(zoomIn:))
137         return [self canZoomIn];
138     if (action == @selector(zoomOut:))
139         return [self canZoomOut];
140     if (action == @selector(resetZoom:))
141         return [self canResetZoom];
142
143     if (action == @selector(showHideWebView:))
144         [menuItem setTitle:[_webView isHidden] ? @"Show Web View" : @"Hide Web View"];
145     else if (action == @selector(removeReinsertWebView:))
146         [menuItem setTitle:[_webView window] ? @"Remove Web View" : @"Insert Web View"];
147     else if (action == @selector(toggleZoomMode:))
148         [menuItem setState:_zoomTextOnly ? NSOnState : NSOffState];
149     else if (action == @selector(toggleEditable:))
150         [menuItem setState:self.isEditable ? NSOnState : NSOffState];
151
152     if (action == @selector(setPageScale:))
153         [menuItem setState:areEssentiallyEqual([_webView _viewScaleFactor], [self pageScaleForMenuItemTag:[menuItem tag]])];
154
155     return YES;
156 }
157
158 - (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)item
159 {
160     SEL action = [item action];
161
162     if (action == @selector(goBack:))
163         return [_webView canGoBack];
164     
165     if (action == @selector(goForward:))
166         return [_webView canGoForward];
167     
168     return YES;
169 }
170
171 - (void)validateToolbar
172 {
173     [toolbar validateVisibleItems];
174 }
175
176 - (BOOL)windowShouldClose:(id)sender
177 {
178     return YES;
179 }
180
181 - (void)windowWillClose:(NSNotification *)notification
182 {
183     [(BrowserAppDelegate *)[[NSApplication sharedApplication] delegate] browserWindowWillClose:self.window];
184     [self autorelease];
185 }
186
187 - (double)currentZoomFactor
188 {
189     return 1;
190 }
191
192 - (BOOL)canZoomIn
193 {
194     return [_webView canMakeTextLarger];
195 }
196
197 - (void)zoomIn:(id)sender
198 {
199     if (![self canZoomIn])
200         return;
201
202     [_webView makeTextLarger:sender];
203 }
204
205 - (BOOL)canZoomOut
206 {
207     return [_webView canMakeTextSmaller];
208 }
209
210 - (void)zoomOut:(id)sender
211 {
212     if (![self canZoomIn])
213         return;
214
215     [_webView makeTextSmaller:sender];
216 }
217
218 - (BOOL)canResetZoom
219 {
220     return [_webView canMakeTextStandardSize];
221 }
222
223 - (void)resetZoom:(id)sender
224 {
225     if (![self canResetZoom])
226         return;
227
228     [_webView makeTextStandardSize:sender];
229 }
230
231 - (IBAction)toggleZoomMode:(id)sender
232 {
233     // FIXME: non-text zoom not implemented.
234     _zoomTextOnly = !_zoomTextOnly;
235 }
236
237 - (IBAction)toggleShrinkToFit:(id)sender
238 {
239 }
240
241 - (IBAction)dumpSourceToConsole:(id)sender
242 {
243 }
244
245 - (NSURL *)currentURL
246 {
247     return _webView.mainFrame.dataSource.request.URL;
248 }
249
250 - (NSView *)mainContentView
251 {
252     return _webView;
253 }
254
255 - (void)setEditable:(BOOL)editable
256 {
257     [super setEditable:editable];
258     _webView.editable = editable;
259 }
260
261 - (void)didChangeSettings
262 {
263     SettingsController *settings = [SettingsController shared];
264
265     [[WebPreferences standardPreferences] setSubpixelCSSOMElementMetricsEnabled:settings.subPixelCSSOMMetricsEnabled];
266     [[WebPreferences standardPreferences] setShowDebugBorders:settings.layerBordersVisible];
267     [[WebPreferences standardPreferences] setSimpleLineLayoutDebugBordersEnabled:settings.simpleLineLayoutDebugBordersEnabled];
268     [[WebPreferences standardPreferences] setShowRepaintCounter:settings.layerBordersVisible];
269     [[WebPreferences standardPreferences] setSuppressesIncrementalRendering:settings.incrementalRenderingSuppressed];
270     [[WebPreferences standardPreferences] setAcceleratedDrawingEnabled:settings.acceleratedDrawingEnabled];
271     [[WebPreferences standardPreferences] setResourceLoadStatisticsEnabled:settings.resourceLoadStatisticsEnabled];
272     [[WebPreferences standardPreferences] setVisualViewportEnabled:settings.visualViewportEnabled];
273     [[WebPreferences standardPreferences] setLargeImageAsyncDecodingEnabled:settings.largeImageAsyncDecodingEnabled];
274     [[WebPreferences standardPreferences] setAnimatedImageAsyncDecodingEnabled:settings.animatedImageAsyncDecodingEnabled];
275
276     BOOL useTransparentWindows = settings.useTransparentWindows;
277     if (useTransparentWindows != !self.window.isOpaque) {
278         [self.window setOpaque:!useTransparentWindows];
279         [self.window setBackgroundColor:[NSColor clearColor]];
280         [self.window setHasShadow:!useTransparentWindows];
281
282         [_webView setBackgroundColor:useTransparentWindows ? [NSColor clearColor] : [NSColor whiteColor]];
283
284         [self.window display];
285     }
286
287     BOOL usePaginatedMode = settings.usePaginatedMode;
288     if (usePaginatedMode != (_webView._paginationMode != WebPaginationModeUnpaginated)) {
289         if (usePaginatedMode) {
290             [_webView _setPaginationMode:WebPaginationModeLeftToRight];
291             [_webView _setPageLength:_webView.bounds.size.width / 2];
292             [_webView _setGapBetweenPages:10];
293         } else
294             [_webView _setPaginationMode:WebPaginationModeUnpaginated];
295     }
296 }
297
298 - (IBAction)printWebView:(id)sender
299 {
300     [[[[_webView mainFrame] frameView] printOperationWithPrintInfo:[NSPrintInfo sharedPrintInfo]] runOperationModalForWindow:self.window delegate:nil didRunSelector:nil contextInfo:nil];
301 }
302
303 - (void)webView:(WebView *)sender didLayout:(WebLayoutMilestones)milestones
304 {
305     if (milestones & WebDidFirstLayout)
306         LOG(@"layout milestone: %@", @"first layout");
307
308     if (milestones & WebDidFirstVisuallyNonEmptyLayout)
309         LOG(@"layout milestone: %@", @"first non-empty layout");
310
311     if (milestones & WebDidHitRelevantRepaintedObjectsAreaThreshold)
312         LOG(@"layout milestone: %@", @"relevant repainted objects area threshold");
313 }
314
315 - (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id<WebPolicyDecisionListener>)listener
316 {
317     [listener use];
318 }
319
320 // WebFrameLoadDelegate Methods
321 - (void)webView:(WebView *)sender didStartProvisionalLoadForFrame:(WebFrame *)frame
322 {
323 }
324
325 - (void)updateTitle:(NSString *)title
326 {
327     if (!title) {
328         NSURL *url = _webView.mainFrame.dataSource.request.URL;
329         title = url.lastPathComponent ?: url._web_userVisibleString;
330     }
331
332     [self.window setTitle:[title stringByAppendingFormat:@" [WK1]%@", _webView.editable ? @" [Editable]" : @""]];
333 }
334
335 - (WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request
336 {
337     WK1BrowserWindowController *newBrowserWindowController = [[WK1BrowserWindowController alloc] initWithWindowNibName:@"BrowserWindow"];
338     [newBrowserWindowController.window makeKeyAndOrderFront:self];
339
340     return newBrowserWindowController->_webView;
341 }
342
343 - (void)webView:(WebView *)sender didCommitLoadForFrame:(WebFrame *)frame
344 {
345     if (frame != [sender mainFrame])
346         return;
347
348     NSURL *committedURL = [[[frame dataSource] request] URL];
349     urlText.stringValue = committedURL._web_userVisibleString;
350
351     [self updateTitle:nil];
352 }
353
354 - (void)webView:(WebView *)sender didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame
355 {
356     if (frame != [sender mainFrame])
357         return;
358
359     [self updateTitle:title];
360 }
361
362 - (NSArray *)webView:(WebView *)sender contextMenuItemsForElement:(NSDictionary *)element defaultMenuItems:(NSArray *)defaultMenuItems
363 {
364     return defaultMenuItems;
365 }
366
367 - (void)webView:(WebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame
368 {
369     NSAlert *alert = [[NSAlert alloc] init];
370     [alert addButtonWithTitle:@"OK"];
371
372     alert.messageText = [NSString stringWithFormat:@"JavaScript alert dialog from %@.", frame.dataSource.request.URL.absoluteString];
373     alert.informativeText = message;
374
375     [alert runModal];
376     [alert release];
377 }
378
379 - (BOOL)webView:(WebView *)sender runBeforeUnloadConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame
380 {
381     NSAlert *alert = [[NSAlert alloc] init];
382
383     alert.messageText = [NSString stringWithFormat:@"JavaScript before unload dialog from %@.", frame.dataSource.request.URL.absoluteString];
384     alert.informativeText = message;
385
386     [alert addButtonWithTitle:@"Leave Page"];
387     [alert addButtonWithTitle:@"Stay On Page"];
388
389     NSModalResponse response = [alert runModal];
390     
391     [alert release];
392
393     return response == NSAlertFirstButtonReturn;
394 }
395
396 @end