react 15.0.0 → 15.0.2-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,196 @@
1
+ /**
2
+ * Copyright (c) 2015-present, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree. An additional grant
7
+ * of patent rights can be found in the PATENTS file in the same directory.
8
+ *
9
+ * @providesModule ReactNativeBaseComponent
10
+ *
11
+ */
12
+ 'use strict';
13
+
14
+ var _assign = require('object-assign');
15
+
16
+ var NativeMethodsMixin = require('./NativeMethodsMixin');
17
+ var ReactNativeAttributePayload = require('./ReactNativeAttributePayload');
18
+ var ReactNativeComponentTree = require('./ReactNativeComponentTree');
19
+ var ReactNativeEventEmitter = require('./ReactNativeEventEmitter');
20
+ var ReactNativeTagHandles = require('./ReactNativeTagHandles');
21
+ var ReactMultiChild = require('./ReactMultiChild');
22
+ var UIManager = require('UIManager');
23
+
24
+ var deepFreezeAndThrowOnMutationInDev = require('deepFreezeAndThrowOnMutationInDev');
25
+
26
+ var registrationNames = ReactNativeEventEmitter.registrationNames;
27
+ var putListener = ReactNativeEventEmitter.putListener;
28
+ var deleteListener = ReactNativeEventEmitter.deleteListener;
29
+ var deleteAllListeners = ReactNativeEventEmitter.deleteAllListeners;
30
+
31
+ // require('UIManagerStatTracker').install(); // uncomment to enable
32
+
33
+ /**
34
+ * @constructor ReactNativeBaseComponent
35
+ * @extends ReactComponent
36
+ * @extends ReactMultiChild
37
+ * @param {!object} UIKit View Configuration.
38
+ */
39
+ var ReactNativeBaseComponent = function (viewConfig) {
40
+ this.viewConfig = viewConfig;
41
+ };
42
+
43
+ /**
44
+ * Mixin for containers that contain UIViews. NOTE: markup is rendered markup
45
+ * which is a `viewID` ... see the return value for `mountComponent` !
46
+ */
47
+ ReactNativeBaseComponent.Mixin = {
48
+ getPublicInstance: function () {
49
+ // TODO: This should probably use a composite wrapper
50
+ return this;
51
+ },
52
+
53
+ unmountComponent: function () {
54
+ ReactNativeComponentTree.uncacheNode(this);
55
+ deleteAllListeners(this);
56
+ this.unmountChildren();
57
+ this._rootNodeID = null;
58
+ },
59
+
60
+ /**
61
+ * Every native component is responsible for allocating its own `tag`, and
62
+ * issuing the native `createView` command. But it is not responsible for
63
+ * recording the fact that its own `rootNodeID` is associated with a
64
+ * `nodeHandle`. Only the code that actually adds its `nodeHandle` (`tag`) as
65
+ * a child of a container can confidently record that in
66
+ * `ReactNativeTagHandles`.
67
+ */
68
+ initializeChildren: function (children, containerTag, transaction, context) {
69
+ var mountImages = this.mountChildren(children, transaction, context);
70
+ // In a well balanced tree, half of the nodes are in the bottom row and have
71
+ // no children - let's avoid calling out to the native bridge for a large
72
+ // portion of the children.
73
+ if (mountImages.length) {
74
+
75
+ // TODO: Pool these per platform view class. Reusing the `mountImages`
76
+ // array would likely be a jit deopt.
77
+ var createdTags = [];
78
+ for (var i = 0, l = mountImages.length; i < l; i++) {
79
+ var mountImage = mountImages[i];
80
+ var childTag = mountImage;
81
+ createdTags[i] = childTag;
82
+ }
83
+ UIManager.setChildren(containerTag, createdTags);
84
+ }
85
+ },
86
+
87
+ /**
88
+ * Updates the component's currently mounted representation.
89
+ *
90
+ * @param {object} nextElement
91
+ * @param {ReactReconcileTransaction} transaction
92
+ * @param {object} context
93
+ * @internal
94
+ */
95
+ receiveComponent: function (nextElement, transaction, context) {
96
+ var prevElement = this._currentElement;
97
+ this._currentElement = nextElement;
98
+
99
+ if (process.env.NODE_ENV !== 'production') {
100
+ for (var key in this.viewConfig.validAttributes) {
101
+ if (nextElement.props.hasOwnProperty(key)) {
102
+ deepFreezeAndThrowOnMutationInDev(nextElement.props[key]);
103
+ }
104
+ }
105
+ }
106
+
107
+ var updatePayload = ReactNativeAttributePayload.diff(prevElement.props, nextElement.props, this.viewConfig.validAttributes);
108
+
109
+ if (updatePayload) {
110
+ UIManager.updateView(this._rootNodeID, this.viewConfig.uiViewClassName, updatePayload);
111
+ }
112
+
113
+ this._reconcileListenersUponUpdate(prevElement.props, nextElement.props);
114
+ this.updateChildren(nextElement.props.children, transaction, context);
115
+ },
116
+
117
+ /**
118
+ * @param {object} initialProps Native component props.
119
+ */
120
+ _registerListenersUponCreation: function (initialProps) {
121
+ for (var key in initialProps) {
122
+ // NOTE: The check for `!props[key]`, is only possible because this method
123
+ // registers listeners the *first* time a component is created.
124
+ if (registrationNames[key] && initialProps[key]) {
125
+ var listener = initialProps[key];
126
+ putListener(this, key, listener);
127
+ }
128
+ }
129
+ },
130
+
131
+ /**
132
+ * Reconciles event listeners, adding or removing if necessary.
133
+ * @param {object} prevProps Native component props including events.
134
+ * @param {object} nextProps Next native component props including events.
135
+ */
136
+ _reconcileListenersUponUpdate: function (prevProps, nextProps) {
137
+ for (var key in nextProps) {
138
+ if (registrationNames[key] && nextProps[key] !== prevProps[key]) {
139
+ if (nextProps[key]) {
140
+ putListener(this, key, nextProps[key]);
141
+ } else {
142
+ deleteListener(this, key);
143
+ }
144
+ }
145
+ }
146
+ },
147
+
148
+ /**
149
+ * Currently this still uses IDs for reconciliation so this can return null.
150
+ *
151
+ * @return {null} Null.
152
+ */
153
+ getNativeNode: function () {
154
+ return this._rootNodeID;
155
+ },
156
+
157
+ /**
158
+ * @param {string} rootID Root ID of this subtree.
159
+ * @param {Transaction} transaction For creating/updating.
160
+ * @return {string} Unique iOS view tag.
161
+ */
162
+ mountComponent: function (transaction, nativeParent, nativeContainerInfo, context) {
163
+ var tag = ReactNativeTagHandles.allocateTag();
164
+
165
+ this._rootNodeID = tag;
166
+ this._nativeParent = nativeParent;
167
+ this._nativeContainerInfo = nativeContainerInfo;
168
+
169
+ if (process.env.NODE_ENV !== 'production') {
170
+ for (var key in this.viewConfig.validAttributes) {
171
+ if (this._currentElement.props.hasOwnProperty(key)) {
172
+ deepFreezeAndThrowOnMutationInDev(this._currentElement.props[key]);
173
+ }
174
+ }
175
+ }
176
+
177
+ var updatePayload = ReactNativeAttributePayload.create(this._currentElement.props, this.viewConfig.validAttributes);
178
+
179
+ var nativeTopRootTag = nativeContainerInfo._tag;
180
+ UIManager.createView(tag, this.viewConfig.uiViewClassName, nativeTopRootTag, updatePayload);
181
+
182
+ ReactNativeComponentTree.precacheNode(this, tag);
183
+
184
+ this._registerListenersUponCreation(this._currentElement.props);
185
+ this.initializeChildren(this._currentElement.props.children, tag, transaction, context);
186
+ return tag;
187
+ }
188
+ };
189
+
190
+ /**
191
+ * Order of mixins is important. ReactNativeBaseComponent overrides methods in
192
+ * ReactMultiChild.
193
+ */
194
+ _assign(ReactNativeBaseComponent.prototype, ReactMultiChild.Mixin, ReactNativeBaseComponent.Mixin, NativeMethodsMixin);
195
+
196
+ module.exports = ReactNativeBaseComponent;
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Copyright (c) 2015-present, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree. An additional grant
7
+ * of patent rights can be found in the PATENTS file in the same directory.
8
+ *
9
+ * @providesModule ReactNativeComponentEnvironment
10
+ *
11
+ */
12
+ 'use strict';
13
+
14
+ var ReactNativeDOMIDOperations = require('./ReactNativeDOMIDOperations');
15
+ var ReactNativeReconcileTransaction = require('./ReactNativeReconcileTransaction');
16
+
17
+ var ReactNativeComponentEnvironment = {
18
+
19
+ processChildrenUpdates: ReactNativeDOMIDOperations.dangerouslyProcessChildrenUpdates,
20
+
21
+ replaceNodeWithMarkup: ReactNativeDOMIDOperations.dangerouslyReplaceNodeWithMarkupByID,
22
+
23
+ /**
24
+ * Nothing to do for UIKit bridge.
25
+ *
26
+ * @private
27
+ */
28
+ unmountIDFromEnvironment: function () /*rootNodeID*/{},
29
+
30
+ /**
31
+ * @param {DOMElement} Element to clear.
32
+ */
33
+ clearNode: function () /*containerView*/{},
34
+
35
+ ReactReconcileTransaction: ReactNativeReconcileTransaction
36
+ };
37
+
38
+ module.exports = ReactNativeComponentEnvironment;
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Copyright 2013-present, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree. An additional grant
7
+ * of patent rights can be found in the PATENTS file in the same directory.
8
+ *
9
+ * @providesModule ReactNativeComponentTree
10
+ */
11
+
12
+ 'use strict';
13
+
14
+ var invariant = require('fbjs/lib/invariant');
15
+
16
+ var instanceCache = {};
17
+
18
+ /**
19
+ * Drill down (through composites and empty components) until we get a native or
20
+ * native text component.
21
+ *
22
+ * This is pretty polymorphic but unavoidable with the current structure we have
23
+ * for `_renderedChildren`.
24
+ */
25
+ function getRenderedNativeOrTextFromComponent(component) {
26
+ var rendered;
27
+ while (rendered = component._renderedComponent) {
28
+ component = rendered;
29
+ }
30
+ return component;
31
+ }
32
+
33
+ /**
34
+ * Populate `_nativeNode` on the rendered native/text component with the given
35
+ * DOM node. The passed `inst` can be a composite.
36
+ */
37
+ function precacheNode(inst, tag) {
38
+ var nativeInst = getRenderedNativeOrTextFromComponent(inst);
39
+ instanceCache[tag] = nativeInst;
40
+ }
41
+
42
+ function uncacheNode(inst) {
43
+ var tag = inst._rootNodeID;
44
+ if (tag) {
45
+ delete instanceCache[tag];
46
+ }
47
+ }
48
+
49
+ function getInstanceFromTag(tag) {
50
+ return instanceCache[tag] || null;
51
+ }
52
+
53
+ function getTagFromInstance(inst) {
54
+ !inst._rootNodeID ? process.env.NODE_ENV !== 'production' ? invariant(false, 'All native instances should have a tag.') : invariant(false) : void 0;
55
+ return inst._rootNodeID;
56
+ }
57
+
58
+ var ReactNativeComponentTree = {
59
+ getClosestInstanceFromNode: getInstanceFromTag,
60
+ getInstanceFromNode: getInstanceFromTag,
61
+ getNodeFromInstance: getTagFromInstance,
62
+ precacheNode: precacheNode,
63
+ uncacheNode: uncacheNode
64
+ };
65
+
66
+ module.exports = ReactNativeComponentTree;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Copyright (c) 2015-present, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree. An additional grant
7
+ * of patent rights can be found in the PATENTS file in the same directory.
8
+ *
9
+ * @providesModule ReactNativeContainerInfo
10
+ *
11
+ */
12
+ 'use strict';
13
+
14
+ function ReactNativeContainerInfo(tag) {
15
+ var info = {
16
+ _tag: tag
17
+ };
18
+ return info;
19
+ }
20
+
21
+ module.exports = ReactNativeContainerInfo;
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Copyright (c) 2015-present, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree. An additional grant
7
+ * of patent rights can be found in the PATENTS file in the same directory.
8
+ *
9
+ * @providesModule ReactNativeDOMIDOperations
10
+ *
11
+ */
12
+ 'use strict';
13
+
14
+ var ReactNativeComponentTree = require('./ReactNativeComponentTree');
15
+ var ReactMultiChildUpdateTypes = require('./ReactMultiChildUpdateTypes');
16
+ var ReactPerf = require('./ReactPerf');
17
+ var UIManager = require('UIManager');
18
+
19
+ /**
20
+ * Updates a component's children by processing a series of updates.
21
+ * For each of the update/create commands, the `fromIndex` refers to the index
22
+ * that the item existed at *before* any of the updates are applied, and the
23
+ * `toIndex` refers to the index after *all* of the updates are applied
24
+ * (including deletes/moves). TODO: refactor so this can be shared with
25
+ * DOMChildrenOperations.
26
+ *
27
+ * @param {ReactNativeBaseComponent} updates List of update configurations.
28
+ * @param {array<string>} markup List of markup strings - in the case of React
29
+ * IOS, the ids of new components assumed to be already created.
30
+ */
31
+ var dangerouslyProcessChildrenUpdates = function (inst, childrenUpdates) {
32
+ if (!childrenUpdates.length) {
33
+ return;
34
+ }
35
+
36
+ var containerTag = ReactNativeComponentTree.getNodeFromInstance(inst);
37
+
38
+ var moveFromIndices;
39
+ var moveToIndices;
40
+ var addChildTags;
41
+ var addAtIndices;
42
+ var removeAtIndices;
43
+
44
+ for (var i = 0; i < childrenUpdates.length; i++) {
45
+ var update = childrenUpdates[i];
46
+ if (update.type === ReactMultiChildUpdateTypes.MOVE_EXISTING) {
47
+ (moveFromIndices || (moveFromIndices = [])).push(update.fromIndex);
48
+ (moveToIndices || (moveToIndices = [])).push(update.toIndex);
49
+ } else if (update.type === ReactMultiChildUpdateTypes.REMOVE_NODE) {
50
+ (removeAtIndices || (removeAtIndices = [])).push(update.fromIndex);
51
+ } else if (update.type === ReactMultiChildUpdateTypes.INSERT_MARKUP) {
52
+ var mountImage = update.content;
53
+ var tag = mountImage;
54
+ (addAtIndices || (addAtIndices = [])).push(update.toIndex);
55
+ (addChildTags || (addChildTags = [])).push(tag);
56
+ }
57
+ }
58
+
59
+ UIManager.manageChildren(containerTag, moveFromIndices, moveToIndices, addChildTags, addAtIndices, removeAtIndices);
60
+ };
61
+
62
+ /**
63
+ * Operations used to process updates to DOM nodes. This is made injectable via
64
+ * `ReactComponent.DOMIDOperations`.
65
+ */
66
+ var ReactNativeDOMIDOperations = {
67
+ dangerouslyProcessChildrenUpdates: ReactPerf.measure(
68
+ // FIXME(frantic): #4441289 Hack to avoid modifying react-tools
69
+ 'ReactDOMIDOperations', 'dangerouslyProcessChildrenUpdates', dangerouslyProcessChildrenUpdates),
70
+
71
+ /**
72
+ * Replaces a view that exists in the document with markup.
73
+ *
74
+ * @param {string} id ID of child to be replaced.
75
+ * @param {string} markup Mount image to replace child with id.
76
+ */
77
+ dangerouslyReplaceNodeWithMarkupByID: ReactPerf.measure('ReactDOMIDOperations', 'dangerouslyReplaceNodeWithMarkupByID', function (id, mountImage) {
78
+ var oldTag = id;
79
+ UIManager.replaceExistingNonRootView(oldTag, mountImage);
80
+ })
81
+ };
82
+
83
+ module.exports = ReactNativeDOMIDOperations;
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Copyright (c) 2015-present, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree. An additional grant
7
+ * of patent rights can be found in the PATENTS file in the same directory.
8
+ *
9
+ * @providesModule ReactNativeDefaultInjection
10
+ *
11
+ */
12
+ 'use strict';
13
+
14
+ /**
15
+ * Make sure essential globals are available and are patched correctly. Please don't remove this
16
+ * line. Bundles created by react-packager `require` it before executing any application code. This
17
+ * ensures it exists in the dependency graph and can be `require`d.
18
+ */
19
+
20
+ require('InitializeJavaScriptAppEngine');
21
+
22
+ var EventPluginHub = require('./EventPluginHub');
23
+ var EventPluginUtils = require('./EventPluginUtils');
24
+ var IOSDefaultEventPluginOrder = require('./IOSDefaultEventPluginOrder');
25
+ var IOSNativeBridgeEventPlugin = require('./IOSNativeBridgeEventPlugin');
26
+ var ReactElement = require('./ReactElement');
27
+ var ReactComponentEnvironment = require('./ReactComponentEnvironment');
28
+ var ReactDefaultBatchingStrategy = require('./ReactDefaultBatchingStrategy');
29
+ var ReactEmptyComponent = require('./ReactEmptyComponent');
30
+ var ReactNativeComponentEnvironment = require('./ReactNativeComponentEnvironment');
31
+ var ReactNativeGlobalResponderHandler = require('./ReactNativeGlobalResponderHandler');
32
+ var ReactNativeTextComponent = require('./ReactNativeTextComponent');
33
+ var ReactNativeTreeTraversal = require('./ReactNativeTreeTraversal');
34
+ var ReactNativeComponent = require('./ReactNativeComponent');
35
+ var ReactNativeComponentTree = require('./ReactNativeComponentTree');
36
+ var ReactSimpleEmptyComponent = require('./ReactSimpleEmptyComponent');
37
+ var ReactUpdates = require('./ReactUpdates');
38
+ var ResponderEventPlugin = require('./ResponderEventPlugin');
39
+
40
+ var invariant = require('fbjs/lib/invariant');
41
+
42
+ // Just to ensure this gets packaged, since its only caller is from Native.
43
+ require('RCTEventEmitter');
44
+ require('RCTLog');
45
+ require('JSTimersExecution');
46
+
47
+ function inject() {
48
+ /**
49
+ * Inject module for resolving DOM hierarchy and plugin ordering.
50
+ */
51
+ EventPluginHub.injection.injectEventPluginOrder(IOSDefaultEventPluginOrder);
52
+ EventPluginUtils.injection.injectComponentTree(ReactNativeComponentTree);
53
+ EventPluginUtils.injection.injectTreeTraversal(ReactNativeTreeTraversal);
54
+
55
+ ResponderEventPlugin.injection.injectGlobalResponderHandler(ReactNativeGlobalResponderHandler);
56
+
57
+ /**
58
+ * Some important event plugins included by default (without having to require
59
+ * them).
60
+ */
61
+ EventPluginHub.injection.injectEventPluginsByName({
62
+ 'ResponderEventPlugin': ResponderEventPlugin,
63
+ 'IOSNativeBridgeEventPlugin': IOSNativeBridgeEventPlugin
64
+ });
65
+
66
+ ReactUpdates.injection.injectReconcileTransaction(ReactNativeComponentEnvironment.ReactReconcileTransaction);
67
+
68
+ ReactUpdates.injection.injectBatchingStrategy(ReactDefaultBatchingStrategy);
69
+
70
+ ReactComponentEnvironment.injection.injectEnvironment(ReactNativeComponentEnvironment);
71
+
72
+ var EmptyComponent = function (instantiate) {
73
+ // Can't import View at the top because it depends on React to make its composite
74
+ var View = require('View');
75
+ return new ReactSimpleEmptyComponent(ReactElement.createElement(View, {
76
+ collapsable: true,
77
+ style: { position: 'absolute' }
78
+ }), instantiate);
79
+ };
80
+
81
+ ReactEmptyComponent.injection.injectEmptyComponentFactory(EmptyComponent);
82
+
83
+ ReactNativeComponent.injection.injectTextComponentClass(ReactNativeTextComponent);
84
+ ReactNativeComponent.injection.injectGenericComponentClass(function (tag) {
85
+ // Show a nicer error message for non-function tags
86
+ var info = '';
87
+ if (typeof tag === 'string' && /^[a-z]/.test(tag)) {
88
+ info += ' Each component name should start with an uppercase letter.';
89
+ }
90
+ !false ? process.env.NODE_ENV !== 'production' ? invariant(false, 'Expected a component class, got %s.%s', tag, info) : invariant(false) : void 0;
91
+ });
92
+ }
93
+
94
+ module.exports = {
95
+ inject: inject
96
+ };