Skip to content

Commit

Permalink
rollback breaking change, add doc for the change
Browse files Browse the repository at this point in the history
  • Loading branch information
kaesonho committed Aug 9, 2016
1 parent dea7f24 commit 9203666
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 11 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ var I13nDempApp = setupI13n(DemoApp, {

Or follow our guide and [create your own](./docs/guides/createPlugins.md).


## I13n Tree
![I13n Tree](https://cloud.githubusercontent.com/assets/3829183/7980892/0b38eb70-0a60-11e5-8cc2-712ec42089fc.png)

Expand Down
9 changes: 9 additions & 0 deletions docs/api/setupI13n.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ var I13nDempApp = setupI13n(DemoApp, {
}, [someReactI13nPlugin]);

// then you could use I13nDemoApp to render you app

### Create and access the ReactI13n instance

What we do with `setupI13n` is that we will create the `ReactI13n` instance, along with a root node of the I13nTree, passing them via component context to the children.

It's designed to work within React components, you should be able to just [utilFuctions](https://github.com/yahoo/react-i13n/blob/master/docs/guides/utilFunctions.md) and trigger i13n events. In case you want to do this out of React components, you can access `window._reactI13nInstance` directly.
If you have multiple react trees in one page, we will create multiple i13n trees based on how many react tree you have. On client side the [utilFuctions](https://github.com/yahoo/react-i13n/blob/master/docs/guides/utilFunctions.md) still work based on the global instance object, while on server side, only the children under `setupI13n` can get the react i13n instance as we don't have a proper way to share the reactI13n instance without causing [memory leak](https://github.com/yahoo/react-i13n/pull/100).

```
### Util Functions
Expand Down
15 changes: 14 additions & 1 deletion src/libs/ReactI13n.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ if ('client' === ENVIRONMENT) {
* @param {Object} options options object
* @param {Boolean} options.isViewportEnabled if enable viewport checking
* @param {Object} options.rootModelData model data of root i13n node
* @param {Object} options.i13nNodeClass the i13nNode class, you can inherit it with your own functionalities
* @param {String} options.scrollableContainerId id of the scrollable element that your components
* reside within. Normally, you won't need to provide a value for this. This is only to
* support viewport checking when your components are contained within a scrollable element.
Expand All @@ -32,6 +33,7 @@ if ('client' === ENVIRONMENT) {
var ReactI13n = function ReactI13n (options) {
debug('init', options);
options = options || {};
this._i13nNodeClass = 'function' === typeof options.i13nNodeClass ? options.i13nNodeClass : I13nNode;
this._plugins = {};
this._eventsQueues = {};
this._isViewportEnabled = options.isViewportEnabled || false;
Expand All @@ -45,7 +47,8 @@ var ReactI13n = function ReactI13n (options) {
* @method createRootI13nNode
*/
ReactI13n.prototype.createRootI13nNode = function createRootI13nNode () {
this._rootI13nNode = new I13nNode(null, this._rootModelData, false);
var I13nNodeClass = this.getI13nNodeClass();
this._rootI13nNode = new I13nNodeClass(null, this._rootModelData, false);
if ('client' === ENVIRONMENT) {
this._rootI13nNode.setDOMNode(document.body);
}
Expand Down Expand Up @@ -128,6 +131,15 @@ ReactI13n.prototype.getEventHandlers = function getEventHandlers (eventName, pay
return promiseHandlers;
};

/**
* Get I13n node class
* @method getI13nNodeClass
* @return {Object} I13nNode class
*/
ReactI13n.prototype.getI13nNodeClass = function getI13nNodeClass () {
return this._i13nNodeClass;
};

/**
* Get isViewportEnabled value
* @method isViewportEnabled
Expand Down Expand Up @@ -175,6 +187,7 @@ ReactI13n.prototype.getRootI13nNode = function getRootI13nNode () {
ReactI13n.prototype.updateOptions = function updateOptions (options) {
debug('updated', options);
options = options || {};
this._i13nNodeClass = 'function' === typeof options.i13nNodeClass ? options.i13nNodeClass : this._i13nNodeClass;
this._isViewportEnabled = (undefined !== options.isViewportEnabled) ?
options.isViewportEnabled : this._isViewportEnabled;
this._rootModelData = options.rootModelData ? options.rootModelData : this._rootModelData;
Expand Down
3 changes: 2 additions & 1 deletion src/mixins/I13nMixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -366,8 +366,9 @@ var I13nMixin = {
var self = this;
var parentI13nNode = self._getParentI13nNode();
var reactI13n = self._getReactI13n();
var I13nNodeClass = (reactI13n && reactI13n.getI13nNodeClass()) || I13nNode;;
// TODO @kaesonho remove BC for model
self._i13nNode = new I13nNode(
self._i13nNode = new I13nNodeClass(
parentI13nNode,
self.props.i13nModel || self.props.model,
self.isLeafNode(),
Expand Down
24 changes: 18 additions & 6 deletions src/mixins/I13nUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ var I13nUtils = {
executeEvent: React.PropTypes.func,
getI13nNode: React.PropTypes.func,
parentI13nNode: React.PropTypes.object,
reactI13nInstance: React.PropTypes.object
_reactI13nInstance: React.PropTypes.object
})
},

Expand All @@ -23,7 +23,7 @@ var I13nUtils = {
executeEvent: React.PropTypes.func,
getI13nNode: React.PropTypes.func,
parentI13nNode: React.PropTypes.object,
reactI13nInstance: React.PropTypes.object
_reactI13nInstance: React.PropTypes.object
})
},

Expand All @@ -34,12 +34,12 @@ var I13nUtils = {
*/
getChildContext: function () {
return {
i13n: Object.assign({}, this.context.i13n, {
i13n: {
executeEvent: this.executeI13nEvent,
getI13nNode: this.getI13nNode,
parentI13nNode: this._i13nNode,
reactI13nInstance: this._getReactI13n()
})
_reactI13nInstance: this._getReactI13n()
}
};
},

Expand All @@ -53,11 +53,23 @@ var I13nUtils = {
*/
executeI13nEvent: function (eventName, payload, callback) {
var reactI13nInstance = this._getReactI13n();
var errorMessage = '';
payload = payload || {};
payload.i13nNode = payload.i13nNode || this.getI13nNode();
if (reactI13nInstance) {
reactI13nInstance.execute(eventName, payload, callback);
} else {
if ('production' !== process.env.NODE_ENV) {
errorMessage = 'ReactI13n instance is not found, ' +
'please make sure you have setupI13n on the root component. ';
if (!IS_CLIENT) {
errorMessage += 'On server side, ' +
'you can only execute the i13n event on the components under setupI13n, ' +
'please make sure you are calling executeI13nEvent correctly';
}
console && console.warn && console.warn(errorMessage);
console && console.trace && console.trace();
}
callback && callback();
}
},
Expand All @@ -83,7 +95,7 @@ var I13nUtils = {
globalReactI13n = window._reactI13nInstance;
}
return this._reactI13nInstance ||
(this.context && this.context.i13n && this.context.i13n.reactI13nInstance) ||
(this.context && this.context.i13n && this.context.i13n._reactI13nInstance) ||
globalReactI13n;
},

Expand Down
2 changes: 1 addition & 1 deletion src/utils/setupI13n.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ module.exports = function setupI13n (Component, options, plugins) {

mixins: [I13nUtils],

displayName: options.displayName || ('setupI13n(' + componentName + ')'),
displayName: options.displayName || ('RootI13n' + componentName),

autobind: false,

Expand Down
2 changes: 1 addition & 1 deletion tests/unit/utils/setupI13n.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ describe('setupI13n', function () {

// check the initial state is correct after render
var I13nTestApp = setupI13n(TestApp, mockData.options, [mockData.plugin]);
expect(I13nTestApp.displayName).to.eql('setupI13n(TestApp)');
expect(I13nTestApp.displayName).to.eql('RootI13nTestApp');
var container = document.createElement('div');
var component = ReactDOM.render(React.createElement(I13nTestApp, {}), container);
expect(mockData.reactI13n._options).to.eql(mockData.options);
Expand Down

0 comments on commit 9203666

Please sign in to comment.