Changeset 273283 in webkit


Ignore:
Timestamp:
Feb 22, 2021 3:19:21 PM (3 years ago)
Author:
Chris Dumez
Message:

[Cocoa] Add WKWebView session restoration API
https://bugs.webkit.org/show_bug.cgi?id=220958
<rdar://70956146>

Reviewed by Geoffrey Garen.

Source/WebKit:

Add WKWebView session restoration API so that applications can easily retrieve
view state (such as back-forward list, scroll position, form data...) and
restore it on a WKWebView later on.

  • UIProcess/API/Cocoa/WKWebView.h:
  • UIProcess/API/Cocoa/WKWebView.mm:

(-[WKWebView interactionState]):
(-[WKWebView setInteractionState:]):

Tools:

Add API test coverage.

  • TestWebKitAPI/Tests/WebKit/WKBackForwardList.mm:

(TEST):

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r273276 r273283  
     12021-02-22  Chris Dumez  <cdumez@apple.com>
     2
     3        [Cocoa] Add WKWebView session restoration API
     4        https://bugs.webkit.org/show_bug.cgi?id=220958
     5        <rdar://70956146>
     6
     7        Reviewed by Geoffrey Garen.
     8
     9        Add WKWebView session restoration API so that applications can easily retrieve
     10        view state (such as back-forward list, scroll position, form data...) and
     11        restore it on a WKWebView later on.
     12
     13        * UIProcess/API/Cocoa/WKWebView.h:
     14        * UIProcess/API/Cocoa/WKWebView.mm:
     15        (-[WKWebView interactionState]):
     16        (-[WKWebView setInteractionState:]):
     17
    1182021-02-22  Chris Dumez  <cdumez@apple.com>
    219
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.h

    r273186 r273283  
    11/*
    2  * Copyright (C) 2014-2020 Apple Inc. All rights reserved.
     2 * Copyright (C) 2014-2021 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    474474@property (nonatomic, nullable, copy) NSString *mediaType WK_API_AVAILABLE(macos(11.0), ios(14.0));
    475475
     476/* @abstract The interaction state for the WKWebView
     477 @discussion The interaction state (back-forward list, currently loaded page, scroll position, form data...) for the WKWebView, which
     478 can be retrieved and set on another WKWebView to restore state.
     479*/
     480@property (nonatomic, nullable, copy) id interactionState WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
     481
    476482#if !TARGET_OS_IPHONE
    477483/* @abstract Returns an NSPrintOperation object configured to print the contents of this WKWebView
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm

    r273276 r273283  
    5353#import "ResourceLoadDelegate.h"
    5454#import "SafeBrowsingWarning.h"
     55#import "SessionStateCoding.h"
    5556#import "SharedBufferCopy.h"
    5657#import "UIDelegate.h"
     
    12361237}
    12371238
     1239- (id)interactionState
     1240{
     1241    return WebKit::encodeSessionState(_page->sessionState()).autorelease();
     1242}
     1243
     1244- (void)setInteractionState:(id)interactionState
     1245{
     1246    if (![(id)interactionState isKindOfClass:[NSData class]])
     1247        return;
     1248
     1249    WebKit::SessionState sessionState;
     1250    if (!WebKit::decodeSessionState((NSData *)(interactionState), sessionState))
     1251        return;
     1252    _page->restoreFromSessionState(sessionState, true);
     1253}
     1254
    12381255#pragma mark - iOS API
    12391256
  • trunk/Tools/ChangeLog

    r273276 r273283  
     12021-02-22  Chris Dumez  <cdumez@apple.com>
     2
     3        [Cocoa] Add WKWebView session restoration API
     4        https://bugs.webkit.org/show_bug.cgi?id=220958
     5        <rdar://70956146>
     6
     7        Reviewed by Geoffrey Garen.
     8
     9        Add API test coverage.
     10
     11        * TestWebKitAPI/Tests/WebKit/WKBackForwardList.mm:
     12        (TEST):
     13
    1142021-02-22  Chris Dumez  <cdumez@apple.com>
    215
  • trunk/Tools/TestWebKitAPI/Tests/WebKit/WKBackForwardList.mm

    r242339 r273283  
    167167    EXPECT_STREQ(webView.get().backForwardList.currentItem.URL.absoluteString.UTF8String, simple.absoluteString.UTF8String);
    168168}
     169
     170TEST(WKBackForwardList, InteractionStateRestoration)
     171{
     172    auto webView = adoptNS([[WKWebView alloc] init]);
     173
     174    NSURL *url1 = [[NSBundle mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
     175    NSURL *url2 = [[NSBundle mainBundle] URLForResource:@"simple2" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
     176    NSURL *url3 = [[NSBundle mainBundle] URLForResource:@"simple3" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
     177
     178    [webView loadRequest:[NSURLRequest requestWithURL:url1]];
     179    [webView _test_waitForDidFinishNavigation];
     180
     181    [webView loadRequest:[NSURLRequest requestWithURL:url2]];
     182    [webView _test_waitForDidFinishNavigation];
     183
     184    [webView loadRequest:[NSURLRequest requestWithURL:url3]];
     185    [webView _test_waitForDidFinishNavigation];
     186
     187    WKBackForwardList *list = [webView backForwardList];
     188    EXPECT_EQ((NSUInteger)2, list.backList.count);
     189    EXPECT_EQ((NSUInteger)0, list.forwardList.count);
     190    EXPECT_STREQ([[list.currentItem URL] absoluteString].UTF8String, url3.absoluteString.UTF8String);
     191
     192    id interactionState = [webView interactionState];
     193    RetainPtr<NSURL> temporaryFile = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:[NSUUID UUID].UUIDString] isDirectory:NO];
     194    NSError *error = nil;
     195    RetainPtr<NSData> archivedInteractionState = [NSKeyedArchiver archivedDataWithRootObject:interactionState requiringSecureCoding:YES error:&error];
     196    EXPECT_TRUE(!error);
     197    interactionState = nil;
     198    [archivedInteractionState writeToURL:temporaryFile.get() options:NSDataWritingAtomic error:&error];
     199    archivedInteractionState = nil;
     200    EXPECT_TRUE(!error);
     201
     202    webView = adoptNS([[WKWebView alloc] init]);
     203
     204    archivedInteractionState = [NSData dataWithContentsOfURL:temporaryFile.get()];
     205    interactionState = [NSKeyedUnarchiver unarchivedObjectOfClass:[(id)[webView interactionState] class] fromData:archivedInteractionState.get() error:&error];
     206    EXPECT_TRUE(!error);
     207
     208    [webView setInteractionState:interactionState];
     209    [webView _test_waitForDidFinishNavigation];
     210
     211    WKBackForwardList *newList = [webView backForwardList];
     212
     213    EXPECT_EQ((NSUInteger)2, newList.backList.count);
     214    EXPECT_EQ((NSUInteger)0, newList.forwardList.count);
     215    EXPECT_STREQ([[newList.currentItem URL] absoluteString].UTF8String, url3.absoluteString.UTF8String);
     216
     217    done = false;
     218    [webView evaluateJavaScript:@"document.body.innerText" completionHandler:^(id result, NSError *error) {
     219        EXPECT_TRUE(!error);
     220        NSString* bodyText = result;
     221        EXPECT_WK_STREQ(@"Third simple HTML file.", bodyText);
     222        done = true;
     223    }];
     224    TestWebKitAPI::Util::run(&done);
     225
     226    [webView goBack];
     227    [webView _test_waitForDidFinishNavigation];
     228
     229    done = false;
     230    [webView evaluateJavaScript:@"document.body.innerText" completionHandler:^(id result, NSError *error) {
     231        EXPECT_TRUE(!error);
     232        NSString* bodyText = result;
     233        EXPECT_WK_STREQ(@"Second simple HTML file.", bodyText);
     234        done = true;
     235    }];
     236    TestWebKitAPI::Util::run(&done);
     237
     238    [webView goBack];
     239    [webView _test_waitForDidFinishNavigation];
     240
     241    done = false;
     242    [webView evaluateJavaScript:@"document.body.innerText" completionHandler:^(id result, NSError *error) {
     243        EXPECT_TRUE(!error);
     244        NSString* bodyText = result;
     245        EXPECT_WK_STREQ(@"Simple HTML file.", bodyText);
     246        done = true;
     247    }];
     248    TestWebKitAPI::Util::run(&done);
     249}
     250
     251TEST(WKBackForwardList, InteractionStateRestorationNil)
     252{
     253    auto webView = adoptNS([[WKWebView alloc] init]);
     254
     255    NSURL *url1 = [[NSBundle mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
     256    NSURL *url2 = [[NSBundle mainBundle] URLForResource:@"simple2" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
     257    NSURL *url3 = [[NSBundle mainBundle] URLForResource:@"simple3" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
     258
     259    [webView loadRequest:[NSURLRequest requestWithURL:url1]];
     260    [webView _test_waitForDidFinishNavigation];
     261
     262    [webView loadRequest:[NSURLRequest requestWithURL:url2]];
     263    [webView _test_waitForDidFinishNavigation];
     264
     265    [webView loadRequest:[NSURLRequest requestWithURL:url3]];
     266    [webView _test_waitForDidFinishNavigation];
     267
     268    WKBackForwardList *list = [webView backForwardList];
     269    EXPECT_EQ((NSUInteger)2, list.backList.count);
     270    EXPECT_EQ((NSUInteger)0, list.forwardList.count);
     271    EXPECT_STREQ([[list.currentItem URL] absoluteString].UTF8String, url3.absoluteString.UTF8String);
     272
     273    [webView setInteractionState:nil];
     274
     275    list = [webView backForwardList];
     276    EXPECT_EQ((NSUInteger)2, list.backList.count);
     277    EXPECT_EQ((NSUInteger)0, list.forwardList.count);
     278    EXPECT_STREQ([[list.currentItem URL] absoluteString].UTF8String, url3.absoluteString.UTF8String);
     279}
     280
     281TEST(WKBackForwardList, InteractionStateRestorationInvalid)
     282{
     283    auto webView = adoptNS([[WKWebView alloc] init]);
     284
     285    NSURL *url1 = [[NSBundle mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
     286    NSURL *url2 = [[NSBundle mainBundle] URLForResource:@"simple2" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
     287    NSURL *url3 = [[NSBundle mainBundle] URLForResource:@"simple3" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
     288
     289    [webView loadRequest:[NSURLRequest requestWithURL:url1]];
     290    [webView _test_waitForDidFinishNavigation];
     291
     292    [webView loadRequest:[NSURLRequest requestWithURL:url2]];
     293    [webView _test_waitForDidFinishNavigation];
     294
     295    [webView loadRequest:[NSURLRequest requestWithURL:url3]];
     296    [webView _test_waitForDidFinishNavigation];
     297
     298    WKBackForwardList *list = [webView backForwardList];
     299    EXPECT_EQ((NSUInteger)2, list.backList.count);
     300    EXPECT_EQ((NSUInteger)0, list.forwardList.count);
     301    EXPECT_STREQ([[list.currentItem URL] absoluteString].UTF8String, url3.absoluteString.UTF8String);
     302
     303    NSString *invalidState = @"foo";
     304    [webView setInteractionState:invalidState];
     305
     306    list = [webView backForwardList];
     307    EXPECT_EQ((NSUInteger)2, list.backList.count);
     308    EXPECT_EQ((NSUInteger)0, list.forwardList.count);
     309    EXPECT_STREQ([[list.currentItem URL] absoluteString].UTF8String, url3.absoluteString.UTF8String);
     310}
     311
Note: See TracChangeset for help on using the changeset viewer.