Index: client/view/view.dart |
diff --git a/client/view/view.dart b/client/view/view.dart |
index 8b5d99e02fab1306c2aac6dbdc321e4926133a8c..6387d171af5a759e917833bacf738d8e739a5938 100644 |
--- a/client/view/view.dart |
+++ b/client/view/view.dart |
@@ -1,4 +1,4 @@ |
-// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
+// Copyright (c) 2011, 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. |
@@ -168,16 +168,11 @@ class View implements Positionable { |
*/ |
void exitDocument() {} |
- /** |
- * Override this to perform behavior after the window is resized. |
- * This method is guaranteed to be called within a measurement frame. To |
- * manipulate the DOM, return a LayoutCallback which will be execututed |
- * in the normal context. |
- */ |
+ /** Override this to perform behavior after the window is resized. */ |
// TODO(jmesserly): this isn't really the event we want. Ideally we want to |
// fire the event only if this particular View changed size. Also we should |
// give a view the ability to measure itself when added to the document. |
- LayoutCallback windowResized() => null; |
+ void windowResized() {} |
/** |
* Registers the given listener callback to the given observable. Also |
@@ -322,41 +317,43 @@ class View implements Positionable { |
} |
void doLayout() { |
- // Callbacks to execute after all layouts are complete. |
- final callbacks = <LayoutCallback>[]; |
- bool changed = false; |
- void _measureLayout(View v) { |
- assert(window.inMeasurementFrame); |
- LayoutCallback callback = v.windowResized(); |
- if (callback != null) { |
- callbacks.add(callback); |
+ _measureLayout().then((bool changed) { |
+ if (changed) { |
+ _applyLayoutToChildren(); |
} |
- // TODO(jmesserly): this logic is more complex than it needs to be |
- // because we're taking pains to not initialize _layout if it's not |
- // needed. Is that a good tradeoff? |
- if (ViewLayout.hasCustomLayout(v)) { |
- final rect = v._node.rect.client; |
- if (v.layout.measureLayout(rect.width, rect.height)) { |
- changed = true; |
- } |
- } else { |
- for (final child in v.childViews) { |
- _measureLayout(child); |
- } |
- } |
- } |
+ }); |
+ } |
+ |
+ Future<bool> _measureLayout() { |
+ final changed = new Completer<bool>(); |
+ _measureLayoutHelper(changed); |
- window.requestMeasurementFrame(() { |
- _measureLayout(this); |
- return () { |
- if (changed) { |
- _applyLayoutToChildren(); |
- } |
- for (LayoutCallback callback in callbacks) { |
- callback(); |
- } |
- }; |
+ window.requestLayoutFrame(() { |
+ if (!changed.future.isComplete) { |
+ changed.complete(false); |
+ } |
}); |
+ return changed.future; |
+ } |
+ |
+ void _measureLayoutHelper(Completer<bool> changed) { |
+ windowResized(); |
+ |
+ // TODO(jmesserly): this logic is more complex than it needs to be because |
+ // we're taking pains to not initialize _layout if it's not needed. Is that |
+ // a good tradeoff? |
+ if (ViewLayout.hasCustomLayout(this)) { |
+ Completer sizeCompleter = new Completer<Size>(); |
+ _node.rect.then((ElementRect rect) { |
+ sizeCompleter.complete( |
+ new Size(rect.client.width, rect.client.height)); |
+ }); |
+ layout.measureLayout(sizeCompleter.future, changed); |
+ } else { |
+ for (final child in childViews) { |
+ child._measureLayoutHelper(changed); |
+ } |
+ } |
} |
void _applyLayoutToChildren() { |