Skip to content

Commit a593675

Browse files
wagenetNullVoxPopuli
authored andcommitted
Deprecate Evented and @ember/object/events per RFC 1111
Squashed from PR #20970 by Peter Wagenet, rebased onto current main. Co-authored-by: Peter Wagenet <peter@wagenet.us> Finish RFC 1111 implementation: id/versions, deep imports, main compatibility - Register the deprecation as `deprecate-evented` (since 7.3.0, until 8.0.0), matching the current DEPRECATIONS id conventions - Use deep module imports per current main conventions - Drop the resurrected packages/ember/barrel.ts (deleted on main) - Drop the mixin-deprecation re-exports from the eager utils barrel Teach the side-effect probe that setDeprecation is metadata association setDeprecation(mixin, value) only writes onto its first argument, so when the mixin is file-local (as in @ember/object/evented) the association is unobservable unless the module's bindings are imported — same category as setClassicDecorator and friends. Restore Function-based signatures in internal event plumbing The Function -> ((...args: any[]) => void) narrowing in metal/meta only served the internal signatures and forced casts at every call site. Keep the this-aware overloads on the public deprecated surface (@ember/object/events, RouterService) and leave the internal plumbing typed as it was on main, so the diff only carries the deprecation work. Inline Evented methods on framework classes instead of applying the mixin CoreView, Route, and EmberRouter now define on/one/off/trigger/has as native class methods delegating to shared standalone implementations (metal/lib/evented-methods), the same shape RouterService already uses. The framework no longer applies the deprecated Evented mixin anywhere, which removes the machinery that existed only to silence internal applications: - utils/lib/mixin-deprecation.ts (setDeprecation/findDeprecation/ disableDeprecations) and the Mixin#reopen DEBUG hook are gone; the deprecation is communicated by the methods themselves. - CoreView's init-time trigger/has swap hack is unnecessary now that the overrides are ordinary class methods. - @ember/object/evented no longer has a top-level setDeprecation call, so the module is side-effect free again and the tree-shakability probe no longer needs to know about setDeprecation. Tests that expected the definition-time "Evented is deprecated" warning now create their objects without a wrapper; method-call deprecations are unchanged. Keep Evented.detect true for framework classes CoreView, Route, and EmberRouter no longer apply the Evented mixin, but their instances still provide its methods. Record Evented in each prototype's meta from a class static block so Mixin#detect keeps answering true for instances and subclasses, exactly as it did when the mixin was applied.
1 parent 4b92a37 commit a593675

30 files changed

Lines changed: 1080 additions & 286 deletions

‎package.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@
222222
"@ember/-internals/views/lib/mixins/action_support.js": "ember-source/@ember/-internals/views/lib/mixins/action_support.js",
223223
"@ember/-internals/views/lib/system/event_dispatcher.js": "ember-source/@ember/-internals/views/lib/system/event_dispatcher.js",
224224
"@ember/-internals/views/lib/system/utils.js": "ember-source/@ember/-internals/views/lib/system/utils.js",
225+
"@ember/-internals/views/lib/views/core-view-utils.js": "ember-source/@ember/-internals/views/lib/views/core-view-utils.js",
225226
"@ember/-internals/views/lib/views/core_view.js": "ember-source/@ember/-internals/views/lib/views/core_view.js",
226227
"@ember/-internals/views/lib/views/states.js": "ember-source/@ember/-internals/views/lib/views/states.js",
227228
"@ember/application/index.js": "ember-source/@ember/application/index.js",

‎packages/@ember/-internals/deprecations/index.ts‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,13 @@ export const DEPRECATIONS = {
126126
until: '8.0.0',
127127
url: 'https://deprecations.emberjs.com/id/deprecate-target-action-support',
128128
}),
129+
DEPRECATE_EVENTED: deprecation({
130+
id: 'deprecate-evented',
131+
for: 'ember-source',
132+
since: { available: '7.3.0' },
133+
until: '8.0.0',
134+
url: 'https://deprecations.emberjs.com/id/deprecate-evented',
135+
}),
129136
};
130137

