OLD | NEW |
(Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 part of html; |
| 6 |
| 7 /** |
| 8 * A rectangle representing all the content of the element in the |
| 9 * [box model](http://www.w3.org/TR/CSS2/box.html). |
| 10 */ |
| 11 class _ContentCssRect extends CssRect { |
| 12 |
| 13 _ContentCssRect(element) : super(element); |
| 14 |
| 15 num get height => _element.offsetHeight + |
| 16 _addOrSubtractToBoxModel(_HEIGHT, _CONTENT); |
| 17 |
| 18 num get width => _element.offsetWidth + |
| 19 _addOrSubtractToBoxModel(_WIDTH, _CONTENT); |
| 20 |
| 21 /** |
| 22 * Set the height to `newHeight`. |
| 23 * |
| 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 |
| 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, |
| 28 * converted to a num in pixels. |
| 29 */ |
| 30 void set height(newHeight) { |
| 31 if (newHeight is Dimension) { |
| 32 if (newHeight.value < 0) newHeight = new Dimension.px(0); |
| 33 _element.style.height = newHeight.toString(); |
| 34 } else { |
| 35 if (newHeight < 0) newHeight = 0; |
| 36 _element.style.height = '${newHeight}px'; |
| 37 } |
| 38 } |
| 39 |
| 40 /** |
| 41 * Set the current computed width in pixels of this element. |
| 42 * |
| 43 * 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 |
| 45 * and the calculated |
| 46 * `width` CSS value, converted to a dimensionless num in pixels. |
| 47 */ |
| 48 void set width(newWidth) { |
| 49 if (newWidth is Dimension) { |
| 50 if (newWidth.value < 0) newWidth = new Dimension.px(0); |
| 51 _element.style.width = newWidth.toString(); |
| 52 } else { |
| 53 if (newWidth < 0) newWidth = 0; |
| 54 _element.style.width = '${newWidth}px'; |
| 55 } |
| 56 } |
| 57 |
| 58 num get left => _element.getBoundingClientRect().left - |
| 59 _addOrSubtractToBoxModel(['left'], _CONTENT); |
| 60 num get top => _element.getBoundingClientRect().top - |
| 61 _addOrSubtractToBoxModel(['top'], _CONTENT); |
| 62 } |
| 63 |
| 64 /** |
| 65 * A list of element content rectangles in the |
| 66 * [box model](http://www.w3.org/TR/CSS2/box.html). |
| 67 */ |
| 68 class _ContentCssListRect extends _ContentCssRect { |
| 69 List<Element> _elementList; |
| 70 |
| 71 _ContentCssListRect(elementList) : super(elementList.first) { |
| 72 _elementList = elementList; |
| 73 } |
| 74 |
| 75 /** |
| 76 * Set the height to `newHeight`. |
| 77 * |
| 78 * Values of newHeight that are less than zero are converted to effectively |
| 79 * setting the height to 0. This is equivalent to the `height` |
| 80 * function in jQuery and the calculated `height` CSS value, converted to a |
| 81 * num in pixels. |
| 82 */ |
| 83 void set height(newHeight) { |
| 84 _elementList.forEach((e) => e.contentEdge.height = newHeight); |
| 85 } |
| 86 |
| 87 /** |
| 88 * Set the current computed width in pixels of this element. |
| 89 * |
| 90 * This is equivalent to the `width` function in jQuery and the calculated |
| 91 * `width` CSS value, converted to a dimensionless num in pixels. |
| 92 */ |
| 93 void set width(newWidth) { |
| 94 _elementList.forEach((e) => e.contentEdge.width = newWidth); |
| 95 } |
| 96 } |
| 97 |
| 98 /** |
| 99 * A rectangle representing the dimensions of the space occupied by the |
| 100 * element's content + padding in the |
| 101 * [box model](http://www.w3.org/TR/CSS2/box.html). |
| 102 */ |
| 103 class _PaddingCssRect extends CssRect { |
| 104 _PaddingCssRect(element) : super(element); |
| 105 num get height => _element.offsetHeight + |
| 106 _addOrSubtractToBoxModel(_HEIGHT, _PADDING); |
| 107 num get width => _element.offsetWidth + |
| 108 _addOrSubtractToBoxModel(_WIDTH, _PADDING); |
| 109 |
| 110 num get left => _element.getBoundingClientRect().left - |
| 111 _addOrSubtractToBoxModel(['left'], _PADDING); |
| 112 num get top => _element.getBoundingClientRect().top - |
| 113 _addOrSubtractToBoxModel(['top'], _PADDING); |
| 114 } |
| 115 |
| 116 /** |
| 117 * A rectangle representing the dimensions of the space occupied by the |
| 118 * element's content + padding + border in the |
| 119 * [box model](http://www.w3.org/TR/CSS2/box.html). |
| 120 */ |
| 121 class _BorderCssRect extends CssRect { |
| 122 _BorderCssRect(element) : super(element); |
| 123 num get height => _element.offsetHeight; |
| 124 num get width => _element.offsetWidth; |
| 125 |
| 126 num get left => _element.getBoundingClientRect().left; |
| 127 num get top => _element.getBoundingClientRect().top; |
| 128 } |
| 129 |
| 130 /** |
| 131 * A rectangle representing the dimensions of the space occupied by the |
| 132 * element's content + padding + border + margin in the |
| 133 * [box model](http://www.w3.org/TR/CSS2/box.html). |
| 134 */ |
| 135 class _MarginCssRect extends CssRect { |
| 136 _MarginCssRect(element) : super(element); |
| 137 num get height => _element.offsetHeight + |
| 138 _addOrSubtractToBoxModel(_HEIGHT, _MARGIN); |
| 139 num get width => |
| 140 _element.offsetWidth + _addOrSubtractToBoxModel(_WIDTH, _MARGIN); |
| 141 |
| 142 num get left => _element.getBoundingClientRect().left - |
| 143 _addOrSubtractToBoxModel(['left'], _MARGIN); |
| 144 num get top => _element.getBoundingClientRect().top - |
| 145 _addOrSubtractToBoxModel(['top'], _MARGIN); |
| 146 } |
| 147 |
| 148 /** |
| 149 * A class for representing CSS dimensions. |
| 150 * |
| 151 * In contrast to the more general purpose [Rect] class, this class's values are |
| 152 * mutable, so one can change the height of an element programmatically. |
| 153 * |
| 154 * _Important_ _note_: use of these methods will perform CSS calculations that |
| 155 * can trigger a browser reflow. Therefore, use of these properties _during_ an |
| 156 * animation frame is discouraged. See also: |
| 157 * [Browser Reflow](https://developers.google.com/speed/articles/reflow) |
| 158 */ |
| 159 abstract class CssRect extends RectBase implements Rect { |
| 160 Element _element; |
| 161 |
| 162 CssRect(this._element); |
| 163 |
| 164 num get left; |
| 165 |
| 166 num get top; |
| 167 |
| 168 /** |
| 169 * The height of this rectangle. |
| 170 * |
| 171 * This is equivalent to the `height` function in jQuery and the calculated |
| 172 * `height` CSS value, converted to a dimensionless num in pixels. Unlike |
| 173 * [getBoundingClientRect], `height` will return the same numerical width if |
| 174 * the element is hidden or not. |
| 175 */ |
| 176 num get height; |
| 177 |
| 178 /** |
| 179 * The width of this rectangle. |
| 180 * |
| 181 * This is equivalent to the `width` function in jQuery and the calculated |
| 182 * `width` CSS value, converted to a dimensionless num in pixels. Unlike |
| 183 * [getBoundingClientRect], `width` will return the same numerical width if |
| 184 * the element is hidden or not. |
| 185 */ |
| 186 num get width; |
| 187 |
| 188 /** |
| 189 * Set the height to `newHeight`. |
| 190 * |
| 191 * newHeight can be either a [num] representing the height in pixels or a |
| 192 * [Dimension] object. Values of newHeight that are less than zero are |
| 193 * converted to effectively setting the height to 0. This is equivalent to the |
| 194 * `height` function in jQuery and the calculated `height` CSS value, |
| 195 * converted to a num in pixels. |
| 196 * |
| 197 * Note that only the content height can actually be set via this method. |
| 198 */ |
| 199 void set height(newHeight) { |
| 200 throw new UnsupportedError("Can only set height for content rect."); |
| 201 } |
| 202 |
| 203 /** |
| 204 * Set the current computed width in pixels of this element. |
| 205 * |
| 206 * newWidth can be either a [num] representing the width in pixels or a |
| 207 * [Dimension] object. This is equivalent to the `width` function in jQuery |
| 208 * and the calculated |
| 209 * `width` CSS value, converted to a dimensionless num in pixels. |
| 210 * |
| 211 * Note that only the content width can be set via this method. |
| 212 */ |
| 213 void set width(newWidth) { |
| 214 throw new UnsupportedError("Can only set width for content rect."); |
| 215 } |
| 216 |
| 217 /** |
| 218 * Return a value that is used to modify the initial height or width |
| 219 * measurement of an element. Depending on the value (ideally an enum) passed |
| 220 * to augmentingMeasurement, we may need to add or subtract margin, padding, |
| 221 * or border values, depending on the measurement we're trying to obtain. |
| 222 */ |
| 223 num _addOrSubtractToBoxModel(List<String> dimensions, |
| 224 String augmentingMeasurement) { |
| 225 // getComputedStyle always returns pixel values (hence, computed), so we're |
| 226 // always dealing with pixels in this method. |
| 227 var styles = _element.getComputedStyle(); |
| 228 |
| 229 var val = 0; |
| 230 |
| 231 for (String measurement in dimensions) { |
| 232 // The border-box and default box model both exclude margin in the regular |
| 233 // height/width calculation, so add it if we want it for this measurement. |
| 234 if (augmentingMeasurement == _MARGIN) { |
| 235 val += new Dimension.css(styles.getPropertyValue( |
| 236 '$augmentingMeasurement-$measurement')).value; |
| 237 } |
| 238 |
| 239 // The border-box includes padding and border, so remove it if we want |
| 240 // just the content itself. |
| 241 if (augmentingMeasurement == _CONTENT) { |
| 242 val -= new Dimension.css( |
| 243 styles.getPropertyValue('${_PADDING}-$measurement')).value; |
| 244 } |
| 245 |
| 246 // At this point, we don't wan't to augment with border or margin, |
| 247 // so remove border. |
| 248 if (augmentingMeasurement != _MARGIN) { |
| 249 val -= new Dimension.css(styles.getPropertyValue( |
| 250 'border-${measurement}-width')).value; |
| 251 } |
| 252 } |
| 253 return val; |
| 254 } |
| 255 } |
| 256 |
| 257 final _HEIGHT = ['top', 'bottom']; |
| 258 final _WIDTH = ['right', 'left']; |
| 259 final _CONTENT = 'content'; |
| 260 final _PADDING = 'padding'; |
| 261 final _MARGIN = 'margin'; |
OLD | NEW |