| Index: third_party/pkg/angular/lib/core_dom/event_handler.dart
|
| diff --git a/third_party/pkg/angular/lib/core_dom/event_handler.dart b/third_party/pkg/angular/lib/core_dom/event_handler.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..1a0f5d9b5336a75717c6db75f103c76cdb794b88
|
| --- /dev/null
|
| +++ b/third_party/pkg/angular/lib/core_dom/event_handler.dart
|
| @@ -0,0 +1,110 @@
|
| +part of angular.core.dom_internal;
|
| +
|
| +typedef void EventFunction(event);
|
| +
|
| +/**
|
| + * [EventHandler] is responsible for handling events bound using on-* syntax
|
| + * (i.e. `on-click="ctrl.doSomething();"`). The root of the application has an
|
| + * EventHandler attached as does every [Component].
|
| + *
|
| + * Events bound within [Component] are handled by EventHandler attached to
|
| + * their [ShadowRoot]. All other events are handled by EventHandler attached
|
| + * to the application root ([Application]).
|
| + *
|
| + * **Note**: The expressions are executed within the closest context.
|
| + *
|
| + * Example:
|
| + *
|
| + * <div foo>
|
| + * <button on-click="ctrl.say('Hello');">Button</button>;
|
| + * </div>
|
| + *
|
| + * @Component(selector: '[foo]', publishAs: ctrl)
|
| + * class FooController {
|
| + * say(String something) => print(something);
|
| + * }
|
| + *
|
| + * When button is clicked, "Hello" will be printed in the console.
|
| + */
|
| +@Injectable()
|
| +class EventHandler {
|
| + dom.Node _rootNode;
|
| + final Expando _expando;
|
| + final ExceptionHandler _exceptionHandler;
|
| + final _listeners = <String, Function>{};
|
| +
|
| + EventHandler(this._rootNode, this._expando, this._exceptionHandler);
|
| +
|
| + /**
|
| + * Register an event. This makes sure that an event (of the specified name)
|
| + * which bubbles to this node, gets processed by this [EventHandler].
|
| + */
|
| + void register(String eventName) {
|
| + _listeners.putIfAbsent(eventName, () {
|
| + dom.EventListener eventListener = this._eventListener;
|
| + _rootNode.on[eventName].listen(eventListener);
|
| + return eventListener;
|
| + });
|
| + }
|
| +
|
| + void _eventListener(dom.Event event) {
|
| + dom.Node element = event.target;
|
| + while (element != null && element != _rootNode) {
|
| + var expression;
|
| + if (element is dom.Element)
|
| + expression = (element as dom.Element).attributes[eventNameToAttrName(event.type)];
|
| + if (expression != null) {
|
| + try {
|
| + var scope = _getScope(element);
|
| + if (scope != null) scope.eval(expression);
|
| + } catch (e, s) {
|
| + _exceptionHandler(e, s);
|
| + }
|
| + }
|
| + element = element.parentNode;
|
| + }
|
| + }
|
| +
|
| + Scope _getScope(dom.Node element) {
|
| + // var topElement = (rootNode is dom.ShadowRoot) ? rootNode.parentNode : rootNode;
|
| + while (element != _rootNode.parentNode) {
|
| + ElementProbe probe = _expando[element];
|
| + if (probe != null) {
|
| + return probe.scope;
|
| + }
|
| + element = element.parentNode;
|
| + }
|
| + return null;
|
| + }
|
| +
|
| + /**
|
| + * Converts event name into attribute. Event named 'someCustomEvent' needs to
|
| + * be transformed into on-some-custom-event.
|
| + */
|
| + static String eventNameToAttrName(String eventName) {
|
| + var part = eventName.replaceAllMapped(new RegExp("([A-Z])"), (Match match) {
|
| + return '-${match.group(0).toLowerCase()}';
|
| + });
|
| + return 'on-${part}';
|
| + }
|
| +
|
| + /**
|
| + * Converts attribute into event name. Attribute 'on-some-custom-event'
|
| + * corresponds to event named 'someCustomEvent'.
|
| + */
|
| + static String attrNameToEventName(String attrName) {
|
| + var part = attrName.startsWith("on-") ? attrName.substring(3) : attrName;
|
| + part = part.replaceAllMapped(new RegExp(r'\-(\w)'), (Match match) {
|
| + return match.group(0).toUpperCase();
|
| + });
|
| + return part.replaceAll("-", "");
|
| + }
|
| +}
|
| +
|
| +@Injectable()
|
| +class ShadowRootEventHandler extends EventHandler {
|
| + ShadowRootEventHandler(dom.ShadowRoot shadowRoot,
|
| + Expando expando,
|
| + ExceptionHandler exceptionHandler)
|
| + : super(shadowRoot, expando, exceptionHandler);
|
| +}
|
|
|