Skip to content

Commit

Permalink
Add roll printing sample (GoogleChrome#1006)
Browse files Browse the repository at this point in the history
* Add roll printing sample

* Copied heavily from existing printing sample

* Changed functionality from existing printing sample as follows:

* Only display printers that support roll printing
* In table, create a row for each unique width for each printer

* Fix wording in README

* Update readme to list a milestone for bug to get fixed

* Update api-samples/printing/roll-printing/README.md

Co-authored-by: Joe Medley <[email protected]>

* Update api-samples/printing/README.md

Co-authored-by: Joe Medley <[email protected]>

* Convert a function call to a promise.

* Clean up a few errors setting element IDs.

Remove the main cancel button that is no longer used.  Instead, the
cancel button that gets created in the print job table is the one that
should be used.

* Consolidate the roll-printing sample with the regular sample

There is now a checkbox on the main UI to select roll printers or all
printers.  For roll printing, this sample now demonstrates how to check
if the printer is capable of roll printing, if the printer is capable of
trimming the paper after printing, and how the media length can be a
variable value.

* Update api-samples/printing/README.md

Co-authored-by: Oliver Dunk <[email protected]>

* Update api-samples/printing/printers.js

Co-authored-by: Oliver Dunk <[email protected]>

* Simplify fuction to use find instead of filter

Update README to link to roll printing info.

* Use new page instead of popup

* Update api-samples/printing/README.md

Co-authored-by: Joe Medley <[email protected]>

---------

Co-authored-by: Joe Medley <[email protected]>
Co-authored-by: Oliver Dunk <[email protected]>
  • Loading branch information
3 people authored Nov 21, 2023
1 parent 0096d67 commit 37b9846
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 51 deletions.
4 changes: 3 additions & 1 deletion api-samples/printing/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
19 changes: 19 additions & 0 deletions api-samples/printing/background.js
Original file line number Diff line number Diff line change
@@ -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'
});
});
4 changes: 3 additions & 1 deletion api-samples/printing/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
8 changes: 4 additions & 4 deletions api-samples/printing/printers.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,9 @@ <h2>Print Job:</h2>
</div>

<h2>Printers:</h2>
<div id="statusDiv">
<p id="jobStatus">JobId: <div id="jobIdDiv"></div></p>
<button id="cancelBtn">Cancel Printing</button>
</div>
<div id="printers">
<input type='checkbox' id='rollPrinters' name='rollPrinters'>
<label for='rollPrinters'>Roll Printers</label>
<table id="printersTable">
<thead>
<tr>
Expand All @@ -45,9 +43,11 @@ <h2>Printers:</h2>
<th>Default</th>
<th>Recently used</th>
<th>Capabilities</th>
<th>Supports trim</th>
<th>Status</th>
</tr>
</thead>
<tbody id="tbody"/>
</table>
</div>
</body>
Expand Down
141 changes: 96 additions & 45 deletions api-samples/printing/printers.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand All @@ -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 = {
Expand All @@ -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);
}
Expand Down Expand Up @@ -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) => {
Expand All @@ -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);
Expand All @@ -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();
}
Expand All @@ -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();
});
});
Binary file added api-samples/printing/test-rollprinting.pdf
Binary file not shown.

0 comments on commit 37b9846

Please sign in to comment.