/
key.js
89 lines (75 loc) · 2.49 KB
/
key.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
var canKey = require("can-key");
var canKeyUtils = require("can-key/utils");
var canReflect = require("can-reflect");
var Observation = require("can-observation");
//!steal-remove-start
if (process.env.NODE_ENV !== 'production') {
var canReflectDependencies = require("can-reflect-dependencies");
}
//!steal-remove-end
module.exports = function keyObservable(root, keyPath) {
var keyPathParts = canKeyUtils.parts(keyPath);
var lastIndex = keyPathParts.length - 1;
// Some variables used to build the dependency/mutation graph
//!steal-remove-start
if (process.env.NODE_ENV !== 'production') {
var lastKey;// This stores the last part of the keyPath, e.g. “key” in “outer.inner.key”
var lastParent;// This stores the object that the last key is on, e.g. “outer.inner” in outer: {inner: {"key": "value"}}
}
//!steal-remove-end
var observation = new Observation(function() {
var value;
// This needs to be walked every time because the objects along the key path might change
canKey.walk(root, keyPathParts, function(keyData, i) {
if (i === lastIndex) {
//!steal-remove-start
if (process.env.NODE_ENV !== 'production') {
// observation is mutating keyData.parent
if (lastParent && (keyData.key !== lastKey || keyData.parent !== lastParent)) {
canReflectDependencies.deleteMutatedBy(lastParent, lastKey, observation);
}
lastKey = keyData.key;
lastParent = keyData.parent;
canReflectDependencies.addMutatedBy(lastParent, lastKey, observation);
}
//!steal-remove-end
value = keyData.value;
}
});
return value;
});
// Function for setting the value
var valueSetter = function(newVal) {
canKey.set(root, keyPathParts, newVal);
};
// The `value` property getter & setter
Object.defineProperty(observation, "value", {
get: observation.get,
set: valueSetter
});
var symbolsToAssign = {
"can.setValue": valueSetter
};
//!steal-remove-start
if (process.env.NODE_ENV !== 'production') {
// Debug name
symbolsToAssign["can.getName"] = function getName() {
var objectName = canReflect.getName(root);
return "keyObservable<" + objectName + "." + keyPath + ">";
};
// Register what this observable changes
symbolsToAssign["can.getWhatIChange"] = function getWhatIChange() {
var m = new Map();
var s = new Set();
s.add(lastKey);
m.set(lastParent, s);
return {
mutate: {
keyDependencies: m
}
};
};
}
//!steal-remove-end
return canReflect.assignSymbols(observation, symbolsToAssign);
}