Chromium Code Reviews| Index: tools/dom/src/CssRectangle.dart |
| diff --git a/tools/dom/src/CssRectangle.dart b/tools/dom/src/CssRectangle.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..6f203aab722d99ab9aa45be762c6c4f1cd7f6a16 |
| --- /dev/null |
| +++ b/tools/dom/src/CssRectangle.dart |
| @@ -0,0 +1,211 @@ |
| +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| +// for details. All rights reserved. Use of this source code is governed by a |
| +// BSD-style license that can be found in the LICENSE file. |
| + |
| +part of html; |
| + |
| +class _ContentCssRect extends CssRect { |
|
Jennifer Messerly
2013/07/16 22:03:16
might be worth adding a short class comment here a
Emily Fortuna
2013/07/18 22:45:02
Done.
|
| + |
| + _ContentCssRect(element) : super(element); |
| + num get height => _element.offsetHeight + |
| + _addOrSubtractToBoxModel(CssRect._HEIGHT, 'content'); |
| + |
| + num get width => _element.offsetWidth + |
| + _addOrSubtractToBoxModel(CssRect._WIDTH, 'content'); |
| + |
| + /** |
| + * Set the height to `newHeight`. |
| + * |
| + * Values of newHeight that are less than zero are converted to effectively |
| + * setting the height to 0. This is equivalent to the `height` |
| + * function in jQuery and the calculated `height` css value, converted to a |
|
Jennifer Messerly
2013/07/16 22:03:16
uppercase CSS?
Emily Fortuna
2013/07/18 22:45:02
Done.
|
| + * num in pixels. |
| + */ |
| + void set height(Dimension newHeight) { |
|
Jennifer Messerly
2013/07/16 22:03:16
hmmm. I'm not sure about having the setter take a
Emily Fortuna
2013/07/18 22:45:02
Done.
|
| + if (newHeight.value < 0) newHeight = new Dimension.px(0); |
| + _element.style.height = newHeight.toString(); |
| + } |
| + |
| + /** |
| + * Set the current computed width in pixels of this element. |
| + * |
| + * This is equivalent to the `width` function in jQuery and the calculated |
| + * `width` css value, converted to a dimensionless num in pixels. |
| + */ |
| + void set width(Dimension newWidth) { |
| + if (newWidth.value < 0) newWidth = new Dimension.px(0); |
| + _element.style.width = newWidth.toString(); |
| + } |
| + |
| + num get left() => _element.getBoundingClientRect().left - |
|
Jennifer Messerly
2013/07/16 22:03:16
not sure about the parens here. that looks like ol
Emily Fortuna
2013/07/18 22:45:02
Oh man. Old habits die hard. Fixed.
|
| + _addOrSubtractToBoxModel(['left'], 'content'); |
| + num get top() => _element.getBoundingClientRect().top - |
| + _addOrSubtractToBoxModel(['top'], 'content'); |
| +} |
| + |
| +class _ContentCssListRect extends _ContentCssRect { |
| + List<Element> _elementList; |
|
Jennifer Messerly
2013/07/16 22:03:16
this could be final?
|
| + |
| + _ContentCssListRect(elementList) : super(elementList.first) { |
| + _elementList = elementList; |
| + } |
| + |
| + /** |
| + * Set the height to `newHeight`. |
| + * |
| + * Values of newHeight that are less than zero are converted to effectively |
| + * setting the height to 0. This is equivalent to the `height` |
| + * function in jQuery and the calculated `height` css value, converted to a |
| + * num in pixels. |
| + */ |
| + void set height(Dimension newHeight) { |
| + _elementList.forEach((e) => e.contentEdge.height = newHeight); |
| + } |
| + |
| + /** |
| + * Set the current computed width in pixels of this element. |
| + * |
| + * This is equivalent to the `width` function in jQuery and the calculated |
| + * `width` css value, converted to a dimensionless num in pixels. |
| + */ |
| + void set width(Dimension newWidth) { |
| + _elementList.forEach((e) => e.contentEdge.width = newWidth); |
| + } |
| +} |
| + |
| +class _PaddingCssRect extends CssRect { |
| + _PaddingCssRect(element) : super(element); |
| + num get height => _element.offsetHeight + |
| + _addOrSubtractToBoxModel(CssRect._HEIGHT, 'padding'); |
| + num get width => _element.offsetWidth + |
| + _addOrSubtractToBoxModel(CssRect._WIDTH, 'padding'); |
| + |
| + num get left() => _element.getBoundingClientRect().left - |
| + _addOrSubtractToBoxModel(['left'], 'padding'); |
| + num get top() => _element.getBoundingClientRect().top - |
| + _addOrSubtractToBoxModel(['top'], 'padding'); |
| +} |
| + |
| +class _BorderCssRect extends CssRect { |
| + _BorderCssRect(element) : super(element); |
| + num get height() => _element.offsetHeight; |
| + num get width() => _element.offsetWidth; |
| + |
| + num get left() => _element.getBoundingClientRect().left; |
| + num get top() => _element.getBoundingClientRect().top; |
| +} |
| + |
| +class _MarginCssRect extends CssRect { |
| + _MarginCssRect(element) : super(element); |
| + num get height() => _element.offsetHeight + |
| + _addOrSubtractToBoxModel(CssRect._HEIGHT, 'margin'); |
| + num get width() => |
| + _element.offsetWidth + _addOrSubtractToBoxModel(CssRect._WIDTH, 'margin'); |
| + |
| + num get left() => _element.getBoundingClientRect().left - |
| + _addOrSubtractToBoxModel(['left'], 'margin'); |
| + num get top() => _element.getBoundingClientRect().top - |
| + _addOrSubtractToBoxModel(['top'], 'margin'); |
| +} |
| + |
| +/** |
| + * A class for representing CSS dimensions. |
| + * |
| + * In contrast to the more general purpose [Rect] class, this class's values are |
| + * mutable, so one can change the height of an element programmatically. |
| + * |
| + * SPECIAL NOTE: Do _not_ use these methods of setting or getting dimensions |
|
Jennifer Messerly
2013/07/16 22:03:16
trivial nit: I think this one is "SPECIAL NOTE" an
Emily Fortuna
2013/07/18 22:45:02
Done.
|
| + * for animations, as they will trigger a redraw of the layout. |
| + */ |
| +abstract class CssRect extends RectBase implements Rect { |
| + Element _element; |
| + |
| + CssRect(this._element); |
| + |
| + num get left(); |
|
Jennifer Messerly
2013/07/16 22:03:16
same issue here with parens
Emily Fortuna
2013/07/18 22:45:02
Done.
|
| + |
| + num get top(); |
| + |
| + /** |
| + * The height of this rectangle. |
| + * |
| + * This is equivalent to the `height` function in jQuery and the calculated |
| + * `height` css value, converted to a dimensionless num in pixels. Unlike |
| + * [getBoundingClientRect], `height` will return the same numerical width if |
| + * the element is hidden or not. |
| + */ |
| + num get height(); |
| + |
| + /** |
| + * The width of this rectangle. |
| + * |
| + * This is equivalent to the `width` function in jQuery and the calculated |
| + * `width` css value, converted to a dimensionless num in pixels. Unlike |
| + * [getBoundingClientRect], `width` will return the same numerical width if |
| + * the element is hidden or not. |
| + */ |
| + num get width(); |
| + |
| + /** |
| + * Set the height to `newHeight`. |
| + * |
| + * Values of newHeight that are less than zero are converted to effectively |
| + * setting the height to 0. Note that only the content height can be set via |
| + * this method. |
| + */ |
| + void set height(Dimension newHeight) { |
| + throw new UnsupportedError("Can only set height for content rect."); |
| + } |
| + |
| + /** |
| + * Set the current computed width in pixels of this element. |
| + * |
| + * Note that only the content width can be set via this method. |
| + */ |
| + void set width(Dimension newWidth) { |
| + throw new UnsupportedError("Can only set width for content rect."); |
| + } |
| + |
| + /** |
| + * Return a value that is used to modify the initial height or width |
| + * measurement of an element. Depending on the value (ideally an enum) passed |
| + * to augmentingMeasurement, we may need to add or subtract margin, padding, |
| + * or border values, depending on the measurement we're trying to obtain. |
| + */ |
| + num _addOrSubtractToBoxModel(List<String> dimensions, |
| + String augmentingMeasurement) { |
| + // getComputedStyle always returns pixel values (hence, computed), so we're |
| + // always dealing with pixels in this method. |
| + var styles = _element.getComputedStyle(); |
| + |
| + var val = 0; |
| + |
| + for (String measurement in dimensions) { |
| + // The border-box and default box model both exclude margin in the regular |
| + // height/width calculation, so add it if we want it for this measurement. |
| + if (augmentingMeasurement == 'margin') { |
| + val += new Dimension._(styles.getPropertyValue( |
| + '$augmentingMeasurement-$measurement')).value; |
| + } |
| + |
| + // The border-box includes padding and border, so remove it if we want |
| + // just the content itself. |
| + if (augmentingMeasurement == 'content') { |
| + val -= new Dimension._( |
| + styles.getPropertyValue('padding-$measurement')).value; |
| + } |
| + |
| + // At this point, we don't wan't to augment with border or margin, |
| + // so remove border. |
| + if (augmentingMeasurement != 'margin') { |
| + val -= new Dimension._(styles.getPropertyValue( |
| + 'border-${measurement}-width')).value; |
| + } |
| + } |
| + return val; |
| + } |
| + |
| + final static _HEIGHT = ['top', 'bottom']; |
| + final static _WIDTH = ['right', 'left']; |
| +} |
| + |