summaryrefslogtreecommitdiffstats
path: root/toolkit/components/printing/content/printPreviewPagination.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/printing/content/printPreviewPagination.js')
-rw-r--r--toolkit/components/printing/content/printPreviewPagination.js185
1 files changed, 185 insertions, 0 deletions
diff --git a/toolkit/components/printing/content/printPreviewPagination.js b/toolkit/components/printing/content/printPreviewPagination.js
new file mode 100644
index 0000000000..c503f0a8cb
--- /dev/null
+++ b/toolkit/components/printing/content/printPreviewPagination.js
@@ -0,0 +1,185 @@
+// This file is loaded into the browser window scope.
+/* eslint-env mozilla/browser-window */
+
+// -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*-
+
+/* 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/. */
+
+customElements.define(
+ "printpreview-pagination",
+ class PrintPreviewPagination extends HTMLElement {
+ static get markup() {
+ return `
+ <html:link rel="stylesheet" href="chrome://global/content/printPagination.css" />
+ <html:div class="container">
+ <html:button id="navigateHome" class="toolbarButton startItem" data-l10n-id="printpreview-homearrow-button"></html:button>
+ <html:button id="navigatePrevious" class="toolbarButton" data-l10n-id="printpreview-previousarrow-button"></html:button>
+ <html:div class="toolbarCenter"><html:span id="sheetIndicator" data-l10n-id="printpreview-sheet-of-sheets" data-l10n-args='{ "sheetNum": 1, "sheetCount": 1 }'></html:span></html:div>
+ <html:button id="navigateNext" class="toolbarButton" data-l10n-id="printpreview-nextarrow-button"></html:button>
+ <html:button id="navigateEnd" class="toolbarButton endItem" data-l10n-id="printpreview-endarrow-button"></html:button>
+ </html:div>
+ `;
+ }
+
+ static get defaultProperties() {
+ return {
+ currentPage: 1,
+ sheetCount: 1,
+ };
+ }
+
+ get previewBrowser() {
+ return this._previewBrowser;
+ }
+
+ set previewBrowser(aBrowser) {
+ this._previewBrowser = aBrowser;
+ }
+
+ observePreviewBrowser(browser) {
+ if (browser == this.previewBrowser || !this.isConnected) {
+ return;
+ }
+ this.previewBrowser = browser;
+ this.mutationObserver.disconnect();
+ this.mutationObserver.observe(browser, {
+ attributes: ["current-page", "sheet-count"],
+ });
+ this.updateFromBrowser();
+ }
+
+ connectedCallback() {
+ MozXULElement.insertFTLIfNeeded("toolkit/printing/printPreview.ftl");
+
+ const shadowRoot = this.attachShadow({ mode: "open" });
+ document.l10n.connectRoot(shadowRoot);
+
+ let fragment = MozXULElement.parseXULToFragment(this.constructor.markup);
+ this.shadowRoot.append(fragment);
+
+ this.elements = {
+ sheetIndicator: shadowRoot.querySelector("#sheetIndicator"),
+ homeButton: shadowRoot.querySelector("#navigateHome"),
+ previousButton: shadowRoot.querySelector("#navigatePrevious"),
+ nextButton: shadowRoot.querySelector("#navigateNext"),
+ endButton: shadowRoot.querySelector("#navigateEnd"),
+ };
+
+ this.shadowRoot.addEventListener("click", this);
+
+ this.mutationObserver = new MutationObserver(() =>
+ this.updateFromBrowser()
+ );
+
+ // Initial render with some default values
+ // We'll be updated with real values when available
+ this.update(this.constructor.defaultProperties);
+ }
+
+ disconnectedCallback() {
+ document.l10n.disconnectRoot(this.shadowRoot);
+ this.shadowRoot.textContent = "";
+ this.mutationObserver?.disconnect();
+ delete this.mutationObserver;
+ this.currentPreviewBrowserObserver?.disconnect();
+ delete this.currentPreviewBrowserObserver;
+ }
+
+ handleEvent(event) {
+ if (event.type == "click" && event.button != 0) {
+ return;
+ }
+ event.stopPropagation();
+
+ switch (event.target) {
+ case this.elements.homeButton:
+ this.navigate(0, 0, "home");
+ break;
+ case this.elements.previousButton:
+ this.navigate(-1, 0, 0);
+ break;
+ case this.elements.nextButton:
+ this.navigate(1, 0, 0);
+ break;
+ case this.elements.endButton:
+ this.navigate(0, 0, "end");
+ break;
+ }
+ }
+
+ navigate(aDirection, aPageNum, aHomeOrEnd) {
+ const nsIWebBrowserPrint = Ci.nsIWebBrowserPrint;
+ let targetNum;
+ let navType;
+ // we use only one of aHomeOrEnd, aDirection, or aPageNum
+ if (aHomeOrEnd) {
+ // We're going to either the very first page ("home"), or the
+ // very last page ("end").
+ if (aHomeOrEnd == "home") {
+ targetNum = 1;
+ navType = nsIWebBrowserPrint.PRINTPREVIEW_HOME;
+ } else {
+ targetNum = this.sheetCount;
+ navType = nsIWebBrowserPrint.PRINTPREVIEW_END;
+ }
+ } else if (aPageNum) {
+ // We're going to a specific page (aPageNum)
+ targetNum = Math.min(Math.max(1, aPageNum), this.sheetCount);
+ navType = nsIWebBrowserPrint.PRINTPREVIEW_GOTO_PAGENUM;
+ } else {
+ // aDirection is either +1 or -1, and allows us to increment
+ // or decrement our currently viewed page.
+ targetNum = Math.min(
+ Math.max(1, this.currentSheet + aDirection),
+ this.sheetCount
+ );
+ navType = nsIWebBrowserPrint.PRINTPREVIEW_GOTO_PAGENUM;
+ }
+
+ // Preemptively update our own state, rather than waiting for the message from the child process
+ // This allows subsequent clicks of next/back to advance 1 page per click if possible
+ // and keeps the UI feeling more responsive
+ this.update({ currentPage: targetNum });
+
+ this.previewBrowser.sendMessageToActor(
+ "Printing:Preview:Navigate",
+ {
+ navType,
+ pageNum: targetNum,
+ },
+ "Printing"
+ );
+ }
+
+ update(data = {}) {
+ if (data.sheetCount) {
+ this.sheetCount = data.sheetCount;
+ }
+ if (data.currentPage) {
+ this.currentSheet = data.currentPage;
+ }
+ document.l10n.setAttributes(
+ this.elements.sheetIndicator,
+ this.elements.sheetIndicator.dataset.l10nId,
+ {
+ sheetNum: this.currentSheet,
+ sheetCount: this.sheetCount,
+ }
+ );
+ }
+
+ updateFromBrowser() {
+ let sheetCount = parseInt(
+ this.previewBrowser.getAttribute("sheet-count"),
+ 10
+ );
+ let currentPage = parseInt(
+ this.previewBrowser.getAttribute("current-page"),
+ 10
+ );
+ this.update({ sheetCount, currentPage });
+ }
+ }
+);