OLD | NEW |
(Empty) | |
| 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 |
| 5 cr.define('print_preview.ticket_items', function() { |
| 6 'use strict'; |
| 7 |
| 8 /** |
| 9 * Custom page margins ticket item whose value is a |
| 10 * {@code print_preview.ticket_items.StringMargins}. The margin values need to |
| 11 * be represented by a string since the user can textually input the values. |
| 12 * @param {!print_preview.DocumentInfo} documentInfo Information about the |
| 13 * document to print. |
| 14 * @param {!print_preview.MeasurementSystem} measurementSystem Used to convert |
| 15 * from string input into measurements in points. |
| 16 * @constructor |
| 17 * @extends {print_preview.ticket_items.TicketItem} |
| 18 */ |
| 19 function CustomMargins(documentInfo, measurementSystem) { |
| 20 print_preview.ticket_items.TicketItem.call(this); |
| 21 |
| 22 /** |
| 23 * Information about the document to print. |
| 24 * @type {!print_preview.DocumentInfo} |
| 25 * @private |
| 26 */ |
| 27 this.documentInfo_ = documentInfo; |
| 28 |
| 29 /** |
| 30 * Used to convert from string input to measurements in points. |
| 31 * @type {!print_preview.MeasurementSystem} |
| 32 * @private |
| 33 */ |
| 34 this.measurementSystem_ = measurementSystem; |
| 35 |
| 36 /** |
| 37 * Default value of the ticket item in points. |
| 38 * @type {!print_preview.Margins} |
| 39 * @private |
| 40 */ |
| 41 this.defaultValueInPts_ = new print_preview.Margins(72, 72, 72, 72); |
| 42 |
| 43 /** |
| 44 * Cache of the the ticket item's value in points. |
| 45 * @type {print_preview.Margins} |
| 46 * @private |
| 47 */ |
| 48 this.valueInPts_ = null; |
| 49 }; |
| 50 |
| 51 /** |
| 52 * Enumeration of the orientations of margins. |
| 53 * @enum {string} |
| 54 */ |
| 55 CustomMargins.Orientation = { |
| 56 TOP: 'top', |
| 57 RIGHT: 'right', |
| 58 BOTTOM: 'bottom', |
| 59 LEFT: 'left' |
| 60 }; |
| 61 |
| 62 /** |
| 63 * Precision used to convert from number in points to string in local units. |
| 64 * @type {number} |
| 65 * @const |
| 66 * @private |
| 67 */ |
| 68 CustomMargins.PRECISION_ = 3; |
| 69 |
| 70 /** |
| 71 * Minimum distance in points two margins can be separated by. |
| 72 * @type {number} |
| 73 * @const |
| 74 * @private |
| 75 */ |
| 76 CustomMargins.MINIMUM_MARGINS_DISTANCE_ = 72; // 1 inch. |
| 77 |
| 78 CustomMargins.prototype = { |
| 79 __proto__: print_preview.ticket_items.TicketItem.prototype, |
| 80 |
| 81 /** @override */ |
| 82 wouldValueBeValid: function(value) { |
| 83 var stringMargins = |
| 84 /** @type {!print_preview.ticket_items.StringMargins} */ (value); |
| 85 var marginsInPts = this.parseStringMarginsToPts_(stringMargins); |
| 86 if (marginsInPts == null) { |
| 87 return false; |
| 88 } |
| 89 for (var key in CustomMargins.Orientation) { |
| 90 var o = CustomMargins.Orientation[key]; |
| 91 var max = this.getMarginMaxInPts_(o, marginsInPts.getOpposite(o)); |
| 92 max = this.measurementSystem_.convertFromPoints(max, true); |
| 93 var min = this.getMarginMinInPts_(o); |
| 94 min = this.measurementSystem_.convertFromPoints(min, false); |
| 95 var margin = |
| 96 this.measurementSystem_.convertFromPoints(marginsInPts.get(o)); |
| 97 if (margin > max || margin < min) { |
| 98 return false; |
| 99 } |
| 100 } |
| 101 return true; |
| 102 }, |
| 103 |
| 104 /** @override */ |
| 105 isCapabilityAvailable: function() { |
| 106 return this.documentInfo_.isModifiable; |
| 107 }, |
| 108 |
| 109 /** |
| 110 * @param {print_preview.ticket_items.CustomMargins.Orientation} orientation |
| 111 * Specifies which margin to check if parseable. |
| 112 * @return {boolean} Whether the specified margin is parseable. |
| 113 */ |
| 114 isMarginParseable: function(orientation) { |
| 115 return this.parseToPts_(this.getValue().get(orientation)) != null; |
| 116 }, |
| 117 |
| 118 /** |
| 119 * @return {!print_preview.Margins} The ticket items custom margins in |
| 120 * points. |
| 121 */ |
| 122 getValueInPts: function() { |
| 123 if (this.valueInPts_ == null) { |
| 124 var stringMargins = |
| 125 /** @type {!print_preview.ticket_items.StringMargins} */ ( |
| 126 this.getValue()); |
| 127 this.valueInPts_ = this.parseStringMarginsToPts_(stringMargins); |
| 128 if (this.valueInPts_ == null) { |
| 129 throw Error('Error while parsing margin values into points'); |
| 130 } |
| 131 } |
| 132 return this.valueInPts_; |
| 133 }, |
| 134 |
| 135 /** @override */ |
| 136 updateValue: function(value) { |
| 137 print_preview.ticket_items.TicketItem.prototype.updateValue.call( |
| 138 this, value); |
| 139 this.valueInPts_ = null; |
| 140 }, |
| 141 |
| 142 /** |
| 143 * Updates the value of the ticket item with the given margins in points. |
| 144 * @param {!print_preview.Margins} valueInPts Updated margins in points. |
| 145 */ |
| 146 updateValueInPts: function(valueInPts) { |
| 147 var o = CustomMargins.Orientation; |
| 148 this.updateValue(new StringMargins( |
| 149 this.serializeMarginFromPts(valueInPts.get(o.TOP)), |
| 150 this.serializeMarginFromPts(valueInPts.get(o.RIGHT)), |
| 151 this.serializeMarginFromPts(valueInPts.get(o.BOTTOM)), |
| 152 this.serializeMarginFromPts(valueInPts.get(o.LEFT)))); |
| 153 this.valueInPts_ = valueInPts; |
| 154 }, |
| 155 |
| 156 /** |
| 157 * Updates the specified margin with a value in points. |
| 158 * @param {print_preview.ticket_items.CustomMargins.Orientation} orientation |
| 159 * Specifies the margin to update. |
| 160 * @param {number} valueInPts Updated margin in points. |
| 161 */ |
| 162 updateMarginInPts: function(orientation, valueInPts) { |
| 163 this.updateMargin(orientation, this.serializeMarginFromPts(valueInPts)); |
| 164 }, |
| 165 |
| 166 /** |
| 167 * Updates the specified margin with the given string input. |
| 168 * @param {print_preview.ticket_items.CustomMargins.Orientation} orientation |
| 169 * Specifies the margin to update. |
| 170 * @param {string} value Updated string value of the margin. |
| 171 */ |
| 172 updateMargin: function(orientation, value) { |
| 173 var stringMargins = |
| 174 /** @type {!print_preview.ticket_items.StringMargins} */ ( |
| 175 this.getValue()); |
| 176 var newStringMargins = stringMargins.set(orientation, value); |
| 177 var newMarginsInPts = this.parseStringMarginsToPts_(newStringMargins); |
| 178 if (newMarginsInPts != null) { |
| 179 // Put updated margin within the valid range (between min and max). |
| 180 var min = this.getMarginMinInPts_(orientation); |
| 181 min = this.measurementSystem_.convertFromPoints(min); |
| 182 var max = this.getMarginMaxInPts_( |
| 183 orientation, newMarginsInPts.getOpposite(orientation)); |
| 184 max = this.measurementSystem_.convertFromPoints(max); |
| 185 var newValue = this.measurementSystem_.convertFromPoints( |
| 186 newMarginsInPts.get(orientation)); |
| 187 newValue = Math.max(min, Math.min(max, newValue)); |
| 188 this.updateValueInPts(newMarginsInPts.set( |
| 189 orientation, this.measurementSystem_.convertToPoints(newValue))); |
| 190 } else { |
| 191 this.updateValue(newStringMargins); |
| 192 } |
| 193 }, |
| 194 |
| 195 /** |
| 196 * Updates the default value of the margins ticket item. This value is used |
| 197 * if the ticket item has not been edited by the user. |
| 198 * @param {!print_preview.Margins} valueInPts Updated margin default values. |
| 199 */ |
| 200 updateDefaultValueInPts: function(valueInPts) { |
| 201 this.defaultValueInPts_ = valueInPts; |
| 202 this.valueInPts_ = null; |
| 203 }, |
| 204 |
| 205 /** |
| 206 * @param {number} marginInPts Value of in points to serialize to a locale |
| 207 * string. |
| 208 * @return {string} Serialized form of the given value in points. The |
| 209 * serialized value is in the user's local measurement system. |
| 210 */ |
| 211 serializeMarginFromPts: function(marginInPts) { |
| 212 return this.measurementSystem_.convertFromPoints(marginInPts) + |
| 213 this.measurementSystem_.unitSymbol; |
| 214 }, |
| 215 |
| 216 /** @override */ |
| 217 getDefaultValueInternal: function() { |
| 218 return new StringMargins( |
| 219 this.serializeMarginFromPts( |
| 220 this.defaultValueInPts_.get(CustomMargins.Orientation.TOP)), |
| 221 this.serializeMarginFromPts( |
| 222 this.defaultValueInPts_.get(CustomMargins.Orientation.RIGHT)), |
| 223 this.serializeMarginFromPts( |
| 224 this.defaultValueInPts_.get(CustomMargins.Orientation.BOTTOM)), |
| 225 this.serializeMarginFromPts( |
| 226 this.defaultValueInPts_.get(CustomMargins.Orientation.LEFT))); |
| 227 }, |
| 228 |
| 229 /** @override */ |
| 230 getCapabilityNotAvailableValueInternal: function() { |
| 231 return this.getDefaultValueInternal(); |
| 232 }, |
| 233 |
| 234 /** |
| 235 * @param {print_preview.ticket_items.CustomMargins.Orientation} orientation |
| 236 * Specifies which margin to get the maximum value of. |
| 237 * @param {number} oppositeMarginInPts Value of the margin in points |
| 238 * opposite the specified margin. |
| 239 * @return {number} Maximum value in points of the specified margin. |
| 240 * @private |
| 241 */ |
| 242 getMarginMaxInPts_: function(orientation, oppositeMarginInPts) { |
| 243 if (orientation == CustomMargins.Orientation.TOP) { |
| 244 return this.documentInfo_.pageSize.height - |
| 245 this.documentInfo_.printableArea.origin.y - |
| 246 oppositeMarginInPts - |
| 247 CustomMargins.MINIMUM_MARGINS_DISTANCE_; |
| 248 } else if (orientation == CustomMargins.Orientation.RIGHT) { |
| 249 return this.documentInfo_.pageSize.width - |
| 250 this.documentInfo_.printableArea.origin.x - |
| 251 oppositeMarginInPts - |
| 252 CustomMargins.MINIMUM_MARGINS_DISTANCE_; |
| 253 } else if (orientation == CustomMargins.Orientation.BOTTOM) { |
| 254 return this.documentInfo_.pageSize.height - |
| 255 this.documentInfo_.printableArea.origin.y - |
| 256 oppositeMarginInPts - |
| 257 CustomMargins.MINIMUM_MARGINS_DISTANCE_; |
| 258 } else { |
| 259 return this.documentInfo_.pageSize.width - |
| 260 this.documentInfo_.printableArea.origin.x - |
| 261 oppositeMarginInPts - |
| 262 CustomMargins.MINIMUM_MARGINS_DISTANCE_; |
| 263 } |
| 264 }, |
| 265 |
| 266 /** |
| 267 * @param {print_preview.ticket_items.CustomMargins.Orientation} orientation |
| 268 * Specifies which margin to get the minimum value of. |
| 269 * @return {number} Minimum value in points of the specified margin. |
| 270 * @private |
| 271 */ |
| 272 getMarginMinInPts_: function(orientation) { |
| 273 if (orientation == CustomMargins.Orientation.TOP) { |
| 274 return this.documentInfo_.printableArea.origin.y; |
| 275 } else if (orientation == CustomMargins.Orientation.RIGHT) { |
| 276 return this.documentInfo_.pageSize.width - |
| 277 this.documentInfo_.printableArea.origin.x - |
| 278 this.documentInfo_.printableArea.size.width; |
| 279 } else if (orientation == CustomMargins.Orientation.BOTTOM) { |
| 280 return this.documentInfo_.pageSize.height - |
| 281 this.documentInfo_.printableArea.origin.y - |
| 282 this.documentInfo_.printableArea.size.height; |
| 283 } else { |
| 284 return this.documentInfo_.printableArea.origin.x; |
| 285 } |
| 286 }, |
| 287 |
| 288 /** |
| 289 * Parses the size of a margin in points from the given string. |
| 290 * Example: "1.00", "1", ".5", "1.1" are valid values. |
| 291 * Example: "1.4dsf", "-1" are invalid. |
| 292 * Note: The inch symbol (") at the end of |text| is allowed. |
| 293 * @param {string} text The text to parse. |
| 294 * @param {print_preview.MeasurementSystem} measurementSystem Used to handle |
| 295 * parsing local units. |
| 296 * @return {?number} The margin value represented by |text| in points or |
| 297 * {@code null} if |text| does not represent a valid value. |
| 298 * @private |
| 299 */ |
| 300 parseToPts_: function(text) { |
| 301 // Removing whitespace anywhere in the string. |
| 302 text = text.replace(/\s*/g, ''); |
| 303 if (text.length == 0) { |
| 304 return null; |
| 305 } |
| 306 var validationRegex = new RegExp('^(^-?)(\\d)+(\\' + |
| 307 this.measurementSystem_.thousandsDelimeter + '\\d{3})*(\\' + |
| 308 this.measurementSystem_.decimalDelimeter + '\\d*)?' + |
| 309 '(' + this.measurementSystem_.unitSymbol + ')?$'); |
| 310 if (validationRegex.test(text)) { |
| 311 // Replacing decimal point with the dot symbol in order to use |
| 312 // parseFloat() properly. |
| 313 var replacementRegex = |
| 314 new RegExp('\\' + this.measurementSystem_.decimalDelimeter + '{1}'); |
| 315 text = text.replace(replacementRegex, '.'); |
| 316 return this.measurementSystem_.convertToPoints(parseFloat(text)); |
| 317 } |
| 318 return null; |
| 319 }, |
| 320 |
| 321 /** |
| 322 * Parses the given string margins into margins in points. |
| 323 * @param {!print_preview.ticket_items.StringMargins} stringMargins String |
| 324 * margins to parse. |
| 325 * @return {print_preview.Margins} The parsed margins in points, or |
| 326 * {@code null} if the string margins could not be parsed. |
| 327 * @private |
| 328 */ |
| 329 parseStringMarginsToPts_: function(stringMargins) { |
| 330 var topInPts = |
| 331 this.parseToPts_(stringMargins.get(CustomMargins.Orientation.TOP)); |
| 332 var rightInPts = |
| 333 this.parseToPts_(stringMargins.get(CustomMargins.Orientation.RIGHT)); |
| 334 var bottomInPts = |
| 335 this.parseToPts_(stringMargins.get(CustomMargins.Orientation.BOTTOM)); |
| 336 var leftInPts = |
| 337 this.parseToPts_(stringMargins.get(CustomMargins.Orientation.LEFT)); |
| 338 if (topInPts == null || |
| 339 rightInPts == null || |
| 340 bottomInPts == null || |
| 341 leftInPts == null) { |
| 342 return null; |
| 343 } |
| 344 return new print_preview.Margins( |
| 345 topInPts, rightInPts, bottomInPts, leftInPts); |
| 346 } |
| 347 }; |
| 348 |
| 349 /** |
| 350 * An immutable object that represents page margins as strings of values in |
| 351 * the system's local measurement system. |
| 352 * @param {string} top Top margin expressed as a string in the local |
| 353 * measurement system. |
| 354 * @param {string} right Right margin expressed as a string in the local |
| 355 * measurement system. |
| 356 * @param {string} bottom Bottom margin expressed as a string in the local |
| 357 * measurement system. |
| 358 * @param {string} left Left margin expressed as a string in the local |
| 359 * measurement system. |
| 360 * @constructor |
| 361 */ |
| 362 function StringMargins(top, right, bottom, left) { |
| 363 /** |
| 364 * Backing store for the margin values. |
| 365 * @type {Object.< |
| 366 * print_preview.ticket_items.CustomMargins.Orientation, |
| 367 * string>} |
| 368 * @private |
| 369 */ |
| 370 this.value_ = {}; |
| 371 this.value_[print_preview.ticket_items.CustomMargins.Orientation.TOP] = top; |
| 372 this.value_[print_preview.ticket_items.CustomMargins.Orientation.RIGHT] = |
| 373 right; |
| 374 this.value_[print_preview.ticket_items.CustomMargins.Orientation.BOTTOM] = |
| 375 bottom; |
| 376 this.value_[print_preview.ticket_items.CustomMargins.Orientation.LEFT] = |
| 377 left; |
| 378 }; |
| 379 |
| 380 StringMargins.prototype = { |
| 381 /** |
| 382 * @param {print_preview.ticket_items.CustomMargins.Orientation} orientation |
| 383 * Specifies which margin value to get. |
| 384 * @return {string} The value of the specified margin. |
| 385 */ |
| 386 get: function(orientation) { |
| 387 return this.value_[orientation]; |
| 388 }, |
| 389 |
| 390 /** |
| 391 * @param {print_preview.ticket_items.CustomMargins.Orientation} orientation |
| 392 * Specifies the margin to modify. |
| 393 * @param {string} value Updated value of the margin to modify. |
| 394 * @return {!print_preview.ticket_items.StringMargins} A new copy of |this| |
| 395 * with the modification made to the specified margin. |
| 396 */ |
| 397 set: function(orientation, value) { |
| 398 var newValue = {}; |
| 399 for (var o in this.value_) { |
| 400 newValue[o] = this.value_[o]; |
| 401 } |
| 402 newValue[orientation] = value; |
| 403 return new StringMargins( |
| 404 newValue[print_preview.ticket_items.CustomMargins.Orientation.TOP], |
| 405 newValue[print_preview.ticket_items.CustomMargins.Orientation.RIGHT], |
| 406 newValue[print_preview.ticket_items.CustomMargins.Orientation.BOTTOM], |
| 407 newValue[print_preview.ticket_items.CustomMargins.Orientation.LEFT]); |
| 408 } |
| 409 }; |
| 410 |
| 411 // Export |
| 412 return { |
| 413 CustomMargins: CustomMargins, |
| 414 StringMargins: StringMargins |
| 415 }; |
| 416 }); |
OLD | NEW |