Bug 193349 - [WPE][GTK] Add a mechanism to reset/clear the Web view session state
Summary: [WPE][GTK] Add a mechanism to reset/clear the Web view session state
Status: ASSIGNED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WPE WebKit (show other bugs)
Version: Other
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Adrian Perez
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-01-11 02:15 PST by Adrian Perez
Modified: 2019-01-31 08:53 PST (History)
11 users (show)

See Also:


Attachments
Patch (6.69 KB, patch)
2019-01-11 05:31 PST, Adrian Perez
no flags Details | Formatted Diff | Diff
Patch v2 (7.99 KB, patch)
2019-01-11 05:43 PST, Adrian Perez
no flags Details | Formatted Diff | Diff
Patch v3 (8.19 KB, patch)
2019-01-11 08:10 PST, Adrian Perez
mcatanzaro: review-
mcatanzaro: commit-queue-
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Adrian Perez 2019-01-11 02:15:20 PST
For an application I am developing it would be desirable to be
able to clear/reset the session state of a web view (e.g. the
navigation back/forward list). 

 - Upon creation of a WebKitWebView, obtain the current “empty”
   state with webkit_web_view_get_session_state().
 - Later on, restore the “empty” state previously saved using
   the webkit_web_view_restore_session_state() function.

Unfortunately, the approach above does NOT work: the code that
restores the session state checks whether the current index in
the back/forward is zero, and skips restoring the list in that
case (which happens to be the case for an “empty” state).

