1- import preRender from './states/pre_render' ;
2- import hasElement from './states/has_element' ;
3- import inDOM from './states/in_dom' ;
4- import destroying from './states/destroying' ;
1+ import { teardownMandatorySetter } from '@ember/-internals/utils' ;
52import type Component from '@ember/component' ;
3+ import { assert } from '@ember/debug' ;
4+ import { flaggedInstrument } from '@ember/instrumentation' ;
5+ import { join } from '@ember/runloop' ;
6+ import { DEBUG } from '@glimmer/env' ;
67
78export interface ViewState {
89 enter ?( view : Component ) : void ;
@@ -13,6 +14,95 @@ export interface ViewState {
1314 destroy ( view : Component ) : void ;
1415}
1516
17+ const DEFAULT : Readonly < ViewState > = Object . freeze ( {
18+ // appendChild is only legal while rendering the buffer.
19+ appendChild ( ) {
20+ throw new Error ( "You can't use appendChild outside of the rendering process" ) ;
21+ } ,
22+
23+ // Handle events from `Ember.EventDispatcher`
24+ handleEvent ( ) {
25+ return true ; // continue event propagation
26+ } ,
27+
28+ rerender ( ) { } ,
29+
30+ destroy ( ) { } ,
31+ } ) ;
32+
33+ const PRE_RENDER : Readonly < ViewState > = Object . freeze ( { ...DEFAULT } ) ;
34+
35+ const HAS_ELEMENT : Readonly < ViewState > = Object . freeze ( {
36+ ...DEFAULT ,
37+
38+ rerender ( view : Component ) {
39+ view . renderer . rerender ( ) ;
40+ } ,
41+
42+ destroy ( view : Component ) {
43+ view . renderer . remove ( view ) ;
44+ } ,
45+
46+ // Handle events from `Ember.EventDispatcher`
47+ handleEvent ( view : Component , eventName : string , event : Event ) {
48+ if ( view . has ( eventName ) ) {
49+ // Handler should be able to re-dispatch events, so we don't
50+ // preventDefault or stopPropagation.
51+ return flaggedInstrument ( `interaction.${ eventName } ` , { event, view } , ( ) => {
52+ return join ( view , view . trigger , eventName , event ) ;
53+ } ) ;
54+ } else {
55+ return true ; // continue event propagation
56+ }
57+ } ,
58+ } ) ;
59+
60+ const IN_DOM : Readonly < ViewState > = Object . freeze ( {
61+ ...HAS_ELEMENT ,
62+
63+ enter ( view : Component ) {
64+ // Register the view for event handling. This hash is used by
65+ // Ember.EventDispatcher to dispatch incoming events.
66+ view . renderer . register ( view ) ;
67+
68+ if ( DEBUG ) {
69+ let elementId = view . elementId ;
70+
71+ assert (
72+ '[BUG] Expected teardownMandatorySetter to be set in DEBUG mode' ,
73+ teardownMandatorySetter
74+ ) ;
75+ teardownMandatorySetter ( view , 'elementId' ) ;
76+
77+ Object . defineProperty ( view , 'elementId' , {
78+ configurable : true ,
79+ enumerable : true ,
80+
81+ get ( ) {
82+ return elementId ;
83+ } ,
84+ set ( value ) {
85+ if ( value !== elementId ) {
86+ throw new Error ( "Changing a view's elementId after creation is not allowed" ) ;
87+ }
88+ } ,
89+ } ) ;
90+ }
91+ } ,
92+ } ) ;
93+
94+ const DESTROYING : Readonly < ViewState > = Object . freeze ( {
95+ ...DEFAULT ,
96+
97+ appendChild ( ) {
98+ throw new Error ( "You can't call appendChild on a view being destroyed" ) ;
99+ } ,
100+
101+ rerender ( ) {
102+ throw new Error ( "You can't call rerender on a view being destroyed" ) ;
103+ } ,
104+ } ) ;
105+
16106/*
17107 Describe how the specified actions should behave in the various
18108 states that a view can exist in. Possible states:
@@ -29,10 +119,10 @@ export interface ViewState {
29119 on a destroyed view.
30120*/
31121const states = Object . freeze ( {
32- preRender,
33- inDOM,
34- hasElement,
35- destroying,
122+ preRender : PRE_RENDER ,
123+ inDOM : IN_DOM ,
124+ hasElement : HAS_ELEMENT ,
125+ destroying : DESTROYING ,
36126} ) ;
37127
38128export default states ;
0 commit comments