@@ -24,6 +24,7 @@ var Events = {
24
24
if ( plotObj . _ev instanceof EventEmitter ) return plotObj ;
25
25
26
26
var ev = new EventEmitter ( ) ;
27
+ var internalEv = new EventEmitter ( ) ;
27
28
28
29
/*
29
30
* Assign to plot._ev while we still live in a land
@@ -32,6 +33,16 @@ var Events = {
32
33
*/
33
34
plotObj . _ev = ev ;
34
35
36
+ /*
37
+ * Create a second event handler that will manage events *internally*.
38
+ * This allows parts of plotly to respond to thing like relayout without
39
+ * having to use the user-facing event handler. They cannot peacefully
40
+ * coexist on the same handler because a user invoking
41
+ * plotObj.removeAllListeners() would detach internal events, breaking
42
+ * plotly.
43
+ */
44
+ plotObj . _internalEv = internalEv ;
45
+
35
46
/*
36
47
* Assign bound methods from the ev to the plot object. These methods
37
48
* will reference the 'this' of plot._ev even though they are methods
@@ -46,6 +57,15 @@ var Events = {
46
57
plotObj . removeListener = ev . removeListener . bind ( ev ) ;
47
58
plotObj . removeAllListeners = ev . removeAllListeners . bind ( ev ) ;
48
59
60
+ /*
61
+ * Create funtions for managing internal events. These are *only* triggered
62
+ * by the mirroring of external events via the emit function.
63
+ */
64
+ plotObj . _internalOn = internalEv . on . bind ( internalEv ) ;
65
+ plotObj . _internalOnce = internalEv . once . bind ( internalEv ) ;
66
+ plotObj . _removeInternalListener = internalEv . removeListener . bind ( internalEv ) ;
67
+ plotObj . _removeAllInternalListeners = internalEv . removeAllListeners . bind ( internalEv ) ;
68
+
49
69
/*
50
70
* We must wrap emit to continue to support JQuery events. The idea
51
71
* is to check to see if the user is using JQuery events, if they are
@@ -58,6 +78,7 @@ var Events = {
58
78
}
59
79
60
80
ev . emit ( event , data ) ;
81
+ internalEv . emit ( event , data ) ;
61
82
} ;
62
83
63
84
return plotObj ;
@@ -70,6 +91,7 @@ var Events = {
70
91
* triggerHandler for backwards compatibility.
71
92
*/
72
93
triggerHandler : function ( plotObj , event , data ) {
94
+ var i ;
73
95
var jQueryHandlerValue ;
74
96
var nodeEventHandlerValue ;
75
97
/*
@@ -98,10 +120,24 @@ var Events = {
98
120
/*
99
121
* Call all the handlers except the last one.
100
122
*/
101
- for ( var i = 0 ; i < handlers . length ; i ++ ) {
123
+ for ( i = 0 ; i < handlers . length ; i ++ ) {
102
124
handlers [ i ] ( data ) ;
103
125
}
104
126
127
+ /* Do the same as for external-facing events, except trigger the same
128
+ * events on the internal handlers. This does *not* affect the return
129
+ * value. It simply mirrors triggers internally so that there's no
130
+ * conflict with external user-defined events when plotly manages
131
+ * events internally.
132
+ */
133
+ var internalHandlers = plotObj . _internalEv . _events [ event ] ;
134
+ if ( internalHandlers ) {
135
+ if ( typeof internalHandlers === 'function' ) internalHandlers = [ internalHandlers ] ;
136
+ for ( i = 0 ; i < internalHandlers . length ; i ++ ) {
137
+ internalHandlers [ i ] ( data ) ;
138
+ }
139
+ }
140
+
105
141
/*
106
142
* Now call the final handler and collect its value
107
143
*/
@@ -124,6 +160,13 @@ var Events = {
124
160
delete plotObj . removeAllListeners ;
125
161
delete plotObj . emit ;
126
162
163
+ delete plotObj . _ev ;
164
+ delete plotObj . _internalEv ;
165
+ delete plotObj . _internalOn ;
166
+ delete plotObj . _internalOnce ;
167
+ delete plotObj . _removeInternalListener ;
168
+ delete plotObj . _removeAllInternalListeners ; ;
169
+
127
170
return plotObj ;
128
171
}
129
172
0 commit comments