pax_global_header 0000666 0000000 0000000 00000000064 13162307160 0014511 g ustar 00root root 0000000 0000000 52 comment=0a02fac537bf5e55fd8cd908af650454523d6b8c
fbjs-0.8.16/ 0000775 0000000 0000000 00000000000 13162307160 0012531 5 ustar 00root root 0000000 0000000 fbjs-0.8.16/.eslintignore 0000664 0000000 0000000 00000000160 13162307160 0015231 0 ustar 00root root 0000000 0000000 flow/
lib/
node_modules/
scripts/node_modules/
# TODO: Fix warnings upstream so this output becomes useful
src/
fbjs-0.8.16/.eslintrc.js 0000664 0000000 0000000 00000000171 13162307160 0014767 0 ustar 00root root 0000000 0000000 module.exports = {
parser: 'babel-eslint',
extends: [
'./node_modules/fbjs-scripts/eslint/.eslintrc.js',
],
};
fbjs-0.8.16/.gitignore 0000664 0000000 0000000 00000000061 13162307160 0014516 0 ustar 00root root 0000000 0000000 node_modules
npm-debug.log
lib/*
module-map.json
fbjs-0.8.16/.travis.yml 0000664 0000000 0000000 00000000222 13162307160 0014636 0 ustar 00root root 0000000 0000000 language: node_js
node_js:
- "4"
env:
- CMD=build
- CMD=test
- CMD=typecheck
- CMD=lint
- CMD=test-babel-presets
script: npm run $CMD
fbjs-0.8.16/CHANGELOG.md 0000664 0000000 0000000 00000012054 13162307160 0014344 0 ustar 00root root 0000000 0000000 ## [Unreleased]
## [0.8.16] - 2017-09-25
### Changed
- Relicense to MIT as part of React relicense.
## [0.8.15] - 2017-09-07
### Fixed
- `getDocumentScrollElement` now correctly returns the `` element in Chrome 61 instead of `
`.
## [0.8.14] - 2017-07-25
### Removed
- Flow annotations for `keyMirror` module. The annotation generates a syntax error after being re-printed by Babel.
## [0.8.13] - 2017-07-25
### Added
- Flow annotations for `keyMirror` module.
### Fixed
- Fixed strict argument arity issues with `Deferred` module.
- Corrected License header in `EventListener`.
## [0.8.12] - 2017-03-29
### Fixed
- Fix use of `global` working inconsistently.
## [0.8.11] - 2017-03-21
### Fixed
- Fixed a regression resulting from making DOM utilities work in nested browsing contexts.
## [0.8.10] - 2017-03-20
### Changed
- Made DOM utilities work in nested browsing contexts.
## [0.8.9] - 2017-01-31
### Fixed
- Updated `partitionObjectByKey` Flow annotations for Flow 0.38.
## [0.8.8] - 2016-12-20
### Changed
- `invariant`: Moved `process.env.NODE_ENV` check to module scope, eliminating check on each call.
## [0.8.7] - 2016-12-19
### Added
- New module: `setImmediate`.
## [0.8.6] - 2016-11-09
### Removed
- Removed runtime dependency on immutable, reducing package size.
## [0.8.5] - 2016-09-27
### Fixed
- Fixed all remaining issues resulting in Flow errors when `fbjs` is a dependency of a dependency.
### Removed
- Removed now extraneous `flow/lib/Promise.js`.
## [0.8.4] - 2016-08-19
### Changed
- Moved `try/catch` in `warning` module to helper function to prevent deopts.
## [0.8.3] - 2016-05-25
### Added
- `Deferred`: added `Deferred.prototype.catch` to avoid having to call this directly on the Promise.
- `UnicodeUtilsExtra`: added several methods for escaping strings.
### Changed
- More Flow annotations: `containsNode`, `emptyFunction`, `memoizeStringOnly`
- Added explicit `` type arguments to in anticipation of a future Flow change requiring them.
- `Object.assign` calls now replaced with usage of `object-assign` module.
### Fixed
- Type imports in .js.flow files are now properly using relative paths.
- `DataTransfer`: handle Firefox better
## [0.8.2] - 2016-05-05
### Removed
- Removed extraneous production dependency
## [0.8.1] - 2016-04-18
### Added
- We now include a `Promise` class definition in `flow/lib` to account for the changes in Flow v0.23 which removed non-spec methods. This will allow our code to continue typechecking while using these methods.
## [0.8.0] - 2016-04-04
### Added
- Several additional modules. Notably, a collection of Unicode utilities and many new `functional` helpers.
- `CSSCore`: added `matchesSelector` method
### Changed
- Copyright headers updated to reflect current boilerplate
- `@providesModule` headers removed from generated source code
- Flow files now contain relative requires, improving compatibility with Haste and CommonJS module systems
### Fixed
- `isEmpty`: Protect from breaking in environments without `Symbol` defined
## [0.7.2] - 2016-02-05
### Fixed
- `URI`: correctly store reference to value in constructor and return it when stringifying
### Removed
- Backed out rejection tracking for React Native `Promise` implementation. That code now lives in React Native.
## [0.7.1] - 2016-02-02
### Fixed
- Corrected require path issue for native `Promise` module
## [0.7.0] - 2016-01-27
### Added
- `Promise` for React Native with rejection tracking in `__DEV__` and a `finally` method
- `_shouldPolyfillES6Collection`: check if ES6 Collections need to be polyfilled.
### Removed
- `toArray`: removed in favor of using `Array.from` directly.
### Changed
- `ErrorUtils`: Re-uses any global instance that already exists
- `fetch`: Switched to `isomorphic-fetch` when a global implementation is missing
- `shallowEqual`: handles `NaN` values appropriately (as equal), now using `Object.is` semantics
## [0.6.1] - 2016-01-06
### Changed
- `getActiveElement`: no longer throws in non-browser environment (again)
## [0.6.0] - 2015-12-29
### Changed
- Flow: Original source files in `fbjs/flow/include` have been removed in favor of placing original files alongside compiled files in lib with a `.flow` suffix. This requires Flow version 0.19 or greater and a change to `.flowconfig` files to remove the include path.
## [0.5.1] - 2015-12-13
### Added
- `base62` module
## [0.5.0] - 2015-12-04
### Changed
- `getActiveElement`: No longer handles a non-existent `document`
## [0.4.0] - 2015-10-16
### Changed
- `invariant`: Message is no longer prefixed with "Invariant Violation: ".
## [0.3.2] - 2015-10-12
### Added
- Apply appropriate transform (`loose-envify`) when bundling with `browserify`
## [0.3.1] - 2015-10-01
### Fixed
- Ensure the build completes correctly before packaging
## [0.3.0] - 2015-10-01
### Added
- More modules: `memoizeStringOnly`, `joinClasses`
- `UserAgent`: Query information about current user agent
### Changed
- `fetchWithRetries`: Reject failure with an Error, not the response
- `getActiveElement`: no longer throws in non-browser environment
fbjs-0.8.16/LICENSE 0000664 0000000 0000000 00000002070 13162307160 0013535 0 ustar 00root root 0000000 0000000 MIT License
Copyright (c) 2013-present, Facebook, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
fbjs-0.8.16/README.md 0000664 0000000 0000000 00000005527 13162307160 0014021 0 ustar 00root root 0000000 0000000 # FBJS
## Purpose
To make it easier for Facebook to share and consume our own JavaScript. Primarily this will allow us to ship code without worrying too much about where it lives, keeping with the spirit of `@providesModule` but working in the broader JavaScript ecosystem.
**Note:** If you are consuming the code here and you are not also a Facebook project, be prepared for a bad time. APIs may appear or disappear and we may not follow semver strictly, though we will do our best to. This library is being published with our use cases in mind and is not necessarily meant to be consumed by the broader public. In order for us to move fast and ship projects like React and Relay, we've made the decision to not support everybody. We probably won't take your feature requests unless they align with our needs. There will be overlap in functionality here and in other open source projects.
## Usage
Any `@providesModule` modules that are used by your project should be added to `src/`. They will be built and added to `module-map.json`. This file will contain a map from `@providesModule` name to what will be published as `fbjs`. The `module-map.json` file can then be consumed in your own project, along with the [rewrite-modules](https://github.com/facebook/fbjs/blob/master/babel-preset/plugins/rewrite-modules.js) Babel plugin (which we'll publish with this), to rewrite requires in your own project. Then, just make sure `fbjs` is a dependency in your `package.json` and your package will consume the shared code.
```js
// Before transform
const emptyFunction = require('emptyFunction');
// After transform
const emptyFunction = require('fbjs/lib/emptyFunction');
```
See React for an example of this. *Coming soon!*
## Building
It's as easy as just running gulp. This assumes you've also done `npm install -g gulp`.
```sh
gulp
```
Alternatively `npm run build` will also work.
### Layout
Right now these packages represent a subset of packages that we use internally at Facebook. Mostly these are support libraries used when shipping larger libraries, like React and Relay, or products. Each of these packages is in its own directory under `src/`.
### Process
Since we use `@providesModule`, we need to rewrite requires to be relative. Thanks to `@providesModule` requiring global uniqueness, we can do this easily. Eventually we'll try to make this part of the process go away by making more projects use CommonJS.
## TODO
- Flow: Ideally we'd ship our original files with type annotations, however that's not doable right now. We have a couple options:
- Make sure our transpilation step converts inline type annotations to the comment format.
- Make our build process also build Flow interface files which we can ship to npm.
- Split into multiple packages. This will be better for more concise versioning, otherwise we'll likely just be shipping lots of major versions.
fbjs-0.8.16/babel-preset/ 0000775 0000000 0000000 00000000000 13162307160 0015076 5 ustar 00root root 0000000 0000000 fbjs-0.8.16/babel-preset/.gitignore 0000664 0000000 0000000 00000000033 13162307160 0017062 0 ustar 00root root 0000000 0000000 node_modules
npm-debug.log
fbjs-0.8.16/babel-preset/.npmignore 0000664 0000000 0000000 00000000045 13162307160 0017074 0 ustar 00root root 0000000 0000000 __tests__
node_modules
npm-debug.log
fbjs-0.8.16/babel-preset/CHANGELOG.md 0000664 0000000 0000000 00000001262 13162307160 0016710 0 ustar 00root root 0000000 0000000 ## [Unreleased]
## [2.0.0] - 2016-05-25
### Added
- More syntaxes are parsed for `.js.flow` file generation: `babel-plugin-syntax-class-properties` & `babel-plugin-syntax-jsx`
- More transforms are applied for ES2015 and React support: `babel-plugin-transform-es2015-function-name`, `babel-plugin-transform-react-display-name`, `babel-plugin-transform-react-jsx`
- New custom transform to convert `Object.assign` to `require('object-assign')`, ensuring the use of a ponyfill that checks for a spec-compliant `Object.assign`.
### Fixed
- Type imports are properly rewritten with the rewrite-modules transform.
## [1.0.0] - 2016-04-28
### Added
- Initial release as a separate module.
fbjs-0.8.16/babel-preset/README.md 0000664 0000000 0000000 00000001163 13162307160 0016356 0 ustar 00root root 0000000 0000000 # babel-preset-fbjs
> Babel preset for Facebook projects.
## Install
```sh
$ npm install --save-dev babel-preset-fbjs
```
## Basic Usage
### Via `.babelrc`
**.babelrc**
```json
{
"presets": ["fbjs"]
}
```
### Via CLI
```sh
$ babel script.js --presets fbjs
```
### Via Node API
```javascript
require('babel-core').transform('code', {
presets: ['fbjs']
});
```
## Advanced Usage
```javascript
require('babel-core').transform('code', {
presets: [
require('babel-preset-fbjs/configure')({
autoImport: true,
inlineRequires: false,
rewriteModules: {},
stripDEV: false
}
]
});
```
fbjs-0.8.16/babel-preset/configure.js 0000664 0000000 0000000 00000007076 13162307160 0017427 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
/* eslint-disable indent */
module.exports = function(options) {
options = Object.assign({
autoImport: true,
inlineRequires: process.env.NODE_ENV === 'test',
objectAssign: true,
rewriteModules: null, // {map: ?{[module: string]: string}, prefix: ?string}
stripDEV: false,
target: 'js',
}, options);
if (options.target !== 'js' && options.target !== 'flow') {
throw new Error('options.target must be one of "js" or "flow".');
}
// Always enable these. These will overlap with some transforms (which also
// enable the corresponding syntax, eg Flow), but these are the minimal
// additional syntaxes that need to be enabled so we can minimally transform
// to .js.flow files as well.
let presetSets = [
[
require('babel-plugin-syntax-class-properties'),
require('babel-plugin-syntax-flow'),
require('babel-plugin-syntax-jsx'),
require('babel-plugin-syntax-trailing-function-commas'),
require('babel-plugin-syntax-object-rest-spread'),
options.autoImport ? require('./plugins/auto-importer') : null,
options.rewriteModules ?
[require('./plugins/rewrite-modules'), options.rewriteModules || {}] :
null,
],
[
options.inlineRequires ? require('./plugins/inline-requires') : null,
options.stripDEV ? require('./plugins/dev-expression') : null,
]
];
// Enable everything else for js.
if (options.target === 'js') {
presetSets[0] = presetSets[0].concat([
require('babel-plugin-transform-es2015-template-literals'),
require('babel-plugin-transform-es2015-literals'),
require('babel-plugin-transform-es2015-function-name'),
require('babel-plugin-transform-es2015-arrow-functions'),
require('babel-plugin-transform-es2015-block-scoped-functions'),
require('babel-plugin-transform-class-properties'),
[require('babel-plugin-transform-es2015-classes'), {loose: true}],
require('babel-plugin-transform-es2015-object-super'),
require('babel-plugin-transform-es2015-shorthand-properties'),
require('babel-plugin-transform-es2015-computed-properties'),
require('babel-plugin-transform-es2015-for-of'),
require('babel-plugin-check-es2015-constants'),
[require('babel-plugin-transform-es2015-spread'), {loose: true}],
require('babel-plugin-transform-es2015-parameters'),
[require('babel-plugin-transform-es2015-destructuring'), {loose: true}],
require('babel-plugin-transform-es2015-block-scoping'),
require('babel-plugin-transform-es2015-modules-commonjs'),
require('babel-plugin-transform-es3-member-expression-literals'),
require('babel-plugin-transform-es3-property-literals'),
require('babel-plugin-transform-flow-strip-types'),
require('babel-plugin-transform-object-rest-spread'),
require('babel-plugin-transform-react-display-name'),
require('babel-plugin-transform-react-jsx'),
// Don't enable this plugin unless we're compiling JS, even if the option is true
options.objectAssign ? require('./plugins/object-assign') : null,
]);
}
// Use two passes to circumvent bug with auto-importer and inline-requires.
const passPresets = presetSets.map(function(plugins) {
return {
plugins: plugins.filter(function(plugin) {
return plugin != null;
}),
};
});
return {
passPerPreset: true,
presets: passPresets,
};
};
fbjs-0.8.16/babel-preset/index.js 0000664 0000000 0000000 00000000345 13162307160 0016545 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
module.exports = require('./configure')({});
fbjs-0.8.16/babel-preset/package.json 0000664 0000000 0000000 00000004267 13162307160 0017375 0 ustar 00root root 0000000 0000000 {
"name": "babel-preset-fbjs",
"version": "2.0.0",
"description": "Babel preset for Facebook projects.",
"repository": "facebook/fbjs",
"license": "MIT",
"main": "index.js",
"scripts": {
"test": "NODE_ENV=test jest"
},
"dependencies": {
"babel-plugin-check-es2015-constants": "^6.8.0",
"babel-plugin-syntax-class-properties": "^6.8.0",
"babel-plugin-syntax-flow": "^6.8.0",
"babel-plugin-syntax-jsx": "^6.8.0",
"babel-plugin-syntax-object-rest-spread": "^6.8.0",
"babel-plugin-syntax-trailing-function-commas": "^6.8.0",
"babel-plugin-transform-class-properties": "^6.8.0",
"babel-plugin-transform-es2015-arrow-functions": "^6.8.0",
"babel-plugin-transform-es2015-block-scoped-functions": "^6.8.0",
"babel-plugin-transform-es2015-block-scoping": "^6.8.0",
"babel-plugin-transform-es2015-classes": "^6.8.0",
"babel-plugin-transform-es2015-computed-properties": "^6.8.0",
"babel-plugin-transform-es2015-destructuring": "^6.8.0",
"babel-plugin-transform-es2015-for-of": "^6.8.0",
"babel-plugin-transform-es2015-function-name": "^6.8.0",
"babel-plugin-transform-es2015-literals": "^6.8.0",
"babel-plugin-transform-es2015-modules-commonjs": "^6.8.0",
"babel-plugin-transform-es2015-object-super": "^6.8.0",
"babel-plugin-transform-es2015-parameters": "^6.8.0",
"babel-plugin-transform-es2015-shorthand-properties": "^6.8.0",
"babel-plugin-transform-es2015-spread": "^6.8.0",
"babel-plugin-transform-es2015-template-literals": "^6.8.0",
"babel-plugin-transform-es3-member-expression-literals": "^6.8.0",
"babel-plugin-transform-es3-property-literals": "^6.8.0",
"babel-plugin-transform-flow-strip-types": "^6.8.0",
"babel-plugin-transform-object-rest-spread": "^6.8.0",
"babel-plugin-transform-react-display-name": "^6.8.0",
"babel-plugin-transform-react-jsx": "^6.8.0"
},
"devDependencies": {
"babel-core": "^6.8.0",
"jest-cli": "^12.0.2"
},
"jest": {
"modulePathIgnorePatterns": [
"/node_modules/"
],
"persistModuleRegistryBetweenSpecs": true,
"rootDir": "",
"testPathDirs": [
""
],
"unmockedModulePathPatterns": [
""
]
}
}
fbjs-0.8.16/babel-preset/plugins/ 0000775 0000000 0000000 00000000000 13162307160 0016557 5 ustar 00root root 0000000 0000000 fbjs-0.8.16/babel-preset/plugins/__tests__/ 0000775 0000000 0000000 00000000000 13162307160 0020515 5 ustar 00root root 0000000 0000000 fbjs-0.8.16/babel-preset/plugins/__tests__/dev-expression-test.js 0000664 0000000 0000000 00000002541 13162307160 0025005 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
/* eslint-disable max-len */
let babel = require('babel-core');
let devExpression = require('../dev-expression');
function transform(input) {
return babel.transform(input, {
plugins: [devExpression],
}).code;
}
function compare(input, output) {
var compiled = transform(input);
expect(compiled).toEqual(output);
}
var oldEnv;
describe('dev-expression', function() {
beforeEach(() => {
oldEnv = process.env.NODE_ENV;
process.env.NODE_ENV = '';
});
afterEach(() => {
process.env.NODE_ENV = oldEnv;
});
it('should replace __DEV__ in if', () => {
compare(
`
if (__DEV__) {
console.log('foo')
}`,
`
if (process.env.NODE_ENV !== 'production') {
console.log('foo');
}`
);
});
it('should replace warning calls', () => {
compare(
"warning(condition, 'a %s b', 'c');",
"process.env.NODE_ENV !== 'production' ? warning(condition, 'a %s b', 'c') : void 0;"
);
});
it('should replace invariant calls', () => {
compare(
"invariant(condition, 'a %s b', 'c');",
"!condition ? process.env.NODE_ENV !== 'production' ? invariant(false, 'a %s b', 'c') : invariant(false) : void 0;"
);
});
});
fbjs-0.8.16/babel-preset/plugins/__tests__/inline-requires-test.js 0000664 0000000 0000000 00000002566 13162307160 0025154 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
jest.autoMockOff();
var babel = require('babel-core');
describe('inline-requires', function() {
it('should inline single usage', function() {
compare([
'var foo = require("foo");',
'foo.bar()',
], [
'require("foo").bar();',
]);
});
it('should inline requires that are not assigned', function() {
compare([
'require("foo");',
], [
'require("foo");',
]);
});
it('should delete unused requires', function() {
compare([
'var foo = require("foo");',
], [
'',
]);
});
it('should throw when assigning to a require', function() {
expect(function() {
transform([
'var foo = require("foo");',
'foo = "bar";',
]);
}).toThrow();
});
});
function transform(input) {
return babel.transform(normalise(input), {
plugins: [require('../inline-requires.js')],
}).code;
}
function normalise(input) {
return Array.isArray(input) ? input.join('\n') : input;
}
function compare(input, output) {
var compiled = transform(input);
output = normalise(output);
expect(strip(compiled)).toEqual(strip(output));
}
function strip(input) {
return input.replace(/\s/g, '');
}
fbjs-0.8.16/babel-preset/plugins/__tests__/object-assign-test.js 0000664 0000000 0000000 00000002202 13162307160 0024554 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
/* eslint-disable max-len */
let babel = require('babel-core');
let assign = require('../object-assign');
function transform(input) {
return babel.transform(input, {
plugins: [assign],
}).code;
}
function compare(input, output) {
var compiled = transform(input);
expect(compiled).toEqual(output);
}
describe('object-assign', function() {
it('should replace calls', () => {
compare(
`Object.assign({}, null);`,
`var _assign = require("object-assign");
_assign({}, null);`
);
});
it('does not make multiple assignments', () => {
compare(
`Object.assign({}, null);
Object.assign(Object.prototype, null)`,
`var _assign = require("object-assign");
_assign({}, null);
_assign(Object.prototype, null);`
);
});
it('should replace simple access', () => {
compare(
`var assign = Object.assign;
assign({}, null);`,
`var _assign = require("object-assign");
var assign = _assign;
assign({}, null);`
);
});
});
fbjs-0.8.16/babel-preset/plugins/__tests__/rewrite-modules-test.js 0000664 0000000 0000000 00000005107 13162307160 0025162 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
jest.dontMock('babel-core');
jest.dontMock('../rewrite-modules');
describe('rewrite-modules', function() {
let babel = require('babel-core');
let rewriteModules = require('../rewrite-modules');
function normalizeResults(code) {
return code && code.replace(/\s/g, '');
}
describe('rewriteModules', function() {
describe('opts._moduleMap', function() {
it('should replace the prefix on normal requires', function() {
let result = babel.transform(
'require(\'test\');',
{
plugins: [[rewriteModules, {map: {'test': 'test/test'}}]],
}
);
expect(result.code).toEqual('require(\'test/test\');');
});
it('should replace the prefix on type imports', function() {
let result = babel.transform(
'import type Test from "test";',
{
plugins: [
'syntax-flow',
[rewriteModules, {map: {'test': 'test/test'}}]
],
}
);
expect(result.code).toEqual('import type Test from "test/test";');
});
it('should transform jest and requireActual methods', function() {
const code = `function test() {
'use strict';
jest.mock('foo');
jest.mock('foo').mock('bar').dontMock('baz');
var fooMock = jest.genMockFromModule('foo');
jest.unmock('foo');
jest.setMock('foo', () => {});
var foo = require('foo');
var actualFoo = require.requireActual('foo');
}`;
const expected = `function test() {
'use strict';
jest.mock('foo/foo');
jest.mock('foo/foo').mock('bar/bar').dontMock('baz/baz');
var fooMock = jest.genMockFromModule('foo/foo');
jest.unmock('foo/foo');
jest.setMock('foo/foo', () => {});
var foo = require('foo/foo');
var actualFoo = require.requireActual('foo/foo');
}`;
const rewritePlugin = [
rewriteModules, {
map: {
'foo': 'foo/foo',
'bar': 'bar/bar',
'baz': 'baz/baz',
},
},
];
let result = babel.transform(
code,
{
plugins: [rewritePlugin],
}
);
expect(normalizeResults(result.code))
.toEqual(normalizeResults(expected));
});
});
});
});
fbjs-0.8.16/babel-preset/plugins/auto-importer.js 0000664 0000000 0000000 00000002544 13162307160 0021731 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
const MODULES = [
// Local Promise implementation.
'Promise',
];
/**
* Automatically imports a module if its identifier is in the AST.
*/
module.exports = function autoImporter(babel) {
const t = babel.types;
function isAppropriateModule(name, scope, state) {
const autoImported = state.autoImported;
return MODULES.indexOf(name) !== -1
&& !autoImported.hasOwnProperty(name)
&& !scope.hasBinding(name, /*skip globals*/true);
}
return {
pre: function() {
// Cache per file to avoid calling `scope.hasBinding` several
// times for the same module, which has already been auto-imported.
this.autoImported = {};
},
visitor: {
ReferencedIdentifier: function(path) {
const node = path.node;
const scope = path.scope;
if (!isAppropriateModule(node.name, scope, this)) {
return;
}
scope.getProgramParent().push({
id: t.identifier(node.name),
init: t.callExpression(
t.identifier('require'),
[t.stringLiteral(node.name)]
),
});
this.autoImported[node.name] = true;
},
},
};
};
fbjs-0.8.16/babel-preset/plugins/dev-expression.js 0000664 0000000 0000000 00000007666 13162307160 0022107 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
module.exports = function(babel) {
var t = babel.types;
var SEEN_SYMBOL = Symbol();
var DEV_EXPRESSION = t.binaryExpression(
'!==',
t.memberExpression(
t.memberExpression(
t.identifier('process'),
t.identifier('env'),
false
),
t.identifier('NODE_ENV'),
false
),
t.stringLiteral('production')
);
return {
visitor: {
Identifier: {
enter: function(path) {
// Do nothing when testing
if (process.env.NODE_ENV === 'test') {
return;
}
// replace __DEV__ with process.env.NODE_ENV !== 'production'
if (path.isIdentifier({name: '__DEV__'})) {
path.replaceWith(DEV_EXPRESSION);
}
},
},
CallExpression: {
exit: function(path) {
var node = path.node;
// Do nothing when testing
if (process.env.NODE_ENV === 'test') {
return;
}
// Ignore if it's already been processed
if (node[SEEN_SYMBOL]) {
return;
}
if (path.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];
var devInvariant = t.callExpression(
node.callee,
[t.booleanLiteral(false)].concat(node.arguments.slice(1))
);
devInvariant[SEEN_SYMBOL] = true;
var prodInvariant = t.callExpression(
node.callee,
[t.booleanLiteral(false)]
);
prodInvariant[SEEN_SYMBOL] = true;
path.replaceWith(t.ifStatement(
t.unaryExpression('!', condition),
t.blockStatement([
t.ifStatement(
DEV_EXPRESSION,
t.blockStatement([
t.expressionStatement(devInvariant),
]),
t.blockStatement([
t.expressionStatement(prodInvariant),
])
),
])
));
} else if (path.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__
node[SEEN_SYMBOL] = true;
path.replaceWith(t.ifStatement(
DEV_EXPRESSION,
t.blockStatement([
t.expressionStatement(
node
),
])
));
}
},
},
},
};
};
fbjs-0.8.16/babel-preset/plugins/inline-requires.js 0000664 0000000 0000000 00000006166 13162307160 0022241 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
/**
* Map of require(...) aliases to module names.
*
* `Foo` is an alias for `require('ModuleFoo')` in the following example:
* var Foo = require('ModuleFoo');
*/
var inlineRequiredDependencyMap;
/**
* This transform inlines top-level require(...) aliases with to enable lazy
* loading of dependencies.
*
* Continuing with the example above, this replaces all references to `Foo` in
* the module to `require('ModuleFoo')`.
*/
module.exports = function fbjsInlineRequiresTransform(babel) {
var t = babel.types;
function buildRequireCall(name) {
var call = t.callExpression(
t.identifier('require'),
[t.stringLiteral(inlineRequiredDependencyMap[name])]
);
call.new = true;
return call;
}
return {
visitor: {
Program: function() {
resetCollection();
},
/**
* Collect top-level require(...) aliases.
*/
CallExpression: function(path) {
var node = path.node;
if (isTopLevelRequireAlias(path)) {
var varName = path.parent.id.name;
var moduleName = node.arguments[0].value;
inlineRequiredDependencyMap[varName] = moduleName;
// Remove the declaration.
path.parentPath.parentPath.remove();
// And the associated binding in the scope.
path.scope.removeBinding(varName);
}
},
/**
* Inline require(...) aliases.
*/
Identifier: function(path) {
var node = path.node;
var parent = path.parent;
var scope = path.scope;
if (!shouldInlineRequire(node, scope)) {
return;
}
if (
parent.type === 'AssignmentExpression' &&
path.isBindingIdentifier() &&
!scope.bindingIdentifierEquals(node.name, node)
) {
throw new Error(
'Cannot assign to a require(...) alias, ' + node.name +
'. Line: ' + node.loc.start.line + '.'
);
}
path.replaceWith(
path.isReferenced() ? buildRequireCall(node.name) : node
);
},
},
};
};
function resetCollection() {
inlineRequiredDependencyMap = {};
}
function isTopLevelRequireAlias(path) {
return (
isRequireCall(path.node) &&
path.parent.type === 'VariableDeclarator' &&
path.parent.id.type === 'Identifier' &&
path.parentPath.parent.type === 'VariableDeclaration' &&
path.parentPath.parent.declarations.length === 1 &&
path.parentPath.parentPath.parent.type === 'Program'
);
}
function isRequireCall(node) {
return (
!node.new &&
node.type === 'CallExpression' &&
node.callee.type === 'Identifier' &&
node.callee.name === 'require' &&
node['arguments'].length === 1 &&
node['arguments'][0].type === 'StringLiteral'
);
}
function shouldInlineRequire(node, scope) {
return (
inlineRequiredDependencyMap.hasOwnProperty(node.name) &&
!scope.hasBinding(node.name, true /* noGlobals */)
);
}
fbjs-0.8.16/babel-preset/plugins/object-assign.js 0000664 0000000 0000000 00000002361 13162307160 0021647 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
module.exports = function autoImporter(babel) {
const t = babel.types;
function getAssignIdent(path, file, state) {
if (!state.id) {
state.id = path.scope.generateUidIdentifier('assign');
path.scope.getProgramParent().push({
id: state.id,
init: t.callExpression(
t.identifier('require'),
[t.stringLiteral('object-assign')]
),
});
}
return state.id;
}
return {
pre: function() {
// map from module to generated identifier
this.id = null;
},
visitor: {
CallExpression: function(path, file) {
if (path.get('callee').matchesPattern('Object.assign')) {
// generate identifier and require if it hasn't been already
var id = getAssignIdent(path, file, this);
path.node.callee = id;
}
},
MemberExpression: function(path, file) {
if (path.matchesPattern('Object.assign')) {
var id = getAssignIdent(path, file, this);
path.replaceWith(id);
}
},
},
};
};
fbjs-0.8.16/babel-preset/plugins/rewrite-modules.js 0000664 0000000 0000000 00000007167 13162307160 0022257 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
/**
* Rewrites module string literals according to the `map` and `prefix` options.
* This allows other npm packages to be published and used directly without
* being a part of the same build.
*/
function mapModule(state, module) {
var moduleMap = state.opts.map || {};
if (moduleMap.hasOwnProperty(module)) {
return moduleMap[module];
}
// Jest understands the haste module system, so leave modules intact.
if (process.env.NODE_ENV !== 'test') {
var modulePrefix = state.opts.prefix;
if (modulePrefix == null) {
modulePrefix = './';
}
return modulePrefix + module;
}
return null;
}
var jestMethods = [
'dontMock',
'genMockFromModule',
'mock',
'setMock',
'unmock',
];
function isJestProperty(t, property) {
return t.isIdentifier(property) && jestMethods.indexOf(property.name) !== -1;
}
module.exports = function(babel) {
var t = babel.types;
/**
* Transforms `require('Foo')` and `require.requireActual('Foo')`.
*/
function transformRequireCall(path, state) {
var calleePath = path.get('callee');
if (
!t.isIdentifier(calleePath.node, {name: 'require'}) &&
!(
t.isMemberExpression(calleePath.node) &&
t.isIdentifier(calleePath.node.object, {name: 'require'}) &&
t.isIdentifier(calleePath.node.property, {name: 'requireActual'})
)
) {
return;
}
var args = path.get('arguments');
if (!args.length) {
return;
}
var moduleArg = args[0];
if (moduleArg.node.type === 'StringLiteral') {
var module = mapModule(state, moduleArg.node.value);
if (module) {
moduleArg.replaceWith(t.stringLiteral(module));
}
}
}
/**
* Transforms `import type Bar from 'foo'`
*/
function transformTypeImport(path, state) {
var source = path.get('source');
if (source.type === 'StringLiteral') {
var module = mapModule(state, source.node.value);
if (module) {
source.replaceWith(t.stringLiteral(module));
}
}
}
/**
* Transforms either individual or chained calls to `jest.dontMock('Foo')`,
* `jest.mock('Foo')`, and `jest.genMockFromModule('Foo')`.
*/
function transformJestHelper(path, state) {
var calleePath = path.get('callee');
var args = path.get('arguments');
if (!args.length) {
return;
}
var moduleArg = args[0];
if (
moduleArg.node.type === 'StringLiteral' &&
calleePath.node &&
isJestProperty(t, calleePath.node.property)
) {
var module = mapModule(state, moduleArg.node.value);
if (module) {
moduleArg.replaceWith(t.stringLiteral(module));
}
}
}
const jestIdentifier = {
Identifier(path) {
if (path.node.name === 'jest') {
this.isJest = true;
}
},
};
function transformJestCall(path, state) {
let params = {isJest: false};
path.traverse(jestIdentifier, params);
if (params.isJest) {
transformJestHelper(path, state);
}
}
return {
visitor: {
CallExpression: {
exit(path, state) {
if (path.node.seen) {
return;
}
transformRequireCall(path, state);
transformJestCall(path, state);
path.node.seen = true;
},
},
ImportDeclaration: {
exit(path, state) {
if (path.node.importKind !== 'type') {
return;
}
transformTypeImport(path, state);
}
}
},
};
};
fbjs-0.8.16/flow/ 0000775 0000000 0000000 00000000000 13162307160 0013500 5 ustar 00root root 0000000 0000000 fbjs-0.8.16/flow/lib/ 0000775 0000000 0000000 00000000000 13162307160 0014246 5 ustar 00root root 0000000 0000000 fbjs-0.8.16/flow/lib/dev.js 0000664 0000000 0000000 00000000326 13162307160 0015363 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
declare var __DEV__: boolean;
fbjs-0.8.16/gulpfile.js 0000664 0000000 0000000 00000005421 13162307160 0014700 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
const del = require('del');
const flatten = require('gulp-flatten');
const gulp = require('gulp');
const gulpBabel = require('gulp-babel');
const mergeStream = require('merge-stream');
const rename = require('gulp-rename');
const runSequence = require('run-sequence');
const fbjsConfigurePreset = require('babel-preset-fbjs/configure');
const gulpModuleMap = require('fbjs-scripts/gulp/module-map');
const gulpStripProvidesModule = require('fbjs-scripts/gulp/strip-provides-module');
const gulpCheckDependencies = require('fbjs-scripts/gulp/check-dependencies');
const paths = {
lib: {
src: [
'src/**/*.js',
'!src/**/__tests__/**/*.js',
'!src/**/__mocks__/**/*.js',
],
dest: 'lib',
presetOptions: {
stripDEV: true,
rewriteModules: {
map: require('fbjs-scripts/third-party-module-map'),
},
},
},
mocks: {
src: [
'src/**/__mocks__/**/*.js',
],
dest: 'lib/__mocks__',
presetOptions: {
stripDEV: true,
rewriteModules: {
map: require('fbjs-scripts/third-party-module-map'),
prefix: '../',
},
},
},
};
const rewriteOptions = {
moduleMapFile: './module-map.json',
prefix: 'fbjs/lib/',
};
gulp.task('clean', function() {
return del([paths.lib.dest, paths.mocks.dest]);
});
gulp.task('lib', function() {
const libTask = gulp
.src(paths.lib.src)
.pipe(gulpModuleMap(rewriteOptions))
.pipe(gulpStripProvidesModule())
.pipe(gulpBabel(fbjsConfigurePreset(paths.lib.presetOptions)))
.pipe(flatten())
.pipe(gulp.dest(paths.lib.dest));
const mockTask = gulp
.src(paths.mocks.src)
.pipe(gulpBabel(fbjsConfigurePreset(paths.mocks.presetOptions)))
.pipe(flatten())
.pipe(gulp.dest(paths.mocks.dest));
return mergeStream(libTask, mockTask);
});
gulp.task('flow', function() {
return gulp
.src(paths.lib.src)
.pipe(gulpModuleMap(rewriteOptions))
.pipe(gulpBabel({
presets: [
fbjsConfigurePreset({
autoImport: false,
target: 'flow',
rewriteModules: {
map: require('fbjs-scripts/third-party-module-map'),
},
}),
],
}))
.pipe(flatten())
.pipe(rename({extname: '.js.flow'}))
.pipe(gulp.dest(paths.lib.dest));
});
gulp.task('check-dependencies', function() {
return gulp
.src('package.json')
.pipe(gulpCheckDependencies());
});
gulp.task('watch', function() {
gulp.watch(paths.src, ['lib', 'flow']);
});
gulp.task('build', function(cb) {
runSequence('check-dependencies', 'clean', ['lib', 'flow'], cb);
});
gulp.task('default', ['build']);
fbjs-0.8.16/index.js 0000664 0000000 0000000 00000000430 13162307160 0014173 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
throw new Error('The fbjs package should not be required without a full path.');
fbjs-0.8.16/package.json 0000664 0000000 0000000 00000004031 13162307160 0015015 0 ustar 00root root 0000000 0000000 {
"name": "fbjs",
"version": "0.8.16",
"description": "A collection of utility libraries used by other Facebook JS projects",
"main": "index.js",
"repository": "facebook/fbjs",
"scripts": {
"build": "gulp build",
"postbuild": "node scripts/node/check-lib-requires.js lib",
"lint": "eslint .",
"prepublish": "npm run build",
"pretest": "node node_modules/fbjs-scripts/node/check-dev-engines.js package.json",
"test": "NODE_ENV=test jest",
"test-babel-presets": "cd babel-preset && npm install && npm test",
"typecheck": "flow check src"
},
"devDependencies": {
"babel-eslint": "^6.0.3",
"babel-preset-fbjs": "file:babel-preset",
"del": "^2.2.0",
"eslint": "^2.8.0",
"fbjs-scripts": "file:scripts",
"flow-bin": "^0.38.0",
"gulp": "^3.9.1",
"gulp-babel": "^6.1.2",
"gulp-flatten": "^0.2.0",
"gulp-rename": "^1.2.2",
"immutable": "^3.7.6",
"jest-cli": "^0.9.2",
"merge-stream": "^1.0.0",
"run-sequence": "^1.1.5"
},
"license": "MIT",
"files": [
"LICENSE",
"README.md",
"flow/",
"index.js",
"lib/",
"module-map.json"
],
"jest": {
"modulePathIgnorePatterns": [
"/lib/",
"/node_modules/"
],
"persistModuleRegistryBetweenSpecs": true,
"preprocessorIgnorePatterns": [
"/node_modules/"
],
"rootDir": "",
"scriptPreprocessor": "node_modules/fbjs-scripts/jest/preprocessor.js",
"setupEnvScriptFile": "node_modules/fbjs-scripts/jest/environment.js",
"testPathDirs": [
"/src"
],
"unmockedModulePathPatterns": [
"/node_modules/",
"/src/(?!(__forks__/fetch.js$|fetch/))"
]
},
"dependencies": {
"core-js": "^1.0.0",
"isomorphic-fetch": "^2.1.1",
"loose-envify": "^1.0.0",
"object-assign": "^4.1.0",
"promise": "^7.1.1",
"setimmediate": "^1.0.5",
"ua-parser-js": "^0.7.9"
},
"devEngines": {
"node": ">=4.x",
"npm": ">=2.x"
},
"browserify": {
"transform": [
"loose-envify"
]
}
}
fbjs-0.8.16/scripts/ 0000775 0000000 0000000 00000000000 13162307160 0014220 5 ustar 00root root 0000000 0000000 fbjs-0.8.16/scripts/CHANGELOG.md 0000664 0000000 0000000 00000003640 13162307160 0016034 0 ustar 00root root 0000000 0000000 ## [Unreleased]
## [0.7.1] - 2016-05-25
### Added
- `object-assign` and `immutable` are now included in `third-party-module-map.json`.
### Changed
- Upgraded `cross-spawn` dependency
## [0.7.0] - 2016-04-28
### Changed
- [lint] Upgraded config to match latest internal config. Requires ESLint >= v2.0.0 (may be using newer rules).
- [babel] `babel/default-options` expects Babel 6 and `babel-preset-fbjs` to be installed.
### Removed
- [babel] Moved all plugins into new `babel-preset-fbjs` package.
## [0.6.0] - 2016-04-04
### Added
- [babel] Added rewrite-modules plugin for Babel 6
- [babel] Added dev-expression plugin for Babel 6
- [babel] Added default-options for Babel 6
- [gulp] Added strip-provides-module to strip `@providesModule` headers
- [gulp] Added check-dependencies to ensure installed packages are compatible with package.json specification
- [node] Added check-lib-requires script to ensure all lib files can be required
### Changed
- [lint] Moved ESLint config from `eslint/.eslintrc` to `eslint/.eslintrc.js`. requires ESLint >= v1.10.
- [lint] Base config updated to match internal config
### Fixed
- [babel] Fixed the rewrite-modules plugin to support more Jest methods
- [babel] Removed dependency on babel-types
## [0.5.0] - 2015-11-11
- [babel] Add auto-importer plugin for Babel & Babel 6
- [babel] Add auto-importer plugin to default babel options
## [0.4.0] - 2015-11-09
- [babel] Add inline-requires plugin for Babel 6
## [0.3.0] - 2015-10-23
### Changed
- [lint] `comma-dangle` rule upgraded to warning
- [jest] Update `createCacheKeyFunction` to make it compatible with Jest v0.6
## [0.2.2] - 2015-10-01
### Added
- [lint] Add several globals used by Relay and others
- [babel] Added `ua-parser-js` to default module map
## [0.2.1] - 2015-09-17
### Changed
- [jest] Ignore `config` option when creating a cache key
## [0.2.0] - 2015-08-31
### Added
- Initial release as a separate module.
fbjs-0.8.16/scripts/README.md 0000664 0000000 0000000 00000001175 13162307160 0015503 0 ustar 00root root 0000000 0000000 # fbjs-scripts
This is a collection of tools and scripts intended to be used in conjunction with `fbjs`. Previously these were shipped as a part of `fbjs`.
```js
// before (fbjs@0.1.0)
var invariant = require('fbjs/lib/invariant');
var devExpression = require('fbjs/scripts/babel/dev-expression');
// after (fbjs, fbjs-scripts@0.2.0)
var invariant = require('fbjs/lib/invariant');
var devExpression = require('fbjs-scripts/babel/dev-expression');
```
## Why?
This ensures that production code consuming `fbjs` library code does not need to install script dependencies, unless you explicitly use them via the `fbjs-scripts` package.
fbjs-0.8.16/scripts/babel/ 0000775 0000000 0000000 00000000000 13162307160 0015265 5 ustar 00root root 0000000 0000000 fbjs-0.8.16/scripts/babel/default-options.js 0000664 0000000 0000000 00000001022 13162307160 0020733 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
const assign = require('object-assign');
module.exports = function(options) {
return {
presets: [
require('babel-preset-fbjs/configure')({
rewriteModules: assign({
map: require('../third-party-module-map'),
}, options.moduleOpts),
}),
],
plugins: options.plugins || [],
};
};
fbjs-0.8.16/scripts/eslint/ 0000775 0000000 0000000 00000000000 13162307160 0015516 5 ustar 00root root 0000000 0000000 fbjs-0.8.16/scripts/eslint/.eslintrc.js 0000664 0000000 0000000 00000050603 13162307160 0017761 0 ustar 00root root 0000000 0000000 /**
* 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.
*/
/**
* This file resembles what we use for our internal configuration. Several changes
* have been made to acoomodate the differences between our internal setup and
* what we would expect to see in open source.
*
* Internally we also lint each file individually, allowing use to use the file
* path to selectively enable/disable pieces of the lint configuration. For
* example, we don't actually want jest globals to be enabled all the time so
* we only enable that when we know we're linting a test file. That isn't possible
* here so we just always enable that.
*
* We are also missing our growing library of custom rules. Many of those will
* make their way out here soon, but it does mean we need to do some editing of
* our configuration object.
*/
'use strict';
var assign = require('object-assign');
// see http://eslint.org/docs/user-guide/configuring.html#configuring-rules
const OFF = 0;
const WARNING = 1;
const ERROR = 2;
// This pattern will match these texts:
// var Foo = require('Foo');
// var Bar = require('Foo').Bar;
// var BarFoo = require(Bar + 'Foo');
// var {Bar, Foo} = require('Foo');
// import type {Bar, Foo} from 'Foo';
// Also supports 'let' and 'const'.
const variableNamePattern = String.raw`\s*[a-zA-Z_$][a-zA-Z_$\d]*\s*`;
const maxLenIgnorePattern = String.raw`^(?:var|let|const|import type)\s+` +
'{?' + variableNamePattern + '(?:,' + variableNamePattern + ')*}?' +
String.raw`\s*(?:=\s*require\(|from)[a-zA-Z_+./"'\s\d\-]+\)?[^;\n]*[;\n]`;
function getBaseConfig() {
return {
parser: 'babel-eslint',
parserOptions: {
ecmaVersion: 6,
sourceType: 'module',
},
// Tries to match the jshint configuration as closely as possible, with the
// exeception of a few things that jshint doesn't check, but that we really
// shouldn't be using anyways.
//
// Things that jshint checked for are errors, new rules are warnings.
//
// If you update eslint, be sure to check the changelog to figure out what
// rules to add/remove to/from this list.
rules: {
// Possible Errors
// Forked and moved to fb-www/comma-dangle
'comma-dangle': OFF,
// equivalent to jshint boss
'no-cond-assign': OFF,
// equivalent to jshint devel
'no-console': OFF,
// prohibits things like `while (true)`
'no-constant-condition': OFF,
// we need to be able to match these
'no-control-regex': OFF,
// equivalent to jshint debug
'no-debugger': ERROR,
// equivalent to jshint W004
'no-dupe-args': ERROR,
// syntax error in strict mode, almost certainly unintended in any case
'no-dupe-keys': ERROR,
// almost certainly a bug
'no-duplicate-case': WARNING,
// almost certainly a bug
'no-empty-character-class': WARNING,
// would warn on uncommented empty `catch (ex) {}` blocks
'no-empty': OFF,
// can cause subtle bugs in IE 8, and we shouldn't do this anyways
'no-ex-assign': WARNING,
// we shouldn't do this anyways
'no-extra-boolean-cast': WARNING,
// parens may be used to improve clarity, equivalent to jshint W068
'no-extra-parens': [WARNING, 'functions'],
// equivalent to jshint W032
'no-extra-semi': WARNING,
// a function delaration shouldn't be rewritable
'no-func-assign': ERROR,
// babel and es6 allow block-scoped functions
'no-inner-declarations': OFF,
// will cause a runtime error
'no-invalid-regexp': WARNING,
// disallow non-space or tab whitespace characters
'no-irregular-whitespace': WARNING,
// write `if (!(a in b))`, not `if (!a in b)`, equivalent to jshint W007
'no-negated-in-lhs': ERROR,
// will cause a runtime error
'no-obj-calls': ERROR,
// improves legibility
'no-regex-spaces': WARNING,
// equivalent to jshint elision
'no-sparse-arrays': ERROR,
// equivalent to jshint W027
'no-unreachable': ERROR,
// equivalent to jshint use-isnan
'use-isnan': ERROR,
// probably too noisy ATM
'valid-jsdoc': OFF,
// equivalent to jshint notypeof
'valid-typeof': ERROR,
// we already require semicolons
'no-unexpected-multiline': OFF,
// Best Practices
// probably a bug, we shouldn't actually even use this yet, because of IE8
'accessor-pairs': [WARNING, {setWithoutGet: true}],
// probably too noisy ATM
'block-scoped-var': OFF,
// cyclomatic complexity, we're too far gone
'complexity': OFF,
// require return statements to either always or never specify values
'consistent-return': WARNING,
// style guide: Always use brackets, even when optional.
'curly': [WARNING, 'all'],
// we don't do this/care about this
'default-case': OFF,
// disabled in favor of our temporary fork
'dot-notation': OFF,
// we don't do this/care about this, but probably should eventually
'dot-location': OFF,
// disabled as it's too noisy ATM
'eqeqeq': [OFF, 'allow-null'],
// we don't do this/care about this, equivalent to jshint forin
'guard-for-in': OFF,
// we have too many internal examples/tools using this
'no-alert': OFF,
// incompatible with 'use strict' equivalent to jshint noarg
'no-caller': ERROR,
// we don't care about this right now, but might later
'no-case-declarations': OFF,
// we don't do this/care about this
'no-div-regex': OFF,
// we don't do this/care about this
'no-else-return': OFF,
// avoid mistaken variables when destructuring
'no-empty-pattern': WARNING,
// see eqeqeq: we explicitly allow this, equivalent to jshint eqnull
'no-eq-null': OFF,
// equivalent to jshint evil
'no-eval': ERROR,
// should only be triggered on polyfills, which we can fix case-by-case
'no-extend-native': WARNING,
// might be a sign of a bug
'no-extra-bind': WARNING,
// equivalent to jshint W089
'no-fallthrough': WARNING,
// equivalent to jshint W008
'no-floating-decimal': ERROR,
// implicit coercion is often idiomatic
'no-implicit-coercion': OFF,
// equivalent to jshint evil/W066
'no-implied-eval': ERROR,
// will likely create more signal than noise
'no-invalid-this': OFF,
// babel should handle this fine
'no-iterator': OFF,
// Should be effectively equivalent to jshint W028 - allowing the use
// of labels in very specific situations. ESLint no-empty-labels was
// deprecated.
'no-labels': [ERROR, {allowLoop: true, allowSwitch: true}],
// lone blocks create no scope, will ignore blocks with let/const
'no-lone-blocks': WARNING,
// equivalent to jshint loopfunc
'no-loop-func': OFF,
// we surely have these, don't bother with it
'no-magic-numbers': OFF,
// we may use this for alignment in some places
'no-multi-spaces': OFF,
// equivalent to jshint multistr, consider using es6 template strings
'no-multi-str': ERROR,
// equivalent to jshint W02OFF, similar to no-extend-native
'no-native-reassign': [ERROR, {exceptions: ['Map', 'Set']}],
// equivalent to jshint evil/W054
'no-new-func': ERROR,
// don't use constructors for side-effects, equivalent to jshint nonew
'no-new': WARNING,
// very limited uses, mostly in third_party
'no-new-wrappers': WARNING,
// deprecated in ES5, but we still use it in some places
'no-octal-escape': WARNING,
// deprecated in ES5, may cause unexpected behavior
'no-octal': WARNING,
// treats function parameters as constants, probably too noisy ATM
'no-param-reassign': OFF,
// only relevant to node code
'no-process-env': OFF,
// deprecated in ES3.WARNING, equivalent to jshint proto
'no-proto': ERROR,
// jshint doesn't catch this, but this is inexcusable
'no-redeclare': WARNING,
// equivalent to jshint boss
'no-return-assign': OFF,
// equivalent to jshint scripturl
'no-script-url': ERROR,
// not in jshint, but is in jslint, and is almost certainly a mistake
'no-self-compare': WARNING,
// there are very limited valid use-cases for this
'no-sequences': WARNING,
// we're already pretty good about this, and it hides stack traces
'no-throw-literal': WARNING,
// breaks on `foo && foo.bar()` expression statements, which are common
'no-unused-expressions': OFF,
// disallow unnecessary .call() and .apply()
'no-useless-call': WARNING,
// disallow concatenating string literals
'no-useless-concat': WARNING,
// this has valid use-cases, eg. to circumvent no-unused-expressions
'no-void': OFF,
// this journey is 1% finished (allow TODO comments)
'no-warning-comments': OFF,
// equivalent to jshint withstmt
'no-with': OFF,
// require radix argument in parseInt, we do this in most places already
'radix': WARNING,
// we don't do this/care about this
'vars-on-top': OFF,
// equivalent to jshint immed
'wrap-iife': OFF,
// probably too noisy ATM
'yoda': OFF,
// Strict Mode
// jshint wasn't checking this, and the compiler should add this anyways
'strict': OFF,
// Variables
// we don't do this/care about this
'init-declarations': OFF,
// equivalent to jshint W002, catches an IE8 bug
'no-catch-shadow': ERROR,
// equivalent to jshint W051, is a strict mode violation
'no-delete-var': ERROR,
// we should avoid labels anyways
'no-label-var': WARNING,
// redefining undefined, NaN, Infinity, arguments, and eval is bad, mkay?
'no-shadow-restricted-names': WARNING,
// a definite code-smell, but probably too noisy
'no-shadow': OFF,
// it's nice to be explicit sometimes: `let foo = undefined;`
'no-undef-init': OFF,
// equivalent to jshint undef, turned into an error in getConfig
'no-undef': WARNING,
// using undefined is safe because we enforce no-shadow-restricted-names
'no-undefined': OFF,
// equivalent to jshint unused
'no-unused-vars': [WARNING, {args: 'none'}],
// too noisy
'no-use-before-define': OFF,
// Node.js
// TODO: turn some of these on in places where we lint node code
'callback-return': OFF,
'global-require': OFF,
'handle-callback-err': OFF,
'no-mixed-requires': OFF,
'no-new-require': OFF,
'no-path-concat': OFF,
'no-process-exit': OFF,
'no-restricted-modules': OFF,
'no-sync': OFF,
// Stylistic Issues
// See also: https://our.intern.facebook.com/intern/dex/style-guide/
'array-bracket-spacing': WARNING,
// TODO: enable this with consensus on single line blocks
'block-spacing': OFF,
'brace-style': [WARNING, '1tbs', {allowSingleLine: true}],
// too noisy at the moment, and jshint didn't check it
'camelcase': [OFF, {properties: 'always'}],
'comma-spacing': [WARNING, {before: false, after: true}],
// jshint had laxcomma, but that was against our style guide
'comma-style': [WARNING, 'last'],
'computed-property-spacing': [WARNING, 'never'],
// we may use more contextually relevant names for this than self
'consistent-this': [OFF, 'self'],
// should be handled by a generic TXT linter instead
'eol-last': OFF,
'func-names': OFF,
// too noisy ATM
'func-style': [OFF, 'declaration'],
// no way we could enforce min/max lengths or patterns for vars
'id-length': OFF,
'id-match': OFF,
// we weren't enforcing this with jshint, so erroring would be too noisy
'indent': [WARNING, 2, {SwitchCase: 1}],
// we use single quotes for JS literals, double quotes for JSX literals
'jsx-quotes': [WARNING, 'prefer-double'],
// we may use extra spaces for alignment
'key-spacing': [OFF, {beforeColon: false, afterColon: true}],
'keyword-spacing': [WARNING],
'lines-around-comment': OFF,
// should be handled by a generic TXT linter instead
'linebreak-style': [OFF, 'unix'],
'max-depth': OFF,
'max-len': [WARNING, 120, 2,
{'ignorePattern': maxLenIgnorePattern},
],
'max-nested-callbacks': OFF,
'max-params': OFF,
'max-statements': OFF,
// https://facebook.com/groups/995898333776940/1027358627297577
'new-cap': OFF,
// equivalent to jshint W058
'new-parens': ERROR,
'newline-after-var': OFF,
'no-array-constructor': ERROR,
'no-bitwise': WARNING,
'no-continue': OFF,
'no-inline-comments': OFF,
// doesn't play well with `if (__DEV__) {}`
'no-lonely-if': OFF,
// stopgap, irrelevant if we can eventually turn `indent` on to error
'no-mixed-spaces-and-tabs': ERROR,
// don't care
'no-multiple-empty-lines': OFF,
'no-negated-condition': OFF,
// we do this a bunch of places, and it's less bad with proper indentation
'no-nested-ternary': OFF,
// similar to FacebookWebJSLintLinter's checkPhpStyleArray
'no-new-object': WARNING,
'no-plusplus': OFF,
'no-restricted-syntax': OFF,
'no-spaced-func': WARNING,
'no-ternary': OFF,
// should be handled by a generic TXT linter instead
'no-trailing-spaces': OFF,
// we use this for private/protected identifiers
'no-underscore-dangle': OFF,
// disallow `let isYes = answer === 1 ? true : false;`
'no-unneeded-ternary': WARNING,
// too noisy ATM
'object-curly-spacing': OFF,
// makes indentation warnings clearer
'one-var': [WARNING, {initialized: 'never'}],
// prefer `x += 4` over `x = x + 4`
'operator-assignment': [WARNING, 'always'],
// equivalent to jshint laxbreak
'operator-linebreak': OFF,
'padded-blocks': OFF,
// probably too noisy on pre-ES5 code
'quote-props': [OFF, 'as-needed'],
'quotes': [WARNING, 'single', 'avoid-escape'],
'require-jsdoc': OFF,
'semi-spacing': [WARNING, {before: false, after: true}],
// equivalent to jshint asi/W032
'semi': [WARNING, 'always'],
'sort-vars': OFF,
// require `if () {` instead of `if (){`
'space-before-blocks': [WARNING, 'always'],
// require `function foo()` instead of `function foo ()`
'space-before-function-paren': [
WARNING,
{anonymous: 'never', named: 'never'},
],
// incompatible with our legacy inline type annotations
'space-in-parens': [OFF, 'never'],
'space-infix-ops': OFF,
// Currently broken: https://github.com/eslint/eslint/issues/2764
'space-unary-ops': [OFF, {words: true, nonwords: false}],
// TODO: Figure out a way to do this that doesn't break typechecks
// or wait for https://github.com/eslint/eslint/issues/2897
'spaced-comment':
[OFF, 'always', {exceptions: ['jshint', 'jslint', 'eslint', 'global']}],
'wrap-regex': OFF,
// ECMAScript 6
'arrow-body-style': OFF,
// Forked to fb-www/arrow-parens to fix issues with flow and add fixer
'arrow-parens': OFF,
// tbgs finds *very few* places where we don't put spaces around =>
'arrow-spacing': [WARNING, {before: true, after: true}],
// violation of the ES6 spec, won't transform
'constructor-super': ERROR,
// https://github.com/babel/babel-eslint#known-issues
'generator-star-spacing': OFF,
'no-class-assign': WARNING,
'no-confusing-arrow': OFF,
// this is a runtime error
'no-const-assign': ERROR,
'no-dupe-class-members': ERROR,
// violation of the ES6 spec, won't transform, `this` is part of the TDZ
'no-this-before-super': ERROR,
// we have way too much ES3 & ES5 code
'no-var': OFF,
'object-shorthand': OFF,
'prefer-const': OFF,
'prefer-spread': OFF,
// we don't support/polyfill this yet
'prefer-reflect': OFF,
'prefer-template': OFF,
// there are legitimate use-cases for an empty generator
'require-yield': OFF,
},
// Defines a basic set of globals
env: {
browser: true,
es6: true,
},
// The jshint code had more globals, which may have had something to do with
// machine-generated code. I couldn't find references with tbgs.
//
// Values of true mean the global may be modified. Values of false represent
// constants.
globals: {
__DEV__: true,
// Haste-defined variables
require: true,
requireDynamic: true,
requireLazy: true,
// more haste variables are defined in getConfig for modules
// Workarounds for https://github.com/babel/babel-eslint/issues/130
// no-undef errors incorrectly on these global flow types
// https://fburl.com/flow-react-defs
ReactComponent: false,
ReactClass: false,
ReactElement: false,
ReactPropsCheckType: false,
ReactPropsChainableTypeChecker: false,
ReactPropTypes: false,
SyntheticEvent: false,
SyntheticClipboardEvent: false,
SyntheticCompositionEvent: false,
SyntheticInputEvent: false,
SyntheticUIEvent: false,
SyntheticFocusEvent: false,
SyntheticKeyboardEvent: false,
SyntheticMouseEvent: false,
SyntheticDragEvent: false,
SyntheticWheelEvent: false,
SyntheticTouchEvent: false,
// a bunch of types extracted from http://git.io/vOtv9
// there's a bunch of overlap with browser globals, so we try to avoid
// redefining some of those.
$Either: false,
$All: false,
$Tuple: false,
$Supertype: false,
$Subtype: false,
$Shape: false,
$Diff: false,
$Keys: false,
$Enum: false,
$Exports: false,
Class: false,
function: false,
Iterable: false,
// suppress types
$FlowIssue: false,
$FlowFixMe: false,
$FixMe: false,
// https://fburl.com/flow-core-defs
Iterator: false,
IteratorResult: false,
$await: false,
ArrayBufferView: false,
// https://fburl.com/flow-fb-defs
FbtResult: false,
$jsx: false,
FBID: false,
AdAccountID: false,
UID: false,
ReactNode: false,
Fbt: false,
// https://fburl.com/flow-liverail-defs
LRID: false,
// https://fburl.com/flow-powereditor-def
UkiAccount: false,
UkiAdgroup: false,
UkiCampaign: false,
UkiCampaignGroup: false,
// some of this maybe should be handled by the npm globals module, but it
// doesn't have proper WebRTC support yet
// https://fburl.com/flow-webrtc-defs
RTCConfiguration: false,
RTCIceServer: false,
RTCOfferOptions: false,
RTCStatsReport: false,
RTCStatsCallback: false,
RTCPeerConnection: false,
RTCPeerConnectionErrorCallback: false,
RTCSessionDescription: false,
RTCSessionDescriptionInit: false,
RTCSessionDescriptionCallback: false,
RTCIceCandidate: false,
RTCIceCandidateInit: false,
RTCPeerConnectionIceEvent: false,
RTCPeerConnectionIceEventInit: false,
RTCDataChannel: false,
RTCDataChannelInit: false,
RTCDataChannelEvent: false,
RTCDataChannelEventInit: false,
},
};
}
// Override some rules for open source. Due to the way we apply our configuation
// internally, these are effectively part of the same configuration we apply.
var config = getBaseConfig();
var extendedConfig = {
env: {
// Enable these blindly because we can't make a per-file decision about this.
node: true,
jest: true,
jasmine: true,
},
rules: {
// just turned into an error here since we almost always do that anyway.
'no-undef': ERROR,
},
};
Object.keys(extendedConfig).forEach((key) => {
config[key] = assign(config[key], extendedConfig[key]);
});
module.exports = config;
fbjs-0.8.16/scripts/gulp/ 0000775 0000000 0000000 00000000000 13162307160 0015167 5 ustar 00root root 0000000 0000000 fbjs-0.8.16/scripts/gulp/check-dependencies.js 0000664 0000000 0000000 00000003721 13162307160 0021231 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
var gutil = require('gulp-util');
var path = require('path');
var semver = require('semver');
var spawn = require('cross-spawn');
var through = require('through2');
var colors = gutil.colors;
var PLUGIN_NAME = 'check-dependencies';
module.exports = function(opts) {
function read(file, enc, cb) {
var cwd = path.dirname(file.path);
var pkgData = JSON.parse(file.contents.toString());
var outdated = spawn(
'npm',
['outdated', '--json', '--long'],
{ cwd: cwd }
);
var data = '';
outdated.stdout.on('data', function(chunk) {
data += chunk.toString();
});
outdated.on('exit', function(code) {
if (code !== 0) {
cb(new gutil.PluginError(PLUGIN_NAME, 'npm broke'));
}
var outdatedData = JSON.parse(data);
var failures = [];
Object.keys(outdatedData).forEach(function(name) {
var current = outdatedData[name].current;
var type = outdatedData[name].type;
var requested = pkgData[type][name];
if (!requested.startsWith('file:') && !semver.satisfies(current, requested)) {
// Definitely wrong, so we should error
failures.push({name, current, requested});
}
});
if (failures.length) {
failures.forEach((failure) => {
gutil.log(
`${colors.bold(failure.name)} is outdated ` +
`(${colors.red(failure.current)} does not satisfy ` +
`${colors.yellow(failure.requested)})`
);
});
var msg =
'Some of your dependencies are outdated. Please run ' +
`${colors.bold('npm update')} to ensure you are up to date.`;
cb(new gutil.PluginError(PLUGIN_NAME, msg));
return;
}
cb();
});
}
return through.obj(read);
};
fbjs-0.8.16/scripts/gulp/module-map.js 0000664 0000000 0000000 00000004026 13162307160 0017567 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
var gutil = require('gulp-util');
var through = require('through2');
var fs = require('fs');
var path = require('path');
var PM_REGEXP = require('./shared/provides-module').regexp;
var PLUGIN_NAME = 'module-map';
module.exports = function(opts) {
// Assume file is a string for now
if (!opts || !('moduleMapFile' in opts && 'prefix' in opts)) {
throw new gutil.PluginError(
PLUGIN_NAME,
'Missing options. Ensure you pass an object with `moduleMapFile` and `prefix`'
);
}
var moduleMapFile = opts.moduleMapFile;
var prefix = opts.prefix;
var moduleMap = {};
function transform(file, enc, cb) {
if (file.isNull()) {
cb(null, file);
return;
}
if (file.isStream()) {
cb(new gutil.PluginError('module-map', 'Streaming not supported'));
return;
}
// Get the @providesModule piece of out the file and save that.
var matches = file.contents.toString().match(PM_REGEXP);
if (matches) {
var name = matches[1];
if (moduleMap.hasOwnProperty(name)) {
this.emit(
'error',
new gutil.PluginError(
PLUGIN_NAME,
'Duplicate module found: ' + name + ' at ' + file.path + ' and ' +
moduleMap[name]
)
);
}
moduleMap[name] = file.path;
}
this.push(file);
cb();
}
function flush(cb) {
// Keep it ABC order for better diffing.
var map = Object.keys(moduleMap).sort().reduce(function(prev, curr) {
// Rewrite path here since we don't need the full path anymore.
prev[curr] = prefix + path.basename(moduleMap[curr], '.js');
return prev;
}, {});
fs.writeFile(moduleMapFile, JSON.stringify(map, null, 2), 'utf-8', function() {
// avoid calling cb with fs.write callback data
cb();
});
}
return through.obj(transform, flush);
};
fbjs-0.8.16/scripts/gulp/shared/ 0000775 0000000 0000000 00000000000 13162307160 0016435 5 ustar 00root root 0000000 0000000 fbjs-0.8.16/scripts/gulp/shared/provides-module.js 0000664 0000000 0000000 00000000423 13162307160 0022110 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
module.exports = {
regexp: /\r?\n \* \@providesModule (\S+)(?=\r?\n)/,
};
fbjs-0.8.16/scripts/gulp/strip-provides-module.js 0000664 0000000 0000000 00000001511 13162307160 0022000 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
var gutil = require('gulp-util');
var through = require('through2');
var PM_REGEXP = require('./shared/provides-module').regexp;
module.exports = function(opts) {
function transform(file, enc, cb) {
if (file.isNull()) {
cb(null, file);
return;
}
if (file.isStream()) {
cb(new gutil.PluginError('module-map', 'Streaming not supported'));
return;
}
// Get the @providesModule piece out of the file and save that.
var contents = file.contents.toString().replace(PM_REGEXP, '');
file.contents = new Buffer(contents);
this.push(file);
cb();
}
return through.obj(transform);
};
fbjs-0.8.16/scripts/jest/ 0000775 0000000 0000000 00000000000 13162307160 0015165 5 ustar 00root root 0000000 0000000 fbjs-0.8.16/scripts/jest/createCacheKeyFunction.js 0000664 0000000 0000000 00000001302 13162307160 0022065 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
const crypto = require('crypto');
const fs = require('fs');
function buildCacheKey(files, base) {
return files.reduce(
(src, fileName) => src + fs.readFileSync(fileName),
base
);
}
module.exports = files => {
const presetVersion = require('../package').dependencies['babel-preset-fbjs'];
const cacheKey = buildCacheKey(files, presetVersion);
return (src, file, configString) => crypto.createHash('md5')
.update(cacheKey)
.update(src + file + configString)
.digest('hex');
};
fbjs-0.8.16/scripts/jest/environment.js 0000664 0000000 0000000 00000000060 13162307160 0020063 0 ustar 00root root 0000000 0000000 require('core-js/es6');
global.__DEV__ = true;
fbjs-0.8.16/scripts/jest/preprocessor.js 0000664 0000000 0000000 00000001627 13162307160 0020257 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
const babel = require('babel-core');
const createCacheKeyFunction = require('./createCacheKeyFunction');
const path = require('path');
module.exports = {
process(src, filename) {
const options = {
presets: [
require('babel-preset-fbjs'),
],
filename: filename,
retainLines: true,
};
return babel.transform(src, options).code;
},
// Generate a cache key that is based on the contents of this file and the
// fbjs preset package.json (used as a proxy for determining if the preset has
// changed configuration at all).
getCacheKey: createCacheKeyFunction([
__filename,
path.join(path.dirname(require.resolve('babel-preset-fbjs')), 'package.json')
]),
};
fbjs-0.8.16/scripts/node/ 0000775 0000000 0000000 00000000000 13162307160 0015145 5 ustar 00root root 0000000 0000000 fbjs-0.8.16/scripts/node/check-dev-engines.js 0000664 0000000 0000000 00000003602 13162307160 0020763 0 ustar 00root root 0000000 0000000 /*eslint-disable max-len*/
'use strict';
var fs = require('fs');
var assert = require('assert');
var exec = require('child_process').exec;
var semver = require('semver');
var f = require('util').format;
// Make sure we have a package.json to parse. Take it as the first argument
// (actually the 3rd for argv).
assert(
process.argv.length >= 3,
'Expected to receive a package.json file argument to parse'
);
var packageFilePath = process.argv[2];
var packageData;
try {
var packageFile = fs.readFileSync(packageFilePath, {encoding: 'utf-8'});
packageData = JSON.parse(packageFile);
} catch (e) {
assert(
false,
f('Expected to be able to parse %s as JSON but we got this error instead: %s', packageFilePath, e)
);
}
var devEngines = packageData.devEngines;
if (devEngines.node !== undefined) {
// First check that devEngines are valid semver
assert(
semver.validRange(devEngines.node),
f('devEngines.node (%s) is not a valid semver range', devEngines.node)
);
// Then actually check that our version satisfies
var nodeVersion = process.versions.node;
assert(
semver.satisfies(nodeVersion, devEngines.node),
f('Current node version is not supported for development, expected "%s" to satisfy "%s".', nodeVersion, devEngines.node)
);
}
if (devEngines.npm !== undefined) {
// First check that devEngines are valid semver
assert(
semver.validRange(devEngines.npm),
f('devEngines.npm (%s) is not a valid semver range', devEngines.npm)
);
// Then actually check that our version satisfies
exec('npm --version', function(err, stdout, stderr) {
assert(err === null, f('Failed to get npm version... %s'), stderr);
var npmVersion = stdout.trim();
assert(
semver.satisfies(npmVersion, devEngines.npm),
f('Current npm version is not supported for development, expected "%s" to satisfy "%s".', npmVersion, devEngines.npm)
);
});
}
fbjs-0.8.16/scripts/node/check-lib-requires.js 0000664 0000000 0000000 00000002053 13162307160 0021161 0 ustar 00root root 0000000 0000000 'use strict';
const assert = require('assert');
const fs = require('fs');
const path = require('path');
const EXTRACT_MODULE_NAME_REGEX = /'\.\/(.+)'/;
let didError = false;
// Make sure we have a lib to read files from. Take it as the first argument.
assert(
process.argv.length >= 3,
'Expected to receive an argument to a lib directory'
);
const pathToLib = path.resolve(process.cwd(), process.argv[2]);
fs.readdir(pathToLib, (err, files) => {
files = files.filter((filename) => path.parse(filename).ext === '.js');
files.forEach((filename) => {
const requirePath = path.join(pathToLib, filename);
const moduleName = path.parse(filename).name;
try {
require(requirePath);
} catch (e) {
if (e.code === 'MODULE_NOT_FOUND') {
const missingModule = e.toString().match(EXTRACT_MODULE_NAME_REGEX)[1];
console.error(moduleName, 'is missing a dependency:', missingModule);
} else {
console.error('UNKNOWN ERROR', e);
}
didError = true;
}
});
process.exit(didError ? 1 : 0);
});
fbjs-0.8.16/scripts/package.json 0000664 0000000 0000000 00000000662 13162307160 0016512 0 ustar 00root root 0000000 0000000 {
"name": "fbjs-scripts",
"version": "0.7.1",
"description": "A bundle of helpful scripts used in projects consuming fbjs.",
"repository": "facebook/fbjs",
"license": "MIT",
"dependencies": {
"babel-core": "^6.7.2",
"babel-preset-fbjs": "^1.0.0",
"core-js": "^1.0.0",
"cross-spawn": "^3.0.1",
"gulp-util": "^3.0.4",
"object-assign": "^4.0.1",
"semver": "^5.1.0",
"through2": "^2.0.0"
}
}
fbjs-0.8.16/scripts/third-party-module-map.json 0000664 0000000 0000000 00000000651 13162307160 0021422 0 ustar 00root root 0000000 0000000 {
"core-js/library/es6/map": "core-js/library/es6/map",
"core-js/library/es6/set": "core-js/library/es6/set",
"isomorphic-fetch": "isomorphic-fetch",
"object-assign": "object-assign",
"promise": "promise",
"promise/setimmediate/done": "promise/setimmediate/done",
"promise/setimmediate/es6-extensions": "promise/setimmediate/es6-extensions",
"setimmediate": "setimmediate",
"ua-parser-js": "ua-parser-js"
}
fbjs-0.8.16/src/ 0000775 0000000 0000000 00000000000 13162307160 0013320 5 ustar 00root root 0000000 0000000 fbjs-0.8.16/src/.flowconfig 0000664 0000000 0000000 00000000163 13162307160 0015456 0 ustar 00root root 0000000 0000000 [ignore]
.*/__tests__/.*
.*/node_modules/invariant/.*
[include]
[options]
module.system=haste
[version]
^0.38.0
fbjs-0.8.16/src/__forks__/ 0000775 0000000 0000000 00000000000 13162307160 0015240 5 ustar 00root root 0000000 0000000 fbjs-0.8.16/src/__forks__/Map.js 0000664 0000000 0000000 00000000407 13162307160 0016314 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule Map
*/
module.exports = require('core-js/library/es6/map');
fbjs-0.8.16/src/__forks__/Promise.js 0000664 0000000 0000000 00000000373 13162307160 0017217 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule Promise
*/
module.exports = require('promise');
fbjs-0.8.16/src/__forks__/Promise.native.js 0000664 0000000 0000000 00000001166 13162307160 0020505 0 ustar 00root root 0000000 0000000 /**
*
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* This module wraps and augments the minimally ES6-compliant Promise
* implementation provided by the promise npm package.
*
*/
'use strict';
var Promise = require('promise/setimmediate/es6-extensions');
require('promise/setimmediate/done');
/**
* Handle either fulfillment or rejection with the same callback.
*/
Promise.prototype.finally = function(onSettled) {
return this.then(onSettled, onSettled);
};
module.exports = Promise;
fbjs-0.8.16/src/__forks__/Set.js 0000664 0000000 0000000 00000000407 13162307160 0016332 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule Set
*/
module.exports = require('core-js/library/es6/set');
fbjs-0.8.16/src/__forks__/Style.js 0000664 0000000 0000000 00000003346 13162307160 0016704 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule Style
* @typechecks
*/
var getStyleProperty = require('getStyleProperty');
/**
* @param {DOMNode} element [description]
* @param {string} name Overflow style property name.
* @return {boolean} True if the supplied ndoe is scrollable.
*/
function _isNodeScrollable(element, name) {
var overflow = Style.get(element, name);
return (overflow === 'auto' || overflow === 'scroll');
}
/**
* Utilities for querying and mutating style properties.
*/
var Style = {
/**
* Gets the style property for the supplied node. This will return either the
* computed style, if available, or the declared style.
*
* @param {DOMNode} node
* @param {string} name Style property name.
* @return {?string} Style property value.
*/
get: getStyleProperty,
/**
* Determines the nearest ancestor of a node that is scrollable.
*
* NOTE: This can be expensive if used repeatedly or on a node nested deeply.
*
* @param {?DOMNode} node Node from which to start searching.
* @return {?DOMWindow|DOMElement} Scroll parent of the supplied node.
*/
getScrollParent: function(node) {
if (!node) {
return null;
}
var ownerDocument = node.ownerDocument;
while (node && node !== ownerDocument.body) {
if (_isNodeScrollable(node, 'overflow') ||
_isNodeScrollable(node, 'overflowY') ||
_isNodeScrollable(node, 'overflowX')) {
return node;
}
node = node.parentNode;
}
return ownerDocument.defaultView || ownerDocument.parentWindow;
},
};
module.exports = Style;
fbjs-0.8.16/src/__forks__/TokenizeUtil.js 0000664 0000000 0000000 00000002537 13162307160 0020233 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule TokenizeUtil
* @typechecks
* @stub
* @flow
*/
'use strict';
// \u00a1-\u00b1\u00b4-\u00b8\u00ba\u00bb\u00bf
// is latin supplement punctuation except fractions and superscript
// numbers
// \u2010-\u2027\u2030-\u205e
// is punctuation from the general punctuation block:
// weird quotes, commas, bullets, dashes, etc.
// \u30fb\u3001\u3002\u3008-\u3011\u3014-\u301f
// is CJK punctuation
// \uff1a-\uff1f\uff01-\uff0f\uff3b-\uff40\uff5b-\uff65
// is some full-width/half-width punctuation
// \u2E2E\u061f\u066a-\u066c\u061b\u060c\u060d\uFD3e\uFD3F
// is some Arabic punctuation marks
// \u1801\u0964\u104a\u104b
// is misc. other language punctuation marks
var PUNCTUATION = (
'[.,+*?$|#{}()\'\\^\\-\\[\\]\\\\\\/!@%"~=<>_:;' +
'\u30fb\u3001\u3002\u3008-\u3011\u3014-\u301f\uff1a-\uff1f\uff01-\uff0f' +
'\uff3b-\uff40\uff5b-\uff65\u2E2E\u061f\u066a-\u066c\u061b\u060c\u060d' +
'\uFD3e\uFD3F\u1801\u0964\u104a\u104b\u2010-\u2027\u2030-\u205e' +
'\u00a1-\u00b1\u00b4-\u00b8\u00ba\u00bb\u00bf]'
);
module.exports = {
getPunctuation: (): string => PUNCTUATION,
};
fbjs-0.8.16/src/__forks__/URI.js 0000664 0000000 0000000 00000000610 13162307160 0016232 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule URI
* @flow
*/
'use strict';
class URI {
_uri: string;
constructor(uri: string) {
this._uri = uri;
}
toString(): string {
return this._uri;
}
}
module.exports = URI;
fbjs-0.8.16/src/__forks__/UserAgentData.js 0000664 0000000 0000000 00000004517 13162307160 0020274 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule UserAgentData
*/
/**
* Usage note:
* This module makes a best effort to export the same data we would internally.
* At Facebook we use a server-generated module that does the parsing and
* exports the data for the client to use. We can't rely on a server-side
* implementation in open source so instead we make use of an open source
* library to do the heavy lifting and then make some adjustments as necessary.
* It's likely there will be some differences. Some we can smooth over.
* Others are going to be harder.
*/
'use strict';
var UAParser = require('ua-parser-js');
var UNKNOWN = 'Unknown';
var PLATFORM_MAP = {
'Mac OS': 'Mac OS X',
};
/**
* Convert from UAParser platform name to what we expect.
*/
function convertPlatformName(name) {
return PLATFORM_MAP[name] || name;
}
/**
* Get the version number in parts. This is very naive. We actually get major
* version as a part of UAParser already, which is generally good enough, but
* let's get the minor just in case.
*/
function getBrowserVersion(version) {
if (!version) {
return {
major: '',
minor: '',
};
}
var parts = version.split('.');
return {
major: parts[0],
minor: parts[1],
};
}
/**
* Get the UA data fom UAParser and then convert it to the format we're
* expecting for our APIS.
*/
var parser = new UAParser();
var results = parser.getResult();
// Do some conversion first.
var browserVersionData = getBrowserVersion(results.browser.version);
var uaData = {
browserArchitecture: results.cpu.architecture || UNKNOWN,
browserFullVersion: results.browser.version || UNKNOWN,
browserMinorVersion: browserVersionData.minor || UNKNOWN,
browserName: results.browser.name || UNKNOWN,
browserVersion: results.browser.major || UNKNOWN,
deviceName: results.device.model || UNKNOWN,
engineName: results.engine.name || UNKNOWN,
engineVersion: results.engine.version || UNKNOWN,
platformArchitecture: results.cpu.architecture || UNKNOWN,
platformName: convertPlatformName(results.os.name) || UNKNOWN,
platformVersion: results.os.version || UNKNOWN,
platformFullVersion: results.os.version || UNKNOWN,
};
module.exports = uaData;
fbjs-0.8.16/src/__forks__/cx.js 0000664 0000000 0000000 00000002506 13162307160 0016213 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule cx
*/
/**
* This function is used to mark string literals representing CSS class names
* so that they can be transformed statically. This allows for modularization
* and minification of CSS class names.
*
* In static_upstream, this function is actually implemented, but it should
* eventually be replaced with something more descriptive, and the transform
* that is used in the main stack should be ported for use elsewhere.
*
* @param string|object className to modularize, or an object of key/values.
* In the object case, the values are conditions that
* determine if the className keys should be included.
* @param [string ...] Variable list of classNames in the string case.
* @return string Renderable space-separated CSS className.
*/
function cx(classNames) {
if (typeof classNames == 'object') {
return Object.keys(classNames)
.filter(className => classNames[className])
.map(replace)
.join(' ');
}
return Array.prototype.map.call(arguments, replace).join(' ');
}
function replace(str) {
return str.replace(/\//g, '-');
}
module.exports = cx;
fbjs-0.8.16/src/__forks__/fetch.js 0000664 0000000 0000000 00000001125 13162307160 0016666 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule fetch
*/
'use strict';
// This hopefully supports the React Native case, which is already bringing along
// its own fetch polyfill. That should exist on `global`. If that doesn't exist
// then we'll try to polyfill, which might not work correctly in all environments.
if (global.fetch) {
module.exports = global.fetch.bind(global);
} else {
module.exports = require('isomorphic-fetch');
}
fbjs-0.8.16/src/__forks__/getUnboundedScrollPosition.js 0000664 0000000 0000000 00000002022 13162307160 0023121 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @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 && scrollable instanceof scrollable.Window) {
return {
x: scrollable.pageXOffset || scrollable.document.documentElement.scrollLeft,
y: scrollable.pageYOffset || scrollable.document.documentElement.scrollTop
};
}
return {
x: scrollable.scrollLeft,
y: scrollable.scrollTop
};
}
module.exports = getUnboundedScrollPosition;
fbjs-0.8.16/src/__forks__/invariant.js 0000664 0000000 0000000 00000002735 13162307160 0017600 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @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 validateFormat = function(format) {};
if (__DEV__) {
validateFormat = function(format) {
if (format === undefined) {
throw new Error('invariant requires an error message argument');
}
};
}
function invariant(condition, format, a, b, c, d, e, f) {
validateFormat(format);
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(
format.replace(/%s/g, function() { return args[argIndex++]; })
);
error.name = 'Invariant Violation';
}
error.framesToPop = 1; // we don't care about invariant's own frame
throw error;
}
}
module.exports = invariant;
fbjs-0.8.16/src/__forks__/monitorCodeUse.js 0000664 0000000 0000000 00000001403 13162307160 0020533 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2014-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @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;
fbjs-0.8.16/src/__forks__/requestAnimationFrame.js 0000664 0000000 0000000 00000001504 13162307160 0022101 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2014-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @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;
fbjs-0.8.16/src/__forks__/setImmediate.js 0000664 0000000 0000000 00000000620 13162307160 0020206 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule setImmediate
*/
'use strict';
// setimmediate adds setImmediate to the global. We want to make sure we export
// the actual function.
require('setimmediate')
module.exports = global.setImmediate;
fbjs-0.8.16/src/__forks__/warning.js 0000664 0000000 0000000 00000002767 13162307160 0017257 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2014-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @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__) {
function printWarning(format, ...args) {
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) {}
}
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) {
printWarning(format, ...args);
}
};
}
module.exports = warning;
fbjs-0.8.16/src/core/ 0000775 0000000 0000000 00000000000 13162307160 0014250 5 ustar 00root root 0000000 0000000 fbjs-0.8.16/src/core/CSSCore.js 0000664 0000000 0000000 00000010171 13162307160 0016047 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule CSSCore
* @typechecks
*/
const 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.
*/
/* Slow implementation for browsers that don't natively support .matches() */
function matchesSelector_SLOW(element, selector) {
let root = element;
while (root.parentNode) {
root = root.parentNode;
}
const all = root.querySelectorAll(selector);
return Array.prototype.indexOf.call(all, element) !== -1;
}
const 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 check 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;
},
/**
* Tests whether the element matches the selector specified
*
* @param {DOMNode|DOMWindow} element the element that we are querying
* @param {string} selector the CSS selector
* @return {boolean} true if the element matches the selector, false if not
*/
matchesSelector: function(element, selector) {
const matchesImpl = element.matches ||
element.webkitMatchesSelector ||
element.mozMatchesSelector ||
element.msMatchesSelector ||
(s => matchesSelector_SLOW(element, s));
return matchesImpl.call(element, selector);
},
};
module.exports = CSSCore;
fbjs-0.8.16/src/core/Deferred.js 0000664 0000000 0000000 00000004067 13162307160 0016335 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule Deferred
* @typechecks
* @flow
*/
/**
* Deferred provides a Promise-like API that exposes methods to resolve and
* reject the Promise. It is most useful when converting non-Promise code to use
* Promises.
*
* If you want to export the Promise without exposing access to the resolve and
* reject methods, you should export `getPromise` which returns a Promise with
* the same semantics excluding those methods.
*/
class Deferred {
_settled: boolean;
_promise: Promise;
_resolve: (value: Tvalue) => void;
_reject: (reason: Treason) => void;
constructor() {
this._settled = false;
this._promise = new Promise((resolve, reject) => {
this._resolve = (resolve: any);
this._reject = (reject: any);
});
}
getPromise(): Promise {
return this._promise;
}
resolve(value: Tvalue): void {
this._settled = true;
this._resolve(value);
}
reject(reason: Treason): void {
this._settled = true;
this._reject(reason);
}
catch(
onReject?: ?(error: any) => mixed
): Promise {
return Promise.prototype.catch.apply(this._promise, arguments);
}
then(
onFulfill?: ?(value: any) => mixed,
onReject?: ?(error: any) => mixed
): Promise {
return Promise.prototype.then.apply(this._promise, arguments);
}
done(
onFulfill?: ?(value: any) => mixed,
onReject?: ?(error: any) => mixed
): void {
// Embed the polyfill for the non-standard Promise.prototype.done so that
// users of the open source fbjs don't need a custom lib for Promise
const promise = arguments.length ?
this._promise.then.apply(this._promise, arguments) :
this._promise;
promise.then(undefined, function(err) {
setTimeout(function() {
throw err;
}, 0);
});
}
isSettled(): boolean {
return this._settled;
}
}
module.exports = Deferred;
fbjs-0.8.16/src/core/ExecutionEnvironment.js 0000664 0000000 0000000 00000001740 13162307160 0021000 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule ExecutionEnvironment
*/
'use strict';
const 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.
*/
const 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;
fbjs-0.8.16/src/core/Keys.js 0000664 0000000 0000000 00000001136 13162307160 0015522 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule Keys
*/
module.exports = {
BACKSPACE: 8,
TAB: 9,
RETURN: 13,
ALT: 18,
ESC: 27,
SPACE: 32,
PAGE_UP: 33,
PAGE_DOWN: 34,
END: 35,
HOME: 36,
LEFT: 37,
UP: 38,
RIGHT: 39,
DOWN: 40,
DELETE: 46,
COMMA: 188,
PERIOD: 190,
A: 65,
Z: 90,
ZERO: 48,
NUMPAD_0: 96,
NUMPAD_9: 105
};
fbjs-0.8.16/src/core/PromiseMap.js 0000664 0000000 0000000 00000002650 13162307160 0016665 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule PromiseMap
* @flow
*/
'use strict';
const Deferred = require('Deferred');
const invariant = require('invariant');
/**
* A map of asynchronous values that can be get or set in any order. Unlike a
* normal map, setting the value for a particular key more than once throws.
* Also unlike a normal map, a key can either be resolved or rejected.
*/
class PromiseMap {
_deferred: {[key:string]: Deferred};
constructor() {
this._deferred = {};
}
get(key: string): Promise {
return getDeferred(this._deferred, key).getPromise();
}
resolveKey(key: string, value: Tvalue): void {
const entry = getDeferred(this._deferred, key);
invariant(!entry.isSettled(), 'PromiseMap: Already settled `%s`.', key);
entry.resolve(value);
}
rejectKey(key: string, reason: Treason): void {
const entry = getDeferred(this._deferred, key);
invariant(!entry.isSettled(), 'PromiseMap: Already settled `%s`.', key);
entry.reject(reason);
}
}
function getDeferred(
entries: {[key: string]: Deferred},
key: string
): Deferred {
if (!entries.hasOwnProperty(key)) {
entries[key] = new Deferred();
}
return entries[key];
}
module.exports = PromiseMap;
fbjs-0.8.16/src/core/TouchEventUtils.js 0000664 0000000 0000000 00000002171 13162307160 0017714 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule TouchEventUtils
*/
const 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) {
const touches = nativeEvent.touches;
const changedTouches = nativeEvent.changedTouches;
const hasTouches = touches && touches.length > 0;
const hasChangedTouches = changedTouches && changedTouches.length > 0;
return !hasTouches && hasChangedTouches ? changedTouches[0] :
hasTouches ? touches[0] :
nativeEvent;
}
};
module.exports = TouchEventUtils;
fbjs-0.8.16/src/core/__tests__/ 0000775 0000000 0000000 00000000000 13162307160 0016206 5 ustar 00root root 0000000 0000000 fbjs-0.8.16/src/core/__tests__/PromiseMap-test.js 0000664 0000000 0000000 00000006357 13162307160 0021610 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @emails oncall+jsinfra
*/
/*eslint-disable fb-www/promise-termination */
'use strict';
jest.dontMock('PromiseMap');
const PromiseMap = require('PromiseMap');
describe('PromiseMap', () => {
beforeEach(() => {
jest.resetModuleRegistry();
});
it('can get a value after resolving it', () => {
const map = new PromiseMap();
let fooValue;
let barValue;
map.resolveKey('foo', 42);
map.resolveKey('bar', 1337);
map.get('foo').then(value => {
fooValue = value;
});
map.get('bar').then(value => {
barValue = value;
});
jest.runAllTimers();
expect(fooValue).toBe(42);
expect(barValue).toBe(1337);
});
it('can get a value before resolving it', () => {
const map = new PromiseMap();
let fooValue;
let barValue;
map.get('foo').then(value => {
fooValue = value;
});
map.get('bar').then(value => {
barValue = value;
});
map.resolveKey('foo', 42);
map.resolveKey('bar', 1337);
jest.runAllTimers();
expect(fooValue).toBe(42);
expect(barValue).toBe(1337);
});
it('can get an error after rejecting it', () => {
const map = new PromiseMap();
let fooValue;
let barValue;
map.rejectKey('foo', 42);
map.rejectKey('bar', 1337);
map.get('foo').catch(value => {
fooValue = value;
});
map.get('bar').catch(value => {
barValue = value;
});
jest.runAllTimers();
expect(fooValue).toBe(42);
expect(barValue).toBe(1337);
});
it('can get an error before rejecting it', () => {
const map = new PromiseMap();
let fooValue;
let barValue;
map.get('foo').catch(value => {
fooValue = value;
});
map.get('bar').catch(value => {
barValue = value;
});
map.rejectKey('foo', 42);
map.rejectKey('bar', 1337);
jest.runAllTimers();
expect(fooValue).toBe(42);
expect(barValue).toBe(1337);
});
it('throws if the same key is resolved more than once', () => {
const map = new PromiseMap();
let getValue;
map.resolveKey('foo', 42);
expect(() => {
map.resolveKey('foo', 1337);
}).toThrowError('PromiseMap: Already settled `foo`.');
map.get('foo').then(value => {
getValue = value;
});
jest.runAllTimers();
expect(getValue).toBe(42);
});
it('throws if the same key is rejected more than once', () => {
const map = new PromiseMap();
let getValue;
map.rejectKey('foo', 42);
expect(() => {
map.rejectKey('foo', 1337);
}).toThrowError('PromiseMap: Already settled `foo`.');
map.get('foo').catch(value => {
getValue = value;
});
jest.runAllTimers();
expect(getValue).toBe(42);
});
it('throws if the same key is both rejected and resolved', () => {
const map = new PromiseMap();
let getValue;
map.resolveKey('foo', 42);
expect(() => {
map.rejectKey('foo', 1337);
}).toThrowError('PromiseMap: Already settled `foo`.');
map.get('foo').then(value => {
getValue = value;
});
jest.runAllTimers();
expect(getValue).toBe(42);
});
});
fbjs-0.8.16/src/core/__tests__/areEqual-test.js 0000664 0000000 0000000 00000044763 13162307160 0021276 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @emails oncall+jsinfra
*/
'use strict';
jest.dontMock('areEqual');
const areEqual = require('areEqual');
describe('areEqual', function() {
function First() {
this.value = 1;
}
First.prototype.value = 1;
function Second() {
this.value = 1;
}
Second.prototype.value = 2;
it('works with basic equality and identity comparisons', () => {
// `null` is equal to `null`
expect(areEqual(null, null)).toBe(true);
// `undefined` is equal to `undefined`
expect(areEqual()).toBe(true);
// `0` is not equal to `-0`
expect(areEqual(0, -0)).toBe(false);
// Commutative equality is implemented for `0` and `-0`
expect(areEqual(-0, 0)).toBe(false);
// `null` is not equal to `undefined`
expect(areEqual(null, undefined)).toBe(false);
// Commutative equality is implemented for `null` and `undefined`
expect(areEqual(undefined, null)).toBe(false);
});
it('works with string object and primitive comparisons', () => {
// Identical string primitives are equal
expect(areEqual('Curly', 'Curly')).toBe(true);
// String objects with identical primitive values are equal
expect(areEqual(String('Curly'), String('Curly'))).toBe(true);
// String primitives and their corresponding object wrappers are equal
expect(areEqual(String('Curly'), 'Curly')).toBe(true);
// Commutative equality is implemented for string objects and primitives
expect(areEqual('Curly', String('Curly'))).toBe(true);
// String primitives with different values are not equal
expect(areEqual('Curly', 'Larry')).toBe(false);
// String objects with different primitive values are not equal
expect(areEqual(String('Curly'), String('Larry'))).toBe(false);
// String objects and objects with a custom `toString` method are not equal
expect(areEqual(String('Curly'), {toString() { return 'Curly'; }}))
.toBe(false);
});
it('works with number object and primitive comparisons.', () => {
// Identical number primitives are equal
expect(areEqual(75, 75)).toBe(true);
// Number objects with identical primitive values are equal
expect(areEqual(Number(75), Number(75))).toBe(true);
// Number primitives and their corresponding object wrappers are equal
expect(areEqual(75, Number(75))).toBe(true);
// Commutative equality is implemented for number objects and primitives
expect(areEqual(Number(75), 75)).toBe(true);
// `new Number(0)` and `-0` are not equal
expect(areEqual(Number(0), -0)).toBe(false);
// Commutative equality is implemented for `new Number(0)` and `-0`
expect(areEqual(0, Number(-0))).toBe(false);
// Number objects with different primitive values are not equal
expect(areEqual(Number(75), Number(63))).toBe(false);
// Number objects and objects with a `valueOf` method are not equal
expect(areEqual(Number(63), {valueOf: function() { return 63; }}))
.toBe(false);
});
it('works with comparisons involving `NaN`', () => {
// `NaN` is equal to `NaN`
expect(areEqual(NaN, NaN)).toBe(false);
// A number primitive is not equal to `NaN`
expect(areEqual(61, NaN)).toBe(false);
// A number object is not equal to `NaN`
expect(areEqual(Number(79), NaN)).toBe(false);
// `Infinity` is not equal to `NaN`
expect(areEqual(Infinity, NaN)).toBe(false);
});
it('works with boolean object and primitive comparisons', () => {
// Identical boolean primitives are equal
expect(areEqual(true, true)).toBe(true);
// Boolean objects with identical primitive values are equal
expect(areEqual(Boolean(), Boolean())).toBe(true);
// Boolean primitives and their corresponding object wrappers are equal
expect(areEqual(true, Boolean(true))).toBe(true);
// Commutative equality is implemented for booleans
expect(areEqual(Boolean(true), true)).toBe(true);
// Boolean objects with different primitive values are not equal
expect(areEqual(Boolean(true), Boolean())).toBe(false);
});
it('works with common type coercion', () => {
// Boolean objects are not equal to the boolean primitive `true`
expect(areEqual(true, Boolean(false))).toBe(false);
// String and number primitives with like values are not equal
expect(areEqual('75', 75)).toBe(false);
// String and number objects with like values are not equal
expect(areEqual(Number(63), String(63))).toBe(false);
// Commutative equality is implemented for like string and number values
expect(areEqual(75, '75')).toBe(false);
// Number and string primitives with like values are not equal
expect(areEqual(0, '')).toBe(false);
// Number and boolean primitives with like values are not equal
expect(areEqual(1, true)).toBe(false);
// Boolean and number objects with like values are not equal
expect(areEqual(Boolean(false), Number(0))).toBe(false);
// Boolean primitives and string objects with like values are not equal
expect(areEqual(false, String(''))).toBe(false);
// Dates and their corresponding numeric primitive values are not equal
expect(areEqual(12564504e5, new Date(2009, 9, 25))).toBe(false);
});
it('works with dates', () => {
// Date objects referencing identical times are equal
expect(areEqual(new Date(2009, 9, 25), new Date(2009, 9, 25)))
.toBe(true);
// Date objects referencing different times are not equal
expect(areEqual(new Date(2009, 9, 25), new Date(2009, 11, 13)))
.toBe(false);
// Date objects and objects with a `getTime` method are not equal
expect(areEqual(new Date(2009, 11, 13), {
getTime: function() {
return 12606876e5;
}
})).toBe(false);
// Invalid dates are not equal
expect(areEqual(new Date('Curly'), new Date('Curly'))).toBe(false);
});
it('works with functions', () => {
// Different functions with identical bodies and source code
// representations are not equal
expect(areEqual(First, Second)).toBe(false);
});
it('works with regular expressions', () => {
// RegExps with equivalent patterns and flags are equal
expect(areEqual(/(?:)/gim, /(?:)/gim)).toBe(true);
// RegExps with equivalent patterns and different flags are not equal
expect(areEqual(/(?:)/g, /(?:)/gi)).toBe(false);
// RegExps with different patterns and equivalent flags are not equal
expect(areEqual(/Moe/gim, /Curly/gim)).toBe(false);
// Commutative equality is implemented for RegExps
expect(areEqual(/(?:)/gi, /(?:)/g)).toBe(false);
// RegExps and RegExp-like objects are not equal
expect(areEqual(/Curly/g,
{source: 'Larry', global: true, ignoreCase: false, multiline: false}))
.toBe(false);
});
it('works with empty arrays, array-like objects, and object literals',
function() {
// Empty object literals are equal
expect(areEqual({}, {})).toBe(true);
// Empty array literals are equal
expect(areEqual([], [])).toBe(true);
// Empty nested arrays and objects are equal
expect(areEqual([{}], [{}])).toBe(true);
// Array-like objects and arrays are not equal
expect(areEqual({length: 0}, [])).toBe(false);
// Commutative equality is implemented for array-like objects
expect(areEqual([], {length: 0})).toBe(false);
// Object literals and array literals are not equal
expect(areEqual({}, [])).toBe(false);
// Commutative equality is implemented for objects and arrays
expect(areEqual([], {})).toBe(false);
});
it('works with arrays containing primitive and object values',
function() {
// Arrays containing identical primitives are equal
expect(areEqual([1, 'Larry', true], [1, 'Larry', true])).toBe(true);
// Arrays containing equivalent elements are equal
expect(areEqual([(/Moe/g), new Date(2009, 9, 25)], [(/Moe/g),
new Date(2009, 9, 25)])).toBe(true);
});
it('works with multidimentional arrays', () => {
const a = [Number(47), false, 'Larry', /Moe/, new Date(2009, 11, 13),
['running', 'biking', String('programming')], {a: 47}];
const b = [Number(47), false, 'Larry', /Moe/, new Date(2009, 11, 13),
['running', 'biking', String('programming')], {a: 47}];
const c = [Number(47), false, 'Larry', /Moe/, new Date(2009, 11, 13),
['running', 'biking', String('programming')], [32]];
// Arrays containing nested arrays and objects are recursively compared
expect(areEqual(a, b)).toBe(true);
expect(areEqual(a, c)).toBe(false);
// Arrays containing equivalent elements and different non-numeric
// properties are equal
expect(areEqual(a, b)).toBe(true);
a.push('White Rocks');
// Arrays of different lengths are not equal
expect(areEqual(a, b)).toBe(false);
a.push('East Boulder');
b.push('Gunbarrel Ranch', 'Teller Farm');
// Arrays of identical lengths containing different elements are not equal
expect(areEqual(a, b)).toBe(false);
});
it('works with sparse arrays', () => {
// Sparse arrays of identical lengths are equal
expect(areEqual(Array(3), Array(3))).toBe(true);
// Sparse arrays of different lengths are not equal when both are empty
expect(areEqual(Array(3), Array(6))).toBe(false);
});
it('works with simple objects', function() {
// Objects containing identical primitives are equal
expect(areEqual({a: 'Curly', b: 1, c: true}, {a: 'Curly', b: 1, c: true}))
.toBe(true);
// Objects containing equivalent members are equal
expect(areEqual({b: new Date(2009, 11, 13)}, {b: new Date(2009, 11, 13)}))
.toBe(true);
expect(areEqual({a: /Curly/g}, {a: /Curly/g})).toBe(true);
expect(areEqual({a: /Curly/g}, {b: /Curly/g})).toBe(false);
expect(areEqual({a: /Curly/g, b: new Date(2009, 11, 13)},
{a: /Curly/g, b: new Date(2009, 11, 13)})).toBe(true);
expect(areEqual({a: 1}, {b: 2})).toBe(false);
// Objects of identical sizes with different values are not equal
expect(areEqual({a: 63, b: 75}, {a: 61, b: 55})).toBe(false);
// Objects of identical sizes with different property names are not equal
expect(areEqual({a: 63, b: 75}, {a: 61, c: 55})).toBe(false);
// Objects of different sizes are not equal
expect(areEqual({a: 1, b: 2}, {a: 1})).toBe(false);
// Commutative equality is implemented for objects
expect(areEqual({a: 1}, {a: 1, b: 2})).toBe(false);
// Objects with identical keys and different values are not equivalent
expect(areEqual({x: 1, z: 3}, {x: 1, z: 2})).toBe(false);
// `A` contains nested objects and arrays.
var a = {
name: String('Moe Howard'),
age: Number(77),
stooge: true,
hobbies: ['acting'],
film: {
name: 'Sing a Song of Six Pants',
release: new Date(1947, 9, 30),
stars: [String('Larry Fine'), 'Shemp Howard'],
minutes: Number(16),
seconds: 54
}
};
// `B` contains equivalent nested objects and arrays.
var b = {
name: String('Moe Howard'),
age: Number(77),
stooge: true,
hobbies: ['acting'],
film: {
name: 'Sing a Song of Six Pants',
release: new Date(1947, 9, 30),
stars: [String('Larry Fine'), 'Shemp Howard'],
minutes: Number(16),
seconds: 54
}
};
// Objects with nested equivalent members are recursively compared
expect(areEqual(a, b)).toBe(true);
b.hobbies = ['swimming'];
expect(areEqual(a, b)).toBe(false);
});
it('works with instances', () => {
function First() {
this.value = 1;
}
First.prototype.value = 1;
function Second() {
this.value = 1;
}
Second.prototype.value = 2;
// Object instances are equal
expect(areEqual(new First(), new First())).toBe(true);
// Objects with different constructors and identical own properties
// are not equal
expect(areEqual(new First(), new Second())).toBe(false);
// Object instances and objects sharing equivalent properties
// are not equal
expect(areEqual({value: 1}, new First())).toBe(false);
// The prototype chain of objects should not be examined
expect(areEqual({value: 2}, new Second())).toBe(false);
});
it('works with circular arrays', () => {
let a, b;
(a = []).push(a);
(b = []).push(b);
// Arrays containing circular references are equal
expect(areEqual(a, b)).toBe(true);
a.push(String('Larry'));
b.push(String('Larry'));
// Arrays containing circular references and equivalent properties
// are equal
expect(areEqual(a, b)).toBe(true);
a.push('Shemp');
b.push('Curly');
// Arays containing circular references and different properties
// are not equal
expect(areEqual(a, b)).toBe(false);
a = ['everything is checked but', 'this', 'is not'];
a[1] = a;
b = ['everything is checked but', ['this', 'array'], 'is not'];
// Comparison of circular references with non-circular references
// are not equal
expect(areEqual(a, b)).toBe(false);
});
it('works with circular objects', () => {
let a, b;
a = {abc: null};
b = {abc: null};
a.abc = a;
b.abc = b;
// Objects containing circular references are equal
expect(areEqual(a, b)).toBe(true);
a.def = 75;
b.def = 75;
// Objects containing circular references and equivalent properties
// are equal
expect(areEqual(a, b)).toBe(true);
a.def = Number(75);
b.def = Number(63);
// Objects containing circular references and different properties
// are not equal
expect(areEqual(a, b)).toBe(false);
a = {everything: 'is checked', but: 'this', is: 'not'};
a.but = a;
b = {everything: 'is checked', but: {that:'object'}, is: 'not'};
// Comparison of circular references with non-circular object references
// are not equal
expect(areEqual(a, b)).toBe(false);
});
it('works with all sorts of cyclic structures', () => {
let a, b;
a = [{abc: null}];
b = [{abc: null}];
(a[0].abc = a).push(a);
(b[0].abc = b).push(b);
// Cyclic structures are equal
expect(areEqual(a, b)).toBe(true);
a[0].def = 'Larry';
b[0].def = 'Larry';
// Cyclic structures containing equivalent properties are equal
expect(areEqual(a, b)).toBe(true);
a[0].def = String('Larry');
b[0].def = String('Curly');
// Cyclic structures containing different properties are not equal
expect(areEqual(a, b)).toBe(false);
});
it('works using object implementing `valueOf`', () => {
class Vector {
constructor(x, y) {
this.x = x;
this.y = y;
this.valueOf = this.valueOf;
}
valueOf() {
return this.x + this.y;
}
}
const v1 = new Vector(1, 4);
const v2 = new Vector(2, 3);
expect(areEqual(v1, v2)).toBe(true);
const v3 = new Vector(1, 5);
expect(areEqual(v1, v3)).toBe(false);
});
it('works with primitives', () => {
expect(areEqual(1, 1)).toBe(true);
expect(areEqual(3.14, 3)).toBe(false);
expect(areEqual('a', 'a')).toBe(true);
expect(areEqual('a', 'b')).toBe(false);
expect(areEqual(true, true)).toBe(true);
expect(areEqual(true, false)).toBe(false);
// We should support Regex and Date Type
expect(areEqual(/a/, /a/)).toBe(true);
expect(areEqual(/a/, /b/)).toBe(false);
expect(areEqual(/a/i, /a/)).toBe(false);
expect(areEqual(/a/g, /a/)).toBe(false);
expect(areEqual(/a/m, /a/)).toBe(false);
expect(areEqual(new Date(1000), new Date(1000))).toBe(true);
expect(areEqual(new Date(1000), new Date(2000))).toBe(false);
});
it('works with null or undefined', () => {
expect(areEqual(null, null)).toBe(true);
expect(areEqual(undefined, undefined)).toBe(true);
// But this should be false
expect(areEqual(null, undefined)).toBe(false);
});
it('should compare two equal arrays and return true', () => {
expect(areEqual([1, 2, 3], [1, 2, 3])).toBe(true);
expect(areEqual(['a', 'b', 'c'], ['a', 'b', 'c'])).toBe(true);
});
it('should be false on arrays with values in different order ', () => {
const a = [3, 2, 1];
const b = [2, 3, 1];
expect(areEqual(a, b)).toBe(false);
// See if they actually contain the same values
a.sort();
b.sort();
expect(areEqual(a, b)).toBe(true);
});
it('should only work with equal values and equal types', () => {
const a = [1, '2', 3];
const b = [1, 2, 3];
expect(areEqual(a, b)).toBe(false);
});
it('should be true on empty arrays', () => {
expect(areEqual([], [])).toBe(true);
});
it('should be false on arrays with different length', () => {
const a = [1, 2];
const b = [3];
expect(areEqual(a, b)).toBe(false);
expect(areEqual(b, a)).toBe(false);
});
it('should be true if an array contains equal objects', () => {
const object = {};
const div = document.createElement('div');
const a = [object, div, window];
const b = [object, div, window];
expect(areEqual(a, b)).toBe(true);
});
it('should be true on null or undefined values', () => {
const a = [null, 1, undefined];
const b = [null, 1, undefined];
expect(areEqual(a, b)).toBe(true);
});
it('should compare two equal objects and return true', () => {
let a = {a: 1, b: 2, c: 3};
var b = {a: 1, b: 2, c: 3};
expect(areEqual(a, b)).toBe(true);
a = {'1': 'a', '2': 'b', '3': 'c'};
b = {'1': 'a', '2': 'b', '3': 'c'};
expect(areEqual(a, b)).toBe(true);
});
it('should compare two objects with random key order', () => {
const a = {a: 1, c: 3, b: 2};
var b = {c: 3, b: 2, a: 1};
expect(areEqual(a, b)).toBe(true);
});
it('should be false on array-like inputs', () => {
const a = [1, 2, 3];
const b = [1, 2, 3];
const arraylike = {'0': 1, '1': 2, '2': 3, length: 3};
const arraylikeB = {'0': 1, '1': 2, '2': 3, length: 3};
expect(areEqual(a, arraylike)).toBe(false);
expect(areEqual(arraylike, a)).toBe(false);
expect(areEqual(a, b)).toBe(true);
expect(areEqual(arraylike, arraylikeB)).toBe(true);
});
it('works with deep equality checks', () => {
const a = {array: [1, 2, 3, {a: '1', b: [1, 2, 5]}]};
var b = {array: [1, 2, 3, {a: '1', b: [1, 2, 5]}]};
expect(areEqual(a, b)).toBe(true);
b.array[3] = a.array[3];
expect(areEqual(a, b)).toBe(true);
});
it('works with values where triple-equals returns true', () => {
const div = document.createElement('div');
const a = {
a: null, b: undefined, c: window, d: div, e: true, f: 'string', g: 42
};
var b = {
c: window, b: undefined, g: 42, d: div, f: 'string', a: null, e: true
};
expect(areEqual(a, b)).toBe(true);
});
});
fbjs-0.8.16/src/core/__tests__/isEmpty-test.js 0000664 0000000 0000000 00000002710 13162307160 0021153 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @emails oncall+jsinfra
*/
jest.mock('_shouldPolyfillES6Collection');
const Map = require('Map');
const Set = require('Set');
const isEmpty = require('isEmpty');
const _shouldPolyfillES6Collection = require('_shouldPolyfillES6Collection');
describe('isEmpty', () => {
it('should return true for empty supported types', () => {
expect(isEmpty(undefined)).toBe(true);
expect(isEmpty(null)).toBe(true);
expect(isEmpty(false)).toBe(true);
expect(isEmpty(0)).toBe(true);
expect(isEmpty('')).toBe(true);
expect(isEmpty([])).toBe(true);
expect(isEmpty({})).toBe(true);
expect(isEmpty(Object.create(null))).toBe(true);
});
it('should return false for non-empty supported types', () => {
expect(isEmpty(1)).toBe(false);
expect(isEmpty('0')).toBe(false);
expect(isEmpty([1])).toBe(false);
expect(isEmpty({a: 1})).toBe(false);
});
it('should not allow maps and sets', () => {
// Ensure that `Map` and `Set` use non-native polyfills
_shouldPolyfillES6Collection.mockReturnValue(true);
// Polyfilled
expect(() => isEmpty(new Map())).toThrow();
expect(() => isEmpty(new Set())).toThrow();
// Native
expect(() => isEmpty(new global.Map())).toThrow();
expect(() => isEmpty(new global.Set())).toThrow();
});
});
fbjs-0.8.16/src/core/__tests__/joinClasses-test.js 0000664 0000000 0000000 00000002265 13162307160 0022003 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @emails oncall+jsinfra
*/
'use strict';
jest.dontMock('joinClasses');
const joinClasses = require('joinClasses');
describe('joinClasses', function() {
it('should return a single className', function() {
expect(joinClasses('aaa')).toEqual('aaa');
});
it('should join two classes together', function() {
const aaa = 'aaa';
const bbb = 'bbb';
expect(joinClasses(aaa, bbb)).toEqual('aaa bbb');
});
it('should join many classes together', function() {
const aaa = 'aaa';
const bbb = 'bbb';
const ccc = 'ccc';
const ddd = 'ddd';
const eee = 'eee';
expect(joinClasses(aaa, bbb, ccc, ddd, eee)).toEqual('aaa bbb ccc ddd eee');
});
it('should omit undefined and empty classes', function() {
const aaa = 'aaa';
let bbb;
const ccc = null;
const ddd = '';
const eee = 'eee';
expect(joinClasses(bbb)).toEqual('');
expect(joinClasses(bbb, bbb, bbb)).toEqual('');
expect(joinClasses(aaa, bbb, ccc, ddd, eee)).toEqual('aaa eee');
});
});
fbjs-0.8.16/src/core/__tests__/memoizeStringOnly-test.js 0000664 0000000 0000000 00000001205 13162307160 0023215 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @emails oncall+jsinfra
*/
'use strict';
describe('memoizeStringOnly', function() {
let memoizeStringOnly;
beforeEach(function() {
jest.resetModuleRegistry();
memoizeStringOnly = require('memoizeStringOnly');
});
it('should be transparent to callers', function() {
const callback = function(string) {
return string;
};
const memoized = memoizeStringOnly(callback);
expect(memoized('foo'), callback('foo'));
});
});
fbjs-0.8.16/src/core/__tests__/shallowEqual-test.js 0000664 0000000 0000000 00000004044 13162307160 0022164 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
*/
'use strict';
jest.dontMock('shallowEqual');
const shallowEqual = require('shallowEqual');
describe('shallowEqual', () => {
it('returns false if either argument is null', () => {
expect(shallowEqual(null, {})).toBe(false);
expect(shallowEqual({}, null)).toBe(false);
});
it('returns true if both arguments are null or undefined', () => {
expect(shallowEqual(null, null)).toBe(true);
expect(shallowEqual(undefined, undefined)).toBe(true);
});
it('returns true if arguments are not objects and are equal', () => {
expect(shallowEqual(1, 1)).toBe(true);
});
it('returns true if arguments are shallow equal', () => {
expect(
shallowEqual(
{a: 1, b: 2, c: 3},
{a: 1, b: 2, c: 3}
)
).toBe(true);
});
it('returns true when comparing NaN', () => {
expect(shallowEqual(NaN, NaN)).toBe(true);
expect(
shallowEqual(
{a: 1, b: 2, c: 3, d: NaN},
{a: 1, b: 2, c: 3, d: NaN}
)
).toBe(true);
});
it('returns false if arguments are not objects and not equal', () => {
expect(
shallowEqual(
1,
2
)
).toBe(false);
});
it('returns false if only one argument is not an object', () => {
expect(
shallowEqual(
1,
{}
)
).toBe(false);
});
it('returns false if first argument has too many keys', () => {
expect(
shallowEqual(
{a: 1, b: 2, c: 3},
{a: 1, b: 2}
)
).toBe(false);
});
it('returns false if second argument has too many keys', () => {
expect(
shallowEqual(
{a: 1, b: 2},
{a: 1, b: 2, c: 3}
)
).toBe(false);
});
it('returns false if arguments are not shallow equal', () => {
expect(
shallowEqual(
{a: 1, b: 2, c: {}},
{a: 1, b: 2, c: {}}
)
).toBe(false);
});
});
fbjs-0.8.16/src/core/__tests__/sprintf-test.js 0000664 0000000 0000000 00000000703 13162307160 0021206 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @emails oncall+jsinfra
*/
jest
.dontMock('sprintf');
const sprintf = require('sprintf');
describe('sprintf', function() {
it('works with %s', function() {
expect(sprintf('aaa %s bbb %s ccc', '111', '222'))
.toBe('aaa 111 bbb 222 ccc');
});
});
fbjs-0.8.16/src/core/_shouldPolyfillES6Collection.js 0000664 0000000 0000000 00000002572 13162307160 0022316 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule _shouldPolyfillES6Collection
* @preventMunge
* @flow
*/
/**
* Checks whether a collection name (e.g. "Map" or "Set") has a native polyfill
* that is safe to be used.
*/
function shouldPolyfillES6Collection(collectionName: string): boolean {
const Collection = global[collectionName];
if (Collection == null) {
return true;
}
// The iterator protocol depends on `Symbol.iterator`. If a collection is
// implemented, but `Symbol` is not, it's going to break iteration because
// we'll be using custom "@@iterator" instead, which is not implemented on
// native collections.
if (typeof global.Symbol !== 'function') {
return true;
}
const proto = Collection.prototype;
// These checks are adapted from es6-shim: https://fburl.com/34437854
// NOTE: `isCallableWithoutNew` and `!supportsSubclassing` are not checked
// because they make debugging with "break on exceptions" difficult.
return Collection == null ||
typeof Collection !== 'function' ||
typeof proto.clear !== 'function' ||
new Collection().size !== 0 ||
typeof proto.keys !== 'function' ||
typeof proto.forEach !== 'function';
}
module.exports = shouldPolyfillES6Collection;
fbjs-0.8.16/src/core/areEqual.js 0000664 0000000 0000000 00000005516 13162307160 0016354 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule areEqual
* @flow
*/
const aStackPool = [];
const bStackPool = [];
/**
* Checks if two values are equal. Values may be primitives, arrays, or objects.
* Returns true if both arguments have the same keys and values.
*
* @see http://underscorejs.org
* @copyright 2009-2013 Jeremy Ashkenas, DocumentCloud Inc.
* @license MIT
*/
function areEqual(a: any, b: any): boolean {
const aStack = aStackPool.length ? aStackPool.pop() : [];
const bStack = bStackPool.length ? bStackPool.pop() : [];
const result = eq(a, b, aStack, bStack);
aStack.length = 0;
bStack.length = 0;
aStackPool.push(aStack);
bStackPool.push(bStack);
return result;
}
function eq(a: any, b: any, aStack: Array, bStack: Array): boolean {
if (a === b) {
// Identical objects are equal. `0 === -0`, but they aren't identical.
return a !== 0 || 1 / a == 1 / b;
}
if (a == null || b == null) {
// a or b can be `null` or `undefined`
return false;
}
if (typeof a != 'object' || typeof b != 'object') {
return false;
}
const objToStr = Object.prototype.toString;
const className = objToStr.call(a);
if (className != objToStr.call(b)) {
return false;
}
switch (className) {
case '[object String]':
return a == String(b);
case '[object Number]':
return isNaN(a) || isNaN(b) ? false : a == Number(b);
case '[object Date]':
case '[object Boolean]':
return +a == +b;
case '[object RegExp]':
return a.source == b.source &&
a.global == b.global &&
a.multiline == b.multiline &&
a.ignoreCase == b.ignoreCase;
}
// Assume equality for cyclic structures.
let length = aStack.length;
while (length--) {
if (aStack[length] == a) {
return bStack[length] == b;
}
}
aStack.push(a);
bStack.push(b);
let size = 0;
// Recursively compare objects and arrays.
if (className === '[object Array]') {
size = a.length;
if (size !== b.length) {
return false;
}
// Deep compare the contents, ignoring non-numeric properties.
while (size--) {
if (!eq(a[size], b[size], aStack, bStack)) {
return false;
}
}
} else {
if (a.constructor !== b.constructor) {
return false;
}
if (a.hasOwnProperty('valueOf') && b.hasOwnProperty('valueOf')) {
return a.valueOf() == b.valueOf();
}
const keys = Object.keys(a);
if (keys.length != Object.keys(b).length) {
return false;
}
for (let i = 0; i < keys.length; i++) {
if (!eq(a[keys[i]], b[keys[i]], aStack, bStack)) {
return false;
}
}
}
aStack.pop();
bStack.pop();
return true;
}
module.exports = areEqual;
fbjs-0.8.16/src/core/camelize.js 0000664 0000000 0000000 00000001125 13162307160 0016376 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule camelize
* @typechecks
*/
const _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;
fbjs-0.8.16/src/core/camelizeStyleName.js 0000664 0000000 0000000 00000001623 13162307160 0020223 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule camelizeStyleName
* @typechecks
*/
'use strict';
const camelize = require('camelize');
const 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;
fbjs-0.8.16/src/core/createArrayFromMixed.js 0000664 0000000 0000000 00000007317 13162307160 0020673 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule createArrayFromMixed
* @typechecks
*/
const 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) {
const length = obj.length;
// Some browsers 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'
);
invariant(
typeof obj.callee !== 'function',
'toArray: Object can\'t be `arguments`. Use rest params ' +
'(function(...args) {}) or Array.from() instead.'
);
// 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.
const ret = Array(length);
for (let ii = 0; ii < length; ii++) {
ret[ii] = obj[ii];
}
return ret;
}
/**
* 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;
fbjs-0.8.16/src/core/createNodesFromMarkup.js 0000664 0000000 0000000 00000004613 13162307160 0021052 0 ustar 00root root 0000000 0000000 /**
* Copyright (c) 2013-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @providesModule createNodesFromMarkup
* @typechecks
*/
/*eslint-disable fb-www/unsafe-html*/
const ExecutionEnvironment = require('ExecutionEnvironment');
const createArrayFromMixed = require('createArrayFromMixed');
const getMarkupWrap = require('getMarkupWrap');
const invariant = require('invariant');
/**
* Dummy container used to render all markup.
*/
const dummyNode =
ExecutionEnvironment.canUseDOM ? document.createElement('div') : null;
/**
* Pattern used by `getNodeName`.
*/
const 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) {
const 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
*