d45d3596c5
Using 2, instead of 1 type arguments is only a warning (this matches the vm) Review URL: http://codereview.chromium.org//8856004 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@2189 260f80e4-7a28-3924-810f-c04153c831b5
121 lines
3.7 KiB
Dart
121 lines
3.7 KiB
Dart
// Copyright (c) 2011, 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 EventsImplementation implements Events {
|
|
/* Raw event target. */
|
|
var _ptr;
|
|
|
|
Map<String, EventListenerList> _listenerMap;
|
|
|
|
EventsImplementation._wrap(this._ptr) {
|
|
// TODO(sigmund): the key type (String) yields a warning in frog and the vm,
|
|
// but it is currently necessary to compile with dartc.
|
|
_listenerMap = <String, EventListenerList>{};
|
|
}
|
|
|
|
EventListenerList operator [](String type) {
|
|
return _get(type.toLowerCase());
|
|
}
|
|
|
|
EventListenerList _get(String type) {
|
|
return _listenerMap.putIfAbsent(type,
|
|
() => new EventListenerListImplementation(_ptr, type));
|
|
}
|
|
}
|
|
|
|
class _EventListenerWrapper {
|
|
final EventListener raw;
|
|
final Function wrapped;
|
|
final bool useCapture;
|
|
_EventListenerWrapper(this.raw, this.wrapped, this.useCapture);
|
|
}
|
|
|
|
class EventListenerListImplementation implements EventListenerList {
|
|
final _ptr;
|
|
final String _type;
|
|
List<_EventListenerWrapper> _wrappers;
|
|
|
|
EventListenerListImplementation(this._ptr, this._type) :
|
|
// TODO(jacobr): switch to <_EventListenerWrapper>[] when the VM allow it.
|
|
_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
|
|
// force the event to have the expected type.
|
|
assert(evt.type == _type);
|
|
return _ptr.dispatchEvent(LevelDom.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) {
|
|
return null;
|
|
}
|
|
for (int i = 0; i < _wrappers.length; i++) {
|
|
_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(LevelDom.wrapEvent(e)); };
|
|
_wrappers.add(new _EventListenerWrapper(listener, wrapped, useCapture));
|
|
return wrapped;
|
|
}
|
|
}
|
|
|
|
class EventTargetWrappingImplementation extends DOMWrapperBase implements EventTarget {
|
|
Events _on;
|
|
|
|
EventTargetWrappingImplementation._wrap(ptr) : super._wrap(ptr);
|
|
|
|
Events get on() {
|
|
if (_on === null) {
|
|
_on = new EventsImplementation._wrap(_ptr);
|
|
}
|
|
return _on;
|
|
}
|
|
}
|