mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[Effen] add StyleNode
This patch adds a new (non-Render) StyleNode which takes two arguments: A (content) node, which it wraps and a Style object. This allows for styles to be applied to Nodes which are constructed elsewhere (e.g. passed in as arguments). R=abarth@chromium.org Review URL: https://codereview.chromium.org/1027653002
This commit is contained in:
parent
f64fc80e81
commit
082ca7c2c0
@ -40,6 +40,10 @@ class StocksApp extends App {
|
||||
${typography.white.title};'''
|
||||
);
|
||||
|
||||
static Style _stocklistHeight = new Style('''
|
||||
flex: 1;'''
|
||||
);
|
||||
|
||||
List<Stock> _sortedStocks;
|
||||
bool _isSearching = false;
|
||||
bool _isShowingMenu = false;
|
||||
@ -137,7 +141,9 @@ class StocksApp extends App {
|
||||
]
|
||||
);
|
||||
|
||||
var list = new Stocklist(stocks: _sortedStocks, query: _searchQuery);
|
||||
var list = new StyleNode(
|
||||
new Stocklist(stocks: _sortedStocks, query: _searchQuery),
|
||||
_stocklistHeight);
|
||||
|
||||
var fab = new FloatingActionButton(content: new Icon(
|
||||
type: 'content/add_white', size: 24), level: 3);
|
||||
|
||||
@ -9,13 +9,9 @@ import 'dart:sky' as sky;
|
||||
import 'scrollable.dart';
|
||||
|
||||
abstract class FixedHeightScrollable extends Scrollable {
|
||||
// TODO(rafaelw): This component really shouldn't have an opinion
|
||||
// about how it is sized. The owning component should decide whether
|
||||
// it's explicitly sized or flexible or whatever...
|
||||
static final Style _style = new Style('''
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
flex: 1;
|
||||
will-change: transform;'''
|
||||
);
|
||||
|
||||
|
||||
@ -52,6 +52,29 @@ class Style {
|
||||
Style._internal(this._className);
|
||||
}
|
||||
|
||||
abstract class ContentNode extends Node {
|
||||
Node content;
|
||||
|
||||
ContentNode(Node content) : this.content = content, super(key: content._key);
|
||||
|
||||
void _sync(Node old, sky.ParentNode host, sky.Node insertBefore) {
|
||||
Node oldContent = old == null ? null : (old as ContentNode).content;
|
||||
content = _syncChild(content, oldContent, host, insertBefore);
|
||||
_root = content._root;
|
||||
}
|
||||
|
||||
void _remove() {
|
||||
_removeChild(content);
|
||||
super._remove();
|
||||
}
|
||||
}
|
||||
|
||||
class StyleNode extends ContentNode {
|
||||
final Style style;
|
||||
|
||||
StyleNode(Node content, this.style): super(content);
|
||||
}
|
||||
|
||||
void _parentInsertBefore(sky.ParentNode parent,
|
||||
sky.Node node,
|
||||
sky.Node ref) {
|
||||
@ -133,8 +156,7 @@ abstract class Node {
|
||||
// new component was built that could re-use some of it. Consider
|
||||
// syncing the new VDOM against the old one.
|
||||
if (oldNode != null && node._key != oldNode._key) {
|
||||
_trace('_sync(remove) ${node._key}');
|
||||
oldNode._remove();
|
||||
_removeChild(oldNode);
|
||||
}
|
||||
|
||||
if (node._willSync(oldNode)) {
|
||||
@ -207,8 +229,7 @@ typedef GestureEventListener(sky.GestureEvent e);
|
||||
typedef PointerEventListener(sky.PointerEvent e);
|
||||
typedef EventListener(sky.Event e);
|
||||
|
||||
class EventTarget extends Node {
|
||||
Node content;
|
||||
class EventTarget extends ContentNode {
|
||||
final Map<String, sky.EventListener> listeners;
|
||||
|
||||
static final Set<String> _registeredEvents = new HashSet<String>();
|
||||
@ -270,8 +291,7 @@ class EventTarget extends Node {
|
||||
PointerEventListener onPointerMove,
|
||||
PointerEventListener onPointerUp,
|
||||
Map<String, sky.EventListener> custom
|
||||
}) : this.content = content,
|
||||
listeners = _createListeners(
|
||||
}) : listeners = _createListeners(
|
||||
onWheel: onWheel,
|
||||
onGestureFlingCancel: onGestureFlingCancel,
|
||||
onGestureFlingStart: onGestureFlingStart,
|
||||
@ -285,7 +305,7 @@ class EventTarget extends Node {
|
||||
onPointerUp: onPointerUp,
|
||||
custom: custom
|
||||
),
|
||||
super(key: content._key);
|
||||
super(content);
|
||||
|
||||
void _handleEvent(sky.Event e) {
|
||||
sky.EventListener listener = listeners[e.type];
|
||||
@ -318,14 +338,7 @@ class EventTarget extends Node {
|
||||
_ensureDocumentListener(type);
|
||||
}
|
||||
|
||||
Node oldContent = old == null ? null : (old as EventTarget).content;
|
||||
content = _syncChild(content, oldContent , host, insertBefore);
|
||||
_root = content._root;
|
||||
}
|
||||
|
||||
void _remove() {
|
||||
_removeChild(content);
|
||||
super._remove();
|
||||
super._sync(old, host, insertBefore);
|
||||
}
|
||||
}
|
||||
|
||||
@ -362,18 +375,18 @@ abstract class Element extends RenderNode {
|
||||
|
||||
sky.Node _createNode() => sky.document.createElement(_tagName);
|
||||
|
||||
final List<Node> children;
|
||||
final Style style;
|
||||
final String inlineStyle;
|
||||
|
||||
final List<Node> _children;
|
||||
final String _class;
|
||||
String _class;
|
||||
|
||||
Element({
|
||||
Object key,
|
||||
List<Node> children,
|
||||
Style style,
|
||||
this.style,
|
||||
this.inlineStyle
|
||||
}) : _class = style == null ? '' : style._className,
|
||||
_children = children == null ? _emptyList : children,
|
||||
}) : this.children = children == null ? _emptyList : children,
|
||||
super(key:key) {
|
||||
|
||||
if (_isInCheckedMode) {
|
||||
@ -383,8 +396,8 @@ abstract class Element extends RenderNode {
|
||||
|
||||
void _remove() {
|
||||
super._remove();
|
||||
if (_children != null) {
|
||||
for (var child in _children) {
|
||||
if (children != null) {
|
||||
for (var child in children) {
|
||||
_removeChild(child);
|
||||
}
|
||||
}
|
||||
@ -392,7 +405,7 @@ abstract class Element extends RenderNode {
|
||||
|
||||
void _debugReportDuplicateIds() {
|
||||
var idSet = new HashSet<String>();
|
||||
for (var child in _children) {
|
||||
for (var child in children) {
|
||||
if (child is Text) {
|
||||
continue; // Text nodes all have the same key and are never reordered.
|
||||
}
|
||||
@ -404,10 +417,30 @@ abstract class Element extends RenderNode {
|
||||
}
|
||||
}
|
||||
|
||||
void _ensureClass() {
|
||||
if (_class == null) {
|
||||
List<Style> styles = new List<Style>();
|
||||
if (style != null) {
|
||||
styles.add(style);
|
||||
}
|
||||
|
||||
Node parent = _parent;
|
||||
while (parent != null && parent is! RenderNode) {
|
||||
if (parent is StyleNode)
|
||||
styles.add((parent as StyleNode).style);
|
||||
|
||||
parent = parent._parent;
|
||||
}
|
||||
|
||||
_class = styles.map((s) => s._className).join(' ');
|
||||
}
|
||||
}
|
||||
|
||||
void _syncNode(RenderNode old) {
|
||||
Element oldElement = old as Element;
|
||||
sky.Element root = _root as sky.Element;
|
||||
|
||||
_ensureClass();
|
||||
if (_class != oldElement._class)
|
||||
root.setAttribute('class', _class);
|
||||
|
||||
@ -422,9 +455,9 @@ abstract class Element extends RenderNode {
|
||||
assert(root != null);
|
||||
|
||||
var startIndex = 0;
|
||||
var endIndex = _children.length;
|
||||
var endIndex = children.length;
|
||||
|
||||
var oldChildren = oldElement._children;
|
||||
var oldChildren = oldElement.children;
|
||||
var oldStartIndex = 0;
|
||||
var oldEndIndex = oldChildren.length;
|
||||
|
||||
@ -433,13 +466,13 @@ abstract class Element extends RenderNode {
|
||||
Node oldNode = null;
|
||||
|
||||
void sync(int atIndex) {
|
||||
_children[atIndex] = _syncChild(currentNode, oldNode, _root, nextSibling);
|
||||
children[atIndex] = _syncChild(currentNode, oldNode, _root, nextSibling);
|
||||
}
|
||||
|
||||
// Scan backwards from end of list while nodes can be directly synced
|
||||
// without reordering.
|
||||
while (endIndex > startIndex && oldEndIndex > oldStartIndex) {
|
||||
currentNode = _children[endIndex - 1];
|
||||
currentNode = children[endIndex - 1];
|
||||
oldNode = oldChildren[oldEndIndex - 1];
|
||||
|
||||
if (currentNode._key != oldNode._key) {
|
||||
@ -498,7 +531,7 @@ abstract class Element extends RenderNode {
|
||||
// Scan forwards, this time we may re-order;
|
||||
nextSibling = root.firstChild;
|
||||
while (startIndex < endIndex && oldStartIndex < oldEndIndex) {
|
||||
currentNode = _children[startIndex];
|
||||
currentNode = children[startIndex];
|
||||
oldNode = oldChildren[oldStartIndex];
|
||||
|
||||
if (currentNode._key == oldNode._key) {
|
||||
@ -519,7 +552,7 @@ abstract class Element extends RenderNode {
|
||||
// New insertions
|
||||
oldNode = null;
|
||||
while (startIndex < endIndex) {
|
||||
currentNode = _children[startIndex];
|
||||
currentNode = children[startIndex];
|
||||
sync(startIndex);
|
||||
startIndex++;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user