-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
/
Copy path-proxy.js
138 lines (116 loc) · 3.4 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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/**
@module ember
*/
import { CachedTag, DirtyableTag, UpdatableTag } from '@glimmer/reference';
import {
get,
set,
meta,
on,
addObserver,
removeObserver,
_addBeforeObserver,
_removeBeforeObserver,
propertyWillChange,
propertyDidChange,
defineProperty,
Mixin,
observer,
tagFor,
} from 'ember-metal';
import {
assert,
deprecate
} from 'ember-debug';
import { bool } from '../computed/computed_macros';
function contentPropertyWillChange(content, contentKey) {
let key = contentKey.slice(8); // remove "content."
if (key in this) { return; } // if shadowed in proxy
propertyWillChange(this, key);
}
function contentPropertyDidChange(content, contentKey) {
let key = contentKey.slice(8); // remove "content."
if (key in this) { return; } // if shadowed in proxy
propertyDidChange(this, key);
}
class ProxyTag extends CachedTag {
constructor(proxy) {
super();
let content = get(proxy, 'content');
this.proxy = proxy;
this.proxyWrapperTag = new DirtyableTag();
this.proxyContentTag = new UpdatableTag(tagFor(content));
}
compute() {
return Math.max(this.proxyWrapperTag.value(), this.proxyContentTag.value());
}
dirty() {
this.proxyWrapperTag.dirty();
}
contentDidChange() {
let content = get(this.proxy, 'content');
this.proxyContentTag.update(tagFor(content));
}
}
/**
`Ember.ProxyMixin` forwards all properties not defined by the proxy itself
to a proxied `content` object. See Ember.ObjectProxy for more details.
@class ProxyMixin
@namespace Ember
@private
*/
export default Mixin.create({
/**
The object whose properties will be forwarded.
@property content
@type Ember.Object
@default null
@private
*/
content: null,
init() {
this._super(...arguments);
let m = meta(this);
m.setProxy();
m.writableTag((source)=> new ProxyTag(source));
},
isTruthy: bool('content'),
willWatchProperty(key) {
let contentKey = `content.${key}`;
_addBeforeObserver(this, contentKey, null, contentPropertyWillChange);
addObserver(this, contentKey, null, contentPropertyDidChange);
},
didUnwatchProperty(key) {
let contentKey = `content.${key}`;
_removeBeforeObserver(this, contentKey, null, contentPropertyWillChange);
removeObserver(this, contentKey, null, contentPropertyDidChange);
},
unknownProperty(key) {
let content = get(this, 'content');
if (content) {
deprecate(
`You attempted to access \`${key}\` from \`${this}\`, but object proxying is deprecated. Please use \`model.${key}\` instead.`,
!this.isController,
{ id: 'ember-runtime.controller-proxy', until: '3.0.0' }
);
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 = get(this, 'content');
assert(`Cannot delegate set('${key}', ${value}) to the \'content\' property of object proxy ${this}: its 'content' is undefined.`, content);
deprecate(
`You attempted to set \`${key}\` from \`${this}\`, but object proxying is deprecated. Please use \`model.${key}\` instead.`,
!this.isController,
{ id: 'ember-runtime.controller-proxy', until: '3.0.0' }
);
return set(content, key, value);
}
});