mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-01-31 17:18:45 +08:00
[react-packager][streamline oss] Move open sourced JS source to react-native-github
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
/**
|
||||
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||
*
|
||||
* Sets up global variables typical in most JavaScript environments.
|
||||
*
|
||||
* 1. Global timers (via `setTimeout` etc).
|
||||
* 2. Global console object.
|
||||
* 3. Hooks for printing stack traces with source maps.
|
||||
*
|
||||
* Leaves enough room in the environment for implementing your own:
|
||||
* 1. Require system.
|
||||
* 2. Bridged modules.
|
||||
*
|
||||
* @providesModule InitializeJavaScriptAppEngine
|
||||
*/
|
||||
|
||||
/* eslint global-strict: 0 */
|
||||
/* globals GLOBAL: true, window: true */
|
||||
|
||||
var JSTimers = require('JSTimers');
|
||||
|
||||
// Just to make sure the JS gets packaged up
|
||||
require('RCTDeviceEventEmitter');
|
||||
var ErrorUtils = require('ErrorUtils');
|
||||
var RKAlertManager = require('RKAlertManager');
|
||||
var RKExceptionsManager = require('NativeModules').RKExceptionsManager;
|
||||
|
||||
var errorToString = require('errorToString');
|
||||
var loadSourceMap = require('loadSourceMap');
|
||||
|
||||
if (typeof GLOBAL === 'undefined') {
|
||||
GLOBAL = this;
|
||||
}
|
||||
|
||||
if (typeof window === 'undefined') {
|
||||
window = GLOBAL;
|
||||
}
|
||||
|
||||
function handleErrorWithRedBox(e) {
|
||||
GLOBAL.console.error(
|
||||
'Error: ' +
|
||||
'\n stack: \n' + e.stack +
|
||||
'\n URL: ' + e.sourceURL +
|
||||
'\n line: ' + e.line +
|
||||
'\n message: ' + e.message
|
||||
);
|
||||
|
||||
if (RKExceptionsManager) {
|
||||
RKExceptionsManager.reportUnhandledException(e.message, errorToString(e));
|
||||
if (__DEV__) {
|
||||
try {
|
||||
var sourceMapInstance = loadSourceMap();
|
||||
var prettyStack = errorToString(e, sourceMapInstance);
|
||||
RKExceptionsManager.updateExceptionMessage(e.message, prettyStack);
|
||||
} catch (ee) {
|
||||
GLOBAL.console.error('#CLOWNTOWN (error while displaying error): ' + ee.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setupRedBoxErrorHandler() {
|
||||
ErrorUtils.setGlobalHandler(handleErrorWithRedBox);
|
||||
}
|
||||
|
||||
function setupDocumentShim() {
|
||||
// The browser defines Text and Image globals by default. If you forget to
|
||||
// require them, then the error message is very confusing.
|
||||
function getInvalidGlobalUseError(name) {
|
||||
return new Error(
|
||||
'You are trying to render the global ' + name + ' variable as a ' +
|
||||
'React element. You probably forgot to require ' + name + '.'
|
||||
);
|
||||
}
|
||||
GLOBAL.Text = {
|
||||
get defaultProps() {
|
||||
throw getInvalidGlobalUseError('Text');
|
||||
}
|
||||
};
|
||||
GLOBAL.Image = {
|
||||
get defaultProps() {
|
||||
throw getInvalidGlobalUseError('Image');
|
||||
}
|
||||
};
|
||||
|
||||
GLOBAL.document = {
|
||||
// This shouldn't be needed but scroller library fails without it. If
|
||||
// we fixed the scroller, we wouldn't need this.
|
||||
body: {},
|
||||
// Workaround for setImmediate
|
||||
createElement: function() {return {};}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a set of window environment wrappers that ensure that the
|
||||
* BatchedBridge is flushed after each tick. In both the case of the
|
||||
* `UIWebView` based `RKJavaScriptCaller` and `RKContextCaller`, we
|
||||
* implement our own custom timing bridge that should be immune to
|
||||
* unexplainably dropped timing signals.
|
||||
*/
|
||||
function setupTimers() {
|
||||
GLOBAL.setTimeout = JSTimers.setTimeout;
|
||||
GLOBAL.setInterval = JSTimers.setInterval;
|
||||
GLOBAL.setImmediate = JSTimers.setImmediate;
|
||||
GLOBAL.clearTimeout = JSTimers.clearTimeout;
|
||||
GLOBAL.clearInterval = JSTimers.clearInterval;
|
||||
GLOBAL.clearImmediate = JSTimers.clearImmediate;
|
||||
GLOBAL.cancelAnimationFrame = JSTimers.clearInterval;
|
||||
GLOBAL.requestAnimationFrame = function(cb) {
|
||||
/*requestAnimationFrame() { [native code] };*/ // Trick scroller library
|
||||
return JSTimers.requestAnimationFrame(cb); // into thinking it's native
|
||||
};
|
||||
}
|
||||
|
||||
function setupAlert() {
|
||||
if (!GLOBAL.alert) {
|
||||
GLOBAL.alert = function(text) {
|
||||
var alertOpts = {
|
||||
title: 'Alert',
|
||||
message: '' + text,
|
||||
buttons: [{'cancel': 'Okay'}],
|
||||
};
|
||||
RKAlertManager.alertWithArgs(alertOpts, null);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function setupPromise() {
|
||||
// The native Promise implementation throws the following error:
|
||||
// ERROR: Event loop not supported.
|
||||
GLOBAL.Promise = require('Promise');
|
||||
}
|
||||
|
||||
function setupXHR() {
|
||||
// The native XMLHttpRequest in Chrome dev tools is CORS aware and won't
|
||||
// let you fetch anything from the internet
|
||||
GLOBAL.XMLHttpRequest = require('XMLHttpRequest');
|
||||
GLOBAL.fetch = require('fetch');
|
||||
}
|
||||
|
||||
setupRedBoxErrorHandler();
|
||||
setupDocumentShim();
|
||||
setupTimers();
|
||||
setupAlert();
|
||||
setupPromise();
|
||||
setupXHR();
|
||||
1958
Libraries/JavaScriptAppEngine/Initialization/SourceMap.js
Normal file
1958
Libraries/JavaScriptAppEngine/Initialization/SourceMap.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||
*
|
||||
* @providesModule errorToString
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var Platform = require('Platform');
|
||||
|
||||
var stacktraceParser = require('stacktrace-parser');
|
||||
|
||||
function stackFrameToString(stackFrame) {
|
||||
var fileNameParts = stackFrame.file.split('/');
|
||||
var fileName = fileNameParts[fileNameParts.length - 1];
|
||||
|
||||
return stackFrame.methodName + '\n in ' + fileName + ':' + stackFrame.lineNumber + '\n';
|
||||
}
|
||||
|
||||
function resolveSourceMaps(sourceMapInstance, stackFrame) {
|
||||
try {
|
||||
var orig = sourceMapInstance.originalPositionFor({
|
||||
line: stackFrame.lineNumber,
|
||||
column: stackFrame.column,
|
||||
});
|
||||
if (orig) {
|
||||
stackFrame.file = orig.source;
|
||||
stackFrame.lineNumber = orig.line;
|
||||
stackFrame.column = orig.column;
|
||||
}
|
||||
} catch (innerEx) {
|
||||
}
|
||||
}
|
||||
|
||||
function errorToString(e, sourceMapInstance) {
|
||||
var stack = stacktraceParser.parse(e.stack);
|
||||
|
||||
var framesToPop = e.framesToPop || 0;
|
||||
while (framesToPop--) {
|
||||
stack.shift();
|
||||
}
|
||||
|
||||
if (sourceMapInstance) {
|
||||
stack.forEach(resolveSourceMaps.bind(null, sourceMapInstance));
|
||||
}
|
||||
|
||||
// HACK(frantic) Android currently expects stack trace to be a string #5920439
|
||||
if (Platform.OS === 'android') {
|
||||
return stack.map(stackFrameToString).join('\n');
|
||||
} else {
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = errorToString;
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||
*
|
||||
* @providesModule loadSourceMap
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var SourceMapConsumer = require('SourceMap').SourceMapConsumer;
|
||||
|
||||
var sourceMapInstance;
|
||||
|
||||
function loadSourceMap() {
|
||||
if (sourceMapInstance !== undefined) {
|
||||
return sourceMapInstance;
|
||||
}
|
||||
if (!global.RAW_SOURCE_MAP) {
|
||||
return null;
|
||||
}
|
||||
sourceMapInstance = new SourceMapConsumer(global.RAW_SOURCE_MAP);
|
||||
return sourceMapInstance;
|
||||
}
|
||||
|
||||
module.exports = loadSourceMap;
|
||||
135
Libraries/JavaScriptAppEngine/System/JSTimers/JSTimers.js
Normal file
135
Libraries/JavaScriptAppEngine/System/JSTimers/JSTimers.js
Normal file
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||
*
|
||||
* @providesModule JSTimers
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
// Note that the module JSTimers is split into two in order to solve a cycle
|
||||
// in dependencies. NativeModules > BatchedBridge > MessageQueue > JSTimersExecution
|
||||
var RKTiming = require('NativeModules').RKTiming;
|
||||
var JSTimersExecution = require('JSTimersExecution');
|
||||
|
||||
/**
|
||||
* JS implementation of timer functions. Must be completely driven by an
|
||||
* external clock signal, all that's stored here is timerID, timer type, and
|
||||
* callback.
|
||||
*/
|
||||
var JSTimers = {
|
||||
Types: JSTimersExecution.Types,
|
||||
|
||||
/**
|
||||
* Returns a free index if one is available, and the next consecutive index
|
||||
* otherwise.
|
||||
*/
|
||||
_getFreeIndex: function() {
|
||||
var freeIndex = JSTimersExecution.timerIDs.indexOf(null);
|
||||
if (freeIndex === -1) {
|
||||
freeIndex = JSTimersExecution.timerIDs.length;
|
||||
}
|
||||
return freeIndex;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {function} func Callback to be invoked after `duration` ms.
|
||||
* @param {number} duration Number of milliseconds.
|
||||
*/
|
||||
setTimeout: function(func, duration, ...args) {
|
||||
var newID = JSTimersExecution.GUID++;
|
||||
var freeIndex = JSTimers._getFreeIndex();
|
||||
JSTimersExecution.timerIDs[freeIndex] = newID;
|
||||
JSTimersExecution.callbacks[freeIndex] = func;
|
||||
JSTimersExecution.callbacks[freeIndex] = function() {
|
||||
return func.apply(undefined, args);
|
||||
};
|
||||
JSTimersExecution.types[freeIndex] = JSTimersExecution.Type.setTimeout;
|
||||
RKTiming.createTimer(newID, duration, Date.now(), /** recurring */ false);
|
||||
return newID;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {function} func Callback to be invoked every `duration` ms.
|
||||
* @param {number} duration Number of milliseconds.
|
||||
*/
|
||||
setInterval: function(func, duration, ...args) {
|
||||
var newID = JSTimersExecution.GUID++;
|
||||
var freeIndex = JSTimers._getFreeIndex();
|
||||
JSTimersExecution.timerIDs[freeIndex] = newID;
|
||||
JSTimersExecution.callbacks[freeIndex] = func;
|
||||
JSTimersExecution.callbacks[freeIndex] = function() {
|
||||
return func.apply(undefined, args);
|
||||
};
|
||||
JSTimersExecution.types[freeIndex] = JSTimersExecution.Type.setInterval;
|
||||
RKTiming.createTimer(newID, duration, Date.now(), /** recurring */ true);
|
||||
return newID;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {function} func Callback to be invoked before the end of the
|
||||
* current JavaScript execution loop.
|
||||
*/
|
||||
setImmediate: function(func, ...args) {
|
||||
var newID = JSTimersExecution.GUID++;
|
||||
var freeIndex = JSTimers._getFreeIndex();
|
||||
JSTimersExecution.timerIDs[freeIndex] = newID;
|
||||
JSTimersExecution.callbacks[freeIndex] = func;
|
||||
JSTimersExecution.callbacks[freeIndex] = function() {
|
||||
return func.apply(undefined, args);
|
||||
};
|
||||
JSTimersExecution.types[freeIndex] = JSTimersExecution.Type.setImmediate;
|
||||
JSTimersExecution.immediates.push(newID);
|
||||
return newID;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {function} func Callback to be invoked every frame.
|
||||
*/
|
||||
requestAnimationFrame: function(func) {
|
||||
var newID = JSTimersExecution.GUID++;
|
||||
var freeIndex = JSTimers._getFreeIndex();
|
||||
JSTimersExecution.timerIDs[freeIndex] = newID;
|
||||
JSTimersExecution.callbacks[freeIndex] = func;
|
||||
JSTimersExecution.types[freeIndex] = JSTimersExecution.Type.requestAnimationFrame;
|
||||
RKTiming.createTimer(newID, 0, Date.now(), /** recurring */ false);
|
||||
return newID;
|
||||
},
|
||||
|
||||
clearTimeout: function(timerID) {
|
||||
JSTimers._clearTimerID(timerID);
|
||||
},
|
||||
|
||||
clearInterval: function(timerID) {
|
||||
JSTimers._clearTimerID(timerID);
|
||||
},
|
||||
|
||||
clearImmediate: function(timerID) {
|
||||
JSTimers._clearTimerID(timerID);
|
||||
JSTimersExecution.immediates.splice(
|
||||
JSTimersExecution.immediates.indexOf(timerID),
|
||||
1
|
||||
);
|
||||
},
|
||||
|
||||
cancelAnimationFrame: function(timerID) {
|
||||
JSTimers._clearTimerID(timerID);
|
||||
},
|
||||
|
||||
_clearTimerID: function(timerID) {
|
||||
// JSTimersExecution.timerIDs contains nulls after timers have been removed;
|
||||
// ignore nulls upfront so indexOf doesn't find them
|
||||
if (timerID == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
var index = JSTimersExecution.timerIDs.indexOf(timerID);
|
||||
// See corresponding comment in `callTimers` for reasoning behind this
|
||||
if (index !== -1) {
|
||||
JSTimersExecution._clearIndex(index);
|
||||
if (JSTimersExecution.types[index] !== JSTimersExecution.Type.setImmediate) {
|
||||
RKTiming.deleteTimer(timerID);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = JSTimers;
|
||||
@@ -0,0 +1,128 @@
|
||||
/**
|
||||
* Copyright 2004-present Facebook. All Rights Reserved.
|
||||
*
|
||||
* @providesModule JSTimersExecution
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var invariant = require('invariant');
|
||||
var keyMirror = require('keyMirror');
|
||||
var performanceNow = require('performanceNow');
|
||||
var warning = require('warning');
|
||||
|
||||
/**
|
||||
* JS implementation of timer functions. Must be completely driven by an
|
||||
* external clock signal, all that's stored here is timerID, timer type, and
|
||||
* callback.
|
||||
*/
|
||||
var JSTimersExecution = {
|
||||
GUID: 1,
|
||||
Type: keyMirror({
|
||||
setTimeout: null,
|
||||
setInterval: null,
|
||||
requestAnimationFrame: null,
|
||||
setImmediate: null,
|
||||
}),
|
||||
|
||||
// Parallel arrays:
|
||||
callbacks: [],
|
||||
types: [],
|
||||
timerIDs: [],
|
||||
immediates: [],
|
||||
|
||||
/**
|
||||
* Calls the callback associated with the ID. Also unregister that callback
|
||||
* if it was a one time timer (setTimeout), and not unregister it if it was
|
||||
* recurring (setInterval).
|
||||
*/
|
||||
callTimer: function(timerID) {
|
||||
warning(timerID <= JSTimersExecution.GUID, 'Tried to call timer with ID ' + timerID + ' but no such timer exists');
|
||||
var timerIndex = JSTimersExecution.timerIDs.indexOf(timerID);
|
||||
// timerIndex of -1 means that no timer with that ID exists. There are
|
||||
// two situations when this happens, when a garbage timer ID was given
|
||||
// and when a previously existing timer was deleted before this callback
|
||||
// fired. In both cases we want to ignore the timer id, but in the former
|
||||
// case we warn as well.
|
||||
if (timerIndex === -1) {
|
||||
return;
|
||||
}
|
||||
var type = JSTimersExecution.types[timerIndex];
|
||||
var callback = JSTimersExecution.callbacks[timerIndex];
|
||||
|
||||
// Clear the metadata
|
||||
if (type === JSTimersExecution.Type.setTimeout ||
|
||||
type === JSTimersExecution.Type.setImmediate ||
|
||||
type === JSTimersExecution.Type.requestAnimationFrame) {
|
||||
JSTimersExecution._clearIndex(timerIndex);
|
||||
}
|
||||
|
||||
try {
|
||||
if (type === JSTimersExecution.Type.setTimeout ||
|
||||
type === JSTimersExecution.Type.setInterval ||
|
||||
type === JSTimersExecution.Type.setImmediate) {
|
||||
callback();
|
||||
} else if (type === JSTimersExecution.Type.requestAnimationFrame) {
|
||||
var currentTime = performanceNow();
|
||||
callback(currentTime);
|
||||
} else {
|
||||
console.error('Tried to call a callback with invalid type: ' + type);
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
// Don't rethrow so that we can run every other timer.
|
||||
JSTimersExecution.errors = JSTimersExecution.errors || [];
|
||||
JSTimersExecution.errors.push(e);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* This is called from the native side. We are passed an array of timerIDs,
|
||||
* and
|
||||
*/
|
||||
callTimers: function(timerIDs) {
|
||||
invariant(timerIDs.length !== 0, 'Probably shouldn\'t call "callTimers" with no timerIDs');
|
||||
|
||||
JSTimersExecution.errors = null;
|
||||
timerIDs.forEach(JSTimersExecution.callTimer);
|
||||
|
||||
var errors = JSTimersExecution.errors;
|
||||
if (errors) {
|
||||
var errorCount = errors.length;
|
||||
if (errorCount > 1) {
|
||||
// Throw all the other errors in a setTimeout, which will throw each
|
||||
// error one at a time
|
||||
for (var ii = 1; ii < errorCount; ii++) {
|
||||
require('JSTimers').setTimeout(
|
||||
((error) => { throw error; }).bind(null, errors[ii]),
|
||||
0
|
||||
);
|
||||
}
|
||||
}
|
||||
throw errors[0];
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* This is called after we execute any command we receive from native but
|
||||
* before we hand control back to native.
|
||||
*/
|
||||
callImmediates: function() {
|
||||
JSTimersExecution.errors = null;
|
||||
while (JSTimersExecution.immediates.length !== 0) {
|
||||
JSTimersExecution.callTimer(JSTimersExecution.immediates.shift());
|
||||
}
|
||||
if (JSTimersExecution.errors) {
|
||||
JSTimersExecution.errors.forEach((error) =>
|
||||
require('JSTimers').setTimeout(() => { throw error; }, 0)
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
_clearIndex: function(i) {
|
||||
JSTimersExecution.timerIDs[i] = null;
|
||||
JSTimersExecution.callbacks[i] = null;
|
||||
JSTimersExecution.types[i] = null;
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = JSTimersExecution;
|
||||
Reference in New Issue
Block a user