diff options
Diffstat (limited to 'chromium/chrome/browser/resources/settings/printing_page')
19 files changed, 765 insertions, 244 deletions
diff --git a/chromium/chrome/browser/resources/settings/printing_page/BUILD.gn b/chromium/chrome/browser/resources/settings/printing_page/BUILD.gn index e7619959244..00b021d9f12 100644 --- a/chromium/chrome/browser/resources/settings/printing_page/BUILD.gn +++ b/chromium/chrome/browser/resources/settings/printing_page/BUILD.gn @@ -21,7 +21,8 @@ js_type_check("closure_compile") { ":cups_printers", ":cups_printers_browser_proxy", ":cups_printers_entry", - ":cups_printers_entry_list", + ":cups_printers_entry_list_behavior", + ":cups_printers_entry_manager", ":cups_printers_list", ":cups_saved_printers", ":printing_browser_proxy", @@ -82,6 +83,10 @@ if (is_chromeos) { deps = [ ":cups_printer_types", ":cups_printers_browser_proxy", + ":cups_printers_entry", + ":cups_printers_entry_list_behavior", + ":cups_printers_entry_manager", + "//ui/webui/resources/js:list_property_update_behavior", "//ui/webui/resources/js:web_ui_listener_behavior", ] } @@ -102,6 +107,7 @@ if (is_chromeos) { deps = [ ":cups_nearby_printers", ":cups_printers_browser_proxy", + ":cups_printers_entry_manager", ":cups_saved_printers", "..:route", "//ui/webui/resources/cr_components/chromeos/network:mojo_interface_provider", @@ -128,14 +134,22 @@ if (is_chromeos) { ] } - js_library("cups_printers_entry_list") { + js_library("cups_printers_entry_list_behavior") { deps = [ ":cups_printer_types", - ":cups_printers_browser_proxy", "//ui/webui/resources/js:list_property_update_behavior", ] } + js_library("cups_printers_entry_manager") { + deps = [ + ":cups_printer_types", + ":cups_printers_browser_proxy", + "//ui/webui/resources/js:assert", + "//ui/webui/resources/js:cr", + ] + } + js_library("cups_printers_list") { deps = [ ":cups_printers_browser_proxy", @@ -149,7 +163,11 @@ if (is_chromeos) { deps = [ ":cups_printer_types", ":cups_printers_browser_proxy", + ":cups_printers_entry", + ":cups_printers_entry_list_behavior", + ":cups_printers_entry_manager", "//ui/webui/resources/cr_elements/cr_action_menu:cr_action_menu", + "//ui/webui/resources/js:list_property_update_behavior", "//ui/webui/resources/js:web_ui_listener_behavior", ] } diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.html b/chromium/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.html index 7c9a314bf87..f19b1047748 100644 --- a/chromium/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.html +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_add_printer_dialog.html @@ -78,7 +78,8 @@ <template> <style include="cups-printer-shared"></style> <add-printer-dialog> - <div slot="dialog-title">$i18n{addPrintersManuallyTitle}</div> + <div slot="dialog-title"> + $i18n{addPrintersManuallyTitle} <div id="general-error-container" hidden="[[!errorText_]]"> <div id="general-error"> <iron-icon id="general-error-icon" icon="cr:warning"></iron-icon> @@ -87,6 +88,7 @@ </div> </div> </div> + </div> <div slot="dialog-body"> <div class="settings-box first two-line"> <cr-input class="printer-name-input" autofocus diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.js b/chromium/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.js index 7f78d1dfb77..6b2ceffcc92 100644 --- a/chromium/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.js +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_edit_printer_dialog.js @@ -445,7 +445,7 @@ Polymer({ .getNetworkStateList({ filter: chromeos.networkConfig.mojom.FilterType.kActive, networkType: chromeos.networkConfig.mojom.NetworkType.kAll, - limit: chromeos.networkConfig.mojom.kNoLimit, + limit: chromeos.networkConfig.mojom.NO_LIMIT, }) .then((responseParams) => { this.onActiveNetworksChanged(responseParams.result); diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_nearby_printers.html b/chromium/chrome/browser/resources/settings/printing_page/cups_nearby_printers.html index 7d6bf1824d2..da0573be5ea 100644 --- a/chromium/chrome/browser/resources/settings/printing_page/cups_nearby_printers.html +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_nearby_printers.html @@ -1,26 +1,39 @@ <link rel="import" href="chrome://resources/html/polymer.html"> +<link rel="import" href="chrome://resources/html/list_property_update_behavior.html"> <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html"> <link rel="import" href="cups_printer_types.html"> <link rel="import" href="cups_printers_browser_proxy.html"> -<link rel="import" href="cups_printers_entry_list.html"> +<link rel="import" href="cups_printers_entry_list_behavior.html"> +<link rel="import" href="cups_printers_entry.html"> +<link rel="import" href="cups_printers_entry_manager.html"> <link rel="import" href="../settings_shared_css.html"> <dom-module id="settings-cups-nearby-printers"> <template> - <style include="settings-shared"> - #noPrinterMessage { - margin-inline-start: 60px; + <style include="cups-printer-shared"> + :host { + display: flex; + flex-direction: column; + } + + #no-search-results { margin-top: 20px; } </style> - <settings-cups-printers-entry-list printers="[[nearbyPrinters_]]" - search-term="[[searchTerm]]"> - </settings-cups-printers-entry-list> - <div class="secondary" id="noPrinterMessage" - hidden="[[!shouldShowNoNearbyPrinterMessage_(searchTerm, - nearbyPrinters_)]]"> - $i18n{noPrinterNearbyMessage} + + <iron-list class="list-frame vertical-list flex-auto" id="printerEntryList" + items="[[filteredPrinters_]]"> + <template> + <settings-cups-printers-entry printer-entry="[[item]]"> + </settings-cups-printers-entry> + </template> + </iron-list> + <div id="no-search-results" + hidden="[[!showNoSearchResultsMessage_(searchTerm, + filteredPrinters_.*)]]"> + $i18n{noSearchResults} </div> </template> <script src="cups_nearby_printers.js"></script> diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_nearby_printers.js b/chromium/chrome/browser/resources/settings/printing_page/cups_nearby_printers.js index aa4912c4010..f4020c2e390 100644 --- a/chromium/chrome/browser/resources/settings/printing_page/cups_nearby_printers.js +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_nearby_printers.js @@ -9,20 +9,16 @@ Polymer({ is: 'settings-cups-nearby-printers', - behaviors: [WebUIListenerBehavior], + // ListPropertyUpdateBehavior is used in CupsPrintersEntryListBehavior. + behaviors: [ + CupsPrintersEntryListBehavior, + ListPropertyUpdateBehavior, + WebUIListenerBehavior, + ], properties: { /** - * @type {!Array<!PrinterListEntry>} - * @private - */ - nearbyPrinters_: { - type: Array, - value: () => [], - }, - - /** - * Search term for filtering |nearbyPrinters_|. + * Search term for filtering |nearbyPrinters|. * @type {string} */ searchTerm: { @@ -30,6 +26,12 @@ Polymer({ value: '', }, + /** @type {?CupsPrinterInfo} */ + activePrinter: { + type: Object, + notify: true, + }, + /** * @type {number} * @private @@ -39,48 +41,47 @@ Polymer({ value: -1, }, - /** @type {?CupsPrinterInfo} */ - activePrinter: { - type: Object, - notify: true, + /** + * List of printers filtered through a search term. + * @type {!Array<!PrinterListEntry>} + * @private + */ + filteredPrinters_: { + type: Array, + value: () => [], }, }, listeners: { 'add-automatic-printer': 'onAddAutomaticPrinter_', + 'query-discovered-printer': 'onQueryDiscoveredPrinter_', }, - /** @override */ - attached: function() { - settings.CupsPrintersBrowserProxyImpl.getInstance() - .startDiscoveringPrinters(); - this.addWebUIListener( - 'on-nearby-printers-changed', this.onNearbyPrintersChanged_.bind(this)); - }, + observers: [ + 'onSearchOrPrintersChanged_(nearbyPrinters.*, searchTerm)' + ], /** - * @param {!Array<!CupsPrinterInfo>} automaticPrinters - * @param {!Array<!CupsPrinterInfo>} discoveredPrinters + * Redoes the search whenever |searchTerm| or |nearbyPrinters| changes. * @private */ - onNearbyPrintersChanged_: function(automaticPrinters, discoveredPrinters) { - if (!automaticPrinters && !discoveredPrinters) { + onSearchOrPrintersChanged_: function() { + if (!this.nearbyPrinters) { return; } - - const printers = /** @type{!Array<!PrinterListEntry>} */ ([]); - - for (const printer of automaticPrinters) { - printers.push({printerInfo: printer, - printerType: PrinterType.AUTOMATIC}); - } - - for (const printer of discoveredPrinters) { - printers.push({printerInfo: printer, - printerType: PrinterType.DISCOVERED}); - } - - this.nearbyPrinters_ = printers; + // Filter printers through |searchTerm|. If |searchTerm| is empty, + // |filteredPrinters_| is just |nearbyPrinters|. + const updatedPrinters = this.searchTerm ? + this.nearbyPrinters.filter( + item => settings.printing.matchesSearchTerm( + item.printerInfo,this.searchTerm)) : + this.nearbyPrinters.slice(); + + updatedPrinters.sort(settings.printing.sortPrinters); + + this.updateList( + 'filteredPrinters_', printer => printer.printerInfo.printerId, + updatedPrinters); }, /** @@ -100,18 +101,38 @@ Polymer({ }, /** + * @param {!CustomEvent<{item: !PrinterListEntry}>} e + * @private + */ + onQueryDiscoveredPrinter_: function(e) { + const item = e.detail.item; + this.setActivePrinter_(item); + + // This is a workaround to ensure type safety on the params of the casted + // function. We do this because the closure compiler does not work well with + // rejected js promises. + const queryDiscoveredPrinterFailed = /** @type {!Function}) */( + this.onQueryDiscoveredPrinterFailed_.bind(this)); + settings.CupsPrintersBrowserProxyImpl.getInstance() + .addDiscoveredPrinter(item.printerInfo.printerId) + .then( + this.onQueryDiscoveredPrinterSucceeded_.bind(this, + item.printerInfo.printerName), + queryDiscoveredPrinterFailed); + }, + + /** * Retrieves the index of |item| in |nearbyPrinters_| and sets that printer as * the active printer. * @param {!PrinterListEntry} item * @private */ setActivePrinter_: function(item) { - this.activePrinterListEntryIndex_ = - this.nearbyPrinters_.findIndex( - printer => printer.printerInfo == item.printerInfo); + this.activePrinterListEntryIndex_ = this.nearbyPrinters.findIndex( + printer => printer.printerInfo.printerId == item.printerInfo.printerId); this.activePrinter = - this.get(['nearbyPrinters_', this.activePrinterListEntryIndex_]) + this.get(['nearbyPrinters', this.activePrinterListEntryIndex_]) .printerInfo; }, @@ -140,10 +161,32 @@ Polymer({ }, /** - * @return {boolean} Returns true if noPrinterMessage should be visible. + * Handler for queryDiscoveredPrinter success. + * @param {string} printerName + * @param {!PrinterSetupResult} result + * @private + */ + onQueryDiscoveredPrinterSucceeded_: function(printerName, result) { + this.fire( + 'show-cups-printer-toast', + {resultCode: result, printerName: printerName}); + }, + + /** + * Handler for queryDiscoveredPrinter failure. + * @param {!CupsPrinterInfo} printer + * @private + */ + onQueryDiscoveredPrinterFailed_: function(printer) { + this.fire('open-manufacturer-model-dialog-for-specified-printer', + {item: /** @type {CupsPrinterInfo} */(printer)}); + }, + + /** + * @return {boolean} Returns true if the no search message should be visible. * @private */ - shouldShowNoNearbyPrinterMessage_: function() { - return !this.searchTerm && !this.nearbyPrinters_.length; + showNoSearchResultsMessage_: function() { + return !!this.searchTerm && !this.filteredPrinters_.length; } });
\ No newline at end of file diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printer_dialog_util.js b/chromium/chrome/browser/resources/settings/printing_page/cups_printer_dialog_util.js index 15542cb8d1c..46b1be62226 100644 --- a/chromium/chrome/browser/resources/settings/printing_page/cups_printer_dialog_util.js +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printer_dialog_util.js @@ -141,6 +141,40 @@ cr.define('settings.printing', function() { } } + /** + * We sort by printer type, which is based off of a maintained list in + * cups_printers_types.js. If the types are the same, we sort alphabetically. + * @param {!PrinterListEntry} first + * @param {!PrinterListEntry} second + * @return {number} + */ + function sortPrinters(first, second) { + if (first.printerType == second.printerType) { + return settings.printing.alphabeticalSort( + first.printerInfo, second.printerInfo); + } + + return first.printerType - second.printerType; + } + + /** + * @param {!CupsPrinterInfo} printer + * @param {string} searchTerm + * @return {boolean} True if the printer has |searchTerm| in its name. + */ + function matchesSearchTerm(printer, searchTerm) { + return printer.printerName.toLowerCase().includes(searchTerm.toLowerCase()); + } + + /** + * @param {!PrinterListEntry} first + * @param {!PrinterListEntry} second + * @return {boolean} + */ + function arePrinterIdsEqual(first, second) { + return first.printerInfo.printerId == second.printerInfo.printerId; + } + return { isNetworkProtocol: isNetworkProtocol, isNameAndAddressValid: isNameAndAddressValid, @@ -148,5 +182,8 @@ cr.define('settings.printing', function() { getBaseName: getBaseName, alphabeticalSort: alphabeticalSort, getErrorText: getErrorText, + sortPrinters: sortPrinters, + matchesSearchTerm: matchesSearchTerm, + arePrinterIdsEqual: arePrinterIdsEqual, }; }); diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printer_shared_css.html b/chromium/chrome/browser/resources/settings/printing_page/cups_printer_shared_css.html index cda0410aaa6..68ee364dca0 100644 --- a/chromium/chrome/browser/resources/settings/printing_page/cups_printer_shared_css.html +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printer_shared_css.html @@ -68,6 +68,10 @@ width: 100%; } + .flex-auto { + flex: 1 1 auto; + } + .list-item { background: none; border: none; @@ -109,6 +113,10 @@ font-size: 10px; margin-inline-start: 5px; } + + #no-search-results { + text-align: center; + } </style> </template> </dom-module> diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printers.html b/chromium/chrome/browser/resources/settings/printing_page/cups_printers.html index 6777282b161..c5b866a04bc 100644 --- a/chromium/chrome/browser/resources/settings/printing_page/cups_printers.html +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printers.html @@ -16,6 +16,7 @@ <link rel="import" href="cups_add_printer_dialog.html"> <link rel="import" href="cups_edit_printer_dialog.html"> <link rel="import" href="cups_printer_shared_css.html"> +<link rel="import" href="cups_printers_entry_manager.html"> <link rel="import" href="cups_printers_list.html"> <link rel="import" href="cups_saved_printers.html"> <link rel="import" href="cups_nearby_printers.html"> @@ -142,7 +143,6 @@ <settings-cups-saved-printers id="savedPrinters" active-printer="{{activePrinter}}" - saved-printers="[[savedPrinters_]]" search-term="[[searchTerm]]"> </settings-cups-saved-printers> </div> @@ -197,7 +197,7 @@ </settings-cups-edit-printer-dialog> </template> - <cr-toast id="errorToast" duration="3000"> + <cr-toast id="errorToast" duration="3000" role="alert"> <div class="error-message" id="addPrinterDoneMessage"> [[addPrinterResultText_]] </div> diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printers.js b/chromium/chrome/browser/resources/settings/printing_page/cups_printers.js index 21109350ab6..ece618460ad 100644 --- a/chromium/chrome/browser/resources/settings/printing_page/cups_printers.js +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printers.js @@ -81,11 +81,16 @@ Polymer({ /** @private {?chromeos.networkConfig.mojom.CrosNetworkConfigRemote} */ networkConfig_: null, + /** @private {settings.printing.CupsPrintersEntryManager} */ + entryManager_: null, + /** @override */ created: function() { this.networkConfig_ = network_config.MojoInterfaceProviderImpl.getInstance() .getMojoServiceRemote(); + this.entryManager_ = + settings.printing.CupsPrintersEntryManager.getInstance(); }, /** @override */ @@ -94,7 +99,7 @@ Polymer({ .getNetworkStateList({ filter: chromeos.networkConfig.mojom.FilterType.kActive, networkType: chromeos.networkConfig.mojom.NetworkType.kAll, - limit: chromeos.networkConfig.mojom.kNoLimit, + limit: chromeos.networkConfig.mojom.NO_LIMIT, }) .then((responseParams) => { this.onActiveNetworksChanged(responseParams.result); @@ -110,7 +115,6 @@ Polymer({ this.updateCupsPrintersList_(); }, - /** * settings.RouteObserverBehavior * @param {!settings.Route} route @@ -119,10 +123,14 @@ Polymer({ currentRouteChanged: function(route) { if (route != settings.routes.CUPS_PRINTERS) { cr.removeWebUIListener('on-printers-changed'); + this.entryManager_.removeWebUIListeners(); return; } + + this.entryManager_.addWebUIListeners(); cr.addWebUIListener( 'on-printers-changed', this.onPrintersChanged_.bind(this)); + this.updateCupsPrintersList_(); }, /** @@ -148,17 +156,15 @@ Polymer({ * }>} event * @private */ - openResultToast_: function(event) { + openResultToast_: function(event) { const printerName = event.detail.printerName; switch (event.detail.resultCode) { case PrinterSetupResult.SUCCESS: - this.updateCupsPrintersList_(); this.addPrinterResultText_ = loadTimeData.getStringF('printerAddedSuccessfulMessage', printerName); break; case PrinterSetupResult.EDIT_SUCCESS: - this.updateCupsPrintersList_(); this.addPrinterResultText_ = loadTimeData.getStringF('printerEditedSuccessfulMessage', printerName); @@ -203,6 +209,7 @@ Polymer({ printer => /** @type {!PrinterListEntry} */({ printerInfo: printer, printerType: PrinterType.SAVED})); + this.entryManager_.setSavedPrintersList(this.savedPrinters_); } else { this.printers = cupsPrintersList.printerList; } diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry.html b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry.html index c8df839a0ee..8d7c6b5145c 100644 --- a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry.html +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry.html @@ -29,7 +29,7 @@ <template is="dom-if" if="[[isDiscoveredPrinter_(printerEntry.printerType)]]"> <cr-button id="setupPrinterButton" - on-click="onOpenManufacturerModelDialogTap_"> + on-click="onAddDiscoveredPrinterTap_"> $i18n{setupPrinter} </cr-button> </template> diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry.js b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry.js index fe225dcf9fa..5734b7717ae 100644 --- a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry.js +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry.js @@ -33,9 +33,8 @@ Polymer({ }); }, - onOpenManufacturerModelDialogTap_: function(e) { - this.fire('open-manufacturer-model-dialog-for-specified-printer', - {item: this.printerEntry.printerInfo}); + onAddDiscoveredPrinterTap_: function(e) { + this.fire('query-discovered-printer', {item: this.printerEntry}); }, onAddAutomaticPrinterTap_: function() { diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list.html b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list.html deleted file mode 100644 index bf9fbaf1f9f..00000000000 --- a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list.html +++ /dev/null @@ -1,42 +0,0 @@ -<link rel="import" href="chrome://resources/html/polymer.html"> - -<link rel="import" href="chrome://resources/html/list_property_update_behavior.html"> -<link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html"> -<link rel="import" href="cups_printer_dialog_util.html"> -<link rel="import" href="cups_printer_types.html"> -<link rel="import" href="cups_printers_browser_proxy.html"> -<link rel="import" href="cups_printers_entry.html"> -<link rel="import" href="../settings_shared_css.html"> - -<dom-module id="settings-cups-printers-entry-list"> - <template> - <style include="settings-shared"> - :host { - display: flex; - flex-direction: column; - } - - iron-list { - flex: 1 1 auto; - } - - #no-search-results { - margin-top: 20px; - text-align: center; - } - - </style> - <iron-list class="list-frame vertical-list" id="printerEntryList" - items="[[filteredPrinters_]]"> - <template> - <settings-cups-printers-entry printer-entry="[[item]]"> - </settings-cups-printers-entry> - </template> - </iron-list> - <div id="no-search-results" - hidden="[[!showNoSearchResultsMessage_]]"> - $i18n{noSearchResults} - </div> - </template> - <script src="cups_printers_entry_list.js"></script> -</dom-module> diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list.js b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list.js deleted file mode 100644 index 3fe5f69bd12..00000000000 --- a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list.js +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2019 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 'settings-cups-printers-entry-list' is a component for a list - * of PrinterListEntry's. - */ -Polymer({ - is: 'settings-cups-printers-entry-list', - - behaviors: [ - ListPropertyUpdateBehavior, - ], - - properties: { - /** - * List of printers. - * @type {!Array<!PrinterListEntry>} - */ - printers: { - type: Array, - value: () => [], - }, - - /** - * List of printers filtered through a search term. - * @type {!Array<!PrinterListEntry>} - * @private - */ - filteredPrinters_: { - type: Array, - value: () => [], - }, - - /** - * Search term for filtering |printers|. - * @type {string} - */ - searchTerm: { - type: String, - value: '', - }, - - /** - * Whether to show the no search results message. - * @type {boolean} - * @private - */ - showNoSearchResultsMessage_: { - type: Boolean, - value: false, - }, - }, - - observers: [ - 'onSearchChanged_(printers.*, searchTerm)' - ], - - /** - * Redoes the search whenever |searchTerm| or |printers| changes. - * @private - */ - onSearchChanged_: function() { - if (!this.printers) { - return; - } - // Filter printers through |searchTerm|. If |searchTerm| is empty, - // |filteredPrinters_| is just |printers|. - const updatedPrinters = this.searchTerm ? - this.printers.filter( - item =>this.matchesSearchTerm_(item.printerInfo,this.searchTerm)) : - this.printers.slice(); - - updatedPrinters.sort(this.sortPrinters_); - - this.updateList('filteredPrinters_', printer => printer.printerInfo, - updatedPrinters); - - this.showNoSearchResultsMessage_ = - !!this.searchTerm && !this.filteredPrinters_.length; - }, - - - /** - * @param {!PrinterListEntry} first - * @param {!PrinterListEntry} second - * @return {number} - * @private - */ - sortPrinters_: function(first, second) { - if (first.printerType == second.printerType) { - return settings.printing.alphabeticalSort( - first.printerInfo, second.printerInfo); - } - - // PrinterType sort order maintained in cups_printer_types.js - return first.printerType - second.printerType; - }, - - /** - * @param {!CupsPrinterInfo} printer - * @param {string} searchTerm - * @return {boolean} True if the printer has |searchTerm| in its name. - * @private - */ - matchesSearchTerm_: function(printer, searchTerm) { - return printer.printerName.toLowerCase().includes(searchTerm.toLowerCase()); - } -}); diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list_behavior.html b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list_behavior.html new file mode 100644 index 00000000000..6f30319498f --- /dev/null +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list_behavior.html @@ -0,0 +1,2 @@ +<link rel="import" href="cups_printer_types.html"> +<script src="cups_printers_entry_list_behavior.js"></script>
\ No newline at end of file diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list_behavior.js b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list_behavior.js new file mode 100644 index 00000000000..59588b24629 --- /dev/null +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_list_behavior.js @@ -0,0 +1,98 @@ +// Copyright 2019 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 Polymer behavior for observing CupsPrintersEntryManager events. + * Use this behavior if you want to receive a dynamically updated list of both + * saved and nearby printers. + */ + +/** @polymerBehavior */ +const CupsPrintersEntryListBehavior = { + properties: { + /** @private {!settings.printing.CupsPrintersEntryManager} */ + entryManager_: Object, + + /** @type {!Array<!PrinterListEntry>} */ + savedPrinters: { + type: Array, + value: () => [], + }, + + /** @type {!Array<!PrinterListEntry>} */ + nearbyPrinters: { + type: Array, + value: () => [], + }, + }, + + /** @override */ + created: function() { + this.entryManager_ = + settings.printing.CupsPrintersEntryManager.getInstance(); + }, + + /** @override */ + attached: function() { + this.entryManager_.addOnSavedPrintersChangedListener( + this.onSavedPrintersChanged_.bind(this)); + this.entryManager_.addOnNearbyPrintersChangedListener( + this.onNearbyPrintersChanged_.bind(this)); + + // Initialize saved and nearby printers list. + this.onSavedPrintersChanged_( + this.entryManager_.savedPrinters, [] /* printerAdded */, + [] /* printerRemoved */); + this.onNearbyPrintersChanged_(this.entryManager_.nearbyPrinters); + }, + + /** @override */ + detached: function() { + this.entryManager_.removeOnSavedPrintersChangedListener( + this.onSavedPrintersChanged_.bind(this)); + this.entryManager_.removeOnNearbyPrintersChangedListener( + this.onNearbyPrintersChanged_.bind(this)); + }, + + /** + * Non-empty params indicate the applicable change to be notified. + * @param {!Array<!PrinterListEntry>} savedPrinters + * @param {!Array<!PrinterListEntry>} addedPrinters + * @param {!Array<!PrinterListEntry>} removedPrinters + * @private + */ + onSavedPrintersChanged_: function( + savedPrinters, addedPrinters, removedPrinters) { + this.updateList( + 'savedPrinters', printer => printer.printerInfo.printerId, + savedPrinters); + + assert(!(addedPrinters.length && removedPrinters.length)); + + if (addedPrinters.length) { + this.onSavedPrintersAdded(addedPrinters); + } else if (removedPrinters.length) { + this.onSavedPrintersRemoved(removedPrinters); + } + }, + + /** + * @param {!Array<!PrinterListEntry>} printerList + * @private + */ + onNearbyPrintersChanged_: function(printerList) { + this.updateList( + 'nearbyPrinters', printer => printer.printerInfo.printerId, + printerList); + }, + + // CupsPrintersEntryListBehavior methods. Override these in the + // implementations. + + /** @param{!Array<!PrinterListEntry>} addedPrinters */ + onSavedPrintersAdded: function(addedPrinters) {}, + + /** @param{!Array<!PrinterListEntry>} removedPrinters */ + onSavedPrintersRemoved: function(removedPrinters) {}, +};
\ No newline at end of file diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_manager.html b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_manager.html new file mode 100644 index 00000000000..d8e4aac3867 --- /dev/null +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_manager.html @@ -0,0 +1,5 @@ +<link rel="import" href="chrome://resources/html/assert.html"> +<link rel="import" href="chrome://resources/html/cr.html"> +<link rel="import" href="cups_printer_types.html"> +<link rel="import" href="cups_printers_browser_proxy.html"> +<script src="cups_printers_entry_manager.js"></script>
\ No newline at end of file diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_manager.js b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_manager.js new file mode 100644 index 00000000000..86908fbb3c3 --- /dev/null +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_printers_entry_manager.js @@ -0,0 +1,182 @@ +// Copyright 2019 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. + +/** + * Function which provides the client with metadata about a change + * to a list of saved printers. The first parameter is the updated list of + * printers after the change, the second parameter is the newly-added printer + * (if it exists), and the third parameter is the newly-removed printer + * (if it exists). + * @typedef {!function(!Array<!PrinterListEntry>, !Array<!PrinterListEntry>, + * !Array<!PrinterListEntry>): void} + */ +let PrintersListWithDeltasCallback; + +/** + * Function which provides the client with a list that contains the nearby + * printers list. The parameter is the updated list of printers after any + * changes. + * @typedef {function(!Array<!PrinterListEntry>): void} + */ +let PrintersListCallback; + +cr.define('settings.printing', function() { + /** + * Finds the printers that are in |firstArr| but not in |secondArr|. + * @param {!Array<!PrinterListEntry>} firstArr + * @param {!Array<!PrinterListEntry>} secondArr + * @return {!Array<!PrinterListEntry>} + * @private + */ + function findDifference_(firstArr, secondArr) { + return firstArr.filter((firstArrEntry) => { + return !secondArr.some( + p => p.printerInfo.printerId == firstArrEntry.printerInfo.printerId); + }); + } + + /** + * Class for managing printer entries. Holds both Saved and Nearby printers + * and notifies observers of any applicable changes to either printer lists. + */ + class CupsPrintersEntryManager { + constructor() { + /** @private {!Array<!PrinterListEntry>} */ + this.savedPrinters_ = []; + + /** @private {!Array<!PrinterListEntry>} */ + this.nearbyPrinters_ = []; + + /** @private {!Array<PrintersListWithDeltasCallback>} */ + this.onSavedPrintersChangedListeners_ = []; + + /** @type {!Array<PrintersListCallback>} */ + this.onNearbyPrintersChangedListeners_ = []; + } + + addWebUIListeners() { + // TODO(1005905): Add on-printers-changed listener here once legacy code + // is removed. + cr.addWebUIListener( + 'on-nearby-printers-changed', this.setNearbyPrintersList.bind(this)); + settings.CupsPrintersBrowserProxyImpl.getInstance() + .startDiscoveringPrinters(); + } + + removeWebUIListeners() { + cr.removeWebUIListener('on-nearby-printers-changed'); + } + + /** @return {!Array<!PrinterListEntry>} */ + get savedPrinters() { + return this.savedPrinters_; + } + + /** @return {!Array<!PrinterListEntry>} */ + get nearbyPrinters() { + return this.nearbyPrinters_; + } + + /** @param {PrintersListWithDeltasCallback} listener */ + addOnSavedPrintersChangedListener(listener) { + this.onSavedPrintersChangedListeners_.push(listener); + } + + /** @param {PrintersListWithDeltasCallback} listener */ + removeOnSavedPrintersChangedListener(listener) { + this.onSavedPrintersChangedListeners_ = + this.onSavedPrintersChangedListeners_.filter(lis => lis != listener); + } + + /** @param {PrintersListCallback} listener */ + addOnNearbyPrintersChangedListener(listener) { + this.onNearbyPrintersChangedListeners_.push(listener); + } + + /** @param {PrintersListCallback} listener */ + removeOnNearbyPrintersChangedListener(listener) { + this.onNearbyPrintersChangedListeners_ = + this.onNearbyPrintersChangedListeners_.filter(lis => lis != listener); + } + + /** + * Sets the saved printers list and notifies observers of any applicable + * changes. + * @param {!Array<!PrinterListEntry>} printerList + */ + setSavedPrintersList(printerList) { + if (printerList.length > this.savedPrinters_.length) { + const diff = findDifference_(printerList, this.savedPrinters_); + this.savedPrinters_ = printerList; + this.notifyOnSavedPrintersChangedListeners_( + this.savedPrinters_, diff, [] /* printersRemoved */); + return; + } + + if (printerList.length < this.savedPrinters_.length) { + const diff = findDifference_(this.savedPrinters_, printerList); + this.savedPrinters_ = printerList; + this.notifyOnSavedPrintersChangedListeners_( + this.savedPrinters_, [] /* printersAdded */, diff); + return; + } + + this.savedPrinters_ = printerList; + this.notifyOnSavedPrintersChangedListeners_( + this.savedPrinters_, [] /* printersAdded */, + [] /* printersRemoved */); + } + + /** + * Sets the nearby printers list and notifies observers of any applicable + * changes. + * @param {!Array<!CupsPrinterInfo>} automaticPrinters + * @param {!Array<!CupsPrinterInfo>} discoveredPrinters + */ + setNearbyPrintersList(automaticPrinters, discoveredPrinters) { + if (!automaticPrinters && !discoveredPrinters) { + return; + } + + this.nearbyPrinters_ = []; + + for (const printer of automaticPrinters) { + this.nearbyPrinters_.push( + {printerInfo: printer, printerType: PrinterType.AUTOMATIC}); + } + + for (const printer of discoveredPrinters) { + this.nearbyPrinters_.push( + {printerInfo: printer, printerType: PrinterType.DISCOVERED}); + } + + this.notifyOnNearbyPrintersChangedListeners_(); + } + + /** + * Non-empty/null fields indicate the applicable change to be notified. + * @param {!Array<!PrinterListEntry>} savedPrinters + * @param {!Array<!PrinterListEntry>} addedPrinter + * @param {!Array<!PrinterListEntry>} removedPrinter + * @private + */ + notifyOnSavedPrintersChangedListeners_( + savedPrinters, addedPrinter, removedPrinter) { + this.onSavedPrintersChangedListeners_.forEach( + listener => listener(savedPrinters, addedPrinter, removedPrinter)); + } + + /** @private */ + notifyOnNearbyPrintersChangedListeners_() { + this.onNearbyPrintersChangedListeners_.forEach( + listener => listener(this.nearbyPrinters_)); + } + } + + cr.addSingletonGetter(CupsPrintersEntryManager); + + return { + CupsPrintersEntryManager: CupsPrintersEntryManager, + }; +});
\ No newline at end of file diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_saved_printers.html b/chromium/chrome/browser/resources/settings/printing_page/cups_saved_printers.html index 1bb09c08fc0..c89d0230a99 100644 --- a/chromium/chrome/browser/resources/settings/printing_page/cups_saved_printers.html +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_saved_printers.html @@ -1,14 +1,52 @@ <link rel="import" href="chrome://resources/html/polymer.html"> <link rel="import" href="chrome://resources/cr_elements/cr_action_menu/cr_action_menu.html"> +<link rel="import" href="chrome://resources/html/list_property_update_behavior.html"> <link rel="import" href="chrome://resources/html/web_ui_listener_behavior.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/iron-flex-layout-classes.html"> +<link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html"> <link rel="import" href="cups_printer_types.html"> <link rel="import" href="cups_printers_browser_proxy.html"> -<link rel="import" href="cups_printers_entry_list.html"> +<link rel="import" href="cups_printers_entry_list_behavior.html"> +<link rel="import" href="cups_printers_entry.html"> <link rel="import" href="../settings_shared_css.html"> <dom-module id="settings-cups-saved-printers"> <template> + <style include="cups-printer-shared iron-flex iron-flex-alignment + iron-flex-factors"> + :host { + display: flex; + flex-direction: column; + } + + #no-search-results { + margin-bottom: 20px; + } + + /** Height of iron list row entry. */ + #show-more-container { + min-height: var(--settings-row-min-height); + } + + /** Border line that is the same size as a list entry's border. */ + #show-more-line-separator { + border-bottom: var(--cr-separator-line); + left: 60px; + position: relative; + right: 20px; + width: 596px; + } + + #show-more-icon { + --cr-icon-button-margin-end: 0; + } + + #show-more-text { + flex: 1; + } + </style> + <cr-action-menu> <button id="editButton" class="dropdown-item" on-click="onEditTap_"> $i18n{editPrinter} @@ -18,10 +56,32 @@ </button> </cr-action-menu> - <style include="settings-shared"></style> - <settings-cups-printers-entry-list printers="[[savedPrinters]]" - search-term="[[searchTerm]]"> - </settings-cups-printers-entry-list> + <iron-list class="list-frame vertical-list flex-auto" id="printerEntryList" + items="[[filteredPrinters_]]"> + <template> + <settings-cups-printers-entry printer-entry="[[item]]"> + </settings-cups-printers-entry> + </template> + </iron-list> + <template is="dom-if" id="show-more-button-section" + if="[[shouldPrinterListBeCollapsed_(searchTerm, savedPrinters.*, + newPrinters_.*, hasShowMoreBeenTapped_)]]" restamp> + <div id="show-more-line-separator"></div> + <div class="list-frame layout horizontal" id="show-more-container"> + <div id="show-more-text">$i18n{showMorePrinters}</div> + <cr-icon-button class="action-button" id="show-more-icon" + iron-icon="cr:expand-more" + on-click="onShowMoreTap_" + title=$i18n{showMorePrinters}> + </cr-icon-button> + </div> + </template> + + <div id="no-search-results" + hidden="[[!showNoSearchResultsMessage_(searchTerm, + filteredPrinters_.*)]]"> + $i18n{noSearchResults} + </div> </template> <script src="cups_saved_printers.js"></script> </dom-module> diff --git a/chromium/chrome/browser/resources/settings/printing_page/cups_saved_printers.js b/chromium/chrome/browser/resources/settings/printing_page/cups_saved_printers.js index 85ef694f1ec..948bc0526ab 100644 --- a/chromium/chrome/browser/resources/settings/printing_page/cups_saved_printers.js +++ b/chromium/chrome/browser/resources/settings/printing_page/cups_saved_printers.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. +(function() { + +// If the Show more button is visible, the minimum number of printers we show +// is 3. +const kMinVisiblePrinters = 3; + +/** + * Move a printer's position in |printerArr| from |fromIndex| to |toIndex|. + * @param {!Array<!PrinterListEntry>} printerArr + * @param {number} fromIndex + * @param {number} toIndex + */ +function moveEntryInPrinters(printerArr, fromIndex, toIndex) { + const element = printerArr[fromIndex]; + printerArr.splice(fromIndex, 1); + printerArr.splice(toIndex, 0, element); +} + /** * @fileoverview 'settings-cups-saved-printers' is a list container for Saved * Printers. @@ -9,16 +27,14 @@ Polymer({ is: 'settings-cups-saved-printers', + // ListPropertyUpdateBehavior is used in CupsPrintersEntryListBehavior. behaviors: [ - WebUIListenerBehavior, + CupsPrintersEntryListBehavior, + ListPropertyUpdateBehavior, + WebUIListenerBehavior, ], properties: { - /** @type {!Array<!PrinterListEntry>} */ - savedPrinters: { - type: Array, - }, - /** * Search term for filtering |savedPrinters|. * @type {string} @@ -28,6 +44,12 @@ Polymer({ value: '', }, + /** @type {?CupsPrinterInfo} */ + activePrinter: { + type: Object, + notify: true, + }, + /** * @type {number} * @private @@ -37,10 +59,36 @@ Polymer({ value: -1, }, - /** @type {?CupsPrinterInfo} */ - activePrinter: { - type: Object, - notify: true, + /** + * List of printers filtered through a search term. + * @type {!Array<!PrinterListEntry>} + * @private + */ + filteredPrinters_: { + type: Array, + value: () => [], + }, + + /** + * Array of new PrinterListEntry's that were added during this session. + * @type {!Array<!PrinterListEntry>} + * @private + */ + newPrinters_: { + type: Array, + value: () => [], + }, + + /** + * Keeps track of whether the user has tapped the Show more button. A search + * term will expand the collapsed list, so we need to keep track of whether + * the list expanded because of a search term or because the user tapped on + * the Show more button. + * @private + */ + hasShowMoreBeenTapped_: { + type: Boolean, + value: false, }, }, @@ -48,23 +96,50 @@ Polymer({ 'open-action-menu': 'onOpenActionMenu_', }, + observers: [ + 'onSearchOrPrintersChanged_(savedPrinters.*, searchTerm,' + + 'hasShowMoreBeenTapped_, newPrinters_.*)' + ], + /** @private {settings.CupsPrintersBrowserProxy} */ browserProxy_: null, + /** + * The number of printers we display if hidden printers are allowed. + * kMinVisiblePrinters is the default value and we never show fewer printers + * if the Show more button is visible. + */ + visiblePrinterCounter_: kMinVisiblePrinters, + /** @override */ created: function() { this.browserProxy_ = settings.CupsPrintersBrowserProxyImpl.getInstance(); }, /** + * Redoes the search whenever |searchTerm| or |savedPrinters| changes. + * @private + */ + onSearchOrPrintersChanged_: function() { + if (!this.savedPrinters) { + return; + } + + const updatedPrinters = this.getVisiblePrinters_(); + + this.updateList( + 'filteredPrinters_', printer => printer.printerInfo.printerId, + updatedPrinters); + }, + + /** * @param {!CustomEvent<{target: !HTMLElement, item: !PrinterListEntry}>} e * @private */ onOpenActionMenu_: function(e) { const item = /** @type {!PrinterListEntry} */(e.detail.item); - this.activePrinterListEntryIndex_ = - this.savedPrinters.findIndex( - printer => printer.printerInfo == item.printerInfo); + this.activePrinterListEntryIndex_ = this.savedPrinters.findIndex( + printer => printer.printerInfo.printerId == item.printerInfo.printerId); this.activePrinter = this.get(['savedPrinters', this.activePrinterListEntryIndex_]) .printerInfo; @@ -90,7 +165,131 @@ Polymer({ }, /** @private */ + onShowMoreTap_: function() { + this.hasShowMoreBeenTapped_ = true; + }, + + /** + * Gets the printers to be shown in the UI. These printers are filtered + * by the search term, alphabetically sorted (if applicable), and are the + * printers not hidden by the Show more section. + * @return {!Array<!PrinterListEntry>} Returns only the visible printers. + * @private + */ + getVisiblePrinters_: function() { + // Filter printers through |searchTerm|. If |searchTerm| is empty, + // |filteredPrinters_| is just |savedPrinters|. + const updatedPrinters = this.searchTerm ? + this.savedPrinters.filter( + item => settings.printing.matchesSearchTerm( + item.printerInfo, this.searchTerm)) : + this.savedPrinters.slice(); + + updatedPrinters.sort(settings.printing.sortPrinters); + + this.moveNewlyAddedPrinters_(updatedPrinters, 0 /* toIndex */); + + if (this.shouldPrinterListBeCollapsed_()) { + // If the Show more button is visible, we only display the first + // N < |visiblePrinterCounter_| printers and the rest are hidden. + return updatedPrinters.filter( + (printer, idx) => idx < this.visiblePrinterCounter_); + } + return updatedPrinters; + }, + + /** @private */ closeActionMenu_: function() { this.$$('cr-action-menu').close(); + }, + + /** + * @return {boolean} Returns true if the no search message should be visible. + * @private + */ + showNoSearchResultsMessage_: function() { + return !!this.searchTerm && !this.filteredPrinters_.length; + }, + + /** @param{!Array<!PrinterListEntry>} addedPrinters */ + onSavedPrintersAdded: function(addedPrinters) { + const currArr = this.newPrinters_.slice(); + for (const printer of addedPrinters) { + this.visiblePrinterCounter_++; + currArr.push(printer); + } + + this.set('newPrinters_', currArr); + }, + + /** @param{!Array<!PrinterListEntry>} removedPrinters */ + onSavedPrintersRemoved: function(removedPrinters) { + const currArr = this.newPrinters_.slice(); + for (const printer of removedPrinters) { + const newPrinterRemovedIdx = currArr.findIndex( + p => p.printerInfo.printerId == printer.printerInfo.printerId); + // If the removed printer is a recently added printer, remove it from + // |currArr|. + if (newPrinterRemovedIdx > -1) { + currArr.splice(newPrinterRemovedIdx, 1); + } + + this.visiblePrinterCounter_ = Math.max( + kMinVisiblePrinters, --this.visiblePrinterCounter_); + } + + this.set('newPrinters_', currArr); + }, + + /** + * Keeps track of whether the Show more button should be visible which means + * that the printer list is collapsed. There are two ways a collapsed list + * may be expanded: the Show more button is tapped or if there is a search + * term. + * @return {boolean} True if the printer list should be collapsed. + * @private + */ + shouldPrinterListBeCollapsed_: function() { + // If |searchTerm| is set, never collapse the list. + if (this.searchTerm) { + return false; + } + + // If |hasShowMoreBeenTapped_| is set to true, never collapse the list. + if (this.hasShowMoreBeenTapped_) { + return false; + } + + // If the total number of saved printers does not exceed the number of + // visible printers, there is no need for the list to be collapsed. + if (this.savedPrinters.length - this.visiblePrinterCounter_ < 1) { + return false; + } + + return true; + }, + + /** + * Moves printers that are in |newPrinters_| to position |toIndex| of + * |printerArr|. This moves all recently added printers to the top of the + * printer list. + * @param {!Array<!PrinterListEntry>} printerArr + * @param {number} toIndex + * @private + */ + moveNewlyAddedPrinters_: function(printerArr, toIndex) { + if (!this.newPrinters_.length) { + return; + } + + // We have newly added printers, move them to the top of the list. + for (const printer of this.newPrinters_) { + const idx = printerArr.findIndex( + p => p.printerInfo.printerId == printer.printerInfo.printerId); + if (idx > -1) { + moveEntryInPrinters(printerArr, idx, toIndex); + } + } } }); +})(); |