44*/
55
66import { assert } from 'ember-metal/debug' ;
7- import Stream from 'ember-metal/streams/stream' ;
7+ import BasicStream from 'ember-metal/streams/stream' ;
88import KeyStream from 'ember-metal/streams/key-stream' ;
99import { isStream } from 'ember-metal/streams/utils' ;
10- import merge from 'ember-metal/merge' ;
1110import subscribe from 'ember-htmlbars/utils/subscribe' ;
1211import { get } from 'ember-metal/property_get' ;
1312import { set } from 'ember-metal/property_set' ;
@@ -22,17 +21,90 @@ function labelFor(source, key) {
2221 return `(get ${ sourceLabel } ${ keyLabel } )` ;
2322}
2423
24+ let DynamicKeyStream = BasicStream . extend ( {
25+ init ( source , keySource ) {
26+ assert ( 'DynamicKeyStream error: source must be a stream' , isStream ( source ) ) ; // TODO: This isn't necessary.
27+
28+ // used to get the original path for debugging and legacy purposes
29+ var label = labelFor ( source , keySource ) ;
30+
31+ this . label = label ;
32+ this . path = label ;
33+ this . sourceDep = this . addMutableDependency ( source ) ;
34+ this . keyDep = this . addMutableDependency ( keySource ) ;
35+ this . observedObject = null ;
36+ this . observedKey = null ;
37+ } ,
38+
39+ key ( ) {
40+ const key = this . keyDep . getValue ( ) ;
41+ if ( typeof key === 'string' ) {
42+ assert ( 'DynamicKeyStream error: key must not have a \'.\'' , key . indexOf ( '.' ) === - 1 ) ;
43+ return key ;
44+ }
45+ } ,
46+
47+ compute ( ) {
48+ var object = this . sourceDep . getValue ( ) ;
49+ var key = this . key ( ) ;
50+ if ( object && key ) {
51+ return get ( object , key ) ;
52+ }
53+ } ,
54+
55+ setValue ( value ) {
56+ var object = this . sourceDep . getValue ( ) ;
57+ var key = this . key ( ) ;
58+ if ( object ) {
59+ set ( object , key , value ) ;
60+ }
61+ } ,
62+
63+ _super$revalidate : BasicStream . prototype . revalidate ,
64+
65+ revalidate ( value ) {
66+ this . _super$revalidate ( value ) ;
67+
68+ var object = this . sourceDep . getValue ( ) ;
69+ var key = this . key ( ) ;
70+ if ( object !== this . observedObject || key !== this . observedKey ) {
71+ this . _clearObservedObject ( ) ;
72+
73+ if ( object && typeof object === 'object' && key ) {
74+ addObserver ( object , key , this , this . notify ) ;
75+ this . observedObject = object ;
76+ this . observedKey = key ;
77+ }
78+ }
79+ } ,
80+
81+ _clearObservedObject ( ) {
82+ if ( this . observedObject ) {
83+ removeObserver ( this . observedObject , this . observedKey , this , this . notify ) ;
84+ this . observedObject = null ;
85+ this . observedKey = null ;
86+ }
87+ }
88+ } ) ;
89+
2590const buildStream = function buildStream ( params ) {
2691 const [ objRef , pathRef ] = params ;
2792
2893 assert ( 'The first argument to {{get}} must be a stream' , isStream ( objRef ) ) ;
2994 assert ( '{{get}} requires at least two arguments' , params . length > 1 ) ;
3095
31- const stream = new DynamicKeyStream ( objRef , pathRef ) ;
96+ const stream = buildDynamicKeyStream ( objRef , pathRef ) ;
3297
3398 return stream ;
3499} ;
35100
101+ function buildDynamicKeyStream ( source , keySource ) {
102+ if ( ! isStream ( keySource ) ) {
103+ return new KeyStream ( source , keySource ) ;
104+ } else {
105+ return new DynamicKeyStream ( source , keySource ) ;
106+ }
107+ }
36108
37109/**
38110 Dynamically look up a property on an object. The second argument to `{{get}}`
@@ -97,75 +169,4 @@ var getKeyword = function getKeyword(morph, env, scope, params, hash, template,
97169 return true ;
98170} ;
99171
100- var DynamicKeyStream = function DynamicKeyStream ( source , keySource ) {
101- if ( ! isStream ( keySource ) ) {
102- return new KeyStream ( source , keySource ) ;
103- }
104- assert ( 'DynamicKeyStream error: source must be a stream' , isStream ( source ) ) ; // TODO: This isn't necessary.
105-
106- // used to get the original path for debugging and legacy purposes
107- var label = labelFor ( source , keySource ) ;
108-
109- this . init ( label ) ;
110- this . path = label ;
111- this . sourceDep = this . addMutableDependency ( source ) ;
112- this . keyDep = this . addMutableDependency ( keySource ) ;
113- this . observedObject = null ;
114- this . observedKey = null ;
115- } ;
116-
117- DynamicKeyStream . prototype = Object . create ( KeyStream . prototype ) ;
118-
119- merge ( DynamicKeyStream . prototype , {
120- key ( ) {
121- const key = this . keyDep . getValue ( ) ;
122- if ( typeof key === 'string' ) {
123- assert ( 'DynamicKeyStream error: key must not have a \'.\'' , key . indexOf ( '.' ) === - 1 ) ;
124- return key ;
125- }
126- } ,
127-
128- compute ( ) {
129- var object = this . sourceDep . getValue ( ) ;
130- var key = this . key ( ) ;
131- if ( object && key ) {
132- return get ( object , key ) ;
133- }
134- } ,
135-
136- setValue ( value ) {
137- var object = this . sourceDep . getValue ( ) ;
138- var key = this . key ( ) ;
139- if ( object ) {
140- set ( object , key , value ) ;
141- }
142- } ,
143-
144- _super$revalidate : Stream . prototype . revalidate ,
145-
146- revalidate ( value ) {
147- this . _super$revalidate ( value ) ;
148-
149- var object = this . sourceDep . getValue ( ) ;
150- var key = this . key ( ) ;
151- if ( object !== this . observedObject || key !== this . observedKey ) {
152- this . _clearObservedObject ( ) ;
153-
154- if ( object && typeof object === 'object' && key ) {
155- addObserver ( object , key , this , this . notify ) ;
156- this . observedObject = object ;
157- this . observedKey = key ;
158- }
159- }
160- } ,
161-
162- _clearObservedObject ( ) {
163- if ( this . observedObject ) {
164- removeObserver ( this . observedObject , this . observedKey , this , this . notify ) ;
165- this . observedObject = null ;
166- this . observedKey = null ;
167- }
168- }
169- } ) ;
170-
171172export default getKeyword ;
0 commit comments