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

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

Issue 9148015: Example showing alternate async measurement solution (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Final version Created 8 years, 11 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 8f9abb72c0912f01c9f612180b4ec7d5751087e5..5220caaa8dc97e9e282ddfeb85c385bf3267c48e 100644
--- a/client/html/src/ElementWrappingImplementation.dart
+++ b/client/html/src/ElementWrappingImplementation.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2012, 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.
@@ -12,6 +12,7 @@ class _ChildrenElementList implements ElementList {
: _childElements = element.children,
_element = element;
+ bool get _inDocument() => _nodeInDocument(_element);
List<Element> _toList() {
final output = new List(_childElements.length);
for (int i = 0, len = _childElements.length; i < len; i++) {
@@ -61,6 +62,7 @@ class _ChildrenElementList implements ElementList {
}
void operator []=(int index, Element value) {
+ assert(!_inMeasurementFrame || (!_inDocument && !value._inDocument));
_element.replaceChild(LevelDom.unwrap(value), _childElements.item(index));
}
@@ -70,6 +72,7 @@ class _ChildrenElementList implements ElementList {
}
Element add(Element value) {
+ assert(!_inMeasurementFrame || (!_inDocument && !value._inDocument));
_element.appendChild(LevelDom.unwrap(value));
return value;
}
@@ -79,7 +82,9 @@ class _ChildrenElementList implements ElementList {
Iterator<Element> iterator() => _toList().iterator();
void addAll(Collection<Element> collection) {
+ assert(!_inMeasurementFrame || !_inDocument);
for (Element element in collection) {
+ assert(!_inMeasurementFrame || !element._inDocument);
_element.appendChild(LevelDom.unwrap(element));
}
}
@@ -114,11 +119,13 @@ class _ChildrenElementList implements ElementList {
}
void clear() {
+ assert(!_inMeasurementFrame || !_inDocument);
// It is unclear if we want to keep non element nodes?
_element.textContent = '';
}
Element removeLast() {
+ assert(!_inMeasurementFrame || !_inDocument);
final last = this.last();
if (last != null) {
_element.removeChild(LevelDom.unwrap(last));
@@ -312,10 +319,12 @@ class ElementAttributeMap implements Map<String, String> {
}
String remove(String key) {
+ assert(!_inMeasurementFrame || !_nodeInDocument(_element));
_element.removeAttribute(key);
}
void clear() {
+ assert(!_inMeasurementFrame || !_nodeInDocument(_element));
final attributes = _element.attributes;
for (int i = attributes.length - 1; i >= 0; i--) {
_element.removeAttribute(attributes.item(i).name);
@@ -434,48 +443,52 @@ class SimpleClientRect implements ClientRect {
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
+ * All your element measurement needs in one place.
+ * All members of this class can only be cassed when inside a measurement
+ * frame or when the element is not attached to the DOM.
* @domName none
*/
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 _clientRects; // TODO(jacobr): should be dom.ClientRectList
-
- 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);
+ final dom.HTMLElement _element;
+
+ ElementRectWrappingImplementation(this._element);
+
+ ClientRect get client() {
+ assert(window.inMeasurementFrame || !_nodeInDocument(_element));
+ return new SimpleClientRect(_element.clientLeft,
+ _element.clientTop,
+ _element.clientWidth,
+ _element.clientHeight);
+ }
+
+ ClientRect get offset() {
+ assert(window.inMeasurementFrame || !_nodeInDocument(_element));
+ return new SimpleClientRect(_element.offsetLeft,
+ _element.offsetTop,
+ _element.offsetWidth,
+ _element.offsetHeight);
+ }
+
+ ClientRect get scroll() {
+ assert(window.inMeasurementFrame || !_nodeInDocument(_element));
+ return new SimpleClientRect(_element.scrollLeft,
+ _element.scrollTop,
+ _element.scrollWidth,
+ _element.scrollHeight);
+ }
+
+ ClientRect get bounding() {
+ assert(window.inMeasurementFrame || !_nodeInDocument(_element));
+ return LevelDom.wrapClientRect(_element.getBoundingClientRect());
+ }
List<ClientRect> get clientRects() {
- final out = new List(_clientRects.length);
- for (num i = 0; i < _clientRects.length; i++) {
- out[i] = LevelDom.wrapClientRect(_clientRects.item(i));
+ assert(window.inMeasurementFrame || !_nodeInDocument(_element));
+ final clientRects = _element.getClientRects();
+ final out = new List(clientRects.length);
+ for (num i = 0, len = clientRects.length; i < len; i++) {
+ out[i] = LevelDom.wrapClientRect(clientRects.item(i));
}
return out;
}
@@ -559,6 +572,7 @@ class ElementWrappingImplementation extends NodeWrappingImplementation implement
}
void set attributes(Map<String, String> value) {
+ assert(!_inMeasurementFrame || !_inDocument);
Map<String, String> attributes = this.attributes;
attributes.clear();
for (String key in value.getKeys()) {
@@ -567,6 +581,7 @@ class ElementWrappingImplementation extends NodeWrappingImplementation implement
}
void set elements(Collection<Element> value) {
+ assert(!_inMeasurementFrame || !_inDocument);
final elements = this.elements;
elements.clear();
elements.addAll(value);
@@ -592,6 +607,7 @@ class ElementWrappingImplementation extends NodeWrappingImplementation implement
}
void set classes(Collection<String> value) {
+ assert(!_inMeasurementFrame || !_inDocument);
_CssClassSet classSet = classes;
classSet.clear();
classSet.addAll(value);
@@ -605,6 +621,7 @@ class ElementWrappingImplementation extends NodeWrappingImplementation implement
}
void set dataAttributes(Map<String, String> value) {
+ assert(!_inMeasurementFrame || !_inDocument);
Map<String, String> dataAttributes = this.dataAttributes;
dataAttributes.clear();
for (String key in value.getKeys()) {
@@ -614,11 +631,17 @@ class ElementWrappingImplementation extends NodeWrappingImplementation implement
String get contentEditable() => _ptr.contentEditable;
- void set contentEditable(String value) { _ptr.contentEditable = value; }
+ void set contentEditable(String value) {
+ assert(!_inMeasurementFrame || !_inDocument);
+ _ptr.contentEditable = value;
+ }
String get dir() => _ptr.dir;
- void set dir(String value) { _ptr.dir = value; }
+ void set dir(String value) {
+ assert(!_inMeasurementFrame || !_inDocument);
+ _ptr.dir = value;
+ }
bool get draggable() => _ptr.draggable;
@@ -628,21 +651,33 @@ class ElementWrappingImplementation extends NodeWrappingImplementation implement
bool get hidden() => _ptr.hidden;
- void set hidden(bool value) { _ptr.hidden = value; }
+ void set hidden(bool value) {
+ assert(!_inMeasurementFrame || !_inDocument);
+ _ptr.hidden = value;
+ }
String get id() => _ptr.id;
- void set id(String value) { _ptr.id = value; }
+ void set id(String value) {
+ assert(!_inMeasurementFrame || !_inDocument);
+ _ptr.id = value;
+ }
String get innerHTML() => _ptr.innerHTML;
- void set innerHTML(String value) { _ptr.innerHTML = value; }
+ void set innerHTML(String value) {
+ assert(!_inMeasurementFrame || !_inDocument);
+ _ptr.innerHTML = value;
+ }
bool get isContentEditable() => _ptr.isContentEditable;
String get lang() => _ptr.lang;
- void set lang(String value) { _ptr.lang = value; }
+ void set lang(String value) {
+ assert(!_inMeasurementFrame || !_inDocument);
+ _ptr.lang = value;
+ }
Element get lastElementChild() => LevelDom.wrapElement(_ptr.lastElementChild);
@@ -656,25 +691,46 @@ class ElementWrappingImplementation extends NodeWrappingImplementation implement
bool get spellcheck() => _ptr.spellcheck;
- void set spellcheck(bool value) { _ptr.spellcheck = value; }
+ void set spellcheck(bool value) {
+ assert(!_inMeasurementFrame || !_inDocument);
+ _ptr.spellcheck = value;
+ }
- CSSStyleDeclaration get style() => LevelDom.wrapCSSStyleDeclaration(_ptr.style);
+ CSSStyleDeclaration get style() {
+ // Changes to this CSSStyleDeclaration dirty the layout so we must pass
+ // the associated Element to the CSSStyleDeclaration constructor so that
+ // we can compute whether the current element is attached to the document
+ // which is required to decide whether modification inside a measurement
+ // frame is allowed.
+ final raw = _ptr.style;
+ return raw.dartObjectLocalStorage !== null ?
+ raw.dartObjectLocalStorage :
+ new CSSStyleDeclarationWrappingImplementation._wrapWithElement(
+ raw, this);
+ }
int get tabIndex() => _ptr.tabIndex;
- void set tabIndex(int value) { _ptr.tabIndex = value; }
+ void set tabIndex(int value) {
+ assert(!_inMeasurementFrame || !_inDocument);
+ _ptr.tabIndex = value;
+ }
String get tagName() => _ptr.tagName;
String get title() => _ptr.title;
- void set title(String value) { _ptr.title = value; }
+ void set title(String value) {
+ assert(!_inMeasurementFrame || !_inDocument);
+ _ptr.title = value;
+ }
String get webkitdropzone() => _ptr.webkitdropzone;
void set webkitdropzone(String value) { _ptr.webkitdropzone = value; }
void blur() {
+ assert(!_inMeasurementFrame || !_inDocument);
_ptr.blur();
}
@@ -683,18 +739,22 @@ class ElementWrappingImplementation extends NodeWrappingImplementation implement
}
void focus() {
+ assert(!_inMeasurementFrame || !_inDocument);
_ptr.focus();
}
Element insertAdjacentElement([String where = null, Element element = null]) {
+ assert(!_inMeasurementFrame || !_inDocument);
return LevelDom.wrapElement(_ptr.insertAdjacentElement(where, LevelDom.unwrap(element)));
}
void insertAdjacentHTML([String position_OR_where = null, String text = null]) {
+ assert(!_inMeasurementFrame || !_inDocument);
_ptr.insertAdjacentHTML(position_OR_where, text);
}
void insertAdjacentText([String where = null, String text = null]) {
+ assert(!_inMeasurementFrame || !_inDocument);
_ptr.insertAdjacentText(where, text);
}
@@ -739,24 +799,21 @@ class ElementWrappingImplementation extends NodeWrappingImplementation implement
* clientTop, clientLeft, offsetHeight, offsetWidth, offsetTop, offsetLeft,
* scrollHeight, scrollWidth, scrollTop, scrollLeft
*/
- Future<ElementRect> get rect() {
- return _createMeasurementFuture(
- () => new ElementRectWrappingImplementation(_ptr),
- new Completer<ElementRect>());
+ ElementRect get rect() {
+ return new ElementRectWrappingImplementation(_ptr);
}
/** @domName Window.getComputedStyle */
- Future<CSSStyleDeclaration> get computedStyle() {
+ CSSStyleDeclaration get computedStyle() {
// TODO(jacobr): last param should be null, see b/5045788
- return getComputedStyle('');
+ return getComputedStyle('');
}
/** @domName Window.getComputedStyle */
- Future<CSSStyleDeclaration> getComputedStyle(String pseudoElement) {
- return _createMeasurementFuture(() =>
- LevelDom.wrapCSSStyleDeclaration(
- dom.window.getComputedStyle(_ptr, pseudoElement)),
- new Completer<CSSStyleDeclaration>());
+ CSSStyleDeclaration getComputedStyle(String pseudoElement) {
+ assert(window.inMeasurementFrame || !_inDocument);
+ return LevelDom.wrapCSSStyleDeclaration(
+ dom.window.getComputedStyle(_ptr, pseudoElement));
}
ElementEvents get on() {

Powered by Google App Engine
This is Rietveld 408576698