Backed out 3 changesets (bug 1700963) for Browser-chrome failures in docshell/test/browser/browser_bug1309900_crossProcessHistoryNavigation.js. CLOSED TREE

Backed out changeset cda35e554327 (bug 1700963)
Backed out changeset fbafd75b06d3 (bug 1700963)
Backed out changeset 8b922e4f612b (bug 1700963)
This commit is contained in:
Dorel Luca 2021-04-14 23:26:05 +03:00
Родитель d2ad4ace31
Коммит b15d7d893e
4 изменённых файлов: 145 добавлений и 154 удалений

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

@ -522,7 +522,9 @@ class ContentSessionStore {
this.contentRestoreInitialized = false; this.contentRestoreInitialized = false;
this.handlers = [this.messageQueue]; this.handlers = [this.messageQueue];
if (!Services.appinfo.sessionHistoryInParent) { if (Services.appinfo.sessionHistoryInParent) {
this.mm.sendAsyncMessage("SessionStore:addSHistoryListener");
} else {
this.handlers.push(new EventListener(this)); this.handlers.push(new EventListener(this));
this.handlers.push(new SessionHistoryListener(this)); this.handlers.push(new SessionHistoryListener(this));

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

@ -53,8 +53,6 @@ const OBSERVING = [
"browser:purge-session-history-for-domain", "browser:purge-session-history-for-domain",
"idle-daily", "idle-daily",
"clear-origin-attributes-data", "clear-origin-attributes-data",
"browsing-context-did-set-embedder",
"browsing-context-discarded",
]; ];
// XUL Window properties to (re)store // XUL Window properties to (re)store
@ -97,6 +95,10 @@ const MESSAGES = [
// The content script encountered an error. // The content script encountered an error.
"SessionStore:error", "SessionStore:error",
// The content script asks us to add the session history listener in the
// parent process when sessionHistory is in the parent process.
"SessionStore:addSHistoryListener",
]; ];
// The list of messages we accept from <xul:browser>s that have no tab // The list of messages we accept from <xul:browser>s that have no tab
@ -112,6 +114,9 @@ const NOTAB_MESSAGES = new Set([
// For a description see above. // For a description see above.
"SessionStore:error", "SessionStore:error",
// For a description see above.
"SessionStore:addSHistoryListener",
]); ]);
// The list of messages we accept without an "epoch" parameter. // The list of messages we accept without an "epoch" parameter.
@ -122,6 +127,9 @@ const NOEPOCH_MESSAGES = new Set([
// For a description see above. // For a description see above.
"SessionStore:error", "SessionStore:error",
// For a description see above.
"SessionStore:addSHistoryListener",
]); ]);
// The list of messages we want to receive even during the short period after a // The list of messages we want to receive even during the short period after a
@ -986,83 +994,40 @@ var SessionStoreInternal = {
this._forgetTabsWithUserContextId(userContextId); this._forgetTabsWithUserContextId(userContextId);
} }
break; break;
case "browsing-context-did-set-embedder":
if (Services.appinfo.sessionHistoryInParent) {
if (
aSubject &&
aSubject === aSubject.top &&
aSubject.isContent &&
aSubject.embedderElement
) {
this.addSHistoryListener(aSubject.embedderElement, aSubject);
}
}
break;
case "browsing-context-discarded":
if (Services.appinfo.sessionHistoryInParent) {
let listener = this._browserSHistoryListener.get(
aSubject.embedderElement?.permanentKey
);
if (listener) {
listener.uninstall();
}
}
break;
} }
}, },
// Create a new SessionHistory listener on the provided browser element and // Create a sHistoryListener and register it.
// save a reference to that listener on the _browserSHistoryListener map. // We also need to save the SHistoryLister into this._browserSHistoryListener.
addSHistoryListener(aBrowser, aBrowsingContext) { addSHistoryListener(aBrowser) {
class SHistoryListener { function SHistoryListener(browser) {
constructor(browser, browsingContext) { browser.browsingContext.sessionHistory.addSHistoryListener(this);
if (!browsingContext.sessionHistory) {
throw new Error("no SessionHistory object!");
}
this._permanentKey = browser.permanentKey; this.browserId = browser.browsingContext.browserId;
this._browserId = browsingContext.browserId; this._fromIdx = kNoIndex;
this._fromIdx = kNoIndex; this._sHistoryChanges = false;
this._permanentKey = browser.permanentKey;
if (browser.currentURI && browser.ownerGlobal) {
this._lastKnownBody = browser.ownerGlobal.document.body;
}
}
SHistoryListener.prototype = {
QueryInterface: ChromeUtils.generateQI([
"nsISHistoryListener",
"nsISupportsWeakReference",
]),
// Immediately collect data if we start with a non-empty SHistory. notifySHistoryChanges(index) {
if (
browsingContext.currentURI?.spec !== "about:blank" ||
browsingContext.sessionHistory.count !== 0
) {
browser.frameLoader.requestSHistoryUpdate(/* aImmediately */ true);
}
browsingContext.sessionHistory.addSHistoryListener(this);
}
uninstall() {
let bc = BrowsingContext.getCurrentTopByBrowserId(this._browserId);
if (bc?.sessionHistory) {
bc.sessionHistory.removeSHistoryListener(this);
}
SessionStoreInternal._browserSHistoryListener.delete(
this._permanentKey
);
}
reset() {
this._fromIdx = kNoIndex;
}
didCollect() {
return this._fromIdx !== kNoIndex;
}
collectFrom(index) {
if (this._fromIdx <= index) { if (this._fromIdx <= index) {
// If we already know that we need to update history from index N we // If we already know that we need to update history from index N we can ignore any changes
// can ignore any changes that happened with an element with index // that happened with an element with index larger than N.
// larger than N. // Note: initially we use kNoIndex which is MAX_SAFE_INTEGER which means we don't ignore anything
// // here, and in case of navigation in the history back and forth we use kLastIndex which ignores
// Note: initially we use kNoIndex which is MAX_SAFE_INTEGER which
// means we don't ignore anything here, and in case of navigation in
// the history back and forth cases we use kLastIndex which ignores
// only the subsequent navigations, but not any new elements added. // only the subsequent navigations, but not any new elements added.
return; return;
} }
let browser = BrowsingContext.getCurrentTopByBrowserId(this._browserId) let browser = BrowsingContext.getCurrentTopByBrowserId(this.browserId)
?.embedderElement; ?.embedderElement;
if (!browser) { if (!browser) {
@ -1070,40 +1035,49 @@ var SessionStoreInternal = {
return; return;
} }
if (!this.didCollect()) { if (!this._sHistoryChanges) {
browser.frameLoader.requestSHistoryUpdate(/* aImmediately */ false); browser.frameLoader.requestSHistoryUpdate(/*aImmediately*/ false);
this._sHistoryChanges = true;
} }
this._fromIdx = index; this._fromIdx = index;
} if (browser.currentURI && browser.ownerGlobal) {
OnHistoryNewEntry(newURI, oldIndex) { this._lastKnownBody = browser.ownerGlobal.document.body;
// We use oldIndex - 1 to collect the current entry as well. This makes }
// sure to collect any changes that were made to the entry while the },
// document was active.
this.collectFrom(oldIndex == -1 ? oldIndex : oldIndex - 1);
}
OnHistoryGotoIndex() {
this.collectFrom(kLastIndex);
}
OnHistoryPurge() {
this.collectFrom(-1);
}
OnHistoryReload() {
this.collectFrom(-1);
return true;
}
OnHistoryReplaceEntry() {
this.collectFrom(-1);
}
}
SHistoryListener.prototype.QueryInterface = ChromeUtils.generateQI([
"nsISHistoryListener",
"nsISupportsWeakReference",
]);
if (!aBrowser || !aBrowser.permanentKey) { uninstall() {
return; let bc = BrowsingContext.getCurrentTopByBrowserId(this.browserId);
}
if (bc?.sessionHistory) {
bc.sessionHistory.removeSHistoryListener(this);
}
SessionStoreInternal._browserSHistoryListener.delete(
this._permanentKey
);
},
OnHistoryNewEntry(newURI, oldIndex) {
// We use oldIndex - 1 to collect the current entry as well. This makes sure to
// collect any changes that were made to the entry while the document was active.
this.notifySHistoryChanges(oldIndex == -1 ? oldIndex : oldIndex - 1);
},
OnHistoryGotoIndex() {
this.notifySHistoryChanges(kLastIndex);
},
OnHistoryPurge() {
this.notifySHistoryChanges(-1);
},
OnHistoryReload() {
this.notifySHistoryChanges(-1);
return true;
},
OnHistoryReplaceEntry() {
this.notifySHistoryChanges(-1);
},
};
// Don't bother registering another listener if we already have one for this // Don't bother registering another listener if we already have one for this
// browser. We would've already updated the listener's state in response to // browser. We would've already updated the listener's state in response to
@ -1112,8 +1086,20 @@ var SessionStoreInternal = {
return; return;
} }
let listener = new SHistoryListener(aBrowser, aBrowsingContext); // XXX: When can this happen?
if (!aBrowser.browsingContext?.sessionHistory) {
throw new Error("no SessionHistory object");
}
let listener = new SHistoryListener(aBrowser);
this._browserSHistoryListener.set(aBrowser.permanentKey, listener); this._browserSHistoryListener.set(aBrowser.permanentKey, listener);
// Collect data if we start with a non-empty shistory.
let uri = aBrowser.currentURI.displaySpec;
let history = aBrowser.frameLoader.browsingContext.sessionHistory;
if (uri != "about:blank" || history.count != 0) {
aBrowser.frameLoader.requestSHistoryUpdate(/*aImmediately*/ true);
}
}, },
/** /**
@ -1249,45 +1235,62 @@ var SessionStoreInternal = {
return; return;
} }
// Only collect history changes for toplevel contexts. let sHistoryChangedInListener = false;
if (aBrowsingContext === aBrowsingContext.top) { let listener = this._browserSHistoryListener.get(aBrowser.permanentKey);
let listener = this._browserSHistoryListener.get(aBrowser.permanentKey); if (listener) {
sHistoryChangedInListener = listener._sHistoryChanges;
}
if (aData.sHistoryNeeded || sHistoryChangedInListener) {
if (!listener) { if (!listener) {
this.addSHistoryListener(aBrowser, aBrowsingContext); debug(
"updateSessionStoreFromTablistener() with aData.sHistoryNeeded, but no SHlistener. Add again!!!"
);
this.addSHistoryListener(aBrowser);
listener = this._browserSHistoryListener.get(aBrowser.permanentKey); listener = this._browserSHistoryListener.get(aBrowser.permanentKey);
} }
if (!listener) {
throw new Error("no SHistoryListener!");
}
let needsFullCollect = !!aData.sHistoryNeeded; if (listener) {
if (needsFullCollect || listener.didCollect()) { if (!aData.sHistoryNeeded && listener._fromIdx == kNoIndex) {
if (!aBrowsingContext.sessionHistory) { // No shistory changes needed.
throw new Error("no SessionHistory object!"); listener._sHistoryChanges = false;
} else if (aBrowsingContext.sessionHistory) {
let uri = aBrowsingContext.currentURI?.displaySpec;
let body =
aBrowser.ownerGlobal?.document.body ?? listener._lastKnownBody;
// If aData.sHistoryNeeded we need to collect all session
// history entries, because with SHIP this indicates that we
// either saw 'DOMTitleChanged' in
// mozilla::dom::TabListener::HandleEvent or
// 'OnDocumentStart/OnDocumentEnd' was called on
// mozilla::dom::ContentSessionStore, and both needs a full
// collect.
aData.data.historychange = SessionHistory.collectFromParent(
uri,
body,
aBrowsingContext.sessionHistory,
listener._sHistoryChanges && !aData.sHistoryNeeded
? listener._fromIdx
: -1
);
listener._sHistoryChanges = false;
listener._fromIdx = kNoIndex;
} else {
debug(
"updateSessionStoreFromTablistener() with sHistoryNeeded, but no sessionHistory.\n"
);
} }
} else {
// If |needsFullCollect| we need to collect all session history entries, debug(
// because with SHIP this indicates that we either saw 'DOMTitleChanged' "updateSessionStoreFromTablistener() with sHistoryNeeded, but no sHlistener.\n"
// in mozilla::dom::TabListener::HandleEvent or 'OnDocument{Start,End}'
// was called on mozilla::dom::ContentSessionStore, and both need a full
// collect.
let fromIdx = -1;
if (listener.didCollect() && !needsFullCollect) {
fromIdx = listener._fromIdx;
}
aData.data.historychange = SessionHistory.collectFromParent(
aBrowsingContext.currentURI?.spec,
true, // Bug 1704574
aBrowsingContext.sessionHistory,
fromIdx
); );
listener.reset();
} }
} }
delete aData.sHistoryNeeded; // Avoid saving this to disk. if ("sHistoryNeeded" in aData) {
delete aData.sHistoryNeeded;
}
TabState.update(aBrowser, aData); TabState.update(aBrowser, aData);
let win = aBrowser.ownerGlobal; let win = aBrowser.ownerGlobal;
this.saveStateDelayed(win); this.saveStateDelayed(win);
@ -1329,6 +1332,9 @@ var SessionStoreInternal = {
} }
switch (aMessage.name) { switch (aMessage.name) {
case "SessionStore:addSHistoryListener":
this.addSHistoryListener(browser);
break;
case "SessionStore:update": case "SessionStore:update":
// |browser.frameLoader| might be empty if the browser was already // |browser.frameLoader| might be empty if the browser was already
// destroyed and its tab removed. In that case we still have the last // destroyed and its tab removed. In that case we still have the last

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

@ -688,13 +688,6 @@ void BrowsingContext::SetEmbedderElement(Element* aEmbedder) {
} }
mEmbedderElement = aEmbedder; mEmbedderElement = aEmbedder;
if (mEmbedderElement) {
if (nsCOMPtr<nsIObserverService> obs = services::GetObserverService()) {
obs->NotifyWhenScriptSafe(ToSupports(this),
"browsing-context-did-set-embedder", nullptr);
}
}
} }
void BrowsingContext::Embed() { void BrowsingContext::Embed() {

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

@ -42,13 +42,8 @@ var SessionHistory = Object.freeze({
return SessionHistoryInternal.collect(docShell, aFromIdx); return SessionHistoryInternal.collect(docShell, aFromIdx);
}, },
collectFromParent(uri, documentHasChildNodes, history, aFromIdx = -1) { collectFromParent(uri, body, history, aFromIdx = -1) {
return SessionHistoryInternal.collectCommon( return SessionHistoryInternal.collectCommon(uri, body, history, aFromIdx);
uri,
documentHasChildNodes,
history,
aFromIdx
);
}, },
restore(docShell, tabData) { restore(docShell, tabData) {
@ -106,15 +101,10 @@ var SessionHistoryInternal = {
let uri = webNavigation.currentURI.displaySpec; let uri = webNavigation.currentURI.displaySpec;
let body = webNavigation.document.body; let body = webNavigation.document.body;
let history = webNavigation.sessionHistory; let history = webNavigation.sessionHistory;
return this.collectCommon( return this.collectCommon(uri, body, history.legacySHistory, aFromIdx);
uri,
body && body.hasChildNodes(),
history.legacySHistory,
aFromIdx
);
}, },
collectCommon(uri, documentHasChildNodes, shistory, aFromIdx) { collectCommon(uri, body, shistory, aFromIdx) {
let data = { let data = {
entries: [], entries: [],
requestedIndex: shistory.requestedIndex + 1, requestedIndex: shistory.requestedIndex + 1,
@ -152,7 +142,7 @@ var SessionHistoryInternal = {
// or it's a blank tab that was modified (like a custom newtab page), // or it's a blank tab that was modified (like a custom newtab page),
// record it. For about:blank we explicitly want an empty array without // record it. For about:blank we explicitly want an empty array without
// an 'index' property to denote that there are no history entries. // an 'index' property to denote that there are no history entries.
if (uri != "about:blank" || documentHasChildNodes) { if (uri != "about:blank" || (body && body.hasChildNodes())) {
data.entries.push({ data.entries.push({
url: uri, url: uri,
triggeringPrincipal_base64: E10SUtils.SERIALIZED_SYSTEMPRINCIPAL, triggeringPrincipal_base64: E10SUtils.SERIALIZED_SYSTEMPRINCIPAL,