Chromium Code Reviews| Index: client/dom/templates/html/dartium/impl_EventTarget.darttemplate |
| diff --git a/client/dom/templates/html/dartium/impl_EventTarget.darttemplate b/client/dom/templates/html/dartium/impl_EventTarget.darttemplate |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..6cad86779008d9006e84346ce5be3b6a8abf635f |
| --- /dev/null |
| +++ b/client/dom/templates/html/dartium/impl_EventTarget.darttemplate |
| @@ -0,0 +1,115 @@ |
| +// Copyright (c) 2012, 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. |
| + |
| +class _EventsImpl implements Events { |
| + |
| + final _EventTargetImpl _ptr; |
| + |
| + final Map<String, EventListenerList> _listenerMap; |
| + |
| + _EventsImpl(this._ptr) : _listenerMap = <EventListenerList>{}; |
| + |
| + EventListenerList operator [](String type) { |
| + return _get(type.toLowerCase()); |
| + } |
| + |
| + EventListenerList _get(String type) { |
|
nweiz
2012/03/01 21:18:03
Why is this a separate method? Same with _add/_rem
|
| + return _listenerMap.putIfAbsent(type, |
| + () => new _EventListenerListImpl(_ptr, type)); |
| + } |
| +} |
| + |
| +class _EventListenerWrapper { |
| + final EventListener raw; |
| + final Function wrapped; |
| + final bool useCapture; |
| + _EventListenerWrapper(this.raw, this.wrapped, this.useCapture); |
| +} |
| + |
| +class _EventListenerListImpl implements EventListenerList { |
| + final _EventTargetImpl _ptr; |
| + final String _type; |
| + List<_EventListenerWrapper> _wrappers; |
| + |
| + _EventListenerListImpl(this._ptr, this._type) : |
| + // TODO(jacobr): switch to <_EventListenerWrapper>[] when the VM allow it. |
|
nweiz
2012/03/01 21:18:03
Issue number?
|
| + _wrappers = new List<_EventListenerWrapper>(); |
| + |
| + EventListenerList add(EventListener listener, [bool useCapture = false]) { |
| + _add(listener, useCapture); |
| + return this; |
| + } |
| + |
| + EventListenerList remove(EventListener listener, [bool useCapture = false]) { |
| + _remove(listener, useCapture); |
| + return this; |
| + } |
| + |
| + bool dispatch(Event evt) { |
| + // TODO(jacobr): what is the correct behavior here. We could alternately |
|
nweiz
2012/03/01 21:18:03
I like asserting. If the type doesn't match it's a
|
| + // force the event to have the expected type. |
| + assert(evt.type == _type); |
| + return _ptr._dispatchEvent(_unwrap(evt)); |
| + } |
| + |
| + void _add(EventListener listener, bool useCapture) { |
| + _ptr._addEventListener(_type, |
| + _findOrAddWrapper(listener, useCapture), |
| + useCapture); |
| + } |
| + |
| + void _remove(EventListener listener, bool useCapture) { |
| + Function wrapper = _removeWrapper(listener, useCapture); |
| + if (wrapper !== null) { |
| + _ptr._removeEventListener(_type, wrapper, useCapture); |
| + } |
| + } |
| + |
| + Function _removeWrapper(EventListener listener, bool useCapture) { |
| + if (_wrappers === null) { |
|
nweiz
2012/03/01 21:18:03
When is _wrappers ever null? Same question for _fi
|
| + return null; |
| + } |
| + for (int i = 0; i < _wrappers.length; i++) { |
|
nweiz
2012/03/01 21:18:03
Maybe it's my Ruby bias, but I hate mixing raw for
|
| + _EventListenerWrapper wrapper = _wrappers[i]; |
| + if (wrapper.raw === listener && wrapper.useCapture == useCapture) { |
| + // Order doesn't matter so we swap with the last element instead of |
| + // performing a more expensive remove from the middle of the list. |
| + if (i + 1 != _wrappers.length) { |
| + _wrappers[i] = _wrappers.removeLast(); |
| + } else { |
| + _wrappers.removeLast(); |
| + } |
| + return wrapper.wrapped; |
| + } |
| + } |
| + return null; |
| + } |
| + |
| + Function _findOrAddWrapper(EventListener listener, bool useCapture) { |
| + if (_wrappers === null) { |
| + _wrappers = <_EventListenerWrapper>[]; |
| + } else { |
| + for (_EventListenerWrapper wrapper in _wrappers) { |
| + if (wrapper.raw === listener && wrapper.useCapture == useCapture) { |
| + return wrapper.wrapped; |
| + } |
| + } |
| + } |
| + final wrapped = (e) { listener(_wrap(e)); }; |
|
nweiz
2012/03/01 21:18:03
Style nit: wrapped = listener . _wrap
Oh wait, wr
|
| + _wrappers.add(new _EventListenerWrapper(listener, wrapped, useCapture)); |
| + return wrapped; |
| + } |
| +} |
| + |
| +class $CLASSNAME$EXTENDS$IMPLEMENTS$NATIVESPEC { |
| + |
| + Events _on; |
| + |
| + Events get on() { |
| + if (_on == null) _on = new _EventsImpl(this); |
| + return _on; |
| + } |
| + |
| +$!MEMBERS |
| +} |