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

Unified Diff: client/html/src/ElementWrappingImplementation.dart

Issue 8363040: Implement measurement using futures (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: take2 Created 9 years, 2 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: client/html/src/ElementWrappingImplementation.dart
diff --git a/client/html/src/ElementWrappingImplementation.dart b/client/html/src/ElementWrappingImplementation.dart
index 6f33dc949e91339d206082c9b3d3495c047f761c..18ee97d84066c9d0321c99fc4dfbfcd561684480 100644
--- a/client/html/src/ElementWrappingImplementation.dart
+++ b/client/html/src/ElementWrappingImplementation.dart
@@ -411,20 +411,115 @@ class ElementEventsImplementation extends EventsImplementation implements Elemen
EventListenerList get touchMove() => _get("touchmove");
EventListenerList get touchStart() => _get("touchstart");
EventListenerList get transitionEnd() => _get("webkitTransitionEnd");
- EventListenerList get fullscreenChange() => _get("fullscreenchange");
+ EventListenerList get fullscreenChange() => _get("webkitfullscreenchange");
+}
+
+class SimpleClientRect implements ClientRect {
+ final num left;
+ final num top;
+ final num width;
+ final num height;
+ num get right() => left + width;
+ num get bottom() => top + height;
+
+ SimpleClientRect(this.left, this.top, this.width, this.height);
+
+ bool operator ==(ClientRect other) {
+ return other !== null && left == other.left && top == other.top
+ && width == other.width && height == other.height;
+ }
+
+ String toString() => "($left, $top, $width, $height)";
+}
+
+// TODO(jacobr): we cannot currently be lazy about calculating the client
+// rects as we must perform all measurement queries at a safe point to avoid
+// triggering unneeded layouts.
+/**
+ * All your element measurement needs in one place
+ */
+class ElementRectWrappingImplementation implements ElementRect {
+ final ClientRect client;
+ final ClientRect offset;
+ final ClientRect scroll;
+
+ // TODO(jacobr): should we move these outside of ElementRect to avoid the
+ // overhead of computing them every time even though they are rarely used.
+ // This should be type dom.ClientRect but that fails on dartium. b/5522629
+ final _boundingClientRect;
+ // an exception due to a dartium bug.
+ final dom.ClientRectList _clientRects;
+
+ ElementRectWrappingImplementation(dom.HTMLElement element) :
+ client = new SimpleClientRect(element.clientLeft,
+ element.clientTop,
+ element.clientWidth,
+ element.clientHeight),
+ offset = new SimpleClientRect(element.offsetLeft,
+ element.offsetTop,
+ element.offsetWidth,
+ element.offsetHeight),
+ scroll = new SimpleClientRect(element.scrollLeft,
+ element.scrollTop,
+ element.scrollWidth,
+ element.scrollHeight),
+ _boundingClientRect = element.getBoundingClientRect(),
+ _clientRects = element.getClientRects();
+
+ ClientRect get bounding() =>
+ LevelDom.wrapClientRect(_boundingClientRect);
+
+ List<ClientRect> get clientRects() {
arv (Not doing code reviews) 2011/10/27 03:16:13 Maybe just an iterable instead?
Jacob 2011/10/27 20:59:25 Any reason why this case should just be iterable w
+ final out = new List(_clientRects.length);
+ for (num i = 0; i < _clientRects.length; i++) {
+ out[i] = LevelDom.wrapClientRect(_clientRects.item(i));
+ }
+ return out;
+ }
}
class ElementWrappingImplementation extends NodeWrappingImplementation implements Element {
+
+ static final _START_TAG_REGEXP = const RegExp('<(\\w+)');
arv (Not doing code reviews) 2011/10/27 03:16:13 Can this be moved to a different patch?
Jacob 2011/10/27 20:59:25 I agree this bug fix is unrelated but at this earl
+ static final _CUSTOM_PARENT_TAG_MAP = const {
+ 'body' : 'html',
+ 'head' : 'html',
+ 'caption' : 'table',
+ 'td': 'tr',
+ 'tbody': 'table',
+ 'colgroup': 'table',
+ 'col' : 'colgroup',
+ 'tr' : 'tbody',
+ 'tbody' : 'table',
+ 'tfoot' : 'table',
+ 'thead' : 'table',
+ 'track' : 'audio',
+ };
factory ElementWrappingImplementation.html(String html) {
- final temp = dom.document.createElement('div');
+ String parentTag = 'div';
+ String tag;
+ final match = _START_TAG_REGEXP.firstMatch(html);
+ if (null != match) {
+ tag = match.group(1).toLowerCase();
+ if (_CUSTOM_PARENT_TAG_MAP.containsKey(tag)) {
+ parentTag = _CUSTOM_PARENT_TAG_MAP[tag];
+ }
+ }
+ final temp = dom.document.createElement(parentTag);
arv (Not doing code reviews) 2011/10/27 03:16:13 This code is really great. A big improvement over
Jacob 2011/10/27 20:59:25 I think this can be improved further. Added a TODO
temp.innerHTML = html;
- if (temp.childElementCount != 1) {
+ if (temp.childElementCount == 1) {
+ return LevelDom.wrapElement(temp.firstElementChild);
+ } else if (temp.childElementCount > 0 && tag != null &&
+ parentTag == 'html') {
+ // Work around for edge case where both body and head
arv (Not doing code reviews) 2011/10/27 03:16:13 Which browsers? Can we link to bugs here? I think
Jacob 2011/10/27 20:59:25 The issue occurs in WebKit. I agree that your code
+ // elements are created even though the html contains a head or
+ // body.
+ return LevelDom.wrapElement(temp.querySelector(tag));
+ } else {
throw 'HTML had ${temp.childElementCount} top level elements but 1 expected';
}
-
- return LevelDom.wrapElement(temp.firstElementChild);
}
factory ElementWrappingImplementation.tag(String tag) {
@@ -496,14 +591,6 @@ class ElementWrappingImplementation extends NodeWrappingImplementation implement
}
}
- int get clientHeight() => _ptr.clientHeight;
-
- int get clientLeft() => _ptr.clientLeft;
-
- int get clientTop() => _ptr.clientTop;
-
- int get clientWidth() => _ptr.clientWidth;
-
String get contentEditable() => _ptr.contentEditable;
void set contentEditable(String value) { _ptr.contentEditable = value; }
@@ -540,32 +627,12 @@ class ElementWrappingImplementation extends NodeWrappingImplementation implement
Element get nextElementSibling() => LevelDom.wrapElement(_ptr.nextElementSibling);
- int get offsetHeight() => _ptr.offsetHeight;
-
- int get offsetLeft() => _ptr.offsetLeft;
-
Element get offsetParent() => LevelDom.wrapElement(_ptr.offsetParent);
- int get offsetTop() => _ptr.offsetTop;
-
- int get offsetWidth() => _ptr.offsetWidth;
-
String get outerHTML() => _ptr.outerHTML;
Element get previousElementSibling() => LevelDom.wrapElement(_ptr.previousElementSibling);
- int get scrollHeight() => _ptr.scrollHeight;
-
- int get scrollLeft() => _ptr.scrollLeft;
-
- void set scrollLeft(int value) { _ptr.scrollLeft = value; }
-
- int get scrollTop() => _ptr.scrollTop;
-
- void set scrollTop(int value) { _ptr.scrollTop = value; }
-
- int get scrollWidth() => _ptr.scrollWidth;
-
bool get spellcheck() => _ptr.spellcheck;
void set spellcheck(bool value) { _ptr.spellcheck = value; }
@@ -598,19 +665,6 @@ class ElementWrappingImplementation extends NodeWrappingImplementation implement
_ptr.focus();
}
- ClientRect getBoundingClientRect() {
- return LevelDom.wrapClientRect(_ptr.getBoundingClientRect());
- }
-
- List<ClientRect> getClientRects() {
- var rects = _ptr.getClientRects();
- var out = new List(rects.length);
- for (var i = 0; i < rects.length; i++) {
- out.add(LevelDom.wrapClientRect(rects.item(i)));
- }
- return out;
- }
-
Element insertAdjacentElement([String where = null, Element element = null]) {
return LevelDom.wrapElement(_ptr.insertAdjacentElement(where, LevelDom.unwrap(element)));
}
@@ -649,6 +703,28 @@ class ElementWrappingImplementation extends NodeWrappingImplementation implement
return _ptr.webkitMatchesSelector(selectors);
}
+ void set scrollLeft(int value) { _ptr.scrollLeft = value; }
+
+ void set scrollTop(int value) { _ptr.scrollTop = value; }
+
+ Future<ElementRect> get rect() {
+ return _createMeasurementFuture(
+ () => new ElementRectWrappingImplementation(_ptr),
+ new Completer<ElementRect>());
+ }
+
+ Future<CSSStyleDeclaration> get computedStyle() {
+ // TODO(jacobr): last param should be null, see b/5045788
+ return getComputedStyle('');
+ }
+
+ Future<CSSStyleDeclaration> getComputedStyle(String pseudoElement) {
+ return _createMeasurementFuture(() =>
+ LevelDom.wrapCSSStyleDeclaration(
+ dom.window.getComputedStyle(_ptr, pseudoElement)),
+ new Completer<CSSStyleDeclaration>());
+ }
+
ElementEvents get on() {
if (_on === null) {
_on = new ElementEventsImplementation._wrap(_ptr);

Powered by Google App Engine
This is Rietveld 408576698