Bug 131043 - Web Replay: save and restore page history state at main frame navigations
Summary: Web Replay: save and restore page history state at main frame navigations
Status: RESOLVED LATER
Alias: None
Product: WebKit
Classification: Unclassified
Component: History (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords:
Depends on: 131554 131564
Blocks: WebReplay 129447
  Show dependency treegraph
 
Reported: 2014-04-01 09:35 PDT by Brian Burg
Modified: 2017-07-10 14:01 PDT (History)
9 users (show)

See Also:


Attachments
the patch (40.80 KB, patch)
2014-04-22 11:43 PDT, Brian Burg
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Brian Burg 2014-04-01 09:35:57 PDT
The easy part is encoding/decoding the HistoryItem tree.
Comment 1 Brian Burg 2014-04-01 10:47:58 PDT
(comment got truncated)

The main use cases here are to support replaying the following:
 - introspection through History.idl interface
 - programmatic pushState/popState
 - history navigations within the document

The page cache is always disabled during capture/replay, so history navigations outside the document should just start a normal page load.

Current implementation plan is to encode history item trees in the back/forward list, and replace page's back/forward list at the beginning of replay.
Comment 2 Anders Carlsson 2014-04-01 10:56:43 PDT
 One thing that we desperately need to do is to dumb down the back forward list and history in the web process - the web process should just know:

1. the length of the back forward list
2. the current index of the back forward list.

Everything else should be managed by the UI process.
Comment 3 Brian Burg 2014-04-01 11:21:45 PDT
(In reply to comment #2)
>  One thing that we desperately need to do is to dumb down the back forward list and history in the web process - the web process should just know:
> 
> 1. the length of the back forward list
> 2. the current index of the back forward list.
> 
> Everything else should be managed by the UI process.

That shouldn't affect the replay strategy AFAICT. It'll require some extra plumbing to get the initial state to/from to the UI process.
Comment 4 Brian Burg 2014-04-18 14:08:20 PDT
I've implemented a prototype of save/restore of the back forward list. Basic details:

On capture, save current and back entries on the list.
On replay, clear the back/forward list and append saved entries. Then, tell HistoryController that the current position is the final entry.

I promoted clear() to be part of the BackForwardClient interface. The WebProcess version had already implemented this. Doing the same for WK1 is easy.

This doesn't quite work, since clear() truncates all entries except the current entry. So if we start replaying with 2 entries, clear(), then append two more entries, window.history.length will be 3 instead of 2 on replay.

Some alternatives that might work better, which I'm investigating:

One alternative is to do the same clear+append when capturing: save entries, clear all but current, then immediately append and set current cursor. But, this isn't great either: you'll have duplicate entries (at the beginning and end) representing the page that you were on when capturing started. From this point, if the program calls window.history.go(-3), the resulting navigation will be nondeterministic (depends on the page from which you started replaying).

Another alternative is to add a flag to clear() which completely empties out the back forward list, including the current item. I'm assuming this may introduce complications for other clients.

Another alternative is to add a method to completely replace the history list with a saved list. This is essentially the same as the previous alternative but adds another method to the API.

A final alternative is a variant of the first. To capture, we start by saving the back-forward list, then navigate to about:blank, restore the saved back-forward list, then kick off the initial navigation to the page we actually want to capture. To replay, we similarly navigate to about:blank, clear+append history, then do the initial navigation to the page we want to replay.

I prefer the last alternative, and am going to look at it next. Springboarding from the clean slate of about:blank between every session segment may be useful for other things, like making document.referer easy to memoize and handling replay of unload behavior.
Comment 5 Brian Burg 2014-04-22 11:43:58 PDT
Created attachment 229901 [details]
the patch
Comment 6 WebKit Commit Bot 2014-04-22 11:46:18 PDT
Attachment 229901 [details] did not pass style-queue:


ERROR: Source/WebCore/replay/SerializationMethods.cpp:201:  The parameter type should use PassRefPtr instead of RefPtr.  [readability/pass_ptr] [5]
ERROR: Source/WebCore/replay/SerializationMethods.cpp:288:  The parameter type should use PassRefPtr instead of RefPtr.  [readability/pass_ptr] [5]
ERROR: Source/WebCore/replay/SerializationMethods.cpp:696:  The parameter type should use PassRefPtr instead of RefPtr.  [readability/pass_ptr] [5]
ERROR: Source/WebCore/replay/SerializationMethods.h:78:  The parameter type should use PassRefPtr instead of RefPtr.  [readability/pass_ptr] [5]
ERROR: Source/WebCore/replay/SerializationMethods.h:85:  The parameter type should use PassRefPtr instead of RefPtr.  [readability/pass_ptr] [5]
ERROR: Source/WebCore/replay/SerializationMethods.h:141:  The parameter type should use PassRefPtr instead of RefPtr.  [readability/pass_ptr] [5]
Total errors found: 6 in 26 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 7 BJ Burg 2017-07-10 14:01:28 PDT
Closing web replay-related bugs until we resume working on the feature again.