зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1669369, remove legacy actor from PrintingChild and replace with JSWindowActor, r=mstriemer
Differential Revision: https://phabricator.services.mozilla.com/D92519
This commit is contained in:
Родитель
c75bed1584
Коммит
8773757bb3
|
@ -60,10 +60,18 @@ add_task(async function test() {
|
|||
|
||||
// Enter print preview
|
||||
let ppBrowser = PrintPreviewListener.getPrintPreviewBrowser();
|
||||
let printPreviewEntered = BrowserTestUtils.waitForMessage(
|
||||
ppBrowser.messageManager,
|
||||
"Printing:Preview:Entered"
|
||||
|
||||
const { PrintingParent } = ChromeUtils.import(
|
||||
"resource://gre/actors/PrintingParent.jsm"
|
||||
);
|
||||
let printPreviewEntered = new Promise(resolve => {
|
||||
PrintingParent.setTestListener(browserPreviewing => {
|
||||
if (browserPreviewing == ppBrowser) {
|
||||
PrintingParent.setTestListener(null);
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
document.getElementById("cmd_printPreview").doCommand();
|
||||
await printPreviewEntered;
|
||||
|
||||
|
|
|
@ -6,9 +6,6 @@
|
|||
|
||||
var EXPORTED_SYMBOLS = ["PrintingChild"];
|
||||
|
||||
const { ActorChild } = ChromeUtils.import(
|
||||
"resource://gre/modules/ActorChild.jsm"
|
||||
);
|
||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
ChromeUtils.defineModuleGetter(
|
||||
|
@ -23,7 +20,20 @@ ChromeUtils.defineModuleGetter(
|
|||
"resource://gre/modules/ReaderMode.jsm"
|
||||
);
|
||||
|
||||
class PrintingChild extends ActorChild {
|
||||
let gPrintPreviewInitializingInfo = null;
|
||||
|
||||
let gPendingPreviewsMap = new Map();
|
||||
|
||||
class PrintingChild extends JSWindowActorChild {
|
||||
actorCreated() {
|
||||
// When the print preview page is loaded, the actor will change, so update
|
||||
// the state/progress listener to the new actor.
|
||||
let listener = gPendingPreviewsMap.get(this.browsingContext.id);
|
||||
if (listener) {
|
||||
listener.actor = this;
|
||||
}
|
||||
}
|
||||
|
||||
// Bug 1088061: nsPrintJob's DoCommonPrint currently expects the
|
||||
// progress listener passed to it to QI to an nsIPrintingPromptService
|
||||
// in order to know that a printing progress dialog has been shown. That's
|
||||
|
@ -41,7 +51,7 @@ class PrintingChild extends ActorChild {
|
|||
let win = event.target.defaultView;
|
||||
let wbp = win.getInterface(Ci.nsIWebBrowserPrint);
|
||||
let nsresult = event.detail;
|
||||
this.mm.sendAsyncMessage("Printing:Error", {
|
||||
this.sendAsyncMessage("Printing:Error", {
|
||||
isPrinting: wbp.doingPrint,
|
||||
nsresult,
|
||||
});
|
||||
|
@ -49,18 +59,20 @@ class PrintingChild extends ActorChild {
|
|||
}
|
||||
|
||||
case "printPreviewUpdate": {
|
||||
let info = this.printPreviewInitializingInfo;
|
||||
let info = gPrintPreviewInitializingInfo;
|
||||
if (!info) {
|
||||
// If there is no printPreviewInitializingInfo then we did not
|
||||
// If there is no gPrintPreviewInitializingInfo then we did not
|
||||
// initiate the preview so ignore this event.
|
||||
return;
|
||||
}
|
||||
|
||||
// Only send Printing:Preview:Entered message on first update, indicated
|
||||
// by printPreviewInitializingInfo.entered not being set.
|
||||
// by gPrintPreviewInitializingInfo.entered not being set.
|
||||
if (!info.entered) {
|
||||
gPendingPreviewsMap.delete(this.browsingContext.id);
|
||||
|
||||
info.entered = true;
|
||||
this.mm.sendAsyncMessage("Printing:Preview:Entered", {
|
||||
this.sendAsyncMessage("Printing:Preview:Entered", {
|
||||
failed: false,
|
||||
changingBrowsers: info.changingBrowsers,
|
||||
});
|
||||
|
@ -72,7 +84,7 @@ class PrintingChild extends ActorChild {
|
|||
}
|
||||
|
||||
// Always send page count update.
|
||||
this.updatePageCount(this.mm);
|
||||
this.updatePageCount();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -106,13 +118,14 @@ class PrintingChild extends ActorChild {
|
|||
}
|
||||
|
||||
case "Printing:Preview:ParseDocument": {
|
||||
this.parseDocument(
|
||||
return this.parseDocument(
|
||||
data.URL,
|
||||
Services.wm.getOuterWindowWithId(data.windowID)
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
getPrintSettings(lastUsedPrinterName) {
|
||||
|
@ -145,169 +158,174 @@ class PrintingChild extends ActorChild {
|
|||
return null;
|
||||
}
|
||||
|
||||
parseDocument(URL, contentWindow) {
|
||||
async parseDocument(URL, contentWindow) {
|
||||
// The document in 'contentWindow' will be simplified and the resulting nodes
|
||||
// will be inserted into this.contentWindow.
|
||||
let thisWindow = this.contentWindow;
|
||||
|
||||
// By using ReaderMode primitives, we parse given document and place the
|
||||
// resulting JS object into the DOM of current browser.
|
||||
let articlePromise = ReaderMode.parseDocument(contentWindow.document).catch(
|
||||
Cu.reportError
|
||||
);
|
||||
articlePromise.then(article => {
|
||||
// We make use of a web progress listener in order to know when the content we inject
|
||||
// into the DOM has finished rendering. If our layout engine is still painting, we
|
||||
// will wait for MozAfterPaint event to be fired.
|
||||
let { mm } = this;
|
||||
let webProgressListener = {
|
||||
onStateChange(webProgress, req, flags, status) {
|
||||
if (flags & Ci.nsIWebProgressListener.STATE_STOP) {
|
||||
webProgress.removeProgressListener(webProgressListener);
|
||||
let domUtils = contentWindow.windowUtils;
|
||||
// Here we tell the parent that we have parsed the document successfully
|
||||
// using ReaderMode primitives and we are able to enter on preview mode.
|
||||
if (domUtils.isMozAfterPaintPending) {
|
||||
let onPaint = function() {
|
||||
mm.removeEventListener("MozAfterPaint", onPaint);
|
||||
mm.sendAsyncMessage("Printing:Preview:ReaderModeReady");
|
||||
};
|
||||
contentWindow.addEventListener("MozAfterPaint", onPaint);
|
||||
// This timer need when display list invalidation doesn't invalidate.
|
||||
setTimeout(() => {
|
||||
mm.removeEventListener("MozAfterPaint", onPaint);
|
||||
mm.sendAsyncMessage("Printing:Preview:ReaderModeReady");
|
||||
}, 100);
|
||||
} else {
|
||||
mm.sendAsyncMessage("Printing:Preview:ReaderModeReady");
|
||||
}
|
||||
let article;
|
||||
try {
|
||||
article = await ReaderMode.parseDocument(contentWindow.document);
|
||||
} catch (ex) {
|
||||
Cu.reportError(ex);
|
||||
}
|
||||
|
||||
// We make use of a web progress listener in order to know when the content we inject
|
||||
// into the DOM has finished rendering. If our layout engine is still painting, we
|
||||
// will wait for MozAfterPaint event to be fired.
|
||||
let actor = thisWindow.windowGlobalChild.getActor("Printing");
|
||||
let webProgressListener = {
|
||||
onStateChange(webProgress, req, flags, status) {
|
||||
if (flags & Ci.nsIWebProgressListener.STATE_STOP) {
|
||||
webProgress.removeProgressListener(webProgressListener);
|
||||
let domUtils = contentWindow.windowUtils;
|
||||
// Here we tell the parent that we have parsed the document successfully
|
||||
// using ReaderMode primitives and we are able to enter on preview mode.
|
||||
if (domUtils.isMozAfterPaintPending) {
|
||||
let onPaint = function() {
|
||||
contentWindow.removeEventListener("MozAfterPaint", onPaint);
|
||||
actor.sendAsyncMessage("Printing:Preview:ReaderModeReady");
|
||||
};
|
||||
contentWindow.addEventListener("MozAfterPaint", onPaint);
|
||||
// This timer is needed for when display list invalidation doesn't invalidate.
|
||||
setTimeout(() => {
|
||||
contentWindow.removeEventListener("MozAfterPaint", onPaint);
|
||||
actor.sendAsyncMessage("Printing:Preview:ReaderModeReady");
|
||||
}, 100);
|
||||
} else {
|
||||
actor.sendAsyncMessage("Printing:Preview:ReaderModeReady");
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
QueryInterface: ChromeUtils.generateQI([
|
||||
"nsIWebProgressListener",
|
||||
"nsISupportsWeakReference",
|
||||
"nsIObserver",
|
||||
]),
|
||||
};
|
||||
QueryInterface: ChromeUtils.generateQI([
|
||||
"nsIWebProgressListener",
|
||||
"nsISupportsWeakReference",
|
||||
"nsIObserver",
|
||||
]),
|
||||
};
|
||||
|
||||
const { content, docShell } = this.mm;
|
||||
// Here we QI the docShell into a nsIWebProgress passing our web progress listener in.
|
||||
let webProgress = thisWindow.docShell
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebProgress);
|
||||
webProgress.addProgressListener(
|
||||
webProgressListener,
|
||||
Ci.nsIWebProgress.NOTIFY_STATE_REQUEST
|
||||
);
|
||||
|
||||
// Here we QI the docShell into a nsIWebProgress passing our web progress listener in.
|
||||
let webProgress = docShell
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebProgress);
|
||||
webProgress.addProgressListener(
|
||||
webProgressListener,
|
||||
Ci.nsIWebProgress.NOTIFY_STATE_REQUEST
|
||||
let document = thisWindow.document;
|
||||
document.head.innerHTML = "";
|
||||
|
||||
// Set base URI of document. Print preview code will read this value to
|
||||
// populate the URL field in print settings so that it doesn't show
|
||||
// "about:blank" as its URI.
|
||||
let headBaseElement = document.createElement("base");
|
||||
headBaseElement.setAttribute("href", URL);
|
||||
document.head.appendChild(headBaseElement);
|
||||
|
||||
// Create link element referencing aboutReader.css and append it to head
|
||||
let headStyleElement = document.createElement("link");
|
||||
headStyleElement.setAttribute("rel", "stylesheet");
|
||||
headStyleElement.setAttribute(
|
||||
"href",
|
||||
"chrome://global/skin/aboutReader.css"
|
||||
);
|
||||
headStyleElement.setAttribute("type", "text/css");
|
||||
document.head.appendChild(headStyleElement);
|
||||
|
||||
// Create link element referencing simplifyMode.css and append it to head
|
||||
headStyleElement = document.createElement("link");
|
||||
headStyleElement.setAttribute("rel", "stylesheet");
|
||||
headStyleElement.setAttribute(
|
||||
"href",
|
||||
"chrome://global/content/simplifyMode.css"
|
||||
);
|
||||
headStyleElement.setAttribute("type", "text/css");
|
||||
document.head.appendChild(headStyleElement);
|
||||
|
||||
document.body.innerHTML = "";
|
||||
|
||||
// Create container div (main element) and append it to body
|
||||
let containerElement = document.createElement("div");
|
||||
containerElement.setAttribute("id", "container");
|
||||
document.body.appendChild(containerElement);
|
||||
|
||||
// Reader Mode might return null if there's a failure when parsing the document.
|
||||
// We'll render the error message for the Simplify Page document when that happens.
|
||||
if (article) {
|
||||
// Set title of document
|
||||
document.title = article.title;
|
||||
|
||||
// Create header div and append it to container
|
||||
let headerElement = document.createElement("div");
|
||||
headerElement.setAttribute("id", "reader-header");
|
||||
headerElement.setAttribute("class", "header");
|
||||
containerElement.appendChild(headerElement);
|
||||
|
||||
// Jam the article's title and byline into header div
|
||||
let titleElement = document.createElement("h1");
|
||||
titleElement.setAttribute("id", "reader-title");
|
||||
titleElement.textContent = article.title;
|
||||
headerElement.appendChild(titleElement);
|
||||
|
||||
let bylineElement = document.createElement("div");
|
||||
bylineElement.setAttribute("id", "reader-credits");
|
||||
bylineElement.setAttribute("class", "credits");
|
||||
bylineElement.textContent = article.byline;
|
||||
headerElement.appendChild(bylineElement);
|
||||
|
||||
// Display header element
|
||||
headerElement.style.display = "block";
|
||||
|
||||
// Create content div and append it to container
|
||||
let contentElement = document.createElement("div");
|
||||
contentElement.setAttribute("class", "content");
|
||||
containerElement.appendChild(contentElement);
|
||||
|
||||
// Jam the article's content into content div
|
||||
let readerContent = document.createElement("div");
|
||||
readerContent.setAttribute("id", "moz-reader-content");
|
||||
contentElement.appendChild(readerContent);
|
||||
|
||||
let articleUri = Services.io.newURI(article.url);
|
||||
let parserUtils = Cc["@mozilla.org/parserutils;1"].getService(
|
||||
Ci.nsIParserUtils
|
||||
);
|
||||
let contentFragment = parserUtils.parseFragment(
|
||||
article.content,
|
||||
Ci.nsIParserUtils.SanitizerDropForms |
|
||||
Ci.nsIParserUtils.SanitizerAllowStyle,
|
||||
false,
|
||||
articleUri,
|
||||
readerContent
|
||||
);
|
||||
|
||||
content.document.head.innerHTML = "";
|
||||
readerContent.appendChild(contentFragment);
|
||||
|
||||
// Set base URI of document. Print preview code will read this value to
|
||||
// populate the URL field in print settings so that it doesn't show
|
||||
// "about:blank" as its URI.
|
||||
let headBaseElement = content.document.createElement("base");
|
||||
headBaseElement.setAttribute("href", URL);
|
||||
content.document.head.appendChild(headBaseElement);
|
||||
|
||||
// Create link element referencing aboutReader.css and append it to head
|
||||
let headStyleElement = content.document.createElement("link");
|
||||
headStyleElement.setAttribute("rel", "stylesheet");
|
||||
headStyleElement.setAttribute(
|
||||
"href",
|
||||
"chrome://global/skin/aboutReader.css"
|
||||
// Display reader content element
|
||||
readerContent.style.display = "block";
|
||||
} else {
|
||||
let aboutReaderStrings = Services.strings.createBundle(
|
||||
"chrome://global/locale/aboutReader.properties"
|
||||
);
|
||||
headStyleElement.setAttribute("type", "text/css");
|
||||
content.document.head.appendChild(headStyleElement);
|
||||
|
||||
// Create link element referencing simplifyMode.css and append it to head
|
||||
headStyleElement = content.document.createElement("link");
|
||||
headStyleElement.setAttribute("rel", "stylesheet");
|
||||
headStyleElement.setAttribute(
|
||||
"href",
|
||||
"chrome://global/content/simplifyMode.css"
|
||||
let errorMessage = aboutReaderStrings.GetStringFromName(
|
||||
"aboutReader.loadError"
|
||||
);
|
||||
headStyleElement.setAttribute("type", "text/css");
|
||||
content.document.head.appendChild(headStyleElement);
|
||||
|
||||
content.document.body.innerHTML = "";
|
||||
document.title = errorMessage;
|
||||
|
||||
// Create container div (main element) and append it to body
|
||||
let containerElement = content.document.createElement("div");
|
||||
containerElement.setAttribute("id", "container");
|
||||
content.document.body.appendChild(containerElement);
|
||||
// Create reader message div and append it to body
|
||||
let readerMessageElement = document.createElement("div");
|
||||
readerMessageElement.setAttribute("class", "reader-message");
|
||||
readerMessageElement.textContent = errorMessage;
|
||||
containerElement.appendChild(readerMessageElement);
|
||||
|
||||
// Reader Mode might return null if there's a failure when parsing the document.
|
||||
// We'll render the error message for the Simplify Page document when that happens.
|
||||
if (article) {
|
||||
// Set title of document
|
||||
content.document.title = article.title;
|
||||
|
||||
// Create header div and append it to container
|
||||
let headerElement = content.document.createElement("div");
|
||||
headerElement.setAttribute("id", "reader-header");
|
||||
headerElement.setAttribute("class", "header");
|
||||
containerElement.appendChild(headerElement);
|
||||
|
||||
// Jam the article's title and byline into header div
|
||||
let titleElement = content.document.createElement("h1");
|
||||
titleElement.setAttribute("id", "reader-title");
|
||||
titleElement.textContent = article.title;
|
||||
headerElement.appendChild(titleElement);
|
||||
|
||||
let bylineElement = content.document.createElement("div");
|
||||
bylineElement.setAttribute("id", "reader-credits");
|
||||
bylineElement.setAttribute("class", "credits");
|
||||
bylineElement.textContent = article.byline;
|
||||
headerElement.appendChild(bylineElement);
|
||||
|
||||
// Display header element
|
||||
headerElement.style.display = "block";
|
||||
|
||||
// Create content div and append it to container
|
||||
let contentElement = content.document.createElement("div");
|
||||
contentElement.setAttribute("class", "content");
|
||||
containerElement.appendChild(contentElement);
|
||||
|
||||
// Jam the article's content into content div
|
||||
let readerContent = content.document.createElement("div");
|
||||
readerContent.setAttribute("id", "moz-reader-content");
|
||||
contentElement.appendChild(readerContent);
|
||||
|
||||
let articleUri = Services.io.newURI(article.url);
|
||||
let parserUtils = Cc["@mozilla.org/parserutils;1"].getService(
|
||||
Ci.nsIParserUtils
|
||||
);
|
||||
let contentFragment = parserUtils.parseFragment(
|
||||
article.content,
|
||||
Ci.nsIParserUtils.SanitizerDropForms |
|
||||
Ci.nsIParserUtils.SanitizerAllowStyle,
|
||||
false,
|
||||
articleUri,
|
||||
readerContent
|
||||
);
|
||||
|
||||
readerContent.appendChild(contentFragment);
|
||||
|
||||
// Display reader content element
|
||||
readerContent.style.display = "block";
|
||||
} else {
|
||||
let aboutReaderStrings = Services.strings.createBundle(
|
||||
"chrome://global/locale/aboutReader.properties"
|
||||
);
|
||||
let errorMessage = aboutReaderStrings.GetStringFromName(
|
||||
"aboutReader.loadError"
|
||||
);
|
||||
|
||||
content.document.title = errorMessage;
|
||||
|
||||
// Create reader message div and append it to body
|
||||
let readerMessageElement = content.document.createElement("div");
|
||||
readerMessageElement.setAttribute("class", "reader-message");
|
||||
readerMessageElement.textContent = errorMessage;
|
||||
containerElement.appendChild(readerMessageElement);
|
||||
|
||||
// Display reader message element
|
||||
readerMessageElement.style.display = "block";
|
||||
}
|
||||
});
|
||||
// Display reader message element
|
||||
readerMessageElement.style.display = "block";
|
||||
}
|
||||
}
|
||||
|
||||
enterPrintPreview(
|
||||
|
@ -349,6 +367,9 @@ class PrintingChild extends ActorChild {
|
|||
printSettings.docURL = contentWindow.document.baseURI;
|
||||
}
|
||||
|
||||
// Get this early in case the actor goes away during print preview.
|
||||
let browserContextId = this.browsingContext.id;
|
||||
|
||||
// The print preview docshell will be in a different TabGroup, so
|
||||
// printPreviewInitialize must be run in a separate runnable to avoid
|
||||
// touching a different TabGroup in our own runnable.
|
||||
|
@ -357,37 +378,39 @@ class PrintingChild extends ActorChild {
|
|||
// might be destroyed, for example the print preview window gets closed
|
||||
// soon after it's opened, in such case we should just simply bail out.
|
||||
if (docShell.isBeingDestroyed()) {
|
||||
this.mm.sendAsyncMessage("Printing:Preview:Entered", {
|
||||
this.sendAsyncMessage("Printing:Preview:Entered", {
|
||||
failed: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
let listener = new PrintingListener(this.mm);
|
||||
let listener = new PrintingListener(this);
|
||||
gPendingPreviewsMap.set(browserContextId, listener);
|
||||
|
||||
gPrintPreviewInitializingInfo = { changingBrowsers };
|
||||
|
||||
this.printPreviewInitializingInfo = { changingBrowsers };
|
||||
contentWindow.printPreview(printSettings, listener, docShell);
|
||||
} catch (error) {
|
||||
// This might fail if we, for example, attempt to print a XUL document.
|
||||
// In that case, we inform the parent to bail out of print preview.
|
||||
Cu.reportError(error);
|
||||
this.printPreviewInitializingInfo = null;
|
||||
this.mm.sendAsyncMessage("Printing:Preview:Entered", {
|
||||
gPrintPreviewInitializingInfo = null;
|
||||
this.sendAsyncMessage("Printing:Preview:Entered", {
|
||||
failed: true,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// If printPreviewInitializingInfo.entered is not set we are still in the
|
||||
// If gPrintPreviewInitializingInfo.entered is not set we are still in the
|
||||
// initial setup of a previous preview request. We delay this one until
|
||||
// that has finished because running them at the same time will almost
|
||||
// certainly cause failures.
|
||||
if (
|
||||
this.printPreviewInitializingInfo &&
|
||||
!this.printPreviewInitializingInfo.entered
|
||||
gPrintPreviewInitializingInfo &&
|
||||
!gPrintPreviewInitializingInfo.entered
|
||||
) {
|
||||
this.printPreviewInitializingInfo.nextRequest = printPreviewInitialize;
|
||||
gPrintPreviewInitializingInfo.nextRequest = printPreviewInitialize;
|
||||
} else {
|
||||
Services.tm.dispatchToMainThread(printPreviewInitialize);
|
||||
}
|
||||
|
@ -395,19 +418,21 @@ class PrintingChild extends ActorChild {
|
|||
// This might fail if we, for example, attempt to print a XUL document.
|
||||
// In that case, we inform the parent to bail out of print preview.
|
||||
Cu.reportError(error);
|
||||
this.mm.sendAsyncMessage("Printing:Preview:Entered", { failed: true });
|
||||
this.sendAsyncMessage("Printing:Preview:Entered", {
|
||||
failed: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
exitPrintPreview(glo) {
|
||||
this.printPreviewInitializingInfo = null;
|
||||
exitPrintPreview() {
|
||||
gPrintPreviewInitializingInfo = null;
|
||||
this.docShell.exitPrintPreview();
|
||||
}
|
||||
|
||||
updatePageCount() {
|
||||
let cv = this.docShell.contentViewer;
|
||||
cv.QueryInterface(Ci.nsIWebBrowserPrint);
|
||||
this.mm.sendAsyncMessage("Printing:Preview:UpdatePageCount", {
|
||||
this.sendAsyncMessage("Printing:Preview:UpdatePageCount", {
|
||||
numPages: cv.printPreviewNumPages,
|
||||
totalPages: cv.rawNumPages,
|
||||
});
|
||||
|
@ -424,14 +449,14 @@ PrintingChild.prototype.QueryInterface = ChromeUtils.generateQI([
|
|||
"nsIPrintingPromptService",
|
||||
]);
|
||||
|
||||
function PrintingListener(global) {
|
||||
this.global = global;
|
||||
function PrintingListener(actor) {
|
||||
this.actor = actor;
|
||||
}
|
||||
PrintingListener.prototype = {
|
||||
QueryInterface: ChromeUtils.generateQI(["nsIWebProgressListener"]),
|
||||
|
||||
onStateChange(aWebProgress, aRequest, aStateFlags, aStatus) {
|
||||
this.global.sendAsyncMessage("Printing:Preview:StateChange", {
|
||||
this.actor.sendAsyncMessage("Printing:Preview:StateChange", {
|
||||
stateFlags: aStateFlags,
|
||||
status: aStatus,
|
||||
});
|
||||
|
@ -445,7 +470,7 @@ PrintingListener.prototype = {
|
|||
aCurTotalProgress,
|
||||
aMaxTotalProgress
|
||||
) {
|
||||
this.global.sendAsyncMessage("Printing:Preview:ProgressChange", {
|
||||
this.actor.sendAsyncMessage("Printing:Preview:ProgressChange", {
|
||||
curSelfProgress: aCurSelfProgress,
|
||||
maxSelfProgress: aMaxSelfProgress,
|
||||
curTotalProgress: aCurTotalProgress,
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
/* vim: set ts=2 sw=2 sts=2 et tw=80: */
|
||||
/* 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 = ["PrintingParent"];
|
||||
|
||||
let gTestListener = null;
|
||||
|
||||
class PrintingParent extends JSWindowActorParent {
|
||||
static setTestListener(listener) {
|
||||
gTestListener = listener;
|
||||
}
|
||||
|
||||
getPrintPreviewToolbar(browser) {
|
||||
return browser.ownerDocument.getElementById("print-preview-toolbar");
|
||||
}
|
||||
|
||||
receiveMessage(message) {
|
||||
let browser = this.browsingContext.top.embedderElement;
|
||||
let PrintUtils = browser.ownerGlobal.PrintUtils;
|
||||
|
||||
if (message.name == "Printing:Error") {
|
||||
PrintUtils._displayPrintingError(
|
||||
message.data.nsresult,
|
||||
message.data.isPrinting
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (this.ignoreListeners) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let listener = PrintUtils._webProgressPP.value;
|
||||
let data = message.data;
|
||||
|
||||
switch (message.name) {
|
||||
case "Printing:Preview:Entered": {
|
||||
// This message is sent by the content process once it has completed
|
||||
// putting the content into print preview mode. We must wait for that to
|
||||
// to complete before switching the chrome UI to print preview mode,
|
||||
// otherwise we have layout issues.
|
||||
|
||||
if (gTestListener) {
|
||||
gTestListener(browser);
|
||||
}
|
||||
|
||||
PrintUtils.printPreviewEntered(browser, message.data);
|
||||
break;
|
||||
}
|
||||
|
||||
case "Printing:Preview:ReaderModeReady": {
|
||||
PrintUtils.readerModeReady(browser);
|
||||
break;
|
||||
}
|
||||
|
||||
case "Printing:Preview:UpdatePageCount": {
|
||||
let toolbar = this.getPrintPreviewToolbar(browser);
|
||||
toolbar.updatePageCount(message.data.totalPages);
|
||||
break;
|
||||
}
|
||||
|
||||
case "Printing:Preview:ProgressChange": {
|
||||
if (!PrintUtils._webProgressPP.value) {
|
||||
// We somehow didn't get a nsIWebProgressListener to be updated...
|
||||
// I guess there's nothing to do.
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return listener.onProgressChange(
|
||||
null,
|
||||
null,
|
||||
data.curSelfProgress,
|
||||
data.maxSelfProgress,
|
||||
data.curTotalProgress,
|
||||
data.maxTotalProgress
|
||||
);
|
||||
}
|
||||
|
||||
case "Printing:Preview:StateChange": {
|
||||
if (!PrintUtils._webProgressPP.value) {
|
||||
// We somehow didn't get a nsIWebProgressListener to be updated...
|
||||
// I guess there's nothing to do.
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (data.stateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
|
||||
// Strangely, the printing engine sends 2 STATE_STOP messages when
|
||||
// print preview is finishing. One has the STATE_IS_DOCUMENT flag,
|
||||
// the other has the STATE_IS_NETWORK flag. However, the webProgressPP
|
||||
// listener stops listening once the first STATE_STOP is sent.
|
||||
// Any subsequent messages result in NS_ERROR_FAILURE errors getting
|
||||
// thrown. This should all get torn out once bug 1088061 is fixed.
|
||||
|
||||
// Enable toobar elements that we disabled during update.
|
||||
let printPreviewTB = this.getPrintPreviewToolbar(browser);
|
||||
printPreviewTB.disableUpdateTriggers(false);
|
||||
}
|
||||
|
||||
return listener.onStateChange(null, null, data.stateFlags, data.status);
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
}
|
|
@ -52,6 +52,7 @@ FINAL_TARGET_FILES.actors += [
|
|||
"PopupBlockingChild.jsm",
|
||||
"PopupBlockingParent.jsm",
|
||||
"PrintingChild.jsm",
|
||||
"PrintingParent.jsm",
|
||||
"PurgeSessionHistoryChild.jsm",
|
||||
"RemotePageChild.jsm",
|
||||
"SelectChild.jsm",
|
||||
|
|
|
@ -125,8 +125,6 @@ customElements.define(
|
|||
|
||||
this.mPPBrowser = null;
|
||||
|
||||
this.mMessageManager = null;
|
||||
|
||||
this.mOnPageTextBoxChange = () => {
|
||||
this.navigate(0, Number(this.mPageTextBox.value), 0);
|
||||
};
|
||||
|
@ -154,11 +152,6 @@ customElements.define(
|
|||
this.mSimplifyPageToolbarSeparator.hidden = true;
|
||||
}
|
||||
this.mPPBrowser = aPPBrowser;
|
||||
this.mMessageManager = aPPBrowser.messageManager;
|
||||
this.mMessageManager.addMessageListener(
|
||||
"Printing:Preview:UpdatePageCount",
|
||||
this
|
||||
);
|
||||
this.updateToolbar();
|
||||
|
||||
let ltr = document.documentElement.matches(":root:-moz-locale-dir(ltr)");
|
||||
|
@ -196,14 +189,7 @@ customElements.define(
|
|||
}
|
||||
|
||||
destroy() {
|
||||
if (this.mMessageManager) {
|
||||
this.mMessageManager.removeMessageListener(
|
||||
"Printing:Preview:UpdatePageCount",
|
||||
this
|
||||
);
|
||||
delete this.mMessageManager;
|
||||
delete this.mPPBrowser;
|
||||
}
|
||||
delete this.mPPBrowser;
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
|
@ -276,10 +262,14 @@ customElements.define(
|
|||
}
|
||||
}
|
||||
|
||||
this.mMessageManager.sendAsyncMessage("Printing:Preview:Navigate", {
|
||||
navType,
|
||||
pageNum,
|
||||
});
|
||||
this.mPPBrowser.sendMessageToActor(
|
||||
"Printing:Preview:Navigate",
|
||||
{
|
||||
navType,
|
||||
pageNum,
|
||||
},
|
||||
"Printing"
|
||||
);
|
||||
}
|
||||
|
||||
print() {
|
||||
|
@ -445,12 +435,9 @@ customElements.define(
|
|||
PSSVC.savePrintSettingsToPrefs(settings, true, flags);
|
||||
}
|
||||
|
||||
receiveMessage(message) {
|
||||
if (message.name == "Printing:Preview:UpdatePageCount") {
|
||||
let totalPages = message.data.totalPages;
|
||||
this.mTotalPages.value = totalPages;
|
||||
this.mPageTextBox.max = totalPages;
|
||||
}
|
||||
updatePageCount(totalPages) {
|
||||
this.mTotalPages.value = totalPages;
|
||||
this.mPageTextBox.max = totalPages;
|
||||
}
|
||||
},
|
||||
{ extends: "toolbar" }
|
||||
|
|
|
@ -18,17 +18,11 @@
|
|||
*
|
||||
* To compound that, we need to support remote browsers, and that means
|
||||
* kicking off the print jobs in the content process. This means we send
|
||||
* messages back and forth to that process. browser-content.js contains
|
||||
* the object that listens and responds to the messages that PrintUtils
|
||||
* sends.
|
||||
* messages back and forth to that process via the Printing actor.
|
||||
*
|
||||
* This also means that <xul:browser>'s that hope to use PrintUtils must have
|
||||
* their type attribute set to "content".
|
||||
*
|
||||
* PrintUtils sends messages at different points in its implementation, but
|
||||
* their documentation is consolidated here for ease-of-access.
|
||||
*
|
||||
*
|
||||
* Messages sent:
|
||||
*
|
||||
* Printing:Preview:Enter
|
||||
|
@ -39,23 +33,6 @@
|
|||
*
|
||||
* Printing:Preview:Exit
|
||||
* This message is sent to take content out of print preview mode.
|
||||
*
|
||||
*
|
||||
* Messages Received
|
||||
*
|
||||
* Printing:Preview:Entered
|
||||
* This message is sent by the content process once it has completed
|
||||
* putting the content into print preview mode. We must wait for that to
|
||||
* to complete before switching the chrome UI to print preview mode,
|
||||
* otherwise we have layout issues.
|
||||
*
|
||||
* Printing:Preview:StateChange, Printing:Preview:ProgressChange
|
||||
* Due to a timing issue resulting in a main-process crash, we have to
|
||||
* manually open the progress dialog for print preview. The progress
|
||||
* dialog is opened here in PrintUtils, and then we listen for update
|
||||
* messages from the child. Bug 1088061 has been filed to investigate
|
||||
* other solutions.
|
||||
*
|
||||
*/
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
|
@ -78,15 +55,19 @@ ChromeUtils.defineModuleGetter(
|
|||
"resource://gre/modules/SharedPromptUtils.jsm"
|
||||
);
|
||||
|
||||
ChromeUtils.defineModuleGetter(
|
||||
this,
|
||||
"PrintingParent",
|
||||
"resource://gre/actors/PrintingParent.jsm"
|
||||
);
|
||||
|
||||
var gFocusedElement = null;
|
||||
|
||||
var gPendingPrintPreviews = new Map();
|
||||
|
||||
var PrintUtils = {
|
||||
SAVE_TO_PDF_PRINTER: "Mozilla Save to PDF",
|
||||
|
||||
init() {
|
||||
window.messageManager.addMessageListener("Printing:Error", this);
|
||||
},
|
||||
|
||||
get _bundle() {
|
||||
delete this._bundle;
|
||||
return (this._bundle = Services.strings.createBundle(
|
||||
|
@ -423,6 +404,11 @@ var PrintUtils = {
|
|||
* with aListenerObj as null iff this window is already displaying
|
||||
* print preview (in which case, the previous aListenerObj passed
|
||||
* to it will be used).
|
||||
*
|
||||
* Due to a timing issue resulting in a main-process crash, we have to
|
||||
* manually open the progress dialog for print preview. The progress
|
||||
* dialog is opened here in PrintUtils, and then we listen for update
|
||||
* messages from the child. Bug 1558588 is about removing this.
|
||||
*/
|
||||
printPreview(aTrigger, aListenerObj) {
|
||||
if (aTrigger) {
|
||||
|
@ -593,61 +579,6 @@ var PrintUtils = {
|
|||
);
|
||||
},
|
||||
|
||||
receiveMessage(aMessage) {
|
||||
if (aMessage.name == "Printing:Error") {
|
||||
this._displayPrintingError(
|
||||
aMessage.data.nsresult,
|
||||
aMessage.data.isPrinting
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// If we got here, then the message we've received must involve
|
||||
// updating the print progress UI.
|
||||
if (!this._webProgressPP.value) {
|
||||
// We somehow didn't get a nsIWebProgressListener to be updated...
|
||||
// I guess there's nothing to do.
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let listener = this._webProgressPP.value;
|
||||
let mm = aMessage.target.messageManager;
|
||||
let data = aMessage.data;
|
||||
|
||||
switch (aMessage.name) {
|
||||
case "Printing:Preview:ProgressChange": {
|
||||
return listener.onProgressChange(
|
||||
null,
|
||||
null,
|
||||
data.curSelfProgress,
|
||||
data.maxSelfProgress,
|
||||
data.curTotalProgress,
|
||||
data.maxTotalProgress
|
||||
);
|
||||
}
|
||||
|
||||
case "Printing:Preview:StateChange": {
|
||||
if (data.stateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
|
||||
// Strangely, the printing engine sends 2 STATE_STOP messages when
|
||||
// print preview is finishing. One has the STATE_IS_DOCUMENT flag,
|
||||
// the other has the STATE_IS_NETWORK flag. However, the webProgressPP
|
||||
// listener stops listening once the first STATE_STOP is sent.
|
||||
// Any subsequent messages result in NS_ERROR_FAILURE errors getting
|
||||
// thrown. This should all get torn out once bug 1088061 is fixed.
|
||||
mm.removeMessageListener("Printing:Preview:StateChange", this);
|
||||
mm.removeMessageListener("Printing:Preview:ProgressChange", this);
|
||||
|
||||
// Enable toobar elements that we disabled during update.
|
||||
let printPreviewTB = document.getElementById("print-preview-toolbar");
|
||||
printPreviewTB.disableUpdateTriggers(false);
|
||||
}
|
||||
|
||||
return listener.onStateChange(null, null, data.stateFlags, data.status);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
|
||||
_setPrinterDefaultsForSelectedPrinter(
|
||||
aPSSVC,
|
||||
aPrintSettings,
|
||||
|
@ -771,8 +702,180 @@ var PrintUtils = {
|
|||
oldPPBrowser = this._currentPPBrowser;
|
||||
}
|
||||
this._currentPPBrowser = ppBrowser;
|
||||
let mm = ppBrowser.messageManager;
|
||||
|
||||
let waitForPrintProgressToEnableToolbar = false;
|
||||
if (this._webProgressPP.value) {
|
||||
waitForPrintProgressToEnableToolbar = true;
|
||||
}
|
||||
|
||||
gPendingPrintPreviews.set(ppBrowser, waitForPrintProgressToEnableToolbar);
|
||||
|
||||
// If we happen to have gotten simplify page checked, we will lazily
|
||||
// instantiate a new tab that parses the original page using ReaderMode
|
||||
// primitives. When it's ready, and in order to enter on preview, we send
|
||||
// over a message to print preview browser passing up the simplified tab as
|
||||
// reference. If not, we pass the original tab instead as content source.
|
||||
if (this._shouldSimplify) {
|
||||
let simplifiedBrowser = this._listener.getSimplifiedSourceBrowser();
|
||||
if (!simplifiedBrowser) {
|
||||
simplifiedBrowser = this._listener.createSimplifiedBrowser();
|
||||
|
||||
// Here, we send down a message to simplified browser in order to parse
|
||||
// the original page. After we have parsed it, content will tell parent
|
||||
// that the document is ready for print previewing.
|
||||
simplifiedBrowser.sendMessageToActor(
|
||||
"Printing:Preview:ParseDocument",
|
||||
{
|
||||
URL: this._originalURL,
|
||||
windowID: oldPPBrowser.outerWindowID,
|
||||
},
|
||||
"Printing"
|
||||
);
|
||||
|
||||
// Here we log telemetry data for when the user enters simplify mode.
|
||||
this.logTelemetry("PRINT_PREVIEW_SIMPLIFY_PAGE_OPENED_COUNT");
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.sendEnterPrintPreviewToChild(
|
||||
ppBrowser,
|
||||
this._sourceBrowser,
|
||||
this._shouldSimplify,
|
||||
changingPrintPreviewBrowsers
|
||||
);
|
||||
},
|
||||
|
||||
sendEnterPrintPreviewToChild(
|
||||
ppBrowser,
|
||||
sourceBrowser,
|
||||
simplifiedMode,
|
||||
changingBrowsers
|
||||
) {
|
||||
ppBrowser.sendMessageToActor(
|
||||
"Printing:Preview:Enter",
|
||||
{
|
||||
browsingContextId: sourceBrowser.browsingContext.id,
|
||||
simplifiedMode,
|
||||
changingBrowsers,
|
||||
lastUsedPrinterName: this.getLastUsedPrinterName(),
|
||||
},
|
||||
"Printing"
|
||||
);
|
||||
},
|
||||
|
||||
printPreviewEntered(ppBrowser, previewResult) {
|
||||
let waitForPrintProgressToEnableToolbar = gPendingPrintPreviews.get(
|
||||
ppBrowser
|
||||
);
|
||||
gPendingPrintPreviews.delete(ppBrowser);
|
||||
|
||||
for (let { resolve, reject } of this._onEntered) {
|
||||
if (previewResult.failed) {
|
||||
reject();
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
|
||||
this._onEntered = [];
|
||||
if (previewResult.failed) {
|
||||
// Something went wrong while putting the document into print preview
|
||||
// mode. Bail out.
|
||||
this._ppBrowsers.clear();
|
||||
this._listener.onEnter();
|
||||
this._listener.onExit();
|
||||
return;
|
||||
}
|
||||
|
||||
// Stash the focused element so that we can return to it after exiting
|
||||
// print preview.
|
||||
gFocusedElement = document.commandDispatcher.focusedElement;
|
||||
|
||||
let printPreviewTB = document.getElementById("print-preview-toolbar");
|
||||
if (printPreviewTB) {
|
||||
if (previewResult.changingBrowsers) {
|
||||
printPreviewTB.destroy();
|
||||
printPreviewTB.initialize(ppBrowser);
|
||||
} else {
|
||||
// printPreviewTB.initialize above already calls updateToolbar.
|
||||
printPreviewTB.updateToolbar();
|
||||
}
|
||||
|
||||
// If we don't have a progress listener to enable the toolbar do it now.
|
||||
if (!waitForPrintProgressToEnableToolbar) {
|
||||
printPreviewTB.disableUpdateTriggers(false);
|
||||
}
|
||||
|
||||
ppBrowser.collapsed = false;
|
||||
ppBrowser.focus();
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the original window as an active window so any mozPrintCallbacks can
|
||||
// run without delayed setTimeouts.
|
||||
if (this._listener.activateBrowser) {
|
||||
this._listener.activateBrowser(this._sourceBrowser);
|
||||
} else {
|
||||
this._sourceBrowser.docShellIsActive = true;
|
||||
}
|
||||
|
||||
// show the toolbar after we go into print preview mode so
|
||||
// that we can initialize the toolbar with total num pages
|
||||
printPreviewTB = document.createXULElement("toolbar", {
|
||||
is: "printpreview-toolbar",
|
||||
});
|
||||
printPreviewTB.setAttribute("fullscreentoolbar", true);
|
||||
printPreviewTB.setAttribute("flex", "1");
|
||||
printPreviewTB.id = "print-preview-toolbar";
|
||||
|
||||
let navToolbox = this._listener.getNavToolbox();
|
||||
navToolbox.parentNode.insertBefore(printPreviewTB, navToolbox);
|
||||
printPreviewTB.initialize(ppBrowser);
|
||||
|
||||
// The print preview processing may not have fully completed, so if we
|
||||
// have a progress listener, disable the toolbar elements that can trigger
|
||||
// updates and it will enable them when completed.
|
||||
if (waitForPrintProgressToEnableToolbar) {
|
||||
printPreviewTB.disableUpdateTriggers(true);
|
||||
}
|
||||
|
||||
// Enable simplify page checkbox when the page is an article
|
||||
if (this._sourceBrowser.isArticle) {
|
||||
printPreviewTB.enableSimplifyPage();
|
||||
} else {
|
||||
this.logTelemetry("PRINT_PREVIEW_SIMPLIFY_PAGE_UNAVAILABLE_COUNT");
|
||||
printPreviewTB.disableSimplifyPage();
|
||||
}
|
||||
|
||||
// copy the window close handler
|
||||
if (window.onclose) {
|
||||
this._closeHandlerPP = window.onclose;
|
||||
} else {
|
||||
this._closeHandlerPP = null;
|
||||
}
|
||||
window.onclose = function() {
|
||||
PrintUtils.exitPrintPreview();
|
||||
return false;
|
||||
};
|
||||
|
||||
// disable chrome shortcuts...
|
||||
window.addEventListener("keydown", this.onKeyDownPP, true);
|
||||
window.addEventListener("keypress", this.onKeyPressPP, true);
|
||||
|
||||
ppBrowser.collapsed = false;
|
||||
ppBrowser.focus();
|
||||
// on Enter PP Call back
|
||||
this._listener.onEnter();
|
||||
},
|
||||
|
||||
readerModeReady(sourceBrowser) {
|
||||
let ppBrowser = this._listener.getSimplifiedPrintPreviewBrowser();
|
||||
this.sendEnterPrintPreviewToChild(ppBrowser, sourceBrowser, true, true);
|
||||
},
|
||||
|
||||
getLastUsedPrinterName() {
|
||||
let PSSVC = Cc["@mozilla.org/gfx/printsettings-service;1"].getService(
|
||||
Ci.nsIPrintSettingsService
|
||||
);
|
||||
|
@ -801,171 +904,12 @@ var PrintUtils = {
|
|||
}
|
||||
}
|
||||
|
||||
let sendEnterPreviewMessage = function(browser, simplified) {
|
||||
mm.sendAsyncMessage("Printing:Preview:Enter", {
|
||||
browsingContextId: browser.browsingContext.id,
|
||||
simplifiedMode: simplified,
|
||||
changingBrowsers: changingPrintPreviewBrowsers,
|
||||
lastUsedPrinterName,
|
||||
});
|
||||
};
|
||||
|
||||
// If we happen to have gotten simplify page checked, we will lazily
|
||||
// instantiate a new tab that parses the original page using ReaderMode
|
||||
// primitives. When it's ready, and in order to enter on preview, we send
|
||||
// over a message to print preview browser passing up the simplified tab as
|
||||
// reference. If not, we pass the original tab instead as content source.
|
||||
if (this._shouldSimplify) {
|
||||
let simplifiedBrowser = this._listener.getSimplifiedSourceBrowser();
|
||||
if (simplifiedBrowser) {
|
||||
sendEnterPreviewMessage(simplifiedBrowser, true);
|
||||
} else {
|
||||
simplifiedBrowser = this._listener.createSimplifiedBrowser();
|
||||
|
||||
// After instantiating the simplified tab, we attach a listener as
|
||||
// callback. Once we discover reader mode has been loaded, we fire
|
||||
// up a message to enter on print preview.
|
||||
let spMM = simplifiedBrowser.messageManager;
|
||||
spMM.addMessageListener(
|
||||
"Printing:Preview:ReaderModeReady",
|
||||
function onReaderReady() {
|
||||
spMM.removeMessageListener(
|
||||
"Printing:Preview:ReaderModeReady",
|
||||
onReaderReady
|
||||
);
|
||||
sendEnterPreviewMessage(simplifiedBrowser, true);
|
||||
}
|
||||
);
|
||||
|
||||
// Here, we send down a message to simplified browser in order to parse
|
||||
// the original page. After we have parsed it, content will tell parent
|
||||
// that the document is ready for print previewing.
|
||||
spMM.sendAsyncMessage("Printing:Preview:ParseDocument", {
|
||||
URL: this._originalURL,
|
||||
windowID: oldPPBrowser.outerWindowID,
|
||||
});
|
||||
|
||||
// Here we log telemetry data for when the user enters simplify mode.
|
||||
this.logTelemetry("PRINT_PREVIEW_SIMPLIFY_PAGE_OPENED_COUNT");
|
||||
}
|
||||
} else {
|
||||
sendEnterPreviewMessage(this._sourceBrowser, false);
|
||||
}
|
||||
|
||||
let waitForPrintProgressToEnableToolbar = false;
|
||||
if (this._webProgressPP.value) {
|
||||
mm.addMessageListener("Printing:Preview:StateChange", this);
|
||||
mm.addMessageListener("Printing:Preview:ProgressChange", this);
|
||||
waitForPrintProgressToEnableToolbar = true;
|
||||
}
|
||||
|
||||
let onEntered = message => {
|
||||
mm.removeMessageListener("Printing:Preview:Entered", onEntered);
|
||||
for (let { resolve, reject } of this._onEntered) {
|
||||
if (message.data.failed) {
|
||||
reject();
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
this._onEntered = [];
|
||||
if (message.data.failed) {
|
||||
// Something went wrong while putting the document into print preview
|
||||
// mode. Bail out.
|
||||
this._ppBrowsers.clear();
|
||||
this._listener.onEnter();
|
||||
this._listener.onExit();
|
||||
return;
|
||||
}
|
||||
|
||||
// Stash the focused element so that we can return to it after exiting
|
||||
// print preview.
|
||||
gFocusedElement = document.commandDispatcher.focusedElement;
|
||||
|
||||
let printPreviewTB = document.getElementById("print-preview-toolbar");
|
||||
if (printPreviewTB) {
|
||||
if (message.data.changingBrowsers) {
|
||||
printPreviewTB.destroy();
|
||||
printPreviewTB.initialize(ppBrowser);
|
||||
} else {
|
||||
// printPreviewTB.initialize above already calls updateToolbar.
|
||||
printPreviewTB.updateToolbar();
|
||||
}
|
||||
|
||||
// If we don't have a progress listener to enable the toolbar do it now.
|
||||
if (!waitForPrintProgressToEnableToolbar) {
|
||||
printPreviewTB.disableUpdateTriggers(false);
|
||||
}
|
||||
|
||||
ppBrowser.collapsed = false;
|
||||
ppBrowser.focus();
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the original window as an active window so any mozPrintCallbacks can
|
||||
// run without delayed setTimeouts.
|
||||
if (this._listener.activateBrowser) {
|
||||
this._listener.activateBrowser(this._sourceBrowser);
|
||||
} else {
|
||||
this._sourceBrowser.docShellIsActive = true;
|
||||
}
|
||||
|
||||
// show the toolbar after we go into print preview mode so
|
||||
// that we can initialize the toolbar with total num pages
|
||||
printPreviewTB = document.createXULElement("toolbar", {
|
||||
is: "printpreview-toolbar",
|
||||
});
|
||||
printPreviewTB.setAttribute("fullscreentoolbar", true);
|
||||
printPreviewTB.setAttribute("flex", "1");
|
||||
printPreviewTB.id = "print-preview-toolbar";
|
||||
|
||||
let navToolbox = this._listener.getNavToolbox();
|
||||
navToolbox.parentNode.insertBefore(printPreviewTB, navToolbox);
|
||||
printPreviewTB.initialize(ppBrowser);
|
||||
|
||||
// The print preview processing may not have fully completed, so if we
|
||||
// have a progress listener, disable the toolbar elements that can trigger
|
||||
// updates and it will enable them when completed.
|
||||
if (waitForPrintProgressToEnableToolbar) {
|
||||
printPreviewTB.disableUpdateTriggers(true);
|
||||
}
|
||||
|
||||
// Enable simplify page checkbox when the page is an article
|
||||
if (this._sourceBrowser.isArticle) {
|
||||
printPreviewTB.enableSimplifyPage();
|
||||
} else {
|
||||
this.logTelemetry("PRINT_PREVIEW_SIMPLIFY_PAGE_UNAVAILABLE_COUNT");
|
||||
printPreviewTB.disableSimplifyPage();
|
||||
}
|
||||
|
||||
// copy the window close handler
|
||||
if (window.onclose) {
|
||||
this._closeHandlerPP = window.onclose;
|
||||
} else {
|
||||
this._closeHandlerPP = null;
|
||||
}
|
||||
window.onclose = function() {
|
||||
PrintUtils.exitPrintPreview();
|
||||
return false;
|
||||
};
|
||||
|
||||
// disable chrome shortcuts...
|
||||
window.addEventListener("keydown", this.onKeyDownPP, true);
|
||||
window.addEventListener("keypress", this.onKeyPressPP, true);
|
||||
|
||||
ppBrowser.collapsed = false;
|
||||
ppBrowser.focus();
|
||||
// on Enter PP Call back
|
||||
this._listener.onEnter();
|
||||
};
|
||||
|
||||
mm.addMessageListener("Printing:Preview:Entered", onEntered);
|
||||
return lastUsedPrinterName;
|
||||
},
|
||||
|
||||
exitPrintPreview() {
|
||||
for (let browser of this._ppBrowsers) {
|
||||
let browserMM = browser.messageManager;
|
||||
browserMM.sendAsyncMessage("Printing:Preview:Exit");
|
||||
browser.sendMessageToActor("Printing:Preview:Exit", {}, "Printing");
|
||||
}
|
||||
this._ppBrowsers.clear();
|
||||
this._currentPPBrowser = null;
|
||||
|
@ -1065,5 +1009,3 @@ var PrintUtils = {
|
|||
}
|
||||
},
|
||||
};
|
||||
|
||||
PrintUtils.init();
|
||||
|
|
|
@ -37,10 +37,7 @@ add_task(async function pp_after_orientation_change() {
|
|||
let originalTabNavigated = BrowserTestUtils.browserStopped(browserToPrint);
|
||||
|
||||
// Enter print preview:
|
||||
let printPreviewEntered = BrowserTestUtils.waitForMessage(
|
||||
ppBrowser.messageManager,
|
||||
"Printing:Preview:Entered"
|
||||
);
|
||||
let printPreviewEntered = PrintHelper.waitForOldPrintPreview(ppBrowser);
|
||||
document.getElementById("cmd_printPreview").doCommand();
|
||||
await printPreviewEntered;
|
||||
|
||||
|
@ -63,10 +60,7 @@ add_task(async function pp_after_orientation_change() {
|
|||
: "landscape";
|
||||
let printPreviewToolbar = document.getElementById("print-preview-toolbar");
|
||||
|
||||
printPreviewEntered = BrowserTestUtils.waitForMessage(
|
||||
ppBrowser.messageManager,
|
||||
"Printing:Preview:Entered"
|
||||
);
|
||||
printPreviewEntered = PrintHelper.waitForOldPrintPreview(ppBrowser);
|
||||
printPreviewToolbar.orient(orientToSwitchTo);
|
||||
await printPreviewEntered;
|
||||
|
||||
|
|
|
@ -23,12 +23,9 @@ add_task(async function test() {
|
|||
|
||||
// Enter print preview
|
||||
let ppBrowser = PrintPreviewListener.getPrintPreviewBrowser();
|
||||
let printPreviewEntered = BrowserTestUtils.waitForMessage(
|
||||
ppBrowser.messageManager,
|
||||
"Printing:Preview:Entered"
|
||||
);
|
||||
let ppPromise = PrintHelper.waitForOldPrintPreview(ppBrowser);
|
||||
document.getElementById("cmd_printPreview").doCommand();
|
||||
await printPreviewEntered;
|
||||
await ppPromise;
|
||||
|
||||
await BrowserTestUtils.waitForCondition(
|
||||
() => gInPrintPreviewMode,
|
||||
|
|
|
@ -41,10 +41,7 @@ add_task(async function switch_print_preview_browsers() {
|
|||
|
||||
// Enter print preview
|
||||
let defaultPPBrowser = PrintPreviewListener.getPrintPreviewBrowser();
|
||||
let defaultPPEntered = BrowserTestUtils.waitForMessage(
|
||||
defaultPPBrowser.messageManager,
|
||||
"Printing:Preview:Entered"
|
||||
);
|
||||
let defaultPPEntered = PrintHelper.waitForOldPrintPreview(defaultPPBrowser);
|
||||
document.getElementById("cmd_printPreview").doCommand();
|
||||
await defaultPPEntered;
|
||||
|
||||
|
@ -59,9 +56,8 @@ add_task(async function switch_print_preview_browsers() {
|
|||
|
||||
// Here we call simplified mode
|
||||
let simplifiedPPBrowser = PrintPreviewListener.getSimplifiedPrintPreviewBrowser();
|
||||
let simplifiedPPEntered = BrowserTestUtils.waitForMessage(
|
||||
simplifiedPPBrowser.messageManager,
|
||||
"Printing:Preview:Entered"
|
||||
let simplifiedPPEntered = PrintHelper.waitForOldPrintPreview(
|
||||
simplifiedPPBrowser
|
||||
);
|
||||
let printPreviewToolbar = document.getElementById("print-preview-toolbar");
|
||||
|
||||
|
|
|
@ -43,10 +43,7 @@ add_task(async function switch_print_preview_browsers() {
|
|||
|
||||
// Enter print preview
|
||||
let defaultPPBrowser = PrintPreviewListener.getPrintPreviewBrowser();
|
||||
let defaultPPEntered = BrowserTestUtils.waitForMessage(
|
||||
defaultPPBrowser.messageManager,
|
||||
"Printing:Preview:Entered"
|
||||
);
|
||||
let defaultPPEntered = PrintHelper.waitForOldPrintPreview(defaultPPBrowser);
|
||||
document.getElementById("cmd_printPreview").doCommand();
|
||||
await defaultPPEntered;
|
||||
|
||||
|
@ -57,9 +54,8 @@ add_task(async function switch_print_preview_browsers() {
|
|||
|
||||
// Here we call simplified mode
|
||||
let simplifiedPPBrowser = PrintPreviewListener.getSimplifiedPrintPreviewBrowser();
|
||||
let simplifiedPPEntered = BrowserTestUtils.waitForMessage(
|
||||
simplifiedPPBrowser.messageManager,
|
||||
"Printing:Preview:Entered"
|
||||
let simplifiedPPEntered = PrintHelper.waitForOldPrintPreview(
|
||||
simplifiedPPBrowser
|
||||
);
|
||||
let printPreviewToolbar = document.getElementById("print-preview-toolbar");
|
||||
|
||||
|
@ -96,10 +92,7 @@ add_task(async function switch_print_preview_browsers() {
|
|||
);
|
||||
|
||||
// Switch back to default print preview content
|
||||
defaultPPEntered = BrowserTestUtils.waitForMessage(
|
||||
defaultPPBrowser.messageManager,
|
||||
"Printing:Preview:Entered"
|
||||
);
|
||||
defaultPPEntered = PrintHelper.waitForOldPrintPreview(defaultPPBrowser);
|
||||
printPreviewToolbar.mSimplifyPageCheckbox.click();
|
||||
await defaultPPEntered;
|
||||
|
||||
|
|
|
@ -55,6 +55,23 @@ class PrintHelper {
|
|||
);
|
||||
}
|
||||
|
||||
// This is used only for the old print preview. For tests
|
||||
// involving the newer UI, use waitForPreview instead.
|
||||
static waitForOldPrintPreview(expectedBrowser) {
|
||||
const { PrintingParent } = ChromeUtils.import(
|
||||
"resource://gre/actors/PrintingParent.jsm"
|
||||
);
|
||||
|
||||
return new Promise(resolve => {
|
||||
PrintingParent.setTestListener(browser => {
|
||||
if (browser == expectedBrowser) {
|
||||
PrintingParent.setTestListener(null);
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
constructor(sourceBrowser) {
|
||||
this.sourceBrowser = sourceBrowser;
|
||||
}
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
/* vim: set ts=2 sw=2 sts=2 et tw=80: */
|
||||
/* 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 = ["ActorChild"];
|
||||
|
||||
/**
|
||||
* This should be the base class of any actor class registered via
|
||||
* ActorManagerParent and implemented in the child process. It currently takes
|
||||
* care of setting the `mm`, `content`, and `docShell` properties based on the
|
||||
* message manager it's bound to, but may do more in the future.
|
||||
*
|
||||
* If Fission is being simulated, and the actor is registered as "allFrames",
|
||||
* the `content` property of this class will be bound to a specific subframe.
|
||||
* Otherwise, the `content` is always the top-level content tied to the `mm`.
|
||||
*/
|
||||
this.ActorChild = class ActorChild {
|
||||
constructor(dispatcher) {
|
||||
this._dispatcher = dispatcher;
|
||||
this.mm = dispatcher.mm;
|
||||
}
|
||||
|
||||
get content() {
|
||||
return this._dispatcher.window;
|
||||
}
|
||||
|
||||
get docShell() {
|
||||
return this.mm.docShell;
|
||||
}
|
||||
|
||||
addEventListener(event, options) {
|
||||
this._dispatcher.addEventListener(event, this.constructor.name, options);
|
||||
}
|
||||
|
||||
addMessageListener(msg) {
|
||||
this._dispatcher.addMessageListener(msg, this.constructor.name);
|
||||
}
|
||||
|
||||
sendAsyncMessage(msg, data = {}) {
|
||||
data.frameId = this._dispatcher.frameId;
|
||||
data.browsingContextId = this._dispatcher.browsingContextId;
|
||||
this.mm.sendAsyncMessage(msg, data);
|
||||
}
|
||||
};
|
|
@ -51,6 +51,16 @@ class Dispatcher {
|
|||
constructor(mm, data) {
|
||||
this.mm = mm;
|
||||
|
||||
// Temporarily disable to prevent an exception until this file is removed.
|
||||
if (!data) {
|
||||
data = {
|
||||
actors: new Map(),
|
||||
events: new Map(),
|
||||
messages: new Map(),
|
||||
observers: new Map(),
|
||||
};
|
||||
}
|
||||
|
||||
this.actors = data.actors;
|
||||
this.events = data.events;
|
||||
this.messages = data.messages;
|
||||
|
|
|
@ -365,6 +365,19 @@ let JSWINDOWACTORS = {
|
|||
allFrames: true,
|
||||
},
|
||||
|
||||
Printing: {
|
||||
parent: {
|
||||
moduleURI: "resource://gre/actors/PrintingParent.jsm",
|
||||
},
|
||||
child: {
|
||||
moduleURI: "resource://gre/actors/PrintingChild.jsm",
|
||||
events: {
|
||||
PrintingError: { capture: true },
|
||||
printPreviewUpdate: { capture: true },
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
PurgeSessionHistory: {
|
||||
child: {
|
||||
moduleURI: "resource://gre/actors/PurgeSessionHistoryChild.jsm",
|
||||
|
@ -554,23 +567,7 @@ let JSWINDOWACTORS = {
|
|||
* If Fission is being simulated, and an actor needs to receive events from
|
||||
* sub-frames, it must use "allFrames".
|
||||
*/
|
||||
let LEGACY_ACTORS = {
|
||||
Printing: {
|
||||
child: {
|
||||
module: "resource://gre/actors/PrintingChild.jsm",
|
||||
events: {
|
||||
PrintingError: { capture: true },
|
||||
printPreviewUpdate: { capture: true },
|
||||
},
|
||||
messages: [
|
||||
"Printing:Preview:Enter",
|
||||
"Printing:Preview:Exit",
|
||||
"Printing:Preview:Navigate",
|
||||
"Printing:Preview:ParseDocument",
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
let LEGACY_ACTORS = {};
|
||||
|
||||
class ActorSet {
|
||||
constructor(group, actorSide) {
|
||||
|
|
|
@ -155,7 +155,6 @@ with Files("docs/**"):
|
|||
|
||||
EXTRA_JS_MODULES += [
|
||||
"AboutPagesUtils.jsm",
|
||||
"ActorChild.jsm",
|
||||
"ActorManagerChild.jsm",
|
||||
"ActorManagerParent.jsm",
|
||||
"AppMenuNotifications.jsm",
|
||||
|
|
Загрузка…
Ссылка в новой задаче