131138
export function deprecateUntil(message: string, deprecation: DeprecationObject) {

‎packages/@ember/-internals/glimmer/lib/component-managers/curly.ts‎

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
setElementView,
1111
setViewElement,
1212
} from '@ember/-internals/views/lib/system/utils';
13+
import { sendCoreViewEvent } from '@ember/-internals/views/lib/views/core-view-utils';
1314
import type { Nullable } from '@ember/-internals/utility-types';
1415
import { assert, debugFreeze } from '@ember/debug';
1516
import { _instrumentStart } from '@ember/instrumentation';
@@ -318,20 +319,20 @@ export default class CurlyComponentManager
318319
addChildView(parentView, component);
319320
}
320321

321-
component.trigger('didReceiveAttrs');
322+
sendCoreViewEvent(component, 'didReceiveAttrs');
322323

323324
let hasWrappedElement = component.tagName !== '';
324325

325326
// We usually do this in the `didCreateElement`, but that hook doesn't fire for tagless components
326327
if (!hasWrappedElement) {
327328
if (isInteractive) {
328-
component.trigger('willRender');
329+
sendCoreViewEvent(component, 'willRender');
329330
}
330331

331332
component._transitionTo('hasElement');
332333

333334
if (isInteractive) {
334-
component.trigger('willInsertElement');
335+
sendCoreViewEvent(component, 'willInsertElement');
335336
}
336337
}
337338

@@ -355,7 +356,7 @@ export default class CurlyComponentManager
355356
}
356357

357358
if (isInteractive && hasWrappedElement) {
358-
component.trigger('willRender');
359+
sendCoreViewEvent(component, 'willRender');
359360
}
360361

361362
endUntrackFrame();
@@ -420,7 +421,7 @@ export default class CurlyComponentManager
420421

421422
if (isInteractive) {
422423
beginUntrackFrame();
423-
component.trigger('willInsertElement');
424+
sendCoreViewEvent(component, 'willInsertElement');
424425
endUntrackFrame();
425426
}
426427
}
@@ -433,8 +434,8 @@ export default class CurlyComponentManager
433434
didCreate({ component, isInteractive }: ComponentStateBucket): void {
434435
if (isInteractive) {
435436
component._transitionTo('inDOM');
436-
component.trigger('didInsertElement');
437-
component.trigger('didRender');
437+
sendCoreViewEvent(component, 'didInsertElement');
438+
sendCoreViewEvent(component, 'didRender');
438439
}
439440
}
440441

@@ -456,13 +457,13 @@ export default class CurlyComponentManager
456457
component.setProperties(props);
457458
component[IS_DISPATCHING_ATTRS] = false;
458459

459-
component.trigger('didUpdateAttrs');
460-
component.trigger('didReceiveAttrs');
460+
sendCoreViewEvent(component, 'didUpdateAttrs');
461+
sendCoreViewEvent(component, 'didReceiveAttrs');
461462
}
462463

463464
if (isInteractive) {
464-
component.trigger('willUpdate');
465-
component.trigger('willRender');
465+
sendCoreViewEvent(component, 'willUpdate');
466+
sendCoreViewEvent(component, 'willRender');
466467
}
467468

468469
endUntrackFrame();
@@ -477,8 +478,8 @@ export default class CurlyComponentManager
477478

478479
didUpdate({ component, isInteractive }: ComponentStateBucket): void {
479480
if (isInteractive) {
480-
component.trigger('didUpdate');
481-
component.trigger('didRender');
481+
sendCoreViewEvent(component, 'didUpdate');
482+
sendCoreViewEvent(component, 'didRender');
482483
}
483484
}
484485

‎packages/@ember/-internals/glimmer/lib/component-managers/root.ts‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import CurlyComponentManager, {
2121
initialRenderInstrumentDetails,
2222
processComponentInitializationAssertions,
2323
} from './curly';
24+
import { sendCoreViewEvent } from '@ember/-internals/views/lib/views/core-view-utils';
2425

