ticket_item.js revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
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. 4 5cr.define('print_preview.ticket_items', function() { 6 'use strict'; 7 8 /** 9 * An object that represents a user modifiable item in a print ticket. Each 10 * ticket item has a value which can be set by the user. Ticket items can also 11 * be unavailable for modifying if the print destination doesn't support it or 12 * if other ticket item constraints are not met. 13 * @param {print_preview.AppState=} appState Application state model to update 14 * when ticket items update. 15 * @param {print_preview.AppState.Field=} field Field of the app state to 16 * update when ticket item is updated. 17 * @param {print_preview.DestinationStore=} destinationStore Used listen for 18 * changes in the currently selected destination's capabilities. Since 19 * this is a common dependency of ticket items, it's handled in the base 20 * class. 21 * @param {print_preview.DocumentInfo=} documentInfo Used to listen for 22 * changes in the document. Since this is a common dependency of ticket 23 * items, it's handled in the base class. 24 * @constructor 25 */ 26 function TicketItem(appState, field, destinationStore, documentInfo) { 27 cr.EventTarget.call(this); 28 29 /** 30 * Application state model to update when ticket items update. 31 * @type {print_preview.AppState} 32 * @private 33 */ 34 this.appState_ = appState || null; 35 36 /** 37 * Field of the app state to update when ticket item is updated. 38 * @type {print_preview.AppState.Field} 39 * @private 40 */ 41 this.field_ = field || null; 42 43 /** 44 * Used listen for changes in the currently selected destination's 45 * capabilities. 46 * @type {print_preview.DestinationStore} 47 * @private 48 */ 49 this.destinationStore_ = destinationStore || null; 50 51 /** 52 * Used to listen for changes in the document. 53 * @type {print_preview.DocumentInfo} 54 * @private 55 */ 56 this.documentInfo_ = documentInfo || null; 57 58 /** 59 * Backing store of the print ticket item. 60 * @type {Object} 61 * @private 62 */ 63 this.value_ = null; 64 65 /** 66 * Keeps track of event listeners for the ticket item. 67 * @type {!EventTracker} 68 * @private 69 */ 70 this.tracker_ = new EventTracker(); 71 72 this.addEventHandlers_(); 73 }; 74 75 /** 76 * Event types dispatched by this class. 77 * @enum {string} 78 */ 79 TicketItem.EventType = { 80 CHANGE: 'print_preview.ticket_items.TicketItem.CHANGE' 81 }; 82 83 TicketItem.prototype = { 84 __proto__: cr.EventTarget.prototype, 85 86 /** 87 * Determines whether a given value is valid for the ticket item. 88 * @param {Object} value The value to check for validity. 89 * @return {boolean} Whether the given value is valid for the ticket item. 90 */ 91 wouldValueBeValid: function(value) { 92 throw Error('Abstract method not overridden'); 93 }, 94 95 /** 96 * @return {boolean} Whether the print destination capability is available. 97 */ 98 isCapabilityAvailable: function() { 99 throw Error('Abstract method not overridden'); 100 }, 101 102 /** @return {!Object} The value of the ticket item. */ 103 getValue: function() { 104 if (this.isCapabilityAvailable()) { 105 if (this.value_ == null) { 106 return this.getDefaultValueInternal(); 107 } else { 108 return this.value_; 109 } 110 } else { 111 return this.getCapabilityNotAvailableValueInternal(); 112 } 113 }, 114 115 /** @return {boolean} Whether the ticket item was modified by the user. */ 116 isUserEdited: function() { 117 return this.value_ != null; 118 }, 119 120 /** @return {boolean} Whether the ticket item's value is valid. */ 121 isValid: function() { 122 if (!this.isUserEdited()) { 123 return true; 124 } 125 return this.wouldValueBeValid(this.value_); 126 }, 127 128 /** 129 * @param {Object} value Value to compare to the value of this ticket item. 130 * @return {boolean} Whether the given value is equal to the value of the 131 * ticket item. 132 */ 133 isValueEqual: function(value) { 134 return this.getValue() == value; 135 }, 136 137 /** @param {!Object} value Value to set as the value of the ticket item. */ 138 updateValue: function(value) { 139 // Use comparison with capabilities for event. 140 var sendUpdateEvent = !this.isValueEqual(value); 141 // Don't lose requested value if capability is not available. 142 this.updateValueInternal(value); 143 if (this.appState_) { 144 this.appState_.persistField(this.field_, value); 145 } 146 if (sendUpdateEvent) 147 cr.dispatchSimpleEvent(this, TicketItem.EventType.CHANGE); 148 }, 149 150 /** 151 * @return {!Object} Default value of the ticket item if no value was set by 152 * the user. 153 * @protected 154 */ 155 getDefaultValueInternal: function() { 156 throw Error('Abstract method not overridden'); 157 }, 158 159 /** 160 * @return {!Object} Default value of the ticket item if the capability is 161 * not available. 162 * @protected 163 */ 164 getCapabilityNotAvailableValueInternal: function() { 165 throw Error('Abstract method not overridden'); 166 }, 167 168 /** 169 * @return {!EventTracker} Event tracker to keep track of events from 170 * dependencies. 171 * @protected 172 */ 173 getTrackerInternal: function() { 174 return this.tracker_; 175 }, 176 177 /** 178 * @return {print_preview.Destination} Selected destination from the 179 * destination store, or {@code null} if no destination is selected. 180 * @protected 181 */ 182 getSelectedDestInternal: function() { 183 return this.destinationStore_ ? 184 this.destinationStore_.selectedDestination : null; 185 }, 186 187 /** 188 * @return {print_preview.DocumentInfo} Document data model. 189 * @protected 190 */ 191 getDocumentInfoInternal: function() { 192 return this.documentInfo_; 193 }, 194 195 /** 196 * Dispatches a CHANGE event. 197 * @protected 198 */ 199 dispatchChangeEventInternal: function() { 200 cr.dispatchSimpleEvent( 201 this, print_preview.ticket_items.TicketItem.EventType.CHANGE); 202 }, 203 204 /** 205 * Updates the value of the ticket item without dispatching any events or 206 * persisting the value. 207 * @protected 208 */ 209 updateValueInternal: function(value) { 210 this.value_ = value; 211 }, 212 213 /** 214 * Adds event handlers for this class. 215 * @private 216 */ 217 addEventHandlers_: function() { 218 if (this.destinationStore_) { 219 this.tracker_.add( 220 this.destinationStore_, 221 print_preview.DestinationStore.EventType. 222 SELECTED_DESTINATION_CAPABILITIES_READY, 223 this.dispatchChangeEventInternal.bind(this)); 224 } 225 if (this.documentInfo_) { 226 this.tracker_.add( 227 this.documentInfo_, 228 print_preview.DocumentInfo.EventType.CHANGE, 229 this.dispatchChangeEventInternal.bind(this)); 230 } 231 }, 232 }; 233 234 // Export 235 return { 236 TicketItem: TicketItem 237 }; 238}); 239