зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1155730, implement History.scrollRestoration r=jst
This commit is contained in:
Родитель
8b2a176dce
Коммит
2b2b2cc690
|
@ -154,10 +154,14 @@ var SessionHistoryInternal = {
|
|||
if (shEntry.contentType)
|
||||
entry.contentType = shEntry.contentType;
|
||||
|
||||
let x = {}, y = {};
|
||||
shEntry.getScrollPosition(x, y);
|
||||
if (x.value != 0 || y.value != 0)
|
||||
entry.scroll = x.value + "," + y.value;
|
||||
if (shEntry.scrollRestorationIsManual) {
|
||||
entry.scrollRestorationIsManual = true;
|
||||
} else {
|
||||
let x = {}, y = {};
|
||||
shEntry.getScrollPosition(x, y);
|
||||
if (x.value != 0 || y.value != 0)
|
||||
entry.scroll = x.value + "," + y.value;
|
||||
}
|
||||
|
||||
// Collect owner data for the current history entry.
|
||||
try {
|
||||
|
@ -338,7 +342,9 @@ var SessionHistoryInternal = {
|
|||
entry.structuredCloneVersion);
|
||||
}
|
||||
|
||||
if (entry.scroll) {
|
||||
if (entry.scrollRestorationIsManual) {
|
||||
shEntry.scrollRestorationIsManual = true;
|
||||
} else if (entry.scroll) {
|
||||
var scrollPos = (entry.scroll || "0,0").split(",");
|
||||
scrollPos = [parseInt(scrollPos[0]) || 0, parseInt(scrollPos[1]) || 0];
|
||||
shEntry.setScrollPosition(scrollPos[0], scrollPos[1]);
|
||||
|
|
|
@ -10043,9 +10043,11 @@ nsDocShell::InternalLoad(nsIURI* aURI,
|
|||
nsCOMPtr<nsIInputStream> postData;
|
||||
nsCOMPtr<nsISupports> cacheKey;
|
||||
|
||||
bool scrollRestorationIsManual = false;
|
||||
if (mOSHE) {
|
||||
/* save current position of scroller(s) (bug 59774) */
|
||||
mOSHE->SetScrollPosition(cx, cy);
|
||||
mOSHE->GetScrollRestorationIsManual(&scrollRestorationIsManual);
|
||||
// Get the postdata and page ident from the current page, if
|
||||
// the new load is being done via normal means. Note that
|
||||
// "normal means" can be checked for just by checking for
|
||||
|
@ -10060,6 +10062,11 @@ nsDocShell::InternalLoad(nsIURI* aURI,
|
|||
// cache data, since the two SHEntries correspond to the
|
||||
// same document.
|
||||
if (mLSHE) {
|
||||
if (!aSHEntry) {
|
||||
// If we're not doing a history load, scroll restoration
|
||||
// should be inherited from the previous session history entry.
|
||||
mLSHE->SetScrollRestorationIsManual(scrollRestorationIsManual);
|
||||
}
|
||||
mLSHE->AdoptBFCacheEntry(mOSHE);
|
||||
}
|
||||
}
|
||||
|
@ -10132,10 +10139,12 @@ nsDocShell::InternalLoad(nsIURI* aURI,
|
|||
/* restore previous position of scroller(s), if we're moving
|
||||
* back in history (bug 59774)
|
||||
*/
|
||||
nscoord bx, by;
|
||||
nscoord bx = 0;
|
||||
nscoord by = 0;
|
||||
bool needsScrollPosUpdate = false;
|
||||
if (mOSHE && (aLoadType == LOAD_HISTORY ||
|
||||
aLoadType == LOAD_RELOAD_NORMAL)) {
|
||||
aLoadType == LOAD_RELOAD_NORMAL) &&
|
||||
!scrollRestorationIsManual) {
|
||||
needsScrollPosUpdate = true;
|
||||
mOSHE->GetScrollPosition(&bx, &by);
|
||||
}
|
||||
|
@ -11624,6 +11633,9 @@ nsDocShell::AddState(JS::Handle<JS::Value> aData, const nsAString& aTitle,
|
|||
GetCurScrollPos(ScrollOrientation_Y, &cy);
|
||||
mOSHE->SetScrollPosition(cx, cy);
|
||||
|
||||
bool scrollRestorationIsManual = false;
|
||||
mOSHE->GetScrollRestorationIsManual(&scrollRestorationIsManual);
|
||||
|
||||
// Since we're not changing which page we have loaded, pass
|
||||
// true for aCloneChildren.
|
||||
rv = AddToSessionHistory(newURI, nullptr, nullptr, true,
|
||||
|
@ -11632,6 +11644,10 @@ nsDocShell::AddState(JS::Handle<JS::Value> aData, const nsAString& aTitle,
|
|||
|
||||
NS_ENSURE_TRUE(newSHEntry, NS_ERROR_FAILURE);
|
||||
|
||||
// Session history entries created by pushState inherit scroll restoration
|
||||
// mode from the current entry.
|
||||
newSHEntry->SetScrollRestorationIsManual(scrollRestorationIsManual);
|
||||
|
||||
// Link the new SHEntry to the old SHEntry's BFCache entry, since the
|
||||
// two entries correspond to the same document.
|
||||
NS_ENSURE_SUCCESS(newSHEntry->AdoptBFCacheEntry(oldOSHE), NS_ERROR_FAILURE);
|
||||
|
@ -11740,6 +11756,27 @@ nsDocShell::AddState(JS::Handle<JS::Value> aData, const nsAString& aTitle,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::GetCurrentScrollRestorationIsManual(bool* aIsManual)
|
||||
{
|
||||
*aIsManual = false;
|
||||
if (mOSHE) {
|
||||
mOSHE->GetScrollRestorationIsManual(aIsManual);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocShell::SetCurrentScrollRestorationIsManual(bool aIsManual)
|
||||
{
|
||||
if (mOSHE) {
|
||||
mOSHE->SetScrollRestorationIsManual(aIsManual);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
nsDocShell::ShouldAddToSessionHistory(nsIURI* aURI)
|
||||
{
|
||||
|
@ -12140,10 +12177,21 @@ nsDocShell::PersistLayoutHistoryState()
|
|||
nsresult rv = NS_OK;
|
||||
|
||||
if (mOSHE) {
|
||||
bool scrollRestorationIsManual = false;
|
||||
mOSHE->GetScrollRestorationIsManual(&scrollRestorationIsManual);
|
||||
|
||||
nsCOMPtr<nsIPresShell> shell = GetPresShell();
|
||||
nsCOMPtr<nsILayoutHistoryState> layoutState;
|
||||
if (shell) {
|
||||
nsCOMPtr<nsILayoutHistoryState> layoutState;
|
||||
rv = shell->CaptureHistoryState(getter_AddRefs(layoutState));
|
||||
} else if (scrollRestorationIsManual) {
|
||||
// Even if we don't have layout anymore, we may want to reset the current
|
||||
// scroll state in layout history.
|
||||
GetLayoutHistoryState(getter_AddRefs(layoutState));
|
||||
}
|
||||
|
||||
if (scrollRestorationIsManual && layoutState) {
|
||||
layoutState->ResetScrollState();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ interface nsITabParent;
|
|||
|
||||
typedef unsigned long nsLoadFlags;
|
||||
|
||||
[scriptable, builtinclass, uuid(bc3524bd-023c-4fc8-ace1-472bc999fb12)]
|
||||
[scriptable, builtinclass, uuid(811aa3e1-7c4d-45ae-89da-ea1b107c60ed)]
|
||||
interface nsIDocShell : nsIDocShellTreeItem
|
||||
{
|
||||
/**
|
||||
|
@ -1090,4 +1090,10 @@ interface nsIDocShell : nsIDocShellTreeItem
|
|||
* top level chrome docshell.
|
||||
*/
|
||||
attribute boolean windowDraggingAllowed;
|
||||
|
||||
/**
|
||||
* Sets/gets the current scroll restoration mode.
|
||||
* @see https://html.spec.whatwg.org/#dom-history-scroll-restoration
|
||||
*/
|
||||
attribute boolean currentScrollRestorationIsManual;
|
||||
};
|
||||
|
|
|
@ -30,7 +30,7 @@ class nsSHEntryShared;
|
|||
[ptr] native nsDocShellEditorDataPtr(nsDocShellEditorData);
|
||||
[ptr] native nsSHEntryShared(nsSHEntryShared);
|
||||
|
||||
[scriptable, uuid(3a5e5fa0-5364-4fbb-a87a-3f12a6b51903)]
|
||||
[scriptable, uuid(0dad26b8-a259-42c7-93f1-2fa7fc076e45)]
|
||||
interface nsISHEntry : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -301,6 +301,12 @@ interface nsISHEntry : nsISupports
|
|||
* for example with view-source.
|
||||
*/
|
||||
attribute nsIURI baseURI;
|
||||
|
||||
/**
|
||||
* Sets/gets the current scroll restoration state,
|
||||
* if true == "manual", false == "auto".
|
||||
*/
|
||||
attribute boolean scrollRestorationIsManual;
|
||||
};
|
||||
|
||||
[scriptable, uuid(bb66ac35-253b-471f-a317-3ece940f04c5)]
|
||||
|
|
|
@ -33,6 +33,7 @@ nsSHEntry::nsSHEntry()
|
|||
, mParent(nullptr)
|
||||
, mURIWasModified(false)
|
||||
, mIsSrcdocEntry(false)
|
||||
, mScrollRestorationIsManual(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -53,6 +54,7 @@ nsSHEntry::nsSHEntry(const nsSHEntry& aOther)
|
|||
, mURIWasModified(aOther.mURIWasModified)
|
||||
, mStateData(aOther.mStateData)
|
||||
, mIsSrcdocEntry(aOther.mIsSrcdocEntry)
|
||||
, mScrollRestorationIsManual(false)
|
||||
, mSrcdocData(aOther.mSrcdocData)
|
||||
, mBaseURI(aOther.mBaseURI)
|
||||
{
|
||||
|
@ -598,6 +600,20 @@ nsSHEntry::SetBaseURI(nsIURI* aBaseURI)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetScrollRestorationIsManual(bool* aIsManual)
|
||||
{
|
||||
*aIsManual = mScrollRestorationIsManual;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::SetScrollRestorationIsManual(bool aIsManual)
|
||||
{
|
||||
mScrollRestorationIsManual = aIsManual;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHEntry::GetChildCount(int32_t* aCount)
|
||||
{
|
||||
|
|
|
@ -64,6 +64,7 @@ private:
|
|||
bool mURIWasModified;
|
||||
nsCOMPtr<nsIStructuredCloneContainer> mStateData;
|
||||
bool mIsSrcdocEntry;
|
||||
bool mScrollRestorationIsManual;
|
||||
nsString mSrcdocData;
|
||||
nsCOMPtr<nsIURI> mBaseURI;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
<html>
|
||||
<head>
|
||||
<script>
|
||||
var oldHistoryObject = null;
|
||||
|
||||
function test(event) {
|
||||
if (!opener.scrollRestorationTest) {
|
||||
opener.scrollRestorationTest = 0;
|
||||
}
|
||||
++opener.scrollRestorationTest;
|
||||
|
||||
switch (opener.scrollRestorationTest) {
|
||||
case 1: {
|
||||
opener.is(event.persisted, false, "Shouldn't have persisted session history entry.");
|
||||
opener.ok(history.scrollRestoration, "History object has scrollRestoration property.");
|
||||
opener.ok(history.scrollRestoration, "auto", "history.scrollRestoration's default value should be 'auto'.");
|
||||
history.scrollRestoration = "foobar";
|
||||
opener.ok(history.scrollRestoration, "auto", "Invalid enum value should not change the value of an attribute.");
|
||||
history.scrollRestoration = "manual";
|
||||
opener.ok(history.scrollRestoration, "manual", "Valid enum value should change the value of an attribute.");
|
||||
history.scrollRestoration = "auto";
|
||||
opener.ok(history.scrollRestoration, "auto", "Valid enum value should change the value of an attribute.");
|
||||
document.getElementById("bottom").scrollIntoView();
|
||||
window.location.reload(false);
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
opener.is(event.persisted, false, "Shouldn't have persisted session history entry.");
|
||||
opener.isnot(window.scrollY, 0, "Should have restored scrolling.");
|
||||
opener.is(history.scrollRestoration, "auto", "Should have the same scrollRestoration as before reload.");
|
||||
history.scrollRestoration = "manual";
|
||||
window.onunload = function() {} // Disable bfcache.
|
||||
window.location.reload(false);
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
opener.is(event.persisted, false, "Shouldn't have persisted session history entry.");
|
||||
opener.is(window.scrollY, 0, "Should not have restored scrolling.");
|
||||
opener.is(history.scrollRestoration, "manual", "Should have the same scrollRestoration as before reload.");
|
||||
document.getElementById("bottom").scrollIntoView();
|
||||
window.onunload = null; // Should get bfcache behavior.
|
||||
opener.setTimeout("testWindow.history.back();", 250);
|
||||
window.location.href = 'data:text/html,';
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
opener.is(event.persisted, true, "Should have persisted session history entry.");
|
||||
opener.isnot(window.scrollY, 0, "Should have kept the old scroll position.");
|
||||
opener.is(history.scrollRestoration, "manual", "Should have the same scrollRestoration as before reload.");
|
||||
window.scrollTo(0, 0);
|
||||
window.location.hash = "hash";
|
||||
requestAnimationFrame(test);
|
||||
break;
|
||||
}
|
||||
case 5: {
|
||||
opener.isnot(window.scrollY, 0, "Should have scrolled to #hash.");
|
||||
opener.is(history.scrollRestoration, "manual", "Should have the same scrollRestoration mode as before fragment navigation.");
|
||||
window.onunload = function() {} // Disable bfcache.
|
||||
opener.setTimeout("is(testWindow.history.scrollRestoration, 'auto'); testWindow.history.back();", 250);
|
||||
window.location.href = 'data:text/html,';
|
||||
break;
|
||||
}
|
||||
case 6: {
|
||||
opener.is(event.persisted, false, "Shouldn't have persisted session history entry.");
|
||||
opener.is(window.scrollY, 0, "Shouldn't have kept the old scroll position.");
|
||||
opener.is(history.scrollRestoration, "manual", "Should have the same scrollRestoration mode as before fragment navigation.");
|
||||
history.scrollRestoration = "auto";
|
||||
document.getElementById("bottom").scrollIntoView();
|
||||
history.pushState({ state: "state1" }, "state1");
|
||||
history.pushState({ state: "state2" }, "state2");
|
||||
window.scrollTo(0, 0);
|
||||
history.back();
|
||||
opener.isnot(window.scrollY, 0, "Should have scrolled back to the state1's position");
|
||||
opener.is(history.state.state, "state1", "Unexpected state.");
|
||||
|
||||
history.scrollRestoration = "manual";
|
||||
document.getElementById("bottom").scrollIntoView();
|
||||
history.pushState({ state: "state3" }, "state3");
|
||||
history.pushState({ state: "state4" }, "state4");
|
||||
window.scrollTo(0, 0);
|
||||
history.back();
|
||||
opener.is(window.scrollY, 0, "Shouldn't have scrolled back to the state3's position");
|
||||
opener.is(history.state.state, "state3", "Unexpected state.");
|
||||
|
||||
var ifr = document.createElement("iframe");
|
||||
ifr.src = "data:text/html,";
|
||||
document.body.appendChild(ifr);
|
||||
ifr.onload = test;
|
||||
break;
|
||||
}
|
||||
case 7: {
|
||||
oldHistoryObject = event.target.contentWindow.history;
|
||||
event.target.src = "about:blank";
|
||||
break;
|
||||
}
|
||||
case 8: {
|
||||
try {
|
||||
var sr = oldHistoryObject.scrollRestoration;
|
||||
opener.ok(false, "Should have thrown an exception.");
|
||||
} catch(ex) {
|
||||
opener.isnot(ex, null, "Did get an exception");
|
||||
}
|
||||
try {
|
||||
oldHistoryObject.scrollRestoration = "auto";
|
||||
opener.ok(false, "Should have thrown an exception.");
|
||||
} catch(ex) {
|
||||
opener.isnot(ex, null, "Did get an exception");
|
||||
}
|
||||
opener.nextTest();
|
||||
window.close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("pageshow",
|
||||
function(e) {
|
||||
setTimeout(test, 0, e);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div style="border: 1px solid black; height: 5000px;">
|
||||
</div>
|
||||
<div id="bottom">Hello world</div>
|
||||
<a href="#hash" name="hash">hash</a>
|
||||
</body>
|
||||
</html>
|
|
@ -10,6 +10,7 @@ support-files =
|
|||
file_document_write_1.html
|
||||
file_fragment_handling_during_load.html
|
||||
file_nested_frames.html
|
||||
file_scrollRestoration.html
|
||||
file_shiftReload_and_pushState.html
|
||||
file_static_and_dynamic_1.html
|
||||
frame0.html
|
||||
|
|
|
@ -29,7 +29,8 @@ var testFiles =
|
|||
"file_bug534178.html", // Session history transaction clean-up.
|
||||
"file_fragment_handling_during_load.html",
|
||||
"file_nested_frames.html",
|
||||
"file_shiftReload_and_pushState.html"
|
||||
"file_shiftReload_and_pushState.html",
|
||||
"file_scrollRestoration.html"
|
||||
];
|
||||
var testCount = 0; // Used by the test files.
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include "nsHistory.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "mozilla/dom/HistoryBinding.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIDocument.h"
|
||||
|
@ -96,6 +95,38 @@ nsHistory::GetLength(ErrorResult& aRv) const
|
|||
return len >= 0 ? len : 0;
|
||||
}
|
||||
|
||||
ScrollRestoration
|
||||
nsHistory::GetScrollRestoration(mozilla::ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
|
||||
if (!win || !win->HasActiveDocument() || !win->GetDocShell()) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return mozilla::dom::ScrollRestoration::Auto;
|
||||
}
|
||||
|
||||
bool currentScrollRestorationIsManual = false;
|
||||
win->GetDocShell()->
|
||||
GetCurrentScrollRestorationIsManual(¤tScrollRestorationIsManual);
|
||||
return currentScrollRestorationIsManual ?
|
||||
mozilla::dom::ScrollRestoration::Manual :
|
||||
mozilla::dom::ScrollRestoration::Auto;
|
||||
}
|
||||
|
||||
void
|
||||
nsHistory::SetScrollRestoration(mozilla::dom::ScrollRestoration aMode,
|
||||
mozilla::ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> win(do_QueryReferent(mInnerWindow));
|
||||
if (!win || !win->HasActiveDocument() || !win->GetDocShell()) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
win->GetDocShell()->
|
||||
SetCurrentScrollRestorationIsManual(
|
||||
aMode == mozilla::dom::ScrollRestoration::Manual);
|
||||
}
|
||||
|
||||
void
|
||||
nsHistory::GetState(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
|
||||
ErrorResult& aRv) const
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/dom/HistoryBinding.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsIDOMHistory.h"
|
||||
|
@ -36,6 +37,9 @@ public:
|
|||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
uint32_t GetLength(mozilla::ErrorResult& aRv) const;
|
||||
mozilla::dom::ScrollRestoration GetScrollRestoration(mozilla::ErrorResult& aRv);
|
||||
void SetScrollRestoration(mozilla::dom::ScrollRestoration aMode,
|
||||
mozilla::ErrorResult& aRv);
|
||||
void GetState(JSContext* aCx, JS::MutableHandle<JS::Value> aResult,
|
||||
mozilla::ErrorResult& aRv) const;
|
||||
void Go(int32_t aDelta, mozilla::ErrorResult& aRv);
|
||||
|
|
|
@ -11,10 +11,14 @@
|
|||
* and create derivative works of this document.
|
||||
*/
|
||||
|
||||
enum ScrollRestoration { "auto", "manual" };
|
||||
|
||||
interface History {
|
||||
[Throws]
|
||||
readonly attribute unsigned long length;
|
||||
[Throws]
|
||||
attribute ScrollRestoration scrollRestoration;
|
||||
[Throws]
|
||||
readonly attribute any state;
|
||||
[Throws, UnsafeInPrerendering]
|
||||
void go(optional long delta = 0);
|
||||
|
|
|
@ -2084,6 +2084,11 @@ nsDocumentViewer::Hide(void)
|
|||
|
||||
nsCOMPtr<nsIDocShell> docShell(mContainer);
|
||||
if (docShell) {
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsIContentViewer> currentViewer;
|
||||
docShell->GetContentViewer(getter_AddRefs(currentViewer));
|
||||
MOZ_ASSERT(currentViewer == this);
|
||||
#endif
|
||||
nsCOMPtr<nsILayoutHistoryState> layoutState;
|
||||
mPresShell->CaptureHistoryState(getter_AddRefs(layoutState));
|
||||
}
|
||||
|
|
|
@ -18,8 +18,8 @@ class nsPresState;
|
|||
template<typename> struct already_AddRefed;
|
||||
|
||||
#define NS_ILAYOUTHISTORYSTATE_IID \
|
||||
{ 0x5208993e, 0xd812, 0x431e, \
|
||||
{ 0x95, 0x9c, 0xc3, 0x84, 0x5b, 0x6e, 0x5a, 0xce } }
|
||||
{ 0xaef27cb3, 0x4df9, 0x4eeb, \
|
||||
{ 0xb0, 0xb0, 0xac, 0x56, 0xcf, 0x86, 0x1d, 0x04 } }
|
||||
|
||||
class nsILayoutHistoryState : public nsISupports {
|
||||
public:
|
||||
|
@ -53,6 +53,11 @@ class nsILayoutHistoryState : public nsISupports {
|
|||
* or all possible history
|
||||
*/
|
||||
virtual void SetScrollPositionOnly(const bool aFlag) = 0;
|
||||
|
||||
/**
|
||||
* Resets nsPresState::GetScrollState of all nsPresState objects to 0,0.
|
||||
*/
|
||||
virtual void ResetScrollState() = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsILayoutHistoryState,
|
||||
|
|
|
@ -36,7 +36,8 @@ public:
|
|||
HasStates() const override;
|
||||
virtual void
|
||||
SetScrollPositionOnly(const bool aFlag) override;
|
||||
|
||||
virtual void
|
||||
ResetScrollState() override;
|
||||
|
||||
private:
|
||||
~nsLayoutHistoryState() {}
|
||||
|
@ -94,3 +95,14 @@ nsLayoutHistoryState::SetScrollPositionOnly(const bool aFlag)
|
|||
{
|
||||
mScrollPositionOnly = aFlag;
|
||||
}
|
||||
|
||||
void
|
||||
nsLayoutHistoryState::ResetScrollState()
|
||||
{
|
||||
for (auto iter = mStates.Iter(); !iter.Done(); iter.Next()) {
|
||||
nsPresState* state = iter.UserData();
|
||||
if (state) {
|
||||
state->SetScrollState(nsPoint(0, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -756,10 +756,14 @@ SessionStore.prototype = {
|
|||
entry.contentType = aEntry.contentType;
|
||||
}
|
||||
|
||||
let x = {}, y = {};
|
||||
aEntry.getScrollPosition(x, y);
|
||||
if (x.value != 0 || y.value != 0) {
|
||||
entry.scroll = x.value + "," + y.value;
|
||||
if (aEntry.scrollRestorationIsManual) {
|
||||
entry.scrollRestorationIsManual = true;
|
||||
} else {
|
||||
let x = {}, y = {};
|
||||
aEntry.getScrollPosition(x, y);
|
||||
if (x.value != 0 || y.value != 0) {
|
||||
entry.scroll = x.value + "," + y.value;
|
||||
}
|
||||
}
|
||||
|
||||
if (aEntry.owner) {
|
||||
|
@ -862,7 +866,9 @@ SessionStore.prototype = {
|
|||
shEntry.stateData.initFromBase64(aEntry.structuredCloneState, aEntry.structuredCloneVersion);
|
||||
}
|
||||
|
||||
if (aEntry.scroll) {
|
||||
if (aEntry.scrollRestorationIsManual) {
|
||||
shEntry.scrollRestorationIsManual = true;
|
||||
} else if (aEntry.scroll) {
|
||||
let scrollPos = aEntry.scroll.split(",");
|
||||
scrollPos = [parseInt(scrollPos[0]) || 0, parseInt(scrollPos[1]) || 0];
|
||||
shEntry.setScrollPosition(scrollPos[0], scrollPos[1]);
|
||||
|
|
Загрузка…
Ссылка в новой задаче