prepack
Version:
Execute a JS bundle, serialize global state and side effects to a snapshot that can be quickly restored.
1,652 lines (1,510 loc) • 52.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createMockReactNative = createMockReactNative;
var _index = require("../../values/index.js");
var _singletons = require("../../singletons.js");
var _invariant = _interopRequireDefault(require("../../invariant.js"));
var _parser = require("@babel/parser");
var _generator = require("../../utils/generator.js");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Copyright (c) 2017-present, 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.
*/
let reactNativeCode = `
function createReactNative(React, reactNameRequireName) {
var Platform = __abstract("object", 'require("' + reactNameRequireName + '").Platform');
var NativeModules = __abstract({
nativePerformanceNow: __abstract("function"),
nativeTraceBeginAsyncSection: __abstract("function"),
nativeTraceEndAsyncSection: __abstract("function"),
UIManager: __abstract({
customBubblingEventTypes: __abstract(),
customDirectEventTypes: __abstract(),
ViewManagerNames: __abstract(),
__takeSnapshot: undefined,
takeSnapshot: undefined,
RCTVirtualText: null,
}),
DeviceInfo: __abstract({
Dimensions: __abstract({
window: undefined,
screen: undefined,
windowPhysicalPixels: __abstract({
width: __abstract("number"),
height: __abstract("number"),
scale: __abstract("number"),
fontScale: __abstract("number"),
}),
screenPhysicalPixels: __abstract({
width: __abstract("number"),
height: __abstract("number"),
scale: __abstract("number"),
fontScale: __abstract("number"),
}),
}),
}),
I18n: __abstract({
localeCountryCode: __abstract(),
localeIdentifier: __abstract(),
fbLocaleIdentifier: __abstract(),
AdsCountriesConfig: __abstract({}),
exports: __abstract({}),
}),
I18nManager: __abstract({
isRTL: __abstract("boolean"),
isRTLForced: __abstract("boolean"),
doLeftAndRightSwapInRTL: __abstract("boolean"),
allowRTL: function(allowRTL) {
return __residual("void", function(allowRTL, global) {
global.nativeModuleProxy.I18nManager.allowRTL(allowRTL);
}, allowRTL, global);
},
forceRTL: function(forceRTL) {
return __residual("void", function(forceRTL, global) {
global.nativeModuleProxy.I18nManager.forceRTL(forceRTL);
}, forceRTL, global);
},
swapLeftAndRightInRTL: function(flipStyles) {
return __residual("void", function(flipStyles, global) {
global.nativeModuleProxy.I18nManager.swapLeftAndRightInRTL(flipStyles);
}, flipStyles, global);
},
exports: __abstract({}),
}),
DeviceEventManager: __abstract({}),
Timing: __abstract({
createTimer: function(id, duration, time, recurring) {
return __residual("object", function(id, duration, time, recurring, global, Object) {
global.nativeModuleProxy.Timing.createTimer(id, duration, time, recurring);
return Object.create(null);
}, id, duration, time, recurring, global, Object);
}
}),
ExceptionsManager: __abstract({
reportFatalException: function(message, stack, id) {
console.log("nativeModuleProxy.ExceptionsManager.reportFatalException");
console.log(message);
for (var i = 0; i < stack.length; i++) {
var s = stack[i];
console.log(" at " + s.methodName + " (" + s.file + ":" + s.lineNumber + ":" + s.column + ")");
}
}
}),
PlatformConstants: __abstract({
isTesting: false,
reactNativeVersion: __abstract({
major: 0,
minor: 0,
patch: 0,
prerelease: null,
}),
Version: __abstract("number"),
forceTouchAvailable: undefined,
uiMode: __abstract(),
}),
RelayAPIConfig: __abstract({
graphBatchURI: __abstract(),
}),
SourceCode: __abstract({
scriptURL: __abstract("string"),
}),
}, 'require("' + reactNameRequireName + '").NativeModules');
const {UIManager} = NativeModules;
const ReactNativeViewAttributes = {};
const viewConfigCallbacks = new Map();
const TextAncestor = React.createContext(false);
const ReactNativeStyleAttributes = {};
const dummySize = {width: undefined, height: undefined};
const sizesDiffer = function(one, two) {
one = one || dummySize;
two = two || dummySize;
return one !== two && (one.width !== two.width || one.height !== two.height);
};
ReactNativeStyleAttributes.transform = {process: processTransform};
ReactNativeStyleAttributes.shadowOffset = {diff: sizesDiffer};
const colorAttributes = {process: processColor};
ReactNativeStyleAttributes.backgroundColor = colorAttributes;
ReactNativeStyleAttributes.borderBottomColor = colorAttributes;
ReactNativeStyleAttributes.borderColor = colorAttributes;
ReactNativeStyleAttributes.borderLeftColor = colorAttributes;
ReactNativeStyleAttributes.borderRightColor = colorAttributes;
ReactNativeStyleAttributes.borderTopColor = colorAttributes;
ReactNativeStyleAttributes.borderStartColor = colorAttributes;
ReactNativeStyleAttributes.borderEndColor = colorAttributes;
ReactNativeStyleAttributes.color = colorAttributes;
ReactNativeStyleAttributes.shadowColor = colorAttributes;
ReactNativeStyleAttributes.textDecorationColor = colorAttributes;
ReactNativeStyleAttributes.tintColor = colorAttributes;
ReactNativeStyleAttributes.textShadowColor = colorAttributes;
ReactNativeStyleAttributes.overlayColor = colorAttributes;
ReactNativeViewAttributes.UIView = {
pointerEvents: true,
accessible: true,
accessibilityActions: true,
accessibilityLabel: true,
accessibilityComponentType: true,
accessibilityLiveRegion: true,
accessibilityRole: true,
accessibilityStates: true,
accessibilityTraits: true,
importantForAccessibility: true,
nativeID: true,
testID: true,
renderToHardwareTextureAndroid: true,
shouldRasterizeIOS: true,
onLayout: true,
onAccessibilityAction: true,
onAccessibilityTap: true,
onMagicTap: true,
collapsable: true,
needsOffscreenAlphaCompositing: true,
style: ReactNativeStyleAttributes,
};
ReactNativeViewAttributes.RCTView = Object.assign({},
ReactNativeViewAttributes.UIView,
{ removeClippedSubviews: true }
);
var viewConfig = {
validAttributes: Object.assign({}, ReactNativeViewAttributes.UIView, {
isHighlighted: true,
numberOfLines: true,
ellipsizeMode: true,
allowFontScaling: true,
disabled: true,
selectable: true,
selectionColor: true,
adjustsFontSizeToFit: true,
minimumFontScale: true,
textBreakStrategy: true
}),
uiViewClassName: 'RCTText'
};
var MatrixMath = {
createIdentityMatrix: function() {
return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
},
createCopy: function(m) {
return [
m[0],
m[1],
m[2],
m[3],
m[4],
m[5],
m[6],
m[7],
m[8],
m[9],
m[10],
m[11],
m[12],
m[13],
m[14],
m[15],
];
},
createOrthographic: function(left, right, bottom, top, near, far) {
const a = 2 / (right - left);
const b = 2 / (top - bottom);
const c = -2 / (far - near);
const tx = -(right + left) / (right - left);
const ty = -(top + bottom) / (top - bottom);
const tz = -(far + near) / (far - near);
return [a, 0, 0, 0, 0, b, 0, 0, 0, 0, c, 0, tx, ty, tz, 1];
},
createFrustum: function(left, right, bottom, top, near, far) {
const r_width = 1 / (right - left);
const r_height = 1 / (top - bottom);
const r_depth = 1 / (near - far);
const x = 2 * (near * r_width);
const y = 2 * (near * r_height);
const A = (right + left) * r_width;
const B = (top + bottom) * r_height;
const C = (far + near) * r_depth;
const D = 2 * (far * near * r_depth);
return [x, 0, 0, 0, 0, y, 0, 0, A, B, C, -1, 0, 0, D, 0];
},
/**
* This create a perspective projection towards negative z
* Clipping the z range of [-near, -far]
*
* @param fovInRadians - field of view in randians
*/
createPerspective: function(fovInRadians, aspect, near, far) {
const h = 1 / Math.tan(fovInRadians / 2);
const r_depth = 1 / (near - far);
const C = (far + near) * r_depth;
const D = 2 * (far * near * r_depth);
return [h / aspect, 0, 0, 0, 0, h, 0, 0, 0, 0, C, -1, 0, 0, D, 0];
},
createTranslate2d: function(x, y) {
const mat = MatrixMath.createIdentityMatrix();
MatrixMath.reuseTranslate2dCommand(mat, x, y);
return mat;
},
reuseTranslate2dCommand: function(matrixCommand, x, y) {
matrixCommand[12] = x;
matrixCommand[13] = y;
},
reuseTranslate3dCommand: function(matrixCommand, x, y, z) {
matrixCommand[12] = x;
matrixCommand[13] = y;
matrixCommand[14] = z;
},
createScale: function(factor) {
const mat = MatrixMath.createIdentityMatrix();
MatrixMath.reuseScaleCommand(mat, factor);
return mat;
},
reuseScaleCommand: function(matrixCommand, factor) {
matrixCommand[0] = factor;
matrixCommand[5] = factor;
},
reuseScale3dCommand: function(matrixCommand, x, y, z) {
matrixCommand[0] = x;
matrixCommand[5] = y;
matrixCommand[10] = z;
},
reusePerspectiveCommand: function(matrixCommand, p) {
matrixCommand[11] = -1 / p;
},
reuseScaleXCommand(matrixCommand, factor) {
matrixCommand[0] = factor;
},
reuseScaleYCommand(matrixCommand, factor) {
matrixCommand[5] = factor;
},
reuseScaleZCommand(matrixCommand, factor) {
matrixCommand[10] = factor;
},
reuseRotateXCommand: function(matrixCommand, radians) {
matrixCommand[5] = Math.cos(radians);
matrixCommand[6] = Math.sin(radians);
matrixCommand[9] = -Math.sin(radians);
matrixCommand[10] = Math.cos(radians);
},
reuseRotateYCommand: function(matrixCommand, amount) {
matrixCommand[0] = Math.cos(amount);
matrixCommand[2] = -Math.sin(amount);
matrixCommand[8] = Math.sin(amount);
matrixCommand[10] = Math.cos(amount);
},
// http://www.w3.org/TR/css3-transforms/#recomposing-to-a-2d-matrix
reuseRotateZCommand: function(matrixCommand, radians) {
matrixCommand[0] = Math.cos(radians);
matrixCommand[1] = Math.sin(radians);
matrixCommand[4] = -Math.sin(radians);
matrixCommand[5] = Math.cos(radians);
},
createRotateZ: function(radians) {
const mat = MatrixMath.createIdentityMatrix();
MatrixMath.reuseRotateZCommand(mat, radians);
return mat;
},
reuseSkewXCommand: function(matrixCommand, radians) {
matrixCommand[4] = Math.tan(radians);
},
reuseSkewYCommand: function(matrixCommand, radians) {
matrixCommand[1] = Math.tan(radians);
},
multiplyInto: function(out, a, b) {
const a00 = a[0],
a01 = a[1],
a02 = a[2],
a03 = a[3],
a10 = a[4],
a11 = a[5],
a12 = a[6],
a13 = a[7],
a20 = a[8],
a21 = a[9],
a22 = a[10],
a23 = a[11],
a30 = a[12],
a31 = a[13],
a32 = a[14],
a33 = a[15];
let b0 = b[0],
b1 = b[1],
b2 = b[2],
b3 = b[3];
out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
b0 = b[4];
b1 = b[5];
b2 = b[6];
b3 = b[7];
out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
b0 = b[8];
b1 = b[9];
b2 = b[10];
b3 = b[11];
out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
b0 = b[12];
b1 = b[13];
b2 = b[14];
b3 = b[15];
out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
},
determinant(matrix) {
const [
m00,
m01,
m02,
m03,
m10,
m11,
m12,
m13,
m20,
m21,
m22,
m23,
m30,
m31,
m32,
m33,
] = matrix;
return (
m03 * m12 * m21 * m30 -
m02 * m13 * m21 * m30 -
m03 * m11 * m22 * m30 +
m01 * m13 * m22 * m30 +
m02 * m11 * m23 * m30 -
m01 * m12 * m23 * m30 -
m03 * m12 * m20 * m31 +
m02 * m13 * m20 * m31 +
m03 * m10 * m22 * m31 -
m00 * m13 * m22 * m31 -
m02 * m10 * m23 * m31 +
m00 * m12 * m23 * m31 +
m03 * m11 * m20 * m32 -
m01 * m13 * m20 * m32 -
m03 * m10 * m21 * m32 +
m00 * m13 * m21 * m32 +
m01 * m10 * m23 * m32 -
m00 * m11 * m23 * m32 -
m02 * m11 * m20 * m33 +
m01 * m12 * m20 * m33 +
m02 * m10 * m21 * m33 -
m00 * m12 * m21 * m33 -
m01 * m10 * m22 * m33 +
m00 * m11 * m22 * m33
);
},
/**
* Inverse of a matrix. Multiplying by the inverse is used in matrix math
* instead of division.
*
* Formula from:
* http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm
*/
inverse(matrix: Array<number>): Array<number> {
const det = MatrixMath.determinant(matrix);
if (!det) {
return matrix;
}
const [
m00,
m01,
m02,
m03,
m10,
m11,
m12,
m13,
m20,
m21,
m22,
m23,
m30,
m31,
m32,
m33,
] = matrix;
return [
(m12 * m23 * m31 -
m13 * m22 * m31 +
m13 * m21 * m32 -
m11 * m23 * m32 -
m12 * m21 * m33 +
m11 * m22 * m33) /
det,
(m03 * m22 * m31 -
m02 * m23 * m31 -
m03 * m21 * m32 +
m01 * m23 * m32 +
m02 * m21 * m33 -
m01 * m22 * m33) /
det,
(m02 * m13 * m31 -
m03 * m12 * m31 +
m03 * m11 * m32 -
m01 * m13 * m32 -
m02 * m11 * m33 +
m01 * m12 * m33) /
det,
(m03 * m12 * m21 -
m02 * m13 * m21 -
m03 * m11 * m22 +
m01 * m13 * m22 +
m02 * m11 * m23 -
m01 * m12 * m23) /
det,
(m13 * m22 * m30 -
m12 * m23 * m30 -
m13 * m20 * m32 +
m10 * m23 * m32 +
m12 * m20 * m33 -
m10 * m22 * m33) /
det,
(m02 * m23 * m30 -
m03 * m22 * m30 +
m03 * m20 * m32 -
m00 * m23 * m32 -
m02 * m20 * m33 +
m00 * m22 * m33) /
det,
(m03 * m12 * m30 -
m02 * m13 * m30 -
m03 * m10 * m32 +
m00 * m13 * m32 +
m02 * m10 * m33 -
m00 * m12 * m33) /
det,
(m02 * m13 * m20 -
m03 * m12 * m20 +
m03 * m10 * m22 -
m00 * m13 * m22 -
m02 * m10 * m23 +
m00 * m12 * m23) /
det,
(m11 * m23 * m30 -
m13 * m21 * m30 +
m13 * m20 * m31 -
m10 * m23 * m31 -
m11 * m20 * m33 +
m10 * m21 * m33) /
det,
(m03 * m21 * m30 -
m01 * m23 * m30 -
m03 * m20 * m31 +
m00 * m23 * m31 +
m01 * m20 * m33 -
m00 * m21 * m33) /
det,
(m01 * m13 * m30 -
m03 * m11 * m30 +
m03 * m10 * m31 -
m00 * m13 * m31 -
m01 * m10 * m33 +
m00 * m11 * m33) /
det,
(m03 * m11 * m20 -
m01 * m13 * m20 -
m03 * m10 * m21 +
m00 * m13 * m21 +
m01 * m10 * m23 -
m00 * m11 * m23) /
det,
(m12 * m21 * m30 -
m11 * m22 * m30 -
m12 * m20 * m31 +
m10 * m22 * m31 +
m11 * m20 * m32 -
m10 * m21 * m32) /
det,
(m01 * m22 * m30 -
m02 * m21 * m30 +
m02 * m20 * m31 -
m00 * m22 * m31 -
m01 * m20 * m32 +
m00 * m21 * m32) /
det,
(m02 * m11 * m30 -
m01 * m12 * m30 -
m02 * m10 * m31 +
m00 * m12 * m31 +
m01 * m10 * m32 -
m00 * m11 * m32) /
det,
(m01 * m12 * m20 -
m02 * m11 * m20 +
m02 * m10 * m21 -
m00 * m12 * m21 -
m01 * m10 * m22 +
m00 * m11 * m22) /
det,
];
},
/**
* Turns columns into rows and rows into columns.
*/
transpose(m: Array<number>): Array<number> {
return [
m[0],
m[4],
m[8],
m[12],
m[1],
m[5],
m[9],
m[13],
m[2],
m[6],
m[10],
m[14],
m[3],
m[7],
m[11],
m[15],
];
},
/**
* Based on: http://tog.acm.org/resources/GraphicsGems/gemsii/unmatrix.c
*/
multiplyVectorByMatrix(v: Array<number>, m: Array<number>): Array<number> {
const [vx, vy, vz, vw] = v;
return [
vx * m[0] + vy * m[4] + vz * m[8] + vw * m[12],
vx * m[1] + vy * m[5] + vz * m[9] + vw * m[13],
vx * m[2] + vy * m[6] + vz * m[10] + vw * m[14],
vx * m[3] + vy * m[7] + vz * m[11] + vw * m[15],
];
},
/**
* From: https://code.google.com/p/webgl-mjs/source/browse/mjs.js
*/
v3Length(a: Array<number>): number {
return Math.sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
},
/**
* Based on: https://code.google.com/p/webgl-mjs/source/browse/mjs.js
*/
v3Normalize(vector: Array<number>, v3Length: number): Array<number> {
const im = 1 / (v3Length || MatrixMath.v3Length(vector));
return [vector[0] * im, vector[1] * im, vector[2] * im];
},
/**
* The dot product of a and b, two 3-element vectors.
* From: https://code.google.com/p/webgl-mjs/source/browse/mjs.js
*/
v3Dot(a, b) {
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
},
/**
* From:
* http://www.opensource.apple.com/source/WebCore/WebCore-514/platform/graphics/transforms/TransformationMatrix.cpp
*/
v3Combine(
a: Array<number>,
b: Array<number>,
aScale: number,
bScale: number,
): Array<number> {
return [
aScale * a[0] + bScale * b[0],
aScale * a[1] + bScale * b[1],
aScale * a[2] + bScale * b[2],
];
},
/**
* From:
* http://www.opensource.apple.com/source/WebCore/WebCore-514/platform/graphics/transforms/TransformationMatrix.cpp
*/
v3Cross(a: Array<number>, b: Array<number>): Array<number> {
return [
a[1] * b[2] - a[2] * b[1],
a[2] * b[0] - a[0] * b[2],
a[0] * b[1] - a[1] * b[0],
];
},
/**
* Based on:
* http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/
* and:
* http://quat.zachbennett.com/
*
* Note that this rounds degrees to the thousandth of a degree, due to
* floating point errors in the creation of the quaternion.
*
* Also note that this expects the qw value to be last, not first.
*
* Also, when researching this, remember that:
* yaw === heading === z-axis
* pitch === elevation/attitude === y-axis
* roll === bank === x-axis
*/
quaternionToDegreesXYZ(q: Array<number>, matrix, row): Array<number> {
const [qx, qy, qz, qw] = q;
const qw2 = qw * qw;
const qx2 = qx * qx;
const qy2 = qy * qy;
const qz2 = qz * qz;
const test = qx * qy + qz * qw;
const unit = qw2 + qx2 + qy2 + qz2;
const conv = 180 / Math.PI;
if (test > 0.49999 * unit) {
return [0, 2 * Math.atan2(qx, qw) * conv, 90];
}
if (test < -0.49999 * unit) {
return [0, -2 * Math.atan2(qx, qw) * conv, -90];
}
return [
MatrixMath.roundTo3Places(
Math.atan2(2 * qx * qw - 2 * qy * qz, 1 - 2 * qx2 - 2 * qz2) * conv,
),
MatrixMath.roundTo3Places(
Math.atan2(2 * qy * qw - 2 * qx * qz, 1 - 2 * qy2 - 2 * qz2) * conv,
),
MatrixMath.roundTo3Places(Math.asin(2 * qx * qy + 2 * qz * qw) * conv),
];
},
/**
* Based on:
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round
*/
roundTo3Places(n: number): number {
const arr = n.toString().split('e');
return Math.round(arr[0] + 'e' + (arr[1] ? +arr[1] - 3 : 3)) * 0.001;
},
/**
* Decompose a matrix into separate transform values, for use on platforms
* where applying a precomposed matrix is not possible, and transforms are
* applied in an inflexible ordering (e.g. Android).
*
* Implementation based on
* http://www.w3.org/TR/css3-transforms/#decomposing-a-2d-matrix
* http://www.w3.org/TR/css3-transforms/#decomposing-a-3d-matrix
* which was based on
* http://tog.acm.org/resources/GraphicsGems/gemsii/unmatrix.c
*/
decomposeMatrix(transformMatrix: Array<number>): ?Object {
// output values
var perspective = [];
const quaternion = [];
const scale = [];
const skew = [];
const translation = [];
// create normalized, 2d array matrix
// and normalized 1d array perspectiveMatrix with redefined 4th column
if (!transformMatrix[15]) {
return;
}
const matrix = [];
const perspectiveMatrix = [];
for (var i = 0; i < 4; i++) {
matrix.push([]);
for (let j = 0; j < 4; j++) {
const value = transformMatrix[i * 4 + j] / transformMatrix[15];
matrix[i].push(value);
perspectiveMatrix.push(j === 3 ? 0 : value);
}
}
perspectiveMatrix[15] = 1;
// test for singularity of upper 3x3 part of the perspective matrix
if (!MatrixMath.determinant(perspectiveMatrix)) {
return;
}
// isolate perspective
if (matrix[0][3] !== 0 || matrix[1][3] !== 0 || matrix[2][3] !== 0) {
// rightHandSide is the right hand side of the equation.
// rightHandSide is a vector, or point in 3d space relative to the origin.
const rightHandSide = [
matrix[0][3],
matrix[1][3],
matrix[2][3],
matrix[3][3],
];
// Solve the equation by inverting perspectiveMatrix and multiplying
// rightHandSide by the inverse.
const inversePerspectiveMatrix = MatrixMath.inverse(perspectiveMatrix);
const transposedInversePerspectiveMatrix = MatrixMath.transpose(
inversePerspectiveMatrix,
);
var perspective = MatrixMath.multiplyVectorByMatrix(
rightHandSide,
transposedInversePerspectiveMatrix,
);
} else {
// no perspective
perspective[0] = perspective[1] = perspective[2] = 0;
perspective[3] = 1;
}
// translation is simple
for (var i = 0; i < 3; i++) {
translation[i] = matrix[3][i];
}
// Now get scale and shear.
// 'row' is a 3 element array of 3 component vectors
const row = [];
for (i = 0; i < 3; i++) {
row[i] = [matrix[i][0], matrix[i][1], matrix[i][2]];
}
// Compute X scale factor and normalize first row.
scale[0] = MatrixMath.v3Length(row[0]);
row[0] = MatrixMath.v3Normalize(row[0], scale[0]);
// Compute XY shear factor and make 2nd row orthogonal to 1st.
skew[0] = MatrixMath.v3Dot(row[0], row[1]);
row[1] = MatrixMath.v3Combine(row[1], row[0], 1.0, -skew[0]);
// Compute XY shear factor and make 2nd row orthogonal to 1st.
skew[0] = MatrixMath.v3Dot(row[0], row[1]);
row[1] = MatrixMath.v3Combine(row[1], row[0], 1.0, -skew[0]);
// Now, compute Y scale and normalize 2nd row.
scale[1] = MatrixMath.v3Length(row[1]);
row[1] = MatrixMath.v3Normalize(row[1], scale[1]);
skew[0] /= scale[1];
// Compute XZ and YZ shears, orthogonalize 3rd row
skew[1] = MatrixMath.v3Dot(row[0], row[2]);
row[2] = MatrixMath.v3Combine(row[2], row[0], 1.0, -skew[1]);
skew[2] = MatrixMath.v3Dot(row[1], row[2]);
row[2] = MatrixMath.v3Combine(row[2], row[1], 1.0, -skew[2]);
// Next, get Z scale and normalize 3rd row.
scale[2] = MatrixMath.v3Length(row[2]);
row[2] = MatrixMath.v3Normalize(row[2], scale[2]);
skew[1] /= scale[2];
skew[2] /= scale[2];
// At this point, the matrix (in rows) is orthonormal.
// Check for a coordinate system flip. If the determinant
// is -1, then negate the matrix and the scaling factors.
const pdum3 = MatrixMath.v3Cross(row[1], row[2]);
if (MatrixMath.v3Dot(row[0], pdum3) < 0) {
for (i = 0; i < 3; i++) {
scale[i] *= -1;
row[i][0] *= -1;
row[i][1] *= -1;
row[i][2] *= -1;
}
}
// Now, get the rotations out
quaternion[0] =
0.5 * Math.sqrt(Math.max(1 + row[0][0] - row[1][1] - row[2][2], 0));
quaternion[1] =
0.5 * Math.sqrt(Math.max(1 - row[0][0] + row[1][1] - row[2][2], 0));
quaternion[2] =
0.5 * Math.sqrt(Math.max(1 - row[0][0] - row[1][1] + row[2][2], 0));
quaternion[3] =
0.5 * Math.sqrt(Math.max(1 + row[0][0] + row[1][1] + row[2][2], 0));
if (row[2][1] > row[1][2]) {
quaternion[0] = -quaternion[0];
}
if (row[0][2] > row[2][0]) {
quaternion[1] = -quaternion[1];
}
if (row[1][0] > row[0][1]) {
quaternion[2] = -quaternion[2];
}
// correct for occasional, weird Euler synonyms for 2d rotation
let rotationDegrees;
if (
quaternion[0] < 0.001 &&
quaternion[0] >= 0 &&
quaternion[1] < 0.001 &&
quaternion[1] >= 0
) {
// this is a 2d rotation on the z-axis
rotationDegrees = [
0,
0,
MatrixMath.roundTo3Places(
Math.atan2(row[0][1], row[0][0]) * 180 / Math.PI,
),
];
} else {
rotationDegrees = MatrixMath.quaternionToDegreesXYZ(
quaternion,
matrix,
row,
);
}
// expose both base data and convenience names
return {
rotationDegrees,
perspective,
quaternion,
scale,
skew,
translation,
rotate: rotationDegrees[2],
rotateX: rotationDegrees[0],
rotateY: rotationDegrees[1],
scaleX: scale[0],
scaleY: scale[1],
translateX: translation[0],
translateY: translation[1],
};
},
};
function _multiplyTransform(result, matrixMathFunction, args): void {
const matrixToApply = MatrixMath.createIdentityMatrix();
const argsWithIdentity = [matrixToApply].concat(args);
matrixMathFunction.apply(this, argsWithIdentity);
MatrixMath.multiplyInto(result, result, matrixToApply);
}
function _convertToRadians(value: string): number {
const floatValue = parseFloat(value);
return value.indexOf('rad') > -1 ? floatValue : floatValue * Math.PI / 180;
}
function processTransform(transform) {
// Android & iOS implementations of transform property accept the list of
// transform properties as opposed to a transform Matrix. This is necessary
// to control transform property updates completely on the native thread.
if (Platform.OS === 'android' || Platform.OS === 'ios') {
return transform;
}
const result = MatrixMath.createIdentityMatrix();
transform.forEach(transformation => {
const key = Object.keys(transformation)[0];
const value = transformation[key];
switch (key) {
case 'matrix':
MatrixMath.multiplyInto(result, result, value);
break;
case 'perspective':
_multiplyTransform(result, MatrixMath.reusePerspectiveCommand, [value]);
break;
case 'rotateX':
_multiplyTransform(result, MatrixMath.reuseRotateXCommand, [
_convertToRadians(value),
]);
break;
case 'rotateY':
_multiplyTransform(result, MatrixMath.reuseRotateYCommand, [
_convertToRadians(value),
]);
break;
case 'rotate':
case 'rotateZ':
_multiplyTransform(result, MatrixMath.reuseRotateZCommand, [
_convertToRadians(value),
]);
break;
case 'scale':
_multiplyTransform(result, MatrixMath.reuseScaleCommand, [value]);
break;
case 'scaleX':
_multiplyTransform(result, MatrixMath.reuseScaleXCommand, [value]);
break;
case 'scaleY':
_multiplyTransform(result, MatrixMath.reuseScaleYCommand, [value]);
break;
case 'translate':
_multiplyTransform(result, MatrixMath.reuseTranslate3dCommand, [
value[0],
value[1],
value[2] || 0,
]);
break;
case 'translateX':
_multiplyTransform(result, MatrixMath.reuseTranslate2dCommand, [
value,
0,
]);
break;
case 'translateY':
_multiplyTransform(result, MatrixMath.reuseTranslate2dCommand, [
0,
value,
]);
break;
case 'skewX':
_multiplyTransform(result, MatrixMath.reuseSkewXCommand, [
_convertToRadians(value),
]);
break;
case 'skewY':
_multiplyTransform(result, MatrixMath.reuseSkewYCommand, [
_convertToRadians(value),
]);
break;
default:
throw new Error('Invalid transform name: ' + key);
}
});
return result;
}
function register(name, callback) {
viewConfigCallbacks.set(name, callback);
return name;
};
const createReactNativeComponentClass = function(name, callback) {
return register(name, callback);
};
const RCTText = createReactNativeComponentClass(
viewConfig.uiViewClassName,
function () { return viewConfig }
);
const RCTVirtualText = UIManager.RCTVirtualText == null
? RCTText
: createReactNativeComponentClass('RCTVirtualText', () => ({
validAttributes: Object.assign({},
ReactNativeViewAttributes.UIView,
{ isHighlighted: true }
),
uiViewClassName: 'RCTVirtualText',
}));
function normalizeColor(color) {
const matchers = getMatchers();
let match;
if (typeof color === 'number') {
if (color >>> 0 === color && color >= 0 && color <= 0xffffffff) {
return color;
}
return null;
}
// Ordered based on occurrences on Facebook codebase
if ((match = matchers.hex6.exec(color))) {
return parseInt(match[1] + 'ff', 16) >>> 0;
}
if (names.hasOwnProperty(color)) {
return names[color];
}
if ((match = matchers.rgb.exec(color))) {
return (
// b
((parse255(match[1]) << 24) | // r
(parse255(match[2]) << 16) | // g
(parse255(match[3]) << 8) |
0x000000ff) >>> // a
0
);
}
if ((match = matchers.rgba.exec(color))) {
return (
// b
((parse255(match[1]) << 24) | // r
(parse255(match[2]) << 16) | // g
(parse255(match[3]) << 8) |
parse1(match[4])) >>> // a
0
);
}
if ((match = matchers.hex3.exec(color))) {
return (
parseInt(
match[1] +
match[1] + // r
match[2] +
match[2] + // g
match[3] +
match[3] + // b
'ff', // a
16,
) >>> 0
);
}
// https://drafts.csswg.org/css-color-4/#hex-notation
if ((match = matchers.hex8.exec(color))) {
return parseInt(match[1], 16) >>> 0;
}
if ((match = matchers.hex4.exec(color))) {
return (
parseInt(
match[1] +
match[1] + // r
match[2] +
match[2] + // g
match[3] +
match[3] + // b
match[4] +
match[4], // a
16,
) >>> 0
);
}
if ((match = matchers.hsl.exec(color))) {
return (
(hslToRgb(
parse360(match[1]), // h
parsePercentage(match[2]), // s
parsePercentage(match[3]), // l
) |
0x000000ff) >>> // a
0
);
}
if ((match = matchers.hsla.exec(color))) {
return (
(hslToRgb(
parse360(match[1]), // h
parsePercentage(match[2]), // s
parsePercentage(match[3]), // l
) |
parse1(match[4])) >>> // a
0
);
}
return null;
}
function hue2rgb(p, q, t) {
if (t < 0) {
t += 1;
}
if (t > 1) {
t -= 1;
}
if (t < 1 / 6) {
return p + (q - p) * 6 * t;
}
if (t < 1 / 2) {
return q;
}
if (t < 2 / 3) {
return p + (q - p) * (2 / 3 - t) * 6;
}
return p;
}
function hslToRgb(h, s, l) {
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
const p = 2 * l - q;
const r = hue2rgb(p, q, h + 1 / 3);
const g = hue2rgb(p, q, h);
const b = hue2rgb(p, q, h - 1 / 3);
return (
(Math.round(r * 255) << 24) |
(Math.round(g * 255) << 16) |
(Math.round(b * 255) << 8)
);
}
// var INTEGER = '[-+]?\\d+';
const NUMBER = '[-+]?\\d*\\.?\\d+';
const PERCENTAGE = NUMBER + '%';
function call(...args) {
return '\\(\\s*(' + args.join(')\\s*,\\s*(') + ')\\s*\\)';
}
function getMatchers() {
var cachedMatchers = {
rgb: new RegExp('rgb' + call(NUMBER, NUMBER, NUMBER)),
rgba: new RegExp('rgba' + call(NUMBER, NUMBER, NUMBER, NUMBER)),
hsl: new RegExp('hsl' + call(NUMBER, PERCENTAGE, PERCENTAGE)),
hsla: new RegExp('hsla' + call(NUMBER, PERCENTAGE, PERCENTAGE, NUMBER)),
hex3: /^#([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
hex4: /^#([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
hex6: /^#([0-9a-fA-F]{6})$/,
hex8: /^#([0-9a-fA-F]{8})$/,
};
return cachedMatchers;
}
function parse255(str) {
const int = parseInt(str, 10);
if (int < 0) {
return 0;
}
if (int > 255) {
return 255;
}
return int;
}
function parse360(str) {
const int = parseFloat(str);
return (((int % 360) + 360) % 360) / 360;
}
function parse1(str) {
const num = parseFloat(str);
if (num < 0) {
return 0;
}
if (num > 1) {
return 255;
}
return Math.round(num * 255);
}
function parsePercentage(str) {
// parseFloat conveniently ignores the final %
const int = parseFloat(str);
if (int < 0) {
return 0;
}
if (int > 100) {
return 1;
}
return int / 100;
}
const names = {
transparent: 0x00000000,
// http://www.w3.org/TR/css3-color/#svg-color
aliceblue: 0xf0f8ffff,
antiquewhite: 0xfaebd7ff,
aqua: 0x00ffffff,
aquamarine: 0x7fffd4ff,
azure: 0xf0ffffff,
beige: 0xf5f5dcff,
bisque: 0xffe4c4ff,
black: 0x000000ff,
blanchedalmond: 0xffebcdff,
blue: 0x0000ffff,
blueviolet: 0x8a2be2ff,
brown: 0xa52a2aff,
burlywood: 0xdeb887ff,
burntsienna: 0xea7e5dff,
cadetblue: 0x5f9ea0ff,
chartreuse: 0x7fff00ff,
chocolate: 0xd2691eff,
coral: 0xff7f50ff,
cornflowerblue: 0x6495edff,
cornsilk: 0xfff8dcff,
crimson: 0xdc143cff,
cyan: 0x00ffffff,
darkblue: 0x00008bff,
darkcyan: 0x008b8bff,
darkgoldenrod: 0xb8860bff,
darkgray: 0xa9a9a9ff,
darkgreen: 0x006400ff,
darkgrey: 0xa9a9a9ff,
darkkhaki: 0xbdb76bff,
darkmagenta: 0x8b008bff,
darkolivegreen: 0x556b2fff,
darkorange: 0xff8c00ff,
darkorchid: 0x9932ccff,
darkred: 0x8b0000ff,
darksalmon: 0xe9967aff,
darkseagreen: 0x8fbc8fff,
darkslateblue: 0x483d8bff,
darkslategray: 0x2f4f4fff,
darkslategrey: 0x2f4f4fff,
darkturquoise: 0x00ced1ff,
darkviolet: 0x9400d3ff,
deeppink: 0xff1493ff,
deepskyblue: 0x00bfffff,
dimgray: 0x696969ff,
dimgrey: 0x696969ff,
dodgerblue: 0x1e90ffff,
firebrick: 0xb22222ff,
floralwhite: 0xfffaf0ff,
forestgreen: 0x228b22ff,
fuchsia: 0xff00ffff,
gainsboro: 0xdcdcdcff,
ghostwhite: 0xf8f8ffff,
gold: 0xffd700ff,
goldenrod: 0xdaa520ff,
gray: 0x808080ff,
green: 0x008000ff,
greenyellow: 0xadff2fff,
grey: 0x808080ff,
honeydew: 0xf0fff0ff,
hotpink: 0xff69b4ff,
indianred: 0xcd5c5cff,
indigo: 0x4b0082ff,
ivory: 0xfffff0ff,
khaki: 0xf0e68cff,
lavender: 0xe6e6faff,
lavenderblush: 0xfff0f5ff,
lawngreen: 0x7cfc00ff,
lemonchiffon: 0xfffacdff,
lightblue: 0xadd8e6ff,
lightcoral: 0xf08080ff,
lightcyan: 0xe0ffffff,
lightgoldenrodyellow: 0xfafad2ff,
lightgray: 0xd3d3d3ff,
lightgreen: 0x90ee90ff,
lightgrey: 0xd3d3d3ff,
lightpink: 0xffb6c1ff,
lightsalmon: 0xffa07aff,
lightseagreen: 0x20b2aaff,
lightskyblue: 0x87cefaff,
lightslategray: 0x778899ff,
lightslategrey: 0x778899ff,
lightsteelblue: 0xb0c4deff,
lightyellow: 0xffffe0ff,
lime: 0x00ff00ff,
limegreen: 0x32cd32ff,
linen: 0xfaf0e6ff,
magenta: 0xff00ffff,
maroon: 0x800000ff,
mediumaquamarine: 0x66cdaaff,
mediumblue: 0x0000cdff,
mediumorchid: 0xba55d3ff,
mediumpurple: 0x9370dbff,
mediumseagreen: 0x3cb371ff,
mediumslateblue: 0x7b68eeff,
mediumspringgreen: 0x00fa9aff,
mediumturquoise: 0x48d1ccff,
mediumvioletred: 0xc71585ff,
midnightblue: 0x191970ff,
mintcream: 0xf5fffaff,
mistyrose: 0xffe4e1ff,
moccasin: 0xffe4b5ff,
navajowhite: 0xffdeadff,
navy: 0x000080ff,
oldlace: 0xfdf5e6ff,
olive: 0x808000ff,
olivedrab: 0x6b8e23ff,
orange: 0xffa500ff,
orangered: 0xff4500ff,
orchid: 0xda70d6ff,
palegoldenrod: 0xeee8aaff,
palegreen: 0x98fb98ff,
paleturquoise: 0xafeeeeff,
palevioletred: 0xdb7093ff,
papayawhip: 0xffefd5ff,
peachpuff: 0xffdab9ff,
peru: 0xcd853fff,
pink: 0xffc0cbff,
plum: 0xdda0ddff,
powderblue: 0xb0e0e6ff,
purple: 0x800080ff,
rebeccapurple: 0x663399ff,
red: 0xff0000ff,
rosybrown: 0xbc8f8fff,
royalblue: 0x4169e1ff,
saddlebrown: 0x8b4513ff,
salmon: 0xfa8072ff,
sandybrown: 0xf4a460ff,
seagreen: 0x2e8b57ff,
seashell: 0xfff5eeff,
sienna: 0xa0522dff,
silver: 0xc0c0c0ff,
skyblue: 0x87ceebff,
slateblue: 0x6a5acdff,
slategray: 0x708090ff,
slategrey: 0x708090ff,
snow: 0xfffafaff,
springgreen: 0x00ff7fff,
steelblue: 0x4682b4ff,
tan: 0xd2b48cff,
teal: 0x008080ff,
thistle: 0xd8bfd8ff,
tomato: 0xff6347ff,
turquoise: 0x40e0d0ff,
violet: 0xee82eeff,
wheat: 0xf5deb3ff,
white: 0xffffffff,
whitesmoke: 0xf5f5f5ff,
yellow: 0xffff00ff,
yellowgreen: 0x9acd32ff,
};
function processColor(color) {
if (color === undefined || color === null) {
return color;
}
var int32Color = normalizeColor(color);
if (int32Color === null || int32Color === undefined) {
return undefined;
}
// Converts 0xrrggbbaa into 0xaarrggbb
int32Color = ((int32Color << 24) | (int32Color >>> 8)) >>> 0;
if (Platform.OS === 'android') {
// Android use 32 bit *signed* integer to represent the color
// We utilize the fact that bitwise operations in JS also operates on
// signed 32 bit integers, so that we can use those to convert from
// *unsigned* to *signed* 32bit int that way.
int32Color = int32Color | 0x0;
}
return int32Color;
}
const isTouchable = props =>
props.onPress != null ||
props.onLongPress != null ||
props.onStartShouldSetResponder != null;
// this is not a full implementation, but just for a hack
function TouchableText(props) {
var newProps = props;
if (isTouchable(newProps)) {
throw new Error("TODO: mocked TouchableText does not handle touch events");
}
if (props.selectionColor != null) {
newProps = Object.assign({}, props, {
selectionColor: processColor(props.selectionColor)
});
}
return (
React.createElement(
TextAncestor.Consumer,
null,
function (hasTextAncestor) {
return (
hasTextAncestor ? (
React.createElement(
RCTVirtualText,
Object.assign(
{},
newProps,
{ ref: newProps.forwardedRef }
)
)
) : (
React.createElement(
TextAncestor.Provider,
{ value: true },
React.createElement(
RCTText,
Object.assign(
{},
newProps,
{ ref: newProps.forwardedRef }
)
)
)
)
);
}
)
);
}
TouchableText.defaultProps = {
accessible: true,
allowFontScaling: true,
ellipsizeMode: 'tail',
};
function getDifferForType(typeName: string) {
switch (typeName) {
// iOS Types
case 'CATransform3D':
return matricesDiffer;
case 'CGPoint':
return pointsDiffer;
case 'CGSize':
return sizesDiffer;
case 'UIEdgeInsets':
return insetsDiffer;
// Android Types
// (not yet implemented)
}
return null;
}
function getProcessorForType(typeName) {
switch (typeName) {
// iOS Types
case 'CGColor':
case 'UIColor':
return processColor;
case 'CGColorArray':
case 'UIColorArray':
return processColorArray;
case 'CGImage':
case 'UIImage':
case 'RCTImageSource':
return resolveAssetSource;
// Android Types
case 'Color':
return processColor;
case 'ColorArray':
return processColorArray;
}
return null;
}
function merge(destination, source) {
if (!source) {
return destination;
}
if (!destination) {
return source;
}
for (const key in source) {
if (!source.hasOwnProperty(key)) {
continue;
}
let sourceValue = source[key];
if (destination.hasOwnProperty(key)) {
const destinationValue = destination[key];
if (
typeof sourceValue === 'object' &&
typeof destinationValue === 'object'
) {
sourceValue = merge(destinationValue, sourceValue);
}
}
destination[key] = sourceValue;
}
return destination;
}
function requireNativeComponent(uiViewClassName) {
return createReactNativeComponentClass(uiViewClassName, function() {
const viewConfig = UIManager[viewName];
let {baseModuleName, bubblingEventTypes, directEventTypes} = viewConfig;
let nativeProps = viewConfig.NativeProps;
while (baseModuleName) {
const baseModule = UIManager[baseModuleName];
if (!baseModule) {
baseModuleName = null;
} else {
bubblingEventTypes = Object.assign({}, baseModule.bubblingEventTypes, bubblingEventTypes);
directEventTypes = Object.assign({}, baseModule.directEventTypes, directEventTypes);
nativeProps = Object.assign({}, baseModule.NativeProps, nativeProps);
baseModuleName = baseModule.baseModuleName;
}
}
const viewAttributes = {};
for (const key in nativeProps) {
const typeName = nativeProps[key];
const diff = getDifferForType(typeName);
const process = getProcessorForType(typeName);
viewAttributes[key] =
diff == null && process == null ? true : {diff, process};
}
viewAttributes.style = ReactNativeStyleAttributes;
Object.assign(viewConfig, {
uiViewClassName: viewName,
validAttributes: viewAttributes,
bubblingEventTypes,
directEventTypes,
});
if (!hasAttachedDefaultEventTypes) {
attachDefaultEventTypes(viewConfig);
hasAttachedDefaultEventTypes = true;
}
return viewConfig;
});
}
var hasAttachedDefaultEventTypes = false;
function attachDefaultEventTypes(viewConfig) {
// This is supported on UIManager platforms (ex: Android),
// as lazy view managers are not implemented for all platforms.
// See [UIManager] for details on constants and implementations.
if (UIManager.ViewManagerNames) {
// Lazy view managers enabled.
viewConfig = merge(viewConfig, UIManager.getDefaultEventTypes());
} else {
viewConfig.bubblingEventTypes = merge(
viewConfig.bubblingEventTypes,
UIManager.genericBubblingEventTypes,
);
viewConfig.directEventTypes = merge(
viewConfig.directEventTypes,
UIManager.genericDirectEventTypes,
);
}
}
const Text = React.forwardRef(function(props, ref) {
return React.createElement(
TouchableText,
Object.assign(
{},
props
// { forwardedRef: ref }
)
);
});
const StyleSheet = {
create(obj){
return obj;
},
};
const RCTView = requireNativeComponent(
'RCTView',
{},
{
nativeOnly: {
nativeBackgroundAndroid: true,
nativeForegroundAndroid: true,
},
},
);