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

Side by Side Diff: sky/framework/fn.dart

Issue 1027653002: [Effen] add StyleNode (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: moar Created 5 years, 9 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 unified diff | Download patch
« no previous file with comments | « sky/framework/components/fixed_height_scrollable.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 library fn; 5 library fn;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection'; 8 import 'dart:collection';
9 import 'dart:sky' as sky; 9 import 'dart:sky' as sky;
10 import 'reflect.dart' as reflect; 10 import 'reflect.dart' as reflect;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 sky.Element styleNode = sky.document.createElement('style'); 45 sky.Element styleNode = sky.document.createElement('style');
46 styleNode.setChild(new sky.Text(".$className { $styles }")); 46 styleNode.setChild(new sky.Text(".$className { $styles }"));
47 sky.document.appendChild(styleNode); 47 sky.document.appendChild(styleNode);
48 return new Style._internal(className); 48 return new Style._internal(className);
49 }); 49 });
50 } 50 }
51 51
52 Style._internal(this._className); 52 Style._internal(this._className);
53 } 53 }
54 54
55 abstract class ContentNode extends Node {
56 Node content;
57
58 ContentNode(Node content) : this.content = content, super(key: content._key);
59
60 void _sync(Node old, sky.ParentNode host, sky.Node insertBefore) {
61 Node oldContent = old == null ? null : (old as ContentNode).content;
62 content = _syncChild(content, oldContent, host, insertBefore);
63 _root = content._root;
64 }
65
66 void _remove() {
67 _removeChild(content);
68 super._remove();
69 }
70 }
71
72 class StyleNode extends ContentNode {
73 final Style style;
74
75 StyleNode(Node content, this.style): super(content);
76 }
77
55 void _parentInsertBefore(sky.ParentNode parent, 78 void _parentInsertBefore(sky.ParentNode parent,
56 sky.Node node, 79 sky.Node node,
57 sky.Node ref) { 80 sky.Node ref) {
58 if (ref != null) { 81 if (ref != null) {
59 ref.insertBefore([node]); 82 ref.insertBefore([node]);
60 } else { 83 } else {
61 parent.appendChild(node); 84 parent.appendChild(node);
62 } 85 }
63 } 86 }
64 87
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 149
127 if (node == oldNode) { 150 if (node == oldNode) {
128 _trace('_sync(identical) ${node._key}'); 151 _trace('_sync(identical) ${node._key}');
129 return node; // Nothing to do. Subtrees must be identical. 152 return node; // Nothing to do. Subtrees must be identical.
130 } 153 }
131 154
132 // TODO(rafaelw): This eagerly removes the old DOM. It may be that a 155 // TODO(rafaelw): This eagerly removes the old DOM. It may be that a
133 // new component was built that could re-use some of it. Consider 156 // new component was built that could re-use some of it. Consider
134 // syncing the new VDOM against the old one. 157 // syncing the new VDOM against the old one.
135 if (oldNode != null && node._key != oldNode._key) { 158 if (oldNode != null && node._key != oldNode._key) {
136 _trace('_sync(remove) ${node._key}'); 159 _removeChild(oldNode);
137 oldNode._remove();
138 } 160 }
139 161
140 if (node._willSync(oldNode)) { 162 if (node._willSync(oldNode)) {
141 _trace('_sync(statefull) ${node._key}'); 163 _trace('_sync(statefull) ${node._key}');
142 oldNode._sync(node, host, insertBefore); 164 oldNode._sync(node, host, insertBefore);
143 node._defunct = true; 165 node._defunct = true;
144 assert(oldNode._root is sky.Node); 166 assert(oldNode._root is sky.Node);
145 return oldNode; 167 return oldNode;
146 } 168 }
147 169
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 _root.remove(); 222 _root.remove();
201 _nodeMap.remove(_root); 223 _nodeMap.remove(_root);
202 super._remove(); 224 super._remove();
203 } 225 }
204 } 226 }
205 227
206 typedef GestureEventListener(sky.GestureEvent e); 228 typedef GestureEventListener(sky.GestureEvent e);
207 typedef PointerEventListener(sky.PointerEvent e); 229 typedef PointerEventListener(sky.PointerEvent e);
208 typedef EventListener(sky.Event e); 230 typedef EventListener(sky.Event e);
209 231
210 class EventTarget extends Node { 232 class EventTarget extends ContentNode {
211 Node content;
212 final Map<String, sky.EventListener> listeners; 233 final Map<String, sky.EventListener> listeners;
213 234
214 static final Set<String> _registeredEvents = new HashSet<String>(); 235 static final Set<String> _registeredEvents = new HashSet<String>();
215 236
216 static Map<String, sky.EventListener> _createListeners({ 237 static Map<String, sky.EventListener> _createListeners({
217 EventListener onWheel, 238 EventListener onWheel,
218 GestureEventListener onGestureFlingCancel, 239 GestureEventListener onGestureFlingCancel,
219 GestureEventListener onGestureFlingStart, 240 GestureEventListener onGestureFlingStart,
220 GestureEventListener onGestureScrollStart, 241 GestureEventListener onGestureScrollStart,
221 GestureEventListener onGestureScrollUpdate, 242 GestureEventListener onGestureScrollUpdate,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 GestureEventListener onGestureFlingStart, 284 GestureEventListener onGestureFlingStart,
264 GestureEventListener onGestureScrollStart, 285 GestureEventListener onGestureScrollStart,
265 GestureEventListener onGestureScrollUpdate, 286 GestureEventListener onGestureScrollUpdate,
266 GestureEventListener onGestureTap, 287 GestureEventListener onGestureTap,
267 GestureEventListener onGestureTapDown, 288 GestureEventListener onGestureTapDown,
268 PointerEventListener onPointerCancel, 289 PointerEventListener onPointerCancel,
269 PointerEventListener onPointerDown, 290 PointerEventListener onPointerDown,
270 PointerEventListener onPointerMove, 291 PointerEventListener onPointerMove,
271 PointerEventListener onPointerUp, 292 PointerEventListener onPointerUp,
272 Map<String, sky.EventListener> custom 293 Map<String, sky.EventListener> custom
273 }) : this.content = content, 294 }) : listeners = _createListeners(
274 listeners = _createListeners(
275 onWheel: onWheel, 295 onWheel: onWheel,
276 onGestureFlingCancel: onGestureFlingCancel, 296 onGestureFlingCancel: onGestureFlingCancel,
277 onGestureFlingStart: onGestureFlingStart, 297 onGestureFlingStart: onGestureFlingStart,
278 onGestureScrollUpdate: onGestureScrollUpdate, 298 onGestureScrollUpdate: onGestureScrollUpdate,
279 onGestureScrollStart: onGestureScrollStart, 299 onGestureScrollStart: onGestureScrollStart,
280 onGestureTap: onGestureTap, 300 onGestureTap: onGestureTap,
281 onGestureTapDown: onGestureTapDown, 301 onGestureTapDown: onGestureTapDown,
282 onPointerCancel: onPointerCancel, 302 onPointerCancel: onPointerCancel,
283 onPointerDown: onPointerDown, 303 onPointerDown: onPointerDown,
284 onPointerMove: onPointerMove, 304 onPointerMove: onPointerMove,
285 onPointerUp: onPointerUp, 305 onPointerUp: onPointerUp,
286 custom: custom 306 custom: custom
287 ), 307 ),
288 super(key: content._key); 308 super(content);
289 309
290 void _handleEvent(sky.Event e) { 310 void _handleEvent(sky.Event e) {
291 sky.EventListener listener = listeners[e.type]; 311 sky.EventListener listener = listeners[e.type];
292 if (listener != null) { 312 if (listener != null) {
293 listener(e); 313 listener(e);
294 } 314 }
295 } 315 }
296 316
297 static void _dispatchEvent(sky.Event e) { 317 static void _dispatchEvent(sky.Event e) {
298 Node target = RenderNode._getMounted(e.target); 318 Node target = RenderNode._getMounted(e.target);
(...skipping 12 matching lines...) Expand all
311 if (_registeredEvents.add(eventType)) { 331 if (_registeredEvents.add(eventType)) {
312 sky.document.addEventListener(eventType, _dispatchEvent); 332 sky.document.addEventListener(eventType, _dispatchEvent);
313 } 333 }
314 } 334 }
315 335
316 void _sync(Node old, sky.ParentNode host, sky.Node insertBefore) { 336 void _sync(Node old, sky.ParentNode host, sky.Node insertBefore) {
317 for (var type in listeners.keys) { 337 for (var type in listeners.keys) {
318 _ensureDocumentListener(type); 338 _ensureDocumentListener(type);
319 } 339 }
320 340
321 Node oldContent = old == null ? null : (old as EventTarget).content; 341 super._sync(old, host, insertBefore);
322 content = _syncChild(content, oldContent , host, insertBefore);
323 _root = content._root;
324 }
325
326 void _remove() {
327 _removeChild(content);
328 super._remove();
329 } 342 }
330 } 343 }
331 344
332 class Text extends RenderNode { 345 class Text extends RenderNode {
333 final String data; 346 final String data;
334 347
335 // Text nodes are special cases of having non-unique keys (which don't need 348 // Text nodes are special cases of having non-unique keys (which don't need
336 // to be assigned as part of the API). Since they are unique in not having 349 // to be assigned as part of the API). Since they are unique in not having
337 // children, there's little point to reordering, so we always just re-assign 350 // children, there's little point to reordering, so we always just re-assign
338 // the data. 351 // the data.
(...skipping 16 matching lines...) Expand all
355 } 368 }
356 369
357 final List<Node> _emptyList = new List<Node>(); 370 final List<Node> _emptyList = new List<Node>();
358 371
359 abstract class Element extends RenderNode { 372 abstract class Element extends RenderNode {
360 373
361 String get _tagName; 374 String get _tagName;
362 375
363 sky.Node _createNode() => sky.document.createElement(_tagName); 376 sky.Node _createNode() => sky.document.createElement(_tagName);
364 377
378 final List<Node> children;
379 final Style style;
365 final String inlineStyle; 380 final String inlineStyle;
366 381
367 final List<Node> _children; 382 String _class;
368 final String _class;
369 383
370 Element({ 384 Element({
371 Object key, 385 Object key,
372 List<Node> children, 386 List<Node> children,
373 Style style, 387 this.style,
374 this.inlineStyle 388 this.inlineStyle
375 }) : _class = style == null ? '' : style._className, 389 }) : this.children = children == null ? _emptyList : children,
376 _children = children == null ? _emptyList : children,
377 super(key:key) { 390 super(key:key) {
378 391
379 if (_isInCheckedMode) { 392 if (_isInCheckedMode) {
380 _debugReportDuplicateIds(); 393 _debugReportDuplicateIds();
381 } 394 }
382 } 395 }
383 396
384 void _remove() { 397 void _remove() {
385 super._remove(); 398 super._remove();
386 if (_children != null) { 399 if (children != null) {
387 for (var child in _children) { 400 for (var child in children) {
388 _removeChild(child); 401 _removeChild(child);
389 } 402 }
390 } 403 }
391 } 404 }
392 405
393 void _debugReportDuplicateIds() { 406 void _debugReportDuplicateIds() {
394 var idSet = new HashSet<String>(); 407 var idSet = new HashSet<String>();
395 for (var child in _children) { 408 for (var child in children) {
396 if (child is Text) { 409 if (child is Text) {
397 continue; // Text nodes all have the same key and are never reordered. 410 continue; // Text nodes all have the same key and are never reordered.
398 } 411 }
399 412
400 if (!idSet.add(child._key)) { 413 if (!idSet.add(child._key)) {
401 throw '''If multiple (non-Text) nodes of the same type exist as children 414 throw '''If multiple (non-Text) nodes of the same type exist as children
402 of another node, they must have unique keys.'''; 415 of another node, they must have unique keys.''';
403 } 416 }
404 } 417 }
405 } 418 }
406 419
420 void _ensureClass() {
421 if (_class == null) {
422 List<Style> styles = new List<Style>();
423 if (style != null) {
424 styles.add(style);
425 }
426
427 Node parent = _parent;
428 while (parent != null && parent is! RenderNode) {
429 if (parent is StyleNode)
430 styles.add((parent as StyleNode).style);
431
432 parent = parent._parent;
433 }
434
435 _class = styles.map((s) => s._className).join(' ');
436 }
437 }
438
407 void _syncNode(RenderNode old) { 439 void _syncNode(RenderNode old) {
408 Element oldElement = old as Element; 440 Element oldElement = old as Element;
409 sky.Element root = _root as sky.Element; 441 sky.Element root = _root as sky.Element;
410 442
443 _ensureClass();
411 if (_class != oldElement._class) 444 if (_class != oldElement._class)
412 root.setAttribute('class', _class); 445 root.setAttribute('class', _class);
413 446
414 if (inlineStyle != oldElement.inlineStyle) 447 if (inlineStyle != oldElement.inlineStyle)
415 root.setAttribute('style', inlineStyle); 448 root.setAttribute('style', inlineStyle);
416 449
417 _syncChildren(oldElement); 450 _syncChildren(oldElement);
418 } 451 }
419 452
420 void _syncChildren(Element oldElement) { 453 void _syncChildren(Element oldElement) {
421 sky.Element root = _root as sky.Element; 454 sky.Element root = _root as sky.Element;
422 assert(root != null); 455 assert(root != null);
423 456
424 var startIndex = 0; 457 var startIndex = 0;
425 var endIndex = _children.length; 458 var endIndex = children.length;
426 459
427 var oldChildren = oldElement._children; 460 var oldChildren = oldElement.children;
428 var oldStartIndex = 0; 461 var oldStartIndex = 0;
429 var oldEndIndex = oldChildren.length; 462 var oldEndIndex = oldChildren.length;
430 463
431 sky.Node nextSibling = null; 464 sky.Node nextSibling = null;
432 Node currentNode = null; 465 Node currentNode = null;
433 Node oldNode = null; 466 Node oldNode = null;
434 467
435 void sync(int atIndex) { 468 void sync(int atIndex) {
436 _children[atIndex] = _syncChild(currentNode, oldNode, _root, nextSibling); 469 children[atIndex] = _syncChild(currentNode, oldNode, _root, nextSibling);
437 } 470 }
438 471
439 // Scan backwards from end of list while nodes can be directly synced 472 // Scan backwards from end of list while nodes can be directly synced
440 // without reordering. 473 // without reordering.
441 while (endIndex > startIndex && oldEndIndex > oldStartIndex) { 474 while (endIndex > startIndex && oldEndIndex > oldStartIndex) {
442 currentNode = _children[endIndex - 1]; 475 currentNode = children[endIndex - 1];
443 oldNode = oldChildren[oldEndIndex - 1]; 476 oldNode = oldChildren[oldEndIndex - 1];
444 477
445 if (currentNode._key != oldNode._key) { 478 if (currentNode._key != oldNode._key) {
446 break; 479 break;
447 } 480 }
448 481
449 endIndex--; 482 endIndex--;
450 oldEndIndex--; 483 oldEndIndex--;
451 sync(endIndex); 484 sync(endIndex);
452 nextSibling = currentNode._root; 485 nextSibling = currentNode._root;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 return false; 524 return false;
492 525
493 oldNodeIdMap[currentNode._key] = null; // mark it reordered. 526 oldNodeIdMap[currentNode._key] = null; // mark it reordered.
494 _parentInsertBefore(root, oldNode._root, nextSibling); 527 _parentInsertBefore(root, oldNode._root, nextSibling);
495 return true; 528 return true;
496 } 529 }
497 530
498 // Scan forwards, this time we may re-order; 531 // Scan forwards, this time we may re-order;
499 nextSibling = root.firstChild; 532 nextSibling = root.firstChild;
500 while (startIndex < endIndex && oldStartIndex < oldEndIndex) { 533 while (startIndex < endIndex && oldStartIndex < oldEndIndex) {
501 currentNode = _children[startIndex]; 534 currentNode = children[startIndex];
502 oldNode = oldChildren[oldStartIndex]; 535 oldNode = oldChildren[oldStartIndex];
503 536
504 if (currentNode._key == oldNode._key) { 537 if (currentNode._key == oldNode._key) {
505 assert(currentNode.runtimeType == oldNode.runtimeType); 538 assert(currentNode.runtimeType == oldNode.runtimeType);
506 nextSibling = nextSibling.nextSibling; 539 nextSibling = nextSibling.nextSibling;
507 sync(startIndex); 540 sync(startIndex);
508 startIndex++; 541 startIndex++;
509 advanceOldStartIndex(); 542 advanceOldStartIndex();
510 continue; 543 continue;
511 } 544 }
512 545
513 oldNode = null; 546 oldNode = null;
514 searchForOldNode(); 547 searchForOldNode();
515 sync(startIndex); 548 sync(startIndex);
516 startIndex++; 549 startIndex++;
517 } 550 }
518 551
519 // New insertions 552 // New insertions
520 oldNode = null; 553 oldNode = null;
521 while (startIndex < endIndex) { 554 while (startIndex < endIndex) {
522 currentNode = _children[startIndex]; 555 currentNode = children[startIndex];
523 sync(startIndex); 556 sync(startIndex);
524 startIndex++; 557 startIndex++;
525 } 558 }
526 559
527 // Removals 560 // Removals
528 currentNode = null; 561 currentNode = null;
529 while (oldStartIndex < oldEndIndex) { 562 while (oldStartIndex < oldEndIndex) {
530 oldNode = oldChildren[oldStartIndex]; 563 oldNode = oldChildren[oldStartIndex];
531 _removeChild(oldNode); 564 _removeChild(oldNode);
532 advanceOldStartIndex(); 565 advanceOldStartIndex();
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
831 864
832 abstract class App extends Component { 865 abstract class App extends Component {
833 sky.Node _host; 866 sky.Node _host;
834 867
835 App() : super(stateful: true) { 868 App() : super(stateful: true) {
836 _host = sky.document.createElement('div'); 869 _host = sky.document.createElement('div');
837 sky.document.appendChild(_host); 870 sky.document.appendChild(_host);
838 _scheduleComponentForRender(this); 871 _scheduleComponentForRender(this);
839 } 872 }
840 } 873 }
OLDNEW
« no previous file with comments | « sky/framework/components/fixed_height_scrollable.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698