| OLD | NEW |
| 1 part of angular.directive; | 1 part of angular.directive; |
| 2 | 2 |
| 3 // NOTE(deboer): onXX functions are now typed as 'var' instead of 'Getter' | 3 // NOTE(deboer): onXX functions are now typed as 'var' instead of 'Getter' |
| 4 // to work-around https://code.google.com/p/dart/issues/detail?id=13519 | 4 // to work-around https://code.google.com/p/dart/issues/detail?id=13519 |
| 5 | 5 |
| 6 /** | 6 /** |
| 7 * Allows you to specify custom behavior for DOM UI events such as mouse, | 7 * Allows you to specify custom behavior for DOM UI events such as mouse, |
| 8 * keyboard and touch events. | 8 * keyboard and touch events. |
| 9 * | 9 * |
| 10 * The custom behavior is specified via an Angular binding expression specified | 10 * The custom behavior is specified via an Angular binding expression specified |
| 11 * on the `ng-`*event* directive (e.g. `ng-click`). This expression is evaluate
d | 11 * on the `ng-`*event* directive (e.g. `ng-click`). This expression is evaluate
d |
| 12 * on the correct `scope` every time the event occurs. The event is available | 12 * on the correct `scope` every time the event occurs. The event is available |
| 13 * to the expression as `$event`. | 13 * to the expression as `$event`. |
| 14 * | 14 * |
| 15 * This is more secure than inline DOM handlers in HTML that execute arbitrary | 15 * This is more secure than inline DOM handlers in HTML that execute arbitrary |
| 16 * JavaScript code and have access to globals instead of the scope without the | 16 * JavaScript code and have access to globals instead of the scope without the |
| 17 * safety constraints of the Angular expression language. | 17 * safety constraints of the Angular expression language. |
| 18 * | 18 * |
| 19 * Example: | 19 * Example: |
| 20 * | 20 * |
| 21 * <button ng-click="lastEvent='Click'" | 21 * <button ng-click="lastEvent='Click'" |
| 22 * ng-doubleclick="lastEvent='DblClick'"> | 22 * ng-doubleclick="lastEvent='DblClick'"> |
| 23 * Button | 23 * Button |
| 24 * </button> | 24 * </button> |
| 25 * | 25 * |
| 26 * The full list of supported handlers are: | 26 * The full list of supported handlers are: |
| 27 * | 27 * |
| 28 * - [ng-blur] | 28 * - [ng-blur] |
| 29 * - [ng-abort] |
| 30 * - [ng-beforecopy] |
| 31 * - [ng-beforecut] |
| 32 * - [ng-beforepaste] |
| 33 * - [ng-blur] |
| 29 * - [ng-change] | 34 * - [ng-change] |
| 30 * - [ng-click] | 35 * - [ng-click] |
| 31 * - [ng-contextmenu] | 36 * - [ng-contextmenu] |
| 37 * - [ng-copy] |
| 38 * - [ng-cut] |
| 32 * - [ng-doubleclick] | 39 * - [ng-doubleclick] |
| 33 * - [ng-drag] | 40 * - [ng-drag] |
| 34 * - [ng-dragend] | 41 * - [ng-dragend] |
| 35 * - [ng-dragenter] | 42 * - [ng-dragenter] |
| 36 * - [ng-dragleave] | 43 * - [ng-dragleave] |
| 37 * - [ng-dragover] | 44 * - [ng-dragover] |
| 38 * - [ng-dragstart] | 45 * - [ng-dragstart] |
| 39 * - [ng-drop] | 46 * - [ng-drop] |
| 47 * - [ng-error] |
| 40 * - [ng-focus] | 48 * - [ng-focus] |
| 49 * - [ng-fullscreenchange] |
| 50 * - [ng-fullscreenerror]' |
| 51 * - [ng-input] |
| 52 * - [ng-invalid] |
| 41 * - [ng-keydown] | 53 * - [ng-keydown] |
| 42 * - [ng-keypress] | 54 * - [ng-keypress] |
| 43 * - [ng-keyup] | 55 * - [ng-keyup] |
| 56 * - [ng-load] |
| 44 * - [ng-mousedown] | 57 * - [ng-mousedown] |
| 45 * - [ng-mouseenter] | 58 * - [ng-mouseenter] |
| 46 * - [ng-mouseleave] | 59 * - [ng-mouseleave] |
| 47 * - [ng-mousemove] | 60 * - [ng-mousemove] |
| 48 * - [ng-mouseout] | 61 * - [ng-mouseout] |
| 49 * - [ng-mouseover] | 62 * - [ng-mouseover] |
| 50 * - [ng-mouseup] | 63 * - [ng-mouseup] |
| 51 * - [ng-mousewheel] | 64 * - [ng-mousewheel] |
| 65 * - [ng-paste] |
| 66 * - [ng-reset] |
| 52 * - [ng-scroll] | 67 * - [ng-scroll] |
| 68 * - [ng-search] |
| 69 * - [ng-select] |
| 70 * - [ng-selectstart] |
| 71 * - [ng-speechchange] (documented in dart but not available) |
| 53 * - [ng-submit] | 72 * - [ng-submit] |
| 54 * - [ng-touchcancel] | 73 * - [ng-toucheancel] |
| 55 * - [ng-touchend] | 74 * - [ng-touchend] |
| 75 * - [ng-touchenter] |
| 76 * - [ng-touchleave] |
| 56 * - [ng-touchmove] | 77 * - [ng-touchmove] |
| 57 * - [ng-touchstart] | 78 * - [ng-touchstart] |
| 79 * - [ng-transitionend] |
| 58 */ | 80 */ |
| 59 @NgDirective(selector: '[ng-blur]', map: const {'ng-blur': '&onBlu
r'}) | 81 @NgDirective(selector: '[ng-abort]', map: const {'ng-abort':
'&onAbort'}) |
| 60 @NgDirective(selector: '[ng-change]', map: const {'ng-change': '&onCha
nge'}) | 82 @NgDirective(selector: '[ng-beforecopy]', map: const {'ng-beforecopy':
'&onBeforeCopy'}) |
| 61 @NgDirective(selector: '[ng-click]', map: const {'ng-click': '&onCli
ck'}) | 83 @NgDirective(selector: '[ng-beforecut]', map: const {'ng-beforecut':
'&onBeforeCut'}) |
| 62 @NgDirective(selector: '[ng-contextmenu]', map: const {'ng-contextmenu': '&onCon
textMenu'}) | 84 @NgDirective(selector: '[ng-beforepaste]', map: const {'ng-beforepaste':
'&onBeforePaste'}) |
| 63 @NgDirective(selector: '[ng-doubleclick]', map: const {'ng-doubleclick': '&onDou
bleClick'}) | 85 @NgDirective(selector: '[ng-blur]', map: const {'ng-blur':
'&onBlur'}) |
| 64 @NgDirective(selector: '[ng-drag]', map: const {'ng-drag': '&onDra
g'}) | 86 @NgDirective(selector: '[ng-change]', map: const {'ng-change':
'&onChange'}) |
| 65 @NgDirective(selector: '[ng-dragend]', map: const {'ng-dragend': '&onDra
gEnd'}) | 87 @NgDirective(selector: '[ng-click]', map: const {'ng-click':
'&onClick'}) |
| 66 @NgDirective(selector: '[ng-dragenter]', map: const {'ng-dragenter': '&onDra
gEnter'}) | 88 @NgDirective(selector: '[ng-contextmenu]', map: const {'ng-contextmenu':
'&onContextMenu'}) |
| 67 @NgDirective(selector: '[ng-dragleave]', map: const {'ng-dragleave': '&onDra
gLeave'}) | 89 @NgDirective(selector: '[ng-copy]', map: const {'ng-copy':
'&onCopy'}) |
| 68 @NgDirective(selector: '[ng-dragover]', map: const {'ng-dragover': '&onDra
gOver'}) | 90 @NgDirective(selector: '[ng-cut]', map: const {'ng-cut':
'&onCut'}) |
| 69 @NgDirective(selector: '[ng-dragstart]', map: const {'ng-dragstart': '&onDra
gStart'}) | 91 @NgDirective(selector: '[ng-doubleclick]', map: const {'ng-doubleclick':
'&onDoubleClick'}) |
| 70 @NgDirective(selector: '[ng-drop]', map: const {'ng-drop': '&onDro
p'}) | 92 @NgDirective(selector: '[ng-drag]', map: const {'ng-drag':
'&onDrag'}) |
| 71 @NgDirective(selector: '[ng-focus]', map: const {'ng-focus': '&onFoc
us'}) | 93 @NgDirective(selector: '[ng-dragend]', map: const {'ng-dragend':
'&onDragEnd'}) |
| 72 @NgDirective(selector: '[ng-keydown]', map: const {'ng-keydown': '&onKey
Down'}) | 94 @NgDirective(selector: '[ng-dragenter]', map: const {'ng-dragenter':
'&onDragEnter'}) |
| 73 @NgDirective(selector: '[ng-keypress]', map: const {'ng-keypress': '&onKey
Press'}) | 95 @NgDirective(selector: '[ng-dragleave]', map: const {'ng-dragleave':
'&onDragLeave'}) |
| 74 @NgDirective(selector: '[ng-keyup]', map: const {'ng-keyup': '&onKey
Up'}) | 96 @NgDirective(selector: '[ng-dragover]', map: const {'ng-dragover':
'&onDragOver'}) |
| 75 @NgDirective(selector: '[ng-mousedown]', map: const {'ng-mousedown': '&onMou
seDown'}) | 97 @NgDirective(selector: '[ng-dragstart]', map: const {'ng-dragstart':
'&onDragStart'}) |
| 76 @NgDirective(selector: '[ng-mouseenter]', map: const {'ng-mouseenter': '&onMou
seEnter'}) | 98 @NgDirective(selector: '[ng-drop]', map: const {'ng-drop':
'&onDrop'}) |
| 77 @NgDirective(selector: '[ng-mouseleave]', map: const {'ng-mouseleave': '&onMou
seLeave'}) | 99 @NgDirective(selector: '[ng-error]', map: const {'ng-error':
'&onError'}) |
| 78 @NgDirective(selector: '[ng-mousemove]', map: const {'ng-mousemove': '&onMou
seMove'}) | 100 @NgDirective(selector: '[ng-focus]', map: const {'ng-focus':
'&onFocus'}) |
| 79 @NgDirective(selector: '[ng-mouseout]', map: const {'ng-mouseout': '&onMou
seOut'}) | 101 @NgDirective(selector: '[ng-fullscreenchange]', map: const {'ng-fullscreenchange
': '&onFullscreenChange'}) |
| 80 @NgDirective(selector: '[ng-mouseover]', map: const {'ng-mouseover': '&onMou
seOver'}) | 102 @NgDirective(selector: '[ng-fullscreenerror]', map: const {'ng-fullscreenerror'
: '&onFullscreenError'}) |
| 81 @NgDirective(selector: '[ng-mouseup]', map: const {'ng-mouseup': '&onMou
seUp'}) | 103 @NgDirective(selector: '[ng-input]', map: const {'ng-input':
'&onInput'}) |
| 82 @NgDirective(selector: '[ng-mousewheel]', map: const {'ng-mousewheel': '&onMou
seWheel'}) | 104 @NgDirective(selector: '[ng-invalid]', map: const {'ng-invalid':
'&onInvalid'}) |
| 83 @NgDirective(selector: '[ng-scroll]', map: const {'ng-scroll': '&onScr
oll'}) | 105 @NgDirective(selector: '[ng-keydown]', map: const {'ng-keydown':
'&onKeyDown'}) |
| 84 @NgDirective(selector: '[ng-submit]', map: const {'ng-submit': '&onSub
mit'}) | 106 @NgDirective(selector: '[ng-keypress]', map: const {'ng-keypress':
'&onKeyPress'}) |
| 85 @NgDirective(selector: '[ng-touchcancel]', map: const {'ng-touchcancel': '&onTou
chCancel'}) | 107 @NgDirective(selector: '[ng-keyup]', map: const {'ng-keyup':
'&onKeyUp'}) |
| 86 @NgDirective(selector: '[ng-touchend]', map: const {'ng-touchend': '&onTou
chEnd'}) | 108 @NgDirective(selector: '[ng-load]', map: const {'ng-load':
'&onLoad'}) |
| 87 @NgDirective(selector: '[ng-touchmove]', map: const {'ng-touchmove': '&onTou
chMove'}) | 109 @NgDirective(selector: '[ng-mousedown]', map: const {'ng-mousedown':
'&onMouseDown'}) |
| 88 @NgDirective(selector: '[ng-touchstart]', map: const {'ng-touchstart': '&onTou
chStart'}) | 110 @NgDirective(selector: '[ng-mouseenter]', map: const {'ng-mouseenter':
'&onMouseEnter'}) |
| 111 @NgDirective(selector: '[ng-mouseleave]', map: const {'ng-mouseleave':
'&onMouseLeave'}) |
| 112 @NgDirective(selector: '[ng-mousemove]', map: const {'ng-mousemove':
'&onMouseMove'}) |
| 113 @NgDirective(selector: '[ng-mouseout]', map: const {'ng-mouseout':
'&onMouseOut'}) |
| 114 @NgDirective(selector: '[ng-mouseover]', map: const {'ng-mouseover':
'&onMouseOver'}) |
| 115 @NgDirective(selector: '[ng-mouseup]', map: const {'ng-mouseup':
'&onMouseUp'}) |
| 116 @NgDirective(selector: '[ng-mousewheel]', map: const {'ng-mousewheel':
'&onMouseWheel'}) |
| 117 @NgDirective(selector: '[ng-paste]', map: const {'ng-paste':
'&onPaste'}) |
| 118 @NgDirective(selector: '[ng-reset]', map: const {'ng-reset':
'&onReset'}) |
| 119 @NgDirective(selector: '[ng-scroll]', map: const {'ng-scroll':
'&onScroll'}) |
| 120 @NgDirective(selector: '[ng-search]', map: const {'ng-search':
'&onSearch'}) |
| 121 @NgDirective(selector: '[ng-select]', map: const {'ng-select':
'&onSelect'}) |
| 122 @NgDirective(selector: '[ng-selectstart]', map: const {'ng-selectstart':
'&onSelectStart'}) |
| 123 //@NgDirective(selector: '[ng-speechchange]', map: const {'ng-speechchange':
'&onSpeechChange'}) |
| 124 @NgDirective(selector: '[ng-submit]', map: const {'ng-submit':
'&onSubmit'}) |
| 125 @NgDirective(selector: '[ng-toucheancel]', map: const {'ng-touchcancel':
'&onTouchCancel'}) |
| 126 @NgDirective(selector: '[ng-touchend]', map: const {'ng-touchend':
'&onTouchEnd'}) |
| 127 @NgDirective(selector: '[ng-touchenter]', map: const {'ng-touchenter':
'&onTouchEnter'}) |
| 128 @NgDirective(selector: '[ng-touchleave]', map: const {'ng-touchleave':
'&onTouchLeave'}) |
| 129 @NgDirective(selector: '[ng-touchmove]', map: const {'ng-touchmove':
'&onTouchMove'}) |
| 130 @NgDirective(selector: '[ng-touchstart]', map: const {'ng-touchstart':
'&onTouchStart'}) |
| 131 @NgDirective(selector: '[ng-transitionend]', map: const {'ng-transitionend':
'&onTransitionEnd'}) |
| 132 |
| 89 class NgEventDirective { | 133 class NgEventDirective { |
| 90 | 134 |
| 91 // NOTE: Do not use the element.on['some_event'].listen(...) syntax. Doing so | 135 // NOTE: Do not use the element.on['some_event'].listen(...) syntax. Doing so |
| 92 // has two downsides: | 136 // has two downsides: |
| 93 // - it loses the event typing | 137 // - it loses the event typing |
| 94 // - some DOM events may have multiple platform-dependent event names | 138 // - some DOM events may have multiple platform-dependent event names |
| 95 // under the covers. The standard Stream getters you will get the | 139 // under the covers. The standard Stream getters you will get the |
| 96 // platform specific event name automatically but you're on your own if | 140 // platform specific event name automatically but you're on your own if |
| 97 // you use the on[] syntax. This also applies to $dom_addEventListener. | 141 // you use the on[] syntax. This also applies to $dom_addEventListener. |
| 98 // Ref: http://api.dartlang.org/docs/releases/latest/dart_html/Events.html | 142 // Ref: http://api.dartlang.org/docs/releases/latest/dart_html/Events.html |
| 99 initListener(var stream, var handler) { | 143 initListener(var stream, var handler) { |
| 100 int key = stream.hashCode; | 144 int key = stream.hashCode; |
| 101 if (!listeners.containsKey(key)) { | 145 if (!listeners.containsKey(key)) { |
| 102 listeners[key] = handler; | 146 listeners[key] = handler; |
| 103 stream.listen((event) => scope.$apply(() { | 147 stream.listen((event) => scope.$apply(() { |
| 104 handler({r"$event": event}); | 148 handler({r"$event": event}); |
| 105 })); | 149 })); |
| 106 } | 150 } |
| 107 } | 151 } |
| 108 | 152 |
| 109 set onBlur(value) => initListener(element.onBlur, value); | 153 set onAbort(value) => initListener(element.onAbort, val
ue); |
| 110 set onChange(value) => initListener(element.onChange, value); | 154 set onBeforeCopy(value) => initListener(element.onBeforeCopy, val
ue); |
| 111 set onClick(value) => initListener(element.onClick, value); | 155 set onBeforeCut(value) => initListener(element.onBeforeCut, val
ue); |
| 112 set onContextMenu(value) => initListener(element.onContextMenu, value); | 156 set onBeforePaste(value) => initListener(element.onBeforePaste, val
ue); |
| 113 set onDoubleClick(value) => initListener(element.onDoubleClick, value); | 157 set onBlur(value) => initListener(element.onBlur, val
ue); |
| 114 set onDrag(value) => initListener(element.onDrag, value); | 158 set onChange(value) => initListener(element.onChange, val
ue); |
| 115 set onDragEnd(value) => initListener(element.onDragEnd, value); | 159 set onClick(value) => initListener(element.onClick, val
ue); |
| 116 set onDragEnter(value) => initListener(element.onDragEnter, value); | 160 set onContextMenu(value) => initListener(element.onContextMenu, val
ue); |
| 117 set onDragLeave(value) => initListener(element.onDragLeave, value); | 161 set onCopy(value) => initListener(element.onCopy, val
ue); |
| 118 set onDragOver(value) => initListener(element.onDragOver, value); | 162 set onCut(value) => initListener(element.onCut, val
ue); |
| 119 set onDragStart(value) => initListener(element.onDragStart, value); | 163 set onDoubleClick(value) => initListener(element.onDoubleClick, val
ue); |
| 120 set onDrop(value) => initListener(element.onDrop, value); | 164 set onDrag(value) => initListener(element.onDrag, val
ue); |
| 121 set onFocus(value) => initListener(element.onFocus, value); | 165 set onDragEnd(value) => initListener(element.onDragEnd, val
ue); |
| 122 set onKeyDown(value) => initListener(element.onKeyDown, value); | 166 set onDragEnter(value) => initListener(element.onDragEnter, val
ue); |
| 123 set onKeyPress(value) => initListener(element.onKeyPress, value); | 167 set onDragLeave(value) => initListener(element.onDragLeave, val
ue); |
| 124 set onKeyUp(value) => initListener(element.onKeyUp, value); | 168 set onDragOver(value) => initListener(element.onDragOver, val
ue); |
| 125 set onMouseDown(value) => initListener(element.onMouseDown, value); | 169 set onDragStart(value) => initListener(element.onDragStart, val
ue); |
| 126 set onMouseEnter(value) => initListener(element.onMouseEnter, value); | 170 set onDrop(value) => initListener(element.onDrop, val
ue); |
| 127 set onMouseLeave(value) => initListener(element.onMouseLeave, value); | 171 set onError(value) => initListener(element.onError, val
ue); |
| 128 set onMouseMove(value) => initListener(element.onMouseMove, value); | 172 set onFocus(value) => initListener(element.onFocus, val
ue); |
| 129 set onMouseOut(value) => initListener(element.onMouseOut, value); | 173 set onFullscreenChange(value) => initListener(element.onFullscreenChange, val
ue); |
| 130 set onMouseOver(value) => initListener(element.onMouseOver, value); | 174 set onFullscreenError(value) => initListener(element.onFullscreenError, val
ue); |
| 131 set onMouseUp(value) => initListener(element.onMouseUp, value); | 175 set onInput(value) => initListener(element.onInput, val
ue); |
| 132 set onMouseWheel(value) => initListener(element.onMouseWheel, value); | 176 set onInvalid(value) => initListener(element.onInvalid, val
ue); |
| 133 set onScroll(value) => initListener(element.onScroll, value); | 177 set onKeyDown(value) => initListener(element.onKeyDown, val
ue); |
| 134 set onSubmit(value) => initListener(element.onSubmit, value); | 178 set onKeyPress(value) => initListener(element.onKeyPress, val
ue); |
| 135 set onTouchCancel(value) => initListener(element.onTouchCancel, value); | 179 set onKeyUp(value) => initListener(element.onKeyUp, val
ue); |
| 136 set onTouchEnd(value) => initListener(element.onTouchEnd, value); | 180 set onLoad(value) => initListener(element.onLoad, val
ue); |
| 137 set onTouchMove(value) => initListener(element.onTouchMove, value); | 181 set onMouseDown(value) => initListener(element.onMouseDown, val
ue); |
| 138 set onTouchStart(value) => initListener(element.onTouchStart, value); | 182 set onMouseEnter(value) => initListener(element.onMouseEnter, val
ue); |
| 183 set onMouseLeave(value) => initListener(element.onMouseLeave, val
ue); |
| 184 set onMouseMove(value) => initListener(element.onMouseMove, val
ue); |
| 185 set onMouseOut(value) => initListener(element.onMouseOut, val
ue); |
| 186 set onMouseOver(value) => initListener(element.onMouseOver, val
ue); |
| 187 set onMouseUp(value) => initListener(element.onMouseUp, val
ue); |
| 188 set onMouseWheel(value) => initListener(element.onMouseWheel, val
ue); |
| 189 set onPaste(value) => initListener(element.onPaste, val
ue); |
| 190 set onReset(value) => initListener(element.onReset, val
ue); |
| 191 set onScroll(value) => initListener(element.onScroll, val
ue); |
| 192 set onSearch(value) => initListener(element.onSearch, val
ue); |
| 193 set onSelect(value) => initListener(element.onSelect, val
ue); |
| 194 set onSelectStart(value) => initListener(element.onSelectStart, val
ue); |
| 195 // set onSpeechChange(value) => initListener(element.onSpeechChange, v
alue); |
| 196 set onSubmit(value) => initListener(element.onSubmit, val
ue); |
| 197 set onTouchCancel(value) => initListener(element.onTouchCancel, val
ue); |
| 198 set onTouchEnd(value) => initListener(element.onTouchEnd, val
ue); |
| 199 set onTouchEnter(value) => initListener(element.onTouchEnter, val
ue); |
| 200 set onTouchLeave(value) => initListener(element.onTouchLeave, val
ue); |
| 201 set onTouchMove(value) => initListener(element.onTouchMove, val
ue); |
| 202 set onTouchStart(value) => initListener(element.onTouchStart, val
ue); |
| 203 set onTransitionEnd(value) => initListener(element.onTransitionEnd, val
ue); |
| 139 | 204 |
| 140 // Is it better to use a map of listeners or have 29 properties on this | 205 // Is it better to use a map of listeners or have 29 properties on this |
| 141 // object? One would pretty much only assign to one or two of those | 206 // object? One would pretty much only assign to one or two of those |
| 142 // properties. I'm opting for the map since it's less boilerplate code. | 207 // properties. I'm opting for the map since it's less boilerplate code. |
| 143 var listeners = {}; | 208 var listeners = {}; |
| 144 dom.Element element; | 209 dom.Element element; |
| 145 Scope scope; | 210 Scope scope; |
| 146 | 211 |
| 147 NgEventDirective(this.element, this.scope); | 212 NgEventDirective(this.element, this.scope); |
| 148 } | 213 } |
| OLD | NEW |