react / react-0.13.3 / examples / basic-commonjs / node_modules / reactify / node_modules / react-tools / src / event / EventPluginRegistry.js
81152 views/**1* Copyright 2013-2014, Facebook, Inc.2* All rights reserved.3*4* This source code is licensed under the BSD-style license found in the5* LICENSE file in the root directory of this source tree. An additional grant6* of patent rights can be found in the PATENTS file in the same directory.7*8* @providesModule EventPluginRegistry9* @typechecks static-only10*/1112"use strict";1314var invariant = require('invariant');1516/**17* Injectable ordering of event plugins.18*/19var EventPluginOrder = null;2021/**22* Injectable mapping from names to event plugin modules.23*/24var namesToPlugins = {};2526/**27* Recomputes the plugin list using the injected plugins and plugin ordering.28*29* @private30*/31function recomputePluginOrdering() {32if (!EventPluginOrder) {33// Wait until an `EventPluginOrder` is injected.34return;35}36for (var pluginName in namesToPlugins) {37var PluginModule = namesToPlugins[pluginName];38var pluginIndex = EventPluginOrder.indexOf(pluginName);39invariant(40pluginIndex > -1,41'EventPluginRegistry: Cannot inject event plugins that do not exist in ' +42'the plugin ordering, `%s`.',43pluginName44);45if (EventPluginRegistry.plugins[pluginIndex]) {46continue;47}48invariant(49PluginModule.extractEvents,50'EventPluginRegistry: Event plugins must implement an `extractEvents` ' +51'method, but `%s` does not.',52pluginName53);54EventPluginRegistry.plugins[pluginIndex] = PluginModule;55var publishedEvents = PluginModule.eventTypes;56for (var eventName in publishedEvents) {57invariant(58publishEventForPlugin(59publishedEvents[eventName],60PluginModule,61eventName62),63'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.',64eventName,65pluginName66);67}68}69}7071/**72* Publishes an event so that it can be dispatched by the supplied plugin.73*74* @param {object} dispatchConfig Dispatch configuration for the event.75* @param {object} PluginModule Plugin publishing the event.76* @return {boolean} True if the event was successfully published.77* @private78*/79function publishEventForPlugin(dispatchConfig, PluginModule, eventName) {80invariant(81!EventPluginRegistry.eventNameDispatchConfigs.hasOwnProperty(eventName),82'EventPluginHub: More than one plugin attempted to publish the same ' +83'event name, `%s`.',84eventName85);86EventPluginRegistry.eventNameDispatchConfigs[eventName] = dispatchConfig;8788var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;89if (phasedRegistrationNames) {90for (var phaseName in phasedRegistrationNames) {91if (phasedRegistrationNames.hasOwnProperty(phaseName)) {92var phasedRegistrationName = phasedRegistrationNames[phaseName];93publishRegistrationName(94phasedRegistrationName,95PluginModule,96eventName97);98}99}100return true;101} else if (dispatchConfig.registrationName) {102publishRegistrationName(103dispatchConfig.registrationName,104PluginModule,105eventName106);107return true;108}109return false;110}111112/**113* Publishes a registration name that is used to identify dispatched events and114* can be used with `EventPluginHub.putListener` to register listeners.115*116* @param {string} registrationName Registration name to add.117* @param {object} PluginModule Plugin publishing the event.118* @private119*/120function publishRegistrationName(registrationName, PluginModule, eventName) {121invariant(122!EventPluginRegistry.registrationNameModules[registrationName],123'EventPluginHub: More than one plugin attempted to publish the same ' +124'registration name, `%s`.',125registrationName126);127EventPluginRegistry.registrationNameModules[registrationName] = PluginModule;128EventPluginRegistry.registrationNameDependencies[registrationName] =129PluginModule.eventTypes[eventName].dependencies;130}131132/**133* Registers plugins so that they can extract and dispatch events.134*135* @see {EventPluginHub}136*/137var EventPluginRegistry = {138139/**140* Ordered list of injected plugins.141*/142plugins: [],143144/**145* Mapping from event name to dispatch config146*/147eventNameDispatchConfigs: {},148149/**150* Mapping from registration name to plugin module151*/152registrationNameModules: {},153154/**155* Mapping from registration name to event name156*/157registrationNameDependencies: {},158159/**160* Injects an ordering of plugins (by plugin name). This allows the ordering161* to be decoupled from injection of the actual plugins so that ordering is162* always deterministic regardless of packaging, on-the-fly injection, etc.163*164* @param {array} InjectedEventPluginOrder165* @internal166* @see {EventPluginHub.injection.injectEventPluginOrder}167*/168injectEventPluginOrder: function(InjectedEventPluginOrder) {169invariant(170!EventPluginOrder,171'EventPluginRegistry: Cannot inject event plugin ordering more than ' +172'once. You are likely trying to load more than one copy of React.'173);174// Clone the ordering so it cannot be dynamically mutated.175EventPluginOrder = Array.prototype.slice.call(InjectedEventPluginOrder);176recomputePluginOrdering();177},178179/**180* Injects plugins to be used by `EventPluginHub`. The plugin names must be181* in the ordering injected by `injectEventPluginOrder`.182*183* Plugins can be injected as part of page initialization or on-the-fly.184*185* @param {object} injectedNamesToPlugins Map from names to plugin modules.186* @internal187* @see {EventPluginHub.injection.injectEventPluginsByName}188*/189injectEventPluginsByName: function(injectedNamesToPlugins) {190var isOrderingDirty = false;191for (var pluginName in injectedNamesToPlugins) {192if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {193continue;194}195var PluginModule = injectedNamesToPlugins[pluginName];196if (!namesToPlugins.hasOwnProperty(pluginName) ||197namesToPlugins[pluginName] !== PluginModule) {198invariant(199!namesToPlugins[pluginName],200'EventPluginRegistry: Cannot inject two different event plugins ' +201'using the same name, `%s`.',202pluginName203);204namesToPlugins[pluginName] = PluginModule;205isOrderingDirty = true;206}207}208if (isOrderingDirty) {209recomputePluginOrdering();210}211},212213/**214* Looks up the plugin for the supplied event.215*216* @param {object} event A synthetic event.217* @return {?object} The plugin that created the supplied event.218* @internal219*/220getPluginModuleForEvent: function(event) {221var dispatchConfig = event.dispatchConfig;222if (dispatchConfig.registrationName) {223return EventPluginRegistry.registrationNameModules[224dispatchConfig.registrationName225] || null;226}227for (var phase in dispatchConfig.phasedRegistrationNames) {228if (!dispatchConfig.phasedRegistrationNames.hasOwnProperty(phase)) {229continue;230}231var PluginModule = EventPluginRegistry.registrationNameModules[232dispatchConfig.phasedRegistrationNames[phase]233];234if (PluginModule) {235return PluginModule;236}237}238return null;239},240241/**242* Exposed for unit testing.243* @private244*/245_resetEventPlugins: function() {246EventPluginOrder = null;247for (var pluginName in namesToPlugins) {248if (namesToPlugins.hasOwnProperty(pluginName)) {249delete namesToPlugins[pluginName];250}251}252EventPluginRegistry.plugins.length = 0;253254var eventNameDispatchConfigs = EventPluginRegistry.eventNameDispatchConfigs;255for (var eventName in eventNameDispatchConfigs) {256if (eventNameDispatchConfigs.hasOwnProperty(eventName)) {257delete eventNameDispatchConfigs[eventName];258}259}260261var registrationNameModules = EventPluginRegistry.registrationNameModules;262for (var registrationName in registrationNameModules) {263if (registrationNameModules.hasOwnProperty(registrationName)) {264delete registrationNameModules[registrationName];265}266}267}268269};270271module.exports = EventPluginRegistry;272273274