diff options
Diffstat (limited to 'chromium/chrome/browser/resources/print_preview')
67 files changed, 2245 insertions, 956 deletions
diff --git a/chromium/chrome/browser/resources/print_preview/BUILD.gn b/chromium/chrome/browser/resources/print_preview/BUILD.gn index 0454c79bae6..e36e45667c0 100644 --- a/chromium/chrome/browser/resources/print_preview/BUILD.gn +++ b/chromium/chrome/browser/resources/print_preview/BUILD.gn @@ -1,46 +1,206 @@ +# Copyright 2018 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("//third_party/closure_compiler/compile_js.gni") import("../optimize_webui.gni") import("//tools/grit/grit_rule.gni") import("//chrome/common/features.gni") -print_preview_pak_file = "print_preview_resources.pak" -unpak_folder = "print_preview_resources.unpak" +if (optimize_webui) { + print_preview_pak_file = "print_preview_resources.pak" + unpak_folder = "print_preview_resources.unpak" + + optimize_webui("build") { + host = "print" + html_in_files = [ "print_preview_new.html" ] + html_out_files = [ "vulcanized.html" ] + insert_in_head = "<base href=\"chrome://print\">" + input = rebase_path("$target_gen_dir/$unpak_folder", root_build_dir) + js_out_files = [ "crisper.js" ] + + excludes = [ "pdf/pdf_scripting_api.js" ] + + deps = [ + ":unpak", + ] + } + + unpak("unpak") { + pak_file = print_preview_pak_file + out_folder = unpak_folder + + deps = [ + ":flattened_resources", + ] + } + + grit("flattened_resources") { + source = "print_preview_resources.grd" -optimize_webui("build") { - host = "print" - html_in_files = [ "print_preview_new.html" ] - html_out_files = [ "vulcanized.html" ] - insert_in_head = "<base href=\"chrome://print\">" - input = rebase_path("$target_gen_dir/$unpak_folder", root_build_dir) - js_out_files = [ "crisper.js" ] + # The .grd contains references to generated files. + source_is_generated = true - excludes = [ "pdf/pdf_scripting_api.js" ] + defines = chrome_grit_defines + outputs = [ + "grit/print_preview_resources.h", + "grit/print_preview_resources_map.cc", + "grit/print_preview_resources_map.h", + print_preview_pak_file, + ] + output_dir = "$root_gen_dir/chrome/browser/resources/print_preview" + } +} + +group("closure_compile") { + deps = [ + ":print_preview_resources", + "data:closure_compile", + "new:closure_compile", + ] +} + +js_type_check("print_preview_resources") { + deps = [ + ":cloud_print_interface", + ":metrics", + ":native_layer", + ":print_preview", + ":print_preview_utils", + ] +} +js_library("print_preview") { deps = [ - ":unpak", + "../pdf:pdf_scripting_api", + "//ui/webui/resources/js:cr", + "//ui/webui/resources/js:event_tracker", + "//ui/webui/resources/js:load_time_data", + "//ui/webui/resources/js:promise_resolver", + "//ui/webui/resources/js:util", + "//ui/webui/resources/js:webui_listener_tracker", + "//ui/webui/resources/js/cr:event_target", + "//ui/webui/resources/js/cr:ui", + "//ui/webui/resources/js/cr/ui:focus_manager", + "//ui/webui/resources/js/cr/ui:focus_outline_manager", + "//ui/webui/resources/js/cr/ui:node_utils", + ] + + sources = [ + "cloud_print_interface.js", + "common/overlay.js", + "common/search_box.js", + "common/search_bubble.js", + "component.js", + "data/app_state.js", + "data/capabilities_holder.js", + "data/cloud_parsers.js", + "data/coordinate2d.js", + "data/destination.js", + "data/destination_match.js", + "data/destination_store.js", + "data/document_info.js", + "data/invitation.js", + "data/invitation_store.js", + "data/local_parsers.js", + "data/margins.js", + "data/measurement_system.js", + "data/page_number_set.js", + "data/print_ticket_store.js", + "data/printable_area.js", + "data/size.js", + "data/ticket_items/collate.js", + "data/ticket_items/color.js", + "data/ticket_items/copies.js", + "data/ticket_items/css_background.js", + "data/ticket_items/custom_margins.js", + "data/ticket_items/dpi.js", + "data/ticket_items/duplex.js", + "data/ticket_items/fit_to_page.js", + "data/ticket_items/header_footer.js", + "data/ticket_items/landscape.js", + "data/ticket_items/margins_type.js", + "data/ticket_items/media_size.js", + "data/ticket_items/page_range.js", + "data/ticket_items/rasterize.js", + "data/ticket_items/scaling.js", + "data/ticket_items/selection_only.js", + "data/ticket_items/ticket_item.js", + "data/ticket_items/vendor_items.js", + "data/user_info.js", + "metrics.js", + "native_layer.js", + "preview_generator.js", + "previewarea/margin_control.js", + "previewarea/margin_control_container.js", + "previewarea/preview_area.js", + "print_header.js", + "print_preview.js", + "print_preview_animations.js", + "print_preview_focus_manager.js", + "print_preview_utils.js", + "search/destination_list.js", + "search/destination_list_item.js", + "search/destination_search.js", + "search/provisional_destination_resolver.js", + "search/recent_destination_list.js", + "settings/advanced_options_settings.js", + "settings/advanced_settings/advanced_settings.js", + "settings/advanced_settings/advanced_settings_item.js", + "settings/color_settings.js", + "settings/copies_settings.js", + "settings/destination_settings.js", + "settings/dpi_settings.js", + "settings/layout_settings.js", + "settings/margin_settings.js", + "settings/media_size_settings.js", + "settings/more_settings.js", + "settings/other_options_settings.js", + "settings/page_settings.js", + "settings/scaling_settings.js", + "settings/settings_section.js", + "settings/settings_section_select.js", ] + + externs_list = [ "$externs_path/chrome_send.js" ] } -unpak("unpak") { - pak_file = print_preview_pak_file - out_folder = unpak_folder +js_library("print_preview_utils") { + deps = [ + "data:coordinate2d", + "data:size", + "//ui/webui/resources/js:cr", + ] +} +js_library("metrics") { deps = [ - ":flattened_resources", + ":native_layer", + "//ui/webui/resources/js:cr", ] } -grit("flattened_resources") { - source = "print_preview_resources.grd" +js_library("component") { +} +js_library("print_preview_focus_manager") { +} - # The .grd contains references to generated files. - source_is_generated = true +js_library("cloud_print_interface") { + deps = [ + ":native_layer", + "data:cloud_parsers", + "data:destination", + "data:document_info", + "data:invitation", + "data:user_info", + "//ui/webui/resources/js:cr", + ] +} - defines = chrome_grit_defines - outputs = [ - "grit/print_preview_resources.h", - "grit/print_preview_resources_map.cc", - "grit/print_preview_resources_map.h", - print_preview_pak_file, +js_library("native_layer") { + deps = [ + "data:destination", + "data:measurement_system", + "//ui/webui/resources/js:cr", ] - output_dir = "$root_gen_dir/chrome/browser/resources/print_preview" } diff --git a/chromium/chrome/browser/resources/print_preview/compiled_resources2.gyp b/chromium/chrome/browser/resources/print_preview/compiled_resources2.gyp deleted file mode 100644 index 311e09e0400..00000000000 --- a/chromium/chrome/browser/resources/print_preview/compiled_resources2.gyp +++ /dev/null @@ -1,69 +0,0 @@ -# Copyright 2014 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. -{ - 'targets': [ - { - 'target_name': 'print_preview', - 'dependencies': [ - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:event_tracker', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:webui_listener_tracker', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:promise_resolver', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:util', - '<(DEPTH)/ui/webui/resources/js/cr/compiled_resources2.gyp:event_target', - '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:focus_manager', - '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:focus_outline_manager', - '<(DEPTH)/ui/webui/resources/js/cr/ui/compiled_resources2.gyp:node_utils', - '<(DEPTH)/ui/webui/resources/js/cr/compiled_resources2.gyp:ui', - '<(EXTERNS_GYP):chrome_send', - ], - 'variables': { - 'extra_inputs': [ - '<!@(python <(CLOSURE_DIR)/build/get_includes.py print_preview.js)', - ], - }, - 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'print_preview_utils', - 'dependencies': [ - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', - 'data/compiled_resources2.gyp:size', - 'data/compiled_resources2.gyp:coordinate2d' - ], - 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'metrics', - 'dependencies': [ - 'native_layer', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', - ], - 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'cloud_print_interface', - 'dependencies': [ - 'native_layer', - 'data/compiled_resources2.gyp:cloud_parsers', - 'data/compiled_resources2.gyp:destination', - 'data/compiled_resources2.gyp:document_info', - 'data/compiled_resources2.gyp:invitation', - 'data/compiled_resources2.gyp:user_info', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', - ], - 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'native_layer', - 'dependencies': [ - 'data/compiled_resources2.gyp:destination', - 'data/compiled_resources2.gyp:measurement_system', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', - ], - 'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - ], -} diff --git a/chromium/chrome/browser/resources/print_preview/component.js b/chromium/chrome/browser/resources/print_preview/component.js index 00227848188..1f69a934a52 100644 --- a/chromium/chrome/browser/resources/print_preview/component.js +++ b/chromium/chrome/browser/resources/print_preview/component.js @@ -15,7 +15,7 @@ cr.define('print_preview', function() { /** * Component's HTML element. - * @private {Element} + * @protected {Element} */ this.element_ = null; @@ -23,7 +23,7 @@ cr.define('print_preview', function() { /** * Component's event tracker. - * @private {!EventTracker} + * @protected {!EventTracker} */ this.tracker_ = new EventTracker(); diff --git a/chromium/chrome/browser/resources/print_preview/data/BUILD.gn b/chromium/chrome/browser/resources/print_preview/data/BUILD.gn new file mode 100644 index 00000000000..a93e13c5113 --- /dev/null +++ b/chromium/chrome/browser/resources/print_preview/data/BUILD.gn @@ -0,0 +1,139 @@ +# Copyright 2018 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("//third_party/closure_compiler/compile_js.gni") + +js_type_check("closure_compile") { + deps = [ + ":cloud_parsers", + ":coordinate2d", + ":destination", + ":destination_match", + ":destination_store", + ":document_info", + ":invitation", + ":invitation_store", + ":local_parsers", + ":margins", + ":measurement_system", + ":printable_area", + ":size", + ":user_info", + ] +} + +js_library("destination_store") { + deps = [ + ":destination", + ":destination_match", + ":local_parsers", + ":user_info", + "..:cloud_print_interface", + "..:metrics", + "..:native_layer", + "//ui/webui/resources/js:cr", + "//ui/webui/resources/js:event_tracker", + "//ui/webui/resources/js:webui_listener_tracker", + "//ui/webui/resources/js/cr:event_target", + ] +} + +js_library("invitation_store") { + deps = [ + ":invitation", + ":user_info", + "..:cloud_print_interface", + "//ui/webui/resources/js:event_tracker", + "//ui/webui/resources/js/cr:event_target", + ] +} + +js_library("local_parsers") { + deps = [ + ":destination", + "..:native_layer", + "//ui/webui/resources/js:cr", + ] +} + +js_library("destination_match") { + deps = [ + ":destination", + "..:native_layer", + "//ui/webui/resources/js:cr", + ] +} + +js_library("cloud_parsers") { + deps = [ + ":destination", + ":invitation", + "//ui/webui/resources/js:cr", + ] +} + +js_library("invitation") { + deps = [ + ":destination", + "//ui/webui/resources/js:cr", + ] +} + +js_library("destination") { + deps = [ + "..:print_preview_utils", + "//ui/webui/resources/js:cr", + "//ui/webui/resources/js:load_time_data", + ] +} + +js_library("document_info") { + deps = [ + ":coordinate2d", + ":margins", + ":printable_area", + ":size", + "//ui/webui/resources/js:cr", + "//ui/webui/resources/js/cr:event_target", + ] +} + +js_library("margins") { + deps = [ + "//ui/webui/resources/js:cr", + ] +} + +js_library("measurement_system") { + deps = [ + "//ui/webui/resources/js:cr", + ] +} + +js_library("printable_area") { + deps = [ + ":coordinate2d", + ":size", + "//ui/webui/resources/js:cr", + ] +} + +js_library("size") { + deps = [ + "//ui/webui/resources/js:cr", + ] +} + +js_library("coordinate2d") { + deps = [ + "//ui/webui/resources/js:cr", + ] +} + +js_library("user_info") { + deps = [ + "//ui/webui/resources/js:cr", + "//ui/webui/resources/js/cr:event_target", + ] +} diff --git a/chromium/chrome/browser/resources/print_preview/data/compiled_resources2.gyp b/chromium/chrome/browser/resources/print_preview/data/compiled_resources2.gyp deleted file mode 100644 index db082079ecc..00000000000 --- a/chromium/chrome/browser/resources/print_preview/data/compiled_resources2.gyp +++ /dev/null @@ -1,136 +0,0 @@ -# Copyright 2017 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. -{ - 'targets': [ - { - 'target_name': 'destination_store', - 'dependencies': [ - 'destination', - 'destination_match', - 'local_parsers', - 'user_info', - '../compiled_resources2.gyp:cloud_print_interface', - '../compiled_resources2.gyp:metrics', - '../compiled_resources2.gyp:native_layer', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:event_tracker', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:webui_listener_tracker', - '<(DEPTH)/ui/webui/resources/js/cr/compiled_resources2.gyp:event_target', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'invitation_store', - 'dependencies': [ - 'invitation', - 'user_info', - '../compiled_resources2.gyp:cloud_print_interface', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:event_tracker', - '<(DEPTH)/ui/webui/resources/js/cr/compiled_resources2.gyp:event_target', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'local_parsers', - 'dependencies': [ - 'destination', - '../compiled_resources2.gyp:native_layer', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'destination_match', - 'dependencies': [ - 'destination', - '../compiled_resources2.gyp:native_layer', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'cloud_parsers', - 'dependencies': [ - 'destination', - 'invitation', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'invitation', - 'dependencies': [ - 'destination', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'destination', - 'dependencies': [ - '../compiled_resources2.gyp:print_preview_utils', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'document_info', - 'dependencies': [ - 'margins', - 'size', - 'coordinate2d', - 'printable_area', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', - '<(DEPTH)/ui/webui/resources/js/cr/compiled_resources2.gyp:event_target', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'margins', - 'dependencies': [ - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'measurement_system', - 'dependencies': [ - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'printable_area', - 'dependencies': [ - 'size', - 'coordinate2d', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'size', - 'dependencies': [ - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'coordinate2d', - 'dependencies': [ - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'user_info', - 'dependencies': [ - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', - '<(DEPTH)/ui/webui/resources/js/cr/compiled_resources2.gyp:event_target', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - ] -} diff --git a/chromium/chrome/browser/resources/print_preview/data/destination.html b/chromium/chrome/browser/resources/print_preview/data/destination.html index cdaabd9beb7..7690ac8b807 100644 --- a/chromium/chrome/browser/resources/print_preview/data/destination.html +++ b/chromium/chrome/browser/resources/print_preview/data/destination.html @@ -1,5 +1,6 @@ <link rel="import" href="chrome://resources/html/cr.html"> <link rel="import" href="chrome://resources/html/load_time_data.html"> <link rel="import" href="../print_preview_utils.html"> +<link rel="import" href="../new/strings.html"> <script src="destination.js"></script> diff --git a/chromium/chrome/browser/resources/print_preview/data/destination.js b/chromium/chrome/browser/resources/print_preview/data/destination.js index a3b1e5627d0..a51790037dc 100644 --- a/chromium/chrome/browser/resources/print_preview/data/destination.js +++ b/chromium/chrome/browser/resources/print_preview/data/destination.js @@ -574,6 +574,14 @@ cr.define('print_preview', function() { return this.isOffline || this.shouldShowInvalidCertificateError; } + /** @return {boolean} Whether the destination is ready to be selected. */ + get readyForSelection() { + return (!cr.isChromeOS || + this.origin_ != print_preview.DestinationOrigin.CROS || + this.capabilities_ != null) && + !this.isProvisional; + } + /** * @return {string} Human readable status for a destination that is offline * or has a bad certificate. */ 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 638e1f951a1..b7a3a5148e3 100644 --- a/chromium/chrome/browser/resources/print_preview/data/destination_store.js +++ b/chromium/chrome/browser/resources/print_preview/data/destination_store.js @@ -748,13 +748,14 @@ cr.define('print_preview', function() { * Attempts to resolve a provisional destination. * @param {!print_preview.Destination} destination Provisional destination * that should be resolved. + * @return {!Promise<?print_preview.Destination>} */ resolveProvisionalDestination(destination) { assert( destination.provisionalType == print_preview.DestinationProvisionalType.NEEDS_USB_PERMISSION, 'Provisional type cannot be resolved.'); - this.nativeLayer_.grantExtensionPrinterAccess(destination.id) + return this.nativeLayer_.grantExtensionPrinterAccess(destination.id) .then( destinationInfo => { /** @@ -769,6 +770,7 @@ cr.define('print_preview', function() { this.insertIntoStore_(parsedDestination); this.dispatchProvisionalDestinationResolvedEvent_( destination.id, parsedDestination); + return parsedDestination; }, () => { /** @@ -779,6 +781,7 @@ cr.define('print_preview', function() { this.removeProvisionalDestination_(destination.id); this.dispatchProvisionalDestinationResolvedEvent_( destination.id, null); + return null; }); } @@ -1005,11 +1008,11 @@ cr.define('print_preview', function() { */ updateDestination_(destination) { assert(destination.constructor !== Array, 'Single printer expected'); - destination.capabilities_ = - localizeCapabilities(assert(destination.capabilities_)); + destination.capabilities = + localizeCapabilities(assert(destination.capabilities)); if (print_preview.originToType(destination.origin) !== print_preview.PrinterType.LOCAL_PRINTER) { - destination.capabilities_ = sortMediaSizes(destination.capabilities_); + destination.capabilities = sortMediaSizes(destination.capabilities); } const existingDestination = this.destinationMap_[this.getKey_(destination)]; @@ -1053,7 +1056,7 @@ cr.define('print_preview', function() { const key = this.getKey_(destination); const existingDestination = this.destinationMap_[key]; if (existingDestination == null) { - destination.isRecent |= + destination.isRecent = destination.isRecent || this.recentDestinations_.some(function(recent) { return ( destination.id == recent.id && diff --git a/chromium/chrome/browser/resources/print_preview/data/ticket_items/dpi.js b/chromium/chrome/browser/resources/print_preview/data/ticket_items/dpi.js index 60c401ac920..0e71b329684 100644 --- a/chromium/chrome/browser/resources/print_preview/data/ticket_items/dpi.js +++ b/chromium/chrome/browser/resources/print_preview/data/ticket_items/dpi.js @@ -21,7 +21,7 @@ cr.define('print_preview.ticket_items', function() { wouldValueBeValid(value) { if (!this.isCapabilityAvailable()) return false; - return this.capability.option.some(function(option) { + return this.capability().option.some(function(option) { return option.horizontal_dpi == value.horizontal_dpi && option.vertical_dpi == value.vertical_dpi && option.vendor_id == value.vendor_id; @@ -30,8 +30,8 @@ cr.define('print_preview.ticket_items', function() { /** @override */ isCapabilityAvailable() { - return !!this.capability && !!this.capability.option && - this.capability.option.length > 1; + return !!this.capability() && !!this.capability().option && + this.capability().option.length > 1; } /** @override */ @@ -43,7 +43,7 @@ cr.define('print_preview.ticket_items', function() { } /** @return {Object} DPI capability of the selected destination. */ - get capability() { + capability() { const destination = this.getSelectedDestInternal(); return (destination && destination.capabilities && destination.capabilities.printer && @@ -53,7 +53,7 @@ cr.define('print_preview.ticket_items', function() { /** @override */ getDefaultValueInternal() { - const defaultOptions = this.capability.option.filter(function(option) { + const defaultOptions = this.capability().option.filter(function(option) { return option.is_default; }); return defaultOptions.length > 0 ? defaultOptions[0] : null; diff --git a/chromium/chrome/browser/resources/print_preview/data/ticket_items/media_size.js b/chromium/chrome/browser/resources/print_preview/data/ticket_items/media_size.js index 6302e0b418d..e8e794a80f3 100644 --- a/chromium/chrome/browser/resources/print_preview/data/ticket_items/media_size.js +++ b/chromium/chrome/browser/resources/print_preview/data/ticket_items/media_size.js @@ -44,7 +44,7 @@ cr.define('print_preview.ticket_items', function() { if (!this.isCapabilityAvailable()) { return false; } - return this.capability.option.some(function(option) { + return this.capability().option.some(function(option) { return option.width_microns == value.width_microns && option.height_microns == value.height_microns && option.is_continuous_feed == value.is_continuous_feed && @@ -60,7 +60,7 @@ cr.define('print_preview.ticket_items', function() { this.getSelectedDestInternal() && this.getSelectedDestInternal().id == print_preview.Destination.GooglePromotedId.SAVE_AS_PDF; - return !knownSizeToSaveAsPdf && !!this.capability; + return !knownSizeToSaveAsPdf && !!this.capability(); } /** @override */ @@ -73,7 +73,7 @@ cr.define('print_preview.ticket_items', function() { } /** @return {Object} Media size capability of the selected destination. */ - get capability() { + capability() { const destination = this.getSelectedDestInternal(); return (destination && destination.capabilities && destination.capabilities.printer && @@ -83,7 +83,7 @@ cr.define('print_preview.ticket_items', function() { /** @override */ getDefaultValueInternal() { - const defaultOptions = this.capability.option.filter(function(option) { + const defaultOptions = this.capability().option.filter(function(option) { return option.is_default; }); return defaultOptions.length > 0 ? defaultOptions[0] : null; diff --git a/chromium/chrome/browser/resources/print_preview/native_layer.js b/chromium/chrome/browser/resources/print_preview/native_layer.js index d2227130df1..2975eadf152 100644 --- a/chromium/chrome/browser/resources/print_preview/native_layer.js +++ b/chromium/chrome/browser/resources/print_preview/native_layer.js @@ -71,7 +71,7 @@ print_preview.CapabilitiesResponse; * @typedef {{ * printerId: string, * success: boolean, - * capabilities: Object, + * capabilities: !print_preview.Cdd, * }} */ print_preview.PrinterSetupResponse; @@ -197,13 +197,11 @@ cr.define('print_preview', function() { * 'page-layout-ready', * 'page-preview-ready' * @param {string} printTicket JSON print ticket for the request. - * @param {number} pageCount Page count for the preview request, or -1 if - * unknown (first request). * @return {!Promise<number>} Promise that resolves with the unique ID of * the preview UI when the preview has been generated. */ - getPreview(printTicket, pageCount) { - return cr.sendWithPromise('getPreview', printTicket, pageCount); + getPreview(printTicket) { + return cr.sendWithPromise('getPreview', printTicket); } /** diff --git a/chromium/chrome/browser/resources/print_preview/new/BUILD.gn b/chromium/chrome/browser/resources/print_preview/new/BUILD.gn new file mode 100644 index 00000000000..c239b1ea5ac --- /dev/null +++ b/chromium/chrome/browser/resources/print_preview/new/BUILD.gn @@ -0,0 +1,370 @@ +# Copyright 2018 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("//third_party/closure_compiler/compile_js.gni") + +js_type_check("closure_compile") { + deps = [ + ":advanced_options_settings", + ":advanced_settings_dialog", + ":advanced_settings_item", + ":app", + ":color_settings", + ":copies_settings", + ":destination_dialog", + ":destination_list", + ":destination_list_item", + ":destination_settings", + ":dpi_settings", + ":header", + ":highlight_utils", + ":input_behavior", + ":layout_settings", + ":link_container", + ":margin_control", + ":margin_control_container", + ":margins_settings", + ":media_size_settings", + ":model", + ":more_settings", + ":number_settings_section", + ":other_options_settings", + ":pages_per_sheet_settings", + ":pages_settings", + ":preview_area", + ":print_preview_search_box", + ":provisional_destination_resolver", + ":scaling_settings", + ":select_behavior", + ":settings_behavior", + ":settings_select", + ":state", + ] +} + +js_library("app") { + deps = [ + ":advanced_options_settings", + ":color_settings", + ":copies_settings", + ":destination_settings", + ":dpi_settings", + ":header", + ":layout_settings", + ":link_container", + ":margins_settings", + ":media_size_settings", + ":model", + ":more_settings", + ":other_options_settings", + ":pages_per_sheet_settings", + ":pages_settings", + ":preview_area", + ":scaling_settings", + ":state", + "..:cloud_print_interface", + "..:metrics", + "..:native_layer", + "../data:destination", + "../data:destination_store", + "../data:document_info", + "../data:invitation_store", + "../data:measurement_system", + "../data:user_info", + "//ui/webui/resources/js:event_tracker", + "//ui/webui/resources/js:util", + "//ui/webui/resources/js:webui_listener_tracker", + ] +} + +js_library("header") { + deps = [ + ":model", + ":settings_behavior", + ":state", + "../data:destination", + "//ui/webui/resources/js:cr", + "//ui/webui/resources/js:load_time_data", + ] +} + +js_library("destination_settings") { + deps = [ + ":destination_dialog", + ":state", + "../data:destination", + "../data:destination_store", + "../data:invitation_store", + "../data:user_info", + "//ui/webui/resources/cr_elements/cr_lazy_render:cr_lazy_render", + "//ui/webui/resources/js:i18n_behavior", + ] +} + +js_library("pages_settings") { + deps = [ + ":input_behavior", + ":settings_behavior", + "../data:document_info", + "//ui/webui/resources/js:load_time_data", + ] +} + +js_library("copies_settings") { + deps = [ + ":number_settings_section", + ":settings_behavior", + ] +} + +js_library("layout_settings") { + deps = [ + ":select_behavior", + ":settings_behavior", + ] +} + +js_library("color_settings") { + deps = [ + ":select_behavior", + ":settings_behavior", + ] +} + +js_library("media_size_settings") { + deps = [ + ":settings_behavior", + ":settings_select", + ] +} + +js_library("margins_settings") { + deps = [ + ":select_behavior", + ":settings_behavior", + ] +} + +js_library("dpi_settings") { + deps = [ + ":settings_behavior", + ":settings_select", + "//ui/webui/resources/js:cr", + "//ui/webui/resources/js:load_time_data", + ] +} + +js_library("pages_per_sheet_settings") { + deps = [ + ":select_behavior", + ":settings_behavior", + ] +} + +js_library("scaling_settings") { + deps = [ + ":number_settings_section", + ":settings_behavior", + "../data:document_info", + ] +} + +js_library("other_options_settings") { + deps = [ + ":settings_behavior", + ] +} + +js_library("advanced_options_settings") { + deps = [ + ":advanced_settings_dialog", + ":settings_behavior", + "../data:destination", + ] +} + +js_library("more_settings") { + deps = [ + "..:metrics", + "//ui/webui/resources/js:i18n_behavior", + ] +} + +js_library("number_settings_section") { + deps = [ + ":input_behavior", + ] +} + +js_library("settings_select") { + deps = [ + ":select_behavior", + ":settings_behavior", + "..:print_preview_utils", + "//ui/webui/resources/js:cr", + ] +} + +js_library("settings_behavior") { + deps = [ + "//ui/webui/resources/js:assert", + "//ui/webui/resources/js:cr", + ] +} + +js_library("input_behavior") { + deps = [ + "//ui/webui/resources/js:cr", + ] +} + +js_library("select_behavior") { + deps = [] +} + +js_library("link_container") { + deps = [ + "../data:destination", + "//ui/webui/resources/js:assert", + "//ui/webui/resources/js:cr", + ] +} + +js_library("preview_area") { + deps = [ + ":margin_control_container", + ":model", + ":settings_behavior", + ":state", + "..:native_layer", + "..:print_preview_utils", + "../../pdf:pdf_scripting_api", + "../data:coordinate2d", + "../data:destination", + "../data:document_info", + "../data:margins", + "../data:printable_area", + "../data:size", + "//ui/webui/resources/js:cr", + "//ui/webui/resources/js:i18n_behavior", + "//ui/webui/resources/js:util", + "//ui/webui/resources/js:web_ui_listener_behavior", + ] +} + +js_library("margin_control_container") { + deps = [ + ":margin_control", + ":settings_behavior", + "../data:coordinate2d", + "../data:margins", + "../data:measurement_system", + "../data:size", + "//ui/webui/resources/js:event_tracker", + ] + externs_list = [ "$externs_path/pending.js" ] +} + +js_library("margin_control") { + deps = [ + ":input_behavior", + "../data:coordinate2d", + "../data:margins", + "../data:size", + ] +} + +js_library("destination_dialog") { + deps = [ + ":destination_list", + ":print_preview_search_box", + ":provisional_destination_resolver", + "..:metrics", + "../data:destination", + "../data:destination_store", + "../data:invitation", + "../data:invitation_store", + "../data:user_info", + "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog", + "//ui/webui/resources/js:event_tracker", + "//ui/webui/resources/js:i18n_behavior", + ] +} + +js_library("destination_list") { + deps = [ + ":destination_list_item", + "..:native_layer", + "../data:destination", + "//ui/webui/resources/js:i18n_behavior", + ] +} + +js_library("destination_list_item") { + deps = [ + ":highlight_utils", + "..:native_layer", + "../data:destination", + "//ui/webui/resources/js:load_time_data", + ] +} + +js_library("advanced_settings_dialog") { + deps = [ + ":advanced_settings_item", + ":print_preview_search_box", + ":settings_behavior", + "..:metrics", + "../data:destination", + "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog", + "//ui/webui/resources/js:i18n_behavior", + ] +} + +js_library("advanced_settings_item") { + deps = [ + ":highlight_utils", + ":settings_behavior", + "..:print_preview_utils", + "../data:destination", + ] +} + +js_library("print_preview_search_box") { + deps = [ + "//ui/webui/resources/cr_elements/cr_search_field:cr_search_field_behavior", + ] +} + +js_library("provisional_destination_resolver") { + deps = [ + "../data:destination", + "../data:destination_store", + "//ui/webui/resources/cr_elements/cr_dialog:cr_dialog", + "//ui/webui/resources/js:cr", + "//ui/webui/resources/js:i18n_behavior", + ] +} + +js_library("highlight_utils") { + deps = [ + "//ui/webui/resources/js:search_highlight_utils", + ] +} + +js_library("model") { + deps = [ + ":settings_behavior", + "../data:destination", + "../data:document_info", + "../data:margins", + "//ui/webui/resources/js:cr", + ] +} + +js_library("state") { + deps = [ + "//ui/webui/resources/js:cr", + ] +} diff --git a/chromium/chrome/browser/resources/print_preview/new/advanced_settings_dialog.html b/chromium/chrome/browser/resources/print_preview/new/advanced_settings_dialog.html index bc4b58562d8..6ad13d0f8d9 100644 --- a/chromium/chrome/browser/resources/print_preview/new/advanced_settings_dialog.html +++ b/chromium/chrome/browser/resources/print_preview/new/advanced_settings_dialog.html @@ -3,22 +3,26 @@ <link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> <link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html"> +<link rel="import" href="../metrics.html"> <link rel="import" href="../data/destination.html"> <link rel="import" href="advanced_settings_item.html"> <link rel="import" href="settings_behavior.html"> <link rel="import" href="button_css.html"> <link rel="import" href="print_preview_shared_css.html"> <link rel="import" href="search_dialog_css.html"> +<link rel="import" href="strings.html"> <dom-module id="print-preview-advanced-dialog"> <style include="print-preview-shared search-dialog button cr-hidden-style"> </style> <template> - <cr-dialog id="dialog" on-close="onCloseOrCancel_"> + <cr-dialog id="dialog" on-close="onCloseOrCancel_" show-close-button> <div slot="title"> <div>[[i18n('advancedSettingsDialogTitle', destination.displayName)]] </div> <print-preview-search-box id="searchBox" + hidden$="[[!hasMultipleItems_( + destination.capabilities.printer.vendor_capability)]]" label="$i18n{advancedSettingsSearchBoxPlaceholder}" search-query="{{searchQuery_}}"> </print-preview-search-box> diff --git a/chromium/chrome/browser/resources/print_preview/new/advanced_settings_dialog.js b/chromium/chrome/browser/resources/print_preview/new/advanced_settings_dialog.js index 989de5b0285..6bec184bead 100644 --- a/chromium/chrome/browser/resources/print_preview/new/advanced_settings_dialog.js +++ b/chromium/chrome/browser/resources/print_preview/new/advanced_settings_dialog.js @@ -25,6 +25,17 @@ Polymer({ }, }, + /** @private {!print_preview.PrintSettingsUiMetricsContext} */ + metrics_: new print_preview.PrintSettingsUiMetricsContext(), + + /** + * @return {boolean} Whether there is more than one vendor item to display. + * @private + */ + hasMultipleItems_: function() { + return this.destination.capabilities.printer.vendor_capability.length > 1; + }, + /** * @return {boolean} Whether there is a setting matching the query. * @private @@ -54,6 +65,10 @@ Polymer({ onCloseOrCancel_: function() { if (this.searchQuery_) this.$.searchBox.setValue(''); + if (this.$.dialog.getNative().returnValue == 'success') { + this.metrics_.record(print_preview.Metrics.PrintSettingsUiBucket + .ADVANCED_SETTINGS_DIALOG_CANCELED); + } }, /** @private */ @@ -73,6 +88,8 @@ Polymer({ }, show: function() { + this.metrics_.record(print_preview.Metrics.PrintSettingsUiBucket + .ADVANCED_SETTINGS_DIALOG_SHOWN); this.$.dialog.showModal(); }, diff --git a/chromium/chrome/browser/resources/print_preview/new/app.html b/chromium/chrome/browser/resources/print_preview/new/app.html index 71931d347f0..1209ecb4b4b 100644 --- a/chromium/chrome/browser/resources/print_preview/new/app.html +++ b/chromium/chrome/browser/resources/print_preview/new/app.html @@ -3,7 +3,9 @@ <link rel="import" href="chrome://resources/html/event_tracker.html"> <link rel="import" href="chrome://resources/html/util.html"> <link rel="import" href="chrome://resources/html/webui_listener_tracker.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/iron-collapse/iron-collapse.html"> <link rel="import" href="../cloud_print_interface.html"> +<link rel="import" href="../metrics.html"> <link rel="import" href="../native_layer.html"> <link rel="import" href="../data/destination.html"> <link rel="import" href="../data/destination_store.html"> @@ -24,9 +26,11 @@ <link rel="import" href="media_size_settings.html"> <link rel="import" href="margins_settings.html"> <link rel="import" href="dpi_settings.html"> +<link rel="import" href="pages_per_sheet_settings.html"> <link rel="import" href="scaling_settings.html"> <link rel="import" href="other_options_settings.html"> <link rel="import" href="advanced_options_settings.html"> +<link rel="import" href="more_settings.html"> <if expr="not chromeos"> <link rel="import" href="link_container.html"> </if> @@ -47,7 +51,7 @@ min-width: 310px; } - #settings-sections { + #settingsSections { background: #fbfbfb; border-top: 1px solid #f3f3f3; flex: 1; @@ -73,17 +77,18 @@ on-print-requested="onPrintRequested_" on-cancel-requested="onCancelRequested_"> </print-preview-header> - <div id="settings-sections"> + <div id="settingsSections"> <print-preview-destination-settings id="destinationSettings" destination="[[destination_]]" destination-store="[[destinationStore_]]" invitation-store="[[invitationStore_]]" disabled="[[controlsDisabled_]]" state="[[state]]" recent-destinations="[[recentDestinations_]]" - user-info="{{userInfo_}}"> + user-info="{{userInfo_}}" available> </print-preview-destination-settings> <print-preview-pages-settings settings="{{settings}}" - document-info="[[documentInfo_]]" disabled="[[controlsDisabled_]]" + document-info="[[documentInfo_]]" + disabled="[[controlsDisabled_]]" hidden$="[[!settings.pages.available]]"> </print-preview-pages-settings> <print-preview-copies-settings settings="{{settings}}" @@ -98,32 +103,47 @@ disabled="[[controlsDisabled_]]" hidden$="[[!settings.color.available]]"> </print-preview-color-settings> - <print-preview-media-size-settings settings="{{settings}}" - capability="[[destination_.capabilities.printer.media_size]]" - disabled="[[controlsDisabled_]]" - hidden$="[[!settings.mediaSize.available]]"> - </print-preview-media-size-settings> - <print-preview-margins-settings settings="{{settings}}" - disabled="[[controlsDisabled_]]" - hidden$="[[!settings.margins.available]]"> - </print-preview-margins-settings> - <print-preview-dpi-settings settings="{{settings}}" - capability="[[destination_.capabilities.printer.dpi]]" - disabled="[[controlsDisabled_]]" - hidden$="[[!settings.dpi.available]]"> - </print-preview-dpi-settings> - <print-preview-scaling-settings settings="{{settings}}" - document-info="[[documentInfo_]]" disabled="[[controlsDisabled_]]" - hidden$="[[!settings.scaling.available]]"> - </print-preview-scaling-settings> - <print-preview-other-options-settings settings="{{settings}}" + <print-preview-more-settings + settings-expanded-by-user="{{settingsExpandedByUser_}}" disabled="[[controlsDisabled_]]" - hidden$="[[!settings.otherOptions.available]]"> - </print-preview-other-options-settings> - <print-preview-advanced-options-settings settings="{{settings}}" - destination="[[destination_]]" disabled="[[controlsDisabled_]]" - hidden$="[[!settings.vendorItems.available]]"> - </print-preview-advanced-options-settings> + hidden$="[[!shouldShowMoreSettings_]]"> + </print-preview-more-settings> + <iron-collapse id="moreSettings" + opened="[[shouldExpandSettings_( + settingsExpandedByUser_, shouldShowMoreSettings_)]]"> + <print-preview-media-size-settings settings="{{settings}}" + capability="[[destination_.capabilities.printer.media_size]]" + disabled="[[controlsDisabled_]]" + hidden$="[[!settings.mediaSize.available]]"> + </print-preview-media-size-settings> + <print-preview-margins-settings settings="{{settings}}" + disabled="[[controlsDisabled_]]" + hidden$="[[!settings.margins.available]]"> + </print-preview-margins-settings> + <print-preview-dpi-settings settings="{{settings}}" + capability="[[destination_.capabilities.printer.dpi]]" + disabled="[[controlsDisabled_]]" + hidden$="[[!settings.dpi.available]]"> + </print-preview-dpi-settings> + <template is="dom-if" if="[[showPagesPerSheet_]]"> + <print-preview-pages-per-sheet-settings settings="{{settings}}" + disabled="[[controlsDisabled_]]" + hidden$="[[!settings.pagesPerSheet.available]]"> + </print-preview-pages-per-sheet-settings> + </template> + <print-preview-scaling-settings settings="{{settings}}" + document-info="[[documentInfo_]]" disabled="[[controlsDisabled_]]" + hidden$="[[!settings.scaling.available]]"> + </print-preview-scaling-settings> + <print-preview-other-options-settings settings="{{settings}}" + disabled="[[controlsDisabled_]]" + hidden$="[[!settings.otherOptions.available]]"> + </print-preview-other-options-settings> + <print-preview-advanced-options-settings settings="{{settings}}" + destination="[[destination_]]" disabled="[[controlsDisabled_]]" + hidden$="[[!settings.vendorItems.available]]"> + </print-preview-advanced-options-settings> + </iron-collapse> <if expr="not chromeos"> <print-preview-link-container destination="[[destination_]]" app-kiosk-mode="[[isInAppKioskMode_]]" @@ -140,9 +160,7 @@ <print-preview-preview-area id="previewArea" settings="{{settings}}" destination="[[destination_]]" document-info="{{documentInfo_}}" state="[[state]]" measurement-system="[[measurementSystem_]]" - on-invalid-printer="onInvalidPrinter_" - on-preview-failed="onPreviewFailed_" - on-preview-loaded="onPreviewLoaded_"> + preview-state="{{previewState_}}"> </print-preview-preview-area> </div> </template> diff --git a/chromium/chrome/browser/resources/print_preview/new/app.js b/chromium/chrome/browser/resources/print_preview/new/app.js index 6698b22ce01..83ccdadd72e 100644 --- a/chromium/chrome/browser/resources/print_preview/new/app.js +++ b/chromium/chrome/browser/resources/print_preview/new/app.js @@ -2,10 +2,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +(function() { +'use strict'; + +/** + * Number of settings sections to show when "More settings" is collapsed. + * @type {number} + */ +const MAX_SECTIONS_TO_SHOW = 6; + Polymer({ is: 'print-preview-app', behaviors: [SettingsBehavior], + properties: { /** * Object containing current settings of Print Preview, for use by Polymer @@ -89,6 +99,42 @@ Polymer({ notify: true, value: false, }, + + /** @private {!print_preview_new.PreviewAreaState} */ + previewState_: { + type: String, + observer: 'onPreviewAreaStateChanged_', + }, + + /** @private {boolean} */ + settingsExpandedByUser_: { + type: Boolean, + notify: true, + value: false, + }, + + /** @private {boolean} */ + shouldShowMoreSettings_: { + type: Boolean, + notify: true, + computed: 'computeShouldShowMoreSettings_(settings.pages.available, ' + + 'settings.copies.available, settings.layout.available, ' + + 'settings.color.available, settings.mediaSize.available, ' + + 'settings.dpi.available, settings.margins.available, ' + + 'settings.pagesPerSheet.available, settings.scaling.available, ' + + 'settings.otherOptions.available, settings.vendorItems.available)', + }, + + /** + * Whether to show pages per sheet feature or not. + * @private {boolean} + */ + showPagesPerSheet_: { + type: Boolean, + value: function() { + return loadTimeData.getBoolean('pagesPerSheetEnabled'); + }, + }, }, /** @private {?WebUIListenerTracker} */ @@ -112,6 +158,9 @@ Polymer({ /** @private {boolean} */ openPdfInPreview_: false, + /** @private {boolean} */ + isInKioskAutoPrintMode_: false, + /** @override */ attached: function() { this.nativeLayer_ = print_preview.NativeLayer.getInstance(); @@ -120,6 +169,9 @@ Polymer({ this.listenerTracker_ = new WebUIListenerTracker(); this.listenerTracker_.add( 'use-cloud-print', this.onCloudPrintEnable_.bind(this)); + this.listenerTracker_.add('print-failed', this.onPrintFailed_.bind(this)); + this.listenerTracker_.add( + 'print-preset-options', this.onPrintPresetOptions_.bind(this)); this.destinationStore_ = new print_preview.DestinationStore( this.userInfo_, this.listenerTracker_); this.invitationStore_ = new print_preview.InvitationStore(this.userInfo_); @@ -232,6 +284,7 @@ Polymer({ settings.serializedDefaultDestinationSelectionRulesStr, this.recentDestinations_); this.isInAppKioskMode_ = settings.isInAppKioskMode; + this.isInKioskAutoPrintMode_ = settings.isInKioskAutoPrintMode; }, /** @@ -271,6 +324,10 @@ Polymer({ /** @private */ onDestinationSelect_: function() { + // If the plugin does not exist do not attempt to load the preview. + if (this.state == print_preview_new.State.FATAL_ERROR) + return; + this.$.state.transitTo(print_preview_new.State.NOT_READY); this.destination_ = this.destinationStore_.selectedDestination; }, @@ -280,10 +337,16 @@ Polymer({ this.set( 'destination_.capabilities', this.destinationStore_.selectedDestination.capabilities); - if (this.state != print_preview_new.State.READY) - this.$.state.transitTo(print_preview_new.State.READY); + if (!this.$.model.initialized()) this.$.model.applyStickySettings(); + + if (this.state == print_preview_new.State.NOT_READY || + this.state == print_preview_new.State.INVALID_PRINTER) { + this.$.state.transitTo(print_preview_new.State.READY); + if (this.isInKioskAutoPrintMode_) + this.onPrintRequested_(); + } }, /** @@ -302,6 +365,14 @@ Polymer({ } else if (this.state == print_preview_new.State.HIDDEN) { this.nativeLayer_.hidePreview(); } else if (this.state == print_preview_new.State.PRINTING) { + if (this.shouldShowMoreSettings_) { + new print_preview.PrintSettingsUiMetricsContext().record( + this.settingsExpandedByUser_ ? + print_preview.Metrics.PrintSettingsUiBucket + .PRINT_WITH_SETTINGS_EXPANDED : + print_preview.Metrics.PrintSettingsUiBucket + .PRINT_WITH_SETTINGS_COLLAPSED); + } const destination = assert(this.destinationStore_.selectedDestination); const whenPrintDone = this.nativeLayer_.print(this.$.model.createPrintTicket( @@ -324,12 +395,6 @@ Polymer({ }, /** @private */ - onPreviewLoaded_: function() { - if (this.state == print_preview_new.State.HIDDEN) - this.$.state.transitTo(print_preview_new.State.PRINTING); - }, - - /** @private */ onPrintRequested_: function() { this.$.state.transitTo( this.$.previewArea.previewLoaded() ? print_preview_new.State.PRINTING : @@ -409,13 +474,31 @@ Polymer({ }, /** @private */ - onPreviewFailed_: function() { - this.$.state.transitTo(print_preview_new.State.FATAL_ERROR); + onInvalidPrinter_: function() { + this.previewState_ = + print_preview_new.PreviewAreaState.UNSUPPORTED_CLOUD_PRINTER; }, /** @private */ - onInvalidPrinter_: function() { - this.$.state.transitTo(print_preview_new.State.INVALID_PRINTER); + onPreviewAreaStateChanged_: function() { + switch (this.previewState_) { + case print_preview_new.PreviewAreaState.PREVIEW_FAILED: + case print_preview_new.PreviewAreaState.NO_PLUGIN: + this.$.state.transitTo(print_preview_new.State.FATAL_ERROR); + break; + case print_preview_new.PreviewAreaState.INVALID_SETTINGS: + case print_preview_new.PreviewAreaState.UNSUPPORTED_CLOUD_PRINTER: + if (this.state != print_preview_new.State.INVALID_PRINTER) + this.$.state.transitTo(print_preview_new.State.INVALID_PRINTER); + break; + case print_preview_new.PreviewAreaState.DISPLAY_PREVIEW: + case print_preview_new.PreviewAreaState.OPEN_IN_PREVIEW_LOADED: + if (this.state == print_preview_new.State.HIDDEN) + this.$.state.transitTo(print_preview_new.State.PRINTING); + break; + default: + break; + } }, /** @@ -443,8 +526,52 @@ Polymer({ } }, + /** + * Updates printing options according to source document presets. + * @param {boolean} disableScaling Whether the document disables scaling. + * @param {number} copies The default number of copies from the document. + * @param {number} duplex The default duplex setting from the document. + * @private + */ + onPrintPresetOptions_: function(disableScaling, copies, duplex) { + if (disableScaling) + this.documentInfo_.updateIsScalingDisabled(true); + + if (copies > 0 && this.getSetting('copies').available) + this.setSetting('copies', copies); + + if (duplex >= 0 && this.getSetting('duplex').available) + this.setSetting('duplex', duplex); + }, + + /** + * @return {boolean} Whether to show the "More settings" link. + * @private + */ + computeShouldShowMoreSettings_: function() { + // Destination settings is always available. See if the total number of + // available sections exceeds the maximum number to show. + return [ + 'pages', 'copies', 'layout', 'color', 'mediaSize', 'margins', 'color', + 'pagesPerSheet', 'scaling', 'otherOptions', 'vendorItems' + ].reduce((count, setting) => { + return this.getSetting(setting).available ? count + 1 : count; + }, 1) > MAX_SECTIONS_TO_SHOW; + }, + + /** + * @return {boolean} Whether the "more settings" collapse should be expanded. + * @private + */ + shouldExpandSettings_: function() { + // Expand the settings if the user has requested them expanded or if more + // settings is not displayed (i.e. less than 6 total settings available). + return this.settingsExpandedByUser_ || !this.shouldShowMoreSettings_; + }, + /** @private */ close_: function() { this.$.state.transitTo(print_preview_new.State.CLOSING); }, }); +})(); diff --git a/chromium/chrome/browser/resources/print_preview/new/button_css.html b/chromium/chrome/browser/resources/print_preview/new/button_css.html index 77481fa255a..b7dff75c563 100644 --- a/chromium/chrome/browser/resources/print_preview/new/button_css.html +++ b/chromium/chrome/browser/resources/print_preview/new/button_css.html @@ -21,6 +21,15 @@ background-image: linear-gradient(#e7e7e7, #e7e7e7 38%, #d7d7d7); @apply --print-preview-active; } + + button.default:not(:focus):not(:disabled) { + border-color: #808080; + } + + button.default { + font-kerning: none; + font-weight: bold; + } </style> </template> </dom-module> diff --git a/chromium/chrome/browser/resources/print_preview/new/color_settings.html b/chromium/chrome/browser/resources/print_preview/new/color_settings.html index 88adf84c90c..242cf8789c8 100644 --- a/chromium/chrome/browser/resources/print_preview/new/color_settings.html +++ b/chromium/chrome/browser/resources/print_preview/new/color_settings.html @@ -2,6 +2,7 @@ <link rel="import" href="print_preview_shared_css.html"> <link rel="import" href="select_css.html"> +<link rel="import" href="select_behavior.html"> <link rel="import" href="settings_section.html"> <dom-module id="print-preview-color-settings"> @@ -11,8 +12,7 @@ <print-preview-settings-section> <span id="color-label" slot="title">$i18n{optionColor}</span> <div slot="controls"> - <select aria-labelledby="color-label" on-change="onChange_" - disabled$="[[disabled]]"> + <select aria-labelledby="color-label" disabled$="[[disabled]]"> <option value="bw" selected>$i18n{optionBw}</option> <option value="color">$i18n{optionColor}</option> </select> diff --git a/chromium/chrome/browser/resources/print_preview/new/color_settings.js b/chromium/chrome/browser/resources/print_preview/new/color_settings.js index 4c8631aa5ec..40e2e6b547e 100644 --- a/chromium/chrome/browser/resources/print_preview/new/color_settings.js +++ b/chromium/chrome/browser/resources/print_preview/new/color_settings.js @@ -5,7 +5,7 @@ Polymer({ is: 'print-preview-color-settings', - behaviors: [SettingsBehavior], + behaviors: [SettingsBehavior, print_preview_new.SelectBehavior], properties: { disabled: Boolean, @@ -21,8 +21,8 @@ Polymer({ this.$$('select').value = /** @type {boolean} */ (value) ? 'color' : 'bw'; }, - /** @private */ - onChange_: function() { - this.setSetting('color', this.$$('select').value == 'color'); + /** @param {string} value The new select value. */ + onProcessSelectChange: function(value) { + this.setSetting('color', value == 'color'); }, }); diff --git a/chromium/chrome/browser/resources/print_preview/new/compiled_resources2.gyp b/chromium/chrome/browser/resources/print_preview/new/compiled_resources2.gyp deleted file mode 100644 index fee39181adc..00000000000 --- a/chromium/chrome/browser/resources/print_preview/new/compiled_resources2.gyp +++ /dev/null @@ -1,324 +0,0 @@ -# Copyright 2017 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. -{ - 'targets': [ - { - 'target_name': 'app', - 'dependencies': [ - 'header', - 'destination_settings', - 'pages_settings', - 'copies_settings', - 'layout_settings', - 'color_settings', - 'media_size_settings', - 'margins_settings', - 'dpi_settings', - 'scaling_settings', - 'other_options_settings', - 'advanced_options_settings', - 'link_container', - 'preview_area', - 'model', - 'state', - '../compiled_resources2.gyp:cloud_print_interface', - '../compiled_resources2.gyp:native_layer', - '../data/compiled_resources2.gyp:destination', - '../data/compiled_resources2.gyp:destination_store', - '../data/compiled_resources2.gyp:invitation_store', - '../data/compiled_resources2.gyp:document_info', - '../data/compiled_resources2.gyp:measurement_system', - '../data/compiled_resources2.gyp:user_info', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:event_tracker', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:util', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:webui_listener_tracker', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'header', - 'dependencies': [ - '../data/compiled_resources2.gyp:destination', - 'model', - 'settings_behavior', - 'state', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'destination_settings', - 'dependencies': [ - '../data/compiled_resources2.gyp:destination', - '../data/compiled_resources2.gyp:destination_store', - '../data/compiled_resources2.gyp:invitation_store', - '../data/compiled_resources2.gyp:user_info', - 'destination_dialog', - 'state', - '<(DEPTH)/ui/webui/resources/cr_elements/cr_lazy_render/compiled_resources2.gyp:cr_lazy_render', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'pages_settings', - 'dependencies': [ - 'input_behavior', - 'settings_behavior', - '../data/compiled_resources2.gyp:document_info', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'copies_settings', - 'dependencies': [ - 'number_settings_section', - 'settings_behavior', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'layout_settings', - 'dependencies': [ - 'settings_behavior', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'color_settings', - 'dependencies': [ - 'settings_behavior', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'media_size_settings', - 'dependencies': [ - 'settings_behavior', - 'settings_select', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'margins_settings', - 'dependencies': [ - 'settings_behavior', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'dpi_settings', - 'dependencies': [ - 'settings_behavior', - 'settings_select', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'scaling_settings', - 'dependencies': [ - '../data/compiled_resources2.gyp:document_info', - 'number_settings_section', - 'settings_behavior', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'other_options_settings', - 'dependencies': [ - 'settings_behavior', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'advanced_options_settings', - 'dependencies': [ - '../data/compiled_resources2.gyp:destination', - 'advanced_settings_dialog', - 'settings_behavior', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'number_settings_section', - 'dependencies': [ - 'input_behavior', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'settings_select', - 'dependencies': [ - 'settings_behavior', - '../compiled_resources2.gyp:print_preview_utils', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'settings_behavior', - 'dependencies': [ - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'input_behavior', - 'dependencies': [ - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'link_container', - 'dependencies': [ - '../data/compiled_resources2.gyp:destination', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'preview_area', - 'dependencies': [ - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:util', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:web_ui_listener_behavior', - '../../pdf/compiled_resources2.gyp:pdf_scripting_api', - '../compiled_resources2.gyp:native_layer', - '../compiled_resources2.gyp:print_preview_utils', - '../data/compiled_resources2.gyp:destination', - '../data/compiled_resources2.gyp:document_info', - '../data/compiled_resources2.gyp:coordinate2d', - '../data/compiled_resources2.gyp:size', - '../data/compiled_resources2.gyp:margins', - '../data/compiled_resources2.gyp:printable_area', - 'margin_control_container', - 'model', - 'settings_behavior', - 'state', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'margin_control_container', - 'dependencies': [ - '../data/compiled_resources2.gyp:coordinate2d', - '../data/compiled_resources2.gyp:margins', - '../data/compiled_resources2.gyp:measurement_system', - '../data/compiled_resources2.gyp:size', - 'margin_control', - 'settings_behavior', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:event_tracker', - '<(EXTERNS_GYP):pending', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'margin_control', - 'dependencies': [ - '../data/compiled_resources2.gyp:coordinate2d', - '../data/compiled_resources2.gyp:margins', - '../data/compiled_resources2.gyp:size', - 'input_behavior', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'destination_dialog', - 'dependencies': [ - '<(DEPTH)/ui/webui/resources/cr_elements/cr_dialog/compiled_resources2.gyp:cr_dialog', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', - '../data/compiled_resources2.gyp:destination', - '../data/compiled_resources2.gyp:destination_store', - '../data/compiled_resources2.gyp:invitation', - '../data/compiled_resources2.gyp:invitation_store', - '../data/compiled_resources2.gyp:user_info', - 'destination_list', - 'print_preview_search_box', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'destination_list', - 'dependencies': [ - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', - '../compiled_resources2.gyp:native_layer', - '../data/compiled_resources2.gyp:destination', - 'destination_list_item', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'destination_list_item', - 'dependencies': [ - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:load_time_data', - 'highlight_utils', - '../compiled_resources2.gyp:native_layer', - '../data/compiled_resources2.gyp:destination', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'advanced_settings_dialog', - 'dependencies': [ - '<(DEPTH)/ui/webui/resources/cr_elements/cr_dialog/compiled_resources2.gyp:cr_dialog', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior', - '../data/compiled_resources2.gyp:destination', - 'advanced_settings_item', - 'print_preview_search_box', - 'settings_behavior', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'advanced_settings_item', - 'dependencies': [ - 'highlight_utils', - '../compiled_resources2.gyp:print_preview_utils', - '../data/compiled_resources2.gyp:destination', - 'settings_behavior', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'print_preview_search_box', - 'dependencies': [ - '<(DEPTH)/ui/webui/resources/cr_elements/cr_search_field/compiled_resources2.gyp:cr_search_field_behavior', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'highlight_utils', - 'dependencies': [ - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:search_highlight_utils', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'model', - 'dependencies': [ - 'settings_behavior', - '../data/compiled_resources2.gyp:destination', - '../data/compiled_resources2.gyp:document_info', - '../data/compiled_resources2.gyp:margins', - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - }, - { - 'target_name': 'state', - 'dependencies': [ - '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr', - ], - 'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'], - } - ], -} diff --git a/chromium/chrome/browser/resources/print_preview/new/copies_settings.js b/chromium/chrome/browser/resources/print_preview/new/copies_settings.js index 1115ac4c99f..aeaa23f0545 100644 --- a/chromium/chrome/browser/resources/print_preview/new/copies_settings.js +++ b/chromium/chrome/browser/resources/print_preview/new/copies_settings.js @@ -17,22 +17,16 @@ Polymer({ disabled: Boolean, }, - /** @private {boolean} */ - isInitialized_: false, - observers: [ 'onInputChanged_(currentValue_, inputValid_)', - 'onInitialized_(settings.copies.value, settings.collate.value)' + 'onSettingsChanged_(settings.copies.value, settings.collate.value)' ], /** * Updates the input string when the setting has been initialized. * @private */ - onInitialized_: function() { - if (this.isInitialized_) - return; - this.isInitialized_ = true; + onSettingsChanged_: function() { const copies = this.getSetting('copies'); this.currentValue_ = /** @type {string} */ (copies.value.toString()); const collate = this.getSetting('collate'); diff --git a/chromium/chrome/browser/resources/print_preview/new/destination_dialog.html b/chromium/chrome/browser/resources/print_preview/new/destination_dialog.html index e740071ef93..182e131217b 100644 --- a/chromium/chrome/browser/resources/print_preview/new/destination_dialog.html +++ b/chromium/chrome/browser/resources/print_preview/new/destination_dialog.html @@ -3,7 +3,9 @@ <link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> <link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html"> <link rel="import" href="chrome://resources/html/action_link_css.html"> +<link rel="import" href="chrome://resources/html/event_tracker.html"> <link rel="import" href="chrome://resources/html/i18n_behavior.html"> +<link rel="import" href="../metrics.html"> <link rel="import" href="../data/destination.html"> <link rel="import" href="../data/destination_store.html"> <link rel="import" href="../data/invitation.html"> @@ -12,8 +14,10 @@ <link rel="import" href="destination_list.html"> <link rel="import" href="print_preview_search_box.html"> <link rel="import" href="print_preview_shared_css.html"> +<link rel="import" href="provisional_destination_resolver.html"> <link rel="import" href="search_dialog_css.html"> <link rel="import" href="select_css.html"> +<link rel="import" href="strings.html"> <link rel="import" href="throbber_css.html"> <dom-module id="print-preview-destination-dialog"> @@ -21,10 +25,24 @@ <style include="print-preview-shared button action-link select cr-hidden-style search-dialog throbber"> :host #dialog { --cr-dialog-native: { + border-radius: 2px; box-shadow: 0 4px 23px 5px rgba(0, 0, 0, 0.2), 0 2px 6px rgba(0, 0, 0, 0.15); + min-height: calc(100vh - 40px); width: 640px; - } + }; + --cr-dialog-wrapper: { + height: 100%; + }; + --cr-dialog-body: { + -webkit-padding-end: 16px; + -webkit-padding-start: 16px; + padding-bottom: 0; + padding-top: 0; + }; + --cr-dialog-body-container: { + flex: 1; + }; } :host .user-info { @@ -91,15 +109,19 @@ flex-direction: column; } - :host #invitationPromo .invitation-text { - padding-bottom: 12px; + :host #invitationPromo .invitation-buttons { + padding: 12px 0; } - :host #invitationPromo .invitation-reject-button { - -webkit-margin-start: 10px; + print-preview-destination-list { + padding-bottom: 18px; + } + + print-preview-destination-list:last-child { + padding-bottom: 0; } </style> - <cr-dialog id="dialog" on-close="onCloseOrCancel_"> + <cr-dialog id="dialog" on-close="onCloseOrCancel_" show-close-button> <div slot="title"> <div>$i18n{destinationSearchTitle}</div> <div class="user-info" hidden$="[[!userInfo.loggedIn]]"> @@ -122,18 +144,23 @@ </print-preview-search-box> </div> <div slot="body" scrollable> - <print-preview-destination-list - destinations="[[recentDestinationList_]]" - search-query="[[searchQuery_]]" - title="$i18n{recentDestinationsTitle}" - on-destination-selected="onDestinationSelected_"> - </print-preview-destination-list> - <print-preview-destination-list destinations="[[destinations_]]" - has-action-link loading-destinations="[[loadingDestinations_]]" - search-query="[[searchQuery_]]" - title="$i18n{printDestinationsTitle}" - on-destination-selected="onDestinationSelected_"> - </print-preview-destination-list> + <div> + <print-preview-destination-list + destinations="[[recentDestinationList_]]" + search-query="[[searchQuery_]]" + title="$i18n{recentDestinationsTitle}" + on-destination-selected="onDestinationSelected_"> + </print-preview-destination-list> + <print-preview-destination-list destinations="[[destinations_]]" + has-action-link loading-destinations="[[loadingDestinations_]]" + search-query="[[searchQuery_]]" + title="$i18n{printDestinationsTitle}" + on-destination-selected="onDestinationSelected_"> + </print-preview-destination-list> + </div> + <print-preview-provisional-destination-resolver id="provisionalResolver" + destination-store="[[destinationStore]]"> + </print-preview-provisional-destination-resolver> </div> <div slot="button-container"> <button class="cancel-button" on-click="onCancelButtonClick_"> @@ -148,20 +175,15 @@ <div class="close-button"></div> </div> <div class="promo" id="invitationPromo" hidden="[[!invitation_]]"> - <div class="invitation-text" - inner-h-t-m-l="[[getInvitationText_(invitation_)]]"> - </div> + <div inner-h-t-m-l="[[getInvitationText_(invitation_)]]"></div> <div class="invitation-buttons"> - <button class="invitation-accept-button" - on-click="onInvitationAcceptClick_"> + <button on-click="onInvitationAcceptClick_"> [[getAcceptButtonText_(invitation_)]] </button> - <button class="invitation-reject-button" - on-click="onInvitationRejectClick_"> - $i18n{reject} - </button> + <button on-click="onInvitationRejectClick_">$i18n{reject}</button> <div id="invitation-process-throbber" class="throbber" hidden></div> </div> + <div>$i18nRaw{registerPrinterInformationMessage}</div> </div> </div> </cr-dialog> diff --git a/chromium/chrome/browser/resources/print_preview/new/destination_dialog.js b/chromium/chrome/browser/resources/print_preview/new/destination_dialog.js index ad5fc91a47d..8500c9fd721 100644 --- a/chromium/chrome/browser/resources/print_preview/new/destination_dialog.js +++ b/chromium/chrome/browser/resources/print_preview/new/destination_dialog.js @@ -36,6 +36,7 @@ Polymer({ showCloudPrintPromo: { type: Boolean, notify: true, + observer: 'onShowCloudPrintPromoChanged_', }, /** @private {!Array<!print_preview.Destination>} */ @@ -73,6 +74,14 @@ Polymer({ /** @private {!EventTracker} */ tracker_: new EventTracker(), + /** @private {!print_preview.DestinationSearchMetricsContext} */ + metrics_: new print_preview.DestinationSearchMetricsContext(), + + // <if expr="chromeos"> + /** @private {?print_preview.Destination} */ + destinationInConfiguring_: null, + // </if> + /** @override */ ready: function() { this.$$('.promo-text').innerHTML = @@ -81,6 +90,8 @@ Polymer({ attrs: { 'is': (node, v) => v == 'action-link', 'class': (node, v) => v == 'sign-in', + 'tabindex': (node, v) => v == '0', + 'role': (node, v) => v == 'link', }, }); }, @@ -165,6 +176,13 @@ Polymer({ onCloseOrCancel_: function() { if (this.searchQuery_) this.$.searchBox.setValue(''); + if (this.$.dialog.getNative().returnValue == 'success') { + this.metrics_.record(print_preview.Metrics.DestinationSearchBucket + .DESTINATION_CLOSED_CHANGED); + } else { + this.metrics_.record(print_preview.Metrics.DestinationSearchBucket + .DESTINATION_CLOSED_UNCHANGED); + } }, /** @private */ @@ -173,12 +191,71 @@ Polymer({ }, /** - * @param {!CustomEvent} e Event containing the selected destination. + * @param {!CustomEvent} e Event containing the selected destination list item + * element. * @private */ onDestinationSelected_: function(e) { - this.destinationStore.selectDestination( - /** @type {!print_preview.Destination} */ (e.detail)); + const listItem = + /** @type {!PrintPreviewDestinationListItemElement} */ (e.detail); + const destination = listItem.destination; + + // ChromeOS local destinations that don't have capabilities need to be + // configured before selecting, and provisional destinations need to be + // resolved. Other destinations can be selected. + if (destination.readyForSelection) { + this.selectDestination_(destination); + return; + } + + // Provisional destinations + if (destination.isProvisional) { + this.$.provisionalResolver.resolveDestination(destination) + .then(this.selectDestination_.bind(this)) + .catch(function() { + console.error( + 'Failed to resolve provisional destination: ' + destination.id); + }) + .then(() => { + if (this.$.dialog.open && !!listItem && !listItem.hidden) { + listItem.focus(); + } + }); + return; + } + + // <if expr="chromeos"> + // Destination must be a CrOS local destination that needs to be set up. + // The user is only allowed to set up printer at one time. + if (this.destinationInConfiguring_) + return; + + // Show the configuring status to the user and resolve the destination. + listItem.onConfigureRequestAccepted(); + this.destinationInConfiguring_ = destination; + this.destinationStore.resolveCrosDestination(destination) + .then( + response => { + this.destinationInConfiguring_ = null; + listItem.onConfigureComplete(response.success); + if (response.success) { + destination.capabilities = response.capabilities; + this.selectDestination_(destination); + } + }, + () => { + this.destinationInConfiguring_ = null; + listItem.onConfigureComplete(false); + }); + // </if> + }, + + /** + * @param {!print_preview.Destination} destination The destination to select. + * @private + */ + selectDestination_: function(destination) { + this.destinationStore.selectDestination(destination); this.$.dialog.close(); }, @@ -186,6 +263,8 @@ Polymer({ this.loadingDestinations_ = this.destinationStore.isPrintDestinationSearchInProgress; this.$.dialog.showModal(); + this.metrics_.record( + print_preview.Metrics.DestinationSearchBucket.DESTINATION_SHOWN); }, /** @return {boolean} Whether the dialog is open. */ @@ -200,6 +279,8 @@ Polymer({ /** @private */ onSignInClick_: function() { + this.metrics_.record( + print_preview.Metrics.DestinationSearchBucket.SIGNIN_TRIGGERED); print_preview.NativeLayer.getInstance().signIn(false).then(() => { this.destinationStore.onDestinationsReload(); }); @@ -218,6 +299,10 @@ Polymer({ const invitations = this.userInfo.activeUser ? this.invitationStore.invitations(this.userInfo.activeUser) : []; + if (this.invitation_ != invitations[0]) { + this.metrics_.record( + print_preview.Metrics.DestinationSearchBucket.INVITATION_AVAILABLE); + } this.invitation_ = invitations.length > 0 ? invitations[0] : null; }, @@ -260,12 +345,16 @@ Polymer({ /** @private */ onInvitationAcceptClick_: function() { + this.metrics_.record( + print_preview.Metrics.DestinationSearchBucket.INVITATION_ACCEPTED); this.invitationStore.processInvitation(assert(this.invitation_), true); this.updateInvitations_(); }, /** @private */ onInvitationRejectClick_: function() { + this.metrics_.record( + print_preview.Metrics.DestinationSearchBucket.INVITATION_REJECTED); this.invitationStore.processInvitation(assert(this.invitation_), false); this.updateInvitations_(); }, @@ -281,6 +370,8 @@ Polymer({ this.notifyPath('userInfo.loggedIn'); this.destinationStore.reloadUserCookieBasedDestinations(); this.invitationStore.startLoadingInvitations(); + this.metrics_.record( + print_preview.Metrics.DestinationSearchBucket.ACCOUNT_CHANGED); } else { print_preview.NativeLayer.getInstance().signIn(true).then( this.destinationStore.onDestinationsReload.bind( @@ -292,6 +383,16 @@ Polymer({ break; } } + this.metrics_.record( + print_preview.Metrics.DestinationSearchBucket.ADD_ACCOUNT_SELECTED); + } + }, + + /** @private */ + onShowCloudPrintPromoChanged_: function() { + if (this.showCloudPrintPromo) { + this.metrics_.record( + print_preview.Metrics.DestinationSearchBucket.SIGNIN_PROMPT); } }, }); diff --git a/chromium/chrome/browser/resources/print_preview/new/destination_list.html b/chromium/chrome/browser/resources/print_preview/new/destination_list.html index 3a008a5df4d..69416e0e6d4 100644 --- a/chromium/chrome/browser/resources/print_preview/new/destination_list.html +++ b/chromium/chrome/browser/resources/print_preview/new/destination_list.html @@ -7,13 +7,14 @@ <link rel="import" href="../data/destination.html"> <link rel="import" href="destination_list_item.html"> <link rel="import" href="print_preview_shared_css.html"> +<link rel="import" href="strings.html"> <link rel="import" href="throbber_css.html"> <dom-module id="print-preview-destination-list"> <template> <style include="print-preview-shared action-link cr-hidden-style throbber"> :host { - padding: 0 14px 18px; + display: block; user-select: none; } diff --git a/chromium/chrome/browser/resources/print_preview/new/destination_list.js b/chromium/chrome/browser/resources/print_preview/new/destination_list.js index b83f9309149..3f8cd873cbe 100644 --- a/chromium/chrome/browser/resources/print_preview/new/destination_list.js +++ b/chromium/chrome/browser/resources/print_preview/new/destination_list.js @@ -129,10 +129,7 @@ Polymer({ * @private */ onDestinationSelected_: function(e) { - this.fire( - 'destination-selected', - /** @type {PrintPreviewDestinationListItemElement} */ - (e.target).destination); + this.fire('destination-selected', e.target); }, }); })(); diff --git a/chromium/chrome/browser/resources/print_preview/new/destination_list_item.html b/chromium/chrome/browser/resources/print_preview/new/destination_list_item.html index 7fe1155fbc8..702662e9541 100644 --- a/chromium/chrome/browser/resources/print_preview/new/destination_list_item.html +++ b/chromium/chrome/browser/resources/print_preview/new/destination_list_item.html @@ -1,11 +1,13 @@ <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html"> +<link rel="import" href="chrome://resources/html/cr.html"> <link rel="import" href="chrome://resources/html/load_time_data.html"> <link rel="import" href="../native_layer.html"> <link rel="import" href="../data/destination.html"> <link rel="import" href="highlight_utils.html"> <link rel="import" href="print_preview_shared_css.html"> +<link rel="import" href="strings.html"> <dom-module id="print-preview-destination-list-item"> <template> @@ -49,11 +51,6 @@ color: rgb(51, 103, 214); } - :host .register-promo { - -webkit-margin-start: 1em; - flex: 0 0 auto; - } - :host .extension-controlled-indicator { display: flex; flex: 1; @@ -110,11 +107,6 @@ on-click="onLearnMoreLinkClick_"> $i18n{learnMore} </a> - <span class="register-promo" hidden$="[[!destination.isUnregistered]]"> - <button class="register-promo-button"> - $i18n{registerPromoButtonText} - </button> - </span> <span class="extension-controlled-indicator" hidden$="[[!destination.isExtension]]"> <span class="extension-name searchable"> @@ -123,13 +115,17 @@ <span class="extension-icon" role="button" tabindex="0"></span> </span> <if expr="chromeos"> - <span class="configuring-in-progress-text" hidden> + <span class="configuring-in-progress-text" + hidden$="[[!checkConfigurationStatus_(statusEnum_.IN_PROGRESS, + configurationStatus_)]]"> $i18n{configuringInProgressText} <span class="configuring-text-jumping-dots"> <span>.</span><span>.</span><span>.</span> </span> </span> - <span class="configuring-failed-text" hidden> + <span class="configuring-failed-text" + hidden$="[[!checkConfigurationStatus_(statusEnum_.FAILED, + configurationStatus_)]]"> $i18n{configuringFailedText} </span> </if> diff --git a/chromium/chrome/browser/resources/print_preview/new/destination_list_item.js b/chromium/chrome/browser/resources/print_preview/new/destination_list_item.js index b68a211d14d..3c3df29119f 100644 --- a/chromium/chrome/browser/resources/print_preview/new/destination_list_item.js +++ b/chromium/chrome/browser/resources/print_preview/new/destination_list_item.js @@ -2,6 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +cr.exportPath('print_preview_new'); + +// <if expr="chromeos"> +/** @enum {number} */ +print_preview_new.DestinationConfigStatus = { + IDLE: 0, + IN_PROGRESS: 1, + FAILED: 2, +}; +// </if> + Polymer({ is: 'print-preview-destination-list-item', @@ -20,11 +31,29 @@ Polymer({ /** @private {string} */ searchHint_: String, + + // <if expr="chromeos"> + /** @private {!print_preview_new.DestinationConfigStatus} */ + configurationStatus_: { + type: Number, + value: print_preview_new.DestinationConfigStatus.IDLE, + }, + + /** + * Mirroring the enum so that it can be used from HTML bindings. + * @private + */ + statusEnum_: { + type: Object, + value: print_preview_new.DestinationConfigStatus, + }, + // </if> }, observers: [ 'onDestinationPropertiesChange_(' + - 'destination.displayName, destination.isOfflineOrInvalid)', + 'destination.displayName, destination.isOfflineOrInvalid, ' + + 'destination.isExtension)', ], /** @private {boolean} */ @@ -34,6 +63,14 @@ Polymer({ onDestinationPropertiesChange_: function() { this.title = this.destination.displayName; this.stale_ = this.destination.isOfflineOrInvalid; + if (this.destination.isExtension) { + const icon = this.$$('.extension-icon'); + icon.style.backgroundImage = '-webkit-image-set(' + + 'url(chrome://extension-icon/' + this.destination.extensionId + + '/24/1) 1x,' + + 'url(chrome://extension-icon/' + this.destination.extensionId + + '/48/1) 2x)'; + } }, /** @private */ @@ -42,6 +79,40 @@ Polymer({ loadTimeData.getString('gcpCertificateErrorLearnMoreURL')); }, + // <if expr="chromeos"> + /** + * Called if the printer configuration request is accepted. Show the waiting + * message to the user as the configuration might take longer than expected. + */ + onConfigureRequestAccepted: function() { + // It must be a Chrome OS CUPS printer which hasn't been set up before. + assert( + this.destination.origin == print_preview.DestinationOrigin.CROS && + !this.destination.capabilities); + this.configurationStatus_ = + print_preview_new.DestinationConfigStatus.IN_PROGRESS; + }, + + /** + * Called when the printer configuration request completes. + * @param {boolean} success Whether configuration was successful. + */ + onConfigureComplete: function(success) { + this.configurationStatus_ = success ? + print_preview_new.DestinationConfigStatus.IDLE : + print_preview_new.DestinationConfigStatus.FAILED; + }, + + /** + * @param {!print_preview_new.DestinationConfigStatus} status + * @return {boolean} Whether the current configuration status is |status|. + * @private + */ + checkConfigurationStatus_: function(status) { + return this.configurationStatus_ == status; + }, + // </if> + update: function() { this.updateSearchHint_(); this.updateHighlighting_(); diff --git a/chromium/chrome/browser/resources/print_preview/new/destination_settings.html b/chromium/chrome/browser/resources/print_preview/new/destination_settings.html index a5edebb475f..f5cf7145087 100644 --- a/chromium/chrome/browser/resources/print_preview/new/destination_settings.html +++ b/chromium/chrome/browser/resources/print_preview/new/destination_settings.html @@ -13,6 +13,7 @@ <link rel="import" href="print_preview_shared_css.html"> <link rel="import" href="throbber_css.html"> <link rel="import" href="settings_section.html"> +<link rel="import" href="strings.html"> <dom-module id="print-preview-destination-settings"> <template> diff --git a/chromium/chrome/browser/resources/print_preview/new/dpi_settings.html b/chromium/chrome/browser/resources/print_preview/new/dpi_settings.html index 1714dc87c91..3511643588a 100644 --- a/chromium/chrome/browser/resources/print_preview/new/dpi_settings.html +++ b/chromium/chrome/browser/resources/print_preview/new/dpi_settings.html @@ -5,6 +5,7 @@ <link rel="import" href="settings_behavior.html"> <link rel="import" href="settings_section.html"> <link rel="import" href="settings_select.html"> +<link rel="import" href="strings.html"> <dom-module id="print-preview-dpi-settings"> <template> diff --git a/chromium/chrome/browser/resources/print_preview/new/header.html b/chromium/chrome/browser/resources/print_preview/new/header.html index 70468e7670d..957e1802e57 100644 --- a/chromium/chrome/browser/resources/print_preview/new/header.html +++ b/chromium/chrome/browser/resources/print_preview/new/header.html @@ -1,5 +1,6 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/html/assert.html"> <link rel="import" href="chrome://resources/html/cr.html"> <link rel="import" href="button_css.html"> <link rel="import" href="../data/destination.html"> diff --git a/chromium/chrome/browser/resources/print_preview/new/header.js b/chromium/chrome/browser/resources/print_preview/new/header.js index 4c5e0240e79..2801f38b453 100644 --- a/chromium/chrome/browser/resources/print_preview/new/header.js +++ b/chromium/chrome/browser/resources/print_preview/new/header.js @@ -49,7 +49,8 @@ Polymer({ observers: ['update_(settings.copies.value, settings.duplex.value, ' + - 'settings.pages.value, state)'], + 'settings.pages.value, settings.pagesPerSheet.value, state, ' + + 'destination.id)'], /** @private */ onPrintClick_: function() { @@ -94,6 +95,14 @@ Polymer({ numSheets = Math.ceil(numPages / 2); } + const pagesPerSheet = parseInt(this.getSettingValue('pagesPerSheet'), 10); + + if (!Number.isNaN(pagesPerSheet)) { + assert(pagesPerSheet > 0); + numSheets = Math.ceil(numSheets / pagesPerSheet); + numPages = Math.ceil(numPages / pagesPerSheet); + } + const copies = parseInt(this.getSettingValue('copies'), 10); numSheets *= copies; numPages *= copies; @@ -151,19 +160,10 @@ Polymer({ * @private */ getSummary_: function(labelInfo) { - let html = null; - if (labelInfo.numPages != labelInfo.numSheets) { - html = loadTimeData.getStringF( - 'printPreviewSummaryFormatLong', - '<b>' + labelInfo.numSheets.toLocaleString() + '</b>', - '<b>' + labelInfo.summaryLabel + '</b>', - labelInfo.numPages.toLocaleString(), labelInfo.pagesLabel); - } else { - html = loadTimeData.getStringF( - 'printPreviewSummaryFormatShort', - '<b>' + labelInfo.numSheets.toLocaleString() + '</b>', - '<b>' + labelInfo.summaryLabel + '</b>'); - } + let html = loadTimeData.getStringF( + 'printPreviewSummaryFormatShort', + '<b>' + labelInfo.numSheets.toLocaleString() + '</b>', + '<b>' + labelInfo.summaryLabel + '</b>'); // Removing extra spaces from within the string. html = html.replace(/\s{2,}/g, ' '); @@ -176,12 +176,6 @@ Polymer({ * @private */ getSummaryLabel_: function(labelInfo) { - if (labelInfo.numPages != labelInfo.numSheets) { - return loadTimeData.getStringF( - 'printPreviewSummaryFormatLong', labelInfo.numSheets.toLocaleString(), - labelInfo.summaryLabel, labelInfo.numPages.toLocaleString(), - labelInfo.pagesLabel); - } return loadTimeData.getStringF( 'printPreviewSummaryFormatShort', labelInfo.numSheets.toLocaleString(), labelInfo.summaryLabel); diff --git a/chromium/chrome/browser/resources/print_preview/new/input_behavior.js b/chromium/chrome/browser/resources/print_preview/new/input_behavior.js index bd63ce05c44..e2aec6d9928 100644 --- a/chromium/chrome/browser/resources/print_preview/new/input_behavior.js +++ b/chromium/chrome/browser/resources/print_preview/new/input_behavior.js @@ -84,7 +84,12 @@ cr.define('print_preview_new', function() { } }, - /** Called to clear the timeout and update the value. */ + // Resets the lastValue_ so that future inputs trigger a change event. + resetString: function() { + this.lastValue_ = null; + }, + + // Called to clear the timeout and update the value. resetAndUpdate: function() { if (this.timeout_) { clearTimeout(this.timeout_); diff --git a/chromium/chrome/browser/resources/print_preview/new/layout_settings.html b/chromium/chrome/browser/resources/print_preview/new/layout_settings.html index 0b0e7ae3098..dc7b9710046 100644 --- a/chromium/chrome/browser/resources/print_preview/new/layout_settings.html +++ b/chromium/chrome/browser/resources/print_preview/new/layout_settings.html @@ -2,6 +2,7 @@ <link rel="import" href="print_preview_shared_css.html"> <link rel="import" href="select_css.html"> +<link rel="import" href="select_behavior.html"> <link rel="import" href="settings_behavior.html"> <link rel="import" href="settings_section.html"> @@ -11,8 +12,7 @@ <print-preview-settings-section> <span id="layout-label" slot="title">$i18n{layoutLabel}</span> <div slot="controls"> - <select aria-labelledby="layout-label" on-change="onChange_" - disabled$="[[disabled]]"> + <select aria-labelledby="layout-label" disabled$="[[disabled]]"> <option value="portrait" selected>$i18n{optionPortrait}</option> <option value="landscape">$i18n{optionLandscape}</option> </select> diff --git a/chromium/chrome/browser/resources/print_preview/new/layout_settings.js b/chromium/chrome/browser/resources/print_preview/new/layout_settings.js index b84fbe2bd00..c5cb3e5fc10 100644 --- a/chromium/chrome/browser/resources/print_preview/new/layout_settings.js +++ b/chromium/chrome/browser/resources/print_preview/new/layout_settings.js @@ -5,7 +5,7 @@ Polymer({ is: 'print-preview-layout-settings', - behaviors: [SettingsBehavior], + behaviors: [SettingsBehavior, print_preview_new.SelectBehavior], properties: { disabled: Boolean, @@ -22,8 +22,8 @@ Polymer({ /** @type {boolean} */ (value) ? 'landscape' : 'portrait'; }, - /** @private */ - onChange_: function() { - this.setSetting('layout', this.$$('select').value == 'landscape'); + /** @param {string} value The new select value. */ + onProcessSelectChange: function(value) { + this.setSetting('layout', value == 'landscape'); }, }); diff --git a/chromium/chrome/browser/resources/print_preview/new/link_container.html b/chromium/chrome/browser/resources/print_preview/new/link_container.html index 2fa93003579..5fca9837360 100644 --- a/chromium/chrome/browser/resources/print_preview/new/link_container.html +++ b/chromium/chrome/browser/resources/print_preview/new/link_container.html @@ -1,6 +1,7 @@ <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html"> +<link rel="import" href="chrome://resources/html/action_link.html"> <link rel="import" href="chrome://resources/html/action_link_css.html"> <link rel="import" href="chrome://resources/html/cr.html"> <link rel="import" href="../data/destination.html"> @@ -27,6 +28,10 @@ :host > div > a { margin: 8px 20px; } + + :host #systemDialogLink { + margin-top: 14px; + } </style> <div> <a is="action-link" id="systemDialogLink" disabled="[[disabled]]" diff --git a/chromium/chrome/browser/resources/print_preview/new/margins_settings.html b/chromium/chrome/browser/resources/print_preview/new/margins_settings.html index 7bf74d1b5a3..87121b453d7 100644 --- a/chromium/chrome/browser/resources/print_preview/new/margins_settings.html +++ b/chromium/chrome/browser/resources/print_preview/new/margins_settings.html @@ -2,6 +2,7 @@ <link rel="import" href="print_preview_shared_css.html"> <link rel="import" href="select_css.html"> +<link rel="import" href="select_behavior.html"> <link rel="import" href="settings_behavior.html"> <link rel="import" href="settings_section.html"> @@ -12,8 +13,7 @@ <print-preview-settings-section> <span id="margins-label" slot="title">$i18n{marginsLabel}</span> <div slot="controls"> - <select aria-labelledby="margins-label" on-change="onChange_" - disabled$="[[disabled]]"> + <select aria-labelledby="margins-label" disabled$="[[disabled]]"> <!-- The order of these options must match the natural order of their values, which come from print_preview.ticket_items.MarginsTypeValue. --> diff --git a/chromium/chrome/browser/resources/print_preview/new/margins_settings.js b/chromium/chrome/browser/resources/print_preview/new/margins_settings.js index c641b40c73b..9145663aab0 100644 --- a/chromium/chrome/browser/resources/print_preview/new/margins_settings.js +++ b/chromium/chrome/browser/resources/print_preview/new/margins_settings.js @@ -5,7 +5,7 @@ Polymer({ is: 'print-preview-margins-settings', - behaviors: [SettingsBehavior], + behaviors: [SettingsBehavior, print_preview_new.SelectBehavior], properties: { disabled: Boolean, @@ -21,8 +21,8 @@ Polymer({ this.$$('select').value = /** @type {string} */ (value).toString(); }, - /** @private */ - onChange_: function() { - this.setSetting('margins', parseInt(this.$$('select').value, 10)); + /** @param {string} value The new select value. */ + onProcessSelectChange: function(value) { + this.setSetting('margins', parseInt(value, 10)); }, }); diff --git a/chromium/chrome/browser/resources/print_preview/new/model.js b/chromium/chrome/browser/resources/print_preview/new/model.js index c4c71e6e2ae..a7ffc573dc7 100644 --- a/chromium/chrome/browser/resources/print_preview/new/model.js +++ b/chromium/chrome/browser/resources/print_preview/new/model.js @@ -219,6 +219,13 @@ Polymer({ available: true, key: 'vendorOptions', }, + pagesPerSheet: { + value: 1, + unavailableValue: 1, + valid: true, + available: true, + key: '', + }, // This does not represent a real setting value, and is used only to // expose the availability of the other options settings section. otherOptions: { @@ -264,14 +271,13 @@ Polymer({ }, observers: [ - 'updateSettings_(' + - 'destination.id, destination.capabilities, ' + + 'updateSettingsFromDestination_(destination.capabilities)', + 'updateSettingsAvailabilityFromDocumentInfo_(' + 'documentInfo.isModifiable, documentInfo.hasCssMediaStyles,' + 'documentInfo.hasSelection)', 'updateHeaderFooterAvailable_(' + - 'documentInfo.isModifiable, documentInfo.margins, ' + - 'settings.margins.value, settings.customMargins.value, ' + - 'settings.mediaSize.value)', + 'documentInfo.margins, settings.margins.value, ' + + 'settings.customMargins.value, settings.mediaSize.value)', 'updateRecentDestinations_(destination, destination.capabilities)', 'stickySettingsChanged_(' + 'settings.collate.value, settings.layout.value, settings.color.value,' + @@ -293,22 +299,26 @@ Polymer({ /** * Updates the availability of the settings sections and values of dpi and - * media size settings. + * media size settings based on the destination capabilities. * @private */ - updateSettings_: function() { - const caps = (!!this.destination && !!this.destination.capabilities) ? - this.destination.capabilities.printer : - null; - this.updateSettingsAvailability_(caps); - - if (!caps) + updateSettingsFromDestination_: function() { + if (!this.destination) return; if (this.destination.capabilities == this.lastDestinationCapabilities_) return; this.lastDestinationCapabilities_ = this.destination.capabilities; + + const caps = !!this.destination.capabilities ? + this.destination.capabilities.printer : + null; + this.updateSettingsAvailabilityFromDestination_(caps); + + if (!caps) + return; + this.updateSettingsValues_(caps); }, @@ -316,31 +326,54 @@ Polymer({ * @param {?print_preview.CddCapabilities} caps The printer capabilities. * @private */ - updateSettingsAvailability_: function(caps) { - const isSaveToPdf = this.destination.id == - print_preview.Destination.GooglePromotedId.SAVE_AS_PDF; - const knownSizeToSaveAsPdf = isSaveToPdf && - (!this.documentInfo.isModifiable || - this.documentInfo.hasCssMediaStyles); + updateSettingsAvailabilityFromDestination_: function(caps) { this.set('settings.copies.available', !!caps && !!(caps.copies)); this.set('settings.collate.available', !!caps && !!(caps.collate)); this.set('settings.layout.available', this.isLayoutAvailable_(caps)); this.set('settings.color.available', this.destination.hasColorCapability); - this.set('settings.margins.available', this.documentInfo.isModifiable); - this.set( - 'settings.customMargins.available', this.documentInfo.isModifiable); - this.set( - 'settings.mediaSize.available', - !!caps && !!caps.media_size && !knownSizeToSaveAsPdf); this.set( 'settings.dpi.available', !!caps && !!caps.dpi && !!caps.dpi.option && caps.dpi.option.length > 1); + this.set('settings.duplex.available', !!caps && !!caps.duplex); + this.set( + 'settings.vendorItems.available', !!caps && !!caps.vendor_capability); + + if (this.documentInfo) + this.updateSettingsAvailabilityFromDestinationAndDocumentInfo_(); + }, + + /** @private */ + updateSettingsAvailabilityFromDestinationAndDocumentInfo_: function() { + const knownSizeToSaveAsPdf = this.destination.id == + print_preview.Destination.GooglePromotedId.SAVE_AS_PDF && + (!this.documentInfo.isModifiable || + this.documentInfo.hasCssMediaStyles); this.set( 'settings.fitToPage.available', - !this.documentInfo.isModifiable && !isSaveToPdf); + !knownSizeToSaveAsPdf && !this.documentInfo.isModifiable); this.set('settings.scaling.available', !knownSizeToSaveAsPdf); - this.set('settings.duplex.available', !!caps && !!caps.duplex); + const caps = (!!this.destination && !!this.destination.capabilities) ? + this.destination.capabilities.printer : + null; + this.set( + 'settings.mediaSize.available', + !!caps && !!caps.media_size && !knownSizeToSaveAsPdf); + this.set('settings.layout.available', this.isLayoutAvailable_(caps)); + this.set( + 'settings.otherOptions.available', + this.settings.duplex.available || + this.settings.cssBackground.available || + this.settings.selectionOnly.available || + this.settings.headerFooter.available || + this.settings.rasterize.available); + }, + + /** @private */ + updateSettingsAvailabilityFromDocumentInfo_: function() { + this.set('settings.margins.available', this.documentInfo.isModifiable); + this.set( + 'settings.customMargins.available', this.documentInfo.isModifiable); this.set( 'settings.cssBackground.available', this.documentInfo.isModifiable); this.set( @@ -351,15 +384,9 @@ Polymer({ this.set( 'settings.rasterize.available', !this.documentInfo.isModifiable && !cr.isWindows && !cr.isMac); - this.set( - 'settings.otherOptions.available', - this.settings.duplex.available || - this.settings.cssBackground.available || - this.settings.selectionOnly.available || - this.settings.headerFooter.available || - this.settings.rasterize.available); - this.set( - 'settings.vendorItems.available', !!caps && !!caps.vendor_capability); + + if (this.destination) + this.updateSettingsAvailabilityFromDestinationAndDocumentInfo_(); }, /** @private */ @@ -441,6 +468,7 @@ Polymer({ const defaultOption = caps.media_size.option.find(o => !!o.is_default); this.set('settings.mediaSize.value', defaultOption); } + if (this.settings.dpi.available) { const defaultOption = caps.dpi.option.find(o => !!o.is_default); this.set('settings.dpi.value', defaultOption); @@ -449,6 +477,25 @@ Polymer({ this.set('settings.dpi.unavailableValue', caps.dpi.option[0]); } + if (this.settings.color.available) { + const defaultOption = this.destination.defaultColorOption; + if (defaultOption) { + this.set( + 'settings.color.value', + !['STANDARD_MONOCHROME', 'CUSTOM_MONOCHROME'].includes( + defaultOption.type)); + } + } else if ( + caps && caps.color && caps.color.option && + caps.color.option.length > 0) { + this.set( + 'settings.color.unavailableValue', + !['STANDARD_MONOCHROME', 'CUSTOM_MONOCHROME'].includes( + caps.color.option[0].type)); + } else { // if no color capability is reported, assume black and white. + this.set('settings.color.unavailableValue', false); + } + if (this.settings.vendorItems.available) { const vendorSettings = {}; for (const item of caps.vendor_capability) { @@ -615,6 +662,7 @@ Polymer({ printWithExtension: destination.isExtension, rasterizePDF: this.getSettingValue('rasterize'), scaleFactor: parseInt(this.getSettingValue('scaling'), 10), + pagesPerSheet: this.getSettingValue('pagesPerSheet'), dpiHorizontal: (dpi && 'horizontal_dpi' in dpi) ? dpi.horizontal_dpi : 0, dpiVertical: (dpi && 'vertical_dpi' in dpi) ? dpi.vertical_dpi : 0, deviceName: destination.id, diff --git a/chromium/chrome/browser/resources/print_preview/new/more_settings.html b/chromium/chrome/browser/resources/print_preview/new/more_settings.html new file mode 100644 index 00000000000..527973849f0 --- /dev/null +++ b/chromium/chrome/browser/resources/print_preview/new/more_settings.html @@ -0,0 +1,53 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> + +<link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html"> +<link rel="import" href="chrome://resources/html/action_link.html"> +<link rel="import" href="chrome://resources/html/action_link_css.html"> +<link rel="import" href="chrome://resources/html/i18n_behavior.html"> +<link rel="import" href="../metrics.html"> +<link rel="import" href="strings.html"> + +<dom-module id="print-preview-more-settings"> + <template> + <style include="action-link cr-hidden-style"> + :host { + align-items: center; + background-color: #f6f6f6; + --border: 1px solid #e1e1e1; + border-bottom: var(--border); + border-top: var(--border); + cursor: pointer; + display: flex; + margin-top: 4px; + min-height: 38px; + padding: 5px 20px; + } + + :host([hidden]) { + display: none; + } + + :host #label { + flex: 1; + } + + :host #icon { + height: 25px; + width: 25px; + } + + :host .minus-icon { + background-image: url(chrome://resources/images/icon_expand_less.svg); + } + + :host .plus-icon { + background-image: url(chrome://resources/images/icon_expand_more.svg); + } + </style> + <a id="label" is="action-link" disabled="[[disabled]]"> + [[getLabelText_(settingsExpandedByUser)]] + </a> + <div id="icon" class$="[[getIconClass_(settingsExpandedByUser)]]"></div> + </template> + <script src="more_settings.js"></script> +</dom-module> diff --git a/chromium/chrome/browser/resources/print_preview/new/more_settings.js b/chromium/chrome/browser/resources/print_preview/new/more_settings.js new file mode 100644 index 00000000000..431625fbea2 --- /dev/null +++ b/chromium/chrome/browser/resources/print_preview/new/more_settings.js @@ -0,0 +1,52 @@ +// Copyright 2018 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. + +Polymer({ + is: 'print-preview-more-settings', + + behaviors: [I18nBehavior], + + properties: { + settingsExpandedByUser: { + type: Boolean, + notify: true, + }, + + disabled: Boolean, + }, + + listeners: { + 'click': 'onMoreSettingsClick_', + }, + + /** @private {!print_preview.PrintSettingsUiMetricsContext} */ + metrics_: new print_preview.PrintSettingsUiMetricsContext(), + + /** + * @return {string} 'plus-icon' if settings are collapsed, 'minus-icon' if + * they are expanded. + * @private + */ + getIconClass_: function() { + return this.settingsExpandedByUser ? 'minus-icon' : 'plus-icon'; + }, + + /** + * @return {string} The text to display on the label. + * @private + */ + getLabelText_: function() { + return this.i18n( + this.settingsExpandedByUser ? 'lessOptionsLabel' : 'moreOptionsLabel'); + }, + + /** @private */ + onMoreSettingsClick_: function() { + this.settingsExpandedByUser = !this.settingsExpandedByUser; + this.metrics_.record( + this.settingsExpandedByUser ? + print_preview.Metrics.PrintSettingsUiBucket.MORE_SETTINGS_CLICKED : + print_preview.Metrics.PrintSettingsUiBucket.LESS_SETTINGS_CLICKED); + }, +}); diff --git a/chromium/chrome/browser/resources/print_preview/new/number_settings_section.js b/chromium/chrome/browser/resources/print_preview/new/number_settings_section.js index 1e52be5f263..2615d7c82d1 100644 --- a/chromium/chrome/browser/resources/print_preview/new/number_settings_section.js +++ b/chromium/chrome/browser/resources/print_preview/new/number_settings_section.js @@ -86,13 +86,13 @@ Polymer({ /** @private */ onInputChanged_: function() { this.inputValid = this.computeValid_(); - if (this.inputValid) - this.currentValue = this.inputString_; + this.currentValue = this.inputString_; }, /** @private */ onCurrentValueChanged_: function() { this.inputString_ = this.currentValue; + this.resetString(); }, /** diff --git a/chromium/chrome/browser/resources/print_preview/new/other_options_settings.html b/chromium/chrome/browser/resources/print_preview/new/other_options_settings.html index afd187b856d..d5ee2d569ef 100644 --- a/chromium/chrome/browser/resources/print_preview/new/other_options_settings.html +++ b/chromium/chrome/browser/resources/print_preview/new/other_options_settings.html @@ -16,37 +16,39 @@ <print-preview-settings-section class="multirow-controls"> <span slot="title" id="options-label">$i18n{optionsLabel}</span> <div slot="controls" class="checkbox"> - <label aria-live="polite" - hidden$="[[!settings.headerFooter.available]]"> - <input type="checkbox" id="header-footer" + <label hidden$="[[!settings.headerFooter.available]]" + aria-live="polite"> + <input type="checkbox" id="headerFooter" disabled$="[[disabled]]" on-change="onHeaderFooterChange_" checked$="[[settings.headerFooter.value]]"> <span>$i18n{optionHeaderFooter}</span> </label> - <label aria-live="polite" hidden$="[[!settings.duplex.available]]"> + <label hidden$="[[!settings.duplex.available]]" + aria-live="polite"> <input type="checkbox" id="duplex" on-change="onDuplexChange_" disabled$="[[disabled]]" checked$="[[settings.duplex.value]]"> <span>$i18n{optionTwoSided}</span> </label> - <label aria-live="polite" - hidden$="[[!settings.cssBackground.available]]"> - <input type="checkbox" id="css-background" + <label hidden$="[[!settings.cssBackground.available]]" + aria-live="polite"> + <input type="checkbox" id="cssBackground" on-change="onCssBackgroundChange_" disabled$="[[disabled]]" checked$="[[settings.cssBackground.value]]"> <span>$i18n{optionBackgroundColorsAndImages}</span> </label> - <label aria-live="polite" hidden$="[[!settings.rasterize.available]]"> + <label hidden$="[[!settings.rasterize.available]]" + aria-live="polite"> <input type="checkbox" id="rasterize" disabled$="[[disabled]]" on-change="onRasterizeChange_" checked$="[[settings.rasterize.value]]"> <span>$i18n{optionRasterize}</span> </label> - <label aria-live="polite" - hidden$="[[!settings.selectionOnly.available]]"> - <input type="checkbox" id="selection-only" + <label hidden$="[[!settings.selectionOnly.available]]" + aria-live="polite"> + <input type="checkbox" id="selectionOnly" disabled$="[[disabled]]" on-change="onSelectionOnlyChange_" checked$="[[settings.selectionOnly.value]]"> diff --git a/chromium/chrome/browser/resources/print_preview/new/other_options_settings.js b/chromium/chrome/browser/resources/print_preview/new/other_options_settings.js index 07d9f82eb58..783dde11e6f 100644 --- a/chromium/chrome/browser/resources/print_preview/new/other_options_settings.js +++ b/chromium/chrome/browser/resources/print_preview/new/other_options_settings.js @@ -19,12 +19,39 @@ Polymer({ 'onSelectionOnlySettingChange_(settings.selectionOnly.value)', ], + /** @private {!Map<string, ?number>} */ + timeouts_: new Map(), + + /** @private {!Map<string, boolean>} */ + previousValues_: new Map(), + + /** + * @param {string} settingName The name of the setting to updated. + * @param {boolean} newValue The new value for the setting. + */ + updateSettingWithTimeout_: function(settingName, newValue) { + const timeout = this.timeouts_.get(settingName); + if (timeout != null) + clearTimeout(timeout); + + this.timeouts_.set(settingName, setTimeout(() => { + this.timeouts_.delete(settingName); + if (this.previousValues_.get(settingName) == newValue) + return; + this.previousValues_.set(settingName, newValue); + this.setSetting(settingName, newValue); + + // For tests only + this.fire('update-checkbox-setting', settingName); + }, 100)); + }, + /** * @param {boolean} value The new value of the header footer setting. * @private */ onHeaderFooterSettingChange_: function(value) { - this.$$('#header-footer').checked = value; + this.$.headerFooter.checked = value; }, /** @@ -32,7 +59,7 @@ Polymer({ * @private */ onDuplexSettingChange_: function(value) { - this.$$('#duplex').checked = value; + this.$.duplex.checked = value; }, /** @@ -40,7 +67,7 @@ Polymer({ * @private */ onCssBackgroundSettingChange_: function(value) { - this.$$('#css-background').checked = value; + this.$.cssBackground.checked = value; }, /** @@ -48,7 +75,7 @@ Polymer({ * @private */ onRasterizeSettingChange_: function(value) { - this.$$('#rasterize').checked = value; + this.$.rasterize.checked = value; }, /** @@ -56,31 +83,33 @@ Polymer({ * @private */ onSelectionOnlySettingChange_: function(value) { - this.$$('#selection-only').checked = value; + this.$.selectionOnly.checked = value; }, /** @private */ onHeaderFooterChange_: function() { - this.setSetting('headerFooter', this.$$('#header-footer').checked); + this.updateSettingWithTimeout_('headerFooter', this.$.headerFooter.checked); }, /** @private */ onDuplexChange_: function() { - this.setSetting('duplex', this.$$('#duplex').checked); + this.updateSettingWithTimeout_('duplex', this.$.duplex.checked); }, /** @private */ onCssBackgroundChange_: function() { - this.setSetting('cssBackground', this.$$('#css-background').checked); + this.updateSettingWithTimeout_( + 'cssBackground', this.$.cssBackground.checked); }, /** @private */ onRasterizeChange_: function() { - this.setSetting('rasterize', this.$$('#rasterize').checked); + this.updateSettingWithTimeout_('rasterize', this.$.rasterize.checked); }, /** @private */ onSelectionOnlyChange_: function() { - this.setSetting('selectionOnly', this.$$('#selection-only').checked); + this.updateSettingWithTimeout_( + 'selectionOnly', this.$.selectionOnly.checked); }, }); diff --git a/chromium/chrome/browser/resources/print_preview/new/pages_per_sheet_settings.html b/chromium/chrome/browser/resources/print_preview/new/pages_per_sheet_settings.html new file mode 100644 index 00000000000..09a4a68b846 --- /dev/null +++ b/chromium/chrome/browser/resources/print_preview/new/pages_per_sheet_settings.html @@ -0,0 +1,30 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> + +<link rel="import" href="print_preview_shared_css.html"> +<link rel="import" href="select_css.html"> +<link rel="import" href="select_behavior.html"> +<link rel="import" href="settings_behavior.html"> +<link rel="import" href="settings_section.html"> + +<dom-module id="print-preview-pages-per-sheet-settings"> + <template> + <style include="print-preview-shared select"> + </style> + <print-preview-settings-section> + <span id="pages-per-sheet-label" slot="title">$i18n{pagesPerSheetLabel} + </span> + <div slot="controls"> + <select aria-labelledby="pages-per-sheet-label" + disabled$="[[disabled]]"> + <option value="1" selected>1</option> + <option value="2">2</option> + <option value="4">4</option> + <option value="6">6</option> + <option value="9">9</option> + <option value="16">16</option> + </select> + </div> + </print-preview-settings-section> + </template> + <script src="pages_per_sheet_settings.js"></script> +</dom-module> diff --git a/chromium/chrome/browser/resources/print_preview/new/pages_per_sheet_settings.js b/chromium/chrome/browser/resources/print_preview/new/pages_per_sheet_settings.js new file mode 100644 index 00000000000..0b23bbcda2f --- /dev/null +++ b/chromium/chrome/browser/resources/print_preview/new/pages_per_sheet_settings.js @@ -0,0 +1,28 @@ +// Copyright 2018 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. + +Polymer({ + is: 'print-preview-pages-per-sheet-settings', + + behaviors: [SettingsBehavior, print_preview_new.SelectBehavior], + + properties: { + disabled: Boolean, + }, + + observers: ['onPagesPerSheetSettingChange_(settings.pagesPerSheet.value)'], + + /** + * @param {*} value The new value of the pages per sheet setting. + * @private + */ + onPagesPerSheetSettingChange_: function(value) { + this.$$('select').value = /** @type {number} */ (value).toString(); + }, + + /** @param {string} value The new select value. */ + onProcessSelectChange: function(value) { + this.setSetting('pagesPerSheet', parseInt(value, 10)); + }, +}); diff --git a/chromium/chrome/browser/resources/print_preview/new/pages_settings.html b/chromium/chrome/browser/resources/print_preview/new/pages_settings.html index d9781a4b421..2cd551e07fd 100644 --- a/chromium/chrome/browser/resources/print_preview/new/pages_settings.html +++ b/chromium/chrome/browser/resources/print_preview/new/pages_settings.html @@ -7,6 +7,7 @@ <link rel="import" href="print_preview_shared_css.html"> <link rel="import" href="settings_behavior.html"> <link rel="import" href="settings_section.html"> +<link rel="import" href="strings.html"> <dom-module id="print-preview-pages-settings"> <template> @@ -42,7 +43,7 @@ <input id="pageSettingsCustomInput" class="user-value" type="text" checked="{{customSelected_::change}}" data-timeout-delay="500" disabled$="[[getDisabled_(disabled, settings.pages.valid)]]" - pattern="([0-9]*(-)?[0-9]*(,)( )?)*([0-9]*(-)?[0-9]*(,)?( )?)?" + pattern="[[inputPattern_]]" on-focus="onCustomInputFocus_" on-blur="onCustomInputBlur_" placeholder="$i18n{examplePageRangeText}" aria-label="$i18n{examplePageRangeText}"> diff --git a/chromium/chrome/browser/resources/print_preview/new/pages_settings.js b/chromium/chrome/browser/resources/print_preview/new/pages_settings.js index 0734e387451..6b4a692c886 100644 --- a/chromium/chrome/browser/resources/print_preview/new/pages_settings.js +++ b/chromium/chrome/browser/resources/print_preview/new/pages_settings.js @@ -65,6 +65,14 @@ Polymer({ type: Array, computed: 'computeRangesToPrint_(pagesToPrint_, allPagesArray_)', }, + + /** @private {string} */ + inputPattern_: { + type: String, + notify: true, + value: + '([0-9]*(-)?[0-9]*(,|\u3001)( )?)*([0-9]*(-)?[0-9]*(,|\u3001)?( )?)?', + }, }, observers: [ @@ -126,16 +134,18 @@ Polymer({ const pages = []; const added = {}; - const ranges = this.inputString_.split(','); + const ranges = this.inputString_.split(/,|\u3001/); const maxPage = this.allPagesArray_.length; for (let range of ranges) { range = range.trim(); - if (range == '') - continue; + if (range == '') { + this.errorState_ = PagesInputErrorState.INVALID_SYNTAX; + return this.pagesToPrint_; + } const limits = range.split('-'); let min = parseInt(limits[0], 10); if (min < 1) { - this.errorState_ = PagesInputErrorState.OUT_OF_BOUNDS; + this.errorState_ = PagesInputErrorState.INVALID_SYNTAX; return this.pagesToPrint_; } if (limits.length == 1) { diff --git a/chromium/chrome/browser/resources/print_preview/new/preview_area.html b/chromium/chrome/browser/resources/print_preview/new/preview_area.html index fa38e388017..b57d5dff0e9 100644 --- a/chromium/chrome/browser/resources/print_preview/new/preview_area.html +++ b/chromium/chrome/browser/resources/print_preview/new/preview_area.html @@ -18,6 +18,7 @@ <link rel="import" href="model.html"> <link rel="import" href="state.html"> <link rel="import" href="settings_behavior.html"> +<link rel="import" href="strings.html"> <dom-module id="print-preview-preview-area"> <template> @@ -115,25 +116,25 @@ } </style> - <div class$="preview-area-overlay-layer [[getInvisible_(previewState_)]]" - aria-hidden$="[[previewLoaded_]]"> + <div class$="preview-area-overlay-layer [[getInvisible_(previewState)]]" + aria-hidden$="[[getAriaHidden_(previewState)]]"> <div class="preview-area-messages"> <div class="preview-area-message"> <div> - <span>[[currentMessage_(previewState_)]]</span> + <span>[[currentMessage_(previewState)]]</span> <span class$="preview-area-loading-message-jumping-dots - [[getJumpingDots_(previewState_)]]" - hidden$="[[!isPreviewLoading_(previewState_)]]"> + [[getJumpingDots_(previewState)]]" + hidden$="[[!isPreviewLoading_(previewState)]]"> <span>.</span><span>.</span><span>.</span> </span> <a is="action-link" class="learn-more-link" - hidden$="[[!shouldShowLearnMoreLink_(previewState_)]]" + hidden$="[[!shouldShowLearnMoreLink_(previewState)]]" on-click="onGcpErrorLearnMoreClick_"> $i18n{learnMore} </a> </div> <div class="preview-area-action-area" - hidden$="[[!displaySystemDialogButton_(previewState_)]]"> + hidden$="[[!displaySystemDialogButton_(previewState)]]"> <button class="preview-area-open-system-dialog-button"> $i18n{launchNativeDialog} </button> diff --git a/chromium/chrome/browser/resources/print_preview/new/preview_area.js b/chromium/chrome/browser/resources/print_preview/new/preview_area.js index a95bb5065ab..28de03e54bc 100644 --- a/chromium/chrome/browser/resources/print_preview/new/preview_area.js +++ b/chromium/chrome/browser/resources/print_preview/new/preview_area.js @@ -34,14 +34,21 @@ cr.exportPath('print_preview_new'); */ print_preview_new.PDFPlugin; -(function() { -'use strict'; +/** + * @typedef {{ + * width_microns: number, + * height_microns: number, + * }} + */ +print_preview_new.MediaSizeValue; /** @enum {string} */ -const PreviewAreaState_ = { +print_preview_new.PreviewAreaState = { + NO_PLUGIN: 'no-plugin', LOADING: 'loading', DISPLAY_PREVIEW: 'display-preview', - OPEN_IN_PREVIEW: 'open-in-preview', + OPEN_IN_PREVIEW_LOADING: 'open-in-preview-loading', + OPEN_IN_PREVIEW_LOADED: 'open-in-preview-loaded', INVALID_SETTINGS: 'invalid-settings', PREVIEW_FAILED: 'preview-failed', UNSUPPORTED_CLOUD_PRINTER: 'unsupported-cloud-printer', @@ -80,19 +87,18 @@ Polymer({ value: false, }, - /** @private {string} */ - previewState_: { + /** @type {!print_preview_new.PreviewAreaState} */ + previewState: { type: String, notify: true, - value: PreviewAreaState_.LOADING, + value: print_preview_new.PreviewAreaState.LOADING, }, /** @private {boolean} */ previewLoaded_: { type: Boolean, notify: true, - computed: 'computePreviewLoaded_(' + - 'previewState_, pluginLoaded_, documentReady_)', + computed: 'computePreviewLoaded_(documentReady_, pluginLoaded_)', }, }, @@ -104,16 +110,28 @@ Polymer({ observers: [ 'onSettingsChanged_(settings.color.value, settings.cssBackground.value, ' + 'settings.fitToPage.value, settings.headerFooter.value, ' + - 'settings.layout.value, settings.margins.value, ' + - 'settings.customMargins.value, settings.mediaSize.value, ' + - 'settings.ranges.value, settings.selectionOnly.value, ' + - 'settings.scaling.value, settings.rasterize.value, destination.id, ' + - 'destination.capabilities)', + 'settings.layout.value, settings.ranges.value, ' + + 'settings.selectionOnly.value, settings.scaling.value, ' + + 'settings.pagesPerSheet.value, settings.rasterize.value, destination)', + 'onMarginsChanged_(settings.margins.value)', + 'onCustomMarginsChanged_(settings.customMargins.value)', + 'onMediaSizeChanged_(settings.mediaSize.value)', + 'pluginOrDocumentStatusChanged_(pluginLoaded_, documentReady_)', ], - /** @private {print_preview.NativeLayer} */ + /** @private {?print_preview.NativeLayer} */ nativeLayer_: null, + /** + * @private {?print_preview.MarginsSetting} + */ + lastCustomMargins_: null, + + /** + * @private {?print_preview_new.MediaSizeValue} + */ + lastMediaSize_: null, + /** @private {number} */ inFlightRequestId_: -1, @@ -136,14 +154,21 @@ Polymer({ this.addWebUIListener( 'page-preview-ready', this.onPagePreviewReady_.bind(this)); + if (!this.checkPluginCompatibility()) + this.previewState = print_preview_new.PreviewAreaState.NO_PLUGIN; + }, + + /** + * @return {boolean} Whether the plugin exists and is compatible. Overridden + * in tests. + */ + checkPluginCompatibility: function() { const oopCompatObj = this.$$('.preview-area-compatibility-object-out-of-process'); const isOOPCompatible = oopCompatObj.postMessage; oopCompatObj.parentElement.removeChild(oopCompatObj); - if (!isOOPCompatible) { - this.previewState_ = PreviewAreaState_.PREVIEW_FAILED; - this.fire('preview-failed'); - } + + return isOOPCompatible; }, /** @@ -151,9 +176,7 @@ Polymer({ * @private */ computePreviewLoaded_: function() { - return this.previewState_ == PreviewAreaState_.DISPLAY_PREVIEW || - (this.documentReady_ && this.pluginLoaded_ && - this.previewState_ == PreviewAreaState_.OPEN_IN_PREVIEW); + return this.documentReady_ && this.pluginLoaded_; }, /** @return {boolean} Whether the preview is loaded. */ @@ -206,12 +229,40 @@ Polymer({ this.requestPreviewWhenReady_ = true; }, + /** @private */ + pluginOrDocumentStatusChanged_: function() { + if (!this.pluginLoaded_ || !this.documentReady_) + return; + + this.previewState = this.previewState == + print_preview_new.PreviewAreaState.OPEN_IN_PREVIEW_LOADING ? + print_preview_new.PreviewAreaState.OPEN_IN_PREVIEW_LOADED : + print_preview_new.PreviewAreaState.DISPLAY_PREVIEW; + }, + /** * @return {string} 'invisible' if overlay is invisible, '' otherwise. * @private */ getInvisible_: function() { - return this.previewLoaded() ? 'invisible' : ''; + return this.isInDisplayPreviewState_() ? 'invisible' : ''; + }, + + /** + * @return {string} 'true' if overlay is aria-hidden, 'false' otherwise. + * @private + */ + getAriaHidden_: function() { + return this.isInDisplayPreviewState_().toString(); + }, + + /** + * @return {boolean} Whether the preview area is in DISPLAY_PREVIEW state. + * @private + */ + isInDisplayPreviewState_: function() { + return this.previewState == + print_preview_new.PreviewAreaState.DISPLAY_PREVIEW; }, /** @@ -219,7 +270,7 @@ Polymer({ * @private */ isPreviewLoading_: function() { - return this.previewState_ == PreviewAreaState_.LOADING; + return this.previewState == print_preview_new.PreviewAreaState.LOADING; }, /** @@ -235,8 +286,12 @@ Polymer({ * @private */ displaySystemDialogButton_: function() { - return this.previewState_ == PreviewAreaState_.INVALID_SETTINGS || - this.previewState_ == PreviewAreaState_.OPEN_IN_PREVIEW; + return this.previewState == + print_preview_new.PreviewAreaState.INVALID_SETTINGS || + this.previewState == + print_preview_new.PreviewAreaState.OPEN_IN_PREVIEW_LOADING || + this.previewState == + print_preview_new.PreviewAreaState.OPEN_IN_PREVIEW_LOADED; }, /** @@ -245,7 +300,8 @@ Polymer({ * @private */ shouldShowLearnMoreLink_: function() { - return this.previewState_ == PreviewAreaState_.UNSUPPORTED_CLOUD_PRINTER; + return this.previewState == + print_preview_new.PreviewAreaState.UNSUPPORTED_CLOUD_PRINTER; }, /** @@ -253,65 +309,56 @@ Polymer({ * @private */ currentMessage_: function() { - if (this.previewState_ == PreviewAreaState_.LOADING) - return this.i18n('loading'); - if (this.previewState_ == PreviewAreaState_.OPEN_IN_PREVIEW) - return this.i18n('openingPDFInPreview'); - if (this.previewState_ == PreviewAreaState_.INVALID_SETTINGS) - return this.i18n('invalidPrinterSettings'); - if (this.previewState_ == PreviewAreaState_.PREVIEW_FAILED) - return this.i18n('previewFailed'); - if (this.previewState_ == PreviewAreaState_.UNSUPPORTED_CLOUD_PRINTER) - return this.i18n('unsupportedCloudPrinter'); - return ''; + switch (this.previewState) { + case print_preview_new.PreviewAreaState.NO_PLUGIN: + return this.i18n('noPlugin'); + case print_preview_new.PreviewAreaState.LOADING: + return this.i18n('loading'); + case print_preview_new.PreviewAreaState.DISPLAY_PREVIEW: + return ''; + // <if expr="is_macosx"> + case print_preview_new.PreviewAreaState.OPEN_IN_PREVIEW_LOADING: + case print_preview_new.PreviewAreaState.OPEN_IN_PREVIEW_LOADED: + return this.i18n('openingPDFInPreview'); + // </if> + case print_preview_new.PreviewAreaState.INVALID_SETTINGS: + return this.i18n('invalidPrinterSettings'); + case print_preview_new.PreviewAreaState.PREVIEW_FAILED: + return this.i18n('previewFailed'); + case print_preview_new.PreviewAreaState.UNSUPPORTED_CLOUD_PRINTER: + return this.i18n('unsupportedCloudPrinter'); + default: + return ''; + } }, /** @private */ startPreview_: function() { - this.previewState_ = PreviewAreaState_.LOADING; + this.previewState = print_preview_new.PreviewAreaState.LOADING; this.documentReady_ = false; this.getPreview_().then( previewUid => { if (!this.documentInfo.isModifiable) this.onPreviewStart_(previewUid, -1); this.documentReady_ = true; - if (this.pluginLoaded_) { - if (this.previewState_ != PreviewAreaState_.OPEN_IN_PREVIEW) - this.previewState_ = PreviewAreaState_.DISPLAY_PREVIEW; - this.fire('preview-loaded'); - } }, type => { if (/** @type{string} */ (type) == 'SETTINGS_INVALID') { - this.previewState_ = PreviewAreaState_.INVALID_SETTINGS; - this.fire('invalid-printer'); + this.previewState = + print_preview_new.PreviewAreaState.INVALID_SETTINGS; } else if (/** @type{string} */ (type) != 'CANCELLED') { - this.previewState_ = PreviewAreaState_.PREVIEW_FAILED; - this.fire('preview-failed'); + this.previewState = + print_preview_new.PreviewAreaState.PREVIEW_FAILED; } }); }, /** @private */ onStateChanged_: function() { - switch (this.state) { - case (print_preview_new.State.NOT_READY): - // Resetting the destination clears the invalid settings error. - this.previewState_ = PreviewAreaState_.LOADING; - break; - case (print_preview_new.State.READY): - // Request a new preview. - if (this.requestPreviewWhenReady_) { - this.startPreview_(); - this.requestPreviewWhenReady_ = false; - } - break; - case (print_preview_new.State.INVALID_PRINTER): - if (this.previewState_ != PreviewAreaState_.INVALID_SETTINGS) - this.previewState_ = PreviewAreaState_.UNSUPPORTED_CLOUD_PRINTER; - break; - default: - break; + if (this.state == print_preview_new.State.READY && + this.requestPreviewWhenReady_) { + this.startPreview_(); + this.requestPreviewWhenReady_ = false; } }, @@ -319,7 +366,10 @@ Polymer({ /** Set the preview state to display the "opening in preview" message. */ setOpeningPdfInPreview: function() { assert(cr.isMac); - this.previewState_ = PreviewAreaState_.OPEN_IN_PREVIEW; + this.previewState = + this.previewState == print_preview_new.PreviewAreaState.LOADING ? + print_preview_new.PreviewAreaState.OPEN_IN_PREVIEW_LOADING : + print_preview_new.PreviewAreaState.OPEN_IN_PREVIEW_LOADED; }, // </if> @@ -405,11 +455,6 @@ Polymer({ */ onPluginLoad_: function() { this.pluginLoaded_ = true; - if (this.documentReady_) { - if (this.previewState_ != PreviewAreaState_.OPEN_IN_PREVIEW) - this.previewState_ = PreviewAreaState_.DISPLAY_PREVIEW; - this.fire('preview-loaded'); - } }, /** @@ -574,6 +619,49 @@ Polymer({ this.i18n('gcpCertificateErrorLearnMoreURL')); }, + /** @private */ + onMarginsChanged_: function() { + if (this.getSettingValue('margins') != + print_preview.ticket_items.MarginsTypeValue.CUSTOM) { + this.lastCustomMargins_ = null; + this.onSettingsChanged_(); + } else { + this.lastCustomMargins_ = + /** @type {!print_preview.MarginsSetting} */ ( + this.getSettingValue('customMargins')); + } + }, + + /** @private */ + onCustomMarginsChanged_: function() { + const newValue = + /** @type {!print_preview.MarginsSetting} */ ( + this.getSettingValue('customMargins')); + if (!!this.lastCustomMargins_ && + this.getSettingValue('margins') == + print_preview.ticket_items.MarginsTypeValue.CUSTOM && + (this.lastCustomMargins_.marginTop != newValue.marginTop || + this.lastCustomMargins_.marginLeft != newValue.marginLeft || + this.lastCustomMargins_.marginRight != newValue.marginRight || + this.lastCustomMargins_.marginBottom != newValue.marginBottom)) { + this.onSettingsChanged_(); + } + this.lastCustomMargins_ = newValue; + }, + + /** @private */ + onMediaSizeChanged_: function() { + const newValue = + /** @type {!print_preview_new.MediaSizeValue} */ ( + this.getSettingValue('mediaSize')); + if (!!this.lastMediaSize_ && + (newValue.height_microns != this.lastMediaSize_.height_microns || + newValue.width_microns != this.lastMediaSize_.width_microns)) { + this.onSettingsChanged_(); + } + this.lastMediaSize_ = newValue; + }, + /** * Requests a preview from the native layer. * @return {!Promise} Promise that resolves when the preview has been @@ -593,10 +681,10 @@ Polymer({ /** @type {boolean} */ (this.getSettingValue('color'))), headerFooterEnabled: this.getSettingValue('headerFooter'), marginsType: this.getSettingValue('margins'), + pagesPerSheet: this.getSettingValue('pagesPerSheet'), isFirstRequest: this.inFlightRequestId_ == 0, requestID: this.inFlightRequestId_, previewModifiable: this.documentInfo.isModifiable, - generateDraftData: this.documentInfo.isModifiable, fitToPageEnabled: this.getSettingValue('fitToPage'), scaleFactor: parseInt(this.getSettingValue('scaling'), 10), shouldPrintBackgrounds: this.getSettingValue('cssBackground'), @@ -629,12 +717,6 @@ Polymer({ print_preview.ticket_items.MarginsTypeValue.CUSTOM) { ticket.marginsCustom = this.getSettingValue('customMargins'); } - let pageCount = -1; - if (this.inFlightRequestId_ > 0) { - pageCount = this.documentInfo.isModifiable ? - this.documentInfo.pageCount : 0; - } - return this.nativeLayer_.getPreview(JSON.stringify(ticket), pageCount); + return this.nativeLayer_.getPreview(JSON.stringify(ticket)); }, }); -})(); diff --git a/chromium/chrome/browser/resources/print_preview/new/provisional_destination_resolver.html b/chromium/chrome/browser/resources/print_preview/new/provisional_destination_resolver.html new file mode 100644 index 00000000000..df3927214aa --- /dev/null +++ b/chromium/chrome/browser/resources/print_preview/new/provisional_destination_resolver.html @@ -0,0 +1,86 @@ +<link rel="import" href="chrome://resources/html/polymer.html"> + +<link rel="import" href="chrome://resources/cr_elements/cr_dialog/cr_dialog.html"> +<link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html"> +<link rel="import" href="chrome://resources/html/cr.html"> +<link rel="import" href="chrome://resources/html/i18n_behavior.html"> +<link rel="import" href="../data/destination.html"> +<link rel="import" href="../data/destination_store.html"> +<link rel="import" href="button_css.html"> +<link rel="import" href="print_preview_shared_css.html"> +<link rel="import" href="search_dialog_css.html"> +<link rel="import" href="strings.html"> +<link rel="import" href="throbber_css.html"> + +<dom-module id="print-preview-provisional-destination-resolver"> + <template> + <style include="print-preview-shared search-dialog button cr-hidden-style throbber"> + :host #dialog { + --cr-dialog-native: { + border-radius: 2px; + box-shadow: 0 4px 23px 5px rgba(0, 0, 0, 0.2), + 0 2px 6px rgba(0, 0, 0, 0.15); + width: 360px; + }; + --cr-dialog-top-container-min-height: 35px; + } + + :host .throbber-placeholder { + height: 16px; + margin: 4px; + width: 16px; + } + + .message { + line-height: 1.4rem; + margin: 0; + padding-bottom: 35px; + } + + .extension-desc { + display: flex; + } + + .extension-icon { + background-position: center; + background-repeat: none; + height: 24px; + width: 24px; + } + + .extension-name { + flex: 1; + line-height: 24px; + overflow-wrap: break-word; + } + + div[slot='button-container'] { + margin: 0 3px 10px; + } + </style> + <cr-dialog id="dialog" on-close="onCancel_" show-close-button> + <div slot="body"> + <p class="message"> + [[getPermissionMessage_(state_, destination_.extensionName)]] + </p> + <div class="extension-desc" hidden="[[isInErrorState_(state_)]]"> + <div class$="throbber-placeholder [[getThrobberClass_(state_)]]" + role="img" alt=""></div> + <div class="extension-icon" role="img" alt=""></div> + <div class="extension-name"> + [[destination_.extensionName]] + </div> + </div> + </div> + <div slot="button-container"> + <button class="cancel" on-click="onCancel_">$i18n{goBackButton}</button> + <button class="default" hidden="[[isInErrorState_(state_)]]" + disabled="[[!isInActiveState_(state_)]]" + on-click="startResolveDestination_"> + $i18n{selectButton} + </button> + </div> + </cr-dialog> + </template> + <script src="provisional_destination_resolver.js"></script> +</dom-module> diff --git a/chromium/chrome/browser/resources/print_preview/new/provisional_destination_resolver.js b/chromium/chrome/browser/resources/print_preview/new/provisional_destination_resolver.js new file mode 100644 index 00000000000..16f5f9c0e51 --- /dev/null +++ b/chromium/chrome/browser/resources/print_preview/new/provisional_destination_resolver.js @@ -0,0 +1,157 @@ +// Copyright 2018 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. + +/** + * @fileoverview PrintPreviewProvisionalDestinationResolver + * This class is a dialog for resolving provisional destinations. Provisional + * destinations are extension controlled destinations that need access to a USB + * device and have not yet been granted access by the user. Destinations are + * resolved when the user confirms they wish to grant access and the handler + * has successfully granted access. + */ + +cr.exportPath('print_preview_new'); + +/** + * States that the provisional destination resolver can be in. + * @enum {string} + */ +print_preview_new.ResolverState = { + INITIAL: 'INITIAL', + ACTIVE: 'ACTIVE', + GRANTING_PERMISSION: 'GRANTING_PERMISSION', + ERROR: 'ERROR', + DONE: 'DONE' +}; + +Polymer({ + is: 'print-preview-provisional-destination-resolver', + + behaviors: [I18nBehavior], + + properties: { + /** @type {?print_preview.DestinationStore} */ + destinationStore: Object, + + /** @private {?print_preview.Destination} */ + destination_: { + type: Object, + value: null, + }, + + /** @private {!print_preview_new.ResolverState} */ + state_: { + type: String, + value: print_preview_new.ResolverState.INITIAL, + }, + }, + + /** + * Promise resolver for promise returned by {@code this.resolveDestination}. + * @private {?PromiseResolver<!print_preview.Destination>} + */ + promiseResolver_: null, + + /** + * @param {!print_preview.Destination} destination The destination this + * dialog is needed to resolve. + * @return {!Promise} Promise that is resolved when the destination has been + * resolved. + */ + resolveDestination: function(destination) { + this.state_ = print_preview_new.ResolverState.ACTIVE; + this.destination_ = destination; + this.$.dialog.showModal(); + const icon = this.$$('.extension-icon'); + icon.style.backgroundImage = '-webkit-image-set(' + + 'url(chrome://extension-icon/' + this.destination_.extensionId + + '/24/1) 1x,' + + 'url(chrome://extension-icon/' + this.destination_.extensionId + + '/48/1) 2x)'; + this.promiseResolver_ = new PromiseResolver(); + return this.promiseResolver_.promise; + }, + + /** + * Handler for click on OK button. It attempts to resolve the destination. + * If successful, promiseResolver_.promise is resolved with the + * resolved destination and the dialog closes. + * @private + */ + startResolveDestination_: function() { + assert( + this.state_ == print_preview_new.ResolverState.ACTIVE, + 'Invalid state in request grant permission'); + + this.state_ = print_preview_new.ResolverState.GRANTING_PERMISSION; + const destination = + /** @type {!print_preview.Destination} */ (this.destination_); + this.destinationStore.resolveProvisionalDestination(destination) + .then( + /** @param {?print_preview.Destination} resolvedDestination */ + (resolvedDestination) => { + if (this.state_ != + print_preview_new.ResolverState.GRANTING_PERMISSION) { + return; + } + + if (destination.id != this.destination_.id) + return; + + if (resolvedDestination) { + this.state_ = print_preview_new.ResolverState.DONE; + this.promiseResolver_.resolve(resolvedDestination); + this.promiseResolver_ = null; + this.$.dialog.close(); + } else { + this.state_ = print_preview_new.ResolverState.ERROR; + } + }); + }, + + /** @private */ + onCancel_: function() { + this.promiseResolver_.reject(); + this.$.dialog.close(); + this.state_ = print_preview_new.ResolverState.INITIAL; + }, + + /** + * @return {string} The USB permission message to display. + * @private + */ + getPermissionMessage_: function() { + return this.state_ == print_preview_new.ResolverState.ERROR ? + this.i18n( + 'resolveExtensionUSBErrorMessage', + this.destination_.extensionName) : + this.i18n('resolveExtensionUSBPermissionMessage'); + }, + + /** + * @return {boolean} Whether the resolver is in the ERROR state. + * @private + */ + isInErrorState_: function() { + return this.state_ == print_preview_new.ResolverState.ERROR; + }, + + /** + * @return {boolean} Whether the resolver is in the ACTIVE state. + * @private + */ + isInActiveState_: function() { + return this.state_ == print_preview_new.ResolverState.ACTIVE; + }, + + /** + * @return {string} 'throbber' if the resolver is in the GRANTING_PERMISSION + * state, empty otherwise. + */ + getThrobberClass_: function() { + return this.state_ == print_preview_new.ResolverState.GRANTING_PERMISSION ? + 'throbber' : + ''; + }, +}); diff --git a/chromium/chrome/browser/resources/print_preview/new/scaling_settings.js b/chromium/chrome/browser/resources/print_preview/new/scaling_settings.js index 977389d25f2..9bbd9ffc089 100644 --- a/chromium/chrome/browser/resources/print_preview/new/scaling_settings.js +++ b/chromium/chrome/browser/resources/print_preview/new/scaling_settings.js @@ -2,6 +2,24 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +cr.exportPath('print_preview_new'); + +/** @enum {number} */ +print_preview_new.ScalingState = { + INIT: 0, + VALID: 1, + INVALID: 2, + FIT_TO_PAGE: 3, +}; + +/* + * When fit to page is available, the checkbox and input interact as follows: + * 1. When checkbox is checked, the fit to page scaling value is displayed in + * the input. The error message is cleared if it was present. + * 2. When checkbox is unchecked, the most recent valid scale value is restored. + * 3. If the input is modified while the checkbox is checked, the checkbox will + * be unchecked automatically, regardless of the validity of the new value. + */ Polymer({ is: 'print-preview-scaling-settings', @@ -17,38 +35,73 @@ Polymer({ /** @private {boolean} */ inputValid_: Boolean, - disabled: Boolean, - }, + /** @private {boolean} */ + hideInput_: Boolean, - /** @private {string} */ - lastValidScaling_: '100', + disabled: Boolean, - /** @private {number} */ - fitToPageFlag_: 0, + /** @private {!print_preview_new.ScalingState} */ + currentState_: { + type: Number, + value: print_preview_new.ScalingState.INIT, + observer: 'onStateChange_', + }, + }, observers: [ - 'onFitToPageSettingChange_(settings.fitToPage.value, ' + - 'settings.fitToPage.available, documentInfo.fitToPageScaling)', + 'onFitToPageSettingChange_(settings.fitToPage.value)', + 'onFitToPageScalingSet_(documentInfo.fitToPageScaling)', 'onInputChanged_(currentValue_, inputValid_)', 'onScalingSettingChanged_(settings.scaling.value)', + 'onScalingValidChanged_(settings.scaling.valid)', ], + /** + * Timeout used to delay processing of the checkbox input. + * @private {?number} + */ + fitToPageTimeout_: null, + + /** @private {boolean} */ + ignoreFtp_: false, + + /** @private {boolean} */ + ignoreValid_: false, + + /** @private {boolean} */ + ignoreValue_: false, + + /** @private {string} */ + lastValidScaling_: '100', + + /** @private {?boolean} */ + lastFitToPageValue_: null, + /** @private */ onFitToPageSettingChange_: function() { - const fitToPage = this.getSetting('fitToPage'); - if (!fitToPage.available) + if (this.ignoreFtp_ || !this.getSetting('fitToPage').available) + return; + + const fitToPage = this.getSetting('fitToPage').value; + + if (fitToPage) { + this.currentState_ = print_preview_new.ScalingState.FIT_TO_PAGE; return; - this.$$('#fit-to-page-checkbox').checked = fitToPage.value; - if (!fitToPage.value) { - // Fit to page is no longer checked. Update the display. - this.currentValue_ = this.lastValidScaling_; - } else if (fitToPage.value) { - // Set flag to number of expected calls to onInputChanged_. If scaling - // is valid, 1 call will occur due to the change to |currentValue_|. If - // not, 2 calls will occur, since |inputValid_| will also change. - this.fitToPageFlag_ = this.inputValid_ ? 1 : 2; - this.currentValue_ = this.documentInfo.fitToPageScaling.toString(); } + + this.currentState_ = this.getSetting('scaling').valid ? + print_preview_new.ScalingState.VALID : + print_preview_new.ScalingState.INVALID; + }, + + /** @private */ + onFitToPageScalingSet_: function() { + if (this.currentState_ != print_preview_new.ScalingState.FIT_TO_PAGE) + return; + + this.ignoreValue_ = true; + this.currentValue_ = this.documentInfo.fitToPageScaling.toString(); + this.ignoreValue_ = false; }, /** @@ -60,6 +113,20 @@ Polymer({ this.lastValidScaling_ = /** @type {string} */ (this.getSetting('scaling').value); this.currentValue_ = this.lastValidScaling_; + this.currentState_ = print_preview_new.ScalingState.VALID; + }, + + /** + * Updates the state of the UI when scaling validity is set. + * @private + */ + onScalingValidChanged_: function() { + if (this.ignoreValid_) + return; + + this.currentState_ = this.getSetting('scaling').valid ? + print_preview_new.ScalingState.VALID : + print_preview_new.ScalingState.INVALID; }, /** @@ -68,34 +135,36 @@ Polymer({ * @private */ onInputChanged_: function() { - const fitToPage = this.$$('#fit-to-page-checkbox').checked; - if (fitToPage && this.fitToPageFlag_ == 0) { - // User modified scaling while fit to page was checked. Uncheck fit to - // page. - const wasValid = this.getSetting('scaling').valid; - if (this.inputValid_ && wasValid) - this.setSetting('scaling', this.currentValue_); - else - this.setSettingValid('scaling', false); - this.$$('#fit-to-page-checkbox').checked = false; - this.setSetting('fitToPage', false); - } else if (fitToPage) { - // Fit to page was checked and scaling changed as a result. - this.fitToPageFlag_--; - this.setSettingValid('scaling', true); - } else { - // User modified scaling while fit to page was not checked or - // scaling setting was set. - const wasValid = this.getSetting('scaling').valid; - this.setSettingValid('scaling', this.inputValid_); - if (this.inputValid_ && wasValid) - this.setSetting('scaling', this.currentValue_); - } + if (this.ignoreValue_) + return; + + this.setSettingValid('scaling', this.inputValid_); + if (this.inputValid_) + this.setSetting('scaling', this.currentValue_); }, /** @private */ onFitToPageChange_: function() { - this.setSetting('fitToPage', this.$$('#fit-to-page-checkbox').checked); + const newValue = this.$$('#fit-to-page-checkbox').checked; + + if (this.fitToPageTimeout_ !== null) + clearTimeout(this.fitToPageTimeout_); + + this.fitToPageTimeout_ = setTimeout(() => { + this.fitToPageTimeout_ = null; + + if (newValue === this.lastFitToPageValue_) + return; + + this.lastFitToPageValue_ = newValue; + this.setSetting('fitToPage', newValue); + + if (newValue == false) + this.currentValue_ = this.lastValidScaling_; + + // For tests only + this.fire('update-checkbox-setting', 'fitToPage'); + }, 100); }, /** @@ -105,4 +174,30 @@ Polymer({ getDisabled_: function() { return this.disabled && this.inputValid_; }, + + /** + * @param {!print_preview_new.ScalingState} current + * @param {!print_preview_new.ScalingState} previous + * @private + */ + onStateChange_: function(current, previous) { + if (previous == print_preview_new.ScalingState.FIT_TO_PAGE) { + this.ignoreFtp_ = true; + this.$$('#fit-to-page-checkbox').checked = false; + this.lastFitToPageValue_ = false; + this.setSetting('fitToPage', false); + this.ignoreFtp_ = false; + } + if (current == print_preview_new.ScalingState.FIT_TO_PAGE) { + if (previous == print_preview_new.ScalingState.INVALID) { + this.ignoreValid_ = true; + this.setSettingValid('scaling', true); + this.ignoreValid_ = false; + } + this.$$('#fit-to-page-checkbox').checked = true; + this.ignoreValue_ = true; + this.currentValue_ = this.documentInfo.fitToPageScaling.toString(); + this.ignoreValue_ = false; + } + } }); diff --git a/chromium/chrome/browser/resources/print_preview/new/search_dialog_css.html b/chromium/chrome/browser/resources/print_preview/new/search_dialog_css.html index 90db69ab4cf..cf41ac97079 100644 --- a/chromium/chrome/browser/resources/print_preview/new/search_dialog_css.html +++ b/chromium/chrome/browser/resources/print_preview/new/search_dialog_css.html @@ -13,7 +13,9 @@ background-color: rgba(255, 255, 255, 0.75) for the inner dialog's backdrop. See context at crbug.com/827397 */ --cr-dialog-close-image: { + -webkit-margin-end: 7px; background-image: url(chrome://theme/IDR_CLOSE_DIALOG); + margin-top: 10px; }; --cr-dialog-close-image-active: { background-image: url(chrome://theme/IDR_CLOSE_DIALOG_P); @@ -22,18 +24,31 @@ background-image: url(chrome://theme/IDR_CLOSE_DIALOG_H); }; --cr-dialog-native: { + border-radius: 2px; box-shadow: 0 4px 23px 5px rgba(0, 0, 0, 0.2), 0 2px 6px rgba(0, 0, 0, 0.15); }; - --cr-icon-ripple-size: 0; + --cr-icon-ripple-size: 14px; --cr-icon-size: 14px; + --cr-dialog-title: { + -webkit-padding-end: 16px; + -webkit-padding-start: 16px; + padding-bottom: 16px; + padding-top: 16px; + }; --cr-dialog-body: { + -webkit-padding-end: 16px; + -webkit-padding-start: 16px; box-sizing: border-box; + padding-bottom: 12px; padding-top: 0; }; --cr-dialog-wrapper: { max-height: calc(100vh - 40px); }; + --cr-dialog-close-ripple: { + display: none; + }; } #searchBox { @@ -44,6 +59,10 @@ #body { height: 100vh; } + + #dialog button { + -webkit-margin-start: 10px; + } </style> </template> </dom-module> diff --git a/chromium/chrome/browser/resources/print_preview/new/select_behavior.html b/chromium/chrome/browser/resources/print_preview/new/select_behavior.html new file mode 100644 index 00000000000..f6ef6283e8e --- /dev/null +++ b/chromium/chrome/browser/resources/print_preview/new/select_behavior.html @@ -0,0 +1,3 @@ +<link rel="import" href="chrome://resources/html/cr.html"> + +<script src="select_behavior.js"></script> diff --git a/chromium/chrome/browser/resources/print_preview/new/select_behavior.js b/chromium/chrome/browser/resources/print_preview/new/select_behavior.js new file mode 100644 index 00000000000..a248f6c958a --- /dev/null +++ b/chromium/chrome/browser/resources/print_preview/new/select_behavior.js @@ -0,0 +1,60 @@ +// Copyright 2018 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. + +cr.define('print_preview_new', function() { + /** + * Helper functions for a select with timeout. Implemented by select settings + * sections, so that the preview does not immediately begin generating and + * freeze the dropdown when the value is changed. + * Assumes that the elements implementing this behavior have no more than one + * select element. + * @polymerBehavior + */ + const SelectBehavior = { + /** @private {string} */ + lastValue_: '', + + /** + * Timeout used to delay processing of the selection. + * @private {?number} + */ + timeout_: null, + + /** @override */ + ready: function() { + assert(this.shadowRoot.querySelectorAll('select').length == 1); + this.$$('select').addEventListener('change', () => { + if (this.timeout_) { + clearTimeout(this.timeout_); + } + this.timeout_ = setTimeout(this.onTimeout_.bind(this), 100); + }); + }, + + /** + * Should be overridden by elements using this behavior to receive select + * value updates. + * @param {string} value The new select value to process. + */ + onProcessSelectChange: function(value) {}, + + /** + * Called after a timeout after user selects a new option. + * @private + */ + onTimeout_: function() { + this.timeout_ = null; + const value = /** @type {!HTMLSelectElement} */ (this.$$('select')).value; + if (this.lastValue_ != value) { + this.lastValue_ = value; + this.onProcessSelectChange(value); + + // For testing only + this.fire('process-select-change'); + } + }, + }; + + return {SelectBehavior: SelectBehavior}; +}); diff --git a/chromium/chrome/browser/resources/print_preview/new/settings_behavior.js b/chromium/chrome/browser/resources/print_preview/new/settings_behavior.js index b28e5fcd8ae..d5976f1b498 100644 --- a/chromium/chrome/browser/resources/print_preview/new/settings_behavior.js +++ b/chromium/chrome/browser/resources/print_preview/new/settings_behavior.js @@ -37,6 +37,7 @@ print_preview_new.Setting; * vendorItems: !print_preview_new.Setting, * otherOptions: !print_preview_new.Setting, * ranges: !print_preview_new.Setting, + * pagesPerSheet: !print_preview_new.Setting, * }} */ print_preview_new.Settings; @@ -91,8 +92,9 @@ const SettingsBehavior = { // is no way for the user to change the value in this case. if (!valid) assert(setting.available, 'Setting is not available: ' + settingName); - if (valid != setting.valid) - this.fire('setting-valid-changed', valid); + const shouldFireEvent = valid != setting.valid; this.set(`settings.${settingName}.valid`, valid); + if (shouldFireEvent) + this.fire('setting-valid-changed', valid); } }; diff --git a/chromium/chrome/browser/resources/print_preview/new/settings_select.html b/chromium/chrome/browser/resources/print_preview/new/settings_select.html index 9b867bec3b0..45eb62fb630 100644 --- a/chromium/chrome/browser/resources/print_preview/new/settings_select.html +++ b/chromium/chrome/browser/resources/print_preview/new/settings_select.html @@ -2,6 +2,7 @@ <link rel="import" href="../print_preview_utils.html"> <link rel="import" href="print_preview_shared_css.html"> +<link rel="import" href="select_behavior.html"> <link rel="import" href="select_css.html"> <link rel="import" href="settings_behavior.html"> @@ -9,7 +10,7 @@ <template> <style include="print-preview-shared select"> </style> - <select on-change="onChange_" disabled$="[[disabled]]"> + <select disabled$="[[disabled]]"> <template is="dom-repeat" items="[[capability.option]]"> <option selected="[[isSelected_(item, selectedValue_)]]" value="[[getValue_(item)]]"> diff --git a/chromium/chrome/browser/resources/print_preview/new/settings_select.js b/chromium/chrome/browser/resources/print_preview/new/settings_select.js index 4877620f573..c855e071752 100644 --- a/chromium/chrome/browser/resources/print_preview/new/settings_select.js +++ b/chromium/chrome/browser/resources/print_preview/new/settings_select.js @@ -17,7 +17,7 @@ print_preview_new.SelectOption; Polymer({ is: 'print-preview-settings-select', - behaviors: [SettingsBehavior], + behaviors: [SettingsBehavior, print_preview_new.SelectBehavior], properties: { /** @type {{ option: Array<!print_preview_new.SelectOption> }} */ @@ -75,15 +75,15 @@ Polymer({ return displayName || option.name || ''; }, - /** @private */ - onChange_: function() { - let value = null; + /** @param {string} value The new select value. */ + onProcessSelectChange: function(value) { + let newValue = null; try { - value = JSON.parse(this.$$('select').value); + newValue = JSON.parse(value); } catch (e) { assertNotReached(); return; } - this.setSetting(this.settingName, /** @type {Object} */ (value)); + this.setSetting(this.settingName, /** @type {Object} */ (newValue)); }, }); diff --git a/chromium/chrome/browser/resources/print_preview/preview_generator.js b/chromium/chrome/browser/resources/print_preview/preview_generator.js index 832529cca5f..2d99ffa60bc 100644 --- a/chromium/chrome/browser/resources/print_preview/preview_generator.js +++ b/chromium/chrome/browser/resources/print_preview/preview_generator.js @@ -55,14 +55,6 @@ cr.define('print_preview', function() { this.inFlightRequestId_ = -1; /** - * Whether the current in flight request requires generating draft pages - * for print preview. This is true only for modifiable documents when the - * print settings has changed sufficiently to require re-rendering. - * @private {boolean} - */ - this.generateDraft_ = false; - - /** * Media size to generate preview with. {@code null} indicates default * size. * @private {print_preview.ValueType} @@ -193,7 +185,6 @@ cr.define('print_preview', function() { this.selectedDestination_ = this.destinationStore_.selectedDestination; this.inFlightRequestId_++; - this.generateDraft_ = this.documentInfo_.isModifiable; return { id: this.inFlightRequestId_, request: this.getPreview_(), @@ -224,7 +215,6 @@ cr.define('print_preview', function() { isFirstRequest: this.inFlightRequestId_ == 0, requestID: this.inFlightRequestId_, previewModifiable: this.documentInfo_.isModifiable, - generateDraftData: this.generateDraft_, fitToPageEnabled: printTicketStore.fitToPage.getValue(), scaleFactor: printTicketStore.scaling.getValueAsNumber(), // NOTE: Even though the following fields dont directly relate to the @@ -271,9 +261,7 @@ cr.define('print_preview', function() { }; } - const pageCount = - this.inFlightRequestId_ > 0 ? this.documentInfo_.pageCount : -1; - return this.nativeLayer_.getPreview(JSON.stringify(ticket), pageCount); + return this.nativeLayer_.getPreview(JSON.stringify(ticket)); } /** @@ -450,9 +438,9 @@ cr.define('print_preview', function() { if (this.inFlightRequestId_ != previewResponseId) { return; // Ignore old response. } - if (!this.generateDraft_) { - // Dispatch a PREVIEW_START event since not generating a draft PDF, - // which includes print preview for non-modifiable documents, does not + if (!this.documentInfo_.isModifiable) { + // Dispatch a PREVIEW_START event since not generating a PDF, which + // includes print preview for non-modifiable documents, does not // trigger PAGE_READY events. this.dispatchPreviewStartEvent_(previewUid, 0); } diff --git a/chromium/chrome/browser/resources/print_preview/print_preview.js b/chromium/chrome/browser/resources/print_preview/print_preview.js index 15f928aaae4..3702bf1cc83 100644 --- a/chromium/chrome/browser/resources/print_preview/print_preview.js +++ b/chromium/chrome/browser/resources/print_preview/print_preview.js @@ -1222,7 +1222,7 @@ cr.define('print_preview', function() { this.nativeLayer_.uiLoadedForTest(); } else { combobox.value = 'landscape'; - this.layoutSettings_.onSelectChange_(); + this.layoutSettings_.onSelectChange(); } }, @@ -1286,7 +1286,7 @@ cr.define('print_preview', function() { this.nativeLayer_.uiLoadedForTest(); } else if (margins >= 0 && margins < combobox.length) { combobox.selectedIndex = margins; - this.marginSettings_.onSelectChange_(); + this.marginSettings_.onSelectChange(); } else { this.nativeLayer_.uiFailedLoadingForTest(); } 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 53c1ef76b60..b3f53d57bb5 100644 --- a/chromium/chrome/browser/resources/print_preview/print_preview_resources.grd +++ b/chromium/chrome/browser/resources/print_preview/print_preview_resources.grd @@ -155,7 +155,8 @@ type="chrome_html" /> <structure name="IDR_PRINT_PREVIEW_NEW_PREVIEW_AREA_JS" file="new/preview_area.js" - type="chrome_html" /> + type="chrome_html" + preprocess="true" /> <structure name="IDR_PRINT_PREVIEW_NEW_HEADER_HTML" file="new/header.html" type="chrome_html" /> @@ -174,6 +175,12 @@ <structure name="IDR_PRINT_PREVIEW_NEW_INPUT_BEHAVIOR_JS" file="new/input_behavior.js" type="chrome_html" /> + <structure name="IDR_PRINT_PREVIEW_NEW_SELECT_BEHAVIOR_HTML" + file="new/select_behavior.html" + type="chrome_html" /> + <structure name="IDR_PRINT_PREVIEW_NEW_SELECT_BEHAVIOR_JS" + file="new/select_behavior.js" + type="chrome_html" /> <structure name="IDR_PRINT_PREVIEW_NEW_STATE_HTML" file="new/state.html" type="chrome_html" /> @@ -246,6 +253,12 @@ <structure name="IDR_PRINT_PREVIEW_NEW_SCALING_SETTINGS_JS" file="new/scaling_settings.js" type="chrome_html" /> + <structure name="IDR_PRINT_PREVIEW_NEW_PAGES_PER_SHEET_SETTINGS_HTML" + file="new/pages_per_sheet_settings.html" + type="chrome_html" /> + <structure name="IDR_PRINT_PREVIEW_NEW_PAGES_PER_SHEET_SETTINGS_JS" + file="new/pages_per_sheet_settings.js" + type="chrome_html" /> <structure name="IDR_PRINT_PREVIEW_NEW_OTHER_OPTIONS_SETTINGS_HTML" file="new/other_options_settings.html" type="chrome_html" /> @@ -255,6 +268,14 @@ <structure name="IDR_PRINT_PREVIEW_NEW_ADVANCED_OPTIONS_SETTINGS_HTML" file="new/advanced_options_settings.html" type="chrome_html" /> + <structure name="IDR_PRINT_PREVIEW_NEW_MORE_SETTINGS_JS" + file="new/more_settings.js" + type="chrome_html" /> + <structure name="IDR_PRINT_PREVIEW_NEW_MORE_SETTINGS_HTML" + file="new/more_settings.html" + type="chrome_html" + flattenhtml="true" + allowexternalscript="true" /> <structure name="IDR_PRINT_PREVIEW_NEW_ADVANCED_OPTIONS_SETTINGS_JS" file="new/advanced_options_settings.js" type="chrome_html" /> @@ -293,7 +314,8 @@ allowexternalscript="true" /> <structure name="IDR_PRINT_PREVIEW_NEW_DESTINATION_DIALOG_JS" file="new/destination_dialog.js" - type="chrome_html" /> + type="chrome_html" + preprocess="true" /> <structure name="IDR_PRINT_PREVIEW_NEW_DESTINATION_LIST_HTML" file="new/destination_list.html" type="chrome_html" /> @@ -306,6 +328,13 @@ preprocess="true" /> <structure name="IDR_PRINT_PREVIEW_NEW_DESTINATION_LIST_ITEM_JS" file="new/destination_list_item.js" + type="chrome_html" + preprocess="true" /> + <structure name="IDR_PRINT_PREVIEW_NEW_PROVISIONAL_DESTINATION_RESOLVER_HTML" + file="new/provisional_destination_resolver.html" + type="chrome_html" /> + <structure name="IDR_PRINT_PREVIEW_NEW_PROVISIONAL_DESTINATION_RESOLVER_JS" + file="new/provisional_destination_resolver.js" type="chrome_html" /> <structure name="IDR_PRINT_PREVIEW_NEW_PRINT_PREVIEW_SEARCH_BOX_HTML" file="new/print_preview_search_box.html" diff --git a/chromium/chrome/browser/resources/print_preview/settings/advanced_settings/advanced_settings_item.js b/chromium/chrome/browser/resources/print_preview/settings/advanced_settings/advanced_settings_item.js index 9c54b548ce9..960f277398d 100644 --- a/chromium/chrome/browser/resources/print_preview/settings/advanced_settings/advanced_settings_item.js +++ b/chromium/chrome/browser/resources/print_preview/settings/advanced_settings/advanced_settings_item.js @@ -48,7 +48,7 @@ cr.define('print_preview', function() { */ this.searchBubble_ = null; - /** @private {!EventTracker} */ + /** @protected {!EventTracker} */ this.tracker_ = new EventTracker(); } diff --git a/chromium/chrome/browser/resources/print_preview/settings/layout_settings.js b/chromium/chrome/browser/resources/print_preview/settings/layout_settings.js index ec423d22f94..93246fc3e26 100644 --- a/chromium/chrome/browser/resources/print_preview/settings/layout_settings.js +++ b/chromium/chrome/browser/resources/print_preview/settings/layout_settings.js @@ -45,7 +45,7 @@ cr.define('print_preview', function() { /** @override */ enterDocument: function() { print_preview.SettingsSection.prototype.enterDocument.call(this); - this.tracker.add(this.select_, 'change', this.onSelectChange_.bind(this)); + this.tracker.add(this.select_, 'change', this.onSelectChange.bind(this)); this.tracker.add( this.landscapeTicketItem_, print_preview.ticket_items.TicketItem.EventType.CHANGE, @@ -55,9 +55,8 @@ cr.define('print_preview', function() { /** * Called when the select element is changed. Updates the print ticket * layout selection. - * @private */ - onSelectChange_: function() { + onSelectChange: function() { const select = this.select_; const isLandscape = select.options[select.selectedIndex].value == 'landscape'; diff --git a/chromium/chrome/browser/resources/print_preview/settings/margin_settings.js b/chromium/chrome/browser/resources/print_preview/settings/margin_settings.js index 4e8168d90a6..6af43ad7099 100644 --- a/chromium/chrome/browser/resources/print_preview/settings/margin_settings.js +++ b/chromium/chrome/browser/resources/print_preview/settings/margin_settings.js @@ -53,7 +53,7 @@ cr.define('print_preview', function() { enterDocument: function() { print_preview.SettingsSection.prototype.enterDocument.call(this); this.tracker.add( - assert(this.select_), 'change', this.onSelectChange_.bind(this)); + assert(this.select_), 'change', this.onSelectChange.bind(this)); this.tracker.add( this.marginsTypeTicketItem_, print_preview.ticket_items.TicketItem.EventType.CHANGE, @@ -62,7 +62,6 @@ cr.define('print_preview', function() { /** * @return {HTMLSelectElement} Select element containing the margin options. - * @private */ get select_() { return this.getElement().getElementsByClassName( @@ -72,9 +71,8 @@ cr.define('print_preview', function() { /** * Called when the select element is changed. Updates the print ticket * margin type. - * @private */ - onSelectChange_: function() { + onSelectChange: function() { const select = this.select_; const marginsType = /** @type {!print_preview.ticket_items.MarginsTypeValue} */ ( diff --git a/chromium/chrome/browser/resources/print_preview/settings/other_options_settings.js b/chromium/chrome/browser/resources/print_preview/settings/other_options_settings.js index ec3d88b7a63..85c826d8349 100644 --- a/chromium/chrome/browser/resources/print_preview/settings/other_options_settings.js +++ b/chromium/chrome/browser/resources/print_preview/settings/other_options_settings.js @@ -138,8 +138,7 @@ cr.define('print_preview', function() { * @private {boolean} rasterizeEnabled Whether the print as image feature is * enabled. */ - this.rasterizeEnabled_ = (!cr.isWindows && !cr.isMac) && - loadTimeData.getBoolean('printPdfAsImageEnabled'); + this.rasterizeEnabled_ = !cr.isWindows && !cr.isMac; /** * @private {!Array<!CheckboxTicketItemElement>} checkbox ticket item @@ -218,7 +217,10 @@ cr.define('print_preview', function() { $('rasterize-container').hidden = !this.rasterizeEnabled_; }, - /** @override */ + /** + * @public + * @override + */ updateUiStateInternal: function() { if (this.isAvailable()) { for (let i = 0; i < this.elements_.length; i++) diff --git a/chromium/chrome/browser/resources/print_preview/settings/scaling_settings.js b/chromium/chrome/browser/resources/print_preview/settings/scaling_settings.js index a4174049a4c..5a8e111aa46 100644 --- a/chromium/chrome/browser/resources/print_preview/settings/scaling_settings.js +++ b/chromium/chrome/browser/resources/print_preview/settings/scaling_settings.js @@ -176,7 +176,7 @@ cr.define('print_preview', function() { /** @override */ isSectionVisibleInternal: function() { return this.fitToPageTicketItem_.isCapabilityAvailable() || - (!this.collapseContent_ && + (!this.collapseContent && this.scalingTicketItem_.isCapabilityAvailable()); }, diff --git a/chromium/chrome/browser/resources/print_preview/settings/settings_section_select.js b/chromium/chrome/browser/resources/print_preview/settings/settings_section_select.js index fb20c2d7e06..f752d963d40 100644 --- a/chromium/chrome/browser/resources/print_preview/settings/settings_section_select.js +++ b/chromium/chrome/browser/resources/print_preview/settings/settings_section_select.js @@ -76,14 +76,14 @@ cr.define('print_preview', function() { } // Should the select content be updated? const sameContent = - this.ticketItem_.capability.option.length == select.length && - this.ticketItem_.capability.option.every(function(option, index) { + this.ticketItem_.capability().option.length == select.length && + this.ticketItem_.capability().option.every(function(option, index) { return select.options[index].value == JSON.stringify(option); }); let indexToSelect = select.selectedIndex; if (!sameContent) { select.innerHTML = ''; - this.ticketItem_.capability.option.forEach(function(option, index) { + this.ticketItem_.capability().option.forEach(function(option, index) { const selectOption = document.createElement('option'); selectOption.text = this.getCustomDisplayName_(option) || this.getDefaultDisplayName_(option); |