-
Notifications
You must be signed in to change notification settings - Fork 1
/
fx-observer.html
95 lines (82 loc) · 2.54 KB
/
fx-observer.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
<!--
Copyright 2014 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<!--
Sends and observes notifications by broadcasting notify events.
Changing the `for` attribute dynamically is not supported and will cause
leaks.
Usage:
<fx-observer for="example" on-notify="{{ handleHashChange }}"></fx-observer>
FxObserver.notify("example", relatedData);
FxObserver.notifyAsync("example", relatedData).then(function() {
// ...
});
-->
<link href="../polymer/polymer.html" rel="import">
<polymer-element name="fx-observer" constructor="FxObserver" attributes="for">
<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 notify(type, data) {
var receivers = instances[type] || [];
for (var i = 0; i < receivers.length; ++i)
notifyInternal(receivers[i], type, data);
}
// FIXME: Hack for v8 since it can't optimize functions with try/catch.
function notifyInternal(receiver, type, data) {
try {
receiver.fire("notify", data);
} catch (e) {
console.log("Failed notification", type, e);
}
}
function notifyAsync(type, data) {
return Promise.resolve().then(function() {
notify(type, data);
});
}
Polymer({
for: "",
active: false,
created: function() {
this.style.display = "none";
},
attached: function() {
registerInstance(this, this.for);
this.active = true;
},
detached: function() {
unregisterInstance(this, this.for);
this.active = false;
},
notify: function(data) {
if (!this.active)
return;
notify(this.for, data);
},
notifyAsync: function(data) {
if (!this.active)
return Promise.reject(new Error("Observer is detached"));
return notifyAsync(this.for, data);
},
});
document.addEventListener("polymer-ready", function() {
// Static API
FxObserver.notify = notify;
FxObserver.notifyAsync = notifyAsync;
});
})();
</script>
</polymer-element>