From 5029864c9557b2288c9ed332baa40706a0098de3 Mon Sep 17 00:00:00 2001 From: Peter Wagenet Date: Fri, 6 Jun 2025 20:06:14 -0700 Subject: [PATCH 1/5] Kill ChildViewsSupport mixin --- .../amd-compat-entrypoints/ember.debug.js | 6 ---- package.json | 1 - .../-internals/glimmer/lib/component.ts | 29 ++++++++++++--- packages/@ember/-internals/views/index.ts | 1 - .../views/lib/mixins/child_views_support.ts | 35 ------------------- 5 files changed, 25 insertions(+), 47 deletions(-) delete mode 100644 packages/@ember/-internals/views/lib/mixins/child_views_support.ts diff --git a/broccoli/amd-compat-entrypoints/ember.debug.js b/broccoli/amd-compat-entrypoints/ember.debug.js index 79a5532ccd9..8b9d3d1cfb5 100644 --- a/broccoli/amd-compat-entrypoints/ember.debug.js +++ b/broccoli/amd-compat-entrypoints/ember.debug.js @@ -113,12 +113,6 @@ d('@ember/-internals/views/lib/component_lookup', emberinternalsViewsLibComponen import * as emberinternalsViewsLibMixinsActionSupport from '@ember/-internals/views/lib/mixins/action_support'; d('@ember/-internals/views/lib/mixins/action_support', emberinternalsViewsLibMixinsActionSupport); -import * as emberinternalsViewsLibMixinsChildViewsSupport from '@ember/-internals/views/lib/mixins/child_views_support'; -d( - '@ember/-internals/views/lib/mixins/child_views_support', - emberinternalsViewsLibMixinsChildViewsSupport -); - import * as emberinternalsViewsLibMixinsClassNamesSupport from '@ember/-internals/views/lib/mixins/class_names_support'; d( '@ember/-internals/views/lib/mixins/class_names_support', diff --git a/package.json b/package.json index b0cd29f520e..8a72dab0100 100644 --- a/package.json +++ b/package.json @@ -217,7 +217,6 @@ "@ember/-internals/views/lib/compat/fallback-view-registry.js": "ember-source/@ember/-internals/views/lib/compat/fallback-view-registry.js", "@ember/-internals/views/lib/component_lookup.js": "ember-source/@ember/-internals/views/lib/component_lookup.js", "@ember/-internals/views/lib/mixins/action_support.js": "ember-source/@ember/-internals/views/lib/mixins/action_support.js", - "@ember/-internals/views/lib/mixins/child_views_support.js": "ember-source/@ember/-internals/views/lib/mixins/child_views_support.js", "@ember/-internals/views/lib/mixins/class_names_support.js": "ember-source/@ember/-internals/views/lib/mixins/class_names_support.js", "@ember/-internals/views/lib/mixins/view_state_support.js": "ember-source/@ember/-internals/views/lib/mixins/view_state_support.js", "@ember/-internals/views/lib/mixins/view_support.js": "ember-source/@ember/-internals/views/lib/mixins/view_support.js", diff --git a/packages/@ember/-internals/glimmer/lib/component.ts b/packages/@ember/-internals/glimmer/lib/component.ts index aff814ee6ce..4fa96e10f33 100644 --- a/packages/@ember/-internals/glimmer/lib/component.ts +++ b/packages/@ember/-internals/glimmer/lib/component.ts @@ -1,13 +1,15 @@ -import { get, PROPERTY_DID_CHANGE } from '@ember/-internals/metal'; +import type { View } from '@ember/-internals/glimmer/lib/renderer'; +import { get, nativeDescDecorator, PROPERTY_DID_CHANGE } from '@ember/-internals/metal'; import type { PropertyDidChange } from '@ember/-internals/metal/lib/property_events'; import { getOwner } from '@ember/-internals/owner'; import { TargetActionSupport } from '@ember/-internals/runtime'; import { ActionSupport, - ChildViewsSupport, + addChildView, ClassNamesSupport, CoreView, EventDispatcher, + getChildViews, getViewElement, ViewMixin, ViewStateSupport, @@ -775,7 +777,6 @@ declare const SIGNATURE: unique symbol; // eslint-disable-next-line @typescript-eslint/no-unused-vars interface Component extends CoreView, - ChildViewsSupport, ViewStateSupport, ClassNamesSupport, TargetActionSupport, @@ -785,7 +786,6 @@ interface Component class Component extends CoreView.extend( - ChildViewsSupport, ViewStateSupport, ClassNamesSupport, TargetActionSupport, @@ -1132,6 +1132,27 @@ class Component */ declare ariaRole?: string; + /** + Array of child views. You should never edit this array directly. + + @property childViews + @type Array + @default [] + @private + */ + // @ts-expect-error TODO: Fix these types + @nativeDescDecorator({ + configurable: false, + enumerable: false, + }) + get childViews() { + return getChildViews(this); + } + + appendChild(view: View) { + addChildView(this, view); + } + static isComponentFactory = true; static toString() { diff --git a/packages/@ember/-internals/views/index.ts b/packages/@ember/-internals/views/index.ts index b103f9f0550..3c112e64507 100644 --- a/packages/@ember/-internals/views/index.ts +++ b/packages/@ember/-internals/views/index.ts @@ -19,7 +19,6 @@ export { default as EventDispatcher } from './lib/system/event_dispatcher'; export { default as ComponentLookup } from './lib/component_lookup'; export { default as CoreView } from './lib/views/core_view'; export { default as ClassNamesSupport } from './lib/mixins/class_names_support'; -export { default as ChildViewsSupport } from './lib/mixins/child_views_support'; export { default as ViewStateSupport } from './lib/mixins/view_state_support'; export { default as ViewMixin } from './lib/mixins/view_support'; export { default as ActionSupport } from './lib/mixins/action_support'; diff --git a/packages/@ember/-internals/views/lib/mixins/child_views_support.ts b/packages/@ember/-internals/views/lib/mixins/child_views_support.ts deleted file mode 100644 index 0cde2a25738..00000000000 --- a/packages/@ember/-internals/views/lib/mixins/child_views_support.ts +++ /dev/null @@ -1,35 +0,0 @@ -/** -@module ember -*/ -import type { View } from '@ember/-internals/glimmer/lib/renderer'; -import { nativeDescDecorator } from '@ember/-internals/metal'; -import Mixin from '@ember/object/mixin'; -import { getChildViews, addChildView } from '../system/utils'; - -interface ChildViewsSupport { - readonly childViews: View[]; - appendChild(view: View): void; -} -const ChildViewsSupport = Mixin.create({ - /** - Array of child views. You should never edit this array directly. - - @property childViews - @type Array - @default [] - @private - */ - childViews: nativeDescDecorator({ - configurable: false, - enumerable: false, - get(this: View) { - return getChildViews(this); - }, - }), - - appendChild(view: View) { - addChildView(this, view); - }, -}); - -export default ChildViewsSupport; From 3a575b0f72000da59e641fa92c848b5ee9ea22de Mon Sep 17 00:00:00 2001 From: Peter Wagenet Date: Tue, 10 Jun 2025 16:45:48 -0700 Subject: [PATCH 2/5] Kill ClassNamesSupport --- .../amd-compat-entrypoints/ember.debug.js | 6 - package.json | 1 - .../-internals/glimmer/lib/component.ts | 101 +++++++++++++++- packages/@ember/-internals/views/index.ts | 1 - .../views/lib/mixins/class_names_support.ts | 108 ------------------ 5 files changed, 95 insertions(+), 122 deletions(-) delete mode 100644 packages/@ember/-internals/views/lib/mixins/class_names_support.ts diff --git a/broccoli/amd-compat-entrypoints/ember.debug.js b/broccoli/amd-compat-entrypoints/ember.debug.js index 8b9d3d1cfb5..26d78ec66f8 100644 --- a/broccoli/amd-compat-entrypoints/ember.debug.js +++ b/broccoli/amd-compat-entrypoints/ember.debug.js @@ -113,12 +113,6 @@ d('@ember/-internals/views/lib/component_lookup', emberinternalsViewsLibComponen import * as emberinternalsViewsLibMixinsActionSupport from '@ember/-internals/views/lib/mixins/action_support'; d('@ember/-internals/views/lib/mixins/action_support', emberinternalsViewsLibMixinsActionSupport); -import * as emberinternalsViewsLibMixinsClassNamesSupport from '@ember/-internals/views/lib/mixins/class_names_support'; -d( - '@ember/-internals/views/lib/mixins/class_names_support', - emberinternalsViewsLibMixinsClassNamesSupport -); - import * as emberinternalsViewsLibMixinsViewStateSupport from '@ember/-internals/views/lib/mixins/view_state_support'; d( '@ember/-internals/views/lib/mixins/view_state_support', diff --git a/package.json b/package.json index 8a72dab0100..b4885bfea40 100644 --- a/package.json +++ b/package.json @@ -217,7 +217,6 @@ "@ember/-internals/views/lib/compat/fallback-view-registry.js": "ember-source/@ember/-internals/views/lib/compat/fallback-view-registry.js", "@ember/-internals/views/lib/component_lookup.js": "ember-source/@ember/-internals/views/lib/component_lookup.js", "@ember/-internals/views/lib/mixins/action_support.js": "ember-source/@ember/-internals/views/lib/mixins/action_support.js", - "@ember/-internals/views/lib/mixins/class_names_support.js": "ember-source/@ember/-internals/views/lib/mixins/class_names_support.js", "@ember/-internals/views/lib/mixins/view_state_support.js": "ember-source/@ember/-internals/views/lib/mixins/view_state_support.js", "@ember/-internals/views/lib/mixins/view_support.js": "ember-source/@ember/-internals/views/lib/mixins/view_support.js", "@ember/-internals/views/lib/system/action_manager.js": "ember-source/@ember/-internals/views/lib/system/action_manager.js", diff --git a/packages/@ember/-internals/glimmer/lib/component.ts b/packages/@ember/-internals/glimmer/lib/component.ts index 4fa96e10f33..350b4e7fb6e 100644 --- a/packages/@ember/-internals/glimmer/lib/component.ts +++ b/packages/@ember/-internals/glimmer/lib/component.ts @@ -1,12 +1,16 @@ import type { View } from '@ember/-internals/glimmer/lib/renderer'; -import { get, nativeDescDecorator, PROPERTY_DID_CHANGE } from '@ember/-internals/metal'; +import { + descriptorForProperty, + get, + nativeDescDecorator, + PROPERTY_DID_CHANGE, +} from '@ember/-internals/metal'; import type { PropertyDidChange } from '@ember/-internals/metal/lib/property_events'; import { getOwner } from '@ember/-internals/owner'; import { TargetActionSupport } from '@ember/-internals/runtime'; import { ActionSupport, addChildView, - ClassNamesSupport, CoreView, EventDispatcher, getChildViews, @@ -34,6 +38,8 @@ import { // Keep track of which component classes have already been processed for lazy event setup. let lazyEventsProcessed = new WeakMap>(); +const EMPTY_ARRAY = Object.freeze([]); + /** @module @ember/component */ @@ -767,7 +773,6 @@ declare const SIGNATURE: unique symbol; @class Component @extends Ember.CoreView @uses Ember.TargetActionSupport - @uses Ember.ClassNamesSupport @uses Ember.ActionSupport @uses Ember.ViewMixin @uses Ember.ViewStateSupport @@ -778,7 +783,6 @@ declare const SIGNATURE: unique symbol; interface Component extends CoreView, ViewStateSupport, - ClassNamesSupport, TargetActionSupport, ActionSupport, ViewMixin, @@ -787,7 +791,6 @@ interface Component class Component extends CoreView.extend( ViewStateSupport, - ClassNamesSupport, TargetActionSupport, ActionSupport, ViewMixin, @@ -800,7 +803,12 @@ class Component didUpdateAttrs() {}, willRender() {}, willUpdate() {}, - } as ComponentMethods + } as ComponentMethods, + { + concatenatedProperties: ['classNames', 'classNameBindings'], + classNames: EMPTY_ARRAY, + classNameBindings: EMPTY_ARRAY, + } ) implements PropertyDidChange { @@ -816,6 +824,77 @@ class Component declare [IS_DISPATCHING_ATTRS]: boolean; declare [DIRTY_TAG]: DirtyableTag; + /** + Standard CSS class names to apply to the view's outer element. This + property automatically inherits any class names defined by the view's + superclasses as well. + + @property classNames + @type Array + @default ['ember-view'] + @public + */ + declare classNames: string[]; + + /** + A list of properties of the view to apply as class names. If the property + is a string value, the value of that string will be applied as a class + name. + + ```javascript + // Applies the 'high' class to the view element + import Component from '@ember/component'; + Component.extend({ + classNameBindings: ['priority'], + priority: 'high' + }); + ``` + + If the value of the property is a Boolean, the name of that property is + added as a dasherized class name. + + ```javascript + // Applies the 'is-urgent' class to the view element + import Component from '@ember/component'; + Component.extend({ + classNameBindings: ['isUrgent'], + isUrgent: true + }); + ``` + + If you would prefer to use a custom value instead of the dasherized + property name, you can pass a binding like this: + + ```javascript + // Applies the 'urgent' class to the view element + import Component from '@ember/component'; + Component.extend({ + classNameBindings: ['isUrgent:urgent'], + isUrgent: true + }); + ``` + + If you would like to specify a class that should only be added when the + property is false, you can declare a binding like this: + + ```javascript + // Applies the 'disabled' class to the view element + import Component from '@ember/component'; + Component.extend({ + classNameBindings: ['isEnabled::disabled'], + isEnabled: false + }); + ``` + + This list of properties is inherited from the component's superclasses as well. + + @property classNameBindings + @type Array + @default [] + @public + */ + declare classNameBindings: string[]; + init(properties?: object | undefined) { super.init(properties); @@ -869,6 +948,16 @@ class Component !eventNames.length ); } + + assert( + `Only arrays are allowed for 'classNameBindings'`, + descriptorForProperty(this, 'classNameBindings') === undefined && + Array.isArray(this.classNameBindings) + ); + assert( + `Only arrays of static class strings are allowed for 'classNames'. For dynamic classes, use 'classNameBindings'.`, + descriptorForProperty(this, 'classNames') === undefined && Array.isArray(this.classNames) + ); } __dispatcher?: EventDispatcher | null; diff --git a/packages/@ember/-internals/views/index.ts b/packages/@ember/-internals/views/index.ts index 3c112e64507..e4731bc9a5b 100644 --- a/packages/@ember/-internals/views/index.ts +++ b/packages/@ember/-internals/views/index.ts @@ -18,7 +18,6 @@ export { export { default as EventDispatcher } from './lib/system/event_dispatcher'; export { default as ComponentLookup } from './lib/component_lookup'; export { default as CoreView } from './lib/views/core_view'; -export { default as ClassNamesSupport } from './lib/mixins/class_names_support'; export { default as ViewStateSupport } from './lib/mixins/view_state_support'; export { default as ViewMixin } from './lib/mixins/view_support'; export { default as ActionSupport } from './lib/mixins/action_support'; diff --git a/packages/@ember/-internals/views/lib/mixins/class_names_support.ts b/packages/@ember/-internals/views/lib/mixins/class_names_support.ts deleted file mode 100644 index 87cc85e70b1..00000000000 --- a/packages/@ember/-internals/views/lib/mixins/class_names_support.ts +++ /dev/null @@ -1,108 +0,0 @@ -/** -@module ember -*/ -import { descriptorForProperty } from '@ember/-internals/metal'; -import Mixin from '@ember/object/mixin'; -import { assert } from '@ember/debug'; - -const EMPTY_ARRAY = Object.freeze([]); - -/** - @class ClassNamesSupport - @namespace Ember - @private -*/ -interface ClassNamesSupport { - classNames: string[]; - classNameBindings: string[]; -} -const ClassNamesSupport = Mixin.create({ - concatenatedProperties: ['classNames', 'classNameBindings'], - - init() { - this._super(...arguments); - - assert( - `Only arrays are allowed for 'classNameBindings'`, - descriptorForProperty(this, 'classNameBindings') === undefined && - Array.isArray(this.classNameBindings) - ); - assert( - `Only arrays of static class strings are allowed for 'classNames'. For dynamic classes, use 'classNameBindings'.`, - descriptorForProperty(this, 'classNames') === undefined && Array.isArray(this.classNames) - ); - }, - - /** - Standard CSS class names to apply to the view's outer element. This - property automatically inherits any class names defined by the view's - superclasses as well. - - @property classNames - @type Array - @default ['ember-view'] - @public - */ - classNames: EMPTY_ARRAY, - - /** - A list of properties of the view to apply as class names. If the property - is a string value, the value of that string will be applied as a class - name. - - ```javascript - // Applies the 'high' class to the view element - import Component from '@ember/component'; - Component.extend({ - classNameBindings: ['priority'], - priority: 'high' - }); - ``` - - If the value of the property is a Boolean, the name of that property is - added as a dasherized class name. - - ```javascript - // Applies the 'is-urgent' class to the view element - import Component from '@ember/component'; - Component.extend({ - classNameBindings: ['isUrgent'], - isUrgent: true - }); - ``` - - If you would prefer to use a custom value instead of the dasherized - property name, you can pass a binding like this: - - ```javascript - // Applies the 'urgent' class to the view element - import Component from '@ember/component'; - Component.extend({ - classNameBindings: ['isUrgent:urgent'], - isUrgent: true - }); - ``` - - If you would like to specify a class that should only be added when the - property is false, you can declare a binding like this: - - ```javascript - // Applies the 'disabled' class to the view element - import Component from '@ember/component'; - Component.extend({ - classNameBindings: ['isEnabled::disabled'], - isEnabled: false - }); - ``` - - This list of properties is inherited from the component's superclasses as well. - - @property classNameBindings - @type Array - @default [] - @public - */ - classNameBindings: EMPTY_ARRAY, -}); - -export default ClassNamesSupport; From 4a8a900010f05a2af2f6b48879eae6bda3e0e9ec Mon Sep 17 00:00:00 2001 From: Peter Wagenet Date: Sat, 7 Jun 2025 18:25:15 -0700 Subject: [PATCH 3/5] Kill ViewStateSupport mixin --- .../amd-compat-entrypoints/ember.debug.js | 6 ----- package.json | 1 - .../-internals/glimmer/lib/component.ts | 18 ++++++++++--- packages/@ember/-internals/views/index.ts | 2 +- .../views/lib/mixins/view_state_support.ts | 27 ------------------- 5 files changed, 15 insertions(+), 39 deletions(-) delete mode 100644 packages/@ember/-internals/views/lib/mixins/view_state_support.ts diff --git a/broccoli/amd-compat-entrypoints/ember.debug.js b/broccoli/amd-compat-entrypoints/ember.debug.js index 26d78ec66f8..0c2ac158426 100644 --- a/broccoli/amd-compat-entrypoints/ember.debug.js +++ b/broccoli/amd-compat-entrypoints/ember.debug.js @@ -113,12 +113,6 @@ d('@ember/-internals/views/lib/component_lookup', emberinternalsViewsLibComponen import * as emberinternalsViewsLibMixinsActionSupport from '@ember/-internals/views/lib/mixins/action_support'; d('@ember/-internals/views/lib/mixins/action_support', emberinternalsViewsLibMixinsActionSupport); -import * as emberinternalsViewsLibMixinsViewStateSupport from '@ember/-internals/views/lib/mixins/view_state_support'; -d( - '@ember/-internals/views/lib/mixins/view_state_support', - emberinternalsViewsLibMixinsViewStateSupport -); - import * as emberinternalsViewsLibMixinsViewSupport from '@ember/-internals/views/lib/mixins/view_support'; d('@ember/-internals/views/lib/mixins/view_support', emberinternalsViewsLibMixinsViewSupport); diff --git a/package.json b/package.json index b4885bfea40..e1abf1eb941 100644 --- a/package.json +++ b/package.json @@ -217,7 +217,6 @@ "@ember/-internals/views/lib/compat/fallback-view-registry.js": "ember-source/@ember/-internals/views/lib/compat/fallback-view-registry.js", "@ember/-internals/views/lib/component_lookup.js": "ember-source/@ember/-internals/views/lib/component_lookup.js", "@ember/-internals/views/lib/mixins/action_support.js": "ember-source/@ember/-internals/views/lib/mixins/action_support.js", - "@ember/-internals/views/lib/mixins/view_state_support.js": "ember-source/@ember/-internals/views/lib/mixins/view_state_support.js", "@ember/-internals/views/lib/mixins/view_support.js": "ember-source/@ember/-internals/views/lib/mixins/view_support.js", "@ember/-internals/views/lib/system/action_manager.js": "ember-source/@ember/-internals/views/lib/system/action_manager.js", "@ember/-internals/views/lib/system/event_dispatcher.js": "ember-source/@ember/-internals/views/lib/system/event_dispatcher.js", diff --git a/packages/@ember/-internals/glimmer/lib/component.ts b/packages/@ember/-internals/glimmer/lib/component.ts index 350b4e7fb6e..424526395cb 100644 --- a/packages/@ember/-internals/glimmer/lib/component.ts +++ b/packages/@ember/-internals/glimmer/lib/component.ts @@ -8,6 +8,7 @@ import { import type { PropertyDidChange } from '@ember/-internals/metal/lib/property_events'; import { getOwner } from '@ember/-internals/owner'; import { TargetActionSupport } from '@ember/-internals/runtime'; +import type { ViewStates } from '@ember/-internals/views'; import { ActionSupport, addChildView, @@ -16,7 +17,6 @@ import { getChildViews, getViewElement, ViewMixin, - ViewStateSupport, } from '@ember/-internals/views'; import { assert } from '@ember/debug'; import { DEBUG } from '@glimmer/env'; @@ -775,14 +775,12 @@ declare const SIGNATURE: unique symbol; @uses Ember.TargetActionSupport @uses Ember.ActionSupport @uses Ember.ViewMixin - @uses Ember.ViewStateSupport @public */ // This type param is used in the class, so must appear here. // eslint-disable-next-line @typescript-eslint/no-unused-vars interface Component extends CoreView, - ViewStateSupport, TargetActionSupport, ActionSupport, ViewMixin, @@ -790,7 +788,6 @@ interface Component class Component extends CoreView.extend( - ViewStateSupport, TargetActionSupport, ActionSupport, ViewMixin, @@ -1242,6 +1239,19 @@ class Component addChildView(this, view); } + _transitionTo(this: Component, state: keyof typeof ViewStates) { + let priorState = this._currentState; + let currentState = (this._currentState = this._states[state]); + this._state = state; + + if (priorState && priorState.exit) { + priorState.exit(this); + } + if (currentState.enter) { + currentState.enter(this); + } + } + static isComponentFactory = true; static toString() { diff --git a/packages/@ember/-internals/views/index.ts b/packages/@ember/-internals/views/index.ts index e4731bc9a5b..ac7203ccb50 100644 --- a/packages/@ember/-internals/views/index.ts +++ b/packages/@ember/-internals/views/index.ts @@ -18,8 +18,8 @@ export { export { default as EventDispatcher } from './lib/system/event_dispatcher'; export { default as ComponentLookup } from './lib/component_lookup'; export { default as CoreView } from './lib/views/core_view'; -export { default as ViewStateSupport } from './lib/mixins/view_state_support'; export { default as ViewMixin } from './lib/mixins/view_support'; export { default as ActionSupport } from './lib/mixins/action_support'; export { MUTABLE_CELL } from './lib/compat/attrs'; export { default as ActionManager } from './lib/system/action_manager'; +export { default as ViewStates } from './lib/views/states'; diff --git a/packages/@ember/-internals/views/lib/mixins/view_state_support.ts b/packages/@ember/-internals/views/lib/mixins/view_state_support.ts deleted file mode 100644 index aec7ccb5e0b..00000000000 --- a/packages/@ember/-internals/views/lib/mixins/view_state_support.ts +++ /dev/null @@ -1,27 +0,0 @@ -/** -@module ember -*/ -import Mixin from '@ember/object/mixin'; -import type Component from '@ember/component'; -import type states from '../views/states'; - -interface ViewStateSupport { - /** @internal */ - _transitionTo(state: keyof typeof states): void; -} -const ViewStateSupport = Mixin.create({ - _transitionTo(this: Component, state: keyof typeof states) { - let priorState = this._currentState; - let currentState = (this._currentState = this._states[state]); - this._state = state; - - if (priorState && priorState.exit) { - priorState.exit(this); - } - if (currentState.enter) { - currentState.enter(this); - } - }, -}); - -export default ViewStateSupport; From bab64a2cd55d948e861952ce67d9746933362b18 Mon Sep 17 00:00:00 2001 From: Peter Wagenet Date: Mon, 9 Jun 2025 07:59:59 -0700 Subject: [PATCH 4/5] Kill ViewMixin --- .../amd-compat-entrypoints/ember.debug.js | 3 - package.json | 1 - .../-internals/glimmer/lib/component.ts | 441 ++++++++++++++++- packages/@ember/-internals/views/index.ts | 1 - .../views/lib/mixins/view_support.ts | 452 ------------------ .../-internals/views/lib/system/utils.ts | 16 - packages/@ember/application/instance.ts | 5 +- type-tests/@ember/component-test/component.ts | 2 +- 8 files changed, 438 insertions(+), 483 deletions(-) delete mode 100644 packages/@ember/-internals/views/lib/mixins/view_support.ts diff --git a/broccoli/amd-compat-entrypoints/ember.debug.js b/broccoli/amd-compat-entrypoints/ember.debug.js index 0c2ac158426..c4ac39d47b3 100644 --- a/broccoli/amd-compat-entrypoints/ember.debug.js +++ b/broccoli/amd-compat-entrypoints/ember.debug.js @@ -113,9 +113,6 @@ d('@ember/-internals/views/lib/component_lookup', emberinternalsViewsLibComponen import * as emberinternalsViewsLibMixinsActionSupport from '@ember/-internals/views/lib/mixins/action_support'; d('@ember/-internals/views/lib/mixins/action_support', emberinternalsViewsLibMixinsActionSupport); -import * as emberinternalsViewsLibMixinsViewSupport from '@ember/-internals/views/lib/mixins/view_support'; -d('@ember/-internals/views/lib/mixins/view_support', emberinternalsViewsLibMixinsViewSupport); - import * as emberinternalsViewsLibSystemActionManager from '@ember/-internals/views/lib/system/action_manager'; d('@ember/-internals/views/lib/system/action_manager', emberinternalsViewsLibSystemActionManager); diff --git a/package.json b/package.json index e1abf1eb941..85399423207 100644 --- a/package.json +++ b/package.json @@ -217,7 +217,6 @@ "@ember/-internals/views/lib/compat/fallback-view-registry.js": "ember-source/@ember/-internals/views/lib/compat/fallback-view-registry.js", "@ember/-internals/views/lib/component_lookup.js": "ember-source/@ember/-internals/views/lib/component_lookup.js", "@ember/-internals/views/lib/mixins/action_support.js": "ember-source/@ember/-internals/views/lib/mixins/action_support.js", - "@ember/-internals/views/lib/mixins/view_support.js": "ember-source/@ember/-internals/views/lib/mixins/view_support.js", "@ember/-internals/views/lib/system/action_manager.js": "ember-source/@ember/-internals/views/lib/system/action_manager.js", "@ember/-internals/views/lib/system/event_dispatcher.js": "ember-source/@ember/-internals/views/lib/system/event_dispatcher.js", "@ember/-internals/views/lib/system/utils.js": "ember-source/@ember/-internals/views/lib/system/utils.js", diff --git a/packages/@ember/-internals/glimmer/lib/component.ts b/packages/@ember/-internals/glimmer/lib/component.ts index 424526395cb..44fc9695a33 100644 --- a/packages/@ember/-internals/glimmer/lib/component.ts +++ b/packages/@ember/-internals/glimmer/lib/component.ts @@ -16,8 +16,8 @@ import { EventDispatcher, getChildViews, getViewElement, - ViewMixin, } from '@ember/-internals/views'; +import { guidFor } from '@ember/-internals/utils'; import { assert } from '@ember/debug'; import { DEBUG } from '@glimmer/env'; import type { Environment, Template, TemplateFactory } from '@glimmer/interfaces'; @@ -34,12 +34,29 @@ import { DIRTY_TAG, IS_DISPATCHING_ATTRS, } from './component-managers/curly'; +import { hasDOM } from '@ember/-internals/browser-environment'; // Keep track of which component classes have already been processed for lazy event setup. let lazyEventsProcessed = new WeakMap>(); const EMPTY_ARRAY = Object.freeze([]); +/** + Determines if the element matches the specified selector. + + @private + @method matches + @param {DOMElement} el + @param {String} selector +*/ +const elMatches: typeof Element.prototype.matches | undefined = + typeof Element !== 'undefined' ? Element.prototype.matches : undefined; + +function matches(el: Element, selector: string): boolean { + assert('cannot call `matches` in fastboot mode', elMatches !== undefined); + return elMatches.call(el, selector); +} + /** @module @ember/component */ @@ -774,7 +791,6 @@ declare const SIGNATURE: unique symbol; @extends Ember.CoreView @uses Ember.TargetActionSupport @uses Ember.ActionSupport - @uses Ember.ViewMixin @public */ // This type param is used in the class, so must appear here. @@ -783,14 +799,12 @@ interface Component extends CoreView, TargetActionSupport, ActionSupport, - ViewMixin, ComponentMethods {} class Component extends CoreView.extend( TargetActionSupport, ActionSupport, - ViewMixin, { // These need to be overridable via extend/create but should still // have a default. Defining them here is the best way to achieve that. @@ -802,7 +816,7 @@ class Component willUpdate() {}, } as ComponentMethods, { - concatenatedProperties: ['classNames', 'classNameBindings'], + concatenatedProperties: ['attributeBindings', 'classNames', 'classNameBindings'], classNames: EMPTY_ARRAY, classNameBindings: EMPTY_ARRAY, } @@ -816,7 +830,7 @@ class Component declare private [SIGNATURE]: S; // SAFTEY: This is set in `init`. - declare _superRerender: ViewMixin['rerender']; + declare _superRerender: this['rerender']; declare [IS_DISPATCHING_ATTRS]: boolean; declare [DIRTY_TAG]: DirtyableTag; @@ -955,6 +969,28 @@ class Component `Only arrays of static class strings are allowed for 'classNames'. For dynamic classes, use 'classNameBindings'.`, descriptorForProperty(this, 'classNames') === undefined && Array.isArray(this.classNames) ); + + // ViewMixin + + // Setup a view, but do not finish waking it up. + + // * configure `childViews` + // * register the view with the global views hash, which is used for event + // dispatch + + assert( + `You cannot use a computed property for the component's \`elementId\` (${this}).`, + descriptorForProperty(this, 'elementId') === undefined + ); + + assert( + `You cannot use a computed property for the component's \`tagName\` (${this}).`, + descriptorForProperty(this, 'tagName') === undefined + ); + + if (!this.elementId && this.tagName !== '') { + this.elementId = guidFor(this); + } } __dispatcher?: EventDispatcher | null; @@ -1076,6 +1112,58 @@ class Component // to calling `defineProperty` in the class constructor, they would "stomp" // the properties supplied by mixins. + /** + A list of properties of the view to apply as attributes. If the property + is a string value, the value of that string will be applied as the value + for an attribute of the property's name. + + The following example creates a tag like `
`. + + ```app/components/my-component.js + import Component from '@ember/component'; + + export default Component.extend({ + attributeBindings: ['priority'], + priority: 'high' + }); + ``` + + If the value of the property is a Boolean, the attribute is treated as + an HTML Boolean attribute. It will be present if the property is `true` + and omitted if the property is `false`. + + The following example creates markup like `
`. + + ```app/components/my-component.js + import Component from '@ember/component'; + + export default Component.extend({ + attributeBindings: ['visible'], + visible: true + }); + ``` + + If you would prefer to use a custom value instead of the property name, + you can create the same markup as the last example with a binding like + this: + + ```app/components/my-component.js + import Component from '@ember/component'; + + export default Component.extend({ + attributeBindings: ['isVisible:visible'], + isVisible: true + }); + ``` + + This list of attributes is inherited from the component's superclasses, + as well. + + @property attributeBindings + @type Array + @default [] + @public + */ declare attributeBindings?: string[]; /** @@ -1252,6 +1340,347 @@ class Component } } + // Begin ViewMixin + + // .......................................................... + // TEMPLATE SUPPORT + // + + /** + Return the nearest ancestor that is an instance of the provided + class or mixin. + + @method nearestOfType + @param {Class,Mixin} klass Subclass of Ember.View (or Ember.View itself), + or an instance of Mixin. + @return Ember.View + @deprecated use `yield` and contextual components for composition instead. + @private + */ + nearestOfType(klass: any) { + let view = this.parentView; + + while (view) { + if (klass.detect(view.constructor)) { + return view; + } + view = view.parentView; + } + + return; + } + + /** + Return the nearest ancestor that has a given property. + + @method nearestWithProperty + @param {String} property A property name + @return Ember.View + @deprecated use `yield` and contextual components for composition instead. + @private + */ + nearestWithProperty(property: string) { + let view = this.parentView; + + while (view) { + if (property in view) { + return view; + } + view = view.parentView; + } + + return; + } + + /** + Renders the view again. This will work regardless of whether the + view is already in the DOM or not. If the view is in the DOM, the + rendering process will be deferred to give bindings a chance + to synchronize. + + If children were added during the rendering process using `appendChild`, + `rerender` will remove them, because they will be added again + if needed by the next `render`. + + In general, if the display of your view changes, you should modify + the DOM element directly instead of manually calling `rerender`, which can + be slow. + + @method rerender + @public + */ + rerender() { + return this._currentState.rerender(this); + } + + // .......................................................... + // ELEMENT SUPPORT + // + + /** + Returns the current DOM element for the view. + + @property element + @type DOMElement + @public + */ + // @ts-expect-error The types are not correct here + @nativeDescDecorator({ configurable: false, enumerable: false }) + get element() { + return this.renderer.getElement(this); + } + + /** + Appends the view's element to the specified parent element. + + Note that this method just schedules the view to be appended; the DOM + element will not be appended to the given element until all bindings have + finished synchronizing. + + This is not typically a function that you will need to call directly when + building your application. If you do need to use `appendTo`, be sure that + the target element you are providing is associated with an `Application` + and does not have an ancestor element that is associated with an Ember view. + + @method appendTo + @param {String|DOMElement} A selector, element, HTML string + @return {Ember.View} receiver + @private + */ + appendTo(selector: string | Element | SimpleElement) { + let target; + + if (hasDOM) { + assert( + `Expected a selector or instance of Element`, + typeof selector === 'string' || selector instanceof Element + ); + + target = typeof selector === 'string' ? document.querySelector(selector) : selector; + + assert(`You tried to append to (${selector}) but that isn't in the DOM`, target); + assert('You cannot append to an existing Ember.View.', !matches(target, '.ember-view')); + assert( + 'You cannot append to an existing Ember.View.', + (() => { + let node = target.parentNode; + while (node instanceof Element) { + if (matches(node, '.ember-view')) { + return false; + } + + node = node.parentNode; + } + + return true; + })() + ); + } else { + target = selector; + + assert( + `You tried to append to a selector string (${selector}) in an environment without a DOM`, + typeof target !== 'string' + ); + assert( + `You tried to append to a non-Element (${selector}) in an environment without a DOM`, + typeof target.appendChild === 'function' + ); + } + + // SAFETY: SimpleElement is supposed to be a subset of Element so this _should_ be safe. + // However, the types are more specific in some places which necessitates the `as`. + this.renderer.appendTo(this, target as unknown as SimpleElement); + + return this; + } + + /** + Appends the view's element to the document body. If the view does + not have an HTML representation yet + the element will be generated automatically. + + If your application uses the `rootElement` property, you must append + the view within that element. Rendering views outside of the `rootElement` + is not supported. + + Note that this method just schedules the view to be appended; the DOM + element will not be appended to the document body until all bindings have + finished synchronizing. + + @method append + @return {Ember.View} receiver + @private + */ + append() { + return this.appendTo(document.body); + } + + /** + The HTML `id` of the view's element in the DOM. You can provide this + value yourself but it must be unique (just as in HTML): + + ```handlebars + {{my-component elementId="a-really-cool-id"}} + ``` + + If not manually set a default value will be provided by the framework. + + Once rendered an element's `elementId` is considered immutable and you + should never change it. If you need to compute a dynamic value for the + `elementId`, you should do this when the component or element is being + instantiated: + + ```app/components/my-component.js + import Component from '@ember/component'; + + export default Component.extend({ + init() { + this._super(...arguments); + let index = this.get('index'); + this.set('elementId', 'component-id' + index); + } + }); + ``` + + @property elementId + @type String + @public + */ + declare elementId: string | null; + + /** + Called when a view is going to insert an element into the DOM. + + @event willInsertElement + @public + */ + willInsertElement() { + return this; + } + + /** + Called when the element of the view has been inserted into the DOM. + Override this function to do any set up that requires an element + in the document body. + + When a view has children, didInsertElement will be called on the + child view(s) first and on itself afterwards. + + @event didInsertElement + @public + */ + didInsertElement() { + return this; + } + + /** + Called when the view is about to rerender, but before anything has + been torn down. This is a good opportunity to tear down any manual + observers you have installed based on the DOM state + + @event willClearRender + @public + */ + willClearRender() { + return this; + } + + /** + You must call `destroy` on a view to destroy the view (and all of its + child views). This will remove the view from any parent node, then make + sure that the DOM element managed by the view can be released by the + memory manager. + + @method destroy + @private + */ + destroy() { + super.destroy(); + this._currentState.destroy(this); + return this; + } + + /** + Called when the element of the view is going to be destroyed. Override + this function to do any teardown that requires an element, like removing + event listeners. + + Please note: any property changes made during this event will have no + effect on object observers. + + @event willDestroyElement + @public + */ + willDestroyElement() { + return this; + } + + /** + Called after the element of the view is destroyed. + + @event willDestroyElement + @public + */ + didDestroyElement() { + return this; + } + + /** + Called when the parentView property has changed. + + @event parentViewDidChange + @private + */ + parentViewDidChange() { + return this; + } + + // .......................................................... + // STANDARD RENDER PROPERTIES + // + + /** + Tag name for the view's outer element. The tag name is only used when an + element is first created. If you change the `tagName` for an element, you + must destroy and recreate the view element. + + By default, the render buffer will use a `
` tag for views. + + If the tagName is `''`, the view will be tagless, with no outer element. + Component properties that depend on the presence of an outer element, such + as `classNameBindings` and `attributeBindings`, do not work with tagless + components. Tagless components cannot implement methods to handle events, + and their `element` property has a `null` value. + + @property tagName + @type String + @default null + @public + */ + + // We leave this null by default so we can tell the difference between + // the default case and a user-specified tag. + declare tagName: string | null; + + // ....................................................... + // EVENT HANDLING + // + + /** + Handle events from `EventDispatcher` + + @method handleEvent + @param eventName {String} + @param evt {Event} + @private + */ + handleEvent(eventName: string, evt: Event) { + return this._currentState.handleEvent(this, eventName, evt); + } + + // End ViewMixin + static isComponentFactory = true; static toString() { diff --git a/packages/@ember/-internals/views/index.ts b/packages/@ember/-internals/views/index.ts index ac7203ccb50..71a23252628 100644 --- a/packages/@ember/-internals/views/index.ts +++ b/packages/@ember/-internals/views/index.ts @@ -18,7 +18,6 @@ export { export { default as EventDispatcher } from './lib/system/event_dispatcher'; export { default as ComponentLookup } from './lib/component_lookup'; export { default as CoreView } from './lib/views/core_view'; -export { default as ViewMixin } from './lib/mixins/view_support'; export { default as ActionSupport } from './lib/mixins/action_support'; export { MUTABLE_CELL } from './lib/compat/attrs'; export { default as ActionManager } from './lib/system/action_manager'; diff --git a/packages/@ember/-internals/views/lib/mixins/view_support.ts b/packages/@ember/-internals/views/lib/mixins/view_support.ts deleted file mode 100644 index 077ee789070..00000000000 --- a/packages/@ember/-internals/views/lib/mixins/view_support.ts +++ /dev/null @@ -1,452 +0,0 @@ -import { guidFor } from '@ember/-internals/utils'; -import { descriptorForProperty, nativeDescDecorator } from '@ember/-internals/metal'; -import Mixin from '@ember/object/mixin'; -import { assert } from '@ember/debug'; -import { hasDOM } from '@ember/-internals/browser-environment'; -import { matches } from '../system/utils'; -import type { View } from '@ember/-internals/glimmer/lib/renderer'; -import type { SimpleElement } from '@simple-dom/interface'; -import type CoreView from '../views/core_view'; - -function K(this: unknown) { - return this; -} - -/** - @class ViewMixin - @namespace Ember - @private -*/ -interface ViewMixin { - rerender(): unknown; - element: Element; - appendTo(selector: string | Element | SimpleElement): this; - append(): this; - elementId: string | null; - willInsertElement(): void; - didInsertElement(): void; - willClearRender(): void; - willDestroyElement(): void; - parentViewDidChange(): void; - tagName: string | null; - handleEvent(eventName: string, evt: Event): boolean; -} -const ViewMixin = Mixin.create({ - /** - A list of properties of the view to apply as attributes. If the property - is a string value, the value of that string will be applied as the value - for an attribute of the property's name. - - The following example creates a tag like `
`. - - ```app/components/my-component.js - import Component from '@ember/component'; - - export default Component.extend({ - attributeBindings: ['priority'], - priority: 'high' - }); - ``` - - If the value of the property is a Boolean, the attribute is treated as - an HTML Boolean attribute. It will be present if the property is `true` - and omitted if the property is `false`. - - The following example creates markup like `
`. - - ```app/components/my-component.js - import Component from '@ember/component'; - - export default Component.extend({ - attributeBindings: ['visible'], - visible: true - }); - ``` - - If you would prefer to use a custom value instead of the property name, - you can create the same markup as the last example with a binding like - this: - - ```app/components/my-component.js - import Component from '@ember/component'; - - export default Component.extend({ - attributeBindings: ['isVisible:visible'], - isVisible: true - }); - ``` - - This list of attributes is inherited from the component's superclasses, - as well. - - @property attributeBindings - @type Array - @default [] - @public - */ - concatenatedProperties: ['attributeBindings'], - - // .......................................................... - // TEMPLATE SUPPORT - // - - /** - Return the nearest ancestor that is an instance of the provided - class or mixin. - - @method nearestOfType - @param {Class,Mixin} klass Subclass of Ember.View (or Ember.View itself), - or an instance of Mixin. - @return Ember.View - @deprecated use `yield` and contextual components for composition instead. - @private - */ - nearestOfType(klass: any) { - let view = this.parentView; - let isOfType = - klass instanceof Mixin - ? (view: View) => klass.detect(view) - : (view: View) => klass.detect(view.constructor); - - while (view) { - if (isOfType(view)) { - return view; - } - view = view.parentView; - } - - return; - }, - - /** - Return the nearest ancestor that has a given property. - - @method nearestWithProperty - @param {String} property A property name - @return Ember.View - @deprecated use `yield` and contextual components for composition instead. - @private - */ - nearestWithProperty(property: string) { - let view = this.parentView; - - while (view) { - if (property in view) { - return view; - } - view = view.parentView; - } - }, - - /** - Renders the view again. This will work regardless of whether the - view is already in the DOM or not. If the view is in the DOM, the - rendering process will be deferred to give bindings a chance - to synchronize. - - If children were added during the rendering process using `appendChild`, - `rerender` will remove them, because they will be added again - if needed by the next `render`. - - In general, if the display of your view changes, you should modify - the DOM element directly instead of manually calling `rerender`, which can - be slow. - - @method rerender - @public - */ - rerender() { - return this._currentState.rerender(this); - }, - - // .......................................................... - // ELEMENT SUPPORT - // - - /** - Returns the current DOM element for the view. - - @property element - @type DOMElement - @public - */ - element: nativeDescDecorator({ - configurable: false, - enumerable: false, - get(this: CoreView) { - return this.renderer.getElement(this); - }, - }), - - /** - Appends the view's element to the specified parent element. - - Note that this method just schedules the view to be appended; the DOM - element will not be appended to the given element until all bindings have - finished synchronizing. - - This is not typically a function that you will need to call directly when - building your application. If you do need to use `appendTo`, be sure that - the target element you are providing is associated with an `Application` - and does not have an ancestor element that is associated with an Ember view. - - @method appendTo - @param {String|DOMElement} A selector, element, HTML string - @return {Ember.View} receiver - @private - */ - appendTo(selector: string | Element | SimpleElement) { - let target; - - if (hasDOM) { - assert( - `Expected a selector or instance of Element`, - typeof selector === 'string' || selector instanceof Element - ); - - target = typeof selector === 'string' ? document.querySelector(selector) : selector; - - assert(`You tried to append to (${selector}) but that isn't in the DOM`, target); - assert('You cannot append to an existing Ember.View.', !matches(target, '.ember-view')); - assert( - 'You cannot append to an existing Ember.View.', - (() => { - let node = target.parentNode; - while (node instanceof Element) { - if (matches(node, '.ember-view')) { - return false; - } - - node = node.parentNode; - } - - return true; - })() - ); - } else { - target = selector; - - assert( - `You tried to append to a selector string (${selector}) in an environment without a DOM`, - typeof target !== 'string' - ); - assert( - `You tried to append to a non-Element (${selector}) in an environment without a DOM`, - typeof target.appendChild === 'function' - ); - } - - // SAFETY: SimpleElement is supposed to be a subset of Element so this _should_ be safe. - // However, the types are more specific in some places which necessitates the `as`. - this.renderer.appendTo(this, target as unknown as SimpleElement); - - return this; - }, - - /** - Appends the view's element to the document body. If the view does - not have an HTML representation yet - the element will be generated automatically. - - If your application uses the `rootElement` property, you must append - the view within that element. Rendering views outside of the `rootElement` - is not supported. - - Note that this method just schedules the view to be appended; the DOM - element will not be appended to the document body until all bindings have - finished synchronizing. - - @method append - @return {Ember.View} receiver - @private - */ - append() { - return this.appendTo(document.body); - }, - - /** - The HTML `id` of the view's element in the DOM. You can provide this - value yourself but it must be unique (just as in HTML): - - ```handlebars - {{my-component elementId="a-really-cool-id"}} - ``` - - If not manually set a default value will be provided by the framework. - - Once rendered an element's `elementId` is considered immutable and you - should never change it. If you need to compute a dynamic value for the - `elementId`, you should do this when the component or element is being - instantiated: - - ```app/components/my-component.js - import Component from '@ember/component'; - - export default Component.extend({ - init() { - this._super(...arguments); - let index = this.get('index'); - this.set('elementId', 'component-id' + index); - } - }); - ``` - - @property elementId - @type String - @public - */ - elementId: null, - - /** - Called when a view is going to insert an element into the DOM. - - @event willInsertElement - @public - */ - willInsertElement: K, - - /** - Called when the element of the view has been inserted into the DOM. - Override this function to do any set up that requires an element - in the document body. - - When a view has children, didInsertElement will be called on the - child view(s) first and on itself afterwards. - - @event didInsertElement - @public - */ - didInsertElement: K, - - /** - Called when the view is about to rerender, but before anything has - been torn down. This is a good opportunity to tear down any manual - observers you have installed based on the DOM state - - @event willClearRender - @public - */ - willClearRender: K, - - /** - You must call `destroy` on a view to destroy the view (and all of its - child views). This will remove the view from any parent node, then make - sure that the DOM element managed by the view can be released by the - memory manager. - - @method destroy - @private - */ - destroy() { - this._super(...arguments); - this._currentState.destroy(this); - }, - - /** - Called when the element of the view is going to be destroyed. Override - this function to do any teardown that requires an element, like removing - event listeners. - - Please note: any property changes made during this event will have no - effect on object observers. - - @event willDestroyElement - @public - */ - willDestroyElement: K, - - /** - Called after the element of the view is destroyed. - - @event willDestroyElement - @public - */ - didDestroyElement: K, - - /** - Called when the parentView property has changed. - - @event parentViewDidChange - @private - */ - parentViewDidChange: K, - - // .......................................................... - // STANDARD RENDER PROPERTIES - // - - /** - Tag name for the view's outer element. The tag name is only used when an - element is first created. If you change the `tagName` for an element, you - must destroy and recreate the view element. - - By default, the render buffer will use a `
` tag for views. - - If the tagName is `''`, the view will be tagless, with no outer element. - Component properties that depend on the presence of an outer element, such - as `classNameBindings` and `attributeBindings`, do not work with tagless - components. Tagless components cannot implement methods to handle events, - and their `element` property has a `null` value. - - @property tagName - @type String - @default null - @public - */ - - // We leave this null by default so we can tell the difference between - // the default case and a user-specified tag. - tagName: null, - - // ....................................................... - // CORE DISPLAY METHODS - // - - /** - Setup a view, but do not finish waking it up. - - * configure `childViews` - * register the view with the global views hash, which is used for event - dispatch - - @method init - @private - */ - init() { - this._super(...arguments); - - assert( - `You cannot use a computed property for the component's \`elementId\` (${this}).`, - descriptorForProperty(this, 'elementId') === undefined - ); - - assert( - `You cannot use a computed property for the component's \`tagName\` (${this}).`, - descriptorForProperty(this, 'tagName') === undefined - ); - - if (!this.elementId && this.tagName !== '') { - this.elementId = guidFor(this); - } - - assert('Using a custom `.render` function is no longer supported.', !this.render); - }, - - // ....................................................... - // EVENT HANDLING - // - - /** - Handle events from `EventDispatcher` - - @method handleEvent - @param eventName {String} - @param evt {Event} - @private - */ - handleEvent(eventName: string, evt: Event) { - return this._currentState.handleEvent(this, eventName, evt); - }, -}); - -export default ViewMixin; diff --git a/packages/@ember/-internals/views/lib/system/utils.ts b/packages/@ember/-internals/views/lib/system/utils.ts index d9c798ab2c4..e288df316cd 100644 --- a/packages/@ember/-internals/views/lib/system/utils.ts +++ b/packages/@ember/-internals/views/lib/system/utils.ts @@ -207,22 +207,6 @@ export function getViewBoundingClientRect(view: View): ClientRect | DOMRect { return range.getBoundingClientRect(); } -/** - Determines if the element matches the specified selector. - - @private - @method matches - @param {DOMElement} el - @param {String} selector -*/ -export const elMatches: typeof Element.prototype.matches | undefined = - typeof Element !== 'undefined' ? Element.prototype.matches : undefined; - -export function matches(el: Element, selector: string): boolean { - assert('cannot call `matches` in fastboot mode', elMatches !== undefined); - return elMatches.call(el, selector); -} - export function contains(a: Node, b: Node): boolean { if (a.contains !== undefined) { return a.contains(b); diff --git a/packages/@ember/application/instance.ts b/packages/@ember/application/instance.ts index 11af0292375..53f39d321d0 100644 --- a/packages/@ember/application/instance.ts +++ b/packages/@ember/application/instance.ts @@ -8,10 +8,9 @@ import EngineInstance from '@ember/engine/instance'; import type { BootOptions } from '@ember/engine/instance'; import type Application from '@ember/application'; import { renderSettled } from '@ember/-internals/glimmer'; -import type { BootEnvironment } from '@ember/-internals/glimmer'; +import type { BootEnvironment, Component } from '@ember/-internals/glimmer'; import { assert } from '@ember/debug'; import Router from '@ember/routing/router'; -import type { ViewMixin } from '@ember/-internals/views'; import { EventDispatcher } from '@ember/-internals/views'; import type { Registry } from '@ember/-internals/container'; import type { SimpleElement } from '@simple-dom/interface'; @@ -149,7 +148,7 @@ class ApplicationInstance extends EngineInstance { @deprecated @private */ - didCreateRootView(view: ViewMixin) { + didCreateRootView(view: Component) { view.appendTo(this.rootElement!); } diff --git a/type-tests/@ember/component-test/component.ts b/type-tests/@ember/component-test/component.ts index 06dde6a3451..e1f82b69666 100644 --- a/type-tests/@ember/component-test/component.ts +++ b/type-tests/@ember/component-test/component.ts @@ -159,6 +159,6 @@ class SigExample extends Component { // There is no type safety mapping `Element` here class ElementOnComponent extends Component<{ Element: HTMLDivElement }> { get hmm(): boolean { - return this.element.dispatchEvent(new Event('mousedown')); + return this.element?.dispatchEvent(new Event('mousedown')) ?? false; } } From 8c6f3dada2672e5934f9e876cb88ab2d1176679e Mon Sep 17 00:00:00 2001 From: Peter Wagenet Date: Tue, 10 Jun 2025 17:28:15 -0700 Subject: [PATCH 5/5] Fix TS 5.0 --- packages/@ember/-internals/glimmer/lib/component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@ember/-internals/glimmer/lib/component.ts b/packages/@ember/-internals/glimmer/lib/component.ts index 44fc9695a33..e106e05157a 100644 --- a/packages/@ember/-internals/glimmer/lib/component.ts +++ b/packages/@ember/-internals/glimmer/lib/component.ts @@ -1409,7 +1409,7 @@ class Component @method rerender @public */ - rerender() { + rerender(): void { return this._currentState.rerender(this); }