Consume react, fbjs from npm
Summary: We don't (yet) treat these the same as any other modules because we still have special resolution rules for them in the packager allowing the use of `providesModule`, but I believe this allows people to use npm react in their RN projects and not have duplicate copies of React. Fixes facebook/react-native#2985. This relies on fbjs 0.6, which includes `.flow` files alongside the `.js` files to allow them to be typechecked without additional configuration. This also uses react 0.14.5, which shims a couple of files (as `.native.js`) to avoid DOM-specific bits. Once we fix these in React, we will use the same code on web and native. Hopefully we can also remove the packager support I'm adding here for `.native.js`. This diff is not the desired end state for us – ideally the packager would know nothing of react or fbjs, and we'll get there eventually by not relying on `providesModule` in order to load react and fbjs modules. (fbjs change posted here but not merged yet: https://github.com/facebook/fbjs/pull/84.) This should also allow relay to work seamlessly with RN, but I haven't verified this. public Reviewed By: sebmarkbage Differential Revision: D2786197 fb-gh-sync-id: ff50f28445e949edc9501f4b599df7970813870d
This commit is contained in:
parent
5bf1f4c05e
commit
6a838a4201
24
.flowconfig
24
.flowconfig
|
@ -14,17 +14,19 @@
|
||||||
|
|
||||||
# Ignore react and fbjs where there are overlaps, but don't ignore
|
# Ignore react and fbjs where there are overlaps, but don't ignore
|
||||||
# anything that react-native relies on
|
# anything that react-native relies on
|
||||||
.*/node_modules/fbjs-haste/.*/__tests__/.*
|
.*/node_modules/fbjs/lib/Map.js
|
||||||
.*/node_modules/fbjs-haste/__forks__/Map.js
|
.*/node_modules/fbjs/lib/Promise.js
|
||||||
.*/node_modules/fbjs-haste/__forks__/Promise.js
|
.*/node_modules/fbjs/lib/fetch.js
|
||||||
.*/node_modules/fbjs-haste/__forks__/fetch.js
|
.*/node_modules/fbjs/lib/ExecutionEnvironment.js
|
||||||
.*/node_modules/fbjs-haste/core/ExecutionEnvironment.js
|
.*/node_modules/fbjs/lib/isEmpty.js
|
||||||
.*/node_modules/fbjs-haste/core/isEmpty.js
|
.*/node_modules/fbjs/lib/crc32.js
|
||||||
.*/node_modules/fbjs-haste/crypto/crc32.js
|
.*/node_modules/fbjs/lib/ErrorUtils.js
|
||||||
.*/node_modules/fbjs-haste/stubs/ErrorUtils.js
|
|
||||||
.*/node_modules/react-haste/React.js
|
# Flow has a built-in definition for the 'react' module which we prefer to use
|
||||||
.*/node_modules/react-haste/renderers/dom/ReactDOM.js
|
# over the currently-untyped source
|
||||||
.*/node_modules/react-haste/renderers/shared/event/eventPlugins/ResponderEventPlugin.js
|
.*/node_modules/react/react.js
|
||||||
|
.*/node_modules/react/lib/React.js
|
||||||
|
.*/node_modules/react/lib/ReactDOM.js
|
||||||
|
|
||||||
# Ignore commoner tests
|
# Ignore commoner tests
|
||||||
.*/node_modules/commoner/test/.*
|
.*/node_modules/commoner/test/.*
|
||||||
|
|
|
@ -89,7 +89,7 @@
|
||||||
|
|
||||||
XCTAssertEqual(_lastLogLevel, RCTLogLevelError);
|
XCTAssertEqual(_lastLogLevel, RCTLogLevelError);
|
||||||
XCTAssertEqual(_lastLogSource, RCTLogSourceJavaScript);
|
XCTAssertEqual(_lastLogSource, RCTLogSourceJavaScript);
|
||||||
XCTAssertEqualObjects(_lastLogMessage, @"Invariant Violation: Invariant failed");
|
XCTAssertEqualObjects(_lastLogMessage, @"Invariant failed");
|
||||||
|
|
||||||
[_bridge enqueueJSCall:@"LoggingTestModule.logErrorToConsole" args:@[@"Invoking console.error"]];
|
[_bridge enqueueJSCall:@"LoggingTestModule.logErrorToConsole" args:@[@"Invoking console.error"]];
|
||||||
dispatch_semaphore_wait(_logSem, DISPATCH_TIME_FOREVER);
|
dispatch_semaphore_wait(_logSem, DISPATCH_TIME_FOREVER);
|
||||||
|
|
|
@ -1,612 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright 2013-2015, Facebook, Inc.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the BSD-style license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree. An additional grant
|
|
||||||
* of patent rights can be found in the PATENTS file in the same directory.
|
|
||||||
*
|
|
||||||
* @providesModule ResponderEventPlugin
|
|
||||||
*/
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
var EventConstants = require('EventConstants');
|
|
||||||
var EventPluginUtils = require('EventPluginUtils');
|
|
||||||
var EventPropagators = require('EventPropagators');
|
|
||||||
var ReactInstanceHandles = require('ReactInstanceHandles');
|
|
||||||
var ResponderSyntheticEvent = require('ResponderSyntheticEvent');
|
|
||||||
var ResponderTouchHistoryStore = require('ResponderTouchHistoryStore');
|
|
||||||
|
|
||||||
var accumulate = require('accumulate');
|
|
||||||
var invariant = require('invariant');
|
|
||||||
var keyOf = require('keyOf');
|
|
||||||
|
|
||||||
var isStartish = EventPluginUtils.isStartish;
|
|
||||||
var isMoveish = EventPluginUtils.isMoveish;
|
|
||||||
var isEndish = EventPluginUtils.isEndish;
|
|
||||||
var executeDirectDispatch = EventPluginUtils.executeDirectDispatch;
|
|
||||||
var hasDispatches = EventPluginUtils.hasDispatches;
|
|
||||||
var executeDispatchesInOrderStopAtTrue =
|
|
||||||
EventPluginUtils.executeDispatchesInOrderStopAtTrue;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ID of element that should respond to touch/move types of interactions, as
|
|
||||||
* indicated explicitly by relevant callbacks.
|
|
||||||
*/
|
|
||||||
var responderID = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Count of current touches. A textInput should become responder iff the
|
|
||||||
* the selection changes while there is a touch on the screen.
|
|
||||||
*/
|
|
||||||
var trackedTouchCount = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Last reported number of active touches.
|
|
||||||
*/
|
|
||||||
var previousActiveTouches = 0;
|
|
||||||
|
|
||||||
var changeResponder = function(nextResponderID, blockNativeResponder) {
|
|
||||||
var oldResponderID = responderID;
|
|
||||||
responderID = nextResponderID;
|
|
||||||
if (ResponderEventPlugin.GlobalResponderHandler !== null) {
|
|
||||||
ResponderEventPlugin.GlobalResponderHandler.onChange(
|
|
||||||
oldResponderID,
|
|
||||||
nextResponderID,
|
|
||||||
blockNativeResponder
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
var eventTypes = {
|
|
||||||
/**
|
|
||||||
* On a `touchStart`/`mouseDown`, is it desired that this element become the
|
|
||||||
* responder?
|
|
||||||
*/
|
|
||||||
startShouldSetResponder: {
|
|
||||||
phasedRegistrationNames: {
|
|
||||||
bubbled: keyOf({onStartShouldSetResponder: null}),
|
|
||||||
captured: keyOf({onStartShouldSetResponderCapture: null}),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* On a `scroll`, is it desired that this element become the responder? This
|
|
||||||
* is usually not needed, but should be used to retroactively infer that a
|
|
||||||
* `touchStart` had occured during momentum scroll. During a momentum scroll,
|
|
||||||
* a touch start will be immediately followed by a scroll event if the view is
|
|
||||||
* currently scrolling.
|
|
||||||
*
|
|
||||||
* TODO: This shouldn't bubble.
|
|
||||||
*/
|
|
||||||
scrollShouldSetResponder: {
|
|
||||||
phasedRegistrationNames: {
|
|
||||||
bubbled: keyOf({onScrollShouldSetResponder: null}),
|
|
||||||
captured: keyOf({onScrollShouldSetResponderCapture: null}),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* On text selection change, should this element become the responder? This
|
|
||||||
* is needed for text inputs or other views with native selection, so the
|
|
||||||
* JS view can claim the responder.
|
|
||||||
*
|
|
||||||
* TODO: This shouldn't bubble.
|
|
||||||
*/
|
|
||||||
selectionChangeShouldSetResponder: {
|
|
||||||
phasedRegistrationNames: {
|
|
||||||
bubbled: keyOf({onSelectionChangeShouldSetResponder: null}),
|
|
||||||
captured: keyOf({onSelectionChangeShouldSetResponderCapture: null}),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* On a `touchMove`/`mouseMove`, is it desired that this element become the
|
|
||||||
* responder?
|
|
||||||
*/
|
|
||||||
moveShouldSetResponder: {
|
|
||||||
phasedRegistrationNames: {
|
|
||||||
bubbled: keyOf({onMoveShouldSetResponder: null}),
|
|
||||||
captured: keyOf({onMoveShouldSetResponderCapture: null}),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Direct responder events dispatched directly to responder. Do not bubble.
|
|
||||||
*/
|
|
||||||
responderStart: {registrationName: keyOf({onResponderStart: null})},
|
|
||||||
responderMove: {registrationName: keyOf({onResponderMove: null})},
|
|
||||||
responderEnd: {registrationName: keyOf({onResponderEnd: null})},
|
|
||||||
responderRelease: {registrationName: keyOf({onResponderRelease: null})},
|
|
||||||
responderTerminationRequest: {
|
|
||||||
registrationName: keyOf({onResponderTerminationRequest: null}),
|
|
||||||
},
|
|
||||||
responderGrant: {registrationName: keyOf({onResponderGrant: null})},
|
|
||||||
responderReject: {registrationName: keyOf({onResponderReject: null})},
|
|
||||||
responderTerminate: {registrationName: keyOf({onResponderTerminate: null})},
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Responder System:
|
|
||||||
* ----------------
|
|
||||||
*
|
|
||||||
* - A global, solitary "interaction lock" on a view.
|
|
||||||
* - If a node becomes the responder, it should convey visual feedback
|
|
||||||
* immediately to indicate so, either by highlighting or moving accordingly.
|
|
||||||
* - To be the responder means, that touches are exclusively important to that
|
|
||||||
* responder view, and no other view.
|
|
||||||
* - While touches are still occuring, the responder lock can be transfered to
|
|
||||||
* a new view, but only to increasingly "higher" views (meaning ancestors of
|
|
||||||
* the current responder).
|
|
||||||
*
|
|
||||||
* Responder being granted:
|
|
||||||
* ------------------------
|
|
||||||
*
|
|
||||||
* - Touch starts, moves, and scrolls can cause an ID to become the responder.
|
|
||||||
* - We capture/bubble `startShouldSetResponder`/`moveShouldSetResponder` to
|
|
||||||
* the "appropriate place".
|
|
||||||
* - If nothing is currently the responder, the "appropriate place" is the
|
|
||||||
* initiating event's `targetID`.
|
|
||||||
* - If something *is* already the responder, the "appropriate place" is the
|
|
||||||
* first common ancestor of the event target and the current `responderID`.
|
|
||||||
* - Some negotiation happens: See the timing diagram below.
|
|
||||||
* - Scrolled views automatically become responder. The reasoning is that a
|
|
||||||
* platform scroll view that isn't built on top of the responder system has
|
|
||||||
* began scrolling, and the active responder must now be notified that the
|
|
||||||
* interaction is no longer locked to it - the system has taken over.
|
|
||||||
*
|
|
||||||
* - Responder being released:
|
|
||||||
* As soon as no more touches that *started* inside of descendents of the
|
|
||||||
* *current* responderID, an `onResponderRelease` event is dispatched to the
|
|
||||||
* current responder, and the responder lock is released.
|
|
||||||
*
|
|
||||||
* TODO:
|
|
||||||
* - on "end", a callback hook for `onResponderEndShouldRemainResponder` that
|
|
||||||
* determines if the responder lock should remain.
|
|
||||||
* - If a view shouldn't "remain" the responder, any active touches should by
|
|
||||||
* default be considered "dead" and do not influence future negotiations or
|
|
||||||
* bubble paths. It should be as if those touches do not exist.
|
|
||||||
* -- For multitouch: Usually a translate-z will choose to "remain" responder
|
|
||||||
* after one out of many touches ended. For translate-y, usually the view
|
|
||||||
* doesn't wish to "remain" responder after one of many touches end.
|
|
||||||
* - Consider building this on top of a `stopPropagation` model similar to
|
|
||||||
* `W3C` events.
|
|
||||||
* - Ensure that `onResponderTerminate` is called on touch cancels, whether or
|
|
||||||
* not `onResponderTerminationRequest` returns `true` or `false`.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Negotiation Performed
|
|
||||||
+-----------------------+
|
|
||||||
/ \
|
|
||||||
Process low level events to + Current Responder + wantsResponderID
|
|
||||||
determine who to perform negot-| (if any exists at all) |
|
|
||||||
iation/transition | Otherwise just pass through|
|
|
||||||
-------------------------------+----------------------------+------------------+
|
|
||||||
Bubble to find first ID | |
|
|
||||||
to return true:wantsResponderID| |
|
|
||||||
| |
|
|
||||||
+-------------+ | |
|
|
||||||
| onTouchStart| | |
|
|
||||||
+------+------+ none | |
|
|
||||||
| return| |
|
|
||||||
+-----------v-------------+true| +------------------------+ |
|
|
||||||
|onStartShouldSetResponder|----->|onResponderStart (cur) |<-----------+
|
|
||||||
+-----------+-------------+ | +------------------------+ | |
|
|
||||||
| | | +--------+-------+
|
|
||||||
| returned true for| false:REJECT +-------->|onResponderReject
|
|
||||||
| wantsResponderID | | | +----------------+
|
|
||||||
| (now attempt | +------------------+-----+ |
|
|
||||||
| handoff) | | onResponder | |
|
|
||||||
+------------------->| TerminationRequest| |
|
|
||||||
| +------------------+-----+ |
|
|
||||||
| | | +----------------+
|
|
||||||
| true:GRANT +-------->|onResponderGrant|
|
|
||||||
| | +--------+-------+
|
|
||||||
| +------------------------+ | |
|
|
||||||
| | onResponderTerminate |<-----------+
|
|
||||||
| +------------------+-----+ |
|
|
||||||
| | | +----------------+
|
|
||||||
| +-------->|onResponderStart|
|
|
||||||
| | +----------------+
|
|
||||||
Bubble to find first ID | |
|
|
||||||
to return true:wantsResponderID| |
|
|
||||||
| |
|
|
||||||
+-------------+ | |
|
|
||||||
| onTouchMove | | |
|
|
||||||
+------+------+ none | |
|
|
||||||
| return| |
|
|
||||||
+-----------v-------------+true| +------------------------+ |
|
|
||||||
|onMoveShouldSetResponder |----->|onResponderMove (cur) |<-----------+
|
|
||||||
+-----------+-------------+ | +------------------------+ | |
|
|
||||||
| | | +--------+-------+
|
|
||||||
| returned true for| false:REJECT +-------->|onResponderRejec|
|
|
||||||
| wantsResponderID | | | +----------------+
|
|
||||||
| (now attempt | +------------------+-----+ |
|
|
||||||
| handoff) | | onResponder | |
|
|
||||||
+------------------->| TerminationRequest| |
|
|
||||||
| +------------------+-----+ |
|
|
||||||
| | | +----------------+
|
|
||||||
| true:GRANT +-------->|onResponderGrant|
|
|
||||||
| | +--------+-------+
|
|
||||||
| +------------------------+ | |
|
|
||||||
| | onResponderTerminate |<-----------+
|
|
||||||
| +------------------+-----+ |
|
|
||||||
| | | +----------------+
|
|
||||||
| +-------->|onResponderMove |
|
|
||||||
| | +----------------+
|
|
||||||
| |
|
|
||||||
| |
|
|
||||||
Some active touch started| |
|
|
||||||
inside current responder | +------------------------+ |
|
|
||||||
+------------------------->| onResponderEnd | |
|
|
||||||
| | +------------------------+ |
|
|
||||||
+---+---------+ | |
|
|
||||||
| onTouchEnd | | |
|
|
||||||
+---+---------+ | |
|
|
||||||
| | +------------------------+ |
|
|
||||||
+------------------------->| onResponderEnd | |
|
|
||||||
No active touches started| +-----------+------------+ |
|
|
||||||
inside current responder | | |
|
|
||||||
| v |
|
|
||||||
| +------------------------+ |
|
|
||||||
| | onResponderRelease | |
|
|
||||||
| +------------------------+ |
|
|
||||||
| |
|
|
||||||
+ + */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A note about event ordering in the `EventPluginHub`.
|
|
||||||
*
|
|
||||||
* Suppose plugins are injected in the following order:
|
|
||||||
*
|
|
||||||
* `[R, S, C]`
|
|
||||||
*
|
|
||||||
* To help illustrate the example, assume `S` is `SimpleEventPlugin` (for
|
|
||||||
* `onClick` etc) and `R` is `ResponderEventPlugin`.
|
|
||||||
*
|
|
||||||
* "Deferred-Dispatched Events":
|
|
||||||
*
|
|
||||||
* - The current event plugin system will traverse the list of injected plugins,
|
|
||||||
* in order, and extract events by collecting the plugin's return value of
|
|
||||||
* `extractEvents()`.
|
|
||||||
* - These events that are returned from `extractEvents` are "deferred
|
|
||||||
* dispatched events".
|
|
||||||
* - When returned from `extractEvents`, deferred-dispatched events contain an
|
|
||||||
* "accumulation" of deferred dispatches.
|
|
||||||
* - These deferred dispatches are accumulated/collected before they are
|
|
||||||
* returned, but processed at a later time by the `EventPluginHub` (hence the
|
|
||||||
* name deferred).
|
|
||||||
*
|
|
||||||
* In the process of returning their deferred-dispatched events, event plugins
|
|
||||||
* themselves can dispatch events on-demand without returning them from
|
|
||||||
* `extractEvents`. Plugins might want to do this, so that they can use event
|
|
||||||
* dispatching as a tool that helps them decide which events should be extracted
|
|
||||||
* in the first place.
|
|
||||||
*
|
|
||||||
* "On-Demand-Dispatched Events":
|
|
||||||
*
|
|
||||||
* - On-demand-dispatched events are not returned from `extractEvents`.
|
|
||||||
* - On-demand-dispatched events are dispatched during the process of returning
|
|
||||||
* the deferred-dispatched events.
|
|
||||||
* - They should not have side effects.
|
|
||||||
* - They should be avoided, and/or eventually be replaced with another
|
|
||||||
* abstraction that allows event plugins to perform multiple "rounds" of event
|
|
||||||
* extraction.
|
|
||||||
*
|
|
||||||
* Therefore, the sequence of event dispatches becomes:
|
|
||||||
*
|
|
||||||
* - `R`s on-demand events (if any) (dispatched by `R` on-demand)
|
|
||||||
* - `S`s on-demand events (if any) (dispatched by `S` on-demand)
|
|
||||||
* - `C`s on-demand events (if any) (dispatched by `C` on-demand)
|
|
||||||
* - `R`s extracted events (if any) (dispatched by `EventPluginHub`)
|
|
||||||
* - `S`s extracted events (if any) (dispatched by `EventPluginHub`)
|
|
||||||
* - `C`s extracted events (if any) (dispatched by `EventPluginHub`)
|
|
||||||
*
|
|
||||||
* In the case of `ResponderEventPlugin`: If the `startShouldSetResponder`
|
|
||||||
* on-demand dispatch returns `true` (and some other details are satisfied) the
|
|
||||||
* `onResponderGrant` deferred dispatched event is returned from
|
|
||||||
* `extractEvents`. The sequence of dispatch executions in this case
|
|
||||||
* will appear as follows:
|
|
||||||
*
|
|
||||||
* - `startShouldSetResponder` (`ResponderEventPlugin` dispatches on-demand)
|
|
||||||
* - `touchStartCapture` (`EventPluginHub` dispatches as usual)
|
|
||||||
* - `touchStart` (`EventPluginHub` dispatches as usual)
|
|
||||||
* - `responderGrant/Reject` (`EventPluginHub` dispatches as usual)
|
|
||||||
*
|
|
||||||
* @param {string} topLevelType Record from `EventConstants`.
|
|
||||||
* @param {string} topLevelTargetID ID of deepest React rendered element.
|
|
||||||
* @param {object} nativeEvent Native browser event.
|
|
||||||
* @return {*} An accumulation of synthetic events.
|
|
||||||
*/
|
|
||||||
function setResponderAndExtractTransfer(
|
|
||||||
topLevelType,
|
|
||||||
topLevelTargetID,
|
|
||||||
nativeEvent,
|
|
||||||
nativeEventTarget) {
|
|
||||||
var shouldSetEventType =
|
|
||||||
isStartish(topLevelType) ? eventTypes.startShouldSetResponder :
|
|
||||||
isMoveish(topLevelType) ? eventTypes.moveShouldSetResponder :
|
|
||||||
topLevelType === EventConstants.topLevelTypes.topSelectionChange ?
|
|
||||||
eventTypes.selectionChangeShouldSetResponder :
|
|
||||||
eventTypes.scrollShouldSetResponder;
|
|
||||||
|
|
||||||
// TODO: stop one short of the the current responder.
|
|
||||||
var bubbleShouldSetFrom = !responderID ?
|
|
||||||
topLevelTargetID :
|
|
||||||
ReactInstanceHandles.getFirstCommonAncestorID(responderID, topLevelTargetID);
|
|
||||||
|
|
||||||
// When capturing/bubbling the "shouldSet" event, we want to skip the target
|
|
||||||
// (deepest ID) if it happens to be the current responder. The reasoning:
|
|
||||||
// It's strange to get an `onMoveShouldSetResponder` when you're *already*
|
|
||||||
// the responder.
|
|
||||||
var skipOverBubbleShouldSetFrom = bubbleShouldSetFrom === responderID;
|
|
||||||
var shouldSetEvent = ResponderSyntheticEvent.getPooled(
|
|
||||||
shouldSetEventType,
|
|
||||||
bubbleShouldSetFrom,
|
|
||||||
nativeEvent,
|
|
||||||
nativeEventTarget
|
|
||||||
);
|
|
||||||
shouldSetEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
|
|
||||||
if (skipOverBubbleShouldSetFrom) {
|
|
||||||
EventPropagators.accumulateTwoPhaseDispatchesSkipTarget(shouldSetEvent);
|
|
||||||
} else {
|
|
||||||
EventPropagators.accumulateTwoPhaseDispatches(shouldSetEvent);
|
|
||||||
}
|
|
||||||
var wantsResponderID = executeDispatchesInOrderStopAtTrue(shouldSetEvent);
|
|
||||||
if (!shouldSetEvent.isPersistent()) {
|
|
||||||
shouldSetEvent.constructor.release(shouldSetEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!wantsResponderID || wantsResponderID === responderID) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
var extracted;
|
|
||||||
var grantEvent = ResponderSyntheticEvent.getPooled(
|
|
||||||
eventTypes.responderGrant,
|
|
||||||
wantsResponderID,
|
|
||||||
nativeEvent,
|
|
||||||
nativeEventTarget
|
|
||||||
);
|
|
||||||
grantEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
|
|
||||||
|
|
||||||
EventPropagators.accumulateDirectDispatches(grantEvent);
|
|
||||||
var blockNativeResponder = executeDirectDispatch(grantEvent) === true;
|
|
||||||
if (responderID) {
|
|
||||||
|
|
||||||
var terminationRequestEvent = ResponderSyntheticEvent.getPooled(
|
|
||||||
eventTypes.responderTerminationRequest,
|
|
||||||
responderID,
|
|
||||||
nativeEvent,
|
|
||||||
nativeEventTarget
|
|
||||||
);
|
|
||||||
terminationRequestEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
|
|
||||||
EventPropagators.accumulateDirectDispatches(terminationRequestEvent);
|
|
||||||
var shouldSwitch = !hasDispatches(terminationRequestEvent) ||
|
|
||||||
executeDirectDispatch(terminationRequestEvent);
|
|
||||||
if (!terminationRequestEvent.isPersistent()) {
|
|
||||||
terminationRequestEvent.constructor.release(terminationRequestEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shouldSwitch) {
|
|
||||||
var terminateType = eventTypes.responderTerminate;
|
|
||||||
var terminateEvent = ResponderSyntheticEvent.getPooled(
|
|
||||||
terminateType,
|
|
||||||
responderID,
|
|
||||||
nativeEvent,
|
|
||||||
nativeEventTarget
|
|
||||||
);
|
|
||||||
terminateEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
|
|
||||||
EventPropagators.accumulateDirectDispatches(terminateEvent);
|
|
||||||
extracted = accumulate(extracted, [grantEvent, terminateEvent]);
|
|
||||||
changeResponder(wantsResponderID, blockNativeResponder);
|
|
||||||
} else {
|
|
||||||
var rejectEvent = ResponderSyntheticEvent.getPooled(
|
|
||||||
eventTypes.responderReject,
|
|
||||||
wantsResponderID,
|
|
||||||
nativeEvent,
|
|
||||||
nativeEventTarget
|
|
||||||
);
|
|
||||||
rejectEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
|
|
||||||
EventPropagators.accumulateDirectDispatches(rejectEvent);
|
|
||||||
extracted = accumulate(extracted, rejectEvent);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
extracted = accumulate(extracted, grantEvent);
|
|
||||||
changeResponder(wantsResponderID, blockNativeResponder);
|
|
||||||
}
|
|
||||||
return extracted;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A transfer is a negotiation between a currently set responder and the next
|
|
||||||
* element to claim responder status. Any start event could trigger a transfer
|
|
||||||
* of responderID. Any move event could trigger a transfer.
|
|
||||||
*
|
|
||||||
* @param {string} topLevelType Record from `EventConstants`.
|
|
||||||
* @return {boolean} True if a transfer of responder could possibly occur.
|
|
||||||
*/
|
|
||||||
function canTriggerTransfer(topLevelType, topLevelTargetID, nativeEvent) {
|
|
||||||
return topLevelTargetID && (
|
|
||||||
// responderIgnoreScroll: We are trying to migrate away from specifically tracking native scroll
|
|
||||||
// events here and responderIgnoreScroll indicates we will send topTouchCancel to handle
|
|
||||||
// canceling touch events instead
|
|
||||||
(topLevelType === EventConstants.topLevelTypes.topScroll &&
|
|
||||||
!nativeEvent.responderIgnoreScroll) ||
|
|
||||||
(trackedTouchCount > 0 &&
|
|
||||||
topLevelType === EventConstants.topLevelTypes.topSelectionChange) ||
|
|
||||||
isStartish(topLevelType) ||
|
|
||||||
isMoveish(topLevelType)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether or not this touch end event makes it such that there are no
|
|
||||||
* longer any touches that started inside of the current `responderID`.
|
|
||||||
*
|
|
||||||
* @param {NativeEvent} nativeEvent Native touch end event.
|
|
||||||
* @return {boolean} Whether or not this touch end event ends the responder.
|
|
||||||
*/
|
|
||||||
function noResponderTouches(nativeEvent) {
|
|
||||||
var touches = nativeEvent.touches;
|
|
||||||
if (!touches || touches.length === 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
for (var i = 0; i < touches.length; i++) {
|
|
||||||
var activeTouch = touches[i];
|
|
||||||
var target = activeTouch.target;
|
|
||||||
if (target !== null && target !== undefined && target !== 0) {
|
|
||||||
// Is the original touch location inside of the current responder?
|
|
||||||
var isAncestor =
|
|
||||||
ReactInstanceHandles.isAncestorIDOf(
|
|
||||||
responderID,
|
|
||||||
EventPluginUtils.getID(target)
|
|
||||||
);
|
|
||||||
if (isAncestor) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
var ResponderEventPlugin = {
|
|
||||||
|
|
||||||
getResponderID: function() {
|
|
||||||
return responderID;
|
|
||||||
},
|
|
||||||
|
|
||||||
eventTypes: eventTypes,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* We must be resilient to `topLevelTargetID` being `undefined` on
|
|
||||||
* `touchMove`, or `touchEnd`. On certain platforms, this means that a native
|
|
||||||
* scroll has assumed control and the original touch targets are destroyed.
|
|
||||||
*
|
|
||||||
* @param {string} topLevelType Record from `EventConstants`.
|
|
||||||
* @param {DOMEventTarget} topLevelTarget The listening component root node.
|
|
||||||
* @param {string} topLevelTargetID ID of `topLevelTarget`.
|
|
||||||
* @param {object} nativeEvent Native browser event.
|
|
||||||
* @return {*} An accumulation of synthetic events.
|
|
||||||
* @see {EventPluginHub.extractEvents}
|
|
||||||
*/
|
|
||||||
extractEvents: function(
|
|
||||||
topLevelType,
|
|
||||||
topLevelTarget,
|
|
||||||
topLevelTargetID,
|
|
||||||
nativeEvent,
|
|
||||||
nativeEventTarget) {
|
|
||||||
if (isStartish(topLevelType)) {
|
|
||||||
trackedTouchCount += 1;
|
|
||||||
} else if (isEndish(topLevelType)) {
|
|
||||||
trackedTouchCount -= 1;
|
|
||||||
invariant(
|
|
||||||
trackedTouchCount >= 0,
|
|
||||||
'Ended a touch event which was not counted in trackedTouchCount.'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
ResponderTouchHistoryStore.recordTouchTrack(topLevelType, nativeEvent, nativeEventTarget);
|
|
||||||
|
|
||||||
var extracted = canTriggerTransfer(topLevelType, topLevelTargetID, nativeEvent) ?
|
|
||||||
setResponderAndExtractTransfer(
|
|
||||||
topLevelType,
|
|
||||||
topLevelTargetID,
|
|
||||||
nativeEvent,
|
|
||||||
nativeEventTarget) :
|
|
||||||
null;
|
|
||||||
// Responder may or may not have transfered on a new touch start/move.
|
|
||||||
// Regardless, whoever is the responder after any potential transfer, we
|
|
||||||
// direct all touch start/move/ends to them in the form of
|
|
||||||
// `onResponderMove/Start/End`. These will be called for *every* additional
|
|
||||||
// finger that move/start/end, dispatched directly to whoever is the
|
|
||||||
// current responder at that moment, until the responder is "released".
|
|
||||||
//
|
|
||||||
// These multiple individual change touch events are are always bookended
|
|
||||||
// by `onResponderGrant`, and one of
|
|
||||||
// (`onResponderRelease/onResponderTerminate`).
|
|
||||||
var isResponderTouchStart = responderID && isStartish(topLevelType);
|
|
||||||
var isResponderTouchMove = responderID && isMoveish(topLevelType);
|
|
||||||
var isResponderTouchEnd = responderID && isEndish(topLevelType);
|
|
||||||
var incrementalTouch =
|
|
||||||
isResponderTouchStart ? eventTypes.responderStart :
|
|
||||||
isResponderTouchMove ? eventTypes.responderMove :
|
|
||||||
isResponderTouchEnd ? eventTypes.responderEnd :
|
|
||||||
null;
|
|
||||||
|
|
||||||
if (incrementalTouch) {
|
|
||||||
var gesture =
|
|
||||||
ResponderSyntheticEvent.getPooled(
|
|
||||||
incrementalTouch,
|
|
||||||
responderID,
|
|
||||||
nativeEvent,
|
|
||||||
nativeEventTarget
|
|
||||||
);
|
|
||||||
gesture.touchHistory = ResponderTouchHistoryStore.touchHistory;
|
|
||||||
EventPropagators.accumulateDirectDispatches(gesture);
|
|
||||||
extracted = accumulate(extracted, gesture);
|
|
||||||
}
|
|
||||||
|
|
||||||
var isResponderTerminate =
|
|
||||||
responderID &&
|
|
||||||
topLevelType === EventConstants.topLevelTypes.topTouchCancel;
|
|
||||||
var isResponderRelease =
|
|
||||||
responderID &&
|
|
||||||
!isResponderTerminate &&
|
|
||||||
isEndish(topLevelType) &&
|
|
||||||
noResponderTouches(nativeEvent);
|
|
||||||
var finalTouch =
|
|
||||||
isResponderTerminate ? eventTypes.responderTerminate :
|
|
||||||
isResponderRelease ? eventTypes.responderRelease :
|
|
||||||
null;
|
|
||||||
if (finalTouch) {
|
|
||||||
var finalEvent =
|
|
||||||
ResponderSyntheticEvent.getPooled(finalTouch, responderID, nativeEvent, nativeEventTarget);
|
|
||||||
finalEvent.touchHistory = ResponderTouchHistoryStore.touchHistory;
|
|
||||||
EventPropagators.accumulateDirectDispatches(finalEvent);
|
|
||||||
extracted = accumulate(extracted, finalEvent);
|
|
||||||
changeResponder(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
var numberActiveTouches =
|
|
||||||
ResponderTouchHistoryStore.touchHistory.numberActiveTouches;
|
|
||||||
if (ResponderEventPlugin.GlobalInteractionHandler &&
|
|
||||||
numberActiveTouches !== previousActiveTouches) {
|
|
||||||
ResponderEventPlugin.GlobalInteractionHandler.onChange(
|
|
||||||
numberActiveTouches
|
|
||||||
);
|
|
||||||
}
|
|
||||||
previousActiveTouches = numberActiveTouches;
|
|
||||||
|
|
||||||
return extracted;
|
|
||||||
},
|
|
||||||
|
|
||||||
GlobalResponderHandler: null,
|
|
||||||
GlobalInteractionHandler: null,
|
|
||||||
|
|
||||||
injection: {
|
|
||||||
/**
|
|
||||||
* @param {{onChange: (ReactID, ReactID) => void} GlobalResponderHandler
|
|
||||||
* Object that handles any change in responder. Use this to inject
|
|
||||||
* integration with an existing touch handling system etc.
|
|
||||||
*/
|
|
||||||
injectGlobalResponderHandler: function(GlobalResponderHandler) {
|
|
||||||
ResponderEventPlugin.GlobalResponderHandler = GlobalResponderHandler;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {{onChange: (numberActiveTouches) => void} GlobalInteractionHandler
|
|
||||||
* Object that handles any change in the number of active touches.
|
|
||||||
*/
|
|
||||||
injectGlobalInteractionHandler: function(GlobalInteractionHandler) {
|
|
||||||
ResponderEventPlugin.GlobalInteractionHandler = GlobalInteractionHandler;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = ResponderEventPlugin;
|
|
|
@ -13,36 +13,41 @@ var path = require('path');
|
||||||
// Don't forget to everything listed here to `testConfig.json`
|
// Don't forget to everything listed here to `testConfig.json`
|
||||||
// modulePathIgnorePatterns.
|
// modulePathIgnorePatterns.
|
||||||
var sharedBlacklist = [
|
var sharedBlacklist = [
|
||||||
'node_modules/react-haste/renderers/shared/event/eventPlugins/ResponderEventPlugin.js',
|
/node_modules[/\\]react[/\\]dist[/\\].*/,
|
||||||
'node_modules/react-haste/React.js',
|
'node_modules/react/lib/React.js',
|
||||||
'node_modules/react-haste/renderers/dom/ReactDOM.js',
|
'node_modules/react/lib/ReactDOM.js',
|
||||||
|
|
||||||
// For each of these fbjs files (especially the non-forks/stubs), we should
|
// For each of these fbjs files (especially the non-forks/stubs), we should
|
||||||
// consider deleting the conflicting copy and just using the fbjs version.
|
// consider deleting the conflicting copy and just using the fbjs version.
|
||||||
'node_modules/fbjs-haste/__forks__/Map.js',
|
//
|
||||||
'node_modules/fbjs-haste/__forks__/Promise.js',
|
// fbjs forks:
|
||||||
'node_modules/fbjs-haste/__forks__/fetch.js',
|
'node_modules/fbjs/lib/Map.js',
|
||||||
'node_modules/fbjs-haste/core/Deferred.js',
|
'node_modules/fbjs/lib/Promise.js',
|
||||||
'node_modules/fbjs-haste/core/PromiseMap.js',
|
'node_modules/fbjs/lib/fetch.js',
|
||||||
'node_modules/fbjs-haste/core/areEqual.js',
|
// fbjs stubs:
|
||||||
'node_modules/fbjs-haste/core/flattenArray.js',
|
'node_modules/fbjs/lib/ErrorUtils.js',
|
||||||
'node_modules/fbjs-haste/core/isEmpty.js',
|
'node_modules/fbjs/lib/URI.js',
|
||||||
'node_modules/fbjs-haste/core/removeFromArray.js',
|
// fbjs modules:
|
||||||
'node_modules/fbjs-haste/core/resolveImmediate.js',
|
'node_modules/fbjs/lib/Deferred.js',
|
||||||
'node_modules/fbjs-haste/core/sprintf.js',
|
'node_modules/fbjs/lib/PromiseMap.js',
|
||||||
'node_modules/fbjs-haste/crypto/crc32.js',
|
'node_modules/fbjs/lib/UserAgent.js',
|
||||||
'node_modules/fbjs-haste/fetch/fetchWithRetries.js',
|
'node_modules/fbjs/lib/areEqual.js',
|
||||||
'node_modules/fbjs-haste/functional/everyObject.js',
|
'node_modules/fbjs/lib/base62.js',
|
||||||
'node_modules/fbjs-haste/functional/filterObject.js',
|
'node_modules/fbjs/lib/crc32.js',
|
||||||
'node_modules/fbjs-haste/functional/forEachObject.js',
|
'node_modules/fbjs/lib/everyObject.js',
|
||||||
'node_modules/fbjs-haste/functional/someObject.js',
|
'node_modules/fbjs/lib/fetchWithRetries.js',
|
||||||
'node_modules/fbjs-haste/request/xhrSimpleDataSerializer.js',
|
'node_modules/fbjs/lib/filterObject.js',
|
||||||
'node_modules/fbjs-haste/stubs/ErrorUtils.js',
|
'node_modules/fbjs/lib/flattenArray.js',
|
||||||
'node_modules/fbjs-haste/stubs/URI.js',
|
'node_modules/fbjs/lib/forEachObject.js',
|
||||||
'node_modules/fbjs-haste/useragent/UserAgent.js',
|
'node_modules/fbjs/lib/isEmpty.js',
|
||||||
'node_modules/fbjs-haste/utils/nullthrows.js',
|
'node_modules/fbjs/lib/nullthrows.js',
|
||||||
|
'node_modules/fbjs/lib/removeFromArray.js',
|
||||||
|
'node_modules/fbjs/lib/resolveImmediate.js',
|
||||||
|
'node_modules/fbjs/lib/someObject.js',
|
||||||
|
'node_modules/fbjs/lib/sprintf.js',
|
||||||
|
'node_modules/fbjs/lib/xhrSimpleDataSerializer.js',
|
||||||
|
|
||||||
// Those conflicts with the ones in fbjs-haste/. We need to blacklist the
|
// Those conflicts with the ones in fbjs/. We need to blacklist the
|
||||||
// internal version otherwise they won't work in open source.
|
// internal version otherwise they won't work in open source.
|
||||||
'downstream/core/CSSCore.js',
|
'downstream/core/CSSCore.js',
|
||||||
'downstream/core/TouchEventUtils.js',
|
'downstream/core/TouchEventUtils.js',
|
||||||
|
@ -63,11 +68,8 @@ var sharedBlacklist = [
|
||||||
'downstream/core/invariant.js',
|
'downstream/core/invariant.js',
|
||||||
'downstream/core/nativeRequestAnimationFrame.js',
|
'downstream/core/nativeRequestAnimationFrame.js',
|
||||||
'downstream/core/toArray.js',
|
'downstream/core/toArray.js',
|
||||||
];
|
|
||||||
|
|
||||||
// Raw unescaped patterns in case you need to use wildcards
|
/website\/node_modules\/.*/,
|
||||||
var sharedBlacklistWildcards = [
|
|
||||||
'website\/node_modules\/.*',
|
|
||||||
];
|
];
|
||||||
|
|
||||||
var platformBlacklists = {
|
var platformBlacklists = {
|
||||||
|
@ -85,10 +87,16 @@ var platformBlacklists = {
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
function escapeRegExp(str) {
|
function escapeRegExp(pattern) {
|
||||||
var escaped = str.replace(/[\-\[\]\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
|
if (Object.prototype.toString.call(pattern) === '[object RegExp]') {
|
||||||
|
return pattern.source;
|
||||||
|
} else if (typeof pattern === 'string') {
|
||||||
|
var escaped = pattern.replace(/[\-\[\]\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
|
||||||
// convert the '/' into an escaped local file separator
|
// convert the '/' into an escaped local file separator
|
||||||
return escaped.replace(/\//g,'\\' + path.sep);
|
return escaped.replace(/\//g,'\\' + path.sep);
|
||||||
|
} else {
|
||||||
|
throw new Error('Unexpected packager blacklist pattern: ' + pattern);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function blacklist(platform, additionalBlacklist) {
|
function blacklist(platform, additionalBlacklist) {
|
||||||
|
@ -96,7 +104,6 @@ function blacklist(platform, additionalBlacklist) {
|
||||||
(additionalBlacklist || []).concat(sharedBlacklist)
|
(additionalBlacklist || []).concat(sharedBlacklist)
|
||||||
.concat(platformBlacklists[platform] || [])
|
.concat(platformBlacklists[platform] || [])
|
||||||
.map(escapeRegExp)
|
.map(escapeRegExp)
|
||||||
.concat(sharedBlacklistWildcards)
|
|
||||||
.join('|') +
|
.join('|') +
|
||||||
')$'
|
')$'
|
||||||
);
|
);
|
||||||
|
|
|
@ -12,12 +12,20 @@ const getPlatformExtension = require('../lib/getPlatformExtension');
|
||||||
const Promise = require('promise');
|
const Promise = require('promise');
|
||||||
|
|
||||||
const GENERIC_PLATFORM = 'generic';
|
const GENERIC_PLATFORM = 'generic';
|
||||||
|
const NATIVE_PLATFORM = 'native';
|
||||||
|
|
||||||
class HasteMap {
|
class HasteMap {
|
||||||
constructor({ extensions, fastfs, moduleCache, helpers }) {
|
constructor({
|
||||||
|
extensions,
|
||||||
|
fastfs,
|
||||||
|
moduleCache,
|
||||||
|
preferNativePlatform,
|
||||||
|
helpers,
|
||||||
|
}) {
|
||||||
this._extensions = extensions;
|
this._extensions = extensions;
|
||||||
this._fastfs = fastfs;
|
this._fastfs = fastfs;
|
||||||
this._moduleCache = moduleCache;
|
this._moduleCache = moduleCache;
|
||||||
|
this._preferNativePlatform = preferNativePlatform;
|
||||||
this._helpers = helpers;
|
this._helpers = helpers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,19 +81,20 @@ class HasteMap {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no platform is given we choose the generic platform module list.
|
// If platform is 'ios', we prefer .ios.js to .native.js which we prefer to
|
||||||
// If a platform is given and no modules exist we fallback
|
// a plain .js file.
|
||||||
// to the generic platform module list.
|
let module = undefined;
|
||||||
if (platform == null) {
|
if (module == null && platform != null) {
|
||||||
return modulesMap[GENERIC_PLATFORM];
|
module = modulesMap[platform];
|
||||||
} else {
|
}
|
||||||
let module = modulesMap[platform];
|
if (module == null && this._preferNativePlatform) {
|
||||||
|
module = modulesMap[NATIVE_PLATFORM];
|
||||||
|
}
|
||||||
if (module == null) {
|
if (module == null) {
|
||||||
module = modulesMap[GENERIC_PLATFORM];
|
module = modulesMap[GENERIC_PLATFORM];
|
||||||
}
|
}
|
||||||
return module;
|
return module;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
_processHasteModule(file) {
|
_processHasteModule(file) {
|
||||||
const module = this._moduleCache.getModule(file);
|
const module = this._moduleCache.getModule(file);
|
||||||
|
|
|
@ -18,6 +18,7 @@ const Promise = require('promise');
|
||||||
class ResolutionRequest {
|
class ResolutionRequest {
|
||||||
constructor({
|
constructor({
|
||||||
platform,
|
platform,
|
||||||
|
preferNativePlatform,
|
||||||
entryPath,
|
entryPath,
|
||||||
hasteMap,
|
hasteMap,
|
||||||
deprecatedAssetMap,
|
deprecatedAssetMap,
|
||||||
|
@ -26,6 +27,7 @@ class ResolutionRequest {
|
||||||
fastfs,
|
fastfs,
|
||||||
}) {
|
}) {
|
||||||
this._platform = platform;
|
this._platform = platform;
|
||||||
|
this._preferNativePlatform = preferNativePlatform;
|
||||||
this._entryPath = entryPath;
|
this._entryPath = entryPath;
|
||||||
this._hasteMap = hasteMap;
|
this._hasteMap = hasteMap;
|
||||||
this._deprecatedAssetMap = deprecatedAssetMap;
|
this._deprecatedAssetMap = deprecatedAssetMap;
|
||||||
|
@ -329,6 +331,9 @@ class ResolutionRequest {
|
||||||
} else if (this._platform != null &&
|
} else if (this._platform != null &&
|
||||||
this._fastfs.fileExists(potentialModulePath + '.' + this._platform + '.js')) {
|
this._fastfs.fileExists(potentialModulePath + '.' + this._platform + '.js')) {
|
||||||
file = potentialModulePath + '.' + this._platform + '.js';
|
file = potentialModulePath + '.' + this._platform + '.js';
|
||||||
|
} else if (this._preferNativePlatform &&
|
||||||
|
this._fastfs.fileExists(potentialModulePath + '.native.js')) {
|
||||||
|
file = potentialModulePath + '.native.js';
|
||||||
} else if (this._fastfs.fileExists(potentialModulePath + '.js')) {
|
} else if (this._fastfs.fileExists(potentialModulePath + '.js')) {
|
||||||
file = potentialModulePath + '.js';
|
file = potentialModulePath + '.js';
|
||||||
} else if (this._fastfs.fileExists(potentialModulePath + '.json')) {
|
} else if (this._fastfs.fileExists(potentialModulePath + '.json')) {
|
||||||
|
|
|
@ -37,6 +37,7 @@ class DependencyGraph {
|
||||||
assetExts,
|
assetExts,
|
||||||
providesModuleNodeModules,
|
providesModuleNodeModules,
|
||||||
platforms,
|
platforms,
|
||||||
|
preferNativePlatform,
|
||||||
cache,
|
cache,
|
||||||
extensions,
|
extensions,
|
||||||
mocksPattern,
|
mocksPattern,
|
||||||
|
@ -51,6 +52,7 @@ class DependencyGraph {
|
||||||
assetExts: assetExts || [],
|
assetExts: assetExts || [],
|
||||||
providesModuleNodeModules,
|
providesModuleNodeModules,
|
||||||
platforms: platforms || [],
|
platforms: platforms || [],
|
||||||
|
preferNativePlatform: preferNativePlatform || false,
|
||||||
cache,
|
cache,
|
||||||
extensions: extensions || ['js', 'json'],
|
extensions: extensions || ['js', 'json'],
|
||||||
mocksPattern,
|
mocksPattern,
|
||||||
|
@ -105,7 +107,7 @@ class DependencyGraph {
|
||||||
fastfs: this._fastfs,
|
fastfs: this._fastfs,
|
||||||
extensions: this._opts.extensions,
|
extensions: this._opts.extensions,
|
||||||
moduleCache: this._moduleCache,
|
moduleCache: this._moduleCache,
|
||||||
assetExts: this._opts.exts,
|
preferNativePlatform: this._opts.preferNativePlatform,
|
||||||
helpers: this._helpers,
|
helpers: this._helpers,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -147,6 +149,7 @@ class DependencyGraph {
|
||||||
const absPath = this._getAbsolutePath(entryPath);
|
const absPath = this._getAbsolutePath(entryPath);
|
||||||
const req = new ResolutionRequest({
|
const req = new ResolutionRequest({
|
||||||
platform,
|
platform,
|
||||||
|
preferNativePlatform: this._opts.preferNativePlatform,
|
||||||
entryPath: absPath,
|
entryPath: absPath,
|
||||||
deprecatedAssetMap: this._deprecatedAssetMap,
|
deprecatedAssetMap: this._deprecatedAssetMap,
|
||||||
hasteMap: this._hasteMap,
|
hasteMap: this._hasteMap,
|
||||||
|
|
|
@ -81,8 +81,8 @@ class Resolver {
|
||||||
(opts.blacklistRE && opts.blacklistRE.test(filepath));
|
(opts.blacklistRE && opts.blacklistRE.test(filepath));
|
||||||
},
|
},
|
||||||
providesModuleNodeModules: [
|
providesModuleNodeModules: [
|
||||||
'fbjs-haste',
|
'fbjs',
|
||||||
'react-haste',
|
'react',
|
||||||
'react-native',
|
'react-native',
|
||||||
// Parse requires AsyncStorage. They will
|
// Parse requires AsyncStorage. They will
|
||||||
// change that to require('react-native') which
|
// change that to require('react-native') which
|
||||||
|
@ -92,6 +92,7 @@ class Resolver {
|
||||||
'react-transform-hmr',
|
'react-transform-hmr',
|
||||||
],
|
],
|
||||||
platforms: ['ios', 'android'],
|
platforms: ['ios', 'android'],
|
||||||
|
preferNativePlatform: true,
|
||||||
fileWatcher: opts.fileWatcher,
|
fileWatcher: opts.fileWatcher,
|
||||||
cache: opts.cache,
|
cache: opts.cache,
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue