結論
InjectではReactUpdates.flushBatchedUpdatesが実行されている形跡はなかった
inject追跡
もはやすべてのinjectを見るしか、queueの処理をつかめないので、頑張る。
ReactDefaultInjection.js
function inject() {
...,
// ReactBrowserEventEmitter.injection.injectReactEventListener(ReactEventListener)
ReactInjection.EventEmitter.injectReactEventListener(
ReactEventListener
);
...,
}
ReactBrowserEventEmitter.js
var ReactBrowserEventEmitter = assign({}, ReactEventEmitterMixin, {
ReactEventListener: null,
injection: {
/**
* @param {object} ReactEventListener
*/
injectReactEventListener: function(ReactEventListener) {
ReactEventListener.setHandleTopLevel(
ReactBrowserEventEmitter.handleTopLevel
);
ReactBrowserEventEmitter.ReactEventListener = ReactEventListener;
},
},
...,
};
ReactBrowserEventEmitter.ReactEventListener= ReactEventListener
となる。
ReactEventListener.js
var ReactEventListener = {
...,
}
ここは外れ。次。
ReactDefaultInjection.js
function inject() {
...,
// EventPluginHub.injection.injectEventPluginOrder(DefaultEventPluginOrder)
// = EventPluginRegistry.injectEventPluginOrder(DefaultEventPluginOrder)
ReactInjection.EventPluginHub.injectEventPluginOrder(DefaultEventPluginOrder);
...,
}
EventPluginHub.js
var EventPluginHub = {
/**
* Methods for injecting dependencies.
*/
injection: {
/**
* @param {array} InjectedEventPluginOrder
* @public
*/
injectEventPluginOrder: EventPluginRegistry.injectEventPluginOrder,
...,
},
...,
};
EventPluginRegistry.js
var EventPluginRegistry = {
...,
injectEventPluginOrder: function(InjectedEventPluginOrder) {
...,
// Clone the ordering so it cannot be dynamically mutated.
// 配列にコピーすることで元のobjectを壊さない
// EventPluginOrder = [DefaultEventPluginOrder]
EventPluginOrder = Array.prototype.slice.call(InjectedEventPluginOrder);
recomputePluginOrdering();
},
...,
};
EventPluginRegistry.js
function recomputePluginOrdering() {
if (!EventPluginOrder) {
// Wait until an `EventPluginOrder` is injected.
return;
}
for (var pluginName in namesToPlugins) {
..., // この時点ではないので無視
}
}
ここも外れ。次。
ReactDefaultInjection.js
function inject() {
...,
// EventPluginUtils.injection.injectComponentTree(ReactDOMComponentTree)
ReactInjection.EventPluginUtils.injectComponentTree(ReactDOMComponentTree);
...,
}
:EventPluginUtils.js
var injection = {
injectComponentTree: function(Injected) {
// ComponentTree = ReactDOMComponentTree
ComponentTree = Injected;
...,
},
...,
};
ここは外れ。次。
ReactDefaultInjection.js
function inject() {
...,
// EventPluginUtils.injection.injectTreeTraversal(ReactDOMTreeTraversal)
ReactInjection.EventPluginUtils.injectTreeTraversal(ReactDOMTreeTraversal);
...,
}
:EventPluginUtils.js
var injection = {
injectTreeTraversal: function(Injected) {
// TreeTraversal = ReactDOMTreeTraversal
TreeTraversal = Injected;
...,
},
...,
};
ここも外れ・・。いつになれば・・。
ReactDefaultInjection.js
function inject() {
...,
ReactInjection.EventPluginHub.injectEventPluginsByName({
SimpleEventPlugin: SimpleEventPlugin,
EnterLeaveEventPlugin: EnterLeaveEventPlugin,
ChangeEventPlugin: ChangeEventPlugin,
SelectEventPlugin: SelectEventPlugin,
BeforeInputEventPlugin: BeforeInputEventPlugin,
});
...,
}
EventPluginHub.js
var EventPluginHub = {
/**
* Methods for injecting dependencies.
*/
injection: {
...,
/**
* @param {object} injectedNamesToPlugins Map from names to plugin modules.
*/
injectEventPluginsByName: EventPluginRegistry.injectEventPluginsByName,
},
...,
};
EventPluginRegistry.js
var EventPluginRegistry = {
...,
injectEventPluginsByName: function(injectedNamesToPlugins) {
var isOrderingDirty = false;
for (var pluginName in injectedNamesToPlugins) {
// 何かのprototypeから継承してるものは無視
if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {
continue;
}
var PluginModule = injectedNamesToPlugins[pluginName];
// namesToPluginsに含まてれいない場合は追加
if (!namesToPlugins.hasOwnProperty(pluginName) ||
namesToPlugins[pluginName] !== PluginModule) {
...,
namesToPlugins[pluginName] = PluginModule;
isOrderingDirty = true;
}
}
if (isOrderingDirty) {
recomputePluginOrdering();
}
},
...,
};
EventPluginRegistry.js
function recomputePluginOrdering() {
if (!EventPluginOrder) {
// Wait until an `EventPluginOrder` is injected.
return;
}
for (var pluginName in namesToPlugins) {
// さっき無視されたのがここで実行される
var PluginModule = namesToPlugins[pluginName];
var pluginIndex = EventPluginOrder.indexOf(pluginName);
...,
if (EventPluginRegistry.plugins[pluginIndex]) {
continue;
}
...,
EventPluginRegistry.plugins[pluginIndex] = PluginModule;
var publishedEvents = PluginModule.eventTypes;
for (var eventName in publishedEvents) {
// エラー処理
}
}
}
DefaultEventPluginOrder.js
// keyOfはfacebook内部のLibraryらしい
var DefaultEventPluginOrder = [
keyOf({ResponderEventPlugin: null}),
keyOf({SimpleEventPlugin: null}),
keyOf({TapEventPlugin: null}),
keyOf({EnterLeaveEventPlugin: null}),
keyOf({ChangeEventPlugin: null}),
keyOf({SelectEventPlugin: null}),
keyOf({BeforeInputEventPlugin: null}),
];
ここも外れ。どこなんだ・・。
ReactDefaultInjection.js
function inject() {
...,
// DOMProperty.injection.injectDOMPorpertyConfig
ReactInjection.DOMProperty.injectDOMPropertyConfig(HTMLDOMPropertyConfig);
ReactInjection.DOMProperty.injectDOMPropertyConfig(SVGDOMPropertyConfig);
...,
}
いっぺんに見ていく。
DOMProperty.js
var DOMPropertyInjection = {
/**
* Mapping from normalized, camelcased property names to a configuration that
* specifies how the associated DOM property should be accessed or rendered.
*/
MUST_USE_PROPERTY: 0x1,
HAS_SIDE_EFFECTS: 0x2,
HAS_BOOLEAN_VALUE: 0x4,
HAS_NUMERIC_VALUE: 0x8,
HAS_POSITIVE_NUMERIC_VALUE: 0x10 | 0x8,
HAS_OVERLOADED_BOOLEAN_VALUE: 0x20,
injectDOMPropertyConfig: function(domPropertyConfig) {
...,
},
};
ここも外れ。とうとう最後・・
ReactDefaultInjection.js
function inject() {
...,
// ReactComponentEnvironment.injection.injectEnvironment(ReactComponentBrowserEnvironment)
ReactInjection.Component.injectEnvironment(ReactComponentBrowserEnvironment);
...,
}
ReactComponentEnvironment.js
var ReactComponentEnvironment = {
injection: {
injectEnvironment: function(environment) {
...,
// environment = ReactComponentBrowserEnvironment
ReactComponentEnvironment.unmountIDFromEnvironment =
environment.unmountIDFromEnvironment;
ReactComponentEnvironment.replaceNodeWithMarkup =
environment.replaceNodeWithMarkup;
ReactComponentEnvironment.processChildrenUpdates =
environment.processChildrenUpdates;
injected = true;
},
},
};
ReactComponentBrowserEnvironment.js
var ReactComponentBrowserEnvironment = {
processChildrenUpdates:
ReactDOMIDOperations.dangerouslyProcessChildrenUpdates,
replaceNodeWithMarkup:
DOMChildrenOperations.dangerouslyReplaceNodeWithMarkup,
unmountIDFromEnvironment: function(rootNodeID) {
},
};
ReactDOMIDOperations.js
var ReactDOMIDOperations = {
dangerouslyProcessChildrenUpdates: function(parentInst, updates) {
var node = ReactDOMComponentTree.getNodeFromInstance(parentInst);
DOMChildrenOperations.processUpdates(node, updates);
},
}
DOMChildrenOperations.js
var DOMChildrenOperations = {
dangerouslyReplaceNodeWithMarkup: Danger.dangerouslyReplaceNodeWithMarkup,
...,
};
Danger.js
var Danger = {
...,
dangerouslyReplaceNodeWithMarkup: function(oldChild, markup) {
...,
if (typeof markup === 'string') {
var newChild = createNodesFromMarkup(markup, emptyFunction)[0];
oldChild.parentNode.replaceChild(newChild, oldChild);
} else {
DOMLazyTree.replaceChildWithTree(oldChild, markup);
}
},
};
どちらもmethodを設定しているだけなので外れ。ナンテコッタイ!