/
-proxy.js
109 lines (92 loc) · 2.42 KB
/
-proxy.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/**
@module ember
*/
import { combine, CONSTANT_TAG, DirtyableTag, UpdatableTag } from '@glimmer/reference';
import { meta } from 'ember-meta';
import {
get,
set,
addObserver,
removeObserver,
notifyPropertyChange,
defineProperty,
Mixin,
tagFor,
computed,
} from 'ember-metal';
import { setProxy } from 'ember-utils';
import { assert } from '@ember/debug';
function contentPropertyDidChange(content, contentKey) {
let key = contentKey.slice(8); // remove "content."
if (key in this) {
return;
} // if shadowed in proxy
notifyPropertyChange(this, key);
}
export function contentFor(proxy, m) {
let content = get(proxy, 'content');
let tag = (m === undefined ? meta(proxy) : m).readableTag();
if (tag !== undefined) {
tag.inner.second.inner.update(tagFor(content));
}
return content;
}
/**
`Ember.ProxyMixin` forwards all properties not defined by the proxy itself
to a proxied `content` object. See ObjectProxy for more details.
@class ProxyMixin
@namespace Ember
@private
*/
export default Mixin.create({
/**
The object whose properties will be forwarded.
@property content
@type EmberObject
@default null
@private
*/
content: null,
init() {
this._super(...arguments);
setProxy(this);
let m = meta(this);
m.writableTag(() => combine([DirtyableTag.create(), UpdatableTag.create(CONSTANT_TAG)]));
},
willDestroy() {
this.set('content', null);
this._super(...arguments);
},
isTruthy: computed('content', function() {
return !!get(this, 'content');
}),
willWatchProperty(key) {
let contentKey = `content.${key}`;
addObserver(this, contentKey, null, contentPropertyDidChange);
},
didUnwatchProperty(key) {
let contentKey = `content.${key}`;
removeObserver(this, contentKey, null, contentPropertyDidChange);
},
unknownProperty(key) {
let content = contentFor(this);
if (content) {
return get(content, key);
}
},
setUnknownProperty(key, value) {
let m = meta(this);
if (m.proto === this) {
// if marked as prototype then just defineProperty
// rather than delegate
defineProperty(this, key, null, value);
return value;
}
let content = contentFor(this, m);
assert(
`Cannot delegate set('${key}', ${value}) to the \'content\' property of object proxy ${this}: its 'content' is undefined.`,
content
);
return set(content, key, value);
},
});