OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2011 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', function() { | |
6 'strict'; | |
7 | |
8 function MarginTextbox(groupName) { | |
9 var box = document.createElement('input'); | |
10 box.__proto__ = MarginTextbox.prototype; | |
11 box.setAttribute('type', 'text'); | |
12 box.className = MarginTextbox.CSS_CLASS_MARGIN_TEXTBOX; | |
13 box.value = '0'; | |
14 | |
15 // @type {string} Specifies which margin this line refers to. | |
16 box.marginGroup = groupName; | |
17 // @type {boolean} True if the displayed value is valid. | |
18 box.isValid = true; | |
19 // @type {number} Timer used to detect when the user stops typing. | |
20 box.timerId_ = null; | |
21 // @type {string} The last valid value diplayed. | |
22 box.lastValidValue = '0'; | |
23 // @type {print_preview.Rect} A rectangle describing the four margins. | |
24 box.marginsRectangle_ = null; | |
25 // @type {number} The upper allowed limit for the corresponding margin. | |
26 box.valueLimit = null; | |
27 | |
28 box.addEventListeners_(); | |
29 return box; | |
30 } | |
31 | |
32 MarginTextbox.CSS_CLASS_MARGIN_TEXTBOX = 'margin-box'; | |
33 MarginTextbox.MARGIN_BOX_HEIGHT = 15; | |
34 MarginTextbox.MARGIN_BOX_VERTICAL_PADDING = 5; | |
35 MarginTextbox.MARGIN_BOX_WIDTH = 40; | |
36 MarginTextbox.MARGIN_BOX_HORIZONTAL_PADDING = 10; | |
37 | |
38 // Keycode for the "Escape" key. | |
39 MarginTextbox.ESCAPE_KEYCODE = 27; | |
40 // Keycode for the "Enter" key. | |
41 MarginTextbox.ENTER_KEYCODE = 13; | |
42 | |
43 MarginTextbox.convertPointsToInchesText = function(toConvert) { | |
44 var inInches = | |
45 print_preview.MarginSettings.convertPointsToInches(toConvert); | |
46 return inInches.toFixed(2) + '"'; | |
47 }; | |
48 | |
49 /** | |
50 * @return {number} The total height of a margin textbox (including padding). | |
51 */ | |
52 MarginTextbox.totalHeight = function() { | |
53 return MarginTextbox.MARGIN_BOX_HEIGHT + | |
54 2 * MarginTextbox.MARGIN_BOX_VERTICAL_PADDING; | |
55 } | |
56 | |
57 /** | |
58 * @return {number} The total width of a margin textbox (including padding). | |
59 */ | |
60 MarginTextbox.totalWidth = function() { | |
61 return MarginTextbox.MARGIN_BOX_WIDTH + | |
62 2 * MarginTextbox.MARGIN_BOX_HORIZONTAL_PADDING; | |
63 } | |
64 | |
65 MarginTextbox.prototype = { | |
66 __proto__: HTMLInputElement.prototype, | |
67 | |
68 /** | |
69 * Updates the state of |this|. | |
70 * @param {print_preview.Rect} marginsRectangle A rectangle describing the | |
71 * margins in percentages. | |
72 * @param {number} value The margin value in points. | |
73 * @param {number} valueLimit The upper allowed value for the margin. | |
74 * @param {boolean} keepDisplayedValue True if the currently displayed value | |
75 * should not be updated. | |
76 */ | |
77 update: function(marginsRectangle, value, valueLimit, keepDisplayedValue) { | |
78 this.marginsRectangle_ = marginsRectangle; | |
79 this.lastValidValue = MarginTextbox.convertPointsToInchesText(value); | |
80 if (!keepDisplayedValue) | |
81 this.value = this.lastValidValue; | |
82 this.valueLimit = valueLimit; | |
83 this.validate(); | |
84 }, | |
85 | |
86 get margin() { | |
87 return print_preview.extractMarginValue(this.value); | |
88 }, | |
89 | |
90 /** | |
91 * Updates |this.isValid|. | |
92 */ | |
93 validate: function() { | |
94 this.isValid = print_preview.isMarginTextValid(this.value, | |
95 this.valueLimit); | |
96 }, | |
97 | |
98 /** | |
99 * Updates the background color depending on |isValid| by adding/removing | |
100 * the appropriate CSS class. | |
101 * @param {boolean} isValid True if the margin is valid. | |
102 */ | |
103 updateColor: function() { | |
104 this.isValid ? this.classList.remove('invalid') : | |
105 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.
| |
106 }, | |
107 | |
108 /** | |
109 * Draws this textbox. | |
110 */ | |
111 draw: function() { | |
112 var topLeft = this.getCoordinates_(); | |
113 var totalWidth = previewArea.pdfPlugin_.offsetWidth; | |
114 var totalHeight = previewArea.pdfPlugin_.offsetHeight; | |
115 | |
116 this.style.left = Math.round(topLeft.x * totalWidth) + 'px'; | |
117 this.style.top = Math.round(topLeft.y * totalHeight) + 'px'; | |
118 this.updateColor(); | |
119 }, | |
120 | |
121 /** | |
122 * @private | |
123 * @return {boolean} True if |this| refers to the top margin. | |
124 */ | |
125 isTop_: function() { | |
126 return this.marginGroup == print_preview.MarginSettings.TOP_GROUP; | |
127 }, | |
128 | |
129 /** | |
130 * @private | |
131 * @return {boolean} True if |this| refers to the bottom margin. | |
132 */ | |
133 isBottom_: function() { | |
134 return this.marginGroup == print_preview.MarginSettings.BOTTOM_GROUP; | |
135 }, | |
136 | |
137 /** | |
138 * @private | |
139 * @return {boolean} True if |this| refers to the left margin. | |
140 */ | |
141 isLeft_: function() { | |
142 return this.marginGroup == print_preview.MarginSettings.LEFT_GROUP; | |
143 }, | |
144 | |
145 /** | |
146 * @private | |
147 * @return {boolean} True if |this| refers to the bottom margin. | |
148 */ | |
149 isRight_: function() { | |
150 return this.marginGroup == print_preview.MarginSettings.RIGHT_GROUP; | |
151 }, | |
152 | |
153 /** | |
154 * Calculates the coordinates where |this| should be displayed. | |
155 * @private | |
156 * @return {Object} The coordinates (in percent) where |this| should be | |
157 * drawn relative to the upper left corner of the plugin. | |
158 */ | |
159 getCoordinates_: function() { | |
160 var point = { x: 0, y: 0 }; | |
161 var totalWidth = previewArea.pdfPlugin_.offsetWidth; | |
162 var totalHeight = previewArea.pdfPlugin_.offsetHeight; | |
163 | |
164 if (this.isTop_()) { | |
165 point.x = this.marginsRectangle_.x + | |
166 this.marginsRectangle_.width / 2 - | |
167 (MarginTextbox.totalWidth() / 2) / totalWidth; | |
168 point.y = this.marginsRectangle_.y; | |
169 } else if (this.isBottom_()) { | |
170 point.x = this.marginsRectangle_.x + | |
171 this.marginsRectangle_.width / 2 - | |
172 (MarginTextbox.totalWidth() / 2) / totalWidth; | |
173 point.y = this.marginsRectangle_.y + this.marginsRectangle_.height - | |
174 (MarginTextbox.totalHeight() / totalHeight); | |
175 } else if (this.isRight_()) { | |
176 point.x = this.marginsRectangle_.x + this.marginsRectangle_.width - | |
177 (MarginTextbox.totalWidth() / totalWidth); | |
178 point.y = this.marginsRectangle_.y + this.marginsRectangle_.height / 2 - | |
179 (MarginTextbox.totalHeight() / 2) / totalHeight; | |
180 } else if (this.isLeft_()) { | |
181 point.x = this.marginsRectangle_.x; | |
182 point.y = this.marginsRectangle_.y + this.marginsRectangle_.height / 2 - | |
183 (MarginTextbox.totalHeight() / 2) / totalHeight; | |
184 } | |
Evan Stade
2011/10/05 22:42:14
newline
dpapad
2011/10/06 00:05:39
Done.
| |
185 return point; | |
186 }, | |
187 | |
188 /** | |
189 * Adds event listeners for various events. | |
190 * @private | |
191 */ | |
192 addEventListeners_: function() { | |
193 this.oninput = this.resetTimer_.bind(this); | |
194 this.onblur = this.onBlur_.bind(this); | |
195 this.onkeypress = this.onKeyPressed_.bind(this); | |
196 this.onkeyup = this.onKeyUp_.bind(this); | |
197 }, | |
198 | |
199 /** | |
200 * Listener executing whenever a blur event occurs. | |
201 * @private | |
202 */ | |
203 onBlur_: function() { | |
204 clearTimeout(this.timerId_); | |
205 this.validate(); | |
206 if (!this.isValid) { | |
207 this.value = this.lastValidValue; | |
208 this.validate(); | |
209 } | |
Evan Stade
2011/10/05 22:42:14
newline
dpapad
2011/10/06 00:05:39
Done.
| |
210 this.updateColor(); | |
211 cr.dispatchSimpleEvent(document, 'updateSummary'); | |
212 cr.dispatchSimpleEvent(document, 'updatePrintButton'); | |
213 cr.dispatchSimpleEvent(this, 'MarginsMayHaveChanged'); | |
214 }, | |
215 | |
216 /** | |
217 * Listener executing whenever a keypressed event occurs. Note: Only the | |
218 * "Enter" key event is handled. The "Escape" key does not result in such | |
219 * event, therefor it is handled by |this.onKeyUp_|. | |
220 * @param {KeyboardEvent} e The event that triggered this listener. | |
221 * @private | |
222 */ | |
223 onKeyPressed_: function(e) { | |
224 if (e.keyCode == MarginTextbox.ENTER_KEYCODE) { | |
225 this.blur(); | |
226 } | |
Evan Stade
2011/10/05 22:42:14
no curlies
dpapad
2011/10/06 00:05:39
Done.
| |
227 }, | |
228 | |
229 /** | |
230 * Listener executing whenever a keyup event occurs. Note: Only the "Escape" | |
231 * key event is handled. | |
232 * @param {KeyboardEvent} e The event that triggered this listener. | |
233 * @private | |
234 */ | |
235 onKeyUp_: function(e) { | |
236 if (e.keyCode == MarginTextbox.ESCAPE_KEYCODE) { | |
237 this.value = this.lastValidValue; | |
238 this.validate(); | |
239 this.updateColor(); | |
240 cr.dispatchSimpleEvent(document, 'updateSummary'); | |
241 cr.dispatchSimpleEvent(document, 'updatePrintButton'); | |
242 } | |
243 }, | |
244 | |
245 /** | |
246 * Resetting the timer used to detect when the user stops typing in order | |
247 * to update the print preview. | |
248 * @private | |
249 */ | |
250 resetTimer_: function() { | |
251 clearTimeout(this.timerId_); | |
252 this.timerId_ = window.setTimeout( | |
253 this.onTextValueMayHaveChanged_.bind(this), 500); | |
254 }, | |
255 | |
256 /** | |
257 * Listener executing whenever the user stops typing. | |
258 * @private | |
259 */ | |
260 onTextValueMayHaveChanged_: function() { | |
261 this.validate(); | |
262 this.updateColor(); | |
263 cr.dispatchSimpleEvent(document, 'updateSummary'); | |
264 cr.dispatchSimpleEvent(document, 'updatePrintButton'); | |
265 | |
266 if (!this.isValid) | |
267 return; | |
268 cr.dispatchSimpleEvent(this, 'MarginsMayHaveChanged'); | |
269 } | |
270 | |
271 }; | |
272 | |
273 return { | |
274 MarginTextbox: MarginTextbox | |
275 }; | |
276 }); | |
OLD | NEW |