Use fbjs package from npm, gulp

This reworks a few things in building and distributing React. The biggest change is using fbjs to share dependencies with other libraries. We're also using Gulp for some build steps.
This commit is contained in:
Paul O’Shannessy
2015-07-17 18:20:38 -07:00
parent ac5e5d789f
commit 1d0c1b1817
49 changed files with 167 additions and 1637 deletions

View File

@@ -1,5 +1,8 @@
'use strict';
var assign = require('object-assign');
var path = require('path');
module.exports = function(grunt) {
grunt.initConfig({
@@ -21,6 +24,21 @@ module.exports = function(grunt) {
grunt.config.set('compress', require('./grunt/config/compress'));
function spawnGulp(args, opts, done) {
grunt.util.spawn({
// This could be more flexible (require.resolve & lookup bin in package)
// but if it breaks we'll fix it then.
cmd: path.join('node_modules', '.bin', 'gulpp'),
args: args,
opts: assign({stdio: 'inherit'}, opts),
}, function(err, result, code) {
if (err) {
grunt.fail.fatal('Something went wrong running gulp: ', result);
}
done(code === 0);
});
}
Object.keys(grunt.file.readJSON('package.json').devDependencies)
.filter(function(npmTaskName) {
return npmTaskName.indexOf('grunt-') === 0;
@@ -37,9 +55,8 @@ module.exports = function(grunt) {
grunt.registerTask('lint', ['eslint']);
grunt.registerTask('delete-build-modules', function() {
if (grunt.file.exists('build/modules')) {
grunt.file.delete('build/modules');
}
// Use gulp here
spawnGulp(['react:clean'], null, this.async());
});
// Register jsx:normal and :release tasks.
@@ -68,30 +85,30 @@ module.exports = function(grunt) {
grunt.registerTask('version-check', require('./grunt/tasks/version-check'));
grunt.registerTask('build:basic', [
'jsx:normal',
'build-modules',
'version-check',
'browserify:basic',
]);
grunt.registerTask('build:addons', [
'jsx:normal',
'build-modules',
'browserify:addons',
]);
grunt.registerTask('build:transformer', [
'jsx:normal',
'build-modules',
'browserify:transformer',
]);
grunt.registerTask('build:min', [
'jsx:normal',
'build-modules',
'version-check',
'browserify:min',
]);
grunt.registerTask('build:addons-min', [
'jsx:normal',
'build-modules',
'browserify:addonsMin',
]);
grunt.registerTask('build:npm-react', [
'version-check',
'jsx:normal',
'build-modules',
'npm-react:release',
]);
@@ -102,10 +119,10 @@ module.exports = function(grunt) {
grunt.registerTask('npm:test', ['build', 'npm:pack']);
// Optimized build task that does all of our builds. The subtasks will be run
// in order so we can take advantage of that and only run jsx:normal once.
// in order so we can take advantage of that and only run build-modules once.
grunt.registerTask('build', [
'delete-build-modules',
'jsx:normal',
'build-modules',
'version-check',
'browserify:basic',
'browserify:transformer',
@@ -141,6 +158,10 @@ module.exports = function(grunt) {
'release:msg',
]);
grunt.registerTask('build-modules', function() {
spawnGulp(['react:modules'], null, this.async());
});
// The default task - build - to keep setup easy.
grunt.registerTask('default', ['build']);
};

View File

@@ -1,16 +1,17 @@
#!/usr/bin/env node
// -*- mode: js -*-
// vim: set ft=javascript :
"use strict";
'use strict';
var babel = require('babel');
var constants = require('../vendor/constants')(babel);
var devExpressionPlugin = require('fbjs/scripts/babel/dev-expression');
var TRANSFORM_IGNORE_RE = /^WebComponents$/;
require("commoner").version(
require("../package.json").version
require('commoner').version(
require('../package.json').version
).resolve(function(id) {
var context = this;
@@ -38,8 +39,8 @@ require("commoner").version(
// This is where JSX, ES6, etc. desugaring happens.
source = babel.transform(source, {
blacklist: ['spec.functionName', 'validation.react'],
plugins: [constants],
filename: id
plugins: [devExpressionPlugin],
filename: id,
}).code;
}

View File

@@ -15,15 +15,18 @@ module.exports = function() {
config.transforms = config.transforms || [];
config.plugins = config.plugins || [];
config.after = config.after || [];
config.paths = config.paths || [];
// create the bundle we'll work with
var entries = grunt.file.expand(config.entries);
var paths = grunt.file.expand(config.paths);
// Extract other options
var options = {
entries: entries,
debug: config.debug, // sourcemaps
standalone: config.standalone, // global
paths: paths,
};
var bundle = browserify(options);

56
gulpfile.js Normal file
View File

@@ -0,0 +1,56 @@
/**
* 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.
*/
'use strict';
var gulp = require('gulp');
var babel = require('gulp-babel');
var flatten = require('gulp-flatten');
var del = require('del');
var babelPluginDEV = require('fbjs/scripts/babel/dev-expression');
var babelPluginRequires = require('fbjs/scripts/babel/rewrite-requires');
var paths = {
react: {
src: [
'src/**/*.js',
'!src/**/__tests__/**/*.js',
'!src/**/__mocks__/**/*.js',
],
lib: 'build/modules',
},
};
var babelOpts = {
nonStandard: true,
blacklist: [
'spec.functionName',
],
optional: [
'es7.trailingFunctionCommas',
],
plugins: [babelPluginDEV, babelPluginRequires],
ignore: ['third_party'],
_moduleMap: require('fbjs/module-map'),
};
gulp.task('react:clean', function(cb) {
del([paths.react.lib], cb);
});
gulp.task('react:modules', function() {
return gulp
.src(paths.react.src)
.pipe(babel(babelOpts))
.pipe(flatten())
.pipe(gulp.dest(paths.react.lib));
});
gulp.task('default', ['react:modules']);

View File

@@ -1,32 +0,0 @@
'use strict';
var babel = require('babel');
var coffee = require('coffee-script');
var tsPreprocessor = require('./ts-preprocessor');
var defaultLibraries = [
require.resolve('./jest.d.ts'),
require.resolve('../src/isomorphic/modern/class/React.d.ts'),
];
var ts = tsPreprocessor(defaultLibraries);
module.exports = {
process: function(src, path) {
if (path.match(/\.coffee$/)) {
return coffee.compile(src, {'bare': true});
}
if (path.match(/\.ts$/) && !path.match(/\.d\.ts$/)) {
return ts.compile(src, path);
}
if (!path.match(/\/node_modules\//) && !path.match(/\/third_party\//)) {
return babel.transform(src, {
blacklist: ['spec.functionName', 'validation.react'],
filename: path,
retainLines: true,
}).code;
}
return src;
},
};

View File

@@ -35,23 +35,31 @@
"browserify": "^9.0.3",
"bundle-collapser": "^1.1.1",
"coffee-script": "^1.8.0",
"del": "^1.2.0",
"derequire": "^2.0.0",
"envify": "^3.0.0",
"eslint": "^0.24.1",
"eslint-plugin-react": "^2.5.0",
"eslint-plugin-react-internal": "file:eslint-rules",
"eslint-tester": "^0.7.0",
"fbjs": "^0.1.0-alpha.0",
"grunt": "^0.4.5",
"grunt-cli": "^0.1.13",
"grunt-compare-size": "^0.4.0",
"grunt-contrib-clean": "^0.6.0",
"grunt-contrib-compress": "^0.13.0",
"grunt-jest": "^0.1.3",
"gulp": "^3.9.0",
"gulp-babel": "^5.1.0",
"gulp-flatten": "^0.1.0",
"gulp-util": "^3.0.5",
"gzip-js": "~0.3.2",
"jest-cli": "^0.4.13",
"object-assign": "^3.0.0",
"optimist": "^0.6.1",
"platform": "^1.1.0",
"run-sequence": "^1.1.0",
"through2": "^2.0.0",
"tmp": "~0.0.18",
"typescript": "~1.4.0",
"uglify-js": "^2.4.23",
@@ -66,21 +74,20 @@
},
"scripts": {
"build": "grunt build",
"jest": "jest",
"jest": "test",
"linc": "git diff --name-only --diff-filter=ACMRTUB `git merge-base HEAD master` | grep '\\.js$' | xargs eslint --",
"lint": "grunt lint",
"test": "jest"
"test": "NODE_ENV=test jest"
},
"jest": {
"modulePathIgnorePatterns": [
"/.module-cache/",
"/node_modules/",
"/react/build/"
],
"persistModuleRegistryBetweenSpecs": true,
"rootDir": "",
"scriptPreprocessor": "jest/preprocessor.js",
"setupEnvScriptFile": "jest/environment.js",
"scriptPreprocessor": "scripts/jest/preprocessor.js",
"setupEnvScriptFile": "scripts/jest/environment.js",
"testFileExtensions": [
"coffee",
"js",
@@ -88,7 +95,8 @@
],
"testPathDirs": [
"<rootDir>/eslint-rules",
"<rootDir>/src"
"<rootDir>/src",
"node_modules/fbjs"
],
"unmockedModulePathPatterns": [
""

View File

@@ -16,6 +16,7 @@
},
"homepage": "https://github.com/facebook/react/tree/master/npm-react-dom",
"dependencies": {
"fbjs": "0.1.0-alpha.0",
"react": "^0.14.0-beta1"
}
}

View File

@@ -24,7 +24,8 @@
"node": ">=0.10.0"
},
"dependencies": {
"envify": "^3.0.0"
"envify": "^3.0.0",
"fbjs": "0.1.0-alpha.0"
},
"browserify": {
"transform": [

View File

@@ -0,0 +1,50 @@
'use strict';
var babel = require('babel');
var coffee = require('coffee-script');
var tsPreprocessor = require('./ts-preprocessor');
var defaultLibraries = [
require.resolve('./jest.d.ts'),
require.resolve('../../src/isomorphic/modern/class/React.d.ts'),
];
var ts = tsPreprocessor(defaultLibraries);
// This assumes the module map has been built. This might not be safe.
// We should consider consuming this from a built fbjs module from npm.
var moduleMap = require('fbjs/module-map');
var babelPluginDEV = require('fbjs/scripts/babel/dev-expression');
var babelPluginRequires = require('fbjs/scripts/babel/rewrite-requires');
module.exports = {
process: function(src, path) {
if (path.match(/\.coffee$/)) {
return coffee.compile(src, {'bare': true});
}
if (path.match(/\.ts$/) && !path.match(/\.d\.ts$/)) {
return ts.compile(src, path);
}
// TODO: make sure this stays in sync with gulpfile
if (!path.match(/\/node_modules\//) && !path.match(/\/third_party\//)) {
var rv = babel.transform(src, {
nonStandard: true,
blacklist: [
'spec.functionName',
'validation.react',
],
optional: [
'es7.trailingFunctionCommas',
],
plugins: [babelPluginDEV, babelPluginRequires],
ignore: ['third_party'],
filename: path,
retainLines: true,
_moduleMap: moduleMap,
}).code;
return rv;
}
return src;
},
};

View File

@@ -11,10 +11,6 @@
'use strict';
require('mock-modules')
.dontMock('cloneWithProps')
.dontMock('emptyObject');
var React;
var ReactTestUtils;

View File

@@ -11,17 +11,6 @@
'use strict';
require('mock-modules')
.dontMock('EventPluginHub')
.dontMock('ReactMount')
.dontMock('ReactBrowserEventEmitter')
.dontMock('ReactInstanceHandles')
.dontMock('EventPluginHub')
.dontMock('TapEventPlugin')
.dontMock('TouchEventUtils')
.dontMock('keyOf');
var keyOf = require('keyOf');
var mocks = require('mocks');

View File

@@ -11,17 +11,12 @@
'use strict';
var mockModules = require('mock-modules');
mockModules.mock('getActiveElement');
var EventConstants;
var React;
var ReactMount;
var ReactTestUtils;
var SelectEventPlugin;
var getActiveElement;
var topLevelTypes;
describe('SelectEventPlugin', function() {
@@ -36,16 +31,12 @@ describe('SelectEventPlugin', function() {
}
beforeEach(function() {
mockModules.dumpCache();
EventConstants = require('EventConstants');
React = require('React');
ReactMount = require('ReactMount');
ReactTestUtils = require('ReactTestUtils');
SelectEventPlugin = require('SelectEventPlugin');
getActiveElement = require('getActiveElement');
topLevelTypes = EventConstants.topLevelTypes;
});
@@ -58,7 +49,7 @@ describe('SelectEventPlugin', function() {
var rendered = ReactTestUtils.renderIntoDocument(<WithoutSelect />);
var node = React.findDOMNode(rendered);
getActiveElement.mockReturnValue(node);
node.focus();
var mousedown = extract(node, topLevelTypes.topMouseDown);
expect(mousedown).toBe(null);
@@ -85,7 +76,7 @@ describe('SelectEventPlugin', function() {
node.selectionStart = 0;
node.selectionEnd = 0;
getActiveElement.mockReturnValue(node);
node.focus();
var focus = extract(node, topLevelTypes.topFocus);
expect(focus).toBe(null);

View File

@@ -11,13 +11,6 @@
'use strict';
require('mock-modules')
.dontMock('ExecutionEnvironment')
.dontMock('React')
.dontMock('ReactServerRendering')
.dontMock('ReactTestUtils')
.dontMock('ReactMarkupChecksum');
var mocks = require('mocks');
var ExecutionEnvironment;

View File

@@ -1 +0,0 @@
The files in this directory are not related to React's core functionality. They are shared utility modules that are also used in other parts of Facebook's front-end. Changes to these files need more consideration than changes to React itself.

View File

@@ -1,108 +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 CSSCore
* @typechecks
*/
var invariant = require('invariant');
/**
* The CSSCore module specifies the API (and implements most of the methods)
* that should be used when dealing with the display of elements (via their
* CSS classes and visibility on screen. It is an API focused on mutating the
* display and not reading it as no logical state should be encoded in the
* display of elements.
*/
var CSSCore = {
/**
* Adds the class passed in to the element if it doesn't already have it.
*
* @param {DOMElement} element the element to set the class on
* @param {string} className the CSS className
* @return {DOMElement} the element passed in
*/
addClass: function(element, className) {
invariant(
!/\s/.test(className),
'CSSCore.addClass takes only a single class name. "%s" contains ' +
'multiple classes.', className
);
if (className) {
if (element.classList) {
element.classList.add(className);
} else if (!CSSCore.hasClass(element, className)) {
element.className = element.className + ' ' + className;
}
}
return element;
},
/**
* Removes the class passed in from the element
*
* @param {DOMElement} element the element to set the class on
* @param {string} className the CSS className
* @return {DOMElement} the element passed in
*/
removeClass: function(element, className) {
invariant(
!/\s/.test(className),
'CSSCore.removeClass takes only a single class name. "%s" contains ' +
'multiple classes.', className
);
if (className) {
if (element.classList) {
element.classList.remove(className);
} else if (CSSCore.hasClass(element, className)) {
element.className = element.className
.replace(new RegExp('(^|\\s)' + className + '(?:\\s|$)', 'g'), '$1')
.replace(/\s+/g, ' ') // multiple spaces to one
.replace(/^\s*|\s*$/g, ''); // trim the ends
}
}
return element;
},
/**
* Helper to add or remove a class from an element based on a condition.
*
* @param {DOMElement} element the element to set the class on
* @param {string} className the CSS className
* @param {*} bool condition to whether to add or remove the class
* @return {DOMElement} the element passed in
*/
conditionClass: function(element, className, bool) {
return (bool ? CSSCore.addClass : CSSCore.removeClass)(element, className);
},
/**
* Tests whether the element has the class specified.
*
* @param {DOMNode|DOMWindow} element the element to set the class on
* @param {string} className the CSS className
* @return {boolean} true if the element has the class, false if not
*/
hasClass: function(element, className) {
invariant(
!/\s/.test(className),
'CSS.hasClass takes only a single class name.'
);
if (element.classList) {
return !!className && element.classList.contains(className);
}
return (' ' + element.className + ' ').indexOf(' ' + className + ' ') > -1;
}
};
module.exports = CSSCore;

View File

@@ -1,43 +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 ExecutionEnvironment
*/
/*jslint evil: true */
"use strict";
var canUseDOM = !!(
typeof window !== 'undefined' &&
window.document &&
window.document.createElement
);
/**
* Simple, lightweight module assisting with the detection and context of
* Worker. Helps avoid circular dependencies and allows code to reason about
* whether or not they are in a Worker, even if they never include the main
* `ReactWorker` dependency.
*/
var ExecutionEnvironment = {
canUseDOM: canUseDOM,
canUseWorkers: typeof Worker !== 'undefined',
canUseEventListeners:
canUseDOM && !!(window.addEventListener || window.attachEvent),
canUseViewport: canUseDOM && !!window.screen,
isInWorker: !canUseDOM // For now, this is true - might change in the future.
};
module.exports = ExecutionEnvironment;

View File

@@ -1,35 +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 TouchEventUtils
*/
var TouchEventUtils = {
/**
* Utility function for common case of extracting out the primary touch from a
* touch event.
* - `touchEnd` events usually do not have the `touches` property.
* http://stackoverflow.com/questions/3666929/
* mobile-sarai-touchend-event-not-firing-when-last-touch-is-removed
*
* @param {Event} nativeEvent Native event that may or may not be a touch.
* @return {TouchesObject?} an object with pageX and pageY or null.
*/
extractSingleTouch: function(nativeEvent) {
var touches = nativeEvent.touches;
var changedTouches = nativeEvent.changedTouches;
var hasTouches = touches && touches.length > 0;
var hasChangedTouches = changedTouches && changedTouches.length > 0;
return !hasTouches && hasChangedTouches ? changedTouches[0] :
hasTouches ? touches[0] :
nativeEvent;
}
};
module.exports = TouchEventUtils;

View File

@@ -1,30 +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 camelize
* @typechecks
*/
var _hyphenPattern = /-(.)/g;
/**
* Camelcases a hyphenated string, for example:
*
* > camelize('background-color')
* < "backgroundColor"
*
* @param {string} string
* @return {string}
*/
function camelize(string) {
return string.replace(_hyphenPattern, function(_, character) {
return character.toUpperCase();
});
}
module.exports = camelize;

View File

@@ -1,40 +0,0 @@
/**
* Copyright 2014-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 camelizeStyleName
* @typechecks
*/
"use strict";
var camelize = require('camelize');
var msPattern = /^-ms-/;
/**
* Camelcases a hyphenated CSS property name, for example:
*
* > camelizeStyleName('background-color')
* < "backgroundColor"
* > camelizeStyleName('-moz-transition')
* < "MozTransition"
* > camelizeStyleName('-ms-transition')
* < "msTransition"
*
* As Andi Smith suggests
* (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
* is converted to lowercase `ms`.
*
* @param {string} string
* @return {string}
*/
function camelizeStyleName(string) {
return camelize(string.replace(msPattern, 'ms-'));
}
module.exports = camelizeStyleName;

View File

@@ -1,85 +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 createArrayFromMixed
* @typechecks
*/
var toArray = require('toArray');
/**
* Perform a heuristic test to determine if an object is "array-like".
*
* A monk asked Joshu, a Zen master, "Has a dog Buddha nature?"
* Joshu replied: "Mu."
*
* This function determines if its argument has "array nature": it returns
* true if the argument is an actual array, an `arguments' object, or an
* HTMLCollection (e.g. node.childNodes or node.getElementsByTagName()).
*
* It will return false for other array-like objects like Filelist.
*
* @param {*} obj
* @return {boolean}
*/
function hasArrayNature(obj) {
return (
// not null/false
!!obj &&
// arrays are objects, NodeLists are functions in Safari
(typeof obj == 'object' || typeof obj == 'function') &&
// quacks like an array
('length' in obj) &&
// not window
!('setInterval' in obj) &&
// no DOM node should be considered an array-like
// a 'select' element has 'length' and 'item' properties on IE8
(typeof obj.nodeType != 'number') &&
(
// a real array
Array.isArray(obj) ||
// arguments
('callee' in obj) ||
// HTMLCollection/NodeList
('item' in obj)
)
);
}
/**
* Ensure that the argument is an array by wrapping it in an array if it is not.
* Creates a copy of the argument if it is already an array.
*
* This is mostly useful idiomatically:
*
* var createArrayFromMixed = require('createArrayFromMixed');
*
* function takesOneOrMoreThings(things) {
* things = createArrayFromMixed(things);
* ...
* }
*
* This allows you to treat `things' as an array, but accept scalars in the API.
*
* If you need to convert an array-like object, like `arguments`, into an array
* use toArray instead.
*
* @param {*} obj
* @return {array}
*/
function createArrayFromMixed(obj) {
if (!hasArrayNature(obj)) {
return [obj];
} else if (Array.isArray(obj)) {
return obj.slice();
} else {
return toArray(obj);
}
}
module.exports = createArrayFromMixed;

View File

@@ -1,86 +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 createNodesFromMarkup
* @typechecks
*/
/*jslint evil: true, sub: true */
var ExecutionEnvironment = require('ExecutionEnvironment');
var createArrayFromMixed = require('createArrayFromMixed');
var getMarkupWrap = require('getMarkupWrap');
var invariant = require('invariant');
/**
* Dummy container used to render all markup.
*/
var dummyNode =
ExecutionEnvironment.canUseDOM ? document.createElement('div') : null;
/**
* Pattern used by `getNodeName`.
*/
var nodeNamePattern = /^\s*<(\w+)/;
/**
* Extracts the `nodeName` of the first element in a string of markup.
*
* @param {string} markup String of markup.
* @return {?string} Node name of the supplied markup.
*/
function getNodeName(markup) {
var nodeNameMatch = markup.match(nodeNamePattern);
return nodeNameMatch && nodeNameMatch[1].toLowerCase();
}
/**
* Creates an array containing the nodes rendered from the supplied markup. The
* optionally supplied `handleScript` function will be invoked once for each
* <script> element that is rendered. If no `handleScript` function is supplied,
* an exception is thrown if any <script> elements are rendered.
*
* @param {string} markup A string of valid HTML markup.
* @param {?function} handleScript Invoked once for each rendered <script>.
* @return {array<DOMElement|DOMTextNode>} An array of rendered nodes.
*/
function createNodesFromMarkup(markup, handleScript) {
var node = dummyNode;
invariant(!!dummyNode, 'createNodesFromMarkup dummy not initialized');
var nodeName = getNodeName(markup);
var wrap = nodeName && getMarkupWrap(nodeName);
if (wrap) {
node.innerHTML = wrap[1] + markup + wrap[2];
var wrapDepth = wrap[0];
while (wrapDepth--) {
node = node.lastChild;
}
} else {
node.innerHTML = markup;
}
var scripts = node.getElementsByTagName('script');
if (scripts.length) {
invariant(
handleScript,
'createNodesFromMarkup(...): Unexpected <script> element rendered.'
);
createArrayFromMixed(scripts).forEach(handleScript);
}
var nodes = createArrayFromMixed(node.childNodes);
while (node.lastChild) {
node.removeChild(node.lastChild);
}
return nodes;
}
module.exports = createNodesFromMarkup;

View File

@@ -1,42 +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 containsNode
* @typechecks
*/
var isTextNode = require('isTextNode');
/*jslint bitwise:true */
/**
* Checks if a given DOM node contains or is another DOM node.
*
* @param {?DOMNode} outerNode Outer DOM node.
* @param {?DOMNode} innerNode Inner DOM node.
* @return {boolean} True if `outerNode` contains or is `innerNode`.
*/
function containsNode(outerNode, innerNode) {
if (!outerNode || !innerNode) {
return false;
} else if (outerNode === innerNode) {
return true;
} else if (isTextNode(outerNode)) {
return false;
} else if (isTextNode(innerNode)) {
return containsNode(outerNode, innerNode.parentNode);
} else if (outerNode.contains) {
return outerNode.contains(innerNode);
} else if (outerNode.compareDocumentPosition) {
return !!(outerNode.compareDocumentPosition(innerNode) & 16);
} else {
return false;
}
}
module.exports = containsNode;

View File

@@ -1,27 +0,0 @@
/**
* Copyright 2014-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 focusNode
*/
"use strict";
/**
* @param {DOMElement} node input/textarea to focus
*/
function focusNode(node) {
// IE8 can throw "Can't move focus to the control because it is invisible,
// not enabled, or of a type that does not accept the focus." for all kinds of
// reasons that are too expensive and fragile to test.
try {
node.focus();
} catch(e) {
}
}
module.exports = focusNode;

View File

@@ -1,27 +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 getActiveElement
* @typechecks
*/
/**
* Same as document.activeElement but wraps in a try-catch block. In IE it is
* not safe to call document.activeElement if there is nothing focused.
*
* The activeElement will be null only if the document body is not yet defined.
*/
function getActiveElement() /*?DOMElement*/ {
try {
return document.activeElement || document.body;
} catch (e) {
return document.body;
}
}
module.exports = getActiveElement;

View File

@@ -1,38 +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 getUnboundedScrollPosition
* @typechecks
*/
"use strict";
/**
* Gets the scroll position of the supplied element or window.
*
* The return values are unbounded, unlike `getScrollPosition`. This means they
* may be negative or exceed the element boundaries (which is possible using
* inertial scrolling).
*
* @param {DOMWindow|DOMElement} scrollable
* @return {object} Map with `x` and `y` keys.
*/
function getUnboundedScrollPosition(scrollable) {
if (scrollable === window) {
return {
x: window.pageXOffset || document.documentElement.scrollLeft,
y: window.pageYOffset || document.documentElement.scrollTop
};
}
return {
x: scrollable.scrollLeft,
y: scrollable.scrollTop
};
}
module.exports = getUnboundedScrollPosition;

View File

@@ -1,26 +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 isNode
* @typechecks
*/
/**
* @param {*} object The object to check.
* @return {boolean} Whether or not the object is a DOM node.
*/
function isNode(object) {
return !!(object && (
typeof Node === 'function' ? object instanceof Node :
typeof object === 'object' &&
typeof object.nodeType === 'number' &&
typeof object.nodeName === 'string'
));
}
module.exports = isNode;

View File

@@ -1,23 +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 isTextNode
* @typechecks
*/
var isNode = require('isNode');
/**
* @param {*} object The object to check.
* @return {boolean} Whether or not the object is a DOM text node.
*/
function isTextNode(object) {
return isNode(object) && object.nodeType == 3;
}
module.exports = isTextNode;

View File

@@ -1,32 +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 emptyFunction
*/
function makeEmptyFunction(arg) {
return function() {
return arg;
};
}
/**
* This function accepts and discards inputs; it has no side effects. This is
* primarily useful idiomatically for overridable function endpoints which
* always need to be callable, since JS lacks a null-call idiom ala Cocoa.
*/
function emptyFunction() {}
emptyFunction.thatReturns = makeEmptyFunction;
emptyFunction.thatReturnsFalse = makeEmptyFunction(false);
emptyFunction.thatReturnsTrue = makeEmptyFunction(true);
emptyFunction.thatReturnsNull = makeEmptyFunction(null);
emptyFunction.thatReturnsThis = function() { return this; };
emptyFunction.thatReturnsArgument = function(arg) { return arg; };
module.exports = emptyFunction;

View File

@@ -1,20 +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 emptyObject
*/
"use strict";
var emptyObject = {};
if (__DEV__) {
Object.freeze(emptyObject);
}
module.exports = emptyObject;

View File

@@ -1,112 +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 getMarkupWrap
*/
var ExecutionEnvironment = require('ExecutionEnvironment');
var invariant = require('invariant');
/**
* Dummy container used to detect which wraps are necessary.
*/
var dummyNode =
ExecutionEnvironment.canUseDOM ? document.createElement('div') : null;
/**
* Some browsers cannot use `innerHTML` to render certain elements standalone,
* so we wrap them, render the wrapped nodes, then extract the desired node.
*
* In IE8, certain elements cannot render alone, so wrap all elements ('*').
*/
var shouldWrap = {};
var selectWrap = [1, '<select multiple="true">', '</select>'];
var tableWrap = [1, '<table>', '</table>'];
var trWrap = [3, '<table><tbody><tr>', '</tr></tbody></table>'];
var svgWrap = [1, '<svg xmlns="http://www.w3.org/2000/svg">', '</svg>'];
var markupWrap = {
'*': [1, '?<div>', '</div>'],
'area': [1, '<map>', '</map>'],
'col': [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'],
'legend': [1, '<fieldset>', '</fieldset>'],
'param': [1, '<object>', '</object>'],
'tr': [2, '<table><tbody>', '</tbody></table>'],
'optgroup': selectWrap,
'option': selectWrap,
'caption': tableWrap,
'colgroup': tableWrap,
'tbody': tableWrap,
'tfoot': tableWrap,
'thead': tableWrap,
'td': trWrap,
'th': trWrap,
};
// Initilize the SVG elements since we know they'll always need to be wrapped
// consistently. If they are created inside a <div> they will be initialized in
// the wrong namespace (and will not display).
var svgElements = [
'circle',
'clipPath',
'defs',
'ellipse',
'g',
'image',
'line',
'linearGradient',
'mask',
'path',
'pattern',
'polygon',
'polyline',
'radialGradient',
'rect',
'stop',
'text',
'tspan',
];
svgElements.forEach((nodeName) => {
markupWrap[nodeName] = svgWrap;
shouldWrap[nodeName] = true;
});
/**
* Gets the markup wrap configuration for the supplied `nodeName`.
*
* NOTE: This lazily detects which wraps are necessary for the current browser.
*
* @param {string} nodeName Lowercase `nodeName`.
* @return {?array} Markup wrap configuration, if applicable.
*/
function getMarkupWrap(nodeName) {
invariant(!!dummyNode, 'Markup wrapping node not initialized');
if (!markupWrap.hasOwnProperty(nodeName)) {
nodeName = '*';
}
if (!shouldWrap.hasOwnProperty(nodeName)) {
if (nodeName === '*') {
dummyNode.innerHTML = '<link />';
} else {
dummyNode.innerHTML = '<' + nodeName + '></' + nodeName + '>';
}
shouldWrap[nodeName] = !dummyNode.firstChild;
}
return shouldWrap[nodeName] ? markupWrap[nodeName] : null;
}
module.exports = getMarkupWrap;

View File

@@ -1,31 +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 hyphenate
* @typechecks
*/
var _uppercasePattern = /([A-Z])/g;
/**
* Hyphenates a camelcased string, for example:
*
* > hyphenate('backgroundColor')
* < "background-color"
*
* For CSS style names, use `hyphenateStyleName` instead which works properly
* with all vendor prefixes, including `ms`.
*
* @param {string} string
* @return {string}
*/
function hyphenate(string) {
return string.replace(_uppercasePattern, '-$1').toLowerCase();
}
module.exports = hyphenate;

View File

@@ -1,39 +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 hyphenateStyleName
* @typechecks
*/
"use strict";
var hyphenate = require('hyphenate');
var msPattern = /^ms-/;
/**
* Hyphenates a camelcased CSS property name, for example:
*
* > hyphenateStyleName('backgroundColor')
* < "background-color"
* > hyphenateStyleName('MozTransition')
* < "-moz-transition"
* > hyphenateStyleName('msTransition')
* < "-ms-transition"
*
* As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix
* is converted to `-ms-`.
*
* @param {string} string
* @return {string}
*/
function hyphenateStyleName(string) {
return hyphenate(string).replace(msPattern, '-ms-');
}
module.exports = hyphenateStyleName;

View File

@@ -1,53 +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 invariant
*/
"use strict";
/**
* Use invariant() to assert state which your program assumes to be true.
*
* Provide sprintf-style format (only %s is supported) and arguments
* to provide information about what broke and what you were
* expecting.
*
* The invariant message will be stripped in production, but the invariant
* will remain to ensure logic does not differ in production.
*/
var invariant = function(condition, format, a, b, c, d, e, f) {
if (__DEV__) {
if (format === undefined) {
throw new Error('invariant requires an error message argument');
}
}
if (!condition) {
var error;
if (format === undefined) {
error = new Error(
'Minified exception occurred; use the non-minified dev environment ' +
'for the full error message and additional helpful warnings.'
);
} else {
var args = [a, b, c, d, e, f];
var argIndex = 0;
error = new Error(
'Invariant Violation: ' +
format.replace(/%s/g, function() { return args[argIndex++]; })
);
}
error.framesToPop = 1; // we don't care about invariant's own frame
throw error;
}
};
module.exports = invariant;

View File

@@ -1,51 +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 mapObject
*/
'use strict';
var hasOwnProperty = Object.prototype.hasOwnProperty;
/**
* Executes the provided `callback` once for each enumerable own property in the
* object and constructs a new object from the results. The `callback` is
* invoked with three arguments:
*
* - the property value
* - the property name
* - the object being traversed
*
* Properties that are added after the call to `mapObject` will not be visited
* by `callback`. If the values of existing properties are changed, the value
* passed to `callback` will be the value at the time `mapObject` visits them.
* Properties that are deleted before being visited are not visited.
*
* @grep function objectMap()
* @grep function objMap()
*
* @param {?object} object
* @param {function} callback
* @param {*} context
* @return {?object}
*/
function mapObject(object, callback, context) {
if (!object) {
return null;
}
var result = {};
for (var name in object) {
if (hasOwnProperty.call(object, name)) {
result[name] = callback.call(context, object[name], name, object);
}
}
return result;
}
module.exports = mapObject;

View File

@@ -1,30 +0,0 @@
/**
* Copyright 2014-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 monitorCodeUse
*/
"use strict";
var invariant = require('invariant');
/**
* Provides open-source compatible instrumentation for monitoring certain API
* uses before we're ready to issue a warning or refactor. It accepts an event
* name which may only contain the characters [a-z0-9_] and an optional data
* object with further information.
*/
function monitorCodeUse(eventName, data) {
invariant(
eventName && !/[^a-z0-9_]/.test(eventName),
'You must provide an eventName using only the characters [a-z0-9_]'
);
}
module.exports = monitorCodeUse;

View File

@@ -1,19 +0,0 @@
/**
* Copyright 2014-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 nativeRequestAnimationFrame
*/
var nativeRequestAnimationFrame =
global.requestAnimationFrame ||
global.webkitRequestAnimationFrame ||
global.mozRequestAnimationFrame ||
global.oRequestAnimationFrame ||
global.msRequestAnimationFrame;
module.exports = nativeRequestAnimationFrame;

View File

@@ -1,31 +0,0 @@
/**
* Copyright 2014-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 requestAnimationFrame
*/
var emptyFunction = require('emptyFunction');
var nativeRequestAnimationFrame = require('nativeRequestAnimationFrame');
var lastTime = 0;
var requestAnimationFrame =
nativeRequestAnimationFrame ||
function(callback) {
var currTime = Date.now();
var timeDelay = Math.max(0, 16 - (currTime - lastTime));
lastTime = currTime + timeDelay;
return global.setTimeout(function() {
callback(Date.now());
}, timeDelay);
};
// Works around a rare bug in Safari 6 where the first request is never invoked.
requestAnimationFrame(emptyFunction);
module.exports = requestAnimationFrame;

View File

@@ -1,66 +0,0 @@
/**
* Copyright 2014-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 toArray
* @typechecks
*/
var invariant = require('invariant');
/**
* Convert array-like objects to arrays.
*
* This API assumes the caller knows the contents of the data type. For less
* well defined inputs use createArrayFromMixed.
*
* @param {object|function|filelist} obj
* @return {array}
*/
function toArray(obj) {
var length = obj.length;
// Some browse builtin objects can report typeof 'function' (e.g. NodeList in
// old versions of Safari).
invariant(
!Array.isArray(obj) &&
(typeof obj === 'object' || typeof obj === 'function'),
'toArray: Array-like object expected'
);
invariant(
typeof length === 'number',
'toArray: Object needs a length property'
);
invariant(
length === 0 ||
(length - 1) in obj,
'toArray: Object should have keys for indices'
);
// Old IE doesn't give collections access to hasOwnProperty. Assume inputs
// without method will throw during the slice call and skip straight to the
// fallback.
if (obj.hasOwnProperty) {
try {
return Array.prototype.slice.call(obj);
} catch (e) {
// IE < 9 does not support Array#slice on collections objects
}
}
// Fall back to copying key by key. This assumes all keys have a value,
// so will not preserve sparsely populated inputs.
var ret = Array(length);
for (var ii = 0; ii < length; ii++) {
ret[ii] = obj[ii];
}
return ret;
}
module.exports = toArray;

View File

@@ -1,54 +0,0 @@
/**
* Copyright 2014-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 warning
*/
"use strict";
var emptyFunction = require('emptyFunction');
/**
* Similar to invariant but only logs a warning if the condition is not met.
* This can be used to log issues in development environments in critical
* paths. Removing the logging code for production environments will keep the
* same logic and follow the same code paths.
*/
var warning = emptyFunction;
if (__DEV__) {
warning = function(condition, format, ...args) {
if (format === undefined) {
throw new Error(
'`warning(condition, format, ...args)` requires a warning ' +
'message argument'
);
}
if (format.indexOf('Failed Composite propType: ') === 0) {
return; // Ignore CompositeComponent proptype check.
}
if (!condition) {
var argIndex = 0;
var message = 'Warning: ' + format.replace(/%s/g, () => args[argIndex++]);
if (typeof console !== 'undefined') {
console.error(message);
}
try {
// --- Welcome to debugging React ---
// This error was thrown as a convenience so that you can use this stack
// to find the callsite that caused this warning to fire.
throw new Error(message);
} catch(x) {}
}
};
}
module.exports = warning;

View File

@@ -1,64 +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.
*
* @emails react-core
*/
'use strict';
require('mock-modules').dontMock('keyMirror');
var keyMirror = require('keyMirror');
describe('keyMirror', function() {
it('should create an object with values matching keys provided', function() {
var mirror = keyMirror({
foo: null,
bar: true,
"baz": {some: "object"},
qux: undefined
});
expect('foo' in mirror).toBe(true);
expect(mirror.foo).toBe('foo');
expect('bar' in mirror).toBe(true);
expect(mirror.bar).toBe('bar');
expect('baz' in mirror).toBe(true);
expect(mirror.baz).toBe('baz');
expect('qux' in mirror).toBe(true);
expect(mirror.qux).toBe('qux');
});
it('should not use properties from prototypes', function() {
function Klass() {
this.useMeToo = true;
}
Klass.prototype.doNotUse = true;
var instance = new Klass();
instance.useMe = true;
var mirror = keyMirror(instance);
expect('doNotUse' in mirror).toBe(false);
expect('useMe' in mirror).toBe(true);
expect('useMeToo' in mirror).toBe(true);
});
it('should throw when a non-object argument is used', function() {
[null, undefined, 0, 7, ['uno'], true, "string"].forEach(function(testVal) {
expect(keyMirror.bind(null, testVal)).toThrow();
});
});
it('should work when "constructor" is a key', function() {
var obj = {constructor: true};
expect(keyMirror.bind(null, obj)).not.toThrow();
var mirror = keyMirror(obj);
expect('constructor' in mirror).toBe(true);
});
});

View File

@@ -1,51 +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 keyMirror
* @typechecks static-only
*/
'use strict';
var invariant = require('invariant');
/**
* Constructs an enumeration with keys equal to their value.
*
* For example:
*
* var COLORS = keyMirror({blue: null, red: null});
* var myColor = COLORS.blue;
* var isColorValid = !!COLORS[myColor];
*
* The last line could not be performed if the values of the generated enum were
* not equal to their keys.
*
* Input: {key1: val1, key2: val2}
* Output: {key1: key1, key2: key2}
*
* @param {object} obj
* @return {object}
*/
var keyMirror = function(obj) {
var ret = {};
var key;
invariant(
obj instanceof Object && !Array.isArray(obj),
'keyMirror(...): Argument must be an object.'
);
for (key in obj) {
if (!obj.hasOwnProperty(key)) {
continue;
}
ret[key] = key;
}
return ret;
};
module.exports = keyMirror;

View File

@@ -1,34 +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 keyOf
*/
/**
* Allows extraction of a minified key. Let's the build system minify keys
* without loosing the ability to dynamically use key strings as values
* themselves. Pass in an object with a single key/val pair and it will return
* you the string key of that single record. Suppose you want to grab the
* value for a key 'className' inside of an object. Key/val minification may
* have aliased that key to be 'xa12'. keyOf({className: null}) will return
* 'xa12' in that case. Resolve keys you want to use once at startup time, then
* reuse those resolutions.
*/
var keyOf = function(oneKeyObj) {
var key;
for (key in oneKeyObj) {
if (!oneKeyObj.hasOwnProperty(key)) {
continue;
}
return key;
}
return null;
};
module.exports = keyOf;

View File

@@ -1,26 +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 performance
* @typechecks
*/
"use strict";
var ExecutionEnvironment = require('ExecutionEnvironment');
var performance;
if (ExecutionEnvironment.canUseDOM) {
performance =
window.performance ||
window.msPerformance ||
window.webkitPerformance;
}
module.exports = performance || {};

View File

@@ -1,26 +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 performanceNow
* @typechecks
*/
var performance = require('performance');
/**
* Detect if we can use `window.performance.now()` and gracefully fallback to
* `Date.now()` if it doesn't exist. We need to support Firefox < 15 for now
* because of Facebook's testing infrastructure.
*/
if (!performance || !performance.now) {
performance = Date;
}
var performanceNow = performance.now.bind(performance);
module.exports = performanceNow;

View File

@@ -1,86 +0,0 @@
/**
* Copyright 2013-2015, Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @providesModule EventListener
* @typechecks
*/
var emptyFunction = require('emptyFunction');
/**
* Upstream version of event listener. Does not take into account specific
* nature of platform.
*/
var EventListener = {
/**
* Listen to DOM events during the bubble phase.
*
* @param {DOMEventTarget} target DOM element to register listener on.
* @param {string} eventType Event type, e.g. 'click' or 'mouseover'.
* @param {function} callback Callback function.
* @return {object} Object with a `remove` method.
*/
listen: function(target, eventType, callback) {
if (target.addEventListener) {
target.addEventListener(eventType, callback, false);
return {
remove: function() {
target.removeEventListener(eventType, callback, false);
}
};
} else if (target.attachEvent) {
target.attachEvent('on' + eventType, callback);
return {
remove: function() {
target.detachEvent('on' + eventType, callback);
}
};
}
},
/**
* Listen to DOM events during the capture phase.
*
* @param {DOMEventTarget} target DOM element to register listener on.
* @param {string} eventType Event type, e.g. 'click' or 'mouseover'.
* @param {function} callback Callback function.
* @return {object} Object with a `remove` method.
*/
capture: function(target, eventType, callback) {
if (target.addEventListener) {
target.addEventListener(eventType, callback, true);
return {
remove: function () {
target.removeEventListener(eventType, callback, true);
}
};
} else {
if (__DEV__) {
console.error(
'Attempted to listen to events during the capture phase on a ' +
'browser that does not support the capture phase. Your application ' +
'will not receive some events.'
);
}
return {
remove: emptyFunction
};
}
},
registerDefault: function() {}
};
module.exports = EventListener;

112
vendor/constants.js vendored
View File

@@ -1,112 +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.
*/
'use strict';
module.exports = function(babel) {
var t = babel.types;
var DEV_EXPRESSION = t.binaryExpression(
'!==',
t.literal('production'),
t.memberExpression(
t.memberExpression(
t.identifier('process'),
t.identifier('env'),
false
),
t.identifier('NODE_ENV'),
false
)
);
return new babel.Transformer('react.constants', {
Identifier: {
enter: function(node, parent) {
// replace __DEV__ with process.env.NODE_ENV !== 'production'
if (this.isIdentifier({name: '__DEV__'})) {
return DEV_EXPRESSION;
}
},
},
CallExpression: {
exit: function(node, parent) {
if (this.get('callee').isIdentifier({name: 'invariant'})) {
// Turns this code:
//
// invariant(condition, argument, argument);
//
// into this:
//
// if (!condition) {
// if ("production" !== process.env.NODE_ENV) {
// invariant(false, argument, argument);
// } else {
// invariant(false);
// }
// }
//
// Specifically this does 2 things:
// 1. Checks the condition first, preventing an extra function call.
// 2. Adds an environment check so that verbose error messages aren't
// shipped to production.
// The generated code is longer than the original code but will dead
// code removal in a minifier will strip that out.
var condition = node.arguments[0];
return t.ifStatement(
t.unaryExpression('!', condition),
t.blockStatement([
t.ifStatement(
DEV_EXPRESSION,
t.blockStatement([
t.expressionStatement(
t.callExpression(
node.callee,
[t.literal(false)].concat(node.arguments.slice(1))
)
),
]),
t.blockStatement([
t.expressionStatement(
t.callExpression(
node.callee,
[t.literal(false)]
)
),
])
),
])
);
} else if (this.get('callee').isIdentifier({name: 'warning'})) {
// Turns this code:
//
// warning(condition, argument, argument);
//
// into this:
//
// if ("production" !== process.env.NODE_ENV) {
// warning(condition, argument, argument);
// }
//
// The goal is to strip out warning calls entirely in production. We
// don't need the same optimizations for conditions that we use for
// invariant because we don't care about an extra call in __DEV__
return t.ifStatement(
DEV_EXPRESSION,
t.blockStatement([
t.expressionStatement(
node
),
])
);
}
},
},
});
};