| 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 | |
| 13 _ContentCssRect(Element element) : super(element); | 12 _ContentCssRect(Element element) : super(element); |
| 14 | 13 |
| 15 num get height => _element.offsetHeight + | 14 num get height => |
| 16 _addOrSubtractToBoxModel(_HEIGHT, _CONTENT); | 15 _element.offsetHeight + _addOrSubtractToBoxModel(_HEIGHT, _CONTENT); |
| 17 | 16 |
| 18 num get width => _element.offsetWidth + | 17 num get width => |
| 19 _addOrSubtractToBoxModel(_WIDTH, _CONTENT); | 18 _element.offsetWidth + _addOrSubtractToBoxModel(_WIDTH, _CONTENT); |
| 20 | 19 |
| 21 /** | 20 /** |
| 22 * Set the height to `newHeight`. | 21 * Set the height to `newHeight`. |
| 23 * | 22 * |
| 24 * newHeight can be either a [num] representing the height in pixels or a | 23 * 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 | 24 * [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 | 25 * converted to effectively setting the height to 0. This is equivalent to the |
| 27 * `height` function in jQuery and the calculated `height` CSS value, | 26 * `height` function in jQuery and the calculated `height` CSS value, |
| 28 * converted to a num in pixels. | 27 * converted to a num in pixels. |
| 29 */ | 28 */ |
| (...skipping 22 matching lines...) Expand all Loading... |
| 52 if (newWidth.value < 0) newWidth = new Dimension.px(0); | 51 if (newWidth.value < 0) newWidth = new Dimension.px(0); |
| 53 _element.style.width = newWidth.toString(); | 52 _element.style.width = newWidth.toString(); |
| 54 } else if (newWidth is num) { | 53 } else if (newWidth is num) { |
| 55 if (newWidth < 0) newWidth = 0; | 54 if (newWidth < 0) newWidth = 0; |
| 56 _element.style.width = '${newWidth}px'; | 55 _element.style.width = '${newWidth}px'; |
| 57 } else { | 56 } else { |
| 58 throw new ArgumentError("newWidth is not a Dimension or num"); | 57 throw new ArgumentError("newWidth is not a Dimension or num"); |
| 59 } | 58 } |
| 60 } | 59 } |
| 61 | 60 |
| 62 num get left => _element.getBoundingClientRect().left - | 61 num get left => |
| 62 _element.getBoundingClientRect().left - |
| 63 _addOrSubtractToBoxModel(['left'], _CONTENT); | 63 _addOrSubtractToBoxModel(['left'], _CONTENT); |
| 64 num get top => _element.getBoundingClientRect().top - | 64 num get top => |
| 65 _element.getBoundingClientRect().top - |
| 65 _addOrSubtractToBoxModel(['top'], _CONTENT); | 66 _addOrSubtractToBoxModel(['top'], _CONTENT); |
| 66 } | 67 } |
| 67 | 68 |
| 68 /** | 69 /** |
| 69 * A list of element content rectangles in the | 70 * A list of element content rectangles in the |
| 70 * [box model](http://www.w3.org/TR/CSS2/box.html). | 71 * [box model](http://www.w3.org/TR/CSS2/box.html). |
| 71 */ | 72 */ |
| 72 class _ContentCssListRect extends _ContentCssRect { | 73 class _ContentCssListRect extends _ContentCssRect { |
| 73 List<Element> _elementList; | 74 List<Element> _elementList; |
| 74 | 75 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 99 } | 100 } |
| 100 } | 101 } |
| 101 | 102 |
| 102 /** | 103 /** |
| 103 * A rectangle representing the dimensions of the space occupied by the | 104 * A rectangle representing the dimensions of the space occupied by the |
| 104 * element's content + padding in the | 105 * element's content + padding in the |
| 105 * [box model](http://www.w3.org/TR/CSS2/box.html). | 106 * [box model](http://www.w3.org/TR/CSS2/box.html). |
| 106 */ | 107 */ |
| 107 class _PaddingCssRect extends CssRect { | 108 class _PaddingCssRect extends CssRect { |
| 108 _PaddingCssRect(element) : super(element); | 109 _PaddingCssRect(element) : super(element); |
| 109 num get height => _element.offsetHeight + | 110 num get height => |
| 110 _addOrSubtractToBoxModel(_HEIGHT, _PADDING); | 111 _element.offsetHeight + _addOrSubtractToBoxModel(_HEIGHT, _PADDING); |
| 111 num get width => _element.offsetWidth + | 112 num get width => |
| 112 _addOrSubtractToBoxModel(_WIDTH, _PADDING); | 113 _element.offsetWidth + _addOrSubtractToBoxModel(_WIDTH, _PADDING); |
| 113 | 114 |
| 114 num get left => _element.getBoundingClientRect().left - | 115 num get left => |
| 116 _element.getBoundingClientRect().left - |
| 115 _addOrSubtractToBoxModel(['left'], _PADDING); | 117 _addOrSubtractToBoxModel(['left'], _PADDING); |
| 116 num get top => _element.getBoundingClientRect().top - | 118 num get top => |
| 119 _element.getBoundingClientRect().top - |
| 117 _addOrSubtractToBoxModel(['top'], _PADDING); | 120 _addOrSubtractToBoxModel(['top'], _PADDING); |
| 118 } | 121 } |
| 119 | 122 |
| 120 /** | 123 /** |
| 121 * A rectangle representing the dimensions of the space occupied by the | 124 * A rectangle representing the dimensions of the space occupied by the |
| 122 * element's content + padding + border in the | 125 * element's content + padding + border in the |
| 123 * [box model](http://www.w3.org/TR/CSS2/box.html). | 126 * [box model](http://www.w3.org/TR/CSS2/box.html). |
| 124 */ | 127 */ |
| 125 class _BorderCssRect extends CssRect { | 128 class _BorderCssRect extends CssRect { |
| 126 _BorderCssRect(element) : super(element); | 129 _BorderCssRect(element) : super(element); |
| 127 num get height => _element.offsetHeight; | 130 num get height => _element.offsetHeight; |
| 128 num get width => _element.offsetWidth; | 131 num get width => _element.offsetWidth; |
| 129 | 132 |
| 130 num get left => _element.getBoundingClientRect().left; | 133 num get left => _element.getBoundingClientRect().left; |
| 131 num get top => _element.getBoundingClientRect().top; | 134 num get top => _element.getBoundingClientRect().top; |
| 132 } | 135 } |
| 133 | 136 |
| 134 /** | 137 /** |
| 135 * A rectangle representing the dimensions of the space occupied by the | 138 * A rectangle representing the dimensions of the space occupied by the |
| 136 * element's content + padding + border + margin in the | 139 * element's content + padding + border + margin in the |
| 137 * [box model](http://www.w3.org/TR/CSS2/box.html). | 140 * [box model](http://www.w3.org/TR/CSS2/box.html). |
| 138 */ | 141 */ |
| 139 class _MarginCssRect extends CssRect { | 142 class _MarginCssRect extends CssRect { |
| 140 _MarginCssRect(element) : super(element); | 143 _MarginCssRect(element) : super(element); |
| 141 num get height => _element.offsetHeight + | 144 num get height => |
| 142 _addOrSubtractToBoxModel(_HEIGHT, _MARGIN); | 145 _element.offsetHeight + _addOrSubtractToBoxModel(_HEIGHT, _MARGIN); |
| 143 num get width => | 146 num get width => |
| 144 _element.offsetWidth + _addOrSubtractToBoxModel(_WIDTH, _MARGIN); | 147 _element.offsetWidth + _addOrSubtractToBoxModel(_WIDTH, _MARGIN); |
| 145 | 148 |
| 146 num get left => _element.getBoundingClientRect().left - | 149 num get left => |
| 150 _element.getBoundingClientRect().left - |
| 147 _addOrSubtractToBoxModel(['left'], _MARGIN); | 151 _addOrSubtractToBoxModel(['left'], _MARGIN); |
| 148 num get top => _element.getBoundingClientRect().top - | 152 num get top => |
| 153 _element.getBoundingClientRect().top - |
| 149 _addOrSubtractToBoxModel(['top'], _MARGIN); | 154 _addOrSubtractToBoxModel(['top'], _MARGIN); |
| 150 } | 155 } |
| 151 | 156 |
| 152 /** | 157 /** |
| 153 * A class for representing CSS dimensions. | 158 * A class for representing CSS dimensions. |
| 154 * | 159 * |
| 155 * In contrast to the more general purpose [Rectangle] class, this class's | 160 * In contrast to the more general purpose [Rectangle] class, this class's |
| 156 * values are mutable, so one can change the height of an element | 161 * values are mutable, so one can change the height of an element |
| 157 * programmatically. | 162 * programmatically. |
| 158 * | 163 * |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 set width(newWidth) { | 223 set width(newWidth) { |
| 219 throw new UnsupportedError("Can only set width for content rect."); | 224 throw new UnsupportedError("Can only set width for content rect."); |
| 220 } | 225 } |
| 221 | 226 |
| 222 /** | 227 /** |
| 223 * Return a value that is used to modify the initial height or width | 228 * Return a value that is used to modify the initial height or width |
| 224 * measurement of an element. Depending on the value (ideally an enum) passed | 229 * measurement of an element. Depending on the value (ideally an enum) passed |
| 225 * to augmentingMeasurement, we may need to add or subtract margin, padding, | 230 * to augmentingMeasurement, we may need to add or subtract margin, padding, |
| 226 * or border values, depending on the measurement we're trying to obtain. | 231 * or border values, depending on the measurement we're trying to obtain. |
| 227 */ | 232 */ |
| 228 num _addOrSubtractToBoxModel(List<String> dimensions, | 233 num _addOrSubtractToBoxModel( |
| 229 String augmentingMeasurement) { | 234 List<String> dimensions, String augmentingMeasurement) { |
| 230 // getComputedStyle always returns pixel values (hence, computed), so we're | 235 // getComputedStyle always returns pixel values (hence, computed), so we're |
| 231 // always dealing with pixels in this method. | 236 // always dealing with pixels in this method. |
| 232 var styles = _element.getComputedStyle(); | 237 var styles = _element.getComputedStyle(); |
| 233 | 238 |
| 234 var val = 0; | 239 var val = 0; |
| 235 | 240 |
| 236 for (String measurement in dimensions) { | 241 for (String measurement in dimensions) { |
| 237 // The border-box and default box model both exclude margin in the regular | 242 // The border-box and default box model both exclude margin in the regular |
| 238 // height/width calculation, so add it if we want it for this measurement. | 243 // height/width calculation, so add it if we want it for this measurement. |
| 239 if (augmentingMeasurement == _MARGIN) { | 244 if (augmentingMeasurement == _MARGIN) { |
| 240 val += new Dimension.css(styles.getPropertyValue( | 245 val += new Dimension.css( |
| 241 '$augmentingMeasurement-$measurement')).value; | 246 styles.getPropertyValue('$augmentingMeasurement-$measurement')) |
| 247 .value; |
| 242 } | 248 } |
| 243 | 249 |
| 244 // The border-box includes padding and border, so remove it if we want | 250 // The border-box includes padding and border, so remove it if we want |
| 245 // just the content itself. | 251 // just the content itself. |
| 246 if (augmentingMeasurement == _CONTENT) { | 252 if (augmentingMeasurement == _CONTENT) { |
| 247 » val -= new Dimension.css( | 253 val -= new Dimension.css( |
| 248 styles.getPropertyValue('${_PADDING}-$measurement')).value; | 254 styles.getPropertyValue('${_PADDING}-$measurement')) |
| 255 .value; |
| 249 } | 256 } |
| 250 | 257 |
| 251 // At this point, we don't wan't to augment with border or margin, | 258 // At this point, we don't wan't to augment with border or margin, |
| 252 // so remove border. | 259 // so remove border. |
| 253 if (augmentingMeasurement != _MARGIN) { | 260 if (augmentingMeasurement != _MARGIN) { |
| 254 » val -= new Dimension.css(styles.getPropertyValue( | 261 val -= new Dimension.css( |
| 255 'border-${measurement}-width')).value; | 262 styles.getPropertyValue('border-${measurement}-width')) |
| 263 .value; |
| 256 } | 264 } |
| 257 } | 265 } |
| 258 return val; | 266 return val; |
| 259 } | 267 } |
| 260 | 268 |
| 261 // TODO(jacobr): these methods are duplicated from _RectangleBase in dart:math | 269 // TODO(jacobr): these methods are duplicated from _RectangleBase in dart:math |
| 262 // Ideally we would provide a RectangleMixin class that provides this implemen
tation. | 270 // Ideally we would provide a RectangleMixin class that provides this implemen
tation. |
| 263 // In an ideal world we would exp | 271 // In an ideal world we would exp |
| 264 /** The x-coordinate of the right edge. */ | 272 /** The x-coordinate of the right edge. */ |
| 265 num get right => left + width; | 273 num get right => left + width; |
| 266 /** The y-coordinate of the bottom edge. */ | 274 /** The y-coordinate of the bottom edge. */ |
| 267 num get bottom => top + height; | 275 num get bottom => top + height; |
| 268 | 276 |
| 269 String toString() { | 277 String toString() { |
| 270 return 'Rectangle ($left, $top) $width x $height'; | 278 return 'Rectangle ($left, $top) $width x $height'; |
| 271 } | 279 } |
| 272 | 280 |
| 273 bool operator ==(other) { | 281 bool operator ==(other) { |
| 274 if (other is !Rectangle) return false; | 282 if (other is! Rectangle) return false; |
| 275 return left == other.left && top == other.top && right == other.right && | 283 return left == other.left && |
| 284 top == other.top && |
| 285 right == other.right && |
| 276 bottom == other.bottom; | 286 bottom == other.bottom; |
| 277 } | 287 } |
| 278 | 288 |
| 279 int get hashCode => _JenkinsSmiHash.hash4(left.hashCode, top.hashCode, | 289 int get hashCode => _JenkinsSmiHash.hash4( |
| 280 right.hashCode, bottom.hashCode); | 290 left.hashCode, top.hashCode, right.hashCode, bottom.hashCode); |
| 281 | 291 |
| 282 /** | 292 /** |
| 283 * Computes the intersection of `this` and [other]. | 293 * Computes the intersection of `this` and [other]. |
| 284 * | 294 * |
| 285 * The intersection of two axis-aligned rectangles, if any, is always another | 295 * The intersection of two axis-aligned rectangles, if any, is always another |
| 286 * axis-aligned rectangle. | 296 * axis-aligned rectangle. |
| 287 * | 297 * |
| 288 * Returns the intersection of this and `other`, or `null` if they don't | 298 * Returns the intersection of this and `other`, or `null` if they don't |
| 289 * intersect. | 299 * intersect. |
| 290 */ | 300 */ |
| 291 Rectangle<num> intersection(Rectangle<num> other) { | 301 Rectangle<num> intersection(Rectangle<num> other) { |
| 292 var x0 = max(left, other.left); | 302 var x0 = max(left, other.left); |
| 293 var x1 = min(left + width, other.left + other.width); | 303 var x1 = min(left + width, other.left + other.width); |
| 294 | 304 |
| 295 if (x0 <= x1) { | 305 if (x0 <= x1) { |
| 296 var y0 = max(top, other.top); | 306 var y0 = max(top, other.top); |
| 297 var y1 = min(top + height, other.top + other.height); | 307 var y1 = min(top + height, other.top + other.height); |
| 298 | 308 |
| 299 if (y0 <= y1) { | 309 if (y0 <= y1) { |
| 300 return new Rectangle<num>(x0, y0, x1 - x0, y1 - y0); | 310 return new Rectangle<num>(x0, y0, x1 - x0, y1 - y0); |
| 301 } | 311 } |
| 302 } | 312 } |
| 303 return null; | 313 return null; |
| 304 } | 314 } |
| 305 | 315 |
| 306 | |
| 307 /** | 316 /** |
| 308 * Returns true if `this` intersects [other]. | 317 * Returns true if `this` intersects [other]. |
| 309 */ | 318 */ |
| 310 bool intersects(Rectangle<num> other) { | 319 bool intersects(Rectangle<num> other) { |
| 311 return (left <= other.left + other.width && | 320 return (left <= other.left + other.width && |
| 312 other.left <= left + width && | 321 other.left <= left + width && |
| 313 top <= other.top + other.height && | 322 top <= other.top + other.height && |
| 314 other.top <= top + height); | 323 other.top <= top + height); |
| 315 } | 324 } |
| 316 | 325 |
| 317 /** | 326 /** |
| 318 * Returns a new rectangle which completely contains `this` and [other]. | 327 * Returns a new rectangle which completely contains `this` and [other]. |
| 319 */ | 328 */ |
| 320 Rectangle<num> boundingBox(Rectangle<num> other) { | 329 Rectangle<num> boundingBox(Rectangle<num> other) { |
| 321 var right = max(this.left + this.width, other.left + other.width); | 330 var right = max(this.left + this.width, other.left + other.width); |
| 322 var bottom = max(this.top + this.height, other.top + other.height); | 331 var bottom = max(this.top + this.height, other.top + other.height); |
| 323 | 332 |
| 324 var left = min(this.left, other.left); | 333 var left = min(this.left, other.left); |
| 325 var top = min(this.top, other.top); | 334 var top = min(this.top, other.top); |
| 326 | 335 |
| 327 return new Rectangle<num>(left, top, right - left, bottom - top); | 336 return new Rectangle<num>(left, top, right - left, bottom - top); |
| 328 } | 337 } |
| 329 | 338 |
| 330 /** | 339 /** |
| 331 * Tests whether `this` entirely contains [another]. | 340 * Tests whether `this` entirely contains [another]. |
| 332 */ | 341 */ |
| 333 bool containsRectangle(Rectangle<num> another) { | 342 bool containsRectangle(Rectangle<num> another) { |
| 334 return left <= another.left && | 343 return left <= another.left && |
| 335 left + width >= another.left + another.width && | 344 left + width >= another.left + another.width && |
| 336 top <= another.top && | 345 top <= another.top && |
| 337 top + height >= another.top + another.height; | 346 top + height >= another.top + another.height; |
| 338 } | 347 } |
| 339 | 348 |
| 340 /** | 349 /** |
| 341 * Tests whether [another] is inside or along the edges of `this`. | 350 * Tests whether [another] is inside or along the edges of `this`. |
| 342 */ | 351 */ |
| 343 bool containsPoint(Point<num> another) { | 352 bool containsPoint(Point<num> another) { |
| 344 return another.x >= left && | 353 return another.x >= left && |
| 345 another.x <= left + width && | 354 another.x <= left + width && |
| 346 another.y >= top && | 355 another.y >= top && |
| 347 another.y <= top + height; | 356 another.y <= top + height; |
| 348 } | 357 } |
| 349 | 358 |
| 350 Point<num> get topLeft => new Point<num>(this.left, this.top); | 359 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); | 360 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, | 361 Point<num> get bottomRight => |
| 353 this.top + this.height); | 362 new Point<num>(this.left + this.width, this.top + this.height); |
| 354 Point<num> get bottomLeft => new Point<num>(this.left, | 363 Point<num> get bottomLeft => |
| 355 this.top + this.height); | 364 new Point<num>(this.left, this.top + this.height); |
| 356 } | 365 } |
| 357 | 366 |
| 358 final _HEIGHT = ['top', 'bottom']; | 367 final _HEIGHT = ['top', 'bottom']; |
| 359 final _WIDTH = ['right', 'left']; | 368 final _WIDTH = ['right', 'left']; |
| 360 final _CONTENT = 'content'; | 369 final _CONTENT = 'content'; |
| 361 final _PADDING = 'padding'; | 370 final _PADDING = 'padding'; |
| 362 final _MARGIN = 'margin'; | 371 final _MARGIN = 'margin'; |
| OLD | NEW |