続き
function ReactReconcileTransaction(useCreateElement) {
this.reinitializeTransaction();
...,
}
ここで各Transactionが初期化されている。
これが胡散臭い。
var Mixin = {
/**
* Sets up this instance so that it is prepared for collecting metrics. Does
* so such that this setup method may be used on an instance that is already
* initialized, in a way that does not consume additional memory upon reuse.
* That can be useful if you decide to make your subclass of this mixin a
* "PooledClass".
*/
reinitializeTransaction: function() {
this.transactionWrappers = this.getTransactionWrappers();
if (this.wrapperInitData) {
this.wrapperInitData.length = 0;
} else {
this.wrapperInitData = [];
}
this._isInTransaction = false;
},
};
getTransactionWrappersはthisがcontextなので、ReactReconcileTransactionを見る。
var Mixin = {
getTransactionWrappers: function() {
return TRANSACTION_WRAPPERS;
},
}:
var SELECTION_RESTORATION = {
/**
* @return {Selection} Selection information.
*/
initialize: ReactInputSelection.getSelectionInformation,
/**
* @param {Selection} sel Selection information returned from `initialize`.
*/
close: ReactInputSelection.restoreSelection,
};
var EVENT_SUPPRESSION = {
/**
* @return {boolean} The enabled status of `ReactBrowserEventEmitter` before
* the reconciliation.
*/
initialize: function() {
var currentlyEnabled = ReactBrowserEventEmitter.isEnabled();
ReactBrowserEventEmitter.setEnabled(false);
return currentlyEnabled;
},
/**
* @param {boolean} previouslyEnabled Enabled status of
* `ReactBrowserEventEmitter` before the reconciliation occurred. `close`
* restores the previous value.
*/
close: function(previouslyEnabled) {
ReactBrowserEventEmitter.setEnabled(previouslyEnabled);
},
};
var ON_DOM_READY_QUEUEING = {
/**
* Initializes the internal `onDOMReady` queue.
*/
initialize: function() {
this.reactMountReady.reset();
},
/**
* After DOM is flushed, invoke all registered `onDOMReady` callbacks.
*/
close: function() {
this.reactMountReady.notifyAll();
},
};
var TRANSACTION_WRAPPERS = [
SELECTION_RESTORATION,
EVENT_SUPPRESSION,
ON_DOM_READY_QUEUEING,
];
ReactReconcileTransactionのmethodを呼び出すWrapperたち。
Wrapperというからには他のTransactionでも使われることを想定しているのだろうか。
最終的にwrapperInitData = []
、_isInTransaction = false
となるだけのようだ。
つぎにちょっと飛んでTransaction.Mixin.performを見に行く。
var Mixin = {
perform: function(method, scope, a, b, c, d, e, f) {
...,
this.initializeAll(0);
...,
},
};
ここが怪しいので見てみる。
var Mixin = {
initializeAll: function(startIndex) {
var transactionWrappers = this.transactionWrappers;
for (var i = startIndex; i < transactionWrappers.length; i++) {
var wrapper = transactionWrappers[i];
try {
this.wrapperInitData[i] = Transaction.OBSERVED_ERROR;
this.wrapperInitData[i] = wrapper.initialize ?
wrapper.initialize.call(this) :
null;
} finally {
// エラー処理
}
}
},
};
ここでTRANSACTION_WRAPPERSの各Wrapperのinializeが走る。
contextはthis=ReactReconcileTransaction
initialize: ReactInputSelection.getSelectionInformation
var ReactInputSelection = {
...,
getSelectionInformation: function() {
var focusedElem = getActiveElement();
return {
focusedElem: focusedElem,
selectionRange:
ReactInputSelection.hasSelectionCapabilities(focusedElem) ?
ReactInputSelection.getSelection(focusedElem) :
null,
};
},
};
ちなみにgetActiveElementはfacebookの内部Libraryになっている。
https://github.com/facebook/fbjs/blob/master/src/core/dom/getActiveElement.js
function getActiveElement() /*?DOMElement*/ {
if (typeof document === 'undefined') {
return null;
}
try {
return document.activeElement || document.body;
} catch (e) {
return document.body;
}
}
activeElementはこちらにある通り現在FocusされているDOMを取得する。
initialize: function() {
var currentlyEnabled = ReactBrowserEventEmitter.isEnabled();
ReactBrowserEventEmitter.setEnabled(false);
return currentlyEnabled;
},
currentlyEnabledはtrueとなる。
initialize: function() {
this.reactMountReady.reset();
},
_callbacks=null
と_contexts=null
を得るだけ。
うーん。全然Queueを処理するような箇所が見当たらない・・