-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathyarn-state-behavior.html
102 lines (72 loc) · 2.3 KB
/
yarn-state-behavior.html
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
<link rel="import" href="../polymer/polymer.html">
<script>
var YarnBehaviors = YarnBehaviors || {};
(function() {
var internals = {
instances: [],
state: {}
};
/**
This behavior should be used to share app state across elements via the `state` property. The behavior ensures that path-notifying calls (e.g. `set()`, `splice()`, etc.) involving the `state` object or its children are delegated to all elements with this behavior, so observers should work as expected.
@polymerBehavior YarnBehaviors.StateBehavior
*/
YarnBehaviors.StateBehavior = {
properties: {
/**
* An object shared among all elements with this behavior.
*/
state: {
type: Object,
notify: true,
readOnly: true,
value: internals.state
}
},
ready: function() {
// Protect from state behavior being mixed-in with itself
// see Polymer/polymer#1894
if (this._usingStateBehavior) {
return;
}
this._usingStateBehavior = true;
// Patch _notifyPath to delegate to all instances.
// This is slightly dirty, but by far most efficient
// code-wise and perf-wise.
if (typeof this._notifyPath !== 'function') {
throw new Error('Polymer version appears to be incompatible with StateBehavior.');
}
var origNotifyPath = this._notifyPath;
this._notifyPath = function() {
// Call on self
origNotifyPath.apply(this, arguments);
// Call on all other instances if necessary
if (arguments[0].split('.')[0] === 'state') {
this._invokeInstances(origNotifyPath, arguments);
}
};
},
attached: function() {
// Protect from state behavior being mixed-in with itself
if (!~internals.instances.indexOf(this)) {
internals.instances.push(this);
}
},
detached: function() {
var i = internals.instances.indexOf(this);
if (i >= 0) {
internals.instances.splice(i, 1);
}
},
_invokeInstances: function(fn, args) {
var instances = internals.instances;
var instance;
for (var i = 0; i < instances.length; i++) {
instance = instances[i];
if (instance !== this) {
fn.apply(instance, args);
}
}
}
};
})();
</script>