Skip to content

Commit

Permalink
AppHistoryNavigateEvent.destination
Browse files Browse the repository at this point in the history
This object includes a url, a sameDocument boolean, and a getState()
function that returns the state object that will be restored when
the navigation completes (if this is a back/forward navigation to
a history entry that had appHistory state).

Bug: 1183545
Change-Id: I049f522108f8cc8bb69e7e3c5b6c9edfb40abcef
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2960662
Reviewed-by: Domenic Denicola <domenic@chromium.org>
Commit-Queue: Nate Chapin <japhet@chromium.org>
Cr-Commit-Position: refs/heads/master@{#892784}
  • Loading branch information
natechapin authored and Chromium LUCI CQ committed Jun 15, 2021
1 parent de608f2 commit 1515c99
Show file tree
Hide file tree
Showing 35 changed files with 174 additions and 9 deletions.
2 changes: 2 additions & 0 deletions third_party/blink/renderer/bindings/generated_in_core.gni
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,8 @@ generated_interface_sources_in_core = [
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_animation_timeline.h",
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_app_history.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_app_history.h",
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_app_history_destination.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_app_history_destination.h",
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_app_history_entry.cc",
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_app_history_entry.h",
"$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_app_history_navigate_event.cc",
Expand Down
1 change: 1 addition & 0 deletions third_party/blink/renderer/bindings/idl_in_core.gni
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ static_idl_files_in_core = get_path_info(
"//third_party/blink/renderer/core/aom/accessible_node_list.idl",
"//third_party/blink/renderer/core/aom/computed_accessible_node.idl",
"//third_party/blink/renderer/core/app_history/app_history.idl",
"//third_party/blink/renderer/core/app_history/app_history_destination.idl",
"//third_party/blink/renderer/core/app_history/app_history_entry.idl",
"//third_party/blink/renderer/core/app_history/app_history_navigate_event.idl",
"//third_party/blink/renderer/core/app_history/app_history_navigate_event_init.idl",
Expand Down
10 changes: 10 additions & 0 deletions third_party/blink/renderer/core/app_history/app_history.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "third_party/blink/renderer/bindings/core/v8/v8_app_history_navigate_event_init.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_app_history_navigate_options.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/core/app_history/app_history_destination.h"
#include "third_party/blink/renderer/core/app_history/app_history_entry.h"
#include "third_party/blink/renderer/core/app_history/app_history_navigate_event.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
Expand Down Expand Up @@ -428,6 +429,15 @@ bool AppHistory::DispatchNavigateEvent(const KURL& url,
init->setHashChange(event_type == NavigateEventType::kFragment &&
url != current_url &&
EqualIgnoringFragmentIdentifier(url, current_url));

SerializedScriptValue* destination_state = nullptr;
if (destination_item)
destination_state = destination_item->GetAppHistoryState();
else if (navigate_serialized_state_)
destination_state = navigate_serialized_state_.get();
init->setDestination(MakeGarbageCollected<AppHistoryDestination>(
url, event_type != NavigateEventType::kCrossDocument, destination_state));

init->setUserInitiated(involvement != UserNavigationInvolvement::kNone);
init->setFormData(form ? FormData::Create(form, ASSERT_NO_EXCEPTION)
: nullptr);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_APP_HISTORY_APP_HISTORY_DESTINATION_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_APP_HISTORY_APP_HISTORY_DESTINATION_H_

#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
#include "third_party/blink/renderer/platform/heap/member.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"

namespace blink {

class CORE_EXPORT AppHistoryDestination final : public ScriptWrappable {
DEFINE_WRAPPERTYPEINFO();

public:
AppHistoryDestination(const KURL& url,
bool same_document,
SerializedScriptValue* state)
: url_(url), same_document_(same_document), state_(state) {}
~AppHistoryDestination() final = default;

const KURL& url() const { return url_; }
bool sameDocument() const { return same_document_; }
ScriptValue getState(ScriptState* script_state) {
v8::Isolate* isolate = script_state->GetIsolate();
return state_ ? ScriptValue(isolate, state_->Deserialize(isolate))
: ScriptValue();
}

private:
KURL url_;
bool same_document_;
scoped_refptr<SerializedScriptValue> state_;
};

} // namespace blink

#endif // THIRD_PARTY_BLINK_RENDERER_CORE_APP_HISTORY_APP_HISTORY_DESTINATION_H_
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// https://github.com/WICG/app-history/
[
Exposed=Window,
RuntimeEnabled=AppHistory
] interface AppHistoryDestination {
readonly attribute USVString url;
readonly attribute boolean sameDocument;
[CallWith=ScriptState] any getState();
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/app_history/app_history_navigate_event.h"

#include "third_party/blink/renderer/bindings/core/v8/v8_app_history_navigate_event_init.h"
#include "third_party/blink/renderer/core/app_history/app_history_destination.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/event_interface_names.h"
#include "third_party/blink/renderer/core/event_type_names.h"
Expand All @@ -22,6 +23,7 @@ AppHistoryNavigateEvent::AppHistoryNavigateEvent(
can_respond_(init->canRespond()),
user_initiated_(init->userInitiated()),
hash_change_(init->hashChange()),
destination_(init->destination()),
form_data_(init->formData()),
info_(init->hasInfo()
? init->info()
Expand Down Expand Up @@ -78,6 +80,7 @@ const AtomicString& AppHistoryNavigateEvent::InterfaceName() const {
void AppHistoryNavigateEvent::Trace(Visitor* visitor) const {
Event::Trace(visitor);
ExecutionContextClient::Trace(visitor);
visitor->Trace(destination_);
visitor->Trace(form_data_);
visitor->Trace(info_);
visitor->Trace(navigation_action_promise_);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

namespace blink {

class AppHistoryDestination;
class AppHistoryNavigateEventInit;
class ExceptionState;
class FormData;
Expand All @@ -43,6 +44,7 @@ class AppHistoryNavigateEvent final : public Event,
bool canRespond() const { return can_respond_; }
bool userInitiated() const { return user_initiated_; }
bool hashChange() const { return hash_change_; }
AppHistoryDestination* destination() { return destination_; }
FormData* formData() const { return form_data_; }
ScriptValue info() const { return info_; }

Expand All @@ -62,6 +64,7 @@ class AppHistoryNavigateEvent final : public Event,
bool can_respond_;
bool user_initiated_;
bool hash_change_;
Member<AppHistoryDestination> destination_;
Member<FormData> form_data_;
ScriptValue info_;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
readonly attribute boolean canRespond;
readonly attribute boolean userInitiated;
readonly attribute boolean hashChange;
// readonly attribute AppHistoryEntry destination;
readonly attribute AppHistoryDestination destination;
// readonly attribute AbortSignal signal;
readonly attribute FormData? formData;
readonly attribute any info;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ dictionary AppHistoryNavigateEventInit : EventInit {
boolean canRespond = false;
boolean userInitiated = false;
boolean hashChange = false;
// AppHistoryEntry destination;
required AppHistoryDestination destination;
// AbortSignal signal;
FormData? formData = null;
any info;
Expand Down
1 change: 1 addition & 0 deletions third_party/blink/renderer/core/app_history/build.gni
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
blink_core_sources_app_history = [
"app_history.cc",
"app_history.h",
"app_history_destination.h",
"app_history_entry.cc",
"app_history_entry.h",
"app_history_navigate_event.cc",
Expand Down
1 change: 1 addition & 0 deletions third_party/blink/renderer/core/core_idl_files.gni
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ core_interface_idl_files_core_only =
"aom/accessible_node_list.idl",
"aom/computed_accessible_node.idl",
"app_history/app_history.idl",
"app_history/app_history_destination.idl",
"app_history/app_history_entry.idl",
"app_history/app_history_navigate_event.idl",
"clipboard/data_transfer.idl",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ interface AppHistoryEntry : EventTarget
interface AppHistoryNavigateEvent : Event
attribute @@toStringTag
getter canRespond
getter destination
getter formData
getter hashChange
getter info
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
assert_false(e.userInitiated);
assert_false(e.hashChange);
assert_equals(e.formData, null);
assert_equals(e.destination.url, "https://does-not-exist/foo.html");
assert_false(e.destination.sameDocument);
e.preventDefault();
});
a.click();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
assert_false(e.userInitiated);
assert_true(e.hashChange);
assert_equals(e.formData, null);
assert_equals(new URL(e.destination.url).hash, "#1");
assert_true(e.destination.sameDocument);
e.preventDefault();
t.step_timeout(t.step_func_done(() => assert_equals(location.hash, "")), 0);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
assert_false(e.userInitiated);
assert_false(e.hashChange);
assert_equals(e.formData, null);
assert_equals(new URL(e.destination.url).pathname,
"/wpt_internal/app-history/navigate-event/foo.html");
assert_false(e.destination.sameDocument);
e.preventDefault();
});
a.click();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
assert_true(e.userInitiated);
assert_true(e.hashChange);
assert_equals(e.formData, null);
assert_equals(new URL(e.destination.url).hash, "#1");
assert_true(e.destination.sameDocument);
e.preventDefault();
t.step_timeout(t.step_func_done(() => assert_equals(location.hash, "")), 0);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
assert_false(e.userInitiated);
assert_false(e.hashChange);
assert_equals(e.formData, null);
assert_equals(new URL(e.destination.url).pathname,
"/wpt_internal/app-history/navigate-event/foo.html");
assert_false(e.destination.sameDocument);
e.preventDefault();
});
a.click();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
assert_false(e.canRespond);
assert_false(e.userInitiated);
assert_false(e.hashChange);
assert_equals(new URL(e.destination.url).pathname, "/common/blank.html");
assert_false(e.destination.sameDocument);
assert_equals(e.formData, null);
assert_equals(e.info, "hi");
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
assert_true(e.canRespond);
assert_false(e.userInitiated);
assert_false(e.hashChange);
assert_equals(new URL(e.destination.url).hash, "");
assert_true(e.destination.sameDocument);
assert_equals(e.formData, null);
assert_equals(e.info, "hi");
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
assert_true(e.canRespond);
assert_false(e.userInitiated);
assert_true(e.hashChange);
assert_equals(new URL(e.destination.url).hash, "#foo");
assert_true(e.destination.sameDocument);
assert_equals(e.formData, null);
});
appHistory.navigate("#foo");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!doctype html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
async_test(t => {
// step_timeout because blink doesn't create history entries if onload has not
// yet completed.
window.onload = () => t.step_timeout(t.step_func_done(() => {
let navState = { statevar: "state" };
appHistory.navigate("#foo", { replace: true, state: navState });
appHistory.navigate("#bar");
appHistory.onnavigate = t.step_func_done(e => {
assert_not_equals(e.destination, null);
assert_not_equals(e.destination.getState(), undefined);
assert_not_equals(e.destination.getState(), e.destination.getState());
});
appHistory.back();
}), 0);
}, "navigate event destination.getState() on back/forward navigation");
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!doctype html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
async_test(t => {
// step_timeout because blink doesn't create history entries if onload has not
// yet completed.
window.onload = () => t.step_timeout(() => {
let navState = { statevar: "state" };
appHistory.onnavigate = t.step_func_done(e => {
assert_not_equals(e.destination, null);
assert_not_equals(e.destination.getState(), undefined);
assert_equals(e.destination.getState().statevar, "state");
assert_not_equals(e.destination.getState(), e.destination.getState());
});
appHistory.navigate("#foo", { state: navState });
}, 0);
}, "navigate event destination.getState() should be the state given to navigate()");
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
assert_true(e.canRespond);
assert_true(e.userInitiated);
assert_false(e.hashChange);
assert_equals(e.destination.url, location.href + "?");
assert_false(e.destination.sameDocument);
assert_not_equals(e.formData, null);
e.preventDefault();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,14 @@
assert_unreached("onnavigate should not have fired in source window");
});
iframe.contentWindow.appHistory.onnavigate = t.step_func_done(e => {
e.preventDefault();
assert_true(e.cancelable);
assert_true(e.canRespond);
assert_false(e.userInitiated);
assert_false(e.hashChange);
assert_equals(new URL(e.destination.url).pathname,
"/wpt_internal/app-history/navigate-event/foo.html");
assert_false(e.destination.sameDocument);
assert_not_equals(e.formData, null);
e.preventDefault();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
assert_true(e.canRespond);
assert_false(e.userInitiated);
assert_false(e.hashChange);
assert_equals(e.destination.url, location.href + "?");
assert_false(e.destination.sameDocument);
assert_not_equals(e.formData, null);
e.preventDefault();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
assert_true(e.canRespond);
assert_false(e.userInitiated);
assert_true(e.hashChange);
assert_equals(new URL(e.destination.url).hash, "");
assert_true(e.destination.sameDocument);
assert_equals(e.formData, null);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
assert_true(e.canRespond);
assert_false(e.userInitiated);
assert_false(e.hashChange);
assert_equals(new URL(e.destination.url).hash, "");
assert_true(e.destination.sameDocument);
assert_equals(e.formData, null);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
assert_true(e.canRespond);
assert_false(e.userInitiated);
assert_false(e.hashChange);
assert_equals(new URL(e.destination.url).pathname, "/common/blank.html");
assert_false(e.destination.sameDocument);
assert_equals(e.formData, null);
e.preventDefault();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
assert_true(e.canRespond);
assert_false(e.userInitiated);
assert_false(e.hashChange);
assert_equals(new URL(e.destination.url).hash, "#1");
assert_true(e.destination.sameDocument);
assert_equals(e.formData, null);
e.preventDefault();
t.step_timeout(t.step_func_done(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
assert_true(e.canRespond);
assert_false(e.userInitiated);
assert_false(e.hashChange);
assert_equals(new URL(e.destination.url).hash, "#1");
assert_true(e.destination.sameDocument);
assert_equals(e.formData, null);
e.preventDefault();
t.step_timeout(t.step_func_done(() => {
Expand All @@ -17,6 +19,6 @@
assert_equals(history.length, start_length);
}), 0);
});
history.replaceState(1, null, "#");
history.replaceState(1, null, "#1");
}, "history.replaceState() fires the navigate event");
</script>

0 comments on commit 1515c99

Please sign in to comment.