Chromium Code Reviews| Index: chrome/browser/resources/print_preview/margin_textbox.js |
| diff --git a/chrome/browser/resources/print_preview/margin_textbox.js b/chrome/browser/resources/print_preview/margin_textbox.js |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..c13b63423a2b16ce7ff50821a8baed1a3cf2ddbc |
| --- /dev/null |
| +++ b/chrome/browser/resources/print_preview/margin_textbox.js |
| @@ -0,0 +1,276 @@ |
| +// Copyright (c) 2011 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() { |
| + 'strict'; |
| + |
| + function MarginTextbox(groupName) { |
| + var box = document.createElement('input'); |
| + box.__proto__ = MarginTextbox.prototype; |
| + box.setAttribute('type', 'text'); |
| + box.className = MarginTextbox.CSS_CLASS_MARGIN_TEXTBOX; |
| + box.value = '0'; |
| + |
| + // @type {string} Specifies which margin this line refers to. |
| + box.marginGroup = groupName; |
| + // @type {boolean} True if the displayed value is valid. |
| + box.isValid = true; |
| + // @type {number} Timer used to detect when the user stops typing. |
| + box.timerId_ = null; |
| + // @type {string} The last valid value diplayed. |
| + box.lastValidValue = '0'; |
| + // @type {print_preview.Rect} A rectangle describing the four margins. |
| + box.marginsRectangle_ = null; |
| + // @type {number} The upper allowed limit for the corresponding margin. |
| + box.valueLimit = null; |
| + |
| + box.addEventListeners_(); |
| + return box; |
| + } |
| + |
| + MarginTextbox.CSS_CLASS_MARGIN_TEXTBOX = 'margin-box'; |
| + MarginTextbox.MARGIN_BOX_HEIGHT = 15; |
| + MarginTextbox.MARGIN_BOX_VERTICAL_PADDING = 5; |
| + MarginTextbox.MARGIN_BOX_WIDTH = 40; |
| + MarginTextbox.MARGIN_BOX_HORIZONTAL_PADDING = 10; |
| + |
| + // Keycode for the "Escape" key. |
| + MarginTextbox.ESCAPE_KEYCODE = 27; |
| + // Keycode for the "Enter" key. |
| + MarginTextbox.ENTER_KEYCODE = 13; |
| + |
| + MarginTextbox.convertPointsToInchesText = function(toConvert) { |
| + var inInches = |
| + print_preview.MarginSettings.convertPointsToInches(toConvert); |
| + return inInches.toFixed(2) + '"'; |
| + }; |
| + |
| + /** |
| + * @return {number} The total height of a margin textbox (including padding). |
| + */ |
| + MarginTextbox.totalHeight = function() { |
| + return MarginTextbox.MARGIN_BOX_HEIGHT + |
| + 2 * MarginTextbox.MARGIN_BOX_VERTICAL_PADDING; |
| + } |
| + |
| + /** |
| + * @return {number} The total width of a margin textbox (including padding). |
| + */ |
| + MarginTextbox.totalWidth = function() { |
| + return MarginTextbox.MARGIN_BOX_WIDTH + |
| + 2 * MarginTextbox.MARGIN_BOX_HORIZONTAL_PADDING; |
| + } |
| + |
| + MarginTextbox.prototype = { |
| + __proto__: HTMLInputElement.prototype, |
| + |
| + /** |
| + * Updates the state of |this|. |
| + * @param {print_preview.Rect} marginsRectangle A rectangle describing the |
| + * margins in percentages. |
| + * @param {number} value The margin value in points. |
| + * @param {number} valueLimit The upper allowed value for the margin. |
| + * @param {boolean} keepDisplayedValue True if the currently displayed value |
| + * should not be updated. |
| + */ |
| + update: function(marginsRectangle, value, valueLimit, keepDisplayedValue) { |
| + this.marginsRectangle_ = marginsRectangle; |
| + this.lastValidValue = MarginTextbox.convertPointsToInchesText(value); |
| + if (!keepDisplayedValue) |
| + this.value = this.lastValidValue; |
| + this.valueLimit = valueLimit; |
| + this.validate(); |
| + }, |
| + |
| + get margin() { |
| + return print_preview.extractMarginValue(this.value); |
| + }, |
| + |
| + /** |
| + * Updates |this.isValid|. |
| + */ |
| + validate: function() { |
| + this.isValid = print_preview.isMarginTextValid(this.value, |
| + this.valueLimit); |
| + }, |
| + |
| + /** |
| + * Updates the background color depending on |isValid| by adding/removing |
| + * the appropriate CSS class. |
| + * @param {boolean} isValid True if the margin is valid. |
| + */ |
| + updateColor: function() { |
| + this.isValid ? this.classList.remove('invalid') : |
| + this.classList.add('invalid'); |
|
Evan Stade
2011/10/05 22:42:14
I think lining up the return vals in a ternary sta
dpapad
2011/10/06 00:05:39
Done.
|
| + }, |
| + |
| + /** |
| + * Draws this textbox. |
| + */ |
| + draw: function() { |
| + var topLeft = this.getCoordinates_(); |
| + var totalWidth = previewArea.pdfPlugin_.offsetWidth; |
| + var totalHeight = previewArea.pdfPlugin_.offsetHeight; |
| + |
| + this.style.left = Math.round(topLeft.x * totalWidth) + 'px'; |
| + this.style.top = Math.round(topLeft.y * totalHeight) + 'px'; |
| + this.updateColor(); |
| + }, |
| + |
| + /** |
| + * @private |
| + * @return {boolean} True if |this| refers to the top margin. |
| + */ |
| + isTop_: function() { |
| + return this.marginGroup == print_preview.MarginSettings.TOP_GROUP; |
| + }, |
| + |
| + /** |
| + * @private |
| + * @return {boolean} True if |this| refers to the bottom margin. |
| + */ |
| + isBottom_: function() { |
| + return this.marginGroup == print_preview.MarginSettings.BOTTOM_GROUP; |
| + }, |
| + |
| + /** |
| + * @private |
| + * @return {boolean} True if |this| refers to the left margin. |
| + */ |
| + isLeft_: function() { |
| + return this.marginGroup == print_preview.MarginSettings.LEFT_GROUP; |
| + }, |
| + |
| + /** |
| + * @private |
| + * @return {boolean} True if |this| refers to the bottom margin. |
| + */ |
| + isRight_: function() { |
| + return this.marginGroup == print_preview.MarginSettings.RIGHT_GROUP; |
| + }, |
| + |
| + /** |
| + * Calculates the coordinates where |this| should be displayed. |
| + * @private |
| + * @return {Object} The coordinates (in percent) where |this| should be |
| + * drawn relative to the upper left corner of the plugin. |
| + */ |
| + getCoordinates_: function() { |
| + var point = { x: 0, y: 0 }; |
| + var totalWidth = previewArea.pdfPlugin_.offsetWidth; |
| + var totalHeight = previewArea.pdfPlugin_.offsetHeight; |
| + |
| + if (this.isTop_()) { |
| + point.x = this.marginsRectangle_.x + |
| + this.marginsRectangle_.width / 2 - |
| + (MarginTextbox.totalWidth() / 2) / totalWidth; |
| + point.y = this.marginsRectangle_.y; |
| + } else if (this.isBottom_()) { |
| + point.x = this.marginsRectangle_.x + |
| + this.marginsRectangle_.width / 2 - |
| + (MarginTextbox.totalWidth() / 2) / totalWidth; |
| + point.y = this.marginsRectangle_.y + this.marginsRectangle_.height - |
| + (MarginTextbox.totalHeight() / totalHeight); |
| + } else if (this.isRight_()) { |
| + point.x = this.marginsRectangle_.x + this.marginsRectangle_.width - |
| + (MarginTextbox.totalWidth() / totalWidth); |
| + point.y = this.marginsRectangle_.y + this.marginsRectangle_.height / 2 - |
| + (MarginTextbox.totalHeight() / 2) / totalHeight; |
| + } else if (this.isLeft_()) { |
| + point.x = this.marginsRectangle_.x; |
| + point.y = this.marginsRectangle_.y + this.marginsRectangle_.height / 2 - |
| + (MarginTextbox.totalHeight() / 2) / totalHeight; |
| + } |
|
Evan Stade
2011/10/05 22:42:14
newline
dpapad
2011/10/06 00:05:39
Done.
|
| + return point; |
| + }, |
| + |
| + /** |
| + * Adds event listeners for various events. |
| + * @private |
| + */ |
| + addEventListeners_: function() { |
| + this.oninput = this.resetTimer_.bind(this); |
| + this.onblur = this.onBlur_.bind(this); |
| + this.onkeypress = this.onKeyPressed_.bind(this); |
| + this.onkeyup = this.onKeyUp_.bind(this); |
| + }, |
| + |
| + /** |
| + * Listener executing whenever a blur event occurs. |
| + * @private |
| + */ |
| + onBlur_: function() { |
| + clearTimeout(this.timerId_); |
| + this.validate(); |
| + if (!this.isValid) { |
| + this.value = this.lastValidValue; |
| + this.validate(); |
| + } |
|
Evan Stade
2011/10/05 22:42:14
newline
dpapad
2011/10/06 00:05:39
Done.
|
| + this.updateColor(); |
| + cr.dispatchSimpleEvent(document, 'updateSummary'); |
| + cr.dispatchSimpleEvent(document, 'updatePrintButton'); |
| + cr.dispatchSimpleEvent(this, 'MarginsMayHaveChanged'); |
| + }, |
| + |
| + /** |
| + * Listener executing whenever a keypressed event occurs. Note: Only the |
| + * "Enter" key event is handled. The "Escape" key does not result in such |
| + * event, therefor it is handled by |this.onKeyUp_|. |
| + * @param {KeyboardEvent} e The event that triggered this listener. |
| + * @private |
| + */ |
| + onKeyPressed_: function(e) { |
| + if (e.keyCode == MarginTextbox.ENTER_KEYCODE) { |
| + this.blur(); |
| + } |
|
Evan Stade
2011/10/05 22:42:14
no curlies
dpapad
2011/10/06 00:05:39
Done.
|
| + }, |
| + |
| + /** |
| + * Listener executing whenever a keyup event occurs. Note: Only the "Escape" |
| + * key event is handled. |
| + * @param {KeyboardEvent} e The event that triggered this listener. |
| + * @private |
| + */ |
| + onKeyUp_: function(e) { |
| + if (e.keyCode == MarginTextbox.ESCAPE_KEYCODE) { |
| + this.value = this.lastValidValue; |
| + this.validate(); |
| + this.updateColor(); |
| + cr.dispatchSimpleEvent(document, 'updateSummary'); |
| + cr.dispatchSimpleEvent(document, 'updatePrintButton'); |
| + } |
| + }, |
| + |
| + /** |
| + * Resetting the timer used to detect when the user stops typing in order |
| + * to update the print preview. |
| + * @private |
| + */ |
| + resetTimer_: function() { |
| + clearTimeout(this.timerId_); |
| + this.timerId_ = window.setTimeout( |
| + this.onTextValueMayHaveChanged_.bind(this), 500); |
| + }, |
| + |
| + /** |
| + * Listener executing whenever the user stops typing. |
| + * @private |
| + */ |
| + onTextValueMayHaveChanged_: function() { |
| + this.validate(); |
| + this.updateColor(); |
| + cr.dispatchSimpleEvent(document, 'updateSummary'); |
| + cr.dispatchSimpleEvent(document, 'updatePrintButton'); |
| + |
| + if (!this.isValid) |
| + return; |
| + cr.dispatchSimpleEvent(this, 'MarginsMayHaveChanged'); |
| + } |
| + |
| + }; |
| + |
| + return { |
| + MarginTextbox: MarginTextbox |
| + }; |
| +}); |