@@ -3,6 +3,7 @@ import { set } from 'ember-metal/property_set';
33import { tagFor } from 'ember-metal/tags' ;
44import { didRender } from 'ember-metal/transaction' ;
55import symbol from 'ember-metal/symbol' ;
6+ import EmptyObject from 'ember-metal/empty_object' ;
67import { CONSTANT_TAG , ConstReference , DirtyableTag , UpdatableTag , combine , isConst } from 'glimmer-reference' ;
78import { ConditionalReference as GlimmerConditionalReference , NULL_REFERENCE , UNDEFINED_REFERENCE } from 'glimmer-runtime' ;
89import emberToBool from './to-bool' ;
@@ -13,8 +14,6 @@ import isEnabled from 'ember-metal/features';
1314import { isProxy } from 'ember-runtime/mixins/-proxy' ;
1415
1516export const UPDATE = symbol ( 'UPDATE' ) ;
16- export const TO_ROOT_REFERENCE = symbol ( 'TO_ROOT_REFERENCE' ) ;
17- export const REFERENCE_FOR_KEY = symbol ( 'REFERENCE_FOR_KEY' ) ;
1817
1918// @implements PathReference
2019export class PrimitiveReference extends ConstReference {
@@ -32,7 +31,7 @@ class EmberPathReference {
3231 // @abstract value()
3332
3433 get ( key ) {
35- return new PropertyReference ( this , key ) ;
34+ return PropertyReference . create ( this , key ) ;
3635 }
3736}
3837
@@ -64,10 +63,19 @@ export class CachedReference extends EmberPathReference {
6463
6564// @implements PathReference
6665export class RootReference extends ConstReference {
66+ constructor ( value ) {
67+ super ( value ) ;
68+ this . children = new EmptyObject ( ) ;
69+ }
70+
6771 get ( propertyKey ) {
68- let self = this . value ( ) ;
69- let ref = self [ REFERENCE_FOR_KEY ] && self [ REFERENCE_FOR_KEY ] ( propertyKey ) ;
70- return ref || new PropertyReference ( this , propertyKey ) ;
72+ let ref = this . children [ propertyKey ] ;
73+
74+ if ( ! ref ) {
75+ ref = this . children [ propertyKey ] = new RootPropertyReference ( this . inner , propertyKey ) ;
76+ }
77+
78+ return ref ;
7179 }
7280}
7381
@@ -106,7 +114,56 @@ if (isEnabled('ember-glimmer-detect-backtracking-rerender') ||
106114 } ;
107115}
108116
109- export class PropertyReference extends CachedReference { // jshint ignore:line
117+ export class PropertyReference extends CachedReference {
118+ static create ( parentReference , propertyKey ) {
119+ if ( isConst ( parentReference ) ) {
120+ return new RootPropertyReference ( parentReference . value ( ) , propertyKey ) ;
121+ } else {
122+ return new NestedPropertyReference ( parentReference , propertyKey ) ;
123+ }
124+ }
125+
126+ get ( key ) {
127+ return new NestedPropertyReference ( this , key ) ;
128+ }
129+ }
130+
131+ export class RootPropertyReference extends PropertyReference {
132+ constructor ( parentValue , propertyKey ) {
133+ super ( ) ;
134+
135+ this . _parentValue = parentValue ;
136+ this . _propertyKey = propertyKey ;
137+
138+ if ( isEnabled ( 'ember-glimmer-detect-backtracking-rerender' ) ||
139+ isEnabled ( 'ember-glimmer-allow-backtracking-rerender' ) ) {
140+ this . tag = new TwoWayFlushDetectionTag ( tagFor ( parentValue ) , propertyKey , this ) ;
141+ } else {
142+ this . tag = tagFor ( parentValue ) ;
143+ }
144+
145+ if ( isEnabled ( 'mandatory-setter' ) ) {
146+ watchKey ( parentValue , propertyKey , metaFor ( parentValue ) ) ;
147+ }
148+ }
149+
150+ compute ( ) {
151+ let { _parentValue, _propertyKey } = this ;
152+
153+ if ( isEnabled ( 'ember-glimmer-detect-backtracking-rerender' ) ||
154+ isEnabled ( 'ember-glimmer-allow-backtracking-rerender' ) ) {
155+ this . tag . didCompute ( _parentValue ) ;
156+ }
157+
158+ return get ( _parentValue , _propertyKey ) ;
159+ }
160+
161+ [ UPDATE ] ( value ) {
162+ set ( this . _parentValue , this . _propertyKey , value ) ;
163+ }
164+ }
165+
166+ export class NestedPropertyReference extends PropertyReference {
110167 constructor ( parentReference , propertyKey ) {
111168 super ( ) ;
112169
@@ -117,10 +174,6 @@ export class PropertyReference extends CachedReference { // jshint ignore:line
117174 this . _parentObjectTag = parentObjectTag ;
118175 this . _propertyKey = propertyKey ;
119176
120- this . _wasProxy = false ;
121- this . _proxyWrapperTag = null ;
122- this . _proxyContentTag = null ;
123-
124177 if ( isEnabled ( 'ember-glimmer-detect-backtracking-rerender' ) ||
125178 isEnabled ( 'ember-glimmer-allow-backtracking-rerender' ) ) {
126179 let tag = combine ( [ parentReferenceTag , parentObjectTag ] ) ;
@@ -131,32 +184,11 @@ export class PropertyReference extends CachedReference { // jshint ignore:line
131184 }
132185
133186 compute ( ) {
134- let { _parentReference, _parentObjectTag, _wasProxy , _propertyKey } = this ;
187+ let { _parentReference, _parentObjectTag, _propertyKey } = this ;
135188
136189 let parentValue = _parentReference . value ( ) ;
137190
138- if ( isProxy ( parentValue ) ) {
139- let proxyContent = get ( parentValue , 'content' ) ;
140-
141- if ( _wasProxy ) {
142- this . _proxyWrapperTag . update ( tagFor ( parentValue ) ) ;
143- this . _proxyContentTag . update ( tagFor ( proxyContent ) ) ;
144- } else {
145- this . _wasProxy = true ;
146- let _proxyWrapperTag = this . _proxyWrapperTag = new UpdatableTag ( tagFor ( parentValue ) ) ;
147- let _proxyContentTag = this . _proxyContentTag = new UpdatableTag ( tagFor ( proxyContent ) ) ;
148-
149- _parentObjectTag . update ( combine ( [ _proxyWrapperTag , _proxyContentTag ] ) ) ;
150- }
151- } else {
152- _parentObjectTag . update ( tagFor ( parentValue ) ) ;
153-
154- if ( _wasProxy ) {
155- this . _wasProxy = false ;
156- this . _proxyWrapperTag = null ;
157- this . _proxyContentTag = null ;
158- }
159- }
191+ _parentObjectTag . update ( tagFor ( parentValue ) ) ;
160192
161193 if ( typeof parentValue === 'object' && parentValue ) {
162194 if ( isEnabled ( 'mandatory-setter' ) ) {
@@ -179,10 +211,6 @@ export class PropertyReference extends CachedReference { // jshint ignore:line
179211 let parent = this . _parentReference . value ( ) ;
180212 set ( parent , this . _propertyKey , value ) ;
181213 }
182-
183- get ( propertyKey ) {
184- return new PropertyReference ( this , propertyKey ) ;
185- }
186214}
187215
188216export class UpdatableReference extends EmberPathReference {
@@ -218,7 +246,9 @@ export class ConditionalReference extends GlimmerConditionalReference {
218246 if ( isConst ( reference ) ) {
219247 let value = reference . value ( ) ;
220248
221- if ( ! isProxy ( value ) ) {
249+ if ( isProxy ( value ) ) {
250+ return new RootPropertyReference ( value , 'isTruthy' ) ;
251+ } else {
222252 return new PrimitiveReference ( emberToBool ( value ) ) ;
223253 }
224254 }
0 commit comments