Index: chrome/browser/resources/print_preview/data/ticket_items/custom_margins.js |
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 |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ae55630477e91d3587a6743327ef858245b9568c |
--- /dev/null |
+++ b/chrome/browser/resources/print_preview/data/ticket_items/custom_margins.js |
@@ -0,0 +1,416 @@ |
+// 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.ticket_items', function() { |
+ 'use strict'; |
+ |
+ /** |
+ * Custom page margins ticket item whose value is a |
+ * {@code print_preview.ticket_items.StringMargins}. The margin values need to |
+ * be represented by a string since the user can textually input the values. |
+ * @param {!print_preview.DocumentInfo} documentInfo Information about the |
+ * document to print. |
+ * @param {!print_preview.MeasurementSystem} measurementSystem Used to convert |
+ * from string input into measurements in points. |
+ * @constructor |
+ * @extends {print_preview.ticket_items.TicketItem} |
+ */ |
+ function CustomMargins(documentInfo, measurementSystem) { |
+ print_preview.ticket_items.TicketItem.call(this); |
+ |
+ /** |
+ * Information about the document to print. |
+ * @type {!print_preview.DocumentInfo} |
+ * @private |
+ */ |
+ this.documentInfo_ = documentInfo; |
+ |
+ /** |
+ * Used to convert from string input to measurements in points. |
+ * @type {!print_preview.MeasurementSystem} |
+ * @private |
+ */ |
+ this.measurementSystem_ = measurementSystem; |
+ |
+ /** |
+ * Default value of the ticket item in points. |
+ * @type {!print_preview.Margins} |
+ * @private |
+ */ |
+ this.defaultValueInPts_ = new print_preview.Margins(72, 72, 72, 72); |
+ |
+ /** |
+ * Cache of the the ticket item's value in points. |
+ * @type {print_preview.Margins} |
+ * @private |
+ */ |
+ this.valueInPts_ = null; |
+ }; |
+ |
+ /** |
+ * Enumeration of the orientations of margins. |
+ * @enum {string} |
+ */ |
+ CustomMargins.Orientation = { |
+ TOP: 'top', |
+ RIGHT: 'right', |
+ BOTTOM: 'bottom', |
+ LEFT: 'left' |
+ }; |
+ |
+ /** |
+ * Precision used to convert from number in points to string in local units. |
+ * @type {number} |
+ * @const |
+ * @private |
+ */ |
+ CustomMargins.PRECISION_ = 3; |
+ |
+ /** |
+ * Minimum distance in points two margins can be separated by. |
+ * @type {number} |
+ * @const |
+ * @private |
+ */ |
+ CustomMargins.MINIMUM_MARGINS_DISTANCE_ = 72; // 1 inch. |
+ |
+ CustomMargins.prototype = { |
+ __proto__: print_preview.ticket_items.TicketItem.prototype, |
+ |
+ /** @override */ |
+ wouldValueBeValid: function(value) { |
+ var stringMargins = |
+ /** @type {!print_preview.ticket_items.StringMargins} */ (value); |
+ var marginsInPts = this.parseStringMarginsToPts_(stringMargins); |
+ if (marginsInPts == null) { |
+ return false; |
+ } |
+ for (var key in CustomMargins.Orientation) { |
+ var o = CustomMargins.Orientation[key]; |
+ var max = this.getMarginMaxInPts_(o, marginsInPts.getOpposite(o)); |
+ max = this.measurementSystem_.convertFromPoints(max, true); |
+ var min = this.getMarginMinInPts_(o); |
+ min = this.measurementSystem_.convertFromPoints(min, false); |
+ var margin = |
+ this.measurementSystem_.convertFromPoints(marginsInPts.get(o)); |
+ if (margin > max || margin < min) { |
+ return false; |
+ } |
+ } |
+ return true; |
+ }, |
+ |
+ /** @override */ |
+ isCapabilityAvailable: function() { |
+ return this.documentInfo_.isModifiable; |
+ }, |
+ |
+ /** |
+ * @param {print_preview.ticket_items.CustomMargins.Orientation} orientation |
+ * Specifies which margin to check if parseable. |
+ * @return {boolean} Whether the specified margin is parseable. |
+ */ |
+ isMarginParseable: function(orientation) { |
+ return this.parseToPts_(this.getValue().get(orientation)) != null; |
+ }, |
+ |
+ /** |
+ * @return {!print_preview.Margins} The ticket items custom margins in |
+ * points. |
+ */ |
+ getValueInPts: function() { |
+ if (this.valueInPts_ == null) { |
+ var stringMargins = |
+ /** @type {!print_preview.ticket_items.StringMargins} */ ( |
+ this.getValue()); |
+ this.valueInPts_ = this.parseStringMarginsToPts_(stringMargins); |
+ if (this.valueInPts_ == null) { |
+ throw Error('Error while parsing margin values into points'); |
+ } |
+ } |
+ return this.valueInPts_; |
+ }, |
+ |
+ /** @override */ |
+ updateValue: function(value) { |
+ print_preview.ticket_items.TicketItem.prototype.updateValue.call( |
+ this, value); |
+ this.valueInPts_ = null; |
+ }, |
+ |
+ /** |
+ * Updates the value of the ticket item with the given margins in points. |
+ * @param {!print_preview.Margins} valueInPts Updated margins in points. |
+ */ |
+ updateValueInPts: function(valueInPts) { |
+ var o = CustomMargins.Orientation; |
+ this.updateValue(new StringMargins( |
+ this.serializeMarginFromPts(valueInPts.get(o.TOP)), |
+ this.serializeMarginFromPts(valueInPts.get(o.RIGHT)), |
+ this.serializeMarginFromPts(valueInPts.get(o.BOTTOM)), |
+ this.serializeMarginFromPts(valueInPts.get(o.LEFT)))); |
+ this.valueInPts_ = valueInPts; |
+ }, |
+ |
+ /** |
+ * Updates the specified margin with a value in points. |
+ * @param {print_preview.ticket_items.CustomMargins.Orientation} orientation |
+ * Specifies the margin to update. |
+ * @param {number} valueInPts Updated margin in points. |
+ */ |
+ updateMarginInPts: function(orientation, valueInPts) { |
+ this.updateMargin(orientation, this.serializeMarginFromPts(valueInPts)); |
+ }, |
+ |
+ /** |
+ * Updates the specified margin with the given string input. |
+ * @param {print_preview.ticket_items.CustomMargins.Orientation} orientation |
+ * Specifies the margin to update. |
+ * @param {string} value Updated string value of the margin. |
+ */ |
+ updateMargin: function(orientation, value) { |
+ var stringMargins = |
+ /** @type {!print_preview.ticket_items.StringMargins} */ ( |
+ this.getValue()); |
+ var newStringMargins = stringMargins.set(orientation, value); |
+ var newMarginsInPts = this.parseStringMarginsToPts_(newStringMargins); |
+ if (newMarginsInPts != null) { |
+ // Put updated margin within the valid range (between min and max). |
+ var min = this.getMarginMinInPts_(orientation); |
+ min = this.measurementSystem_.convertFromPoints(min); |
+ var max = this.getMarginMaxInPts_( |
+ orientation, newMarginsInPts.getOpposite(orientation)); |
+ max = this.measurementSystem_.convertFromPoints(max); |
+ var newValue = this.measurementSystem_.convertFromPoints( |
+ newMarginsInPts.get(orientation)); |
+ newValue = Math.max(min, Math.min(max, newValue)); |
+ this.updateValueInPts(newMarginsInPts.set( |
+ orientation, this.measurementSystem_.convertToPoints(newValue))); |
+ } else { |
+ this.updateValue(newStringMargins); |
+ } |
+ }, |
+ |
+ /** |
+ * Updates the default value of the margins ticket item. This value is used |
+ * if the ticket item has not been edited by the user. |
+ * @param {!print_preview.Margins} valueInPts Updated margin default values. |
+ */ |
+ updateDefaultValueInPts: function(valueInPts) { |
+ this.defaultValueInPts_ = valueInPts; |
+ this.valueInPts_ = null; |
+ }, |
+ |
+ /** |
+ * @param {number} marginInPts Value of in points to serialize to a locale |
+ * string. |
+ * @return {string} Serialized form of the given value in points. The |
+ * serialized value is in the user's local measurement system. |
+ */ |
+ serializeMarginFromPts: function(marginInPts) { |
+ return this.measurementSystem_.convertFromPoints(marginInPts) + |
+ this.measurementSystem_.unitSymbol; |
+ }, |
+ |
+ /** @override */ |
+ getDefaultValueInternal: function() { |
+ return new StringMargins( |
+ this.serializeMarginFromPts( |
+ this.defaultValueInPts_.get(CustomMargins.Orientation.TOP)), |
+ this.serializeMarginFromPts( |
+ this.defaultValueInPts_.get(CustomMargins.Orientation.RIGHT)), |
+ this.serializeMarginFromPts( |
+ this.defaultValueInPts_.get(CustomMargins.Orientation.BOTTOM)), |
+ this.serializeMarginFromPts( |
+ this.defaultValueInPts_.get(CustomMargins.Orientation.LEFT))); |
+ }, |
+ |
+ /** @override */ |
+ getCapabilityNotAvailableValueInternal: function() { |
+ return this.getDefaultValueInternal(); |
+ }, |
+ |
+ /** |
+ * @param {print_preview.ticket_items.CustomMargins.Orientation} orientation |
+ * Specifies which margin to get the maximum value of. |
+ * @param {number} oppositeMarginInPts Value of the margin in points |
+ * opposite the specified margin. |
+ * @return {number} Maximum value in points of the specified margin. |
+ * @private |
+ */ |
+ getMarginMaxInPts_: function(orientation, oppositeMarginInPts) { |
+ if (orientation == CustomMargins.Orientation.TOP) { |
+ return this.documentInfo_.pageSize.height - |
+ this.documentInfo_.printableArea.origin.y - |
+ oppositeMarginInPts - |
+ CustomMargins.MINIMUM_MARGINS_DISTANCE_; |
+ } else if (orientation == CustomMargins.Orientation.RIGHT) { |
+ return this.documentInfo_.pageSize.width - |
+ this.documentInfo_.printableArea.origin.x - |
+ oppositeMarginInPts - |
+ CustomMargins.MINIMUM_MARGINS_DISTANCE_; |
+ } else if (orientation == CustomMargins.Orientation.BOTTOM) { |
+ return this.documentInfo_.pageSize.height - |
+ this.documentInfo_.printableArea.origin.y - |
+ oppositeMarginInPts - |
+ CustomMargins.MINIMUM_MARGINS_DISTANCE_; |
+ } else { |
+ return this.documentInfo_.pageSize.width - |
+ this.documentInfo_.printableArea.origin.x - |
+ oppositeMarginInPts - |
+ CustomMargins.MINIMUM_MARGINS_DISTANCE_; |
+ } |
+ }, |
+ |
+ /** |
+ * @param {print_preview.ticket_items.CustomMargins.Orientation} orientation |
+ * Specifies which margin to get the minimum value of. |
+ * @return {number} Minimum value in points of the specified margin. |
+ * @private |
+ */ |
+ getMarginMinInPts_: function(orientation) { |
+ if (orientation == CustomMargins.Orientation.TOP) { |
+ return this.documentInfo_.printableArea.origin.y; |
+ } else if (orientation == CustomMargins.Orientation.RIGHT) { |
+ return this.documentInfo_.pageSize.width - |
+ this.documentInfo_.printableArea.origin.x - |
+ this.documentInfo_.printableArea.size.width; |
+ } else if (orientation == CustomMargins.Orientation.BOTTOM) { |
+ return this.documentInfo_.pageSize.height - |
+ this.documentInfo_.printableArea.origin.y - |
+ this.documentInfo_.printableArea.size.height; |
+ } else { |
+ return this.documentInfo_.printableArea.origin.x; |
+ } |
+ }, |
+ |
+ /** |
+ * Parses the size of a margin in points from the given string. |
+ * Example: "1.00", "1", ".5", "1.1" are valid values. |
+ * Example: "1.4dsf", "-1" are invalid. |
+ * Note: The inch symbol (") at the end of |text| is allowed. |
+ * @param {string} text The text to parse. |
+ * @param {print_preview.MeasurementSystem} measurementSystem Used to handle |
+ * parsing local units. |
+ * @return {?number} The margin value represented by |text| in points or |
+ * {@code null} if |text| does not represent a valid value. |
+ * @private |
+ */ |
+ parseToPts_: function(text) { |
+ // Removing whitespace anywhere in the string. |
+ text = text.replace(/\s*/g, ''); |
+ if (text.length == 0) { |
+ return null; |
+ } |
+ var validationRegex = new RegExp('^(^-?)(\\d)+(\\' + |
+ this.measurementSystem_.thousandsDelimeter + '\\d{3})*(\\' + |
+ this.measurementSystem_.decimalDelimeter + '\\d*)?' + |
+ '(' + this.measurementSystem_.unitSymbol + ')?$'); |
+ if (validationRegex.test(text)) { |
+ // Replacing decimal point with the dot symbol in order to use |
+ // parseFloat() properly. |
+ var replacementRegex = |
+ new RegExp('\\' + this.measurementSystem_.decimalDelimeter + '{1}'); |
+ text = text.replace(replacementRegex, '.'); |
+ return this.measurementSystem_.convertToPoints(parseFloat(text)); |
+ } |
+ return null; |
+ }, |
+ |
+ /** |
+ * Parses the given string margins into margins in points. |
+ * @param {!print_preview.ticket_items.StringMargins} stringMargins String |
+ * margins to parse. |
+ * @return {print_preview.Margins} The parsed margins in points, or |
+ * {@code null} if the string margins could not be parsed. |
+ * @private |
+ */ |
+ parseStringMarginsToPts_: function(stringMargins) { |
+ var topInPts = |
+ this.parseToPts_(stringMargins.get(CustomMargins.Orientation.TOP)); |
+ var rightInPts = |
+ this.parseToPts_(stringMargins.get(CustomMargins.Orientation.RIGHT)); |
+ var bottomInPts = |
+ this.parseToPts_(stringMargins.get(CustomMargins.Orientation.BOTTOM)); |
+ var leftInPts = |
+ this.parseToPts_(stringMargins.get(CustomMargins.Orientation.LEFT)); |
+ if (topInPts == null || |
+ rightInPts == null || |
+ bottomInPts == null || |
+ leftInPts == null) { |
+ return null; |
+ } |
+ return new print_preview.Margins( |
+ topInPts, rightInPts, bottomInPts, leftInPts); |
+ } |
+ }; |
+ |
+ /** |
+ * An immutable object that represents page margins as strings of values in |
+ * the system's local measurement system. |
+ * @param {string} top Top margin expressed as a string in the local |
+ * measurement system. |
+ * @param {string} right Right margin expressed as a string in the local |
+ * measurement system. |
+ * @param {string} bottom Bottom margin expressed as a string in the local |
+ * measurement system. |
+ * @param {string} left Left margin expressed as a string in the local |
+ * measurement system. |
+ * @constructor |
+ */ |
+ function StringMargins(top, right, bottom, left) { |
+ /** |
+ * Backing store for the margin values. |
+ * @type {Object.< |
+ * print_preview.ticket_items.CustomMargins.Orientation, |
+ * string>} |
+ * @private |
+ */ |
+ this.value_ = {}; |
+ this.value_[print_preview.ticket_items.CustomMargins.Orientation.TOP] = top; |
+ this.value_[print_preview.ticket_items.CustomMargins.Orientation.RIGHT] = |
+ right; |
+ this.value_[print_preview.ticket_items.CustomMargins.Orientation.BOTTOM] = |
+ bottom; |
+ this.value_[print_preview.ticket_items.CustomMargins.Orientation.LEFT] = |
+ left; |
+ }; |
+ |
+ StringMargins.prototype = { |
+ /** |
+ * @param {print_preview.ticket_items.CustomMargins.Orientation} orientation |
+ * Specifies which margin value to get. |
+ * @return {string} The value of the specified margin. |
+ */ |
+ get: function(orientation) { |
+ return this.value_[orientation]; |
+ }, |
+ |
+ /** |
+ * @param {print_preview.ticket_items.CustomMargins.Orientation} orientation |
+ * Specifies the margin to modify. |
+ * @param {string} value Updated value of the margin to modify. |
+ * @return {!print_preview.ticket_items.StringMargins} A new copy of |this| |
+ * with the modification made to the specified margin. |
+ */ |
+ set: function(orientation, value) { |
+ var newValue = {}; |
+ for (var o in this.value_) { |
+ newValue[o] = this.value_[o]; |
+ } |
+ newValue[orientation] = value; |
+ return new StringMargins( |
+ newValue[print_preview.ticket_items.CustomMargins.Orientation.TOP], |
+ newValue[print_preview.ticket_items.CustomMargins.Orientation.RIGHT], |
+ newValue[print_preview.ticket_items.CustomMargins.Orientation.BOTTOM], |
+ newValue[print_preview.ticket_items.CustomMargins.Orientation.LEFT]); |
+ } |
+ }; |
+ |
+ // Export |
+ return { |
+ CustomMargins: CustomMargins, |
+ StringMargins: StringMargins |
+ }; |
+}); |