зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1497144 part 2 - Get rid of ScrollPosition.jsm r=JanH,nika
Differential Revision: https://phabricator.services.mozilla.com/D8534 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
a4e8927982
Коммит
a4a1c5d65f
|
@ -20,30 +20,6 @@ ChromeUtils.defineModuleGetter(this, "Utils",
|
|||
const ssu = Cc["@mozilla.org/browser/sessionstore/utils;1"]
|
||||
.getService(Ci.nsISessionStoreUtils);
|
||||
|
||||
/**
|
||||
* Restores frame tree |data|, starting at the given root |frame|. As the
|
||||
* function recurses into descendant frames it will call cb(frame, data) for
|
||||
* each frame it encounters, starting with the given root.
|
||||
*/
|
||||
function restoreFrameTreeData(frame, data, cb) {
|
||||
// Restore data for the root frame.
|
||||
// The callback can abort by returning false.
|
||||
if (cb(frame, data) === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data.hasOwnProperty("children")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Recurse into child frames.
|
||||
ssu.forEachNonDynamicChildFrame(frame, (subframe, index) => {
|
||||
if (data.children[index]) {
|
||||
restoreFrameTreeData(subframe, data.children[index], cb);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This module implements the content side of session restoration. The chrome
|
||||
* side is handled by SessionStore.jsm. The functions in this module are called
|
||||
|
@ -312,7 +288,7 @@ ContentRestoreInternal.prototype = {
|
|||
let window = this.docShell.domWindow;
|
||||
|
||||
// Restore form data.
|
||||
restoreFrameTreeData(window, formdata, (frame, data) => {
|
||||
Utils.restoreFrameTreeData(window, formdata, (frame, data) => {
|
||||
// restore() will return false, and thus abort restoration for the
|
||||
// current |frame| and its descendants, if |data.url| is given but
|
||||
// doesn't match the loaded document's URL.
|
||||
|
@ -320,7 +296,7 @@ ContentRestoreInternal.prototype = {
|
|||
});
|
||||
|
||||
// Restore scroll data.
|
||||
restoreFrameTreeData(window, scrollPositions, (frame, data) => {
|
||||
Utils.restoreFrameTreeData(window, scrollPositions, (frame, data) => {
|
||||
if (data.scroll) {
|
||||
ssu.restoreScrollPosition(frame, data.scroll);
|
||||
}
|
||||
|
|
|
@ -11,11 +11,13 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
|||
FormLikeFactory: "resource://gre/modules/FormLikeFactory.jsm",
|
||||
GeckoViewAutoFill: "resource://gre/modules/GeckoViewAutoFill.jsm",
|
||||
PrivacyFilter: "resource://gre/modules/sessionstore/PrivacyFilter.jsm",
|
||||
ScrollPosition: "resource://gre/modules/ScrollPosition.jsm",
|
||||
Services: "resource://gre/modules/Services.jsm",
|
||||
SessionHistory: "resource://gre/modules/sessionstore/SessionHistory.jsm",
|
||||
});
|
||||
|
||||
const ssu = Cc["@mozilla.org/browser/sessionstore/utils;1"]
|
||||
.getService(Ci.nsISessionStoreUtils);
|
||||
|
||||
class GeckoViewContent extends GeckoViewContentModule {
|
||||
onInit() {
|
||||
debug `onInit`;
|
||||
|
@ -86,7 +88,7 @@ class GeckoViewContent extends GeckoViewContentModule {
|
|||
|
||||
collectSessionState() {
|
||||
let history = SessionHistory.collect(docShell);
|
||||
let [formdata, scrolldata] = this.Utils.mapFrameTree(content, FormData.collect, ScrollPosition.collect);
|
||||
let [formdata, scrolldata] = this.Utils.mapFrameTree(content, FormData.collect, ssu.collectScrollPosition.bind(ssu));
|
||||
|
||||
// Save the current document resolution.
|
||||
let zoom = { value: 1 };
|
||||
|
@ -201,14 +203,23 @@ class GeckoViewContent extends GeckoViewContentModule {
|
|||
addEventListener("load", _ => {
|
||||
const formdata = this._savedState.formdata;
|
||||
if (formdata) {
|
||||
FormData.restoreTree(content, formdata);
|
||||
this.Utils.restoreFrameTreeData(content, formdata, (frame, data) => {
|
||||
// restore() will return false, and thus abort restoration for the
|
||||
// current |frame| and its descendants, if |data.url| is given but
|
||||
// doesn't match the loaded document's URL.
|
||||
return FormData.restore(frame, data);
|
||||
});
|
||||
}
|
||||
}, {capture: true, mozSystemGroup: true, once: true});
|
||||
|
||||
addEventListener("pageshow", _ => {
|
||||
const scrolldata = this._savedState.scrolldata;
|
||||
if (scrolldata) {
|
||||
ScrollPosition.restoreTree(content, scrolldata);
|
||||
this.Utils.restoreFrameTreeData(content, scrolldata, (frame, data) => {
|
||||
if (data.scroll) {
|
||||
ssu.restoreScrollPosition(frame, data.scroll);
|
||||
}
|
||||
});
|
||||
}
|
||||
delete this._savedState;
|
||||
}, {capture: true, mozSystemGroup: true, once: true});
|
||||
|
|
|
@ -13,7 +13,6 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
|||
OS: "resource://gre/modules/osfile.jsm",
|
||||
PrivacyFilter: "resource://gre/modules/sessionstore/PrivacyFilter.jsm",
|
||||
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
|
||||
ScrollPosition: "resource://gre/modules/ScrollPosition.jsm",
|
||||
SessionHistory: "resource://gre/modules/sessionstore/SessionHistory.jsm",
|
||||
SharedPreferences: "resource://gre/modules/SharedPreferences.jsm",
|
||||
Task: "resource://gre/modules/Task.jsm",
|
||||
|
@ -23,6 +22,9 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
|||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Log", "resource://gre/modules/AndroidLog.jsm", "AndroidLog");
|
||||
|
||||
const ssu = Cc["@mozilla.org/browser/sessionstore/utils;1"]
|
||||
.getService(Ci.nsISessionStoreUtils);
|
||||
|
||||
function dump(a) {
|
||||
Services.console.logStringMessage(a);
|
||||
}
|
||||
|
@ -932,7 +934,7 @@ SessionStore.prototype = {
|
|||
|
||||
// Save the scroll position itself.
|
||||
let content = aBrowser.contentWindow;
|
||||
let [scrolldata] = Utils.mapFrameTree(content, ScrollPosition.collect);
|
||||
let [scrolldata] = Utils.mapFrameTree(content, ssu.collectScrollPosition.bind(ssu));
|
||||
scrolldata = scrolldata || {};
|
||||
|
||||
// Save the current document resolution.
|
||||
|
@ -1384,7 +1386,12 @@ SessionStore.prototype = {
|
|||
_restoreTextData: function ss_restoreTextData(aFormData, aBrowser) {
|
||||
if (aFormData) {
|
||||
log("_restoreTextData()");
|
||||
FormData.restoreTree(aBrowser.contentWindow, aFormData);
|
||||
Utils.restoreFrameTreeData(aBrowser.contentWindow, aFormData, (frame, data) => {
|
||||
// restore() will return false, and thus abort restoration for the
|
||||
// current |frame| and its descendants, if |data.url| is given but
|
||||
// doesn't match the loaded document's URL.
|
||||
return FormData.restore(frame, data);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -1411,7 +1418,11 @@ SessionStore.prototype = {
|
|||
_restoreScrollPosition: function ss_restoreScrollPosition(aScrollData, aBrowser) {
|
||||
if (aScrollData) {
|
||||
log("_restoreScrollPosition()");
|
||||
ScrollPosition.restoreTree(aBrowser.contentWindow, aScrollData);
|
||||
Utils.restoreFrameTreeData(aBrowser.contentWindow, aScrollData, (frame, data) => {
|
||||
if (data.scroll) {
|
||||
ssu.restoreScrollPosition(frame, data.scroll);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -241,7 +241,6 @@ EXTRA_JS_MODULES += [
|
|||
'ServiceRequest.jsm',
|
||||
'Services.jsm',
|
||||
'sessionstore/FormData.jsm',
|
||||
'sessionstore/ScrollPosition.jsm',
|
||||
'ShortcutUtils.jsm',
|
||||
'Sqlite.jsm',
|
||||
'Task.jsm',
|
||||
|
|
|
@ -1,104 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
var EXPORTED_SYMBOLS = ["ScrollPosition"];
|
||||
|
||||
/**
|
||||
* It provides methods to collect scroll positions from single frames and to
|
||||
* restore scroll positions for frame trees.
|
||||
*
|
||||
* This is a child process module.
|
||||
*/
|
||||
var ScrollPosition = Object.freeze({
|
||||
collect(frame) {
|
||||
return ScrollPositionInternal.collect(frame);
|
||||
},
|
||||
|
||||
restore(frame, value) {
|
||||
ScrollPositionInternal.restore(frame, value);
|
||||
},
|
||||
|
||||
restoreTree(root, data) {
|
||||
ScrollPositionInternal.restoreTree(root, data);
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* This module's internal API.
|
||||
*/
|
||||
var ScrollPositionInternal = {
|
||||
/**
|
||||
* Collects scroll position data for any given |frame| in the frame hierarchy.
|
||||
*
|
||||
* @param frame (DOMWindow)
|
||||
*
|
||||
* @return {scroll: "x,y"} e.g. {scroll: "100,200"}
|
||||
* Returns null when there is no scroll data we want to store for the
|
||||
* given |frame|.
|
||||
*/
|
||||
collect(frame) {
|
||||
let utils = frame.windowUtils;
|
||||
let scrollX = {}, scrollY = {};
|
||||
utils.getScrollXY(false /* no layout flush */, scrollX, scrollY);
|
||||
|
||||
if (scrollX.value || scrollY.value) {
|
||||
return {scroll: scrollX.value + "," + scrollY.value};
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Restores scroll position data for any given |frame| in the frame hierarchy.
|
||||
*
|
||||
* @param frame (DOMWindow)
|
||||
* @param value (object, see collect())
|
||||
*/
|
||||
restore(frame, value) {
|
||||
let match;
|
||||
|
||||
if (value && (match = /(\d+),(\d+)/.exec(value))) {
|
||||
frame.scrollTo(match[1], match[2]);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Restores scroll position data for the current frame hierarchy starting at
|
||||
* |root| using the given scroll position |data|.
|
||||
*
|
||||
* If the given |root| frame's hierarchy doesn't match that of the given
|
||||
* |data| object we will silently discard data for unreachable frames. We
|
||||
* may as well assign scroll positions to the wrong frames if some were
|
||||
* reordered or removed.
|
||||
*
|
||||
* @param root (DOMWindow)
|
||||
* @param data (object)
|
||||
* {
|
||||
* scroll: "100,200",
|
||||
* children: [
|
||||
* {scroll: "100,200"},
|
||||
* null,
|
||||
* {scroll: "200,300", children: [ ... ]}
|
||||
* ]
|
||||
* }
|
||||
*/
|
||||
restoreTree(root, data) {
|
||||
if (data.hasOwnProperty("scroll")) {
|
||||
this.restore(root, data.scroll);
|
||||
}
|
||||
|
||||
if (!data.hasOwnProperty("children")) {
|
||||
return;
|
||||
}
|
||||
|
||||
let frames = root.frames;
|
||||
data.children.forEach((child, index) => {
|
||||
if (child && index < frames.length) {
|
||||
this.restoreTree(frames[index], child);
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
|
@ -199,4 +199,28 @@ var Utils = Object.freeze({
|
|||
|
||||
return objs.map((obj) => Object.getOwnPropertyNames(obj).length ? obj : null);
|
||||
},
|
||||
|
||||
/**
|
||||
* Restores frame tree |data|, starting at the given root |frame|. As the
|
||||
* function recurses into descendant frames it will call cb(frame, data) for
|
||||
* each frame it encounters, starting with the given root.
|
||||
*/
|
||||
restoreFrameTreeData(frame, data, cb) {
|
||||
// Restore data for the root frame.
|
||||
// The callback can abort by returning false.
|
||||
if (cb(frame, data) === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data.hasOwnProperty("children")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Recurse into child frames.
|
||||
ssu.forEachNonDynamicChildFrame(frame, (subframe, index) => {
|
||||
if (data.children[index]) {
|
||||
this.restoreFrameTreeData(subframe, data.children[index], cb);
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче