mirror of
https://github.com/status-im/react-native.git
synced 2025-02-13 18:06:37 +00:00
Upgrade to React 0.13
- [React Native] Move copyProperties and mergeHelpers to github dir | Ben Alpert - [React Native] Update core modules for React 0.13 | Ben Alpert - [React Native] Update React to v0.13.0-rc2 | Ben Alpert
This commit is contained in:
parent
cdd13f504f
commit
418b27c36e
@ -65,7 +65,7 @@ var TouchableWithoutFeedback = React.createClass({
|
|||||||
render: function() {
|
render: function() {
|
||||||
// Note(vjeux): use cloneWithProps once React has been upgraded
|
// Note(vjeux): use cloneWithProps once React has been upgraded
|
||||||
var child = onlyChild(this.props.children);
|
var child = onlyChild(this.props.children);
|
||||||
Object.assign(child.props, {
|
return React.cloneElement(child, {
|
||||||
accessible: true,
|
accessible: true,
|
||||||
testID: this.props.testID,
|
testID: this.props.testID,
|
||||||
onStartShouldSetResponder: this.touchableHandleStartShouldSetResponder,
|
onStartShouldSetResponder: this.touchableHandleStartShouldSetResponder,
|
||||||
@ -75,7 +75,6 @@ var TouchableWithoutFeedback = React.createClass({
|
|||||||
onResponderRelease: this.touchableHandleResponderRelease,
|
onResponderRelease: this.touchableHandleResponderRelease,
|
||||||
onResponderTerminate: this.touchableHandleResponderTerminate
|
onResponderTerminate: this.touchableHandleResponderTerminate
|
||||||
});
|
});
|
||||||
return child;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2004-present Facebook. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* @providesModule RKRawText
|
|
||||||
* @typechecks static-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var ReactIOSViewAttributes = require('ReactIOSViewAttributes');
|
|
||||||
|
|
||||||
var createReactIOSNativeComponentClass = require('createReactIOSNativeComponentClass');
|
|
||||||
|
|
||||||
var RKRawText = createReactIOSNativeComponentClass({
|
|
||||||
validAttributes: {
|
|
||||||
text: true,
|
|
||||||
},
|
|
||||||
uiViewClassName: 'RCTRawText',
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = RKRawText;
|
|
@ -7,8 +7,8 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var ReactChildren = require('ReactChildren');
|
var ReactChildren = require('ReactChildren');
|
||||||
|
var ReactClass = require('ReactClass');
|
||||||
var ReactComponent = require('ReactComponent');
|
var ReactComponent = require('ReactComponent');
|
||||||
var ReactCompositeComponent = require('ReactCompositeComponent');
|
|
||||||
var ReactContext = require('ReactContext');
|
var ReactContext = require('ReactContext');
|
||||||
var ReactCurrentOwner = require('ReactCurrentOwner');
|
var ReactCurrentOwner = require('ReactCurrentOwner');
|
||||||
var ReactElement = require('ReactElement');
|
var ReactElement = require('ReactElement');
|
||||||
@ -16,7 +16,6 @@ var ReactElementValidator = require('ReactElementValidator');
|
|||||||
var ReactInstanceHandles = require('ReactInstanceHandles');
|
var ReactInstanceHandles = require('ReactInstanceHandles');
|
||||||
var ReactIOSDefaultInjection = require('ReactIOSDefaultInjection');
|
var ReactIOSDefaultInjection = require('ReactIOSDefaultInjection');
|
||||||
var ReactIOSMount = require('ReactIOSMount');
|
var ReactIOSMount = require('ReactIOSMount');
|
||||||
var ReactLegacyElement = require('ReactLegacyElement');
|
|
||||||
var ReactPropTypes = require('ReactPropTypes');
|
var ReactPropTypes = require('ReactPropTypes');
|
||||||
|
|
||||||
var deprecated = require('deprecated');
|
var deprecated = require('deprecated');
|
||||||
@ -27,20 +26,14 @@ ReactIOSDefaultInjection.inject();
|
|||||||
|
|
||||||
var createElement = ReactElement.createElement;
|
var createElement = ReactElement.createElement;
|
||||||
var createFactory = ReactElement.createFactory;
|
var createFactory = ReactElement.createFactory;
|
||||||
|
var cloneElement = ReactElement.cloneElement;
|
||||||
|
|
||||||
if (__DEV__) {
|
if (__DEV__) {
|
||||||
createElement = ReactElementValidator.createElement;
|
createElement = ReactElementValidator.createElement;
|
||||||
createFactory = ReactElementValidator.createFactory;
|
createFactory = ReactElementValidator.createFactory;
|
||||||
|
cloneElement = ReactElementValidator.cloneElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Drop legacy elements once classes no longer export these factories
|
|
||||||
createElement = ReactLegacyElement.wrapCreateElement(
|
|
||||||
createElement
|
|
||||||
);
|
|
||||||
createFactory = ReactLegacyElement.wrapCreateFactory(
|
|
||||||
createFactory
|
|
||||||
);
|
|
||||||
|
|
||||||
var resolveDefaultProps = function(element) {
|
var resolveDefaultProps = function(element) {
|
||||||
// Could be optimized, but not currently in heavy use.
|
// Could be optimized, but not currently in heavy use.
|
||||||
var defaultProps = element.type.defaultProps;
|
var defaultProps = element.type.defaultProps;
|
||||||
@ -82,9 +75,10 @@ var ReactIOS = {
|
|||||||
only: onlyChild
|
only: onlyChild
|
||||||
},
|
},
|
||||||
PropTypes: ReactPropTypes,
|
PropTypes: ReactPropTypes,
|
||||||
createClass: ReactCompositeComponent.createClass,
|
createClass: ReactClass.createClass,
|
||||||
createElement: createElement,
|
createElement: createElement,
|
||||||
createFactory: createFactory,
|
createFactory: createFactory,
|
||||||
|
cloneElement: cloneElement,
|
||||||
_augmentElement: augmentElement,
|
_augmentElement: augmentElement,
|
||||||
render: render,
|
render: render,
|
||||||
unmountComponentAtNode: ReactIOSMount.unmountComponentAtNode,
|
unmountComponentAtNode: ReactIOSMount.unmountComponentAtNode,
|
||||||
|
@ -13,10 +13,9 @@ var ReactPerf = require('ReactPerf');
|
|||||||
|
|
||||||
var ReactIOSComponentEnvironment = {
|
var ReactIOSComponentEnvironment = {
|
||||||
|
|
||||||
/**
|
processChildrenUpdates: ReactIOSDOMIDOperations.dangerouslyProcessChildrenUpdates,
|
||||||
* Will need to supply something that implements this.
|
|
||||||
*/
|
replaceNodeWithMarkupByID: ReactIOSDOMIDOperations.dangerouslyReplaceNodeWithMarkupByID,
|
||||||
BackendIDOperations: ReactIOSDOMIDOperations,
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Nothing to do for UIKit bridge.
|
* Nothing to do for UIKit bridge.
|
||||||
@ -34,34 +33,6 @@ var ReactIOSComponentEnvironment = {
|
|||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {View} view View tree image.
|
|
||||||
* @param {number} containerViewID View to insert sub-view into.
|
|
||||||
*/
|
|
||||||
mountImageIntoNode: ReactPerf.measure(
|
|
||||||
// FIXME(frantic): #4441289 Hack to avoid modifying react-tools
|
|
||||||
'ReactComponentBrowserEnvironment',
|
|
||||||
'mountImageIntoNode',
|
|
||||||
function(mountImage, containerID) {
|
|
||||||
// Since we now know that the `mountImage` has been mounted, we can
|
|
||||||
// mark it as such.
|
|
||||||
ReactIOSTagHandles.associateRootNodeIDWithMountedNodeHandle(
|
|
||||||
mountImage.rootNodeID,
|
|
||||||
mountImage.tag
|
|
||||||
);
|
|
||||||
var addChildTags = [mountImage.tag];
|
|
||||||
var addAtIndices = [0];
|
|
||||||
RKUIManager.manageChildren(
|
|
||||||
ReactIOSTagHandles.mostRecentMountedNodeHandleForRootNodeID(containerID),
|
|
||||||
null, // moveFromIndices
|
|
||||||
null, // moveToIndices
|
|
||||||
addChildTags,
|
|
||||||
addAtIndices,
|
|
||||||
null // removeAtIndices
|
|
||||||
);
|
|
||||||
}
|
|
||||||
),
|
|
||||||
|
|
||||||
ReactReconcileTransaction: ReactIOSReconcileTransaction,
|
ReactReconcileTransaction: ReactIOSReconcileTransaction,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var ReactIOSTagHandles = require('ReactIOSTagHandles');
|
var ReactIOSTagHandles = require('ReactIOSTagHandles');
|
||||||
|
var ReactInstanceMap = require('ReactInstanceMap');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ReactNative vs ReactWeb
|
* ReactNative vs ReactWeb
|
||||||
@ -55,11 +56,17 @@ var ReactIOSComponentMixin = {
|
|||||||
* `getNodeHandle`.
|
* `getNodeHandle`.
|
||||||
*/
|
*/
|
||||||
getNativeNode: function() {
|
getNativeNode: function() {
|
||||||
return ReactIOSTagHandles.rootNodeIDToTag[this._rootNodeID];
|
// TODO (balpert): Wrap iOS native components in a composite wrapper, then
|
||||||
|
// ReactInstanceMap.get here will always succeed
|
||||||
|
return ReactIOSTagHandles.rootNodeIDToTag[
|
||||||
|
(ReactInstanceMap.get(this) || this)._rootNodeID
|
||||||
|
];
|
||||||
},
|
},
|
||||||
|
|
||||||
getNodeHandle: function() {
|
getNodeHandle: function() {
|
||||||
return ReactIOSTagHandles.rootNodeIDToTag[this._rootNodeID];
|
return ReactIOSTagHandles.rootNodeIDToTag[
|
||||||
|
(ReactInstanceMap.get(this) || this)._rootNodeID
|
||||||
|
];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -15,20 +15,19 @@ var EventPluginUtils = require('EventPluginUtils');
|
|||||||
var IOSDefaultEventPluginOrder = require('IOSDefaultEventPluginOrder');
|
var IOSDefaultEventPluginOrder = require('IOSDefaultEventPluginOrder');
|
||||||
var IOSNativeBridgeEventPlugin = require('IOSNativeBridgeEventPlugin');
|
var IOSNativeBridgeEventPlugin = require('IOSNativeBridgeEventPlugin');
|
||||||
var NodeHandle = require('NodeHandle');
|
var NodeHandle = require('NodeHandle');
|
||||||
var ReactComponent = require('ReactComponent');
|
var ReactClass = require('ReactClass');
|
||||||
var ReactCompositeComponent = require('ReactCompositeComponent');
|
var ReactComponentEnvironment = require('ReactComponentEnvironment');
|
||||||
var ReactDefaultBatchingStrategy = require('ReactDefaultBatchingStrategy');
|
var ReactDefaultBatchingStrategy = require('ReactDefaultBatchingStrategy');
|
||||||
var ReactElement = require('ReactElement');
|
|
||||||
var ReactInstanceHandles = require('ReactInstanceHandles');
|
var ReactInstanceHandles = require('ReactInstanceHandles');
|
||||||
var ReactIOSComponentEnvironment = require('ReactIOSComponentEnvironment');
|
var ReactIOSComponentEnvironment = require('ReactIOSComponentEnvironment');
|
||||||
var ReactIOSComponentMixin = require('ReactIOSComponentMixin');
|
var ReactIOSComponentMixin = require('ReactIOSComponentMixin');
|
||||||
var ReactIOSGlobalInteractionHandler = require('ReactIOSGlobalInteractionHandler');
|
var ReactIOSGlobalInteractionHandler = require('ReactIOSGlobalInteractionHandler');
|
||||||
var ReactIOSGlobalResponderHandler = require('ReactIOSGlobalResponderHandler');
|
var ReactIOSGlobalResponderHandler = require('ReactIOSGlobalResponderHandler');
|
||||||
var ReactIOSMount = require('ReactIOSMount');
|
var ReactIOSMount = require('ReactIOSMount');
|
||||||
var ReactTextComponent = require('ReactTextComponent');
|
var ReactIOSTextComponent = require('ReactIOSTextComponent');
|
||||||
|
var ReactNativeComponent = require('ReactNativeComponent');
|
||||||
var ReactUpdates = require('ReactUpdates');
|
var ReactUpdates = require('ReactUpdates');
|
||||||
var ResponderEventPlugin = require('ResponderEventPlugin');
|
var ResponderEventPlugin = require('ResponderEventPlugin');
|
||||||
var RKRawText = require('RKRawText');
|
|
||||||
var UniversalWorkerNodeHandle = require('UniversalWorkerNodeHandle');
|
var UniversalWorkerNodeHandle = require('UniversalWorkerNodeHandle');
|
||||||
|
|
||||||
// Just to ensure this gets packaged, since its only caller is from Native.
|
// Just to ensure this gets packaged, since its only caller is from Native.
|
||||||
@ -68,23 +67,17 @@ function inject() {
|
|||||||
ReactDefaultBatchingStrategy
|
ReactDefaultBatchingStrategy
|
||||||
);
|
);
|
||||||
|
|
||||||
ReactComponent.injection.injectEnvironment(
|
ReactComponentEnvironment.injection.injectEnvironment(
|
||||||
ReactIOSComponentEnvironment
|
ReactIOSComponentEnvironment
|
||||||
);
|
);
|
||||||
|
|
||||||
EventPluginUtils.injection.injectMount(ReactIOSMount);
|
EventPluginUtils.injection.injectMount(ReactIOSMount);
|
||||||
|
|
||||||
ReactCompositeComponent.injection.injectMixin(ReactIOSComponentMixin);
|
ReactClass.injection.injectMixin(ReactIOSComponentMixin);
|
||||||
|
|
||||||
ReactTextComponent.inject(function(initialText) {
|
ReactNativeComponent.injection.injectTextComponentClass(
|
||||||
// RKRawText is a class so we can't invoke it directly. Instead of using
|
ReactIOSTextComponent
|
||||||
// a factory, we use the internal fast path to create a descriptor.
|
);
|
||||||
// RKRawText is not quite a class yet, so we access the real class from
|
|
||||||
// the type property. TODO: Change this once factory wrappers are gone.
|
|
||||||
return new ReactElement(RKRawText.type, null, null, null, null, {
|
|
||||||
text: initialText
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
NodeHandle.injection.injectImplementation(UniversalWorkerNodeHandle);
|
NodeHandle.injection.injectImplementation(UniversalWorkerNodeHandle);
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,10 @@ var RKUIManager = require('NativeModulesDeprecated').RKUIManager;
|
|||||||
|
|
||||||
var ReactIOSTagHandles = require('ReactIOSTagHandles');
|
var ReactIOSTagHandles = require('ReactIOSTagHandles');
|
||||||
var ReactPerf = require('ReactPerf');
|
var ReactPerf = require('ReactPerf');
|
||||||
|
var ReactReconciler = require('ReactReconciler');
|
||||||
|
var ReactUpdates = require('ReactUpdates');
|
||||||
|
|
||||||
|
var emptyObject = require('emptyObject');
|
||||||
var instantiateReactComponent = require('instantiateReactComponent');
|
var instantiateReactComponent = require('instantiateReactComponent');
|
||||||
var invariant = require('invariant');
|
var invariant = require('invariant');
|
||||||
|
|
||||||
@ -19,6 +22,49 @@ function instanceNumberToChildRootID(rootNodeID, instanceNumber) {
|
|||||||
return rootNodeID + '[' + instanceNumber + ']';
|
return rootNodeID + '[' + instanceNumber + ']';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mounts this component and inserts it into the DOM.
|
||||||
|
*
|
||||||
|
* @param {ReactComponent} componentInstance The instance to mount.
|
||||||
|
* @param {number} rootID ID of the root node.
|
||||||
|
* @param {number} container container element to mount into.
|
||||||
|
* @param {ReactReconcileTransaction} transaction
|
||||||
|
*/
|
||||||
|
function mountComponentIntoNode(
|
||||||
|
componentInstance,
|
||||||
|
rootID,
|
||||||
|
container,
|
||||||
|
transaction) {
|
||||||
|
var markup = ReactReconciler.mountComponent(
|
||||||
|
componentInstance, rootID, transaction, emptyObject
|
||||||
|
);
|
||||||
|
componentInstance._isTopLevel = true;
|
||||||
|
ReactIOSMount._mountImageIntoNode(markup, container);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Batched mount.
|
||||||
|
*
|
||||||
|
* @param {ReactComponent} componentInstance The instance to mount.
|
||||||
|
* @param {number} rootID ID of the root node.
|
||||||
|
* @param {number} container container element to mount into.
|
||||||
|
*/
|
||||||
|
function batchedMountComponentIntoNode(
|
||||||
|
componentInstance,
|
||||||
|
rootID,
|
||||||
|
container) {
|
||||||
|
var transaction = ReactUpdates.ReactReconcileTransaction.getPooled();
|
||||||
|
transaction.perform(
|
||||||
|
mountComponentIntoNode,
|
||||||
|
null,
|
||||||
|
componentInstance,
|
||||||
|
rootID,
|
||||||
|
container,
|
||||||
|
transaction
|
||||||
|
);
|
||||||
|
ReactUpdates.ReactReconcileTransaction.release(transaction);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* As soon as `ReactMount` is refactored to not rely on the DOM, we can share
|
* As soon as `ReactMount` is refactored to not rely on the DOM, we can share
|
||||||
* code between the two. For now, we'll hard code the ID logic.
|
* code between the two. For now, we'll hard code the ID logic.
|
||||||
@ -52,9 +98,47 @@ var ReactIOSMount = {
|
|||||||
ReactIOSMount.instanceCount++
|
ReactIOSMount.instanceCount++
|
||||||
);
|
);
|
||||||
ReactIOSMount._instancesByContainerID[topRootNodeID] = instance;
|
ReactIOSMount._instancesByContainerID[topRootNodeID] = instance;
|
||||||
instance.mountComponentIntoNode(childRootNodeID, topRootNodeID);
|
|
||||||
|
// The initial render is synchronous but any updates that happen during
|
||||||
|
// rendering, in componentWillMount or componentDidMount, will be batched
|
||||||
|
// according to the current batching strategy.
|
||||||
|
|
||||||
|
ReactUpdates.batchedUpdates(
|
||||||
|
batchedMountComponentIntoNode,
|
||||||
|
instance,
|
||||||
|
childRootNodeID,
|
||||||
|
topRootNodeID
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {View} view View tree image.
|
||||||
|
* @param {number} containerViewID View to insert sub-view into.
|
||||||
|
*/
|
||||||
|
_mountImageIntoNode: ReactPerf.measure(
|
||||||
|
// FIXME(frantic): #4441289 Hack to avoid modifying react-tools
|
||||||
|
'ReactComponentBrowserEnvironment',
|
||||||
|
'mountImageIntoNode',
|
||||||
|
function(mountImage, containerID) {
|
||||||
|
// Since we now know that the `mountImage` has been mounted, we can
|
||||||
|
// mark it as such.
|
||||||
|
ReactIOSTagHandles.associateRootNodeIDWithMountedNodeHandle(
|
||||||
|
mountImage.rootNodeID,
|
||||||
|
mountImage.tag
|
||||||
|
);
|
||||||
|
var addChildTags = [mountImage.tag];
|
||||||
|
var addAtIndices = [0];
|
||||||
|
RKUIManager.manageChildren(
|
||||||
|
ReactIOSTagHandles.mostRecentMountedNodeHandleForRootNodeID(containerID),
|
||||||
|
null, // moveFromIndices
|
||||||
|
null, // moveToIndices
|
||||||
|
addChildTags,
|
||||||
|
addAtIndices,
|
||||||
|
null // removeAtIndices
|
||||||
|
);
|
||||||
|
}
|
||||||
|
),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Standard unmounting of the component that is rendered into `containerID`,
|
* Standard unmounting of the component that is rendered into `containerID`,
|
||||||
* but will also execute a command to remove the actual container view
|
* but will also execute a command to remove the actual container view
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var NativeMethodsMixin = require('NativeMethodsMixin');
|
var NativeMethodsMixin = require('NativeMethodsMixin');
|
||||||
var ReactComponent = require('ReactComponent');
|
|
||||||
var ReactIOSComponentMixin = require('ReactIOSComponentMixin');
|
var ReactIOSComponentMixin = require('ReactIOSComponentMixin');
|
||||||
var ReactIOSEventEmitter = require('ReactIOSEventEmitter');
|
var ReactIOSEventEmitter = require('ReactIOSEventEmitter');
|
||||||
var ReactIOSStyleAttributes = require('ReactIOSStyleAttributes');
|
var ReactIOSStyleAttributes = require('ReactIOSStyleAttributes');
|
||||||
@ -32,8 +31,6 @@ var deleteAllListeners = ReactIOSEventEmitter.deleteAllListeners;
|
|||||||
*/
|
*/
|
||||||
var ReactIOSNativeComponent = function(viewConfig) {
|
var ReactIOSNativeComponent = function(viewConfig) {
|
||||||
this.viewConfig = viewConfig;
|
this.viewConfig = viewConfig;
|
||||||
this.props = null;
|
|
||||||
this.previousFlattenedStyle = null;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -65,10 +62,19 @@ cachedIndexArray._cache = {};
|
|||||||
* which is a `viewID` ... see the return value for `mountComponent` !
|
* which is a `viewID` ... see the return value for `mountComponent` !
|
||||||
*/
|
*/
|
||||||
ReactIOSNativeComponent.Mixin = {
|
ReactIOSNativeComponent.Mixin = {
|
||||||
|
getPublicInstance: function() {
|
||||||
|
// TODO: This should probably use a composite wrapper
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
construct: function(element) {
|
||||||
|
this._currentElement = element;
|
||||||
|
},
|
||||||
|
|
||||||
unmountComponent: function() {
|
unmountComponent: function() {
|
||||||
deleteAllListeners(this._rootNodeID);
|
deleteAllListeners(this._rootNodeID);
|
||||||
ReactComponent.Mixin.unmountComponent.call(this);
|
|
||||||
this.unmountChildren();
|
this.unmountChildren();
|
||||||
|
this._rootNodeID = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -79,8 +85,8 @@ ReactIOSNativeComponent.Mixin = {
|
|||||||
* a child of a container can confidently record that in
|
* a child of a container can confidently record that in
|
||||||
* `ReactIOSTagHandles`.
|
* `ReactIOSTagHandles`.
|
||||||
*/
|
*/
|
||||||
initializeChildren: function(children, containerTag, transaction) {
|
initializeChildren: function(children, containerTag, transaction, context) {
|
||||||
var mountImages = this.mountChildren(children, transaction);
|
var mountImages = this.mountChildren(children, transaction, context);
|
||||||
// In a well balanced tree, half of the nodes are in the bottom row and have
|
// In a well balanced tree, half of the nodes are in the bottom row and have
|
||||||
// no children - let's avoid calling out to the native bridge for a large
|
// no children - let's avoid calling out to the native bridge for a large
|
||||||
// portion of the children.
|
// portion of the children.
|
||||||
@ -158,21 +164,18 @@ ReactIOSNativeComponent.Mixin = {
|
|||||||
/**
|
/**
|
||||||
* Updates the component's currently mounted representation.
|
* Updates the component's currently mounted representation.
|
||||||
*
|
*
|
||||||
|
* @param {object} nextElement
|
||||||
* @param {ReactReconcileTransaction} transaction
|
* @param {ReactReconcileTransaction} transaction
|
||||||
* @param {object} prevDescriptor
|
* @param {object} context
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
updateComponent: function(transaction, prevDescriptor) {
|
receiveComponent: function(nextElement, transaction, context) {
|
||||||
ReactComponent.Mixin.updateComponent.call(
|
var prevElement = this._currentElement;
|
||||||
this,
|
this._currentElement = nextElement;
|
||||||
transaction,
|
|
||||||
prevDescriptor
|
|
||||||
);
|
|
||||||
var nextDescriptor = this._currentElement;
|
|
||||||
|
|
||||||
var updatePayload = this.computeUpdatedProperties(
|
var updatePayload = this.computeUpdatedProperties(
|
||||||
prevDescriptor.props,
|
prevElement.props,
|
||||||
nextDescriptor.props,
|
nextElement.props,
|
||||||
this.viewConfig.validAttributes
|
this.viewConfig.validAttributes
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -185,10 +188,10 @@ ReactIOSNativeComponent.Mixin = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._reconcileListenersUponUpdate(
|
this._reconcileListenersUponUpdate(
|
||||||
prevDescriptor.props,
|
prevElement.props,
|
||||||
nextDescriptor.props
|
nextElement.props
|
||||||
);
|
);
|
||||||
this.updateChildren(this.props.children, transaction);
|
this.updateChildren(nextElement.props.children, transaction, context);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -223,25 +226,26 @@ ReactIOSNativeComponent.Mixin = {
|
|||||||
* @param {Transaction} transaction For creating/updating.
|
* @param {Transaction} transaction For creating/updating.
|
||||||
* @return {string} Unique iOS view tag.
|
* @return {string} Unique iOS view tag.
|
||||||
*/
|
*/
|
||||||
mountComponent: function(rootID, transaction, mountDepth) {
|
mountComponent: function(rootID, transaction, context) {
|
||||||
ReactComponent.Mixin.mountComponent.call(
|
this._rootNodeID = rootID;
|
||||||
this,
|
|
||||||
rootID,
|
|
||||||
transaction,
|
|
||||||
mountDepth
|
|
||||||
);
|
|
||||||
var tag = ReactIOSTagHandles.allocateTag();
|
var tag = ReactIOSTagHandles.allocateTag();
|
||||||
|
|
||||||
this.previousFlattenedStyle = {};
|
this.previousFlattenedStyle = {};
|
||||||
var updatePayload = this.computeUpdatedProperties(
|
var updatePayload = this.computeUpdatedProperties(
|
||||||
{}, // previous props
|
{}, // previous props
|
||||||
this.props, // next props
|
this._currentElement.props, // next props
|
||||||
this.viewConfig.validAttributes
|
this.viewConfig.validAttributes
|
||||||
);
|
);
|
||||||
RKUIManager.createView(tag, this.viewConfig.uiViewClassName, updatePayload);
|
RKUIManager.createView(tag, this.viewConfig.uiViewClassName, updatePayload);
|
||||||
|
|
||||||
this._registerListenersUponCreation(this.props);
|
this._registerListenersUponCreation(this._currentElement.props);
|
||||||
this.initializeChildren(this.props.children, tag, transaction);
|
this.initializeChildren(
|
||||||
|
this._currentElement.props.children,
|
||||||
|
tag,
|
||||||
|
transaction,
|
||||||
|
context
|
||||||
|
);
|
||||||
return {
|
return {
|
||||||
rootNodeID: rootID,
|
rootNodeID: rootID,
|
||||||
tag: tag
|
tag: tag
|
||||||
@ -255,7 +259,6 @@ ReactIOSNativeComponent.Mixin = {
|
|||||||
*/
|
*/
|
||||||
Object.assign(
|
Object.assign(
|
||||||
ReactIOSNativeComponent.prototype,
|
ReactIOSNativeComponent.prototype,
|
||||||
ReactComponent.Mixin,
|
|
||||||
ReactMultiChild.Mixin,
|
ReactMultiChild.Mixin,
|
||||||
ReactIOSNativeComponent.Mixin,
|
ReactIOSNativeComponent.Mixin,
|
||||||
NativeMethodsMixin,
|
NativeMethodsMixin,
|
||||||
|
62
Libraries/ReactIOS/ReactIOSTextComponent.js
Normal file
62
Libraries/ReactIOS/ReactIOSTextComponent.js
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* @providesModule ReactIOSTextComponent
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var ReactIOSTagHandles = require('ReactIOSTagHandles');
|
||||||
|
var RKUIManager = require('NativeModulesDeprecated').RKUIManager;
|
||||||
|
|
||||||
|
var assign = require('Object.assign');
|
||||||
|
|
||||||
|
var ReactIOSTextComponent = function(props) {
|
||||||
|
// This constructor and its argument is currently used by mocks.
|
||||||
|
};
|
||||||
|
|
||||||
|
assign(ReactIOSTextComponent.prototype, {
|
||||||
|
|
||||||
|
construct: function(text) {
|
||||||
|
// This is really a ReactText (ReactNode), not a ReactElement
|
||||||
|
this._currentElement = text;
|
||||||
|
this._stringText = '' + text;
|
||||||
|
this._rootNodeID = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
mountComponent: function(rootID, transaction, context) {
|
||||||
|
this._rootNodeID = rootID;
|
||||||
|
var tag = ReactIOSTagHandles.allocateTag();
|
||||||
|
RKUIManager.createView(tag, 'RCTRawText', {text: this._stringText});
|
||||||
|
return {
|
||||||
|
rootNodeID: rootID,
|
||||||
|
tag: tag,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
receiveComponent: function(nextText, transaction, context) {
|
||||||
|
if (nextText !== this._currentElement) {
|
||||||
|
this._currentElement = nextText;
|
||||||
|
var nextStringText = '' + nextText;
|
||||||
|
if (nextStringText !== this._stringText) {
|
||||||
|
this._stringText = nextStringText;
|
||||||
|
RKUIManager.updateView(
|
||||||
|
ReactIOSTagHandles.mostRecentMountedNodeHandleForRootNodeID(
|
||||||
|
this._rootNodeID
|
||||||
|
),
|
||||||
|
'RCTRawText',
|
||||||
|
{text: this._stringText}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
unmountComponent: function() {
|
||||||
|
this._currentElement = null;
|
||||||
|
this._stringText = null;
|
||||||
|
this._rootNodeID = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = ReactIOSTextComponent;
|
@ -1,30 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2004-present Facebook. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
* @providesModule ReactTextComponent
|
|
||||||
* @typechecks static-only
|
|
||||||
*/
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var InjectedTextComponent = null;
|
|
||||||
var ReactTextComponent = function() {
|
|
||||||
return InjectedTextComponent.apply(this, arguments);
|
|
||||||
};
|
|
||||||
ReactTextComponent.inject = function(textComponent) {
|
|
||||||
InjectedTextComponent = textComponent;
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = ReactTextComponent;
|
|
@ -7,7 +7,6 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var ReactElement = require('ReactElement');
|
var ReactElement = require('ReactElement');
|
||||||
var ReactLegacyElement = require('ReactLegacyElement');
|
|
||||||
var ReactIOSNativeComponent = require('ReactIOSNativeComponent');
|
var ReactIOSNativeComponent = require('ReactIOSNativeComponent');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -15,15 +14,17 @@ var ReactIOSNativeComponent = require('ReactIOSNativeComponent');
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
var createReactIOSNativeComponentClass = function(viewConfig) {
|
var createReactIOSNativeComponentClass = function(viewConfig) {
|
||||||
var Constructor = function(props) {
|
var Constructor = function(element) {
|
||||||
|
this._currentElement = element;
|
||||||
|
|
||||||
|
this._rootNodeID = null;
|
||||||
|
this._renderedChildren = null;
|
||||||
|
this.previousFlattenedStyle = null;
|
||||||
};
|
};
|
||||||
Constructor.displayName = viewConfig.uiViewClassName;
|
Constructor.displayName = viewConfig.uiViewClassName;
|
||||||
Constructor.prototype = new ReactIOSNativeComponent(viewConfig);
|
Constructor.prototype = new ReactIOSNativeComponent(viewConfig);
|
||||||
Constructor.prototype.constructor = Constructor;
|
|
||||||
|
|
||||||
return ReactLegacyElement.wrapFactory(
|
return Constructor;
|
||||||
ReactElement.createFactory(Constructor)
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = createReactIOSNativeComponentClass;
|
module.exports = createReactIOSNativeComponentClass;
|
||||||
|
53
Libraries/vendor/core/copyProperties.js
vendored
Normal file
53
Libraries/vendor/core/copyProperties.js
vendored
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* @generated SignedSource<<e8e5ba644b047d0654ca54a100d2f0f3>>
|
||||||
|
*
|
||||||
|
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
* !! This file is a check-in of a static_upstream project! !!
|
||||||
|
* !! !!
|
||||||
|
* !! You should not modify this file directly. Instead: !!
|
||||||
|
* !! 1) Use `fjs use-upstream` to temporarily replace this with !!
|
||||||
|
* !! the latest version from upstream. !!
|
||||||
|
* !! 2) Make your changes, test them, etc. !!
|
||||||
|
* !! 3) Use `fjs push-upstream` to copy your changes back to !!
|
||||||
|
* !! static_upstream. !!
|
||||||
|
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
*
|
||||||
|
* @providesModule copyProperties
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy properties from one or more objects (up to 5) into the first object.
|
||||||
|
* This is a shallow copy. It mutates the first object and also returns it.
|
||||||
|
*
|
||||||
|
* NOTE: `arguments` has a very significant performance penalty, which is why
|
||||||
|
* we don't support unlimited arguments.
|
||||||
|
*/
|
||||||
|
function copyProperties(obj, a, b, c, d, e, f) {
|
||||||
|
obj = obj || {};
|
||||||
|
|
||||||
|
if (__DEV__) {
|
||||||
|
if (f) {
|
||||||
|
throw new Error('Too many arguments passed to copyProperties');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var args = [a, b, c, d, e];
|
||||||
|
var ii = 0, v;
|
||||||
|
while (args[ii]) {
|
||||||
|
v = args[ii++];
|
||||||
|
for (var k in v) {
|
||||||
|
obj[k] = v[k];
|
||||||
|
}
|
||||||
|
|
||||||
|
// IE ignores toString in object iteration.. See:
|
||||||
|
// webreflection.blogspot.com/2007/07/quick-fix-internet-explorer-and.html
|
||||||
|
if (v.hasOwnProperty && v.hasOwnProperty('toString') &&
|
||||||
|
(typeof v.toString != 'undefined') && (obj.toString !== v.toString)) {
|
||||||
|
obj.toString = v.toString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = copyProperties;
|
160
Libraries/vendor/core/mergeHelpers.js
vendored
Normal file
160
Libraries/vendor/core/mergeHelpers.js
vendored
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
/**
|
||||||
|
* @generated SignedSource<<b68d78236d45828b3f7f7fcc740782a9>>
|
||||||
|
*
|
||||||
|
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
* !! This file is a check-in of a static_upstream project! !!
|
||||||
|
* !! !!
|
||||||
|
* !! You should not modify this file directly. Instead: !!
|
||||||
|
* !! 1) Use `fjs use-upstream` to temporarily replace this with !!
|
||||||
|
* !! the latest version from upstream. !!
|
||||||
|
* !! 2) Make your changes, test them, etc. !!
|
||||||
|
* !! 3) Use `fjs push-upstream` to copy your changes back to !!
|
||||||
|
* !! static_upstream. !!
|
||||||
|
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
|
*
|
||||||
|
* Copyright 2013-2014 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* @providesModule mergeHelpers
|
||||||
|
*
|
||||||
|
* requiresPolyfills: Array.isArray
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var invariant = require('invariant');
|
||||||
|
var keyMirror = require('keyMirror');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum number of levels to traverse. Will catch circular structures.
|
||||||
|
* @const
|
||||||
|
*/
|
||||||
|
var MAX_MERGE_DEPTH = 36;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We won't worry about edge cases like new String('x') or new Boolean(true).
|
||||||
|
* Functions are considered terminals, and arrays are not.
|
||||||
|
* @param {*} o The item/object/value to test.
|
||||||
|
* @return {boolean} true iff the argument is a terminal.
|
||||||
|
*/
|
||||||
|
var isTerminal = function(o) {
|
||||||
|
return typeof o !== 'object' || o === null;
|
||||||
|
};
|
||||||
|
|
||||||
|
var mergeHelpers = {
|
||||||
|
|
||||||
|
MAX_MERGE_DEPTH: MAX_MERGE_DEPTH,
|
||||||
|
|
||||||
|
isTerminal: isTerminal,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts null/undefined values into empty object.
|
||||||
|
*
|
||||||
|
* @param {?Object=} arg Argument to be normalized (nullable optional)
|
||||||
|
* @return {!Object}
|
||||||
|
*/
|
||||||
|
normalizeMergeArg: function(arg) {
|
||||||
|
return arg === undefined || arg === null ? {} : arg;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If merging Arrays, a merge strategy *must* be supplied. If not, it is
|
||||||
|
* likely the caller's fault. If this function is ever called with anything
|
||||||
|
* but `one` and `two` being `Array`s, it is the fault of the merge utilities.
|
||||||
|
*
|
||||||
|
* @param {*} one Array to merge into.
|
||||||
|
* @param {*} two Array to merge from.
|
||||||
|
*/
|
||||||
|
checkMergeArrayArgs: function(one, two) {
|
||||||
|
invariant(
|
||||||
|
Array.isArray(one) && Array.isArray(two),
|
||||||
|
'Tried to merge arrays, instead got %s and %s.',
|
||||||
|
one,
|
||||||
|
two
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {*} one Object to merge into.
|
||||||
|
* @param {*} two Object to merge from.
|
||||||
|
*/
|
||||||
|
checkMergeObjectArgs: function(one, two) {
|
||||||
|
mergeHelpers.checkMergeObjectArg(one);
|
||||||
|
mergeHelpers.checkMergeObjectArg(two);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {*} arg
|
||||||
|
*/
|
||||||
|
checkMergeObjectArg: function(arg) {
|
||||||
|
invariant(
|
||||||
|
!isTerminal(arg) && !Array.isArray(arg),
|
||||||
|
'Tried to merge an object, instead got %s.',
|
||||||
|
arg
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {*} arg
|
||||||
|
*/
|
||||||
|
checkMergeIntoObjectArg: function(arg) {
|
||||||
|
invariant(
|
||||||
|
(!isTerminal(arg) || typeof arg === 'function') && !Array.isArray(arg),
|
||||||
|
'Tried to merge into an object, instead got %s.',
|
||||||
|
arg
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks that a merge was not given a circular object or an object that had
|
||||||
|
* too great of depth.
|
||||||
|
*
|
||||||
|
* @param {number} Level of recursion to validate against maximum.
|
||||||
|
*/
|
||||||
|
checkMergeLevel: function(level) {
|
||||||
|
invariant(
|
||||||
|
level < MAX_MERGE_DEPTH,
|
||||||
|
'Maximum deep merge depth exceeded. You may be attempting to merge ' +
|
||||||
|
'circular structures in an unsupported way.'
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks that the supplied merge strategy is valid.
|
||||||
|
*
|
||||||
|
* @param {string} Array merge strategy.
|
||||||
|
*/
|
||||||
|
checkArrayStrategy: function(strategy) {
|
||||||
|
invariant(
|
||||||
|
strategy === undefined || strategy in mergeHelpers.ArrayStrategies,
|
||||||
|
'You must provide an array strategy to deep merge functions to ' +
|
||||||
|
'instruct the deep merge how to resolve merging two arrays.'
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set of possible behaviors of merge algorithms when encountering two Arrays
|
||||||
|
* that must be merged together.
|
||||||
|
* - `clobber`: The left `Array` is ignored.
|
||||||
|
* - `indexByIndex`: The result is achieved by recursively deep merging at
|
||||||
|
* each index. (not yet supported.)
|
||||||
|
*/
|
||||||
|
ArrayStrategies: keyMirror({
|
||||||
|
Clobber: true,
|
||||||
|
IndexByIndex: true
|
||||||
|
})
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = mergeHelpers;
|
10
package.json
10
package.json
@ -28,19 +28,19 @@
|
|||||||
"absolute-path": "0.0.0",
|
"absolute-path": "0.0.0",
|
||||||
"connect": "2.8.3",
|
"connect": "2.8.3",
|
||||||
"debug": "~2.1.0",
|
"debug": "~2.1.0",
|
||||||
"jstransform": "8.2.0",
|
"joi": "~5.1.0",
|
||||||
|
"jstransform": "10.0.1",
|
||||||
"module-deps": "3.5.6",
|
"module-deps": "3.5.6",
|
||||||
"optimist": "0.6.1",
|
"optimist": "0.6.1",
|
||||||
"q": "1.0.1",
|
"q": "1.0.1",
|
||||||
"react-tools": "0.12.2",
|
"react-tools": "0.13.0-rc2",
|
||||||
"sane": "1.0.1",
|
"sane": "1.0.1",
|
||||||
"source-map": "0.1.31",
|
"source-map": "0.1.31",
|
||||||
"stacktrace-parser": "0.1.1",
|
"stacktrace-parser": "0.1.1",
|
||||||
|
"uglify-js": "~2.4.16",
|
||||||
"underscore": "1.7.0",
|
"underscore": "1.7.0",
|
||||||
"worker-farm": "1.1.0",
|
"worker-farm": "1.1.0",
|
||||||
"yargs": "1.3.2",
|
"yargs": "1.3.2"
|
||||||
"joi": "~5.1.0",
|
|
||||||
"uglify-js": "~2.4.16"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"jest-cli": "0.2.1",
|
"jest-cli": "0.2.1",
|
||||||
|
@ -22,7 +22,6 @@ var webBlacklist = [
|
|||||||
var iosBlacklist = [
|
var iosBlacklist = [
|
||||||
'node_modules/react-tools/src/browser/ui/React.js',
|
'node_modules/react-tools/src/browser/ui/React.js',
|
||||||
'node_modules/react-tools/src/browser/eventPlugins/ResponderEventPlugin.js',
|
'node_modules/react-tools/src/browser/eventPlugins/ResponderEventPlugin.js',
|
||||||
'node_modules/react-tools/src/browser/ReactTextComponent.js',
|
|
||||||
// 'node_modules/react-tools/src/vendor/core/ExecutionEnvironment.js',
|
// 'node_modules/react-tools/src/vendor/core/ExecutionEnvironment.js',
|
||||||
'.web.js',
|
'.web.js',
|
||||||
'.android.js',
|
'.android.js',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user