OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * @fileoverview This implements a splitter element which can be used to resize | 6 * @fileoverview This implements a splitter element which can be used to resize |
7 * elements in split panes. | 7 * elements in split panes. |
8 * | 8 * |
9 * The parent of the splitter should be an hbox (display: -webkit-box) with at | 9 * The parent of the splitter should be an hbox (display: -webkit-box) with at |
10 * least one previous element sibling. The splitter controls the width of the | 10 * least one previous element sibling. The splitter controls the width of the |
(...skipping 24 matching lines...) Expand all Loading... |
35 | 35 |
36 /** | 36 /** |
37 * This uses a WebKit bug to work around the same bug. getComputedStyle does | 37 * This uses a WebKit bug to work around the same bug. getComputedStyle does |
38 * not take the page zoom into account so it returns the physical pixels | 38 * not take the page zoom into account so it returns the physical pixels |
39 * instead of the logical pixel size. | 39 * instead of the logical pixel size. |
40 * @param {!Document} doc The document to get the page zoom factor for. | 40 * @param {!Document} doc The document to get the page zoom factor for. |
41 * @return {number} The zoom factor of the document. | 41 * @return {number} The zoom factor of the document. |
42 */ | 42 */ |
43 function getZoomFactor(doc) { | 43 function getZoomFactor(doc) { |
44 var dummyElement = doc.createElement('div'); | 44 var dummyElement = doc.createElement('div'); |
45 dummyElement.style.cssText = | 45 dummyElement.style.cssText = 'position:absolute;width:100px;height:100px;' + |
46 'position:absolute;width:100px;height:100px;top:-1000px;overflow:hidden'; | 46 'top:-1000px;overflow:hidden'; |
47 doc.body.appendChild(dummyElement); | 47 doc.body.appendChild(dummyElement); |
48 var cs = doc.defaultView.getComputedStyle(dummyElement); | 48 var cs = doc.defaultView.getComputedStyle(dummyElement); |
49 var rect = dummyElement.getBoundingClientRect(); | 49 var rect = dummyElement.getBoundingClientRect(); |
50 var zoomFactor = parseFloat(cs.width) / 100; | 50 var zoomFactor = parseFloat(cs.width) / 100; |
51 doc.body.removeChild(dummyElement); | 51 doc.body.removeChild(dummyElement); |
52 return zoomFactor; | 52 return zoomFactor; |
53 } | 53 } |
54 | 54 |
55 /** | 55 /** |
56 * Creates a new splitter element. | 56 * Creates a new splitter element. |
57 * @param {Object=} opt_propertyBag Optional properties. | 57 * @param {Object=} opt_propertyBag Optional properties. |
58 * @constructor | 58 * @constructor |
59 * @extends {HTMLDivElement} | 59 * @extends {HTMLDivElement} |
60 */ | 60 */ |
61 var Splitter = cr.ui.define('div'); | 61 var Splitter = cr.ui.define('div'); |
62 | 62 |
63 Splitter.prototype = { | 63 Splitter.prototype = { |
64 __proto__: HTMLDivElement.prototype, | 64 __proto__: HTMLDivElement.prototype, |
65 | 65 |
66 /** | 66 /** |
67 * Initializes the element. | 67 * Initializes the element. |
68 */ | 68 */ |
69 decorate: function() { | 69 decorate: function() { |
70 this.addEventListener('mousedown', this.handleMouseDown_.bind(this), | 70 this.addEventListener( |
71 true); | 71 'mousedown', this.handleMouseDown_.bind(this), true); |
72 this.addEventListener('touchstart', this.handleTouchStart_.bind(this), | 72 this.addEventListener( |
73 true); | 73 'touchstart', this.handleTouchStart_.bind(this), true); |
74 this.resizeNextElement_ = false; | 74 this.resizeNextElement_ = false; |
75 }, | 75 }, |
76 | 76 |
77 /** | 77 /** |
78 * @param {boolean} resizeNext True if resize the next element. | 78 * @param {boolean} resizeNext True if resize the next element. |
79 * By default, splitter resizes previous (left) element. | 79 * By default, splitter resizes previous (left) element. |
80 */ | 80 */ |
81 set resizeNextElement(resizeNext) { | 81 set resizeNextElement(resizeNext) { this.resizeNextElement_ = resizeNext; }, |
82 this.resizeNextElement_ = resizeNext; | |
83 }, | |
84 | 82 |
85 /** | 83 /** |
86 * Starts the dragging of the splitter. Adds listeners for mouse or touch | 84 * Starts the dragging of the splitter. Adds listeners for mouse or touch |
87 * events and calls splitter drag start handler. | 85 * events and calls splitter drag start handler. |
88 * @param {number} clientX X position of the mouse or touch event that | 86 * @param {number} clientX X position of the mouse or touch event that |
89 * started the drag. | 87 * started the drag. |
90 * @param {boolean} isTouchEvent True if the drag started by touch event. | 88 * @param {boolean} isTouchEvent True if the drag started by touch event. |
91 */ | 89 */ |
92 startDrag: function(clientX, isTouchEvent) { | 90 startDrag: function(clientX, isTouchEvent) { |
93 if (this.handlers_) { | 91 if (this.handlers_) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 calcDeltaX_: function(deltaX) { | 153 calcDeltaX_: function(deltaX) { |
156 return this.resizeNextElement_ ? -deltaX : deltaX; | 154 return this.resizeNextElement_ ? -deltaX : deltaX; |
157 }, | 155 }, |
158 | 156 |
159 /** | 157 /** |
160 * Handles the mousedown event which starts the dragging of the splitter. | 158 * Handles the mousedown event which starts the dragging of the splitter. |
161 * @param {!Event} e The mouse event. | 159 * @param {!Event} e The mouse event. |
162 * @private | 160 * @private |
163 */ | 161 */ |
164 handleMouseDown_: function(e) { | 162 handleMouseDown_: function(e) { |
165 e = /** @type {!MouseEvent} */(e); | 163 e = /** @type {!MouseEvent} */ (e); |
166 if (e.button) | 164 if (e.button) |
167 return; | 165 return; |
168 this.startDrag(e.clientX, false); | 166 this.startDrag(e.clientX, false); |
169 // Default action is to start selection and to move focus. | 167 // Default action is to start selection and to move focus. |
170 e.preventDefault(); | 168 e.preventDefault(); |
171 }, | 169 }, |
172 | 170 |
173 /** | 171 /** |
174 * Handles the touchstart event which starts the dragging of the splitter. | 172 * Handles the touchstart event which starts the dragging of the splitter. |
175 * @param {!Event} e The touch event. | 173 * @param {!Event} e The touch event. |
176 * @private | 174 * @private |
177 */ | 175 */ |
178 handleTouchStart_: function(e) { | 176 handleTouchStart_: function(e) { |
179 e = /** @type {!TouchEvent} */(e); | 177 e = /** @type {!TouchEvent} */ (e); |
180 if (e.touches.length == 1) { | 178 if (e.touches.length == 1) { |
181 this.startDrag(e.touches[0].clientX, true); | 179 this.startDrag(e.touches[0].clientX, true); |
182 e.preventDefault(); | 180 e.preventDefault(); |
183 } | 181 } |
184 }, | 182 }, |
185 | 183 |
186 /** | 184 /** |
187 * Handles the mousemove event which moves the splitter as the user moves | 185 * Handles the mousemove event which moves the splitter as the user moves |
188 * the mouse. | 186 * the mouse. |
189 * @param {!MouseEvent} e The mouse event. | 187 * @param {!MouseEvent} e The mouse event. |
190 * @private | 188 * @private |
191 */ | 189 */ |
192 handleMouseMove_: function(e) { | 190 handleMouseMove_: function(e) { this.handleMove_(e.clientX); }, |
193 this.handleMove_(e.clientX); | |
194 }, | |
195 | 191 |
196 /** | 192 /** |
197 * Handles the touch move event. | 193 * Handles the touch move event. |
198 * @param {!TouchEvent} e The touch event. | 194 * @param {!TouchEvent} e The touch event. |
199 */ | 195 */ |
200 handleTouchMove_: function(e) { | 196 handleTouchMove_: function(e) { |
201 if (e.touches.length == 1) | 197 if (e.touches.length == 1) |
202 this.handleMove_(e.touches[0].clientX); | 198 this.handleMove_(e.touches[0].clientX); |
203 }, | 199 }, |
204 | 200 |
205 /** | 201 /** |
206 * Common part of handling mousemove and touchmove. Calls splitter drag | 202 * Common part of handling mousemove and touchmove. Calls splitter drag |
207 * move handler. | 203 * move handler. |
208 * @param {number} clientX X position of the mouse or touch event. | 204 * @param {number} clientX X position of the mouse or touch event. |
209 * @private | 205 * @private |
210 */ | 206 */ |
211 handleMove_: function(clientX) { | 207 handleMove_: function(clientX) { |
212 var rtl = this.ownerDocument.defaultView.getComputedStyle(this). | 208 var rtl = |
213 direction == 'rtl'; | 209 this.ownerDocument.defaultView.getComputedStyle(this).direction == |
| 210 'rtl'; |
214 var dirMultiplier = rtl ? -1 : 1; | 211 var dirMultiplier = rtl ? -1 : 1; |
215 var deltaX = dirMultiplier * (clientX - this.startX_); | 212 var deltaX = dirMultiplier * (clientX - this.startX_); |
216 this.handleSplitterDragMove(deltaX); | 213 this.handleSplitterDragMove(deltaX); |
217 }, | 214 }, |
218 | 215 |
219 /** | 216 /** |
220 * Handles the mouse up event which ends the dragging of the splitter. | 217 * Handles the mouse up event which ends the dragging of the splitter. |
221 * @param {!MouseEvent} e The mouse event. | 218 * @param {!MouseEvent} e The mouse event. |
222 * @private | 219 * @private |
223 */ | 220 */ |
224 handleMouseUp_: function(e) { | 221 handleMouseUp_: function(e) { this.endDrag_(); }, |
225 this.endDrag_(); | |
226 }, | |
227 | 222 |
228 /** | 223 /** |
229 * Handles start of the splitter dragging. Saves current width of the | 224 * Handles start of the splitter dragging. Saves current width of the |
230 * element being resized. | 225 * element being resized. |
231 * @protected | 226 * @protected |
232 */ | 227 */ |
233 handleSplitterDragStart: function() { | 228 handleSplitterDragStart: function() { |
234 // Use the computed width style as the base so that we can ignore what | 229 // Use the computed width style as the base so that we can ignore what |
235 // box sizing the element has. | 230 // box sizing the element has. |
236 var targetElement = this.getResizeTarget_(); | 231 var targetElement = this.getResizeTarget_(); |
237 var doc = targetElement.ownerDocument; | 232 var doc = targetElement.ownerDocument; |
238 this.startWidth_ = parseFloat( | 233 this.startWidth_ = |
239 doc.defaultView.getComputedStyle(targetElement).width); | 234 parseFloat(doc.defaultView.getComputedStyle(targetElement).width); |
240 }, | 235 }, |
241 | 236 |
242 /** | 237 /** |
243 * Handles splitter moves. Updates width of the element being resized. | 238 * Handles splitter moves. Updates width of the element being resized. |
244 * @param {number} deltaX The change of splitter horizontal position. | 239 * @param {number} deltaX The change of splitter horizontal position. |
245 * @protected | 240 * @protected |
246 */ | 241 */ |
247 handleSplitterDragMove: function(deltaX) { | 242 handleSplitterDragMove: function(deltaX) { |
248 var targetElement = this.getResizeTarget_(); | 243 var targetElement = this.getResizeTarget_(); |
249 var newWidth = this.startWidth_ + this.calcDeltaX_(deltaX); | 244 var newWidth = this.startWidth_ + this.calcDeltaX_(deltaX); |
250 targetElement.style.width = newWidth + 'px'; | 245 targetElement.style.width = newWidth + 'px'; |
251 }, | 246 }, |
252 | 247 |
253 /** | 248 /** |
254 * Handles end of the splitter dragging. This fires a 'resize' event if the | 249 * Handles end of the splitter dragging. This fires a 'resize' event if the |
255 * size changed. | 250 * size changed. |
256 * @protected | 251 * @protected |
257 */ | 252 */ |
258 handleSplitterDragEnd: function() { | 253 handleSplitterDragEnd: function() { |
259 // Check if the size changed. | 254 // Check if the size changed. |
260 var targetElement = this.getResizeTarget_(); | 255 var targetElement = this.getResizeTarget_(); |
261 var doc = targetElement.ownerDocument; | 256 var doc = targetElement.ownerDocument; |
262 var computedWidth = parseFloat( | 257 var computedWidth = |
263 doc.defaultView.getComputedStyle(targetElement).width); | 258 parseFloat(doc.defaultView.getComputedStyle(targetElement).width); |
264 if (this.startWidth_ != computedWidth) | 259 if (this.startWidth_ != computedWidth) |
265 cr.dispatchSimpleEvent(this, 'resize'); | 260 cr.dispatchSimpleEvent(this, 'resize'); |
266 }, | 261 }, |
267 }; | 262 }; |
268 | 263 |
269 return { | 264 return {Splitter: Splitter}; |
270 Splitter: Splitter | |
271 }; | |
272 }); | 265 }); |
OLD | NEW |