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