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:
Alphan Chen 2018-10-23 08:17:51 +00:00
Родитель a4e8927982
Коммит a4a1c5d65f
6 изменённых файлов: 56 добавлений и 139 удалений

Просмотреть файл

@ -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);
}
});
},
});