From b6b82067dee73db14d0a371638a1998bceae780d Mon Sep 17 00:00:00 2001 From: simonihmig Date: Sun, 14 Jul 2019 01:40:31 +0200 Subject: [PATCH 1/3] Add deprecations for mouseEnter/Leave/Move Ember events As per RFC486 --- .../-internals/glimmer/lib/component.ts | 30 ++++- .../glimmer/lib/modifiers/action.ts | 16 ++- .../components/input-angle-test.js | 3 - .../components/input-curly-test.js | 3 - .../integration/event-dispatcher-test.js | 50 ++++++-- .../helpers/element-action-test.js | 121 ++++++++++++++++++ .../views/lib/system/event_dispatcher.js | 65 +++++----- packages/@ember/deprecated-features/index.ts | 1 + 8 files changed, 241 insertions(+), 48 deletions(-) diff --git a/packages/@ember/-internals/glimmer/lib/component.ts b/packages/@ember/-internals/glimmer/lib/component.ts index c2c3db2d38c..ca19aaa3b76 100644 --- a/packages/@ember/-internals/glimmer/lib/component.ts +++ b/packages/@ember/-internals/glimmer/lib/component.ts @@ -11,7 +11,7 @@ import { ViewMixin, ViewStateSupport, } from '@ember/-internals/views'; -import { assert } from '@ember/debug'; +import { assert, deprecate } from '@ember/debug'; import { DEBUG } from '@glimmer/env'; import { DirtyableTag } from '@glimmer/reference'; import { normalizeProperty, SVG_NAMESPACE } from '@glimmer/runtime'; @@ -749,6 +749,34 @@ const Component = CoreView.extend( !eventNames.length ); } + + deprecate( + `Using \`mouseEnter\` event handler methods in components has been deprecated.`, + this.mouseEnter === undefined, + { + id: 'ember-views.event-dispatcher.mouseenter-leave-move', + until: '4.0.0', + url: 'https://emberjs.com/deprecations/v3.x#toc_component-mouseenter-leave-move', + }, + ); + deprecate( + `Using \`mouseLeave\` event handler methods in components has been deprecated.`, + this.mouseLeave === undefined, + { + id: 'ember-views.event-dispatcher.mouseenter-leave-move', + until: '4.0.0', + url: 'https://emberjs.com/deprecations/v3.x#toc_component-mouseenter-leave-move', + }, + ); + deprecate( + `Using \`mouseMove\` event handler methods in components has been deprecated.`, + this.mouseMove === undefined, + { + id: 'ember-views.event-dispatcher.mouseenter-leave-move', + until: '4.0.0', + url: 'https://emberjs.com/deprecations/v3.x#toc_component-mouseenter-leave-move', + }, + ); }, rerender() { diff --git a/packages/@ember/-internals/glimmer/lib/modifiers/action.ts b/packages/@ember/-internals/glimmer/lib/modifiers/action.ts index 2cab05c658a..5d60e20574a 100644 --- a/packages/@ember/-internals/glimmer/lib/modifiers/action.ts +++ b/packages/@ember/-internals/glimmer/lib/modifiers/action.ts @@ -1,6 +1,6 @@ import { uuid } from '@ember/-internals/utils'; import { ActionManager, isSimpleClick } from '@ember/-internals/views'; -import { assert } from '@ember/debug'; +import { assert, deprecate } from '@ember/debug'; import { flaggedInstrument } from '@ember/instrumentation'; import { join } from '@ember/runloop'; import { Opaque, Simple } from '@glimmer/interfaces'; @@ -230,7 +230,7 @@ export default class ActionModifierManager implements ModifierManager`, }); - this.render(`{{x-foo id="outer"}}`); + expectDeprecation( + () => this.render(`{{x-foo id="outer"}}`), + /Using `mouse(Enter|Leave)` event handler methods in components has been deprecated./ + ); let parent = this.element; let outer = this.$('#outer')[0]; @@ -230,7 +233,7 @@ moduleFor( assert.strictEqual(receivedLeaveEvents[0].target, outer); } - ['@test delegated event listeners work for mouseEnter on SVG elements'](assert) { + ['@test [DEPRECATED] delegated event listeners work for mouseEnter on SVG elements'](assert) { let receivedEnterEvents = []; let receivedLeaveEvents = []; @@ -247,7 +250,10 @@ moduleFor( template: ``, }); - this.render(`{{x-foo id="outer"}}`); + expectDeprecation( + () => this.render(`{{x-foo id="outer"}}`), + /Using `mouse(Enter|Leave)` event handler methods in components has been deprecated./ + ); let parent = this.element; let outer = this.$('#outer')[0]; @@ -286,7 +292,7 @@ moduleFor( assert.strictEqual(receivedLeaveEvents[0].target, outer); } - ['@test delegated event listeners work for mouseEnter/Leave with skipped events'](assert) { + ['@test [DEPRECATED] delegated event listeners work for mouseEnter/Leave with skipped events'](assert) { let receivedEnterEvents = []; let receivedLeaveEvents = []; @@ -302,7 +308,10 @@ moduleFor( template: `
`, }); - this.render(`{{x-foo id="outer"}}`); + expectDeprecation( + () => this.render(`{{x-foo id="outer"}}`), + /Using `mouse(Enter|Leave)` event handler methods in components has been deprecated./ + ); let parent = this.element; let outer = this.$('#outer')[0]; @@ -327,7 +336,7 @@ moduleFor( assert.strictEqual(receivedLeaveEvents[0].target, inner); } - ['@test delegated event listeners work for mouseEnter/Leave with skipped events and subcomponent']( + ['@test [DEPRECATED] delegated event listeners work for mouseEnter/Leave with skipped events and subcomponent']( assert ) { let receivedEnterEvents = []; @@ -350,7 +359,10 @@ moduleFor( template: ``, }); - this.render(`{{#x-outer id="outer"}}{{x-inner id="inner"}}{{/x-outer}}`); + expectDeprecation( + () => this.render(`{{#x-outer id="outer"}}{{x-inner id="inner"}}{{/x-outer}}`), + /Using `mouse(Enter|Leave)` event handler methods in components has been deprecated./ + ); let parent = this.element; let outer = this.$('#outer')[0]; @@ -375,6 +387,28 @@ moduleFor( assert.equal(receivedLeaveEvents.length, 1, 'mouseleave event was triggered'); assert.strictEqual(receivedLeaveEvents[0].target, inner); } + + ['@test [DEPRECATED] supports mouseMove events'](assert) { + let receivedEvent; + + this.registerComponent('x-foo', { + ComponentClass: Component.extend({ + mouseMove(event) { + receivedEvent = event; + }, + }), + template: `
`, + }); + + expectDeprecation( + 'Using `mouseMove` event handler methods in components has been deprecated.' + ); + + this.render(`{{x-foo}}`); + + runTask(() => this.$('#inner').trigger('mousemove')); + assert.ok(receivedEvent, 'mousemove event was triggered'); + } } ); diff --git a/packages/@ember/-internals/glimmer/tests/integration/helpers/element-action-test.js b/packages/@ember/-internals/glimmer/tests/integration/helpers/element-action-test.js index 50bad97f7da..80e56fe2188 100644 --- a/packages/@ember/-internals/glimmer/tests/integration/helpers/element-action-test.js +++ b/packages/@ember/-internals/glimmer/tests/integration/helpers/element-action-test.js @@ -1663,5 +1663,126 @@ moduleFor( "Element with action handler has properly updated it's conditional class" ); } + + ['@test [DEPRECATED] it should support mouseEnter events']() { + let showCalled = false; + + let ExampleComponent = Component.extend({ + actions: { + show() { + showCalled = true; + }, + }, + }); + + this.registerComponent('example-component', { + ComponentClass: ExampleComponent, + template: '
', + }); + + expectDeprecation(() => this.render('{{example-component id="outer"}}'), + 'Using the `{{action}}` modifier with `mouseEnter` events has been deprecated.' + ); + + let parent = this.element; + let outer = this.$('#outer')[0]; + let inner = this.$('#inner')[0]; + + runTask(() => { + this.$(outer).trigger('mouseenter', { canBubble: false, relatedTarget: parent }); + this.$(inner).trigger('mouseover', { relatedTarget: parent }); + this.$(parent).trigger('mouseout', { relatedTarget: inner }); + }); + + this.assert.ok(showCalled, 'show action was called on mouseEnter'); + } + + ['@test [DEPRECATED] it should support mouseLeave events']() { + let showCalled = false; + + let ExampleComponent = Component.extend({ + actions: { + show() { + showCalled = true; + }, + }, + }); + + this.registerComponent('example-component', { + ComponentClass: ExampleComponent, + template: '
', + }); + + expectDeprecation(() => this.render('{{example-component id="outer"}}'), + 'Using the `{{action}}` modifier with `mouseLeave` events has been deprecated.' + ); + + let parent = this.element; + let outer = this.$('#outer')[0]; + let inner = this.$('#inner')[0]; + + runTask(() => { + this.$(outer).trigger('mouseleave', { canBubble: false, relatedTarget: parent }); + this.$(inner).trigger('mouseout', { relatedTarget: parent }); + this.$(parent).trigger('mouseover', { relatedTarget: inner }); + }); + + this.assert.ok(showCalled, 'show action was called on mouseLeave'); + } + + ['@test [DEPRECATED] it should support mouseMove events']() { + let showCalled = false; + + let ExampleComponent = Component.extend({ + actions: { + show() { + showCalled = true; + }, + }, + }); + + this.registerComponent('example-component', { + ComponentClass: ExampleComponent, + template: '
', + }); + + expectDeprecation(() => this.render('{{example-component id="outer"}}'), + 'Using the `{{action}}` modifier with `mouseMove` events has been deprecated.' + ); + + runTask(() => { + this.$('#inner').trigger('mousemove'); + }); + + this.assert.ok(showCalled, 'show action was called on mouseMove'); + } + + ['@test [DEPRECATED] it should support bound mouseMove events']() { + let showCalled = false; + + let ExampleComponent = Component.extend({ + eventType: 'mouseMove', + actions: { + show() { + showCalled = true; + }, + }, + }); + + this.registerComponent('example-component', { + ComponentClass: ExampleComponent, + template: '
', + }); + + expectDeprecation(() => this.render('{{example-component id="outer"}}'), + 'Using the `{{action}}` modifier with `mouseMove` events has been deprecated.' + ); + + runTask(() => { + this.$('#inner').trigger('mousemove'); + }); + + this.assert.ok(showCalled, 'show action was called on mouseMove'); + } } ); diff --git a/packages/@ember/-internals/views/lib/system/event_dispatcher.js b/packages/@ember/-internals/views/lib/system/event_dispatcher.js index f000a24c162..f6026eccb0f 100644 --- a/packages/@ember/-internals/views/lib/system/event_dispatcher.js +++ b/packages/@ember/-internals/views/lib/system/event_dispatcher.js @@ -8,7 +8,7 @@ import jQuery, { jQueryDisabled } from './jquery'; import ActionManager from './action_manager'; import addJQueryEventDeprecation from './jquery_event_deprecation'; import { contains } from './utils'; -import { JQUERY_INTEGRATION } from '@ember/deprecated-features'; +import { JQUERY_INTEGRATION, MOUSE_ENTER_LEAVE_MOVE_EVENTS } from '@ember/deprecated-features'; /** @module ember @@ -67,35 +67,38 @@ export default EmberObject.extend({ @type Object @private */ - events: { - touchstart: 'touchStart', - touchmove: 'touchMove', - touchend: 'touchEnd', - touchcancel: 'touchCancel', - keydown: 'keyDown', - keyup: 'keyUp', - keypress: 'keyPress', - mousedown: 'mouseDown', - mouseup: 'mouseUp', - contextmenu: 'contextMenu', - click: 'click', - dblclick: 'doubleClick', - mousemove: 'mouseMove', - focusin: 'focusIn', - focusout: 'focusOut', - mouseenter: 'mouseEnter', - mouseleave: 'mouseLeave', - submit: 'submit', - input: 'input', - change: 'change', - dragstart: 'dragStart', - drag: 'drag', - dragenter: 'dragEnter', - dragleave: 'dragLeave', - dragover: 'dragOver', - drop: 'drop', - dragend: 'dragEnd', - }, + events: assign( + { + touchstart: 'touchStart', + touchmove: 'touchMove', + touchend: 'touchEnd', + touchcancel: 'touchCancel', + keydown: 'keyDown', + keyup: 'keyUp', + keypress: 'keyPress', + mousedown: 'mouseDown', + mouseup: 'mouseUp', + contextmenu: 'contextMenu', + click: 'click', + dblclick: 'doubleClick', + focusin: 'focusIn', + focusout: 'focusOut', + submit: 'submit', + input: 'input', + change: 'change', + dragstart: 'dragStart', + drag: 'drag', + dragenter: 'dragEnter', + dragleave: 'dragLeave', + dragover: 'dragOver', + drop: 'drop', + dragend: 'dragEnd', + }, + MOUSE_ENTER_LEAVE_MOVE_EVENTS ? { + mouseenter: 'mouseEnter', + mouseleave: 'mouseLeave', + mousemove: 'mouseMove', + } : {}), /** The root DOM element to which event listeners should be attached. Event @@ -300,7 +303,7 @@ export default EmberObject.extend({ // Special handling of events that don't bubble (event delegation does not work). // Mimics the way this is handled in jQuery, // see https://github.com/jquery/jquery/blob/899c56f6ada26821e8af12d9f35fa039100e838e/src/event.js#L666-L700 - if (EVENT_MAP[event] !== undefined) { + if (MOUSE_ENTER_LEAVE_MOVE_EVENTS && EVENT_MAP[event] !== undefined) { let mappedEventType = EVENT_MAP[event]; let origEventType = event; diff --git a/packages/@ember/deprecated-features/index.ts b/packages/@ember/deprecated-features/index.ts index bf488ee0bf2..724ffb311f3 100644 --- a/packages/@ember/deprecated-features/index.ts +++ b/packages/@ember/deprecated-features/index.ts @@ -13,3 +13,4 @@ export const JQUERY_INTEGRATION = !!'3.9.0'; export const ALIAS_METHOD = !!'3.9.0'; export const APP_CTRL_ROUTER_PROPS = !!'3.10.0-beta.1'; export const FUNCTION_PROTOTYPE_EXTENSIONS = !!'3.11.0-beta.1'; +export const MOUSE_ENTER_LEAVE_MOVE_EVENTS = !!'3.13.0-beta.1'; From 50fb52c6e44668c244473e4b8f977cd0b0573ecc Mon Sep 17 00:00:00 2001 From: simonihmig Date: Sat, 20 Jul 2019 00:42:09 +0200 Subject: [PATCH 2/3] Remove deprecated events from docs --- packages/@ember/-internals/glimmer/lib/component.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/@ember/-internals/glimmer/lib/component.ts b/packages/@ember/-internals/glimmer/lib/component.ts index ca19aaa3b76..325632baf88 100644 --- a/packages/@ember/-internals/glimmer/lib/component.ts +++ b/packages/@ember/-internals/glimmer/lib/component.ts @@ -642,11 +642,8 @@ export const BOUNDS = symbol('BOUNDS'); * `contextMenu` * `click` * `doubleClick` - * `mouseMove` * `focusIn` * `focusOut` - * `mouseEnter` - * `mouseLeave` Form events: From d922666b2d0383e59cdbdaa5af9bb836dbc2390b Mon Sep 17 00:00:00 2001 From: simonihmig Date: Sat, 20 Jul 2019 00:59:21 +0200 Subject: [PATCH 3/3] Fix linting errors --- packages/@ember/-internals/glimmer/lib/component.ts | 6 +++--- .../-internals/glimmer/lib/modifiers/action.ts | 6 ++++-- .../tests/integration/event-dispatcher-test.js | 4 +++- .../integration/helpers/element-action-test.js | 12 ++++++++---- .../-internals/views/lib/system/event_dispatcher.js | 13 ++++++++----- 5 files changed, 26 insertions(+), 15 deletions(-) diff --git a/packages/@ember/-internals/glimmer/lib/component.ts b/packages/@ember/-internals/glimmer/lib/component.ts index 325632baf88..035e2162486 100644 --- a/packages/@ember/-internals/glimmer/lib/component.ts +++ b/packages/@ember/-internals/glimmer/lib/component.ts @@ -754,7 +754,7 @@ const Component = CoreView.extend( id: 'ember-views.event-dispatcher.mouseenter-leave-move', until: '4.0.0', url: 'https://emberjs.com/deprecations/v3.x#toc_component-mouseenter-leave-move', - }, + } ); deprecate( `Using \`mouseLeave\` event handler methods in components has been deprecated.`, @@ -763,7 +763,7 @@ const Component = CoreView.extend( id: 'ember-views.event-dispatcher.mouseenter-leave-move', until: '4.0.0', url: 'https://emberjs.com/deprecations/v3.x#toc_component-mouseenter-leave-move', - }, + } ); deprecate( `Using \`mouseMove\` event handler methods in components has been deprecated.`, @@ -772,7 +772,7 @@ const Component = CoreView.extend( id: 'ember-views.event-dispatcher.mouseenter-leave-move', until: '4.0.0', url: 'https://emberjs.com/deprecations/v3.x#toc_component-mouseenter-leave-move', - }, + } ); }, diff --git a/packages/@ember/-internals/glimmer/lib/modifiers/action.ts b/packages/@ember/-internals/glimmer/lib/modifiers/action.ts index 5d60e20574a..ef956ee4800 100644 --- a/packages/@ember/-internals/glimmer/lib/modifiers/action.ts +++ b/packages/@ember/-internals/glimmer/lib/modifiers/action.ts @@ -244,12 +244,14 @@ export default class ActionModifierManager implements ModifierManager', }); - expectDeprecation(() => this.render('{{example-component id="outer"}}'), + expectDeprecation( + () => this.render('{{example-component id="outer"}}'), 'Using the `{{action}}` modifier with `mouseEnter` events has been deprecated.' ); @@ -1713,7 +1714,8 @@ moduleFor( template: '
', }); - expectDeprecation(() => this.render('{{example-component id="outer"}}'), + expectDeprecation( + () => this.render('{{example-component id="outer"}}'), 'Using the `{{action}}` modifier with `mouseLeave` events has been deprecated.' ); @@ -1746,7 +1748,8 @@ moduleFor( template: '
', }); - expectDeprecation(() => this.render('{{example-component id="outer"}}'), + expectDeprecation( + () => this.render('{{example-component id="outer"}}'), 'Using the `{{action}}` modifier with `mouseMove` events has been deprecated.' ); @@ -1774,7 +1777,8 @@ moduleFor( template: '
', }); - expectDeprecation(() => this.render('{{example-component id="outer"}}'), + expectDeprecation( + () => this.render('{{example-component id="outer"}}'), 'Using the `{{action}}` modifier with `mouseMove` events has been deprecated.' ); diff --git a/packages/@ember/-internals/views/lib/system/event_dispatcher.js b/packages/@ember/-internals/views/lib/system/event_dispatcher.js index f6026eccb0f..23418e6bd59 100644 --- a/packages/@ember/-internals/views/lib/system/event_dispatcher.js +++ b/packages/@ember/-internals/views/lib/system/event_dispatcher.js @@ -94,11 +94,14 @@ export default EmberObject.extend({ drop: 'drop', dragend: 'dragEnd', }, - MOUSE_ENTER_LEAVE_MOVE_EVENTS ? { - mouseenter: 'mouseEnter', - mouseleave: 'mouseLeave', - mousemove: 'mouseMove', - } : {}), + MOUSE_ENTER_LEAVE_MOVE_EVENTS + ? { + mouseenter: 'mouseEnter', + mouseleave: 'mouseLeave', + mousemove: 'mouseMove', + } + : {} + ), /** The root DOM element to which event listeners should be attached. Event