Commit be1a9a3c authored by Gijs Kruitbosch's avatar Gijs Kruitbosch
Browse files

Bug 1640490 - Backed out changeset 217394da44ac (bug 1591469) for breaking...

Bug 1640490 - Backed out changeset 217394da44ac (bug 1591469) for breaking about:reader in a lot of cases. r=neildeakin, a=jcristau

Differential Revision: https://phabricator.services.mozilla.com/D77671
parent e7293331
......@@ -6,6 +6,10 @@
var EXPORTED_SYMBOLS = ["AboutReaderChild"];
const { ActorChild } = ChromeUtils.import(
"resource://gre/modules/ActorChild.jsm"
);
ChromeUtils.defineModuleGetter(
this,
"AboutReader",
......@@ -22,38 +26,25 @@ ChromeUtils.defineModuleGetter(
"resource://gre/modules/Readerable.jsm"
);
class AboutReaderChild extends JSWindowActorChild {
constructor() {
super();
class AboutReaderChild extends ActorChild {
constructor(dispatcher) {
super(dispatcher);
this._reader = null;
this._articlePromise = null;
this._isLeavingReaderableReaderMode = false;
}
willDestroy() {
this.cancelPotentialPendingReadabilityCheck();
this.readerModeHidden();
}
readerModeHidden() {
if (this._reader) {
this._reader.clearActor();
}
this._reader = null;
}
receiveMessage(message) {
switch (message.name) {
case "Reader:ToggleReaderMode":
if (!this.isAboutReader) {
this._articlePromise = ReaderMode.parseDocument(this.document).catch(
Cu.reportError
);
ReaderMode.enterReaderMode(this.docShell, this.contentWindow);
this._articlePromise = ReaderMode.parseDocument(
this.content.document
).catch(Cu.reportError);
ReaderMode.enterReaderMode(this.mm.docShell, this.content);
} else {
this._isLeavingReaderableReaderMode = this.isReaderableAboutReader;
ReaderMode.leaveReaderMode(this.docShell, this.contentWindow);
ReaderMode.leaveReaderMode(this.mm.docShell, this.content);
}
break;
......@@ -61,40 +52,37 @@ class AboutReaderChild extends JSWindowActorChild {
this.updateReaderButton(!!(message.data && message.data.isArticle));
break;
}
// Forward the message to the reader if it has been created.
if (this._reader) {
this._reader.receiveMessage(message);
}
}
get isAboutReader() {
if (!this.document) {
if (!this.content) {
return false;
}
return this.document.documentURI.startsWith("about:reader");
return this.content.document.documentURI.startsWith("about:reader");
}
get isReaderableAboutReader() {
return this.isAboutReader && !this.document.documentElement.dataset.isError;
return (
this.isAboutReader &&
!this.content.document.documentElement.dataset.isError
);
}
handleEvent(aEvent) {
if (aEvent.originalTarget.defaultView != this.contentWindow) {
if (aEvent.originalTarget.defaultView != this.content) {
return;
}
switch (aEvent.type) {
case "DOMContentLoaded":
case "AboutReaderContentLoaded":
if (!this.isAboutReader) {
this.updateReaderButton();
return;
}
if (this.document.body) {
if (this.content.document.body) {
// Update the toolbar icon to show the "reader active" icon.
this.sendAsyncMessage("Reader:UpdateReaderButton");
this._reader = new AboutReader(this, this._articlePromise);
this.mm.sendAsyncMessage("Reader:UpdateReaderButton");
new AboutReader(this.mm, this.content, this._articlePromise);
this._articlePromise = null;
}
break;
......@@ -104,7 +92,7 @@ class AboutReaderChild extends JSWindowActorChild {
// this._isLeavingReaderableReaderMode is used here to keep the Reader Mode icon
// visible in the location bar when transitioning from reader-mode page
// back to the readable source page.
this.sendAsyncMessage("Reader:UpdateReaderButton", {
this.mm.sendAsyncMessage("Reader:UpdateReaderButton", {
isArticle: this._isLeavingReaderableReaderMode,
});
if (this._isLeavingReaderableReaderMode) {
......@@ -119,6 +107,9 @@ class AboutReaderChild extends JSWindowActorChild {
this.updateReaderButton();
}
break;
case "DOMContentLoaded":
this.updateReaderButton();
break;
}
}
......@@ -132,9 +123,9 @@ class AboutReaderChild extends JSWindowActorChild {
if (
!Readerable.isEnabledForParseOnLoad ||
this.isAboutReader ||
!this.contentWindow ||
!(this.document instanceof this.contentWindow.HTMLDocument) ||
this.document.mozSyntheticDocument
!this.content ||
!(this.content.document instanceof this.content.HTMLDocument) ||
this.content.document.mozSyntheticDocument
) {
return;
}
......@@ -144,14 +135,11 @@ class AboutReaderChild extends JSWindowActorChild {
cancelPotentialPendingReadabilityCheck() {
if (this._pendingReadabilityCheck) {
if (this._listenerWindow) {
this._listenerWindow.removeEventListener(
"MozAfterPaint",
this._pendingReadabilityCheck
);
}
this.mm.removeEventListener(
"MozAfterPaint",
this._pendingReadabilityCheck
);
delete this._pendingReadabilityCheck;
delete this._listenerWindow;
}
}
......@@ -165,43 +153,28 @@ class AboutReaderChild extends JSWindowActorChild {
this,
forceNonArticle
);
this._listenerWindow = this.contentWindow.windowRoot;
this.contentWindow.windowRoot.addEventListener(
"MozAfterPaint",
this._pendingReadabilityCheck
);
this.mm.addEventListener("MozAfterPaint", this._pendingReadabilityCheck);
}
onPaintWhenWaitedFor(forceNonArticle, event) {
// In non-e10s, we'll get called for paints other than ours, and so it's
// possible that this page hasn't been laid out yet, in which case we
// should wait until we get an event that does relate to our layout. We
// determine whether any of our this.contentWindow got painted by checking
// if there are any painted rects.
// determine whether any of our this.content got painted by checking if there
// are any painted rects.
if (!event.clientRects.length) {
return;
}
this.cancelPotentialPendingReadabilityCheck();
// Ignore errors from actors that have been unloaded before the
// paint event timer fires.
let document;
try {
document = this.document;
} catch (ex) {
return;
}
// Only send updates when there are articles; there's no point updating with
// |false| all the time.
if (Readerable.isProbablyReaderable(document)) {
this.sendAsyncMessage("Reader:UpdateReaderButton", {
if (Readerable.isProbablyReaderable(this.content.document)) {
this.mm.sendAsyncMessage("Reader:UpdateReaderButton", {
isArticle: true,
});
} else if (forceNonArticle) {
this.sendAsyncMessage("Reader:UpdateReaderButton", {
this.mm.sendAsyncMessage("Reader:UpdateReaderButton", {
isArticle: false,
});
}
......
......@@ -10,9 +10,6 @@ with Files("**"):
with Files("ContentSearch*.jsm"):
BUG_COMPONENT = ("Firefox", "Search")
with Files("AboutReaderParent.jsm"):
BUG_COMPONENT = ("Toolkit", "Reader Mode")
with Files("LightweightThemeChild.jsm"):
BUG_COMPONENT = ("WebExtensions", "Themes")
......@@ -39,7 +36,6 @@ FINAL_TARGET_FILES.actors += [
'AboutProtectionsChild.jsm',
'AboutProtectionsParent.jsm',
'AboutReaderChild.jsm',
'AboutReaderParent.jsm',
'AboutTabCrashedChild.jsm',
'AboutTabCrashedParent.jsm',
'BlockedSiteChild.jsm',
......
......@@ -334,7 +334,7 @@ var FullZoom = {
async reduce() {
let browser = gBrowser.selectedBrowser;
if (browser.currentURI.spec.startsWith("about:reader")) {
browser.sendMessageToActor("Reader:ZoomOut", {}, "AboutReader");
browser.messageManager.sendAsyncMessage("Reader:ZoomOut");
} else if (this._isPDFViewer(browser)) {
browser.messageManager.sendAsyncMessage("PDFJS:ZoomOut");
} else {
......@@ -351,7 +351,7 @@ var FullZoom = {
async enlarge() {
let browser = gBrowser.selectedBrowser;
if (browser.currentURI.spec.startsWith("about:reader")) {
browser.sendMessageToActor("Reader:ZoomIn", {}, "AboutReader");
browser.messageManager.sendAsyncMessage("Reader:ZoomIn");
} else if (this._isPDFViewer(browser)) {
browser.messageManager.sendAsyncMessage("PDFJS:ZoomIn");
} else {
......@@ -371,7 +371,7 @@ var FullZoom = {
changeZoomBy(aBrowser, aValue) {
if (aBrowser.currentURI.spec.startsWith("about:reader")) {
const message = aValue > 0 ? "Reader::ZoomIn" : "Reader:ZoomOut";
aBrowser.sendMessageToActor(message, {}, "AboutReader");
aBrowser.messageManager.sendAsyncMessage(message);
return;
} else if (this._isPDFViewer(aBrowser)) {
const message = aValue > 0 ? "PDFJS::ZoomIn" : "PDFJS:ZoomOut";
......@@ -412,7 +412,7 @@ var FullZoom = {
reset: function FullZoom_reset(browser = gBrowser.selectedBrowser) {
let forceValue;
if (browser.currentURI.spec.startsWith("about:reader")) {
browser.sendMessageToActor("Reader:ResetZoom", {}, "AboutReader");
browser.messageManager.sendAsyncMessage("Reader:ResetZoom");
} else if (this._isPDFViewer(browser)) {
browser.messageManager.sendAsyncMessage("PDFJS:ZoomReset");
// Ensure that the UI elements of the PDF viewer won't be zoomed in/out
......
......@@ -42,7 +42,7 @@
<command id="View:PageSource" oncommand="BrowserViewSource(window.gBrowser.selectedBrowser);"/>
<command id="View:PageInfo" oncommand="BrowserPageInfo();"/>
<command id="View:FullScreen" oncommand="BrowserFullScreen();"/>
<command id="View:ReaderView" oncommand="AboutReaderParent.toggleReaderMode(event);"/>
<command id="View:ReaderView" oncommand="ReaderParent.toggleReaderMode(event);"/>
<command id="View:PictureInPicture" oncommand="PictureInPicture.onCommand(event);"/>
<command id="cmd_find" oncommand="gLazyFindCommand('onFindCommand')"/>
<command id="cmd_findAgain" oncommand="gLazyFindCommand('onFindAgainCommand', false)"/>
......
......@@ -16,7 +16,6 @@ ChromeUtils.import("resource://gre/modules/NotificationDB.jsm");
XPCOMUtils.defineLazyModuleGetters(this, {
AboutNewTab: "resource:///modules/AboutNewTab.jsm",
AboutReaderParent: "resource:///actors/AboutReaderParent.jsm",
AddonManager: "resource://gre/modules/AddonManager.jsm",
AMTelemetry: "resource://gre/modules/AddonManager.jsm",
NewTabPagePreloading: "resource:///modules/NewTabPagePreloading.jsm",
......@@ -61,6 +60,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
PromiseUtils: "resource://gre/modules/PromiseUtils.jsm",
// TODO (Bug 1529552): Remove once old urlbar code goes away.
ReaderMode: "resource://gre/modules/ReaderMode.jsm",
ReaderParent: "resource:///modules/ReaderParent.jsm",
RFPHelper: "resource://gre/modules/RFPHelper.jsm",
SafeBrowsing: "resource://gre/modules/SafeBrowsing.jsm",
Sanitizer: "resource:///modules/Sanitizer.jsm",
......@@ -5293,7 +5293,7 @@ var XULBrowserWindow = {
}
Services.obs.notifyObservers(null, "touchbar-location-change", location);
UpdateBackForwardCommands(gBrowser.webNavigation);
AboutReaderParent.updateReaderButton(gBrowser.selectedBrowser);
ReaderParent.updateReaderButton(gBrowser.selectedBrowser);
if (!gMultiProcessBrowser) {
// Bug 1108553 - Cannot rotate images with e10s
......@@ -5896,13 +5896,9 @@ var TabsProgressListener = {
if (aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT) {
// Reader mode cares about history.pushState and friends.
// FIXME: The content process should manage this directly (bug 1445351).
aBrowser.sendMessageToActor(
"Reader:PushState",
{
isArticle: aBrowser.isArticle,
},
"AboutReader"
);
aBrowser.messageManager.sendAsyncMessage("Reader:PushState", {
isArticle: aBrowser.isArticle,
});
return;
}
......
......@@ -1056,7 +1056,7 @@
tooltip="dynamic-shortcut-tooltip"
role="button"
hidden="true"
onclick="AboutReaderParent.buttonClick(event);"/>
onclick="ReaderParent.buttonClick(event);"/>
<toolbarbutton id="urlbar-zoom-button"
onclick="FullZoom.reset();"
tooltip="dynamic-shortcut-tooltip"
......
......@@ -44,6 +44,7 @@ const whitelist = {
"resource:///actors/LinkHandlerChild.jsm",
"resource:///actors/SearchTelemetryChild.jsm",
"resource://gre/actors/AutoCompleteChild.jsm",
"resource://gre/modules/ActorChild.jsm",
"resource://gre/modules/ActorManagerChild.jsm",
"resource://gre/modules/E10SUtils.jsm",
"resource://gre/modules/Readerable.jsm",
......
......@@ -181,21 +181,6 @@ let JSWINDOWACTORS = {
matches: ["about:protections"],
},
AboutReader: {
parent: {
moduleURI: "resource:///actors/AboutReaderParent.jsm",
},
child: {
moduleURI: "resource:///actors/AboutReaderChild.jsm",
events: {
DOMContentLoaded: {},
pageshow: { mozSystemGroup: true },
pagehide: { mozSystemGroup: true },
},
},
messageManagerGroups: ["browsers"],
},
AboutTabCrashed: {
parent: {
moduleURI: "resource:///actors/AboutTabCrashedParent.jsm",
......@@ -552,6 +537,20 @@ let JSWINDOWACTORS = {
};
let LEGACY_ACTORS = {
AboutReader: {
child: {
module: "resource:///actors/AboutReaderChild.jsm",
group: "browsers",
events: {
AboutReaderContentLoaded: { wantUntrusted: true },
DOMContentLoaded: {},
pageshow: { mozSystemGroup: true },
pagehide: { mozSystemGroup: true },
},
messages: ["Reader:ToggleReaderMode", "Reader:PushState"],
},
},
URIFixup: {
child: {
module: "resource:///actors/URIFixupChild.jsm",
......@@ -717,6 +716,7 @@ XPCOMUtils.defineLazyModuleGetters(this, {
AboutLoginsParent: "resource:///modules/AboutLoginsParent.jsm",
AsyncPrefs: "resource://gre/modules/AsyncPrefs.jsm",
PluginManager: "resource:///actors/PluginParent.jsm",
ReaderParent: "resource:///modules/ReaderParent.jsm",
});
/**
......
......@@ -25,11 +25,6 @@ ChromeUtils.defineModuleGetter(
"PromiseUtils",
"resource://gre/modules/PromiseUtils.jsm"
);
ChromeUtils.defineModuleGetter(
this,
"AboutReaderParent",
"resource:///actors/AboutReaderParent.jsm"
);
var { ExtensionError } = ExtensionUtils;
......@@ -357,7 +352,7 @@ class TabTracker extends TabTrackerBase {
windowTracker.addOpenListener(this._handleWindowOpen);
windowTracker.addCloseListener(this._handleWindowClose);
AboutReaderParent.addMessageListener("Reader:UpdateReaderButton", this);
Services.mm.addMessageListener("Reader:UpdateReaderButton", this);
/* eslint-disable mozilla/balanced-listeners */
this.on("tab-detached", this._handleTabDestroyed);
......
......@@ -1489,11 +1489,8 @@ this.tabs = class extends ExtensionAPI {
);
}
let nativeTab = getTabOrActive(tabId);
nativeTab.linkedBrowser.sendMessageToActor(
"Reader:ToggleReaderMode",
{},
"AboutReader"
nativeTab.linkedBrowser.messageManager.sendAsyncMessage(
"Reader:ToggleReaderMode"
);
},
......
......@@ -11,7 +11,6 @@ const { XPCOMUtils } = ChromeUtils.import(
XPCOMUtils.defineLazyModuleGetters(this, {
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
EveryWindow: "resource:///modules/EveryWindow.jsm",
AboutReaderParent: "resource:///actors/AboutReaderParent.jsm",
});
const FEW_MINUTES = 15 * 60 * 1000; // 15 mins
......@@ -99,7 +98,7 @@ this.ASRouterTriggerListeners = new Map([
init(triggerHandler, hosts, patterns) {
if (!this._initialized) {
this.receiveMessage = this.receiveMessage.bind(this);
AboutReaderParent.addMessageListener(this.readerModeEvent, this);
Services.mm.addMessageListener(this.readerModeEvent, this);
this._triggerHandler = triggerHandler;
this._initialized = true;
}
......@@ -128,7 +127,7 @@ this.ASRouterTriggerListeners = new Map([
uninit() {
if (this._initialized) {
AboutReaderParent.removeMessageListener(this.readerModeEvent, this);
Services.mm.removeMessageListener(this.readerModeEvent, this);
this._initialized = false;
this._triggerHandler = null;
this._hosts = new Set();
......
......@@ -63,10 +63,7 @@ add_task(async function check_openArticleURL() {
// Send a message from the content page (the TEST_URL) to the parent
// This should trigger the `receiveMessage` cb in the articleTrigger
await ContentTask.spawn(win.gBrowser.selectedBrowser, null, async () => {
let readerActor = content.windowGlobalChild.getActor("AboutReader");
readerActor.sendAsyncMessage("Reader:UpdateReaderButton", {
isArticle: true,
});
sendAsyncMessage("Reader:UpdateReaderButton", { isArticle: true });
});
await listenerTriggered.then(data =>
......
......@@ -102,8 +102,8 @@ describe("ASRouterTriggerListeners", () => {
matches: url => patterns.has(url),
}))
);
sandbox.stub(global.AboutReaderParent, "addMessageListener");
sandbox.stub(global.AboutReaderParent, "removeMessageListener");
sandbox.stub(global.Services.mm, "addMessageListener");
sandbox.stub(global.Services.mm, "removeMessageListener");
});
afterEach(() => {
openArticleURLListener.uninit();
......@@ -111,9 +111,9 @@ describe("ASRouterTriggerListeners", () => {
it("setup an event listener on init", () => {
openArticleURLListener.init(sandbox.stub(), hosts, hosts);
assert.calledOnce(global.AboutReaderParent.addMessageListener);
assert.calledOnce(global.Services.mm.addMessageListener);
assert.calledWithExactly(
global.AboutReaderParent.addMessageListener,
global.Services.mm.addMessageListener,
openArticleURLListener.readerModeEvent,
sinon.match.object
);
......@@ -126,7 +126,7 @@ describe("ASRouterTriggerListeners", () => {
const [
,
{ receiveMessage },
] = global.AboutReaderParent.addMessageListener.firstCall.args;
] = global.Services.mm.addMessageListener.firstCall.args;
receiveMessage({ data: { isArticle: true }, target });
assert.calledOnce(stub);
......@@ -143,7 +143,7 @@ describe("ASRouterTriggerListeners", () => {
const [
,
{ receiveMessage },
] = global.AboutReaderParent.addMessageListener.firstCall.args;
] = global.Services.mm.addMessageListener.firstCall.args;
receiveMessage({ data: { isArticle: true }, target });
assert.calledOnce(stub);
......@@ -156,7 +156,7 @@ describe("ASRouterTriggerListeners", () => {
openArticleURLListener.init(sandbox.stub(), hosts, hosts);
openArticleURLListener.uninit();
assert.calledOnce(global.AboutReaderParent.removeMessageListener);
assert.calledOnce(global.Services.mm.removeMessageListener);
});
});
});
......
......@@ -45,10 +45,6 @@ const RemoteSettings = name => ({
RemoteSettings.pollChanges = () => {};
const TEST_GLOBAL = {
AboutReaderParent: {
addMessageListener: (messageName, listener) => {},
removeMessageListener: (messageName, listener) => {},
},
AddonManager: {
getActiveAddons() {
return Promise.resolve({ addons: [], fullData: false });
......
......@@ -29,11 +29,6 @@ ChromeUtils.defineModuleGetter(
"ReaderMode",
"resource://gre/modules/ReaderMode.jsm"
);
ChromeUtils.defineModuleGetter(
this,
"AboutReaderParent",
"resource:///actors/AboutReaderParent.jsm"
);
var EXPORTED_SYMBOLS = ["SaveToPocket"];
......@@ -255,8 +250,8 @@ var SaveToPocket = {
this.updateElements(false);
Services.obs.addObserver(this, "browser-delayed-startup-finished");
}
AboutReaderParent.addMessageListener("Reader:OnSetup", this);
AboutReaderParent.addMessageListener("Reader:Clicked-pocket-button", this);
Services.mm.addMessageListener("Reader:OnSetup", this);
Services.mm.addMessageListener("Reader:Clicked-pocket-button", this);
},
observe(subject, topic, data) {
......@@ -279,13 +274,13 @@ var SaveToPocket = {
onPrefChange(pref, oldValue, newValue) {
if (!newValue) {
AboutReaderParent.broadcastAsyncMessage("Reader:RemoveButton", {
Services.mm.broadcastAsyncMessage("Reader:RemoveButton", {
id: "pocket-button",
});
PocketOverlay.shutdown();
Services.obs.addObserver(this, "browser-delayed-startup-finished");
} else {
AboutReaderParent.broadcastAsyncMessage(
Services.mm.broadcastAsyncMessage(
"Reader:AddButton",
this._readerButtonData
);
......@@ -321,10 +316,9 @@ var SaveToPocket = {
switch (message.name) {
case "Reader:OnSetup": {
// Tell the reader about our button.
message.target.sendMessageToActor(
message.target.messageManager.sendAsyncMessage(
"Reader:AddButton",
this._readerButtonData,
"AboutReader"
this._readerButtonData
);
break;
}
......
......@@ -46,8 +46,8 @@ ChromeUtils.defineModuleGetter(
);
ChromeUtils.defineModuleGetter(
this,
"AboutReaderParent",
"resource:///actors/AboutReaderParent.jsm"
"ReaderParent",
"resource:///modules/ReaderParent.jsm"
);
ChromeUtils.defineModuleGetter(
this,
......@@ -662,14 +662,14 @@ var UITour = {
}
case "forceShowReaderIcon": {
AboutReaderParent.forceShowReaderIcon(browser);
ReaderParent.forceShowReaderIcon(browser);
break;
}
case "toggleReaderMode": {
let targetPromise = this.getTarget(window, "readerMode-urlBar");
targetPromise.then(target => {
AboutReaderParent.toggleReaderMode({ target: target.node });
ReaderParent.toggleReaderMode({ target: target.node });
});
break;
}
......
......@@ -5,7 +5,7 @@
"use strict";
var EXPORTED_SYMBOLS = ["AboutReaderParent"];
var EXPORTED_SYMBOLS = ["ReaderParent"];
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
......@@ -24,146 +24,61 @@ const gStringBundle = Services.strings.createBundle(
"chrome://global/locale/aboutReader.properties"
);
// A set of all of the AboutReaderParent actors that exist.
// See bug 1631146 for a request for a less manual way of doing this.
let gAllActors = new Set();
// A map of message names to listeners that listen to messages
// received by the AboutReaderParent actors.
let gListeners = new Map();