Move Webstore URL concepts to //extensions and out
[chromium-blink-merge.git] / chrome / browser / resources / print_preview / data / print_ticket_store.js
blob6324762a03c7fc05382b2523c9ddd6bbc660dcf1
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 cr.define('print_preview', function() {
6 'use strict';
8 // TODO(rltoscano): Maybe clear print ticket when destination changes. Or
9 // better yet, carry over any print ticket state that is possible. I.e. if
10 // destination changes, the new destination might not support duplex anymore,
11 // so we should clear the ticket's isDuplexEnabled state.
13 /**
14 * Storage of the print ticket and document statistics. Dispatches events when
15 * the contents of the print ticket or document statistics change. Also
16 * handles validation of the print ticket against destination capabilities and
17 * against the document.
18 * @param {!print_preview.DestinationStore} destinationStore Used to
19 * understand which printer is selected.
20 * @param {!print_preview.AppState} appState Print preview application state.
21 * @param {!print_preview.DocumentInfo} documentInfo Document data model.
22 * @constructor
23 * @extends {cr.EventTarget}
25 function PrintTicketStore(destinationStore, appState, documentInfo) {
26 cr.EventTarget.call(this);
28 /**
29 * Destination store used to understand which printer is selected.
30 * @type {!print_preview.DestinationStore}
31 * @private
33 this.destinationStore_ = destinationStore;
35 /**
36 * App state used to persist and load ticket values.
37 * @type {!print_preview.AppState}
38 * @private
40 this.appState_ = appState;
42 /**
43 * Information about the document to print.
44 * @type {!print_preview.DocumentInfo}
45 * @private
47 this.documentInfo_ = documentInfo;
49 /**
50 * Printing capabilities of Chromium and the currently selected destination.
51 * @type {!print_preview.CapabilitiesHolder}
52 * @private
54 this.capabilitiesHolder_ = new print_preview.CapabilitiesHolder();
56 /**
57 * Current measurement system. Used to work with margin measurements.
58 * @type {!print_preview.MeasurementSystem}
59 * @private
61 this.measurementSystem_ = new print_preview.MeasurementSystem(
62 ',', '.', print_preview.MeasurementSystem.UnitType.IMPERIAL);
64 /**
65 * Collate ticket item.
66 * @type {!print_preview.ticket_items.Collate}
67 * @private
69 this.collate_ = new print_preview.ticket_items.Collate(
70 this.appState_, this.destinationStore_);
72 /**
73 * Color ticket item.
74 * @type {!print_preview.ticket_items.Color}
75 * @private
77 this.color_ = new print_preview.ticket_items.Color(
78 this.appState_, this.destinationStore_);
80 /**
81 * Copies ticket item.
82 * @type {!print_preview.ticket_items.Copies}
83 * @private
85 this.copies_ =
86 new print_preview.ticket_items.Copies(this.destinationStore_);
88 /**
89 * Duplex ticket item.
90 * @type {!print_preview.ticket_items.Duplex}
91 * @private
93 this.duplex_ = new print_preview.ticket_items.Duplex(
94 this.appState_, this.destinationStore_);
96 /**
97 * Page range ticket item.
98 * @type {!print_preview.ticket_items.PageRange}
99 * @private
101 this.pageRange_ =
102 new print_preview.ticket_items.PageRange(this.documentInfo_);
105 * Custom margins ticket item.
106 * @type {!print_preview.ticket_items.CustomMargins}
107 * @private
109 this.customMargins_ = new print_preview.ticket_items.CustomMargins(
110 this.appState_, this.documentInfo_);
113 * Margins type ticket item.
114 * @type {!print_preview.ticket_items.MarginsType}
115 * @private
117 this.marginsType_ = new print_preview.ticket_items.MarginsType(
118 this.appState_, this.documentInfo_, this.customMargins_);
121 * Media size ticket item.
122 * @type {!print_preview.ticket_items.MediaSize}
123 * @private
125 this.mediaSize_ = new print_preview.ticket_items.MediaSize(
126 this.appState_,
127 this.destinationStore_,
128 this.documentInfo_,
129 this.marginsType_,
130 this.customMargins_);
133 * Landscape ticket item.
134 * @type {!print_preview.ticket_items.Landscape}
135 * @private
137 this.landscape_ = new print_preview.ticket_items.Landscape(
138 this.appState_,
139 this.destinationStore_,
140 this.documentInfo_,
141 this.marginsType_,
142 this.customMargins_);
145 * Header-footer ticket item.
146 * @type {!print_preview.ticket_items.HeaderFooter}
147 * @private
149 this.headerFooter_ = new print_preview.ticket_items.HeaderFooter(
150 this.appState_,
151 this.documentInfo_,
152 this.marginsType_,
153 this.customMargins_);
156 * Fit-to-page ticket item.
157 * @type {!print_preview.ticket_items.FitToPage}
158 * @private
160 this.fitToPage_ = new print_preview.ticket_items.FitToPage(
161 this.documentInfo_, this.destinationStore_);
164 * Print CSS backgrounds ticket item.
165 * @type {!print_preview.ticket_items.CssBackground}
166 * @private
168 this.cssBackground_ = new print_preview.ticket_items.CssBackground(
169 this.appState_, this.documentInfo_);
172 * Print selection only ticket item.
173 * @type {!print_preview.ticket_items.SelectionOnly}
174 * @private
176 this.selectionOnly_ =
177 new print_preview.ticket_items.SelectionOnly(this.documentInfo_);
180 * Vendor ticket items.
181 * @type {!print_preview.ticket_items.VendorItems}
182 * @private
184 this.vendorItems_ = new print_preview.ticket_items.VendorItems(
185 this.appState_, this.destinationStore_);
188 * Keeps track of event listeners for the print ticket store.
189 * @type {!EventTracker}
190 * @private
192 this.tracker_ = new EventTracker();
195 * Whether the print preview has been initialized.
196 * @type {boolean}
197 * @private
199 this.isInitialized_ = false;
201 this.addEventListeners_();
205 * Event types dispatched by the print ticket store.
206 * @enum {string}
208 PrintTicketStore.EventType = {
209 CAPABILITIES_CHANGE: 'print_preview.PrintTicketStore.CAPABILITIES_CHANGE',
210 DOCUMENT_CHANGE: 'print_preview.PrintTicketStore.DOCUMENT_CHANGE',
211 INITIALIZE: 'print_preview.PrintTicketStore.INITIALIZE',
212 TICKET_CHANGE: 'print_preview.PrintTicketStore.TICKET_CHANGE'
215 PrintTicketStore.prototype = {
216 __proto__: cr.EventTarget.prototype,
219 * Whether the print preview has been initialized.
220 * @type {boolean}
222 get isInitialized() {
223 return this.isInitialized_;
226 get collate() {
227 return this.collate_;
230 get color() {
231 return this.color_;
234 get copies() {
235 return this.copies_;
238 get cssBackground() {
239 return this.cssBackground_;
242 get customMargins() {
243 return this.customMargins_;
246 get duplex() {
247 return this.duplex_;
250 get fitToPage() {
251 return this.fitToPage_;
254 get headerFooter() {
255 return this.headerFooter_;
258 get mediaSize() {
259 return this.mediaSize_;
262 get landscape() {
263 return this.landscape_;
266 get marginsType() {
267 return this.marginsType_;
270 get pageRange() {
271 return this.pageRange_;
274 get selectionOnly() {
275 return this.selectionOnly_;
278 get vendorItems() {
279 return this.vendorItems_;
283 * @return {!print_preview.MeasurementSystem} Measurement system of the
284 * local system.
286 get measurementSystem() {
287 return this.measurementSystem_;
291 * Initializes the print ticket store. Dispatches an INITIALIZE event.
292 * @param {string} thousandsDelimeter Delimeter of the thousands place.
293 * @param {string} decimalDelimeter Delimeter of the decimal point.
294 * @param {!print_preview.MeasurementSystem.UnitType} unitType Type of unit
295 * of the local measurement system.
296 * @param {boolean} selectionOnly Whether only selected content should be
297 * printed.
299 init: function(
300 thousandsDelimeter, decimalDelimeter, unitType, selectionOnly) {
301 this.measurementSystem_.setSystem(thousandsDelimeter, decimalDelimeter,
302 unitType);
303 this.selectionOnly_.updateValue(selectionOnly);
305 // Initialize ticket with user's previous values.
306 if (this.appState_.hasField(
307 print_preview.AppState.Field.IS_COLOR_ENABLED)) {
308 this.color_.updateValue(this.appState_.getField(
309 print_preview.AppState.Field.IS_COLOR_ENABLED));
311 if (this.appState_.hasField(
312 print_preview.AppState.Field.IS_DUPLEX_ENABLED)) {
313 this.duplex_.updateValue(this.appState_.getField(
314 print_preview.AppState.Field.IS_DUPLEX_ENABLED));
316 if (this.appState_.hasField(print_preview.AppState.Field.MEDIA_SIZE)) {
317 this.mediaSize_.updateValue(this.appState_.getField(
318 print_preview.AppState.Field.MEDIA_SIZE));
320 if (this.appState_.hasField(
321 print_preview.AppState.Field.IS_LANDSCAPE_ENABLED)) {
322 this.landscape_.updateValue(this.appState_.getField(
323 print_preview.AppState.Field.IS_LANDSCAPE_ENABLED));
325 // Initialize margins after landscape because landscape may reset margins.
326 if (this.appState_.hasField(print_preview.AppState.Field.MARGINS_TYPE)) {
327 this.marginsType_.updateValue(
328 this.appState_.getField(print_preview.AppState.Field.MARGINS_TYPE));
330 if (this.appState_.hasField(
331 print_preview.AppState.Field.CUSTOM_MARGINS)) {
332 this.customMargins_.updateValue(this.appState_.getField(
333 print_preview.AppState.Field.CUSTOM_MARGINS));
335 if (this.appState_.hasField(
336 print_preview.AppState.Field.IS_HEADER_FOOTER_ENABLED)) {
337 this.headerFooter_.updateValue(this.appState_.getField(
338 print_preview.AppState.Field.IS_HEADER_FOOTER_ENABLED));
340 if (this.appState_.hasField(
341 print_preview.AppState.Field.IS_COLLATE_ENABLED)) {
342 this.collate_.updateValue(this.appState_.getField(
343 print_preview.AppState.Field.IS_COLLATE_ENABLED));
345 if (this.appState_.hasField(
346 print_preview.AppState.Field.IS_CSS_BACKGROUND_ENABLED)) {
347 this.cssBackground_.updateValue(this.appState_.getField(
348 print_preview.AppState.Field.IS_CSS_BACKGROUND_ENABLED));
350 if (this.appState_.hasField(
351 print_preview.AppState.Field.VENDOR_OPTIONS)) {
352 this.vendorItems_.updateValue(this.appState_.getField(
353 print_preview.AppState.Field.VENDOR_OPTIONS));
358 * @return {boolean} {@code true} if the stored print ticket is valid,
359 * {@code false} otherwise.
361 isTicketValid: function() {
362 return this.isTicketValidForPreview() &&
363 (!this.copies_.isCapabilityAvailable() || this.copies_.isValid()) &&
364 (!this.pageRange_.isCapabilityAvailable() ||
365 this.pageRange_.isValid());
368 /** @return {boolean} Whether the ticket is valid for preview generation. */
369 isTicketValidForPreview: function() {
370 return (!this.marginsType_.isCapabilityAvailable() ||
371 !this.marginsType_.isValueEqual(
372 print_preview.ticket_items.MarginsType.Value.CUSTOM) ||
373 this.customMargins_.isValid());
377 * Creates an object that represents a Google Cloud Print print ticket.
378 * @param {!print_preview.Destination} destination Destination to print to.
379 * @return {!Object} Google Cloud Print print ticket.
381 createPrintTicket: function(destination) {
382 assert(!destination.isLocal || destination.isPrivet,
383 'Trying to create a Google Cloud Print print ticket for a local ' +
384 ' non-privet destination');
386 assert(destination.capabilities,
387 'Trying to create a Google Cloud Print print ticket for a ' +
388 'destination with no print capabilities');
389 var cjt = {
390 version: '1.0',
391 print: {}
393 if (this.collate.isCapabilityAvailable() && this.collate.isUserEdited()) {
394 cjt.print.collate = {collate: this.collate.getValue()};
396 if (this.color.isCapabilityAvailable() && this.color.isUserEdited()) {
397 var selectedOption = this.color.getSelectedOption();
398 if (!selectedOption) {
399 console.error('Could not find correct color option');
400 } else {
401 cjt.print.color = {type: selectedOption.type};
402 if (selectedOption.hasOwnProperty('vendor_id')) {
403 cjt.print.color.vendor_id = selectedOption.vendor_id;
407 if (this.copies.isCapabilityAvailable() && this.copies.isUserEdited()) {
408 cjt.print.copies = {copies: this.copies.getValueAsNumber()};
410 if (this.duplex.isCapabilityAvailable() && this.duplex.isUserEdited()) {
411 cjt.print.duplex =
412 {type: this.duplex.getValue() ? 'LONG_EDGE' : 'NO_DUPLEX'};
414 if (this.mediaSize.isCapabilityAvailable()) {
415 var value = this.mediaSize.getValue();
416 cjt.print.media_size = {
417 width_microns: value.width_microns,
418 height_microns: value.height_microns,
419 is_continuous_feed: value.is_continuous_feed,
420 vendor_id: value.vendor_id
423 if (this.landscape.isCapabilityAvailable() &&
424 this.landscape.isUserEdited()) {
425 cjt.print.page_orientation =
426 {type: this.landscape.getValue() ? 'LANDSCAPE' : 'PORTRAIT'};
428 if (this.vendorItems.isCapabilityAvailable() &&
429 this.vendorItems.isUserEdited()) {
430 var items = this.vendorItems.ticketItems;
431 cjt.print.vendor_ticket_item = [];
432 for (var itemId in items) {
433 if (items.hasOwnProperty(itemId)) {
434 cjt.print.vendor_ticket_item.push(
435 {id: itemId, value: items[itemId]});
439 return JSON.stringify(cjt);
443 * Adds event listeners for the print ticket store.
444 * @private
446 addEventListeners_: function() {
447 this.tracker_.add(
448 this.destinationStore_,
449 print_preview.DestinationStore.EventType.DESTINATION_SELECT,
450 this.onDestinationSelect_.bind(this));
452 this.tracker_.add(
453 this.destinationStore_,
454 print_preview.DestinationStore.EventType.
455 SELECTED_DESTINATION_CAPABILITIES_READY,
456 this.onSelectedDestinationCapabilitiesReady_.bind(this));
458 this.tracker_.add(
459 this.destinationStore_,
460 print_preview.DestinationStore.EventType.
461 CACHED_SELECTED_DESTINATION_INFO_READY,
462 this.onSelectedDestinationCapabilitiesReady_.bind(this));
464 // TODO(rltoscano): Print ticket store shouldn't be re-dispatching these
465 // events, the consumers of the print ticket store events should listen
466 // for the events from document info instead. Will move this when
467 // consumers are all migrated.
468 this.tracker_.add(
469 this.documentInfo_,
470 print_preview.DocumentInfo.EventType.CHANGE,
471 this.onDocumentInfoChange_.bind(this));
475 * Called when the destination selected.
476 * @private
478 onDestinationSelect_: function() {
479 // Reset user selection for certain ticket items.
480 if (this.capabilitiesHolder_.get() != null) {
481 this.customMargins_.updateValue(null);
482 if (this.marginsType_.getValue() ==
483 print_preview.ticket_items.MarginsType.Value.CUSTOM) {
484 this.marginsType_.updateValue(
485 print_preview.ticket_items.MarginsType.Value.DEFAULT);
487 this.vendorItems_.updateValue({});
492 * Called when the capabilities of the selected destination are ready.
493 * @private
495 onSelectedDestinationCapabilitiesReady_: function() {
496 var caps = this.destinationStore_.selectedDestination.capabilities;
497 var isFirstUpdate = this.capabilitiesHolder_.get() == null;
498 this.capabilitiesHolder_.set(caps);
499 if (isFirstUpdate) {
500 this.isInitialized_ = true;
501 cr.dispatchSimpleEvent(this, PrintTicketStore.EventType.INITIALIZE);
502 } else {
503 cr.dispatchSimpleEvent(
504 this, PrintTicketStore.EventType.CAPABILITIES_CHANGE);
509 * Called when document data model has changed. Dispatches a print ticket
510 * store event.
511 * @private
513 onDocumentInfoChange_: function() {
514 cr.dispatchSimpleEvent(this, PrintTicketStore.EventType.DOCUMENT_CHANGE);
518 // Export
519 return {
520 PrintTicketStore: PrintTicketStore