It would be desirable to have a way of clearing the state in
the public API, for example webkit_web_view_clear_session_state().
Comment 1 Adrian Perez 2019-01-11 05:31:34 PST
Created attachment 358891 [details]
Patch
Comment 2 EWS Watchlist 2019-01-11 05:32:56 PST
Thanks for the patch. If this patch contains new public API please make sure it follows the guidelines for new WebKit2 GTK+ API. See http://trac.webkit.org/wiki/WebKitGTK/AddingNewWebKit2API
Comment 3 Adrian Perez 2019-01-11 05:34:02 PST
Ouch, I forgot to add the new function to “webkit2gtk-4.0-sections.txt”,
I'll upload an updated patch in a moment.
Comment 4 Adrian Perez 2019-01-11 05:34:20 PST
(In reply to Adrian Perez from comment #3)
> Ouch, I forgot to add the new function to “webkit2gtk-4.0-sections.txt”,
> I'll upload an updated patch in a moment.

…and to “wpe-0.1-sections.txt” as well.
Comment 5 Adrian Perez 2019-01-11 05:43:11 PST
Created attachment 358893 [details]
Patch v2

Now with the gtk-doc bits added
Comment 6 Carlos Garcia Campos 2019-01-11 06:26:24 PST
Comment on attachment 358893 [details]
Patch v2

View in context: https://bugs.webkit.org/attachment.cgi?id=358893&action=review

> Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp:4153
> + * Note that the currently loaded page is *not* changed, and in order to clear the contents
> + * being displayed webkit_web_view_load_uri() should be used to load the `about:blank`
> + * resource.

We should also say here that the bf list won't be empty, it will have a single item for the currently loaded page.

> Source/WebKit/UIProcess/WebPageProxy.h:811
> +    void clearSessionState() { backForwardClear(); }

There's more in the session state than the bf list, no?

> Tools/TestWebKitAPI/Tests/WebKitGLib/TestBackForwardList.cpp:335
> +    g_assert_cmpuint(webkit_back_forward_list_get_length(bfList), ==, 1);

Should we also check that the item is indeed he currently loaded page with BackForwardListTest::checkItem?

> Tools/TestWebKitAPI/Tests/WebKitGLib/TestBackForwardList.cpp:337
> +    g_assert(!webkit_web_view_can_go_back(view.get()));
> +    g_assert(!webkit_web_view_can_go_forward(view.get()));

Use g_assert_false
Comment 7 Adrian Perez 2019-01-11 08:04:09 PST
(In reply to Carlos Garcia Campos from comment #6)
> Comment on attachment 358893 [details]
> Patch v2
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=358893&action=review
> 
> > Source/WebKit/UIProcess/API/glib/WebKitWebView.cpp:4153
> > + * Note that the currently loaded page is *not* changed, and in order to clear the contents
> > + * being displayed webkit_web_view_load_uri() should be used to load the `about:blank`
> > + * resource.
> 
> We should also say here that the bf list won't be empty, it will have a
> single item for the currently loaded page.

Good point, will do.

> > Source/WebKit/UIProcess/WebPageProxy.h:811
> > +    void clearSessionState() { backForwardClear(); }
> 
> There's more in the session state than the bf list, no?

I checked what WebPageProxy::restoreFromSessionState() does: the only
other things it restores are “m_renderTreeSize” which I do not have a
super clear idea what it is used for (they appear to be used by the
iOS+Mac ViewGestureController and ViewSnapshotStore implementations),
but as far as I can understand it does not need changing because the
currently loaded page is kept.

The rest of things which need updating are handled properly because
the WebBackForwardList::clear() method itself does calls to the
didChangeBackForwardList() method to make the Page (and possible
other objects) notice the changes.

> > Tools/TestWebKitAPI/Tests/WebKitGLib/TestBackForwardList.cpp:335
> > +    g_assert_cmpuint(webkit_back_forward_list_get_length(bfList), ==, 1);
> 
> Should we also check that the item is indeed he currently loaded page with
> BackForwardListTest::checkItem?

It won't hurt to have this check as well, so I will add it.

> > Tools/TestWebKitAPI/Tests/WebKitGLib/TestBackForwardList.cpp:337
> > +    g_assert(!webkit_web_view_can_go_back(view.get()));
> > +    g_assert(!webkit_web_view_can_go_forward(view.get()));
> 
> Use g_assert_false

Okay.
Comment 8 Adrian Perez 2019-01-11 08:08:05 PST
(In reply to Adrian Perez from comment #7)
> (In reply to Carlos Garcia Campos from comment #6)
> > Comment on attachment 358893 [details]
> > Patch v2
> >
> > [...] 
> >
> > > Source/WebKit/UIProcess/WebPageProxy.h:811
> > > +    void clearSessionState() { backForwardClear(); }
> > 
> > There's more in the session state than the bf list, no?
> 
> I checked what WebPageProxy::restoreFromSessionState() does: the only
> other things it restores are “m_renderTreeSize” which I do not have a
> super clear idea what it is used for (they appear to be used by the
> iOS+Mac ViewGestureController and ViewSnapshotStore implementations),
> but as far as I can understand it does not need changing because the
> currently loaded page is kept.
> 
> The rest of things which need updating are handled properly because
> the WebBackForwardList::clear() method itself does calls to the
> didChangeBackForwardList() method to make the Page (and possible
> other objects) notice the changes.

More on this… There is also a “provisionalURL” in the session state,
but as a matter of fact, webkit_web_view_restore_session_state() uses
WebPageProxy::restoreFromState(…, false), and passing “false” there
prevents reading the “.renderTreeSize” and “.provisionalURL“ from the
state which is being restored.

This me even more confident that just clearing the back-forward list
is the only thing needed here :-)
Comment 9 Adrian Perez 2019-01-11 08:10:52 PST
Created attachment 358897 [details]
Patch v3

This version takes into account the review comments.
Comment 10 Michael Catanzaro 2019-01-11 17:40:44 PST
(In reply to Adrian Perez from comment #0)
> Unfortunately, the approach above does NOT work: the code that
> restores the session state checks whether the current index in
> the back/forward is zero, and skips restoring the list in that
> case (which happens to be the case for an “empty” state).

Is this cross-platform code? It sounds like a bug. If the back/forward list in the session state is empty, the web view's back/forward list should be reset, not ignored.
Comment 11 Michael Catanzaro 2019-01-11 17:42:02 PST
Comment on attachment 358897 [details]
Patch v3

View in context: https://bugs.webkit.org/attachment.cgi?id=358897&action=review

> Source/WebKit/UIProcess/WebPageProxy.h:811
>      RefPtr<API::Navigation> restoreFromSessionState(SessionState, bool navigate);
> +    void clearSessionState() { backForwardClear(); }

I think it should be implemented by passing an empty SessionState into restoreFromSessionState. And if that doesn't work, it's probably a bug in restoreFromSessionState. We'll have to see what WK2 owners think.
Comment 12 Adrian Perez 2019-01-14 00:14:12 PST
(In reply to Michael Catanzaro from comment #11)
> Comment on attachment 358897 [details]
> Patch v3
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=358897&action=review
> 
> > Source/WebKit/UIProcess/WebPageProxy.h:811
> >      RefPtr<API::Navigation> restoreFromSessionState(SessionState, bool navigate);
> > +    void clearSessionState() { backForwardClear(); }
> 
> I think it should be implemented by passing an empty SessionState into
> restoreFromSessionState. And if that doesn't work, it's probably a bug in
> restoreFromSessionState. We'll have to see what WK2 owners think.

I have been mulling this over the weekend, and I think there is no bug
in ::restoreFromSessionState(), because I am under the impression that
the idea is to use it right after creating a web view, when there is no
previous (nor current) state to maintain. This means that restoring an
empty state does not need to do anything, because well, a fresh web view
has already an empty state — nothing needs to be done.

As for implementing ::clearSessionState() in terms of restoring an empty
state using ::restoreFromSessionState() behind the scenes, I think that
would be wrong: that would imply passing a state with one element (for
the currently loaded page), which would result in “completely replace
the state with the passed one, do a page reload of the active item”
which is very different from “drop all items from the state which are
not the current page” (which is the behaviour implemented by the
proposed patch).
Comment 13 Michael Catanzaro 2019-01-14 08:24:17 PST
(In reply to Adrian Perez from comment #12)
> I have been mulling this over the weekend, and I think there is no bug
> in ::restoreFromSessionState(), because I am under the impression that
> the idea is to use it right after creating a web view, when there is no
> previous (nor current) state to maintain. This means that restoring an
> empty state does not need to do anything, because well, a fresh web view
> has already an empty state — nothing needs to be done.

Hm, that's certainly how Epiphany uses it, but there is no indication in the API documentation that this is the intended use, and I don't see any reason it shouldn't work....

> As for implementing ::clearSessionState() in terms of restoring an empty
> state using ::restoreFromSessionState() behind the scenes, I think that
> would be wrong: that would imply passing a state with one element (for
> the currently loaded page)

What, why? You should use a completely empty state.

>, which would result in “completely replace
> the state with the passed one, do a page reload of the active item”

I thought restore state always implies reload
Comment 14 Adrian Perez 2019-01-14 16:42:33 PST
(In reply to Michael Catanzaro from comment #13)
> (In reply to Adrian Perez from comment #12)
> > I have been mulling this over the weekend, and I think there is no bug
> > in ::restoreFromSessionState(), because I am under the impression that
> > the idea is to use it right after creating a web view, when there is no
> > previous (nor current) state to maintain. This means that restoring an
> > empty state does not need to do anything, because well, a fresh web view
> > has already an empty state — nothing needs to be done.
> 
> Hm, that's certainly how Epiphany uses it, but there is no indication in the
> API documentation that this is the intended use, and I don't see any reason
> it shouldn't work....
> 
> > As for implementing ::clearSessionState() in terms of restoring an empty
> > state using ::restoreFromSessionState() behind the scenes, I think that
> > would be wrong: that would imply passing a state with one element (for
> > the currently loaded page)
> 
> What, why? You should use a completely empty state.

No, we want to keep the currently displayed content undisturbed.
Which means keeping one item for the current page.

> >, which would result in “completely replace
> > the state with the passed one, do a page reload of the active item”
> 
> I thought restore state always implies reload

It does. So if we pass a state with one item, the back-forward list
is replaced, and the current page reloaded... which will cause the
web view to show a flash of blank content and jump around when
reloading. We don't want a reload.

Clearing the back-forward list does exactly what we want: drops all
the elements which are not the current one, leaving it with a single
element (the current page) without modifying that element nor reloading.
Comment 15 Michael Catanzaro 2019-01-15 08:33:01 PST
(In reply to Adrian Perez from comment #14)
> No, we want to keep the currently displayed content undisturbed.
> Which means keeping one item for the current page.

OK, one last motivating question: what are you really trying to do? Clear the back/forward list? A function that clears the session state should probably also clear the current page, not leave it undisturbed, because the current page is part of the session state. Right?

I'm skeptical because session state includes much more than just back/forward list and even the current page. E.g. scroll position within the page is part of the session state. So a clear function that only clears the back/forward list and has a goal of not reloading the page or resetting the scroll position seems really suspect.

> Clearing the back-forward list does exactly what we want: drops all
> the elements which are not the current one, leaving it with a single
> element (the current page) without modifying that element nor reloading.

It sounds like you really want a function to clear just the back/forward list. We have previous bugs about that on Bugzilla where Apple explained we don't want to make it mutable, but perhaps they might have been open to allowing a simple clear operation without allowing other mutations.
Comment 16 Carlos Garcia Campos 2019-01-28 01:16:46 PST
I also find it confusing and the session state might include more stuff in the future. If we actually want an API to simply clear the bf list let's add webkit_back_forward_list_clear() or reset(), it might be weird a clear() method that leaves one item.
Comment 17 Adrian Perez 2019-01-31 08:37:48 PST
(In reply to Carlos Garcia Campos from comment #16)
> I also find it confusing and the session state might include more stuff in
> the future. If we actually want an API to simply clear the bf list let's add
> webkit_back_forward_list_clear() or reset(), it might be weird a clear()
> method that leaves one item.

I like this idea, and in particular calling the method _reset() to avoid
giving the idea that the back-forward list will be empty after the call.
Thanks for the suggestion!
Comment 18 Alex Christensen 2019-01-31 08:53:00 PST
Comment on attachment 358897 [details]
Patch v3

backForwardClear is only accessible from WKBundleClearHistoryForTesting, and I don't think we should expand the use of this functionality.  In the past we have consistently found that applications which claim to need to mutate the back/forward list do not actually need to.