diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml
index e32dd3b837ec..74488c47fe69 100644
--- a/modules/libpref/init/StaticPrefList.yaml
+++ b/modules/libpref/init/StaticPrefList.yaml
@@ -9028,6 +9028,12 @@
value: @IS_EARLY_BETA_OR_EARLIER@
mirror: always
+# Whether the pages per sheet print setting is enabled.
+- name: print.pages_per_sheet.enabled
+ type: RelaxedAtomicBool
+ value: false
+ mirror: always
+
# Whether we allow the print progress dialog to show up.
- name: print.show_print_progress
type: RelaxedAtomicBool
diff --git a/toolkit/components/printing/content/print.html b/toolkit/components/printing/content/print.html
index e518702d718d..df42f87fa505 100644
--- a/toolkit/components/printing/content/print.html
+++ b/toolkit/components/printing/content/print.html
@@ -163,6 +163,16 @@
+
+
diff --git a/toolkit/components/printing/content/print.js b/toolkit/components/printing/content/print.js
index d35374fc1670..24b68c50888e 100644
--- a/toolkit/components/printing/content/print.js
+++ b/toolkit/components/printing/content/print.js
@@ -148,7 +148,7 @@ var PrintEventHandler = {
// These settings do not have an associated pref value or flag, but
// changing them requires us to update the print preview.
- _nonFlaggedUpdatePreviewSettings: new Set(["pageRanges"]),
+ _nonFlaggedUpdatePreviewSettings: new Set(["pageRanges", "numPagesPerSheet"]),
async init() {
Services.telemetry.scalarAdd("printing.preview_opened_tm", 1);
@@ -1546,6 +1546,10 @@ class PrintUIForm extends PrintUIControlMixin(HTMLFormElement) {
// Move the Print button to the end if this isn't Windows.
this.printButton.parentElement.append(this.printButton);
}
+ this.querySelector("#pages-per-sheet").hidden = !Services.prefs.getBoolPref(
+ "print.pages_per_sheet.enabled",
+ false
+ );
}
requestPrint() {
diff --git a/toolkit/components/printing/tests/browser_sheet_count.js b/toolkit/components/printing/tests/browser_sheet_count.js
index 40fb756572d2..703b94a8bbd6 100644
--- a/toolkit/components/printing/tests/browser_sheet_count.js
+++ b/toolkit/components/printing/tests/browser_sheet_count.js
@@ -117,3 +117,73 @@ add_task(async function testSheetCountPageRange() {
is(sheets, 2, "There are now only 2 pages shown");
});
});
+
+add_task(async function testPagesPerSheetCount() {
+ await PrintHelper.withTestPage(async helper => {
+ let mockPrinterName = "A real printer!";
+ helper.addMockPrinter(mockPrinterName);
+
+ await SpecialPowers.pushPrefEnv({
+ set: [
+ ["print.pages_per_sheet.enabled", true],
+ ["print_printer", mockPrinterName],
+ ],
+ });
+
+ await helper.startPrint();
+
+ await helper.waitForPreview(() =>
+ helper.dispatchSettingsChange({
+ shrinkToFit: false,
+ scaling: 2,
+ })
+ );
+
+ let sheetCount = helper.get("sheet-count");
+ let sheets = getSheetCount(sheetCount);
+
+ ok(sheets > 1, "There are multiple pages");
+
+ await helper.openMoreSettings();
+ let pagesPerSheet = helper.get("pages-per-sheet-picker");
+ ok(BrowserTestUtils.is_visible(pagesPerSheet), "Pages per sheet is shown");
+ pagesPerSheet.focus();
+ EventUtils.sendKey("space", helper.win);
+ for (let i = 0; i < 5; i++) {
+ EventUtils.sendKey("down", helper.win);
+ if (pagesPerSheet.value == 16) {
+ break;
+ }
+ }
+ await helper.waitForPreview(() => EventUtils.sendKey("return", helper.win));
+
+ sheets = getSheetCount(sheetCount);
+ is(sheets, 1, "There's only one sheet now");
+
+ await helper.waitForSettingsEvent(() =>
+ helper.dispatchSettingsChange({ numCopies: 5 })
+ );
+
+ sheets = getSheetCount(sheetCount);
+ is(sheets, 5, "Copies are handled with pages per sheet correctly");
+
+ await helper.closeDialog();
+ });
+});
+
+add_task(async function testPagesPerSheetPref() {
+ await SpecialPowers.pushPrefEnv({
+ set: [["print.pages_per_sheet.enabled", false]],
+ });
+
+ await PrintHelper.withTestPage(async helper => {
+ await helper.startPrint();
+
+ ok(
+ BrowserTestUtils.is_hidden(helper.get("pages-per-sheet")),
+ "Pages per sheet is hidden"
+ );
+
+ await helper.closeDialog();
+ });
+});
diff --git a/toolkit/components/printing/tests/head.js b/toolkit/components/printing/tests/head.js
index 623eb7a4d477..5adfe82d8347 100644
--- a/toolkit/components/printing/tests/head.js
+++ b/toolkit/components/printing/tests/head.js
@@ -265,8 +265,10 @@ class PrintHelper {
await BrowserTestUtils.waitForEvent(this.doc, "preview-updated");
}
- async waitForSettingsEvent() {
- await BrowserTestUtils.waitForEvent(this.doc, "print-settings");
+ async waitForSettingsEvent(changeFn) {
+ let changed = BrowserTestUtils.waitForEvent(this.doc, "print-settings");
+ await changeFn?.();
+ await changed;
}
click(el, { scroll = true } = {}) {
diff --git a/toolkit/locales/en-US/toolkit/printing/printUI.ftl b/toolkit/locales/en-US/toolkit/printing/printUI.ftl
index 4d8b8c303ef1..7b4aa0789589 100644
--- a/toolkit/locales/en-US/toolkit/printing/printUI.ftl
+++ b/toolkit/locales/en-US/toolkit/printing/printUI.ftl
@@ -87,6 +87,8 @@ printui-loading = Preparing Preview
printui-preview-label =
.aria-label = Print Preview
+printui-pages-per-sheet = Pages per sheet
+
## Paper sizes that may be supported by the Save to PDF destination:
printui-paper-a5 = A5