-
Notifications
You must be signed in to change notification settings - Fork 1
/
fx-shared-instance.html
103 lines (91 loc) · 2.97 KB
/
fx-shared-instance.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
103
<!--
Implements the monostate pattern. Allows notifying all instances of a
given instanceType (tagName by default) of some event.
Note that the default of tagName is not friendly to subclassing so you
should specify an explicit instanceType if you expect your component to
be subclassed.
Usage:
<polymer-element name="app-example" extends="fx-shared-instance">
<template>
..
</template>
<script>
Polymer({
doStuff: function() {
this.notifyInstances("updateRect", {
data: // ...
});
},
updateRect: function(data) {
// do something with the notification.
},
});
</script>
</polymer-element>
-->
<link href="../polymer/polymer.html" rel="import">
<polymer-element name="fx-shared-instance" constructor="FxSharedInstance">
<script>
"use strict";
(function() {
var instances = {};
function registerInstance(object, type) {
instances[type] = instances[type] || [];
instances[type].add(object);
}
function unregisterInstance(object, type) {
if (!instances[type])
return;
instances[type].remove(object);
}
function getInstances(type) {
return instances[type] || [];
}
function notify(type, method, data) {
var receivers = getInstances(type);
for (var i = 0; i < receivers.length; ++i)
notifyInternal(receivers[i], type, method, data);
}
// FIXME: Hack for v8 since it can't optimize functions with try/catch.
function notifyInternal(receiver, type, method, data) {
try {
if (typeof receiver[method] == "function")
receiver[method](data);
} catch (e) {
console.log("Failed notification", type, method, e);
}
}
function notifyAsync(type, method, data) {
return Promise.resolve().then(function() {
notify(type, method, data);
});
}
Polymer({
created: function() {
this.instanceType = this.tagName.toLowerCase();
},
attached: function() {
registerInstance(this, this.instanceType);
},
detached: function() {
unregisterInstance(this, this.instanceType);
},
notifyInstances: function(method, data) {
notify(this.instanceType, method, data);
},
notifyInstancesAsync: function(method, data) {
return notifyAsync(this.instanceType, method, data);
},
getInstances: function() {
return getInstances(this.instanceType);
},
});
document.addEventListener("polymer-ready", function() {
// Static API
FxSharedInstance.notify = notify;
FxSharedInstance.notifyAsync = notifyAsync;
FxSharedInstance.getInstances = getInstances;
});
})();
</script>
</polymer-element>