[Effen] Move 'flex' out of CSS also. (mark II)

This introduces a new kind of ContentNode similar to Style but which
instead of changing the styles that apply to the node, provides new
settings to apply to the "parentData" structure.

R=eseidel@chromium.org

Review URL: https://codereview.chromium.org/1122413006
This commit is contained in:
Hixie 2015-05-12 10:40:43 -07:00
parent 42fc77f4b4
commit 02045e37a4
5 changed files with 72 additions and 8 deletions

View File

@ -16,8 +16,9 @@ class ActionBar extends Component {
padding-top: ${kStatusBarHeight}px;''');
static Style _centerStyle = new Style('''
padding-left: 24px;
flex: 1;''');
padding-left: 24px;''');
static FlexBoxParentData _centerLayoutSettings = new FlexBoxParentData()..flex = 1;
UINode left;
UINode center;
@ -31,7 +32,7 @@ class ActionBar extends Component {
}) : super(key: key);
UINode build() {
List<UINode> children = [left, new StyleNode(center, _centerStyle)];
List<UINode> children = [left, new StyleNode(new ParentDataNode(center, _centerLayoutSettings), _centerStyle)];
if (right != null)
children.addAll(right);

View File

@ -148,6 +148,12 @@ class StyleNode extends ContentNode {
StyleNode(UINode content, this.style): super(content);
}
class ParentDataNode extends ContentNode {
final ParentData parentData;
ParentDataNode(UINode content, this.parentData): super(content);
}
/*
* SkyNodeWrappers correspond to a desired state of a RenderCSS. They are fully
* immutable, with one exception: A UINode which is a Component which lives within
@ -389,14 +395,28 @@ abstract class SkyElementWrapper extends SkyNodeWrapper {
List<Style> styles = new List<Style>();
if (style != null)
styles.add(style);
ParentData parentData = null;
UINode parent = _parent;
while (parent != null && parent is! SkyNodeWrapper) {
if (parent is StyleNode && parent.style != null)
styles.add(parent.style);
else
if (parent is ParentDataNode && parent.parentData != null) {
if (parentData != null)
parentData.merge(parent.parentData); // this will throw if the types aren't the same
else
parentData = parent.parentData;
}
parent = parent._parent;
}
_root.updateStyles(styles);
if (parentData != null) {
assert(_root.parentData != null);
_root.parentData.merge(parentData); // this will throw if the types aren't approriate
assert(parent != null);
assert(parent._root != null);
parent._root.markNeedsLayout();
}
_root.updateInlineStyle(inlineStyle);
_syncChildren(oldSkyElementWrapper);

View File

@ -53,6 +53,10 @@ class ParentData {
detachSiblings();
}
void detachSiblings() { } // workaround for lack of inter-class mixins in Dart
void merge(ParentData other) {
// override this in subclasses to merge in data from other into this
assert(other.runtimeType == this.runtimeType);
}
}
abstract class RenderNode extends Node {
@ -261,8 +265,19 @@ abstract class RenderCSS extends RenderBox {
return styles.map((s) => s._className).join(' ');
}
String _inlineStyles = '';
String _additionalStylesFromParent = ''; // used internally to propagate parentData settings to the child
void updateInlineStyle(String newStyle) {
_skyElement.setAttribute('style', newStyle);
_inlineStyles = newStyle != null ? newStyle : '';
_updateInlineStyleAttribute();
}
void _updateInlineStyleAttribute() {
if ((_inlineStyles != '') && (_additionalStylesFromParent != ''))
_skyElement.setAttribute('style', "$_inlineStyles;$_additionalStylesFromParent");
else
_skyElement.setAttribute('style', "$_inlineStyles$_additionalStylesFromParent");
}
double get width {
@ -320,7 +335,14 @@ class RenderCSSContainer extends RenderCSS with ContainerRenderNodeMixin<RenderC
}
class FlexBoxParentData extends CSSParentData { }
class FlexBoxParentData extends CSSParentData {
int flex;
void merge(FlexBoxParentData other) {
if (other.flex != null)
flex = other.flex;
super.merge(other);
}
}
enum FlexDirection { Row }
@ -351,6 +373,21 @@ class RenderCSSFlex extends RenderCSSContainer {
return super.stylesToClasses(styles) + ' ' + settings;
}
void markNeedsLayout() {
super.markNeedsLayout();
// pretend we did the layout:
RenderCSS child = _firstChild;
while (child != null) {
assert(child.parentData is FlexBoxParentData);
if (child.parentData.flex != null) {
child._additionalStylesFromParent = 'flex:${child.parentData.flex};';
child._updateInlineStyleAttribute();
}
child = child.parentData.nextSibling;
}
}
}
class RenderCSSText extends RenderCSS {

View File

@ -1,6 +1,6 @@
<div debug="Instance of 'TestApp'">
<div debug="Instance of 'Container'" class="" style="background-color: green">
<div class="style1" debug="Instance of 'Text'">I am Text</div>
<img debug="Instance of 'Image'" src="resources/united.jpg" class=""></img>
<img debug="Instance of 'Image'" src="resources/united.jpg" class="" style=""></img>
</div>
</div><style>.style1 { display:paragraph }</style>

View File

@ -8,7 +8,13 @@ import 'dart:sky.internals' as internals;
void main() {
new TestApp();
runAfterDisplay(() {
internals.notifyTestComplete(serializeNode(document.lastChild.previousSibling) + serializeNode(document.lastChild));
var result = serializeNode(document.lastChild.previousSibling) + serializeNode(document.lastChild);
try {
internals.notifyTestComplete(result);
} catch (e) {
print(e);
print(result);
}
});
}
</script>