summaryrefslogtreecommitdiff
path: root/chromium/chrome/browser/resources/print_preview
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/chrome/browser/resources/print_preview')
-rw-r--r--chromium/chrome/browser/resources/print_preview/BUILD.gn16
-rw-r--r--chromium/chrome/browser/resources/print_preview/data/BUILD.gn4
-rw-r--r--chromium/chrome/browser/resources/print_preview/data/destination.js28
-rw-r--r--chromium/chrome/browser/resources/print_preview/data/destination_store.js4
-rw-r--r--chromium/chrome/browser/resources/print_preview/data/model.js6
-rw-r--r--chromium/chrome/browser/resources/print_preview/data/printer_status_cros.js56
-rw-r--r--chromium/chrome/browser/resources/print_preview/metrics.js4
-rw-r--r--chromium/chrome/browser/resources/print_preview/native_layer.js229
-rw-r--r--chromium/chrome/browser/resources/print_preview/print_preview.html3
-rw-r--r--chromium/chrome/browser/resources/print_preview/print_preview.js11
-rw-r--r--chromium/chrome/browser/resources/print_preview/print_preview_pdf_resources.grd28
-rw-r--r--chromium/chrome/browser/resources/print_preview/print_preview_resources.grd20
-rw-r--r--chromium/chrome/browser/resources/print_preview/print_preview_resources_vulcanized.grd14
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/BUILD.gn24
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/app.js4
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/button_strip.js25
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/destination_dialog.js15
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.html150
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.js273
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/destination_select_cros.html15
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/destination_select_cros.js251
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/destination_settings.js7
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/header.js53
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/link_container.html2
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/more_settings.html2
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/preview_area.js4
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/print_preview_search_box.html2
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/print_preview_vars_css.html4
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/printer_status_icon_cros.html67
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/printer_status_icon_cros.js40
-rw-r--r--chromium/chrome/browser/resources/print_preview/ui/select_behavior.js9
31 files changed, 1153 insertions, 217 deletions
diff --git a/chromium/chrome/browser/resources/print_preview/BUILD.gn b/chromium/chrome/browser/resources/print_preview/BUILD.gn
index 63df1dd2a18..abe2ff3da74 100644
--- a/chromium/chrome/browser/resources/print_preview/BUILD.gn
+++ b/chromium/chrome/browser/resources/print_preview/BUILD.gn
@@ -44,7 +44,7 @@ if (optimize_webui) {
]
deps = [
- "../pdf/elements:web_components",
+ "../pdf:web_components",
"ui:web_components",
]
defines = chrome_grit_defines
@@ -74,10 +74,23 @@ js_type_check("print_preview_module_resources") {
":dark_mode_behavior",
":metrics",
":native_layer",
+ ":print_preview",
":print_preview_utils",
]
}
+js_library("print_preview") {
+ deps = [
+ ":cloud_print_interface",
+ ":native_layer",
+ "data:destination",
+ "data:destination_store",
+ "data:measurement_system",
+ "ui:app",
+ "ui:settings_select",
+ ]
+}
+
js_library("print_preview_utils") {
deps = [
":dark_mode_behavior",
@@ -118,6 +131,7 @@ js_library("native_layer") {
"data:destination_match",
"data:destination_policies",
"data:measurement_system",
+ "data:printer_status_cros",
"//ui/webui/resources/js:assert.m",
"//ui/webui/resources/js:cr.m",
]
diff --git a/chromium/chrome/browser/resources/print_preview/data/BUILD.gn b/chromium/chrome/browser/resources/print_preview/data/BUILD.gn
index 030f5a2088f..61a94abfa0a 100644
--- a/chromium/chrome/browser/resources/print_preview/data/BUILD.gn
+++ b/chromium/chrome/browser/resources/print_preview/data/BUILD.gn
@@ -22,6 +22,7 @@ js_type_check("closure_compile_module") {
":measurement_system",
":model",
":printable_area",
+ ":printer_status_cros",
":scaling",
":size",
":state",
@@ -165,3 +166,6 @@ js_library("user_manager") {
"//ui/webui/resources/js:web_ui_listener_behavior.m",
]
}
+
+js_library("printer_status_cros") {
+}
diff --git a/chromium/chrome/browser/resources/print_preview/data/destination.js b/chromium/chrome/browser/resources/print_preview/data/destination.js
index 3c6155bd266..a6938175df1 100644
--- a/chromium/chrome/browser/resources/print_preview/data/destination.js
+++ b/chromium/chrome/browser/resources/print_preview/data/destination.js
@@ -10,6 +10,7 @@ import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
// <if expr="chromeos">
import {ColorModeRestriction, DestinationPolicies, DuplexModeRestriction, PinModeRestriction} from './destination_policies.js';
+import {PrinterStatusReason} from '../data/printer_status_cros.js';
// </if>
/**
@@ -139,7 +140,7 @@ export let VendorCapability;
* only on Chrome OS.
*
* @typedef {{
- * vendor_capability: !Array<!VendorCapability>,
+ * vendor_capability: (Array<!VendorCapability>|undefined),
* collate: ({default: (boolean|undefined)}|undefined),
* color: ({
* option: !Array<{
@@ -162,7 +163,8 @@ export let VendorCapability;
* type: (string|undefined),
* vendor_id: (string|undefined),
* custom_display_name: (string|undefined),
- * is_default: (boolean|undefined)
+ * is_default: (boolean|undefined),
+ * name: (string|undefined),
* }>
* }|undefined),
* dpi: ({
@@ -412,6 +414,12 @@ export class Destination {
* @private {string}
*/
this.eulaUrl_ = '';
+
+ /**
+ * Stores the printer status reason for a local Chrome OS printer.
+ * @private {!PrinterStatusReason}
+ */
+ this.printerStatusReason_ = PrinterStatusReason.UNKNOWN_REASON;
// </if>
assert(
@@ -597,6 +605,22 @@ export class Destination {
set eulaUrl(eulaUrl) {
this.eulaUrl_ = eulaUrl;
}
+
+ /**
+ * @return {!PrinterStatusReason} The printer status reason for a local
+ * Chrome OS printer.
+ */
+ get printerStatusReason() {
+ return this.printerStatusReason_;
+ }
+
+ /**
+ * @param {!PrinterStatusReason} printerStatusReason The printer status reason
+ * to be set.
+ */
+ set printerStatusReason(printerStatusReason) {
+ this.printerStatusReason_ = printerStatusReason;
+ }
// </if>
/**
diff --git a/chromium/chrome/browser/resources/print_preview/data/destination_store.js b/chromium/chrome/browser/resources/print_preview/data/destination_store.js
index f8b40cdd974..2844928fe10 100644
--- a/chromium/chrome/browser/resources/print_preview/data/destination_store.js
+++ b/chromium/chrome/browser/resources/print_preview/data/destination_store.js
@@ -10,7 +10,7 @@ import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
import {CloudPrintInterface, CloudPrintInterfaceEventType, CloudPrintInterfacePrinterFailedDetail, CloudPrintInterfaceProcessInviteDetail, CloudPrintInterfaceSearchDoneDetail} from '../cloud_print_interface.js';
import {Metrics, MetricsContext} from '../metrics.js';
-import {CapabilitiesResponse, LocalDestinationInfo, NativeLayer, PrinterSetupResponse, PrivetPrinterDescription, ProvisionalDestinationInfo} from '../native_layer.js';
+import {CapabilitiesResponse, LocalDestinationInfo, NativeLayer, NativeLayerImpl, PrinterSetupResponse, PrivetPrinterDescription, ProvisionalDestinationInfo} from '../native_layer.js';
import {Cdd, CloudOrigins, createDestinationKey, createRecentDestinationKey, Destination, DestinationConnectionStatus, DestinationOrigin, DestinationProvisionalType, DestinationType, RecentDestination} from './destination.js';
import {DestinationMatch, originToType, PrinterType} from './destination_match.js';
@@ -229,7 +229,7 @@ export class DestinationStore extends EventTarget {
* Used to fetch local print destinations.
* @private {!NativeLayer}
*/
- this.nativeLayer_ = NativeLayer.getInstance();
+ this.nativeLayer_ = NativeLayerImpl.getInstance();
/**
* Whether PDF printer is enabled. It's disabled, for example, in App
diff --git a/chromium/chrome/browser/resources/print_preview/data/model.js b/chromium/chrome/browser/resources/print_preview/data/model.js
index 8eea52a6e5f..b0a3948e24e 100644
--- a/chromium/chrome/browser/resources/print_preview/data/model.js
+++ b/chromium/chrome/browser/resources/print_preview/data/model.js
@@ -10,7 +10,7 @@ import {Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.m
import {BackgroundGraphicsModeRestriction, Policies} from '../native_layer.js';
-import {Cdd, CddCapabilities, Destination, DestinationOrigin, DestinationType, RecentDestination} from './destination.js';
+import {Cdd, CddCapabilities, Destination, DestinationOrigin, DestinationType, RecentDestination, VendorCapability} from './destination.js';
import {getPrinterTypeForDestination} from './destination_match.js';
// <if expr="chromeos">
import {ColorModeRestriction, DuplexModeRestriction, PinModeRestriction} from './destination_policies.js';
@@ -44,6 +44,7 @@ export let Setting;
* collate: !Setting,
* layout: !Setting,
* color: !Setting,
+ * customMargins: !Setting,
* mediaSize: !Setting,
* margins: !Setting,
* dpi: !Setting,
@@ -950,7 +951,8 @@ Polymer({
if (this.settings.vendorItems.available) {
const vendorSettings = {};
- for (const item of caps.vendor_capability) {
+ for (const item of /** @type {!Array<!VendorCapability>} */ (
+ caps.vendor_capability)) {
let defaultValue = null;
if (item.type === 'SELECT' && item.select_cap &&
item.select_cap.option) {
diff --git a/chromium/chrome/browser/resources/print_preview/data/printer_status_cros.js b/chromium/chrome/browser/resources/print_preview/data/printer_status_cros.js
new file mode 100644
index 00000000000..0cc0c513121
--- /dev/null
+++ b/chromium/chrome/browser/resources/print_preview/data/printer_status_cros.js
@@ -0,0 +1,56 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * These values must be kept in sync with the Reason enum in
+ * /chromeos/printing/cups_printer_status.h
+ * @enum {number}
+ */
+export const PrinterStatusReason = {
+ CONNECTING_TO_DEVICE: 0,
+ DEVICE_ERROR: 1,
+ DOOR_OPEN: 2,
+ LOW_ON_INK: 3,
+ LOW_ON_PAPER: 4,
+ NO_ERROR: 5,
+ OUT_OF_INK: 6,
+ OUT_OF_PAPER: 7,
+ OUTPUT_ALMOST_FULL: 8,
+ OUTPUT_FULL: 9,
+ PAPER_JAM: 10,
+ PAUSED: 11,
+ PRINTER_QUEUE_FULL: 12,
+ PRINTER_UNREACHABLE: 13,
+ STOPPED: 14,
+ TRAY_MISSING: 15,
+ UNKNOWN_REASON: 16,
+};
+
+/**
+ * These values must be kept in sync with the Severity enum in
+ * /chromeos/printing/cups_printer_status.h
+ * @enum {number}
+ */
+export const PrinterStatusSeverity = {
+ UNKOWN_SEVERITY: 0,
+ REPORT: 1,
+ WARNING: 2,
+ ERROR: 3,
+};
+
+/**
+ * A container for the results of a printer status query. A printer status query
+ * can return multiple error reasons. |timestamp| is set at the time of status
+ * creation.
+ *
+ * @typedef {{
+ * printerId: string,
+ * statusReasons: !Array<{
+ * reason: PrinterStatusReason,
+ * severity: PrinterStatusSeverity,
+ * }>,
+ * timestamp: number,
+ * }}
+ */
+export let PrinterStatus;
diff --git a/chromium/chrome/browser/resources/print_preview/metrics.js b/chromium/chrome/browser/resources/print_preview/metrics.js
index 34325bc2883..dc889e6ad99 100644
--- a/chromium/chrome/browser/resources/print_preview/metrics.js
+++ b/chromium/chrome/browser/resources/print_preview/metrics.js
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-import {NativeLayer} from './native_layer.js';
+import {NativeLayer, NativeLayerImpl} from './native_layer.js';
/**
* Object used to measure usage statistics.
@@ -89,7 +89,7 @@ export class MetricsContext {
this.maxBucket_ = maxBucket;
/** @private {!NativeLayer} */
- this.nativeLayer_ = NativeLayer.getInstance();
+ this.nativeLayer_ = NativeLayerImpl.getInstance();
}
/**
diff --git a/chromium/chrome/browser/resources/print_preview/native_layer.js b/chromium/chrome/browser/resources/print_preview/native_layer.js
index ff0c3d18686..a7f13fc56bb 100644
--- a/chromium/chrome/browser/resources/print_preview/native_layer.js
+++ b/chromium/chrome/browser/resources/print_preview/native_layer.js
@@ -3,12 +3,13 @@
// found in the LICENSE file.
import {assert} from 'chrome://resources/js/assert.m.js';
-import {sendWithPromise} from 'chrome://resources/js/cr.m.js';
+import {addSingletonGetter, sendWithPromise} from 'chrome://resources/js/cr.m.js';
import {Cdd, Destination} from './data/destination.js';
import {PrinterType} from './data/destination_match.js';
// <if expr="chromeos">
import {DestinationPolicies} from './data/destination_policies.js';
+import {PrinterStatus} from './data/printer_status_cros.js';
// </if>
import {MeasurementSystemUnitType} from './data/measurement_system.js';
@@ -118,7 +119,7 @@ export let PrivetPrinterDescription;
* printer:(PrivetPrinterDescription |
* LocalDestinationInfo |
* undefined),
- * capabilities: !Cdd,
+ * capabilities: ?Cdd,
* }}
*/
export let CapabilitiesResponse;
@@ -146,44 +147,22 @@ export let ProvisionalDestinationInfo;
/**
* An interface to the native Chromium printing system layer.
+ * @interface
*/
export class NativeLayer {
- /**
- * Creates a new NativeLayer if the current instance is not set.
- * @return {!NativeLayer} The singleton instance.
- */
- static getInstance() {
- if (currentInstance === null) {
- currentInstance = new NativeLayer();
- }
- return assert(currentInstance);
- }
-
- /**
- * @param {!NativeLayer} instance The NativeLayer instance
- * to set for print preview construction.
- */
- static setInstance(instance) {
- currentInstance = instance;
- }
-
// <if expr="chromeos">
/**
* Requests access token for cloud print requests for DEVICE origin.
* @return {!Promise<string>}
*/
- getAccessToken() {
- return sendWithPromise('getAccessToken');
- }
+ getAccessToken() {}
// </if>
/**
* Gets the initial settings to initialize the print preview with.
* @return {!Promise<!NativeInitialSettings>}
*/
- getInitialSettings() {
- return sendWithPromise('getInitialSettings');
- }
+ getInitialSettings() {}
/**
* Requests the system's print destinations. The promise will be resolved
@@ -193,9 +172,7 @@ export class NativeLayer {
* request.
* @return {!Promise}
*/
- getPrinters(type) {
- return sendWithPromise('getPrinters', type);
- }
+ getPrinters(type) {}
/**
* Requests the destination's printing capabilities. Returns a promise that
@@ -204,13 +181,7 @@ export class NativeLayer {
* @param {!PrinterType} type The destination's printer type.
* @return {!Promise<!CapabilitiesResponse>}
*/
- getPrinterCapabilities(destinationId, type) {
- return sendWithPromise(
- 'getPrinterCapabilities', destinationId,
- destinationId === Destination.GooglePromotedId.SAVE_AS_PDF ?
- PrinterType.PDF_PRINTER :
- type);
- }
+ getPrinterCapabilities(destinationId, type) {}
// <if expr="chromeos">
/**
@@ -220,9 +191,7 @@ export class NativeLayer {
* @param {!string} destinationId ID of the destination.
* @return {!Promise<string>}
*/
- getEulaUrl(destinationId) {
- return sendWithPromise('getEulaUrl', destinationId);
- }
+ getEulaUrl(destinationId) {}
/**
* Requests Chrome to resolve provisional extension destination by granting
@@ -230,19 +199,14 @@ export class NativeLayer {
* @param {string} provisionalDestinationId
* @return {!Promise<!ProvisionalDestinationInfo>}
*/
- grantExtensionPrinterAccess(provisionalDestinationId) {
- return sendWithPromise(
- 'grantExtensionPrinterAccess', provisionalDestinationId);
- }
+ grantExtensionPrinterAccess(provisionalDestinationId) {}
/**
* Requests that Chrome perform printer setup for the given printer.
* @param {string} printerId
* @return {!Promise<!PrinterSetupResponse>}
*/
- setupPrinter(printerId) {
- return sendWithPromise('setupPrinter', printerId);
- }
+ setupPrinter(printerId) {}
// </if>
/**
@@ -256,17 +220,13 @@ export class NativeLayer {
* @return {!Promise<number>} Promise that resolves with the unique ID of
* the preview UI when the preview has been generated.
*/
- getPreview(printTicket) {
- return sendWithPromise('getPreview', printTicket);
- }
+ getPreview(printTicket) {}
/**
* Opens the chrome://settings printing page. For Chrome OS, open the
- * printing settings in the Settings App.
+ * printing settings in the Settings App.
*/
- openSettingsPrintPage() {
- chrome.send('openPrinterSettings');
- }
+ openSettingsPrintPage() {}
/**
* Requests that the document be printed.
@@ -275,28 +235,20 @@ export class NativeLayer {
* @return {!Promise} Promise that will resolve when the print request is
* finished or rejected.
*/
- print(printTicket) {
- return sendWithPromise('print', printTicket);
- }
+ print(printTicket) {}
/** Requests that the current pending print request be cancelled. */
- cancelPendingPrintRequest() {
- chrome.send('cancelPendingPrintRequest');
- }
+ cancelPendingPrintRequest() {}
/**
* Sends the app state to be saved in the sticky settings.
* @param {string} appStateStr JSON string of the app state to persist.
*/
- saveAppState(appStateStr) {
- chrome.send('saveAppState', [appStateStr]);
- }
+ saveAppState(appStateStr) {}
// <if expr="not chromeos and not is_win">
/** Shows the system's native printing dialog. */
- showSystemDialog() {
- chrome.send('showSystemDialog');
- }
+ showSystemDialog() {}
// </if>
/**
@@ -306,17 +258,10 @@ export class NativeLayer {
* @param {boolean} isCancel whether this was called due to the user
* closing the dialog without printing.
*/
- dialogClose(isCancel) {
- if (isCancel) {
- chrome.send('closePrintPreviewDialog');
- }
- chrome.send('dialogClose');
- }
+ dialogClose(isCancel) {}
/** Hide the print preview dialog and allow the native layer to close it. */
- hidePreview() {
- chrome.send('hidePreview');
- }
+ hidePreview() {}
/**
* Opens the Google Cloud Print sign-in tab. If the user signs in
@@ -324,26 +269,16 @@ export class NativeLayer {
* @param {boolean} addAccount Whether to open an 'add a new account' or
* default sign in page.
*/
- signIn(addAccount) {
- chrome.send('signIn', [addAccount]);
- }
-
- /**
- * Sends a message to the test, letting it know that an
- * option has been set to a particular value and that the change has
- * finished modifying the preview area.
- */
- uiLoadedForTest() {
- chrome.send('UILoadedForTest');
- }
+ signIn(addAccount) {}
+ // <if expr="chromeos">
/**
- * Notifies the test that the option it tried to change
- * had not been changed successfully.
+ * Sends a request to the printer with id |printerId| for its current status.
+ * @param {string} printerId
+ * @return {!Promise<!PrinterStatus>}
*/
- uiFailedLoadingForTest() {
- chrome.send('UIFailedLoadingForTest');
- }
+ requestPrinterStatusUpdate(printerId) {}
+ // </if>
/**
* Notifies the metrics handler to record a histogram value.
@@ -351,11 +286,117 @@ export class NativeLayer {
* @param {number} bucket The bucket to record
* @param {number} maxBucket The maximum bucket value in the histogram.
*/
+ recordInHistogram(histogram, bucket, maxBucket) {}
+}
+
+/** @implements {NativeLayer} */
+export class NativeLayerImpl {
+ // <if expr="chromeos">
+ /** @override */
+ getAccessToken() {
+ return sendWithPromise('getAccessToken');
+ }
+ // </if>
+
+ /** @override */
+ getInitialSettings() {
+ return sendWithPromise('getInitialSettings');
+ }
+
+ /** @override */
+ getPrinters(type) {
+ return sendWithPromise('getPrinters', type);
+ }
+
+ /** @override */
+ getPrinterCapabilities(destinationId, type) {
+ return sendWithPromise(
+ 'getPrinterCapabilities', destinationId,
+ destinationId === Destination.GooglePromotedId.SAVE_AS_PDF ?
+ PrinterType.PDF_PRINTER :
+ type);
+ }
+
+ // <if expr="chromeos">
+ /** @override */
+ getEulaUrl(destinationId) {
+ return sendWithPromise('getEulaUrl', destinationId);
+ }
+
+ /** @override */
+ grantExtensionPrinterAccess(provisionalDestinationId) {
+ return sendWithPromise(
+ 'grantExtensionPrinterAccess', provisionalDestinationId);
+ }
+
+ /** @override */
+ setupPrinter(printerId) {
+ return sendWithPromise('setupPrinter', printerId);
+ }
+ // </if>
+
+ /** @override */
+ getPreview(printTicket) {
+ return sendWithPromise('getPreview', printTicket);
+ }
+
+ /** @override */
+ openSettingsPrintPage() {
+ chrome.send('openPrinterSettings');
+ }
+
+ /** @override */
+ print(printTicket) {
+ return sendWithPromise('print', printTicket);
+ }
+
+ /** @override */
+ cancelPendingPrintRequest() {
+ chrome.send('cancelPendingPrintRequest');
+ }
+
+ /** @override */
+ saveAppState(appStateStr) {
+ chrome.send('saveAppState', [appStateStr]);
+ }
+
+ // <if expr="not chromeos and not is_win">
+ /** @override */
+ showSystemDialog() {
+ chrome.send('showSystemDialog');
+ }
+ // </if>
+
+ /** @override */
+ dialogClose(isCancel) {
+ if (isCancel) {
+ chrome.send('closePrintPreviewDialog');
+ }
+ chrome.send('dialogClose');
+ }
+
+ /** @override */
+ hidePreview() {
+ chrome.send('hidePreview');
+ }
+
+ /** @override */
+ signIn(addAccount) {
+ chrome.send('signIn', [addAccount]);
+ }
+
+ // <if expr="chromeos">
+ /** @override */
+ requestPrinterStatusUpdate(printerId) {
+ return sendWithPromise('requestPrinterStatus', printerId);
+ }
+ // </if>
+
+ /** @override */
recordInHistogram(histogram, bucket, maxBucket) {
chrome.send(
'metricsHandler:recordInHistogram', [histogram, bucket, maxBucket]);
}
}
-/** @private {?NativeLayer} */
-let currentInstance = null;
+addSingletonGetter(NativeLayerImpl);
diff --git a/chromium/chrome/browser/resources/print_preview/print_preview.html b/chromium/chrome/browser/resources/print_preview/print_preview.html
index 4aa26d79dbd..6a792ccc483 100644
--- a/chromium/chrome/browser/resources/print_preview/print_preview.html
+++ b/chromium/chrome/browser/resources/print_preview/print_preview.html
@@ -1,6 +1,5 @@
<!doctype html>
-<html dir="$i18n{textdirection}" lang="$i18n{language}" $i18n{a11yenhanced}
- class="loading">
+<html dir="$i18n{textdirection}" lang="$i18n{language}" class="loading">
<head>
<title>$i18n{title}</title>
<meta charset="utf-8">
diff --git a/chromium/chrome/browser/resources/print_preview/print_preview.js b/chromium/chrome/browser/resources/print_preview/print_preview.js
index 21658c88e7f..10d3ac4aae4 100644
--- a/chromium/chrome/browser/resources/print_preview/print_preview.js
+++ b/chromium/chrome/browser/resources/print_preview/print_preview.js
@@ -4,25 +4,30 @@
import './ui/app.js';
+export {PluralStringProxyImpl as PrintPreviewPluralStringProxyImpl} from 'chrome://resources/js/plural_string_proxy.js';
export {CloudPrintInterface, CloudPrintInterfaceEventType} from './cloud_print_interface.js';
export {CloudPrintInterfaceImpl} from './cloud_print_interface_impl.js';
-export {ColorMode, createDestinationKey, Destination, DestinationCertificateStatus, DestinationConnectionStatus, DestinationOrigin, DestinationType, makeRecentDestination} from './data/destination.js';
+export {ColorMode, createDestinationKey, Destination, DestinationCertificateStatus, DestinationConnectionStatus, DestinationOrigin, DestinationType, makeRecentDestination, RecentDestination} from './data/destination.js';
export {PrinterType} from './data/destination_match.js';
// <if expr="chromeos">
export {ColorModeRestriction, DuplexModeRestriction, PinModeRestriction} from './data/destination_policies.js';
+export {PrinterStatus, PrinterStatusReason, PrinterStatusSeverity} from './data/printer_status_cros.js';
+export {PrinterState} from './ui/printer_status_icon_cros.js';
// </if>
export {DestinationErrorType, DestinationStore} from './data/destination_store.js';
+export {PageLayoutInfo} from './data/document_info.js';
export {InvitationStore} from './data/invitation_store.js';
-export {CustomMarginsOrientation, Margins, MarginsType} from './data/margins.js';
+export {CustomMarginsOrientation, Margins, MarginsSetting, MarginsType} from './data/margins.js';
export {MeasurementSystem, MeasurementSystemUnitType} from './data/measurement_system.js';
export {DuplexMode, DuplexType, getInstance, whenReady} from './data/model.js';
export {ScalingType} from './data/scaling.js';
export {Size} from './data/size.js';
export {Error, State} from './data/state.js';
-export {BackgroundGraphicsModeRestriction, NativeLayer} from './native_layer.js';
+export {BackgroundGraphicsModeRestriction, CapabilitiesResponse, LocalDestinationInfo, NativeInitialSettings, NativeLayer, NativeLayerImpl, PrinterSetupResponse, ProvisionalDestinationInfo} from './native_layer.js';
export {getSelectDropdownBackground} from './print_preview_utils.js';
export {DEFAULT_MAX_COPIES} from './ui/copies_settings.js';
export {DestinationState} from './ui/destination_settings.js';
export {PluginProxy} from './ui/plugin_proxy.js';
export {PreviewAreaState} from './ui/preview_area.js';
export {SelectBehavior} from './ui/select_behavior.js';
+export {SelectOption} from './ui/settings_select.js';
diff --git a/chromium/chrome/browser/resources/print_preview/print_preview_pdf_resources.grd b/chromium/chrome/browser/resources/print_preview/print_preview_pdf_resources.grd
new file mode 100644
index 00000000000..d8483272925
--- /dev/null
+++ b/chromium/chrome/browser/resources/print_preview/print_preview_pdf_resources.grd
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<grit latest_public_release="0" current_release="1" output_all_resource_defines="false">
+ <outputs>
+ <output filename="grit/print_preview_pdf_resources.h" type="rc_header">
+ <emit emit_type='prepend'></emit>
+ </output>
+ <output filename="grit/print_preview_pdf_resources_map.cc"
+ type="resource_file_map_source" />
+ <output filename="grit/print_preview_pdf_resources_map.h"
+ type="resource_map_header" />
+ <output filename="print_preview_pdf_resources.pak" type="data_package" />
+ </outputs>
+ <release seq="1">
+ <includes>
+ <include name="IDR_PRINT_PREVIEW_PDF_INDEX_PP_HTML"
+ file="../pdf/index_pp.html"
+ type="BINDATA" />
+ <include name="IDR_PRINT_PREVIEW_PDF_PDF_VIEWER_PP_JS"
+ file="${root_gen_dir}/chrome/browser/resources/pdf/pdf_viewer_pp.js"
+ use_base_dir="false"
+ type="BINDATA" />
+ <include name="IDR_PRINT_PREVIEW_PDF_VIEWER_PAGE_INDICATOR_JS"
+ file="${root_gen_dir}/chrome/browser/resources/pdf/elements/viewer-page-indicator.js"
+ use_base_dir="false"
+ type="BINDATA" />
+ </includes>
+ </release>
+</grit>
diff --git a/chromium/chrome/browser/resources/print_preview/print_preview_resources.grd b/chromium/chrome/browser/resources/print_preview/print_preview_resources.grd
index 8f7cd3fe0b5..9bbd50d630f 100644
--- a/chromium/chrome/browser/resources/print_preview/print_preview_resources.grd
+++ b/chromium/chrome/browser/resources/print_preview/print_preview_resources.grd
@@ -49,6 +49,12 @@
<include name="IDR_PRINT_PREVIEW_UI_DESTINATION_SELECT_CROS_JS"
file="${root_gen_dir}/chrome/browser/resources/print_preview/ui/destination_select_cros.js"
use_base_dir="false" compress="false" type="BINDATA"/>
+ <include name="IDR_PRINT_PREVIEW_UI_PRINT_PREVIEW_DESTINATION_DROPDOWN_CROS_JS"
+ file="${root_gen_dir}/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.js"
+ use_base_dir="false" compress="false" type="BINDATA"/>
+ <include name="IDR_PRINT_PREVIEW_UI_PRINT_PREVIEW_PRINTER_STATUS_ICON_CROS_JS"
+ file="${root_gen_dir}/chrome/browser/resources/print_preview/ui/printer_status_icon_cros.js"
+ use_base_dir="false" compress="false" type="BINDATA"/>
</if>
<include name="IDR_PRINT_PREVIEW_UI_DESTINATION_SELECT_CSS_JS"
file="${root_gen_dir}/chrome/browser/resources/print_preview/ui/destination_select_css.js"
@@ -141,16 +147,6 @@
<include name="IDR_PRINT_PREVIEW_UI_ICONS_JS"
file="${root_gen_dir}/chrome/browser/resources/print_preview/ui/icons.js"
use_base_dir="false" compress="false" type="BINDATA"/>
- <include name="IDR_PRINT_PREVIEW_PDF_INDEX_PP_HTML"
- file="../pdf/index_pp.html"
- type="BINDATA" />
- <include name="IDR_PRINT_PREVIEW_PDF_MAIN_PP_JS"
- file="../pdf/main_pp.js"
- type="BINDATA" />
- <include name="IDR_PRINT_PREVIEW_PDF_VIEWER_PAGE_INDICATOR_JS"
- file="${root_gen_dir}/chrome/browser/resources/pdf/elements/viewer-page-indicator.js"
- use_base_dir="false"
- type="BINDATA" />
</includes>
<structures>
<structure name="IDR_PRINT_PREVIEW_PRINT_PREVIEW_HTML"
@@ -196,6 +192,10 @@
file="data/destination_policies.js"
compress="false"
type="chrome_html" />
+ <structure name="IDR_PRINT_PREVIEW_DATA_PRINTER_STATUS_CROS_JS"
+ file="data/printer_status_cros.js"
+ compress="false"
+ type="chrome_html" />
</if>
<structure name="IDR_PRINT_PREVIEW_DATA_DESTINATION_STORE_JS"
file="data/destination_store.js"
diff --git a/chromium/chrome/browser/resources/print_preview/print_preview_resources_vulcanized.grd b/chromium/chrome/browser/resources/print_preview/print_preview_resources_vulcanized.grd
index 0eecabc3c5d..1ac21ce8b10 100644
--- a/chromium/chrome/browser/resources/print_preview/print_preview_resources_vulcanized.grd
+++ b/chromium/chrome/browser/resources/print_preview/print_preview_resources_vulcanized.grd
@@ -15,23 +15,11 @@
<include name="IDR_PRINT_PREVIEW_PRINT_PREVIEW_HTML"
file="print_preview.html"
type="chrome_html"
- preprocess="true"
- compress="gzip" />
+ preprocess="true" />
<include name="IDR_PRINT_PREVIEW_PRINT_PREVIEW_ROLLUP_JS"
file="${root_gen_dir}\chrome\browser\resources\print_preview\print_preview.rollup.js"
use_base_dir="false"
preprocess="true"
- compress="gzip"
- type="BINDATA" />
- <include name="IDR_PRINT_PREVIEW_PDF_INDEX_PP_HTML"
- file="../pdf/index_pp.html"
- type="BINDATA" />
- <include name="IDR_PRINT_PREVIEW_PDF_MAIN_PP_JS"
- file="../pdf/main_pp.js"
- type="BINDATA" />
- <include name="IDR_PRINT_PREVIEW_PDF_VIEWER_PAGE_INDICATOR_JS"
- file="${root_gen_dir}/chrome/browser/resources/pdf/elements/viewer-page-indicator.js"
- use_base_dir="false"
type="BINDATA" />
</includes>
</release>
diff --git a/chromium/chrome/browser/resources/print_preview/ui/BUILD.gn b/chromium/chrome/browser/resources/print_preview/ui/BUILD.gn
index 860caec75e9..d95c0bb6565 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/BUILD.gn
+++ b/chromium/chrome/browser/resources/print_preview/ui/BUILD.gn
@@ -53,8 +53,10 @@ js_type_check("closure_compile_module") {
if (is_chromeos) {
deps += [
+ ":destination_dropdown_cros",
":destination_select_cros",
":pin_settings",
+ ":printer_status_icon_cros",
]
} else {
deps += [ ":destination_select" ]
@@ -117,6 +119,7 @@ js_library("button_strip") {
"../data:destination",
"../data:state",
"//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
+ "//ui/webui/resources/js:plural_string_proxy",
]
if (is_chromeos) {
@@ -131,6 +134,7 @@ js_library("header") {
"../data:state",
"//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
"//ui/webui/resources/js:load_time_data.m",
+ "//ui/webui/resources/js:plural_string_proxy",
]
}
@@ -160,9 +164,11 @@ js_library("destination_settings") {
if (is_chromeos) {
js_library("destination_select_cros") {
deps = [
+ ":destination_dropdown_cros",
":select_behavior",
"..:print_preview_utils",
"../data:destination",
+ "../data:printer_status_cros",
"//third_party/polymer/v3_0/components-chromium/iron-iconset-svg:iron-iconset-svg",
"//third_party/polymer/v3_0/components-chromium/iron-meta:iron-meta",
"//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
@@ -178,6 +184,22 @@ if (is_chromeos) {
"//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
]
}
+
+ js_library("destination_dropdown_cros") {
+ deps = [
+ ":printer_status_icon_cros",
+ "..:print_preview_utils",
+ "//third_party/polymer/v3_0/components-chromium/iron-dropdown:iron-dropdown",
+ "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
+ "//ui/webui/resources/cr_elements/cr_input:cr_input.m",
+ ]
+ }
+
+ js_library("printer_status_icon_cros") {
+ deps = [
+ "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
+ ]
+ }
} else {
js_library("destination_select") {
deps = [
@@ -544,8 +566,10 @@ html_to_js("web_components") {
]
if (is_chromeos) {
js_files += [
+ "destination_dropdown_cros.js",
"destination_select_cros.js",
"pin_settings.js",
+ "printer_status_icon_cros.js",
]
} else {
js_files += [ "destination_select.js" ]
diff --git a/chromium/chrome/browser/resources/print_preview/ui/app.js b/chromium/chrome/browser/resources/print_preview/ui/app.js
index 575afacd7aa..5c7b6601686 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/app.js
+++ b/chromium/chrome/browser/resources/print_preview/ui/app.js
@@ -26,7 +26,7 @@ import {DuplexMode, whenReady} from '../data/model.js';
import {PrintableArea} from '../data/printable_area.js';
import {Size} from '../data/size.js';
import {Error, State} from '../data/state.js';
-import {NativeInitialSettings, NativeLayer} from '../native_layer.js';
+import {NativeInitialSettings, NativeLayer, NativeLayerImpl} from '../native_layer.js';
import {DestinationState} from './destination_settings.js';
import {PreviewAreaState} from './preview_area.js';
@@ -168,7 +168,7 @@ Polymer({
/** @override */
attached() {
document.documentElement.classList.remove('loading');
- this.nativeLayer_ = NativeLayer.getInstance();
+ this.nativeLayer_ = NativeLayerImpl.getInstance();
this.addWebUIListener('print-failed', this.onPrintFailed_.bind(this));
this.addWebUIListener(
'print-preset-options', this.onPrintPresetOptions_.bind(this));
diff --git a/chromium/chrome/browser/resources/print_preview/ui/button_strip.js b/chromium/chrome/browser/resources/print_preview/ui/button_strip.js
index 28ea8d6232d..4624470278a 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/button_strip.js
+++ b/chromium/chrome/browser/resources/print_preview/ui/button_strip.js
@@ -8,6 +8,7 @@ import 'chrome://resources/cr_elements/shared_vars_css.m.js';
import '../strings.m.js';
import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
+import {PluralStringProxyImpl} from 'chrome://resources/js/plural_string_proxy.js';
import {IronA11yAnnouncer} from 'chrome://resources/polymer/v3_0/iron-a11y-announcer/iron-a11y-announcer.js';
import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
@@ -50,7 +51,6 @@ Polymer({
/** @private */
errorMessage_: {
type: String,
- computed: 'computeErrorMessage_(destination.id, maxSheets, sheetCount)',
observer: 'errorMessageChanged_',
},
// </if>
@@ -59,6 +59,9 @@ Polymer({
observers: [
'updatePrintButtonLabel_(destination.id)',
'updatePrintButtonEnabled_(state, destination.id, maxSheets, sheetCount)',
+ // <if expr="chromeos">
+ 'updateErrorMessage_(state, destination.id, maxSheets, sheetCount)',
+ // </if>
],
/** @private {!State} */
@@ -140,19 +143,17 @@ Polymer({
return this.sheetCount > 0 && this.printButtonDisabled_();
},
- /**
- * @return {string} Localized message to show as an error.
- * @private
- */
- computeErrorMessage_() {
+ /** @private */
+ updateErrorMessage_() {
if (!this.showSheetsError_()) {
- return '';
+ this.errorMessage_ = '';
+ return;
}
-
- const singularOrPlural = this.maxSheets > 1 ? 'Plural' : 'Singular';
- const label = loadTimeData.getString(`sheetsLimitLabel${singularOrPlural}`);
- return loadTimeData.getStringF(
- 'sheetsLimitErrorMessage', this.maxSheets.toLocaleString(), label);
+ PluralStringProxyImpl.getInstance()
+ .getPluralString('sheetsLimitErrorMessage', this.maxSheets)
+ .then(label => {
+ this.errorMessage_ = label;
+ });
},
/**
diff --git a/chromium/chrome/browser/resources/print_preview/ui/destination_dialog.js b/chromium/chrome/browser/resources/print_preview/ui/destination_dialog.js
index e0532e60acf..c3b9f5bbd2c 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/destination_dialog.js
+++ b/chromium/chrome/browser/resources/print_preview/ui/destination_dialog.js
@@ -33,7 +33,7 @@ import {DestinationStore} from '../data/destination_store.js';
import {Invitation} from '../data/invitation.js';
import {InvitationStore} from '../data/invitation_store.js';
import {Metrics, MetricsContext} from '../metrics.js';
-import {NativeLayer} from '../native_layer.js';
+import {NativeLayerImpl} from '../native_layer.js';
Polymer({
is: 'print-preview-destination-dialog',
@@ -129,12 +129,7 @@ Polymer({
this.$$('.promo-text').innerHTML =
this.i18nAdvanced('cloudPrintPromotion', {
substitutions: ['<a is="action-link" class="sign-in">', '</a>'],
- attrs: {
- 'is': (node, v) => v === 'action-link',
- 'class': (node, v) => v === 'sign-in',
- 'tabindex': (node, v) => v === '0',
- 'role': (node, v) => v === 'link',
- },
+ attrs: ['is', 'class', 'tabindex', 'role'],
});
},
@@ -340,7 +335,7 @@ Polymer({
/** @private */
onSignInClick_() {
this.metrics_.record(Metrics.DestinationSearchBucket.SIGNIN_TRIGGERED);
- NativeLayer.getInstance().signIn(false);
+ NativeLayerImpl.getInstance().signIn(false);
},
/** @private */
@@ -426,7 +421,7 @@ Polymer({
this.metrics_.record(Metrics.DestinationSearchBucket.ACCOUNT_CHANGED);
} else {
select.value = this.activeUser;
- NativeLayer.getInstance().signIn(true);
+ NativeLayerImpl.getInstance().signIn(true);
this.metrics_.record(
Metrics.DestinationSearchBucket.ADD_ACCOUNT_SELECTED);
}
@@ -463,6 +458,6 @@ Polymer({
/** @private */
onOpenSettingsPrintPage_() {
this.metrics_.record(Metrics.DestinationSearchBucket.MANAGE_BUTTON_CLICKED);
- NativeLayer.getInstance().openSettingsPrintPage();
+ NativeLayerImpl.getInstance().openSettingsPrintPage();
},
});
diff --git a/chromium/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.html b/chromium/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.html
new file mode 100644
index 00000000000..c20bcbae4a6
--- /dev/null
+++ b/chromium/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.html
@@ -0,0 +1,150 @@
+<style include="cr-shared-style cr-hidden-style md-select">
+ :host([opened_]) cr-input {
+ --cr-input-border-radius: 4px 4px 0 0;
+ }
+
+ iron-dropdown,
+ cr-input {
+ width: var(--md-select-width);
+ }
+
+ cr-input::part(input) {
+ opacity: 1;
+ padding-inline-end: 32px;
+ padding-inline-start: 8px;
+ text-overflow: clip;
+ }
+
+ iron-dropdown {
+ border: 0.5px solid rgba(0, 0, 0, 0.5);
+ max-height: 270px;
+ }
+
+ iron-dropdown [slot='dropdown-content'] {
+ background-color: white;
+ box-shadow: 0 2px 6px var(--google-grey-600);
+ min-width: var(--md-select-width);
+ padding: 8px 0;
+ }
+
+ #input-overlay {
+ border-radius: 4px;
+ height: 100%;
+ left: 0;
+ overflow: hidden;
+ pointer-events: none;
+ position: absolute;
+ top: 0;
+ width: 100%;
+ }
+
+ #dropdown-icon {
+ --iron-icon-height: 20px;
+ --iron-icon-width: 20px;
+ margin-top: -10px;
+ padding-inline-end: 6px;
+ position: absolute;
+ right: 0;
+ top: 50%;
+ }
+
+ :host-context([dir='rtl']) #dropdown-icon {
+ left: 0;
+ right: unset;
+ }
+
+ cr-input:focus-within #dropdown-icon {
+ --iron-icon-fill-color: var(--google-blue-600);
+ }
+
+ #input-box {
+ height: 100%;
+ left: 0;
+ pointer-events: none;
+ top: 0;
+ width: 100%;
+ }
+
+ #dropdown-box {
+ pointer-events: initial;
+ width: 100%;
+ }
+
+ .list-item {
+ background: none;
+ border: none;
+ box-sizing: border-box;
+ font: inherit;
+ min-height: 32px;
+ padding: 0 8px;
+ text-align: start;
+ width: 100%;
+ }
+
+ .list-item:focus {
+ outline: none;
+ }
+
+ .list-item[selected_] {
+ background-color: var(--google-blue-refresh-100);
+ }
+
+ .dot {
+ background-color: #bbb;
+ border-radius: 50%;
+ display: inline-block;
+ height: 10px;
+ width: 10px;
+ }
+
+ #pre-input-box,
+ .printer-display-name {
+ padding-inline-start: 8px;
+ }
+</style>
+<cr-input id="dropdownInput" on-keydown="onKeyDown_"
+ value="[[value.displayName]]" disabled="[[disabled]]" readonly>
+ <div id="pre-input-overlay" slot="inline-prefix">
+ <div id="pre-input-box">
+ <iron-icon icon="[[destinationIcon]]"></iron-icon>
+ </div>
+ </div>
+ <div id="input-overlay" slot="suffix">
+ <div id="input-box">
+ <iron-icon id="dropdown-icon" icon="cr:arrow-drop-down"></iron-icon>
+ </div>
+ <div id="dropdown-box">
+ <iron-dropdown horizontal-align="left" vertical-align="top"
+ vertical-offset="0" no-cancel-on-outside-click
+ no-cancel-on-esc-key>
+ <div slot="dropdown-content">
+ <template is="dom-repeat" items="[[itemList]]">
+ <button id="[[item.key]]" class="list-item" on-click="onSelect_"
+ tabindex="-1" value="[[item.key]]">
+ <printer-status-icon-cros background="white"
+ state$="[[computePrinterState_(item.printerStatusReason)]]">
+ </printer-status-icon-cros>
+ <span class="printer-display-name">[[item.displayName]]</span>
+ </button>
+ </template>
+ <button class="list-item" on-click="onSelect_" tabindex="-1"
+ value="[[pdfDestinationKey]]" hidden$="[[pdfPrinterDisabled]]">
+ $i18n{printToPDF}
+ </button>
+ <button class="list-item" on-click="onSelect_" tabindex="-1"
+ value="[[driveDestinationKey]]" hidden$="[[!driveDestinationKey]]">
+ $i18n{printToGoogleDrive}
+ </button>
+ <button class="list-item" on-click="onSelect_" tabindex="-1"
+ value="noDestinations" hidden$="[[!noDestinations]]">
+ $i18n{noDestinationsMessage}
+ </button>
+ <button class="list-item" on-click="onSelect_" tabindex="-1"
+ value="seeMore" aria-label$="[[i18n(seeMoreDestinationsLabel)]]">
+ $i18n{seeMore}
+ </button>
+ </div>
+ </iron-dropdown>
+ </div>
+ </div>
+</cr-input>
diff --git a/chromium/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.js b/chromium/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.js
new file mode 100644
index 00000000000..3d95796c331
--- /dev/null
+++ b/chromium/chrome/browser/resources/print_preview/ui/destination_dropdown_cros.js
@@ -0,0 +1,273 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'chrome://resources/cr_elements/cr_input/cr_input.m.js';
+import 'chrome://resources/cr_elements/hidden_style_css.m.js';
+import 'chrome://resources/cr_elements/md_select_css.m.js';
+import 'chrome://resources/cr_elements/shared_vars_css.m.js';
+// TODO(gavinwill): Remove iron-dropdown dependency https://crbug.com/1082587.
+import 'chrome://resources/polymer/v3_0/iron-dropdown/iron-dropdown.js';
+import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
+
+import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {Destination} from '../data/destination.js';
+import {PrinterStatusReason} from '../data/printer_status_cros.js';
+
+import {PrinterState} from './printer_status_icon_cros.js';
+
+Polymer({
+ is: 'print-preview-destination-dropdown-cros',
+
+ _template: html`{__html_template__}`,
+
+ properties: {
+ /** @type {!Destination} */
+ value: Object,
+
+ /** @type {!Array<!Destination>} */
+ itemList: {
+ type: Array,
+ observer: 'enqueueDropdownRefit_',
+ },
+
+ /** @type {boolean} */
+ disabled: {
+ type: Boolean,
+ value: false,
+ },
+
+ driveDestinationKey: String,
+
+ noDestinations: Boolean,
+
+ pdfPrinterDisabled: Boolean,
+
+ pdfDestinationKey: String,
+
+ destinationIcon: String,
+ },
+
+ listeners: {
+ 'mousemove': 'onMouseMove_',
+ },
+
+ /** @override */
+ attached() {
+ this.pointerDownListener_ = event => this.onPointerDown_(event);
+ document.addEventListener('pointerdown', this.pointerDownListener_);
+ },
+
+ /** @override */
+ detached() {
+ document.removeEventListener('pointerdown', this.pointerDownListener_);
+ },
+
+ /**
+ * Enqueues a task to refit the iron-dropdown if it is open.
+ * @private
+ */
+ enqueueDropdownRefit_() {
+ const dropdown = this.$$('iron-dropdown');
+ if (!this.dropdownRefitPending_ && dropdown.opened) {
+ this.dropdownRefitPending_ = true;
+ setTimeout(() => {
+ dropdown.refit();
+ this.dropdownRefitPending_ = false;
+ }, 0);
+ }
+ },
+
+ /** @private */
+ openDropdown_() {
+ if (this.disabled) {
+ return;
+ }
+
+ this.$$('iron-dropdown').open();
+ this.opened_ = true;
+ },
+
+ /** @private */
+ closeDropdown_() {
+ this.$$('iron-dropdown').close();
+ this.opened_ = false;
+
+ const selectedItem = this.findSelectedItem_();
+ if (selectedItem) {
+ selectedItem.removeAttribute('selected_');
+ }
+ },
+
+ /**
+ * @param {!Event} event
+ * @private
+ */
+ onMouseMove_(event) {
+ const item = event.composedPath().find(
+ elm => elm.classList && elm.classList.contains('list-item'));
+ if (!item) {
+ return;
+ }
+
+ // Select the item the mouse is hovering over. If the user uses the
+ // keyboard, the selection will shift. But once the user moves the mouse,
+ // selection should be updated based on the location of the mouse cursor.
+ const selectedItem = this.findSelectedItem_();
+ if (item === selectedItem) {
+ return;
+ }
+
+ if (selectedItem) {
+ selectedItem.removeAttribute('selected_');
+ }
+ item.setAttribute('selected_', '');
+ },
+
+ /**
+ * @param {!Event} event
+ * @private
+ */
+ onPointerDown_(event) {
+ const paths = event.composedPath();
+ const dropdown =
+ /** @type {!IronDropdownElement} */ (this.$$('iron-dropdown'));
+ const dropdownInput =
+ /** @type {!CrInputElement} */ (this.$$('#dropdownInput'));
+
+ // Exit if path includes |dropdown| because event will be handled by
+ // onSelect_.
+ if (paths.includes(dropdown)) {
+ return;
+ }
+
+ if (!paths.includes(dropdownInput) || dropdown.opened) {
+ this.closeDropdown_();
+ return;
+ }
+
+ this.openDropdown_();
+ },
+
+ /** @private */
+ onSelect_() {
+ const selectedItem = this.findSelectedItem_();
+ this.closeDropdown_();
+ this.fire('dropdown-value-selected', selectedItem);
+ },
+
+ /**
+ * @param {!Event} event
+ * @private
+ */
+ onKeyDown_(event) {
+ event.stopPropagation();
+ const dropdown = this.$$('iron-dropdown');
+ switch (event.code) {
+ case 'Tab':
+ this.closeDropdown_();
+ break;
+ case 'ArrowUp':
+ case 'ArrowDown': {
+ const items = dropdown.getElementsByClassName('list-item');
+ if (items.length === 0) {
+ break;
+ }
+ this.updateSelected_(event.code === 'ArrowDown');
+ break;
+ }
+ case 'Enter': {
+ if (dropdown.opened) {
+ this.onSelect_();
+ break;
+ }
+ this.openDropdown_();
+ break;
+ }
+ case 'Escape': {
+ if (dropdown.opened) {
+ this.closeDropdown_();
+ event.preventDefault();
+ }
+ break;
+ }
+ }
+ },
+
+ /**
+ * Updates the currently selected element based on keyboard up/down movement.
+ * @param {boolean} moveDown
+ * @private
+ */
+ updateSelected_(moveDown) {
+ const items = this.getButtonListFromDropdown_();
+ const numItems = items.length;
+ if (numItems === 0) {
+ return;
+ }
+
+ let nextIndex = 0;
+ const currentIndex = this.findSelectedItemIndex_();
+ if (currentIndex === -1) {
+ nextIndex = moveDown ? 0 : numItems - 1;
+ } else {
+ const delta = moveDown ? 1 : -1;
+ nextIndex = (numItems + currentIndex + delta) % numItems;
+ items[currentIndex].removeAttribute('selected_');
+ }
+ items[nextIndex].setAttribute('selected_', '');
+ // The newly selected item might not be visible because the dropdown needs
+ // to be scrolled. So scroll the dropdown if necessary.
+ items[nextIndex].scrollIntoViewIfNeeded();
+ },
+
+ /**
+ * Finds the currently selected dropdown item.
+ * @return {Element|undefined} Currently selected dropdown item, or undefined
+ * if no item is selected.
+ * @private
+ */
+ findSelectedItem_() {
+ const items = this.getButtonListFromDropdown_();
+ return items.find(item => item.hasAttribute('selected_'));
+ },
+
+ /**
+ * Finds the index of currently selected dropdown item.
+ * @return {number} Index of the currently selected dropdown item, or -1 if
+ * no item is selected.
+ * @private
+ */
+ findSelectedItemIndex_() {
+ const items = this.getButtonListFromDropdown_();
+ return items.findIndex(item => item.hasAttribute('selected_'));
+ },
+
+ /**
+ * Returns list of all the visible items in the dropdown.
+ * @return {!Array<!Element>}
+ * @private
+ */
+ getButtonListFromDropdown_() {
+ const dropdown = this.$$('iron-dropdown');
+ return Array.from(dropdown.getElementsByClassName('list-item'))
+ .filter(item => !item.hidden);
+ },
+
+ /**
+ * @param {?PrinterStatusReason} printerStatusReason
+ * @return {number}
+ * @private
+ */
+ computePrinterState_(printerStatusReason) {
+ if (!printerStatusReason ||
+ printerStatusReason === PrinterStatusReason.UNKNOWN_REASON) {
+ return PrinterState.UNKNOWN;
+ }
+ if (printerStatusReason === PrinterStatusReason.NO_ERROR) {
+ return PrinterState.GOOD;
+ }
+ return PrinterState.ERROR;
+ },
+});
diff --git a/chromium/chrome/browser/resources/print_preview/ui/destination_select_cros.html b/chromium/chrome/browser/resources/print_preview/ui/destination_select_cros.html
index 2d8d0b8d28f..9ef6b0878c1 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/destination_select_cros.html
+++ b/chromium/chrome/browser/resources/print_preview/ui/destination_select_cros.html
@@ -7,8 +7,8 @@
<div class="throbber"></div>
</div>
<template is="dom-if" if="[[!printerStatusFlagEnabled_]]">
- <select class="md-select" aria-label$="[[i18n(destinationLabel)]]"
- hidden$="[[!loaded]]"
+ <select id="dropdown" class="md-select"
+ aria-label$="[[i18n(destinationLabel)]]" hidden$="[[!loaded]]"
style="background-image:[[backgroundImages_]];"
disabled$="[[disabled]]"
value="{{selectedValue::change}}">
@@ -33,7 +33,16 @@
</select>
</template>
<template is="dom-if" if="[[printerStatusFlagEnabled_]]">
- <div>print-preview-destination-select-cros</div>
+ <print-preview-destination-dropdown-cros id="dropdown"
+ value="[[destination]]" hidden$="[[!loaded]]"
+ item-list="[[recentDestinationList]]"
+ pdf-destination-key="[[pdfDestinationKey_]]"
+ drive-destination-key="[[driveDestinationKey]]"
+ no-destinations="[[noDestinations]]"
+ pdf-printer-disabled="[[pdfPrinterDisabled]]"
+ destination-icon="[[destinationIcon_]]" disabled="[[disabled]]"
+ on-dropdown-value-selected="onDropdownValueSelected_">
+ </print-preview-destination-dropdown-cros>
</template>
</div>
</print-preview-settings-section>
diff --git a/chromium/chrome/browser/resources/print_preview/ui/destination_select_cros.js b/chromium/chrome/browser/resources/print_preview/ui/destination_select_cros.js
index f76ac017631..9eab3a242b4 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/destination_select_cros.js
+++ b/chromium/chrome/browser/resources/print_preview/ui/destination_select_cros.js
@@ -7,22 +7,46 @@ import 'chrome://resources/cr_elements/shared_vars_css.m.js';
import 'chrome://resources/cr_elements/md_select_css.m.js';
import 'chrome://resources/js/util.m.js';
import 'chrome://resources/polymer/v3_0/iron-iconset-svg/iron-iconset-svg.js';
+import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
import 'chrome://resources/polymer/v3_0/iron-meta/iron-meta.js';
+import './destination_dropdown_cros.js';
import './destination_select_css.js';
import './icons.js';
import './print_preview_shared_css.js';
import './throbber_css.js';
import '../strings.m.js';
+import {assert} from 'chrome://resources/js/assert.m.js';
import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
import {Base, html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-import {Destination, DestinationOrigin, PDF_DESTINATION_KEY, RecentDestination} from '../data/destination.js';
+import {CloudOrigins, Destination, DestinationOrigin, PDF_DESTINATION_KEY, RecentDestination} from '../data/destination.js';
+import {PrinterStatus, PrinterStatusReason, PrinterStatusSeverity} from '../data/printer_status_cros.js';
+import {NativeLayer, NativeLayerImpl} from '../native_layer.js';
import {getSelectDropdownBackground} from '../print_preview_utils.js';
import {SelectBehavior} from './select_behavior.js';
+/** @const {!Map<!PrinterStatusReason, string>} */
+const ERROR_STRING_KEY_MAP = new Map([
+ [PrinterStatusReason.CONNECTING_TO_DEVICE, 'printerStatusConnectingToDevice'],
+ [PrinterStatusReason.DEVICE_ERROR, 'printerStatusDeviceError'],
+ [PrinterStatusReason.DOOR_OPEN, 'printerStatusDoorOpen'],
+ [PrinterStatusReason.LOW_ON_INK, 'printerStatusLowOnInk'],
+ [PrinterStatusReason.LOW_ON_PAPER, 'printerStatusLowOnPaper'],
+ [PrinterStatusReason.OUT_OF_INK, 'printerStatusOutOfInk'],
+ [PrinterStatusReason.OUT_OF_PAPER, 'printerStatusOutOfPaper'],
+ [PrinterStatusReason.OUTPUT_ALMOST_FULL, 'printerStatusOutputAlmostFull'],
+ [PrinterStatusReason.OUTPUT_FULL, 'printerStatusOutputFull'],
+ [PrinterStatusReason.PAPER_JAM, 'printerStatusPaperJam'],
+ [PrinterStatusReason.PAUSED, 'printerStatusPaused'],
+ [PrinterStatusReason.PRINTER_QUEUE_FULL, 'printerStatusPrinterQueueFull'],
+ [PrinterStatusReason.PRINTER_UNREACHABLE, 'printerStatusPrinterUnreachable'],
+ [PrinterStatusReason.STOPPED, 'printerStatusStopped'],
+ [PrinterStatusReason.TRAY_MISSING, 'printerStatusTrayMissing'],
+]);
+
Polymer({
is: 'print-preview-destination-select-cros',
@@ -36,7 +60,11 @@ Polymer({
dark: Boolean,
/** @type {!Destination} */
- destination: Object,
+ destination: {
+ type: Object,
+ observer: 'updateStatusText_',
+ },
+
disabled: Boolean,
@@ -49,7 +77,10 @@ Polymer({
pdfPrinterDisabled: Boolean,
/** @type {!Array<!Destination>} */
- recentDestinationList: Array,
+ recentDestinationList: {
+ type: Array,
+ observer: 'onRecentDestinationListChanged_',
+ },
/** @private {string} */
pdfDestinationKey_: {
@@ -57,17 +88,20 @@ Polymer({
value: PDF_DESTINATION_KEY,
},
+ /** @private */
+ statusText_: String,
+
/** @private {string} */
- statusText_: {
+ backgroundImages_: {
type: String,
- computed: 'computeStatusText_(destination)',
+ computed:
+ 'computeBackgroundImages_(destinationIcon_, dark, noDestinations)',
},
/** @private {string} */
- backgroundImages_: {
+ destinationIcon_: {
type: String,
- computed:
- 'computeBackgroundImages_(selectedValue, destination, noDestinations, dark)',
+ computed: 'computeDestinationIcon_(selectedValue, destination)',
},
/** @private */
@@ -78,14 +112,32 @@ Polymer({
},
readOnly: true,
},
+
+ /**
+ * The key for this map is a destination.id and the value is a
+ * destination.key. This map is needed to track which destinations have had
+ * statuses requested while also giving quick look up of destination id to
+ * the corresponding destination key.
+ * @private {!Map<string, string>}
+ */
+ statusRequestedMap_: Map,
},
/** @private {!IronMetaElement} */
meta_: /** @type {!IronMetaElement} */ (
Base.create('iron-meta', {type: 'iconset'})),
+ /** @override */
+ attached() {
+ if (!this.printerStatusFlagEnabled_) {
+ return;
+ }
+
+ this.statusRequestedMap_ = new Map();
+ },
+
focus() {
- this.$$('.md-select').focus();
+ this.$$('#dropdown').focus();
},
/** Sets the select to the current value of |destination|. */
@@ -100,7 +152,7 @@ Polymer({
* @return {string} The iconset and icon for the current selection.
* @private
*/
- getDestinationIcon_() {
+ computeDestinationIcon_() {
if (!this.selectedValue) {
return '';
}
@@ -140,8 +192,7 @@ Polymer({
* @private
*/
computeBackgroundImages_() {
- const icon = this.getDestinationIcon_();
- if (!icon) {
+ if (!this.destinationIcon_) {
return '';
}
@@ -149,7 +200,7 @@ Polymer({
if (this.noDestinations) {
iconSetAndIcon = ['cr', 'error'];
}
- iconSetAndIcon = iconSetAndIcon || icon.split(':');
+ iconSetAndIcon = iconSetAndIcon || this.destinationIcon_.split(':');
const iconset = /** @type {!IronIconsetSvgElement} */ (
this.meta_.byKey(iconSetAndIcon[0]));
return getSelectDropdownBackground(iconset, iconSetAndIcon[1], this);
@@ -160,17 +211,179 @@ Polymer({
},
/**
- * @return {string} The connection status text to display.
+ * @param {!Event} e
* @private
*/
- computeStatusText_() {
+ onDropdownValueSelected_(e) {
+ assert(this.printerStatusFlagEnabled_);
+
+ const selectedItem = e.detail;
+ if (!selectedItem || selectedItem.value === this.destination.key) {
+ return;
+ }
+
+ this.fire('selected-option-change', selectedItem.value);
+ },
+
+ /**
+ * Send a printer status request for any new destination in the dropdown.
+ * @private
+ */
+ onRecentDestinationListChanged_() {
+ if (!this.printerStatusFlagEnabled_) {
+ return;
+ }
+
+ for (const destination of this.recentDestinationList) {
+ if (destination.origin !== DestinationOrigin.CROS ||
+ this.statusRequestedMap_.has(destination.id)) {
+ continue;
+ }
+
+ NativeLayerImpl.getInstance()
+ .requestPrinterStatusUpdate(destination.id)
+ .then(status => this.onPrinterStatusReceived_(status));
+ this.statusRequestedMap_.set(destination.id, destination.key);
+ }
+ },
+
+ /**
+ * Check if the printer in |printerStatus| is currently in the dropdown.
+ * Update its status icon if it's present.
+ * @param {!PrinterStatus} printerStatus
+ * @private
+ */
+ onPrinterStatusReceived_(printerStatus) {
+ assert(this.printerStatusFlagEnabled_);
+ if (!printerStatus.printerId) {
+ return;
+ }
+
+ const destinationKey =
+ this.statusRequestedMap_.get(printerStatus.printerId);
+ if (!destinationKey) {
+ return;
+ }
+
+ const indexFound = this.recentDestinationList.findIndex(destination => {
+ return destination.id === printerStatus.printerId &&
+ destination.origin === DestinationOrigin.CROS;
+ });
+ if (indexFound === -1) {
+ return;
+ }
+
+ const statusReason = this.getStatusReasonFromPrinterStatus_(printerStatus);
+ if (!statusReason) {
+ return;
+ }
+
+
+ this.recentDestinationList[indexFound].printerStatusReason = statusReason;
+ // Set the new printer status reason then use notifyPath to trigger the
+ // dropdown printer status icons to recalculate their badge color.
+ this.notifyPath(`recentDestinationList.${indexFound}.printerStatusReason`);
+
+ // Update the status text if this printer status is for the
+ // currently selected printer.
+ if (this.destination && this.destination.key === destinationKey) {
+ this.updateStatusText_();
+ }
+ },
+
+ /**
+ * A |printerStatus| can have multiple status reasons so this function's
+ * responsibility is to determine which status reason is most relevant to
+ * surface to the user. Any status reason with a severity of WARNING or ERROR
+ * will get highest precedence since this usually means the printer is in a
+ * bad state. NO_ERROR status reason is the next highest precedence so the
+ * printer can be shown as available whenever possible.
+ * @param {!PrinterStatus} printerStatus
+ * @return {!PrinterStatusReason} Status reason extracted from
+ * |printerStatus|.
+ * @private
+ */
+ getStatusReasonFromPrinterStatus_(printerStatus) {
+ assert(this.printerStatusFlagEnabled_);
+
+ if (!printerStatus.printerId) {
+ return PrinterStatusReason.UNKNOWN_REASON;
+ }
+
+ let seenNoErrorReason = false;
+ for (const statusReason of printerStatus.statusReasons) {
+ const reason = statusReason.reason;
+ const severity = statusReason.severity;
+
+ if (reason !== PrinterStatusReason.UNKNOWN_REASON &&
+ (severity === PrinterStatusSeverity.WARNING ||
+ severity === PrinterStatusSeverity.ERROR)) {
+ return reason;
+ }
+
+ if (reason === PrinterStatusReason.NO_ERROR) {
+ seenNoErrorReason = true;
+ }
+ }
+ return seenNoErrorReason ? PrinterStatusReason.NO_ERROR :
+ PrinterStatusReason.UNKNOWN_REASON;
+ },
+
+ /**
+ * Check the current destination for an error status then set |statusText_|
+ * appropriately. If no error status exists, unset |statusText_|.
+ * @private
+ */
+ updateStatusText_: function() {
// |destination| can be either undefined, or null here.
if (!this.destination) {
- return '';
+ this.statusText_ = '';
+ return;
+ }
+
+ // Cloudprint destinations contain their own status text.
+ if (CloudOrigins.some(origin => origin === this.destination.origin)) {
+ this.statusText_ = this.destination.shouldShowInvalidCertificateError ?
+ this.i18n('noLongerSupportedFragment') :
+ this.destination.connectionStatusText;
+ return;
}
- return this.destination.shouldShowInvalidCertificateError ?
- this.i18n('noLongerSupportedFragment') :
- this.destination.connectionStatusText;
+ // Only when the flag is enabled do we need to fetch a local printer status
+ // error string.
+ if (!this.printerStatusFlagEnabled_) {
+ this.statusText_ = '';
+ return;
+ }
+
+ const printerStatusReason = this.destination.printerStatusReason;
+ if (!printerStatusReason ||
+ printerStatusReason === PrinterStatusReason.NO_ERROR ||
+ printerStatusReason === PrinterStatusReason.UNKNOWN_REASON) {
+ this.statusText_ = '';
+ return;
+ }
+
+ this.statusText_ = this.getErrorString_(printerStatusReason);
+ },
+
+ /**
+ * @param {!PrinterStatusReason} printerStatusReason
+ * @return {!string}
+ * @private
+ */
+ getErrorString_: function(printerStatusReason) {
+ const errorTextKey = ERROR_STRING_KEY_MAP.get(printerStatusReason);
+ return errorTextKey ?
+ this.i18n(errorTextKey, this.destination.displayName) :
+ '';
+ },
+
+ /**
+ * @return {!boolean}
+ * @private
+ */
+ shouldShowStatus_: function() {
+ return !!this.statusText_;
},
});
diff --git a/chromium/chrome/browser/resources/print_preview/ui/destination_settings.js b/chromium/chrome/browser/resources/print_preview/ui/destination_settings.js
index f7259dbcfd0..4dce6653ae7 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/destination_settings.js
+++ b/chromium/chrome/browser/resources/print_preview/ui/destination_settings.js
@@ -66,7 +66,7 @@ Polymer({
value: null,
},
- /** @private {!DestinationState} */
+ /** @type {!DestinationState} */
destinationState: {
type: Number,
notify: true,
@@ -527,6 +527,11 @@ Polymer({
});
},
+ /** @return {!DestinationStore} */
+ getDestinationStoreForTest() {
+ return assert(this.destinationStore_);
+ },
+
// <if expr="chromeos">
/**
* @param {!CustomEvent<string>} e Event containing the current destination's
diff --git a/chromium/chrome/browser/resources/print_preview/ui/header.js b/chromium/chrome/browser/resources/print_preview/ui/header.js
index 3848934ecb3..e441b03788d 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/header.js
+++ b/chromium/chrome/browser/resources/print_preview/ui/header.js
@@ -9,6 +9,7 @@ import './print_preview_vars_css.js';
import '../strings.m.js';
import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
+import {PluralStringProxyImpl} from 'chrome://resources/js/plural_string_proxy.js';
import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
import {Destination} from '../data/destination.js';
@@ -40,12 +41,13 @@ Polymer({
sheetCount: Number,
/** @private {?string} */
- summary_: {
- type: String,
- computed: 'computeSummary_(sheetCount, state, destination.id)',
- },
+ summary_: String,
},
+ observers: [
+ 'updateSummary_(sheetCount, state, destination.id)',
+ ],
+
/**
* @return {boolean}
* @private
@@ -56,21 +58,22 @@ Polymer({
this.destination.id === Destination.GooglePromotedId.DOCS);
},
- /**
- * @return {?string}
- * @private
- */
- computeSummary_() {
+ /** @private */
+ updateSummary_() {
switch (this.state) {
case (State.PRINTING):
- return loadTimeData.getString(
+ this.summary_ = loadTimeData.getString(
this.isPdfOrDrive_() ? 'saving' : 'printing');
+ break;
case (State.READY):
- return this.getSheetsSummary_();
+ this.updateSheetsSummary_();
+ break;
case (State.FATAL_ERROR):
- return this.getErrorMessage_();
+ this.summary_ = this.getErrorMessage_();
+ break;
default:
- return null;
+ this.summary_ = null;
+ break;
}
},
@@ -89,21 +92,19 @@ Polymer({
}
},
- /**
- * @return {string}
- * @private
- */
- getSheetsSummary_() {
+ /** @private */
+ updateSheetsSummary_() {
if (this.sheetCount === 0) {
- return '';
+ this.summary_ = '';
+ return;
}
- const pageOrSheets = this.isPdfOrDrive_() ? 'Page' : 'Sheets';
- const singularOrPlural = this.sheetCount > 1 ? 'Plural' : 'Singular';
- const label = loadTimeData.getString(
- `printPreview${pageOrSheets}Label${singularOrPlural}`);
- return loadTimeData.getStringF(
- 'printPreviewSummaryFormatShort', this.sheetCount.toLocaleString(),
- label);
+ const pageOrSheet = this.isPdfOrDrive_() ? 'Page' : 'Sheet';
+ PluralStringProxyImpl.getInstance()
+ .getPluralString(
+ `printPreview${pageOrSheet}SummaryLabel`, this.sheetCount)
+ .then(label => {
+ this.summary_ = label;
+ });
},
});
diff --git a/chromium/chrome/browser/resources/print_preview/ui/link_container.html b/chromium/chrome/browser/resources/print_preview/ui/link_container.html
index 6ada90e22fa..9c483864f6c 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/link_container.html
+++ b/chromium/chrome/browser/resources/print_preview/ui/link_container.html
@@ -42,7 +42,7 @@
}
.link:not([actionable]) .label {
- @apply --print-preview-disabled-label;
+ opacity: var(--cr-disabled-opacity);
}
</style>
<div class="link" id="systemDialogLink"
diff --git a/chromium/chrome/browser/resources/print_preview/ui/more_settings.html b/chromium/chrome/browser/resources/print_preview/ui/more_settings.html
index d63ce664e66..13c6d2c7678 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/more_settings.html
+++ b/chromium/chrome/browser/resources/print_preview/ui/more_settings.html
@@ -33,7 +33,7 @@
}
:host([disabled]) #label {
- @apply --print-preview-disabled-label;
+ opacity: var(--cr-disabled-opacity);
}
</style>
<div on-click="toggleExpandButton_" actionable>
diff --git a/chromium/chrome/browser/resources/print_preview/ui/preview_area.js b/chromium/chrome/browser/resources/print_preview/ui/preview_area.js
index e75d9bffbf7..feb0ebf3849 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/preview_area.js
+++ b/chromium/chrome/browser/resources/print_preview/ui/preview_area.js
@@ -25,7 +25,7 @@ import {PrintableArea} from '../data/printable_area.js';
import {ScalingType} from '../data/scaling.js';
import {Size} from '../data/size.js';
import {Error, State} from '../data/state.js';
-import {NativeLayer} from '../native_layer.js';
+import {NativeLayer, NativeLayerImpl} from '../native_layer.js';
import {areRangesEqual} from '../print_preview_utils.js';
import {MARGIN_KEY_MAP} from './margin_control_container.js';
@@ -140,7 +140,7 @@ Polymer({
/** @override */
attached() {
- this.nativeLayer_ = NativeLayer.getInstance();
+ this.nativeLayer_ = NativeLayerImpl.getInstance();
this.addWebUIListener(
'page-preview-ready', this.onPagePreviewReady_.bind(this));
diff --git a/chromium/chrome/browser/resources/print_preview/ui/print_preview_search_box.html b/chromium/chrome/browser/resources/print_preview/ui/print_preview_search_box.html
index 816b95996fe..6ecd94cd733 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/print_preview_search_box.html
+++ b/chromium/chrome/browser/resources/print_preview/ui/print_preview_search_box.html
@@ -50,7 +50,7 @@
on-search="onSearchTermSearch" on-input="onSearchTermInput"
aria-label$="[[label]]" placeholder="[[label]]"
autofocus="[[autofocus]]" spellcheck="false">
- <div slot="prefix" id="icon" class="cr-icon icon-search" alt=""></div>
+ <div slot="inline-prefix" id="icon" class="cr-icon icon-search" alt=""></div>
<cr-icon-button id="clearSearch" class="icon-cancel"
hidden$="[[!hasSearchText]]" slot="suffix" on-click="onClearClick_"
title="[[clearLabel]]">
diff --git a/chromium/chrome/browser/resources/print_preview/ui/print_preview_vars_css.html b/chromium/chrome/browser/resources/print_preview/ui/print_preview_vars_css.html
index d476823e7ec..2208774d52e 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/print_preview_vars_css.html
+++ b/chromium/chrome/browser/resources/print_preview/ui/print_preview_vars_css.html
@@ -8,10 +8,6 @@
--print-preview-settings-border: 1px solid var(--google-grey-200);
--print-preview-dialog-margin: 34px;
- --print-preview-disabled-label: {
- color: var(--paper-grey-600);
- opacity: .65;
- }
--cr-form-field-label-height: initial;
--cr-form-field-label-line-height: .75rem;
--destination-item-height: 32px;
diff --git a/chromium/chrome/browser/resources/print_preview/ui/printer_status_icon_cros.html b/chromium/chrome/browser/resources/print_preview/ui/printer_status_icon_cros.html
new file mode 100644
index 00000000000..450956a6557
--- /dev/null
+++ b/chromium/chrome/browser/resources/print_preview/ui/printer_status_icon_cros.html
@@ -0,0 +1,67 @@
+<style include="cr-shared-style">
+ div {
+ display: inline;
+ position: relative;
+ }
+
+ .badge {
+ border-radius: 50%;
+ display: inline-block;
+ position: absolute;
+ --status-badge-radius: 8px;
+ --background-badge-radius: 12px;
+ --background-badge-left: 12px;
+ --background-badge-top: 6px;
+ }
+
+ :host-context([dir='rtl']) .badge {
+ --background-badge-left: -4px;
+ }
+
+ #status-badge {
+ height: var(--status-badge-radius);
+ left: calc(var(--background-badge-left) + (var(--background-badge-radius) - var(--status-badge-radius))/2);
+ top: calc(var(--background-badge-top) + (var(--background-badge-radius) - var(--status-badge-radius))/2);
+ width: var(--status-badge-radius);
+ }
+
+ :host-context([state='0']) #status-badge {
+ background-color: var(--google-green-700);
+ }
+
+ :host-context([state='1']) #status-badge {
+ background-color: var(--google-red-600);
+ }
+
+ :host-context([state='2']) #status-badge {
+ background-color: var(--google-grey-500);
+ }
+
+ :host-context([dir='rtl']) #status-badge {
+ right: calc(var(--background-badge-left) + (var(--background-badge-radius) - var(--status-badge-radius))/2);
+ }
+
+ #background-badge {
+ height: var(--background-badge-radius);
+ left: var(--background-badge-left);
+ top: var(--background-badge-top);
+ width: var(--background-badge-radius);
+ }
+
+ :host-context([background='grey']) #background-badge {
+ background-color: var(--google-grey-refresh-100);
+ }
+
+ :host-context([background='white']) #background-badge {
+ background-color: white;
+ }
+
+ :host-context([dir='rtl']) #background-badge {
+ right: var(--background-badge-left);
+ }
+</style>
+<div>
+ <iron-icon icon="print-preview:print"></iron-icon>
+ <span id="background-badge" class="badge"></span>
+ <span id="status-badge" class="badge"></span>
+</div>
diff --git a/chromium/chrome/browser/resources/print_preview/ui/printer_status_icon_cros.js b/chromium/chrome/browser/resources/print_preview/ui/printer_status_icon_cros.js
new file mode 100644
index 00000000000..3ae2dc8a7de
--- /dev/null
+++ b/chromium/chrome/browser/resources/print_preview/ui/printer_status_icon_cros.js
@@ -0,0 +1,40 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'chrome://resources/cr_elements/shared_vars_css.m.js';
+import './icons.js';
+
+import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+/**
+ * Enumeration giving a local Chrome OS printer 3 different state possibilities
+ * depending on its current status.
+ * @enum {number}
+ */
+export const PrinterState = {
+ GOOD: 0,
+ ERROR: 1,
+ UNKNOWN: 2,
+};
+
+Polymer({
+ is: 'printer-status-icon-cros',
+
+ properties: {
+ /** Determines color of the background badge. */
+ background: String,
+
+ /**
+ * State of the associated printer. Determines color of the status badge.
+ * @type {!PrinterState}
+ */
+ state: {
+ type: Number,
+ reflectToAttribute: true,
+ }
+ },
+
+ _template: html`{__html_template__}`,
+
+});
diff --git a/chromium/chrome/browser/resources/print_preview/ui/select_behavior.js b/chromium/chrome/browser/resources/print_preview/ui/select_behavior.js
index 4e21bb4d903..fbc6df96b58 100644
--- a/chromium/chrome/browser/resources/print_preview/ui/select_behavior.js
+++ b/chromium/chrome/browser/resources/print_preview/ui/select_behavior.js
@@ -31,10 +31,11 @@ export const SelectBehavior = {
}
this.debounce('select-change', () => {
- this.onProcessSelectChange(this.selectedValue);
-
- // For testing only
- this.fire('process-select-change');
+ if (this.isConnected) {
+ this.onProcessSelectChange(this.selectedValue);
+ // For testing only
+ this.fire('process-select-change');
+ }
}, 100);
},