Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80517 views
1
/**
2
* Copyright 2013-2015, Facebook, Inc.
3
* All rights reserved.
4
*
5
* This source code is licensed under the BSD-style license found in the
6
* LICENSE file in the root directory of this source tree. An additional grant
7
* of patent rights can be found in the PATENTS file in the same directory.
8
*
9
* @providesModule EventPluginRegistry
10
* @typechecks static-only
11
*/
12
13
'use strict';
14
15
var invariant = require("./invariant");
16
17
/**
18
* Injectable ordering of event plugins.
19
*/
20
var EventPluginOrder = null;
21
22
/**
23
* Injectable mapping from names to event plugin modules.
24
*/
25
var namesToPlugins = {};
26
27
/**
28
* Recomputes the plugin list using the injected plugins and plugin ordering.
29
*
30
* @private
31
*/
32
function recomputePluginOrdering() {
33
if (!EventPluginOrder) {
34
// Wait until an `EventPluginOrder` is injected.
35
return;
36
}
37
for (var pluginName in namesToPlugins) {
38
var PluginModule = namesToPlugins[pluginName];
39
var pluginIndex = EventPluginOrder.indexOf(pluginName);
40
("production" !== process.env.NODE_ENV ? invariant(
41
pluginIndex > -1,
42
'EventPluginRegistry: Cannot inject event plugins that do not exist in ' +
43
'the plugin ordering, `%s`.',
44
pluginName
45
) : invariant(pluginIndex > -1));
46
if (EventPluginRegistry.plugins[pluginIndex]) {
47
continue;
48
}
49
("production" !== process.env.NODE_ENV ? invariant(
50
PluginModule.extractEvents,
51
'EventPluginRegistry: Event plugins must implement an `extractEvents` ' +
52
'method, but `%s` does not.',
53
pluginName
54
) : invariant(PluginModule.extractEvents));
55
EventPluginRegistry.plugins[pluginIndex] = PluginModule;
56
var publishedEvents = PluginModule.eventTypes;
57
for (var eventName in publishedEvents) {
58
("production" !== process.env.NODE_ENV ? invariant(
59
publishEventForPlugin(
60
publishedEvents[eventName],
61
PluginModule,
62
eventName
63
),
64
'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.',
65
eventName,
66
pluginName
67
) : invariant(publishEventForPlugin(
68
publishedEvents[eventName],
69
PluginModule,
70
eventName
71
)));
72
}
73
}
74
}
75
76
/**
77
* Publishes an event so that it can be dispatched by the supplied plugin.
78
*
79
* @param {object} dispatchConfig Dispatch configuration for the event.
80
* @param {object} PluginModule Plugin publishing the event.
81
* @return {boolean} True if the event was successfully published.
82
* @private
83
*/
84
function publishEventForPlugin(dispatchConfig, PluginModule, eventName) {
85
("production" !== process.env.NODE_ENV ? invariant(
86
!EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName),
87
'EventPluginHub: More than one plugin attempted to publish the same ' +
88
'event name, `%s`.',
89
eventName
90
) : invariant(!EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName)));
91
EventPluginRegistry.eventNameDispatchConfigs[eventName] = dispatchConfig;
92
93
var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;
94
if (phasedRegistrationNames) {
95
for (var phaseName in phasedRegistrationNames) {
96
if (phasedRegistrationNames.hasOwnProperty(phaseName)) {
97
var phasedRegistrationName = phasedRegistrationNames[phaseName];
98
publishRegistrationName(
99
phasedRegistrationName,
100
PluginModule,
101
eventName
102
);
103
}
104
}
105
return true;
106
} else if (dispatchConfig.registrationName) {
107
publishRegistrationName(
108
dispatchConfig.registrationName,
109
PluginModule,
110
eventName
111
);
112
return true;
113
}
114
return false;
115
}
116
117
/**
118
* Publishes a registration name that is used to identify dispatched events and
119
* can be used with `EventPluginHub.putListener` to register listeners.
120
*
121
* @param {string} registrationName Registration name to add.
122
* @param {object} PluginModule Plugin publishing the event.
123
* @private
124
*/
125
function publishRegistrationName(registrationName, PluginModule, eventName) {
126
("production" !== process.env.NODE_ENV ? invariant(
127
!EventPluginRegistry.registrationNameModules[registrationName],
128
'EventPluginHub: More than one plugin attempted to publish the same ' +
129
'registration name, `%s`.',
130
registrationName
131
) : invariant(!EventPluginRegistry.registrationNameModules[registrationName]));
132
EventPluginRegistry.registrationNameModules[registrationName] = PluginModule;
133
EventPluginRegistry.registrationNameDependencies[registrationName] =
134
PluginModule.eventTypes[eventName].dependencies;
135
}
136
137
/**
138
* Registers plugins so that they can extract and dispatch events.
139
*
140
* @see {EventPluginHub}
141
*/
142
var EventPluginRegistry = {
143
144
/**
145
* Ordered list of injected plugins.
146
*/
147
plugins: [],
148
149
/**
150
* Mapping from event name to dispatch config
151
*/
152
eventNameDispatchConfigs: {},
153
154
/**
155
* Mapping from registration name to plugin module
156
*/
157
registrationNameModules: {},
158
159
/**
160
* Mapping from registration name to event name
161
*/
162
registrationNameDependencies: {},
163
164
/**
165
* Injects an ordering of plugins (by plugin name). This allows the ordering
166
* to be decoupled from injection of the actual plugins so that ordering is
167
* always deterministic regardless of packaging, on-the-fly injection, etc.
168
*
169
* @param {array} InjectedEventPluginOrder
170
* @internal
171
* @see {EventPluginHub.injection.injectEventPluginOrder}
172
*/
173
injectEventPluginOrder: function(InjectedEventPluginOrder) {
174
("production" !== process.env.NODE_ENV ? invariant(
175
!EventPluginOrder,
176
'EventPluginRegistry: Cannot inject event plugin ordering more than ' +
177
'once. You are likely trying to load more than one copy of React.'
178
) : invariant(!EventPluginOrder));
179
// Clone the ordering so it cannot be dynamically mutated.
180
EventPluginOrder = Array.prototype.slice.call(InjectedEventPluginOrder);
181
recomputePluginOrdering();
182
},
183
184
/**
185
* Injects plugins to be used by `EventPluginHub`. The plugin names must be
186
* in the ordering injected by `injectEventPluginOrder`.
187
*
188
* Plugins can be injected as part of page initialization or on-the-fly.
189
*
190
* @param {object} injectedNamesToPlugins Map from names to plugin modules.
191
* @internal
192
* @see {EventPluginHub.injection.injectEventPluginsByName}
193
*/
194
injectEventPluginsByName: function(injectedNamesToPlugins) {
195
var isOrderingDirty = false;
196
for (var pluginName in injectedNamesToPlugins) {
197
if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {
198
continue;
199
}
200
var PluginModule = injectedNamesToPlugins[pluginName];
201
if (!namesToPlugins.hasOwnProperty(pluginName) ||
202
namesToPlugins[pluginName] !== PluginModule) {
203
("production" !== process.env.NODE_ENV ? invariant(
204
!namesToPlugins[pluginName],
205
'EventPluginRegistry: Cannot inject two different event plugins ' +
206
'using the same name, `%s`.',
207
pluginName
208
) : invariant(!namesToPlugins[pluginName]));
209
namesToPlugins[pluginName] = PluginModule;
210
isOrderingDirty = true;
211
}
212
}
213
if (isOrderingDirty) {
214
recomputePluginOrdering();
215
}
216
},
217
218
/**
219
* Looks up the plugin for the supplied event.
220
*
221
* @param {object} event A synthetic event.
222
* @return {?object} The plugin that created the supplied event.
223
* @internal
224
*/
225
getPluginModuleForEvent: function(event) {
226
var dispatchConfig = event.dispatchConfig;
227
if (dispatchConfig.registrationName) {
228
return EventPluginRegistry.registrationNameModules[
229
dispatchConfig.registrationName
230
] || null;
231
}
232
for (var phase in dispatchConfig.phasedRegistrationNames) {
233
if (!dispatchConfig.phasedRegistrationNames.hasOwnProperty(phase)) {
234
continue;
235
}
236
var PluginModule = EventPluginRegistry.registrationNameModules[
237
dispatchConfig.phasedRegistrationNames[phase]
238
];
239
if (PluginModule) {
240
return PluginModule;
241
}
242
}
243
return null;
244
},
245
246
/**
247
* Exposed for unit testing.
248
* @private
249
*/
250
_resetEventPlugins: function() {
251
EventPluginOrder = null;
252
for (var pluginName in namesToPlugins) {
253
if (namesToPlugins.hasOwnProperty(pluginName)) {
254
delete namesToPlugins[pluginName];
255
}
256
}
257
EventPluginRegistry.plugins.length = 0;
258
259
var eventNameDispatchConfigs = EventPluginRegistry.eventNameDispatchConfigs;
260
for (var eventName in eventNameDispatchConfigs) {
261
if (eventNameDispatchConfigs.hasOwnProperty(eventName)) {
262
delete eventNameDispatchConfigs[eventName];
263
}
264
}
265
266
var registrationNameModules = EventPluginRegistry.registrationNameModules;
267
for (var registrationName in registrationNameModules) {
268
if (registrationNameModules.hasOwnProperty(registrationName)) {
269
delete registrationNameModules[registrationName];
270
}
271
}
272
}
273
274
};
275
276
module.exports = EventPluginRegistry;
277
278