| OLD | NEW |
| 1 Sky Event Model | 1 Sky Event Model |
| 2 =============== | 2 =============== |
| 3 | 3 |
| 4 ```dart | 4 ```dart |
| 5 SKY MODULE | 5 SKY MODULE |
| 6 <!-- part of sky:core --> | 6 <!-- part of sky:core --> |
| 7 | 7 |
| 8 <script> | 8 <script> |
| 9 abstract class Event { | 9 abstract class Event<ReturnType> { |
| 10 Event({bool bubbles}) : this._bubbles = bubbles; | 10 Event({bool this.bubbles}); |
| 11 | 11 |
| 12 bool _bubbles; | 12 final bool bubbles; |
| 13 bool get bubbles => _bubbles; | |
| 14 | 13 |
| 15 EventTarget _target; | 14 EventTarget _target; |
| 16 EventTarget get target => _target; | 15 EventTarget get target => _target; |
| 17 | 16 |
| 18 EventTarget _currentTarget; | 17 EventTarget _currentTarget; |
| 19 EventTarget get currentTarget => _currentTarget; | 18 EventTarget get currentTarget => _currentTarget; |
| 20 | 19 |
| 21 bool handled; // precise semantics depend on the event type, but in general, s
et this when you set result | 20 bool handled; // precise semantics depend on the event type, but in general, s
et this when you set result |
| 22 dynamic result; | 21 ReturnType result; |
| 23 | 22 |
| 24 // TODO(ianh): abstract API for doing things at shadow tree boundaries | 23 // TODO(ianh): abstract API for doing things at shadow tree boundaries |
| 25 // TODO(ianh): do events get blocked at scope boundaries, e.g. focus events wh
en both sides are in the scope? | 24 // TODO(ianh): do events get blocked at scope boundaries, e.g. focus events wh
en both sides are in the scope? |
| 26 // TODO(ianh): do events get retargetted, e.g. focus when leaving a custom ele
ment? | 25 // TODO(ianh): do events get retargetted, e.g. focus when leaving a custom ele
ment? |
| 27 } | 26 } |
| 28 | 27 |
| 29 class EventTarget { | 28 class EventTarget { |
| 30 EventTarget() : _eventsController = new DispatcherController<Event>(); | 29 EventTarget() : _eventsController = new DispatcherController<Event>(); |
| 31 | 30 |
| 32 Dispatcher get events => _eventsController.dispatcher; | 31 Dispatcher get events => _eventsController.dispatcher; |
| 33 EventTarget parentNode; | 32 EventTarget parentNode; |
| 34 | 33 |
| 35 List<EventTarget> getEventDispatchChain() { | 34 List<EventTarget> getEventDispatchChain() { |
| 36 if (this.parentNode == null) { | 35 if (this.parentNode == null) { |
| 37 return [this]; | 36 return [this]; |
| 38 } else { | 37 } else { |
| 39 var result = this.parentNode.getEventDispatchChain(); | 38 var result = this.parentNode.getEventDispatchChain(); |
| 40 result.add(this); | 39 result.add(this); |
| 41 return result; | 40 return result; |
| 42 } | 41 } |
| 43 } | 42 } |
| 44 | 43 |
| 45 final DispatcherController _eventsController; | 44 final DispatcherController _eventsController; |
| 46 | 45 |
| 47 dynamic dispatchEvent(Event event, { defaultResult: null }) { // O(N*M) where
N is the length of the chain and M is the average number of listeners per link i
n the chain | 46 dynamic dispatchEvent(Event event, { defaultResult: null }) { // O(N*M) where
N is the length of the chain and M is the average number of listeners per link i
n the chain |
| 48 // note: this will throw if any of the listeners threw | 47 // note: this will throw an ExceptionListException<ExceptionListException> i
f any of the listeners threw |
| 49 assert(event != null); // event must be non-null | 48 assert(event != null); // event must be non-null |
| 50 event.handled = false; | 49 event.handled = false; |
| 51 event.result = defaultResult; | 50 event.result = defaultResult; |
| 52 event._target = this; | 51 event._target = this; |
| 53 var chain = this.getEventDispatchChain(); | 52 var chain = this.getEventDispatchChain(); |
| 54 var exceptions = new ExceptionListException<ExceptionListException<Exception
>>(); | 53 var exceptions = new ExceptionListException<ExceptionListException>(); |
| 55 for (var link in chain) { | 54 for (var link in chain) { |
| 56 try { | 55 try { |
| 57 link._dispatchEventLocally(event); | 56 link._dispatchEventLocally(event); |
| 58 } on ExceptionListException<Exception> catch (e) { | 57 } on ExceptionListException catch (e) { |
| 59 exceptions.add(e); | 58 exceptions.add(e); |
| 60 } | 59 } |
| 61 } | 60 } |
| 62 if (exceptions.length > 0) | 61 if (exceptions.length > 0) |
| 63 throw exceptions; | 62 throw exceptions; |
| 64 return event.result; | 63 return event.result; |
| 65 } | 64 } |
| 66 | 65 |
| 67 void _dispatchEventLocally(Event event) { | 66 void _dispatchEventLocally(Event event) { |
| 68 event._currentTarget = this; | 67 event._currentTarget = this; |
| 69 _eventsController.add(event); | 68 _eventsController.add(event); |
| 70 } | 69 } |
| 71 } | 70 } |
| 72 </script> | 71 </script> |
| 73 ``` | 72 ``` |
| OLD | NEW |