f3abd9f342ebca61124afb9c406b5622aaa3b9cc
[WebKit-https.git] / Tools / MiniBrowser / mac / WK2BrowserWindowController.m
1 /*
2  * Copyright (C) 2010-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 "WK2BrowserWindowController.h"
27
28 #if WK_API_ENABLED
29
30 #import "AppDelegate.h"
31 #import "SettingsController.h"
32 #import <WebKit/WKFrameInfo.h>
33 #import <WebKit/WKNavigationActionPrivate.h>
34 #import <WebKit/WKNavigationDelegate.h>
35 #import <WebKit/WKPreferencesPrivate.h>
36 #import <WebKit/WKUIDelegate.h>
37 #import <WebKit/WKWebViewConfigurationPrivate.h>
38 #import <WebKit/WKWebViewPrivate.h>
39 #import <WebKit/WKWebsiteDataStorePrivate.h>
40 #import <WebKit/WebNSURLExtras.h>
41 #import <WebKit/_WKUserInitiatedAction.h>
42
43 static void* keyValueObservingContext = &keyValueObservingContext;
44
45 @interface WK2BrowserWindowController () <WKNavigationDelegate, WKUIDelegate>
46 @end
47
48 @implementation WK2BrowserWindowController {
49     WKWebViewConfiguration *_configuration;
50     WKWebView *_webView;
51     BOOL _zoomTextOnly;
52     BOOL _isPrivateBrowsingWindow;
53
54     BOOL _useShrinkToFit;
55 }
56
57 - (void)awakeFromNib
58 {
59     _webView = [[WKWebView alloc] initWithFrame:[containerView bounds] configuration:_configuration];
60     [self didChangeSettings];
61
62     _webView.allowsMagnification = YES;
63     _webView.allowsBackForwardNavigationGestures = YES;
64
65     [_webView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
66     [containerView addSubview:_webView];
67
68     [progressIndicator bind:NSHiddenBinding toObject:_webView withKeyPath:@"loading" options:@{ NSValueTransformerNameBindingOption : NSNegateBooleanTransformerName }];
69     [progressIndicator bind:NSValueBinding toObject:_webView withKeyPath:@"estimatedProgress" options:nil];
70
71     [_webView addObserver:self forKeyPath:@"title" options:0 context:keyValueObservingContext];
72     [_webView addObserver:self forKeyPath:@"URL" options:0 context:keyValueObservingContext];
73
74     _webView.navigationDelegate = self;
75     _webView.UIDelegate = self;
76     
77     _webView._observedRenderingProgressEvents = _WKRenderingProgressEventFirstLayout
78         | _WKRenderingProgressEventFirstVisuallyNonEmptyLayout
79         | _WKRenderingProgressEventFirstPaintWithSignificantArea
80         | _WKRenderingProgressEventFirstLayoutAfterSuppressedIncrementalRendering
81         | _WKRenderingProgressEventFirstPaintAfterSuppressedIncrementalRendering;
82
83     _zoomTextOnly = NO;
84 }
85
86 - (instancetype)initWithConfiguration:(WKWebViewConfiguration *)configuration
87 {
88     if (!(self = [super initWithWindowNibName:@"BrowserWindow"]))
89         return nil;
90
91     _configuration = [configuration copy];
92     _isPrivateBrowsingWindow = !_configuration.websiteDataStore.isPersistent;
93
94     return self;
95 }
96
97 - (void)dealloc
98 {
99     [_webView removeObserver:self forKeyPath:@"title"];
100     [_webView removeObserver:self forKeyPath:@"URL"];
101     
102     [progressIndicator unbind:NSHiddenBinding];
103     [progressIndicator unbind:NSValueBinding];
104
105     [_webView release];
106     [_configuration release];
107
108     [super dealloc];
109 }
110
111 - (IBAction)fetch:(id)sender
112 {
113     [urlText setStringValue:[self addProtocolIfNecessary:[urlText stringValue]]];
114
115     [_webView loadRequest:[NSURLRequest requestWithURL:[NSURL _webkit_URLWithUserTypedString:[urlText stringValue]]]];
116 }
117
118 - (IBAction)showHideWebView:(id)sender
119 {
120     BOOL hidden = ![_webView isHidden];
121     
122     [_webView setHidden:hidden];
123 }
124
125 - (IBAction)removeReinsertWebView:(id)sender
126 {
127     if ([_webView window]) {
128         [_webView retain];
129         [_webView removeFromSuperview]; 
130     } else {
131         [containerView addSubview:_webView];
132         [_webView release];
133     }
134 }
135
136 - (IBAction)setPageScale:(id)sender
137 {
138     CGFloat scale = [self pageScaleForMenuItemTag:[sender tag]];
139     [_webView _setPageScale:scale withOrigin:CGPointZero];
140 }
141
142 - (CGFloat)viewScaleForMenuItemTag:(NSInteger)tag
143 {
144     if (tag == 1)
145         return 1;
146     if (tag == 2)
147         return 0.75;
148     if (tag == 3)
149         return 0.5;
150     if (tag == 4)
151         return 0.25;
152
153     return 1;
154 }
155
156 - (IBAction)setViewScale:(id)sender
157 {
158     CGFloat scale = [self viewScaleForMenuItemTag:[sender tag]];
159     CGFloat oldScale = [_webView _viewScale];
160
161     if (scale == oldScale)
162         return;
163
164     [_webView _setLayoutMode:_WKLayoutModeDynamicSizeComputedFromViewScale];
165
166     NSRect oldFrame = self.window.frame;
167     NSSize newFrameSize = NSMakeSize(oldFrame.size.width * (scale / oldScale), oldFrame.size.height * (scale / oldScale));
168     [self.window setFrame:NSMakeRect(oldFrame.origin.x, oldFrame.origin.y - (newFrameSize.height - oldFrame.size.height), newFrameSize.width, newFrameSize.height) display:NO animate:NO];
169
170     [_webView _setViewScale:scale];
171 }
172
173 static BOOL areEssentiallyEqual(double a, double b)
174 {
175     double tolerance = 0.001;
176     return (fabs(a - b) <= tolerance);
177 }
178
179 - (BOOL)validateMenuItem:(NSMenuItem *)menuItem
180 {
181     SEL action = [menuItem action];
182
183     if (action == @selector(zoomIn:))
184         return [self canZoomIn];
185     if (action == @selector(zoomOut:))
186         return [self canZoomOut];
187     if (action == @selector(resetZoom:))
188         return [self canResetZoom];
189     
190     // Disabled until missing WK2 functionality is exposed via API/SPI.
191     if (action == @selector(dumpSourceToConsole:)
192         || action == @selector(find:)
193         || action == @selector(forceRepaint:))
194         return NO;
195     
196     if (action == @selector(showHideWebView:))
197         [menuItem setTitle:[_webView isHidden] ? @"Show Web View" : @"Hide Web View"];
198     else if (action == @selector(removeReinsertWebView:))
199         [menuItem setTitle:[_webView window] ? @"Remove Web View" : @"Insert Web View"];
200     else if (action == @selector(toggleZoomMode:))
201         [menuItem setState:_zoomTextOnly ? NSOnState : NSOffState];
202
203     if (action == @selector(setPageScale:))
204         [menuItem setState:areEssentiallyEqual([_webView _pageScale], [self pageScaleForMenuItemTag:[menuItem tag]])];
205
206     if (action == @selector(setViewScale:))
207         [menuItem setState:areEssentiallyEqual([_webView _viewScale], [self viewScaleForMenuItemTag:[menuItem tag]])];
208
209     return YES;
210 }
211
212 - (IBAction)reload:(id)sender
213 {
214     [_webView reload];
215 }
216
217 - (IBAction)forceRepaint:(id)sender
218 {
219     // FIXME: This doesn't actually force a repaint.
220     [_webView setNeedsDisplay:YES];
221 }
222
223 - (IBAction)goBack:(id)sender
224 {
225     [_webView goBack];
226 }
227
228 - (IBAction)goForward:(id)sender
229 {
230     [_webView goForward];
231 }
232
233 - (IBAction)toggleZoomMode:(id)sender
234 {
235     if (_zoomTextOnly) {
236         _zoomTextOnly = NO;
237         double currentTextZoom = _webView._textZoomFactor;
238         _webView._textZoomFactor = 1;
239         _webView._pageZoomFactor = currentTextZoom;
240     } else {
241         _zoomTextOnly = YES;
242         double currentPageZoom = _webView._pageZoomFactor;
243         _webView._textZoomFactor = currentPageZoom;
244         _webView._pageZoomFactor = 1;
245     }
246 }
247
248 - (IBAction)resetZoom:(id)sender
249 {
250     if (![self canResetZoom])
251         return;
252
253     if (_zoomTextOnly)
254         _webView._textZoomFactor = 1;
255     else
256         _webView._pageZoomFactor = 1;
257 }
258
259 - (BOOL)canResetZoom
260 {
261     return _zoomTextOnly ? (_webView._textZoomFactor != 1) : (_webView._pageZoomFactor != 1);
262 }
263
264 - (IBAction)toggleShrinkToFit:(id)sender
265 {
266     _useShrinkToFit = !_useShrinkToFit;
267     toggleUseShrinkToFitButton.image = _useShrinkToFit ? [NSImage imageNamed:@"NSExitFullScreenTemplate"] : [NSImage imageNamed:@"NSEnterFullScreenTemplate"];
268     [_webView _setLayoutMode:_useShrinkToFit ? _WKLayoutModeDynamicSizeComputedFromMinimumDocumentSize : _WKLayoutModeViewSize];
269 }
270
271 - (IBAction)dumpSourceToConsole:(id)sender
272 {
273 }
274
275 - (NSURL *)currentURL
276 {
277     return _webView.URL;
278 }
279
280 - (NSView *)mainContentView
281 {
282     return _webView;
283 }
284
285 - (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)item
286 {
287     SEL action = item.action;
288
289     if (action == @selector(goBack:) || action == @selector(goForward:))
290         return [_webView validateUserInterfaceItem:item];
291
292     return YES;
293 }
294
295 - (void)validateToolbar
296 {
297     [toolbar validateVisibleItems];
298 }
299
300 - (BOOL)windowShouldClose:(id)sender
301 {
302     return YES;
303 }
304
305 - (void)windowWillClose:(NSNotification *)notification
306 {
307     [(BrowserAppDelegate *)[[NSApplication sharedApplication] delegate] browserWindowWillClose:self.window];
308     [self autorelease];
309 }
310
311 - (void)applicationTerminating
312 {
313 }
314
315 #define DefaultMinimumZoomFactor (.5)
316 #define DefaultMaximumZoomFactor (3.0)
317 #define DefaultZoomFactorRatio (1.2)
318
319 - (CGFloat)currentZoomFactor
320 {
321     return _zoomTextOnly ? _webView._textZoomFactor : _webView._pageZoomFactor;
322 }
323
324 - (void)setCurrentZoomFactor:(CGFloat)factor
325 {
326     if (_zoomTextOnly)
327         _webView._textZoomFactor = factor;
328     else
329         _webView._pageZoomFactor = factor;
330 }
331
332 - (BOOL)canZoomIn
333 {
334     return self.currentZoomFactor * DefaultZoomFactorRatio < DefaultMaximumZoomFactor;
335 }
336
337 - (void)zoomIn:(id)sender
338 {
339     if (!self.canZoomIn)
340         return;
341
342     self.currentZoomFactor *= DefaultZoomFactorRatio;
343 }
344
345 - (BOOL)canZoomOut
346 {
347     return self.currentZoomFactor / DefaultZoomFactorRatio > DefaultMinimumZoomFactor;
348 }
349
350 - (void)zoomOut:(id)sender
351 {
352     if (!self.canZoomIn)
353         return;
354
355     self.currentZoomFactor /= DefaultZoomFactorRatio;
356 }
357
358 - (void)didChangeSettings
359 {
360     SettingsController *settings = [SettingsController shared];
361     WKPreferences *preferences = _webView.configuration.preferences;
362
363     preferences._tiledScrollingIndicatorVisible = settings.tiledScrollingIndicatorVisible;
364     preferences._compositingBordersVisible = settings.layerBordersVisible;
365     preferences._compositingRepaintCountersVisible = settings.layerBordersVisible;
366     preferences._simpleLineLayoutDebugBordersEnabled = settings.simpleLineLayoutDebugBordersEnabled;
367     preferences._acceleratedDrawingEnabled = settings.acceleratedDrawingEnabled;
368     preferences._resourceUsageOverlayVisible = settings.resourceUsageOverlayVisible;
369     preferences._displayListDrawingEnabled = settings.displayListDrawingEnabled;
370     preferences._visualViewportEnabled = settings.visualViewportEnabled;
371     preferences._largeImageAsyncDecodingEnabled = settings.largeImageAsyncDecodingEnabled;
372     preferences._animatedImageAsyncDecodingEnabled = settings.animatedImageAsyncDecodingEnabled;
373
374     _webView.configuration.websiteDataStore._resourceLoadStatisticsEnabled = settings.resourceLoadStatisticsEnabled;
375
376     BOOL useTransparentWindows = settings.useTransparentWindows;
377     if (useTransparentWindows != !_webView._drawsBackground) {
378         [self.window setOpaque:!useTransparentWindows];
379         [self.window setBackgroundColor:[NSColor clearColor]];
380         [self.window setHasShadow:!useTransparentWindows];
381
382         _webView._drawsBackground = !useTransparentWindows;
383
384         [self.window display];
385     }
386
387     BOOL usePaginatedMode = settings.usePaginatedMode;
388     if (usePaginatedMode != (_webView._paginationMode != _WKPaginationModeUnpaginated)) {
389         if (usePaginatedMode) {
390             _webView._paginationMode = _WKPaginationModeLeftToRight;
391             _webView._pageLength = _webView.bounds.size.width / 2;
392             _webView._gapBetweenPages = 10;
393         } else
394             _webView._paginationMode = _WKPaginationModeUnpaginated;
395     }
396     
397     NSUInteger visibleOverlayRegions = 0;
398     if (settings.nonFastScrollableRegionOverlayVisible)
399         visibleOverlayRegions |= _WKNonFastScrollableRegion;
400     if (settings.wheelEventHandlerRegionOverlayVisible)
401         visibleOverlayRegions |= _WKWheelEventHandlerRegion;
402     
403     preferences._visibleDebugOverlayRegions = visibleOverlayRegions;
404 }
405
406 - (void)updateTitle:(NSString *)title
407 {
408     if (!title) {
409         NSURL *url = _webView.URL;
410         title = url.lastPathComponent ?: url._web_userVisibleString;
411     }
412
413     self.window.title = [NSString stringWithFormat:@"%@%@ [WK2 %d]", _isPrivateBrowsingWindow ? @"🙈 " : @"", title, _webView._webProcessIdentifier];
414 }
415
416 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
417 {
418     if (context != keyValueObservingContext || object != _webView)
419         return;
420
421     if ([keyPath isEqualToString:@"title"])
422         [self updateTitle:_webView.title];
423     else if ([keyPath isEqualToString:@"URL"])
424         [self updateTextFieldFromURL:_webView.URL];
425 }
426
427 - (nullable WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures
428 {
429     WK2BrowserWindowController *controller = [[WK2BrowserWindowController alloc] initWithConfiguration:configuration];
430     [controller awakeFromNib];
431     [controller.window makeKeyAndOrderFront:self];
432
433     return controller->_webView;
434 }
435
436 - (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler
437 {
438     NSAlert* alert = [[NSAlert alloc] init];
439
440     [alert setMessageText:[NSString stringWithFormat:@"JavaScript alert dialog from %@.", [frame.request.URL absoluteString]]];
441     [alert setInformativeText:message];
442     [alert addButtonWithTitle:@"OK"];
443
444     [alert beginSheetModalForWindow:self.window completionHandler:^void (NSModalResponse response) {
445         completionHandler();
446         [alert release];
447     }];
448 }
449
450 - (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler
451 {
452     NSAlert* alert = [[NSAlert alloc] init];
453
454     [alert setMessageText:[NSString stringWithFormat:@"JavaScript confirm dialog from %@.", [frame.request.URL  absoluteString]]];
455     [alert setInformativeText:message];
456     
457     [alert addButtonWithTitle:@"OK"];
458     [alert addButtonWithTitle:@"Cancel"];
459
460     [alert beginSheetModalForWindow:self.window completionHandler:^void (NSModalResponse response) {
461         completionHandler(response == NSAlertFirstButtonReturn);
462         [alert release];
463     }];
464 }
465
466 - (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString *result))completionHandler
467 {
468     NSAlert* alert = [[NSAlert alloc] init];
469
470     [alert setMessageText:[NSString stringWithFormat:@"JavaScript prompt dialog from %@.", [frame.request.URL absoluteString]]];
471     [alert setInformativeText:prompt];
472     
473     [alert addButtonWithTitle:@"OK"];
474     [alert addButtonWithTitle:@"Cancel"];
475     
476     NSTextField* input = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 200, 24)];
477     [input setStringValue:defaultText];
478     [alert setAccessoryView:input];
479     
480     [alert beginSheetModalForWindow:self.window completionHandler:^void (NSModalResponse response) {
481         [input validateEditing];
482         completionHandler(response == NSAlertFirstButtonReturn ? [input stringValue] : nil);
483         [alert release];
484     }];
485 }
486
487 #if __has_feature(objc_generics)
488 - (void)webView:(WKWebView *)webView runOpenPanelWithParameters:(WKOpenPanelParameters *)parameters initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSArray<NSURL *> * URLs))completionHandler
489 #else
490 - (void)webView:(WKWebView *)webView runOpenPanelWithParameters:(WKOpenPanelParameters *)parameters initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSArray *URLs))completionHandler
491 #endif
492 {
493     NSOpenPanel *openPanel = [NSOpenPanel openPanel];
494
495     openPanel.allowsMultipleSelection = parameters.allowsMultipleSelection;
496
497     [openPanel beginSheetModalForWindow:webView.window completionHandler:^(NSInteger result) {
498         if (result == NSFileHandlingPanelOKButton)
499             completionHandler(openPanel.URLs);
500         else
501             completionHandler(nil);
502     }];
503 }
504
505 - (void)updateTextFieldFromURL:(NSURL *)URL
506 {
507     if (!URL)
508         return;
509
510     if (!URL.absoluteString.length)
511         return;
512
513     urlText.stringValue = [URL _web_userVisibleString];
514 }
515
516 - (void)loadURLString:(NSString *)urlString
517 {
518     // FIXME: We shouldn't have to set the url text here.
519     [urlText setStringValue:urlString];
520     [self fetch:nil];
521 }
522
523 - (IBAction)performFindPanelAction:(id)sender
524 {
525     [findPanelWindow makeKeyAndOrderFront:sender];
526 }
527
528 - (IBAction)find:(id)sender
529 {
530 }
531
532 static NSSet *dataTypes()
533 {
534     return [WKWebsiteDataStore allWebsiteDataTypes];
535 }
536
537 - (IBAction)fetchWebsiteData:(id)sender
538 {
539     [_configuration.websiteDataStore _fetchDataRecordsOfTypes:dataTypes() withOptions:_WKWebsiteDataStoreFetchOptionComputeSizes completionHandler:^(NSArray *websiteDataRecords) {
540         NSLog(@"did fetch website data %@.", websiteDataRecords);
541     }];
542 }
543
544 - (IBAction)fetchAndClearWebsiteData:(id)sender
545 {
546     [_configuration.websiteDataStore fetchDataRecordsOfTypes:dataTypes() completionHandler:^(NSArray *websiteDataRecords) {
547         [_configuration.websiteDataStore removeDataOfTypes:dataTypes() forDataRecords:websiteDataRecords completionHandler:^{
548             [_configuration.websiteDataStore fetchDataRecordsOfTypes:dataTypes() completionHandler:^(NSArray *websiteDataRecords) {
549                 NSLog(@"did clear website data, after clearing data is %@.", websiteDataRecords);
550             }];
551         }];
552     }];
553 }
554
555 - (IBAction)clearWebsiteData:(id)sender
556 {
557     [_configuration.websiteDataStore removeDataOfTypes:dataTypes() modifiedSince:[NSDate distantPast] completionHandler:^{
558         NSLog(@"Did clear website data.");
559     }];
560 }
561
562 - (IBAction)printWebView:(id)sender
563 {
564     [[_webView _printOperationWithPrintInfo:[NSPrintInfo sharedPrintInfo]] runOperationModalForWindow:self.window delegate:nil didRunSelector:nil contextInfo:nil];
565 }
566
567 #pragma mark WKNavigationDelegate
568
569 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
570 {
571     LOG(@"decidePolicyForNavigationAction");
572
573     if (navigationAction._canHandleRequest) {
574         decisionHandler(WKNavigationActionPolicyAllow);
575         return;
576     }
577
578     if (navigationAction._userInitiatedAction && !navigationAction._userInitiatedAction.isConsumed) {
579         [navigationAction._userInitiatedAction consume];
580         [[NSWorkspace sharedWorkspace] openURL:navigationAction.request.URL];
581     }
582
583     decisionHandler(WKNavigationActionPolicyCancel);
584 }
585
586 - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler
587 {
588     LOG(@"decidePolicyForNavigationResponse");
589     decisionHandler(WKNavigationResponsePolicyAllow);
590 }
591
592 - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation
593 {
594     LOG(@"didStartProvisionalNavigation: %@", navigation);
595 }
596
597 - (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation
598 {
599     LOG(@"didReceiveServerRedirectForProvisionalNavigation: %@", navigation);
600 }
601
602 - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error
603 {
604     LOG(@"didFailProvisionalNavigation: %@navigation, error: %@", navigation, error);
605 }
606
607 - (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation
608 {
609     LOG(@"didCommitNavigation: %@", navigation);
610     [self updateTitle:nil];
611 }
612
613 - (void)webView:(WKWebView *)webView didFinishLoadingNavigation:(WKNavigation *)navigation
614 {
615     LOG(@"didFinishLoadingNavigation: %@", navigation);
616 }
617
618 - (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *__nullable credential))completionHandler
619 {
620     LOG(@"didReceiveAuthenticationChallenge: %@", challenge);
621     completionHandler(NSURLSessionAuthChallengeRejectProtectionSpace, nil);
622 }
623
624 - (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error
625 {
626     LOG(@"didFailNavigation: %@, error %@", navigation, error);
627 }
628
629 - (void)_webViewWebProcessDidCrash:(WKWebView *)webView
630 {
631     NSLog(@"WebContent process crashed; reloading");
632     [self reload:nil];
633 }
634
635 - (void)_webView:(WKWebView *)webView renderingProgressDidChange:(_WKRenderingProgressEvents)progressEvents
636 {
637     if (progressEvents & _WKRenderingProgressEventFirstLayout)
638         LOG(@"renderingProgressDidChange: %@", @"first layout");
639
640     if (progressEvents & _WKRenderingProgressEventFirstVisuallyNonEmptyLayout)
641         LOG(@"renderingProgressDidChange: %@", @"first visually non-empty layout");
642
643     if (progressEvents & _WKRenderingProgressEventFirstPaintWithSignificantArea)
644         LOG(@"renderingProgressDidChange: %@", @"first paint with significant area");
645
646     if (progressEvents & _WKRenderingProgressEventFirstLayoutAfterSuppressedIncrementalRendering)
647         LOG(@"renderingProgressDidChange: %@", @"first layout after suppressed incremental rendering");
648
649     if (progressEvents & _WKRenderingProgressEventFirstPaintAfterSuppressedIncrementalRendering)
650         LOG(@"renderingProgressDidChange: %@", @"first paint after suppressed incremental rendering");
651 }
652
653 @end
654
655 #endif // WK_API_ENABLED