2526
class RootComponentManager extends CurlyComponentManager {
2627
component: Component;
@@ -48,13 +49,13 @@ class RootComponentManager extends CurlyComponentManager {
4849
// We usually do this in the `didCreateElement`, but that hook doesn't fire for tagless components
4950
if (!hasWrappedElement) {
5051
if (isInteractive) {
51-
component.trigger('willRender');
52+
sendCoreViewEvent(component, 'willRender');
5253
}
5354

5455
component._transitionTo('hasElement');
5556

5657
if (isInteractive) {
57-
component.trigger('willInsertElement');
58+
sendCoreViewEvent(component, 'willInsertElement');
5859
}
5960
}
6061

‎packages/@ember/-internals/glimmer/lib/renderer.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { InternalOwner } from '@ember/-internals/owner';
33
import { getOwner } from '@ember/-internals/owner';
44
import { guidFor } from '@ember/-internals/utils/lib/guid';
55
import { getViewElement, getViewId } from '@ember/-internals/views/lib/system/utils';
6+
import { sendCoreViewEvent } from '@ember/-internals/views/lib/views/core-view-utils';
67
import { assert } from '@ember/debug';
78
import {
89
associateDestroyableChild,
@@ -309,7 +310,7 @@ export class Renderer extends BaseRenderer {
309310
this.cleanupRootFor(view);
310311

311312
if (this.state.isInteractive) {
312-
view.trigger('didDestroyElement');
313+
sendCoreViewEvent(view, 'didDestroyElement');
313314
}
314315
}
315316

‎packages/@ember/-internals/glimmer/lib/utils/curly-component-state-bucket.ts‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
clearViewElement,
44
getViewElement,
55
} from '@ember/-internals/views/lib/system/utils';
6+
import { sendCoreViewEvent } from '@ember/-internals/views/lib/views/core-view-utils';
67
import { registerDestructor } from '@glimmer/destroyable';
78
import type { CapturedNamedArguments } from '@glimmer/interfaces';
89
import type { Reference } from '@glimmer/reference/lib/reference';
@@ -52,8 +53,8 @@ export default class ComponentStateBucket {
5253

5354
if (isInteractive) {
5455
beginUntrackFrame();
55-
component.trigger('willDestroyElement');
56-
component.trigger('willClearRender');
56+
sendCoreViewEvent(component, 'willDestroyElement');
57+
sendCoreViewEvent(component, 'willClearRender');
5758
endUntrackFrame();
5859

5960
let element = getViewElement(component);

‎packages/@ember/-internals/glimmer/tests/integration/components/append-test.js‎

Lines changed: 62 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
import { moduleFor, RenderingTestCase, strip, runTask } from 'internal-test-helpers';
1+
import {
2+
moduleFor,
3+
RenderingTestCase,
4+
strip,
5+
runTask,
6+
expectDeprecation,
7+
} from 'internal-test-helpers';
8+
import { DEPRECATIONS } from '../../../../deprecations';
29

310
import { set } from '@ember/object';
411
import { setComponentTemplate } from '@glimmer/manager';
@@ -57,7 +64,15 @@ class AbstractAppendTest extends RenderingTestCase {
5764
}
5865
componentsByName[name] = this;
5966
pushHook('init');
60-
this.on('init', () => pushHook('on(init)'));
67+
if (!DEPRECATIONS.DEPRECATE_EVENTED.isRemoved) {
68+
expectDeprecation(
69+
() => {
70+
this.on('init', () => pushHook('on(init)'));
71+
},
72+
/Evented#on` is deprecated/,
73+
DEPRECATIONS.DEPRECATE_EVENTED.isEnabled
74+
);
75+
}
6176
}
6277

6378
didReceiveAttrs() {
@@ -145,26 +160,28 @@ class AbstractAppendTest extends RenderingTestCase {
145160
{ parentValue: 1, childValue: 1, foo: 'zomg', show: true }
146161
);
147162

148-
assert.deepEqual(
149-
hooks,
150-
[
151-
['x-parent', 'init'],
152-
['x-parent', 'on(init)'],
153-
['x-parent', 'didReceiveAttrs'],
154-
['x-parent', 'willRender'],
155-
['x-parent', 'willInsertElement'],
156-
['x-child', 'init'],
157-
['x-child', 'on(init)'],
158-
['x-child', 'didReceiveAttrs'],
159-
['x-child', 'willRender'],
160-
['x-child', 'willInsertElement'],
161-
['x-child', 'didInsertElement'],
162-
['x-child', 'didRender'],
163-
['x-parent', 'didInsertElement'],
164-
['x-parent', 'didRender'],
165-
],
166-
'creation of x-parent'
167-
);
163+
let expectedCreationHooks = [
164+
['x-parent', 'init'],
165+
['x-parent', 'on(init)'],
166+
['x-parent', 'didReceiveAttrs'],
167+
['x-parent', 'willRender'],
168+
['x-parent', 'willInsertElement'],
169+
['x-child', 'init'],
170+
['x-child', 'on(init)'],
171+
['x-child', 'didReceiveAttrs'],
172+
['x-child', 'willRender'],
173+
['x-child', 'willInsertElement'],
174+
['x-child', 'didInsertElement'],
175+
['x-child', 'didRender'],
176+
['x-parent', 'didInsertElement'],
177+
['x-parent', 'didRender'],
178+
];
179+
180+
if (DEPRECATIONS.DEPRECATE_EVENTED.isRemoved) {
181+
expectedCreationHooks = expectedCreationHooks.filter(([, hook]) => hook !== 'on(init)');
182+
}
183+
184+
assert.deepEqual(hooks, expectedCreationHooks, 'creation of x-parent');
168185

169186
hooks.length = 0;
170187
runTask(() => this.rerender());
@@ -298,7 +315,15 @@ class AbstractAppendTest extends RenderingTestCase {
298315
}
299316
componentsByName[name] = this;
300317
pushHook('init');
301-
this.on('init', () => pushHook('on(init)'));
318+
if (!DEPRECATIONS.DEPRECATE_EVENTED.isRemoved) {
319+
expectDeprecation(
320+
() => {
321+
this.on('init', () => pushHook('on(init)'));
322+
},
323+
/Evented#on` is deprecated/,
324+
DEPRECATIONS.DEPRECATE_EVENTED.isEnabled
325+
);
326+
}
302327
}
303328

304329
didReceiveAttrs() {
@@ -381,15 +406,18 @@ class AbstractAppendTest extends RenderingTestCase {
381406
XParent = this.owner.factoryFor('component:x-parent');
382407

383408
this.component = XParent.create({ foo: 'zomg' });
384-
385-
assert.deepEqual(
386-
hooks,
387-
[
388-
['x-parent', 'init'],
389-
['x-parent', 'on(init)'],
390-
],
391-
'creation of x-parent'
392-
);
409+
if (DEPRECATIONS.DEPRECATE_EVENTED.isRemoved) {
410+
assert.deepEqual(hooks, [['x-parent', 'init']], 'creation of x-parent');
411+
} else {
412+
assert.deepEqual(
413+
hooks,
414+
[
415+
['x-parent', 'init'],
416+
['x-parent', 'on(init)'],
417+
],
418+
'creation of x-parent'
419+
);
420+
}
393421

394422
hooks.length = 0;
395423

@@ -401,7 +429,7 @@ class AbstractAppendTest extends RenderingTestCase {
401429
['x-parent', 'willInsertElement'],
402430

403431
['x-child', 'init'],
404-
['x-child', 'on(init)'],
432+
!DEPRECATIONS.DEPRECATE_EVENTED.isRemoved && ['x-child', 'on(init)'],
405433
['x-child', 'didReceiveAttrs'],
406434
['x-child', 'willRender'],
407435
['x-child', 'willInsertElement'],
@@ -411,7 +439,7 @@ class AbstractAppendTest extends RenderingTestCase {
411439

412440
['x-parent', 'didInsertElement'],
413441
['x-parent', 'didRender'],
414-
],
442+
].filter(Boolean),
415443
'appending of x-parent'
416444
);
417445

0 commit comments

Comments
 (0)