summaryrefslogtreecommitdiffstats
path: root/chrome/browser/resources/print_preview
diff options
context:
space:
mode:
authorrltoscano@google.com <rltoscano@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-31 18:14:21 +0000
committerrltoscano@google.com <rltoscano@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-31 18:14:21 +0000
commit96ff0da6fa46a6b2a94937ed5c58d578ac670fdb (patch)
treeab80f128e4a831d5c9aee9381bccf90f7ffdcada /chrome/browser/resources/print_preview
parent8daec68f1b4acf5ecc760232daed383c0b0d81cf (diff)
downloadchromium_src-96ff0da6fa46a6b2a94937ed5c58d578ac670fdb.zip
chromium_src-96ff0da6fa46a6b2a94937ed5c58d578ac670fdb.tar.gz
chromium_src-96ff0da6fa46a6b2a94937ed5c58d578ac670fdb.tar.bz2
Implements print-destination search widget which replaces the old select drop-down element.
BUG=114206 NOTRY=true TEST=Use the print preview dialog to switch printers before printing. Also sign-in with a Google Account to gain access to Google Cloud Print Printers. Review URL: https://chromiumcodereview.appspot.com/10450022 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@139820 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/resources/print_preview')
-rw-r--r--chrome/browser/resources/print_preview/cloud_print_interface.js6
-rw-r--r--chrome/browser/resources/print_preview/component.js8
-rw-r--r--chrome/browser/resources/print_preview/data/cloud_capabilities.js14
-rw-r--r--chrome/browser/resources/print_preview/data/cloud_parsers.js80
-rw-r--r--chrome/browser/resources/print_preview/data/destination.js72
-rw-r--r--chrome/browser/resources/print_preview/data/destination_store.js359
-rw-r--r--chrome/browser/resources/print_preview/data/local_parsers.js8
-rw-r--r--chrome/browser/resources/print_preview/data/margins.js13
-rw-r--r--chrome/browser/resources/print_preview/data/measurement_system.js8
-rw-r--r--chrome/browser/resources/print_preview/data/print_ticket_store.js83
-rw-r--r--chrome/browser/resources/print_preview/data/ticket_items/custom_margins.js14
-rw-r--r--chrome/browser/resources/print_preview/data/ticket_items/ticket_item.js8
-rw-r--r--chrome/browser/resources/print_preview/data/user_info.js92
-rw-r--r--chrome/browser/resources/print_preview/images/classic_printer_32.png0
-rw-r--r--chrome/browser/resources/print_preview/images/cloud.png0
-rw-r--r--chrome/browser/resources/print_preview/images/cloud_printer_32.png0
-rw-r--r--chrome/browser/resources/print_preview/images/cloud_printer_shared_32.png0
-rw-r--r--chrome/browser/resources/print_preview/images/google_promoted_printer_32.png0
-rw-r--r--chrome/browser/resources/print_preview/images/mobile_32.png0
-rw-r--r--chrome/browser/resources/print_preview/images/mobile_shared_32.png0
-rw-r--r--chrome/browser/resources/print_preview/images/search.png0
-rw-r--r--chrome/browser/resources/print_preview/native_layer.js18
-rw-r--r--chrome/browser/resources/print_preview/preview_generator.js2
-rw-r--r--chrome/browser/resources/print_preview/previewarea/margin_control.css3
-rw-r--r--chrome/browser/resources/print_preview/previewarea/margin_control.html4
-rw-r--r--chrome/browser/resources/print_preview/previewarea/margin_control.js14
-rw-r--r--chrome/browser/resources/print_preview/previewarea/margin_control_container.css3
-rw-r--r--chrome/browser/resources/print_preview/previewarea/margin_control_container.js6
-rw-r--r--chrome/browser/resources/print_preview/previewarea/preview_area.css3
-rw-r--r--chrome/browser/resources/print_preview/previewarea/preview_area.html12
-rw-r--r--chrome/browser/resources/print_preview/previewarea/preview_area.js6
-rw-r--r--chrome/browser/resources/print_preview/print_header.css3
-rw-r--r--chrome/browser/resources/print_preview/print_header.js4
-rw-r--r--chrome/browser/resources/print_preview/print_preview.css1
-rw-r--r--chrome/browser/resources/print_preview/print_preview.html37
-rw-r--r--chrome/browser/resources/print_preview/print_preview.js408
-rw-r--r--chrome/browser/resources/print_preview/print_preview_utils.js6
-rw-r--r--chrome/browser/resources/print_preview/search/cloud_destination_list.js50
-rw-r--r--chrome/browser/resources/print_preview/search/destination_list.css33
-rw-r--r--chrome/browser/resources/print_preview/search/destination_list.html14
-rw-r--r--chrome/browser/resources/print_preview/search/destination_list.js319
-rw-r--r--chrome/browser/resources/print_preview/search/destination_list_item.css34
-rw-r--r--chrome/browser/resources/print_preview/search/destination_list_item.html4
-rw-r--r--chrome/browser/resources/print_preview/search/destination_list_item.js124
-rw-r--r--chrome/browser/resources/print_preview/search/destination_search.css91
-rw-r--r--chrome/browser/resources/print_preview/search/destination_search.html25
-rw-r--r--chrome/browser/resources/print_preview/search/destination_search.js433
-rw-r--r--chrome/browser/resources/print_preview/search/search_box.css24
-rw-r--r--chrome/browser/resources/print_preview/search/search_box.html5
-rw-r--r--chrome/browser/resources/print_preview/search/search_box.js124
-rw-r--r--chrome/browser/resources/print_preview/settings/copies_settings.css3
-rw-r--r--chrome/browser/resources/print_preview/settings/copies_settings.js2
-rw-r--r--chrome/browser/resources/print_preview/settings/destination_settings.css61
-rw-r--r--chrome/browser/resources/print_preview/settings/destination_settings.html10
-rw-r--r--chrome/browser/resources/print_preview/settings/destination_settings.js185
-rw-r--r--chrome/browser/resources/print_preview/settings/margin_settings.js4
-rw-r--r--chrome/browser/resources/print_preview/settings/page_settings.css3
-rw-r--r--chrome/browser/resources/print_preview/settings/page_settings.js2
58 files changed, 2208 insertions, 637 deletions
diff --git a/chrome/browser/resources/print_preview/cloud_print_interface.js b/chrome/browser/resources/print_preview/cloud_print_interface.js
index b7e7c7c..15cc31d 100644
--- a/chrome/browser/resources/print_preview/cloud_print_interface.js
+++ b/chrome/browser/resources/print_preview/cloud_print_interface.js
@@ -103,7 +103,7 @@ cr.define('cloudprint', function() {
* @param {!print_preview.Destination} destination Destination to print to.
* @param {!print_preview.PrintTicketStore} printTicketStore Used to create
* the state of the print ticket.
- * @return {object} Google Cloud Print print ticket.
+ * @return {!Object} Google Cloud Print print ticket.
*/
createPrintTicket: function(destination, printTicketStore) {
assert(!destination.isLocal,
@@ -247,14 +247,14 @@ cr.define('cloudprint', function() {
onSearchDone_: function(result) {
var printerListJson = result['printers'] || [];
var printerList = [];
- for (var printerJson, i = 0; printerJson = printerListJson[i]; i++) {
+ printerListJson.forEach(function(printerJson) {
try {
printerList.push(
cloudprint.CloudDestinationParser.parse(printerJson));
} catch (err) {
console.error('Unable to parse cloud print destination: ' + err);
}
- }
+ });
var isRecent = result['request']['params']['q'] == '^recent';
var searchDoneEvent =
new cr.Event(CloudPrintInterface.EventType.SEARCH_DONE);
diff --git a/chrome/browser/resources/print_preview/component.js b/chrome/browser/resources/print_preview/component.js
index f51c3ae1..f18864b 100644
--- a/chrome/browser/resources/print_preview/component.js
+++ b/chrome/browser/resources/print_preview/component.js
@@ -73,20 +73,20 @@ cr.define('print_preview', function() {
*/
enterDocument: function() {
this.isInDocument_ = true;
- for (var child, i = 0; child = this.children_[i]; i++) {
+ this.children_.forEach(function(child) {
if (!child.isInDocument && child.getElement()) {
child.enterDocument();
}
- }
+ });
},
/** Removes all event listeners. */
exitDocument: function() {
- for (var child, i = 0; child = this.children_[i]; i++) {
+ this.children_.forEach(function(child) {
if (child.isInDocument) {
child.exitDocument();
}
- }
+ });
this.tracker_.removeAll();
this.isInDocument_ = false;
},
diff --git a/chrome/browser/resources/print_preview/data/cloud_capabilities.js b/chrome/browser/resources/print_preview/data/cloud_capabilities.js
index 7bb107f..abab759 100644
--- a/chrome/browser/resources/print_preview/data/cloud_capabilities.js
+++ b/chrome/browser/resources/print_preview/data/cloud_capabilities.js
@@ -111,7 +111,7 @@ cr.define('print_preview', function() {
/**
* A single print capability of a cloud-based print destination.
* @param {string} id Identifier of the capability.
- * @param {print_preview.CloudCapability.Type} type Type of the capability.
+ * @param {!print_preview.CloudCapability.Type} type Type of the capability.
* @constructor
*/
function CloudCapability(id, type) {
@@ -124,7 +124,7 @@ cr.define('print_preview', function() {
/**
* Type of the capability.
- * @type {print_preview.CloudCapability.Type}
+ * @type {!print_preview.CloudCapability.Type}
* @private
*/
this.type_ = type;
@@ -145,7 +145,7 @@ cr.define('print_preview', function() {
return this.id_;
},
- /** @return {print_preview.CloudCapability.Type} Type of the capability. */
+ /** @return {!print_preview.CloudCapability.Type} Type of the capability. */
get type() {
return this.type_;
}
@@ -190,7 +190,7 @@ cr.define('print_preview', function() {
/**
* Mapping of capability formats to an identifier of the collate capability.
- * @type {object<CloudCapabilities.Format, string>}
+ * @type {!Object.<!CloudCapabilities.Format, string>}
*/
CollateCapability.Id = {};
CollateCapability.Id[CloudCapabilities.Format.PPD] = 'Collate';
@@ -264,7 +264,7 @@ cr.define('print_preview', function() {
/**
* Mapping of capability formats to an identifier of the color capability.
- * @type {object<CloudCapabilities.Format, string>}
+ * @type {!Object.<!CloudCapabilities.Format, string>}
*/
ColorCapability.Id = {};
ColorCapability.Id[CloudCapabilities.Format.HP] = 'ns1:Colors';
@@ -319,7 +319,7 @@ cr.define('print_preview', function() {
/**
* Mapping of capability formats to an identifier of the copies capability.
- * @type {object<CloudCapabilities.Format, string>}
+ * @type {!Object.<!CloudCapabilities.Format, string>}
*/
CopiesCapability.Id = {};
CopiesCapability.Id[CloudCapabilities.Format.XPS] =
@@ -362,7 +362,7 @@ cr.define('print_preview', function() {
/**
* Mapping of capability formats to an identifier of the duplex capability.
- * @type {object<CloudCapabilities.Format, string>}
+ * @type {!Object.<!CloudCapabilities.Format, string>}
*/
DuplexCapability.Id = {};
DuplexCapability.Id[CloudCapabilities.Format.PPD] = 'Duplex';
diff --git a/chrome/browser/resources/print_preview/data/cloud_parsers.js b/chrome/browser/resources/print_preview/data/cloud_parsers.js
index 965e881..ed6cb15 100644
--- a/chrome/browser/resources/print_preview/data/cloud_parsers.js
+++ b/chrome/browser/resources/print_preview/data/cloud_parsers.js
@@ -18,37 +18,61 @@ cr.define('cloudprint', function() {
DISPLAY_NAME: 'displayName',
FORMAT: 'capsFormat',
ID: 'id',
- TAGS: 'tags'
+ TAGS: 'tags',
+ TYPE: 'type'
};
/**
* Special tag that denotes whether the destination has been recently used.
* @type {string}
+ * @const
* @private
*/
CloudDestinationParser.RECENT_TAG_ = '^recent';
/**
+ * Special tag that denotes whether the destination is owned by the user.
+ * @type {string}
+ * @const
+ * @private
+ */
+ CloudDestinationParser.OWNED_TAG_ = '^own';
+
+ /**
+ * Enumeration of cloud destination types that are supported by print preview.
+ * @enum {string}
+ * @private
+ */
+ CloudDestinationParser.CloudType_ = {
+ ANDROID: 'ANDROID_CHROME_SNAPSHOT',
+ DOCS: 'DOCS',
+ IOS: 'IOS_CHROME_SNAPSHOT'
+ };
+
+ /**
* Parses a destination from JSON from a Google Cloud Print search or printer
* response.
- * @param {object} json Object that represents a Google Cloud Print search or
+ * @param {!Object} json Object that represents a Google Cloud Print search or
* printer response.
* @return {!print_preview.Destination} Parsed destination.
*/
CloudDestinationParser.parse = function(json) {
if (!json.hasOwnProperty(CloudDestinationParser.Field_.ID) ||
+ !json.hasOwnProperty(CloudDestinationParser.Field_.TYPE) ||
!json.hasOwnProperty(CloudDestinationParser.Field_.DISPLAY_NAME)) {
throw Error('Cloud destination does not have an ID or a display name');
}
- var isRecent = arrayContains(
- json[CloudDestinationParser.Field_.TAGS] || [],
- CloudDestinationParser.RECENT_TAG_);
+ var tags = json[CloudDestinationParser.Field_.TAGS] || [];
+ var isRecent = arrayContains(tags, CloudDestinationParser.RECENT_TAG_);
+ var isOwned = arrayContains(tags, CloudDestinationParser.OWNED_TAG_);
var cloudDest = new print_preview.Destination(
json[CloudDestinationParser.Field_.ID],
+ CloudDestinationParser.parseType_(
+ json[CloudDestinationParser.Field_.TYPE]),
json[CloudDestinationParser.Field_.DISPLAY_NAME],
isRecent,
- false /*isLocal*/,
- json[CloudDestinationParser.Field_.TAGS] || []);
+ tags,
+ isOwned);
if (json.hasOwnProperty(CloudDestinationParser.Field_.CAPABILITIES) &&
json.hasOwnProperty(CloudDestinationParser.Field_.FORMAT)) {
cloudDest.capabilities = CloudCapabilitiesParser.parse(
@@ -59,6 +83,24 @@ cr.define('cloudprint', function() {
};
/**
+ * Parses the destination type.
+ * @param {string} typeStr Destination type given by the Google Cloud Print
+ * server.
+ * @return {!print_preview.Destination.Type} Destination type.
+ * @private
+ */
+ CloudDestinationParser.parseType_ = function(typeStr) {
+ if (typeStr == CloudDestinationParser.CloudType_.ANDROID ||
+ typeStr == CloudDestinationParser.CloudType_.IOS) {
+ return print_preview.Destination.Type.MOBILE;
+ } else if (typeStr == CloudDestinationParser.CloudType_.DOCS) {
+ return print_preview.Destination.Type.GOOGLE_PROMOTED;
+ } else {
+ return print_preview.Destination.Type.GOOGLE;
+ }
+ };
+
+ /**
* Namespace which contains a method to parse a cloud destination's print
* capabilities.
*/
@@ -81,7 +123,7 @@ cr.define('cloudprint', function() {
* Parses print capabilities from an object in a given capabilities format.
* @param {print_preview.CloudCapabilities.Format} capsFormat Format of the
* printer capabilities.
- * @param {object} json Object representing the cloud capabilities.
+ * @param {!Array.<!Object>} json Object representing the cloud capabilities.
* @return {!print_preview.CloudCapabilities} Parsed print capabilities.
*/
CloudCapabilitiesParser.parse = function(capsFormat, json) {
@@ -89,7 +131,7 @@ cr.define('cloudprint', function() {
var duplexCapability = null;
var copiesCapability = null;
var collateCapability = null;
- for (var cap, i = 0; cap = json[i]; i++) {
+ json.forEach(function(cap) {
var capId = cap[CloudCapabilitiesParser.Field_.CAP_ID];
if (capId == print_preview.CollateCapability.Id[capsFormat]) {
collateCapability = CloudCapabilitiesParser.parseCollate(capId, cap);
@@ -100,7 +142,7 @@ cr.define('cloudprint', function() {
} else if (capId == print_preview.DuplexCapability.Id[capsFormat]) {
duplexCapability = CloudCapabilitiesParser.parseDuplex(capId, cap);
}
- }
+ });
return new print_preview.CloudCapabilities(
collateCapability, colorCapability, copiesCapability, duplexCapability);
};
@@ -108,7 +150,7 @@ cr.define('cloudprint', function() {
/**
* Parses a collate capability from the given object.
* @param {string} capId Native ID of the given capability object.
- * @param {object} Object that represents the collate capability.
+ * @param {!Object} Object that represents the collate capability.
* @return {print_preview.CollateCapability} Parsed collate capability or
* {@code null} if the given capability object was not a valid collate
* capability.
@@ -118,7 +160,7 @@ cr.define('cloudprint', function() {
var collateOption = null;
var noCollateOption = null;
var isCollateDefault = false;
- for (var option, i = 0; option = options[i]; i++) {
+ options.forEach(function(option) {
var optionId = option[CloudCapabilitiesParser.Field_.OPTION_ID];
if (!collateOption &&
print_preview.CollateCapability.COLLATE_REGEX.test(optionId)) {
@@ -128,7 +170,7 @@ cr.define('cloudprint', function() {
print_preview.CollateCapability.NO_COLLATE_REGEX.test(optionId)) {
noCollateOption = optionId;
}
- }
+ });
if (!collateOption || !noCollateOption) {
return null;
}
@@ -139,7 +181,7 @@ cr.define('cloudprint', function() {
/**
* Parses a color capability from the given object.
* @param {string} capId Native ID of the given capability object.
- * @param {object} Object that represents the color capability.
+ * @param {!Object} Object that represents the color capability.
* @return {print_preview.ColorCapability} Parsed color capability or
* {@code null} if the given capability object was not a valid color
* capability.
@@ -149,7 +191,7 @@ cr.define('cloudprint', function() {
var colorOption = null;
var bwOption = null;
var isColorDefault = false;
- for (var option, i = 0; option = options[i]; i++) {
+ options.forEach(function(option) {
var optionId = option[CloudCapabilitiesParser.Field_.OPTION_ID];
if (!colorOption &&
print_preview.ColorCapability.COLOR_REGEX.test(optionId)) {
@@ -159,7 +201,7 @@ cr.define('cloudprint', function() {
print_preview.ColorCapability.BW_REGEX.test(optionId)) {
bwOption = optionId;
}
- }
+ });
if (!colorOption || !bwOption) {
return null;
}
@@ -170,7 +212,7 @@ cr.define('cloudprint', function() {
/**
* Parses a duplex capability from the given object.
* @param {string} capId Native ID of the given capability object.
- * @param {object} Object that represents the duplex capability.
+ * @param {!Object} Object that represents the duplex capability.
* @return {print_preview.DuplexCapability} Parsed duplex capability or
* {@code null} if the given capability object was not a valid duplex
* capability.
@@ -180,7 +222,7 @@ cr.define('cloudprint', function() {
var simplexOption = null;
var longEdgeOption = null;
var isDuplexDefault = false;
- for (var option, i = 0; option = options[i]; i++) {
+ options.forEach(function(option) {
var optionId = option[CloudCapabilitiesParser.Field_.OPTION_ID];
if (!simplexOption &&
print_preview.DuplexCapability.SIMPLEX_REGEX.test(optionId)) {
@@ -190,7 +232,7 @@ cr.define('cloudprint', function() {
longEdgeOption = optionId;
isDuplexDefault = !!option[CloudCapabilitiesParser.Field_.DEFAULT];
}
- }
+ });
if (!simplexOption || !longEdgeOption) {
return null;
}
diff --git a/chrome/browser/resources/print_preview/data/destination.js b/chrome/browser/resources/print_preview/data/destination.js
index 01a9491..b62d818 100644
--- a/chrome/browser/resources/print_preview/data/destination.js
+++ b/chrome/browser/resources/print_preview/data/destination.js
@@ -9,13 +9,15 @@ cr.define('print_preview', function() {
* Print destination data object that holds data for both local and cloud
* destinations.
* @param {string} id ID of the destination.
+ * @param {!print_preview.Destination.Type} type Type of the destination.
* @param {string} displayName Display name of the destination.
* @param {boolean} isRecent Whether the destination has been used recently.
- * @param {boolean} isLocal Whether the destination is local or cloud-based.
* @param {Array.<string>=} opt_tags Tags associated with the destination.
+ * @param {boolean=} opt_isOwned Whether the destination is owned by the user.
+ * Only applies to cloud-based destinations.
* @constructor
*/
- function Destination(id, displayName, isRecent, isLocal, opt_tags) {
+ function Destination(id, type, displayName, isRecent, opt_tags, opt_isOwned) {
/**
* ID of the destination.
* @type {string}
@@ -24,6 +26,13 @@ cr.define('print_preview', function() {
this.id_ = id;
/**
+ * Type of the destination.
+ * @type {!print_preview.Destination.Type}
+ * @private
+ */
+ this.type_ = type;
+
+ /**
* Display name of the destination.
* @type {string}
* @private
@@ -38,13 +47,6 @@ cr.define('print_preview', function() {
this.isRecent_ = isRecent;
/**
- * Whether the destination is local or cloud-based.
- * @type {boolean}
- * @private
- */
- this.isLocal_ = isLocal;
-
- /**
* Tags associated with the destination.
* @type {!Array.<string>}
* @private
@@ -59,8 +61,15 @@ cr.define('print_preview', function() {
this.capabilities_ = null;
/**
+ * Whether the destination is owned by the user.
+ * @type {boolean}
+ * @private
+ */
+ this.isOwned_ = opt_isOwned || false;
+
+ /**
* Cache of destination location fetched from tags.
- * @type {string}
+ * @type {?string}
* @private
*/
this.location_ = null;
@@ -79,8 +88,18 @@ cr.define('print_preview', function() {
*/
Destination.GooglePromotedId = {
DOCS: '__google__docs',
- SAVE_AS_PDF: 'Save as PDF',
- PRINT_WITH_CLOUD_PRINT: 'printWithCloudPrint'
+ FEDEX: '__google__fedex',
+ SAVE_AS_PDF: 'Save as PDF'
+ };
+
+ /**
+ * Enumeration of the types of destinations.
+ * @enum {string}
+ */
+ Destination.Type = {
+ GOOGLE: 'google',
+ LOCAL: 'local',
+ MOBILE: 'mobile'
};
Destination.prototype = {
@@ -89,6 +108,11 @@ cr.define('print_preview', function() {
return this.id_;
},
+ /** @return {!print_preview.Destination.Type} Type of the destination. */
+ get type() {
+ return this.type_;
+ },
+
/** @return {string} Display name of the destination. */
get displayName() {
return this.displayName_;
@@ -106,9 +130,17 @@ cr.define('print_preview', function() {
this.isRecent_ = isRecent;
},
+ /**
+ * @return {boolean} Whether the user owns the destination. Only applies to
+ * cloud-based destinations.
+ */
+ get isOwned() {
+ return this.isOwned_;
+ },
+
/** @return {boolean} Whether the destination is local or cloud-based. */
get isLocal() {
- return this.isLocal_;
+ return this.type_ == Destination.Type.LOCAL;
},
/** @return {boolean} Whether the destination is promoted by Google. */
@@ -122,14 +154,6 @@ cr.define('print_preview', function() {
},
/**
- * @return {boolean} Whether the destination is the "Print with Cloud Print"
- * destination.
- */
- get isPrintWithCloudPrint() {
- return this.id_ == Destination.GooglePromotedId.PRINT_WITH_CLOUD_PRINT;
- },
-
- /**
* @return {string} The location of the destination, or an empty string if
* the location is unknown.
*/
@@ -138,12 +162,10 @@ cr.define('print_preview', function() {
for (var tag, i = 0; tag = this.tags_[i]; i++) {
if (tag.indexOf(Destination.LOCATION_TAG_PREFIX) == 0) {
this.location_ = tag.substring(
- Destination.LOCATION_TAG_PREFIX.length);
+ Destination.LOCATION_TAG_PREFIX.length) || '';
+ break;
}
}
- if (this.location_ == null) {
- this.location_ = '';
- }
}
return this.location_;
},
diff --git a/chrome/browser/resources/print_preview/data/destination_store.js b/chrome/browser/resources/print_preview/data/destination_store.js
index 69f766a..6c8d52d 100644
--- a/chrome/browser/resources/print_preview/data/destination_store.js
+++ b/chrome/browser/resources/print_preview/data/destination_store.js
@@ -8,20 +8,36 @@ cr.define('print_preview', function() {
/**
* A data store that stores destinations and dispatches events when the data
* store changes.
+ * @param {!print_preview.NativeLayer} nativeLayer Used to fetch local print
+ * destinations.
* @constructor
* @extends {cr.EventTarget}
*/
- function DestinationStore() {
+ function DestinationStore(nativeLayer) {
cr.EventTarget.call(this);
/**
+ * Used to fetch local print destinations.
+ * @type {!print_preview.NativeLayer}
+ * @private
+ */
+ this.nativeLayer_ = nativeLayer;
+
+ /**
* Internal backing store for the data store.
- * @type {!Array.<print_preview.Destination>}
+ * @type {!Array.<!print_preview.Destination>}
* @private
*/
this.destinations_ = [];
/**
+ * Cache used for constant lookup of printers.
+ * @type {object.<string, !print_preview.Destination>}
+ * @private
+ */
+ this.destinationMap_ = {};
+
+ /**
* Currently selected destination.
* @type {print_preview.Destination}
* @private
@@ -44,6 +60,41 @@ cr.define('print_preview', function() {
* @private
*/
this.isInAutoSelectMode_ = false;
+
+ /**
+ * Event tracker used to track event listeners of the destination store.
+ * @type {!EventTracker}
+ * @private
+ */
+ this.tracker_ = new EventTracker();
+
+ /**
+ * Used to fetch cloud-based print destinations.
+ * @type {print_preview.CloudPrintInterface}
+ * @private
+ */
+ this.cloudPrintInterface_ = null;
+
+ /**
+ * Whether the destination store has already loaded or is loading all cloud
+ * destinations.
+ * @type {boolean}
+ * @private
+ */
+ this.hasLoadedAllCloudDestinations_ = false;
+
+ /**
+ * ID of a timeout after the initial destination ID is set. If no inserted
+ * destination matches the initial destination ID after the specified
+ * timeout, the first destination in the store will be automatically
+ * selected.
+ * @type {?number}
+ * @private
+ */
+ this.autoSelectTimeout_ = null;
+
+ this.addEventListeners_();
+ this.reset_();
};
/**
@@ -53,7 +104,44 @@ cr.define('print_preview', function() {
DestinationStore.EventType = {
DESTINATIONS_INSERTED:
'print_preview.DestinationStore.DESTINATIONS_INSERTED',
- DESTINATION_SELECT: 'print_preview.DestinationStore.DESTINATION_SELECT'
+ DESTINATION_SELECT: 'print_preview.DestinationStore.DESTINATION_SELECT',
+ SELECTED_DESTINATION_CAPABILITIES_READY:
+ 'print_preview.DestinationStore.SELECTED_DESTINATION_CAPABILITIES_READY'
+ };
+
+ /**
+ * Delay in milliseconds before the destination store ignores the initial
+ * destination ID and just selects any printer (since the initial destination
+ * was not found).
+ * @type {number}
+ * @const
+ * @private
+ */
+ DestinationStore.AUTO_SELECT_TIMEOUT_ = 2000;
+
+ /**
+ * Creates a local PDF print destination.
+ * @return {!print_preview.Destination} Created print destination.
+ * @private
+ */
+ DestinationStore.createLocalPdfPrintDestination_ = function() {
+ var dest = new print_preview.Destination(
+ print_preview.Destination.GooglePromotedId.SAVE_AS_PDF,
+ print_preview.Destination.Type.LOCAL,
+ localStrings.getString('printToPDF'),
+ false /*isRecent*/);
+ dest.capabilities = new print_preview.ChromiumCapabilities(
+ false /*hasCopiesCapability*/,
+ '1' /*defaultCopiesStr*/,
+ false /*hasCollateCapability*/,
+ false /*defaultIsCollateEnabled*/,
+ false /*hasDuplexCapability*/,
+ false /*defaultIsDuplexEnabled*/,
+ true /*hasOrientationCapability*/,
+ false /*defaultIsLandscapeEnabled*/,
+ true /*hasColorCapability*/,
+ true /*defaultIsColorEnabled*/);
+ return dest;
};
DestinationStore.prototype = {
@@ -80,31 +168,68 @@ cr.define('print_preview', function() {
* match this ID, that destination will be automatically selected. This
* occurs only once for every time this setter is called or if the store is
* cleared.
- * @param {string} ID of the destination that should be selected
- * automatically when added to the store.
+ * @param {?string} ID of the destination that should be selected
+ * automatically when added to the store or {@code null} if the first
+ * destination that is inserted should be selected.
*/
setInitialDestinationId: function(initialDestinationId) {
this.initialDestinationId_ = initialDestinationId;
this.isInAutoSelectMode_ = true;
- if (this.initialDestinationId_ == null && this.destinations_.length > 0) {
+ if (this.initialDestinationId_ == null) {
+ assert(this.destinations_.length > 0,
+ 'No destinations available to select');
this.selectDestination(this.destinations_[0]);
- } else if (this.initialDestinationId_ != null) {
- for (var dest, i = 0; dest = this.destinations_[i]; i++) {
- if (dest.id == initialDestinationId) {
- this.selectDestination(dest);
- break;
- }
+ } else {
+ var candidate = this.destinationMap_[this.initialDestinationId_];
+ if (candidate != null) {
+ this.selectDestination(candidate);
}
}
},
+ /**
+ * Sets the destination store's Google Cloud Print interface.
+ * @param {!print_preview.CloudPrintInterface} cloudPrintInterface Interface
+ * to set.
+ */
+ setCloudPrintInterface: function(cloudPrintInterface) {
+ this.cloudPrintInterface_ = cloudPrintInterface;
+ this.tracker_.add(
+ this.cloudPrintInterface_,
+ cloudprint.CloudPrintInterface.EventType.SEARCH_DONE,
+ this.onCloudPrintSearchDone_.bind(this));
+ this.tracker_.add(
+ this.cloudPrintInterface_,
+ cloudprint.CloudPrintInterface.EventType.PRINTER_DONE,
+ this.onCloudPrintPrinterDone_.bind(this));
+ },
+
/** @param {!print_preview.Destination} Destination to select. */
selectDestination: function(destination) {
this.selectedDestination_ = destination;
this.selectedDestination_.isRecent = true;
this.isInAutoSelectMode_ = false;
+ if (this.autoSelectTimeout_ != null) {
+ clearTimeout(this.autoSelectTimeout_);
+ this.autoSelectTimeout_ = null;
+ }
cr.dispatchSimpleEvent(
this, DestinationStore.EventType.DESTINATION_SELECT);
+ if (destination.capabilities == null) {
+ if (destination.isLocal) {
+ this.nativeLayer_.startGetLocalDestinationCapabilities(
+ destination.id);
+ } else {
+ assert(this.cloudPrintInterface_ != null,
+ 'Selected destination is a cloud destination, but Google ' +
+ 'Cloud Print is not enabled');
+ this.cloudPrintInterface_.printer(destination.id);
+ }
+ } else {
+ cr.dispatchSimpleEvent(
+ this,
+ DestinationStore.EventType.SELECTED_DESTINATION_CAPABILITIES_READY);
+ }
},
/**
@@ -115,16 +240,13 @@ cr.define('print_preview', function() {
* insert.
*/
insertDestination: function(destination) {
- this.destinations_.push(destination);
- cr.dispatchSimpleEvent(
- this, DestinationStore.EventType.DESTINATIONS_INSERTED);
- if (this.isInAutoSelectMode_) {
- if (this.initialDestinationId_ == null) {
+ if (this.insertDestination_(destination)) {
+ cr.dispatchSimpleEvent(
+ this, DestinationStore.EventType.DESTINATIONS_INSERTED);
+ if (this.isInAutoSelectMode_ &&
+ (this.initialDestinationId_ == null ||
+ destination.id == this.initialDestinationId_)) {
this.selectDestination(destination);
- } else {
- if (destination.id == this.initialDestinationId_) {
- this.selectDestination(destination);
- }
}
}
},
@@ -137,20 +259,25 @@ cr.define('print_preview', function() {
* destinations to insert.
*/
insertDestinations: function(destinations) {
- this.destinations_ = this.destinations_.concat(destinations);
- cr.dispatchSimpleEvent(
- this, DestinationStore.EventType.DESTINATIONS_INSERTED);
- if (this.isInAutoSelectMode_) {
- if (this.initialDestinationId_ == null && destinations.length > 0) {
- this.selectDestination(destinations[0]);
- } else if (this.initialDestinationId_ != null) {
- for (var dest, i = 0; dest = destinations[i]; i++) {
- if (dest.id == this.initialDestinationId_) {
- this.selectDestination(dest);
- break;
- }
+ var insertedDestination = false;
+ var destinationToAutoSelect = null;
+ destinations.forEach(function(dest) {
+ if (this.insertDestination_(dest)) {
+ insertedDestination = true;
+ if (this.isInAutoSelectMode_ &&
+ destinationToAutoSelect == null &&
+ (this.initialDestinationId_ == null ||
+ dest.id == this.initialDestinationId_)) {
+ destinationToAutoSelect = dest;
}
}
+ }, this);
+ if (insertedDestination) {
+ cr.dispatchSimpleEvent(
+ this, DestinationStore.EventType.DESTINATIONS_INSERTED);
+ }
+ if (destinationToAutoSelect != null) {
+ this.selectDestination(destinationToAutoSelect);
}
},
@@ -162,14 +289,8 @@ cr.define('print_preview', function() {
* updated.
*/
updateDestination: function(destination) {
- var existingDestination = null;
- for (var d, i = 0; d = this.destinations_[i]; i++) {
- if (destination.id == d.id) {
- existingDestination = d;
- break;
- }
- }
- if (existingDestination) {
+ var existingDestination = this.destinationMap_[destination.id];
+ if (existingDestination != null) {
existingDestination.capabilities = destination.capabilities;
return existingDestination;
} else {
@@ -177,11 +298,163 @@ cr.define('print_preview', function() {
}
},
- /** Clears all print destinations. */
- clear: function() {
+ /** Initiates loading of local print destinations. */
+ startLoadLocalDestinations: function() {
+ this.nativeLayer_.startGetLocalDestinations();
+ },
+
+ /** Initiates loading of recent cloud destinations. */
+ startLoadRecentCloudDestinations: function() {
+ if (this.cloudPrintInterface_ != null) {
+ this.cloudPrintInterface_.search(true /*isRecent*/);
+ }
+ },
+
+ /** Initiates loading of all cloud destinations. */
+ startLoadAllCloudDestinations: function() {
+ if (this.cloudPrintInterface_ != null &&
+ !this.hasLoadedAllCloudDestinations_) {
+ this.cloudPrintInterface_.search(false /*isRecent*/);
+ this.hasLoadedAllCloudDestinations_ = true;
+ }
+ },
+
+ /**
+ * Inserts a destination into the store without dispatching any events.
+ * @return {boolean} Whether the inserted destination was not already in the
+ * store.
+ * @private
+ */
+ insertDestination_: function(destination) {
+ if (this.destinationMap_[destination.id] == null) {
+ this.destinations_.push(destination);
+ this.destinationMap_[destination.id] = destination;
+ return true;
+ } else {
+ return false;
+ }
+ },
+
+ /**
+ * Binds handlers to events.
+ * @private
+ */
+ addEventListeners_: function() {
+ this.tracker_.add(
+ this.nativeLayer_,
+ print_preview.NativeLayer.EventType.LOCAL_DESTINATIONS_SET,
+ this.onLocalDestinationsSet_.bind(this));
+ this.tracker_.add(
+ this.nativeLayer_,
+ print_preview.NativeLayer.EventType.CAPABILITIES_SET,
+ this.onLocalDestinationCapabilitiesSet_.bind(this));
+ this.tracker_.add(
+ this.nativeLayer_,
+ print_preview.NativeLayer.EventType.DESTINATIONS_RELOAD,
+ this.onDestinationsReload_.bind(this));
+ },
+
+ /**
+ * Resets the state of the destination store to its initial state.
+ * @private
+ */
+ reset_: function() {
this.destinations_ = [];
+ this.destinationMap_ = {};
this.selectedDestination_ = null;
+ this.hasLoadedAllCloudDestinations_ = false;
+ this.insertDestination(
+ DestinationStore.createLocalPdfPrintDestination_());
+ this.autoSelectTimeout_ = setTimeout(
+ this.onAutoSelectTimeoutExpired_.bind(this),
+ DestinationStore.AUTO_SELECT_TIMEOUT_);
+ },
+
+ /**
+ * Called when the local destinations have been got from the native layer.
+ * @param {cr.Event} Contains the local destinations.
+ * @private
+ */
+ onLocalDestinationsSet_: function(event) {
+ var localDestinations = event.destinationInfos.map(function(destInfo) {
+ return print_preview.LocalDestinationParser.parse(destInfo);
+ });
+ this.insertDestinations(localDestinations);
+ },
+
+ /**
+ * Called when the native layer retrieves the capabilities for the selected
+ * local destination.
+ * @param {cr.Event} event Contains the capabilities of the local print
+ * destination.
+ * @private
+ */
+ onLocalDestinationCapabilitiesSet_: function(event) {
+ // TODO(rltoscano): There may be a race condition here. This method is
+ // assumed to return capabilities for the currently selected printer. But
+ // between the time the local printer was selected and the capabilities
+ // were retrieved, the selected printer can change. One way to address
+ // this is to include the destination ID in the event.settingsInfo
+ // parameter.
+ if (this.selectedDestination_ && this.selectedDestination_.isLocal) {
+ var capabilities = print_preview.LocalCapabilitiesParser.parse(
+ event.settingsInfo);
+ this.selectedDestination_.capabilities = capabilities;
+ cr.dispatchSimpleEvent(
+ this,
+ DestinationStore.EventType.SELECTED_DESTINATION_CAPABILITIES_READY);
+ }
+ },
+
+ /**
+ * Called when the /search call completes. Adds the fetched printers to the
+ * destination store.
+ * @param {cr.Event} event Contains the fetched printers.
+ * @private
+ */
+ onCloudPrintSearchDone_: function(event) {
+ this.insertDestinations(event.printers);
+ },
+
+ /**
+ * Called when /printer call completes. Updates the specified destination's
+ * print capabilities.
+ * @param {cr.Event} event Contains detailed information about the
+ * destination.
+ * @private
+ */
+ onCloudPrintPrinterDone_: function(event) {
+ var dest = this.updateDestination(event.printer);
+ if (this.selectedDestination_ == dest) {
+ cr.dispatchSimpleEvent(
+ this,
+ DestinationStore.EventType.SELECTED_DESTINATION_CAPABILITIES_READY);
+ }
+ },
+
+ /**
+ * Called from native layer after the user was requested to sign in, and did
+ * so successfully.
+ * @private
+ */
+ onDestinationsReload_: function() {
+ this.reset_();
this.isInAutoSelectMode_ = true;
+ this.startLoadLocalDestinations();
+ this.startLoadRecentCloudDestinations();
+ this.startLoadAllCloudDestinations();
+ },
+
+ /**
+ * Called when no destination was auto-selected after some timeout. Selects
+ * the first destination in store.
+ * @private
+ */
+ onAutoSelectTimeoutExpired_: function() {
+ this.autoSelectTimeout_ = null;
+ assert(this.destinations_.length > 0,
+ 'No destinations were loaded before auto-select timeout expired');
+ this.selectDestination(this.destinations_[0]);
}
};
diff --git a/chrome/browser/resources/print_preview/data/local_parsers.js b/chrome/browser/resources/print_preview/data/local_parsers.js
index af58290..b54e5a2 100644
--- a/chrome/browser/resources/print_preview/data/local_parsers.js
+++ b/chrome/browser/resources/print_preview/data/local_parsers.js
@@ -10,16 +10,16 @@ cr.define('print_preview', function() {
/**
* Parses a local print destination.
- * @param {object} destinationInfo Information describing a local print
+ * @param {!Object} destinationInfo Information describing a local print
* destination.
* @return {!print_preview.Destination} Parsed local print destination.
*/
LocalDestinationParser.parse = function(destinationInfo) {
return new print_preview.Destination(
destinationInfo.deviceName,
+ print_preview.Destination.Type.LOCAL,
destinationInfo.printerName,
- false /*isRecent*/,
- true /*isLocal*/);
+ false /*isRecent*/);
};
/** Namespace that contains a method to parse local print capabilities. */
@@ -27,7 +27,7 @@ cr.define('print_preview', function() {
/**
* Parses local print capabilities.
- * @param {object} settingsInfo Object that describes local print
+ * @param {!Object} settingsInfo Object that describes local print
* capabilities.
* @return {!print_preview.ChromiumCapabilities} Parsed local print
* capabilities.
diff --git a/chrome/browser/resources/print_preview/data/margins.js b/chrome/browser/resources/print_preview/data/margins.js
index cf6a6f8..18ed90a 100644
--- a/chrome/browser/resources/print_preview/data/margins.js
+++ b/chrome/browser/resources/print_preview/data/margins.js
@@ -16,9 +16,8 @@ cr.define('print_preview', function() {
function Margins(top, right, bottom, left) {
/**
* Backing store for the margin values in points.
- * @type {Object.<
- * print_preview.ticket_items.CustomMargins.Orientation,
- * number>}
+ * @type {!Object.<
+ * !print_preview.ticket_items.CustomMargins.Orientation, number>}
* @private
*/
this.value_ = {};
@@ -33,8 +32,8 @@ cr.define('print_preview', function() {
Margins.prototype = {
/**
- * @param {print_preview.ticket_items.CustomMargins.Orientation} orientation
- * Specifies the margin value to get.
+ * @param {!print_preview.ticket_items.CustomMargins.Orientation}
+ * orientation Specifies the margin value to get.
* @return {number} Value of the margin of the given orientation.
*/
get: function(orientation) {
@@ -42,8 +41,8 @@ cr.define('print_preview', function() {
},
/**
- * @param {print_preview.ticket_items.CustomMargins.Orientation} orientation
- * Specifies the margin to set.
+ * @param {!print_preview.ticket_items.CustomMargins.Orientation}
+ * orientation Specifies the margin to set.
* @param {number} value Updated value of the margin in points to modify.
* @return {!print_preview.Margins} A new copy of |this| with the
* modification made to the specified margin.
diff --git a/chrome/browser/resources/print_preview/data/measurement_system.js b/chrome/browser/resources/print_preview/data/measurement_system.js
index ccee0d9a..85b7c58 100644
--- a/chrome/browser/resources/print_preview/data/measurement_system.js
+++ b/chrome/browser/resources/print_preview/data/measurement_system.js
@@ -10,8 +10,8 @@ cr.define('print_preview', function() {
* measurements into the system's local units (e.g. millimeters, inches).
* @param {string} thousandsDelimeter Delimeter between thousands digits.
* @param {string} decimalDelimeter Delimeter between integers and decimals.
- * @param {print_preview.MeasurementSystem.UnitType} unitType Measurement unit
- * type of the system.
+ * @param {!print_preview.MeasurementSystem.UnitType} unitType Measurement
+ * unit type of the system.
* @constructor
*/
function MeasurementSystem(thousandsDelimeter, decimalDelimeter, unitType) {
@@ -48,7 +48,7 @@ cr.define('print_preview', function() {
/**
* Maximum resolution of local unit values.
- * @type {Object.<print_preview.MeasurementSystem.UnitType, number>}
+ * @type {!Object.<!print_preview.MeasurementSystem.UnitType, number>}
* @private
*/
MeasurementSystem.Precision_ = {};
@@ -57,7 +57,7 @@ cr.define('print_preview', function() {
/**
* Maximum number of decimal places to keep for local unit.
- * @type {Object.<print_preview.MeasurementSystem.UnitType, number>}
+ * @type {!Object.<!print_preview.MeasurementSystem.UnitType, number>}
* @private
*/
MeasurementSystem.DecimalPlaces_ = {};
diff --git a/chrome/browser/resources/print_preview/data/print_ticket_store.js b/chrome/browser/resources/print_preview/data/print_ticket_store.js
index e200798..7f3a917 100644
--- a/chrome/browser/resources/print_preview/data/print_ticket_store.js
+++ b/chrome/browser/resources/print_preview/data/print_ticket_store.js
@@ -69,7 +69,7 @@ cr.define('print_preview', function() {
* @private
*/
this.collate_ =
- new print_preview.ticket_items.Collate(this.capabilitiesHolder_);
+ new print_preview.ticket_items.Collate(this.capabilitiesHolder_);
/**
* Color ticket item.
@@ -142,6 +142,15 @@ cr.define('print_preview', function() {
*/
this.fitToPage_ = new print_preview.ticket_items.FitToPage(
this.documentInfo_, this.destinationStore_);
+
+ /**
+ * Keeps track of event listeners for the print ticket store.
+ * @type {!EventTracker}
+ * @private
+ */
+ this.tracker_ = new EventTracker();
+
+ this.addEventListeners_();
};
/**
@@ -243,12 +252,12 @@ cr.define('print_preview', function() {
* modifiable (i.e. can be re-flowed by Chromium).
* @param {?boolean} isDuplexEnabled Previous duplex setting.
* @param {?boolean} isHeaderFooterEnabled Previous header-footer setting.
- * @param {?print_preview.ticket_items.MarginsType.Value} marginsType
+ * @param {print_preview.ticket_items.MarginsType.Value} marginsType
* Previous margins type.
* @param {print_preview.Margins} customMargins Previous custom margins.
* @param {string} thousandsDelimeter Delimeter of the thousands place.
* @param {string} decimalDelimeter Delimeter of the decimal point.
- * @param {print_preview.MeasurementSystem.UnitType} unitType Type of unit
+ * @param {!print_preview.MeasurementSystem.UnitType} unitType Type of unit
* of the local measurement system.
*/
initialize: function(
@@ -276,28 +285,6 @@ cr.define('print_preview', function() {
}
},
- /**
- * Updates the capabilities of the destination the print ticket is for.
- * Dispatches a CAPABILITIES_CHANGE event.
- * @param {!print_preview.ChromiumCapabilities} caps New capabilities.
- */
- updateDestinationCapabilities: function(caps) {
- var isFirstUpdate = this.capabilitiesHolder_.get() == null;
- this.capabilitiesHolder_.set(caps);
- if (isFirstUpdate) {
- cr.dispatchSimpleEvent(this, PrintTicketStore.EventType.INITIALIZE);
- } else {
- this.customMargins_.updateValue(null);
- if (this.marginsType_.getValue() ==
- print_preview.ticket_items.MarginsType.Value.CUSTOM) {
- this.marginsType_.updateValue(
- print_preview.ticket_items.MarginsType.Value.DEFAULT);
- }
- cr.dispatchSimpleEvent(
- this, PrintTicketStore.EventType.CAPABILITIES_CHANGE);
- }
- },
-
/** @return {boolean} Whether the ticket store has the copies capability. */
hasCopiesCapability: function() {
return this.copies_.isCapabilityAvailable();
@@ -469,8 +456,8 @@ cr.define('print_preview', function() {
},
/**
- * @return {print_preview.ticket_items.MarginsType.Value} Type of predefined
- * margins.
+ * @return {!print_preview.ticket_items.MarginsType.Value} Type of
+ * predefined margins.
*/
getMarginsType: function() {
return this.marginsType_.getValue();
@@ -509,8 +496,8 @@ cr.define('print_preview', function() {
},
/**
- * @param {print_preview.ticket_items.CustomMargins.Orientation} orientation
- * Specifies the margin to get the maximum value for.
+ * @param {!print_preview.ticket_items.CustomMargins.Orientation}
+ * orientation Specifies the margin to get the maximum value for.
* @return {number} Maximum value in points of the specified margin.
*/
getCustomMarginMax: function(orientation) {
@@ -533,8 +520,8 @@ cr.define('print_preview', function() {
/**
* Updates a single custom margin's value in points.
- * @param {print_preview.ticket_items.CustomMargins.Orientation} orientation
- * Specifies the margin to update.
+ * @param {!print_preview.ticket_items.CustomMargins.Orientation}
+ * orientation Specifies the margin to update.
* @param {number} value Updated margin in points.
*/
updateCustomMargin: function(orientation, value) {
@@ -619,6 +606,40 @@ cr.define('print_preview', function() {
this.getMarginsType() !=
print_preview.ticket_items.MarginsType.Value.CUSTOM ||
this.isCustomMarginsValid());
+ },
+
+ /**
+ * Adds event listeners for the print ticket store.
+ * @private
+ */
+ addEventListeners_: function() {
+ this.tracker_.add(
+ this.destinationStore_,
+ print_preview.DestinationStore.EventType.
+ SELECTED_DESTINATION_CAPABILITIES_READY,
+ this.onSelectedDestinationCapabilitiesReady_.bind(this));
+ },
+
+ /**
+ * Called when the capabilities of the selected destination are ready.
+ * @private
+ */
+ onSelectedDestinationCapabilitiesReady_: function() {
+ var caps = this.destinationStore_.selectedDestination.capabilities;
+ var isFirstUpdate = this.capabilitiesHolder_.get() == null;
+ this.capabilitiesHolder_.set(caps);
+ if (isFirstUpdate) {
+ cr.dispatchSimpleEvent(this, PrintTicketStore.EventType.INITIALIZE);
+ } else {
+ this.customMargins_.updateValue(null);
+ if (this.marginsType_.getValue() ==
+ print_preview.ticket_items.MarginsType.Value.CUSTOM) {
+ this.marginsType_.updateValue(
+ print_preview.ticket_items.MarginsType.Value.DEFAULT);
+ }
+ cr.dispatchSimpleEvent(
+ this, PrintTicketStore.EventType.CAPABILITIES_CHANGE);
+ }
}
};
diff --git a/chrome/browser/resources/print_preview/data/ticket_items/custom_margins.js b/chrome/browser/resources/print_preview/data/ticket_items/custom_margins.js
index 774e35b..a9a0f07 100644
--- a/chrome/browser/resources/print_preview/data/ticket_items/custom_margins.js
+++ b/chrome/browser/resources/print_preview/data/ticket_items/custom_margins.js
@@ -46,7 +46,7 @@ cr.define('print_preview.ticket_items', function() {
/**
* Mapping of a margin orientation to its opposite.
- * @type {object.<CustomMargins.Orientation, CustomMargins.Orientation>}
+ * @type {!Object.<!CustomMargins.Orientation, !CustomMargins.Orientation>}
* @private
*/
CustomMargins.OppositeOrientation_ = {};
@@ -90,8 +90,8 @@ cr.define('print_preview.ticket_items', function() {
},
/**
- * @param {print_preview.ticket_items.CustomMargins.Orientation} orientation
- * Specifies the margin to get the maximum value for.
+ * @param {!print_preview.ticket_items.CustomMargins.Orientation}
+ * orientation Specifies the margin to get the maximum value for.
* @return {number} Maximum value in points of the specified margin.
*/
getMarginMax: function(orientation) {
@@ -117,8 +117,8 @@ cr.define('print_preview.ticket_items', function() {
/**
* Updates the specified margin in points while keeping the value within
* a maximum and minimum.
- * @param {print_preview.ticket_items.CustomMargins.Orientation} orientation
- * Specifies the margin to update.
+ * @param {!print_preview.ticket_items.CustomMargins.Orientation}
+ * orientation Specifies the margin to update.
* @param {number} value Updated margin value in points.
*/
updateMargin: function(orientation, value) {
@@ -143,8 +143,8 @@ cr.define('print_preview.ticket_items', function() {
},
/**
- * @param {print_preview.ticket_items.CustomMargins.Orientation} orientation
- * Specifies which margin to get the maximum value of.
+ * @param {!print_preview.ticket_items.CustomMargins.Orientation}
+ * orientation Specifies which margin to get the maximum value of.
* @param {number} oppositeMargin Value of the margin in points
* opposite the specified margin.
* @return {number} Maximum value in points of the specified margin.
diff --git a/chrome/browser/resources/print_preview/data/ticket_items/ticket_item.js b/chrome/browser/resources/print_preview/data/ticket_items/ticket_item.js
index 1dffd20..4753797 100644
--- a/chrome/browser/resources/print_preview/data/ticket_items/ticket_item.js
+++ b/chrome/browser/resources/print_preview/data/ticket_items/ticket_item.js
@@ -38,7 +38,7 @@ cr.define('print_preview.ticket_items', function() {
throw Error('Abstract method not overridden');
},
- /** @return {object} The value of the ticket item. */
+ /** @return {!Object} The value of the ticket item. */
getValue: function() {
if (this.isCapabilityAvailable()) {
if (this.value_ == null) {
@@ -64,13 +64,13 @@ cr.define('print_preview.ticket_items', function() {
return this.wouldValueBeValid(this.value_);
},
- /** @param {object} Value to set as the value of the ticket item. */
+ /** @param {!Object} Value to set as the value of the ticket item. */
updateValue: function(value) {
this.value_ = value;
},
/**
- * @return {object} Default value of the ticket item if no value was set by
+ * @return {!Object} Default value of the ticket item if no value was set by
* the user.
* @protected
*/
@@ -79,7 +79,7 @@ cr.define('print_preview.ticket_items', function() {
},
/**
- * @return {object} Default value of the ticket item if the capability is
+ * @return {!Object} Default value of the ticket item if the capability is
* not available.
* @protected
*/
diff --git a/chrome/browser/resources/print_preview/data/user_info.js b/chrome/browser/resources/print_preview/data/user_info.js
new file mode 100644
index 0000000..dcab125
--- /dev/null
+++ b/chrome/browser/resources/print_preview/data/user_info.js
@@ -0,0 +1,92 @@
+// Copyright (c) 2012 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', function() {
+ 'use strict';
+
+ /**
+ * Repository which stores information about the user. Events are dispatched
+ * when the information changes.
+ * @constructor
+ * @extends {cr.EventTarget}
+ */
+ function UserInfo() {
+ cr.EventTarget.call(this);
+
+ /**
+ * Tracker used to keep track of event listeners.
+ * @type {!EventTracker}
+ * @private
+ */
+ this.tracker_ = new EventTracker();
+
+ /**
+ * Google Cloud Print interface to listen to for events. Currently, through
+ * Google Cloud Print is how we determine the info of the logged in user.
+ * @type {cloudprint.CloudPrintInterface}
+ * @private
+ */
+ this.cloudPrintInterface_ = null;
+
+ /**
+ * Email address of the logged in user or {@code null} if no user is logged
+ * in.
+ * @type {?string}
+ * @private
+ */
+ this.userEmail_ = null;
+ };
+
+ /**
+ * Enumeration of event types dispatched by the user info.
+ * @enum {string}
+ */
+ UserInfo.EventType = {
+ EMIAL_CHANGE: 'print_preview.UserInfo.EMAIL_CHANGE'
+ };
+
+ UserInfo.prototype = {
+ __proto__: cr.EventTarget.prototype,
+
+ /**
+ * @return {?string} Email address of the logged in user or {@code null} if
+ * no user is logged.
+ */
+ getUserEmail: function() {
+ return this.userEmail_;
+ },
+
+ /**
+ * @param {!cloudprint.CloudPrintInterface} cloudPrintInterface Interface
+ * to Google Cloud Print that the print preview uses.
+ */
+ setCloudPrintInterface: function(cloudPrintInterface) {
+ this.cloudPrintInterface_ = cloudPrintInterface;
+ this.tracker_.add(
+ this.cloudPrintInterface_,
+ cloudprint.CloudPrintInterface.EventType.SEARCH_DONE,
+ this.onCloudPrintSearchDone_.bind(this));
+ },
+
+ /** Removes all event listeners. */
+ removeEventListeners: function() {
+ this.tracker_.removeAll();
+ },
+
+ /**
+ * Called when a Google Cloud Print printer search completes. Updates user
+ * information.
+ * @type {cr.Event} event Contains information about the logged in user.
+ * @private
+ */
+ onCloudPrintSearchDone_: function(event) {
+ this.userEmail_ = event.email;
+ cr.dispatchSimpleEvent(this, UserInfo.EventType.EMAIL_CHANGE);
+ }
+ };
+
+ return {
+ UserInfo: UserInfo
+ };
+});
diff --git a/chrome/browser/resources/print_preview/images/classic_printer_32.png b/chrome/browser/resources/print_preview/images/classic_printer_32.png
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/chrome/browser/resources/print_preview/images/classic_printer_32.png
diff --git a/chrome/browser/resources/print_preview/images/cloud.png b/chrome/browser/resources/print_preview/images/cloud.png
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/chrome/browser/resources/print_preview/images/cloud.png
diff --git a/chrome/browser/resources/print_preview/images/cloud_printer_32.png b/chrome/browser/resources/print_preview/images/cloud_printer_32.png
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/chrome/browser/resources/print_preview/images/cloud_printer_32.png
diff --git a/chrome/browser/resources/print_preview/images/cloud_printer_shared_32.png b/chrome/browser/resources/print_preview/images/cloud_printer_shared_32.png
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/chrome/browser/resources/print_preview/images/cloud_printer_shared_32.png
diff --git a/chrome/browser/resources/print_preview/images/google_promoted_printer_32.png b/chrome/browser/resources/print_preview/images/google_promoted_printer_32.png
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/chrome/browser/resources/print_preview/images/google_promoted_printer_32.png
diff --git a/chrome/browser/resources/print_preview/images/mobile_32.png b/chrome/browser/resources/print_preview/images/mobile_32.png
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/chrome/browser/resources/print_preview/images/mobile_32.png
diff --git a/chrome/browser/resources/print_preview/images/mobile_shared_32.png b/chrome/browser/resources/print_preview/images/mobile_shared_32.png
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/chrome/browser/resources/print_preview/images/mobile_shared_32.png
diff --git a/chrome/browser/resources/print_preview/images/search.png b/chrome/browser/resources/print_preview/images/search.png
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/chrome/browser/resources/print_preview/images/search.png
diff --git a/chrome/browser/resources/print_preview/native_layer.js b/chrome/browser/resources/print_preview/native_layer.js
index 8acec69..522c339 100644
--- a/chrome/browser/resources/print_preview/native_layer.js
+++ b/chrome/browser/resources/print_preview/native_layer.js
@@ -232,7 +232,7 @@ cr.define('print_preview', function() {
'fitToPageEnabled': printTicketStore.isFitToPageEnabled()
};
- if (!destination.isLocal && !destination.isPrintWithCloudPrint) {
+ if (!destination.isLocal) {
// We can't set cloudPrintID if the destination is "Print with Cloud
// Print" because the native system will try to print to Google Cloud
// Print with this ID instead of opening a Google Cloud Print dialog.
@@ -300,17 +300,17 @@ cr.define('print_preview', function() {
},
/** Navigates the user to the system printer settings interface. */
- startManageLocalPrinters: function() {
+ startManageLocalDestinations: function() {
chrome.send('manageLocalPrinters');
},
/** Navigates the user to the Google Cloud Print management page. */
- startManageCloudPrinters: function() {
+ startManageCloudDestinations: function() {
chrome.send('manageCloudPrinters');
},
/**
- * @param {object} initialSettings Object containing all initial settings.
+ * @param {!Object} initialSettings Object containing all initial settings.
*/
onSetInitialSettings_: function(initialSettings) {
// TODO(rltoscano): Use initialSettings['cloudPrintData'] to prepopulate
@@ -562,11 +562,11 @@ cr.define('print_preview', function() {
* in auto-print mode.
* @param {string} thousandsDelimeter Character delimeter of thousands digits.
* @param {string} decimalDelimeter Character delimeter of the decimal point.
- * @param {print_preview.MeasurementSystem.UnitType} unitType Unit type of
+ * @param {!print_preview.MeasurementSystem.UnitType} unitType Unit type of
* local machine's measurement system.
* @param {boolean} isDocumentModifiable Whether the document to print is
* modifiable.
- * @param {?print_preview.ticket_items.MarginsType.Value} marginsType Initial
+ * @param {print_preview.ticket_items.MarginsType.Value} marginsType Initial
* margins type.
* @param {print_preview.Margins} customMargins Initial custom margins.
* @param {boolean} isDuplexEnabled Whether duplexing is initially enabled.
@@ -625,7 +625,7 @@ cr.define('print_preview', function() {
/**
* Initial margins type.
- * @type {?print_preview.ticket_items.MarginsType.Value}
+ * @type {print_preview.ticket_items.MarginsType.Value}
* @private
*/
this.marginsType_ = marginsType;
@@ -678,7 +678,7 @@ cr.define('print_preview', function() {
},
/**
- * @return {print_preview.MeasurementSystem.UnitType} Unit type of local
+ * @return {!print_preview.MeasurementSystem.UnitType} Unit type of local
* machine's measurement system.
*/
get unitType() {
@@ -691,7 +691,7 @@ cr.define('print_preview', function() {
},
/**
- * @return {?print_preview.ticket_items.MarginsType.Value} Initial margins
+ * @return {print_preview.ticket_items.MarginsType.Value} Initial margins
* type or {@code null} if not initially set.
*/
get marginsType() {
diff --git a/chrome/browser/resources/print_preview/preview_generator.js b/chrome/browser/resources/print_preview/preview_generator.js
index 4787dc4..b001489 100644
--- a/chrome/browser/resources/print_preview/preview_generator.js
+++ b/chrome/browser/resources/print_preview/preview_generator.js
@@ -85,7 +85,7 @@ cr.define('print_preview', function() {
/**
* Margins type used to generate the last preview.
- * @type {print_preview.ticket_items.MarginsType.Value}
+ * @type {!print_preview.ticket_items.MarginsType.Value}
* @private
*/
this.marginsType_ = print_preview.ticket_items.MarginsType.Value.DEFAULT;
diff --git a/chrome/browser/resources/print_preview/previewarea/margin_control.css b/chrome/browser/resources/print_preview/previewarea/margin_control.css
index 38c5834..7eb6a1f 100644
--- a/chrome/browser/resources/print_preview/previewarea/margin_control.css
+++ b/chrome/browser/resources/print_preview/previewarea/margin_control.css
@@ -1,7 +1,6 @@
/* Copyright (c) 2012 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.
- */
+ * found in the LICENSE file. */
#preview-area .margin-control {
-webkit-transition: opacity 150ms linear;
diff --git a/chrome/browser/resources/print_preview/previewarea/margin_control.html b/chrome/browser/resources/print_preview/previewarea/margin_control.html
index 58bbdbab..77381b2 100644
--- a/chrome/browser/resources/print_preview/previewarea/margin_control.html
+++ b/chrome/browser/resources/print_preview/previewarea/margin_control.html
@@ -1,6 +1,4 @@
-<div id="margin-control-template"
- class="margin-control invisible"
- style="display: none;">
+<div id="margin-control-template" class="margin-control invisible" hidden>
<div class="margin-control-line"></div>
<input class="margin-control-textbox" type="text"/>
</div>
diff --git a/chrome/browser/resources/print_preview/previewarea/margin_control.js b/chrome/browser/resources/print_preview/previewarea/margin_control.js
index 476371a..3f3c78d 100644
--- a/chrome/browser/resources/print_preview/previewarea/margin_control.js
+++ b/chrome/browser/resources/print_preview/previewarea/margin_control.js
@@ -7,7 +7,7 @@ cr.define('print_preview', function() {
/**
* Draggable control for setting a page margin.
- * @param {print_preview.ticket_items.CustomMargins.Orientation} orientation
+ * @param {!print_preview.ticket_items.CustomMargins.Orientation} orientation
* Orientation of the margin control that determines where the margin
* textbox will be placed.
* @constructor
@@ -18,7 +18,7 @@ cr.define('print_preview', function() {
/**
* Determines where the margin textbox will be placed.
- * @type {print_preview.ticket_items.CustomMargins.Orientation}
+ * @type {!print_preview.ticket_items.CustomMargins.Orientation}
* @private
*/
this.orientation_ = orientation;
@@ -67,7 +67,7 @@ cr.define('print_preview', function() {
/**
* Processing timeout for the textbox.
- * @type {Object}
+ * @type {?number}
* @private
*/
this.textTimeout_ = null;
@@ -140,9 +140,9 @@ cr.define('print_preview', function() {
/**
* Map from orientation to CSS class name.
- * @type {object.<
- * print_preview.ticket_items.CustomMargins.Orientation,
- * MarginControl.Classes_>}
+ * @type {!Object.<
+ * !print_preview.ticket_items.CustomMargins.Orientation,
+ * !MarginControl.Classes_>}
* @private
*/
MarginControl.OrientationToClass_ = {};
@@ -185,7 +185,7 @@ cr.define('print_preview', function() {
},
/**
- * @return {print_preview.ticket_items.CustomMargins.Orientation}
+ * @return {!print_preview.ticket_items.CustomMargins.Orientation}
* Orientation of the margin control.
*/
getOrientation: function() {
diff --git a/chrome/browser/resources/print_preview/previewarea/margin_control_container.css b/chrome/browser/resources/print_preview/previewarea/margin_control_container.css
index bfb1935..70236e6 100644
--- a/chrome/browser/resources/print_preview/previewarea/margin_control_container.css
+++ b/chrome/browser/resources/print_preview/previewarea/margin_control_container.css
@@ -1,7 +1,6 @@
/* Copyright (c) 2012 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.
- */
+ * found in the LICENSE file. */
.margin-control-container-dragging-vertical {
cursor: ns-resize;
diff --git a/chrome/browser/resources/print_preview/previewarea/margin_control_container.js b/chrome/browser/resources/print_preview/previewarea/margin_control_container.js
index 1209da9..52fd782 100644
--- a/chrome/browser/resources/print_preview/previewarea/margin_control_container.js
+++ b/chrome/browser/resources/print_preview/previewarea/margin_control_container.js
@@ -31,8 +31,8 @@ cr.define('print_preview', function() {
/**
* Convenience array that contains all of the margin controls.
- * @type {!Object<
- * print_preview.ticket_items.CustomMargins.Orientation,
+ * @type {!Object.<
+ * !print_preview.ticket_items.CustomMargins.Orientation,
* !print_preview.MarginControl>}
* @private
*/
@@ -90,7 +90,7 @@ cr.define('print_preview', function() {
};
/**
- * @param {print_preview.ticket_items.CustomMargins.Orientation} orientation
+ * @param {!print_preview.ticket_items.CustomMargins.Orientation} orientation
* Orientation value to test.
* @return {boolean} Whether the given orientation is TOP or BOTTOM.
* @private
diff --git a/chrome/browser/resources/print_preview/previewarea/preview_area.css b/chrome/browser/resources/print_preview/previewarea/preview_area.css
index 137f914..c80199a 100644
--- a/chrome/browser/resources/print_preview/previewarea/preview_area.css
+++ b/chrome/browser/resources/print_preview/previewarea/preview_area.css
@@ -1,7 +1,6 @@
/* Copyright (c) 2012 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.
- */
+ * found in the LICENSE file. */
#preview-area.preview-area {
-webkit-box-flex: 1;
diff --git a/chrome/browser/resources/print_preview/previewarea/preview_area.html b/chrome/browser/resources/print_preview/previewarea/preview_area.html
index 39b9d81..4f59507 100644
--- a/chrome/browser/resources/print_preview/previewarea/preview_area.html
+++ b/chrome/browser/resources/print_preview/previewarea/preview_area.html
@@ -8,28 +8,26 @@
><span>.</span><span>.</span><span>.</span></span>
</div>
- <div class="preview-area-custom-message preview-area-message"
- style="display: none;">
+ <div class="preview-area-custom-message preview-area-message" hidden>
<div class="preview-area-custom-message-text"></div>
<div class="preview-area-custom-action-area">
<button class="preview-area-open-system-dialog-button"
i18n-content="launchNativeDialog"></button>
<div class="preview-area-open-system-dialog-button-throbber throbber"
- style="display: none;"></div>
+ hidden></div>
</div>
</div>
<div class="preview-area-preview-failed-message preview-area-message"
- i18n-content="previewFailed"
- style="display: none;"></div>
+ i18n-content="previewFailed" hidden></div>
- <div class="preview-area-print-failed preview-area-message" style="display: none;">
+ <div class="preview-area-print-failed preview-area-message" hidden>
<div i18n-content="invalidPrinterSettings"></div>
<div class="preview-area-print-failed-action-area">
<button class="preview-area-open-system-dialog-button"
i18n-content="launchNativeDialog"></button>
<div class="preview-area-open-system-dialog-button-throbber throbber"
- style="display: none;"></div>
+ hidden></div>
</div>
</div>
diff --git a/chrome/browser/resources/print_preview/previewarea/preview_area.js b/chrome/browser/resources/print_preview/previewarea/preview_area.js
index 1ede80a..7fc8ec02 100644
--- a/chrome/browser/resources/print_preview/previewarea/preview_area.js
+++ b/chrome/browser/resources/print_preview/previewarea/preview_area.js
@@ -95,7 +95,7 @@ cr.define('print_preview', function() {
/**
* Timeout object used to display a loading message if the preview is taking
* a long time to generate.
- * @type {Object}
+ * @type {?number}
* @private
*/
this.loadingTimeout_ = null;
@@ -352,8 +352,8 @@ cr.define('print_preview', function() {
/**
* Shows a given message on the overlay.
- * @param {print_preview.PreviewArea.MessageId_} messageId ID of the message
- * to show.
+ * @param {!print_preview.PreviewArea.MessageId_} messageId ID of the
+ * message to show.
* @param {string=} opt_message Optional message to show that can be used
* by some message IDs.
* @private
diff --git a/chrome/browser/resources/print_preview/print_header.css b/chrome/browser/resources/print_preview/print_header.css
index dca74d3a..5011412 100644
--- a/chrome/browser/resources/print_preview/print_header.css
+++ b/chrome/browser/resources/print_preview/print_header.css
@@ -1,7 +1,6 @@
/* Copyright (c) 2012 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.
- */
+ * found in the LICENSE file. */
.print-header {
padding-bottom: 10px;
diff --git a/chrome/browser/resources/print_preview/print_header.js b/chrome/browser/resources/print_preview/print_header.js
index 2d93429..059fb05 100644
--- a/chrome/browser/resources/print_preview/print_header.js
+++ b/chrome/browser/resources/print_preview/print_header.js
@@ -213,7 +213,9 @@ cr.define('print_preview', function() {
*/
onDestinationSelect_: function() {
if (this.destinationStore_.selectedDestination.id ==
- print_preview.Destination.GooglePromotedId.SAVE_AS_PDF) {
+ print_preview.Destination.GooglePromotedId.SAVE_AS_PDF ||
+ this.destinationStore_.selectedDestination.id ==
+ print_preview.Destination.GooglePromotedId.DOCS) {
this.printButton_.textContent = localStrings.getString('saveButton');
} else {
this.printButton_.textContent = localStrings.getString('printButton');
diff --git a/chrome/browser/resources/print_preview/print_preview.css b/chrome/browser/resources/print_preview/print_preview.css
index 1c91d66..72d0ba4 100644
--- a/chrome/browser/resources/print_preview/print_preview.css
+++ b/chrome/browser/resources/print_preview/print_preview.css
@@ -83,6 +83,7 @@ header {
border-bottom: 1px solid #dcdcdc;
padding-bottom: 10px;
padding-top: 10px;
+ vertical-align: top;
}
.two-column:not(.visible) select {
diff --git a/chrome/browser/resources/print_preview/print_preview.html b/chrome/browser/resources/print_preview/print_preview.html
index c3fd255..f1b283b 100644
--- a/chrome/browser/resources/print_preview/print_preview.html
+++ b/chrome/browser/resources/print_preview/print_preview.html
@@ -10,6 +10,7 @@
<link rel="stylesheet" href="../shared/css/chrome_shared.css"/>
<link rel="stylesheet" href="../shared/css/throbber.css"/>
<link rel="stylesheet" href="print_header.css"/>
+ <link rel="stylesheet" href="settings/destination_settings.css"/>
<link rel="stylesheet" href="settings/copies_settings.css"/>
<link rel="stylesheet" href="settings/page_settings.css"/>
<link rel="stylesheet" href="previewarea/preview_area.css"/>
@@ -17,13 +18,18 @@
<link rel="stylesheet" href="previewarea/margin_control.css"/>
<link rel="stylesheet" href="../shared/css/overlay.css"/>
+ <link rel="stylesheet" href="search/destination_list.css"/>
+ <link rel="stylesheet" href="search/destination_list_item.css"/>
+ <link rel="stylesheet" href="search/destination_search.css"/>
+ <link rel="stylesheet" href="search/search_box.css"/>
+
+ <script src="chrome://print/strings.js"></script>
<script src="chrome://resources/js/cr.js"></script>
<script src="chrome://resources/js/cr/event_target.js"></script>
<script src="chrome://resources/js/event_tracker.js"></script>
<script src="chrome://resources/js/local_strings.js"></script>
<script src="chrome://resources/js/util.js"></script>
<script src="chrome://print/print_preview.js"></script>
- <script src="chrome://print/strings.js"></script>
<script src="chrome://resources/js/i18n_template.js"></script>
</head>
@@ -44,33 +50,26 @@
</div>
<div id="link-container">
<div>
- <button id="cloud-print-dialog-link"
- class="link-button navbar-link"
- style="display: none;"
- i18n-content="cloudPrintDialogOption"></button>
- <button id="system-dialog-link"
- class="link-button navbar-link"
- style="display: none;"
- i18n-content="systemDialogOption"></button>
- <div id="dialog-throbber"
- style="display: none;"
- class="throbber"></div>
+ <button id="cloud-print-dialog-link" class="link-button navbar-link"
+ hidden i18n-content="cloudPrintDialogOption"></button>
+ <button id="system-dialog-link" class="link-button navbar-link"
+ hidden i18n-content="systemDialogOption"></button>
+ <div id="dialog-throbber" hidden class="throbber"></div>
</div>
<div>
- <button id="open-pdf-in-preview-link"
- class="link-button navbar-link"
- style="display: none;"
- i18n-content="openPdfInPreviewOption"></button>
- <div id="open-preview-app-throbber"
- style="display: none;"
- class="throbber"></div>
+ <button id="open-pdf-in-preview-link" class="link-button navbar-link"
+ hidden i18n-content="openPdfInPreviewOption"></button>
+ <div id="open-preview-app-throbber" hidden class="throbber"></div>
</div>
</div>
</div>
+ <include src="search/destination_search.html"/>
<include src="previewarea/preview_area.html"/>
<!-- HTML Templates -->
<include src="previewarea/margin_control.html"/>
+ <include src="search/destination_list.html"/>
+ <include src="search/destination_list_item.html"/>
</body>
</html>
diff --git a/chrome/browser/resources/print_preview/print_preview.js b/chrome/browser/resources/print_preview/print_preview.js
index ed78cfc..1fa15a3 100644
--- a/chrome/browser/resources/print_preview/print_preview.js
+++ b/chrome/browser/resources/print_preview/print_preview.js
@@ -2,16 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// TODO(rltoscano): Might be a problem where might be in fetching destinations
-// state, then to file selection state, then cancel, which results in the
-// fetching destinations state being lost.
-
// TODO(rltoscano): Move data/* into print_preview.data namespace
-// TODO(rltoscano): Handle case where cloud print is initial destination, but
-// cloud print is not enabled.
-
-var localStrings = new LocalStrings();
+var localStrings = new LocalStrings(templateData);
<include src="component.js"/>
@@ -34,11 +27,19 @@ cr.define('print_preview', function() {
this.nativeLayer_ = new print_preview.NativeLayer();
/**
+ * Event target that contains information about the logged in user.
+ * @type {!print_preview.UserInfo}
+ * @private
+ */
+ this.userInfo_ = new print_preview.UserInfo();
+
+ /**
* Data store which holds print destinations.
* @type {!print_preview.DestinationStore}
* @private
*/
- this.destinationStore_ = new print_preview.DestinationStore();
+ this.destinationStore_ = new print_preview.DestinationStore(
+ this.nativeLayer_);
/**
* Storage of the print ticket used to create the print job.
@@ -58,6 +59,15 @@ cr.define('print_preview', function() {
this.addChild(this.printHeader_);
/**
+ * Component used to search for print destinations.
+ * @type {!print_preview.DestinationSearch}
+ * @private
+ */
+ this.destinationSearch_ = new print_preview.DestinationSearch(
+ this.destinationStore_, this.userInfo_);
+ this.addChild(this.destinationSearch_);
+
+ /**
* Component that renders the print destination.
* @type {!print_preview.DestinationSettings}
* @private
@@ -154,20 +164,11 @@ cr.define('print_preview', function() {
this.uiState_ = PrintPreview.UiState_.INITIALIZING;
/**
- * Current state of fetching destinations.
- * @type {print_preview.PrintPreview.FetchState_}
- * @private
- */
- this.fetchState_ = PrintPreview.FetchState_.READY;
-
- /**
* Whether document preview generation is in progress.
* @type {boolean}
* @private
*/
this.isPreviewGenerationInProgress_ = true;
-
- this.tracker.add(window, 'DOMContentLoaded', this.onWindowLoad_.bind(this));
};
/**
@@ -186,36 +187,18 @@ cr.define('print_preview', function() {
ERROR: 'error'
};
- /**
- * Bitfield of the states of fetching destinations.
- * @enum {number}
- * @private
- */
- PrintPreview.FetchState_ = {
- READY: 1,
- LOCAL_DESTINATIONS: 2,
- RECENT_CLOUD_DESTINATIONS: 4,
- ALL_CLOUD_DESTINATIONS: 8
- };
-
PrintPreview.prototype = {
__proto__: print_preview.Component.prototype,
- /** @override */
- decorateInternal: function() {
- this.printHeader_.decorate($('print-header'));
- this.destinationSettings_.decorate($('destination-settings'));
- this.pageSettings_.decorate($('page-settings'));
- this.copiesSettings_.decorate($('copies-settings'));
- this.layoutSettings_.decorate($('layout-settings'));
- this.colorSettings_.decorate($('color-settings'));
- this.marginSettings_.decorate($('margin-settings'));
- this.otherOptionsSettings_.decorate($('other-options-settings'));
- this.previewArea_.decorate($('preview-area'));
-
- setIsVisible($('cloud-print-dialog-link'), cr.isChromeOS);
- setIsVisible($('system-dialog-link'), !cr.isChromeOS);
- setIsVisible($('open-pdf-in-preview-link'), cr.isMac);
+ /** Sets up the page and print preview by getting the printer list. */
+ initialize: function() {
+ this.decorate($('print-preview'));
+ i18nTemplate.process(document, templateData);
+ if (!this.previewArea_.hasCompatiblePlugin) {
+ this.setIsEnabled_(false);
+ }
+ this.nativeLayer_.startGetInitialSettings();
+ this.destinationStore_.startLoadLocalDestinations();
},
/** @override */
@@ -231,18 +214,6 @@ cr.define('print_preview', function() {
this.onCloudPrintEnable_.bind(this));
this.tracker.add(
this.nativeLayer_,
- print_preview.NativeLayer.EventType.LOCAL_DESTINATIONS_SET,
- this.onLocalDestinationsSet_.bind(this));
- this.tracker.add(
- this.nativeLayer_,
- print_preview.NativeLayer.EventType.CAPABILITIES_SET,
- this.onLocalDestinationCapabilitiesSet_.bind(this));
- this.tracker.add(
- this.nativeLayer_,
- print_preview.NativeLayer.EventType.DESTINATIONS_RELOAD,
- this.onDestinationsReload_.bind(this));
- this.tracker.add(
- this.nativeLayer_,
print_preview.NativeLayer.EventType.PRINT_TO_CLOUD,
this.onPrintToCloud_.bind(this));
this.tracker.add(
@@ -294,8 +265,9 @@ cr.define('print_preview', function() {
this.tracker.add(
this.destinationStore_,
- print_preview.DestinationStore.EventType.DESTINATION_SELECT,
- this.onDestinationSelect_.bind(this));
+ print_preview.DestinationStore.EventType.
+ SELECTED_DESTINATION_CAPABILITIES_READY,
+ this.printIfReady_.bind(this));
this.tracker.add(
this.printHeader_,
@@ -306,12 +278,43 @@ cr.define('print_preview', function() {
print_preview.PrintHeader.EventType.CANCEL_BUTTON_CLICK,
this.onCancelButtonClick_.bind(this));
+ this.tracker.add(window, 'keydown', this.onKeyDown_.bind(this));
+
this.tracker.add(
this.destinationSettings_,
- print_preview.DestinationSettings.EventType.MANAGE_PRINTERS_SELECT,
- this.onManagePrinters_.bind(this));
+ print_preview.DestinationSettings.EventType.CHANGE_BUTTON_ACTIVATE,
+ this.onDestinationChangeButtonActivate_.bind(this));
- this.tracker.add(window, 'keydown', this.onKeyDown_.bind(this));
+ this.tracker.add(
+ this.destinationSearch_,
+ print_preview.DestinationSearch.EventType.MANAGE_CLOUD_DESTINATIONS,
+ this.onManageCloudDestinationsActivated_.bind(this));
+ this.tracker.add(
+ this.destinationSearch_,
+ print_preview.DestinationSearch.EventType.MANAGE_LOCAL_DESTINATIONS,
+ this.onManageLocalDestinationsActivated_.bind(this));
+ this.tracker.add(
+ this.destinationSearch_,
+ print_preview.DestinationSearch.EventType.SIGN_IN,
+ this.onCloudPrintSignInActivated_.bind(this));
+ },
+
+ /** @override */
+ decorateInternal: function() {
+ this.printHeader_.decorate($('print-header'));
+ this.destinationSearch_.decorate($('destination-search'));
+ this.destinationSettings_.decorate($('destination-settings'));
+ this.pageSettings_.decorate($('page-settings'));
+ this.copiesSettings_.decorate($('copies-settings'));
+ this.layoutSettings_.decorate($('layout-settings'));
+ this.colorSettings_.decorate($('color-settings'));
+ this.marginSettings_.decorate($('margin-settings'));
+ this.otherOptionsSettings_.decorate($('other-options-settings'));
+ this.previewArea_.decorate($('preview-area'));
+
+ setIsVisible($('cloud-print-dialog-link'), cr.isChromeOS);
+ setIsVisible($('system-dialog-link'), !cr.isChromeOS);
+ setIsVisible($('open-pdf-in-preview-link'), cr.isMac);
},
/**
@@ -335,58 +338,6 @@ cr.define('print_preview', function() {
},
/**
- * Creates a local PDF print destination.
- * @return {!print_preview.Destination} Created print destination.
- * @private
- */
- createLocalPdfPrintDestination_: function() {
- var dest = new print_preview.Destination(
- print_preview.Destination.GooglePromotedId.SAVE_AS_PDF,
- localStrings.getString('printToPDF'),
- false /*isRecent*/,
- true /*isLocal*/);
- dest.capabilities = new print_preview.ChromiumCapabilities(
- false /*hasCopiesCapability*/,
- '1' /*defaultCopiesStr*/,
- false /*hasCollateCapability*/,
- false /*defaultIsCollateEnabled*/,
- false /*hasDuplexCapability*/,
- false /*defaultIsDuplexEnabled*/,
- true /*hasOrientationCapability*/,
- false /*defaultIsLandscapeEnabled*/,
- true /*hasColorCapability*/,
- true /*defaultIsColorEnabled*/);
- return dest;
- },
-
- /**
- * Creates a new "Print with Cloud Print" print destination. NOTE: this
- * destination will appear as "Search for additional printers..." on
- * Chrome OS.
- * @return {!print_preview.Destination} Created print destination.
- * @private
- */
- createPrintWithCloudPrintDestination_: function() {
- var dest = new print_preview.Destination(
- print_preview.Destination.GooglePromotedId.PRINT_WITH_CLOUD_PRINT,
- localStrings.getString('printWithCloudPrint'),
- false /*isRecent*/,
- false /*isLocal*/);
- dest.capabilities = new print_preview.ChromiumCapabilities(
- false /*hasCopiesCapability*/,
- '1' /*defaultCopiesStr*/,
- false /*hasCollateCapability*/,
- false /*defaultIsCollateEnabled*/,
- false /*hasDuplexCapability*/,
- false /*defaultIsDuplexEnabled*/,
- true /*hasOrientationCapability*/,
- false /*defaultIsLandscapeEnabled*/,
- true /*hasColorCapability*/,
- true /*defaultIsColorEnabled*/);
- return dest;
- },
-
- /**
* Prints the document or launches a pdf preview on the local system.
* @param {boolean} isPdfPreview Whether to launch the pdf preview.
* @private
@@ -468,21 +419,6 @@ cr.define('print_preview', function() {
},
/**
- * Window onload handler, sets up the page and starts print preview by
- * getting the printer list.
- * @private
- */
- onWindowLoad_: function() {
- this.decorate($('print-preview'));
- i18nTemplate.process(document, templateData);
- if (!this.previewArea_.hasCompatiblePlugin) {
- this.setIsEnabled_(false);
- }
- this.nativeLayer_.startGetInitialSettings();
- this.nativeLayer_.startGetLocalDestinations();
- },
-
- /**
* Called when the native layer has initial settings to set. Sets the
* initial settings of the print preview and begins fetching print
* destinations.
@@ -519,16 +455,8 @@ cr.define('print_preview', function() {
* @private
*/
onCloudPrintEnable_: function(event) {
- this.cloudPrintInterface_ = new cloudprint.CloudPrintInterface(
- event.baseCloudPrintUrl);
- this.tracker.add(
- this.cloudPrintInterface_,
- cloudprint.CloudPrintInterface.EventType.SEARCH_DONE,
- this.onCloudPrintSearchDone_.bind(this));
- this.tracker.add(
- this.cloudPrintInterface_,
- cloudprint.CloudPrintInterface.EventType.PRINTER_DONE,
- this.onCloudPrintPrinterDone_.bind(this));
+ this.cloudPrintInterface_ =
+ new cloudprint.CloudPrintInterface(event.baseCloudPrintUrl);
this.tracker.add(
this.cloudPrintInterface_,
cloudprint.CloudPrintInterface.EventType.SUBMIT_DONE,
@@ -538,75 +466,9 @@ cr.define('print_preview', function() {
cloudprint.CloudPrintInterface.EventType.ERROR,
this.onCloudPrintError_.bind(this));
- var printWithCloudPrintDest =
- this.createPrintWithCloudPrintDestination_();
- this.destinationStore_.insertDestination(printWithCloudPrintDest);
-
- if (cr.isChromeOS) {
- this.cloudPrintInterface_.search(true /*isRecent*/);
- this.fetchState_ |= PrintPreview.FetchState_.RECENT_CLOUD_DESTINATIONS;
- }
- },
-
- /**
- * Called when the native layer gets local destinations. Adds local
- * destination objects received from the operating system to the destination
- * store. Also adds a save-as-pdf printer.
- * @param {cr.Event} Contains the local destinations to set.
- * @private
- */
- onLocalDestinationsSet_: function(event) {
- var localDestinations = [];
- for (var destInfo, i = 0; destInfo = event.destinationInfos[i]; i++) {
- localDestinations.push(
- print_preview.LocalDestinationParser.parse(destInfo));
- }
- localDestinations.push(this.createLocalPdfPrintDestination_());
- this.destinationStore_.insertDestinations(localDestinations);
- this.fetchState_ &= ~PrintPreview.FetchState_.LOCAL_DESTINATIONS;
- },
-
- /**
- * Called when the native layer retrieves the capabilities for the selected
- * local destination.
- * @param {cr.Event} event Contains the capabilities of the local print
- * destination.
- * @private
- */
- onLocalDestinationCapabilitiesSet_: function(event) {
- // TODO(rltoscano): There may be a race condition here. This method is
- // assumed to return capabilities for the currently selected printer. But
- // between the time the local printer was selected and the capabilities
- // were retrieved, the selected printer can change. One way to address
- // this is to include the destination ID in the settingsInfo parameter.
- var selectedDestination = this.destinationStore_.selectedDestination;
- if (selectedDestination.isLocal) {
- var capabilities = print_preview.LocalCapabilitiesParser.parse(
- event.settingsInfo);
- selectedDestination.capabilities = capabilities;
- this.printTicketStore_.updateDestinationCapabilities(capabilities);
- this.printIfReady_();
- }
- },
-
- /**
- * Called from native layer after the user was requested to sign in, and did
- * so successfully.
- * @private
- */
- onDestinationsReload_: function() {
- this.destinationStore_.clear();
- this.nativeLayer_.startGetLocalDestinations();
- if (this.cloudPrintInterface_) {
- // Fetch recent printers.
- this.cloudPrintInterface_.search(true /*isRecent*/);
- // Fetch the full printer list.
- this.cloudPrintInterface_.search(false /*isRecent*/);
- }
- this.fetchState_ =
- PrintPreview.FetchState_.LOCAL_DESTINATIONS |
- PrintPreview.FetchState_.ALL_CLOUD_DESTINATIONS |
- PrintPreview.FetchState_.RECENT_CLOUD_DESTINATIONS;
+ this.userInfo_.setCloudPrintInterface(this.cloudPrintInterface_);
+ this.destinationStore_.setCloudPrintInterface(this.cloudPrintInterface_);
+ this.destinationStore_.startLoadRecentCloudDestinations();
},
/**
@@ -650,36 +512,6 @@ cr.define('print_preview', function() {
},
/**
- * Called when the Google Cloud Print search API call completes. Adds
- * destinations to the printer store and selects one if it matches the
- * initial destination.
- * @param {cr.Event} event Contains the new cloud destinations.
- * @private
- */
- onCloudPrintSearchDone_: function(event) {
- this.destinationStore_.insertDestinations(event.printers);
- if (event.isRecent) {
- this.fetchState_ &= ~PrintPreview.FetchState_.RECENT_CLOUD_DESTINATIONS;
- } else {
- this.fetchState_ &= ~PrintPreview.FetchState_.ALL_CLOUD_DESTINATIONS;
- }
- },
-
- /**
- * Called when the Google Cloud Print printer API call completes. Updates
- * the UI with the newly received capabilities.
- * @param {cr.Event} event Contains the destination returned in the printer
- * API call.
- */
- onCloudPrintPrinterDone_: function(event) {
- var dest = this.destinationStore_.updateDestination(event.printer);
- if (this.destinationStore_.selectedDestination == dest) {
- this.printTicketStore_.updateDestinationCapabilities(dest.capabilities);
- this.printIfReady_();
- }
- },
-
- /**
* Called after successfully submitting a job to Google Cloud Print.
* @private
*/
@@ -697,41 +529,11 @@ cr.define('print_preview', function() {
* @private
*/
onCloudPrintError_: function(event) {
- if (cr.isChromeOS && event.message == '403') {
- this.nativeLayer_.startCloudPrintSignIn();
+ if (event.message == '403') {
+ this.destinationSearch_.showCloudPrintPromo();
} else {
this.printHeader_.setErrorMessage(event.message);
}
- this.fetchState_ &=
- ~PrintPreview.FetchState_.RECENT_CLOUD_DESTINATIONS &
- ~PrintPreview.FetchState_.ALL_CLOUD_DESTINATIONS;
- },
-
- /**
- * Called when a new destination has been selected. Fetches the
- * destination's capability list.
- * @private
- */
- onDestinationSelect_: function() {
- var destination = this.destinationStore_.selectedDestination;
-
- // Fetch destination capabilities if necessary.
- if (!destination.capabilities) {
- if (destination.isLocal) {
- this.nativeLayer_.startGetLocalDestinationCapabilities(
- destination.id);
- } else {
- assert(this.cloudPrintInterface_ != null,
- 'Selected destination is a cloud destination, but Google ' +
- 'Cloud Print is not enabled');
- this.cloudPrintInterface_.printer(destination.id);
- }
- } else {
- this.printTicketStore_.updateDestinationCapabilities(
- destination.capabilities);
- }
-
- this.printIfReady_();
},
/**
@@ -807,7 +609,11 @@ cr.define('print_preview', function() {
// Escape key closes the dialog.
if (e.keyCode == 27 && !e.shiftKey && !e.ctrlKey && !e.altKey &&
!e.metaKey) {
- this.close_();
+ if (this.destinationSearch_.getIsVisible()) {
+ this.destinationSearch_.setIsVisible(false);
+ } else {
+ this.close_();
+ }
e.preventDefault();
return;
}
@@ -837,25 +643,49 @@ cr.define('print_preview', function() {
},
/**
- * Called when the native layer dispatches a DISABLE_SCALING event. Updates
- * the print ticket.
+ * Called when the destination settings' change button is activated.
+ * Displays the destination search component.
* @private
*/
- onDisableScaling_: function() {
- this.printTicketStore_.updateFitToPage(false);
+ onDestinationChangeButtonActivate_: function() {
+ this.destinationSearch_.setIsVisible(true);
+ this.destinationStore_.startLoadAllCloudDestinations();
},
/**
- * Called when the user selects the "Manage printers..." option in the
- * destination select.
+ * Called when the destination search dispatches manage cloud destinations
+ * event. Calls corresponding native layer method.
* @private
*/
- onManagePrinters_: function() {
- if (cr.isChromeOS) {
- this.nativeLayer_.startManageCloudPrinters();
- } else {
- this.nativeLayer_.startManageLocalPrinters();
- }
+ onManageCloudDestinationsActivated_: function() {
+ this.nativeLayer_.startManageCloudDestinations();
+ },
+
+ /**
+ * Called when the destination search dispatches manage local destinations
+ * event. Calls corresponding native layer method.
+ * @private
+ */
+ onManageLocalDestinationsActivated_: function() {
+ this.nativeLayer_.startManageLocalDestinations();
+ },
+
+ /**
+ * Called when the user wants to sign in to Google Cloud Print. Calls the
+ * corresponding native layer event.
+ * @private
+ */
+ onCloudPrintSignInActivated_: function() {
+ this.nativeLayer_.startCloudPrintSignIn();
+ },
+
+ /**
+ * Called when the native layer dispatches a DISABLE_SCALING event. Updates
+ * the print ticket.
+ * @private
+ */
+ onDisableScaling_: function() {
+ this.printTicketStore_.updateFitToPage(false);
}
};
@@ -881,6 +711,7 @@ cr.define('print_preview', function() {
<include src="data/coordinate2d.js"/>
<include src="data/size.js"/>
<include src="data/capabilities_holder.js"/>
+<include src="data/user_info.js"/>
<include src="data/ticket_items/ticket_item.js"/>
@@ -914,4 +745,13 @@ cr.define('print_preview', function() {
<include src="previewarea/preview_area.js"/>
<include src="preview_generator.js"/>
-var printPreview = new print_preview.PrintPreview();
+<include src="search/destination_list.js"/>
+<include src="search/cloud_destination_list.js"/>
+<include src="search/destination_list_item.js"/>
+<include src="search/destination_search.js"/>
+<include src="search/search_box.js"/>
+
+window.addEventListener('DOMContentLoaded', function() {
+ printPreview = new print_preview.PrintPreview();
+ printPreview.initialize();
+});
diff --git a/chrome/browser/resources/print_preview/print_preview_utils.js b/chrome/browser/resources/print_preview/print_preview_utils.js
index 35bb80a..14eec32 100644
--- a/chrome/browser/resources/print_preview/print_preview_utils.js
+++ b/chrome/browser/resources/print_preview/print_preview_utils.js
@@ -192,12 +192,12 @@ function pageSetToPageRanges(pageSet) {
* @param {boolean} isVisible Whether the element should be visible or not.
*/
function setIsVisible(element, isVisible) {
- element.style.display = isVisible ? '' : 'none';
+ element.hidden = !isVisible;
}
/**
- * @param {Array.<object>} array Array to check for item.
- * @param {object} item Item to look for in array.
+ * @param {!Array} array Array to check for item.
+ * @param {*} item Item to look for in array.
* @return {boolean} Whether the item is in the array.
*/
function arrayContains(array, item) {
diff --git a/chrome/browser/resources/print_preview/search/cloud_destination_list.js b/chrome/browser/resources/print_preview/search/cloud_destination_list.js
new file mode 100644
index 0000000..a5b7c92
--- /dev/null
+++ b/chrome/browser/resources/print_preview/search/cloud_destination_list.js
@@ -0,0 +1,50 @@
+// Copyright (c) 2012 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', function() {
+ 'use strict';
+
+ /**
+ * Sub-class of a destination list that shows cloud-based destinations.
+ * @param {!cr.EventTarget} eventTarget Event target to pass to destination
+ * items for dispatching SELECT events.
+ * @constructor
+ * @extends {print_preview.DestinationList}
+ */
+ function CloudDestinationList(eventTarget) {
+ print_preview.DestinationList.call(
+ this,
+ eventTarget,
+ localStrings.getString('cloudDestinationsTitle'),
+ 0 /*opt_maxSize*/,
+ localStrings.getString('manage'));
+ };
+
+ CloudDestinationList.prototype = {
+ __proto__: print_preview.DestinationList.prototype,
+
+ /** @override */
+ updateDestinations: function(destinations) {
+ // Change the action link from "Manage..." to "Setup..." if user only has
+ // Docs and FedEx printers.
+ var docsId = print_preview.Destination.GooglePromotedId.DOCS;
+ var fedexId = print_preview.Destination.GooglePromotedId.FEDEX;
+ if ((destinations.length == 1 && destinations[0].id == docsId) ||
+ (destinations.length == 2 &&
+ ((destinations[0].id == docsId && destinations[1].id == fedexId) ||
+ (destinations[0].id == fedexId && destinations[1].id == docsId)))) {
+ this.setActionLinkTextInternal(
+ localStrings.getString('setupCloudPrinters'));
+ } else {
+ this.setActionLinkTextInternal(localStrings.getString('manage'));
+ }
+ print_preview.DestinationList.prototype.updateDestinations.call(
+ this, destinations);
+ }
+ };
+
+ return {
+ CloudDestinationList: CloudDestinationList
+ };
+});
diff --git a/chrome/browser/resources/print_preview/search/destination_list.css b/chrome/browser/resources/print_preview/search/destination_list.css
new file mode 100644
index 0000000..0490ff9
--- /dev/null
+++ b/chrome/browser/resources/print_preview/search/destination_list.css
@@ -0,0 +1,33 @@
+/* Copyright (c) 2012 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. */
+
+.destination-list-header {
+ -webkit-padding-start: 0;
+ background-color: transparent;
+}
+
+.destination-list-title {
+ -webkit-padding-end: 8px;
+ display: inline;
+}
+
+.destination-list-destination-list-item-container {
+ -webkit-padding-start: 0;
+ list-style-type: none;
+ margin-bottom: 0;
+}
+
+.destination-list-no-destinations-message {
+ -webkit-padding-start: 18px;
+ color: #999;
+}
+
+.destination-list-footer {
+ -webkit-padding-start: 18px;
+ padding-top: 8px;
+}
+
+.destination-list-total {
+ color: #999;
+}
diff --git a/chrome/browser/resources/print_preview/search/destination_list.html b/chrome/browser/resources/print_preview/search/destination_list.html
new file mode 100644
index 0000000..47ae0ed
--- /dev/null
+++ b/chrome/browser/resources/print_preview/search/destination_list.html
@@ -0,0 +1,14 @@
+<div id="destination-list-template" hidden>
+ <header class="destination-list-header">
+ <h4 class="destination-list-title"></h4>
+ <button class="destination-list-action-link link-button"></button>
+ </header>
+ <ul class="destination-list-destination-list-item-container"></ul>
+ <div class="destination-list-no-destinations-message"
+ i18n-content="noDestinationsMessage"></div>
+ <footer class="destination-list-footer" hidden>
+ <button class="destination-list-show-all-button"
+ i18n-content="showAllButtonText"></button>
+ <span class="destination-list-total"></span>
+ </footer>
+</div>
diff --git a/chrome/browser/resources/print_preview/search/destination_list.js b/chrome/browser/resources/print_preview/search/destination_list.js
new file mode 100644
index 0000000..a64cc1e
--- /dev/null
+++ b/chrome/browser/resources/print_preview/search/destination_list.js
@@ -0,0 +1,319 @@
+// Copyright (c) 2012 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', function() {
+ 'use strict';
+
+ /**
+ * Component that displays a list of destinations with a heading, action link,
+ * and "Show All..." button. An event is dispatched when the action link is
+ * activated.
+ * @param {!cr.EventTarget} eventTarget Event target to pass to destination
+ * items for dispatching SELECT events.
+ * @param {string} title Title of the destination list.
+ * @param {number=} opt_maxSize Maximum size of the list. If not specified,
+ * defaults to no max.
+ * @param {string=} opt_actionLinkLabel Optional label of the action link. If
+ * no label is provided, the action link will not be shown.
+ * @constructor
+ * @extends {print_preview.Component}
+ */
+ function DestinationList(
+ eventTarget, title, opt_maxSize, opt_actionLinkLabel) {
+ print_preview.Component.call(this);
+
+ /**
+ * Event target to pass to destination items for dispatching SELECT events.
+ * @type {!cr.EventTarget}
+ * @private
+ */
+ this.eventTarget_ = eventTarget;
+
+ /**
+ * Title of the destination list.
+ * @type {string}
+ * @private
+ */
+ this.title_ = title;
+
+ /**
+ * Maximum size of the destination list.
+ * @type {number}
+ * @private
+ */
+ this.maxSize_ = opt_maxSize || 0;
+ assert(this.maxSize_ <= DestinationList.SHORT_LIST_SIZE_,
+ 'Max size must be less than or equal to ' +
+ DestinationList.SHORT_LIST_SIZE_);
+
+ /**
+ * Label of the action link.
+ * @type {?string}
+ * @private
+ */
+ this.actionLinkLabel_ = opt_actionLinkLabel || null;
+
+ /**
+ * Backing store for the destination list.
+ * @type {!Array.<print_preview.Destination>}
+ * @private
+ */
+ this.destinations_ = [];
+
+ /**
+ * Current query used for filtering.
+ * @type {?string}
+ * @private
+ */
+ this.query_ = null;
+
+ /**
+ * Whether the destination list is fully expanded.
+ * @type {boolean}
+ * @private
+ */
+ this.isShowAll_ = false;
+
+ /**
+ * Message to show when no destinations are available.
+ * @type {HTMLElement}
+ * @private
+ */
+ this.noDestinationsMessageEl_ = null;
+
+ /**
+ * Footer of the list.
+ * @type {HTMLElement}
+ * @private
+ */
+ this.footerEl_ = null;
+
+ /**
+ * Container for the destination list items.
+ * @type {HTMLElement}
+ * @private
+ */
+ this.destinationListItemContainer_ = null;
+ };
+
+ /**
+ * Enumeration of event types dispatched by the destination list.
+ * @enum {string}
+ */
+ DestinationList.EventType = {
+ // Dispatched when the action linked is activated.
+ ACTION_LINK_ACTIVATED: 'print_preview.DestinationList.ACTION_LINK_ACTIVATED'
+ };
+
+ /**
+ * Classes used by the destination list.
+ * @enum {string}
+ * @private
+ */
+ DestinationList.Classes_ = {
+ ACTION_LINK: 'destination-list-action-link',
+ FOOTER: 'destination-list-footer',
+ NO_PRINTERS_MESSAGE: 'destination-list-no-destinations-message',
+ PRINTER_ITEM_CONTAINER: 'destination-list-destination-list-item-container',
+ SHOW_ALL_BUTTON: 'destination-list-show-all-button',
+ TITLE: 'destination-list-title',
+ TOTAL: 'destination-list-total'
+ };
+
+ /**
+ * Maximum number of destinations before showing the "Show All..." button.
+ * @type {number}
+ * @const
+ * @private
+ */
+ DestinationList.SHORT_LIST_SIZE_ = 5;
+
+ DestinationList.prototype = {
+ __proto__: print_preview.Component.prototype,
+
+ /** @param {boolean} isShowAll Whether the show-all button is activated. */
+ setIsShowAll: function(isShowAll) {
+ this.isShowAll_ = isShowAll;
+ this.renderDestinations_();
+ },
+
+ /** @override */
+ createDom: function() {
+ this.setElementInternal(this.cloneTemplateInternal(
+ 'destination-list-template'));
+
+ var titleEl = this.getElement().getElementsByClassName(
+ DestinationList.Classes_.TITLE)[0];
+ titleEl.textContent = this.title_;
+
+ var actionLinkEl = this.getElement().getElementsByClassName(
+ DestinationList.Classes_.ACTION_LINK)[0];
+ if (this.actionLinkLabel_) {
+ actionLinkEl.textContent = this.actionLinkLabel_;
+ } else {
+ setIsVisible(actionLinkEl, false);
+ }
+
+ this.noDestinationsMessageEl_ = this.getElement().getElementsByClassName(
+ DestinationList.Classes_.NO_PRINTERS_MESSAGE)[0];
+ this.footerEl_ = this.getElement().getElementsByClassName(
+ DestinationList.Classes_.FOOTER)[0];
+ this.destinationListItemContainer_ =
+ this.getElement().getElementsByClassName(
+ DestinationList.Classes_.PRINTER_ITEM_CONTAINER)[0];
+ },
+
+ /** @override */
+ enterDocument: function() {
+ print_preview.Component.prototype.enterDocument.call(this);
+ var actionLinkEl = this.getElement().getElementsByClassName(
+ DestinationList.Classes_.ACTION_LINK)[0];
+ var showAllButton = this.getElement().getElementsByClassName(
+ DestinationList.Classes_.SHOW_ALL_BUTTON)[0];
+ this.tracker.add(
+ actionLinkEl, 'click', this.onActionLinkClick_.bind(this));
+ this.tracker.add(
+ showAllButton, 'click', this.setIsShowAll.bind(this, true));
+ },
+
+ /** @override */
+ exitDocument: function() {
+ print_preview.Component.prototype.exitDocument.call(this);
+ this.noDestinationsMessageEl_ = null;
+ this.footerEl_ = null;
+ this.destinationListItemContainer_ = null;
+ },
+
+ /**
+ * Updates the destinations to render in the destination list.
+ * @param {!Array.<print_preview.Destination>} destinations Destinations to
+ * render.
+ */
+ updateDestinations: function(destinations) {
+ this.destinations_ = destinations;
+ this.renderDestinations_();
+ },
+
+ /**
+ * Filters the destination list with the given query.
+ * @param {?string} query Query to filter the list with.
+ */
+ filter: function(query) {
+ this.query_ = query;
+ this.renderDestinations_();
+ },
+
+ /**
+ * @param {string} text Text to set the action link to.
+ * @protected
+ */
+ setActionLinkTextInternal: function(text) {
+ this.actionLinkLabel_ = text;
+ var actionLinkEl = this.getElement().getElementsByClassName(
+ DestinationList.Classes_.ACTION_LINK)[0];
+ actionLinkEl.textContent = this.actionLinkLabel_;
+ },
+
+ /**
+ * Renders all destinations in the list that match the current query. For
+ * each render, all old destination items are first removed.
+ * @private
+ */
+ renderDestinations_: function() {
+ this.removeChildren();
+
+ var filteredDests = [];
+ this.destinations_.forEach(function(destination) {
+ if (!this.query_ || destination.matches(this.query_)) {
+ filteredDests.push(destination);
+ }
+ }, this);
+
+ // TODO(rltoscano): Sort filtered list?
+
+ if (filteredDests.length == 0) {
+ this.renderEmptyList_();
+ } else if (this.maxSize_) {
+ this.renderListWithMaxSize_(filteredDests);
+ } else {
+ this.renderListWithNoMaxSize_(filteredDests);
+ }
+ },
+
+ /**
+ * Renders a "No destinations found" element.
+ * @private
+ */
+ renderEmptyList_: function() {
+ setIsVisible(this.noDestinationsMessageEl_, true);
+ setIsVisible(this.footerEl_, false);
+ },
+
+ /**
+ * Renders the list of destinations up to the maximum size.
+ * @param {!Array.<print_preview.Destination>} filteredDests Filtered list
+ * of print destinations to render.
+ * @private
+ */
+ renderListWithMaxSize_: function(filteredDests) {
+ setIsVisible(this.noDestinationsMessageEl_, false);
+ setIsVisible(this.footerEl_, false);
+ for (var dest, i = 0;
+ i < this.maxSize_ && (dest = filteredDests[i]);
+ i++) {
+ var destListItem = new print_preview.DestinationListItem(
+ this.eventTarget_, dest);
+ this.addChild(destListItem);
+ destListItem.render(this.destinationListItemContainer_);
+ }
+ },
+
+ /**
+ * Renders all destinations in the given list.
+ * @param {!Array.<print_preview.Destination>} filteredDests Filtered list
+ * of print destinations to render.
+ * @private
+ */
+ renderListWithNoMaxSize_: function(filteredDests) {
+ setIsVisible(this.noDestinationsMessageEl_, false);
+ if (filteredDests.length <= DestinationList.SHORT_LIST_SIZE_ ||
+ this.isShowAll_) {
+ filteredDests.forEach(function(dest) {
+ var destListItem = new print_preview.DestinationListItem(
+ this.eventTarget_, dest);
+ this.addChild(destListItem);
+ destListItem.render(this.destinationListItemContainer_);
+ }, this);
+ setIsVisible(this.footerEl_, false);
+ } else {
+ for (var dest, i = 0; i < DestinationList.SHORT_LIST_SIZE_ - 1; i++) {
+ var destListItem = new print_preview.DestinationListItem(
+ this.eventTarget_, filteredDests[i]);
+ this.addChild(destListItem);
+ destListItem.render(this.destinationListItemContainer_);
+ }
+ setIsVisible(this.footerEl_, true);
+ var totalCountEl = this.getElement().getElementsByClassName(
+ DestinationList.Classes_.TOTAL)[0];
+ totalCountEl.textContent =
+ localStrings.getStringF('destinationCount', filteredDests.length);
+ }
+ },
+
+ /**
+ * Called when the action link is clicked. Dispatches an
+ * ACTION_LINK_ACTIVATED event.
+ * @private
+ */
+ onActionLinkClick_: function() {
+ cr.dispatchSimpleEvent(
+ this, DestinationList.EventType.ACTION_LINK_ACTIVATED);
+ }
+ };
+
+ // Export
+ return {
+ DestinationList: DestinationList
+ };
+});
diff --git a/chrome/browser/resources/print_preview/search/destination_list_item.css b/chrome/browser/resources/print_preview/search/destination_list_item.css
new file mode 100644
index 0000000..25d2dc2
--- /dev/null
+++ b/chrome/browser/resources/print_preview/search/destination_list_item.css
@@ -0,0 +1,34 @@
+/* Copyright (c) 2012 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. */
+
+.destination-list-item {
+ -webkit-padding-end: 2px;
+ -webkit-padding-start: 18px;
+ -webkit-transition: background-color 150ms;
+ cursor: default;
+ padding-bottom: 3px;
+ padding-top: 3px;
+}
+
+.destination-list-item:hover {
+ background-color: rgb(228, 236, 247);
+}
+
+.destination-list-item-icon {
+ -webkit-margin-end: 8px;
+ -webkit-transition: opacity 150ms;
+ display: inline-block;
+ height: 24px;
+ opacity: 0.4;
+ vertical-align: middle;
+ width: 24px;
+}
+
+.destination-list-item:hover .destination-list-item-icon {
+ opacity: 1;
+}
+
+.destination-list-item-name {
+ vertical-align: middle;
+}
diff --git a/chrome/browser/resources/print_preview/search/destination_list_item.html b/chrome/browser/resources/print_preview/search/destination_list_item.html
new file mode 100644
index 0000000..972cda9
--- /dev/null
+++ b/chrome/browser/resources/print_preview/search/destination_list_item.html
@@ -0,0 +1,4 @@
+<li id="destination-list-item-template" class="destination-list-item" hidden>
+ <img class="destination-list-item-icon"/>
+ <span class="destination-list-item-name"></span>
+</li>
diff --git a/chrome/browser/resources/print_preview/search/destination_list_item.js b/chrome/browser/resources/print_preview/search/destination_list_item.js
new file mode 100644
index 0000000..81adf91
--- /dev/null
+++ b/chrome/browser/resources/print_preview/search/destination_list_item.js
@@ -0,0 +1,124 @@
+// Copyright (c) 2012 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', function() {
+ 'use strict';
+
+ /**
+ * Component that renders a destination item in a destination list.
+ * @param {!cr.EventTarget} eventTarget Event target to dispatch selection
+ * events to.
+ * @param {!print_preview.Destination} destination Destination data object to
+ * render.
+ * @constructor
+ * @extends {print_preview.Component}
+ */
+ function DestinationListItem(eventTarget, destination) {
+ print_preview.Component.call(this);
+
+ /**
+ * Event target to dispatch selection events to.
+ * @type {!cr.EventTarget}
+ * @private
+ */
+ this.eventTarget_ = eventTarget;
+
+ /**
+ * Destination that the list item renders.
+ * @type {!print_preview.Destination}
+ * @private
+ */
+ this.destination_ = destination;
+ };
+
+ /**
+ * Event types dispatched by the destination list item.
+ * @enum {string}
+ */
+ DestinationListItem.EventType = {
+ // Dispatched when the list item is activated.
+ SELECT: 'print_preview.DestinationListItem.SELECT'
+ };
+
+ /**
+ * CSS classes used by the destination list item.
+ * @enum {string}
+ * @private
+ */
+ DestinationListItem.Classes_ = {
+ ICON: 'destination-list-item-icon',
+ NAME: 'destination-list-item-name'
+ };
+
+ /**
+ * URLs of the various destination list item icons.
+ * @enum {string}
+ * @private
+ */
+ DestinationListItem.Icons_ = {
+ CLOUD: 'images/cloud_printer_32.png',
+ CLOUD_SHARED: 'images/cloud_printer_shared_32.png',
+ LOCAL: 'images/classic_printer_32.png',
+ MOBILE: 'images/mobile_32.png',
+ MOBILE_SHARED: 'images/mobile_shared_32.png',
+ GOOGLE_PROMOTED: 'images/google_promoted_printer_32.png'
+ },
+
+ DestinationListItem.prototype = {
+ __proto__: print_preview.Component.prototype,
+
+ /** @override */
+ createDom: function() {
+ this.setElementInternal(this.cloneTemplateInternal(
+ 'destination-list-item-template'));
+
+ var iconUrl;
+ if (this.destination_.isGooglePromoted) {
+ iconUrl = DestinationListItem.Icons_.GOOGLE_PROMOTED;
+ } else if (this.destination_.isLocal) {
+ iconUrl = DestinationListItem.Icons_.LOCAL;
+ } else if (this.destination_.type ==
+ print_preview.Destination.Type.MOBILE && this.destination_.isOwned) {
+ iconUrl = DestinationListItem.Icons_.MOBILE;
+ } else if (this.destination_.type ==
+ print_preview.Destination.Type.MOBILE && !this.destination_.isOwned) {
+ iconUrl = DestinationListItem.Icons_.MOBILE_SHARED;
+ } else if (this.destination_.type ==
+ print_preview.Destination.Type.GOOGLE && this.destination_.isOwned) {
+ iconUrl = DestinationListItem.Icons_.CLOUD;
+ } else {
+ iconUrl = DestinationListItem.Icons_.CLOUD_SHARED;
+ }
+
+ var iconImg = this.getElement().getElementsByClassName(
+ print_preview.DestinationListItem.Classes_.ICON)[0];
+ iconImg.src = iconUrl;
+ var nameEl = this.getElement().getElementsByClassName(
+ DestinationListItem.Classes_.NAME)[0];
+ nameEl.textContent = this.destination_.displayName;
+ },
+
+ /** @override */
+ enterDocument: function() {
+ print_preview.Component.prototype.enterDocument.call(this);
+ this.tracker.add(this.getElement(), 'click', this.onActivate_.bind(this));
+ },
+
+ /**
+ * Called when the destination item is activated. Dispatches a SELECT event
+ * on the given event target.
+ * @private
+ */
+ onActivate_: function() {
+ var selectEvt = new cr.Event(DestinationListItem.EventType.SELECT);
+ selectEvt.destination = this.destination_;
+ this.eventTarget_.dispatchEvent(selectEvt);
+ }
+ };
+
+ // Export
+ return {
+ DestinationListItem: DestinationListItem
+ };
+});
diff --git a/chrome/browser/resources/print_preview/search/destination_search.css b/chrome/browser/resources/print_preview/search/destination_search.css
new file mode 100644
index 0000000..2a93e68
--- /dev/null
+++ b/chrome/browser/resources/print_preview/search/destination_search.css
@@ -0,0 +1,91 @@
+/* Copyright (c) 2012 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. */
+
+.destination-search {
+ z-index: 3;
+}
+
+.destination-search.transparent {
+ opacity: 0;
+ pointer-events: none;
+}
+
+.destination-search-page {
+ height: 640px;
+ width: 700px;
+}
+
+.destination-search-user-info {
+ -webkit-user-select: none;
+ position: absolute;
+ right: 80px;
+ top: 16px;
+ white-space: nowrap;
+}
+
+[dir='rtl'] .destination-search-user-info {
+ left: 80px;
+ right: auto;
+}
+
+.destination-search-search-box-container {
+ -webkit-user-select: none;
+ margin: 14px;
+}
+
+.destination-search-lists {
+ -webkit-box-flex: 1;
+ overflow-y: auto;
+}
+
+.destination-search-recent-list,
+.destination-search-local-list,
+.destination-search-cloud-list {
+ -webkit-user-select: none;
+ padding: 0 14px 18px;
+}
+
+.destination-search-cloudprint-promo {
+ -webkit-padding-end: 44px;
+ -webkit-padding-start: 12px;
+ -webkit-user-select: none;
+ background-color: rgb(249, 237, 190);
+ padding-bottom: 12px;
+ padding-top: 12px;
+ position: relative;
+}
+
+.destination-search-cloudprint-promo > * {
+ vertical-align: middle;
+}
+
+.destination-search-sign-in.link-button {
+ padding: inherit;
+}
+
+.destination-search-cloud-icon {
+ -webkit-margin-end: 4px;
+ display: inline-block;
+ height: 24px;
+ width: 24px;
+}
+
+.destination-search-cloudprint-promo-close-button {
+ background-image: url(chrome://resources/images/x.png);
+ height: 24px;
+ margin-top: -9px;
+ position: absolute;
+ right: 10px;
+ top: 50%;
+ width: 24px;
+}
+
+[dir='rtl'] .destination-search-cloudprint-promo-close-button {
+ left: 10px;
+ right: auto;
+}
+
+.destination-search-cloudprint-promo-close-button:hover {
+ background-image: url(chrome://resources/images/x-hover.png);
+}
diff --git a/chrome/browser/resources/print_preview/search/destination_search.html b/chrome/browser/resources/print_preview/search/destination_search.html
new file mode 100644
index 0000000..0d508ec
--- /dev/null
+++ b/chrome/browser/resources/print_preview/search/destination_search.html
@@ -0,0 +1,25 @@
+<div id="destination-search"
+ class="destination-search overlay transparent">
+ <div class="destination-search-page page">
+ <h1 class="destination-search-title"
+ i18n-content="destinationSearchTitle"></h1>
+ <span class="destination-search-user-info" hidden>
+ <span i18n-content="signedInAsPrefix"></span>
+ <span class="destination-search-user-email"></span>
+ </span>
+ <div class="destination-search-close-button close-button"></div>
+ <div class="destination-search-search-box-container">
+ <include src="search_box.html"/>
+ </div>
+ <div class="destination-search-lists">
+ <div class="destination-search-recent-list"></div>
+ <div class="destination-search-local-list"></div>
+ <div class="destination-search-cloud-list" hidden></div>
+ </div>
+ <div class="destination-search-cloudprint-promo" hidden>
+ <div class="destination-search-cloudprint-promo-close-button"></div>
+ <img src="../images/cloud.png" class="destination-search-cloud-icon"/>
+ <span class="destination-search-cloudprint-promo-text"></span>
+ </div>
+ </div>
+</div>
diff --git a/chrome/browser/resources/print_preview/search/destination_search.js b/chrome/browser/resources/print_preview/search/destination_search.js
new file mode 100644
index 0000000..05c2cee
--- /dev/null
+++ b/chrome/browser/resources/print_preview/search/destination_search.js
@@ -0,0 +1,433 @@
+// Copyright (c) 2012 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', function() {
+ 'use strict';
+
+ /**
+ * Component used for searching for a print destination.
+ * This is a modal dialog that allows the user to search and select a
+ * destination to print to. When a destination is selected, it is written to
+ * the destination store.
+ * @param {!print_preview.DestinationStore} destinationStore Data store
+ * containing the destinations to search through.
+ * @param {!print_preview.UserInfo} userInfo Event target that contains
+ * information about the logged in user.
+ * @constructor
+ * @extends {print_preview.Component}
+ */
+ function DestinationSearch(destinationStore, userInfo) {
+ print_preview.Component.call(this);
+
+ /**
+ * Data store containing the destinations to search through.
+ * @type {!print_preview.DestinationStore}
+ * @private
+ */
+ this.destinationStore_ = destinationStore;
+
+ /**
+ * Event target that contains information about the logged in user.
+ * @type {!print_preview.UserInfo}
+ * @private
+ */
+ this.userInfo_ = userInfo;
+
+ /**
+ * Search box used to search through the destination lists.
+ * @type {!print_preview.SearchBox}
+ * @private
+ */
+ this.searchBox_ = new print_preview.SearchBox();
+ this.addChild(this.searchBox_);
+
+ /**
+ * Destination list containing recent destinations.
+ * @type {!print_preview.DestinationList}
+ * @private
+ */
+ this.recentList_ = new print_preview.DestinationList(
+ this,
+ localStrings.getString('recentDestinationsTitle'),
+ 3 /*opt_maxSize*/);
+ this.addChild(this.recentList_);
+
+ /**
+ * Destination list containing local destinations.
+ * @type {!print_preview.DestinationList}
+ * @private
+ */
+ this.localList_ = new print_preview.DestinationList(
+ this,
+ localStrings.getString('localDestinationsTitle'),
+ 0 /*opt_maxSize*/,
+ localStrings.getString('manage'));
+ this.addChild(this.localList_);
+
+ /**
+ * Destination list containing cloud destinations.
+ * @type {!print_preview.DestinationList}
+ * @private
+ */
+ this.cloudList_ = new print_preview.CloudDestinationList(this);
+ this.addChild(this.cloudList_);
+
+ /**
+ * Page element of the overlay.
+ * @type {HTMLElement}
+ * @private
+ */
+ this.pageEl_ = null;
+ };
+
+ /**
+ * Event types dispatched by the component.
+ * @enum {string}
+ */
+ DestinationSearch.EventType = {
+ // Dispatched when the user requests to manage their cloud destinations.
+ MANAGE_CLOUD_DESTINATIONS:
+ 'print_preview.DestinationSearch.MANAGE_CLOUD_DESTINATIONS',
+
+ // Dispatched when the user requests to manage their local destinations.
+ MANAGE_LOCAL_DESTINATIONS:
+ 'print_preview.DestinationSearch.MANAGE_LOCAL_DESTINATIONS',
+
+ // Dispatched when the user requests to sign-in to their Google account.
+ SIGN_IN: 'print_preview.DestinationSearch.SIGN_IN'
+ },
+
+ /**
+ * CSS classes used by the component.
+ * @enum {string}
+ * @private
+ */
+ DestinationSearch.Classes_ = {
+ CLOSE_BUTTON: 'destination-search-close-button',
+ CLOUDPRINT_PROMO: 'destination-search-cloudprint-promo',
+ CLOUDPRINT_PROMO_CLOSE_BUTTON:
+ 'destination-search-cloudprint-promo-close-button',
+ CLOUD_LIST: 'destination-search-cloud-list',
+ LOCAL_LIST: 'destination-search-local-list',
+ PAGE: 'destination-search-page',
+ PROMO_TEXT: 'destination-search-cloudprint-promo-text',
+ PULSE: 'pulse',
+ RECENT_LIST: 'destination-search-recent-list',
+ SEARCH_BOX_CONTAINER: 'destination-search-search-box-container',
+ SIGN_IN: 'destination-search-sign-in',
+ TRANSPARENT: 'transparent',
+ USER_EMAIL: 'destination-search-user-email',
+ USER_INFO: 'destination-search-user-info'
+ };
+
+ DestinationSearch.prototype = {
+ __proto__: print_preview.Component.prototype,
+
+ /** @return {boolean} Whether the component is visible. */
+ getIsVisible: function() {
+ return !this.getElement().classList.contains(
+ DestinationSearch.Classes_.TRANSPARENT);
+ },
+
+ /** @param {boolean} isVisible Whether the component is visible. */
+ setIsVisible: function(isVisible) {
+ if (isVisible) {
+ this.searchBox_.focus();
+ this.getElement().classList.remove(
+ DestinationSearch.Classes_.TRANSPARENT);
+ } else {
+ this.getElement().classList.add(DestinationSearch.Classes_.TRANSPARENT);
+ // Collapse all destination lists
+ this.localList_.setIsShowAll(false);
+ this.cloudList_.setIsShowAll(false);
+ this.searchBox_.setQuery('');
+ this.filterLists_(null);
+ }
+ },
+
+ /** @param {string} email Email of the logged-in user. */
+ setCloudPrintEmail: function(email) {
+ var userEmailEl = this.getElement().getElementsByClassName(
+ DestinationSearch.Classes_.USER_EMAIL)[0];
+ userEmailEl.textContent = email;
+ var userInfoEl = this.getElement().getElementsByClassName(
+ DestinationSearch.Classes_.USER_INFO)[0];
+ setIsVisible(userInfoEl, true);
+ var cloudListEl = this.getElement().getElementsByClassName(
+ DestinationSearch.Classes_.CLOUD_LIST)[0];
+ setIsVisible(cloudListEl, true);
+ var promoEl = this.getElement().getElementsByClassName(
+ DestinationSearch.Classes_.CLOUDPRINT_PROMO)[0];
+ setIsVisible(promoEl, false);
+ },
+
+ /** Shows the Google Cloud Print promotion banner. */
+ showCloudPrintPromo: function() {
+ var promoEl = this.getElement().getElementsByClassName(
+ DestinationSearch.Classes_.CLOUDPRINT_PROMO)[0];
+ setIsVisible(promoEl, true);
+ },
+
+ /** @override */
+ enterDocument: function() {
+ print_preview.Component.prototype.enterDocument.call(this);
+ var closeButtonEl = this.getElement().getElementsByClassName(
+ DestinationSearch.Classes_.CLOSE_BUTTON)[0];
+ var signInButton = this.getElement().getElementsByClassName(
+ DestinationSearch.Classes_.SIGN_IN)[0];
+ var cloudprintPromoCloseButton = this.getElement().getElementsByClassName(
+ DestinationSearch.Classes_.CLOUDPRINT_PROMO_CLOSE_BUTTON)[0];
+
+ this.tracker.add(
+ closeButtonEl, 'click', this.onCloseClick_.bind(this));
+
+ var promoTextEl = this.getElement().getElementsByClassName(
+ DestinationSearch.Classes_.PROMO_TEXT)[0];
+ var signInEl = promoTextEl.getElementsByClassName(
+ DestinationSearch.Classes_.SIGN_IN)[0];
+ this.tracker.add(
+ signInEl, 'click', this.onSignInActivated_.bind(this));
+
+ this.tracker.add(
+ cloudprintPromoCloseButton,
+ 'click',
+ this.onCloudprintPromoCloseButtonClick_.bind(this));
+ this.tracker.add(
+ this.searchBox_,
+ print_preview.SearchBox.EventType.SEARCH,
+ this.onSearch_.bind(this));
+ this.tracker.add(
+ this,
+ print_preview.DestinationListItem.EventType.SELECT,
+ this.onDestinationSelect_.bind(this));
+
+ this.tracker.add(
+ this.destinationStore_,
+ print_preview.DestinationStore.EventType.DESTINATIONS_INSERTED,
+ this.onDestinationsInserted_.bind(this));
+ this.tracker.add(
+ this.destinationStore_,
+ print_preview.DestinationStore.EventType.DESTINATION_SELECT,
+ this.onDestinationStoreSelect_.bind(this));
+
+ this.tracker.add(
+ this.localList_,
+ print_preview.DestinationList.EventType.ACTION_LINK_ACTIVATED,
+ this.onManageLocalDestinationsActivated_.bind(this));
+ this.tracker.add(
+ this.cloudList_,
+ print_preview.DestinationList.EventType.ACTION_LINK_ACTIVATED,
+ this.onManageCloudDestinationsActivated_.bind(this));
+
+ this.tracker.add(
+ this.getElement(), 'click', this.onClick_.bind(this));
+ this.tracker.add(
+ this.pageEl_, 'webkitAnimationEnd', this.onAnimationEnd_.bind(this));
+
+ this.tracker.add(
+ this.userInfo_,
+ print_preview.UserInfo.EventType.EMAIL_CHANGE,
+ this.onEmailChange_.bind(this));
+ },
+
+ /** @override */
+ exitDocument: function() {
+ print_preview.Component.prototype.exitDocument.call(this);
+ this.pageEl_ = null;
+ },
+
+ /** @override */
+ decorateInternal: function() {
+ this.searchBox_.decorate($('search-box'));
+
+ var recentListEl = this.getElement().getElementsByClassName(
+ DestinationSearch.Classes_.RECENT_LIST)[0];
+ this.recentList_.render(recentListEl);
+
+ var localListEl = this.getElement().getElementsByClassName(
+ DestinationSearch.Classes_.LOCAL_LIST)[0];
+ this.localList_.render(localListEl);
+
+ var cloudListEl = this.getElement().getElementsByClassName(
+ DestinationSearch.Classes_.CLOUD_LIST)[0];
+ this.cloudList_.render(cloudListEl);
+
+ this.pageEl_ = this.getElement().getElementsByClassName(
+ DestinationSearch.Classes_.PAGE)[0];
+
+ var promoTextEl = this.getElement().getElementsByClassName(
+ DestinationSearch.Classes_.PROMO_TEXT)[0];
+ promoTextEl.innerHTML = localStrings.getStringF(
+ 'cloudPrintPromotion',
+ '<span class="destination-search-sign-in link-button">',
+ '</span>');
+ },
+
+ /**
+ * Filters all destination lists with the given query.
+ * @param {?string} query Query to filter destination lists by.
+ * @private
+ */
+ filterLists_: function(query) {
+ this.recentList_.filter(query);
+ this.localList_.filter(query);
+ this.cloudList_.filter(query);
+ },
+
+ /**
+ * Resets the search query.
+ * @private
+ */
+ resetSearch_: function() {
+ this.searchBox_.setQuery(null);
+ this.filterLists_(null);
+ },
+
+ /**
+ * Called when a destination search should be executed. Filters the
+ * destination lists with the given query.
+ * @param {cr.Event} evt Contains the search query.
+ * @private
+ */
+ onSearch_: function(evt) {
+ this.filterLists_(evt.query);
+ },
+
+ /**
+ * Called when the close button is clicked. Hides the search widget.
+ * @private
+ */
+ onCloseClick_: function() {
+ this.setIsVisible(false);
+ this.resetSearch_();
+ },
+
+ /**
+ * Called when a destination is selected. Clears the search and hides the
+ * widget.
+ * @param {cr.Event} evt Contains the selected destination.
+ * @private
+ */
+ onDestinationSelect_: function(evt) {
+ this.setIsVisible(false);
+ this.resetSearch_();
+ this.destinationStore_.selectDestination(evt.destination);
+ },
+
+ /**
+ * Called when destinations are added to the destination store. Refreshes UI
+ * with new destinations.
+ * @private
+ */
+ onDestinationsInserted_: function() {
+ var recentDestinations = [];
+ var localDestinations = [];
+ var cloudDestinations = [];
+ this.destinationStore_.destinations.forEach(function(destination) {
+ if (destination.isRecent) {
+ recentDestinations.push(destination);
+ }
+ if (destination.isLocal) {
+ localDestinations.push(destination);
+ } else {
+ cloudDestinations.push(destination);
+ }
+ });
+ this.recentList_.updateDestinations(recentDestinations);
+ this.localList_.updateDestinations(localDestinations);
+ this.cloudList_.updateDestinations(cloudDestinations);
+ },
+
+ /**
+ * Called when a destination is selected. Selected destination are marked as
+ * recent, so we have to update our recent destinations list.
+ * @private
+ */
+ onDestinationStoreSelect_: function() {
+ var destinations = this.destinationStore_.destinations;
+ var recentDestinations = [];
+ destinations.forEach(function(destination) {
+ if (destination.isRecent) {
+ recentDestinations.push(destination);
+ }
+ });
+ this.recentList_.updateDestinations(recentDestinations);
+ },
+
+ /**
+ * Called when the manage cloud printers action is activated.
+ * @private
+ */
+ onManageCloudDestinationsActivated_: function() {
+ cr.dispatchSimpleEvent(
+ this,
+ print_preview.DestinationSearch.EventType.MANAGE_CLOUD_DESTINATIONS);
+ },
+
+ /**
+ * Called when the manage local printers action is activated.
+ * @private
+ */
+ onManageLocalDestinationsActivated_: function() {
+ cr.dispatchSimpleEvent(
+ this,
+ print_preview.DestinationSearch.EventType.MANAGE_LOCAL_DESTINATIONS);
+ },
+
+ /**
+ * Called when the "Sign in" link on the Google Cloud Print promo is
+ * activated.
+ * @private
+ */
+ onSignInActivated_: function() {
+ cr.dispatchSimpleEvent(this, DestinationSearch.EventType.SIGN_IN);
+ },
+
+ /**
+ * Called when the close button on the cloud print promo is clicked. Hides
+ * the promo.
+ * @private
+ */
+ onCloudprintPromoCloseButtonClick_: function() {
+ var promoEl = this.getElement().getElementsByClassName(
+ DestinationSearch.Classes_.CLOUDPRINT_PROMO)[0];
+ setIsVisible(promoEl, false);
+ },
+
+ /**
+ * Called when the overlay is clicked. Pulses the page.
+ * @param {Event} event Contains the element that was clicked.
+ * @private
+ */
+ onClick_: function(event) {
+ if (event.target == this.getElement()) {
+ this.pageEl_.classList.add(DestinationSearch.Classes_.PULSE);
+ }
+ },
+
+ /**
+ * Called when an animation ends on the page.
+ * @private
+ */
+ onAnimationEnd_: function() {
+ this.pageEl_.classList.remove(DestinationSearch.Classes_.PULSE);
+ },
+
+ /**
+ * Called when the user's email field has changed. Updates the UI.
+ * @private
+ */
+ onEmailChange_: function() {
+ var userEmail = this.userInfo_.getUserEmail();
+ if (userEmail) {
+ this.setCloudPrintEmail(userEmail);
+ }
+ }
+ };
+
+ // Export
+ return {
+ DestinationSearch: DestinationSearch
+ };
+});
diff --git a/chrome/browser/resources/print_preview/search/search_box.css b/chrome/browser/resources/print_preview/search/search_box.css
new file mode 100644
index 0000000..bc282f7
--- /dev/null
+++ b/chrome/browser/resources/print_preview/search/search_box.css
@@ -0,0 +1,24 @@
+/* Copyright (c) 2012 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. */
+
+.search-box {
+ -webkit-user-select: none;
+ position: relative;
+}
+
+.search-box-icon {
+ -webkit-user-select: none;
+ display: inline-block;
+ height: 12px;
+ left: 8px;
+ position: absolute;
+ right: 8px;
+ top: 6px;
+ width: 12px;
+}
+
+.search-box-input {
+ text-indent: 24px;
+ width: 100%;
+}
diff --git a/chrome/browser/resources/print_preview/search/search_box.html b/chrome/browser/resources/print_preview/search/search_box.html
new file mode 100644
index 0000000..cb4605a
--- /dev/null
+++ b/chrome/browser/resources/print_preview/search/search_box.html
@@ -0,0 +1,5 @@
+<div id="search-box" class="search-box">
+ <img src="../images/search.png" class="search-box-icon"/>
+ <input type="text" class="search-box-input"
+ i18n-values="placeholder:searchBoxPlaceholder"/>
+</div>
diff --git a/chrome/browser/resources/print_preview/search/search_box.js b/chrome/browser/resources/print_preview/search/search_box.js
new file mode 100644
index 0000000..a0b9f30
--- /dev/null
+++ b/chrome/browser/resources/print_preview/search/search_box.js
@@ -0,0 +1,124 @@
+// Copyright (c) 2012 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', function() {
+ 'use strict';
+
+ /**
+ * Component that renders a search box for searching through destinations.
+ * @constructor
+ * @extends {print_preview.Component}
+ */
+ function SearchBox() {
+ print_preview.Component.call(this);
+
+ /**
+ * Timeout used to control incremental search.
+ * @type {?number}
+ * @private
+ */
+ this.timeout_ = null;
+
+ /**
+ * Input box where the query is entered.
+ * @type {HTMLInputElement}
+ * @private
+ */
+ this.input_ = null;
+ };
+
+ /**
+ * Enumeration of event types dispatched from the search box.
+ * @enum {string}
+ */
+ SearchBox.EventType = {
+ SEARCH: 'print_preview.SearchBox.SEARCH'
+ };
+
+ /**
+ * CSS classes used by the search box.
+ * @enum {string}
+ * @private
+ */
+ SearchBox.Classes_ = {
+ INPUT: 'search-box-input'
+ };
+
+ /**
+ * Delay in milliseconds before dispatching a SEARCH event.
+ * @type {number}
+ * @const
+ * @private
+ */
+ SearchBox.SEARCH_DELAY_ = 150;
+
+ SearchBox.prototype = {
+ __proto__: print_preview.Component.prototype,
+
+ /** @param {string} New query to set the search box's query to. */
+ setQuery: function(query) {
+ query = query || '';
+ this.input_.value = query.trim();
+ },
+
+ /** Sets the input element of the search box in focus. */
+ focus: function() {
+ this.input_.focus();
+ },
+
+ /** @override */
+ enterDocument: function() {
+ print_preview.Component.prototype.enterDocument.call(this);
+ this.tracker.add(this.input_, 'keydown', this.onInputKeyDown_.bind(this));
+ },
+
+ /** @override */
+ exitDocument: function() {
+ print_preview.Component.prototype.exitDocument.call(this);
+ this.input_ = null;
+ },
+
+ /** @override */
+ decorateInternal: function() {
+ this.input_ = this.getElement().getElementsByClassName(
+ SearchBox.Classes_.INPUT)[0];
+ },
+
+ /**
+ * @return {string} The current query of the search box.
+ * @private
+ */
+ getQuery_: function() {
+ return this.input_.value.trim();
+ },
+
+ /**
+ * Dispatches a SEARCH event.
+ * @private
+ */
+ dispatchSearchEvent_: function() {
+ this.timeout_ = null;
+ var searchEvent = new cr.Event(SearchBox.EventType.SEARCH);
+ searchEvent.query = this.getQuery_();
+ this.dispatchEvent(searchEvent);
+ },
+
+ /**
+ * Called when the input element's value changes. Dispatches a search event.
+ * @private
+ */
+ onInputKeyDown_: function() {
+ if (this.timeout_) {
+ clearTimeout(this.timeout_);
+ }
+ this.timeout_ = setTimeout(
+ this.dispatchSearchEvent_.bind(this), SearchBox.SEARCH_DELAY_);
+ }
+ };
+
+ // Export
+ return {
+ SearchBox: SearchBox
+ };
+});
diff --git a/chrome/browser/resources/print_preview/settings/copies_settings.css b/chrome/browser/resources/print_preview/settings/copies_settings.css
index 129943f..a00ee9e9 100644
--- a/chrome/browser/resources/print_preview/settings/copies_settings.css
+++ b/chrome/browser/resources/print_preview/settings/copies_settings.css
@@ -1,7 +1,6 @@
/* Copyright (c) 2012 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.
- */
+ * found in the LICENSE file. */
#copies-settings .copies-settings-copies {
position: relative;
diff --git a/chrome/browser/resources/print_preview/settings/copies_settings.js b/chrome/browser/resources/print_preview/settings/copies_settings.js
index f2baecd..0f5f94cd 100644
--- a/chrome/browser/resources/print_preview/settings/copies_settings.js
+++ b/chrome/browser/resources/print_preview/settings/copies_settings.js
@@ -24,7 +24,7 @@ cr.define('print_preview', function() {
/**
* Timeout used to delay processing of the copies input.
- * @type {Object}
+ * @type {?number}
* @private
*/
this.textfieldTimeout_ = null;
diff --git a/chrome/browser/resources/print_preview/settings/destination_settings.css b/chrome/browser/resources/print_preview/settings/destination_settings.css
new file mode 100644
index 0000000..9d732d8
--- /dev/null
+++ b/chrome/browser/resources/print_preview/settings/destination_settings.css
@@ -0,0 +1,61 @@
+/* Copyright (c) 2012 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. */
+
+.destination-settings-box {
+ display: -webkit-box;
+}
+
+.destination-settings-icon {
+ -webkit-margin-end: 8px;
+ height: 32px;
+ opacity: 0.4;
+ width: 32px;
+}
+
+.destination-settings-icon-local {
+ background-image: url(images/classic_printer_32.png);
+}
+
+.destination-settings-icon-cloud {
+ background-image: url(images/cloud_printer_32.png);
+}
+
+.destination-settings-icon-cloud-shared {
+ background-image: url(images/cloud_printer_shared_32.png);
+}
+
+.destination-settings-icon-google-promoted {
+ background-image: url(images/google_promoted_printer_32.png);
+}
+
+.destination-settings-icon-mobile {
+ background-image: url(images/mobile_32.png);
+}
+
+.destination-settings-icon-mobile-shared {
+ background-image: url(images/mobile_shared_32.png);
+}
+
+.destination-settings-info {
+ -webkit-box-flex: 1;
+ position: relative;
+ white-space: nowrap;
+}
+
+.destination-settings-name {
+ font-size: 110%;
+ overflow: hidden;
+ position: absolute;
+ text-overflow: ellipsis;
+ width: 100%;
+}
+
+.destination-settings-location {
+ color: gray;
+ overflow: hidden;
+ position: absolute;
+ text-overflow: ellipsis;
+ top: 1.5em;
+ width: 100%;
+}
diff --git a/chrome/browser/resources/print_preview/settings/destination_settings.html b/chrome/browser/resources/print_preview/settings/destination_settings.html
index 55a9e47..9e65ad7 100644
--- a/chrome/browser/resources/print_preview/settings/destination_settings.html
+++ b/chrome/browser/resources/print_preview/settings/destination_settings.html
@@ -1,6 +1,14 @@
<div id="destination-settings" class="two-column visible">
<h1 i18n-content="destinationLabel"></h1>
<div class="right-column">
- <select class="destination-settings-select"></select>
+ <div class="destination-settings-box">
+ <div class="destination-settings-icon"></div>
+ <div class="destination-settings-info">
+ <div class="destination-settings-name"></div>
+ <div class="destination-settings-location"></div>
+ </div>
+ </div>
+ <button class="destination-settings-change-button"
+ i18n-content="changeDestination"></button>
</div>
</div>
diff --git a/chrome/browser/resources/print_preview/settings/destination_settings.js b/chrome/browser/resources/print_preview/settings/destination_settings.js
index 4713d0a..e93fc2a 100644
--- a/chrome/browser/resources/print_preview/settings/destination_settings.js
+++ b/chrome/browser/resources/print_preview/settings/destination_settings.js
@@ -25,6 +25,13 @@ cr.define('print_preview', function() {
* @private
*/
this.destinationStore_ = destinationStore;
+
+ /**
+ * Current CSS class of the destination icon.
+ * @type {?DestinationSettings.Classes_}
+ * @private
+ */
+ this.iconClass_ = null;
};
/**
@@ -32,8 +39,8 @@ cr.define('print_preview', function() {
* @enum {string}
*/
DestinationSettings.EventType = {
- MANAGE_PRINTERS_SELECT:
- 'print_preview.DestinationSettings.MANAGE_PRINTERS_SELECT'
+ CHANGE_BUTTON_ACTIVATE:
+ 'print_preview.DestinationSettings.CHANGE_BUTTON_ACTIVATE'
};
/**
@@ -42,157 +49,91 @@ cr.define('print_preview', function() {
* @private
*/
DestinationSettings.Classes_ = {
- SELECT: 'destination-settings-select'
+ CHANGE_BUTTON: 'destination-settings-change-button',
+ ICON: 'destination-settings-icon',
+ ICON_CLOUD: 'destination-settings-icon-cloud',
+ ICON_CLOUD_SHARED: 'destination-settings-icon-cloud-shared',
+ ICON_GOOGLE_PROMOTED: 'destination-settings-icon-google-promoted',
+ ICON_LOCAL: 'destination-settings-icon-local',
+ ICON_MOBILE: 'destination-settings-icon-mobile',
+ ICON_MOBILE_SHARED: 'destination-settings-icon-mobile-shared',
+ LOCATION: 'destination-settings-location',
+ NAME: 'destination-settings-name'
};
- /**
- * Option value of the "Manage Printers..." select option.
- * @type {string}
- * @const
- * @private
- */
- DestinationSettings.MANAGE_ID_ = '__manage';
-
DestinationSettings.prototype = {
__proto__: print_preview.Component.prototype,
+ /** @param {boolean} Whether the component is enabled. */
set isEnabled(isEnabled) {
- this.select_.disabled = !isEnabled;
+ var changeButton = this.getElement().getElementsByClassName(
+ DestinationSettings.Classes_.CHANGE_BUTTON)[0];
+ changeButton.disabled = !isEnabled;
},
/** @override */
enterDocument: function() {
print_preview.Component.prototype.enterDocument.call(this);
+ var changeButton = this.getElement().getElementsByClassName(
+ DestinationSettings.Classes_.CHANGE_BUTTON)[0];
this.tracker.add(
- this.select_, 'change', this.onSelectChange_.bind(this));
+ changeButton, 'click', this.onChangeButtonClick_.bind(this));
this.tracker.add(
this.destinationStore_,
print_preview.DestinationStore.EventType.DESTINATION_SELECT,
this.onDestinationSelect_.bind(this));
- this.tracker.add(
- this.destinationStore_,
- print_preview.DestinationStore.EventType.DESTINATIONS_INSERTED,
- this.onDestinationsInserted_.bind(this));
- },
-
- get select_() {
- return this.getElement().getElementsByClassName(
- DestinationSettings.Classes_.SELECT)[0];
- },
-
- renderDestinations_: function() {
- var select = this.select_;
- select.innerHTML = '';
- var destinations = this.destinationStore_.destinations;
- var selectedDestination = this.destinationStore_.selectedDestination;
- var saveToPdfDest = null;
- var printWithCloudPrintDest = null;
- for (var dest, i = 0; dest = destinations[i]; i++) {
- if (dest.id == print_preview.Destination.GooglePromotedId.SAVE_AS_PDF) {
- saveToPdfDest = dest;
- continue;
- }
- if (dest.isPrintWithCloudPrint) {
- printWithCloudPrintDest = dest;
- continue;
- }
- var optionEl = document.createElement('option');
- optionEl.value = dest.id;
- optionEl.selected =
- selectedDestination && selectedDestination.id == dest.id;
- optionEl.textContent = dest.displayName;
- select.appendChild(optionEl);
- }
-
- // Add special destinations.
- if (saveToPdfDest) {
- select.appendChild(this.createSeparatorOption_());
- var printToPdfOptionEl = document.createElement('option');
- printToPdfOptionEl.value = saveToPdfDest.id;
- printToPdfOptionEl.selected =
- selectedDestination && selectedDestination.id == saveToPdfDest.id;
- printToPdfOptionEl.textContent = saveToPdfDest.displayName;
- select.appendChild(printToPdfOptionEl);
- }
- if (printWithCloudPrintDest) {
- select.appendChild(this.createSeparatorOption_());
- var printWithCloudPrintOptionEl = document.createElement('option');
- printWithCloudPrintOptionEl.value = printWithCloudPrintDest.id;
- printWithCloudPrintOptionEl.selected =
- selectedDestination &&
- selectedDestination.id == printWithCloudPrintDest.id;
- printWithCloudPrintOptionEl.textContent =
- printWithCloudPrintDest.displayName;
- select.appendChild(printWithCloudPrintOptionEl);
- }
- select.appendChild(this.createSeparatorOption_());
- var manageOptionEl = document.createElement('option');
- manageOptionEl.value = DestinationSettings.MANAGE_ID_;
- manageOptionEl.textContent = localStrings.getString('managePrinters');
- select.appendChild(manageOptionEl);
- },
-
- createSeparatorOption_: function() {
- var sep = document.createElement('option');
- sep.disabled = true;
- sep.role = 'separator';
- return sep;
- },
-
- /**
- * Called when a destination is selected. Selects the corresponding option.
- * @private
- */
- onDestinationSelect_: function() {
- var select = this.select_;
- if (select.options.length > 0) {
- select.options[select.selectedIndex].selected = false;
- }
- var selectedDestination = this.destinationStore_.selectedDestination;
- for (var option, i = 0; option = select.options[i]; i++) {
- if (selectedDestination.id == option.value) {
- option.selected = true;
- break;
- }
- }
},
/**
- * Called when destinations are inserted into the destination store. Updates
- * the select element.
+ * Called when the "Change" button is clicked. Dispatches the
+ * CHANGE_BUTTON_ACTIVATE event.
* @private
*/
- onDestinationsInserted_: function() {
- this.renderDestinations_();
+ onChangeButtonClick_: function() {
+ cr.dispatchSimpleEvent(
+ this, DestinationSettings.EventType.CHANGE_BUTTON_ACTIVATE);
},
/**
- * Called when the select element changes options. Selects the corresponding
- * print destination.
+ * Called when the destination selection has changed. Updates UI elements.
* @private
*/
- onSelectChange_: function() {
- var select = this.select_;
- var selectedDestId = select.options[select.selectedIndex].value;
-
- if (selectedDestId == DestinationSettings.MANAGE_ID_) {
- cr.dispatchSimpleEvent(
- this, DestinationSettings.EventType.MANAGE_PRINTERS_SELECT);
- // Select first in the list.
- this.destinationStore_.selectDestination(
- this.destinationStore_.destinations[0]);
+ onDestinationSelect_: function() {
+ var destination = this.destinationStore_.selectedDestination;
+ var nameEl = this.getElement().getElementsByClassName(
+ DestinationSettings.Classes_.NAME)[0];
+ nameEl.textContent = destination.displayName;
+
+ var iconEl = this.getElement().getElementsByClassName(
+ DestinationSettings.Classes_.ICON)[0];
+ if (this.iconClass_) {
+ iconEl.classList.remove(this.iconClass_);
+ }
+ if (destination.isGooglePromoted) {
+ this.iconClass_ = DestinationSettings.Classes_.ICON_GOOGLE_PROMOTED;
+ } else if (destination.isLocal) {
+ this.iconClass_ = DestinationSettings.Classes_.ICON_LOCAL;
+ } else if (destination.type ==
+ print_preview.Destination.Type.MOBILE && destination.isOwned) {
+ this.iconClass_ = DestinationSettings.Classes_.ICON_MOBILE;
+ } else if (destination.type ==
+ print_preview.Destination.Type.MOBILE && !destination.isOwned) {
+ this.iconClass_ = DestinationSettings.Classes_.ICON_MOBILE_SHARED;
+ } else if (destination.type ==
+ print_preview.Destination.Type.GOOGLE && destination.isOwned) {
+ this.iconClass_ = DestinationSettings.Classes_.ICON_CLOUD;
} else {
- var destinations = this.destinationStore_.destinations;
- for (var dest, i = 0; dest = destinations[i]; i++) {
- if (dest.id == selectedDestId) {
- this.destinationStore_.selectDestination(dest);
- break;
- }
- }
+ this.iconClass_ = DestinationSettings.Classes_.ICON_CLOUD_SHARED;
}
+ iconEl.classList.add(this.iconClass_);
+
+ var locationEl = this.getElement().getElementsByClassName(
+ DestinationSettings.Classes_.LOCATION)[0];
+ locationEl.textContent = destination.location;
}
};
+ // Export
return {
DestinationSettings: DestinationSettings
};
diff --git a/chrome/browser/resources/print_preview/settings/margin_settings.js b/chrome/browser/resources/print_preview/settings/margin_settings.js
index 54e5699..290a733 100644
--- a/chrome/browser/resources/print_preview/settings/margin_settings.js
+++ b/chrome/browser/resources/print_preview/settings/margin_settings.js
@@ -77,7 +77,7 @@ cr.define('print_preview', function() {
onSelectChange_: function() {
var select = this.select_;
var marginsType =
- /** @type {print_preview.ticket_items.MarginsType.Value} */ (
+ /** @type {!print_preview.ticket_items.MarginsType.Value} */ (
select.selectedIndex);
this.printTicketStore_.updateMarginsType(marginsType);
},
@@ -92,7 +92,7 @@ cr.define('print_preview', function() {
var select = this.select_;
var marginsType = this.printTicketStore_.getMarginsType();
var selectedMarginsType =
- /** @type {print_preview.ticket_items.MarginsType.Value} */ (
+ /** @type {!print_preview.ticket_items.MarginsType.Value} */ (
select.selectedIndex);
if (marginsType != selectedMarginsType) {
select.options[selectedMarginsType].selected = false;
diff --git a/chrome/browser/resources/print_preview/settings/page_settings.css b/chrome/browser/resources/print_preview/settings/page_settings.css
index cabdf7f..91f3ed4 100644
--- a/chrome/browser/resources/print_preview/settings/page_settings.css
+++ b/chrome/browser/resources/print_preview/settings/page_settings.css
@@ -1,7 +1,6 @@
/* Copyright (c) 2012 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.
- */
+ * found in the LICENSE file. */
#page-settings .page-settings-custom-input.invalid {
background: rgb(255, 240, 240);
diff --git a/chrome/browser/resources/print_preview/settings/page_settings.js b/chrome/browser/resources/print_preview/settings/page_settings.js
index 1489c6b..95bd525 100644
--- a/chrome/browser/resources/print_preview/settings/page_settings.js
+++ b/chrome/browser/resources/print_preview/settings/page_settings.js
@@ -25,7 +25,7 @@ cr.define('print_preview', function() {
/**
* Timeout used to delay processing of the custom page range input.
- * @type {Object}
+ * @type {?number}
* @private
*/
this.customInputTimeout_ = null;