diff --git a/api-samples/printing/README.md b/api-samples/printing/README.md index 70d6ca8264..701598a506 100644 --- a/api-samples/printing/README.md +++ b/api-samples/printing/README.md @@ -8,6 +8,8 @@ The `chrome.printing` namespace only works on ChromeOS. The sample demonstrates Calling `submitJob()` triggers a dialog box asking the user to confirm printing. Use the [`PrintingAPIExtensionsAllowlist`](https://chromeenterprise.google/policies/#PrintingAPIExtensionsAllowlist") policy to bypass confirmation. +If the **Roll Printers** checkbox is selected, only printers capable of roll printing will appear in the table. In this case, a separate test file is printed and the height of the media can be variable. See [`Roll printing`](https://developer.chrome.com/docs/extensions/reference/printing/#roll-printing) for more information. + ## Implementation Notes -Note that the `submitJob()` function throws an error when returning a promise ([crbug: 1422837](https://bugs.chromium.org/p/chromium/issues/detail?id=1422837)). +Before Chrome 120, `submitJob()` function throws an error when returning a promise. diff --git a/api-samples/printing/background.js b/api-samples/printing/background.js new file mode 100644 index 0000000000..aa9bb9acbc --- /dev/null +++ b/api-samples/printing/background.js @@ -0,0 +1,19 @@ +// Copyright 2023 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +chrome.action.onClicked.addListener(() => { + chrome.tabs.create({ + url: 'printers.html' + }); +}); diff --git a/api-samples/printing/manifest.json b/api-samples/printing/manifest.json index 3fc75a98fa..3a38132acc 100644 --- a/api-samples/printing/manifest.json +++ b/api-samples/printing/manifest.json @@ -3,8 +3,10 @@ "version": "1.0", "description": "Demonstrates all four methods of the chrome.printing namespace.", "permissions": ["printing"], + "background": { + "service_worker": "background.js" + }, "action": { - "default_popup": "printers.html", "default_icon": { "16": "icons/icon16.png", "48": "icons/icon48.png", diff --git a/api-samples/printing/printers.html b/api-samples/printing/printers.html index 8bb03b9f89..46408898ec 100644 --- a/api-samples/printing/printers.html +++ b/api-samples/printing/printers.html @@ -28,11 +28,9 @@

Print Job:

Printers:

-
-

JobId:

- -
+ + @@ -45,9 +43,11 @@

Printers:

+ +
Default Recently used CapabilitiesSupports trim Status
diff --git a/api-samples/printing/printers.js b/api-samples/printing/printers.js index 5ecff092ad..735b1c1517 100644 --- a/api-samples/printing/printers.js +++ b/api-samples/printing/printers.js @@ -2,7 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -function onPrintButtonClicked(printerId, dpi) { +let listOfPrinters = []; + +function rollPrintingEnabled() { + return document.getElementById('rollPrinters').checked; +} + +function onPrintButtonClicked(printerId, dpi, performTrim) { let ticket = { version: '1.0', print: { @@ -14,16 +20,34 @@ function onPrintButtonClicked(printerId, dpi) { horizontal_dpi: dpi.horizontal_dpi, vertical_dpi: dpi.vertical_dpi }, - media_size: { - width_microns: 210000, - height_microns: 297000, - vendor_id: 'iso_a4_210x297mm' - }, collate: { collate: false } } }; - fetch('test.pdf') + if (rollPrintingEnabled()) { + filename = 'test-rollprinting.pdf'; + ticket.print.media_size = { + width_microns: 72320, + // Note that this value needs to be between min_height_microns and + // max_height_microns. Usually this matches the height of the document + // being printed. + height_microns: 110000 + }; + // This only makese sense to specify if the printer supports the trim + // option. + if (performTrim) { + ticket.print.vendor_ticket_item = [{id: 'finishings', value: 'trim'}]; + } + } else { + filename = 'test.pdf'; + ticket.print.media_size = { + width_microns: 210000, + height_microns: 297000, + vendor_id: 'iso_a4_210x297mm' + }; + } + + fetch(filename) .then((response) => response.arrayBuffer()) .then((arrayBuffer) => { const request = { @@ -37,7 +61,7 @@ function onPrintButtonClicked(printerId, dpi) { }) } }; - chrome.printing.submitJob(request, (response) => { + chrome.printing.submitJob(request).then((response) => { if (response !== undefined) { console.log(response.status); } @@ -73,48 +97,63 @@ function addCell(parent) { return newCell; } +function supportsRollPrinting(printerInfo) { + // If any of the media size options support continuous feed, return true. + return printerInfo.capabilities.printer.media_size.option.find( + (option) => option.is_continuous_feed); +} + function createPrintersTable() { - chrome.printing.getPrinters().then((printers) => { - const tbody = document.createElement('tbody'); - printers.forEach((printer) => { - chrome.printing.getPrinterInfo(printer.id).then((printerInfo) => { - const columnValues = [ - printer.id, - printer.name, - printer.description, - printer.uri, - printer.source, - printer.isDefault, - printer.recentlyUsedRank, - JSON.stringify(printerInfo.capabilities), - printerInfo.status - ]; - - let tr = document.createElement('tr'); - const printTd = document.createElement('td'); - printTd.appendChild( + // Reset this so the table can be rebuilt with either all printers or just + // printers capable of roll printing. + let tbody = document.getElementById('tbody'); + while (tbody.firstChild) { + tbody.removeChild(tbody.firstChild); + } + + listOfPrinters.forEach((printer) => { + if (!rollPrintingEnabled() || supportsRollPrinting(printer.info)) { + // The printer needs to support this specific vendor capability if the + // print job ticket is going to specify the trim option. + const supportsTrim = + printer.info.capabilities.printer.vendor_capability.some( + (capability) => capability.display_name == "finishings/11"); + const columnValues = [ + printer.data.id, + printer.data.name, + printer.data.description, + printer.data.uri, + printer.data.source, + printer.data.isDefault, + printer.data.recentlyUsedRank, + JSON.stringify(printer.info.capabilities), + supportsTrim, + printer.info.status + ]; + + let tr = document.createElement('tr'); + const printTd = document.createElement('td'); + printTd.appendChild( createButton('Print', () => { onPrintButtonClicked( - printer.id, - printerInfo.capabilities.printer.dpi.option[0] + printer.data.id, + printer.info.capabilities.printer.dpi.option[0], + supportsTrim ); }) - ); + ); - tr.appendChild(printTd); + tr.appendChild(printTd); - for (const columnValue of columnValues) { - const td = document.createElement('td'); - td.appendChild(document.createTextNode(columnValue)); - td.setAttribute('align', 'center'); - tr.appendChild(td); - } + for (const columnValue of columnValues) { + const td = document.createElement('td'); + td.appendChild(document.createTextNode(columnValue)); + td.setAttribute('align', 'center'); + tr.appendChild(td); + } - tbody.appendChild(tr); - }); - }); - const table = document.getElementById('printersTable'); - table.appendChild(tbody); + tbody.appendChild(tr); + } }); chrome.printing.onJobStatusChanged.addListener((jobId, status) => { @@ -128,7 +167,7 @@ function createPrintersTable() { let cancelBtn = createButton('Cancel', () => { onCancelButtonClicked(jobId); }); - cancelBtn.setAttribute(`id ${jobId}-cancelBtn`); + cancelBtn.setAttribute('id', `id ${jobId}-cancelBtn`); cancelTd.appendChild(cancelBtn); const jobIdTd = addCell(jobTr); @@ -140,7 +179,7 @@ function createPrintersTable() { document.getElementById('printJobTbody').appendChild(jobTr); } else { - document.getElementById(`jobId${-status}`).innerText = status; + document.getElementById(`${jobId}-status`).innerText = status; if (status !== 'PENDING' && status !== 'IN_PROGRESS') { jobTr.remove(); } @@ -149,5 +188,17 @@ function createPrintersTable() { } document.addEventListener('DOMContentLoaded', () => { - createPrintersTable(); + chrome.printing.getPrinters().then((printers) => { + printers.forEach((printer) => { + chrome.printing.getPrinterInfo(printer.id).then((printerInfo) => { + listOfPrinters.push({data: printer, info: printerInfo}); + createPrintersTable(); + }); + }); + }); + + let checkbox = document.getElementById('rollPrinters') + checkbox.addEventListener('change', function() { + createPrintersTable(); + }); }); diff --git a/api-samples/printing/test-rollprinting.pdf b/api-samples/printing/test-rollprinting.pdf new file mode 100644 index 0000000000..65aaa7385c Binary files /dev/null and b/api-samples/printing/test-rollprinting.pdf differ