OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of html; | 5 part of html; |
6 | 6 |
7 /** | 7 /** |
8 * A rectangle representing all the content of the element in the | 8 * A rectangle representing all the content of the element in the |
9 * [box model](http://www.w3.org/TR/CSS2/box.html). | 9 * [box model](http://www.w3.org/TR/CSS2/box.html). |
10 */ | 10 */ |
11 class _ContentCssRect extends CssRect { | 11 class _ContentCssRect extends CssRect { |
12 | 12 |
13 _ContentCssRect(element) : super(element); | 13 _ContentCssRect(Element element) : super(element); |
14 | 14 |
15 num get height => _element.offsetHeight + | 15 num get height => _element.offsetHeight + |
16 _addOrSubtractToBoxModel(_HEIGHT, _CONTENT); | 16 _addOrSubtractToBoxModel(_HEIGHT, _CONTENT); |
17 | 17 |
18 num get width => _element.offsetWidth + | 18 num get width => _element.offsetWidth + |
19 _addOrSubtractToBoxModel(_WIDTH, _CONTENT); | 19 _addOrSubtractToBoxModel(_WIDTH, _CONTENT); |
20 | 20 |
21 /** | 21 /** |
22 * Set the height to `newHeight`. | 22 * Set the height to `newHeight`. |
23 * | 23 * |
24 * newHeight can be either a [num] representing the height in pixels or a | 24 * newHeight can be either a [num] representing the height in pixels or a |
25 * [Dimension] object. Values of newHeight that are less than zero are | 25 * [Dimension] object. Values of newHeight that are less than zero are |
26 * converted to effectively setting the height to 0. This is equivalent to the | 26 * converted to effectively setting the height to 0. This is equivalent to the |
27 * `height` function in jQuery and the calculated `height` CSS value, | 27 * `height` function in jQuery and the calculated `height` CSS value, |
28 * converted to a num in pixels. | 28 * converted to a num in pixels. |
29 */ | 29 */ |
30 set height(newHeight) { | 30 set height(newHeight) { |
31 if (newHeight is Dimension) { | 31 if (newHeight is Dimension) { |
32 if (newHeight.value < 0) newHeight = new Dimension.px(0); | 32 if (newHeight.value < 0) newHeight = new Dimension.px(0); |
33 _element.style.height = newHeight.toString(); | 33 _element.style.height = newHeight.toString(); |
34 } else { | 34 } else if (newHeight is num) { |
35 if (newHeight < 0) newHeight = 0; | 35 if (newHeight < 0) newHeight = 0; |
36 _element.style.height = '${newHeight}px'; | 36 _element.style.height = '${newHeight}px'; |
| 37 } else { |
| 38 throw new ArgumentError("newHeight is not a Dimension or num"); |
37 } | 39 } |
38 } | 40 } |
39 | 41 |
40 /** | 42 /** |
41 * Set the current computed width in pixels of this element. | 43 * Set the current computed width in pixels of this element. |
42 * | 44 * |
43 * newWidth can be either a [num] representing the width in pixels or a | 45 * newWidth can be either a [num] representing the width in pixels or a |
44 * [Dimension] object. This is equivalent to the `width` function in jQuery | 46 * [Dimension] object. This is equivalent to the `width` function in jQuery |
45 * and the calculated | 47 * and the calculated |
46 * `width` CSS value, converted to a dimensionless num in pixels. | 48 * `width` CSS value, converted to a dimensionless num in pixels. |
47 */ | 49 */ |
48 set width(newWidth) { | 50 set width(newWidth) { |
49 if (newWidth is Dimension) { | 51 if (newWidth is Dimension) { |
50 if (newWidth.value < 0) newWidth = new Dimension.px(0); | 52 if (newWidth.value < 0) newWidth = new Dimension.px(0); |
51 _element.style.width = newWidth.toString(); | 53 _element.style.width = newWidth.toString(); |
52 } else { | 54 } else if (newWidth is num) { |
53 if (newWidth < 0) newWidth = 0; | 55 if (newWidth < 0) newWidth = 0; |
54 _element.style.width = '${newWidth}px'; | 56 _element.style.width = '${newWidth}px'; |
| 57 } else { |
| 58 throw new ArgumentError("newWidth is not a Dimension or num"); |
55 } | 59 } |
56 } | 60 } |
57 | 61 |
58 num get left => _element.getBoundingClientRect().left - | 62 num get left => _element.getBoundingClientRect().left - |
59 _addOrSubtractToBoxModel(['left'], _CONTENT); | 63 _addOrSubtractToBoxModel(['left'], _CONTENT); |
60 num get top => _element.getBoundingClientRect().top - | 64 num get top => _element.getBoundingClientRect().top - |
61 _addOrSubtractToBoxModel(['top'], _CONTENT); | 65 _addOrSubtractToBoxModel(['top'], _CONTENT); |
62 } | 66 } |
63 | 67 |
64 /** | 68 /** |
65 * A list of element content rectangles in the | 69 * A list of element content rectangles in the |
66 * [box model](http://www.w3.org/TR/CSS2/box.html). | 70 * [box model](http://www.w3.org/TR/CSS2/box.html). |
67 */ | 71 */ |
68 class _ContentCssListRect extends _ContentCssRect { | 72 class _ContentCssListRect extends _ContentCssRect { |
69 List<Element> _elementList; | 73 List<Element> _elementList; |
70 | 74 |
71 _ContentCssListRect(elementList) : super(elementList.first) { | 75 _ContentCssListRect(List<Element> elementList) : super(elementList.first) { |
72 _elementList = elementList; | 76 _elementList = elementList; |
73 } | 77 } |
74 | 78 |
75 /** | 79 /** |
76 * Set the height to `newHeight`. | 80 * Set the height to `newHeight`. |
77 * | 81 * |
78 * Values of newHeight that are less than zero are converted to effectively | 82 * Values of newHeight that are less than zero are converted to effectively |
79 * setting the height to 0. This is equivalent to the `height` | 83 * setting the height to 0. This is equivalent to the `height` |
80 * function in jQuery and the calculated `height` CSS value, converted to a | 84 * function in jQuery and the calculated `height` CSS value, converted to a |
81 * num in pixels. | 85 * num in pixels. |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 * | 154 * |
151 * In contrast to the more general purpose [Rectangle] class, this class's | 155 * In contrast to the more general purpose [Rectangle] class, this class's |
152 * values are mutable, so one can change the height of an element | 156 * values are mutable, so one can change the height of an element |
153 * programmatically. | 157 * programmatically. |
154 * | 158 * |
155 * _Important_ _note_: use of these methods will perform CSS calculations that | 159 * _Important_ _note_: use of these methods will perform CSS calculations that |
156 * can trigger a browser reflow. Therefore, use of these properties _during_ an | 160 * can trigger a browser reflow. Therefore, use of these properties _during_ an |
157 * animation frame is discouraged. See also: | 161 * animation frame is discouraged. See also: |
158 * [Browser Reflow](https://developers.google.com/speed/articles/reflow) | 162 * [Browser Reflow](https://developers.google.com/speed/articles/reflow) |
159 */ | 163 */ |
160 abstract class CssRect extends MutableRectangle<num> { | 164 abstract class CssRect implements Rectangle<num> { |
161 Element _element; | 165 Element _element; |
162 | 166 |
163 CssRect(this._element) : super(0, 0, 0, 0); | 167 CssRect(this._element); |
164 | 168 |
165 num get left; | 169 num get left; |
166 | 170 |
167 num get top; | 171 num get top; |
168 | 172 |
169 /** | 173 /** |
170 * The height of this rectangle. | 174 * The height of this rectangle. |
171 * | 175 * |
172 * This is equivalent to the `height` function in jQuery and the calculated | 176 * This is equivalent to the `height` function in jQuery and the calculated |
173 * `height` CSS value, converted to a dimensionless num in pixels. Unlike | 177 * `height` CSS value, converted to a dimensionless num in pixels. Unlike |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 | 250 |
247 // At this point, we don't wan't to augment with border or margin, | 251 // At this point, we don't wan't to augment with border or margin, |
248 // so remove border. | 252 // so remove border. |
249 if (augmentingMeasurement != _MARGIN) { | 253 if (augmentingMeasurement != _MARGIN) { |
250 val -= new Dimension.css(styles.getPropertyValue( | 254 val -= new Dimension.css(styles.getPropertyValue( |
251 'border-${measurement}-width')).value; | 255 'border-${measurement}-width')).value; |
252 } | 256 } |
253 } | 257 } |
254 return val; | 258 return val; |
255 } | 259 } |
| 260 |
| 261 // TODO(jacobr): these methods are duplicated from _RectangleBase in dart:math |
| 262 // Ideally we would provide a RectangleMixin class that provides this implemen
tation. |
| 263 // In an ideal world we would exp |
| 264 /** The x-coordinate of the right edge. */ |
| 265 num get right => left + width; |
| 266 /** The y-coordinate of the bottom edge. */ |
| 267 num get bottom => top + height; |
| 268 |
| 269 String toString() { |
| 270 return 'Rectangle ($left, $top) $width x $height'; |
| 271 } |
| 272 |
| 273 bool operator ==(other) { |
| 274 if (other is !Rectangle) return false; |
| 275 return left == other.left && top == other.top && right == other.right && |
| 276 bottom == other.bottom; |
| 277 } |
| 278 |
| 279 int get hashCode => _JenkinsSmiHash.hash4(left.hashCode, top.hashCode, |
| 280 right.hashCode, bottom.hashCode); |
| 281 |
| 282 /** |
| 283 * Computes the intersection of `this` and [other]. |
| 284 * |
| 285 * The intersection of two axis-aligned rectangles, if any, is always another |
| 286 * axis-aligned rectangle. |
| 287 * |
| 288 * Returns the intersection of this and `other`, or `null` if they don't |
| 289 * intersect. |
| 290 */ |
| 291 Rectangle<num> intersection(Rectangle<num> other) { |
| 292 var x0 = max(left, other.left); |
| 293 var x1 = min(left + width, other.left + other.width); |
| 294 |
| 295 if (x0 <= x1) { |
| 296 var y0 = max(top, other.top); |
| 297 var y1 = min(top + height, other.top + other.height); |
| 298 |
| 299 if (y0 <= y1) { |
| 300 return new Rectangle<num>(x0, y0, x1 - x0, y1 - y0); |
| 301 } |
| 302 } |
| 303 return null; |
| 304 } |
| 305 |
| 306 |
| 307 /** |
| 308 * Returns true if `this` intersects [other]. |
| 309 */ |
| 310 bool intersects(Rectangle<num> other) { |
| 311 return (left <= other.left + other.width && |
| 312 other.left <= left + width && |
| 313 top <= other.top + other.height && |
| 314 other.top <= top + height); |
| 315 } |
| 316 |
| 317 /** |
| 318 * Returns a new rectangle which completely contains `this` and [other]. |
| 319 */ |
| 320 Rectangle<num> boundingBox(Rectangle<num> other) { |
| 321 var right = max(this.left + this.width, other.left + other.width); |
| 322 var bottom = max(this.top + this.height, other.top + other.height); |
| 323 |
| 324 var left = min(this.left, other.left); |
| 325 var top = min(this.top, other.top); |
| 326 |
| 327 return new Rectangle<num>(left, top, right - left, bottom - top); |
| 328 } |
| 329 |
| 330 /** |
| 331 * Tests whether `this` entirely contains [another]. |
| 332 */ |
| 333 bool containsRectangle(Rectangle<num> another) { |
| 334 return left <= another.left && |
| 335 left + width >= another.left + another.width && |
| 336 top <= another.top && |
| 337 top + height >= another.top + another.height; |
| 338 } |
| 339 |
| 340 /** |
| 341 * Tests whether [another] is inside or along the edges of `this`. |
| 342 */ |
| 343 bool containsPoint(Point<num> another) { |
| 344 return another.x >= left && |
| 345 another.x <= left + width && |
| 346 another.y >= top && |
| 347 another.y <= top + height; |
| 348 } |
| 349 |
| 350 Point<num> get topLeft => new Point<num>(this.left, this.top); |
| 351 Point<num> get topRight => new Point<num>(this.left + this.width, this.top); |
| 352 Point<num> get bottomRight => new Point<num>(this.left + this.width, |
| 353 this.top + this.height); |
| 354 Point<num> get bottomLeft => new Point<num>(this.left, |
| 355 this.top + this.height); |
256 } | 356 } |
257 | 357 |
258 final _HEIGHT = ['top', 'bottom']; | 358 final _HEIGHT = ['top', 'bottom']; |
259 final _WIDTH = ['right', 'left']; | 359 final _WIDTH = ['right', 'left']; |
260 final _CONTENT = 'content'; | 360 final _CONTENT = 'content'; |
261 final _PADDING = 'padding'; | 361 final _PADDING = 'padding'; |
262 final _MARGIN = 'margin'; | 362 final _MARGIN = 'margin'; |
OLD | NEW |