Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(321)

Unified Diff: tools/dom/src/CssRectangle.dart

Issue 15507007: Provide cross-browser Rects for box model dimensions for Elements. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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'];
+}
+

Powered by Google App Engine
This is Rietveld 408576698