├── .eslintignore ├── .eslintrc.js ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .prettierrc.js ├── .watchmanconfig ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── package.json ├── packages ├── babel-preset-fbjs │ ├── .gitignore │ ├── .npmignore │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── configure.js │ ├── index.js │ ├── package.json │ ├── plugins │ │ ├── __tests__ │ │ │ ├── __snapshots__ │ │ │ │ └── inline-requires-test.js.snap │ │ │ ├── dev-declaration-test.js │ │ │ ├── dev-expression-test.js │ │ │ ├── inline-requires-test.js │ │ │ ├── object-assign-test.js │ │ │ └── rewrite-modules-test.js │ │ ├── auto-importer.js │ │ ├── dev-declaration.js │ │ ├── dev-expression.js │ │ ├── inline-requires.js │ │ ├── object-assign.js │ │ ├── rewrite-modules.js │ │ └── test-utils │ │ │ └── validateOutputAst.js │ └── yarn.lock ├── eslint-config-fb-strict │ ├── index.js │ └── package.json ├── eslint-config-fbjs-opensource │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── index.js │ ├── package.json │ ├── warning.js │ └── yarn.lock ├── eslint-config-fbjs │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── index.js │ ├── package.json │ ├── scripts │ │ └── check-rules.js │ ├── shared.js │ ├── strict.js │ └── utils │ │ └── change-error-level.js ├── fbjs-css-vars │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── index.js │ └── package.json ├── fbjs-eslint-utils │ ├── LICENSE │ ├── README.md │ ├── change-error-level.js │ ├── globals.js │ ├── index.js │ ├── package.json │ └── shared.js ├── fbjs-scripts │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── babel │ │ └── default-options.js │ ├── gulp │ │ ├── check-dependencies.js │ │ ├── module-map.js │ │ ├── shared │ │ │ └── provides-module.js │ │ └── strip-provides-module.js │ ├── jest │ │ ├── createCacheKeyFunction.js │ │ ├── environment.js │ │ └── preprocessor.js │ ├── node │ │ ├── check-dev-engines.js │ │ └── check-lib-requires.js │ ├── package.json │ ├── third-party-module-map.json │ └── yarn.lock ├── fbjs │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── flow │ │ └── lib │ │ │ └── dev.js │ ├── gulpfile.js │ ├── index.js │ ├── package.json │ ├── src │ │ ├── .flowconfig │ │ ├── __forks__ │ │ │ ├── Promise.js │ │ │ ├── Promise.native.js │ │ │ ├── SiteData.js │ │ │ ├── Style.js │ │ │ ├── TokenizeUtil.js │ │ │ ├── URI.js │ │ │ ├── UserAgentData.js │ │ │ ├── __tests__ │ │ │ │ └── fetch-test.js │ │ │ ├── cssVar.js │ │ │ ├── cx.js │ │ │ ├── fetch.js │ │ │ ├── getUnboundedScrollPosition.js │ │ │ ├── invariant.js │ │ │ ├── isEventSupported.js │ │ │ ├── monitorCodeUse.js │ │ │ ├── requestAnimationFrame.js │ │ │ ├── requestAnimationFramePolyfill.js │ │ │ ├── setImmediate.js │ │ │ └── warning.js │ │ ├── core │ │ │ ├── CSSCore.js │ │ │ ├── Deferred.js │ │ │ ├── ExecutionEnvironment.js │ │ │ ├── Keys.js │ │ │ ├── PromiseMap.js │ │ │ ├── TouchEventUtils.js │ │ │ ├── __tests__ │ │ │ │ ├── PromiseMap-test.js │ │ │ │ ├── areEqual-test.js │ │ │ │ ├── debounceCore-test.js │ │ │ │ ├── isEmpty-test.js │ │ │ │ ├── joinClasses-test.js │ │ │ │ ├── memoizeStringOnly-test.js │ │ │ │ ├── shallowEqual-test.js │ │ │ │ └── sprintf-test.js │ │ │ ├── _shouldPolyfillES6Collection.js │ │ │ ├── areEqual.js │ │ │ ├── camelize.js │ │ │ ├── camelizeStyleName.js │ │ │ ├── cancelAnimationFramePolyfill.js │ │ │ ├── clamp.js │ │ │ ├── createArrayFromMixed.js │ │ │ ├── createNodesFromMarkup.js │ │ │ ├── debounceCore.js │ │ │ ├── dom │ │ │ │ ├── Scroll.js │ │ │ │ ├── __tests__ │ │ │ │ │ ├── Scroll-test.js │ │ │ │ │ ├── getActiveElement-test.js │ │ │ │ │ ├── isNode-test.js │ │ │ │ │ └── isTextNode-test.js │ │ │ │ ├── containsNode.js │ │ │ │ ├── focusNode.js │ │ │ │ ├── getActiveElement.js │ │ │ │ ├── getDocumentScrollElement.js │ │ │ │ ├── getElementPosition.js │ │ │ │ ├── getElementRect.js │ │ │ │ ├── getScrollPosition.js │ │ │ │ ├── getStyleProperty.js │ │ │ │ ├── getViewportDimensions.js │ │ │ │ ├── isNode.js │ │ │ │ └── isTextNode.js │ │ │ ├── emptyFunction.js │ │ │ ├── emptyObject.js │ │ │ ├── enumerate.js │ │ │ ├── flattenArray.js │ │ │ ├── getMarkupWrap.js │ │ │ ├── getVendorPrefixedName.js │ │ │ ├── hyphenate.js │ │ │ ├── hyphenateStyleName.js │ │ │ ├── isEmail.js │ │ │ ├── isEmpty.js │ │ │ ├── joinClasses.js │ │ │ ├── memoizeStringOnly.js │ │ │ ├── nativeRequestAnimationFrame.js │ │ │ ├── resolveImmediate.js │ │ │ ├── shallowEqual.js │ │ │ └── sprintf.js │ │ ├── core_windowless │ │ │ ├── __tests__ │ │ │ │ └── removeFromArray-test.js │ │ │ └── removeFromArray.js │ │ ├── crypto │ │ │ ├── __mocks__ │ │ │ │ ├── base62.js │ │ │ │ └── crc32.js │ │ │ ├── __tests__ │ │ │ │ ├── base62-test.js │ │ │ │ └── crc32-test.js │ │ │ ├── base62.js │ │ │ └── crc32.js │ │ ├── datatransfer │ │ │ ├── DataTransfer.js │ │ │ └── PhotosMimeType.js │ │ ├── dom │ │ │ ├── BrowserSupportCore.js │ │ │ ├── DOMMouseMoveTracker.js │ │ │ ├── ReactWheelHandler.js │ │ │ ├── normalizeWheel.js │ │ │ └── translateDOMPositionXY.js │ │ ├── fetch │ │ │ ├── __mocks__ │ │ │ │ ├── fetch.js │ │ │ │ └── fetchWithRetries.js │ │ │ ├── __tests__ │ │ │ │ ├── fetchMock-test.js │ │ │ │ └── fetchWithRetries-test.js │ │ │ └── fetchWithRetries.js │ │ ├── functional │ │ │ ├── __tests__ │ │ │ │ ├── compactArray-test.js │ │ │ │ ├── concatAllArray-test.js │ │ │ │ ├── countDistinct-test.js │ │ │ │ ├── distinctArray-test.js │ │ │ │ ├── equalsIterable-test.js │ │ │ │ ├── equalsSet-test.js │ │ │ │ ├── everyObject-test.js │ │ │ │ ├── everySet-test.js │ │ │ │ ├── filterObject-test.js │ │ │ │ ├── flatMapArray-test.js │ │ │ │ ├── forEachObject-test.js │ │ │ │ ├── groupArray-test.js │ │ │ │ ├── mapObject-test.js │ │ │ │ ├── maxBy-test.js │ │ │ │ ├── minBy-test.js │ │ │ │ ├── partitionArray-test.js │ │ │ │ ├── partitionObject-test.js │ │ │ │ ├── partitionObjectByKey-test.js │ │ │ │ ├── someObject-test.js │ │ │ │ └── someSet-test.js │ │ │ ├── compactArray.js │ │ │ ├── concatAllArray.js │ │ │ ├── countDistinct.js │ │ │ ├── distinctArray.js │ │ │ ├── equalsIterable.js │ │ │ ├── equalsSet.js │ │ │ ├── everyObject.js │ │ │ ├── everySet.js │ │ │ ├── filterObject.js │ │ │ ├── flatMapArray.js │ │ │ ├── forEachObject.js │ │ │ ├── groupArray.js │ │ │ ├── mapObject.js │ │ │ ├── maxBy.js │ │ │ ├── minBy.js │ │ │ ├── partitionArray.js │ │ │ ├── partitionObject.js │ │ │ ├── partitionObjectByKey.js │ │ │ ├── someObject.js │ │ │ └── someSet.js │ │ ├── intl │ │ │ └── Locale.js │ │ ├── key-mirror │ │ │ ├── __tests__ │ │ │ │ ├── keyMirror-test.js │ │ │ │ └── keyMirrorRecursive-test.js │ │ │ ├── keyMirror.js │ │ │ ├── keyMirrorRecursive.js │ │ │ └── keyOf.js │ │ ├── misc │ │ │ ├── getByPath.js │ │ │ └── isInternationalPhoneNumber.js │ │ ├── performance │ │ │ ├── __tests__ │ │ │ │ └── performanceNow-test.js │ │ │ ├── performance.js │ │ │ └── performanceNow.js │ │ ├── request │ │ │ └── xhrSimpleDataSerializer.js │ │ ├── struct │ │ │ ├── CircularBuffer.js │ │ │ ├── Heap.js │ │ │ ├── IntegerBufferSet.js │ │ │ ├── PrefixIntervalTree.js │ │ │ └── __tests__ │ │ │ │ ├── CircularBuffer-test.js │ │ │ │ ├── Heap-test.js │ │ │ │ ├── IntegerBufferSet-test.js │ │ │ │ └── PrefixIntervalTree-test.js │ │ ├── stubs │ │ │ ├── ErrorUtils.js │ │ │ ├── EventListener.js │ │ │ └── __mocks__ │ │ │ │ └── ErrorUtils.js │ │ ├── unicode │ │ │ ├── README.md │ │ │ ├── UnicodeBidi.js │ │ │ ├── UnicodeBidiDirection.js │ │ │ ├── UnicodeBidiService.js │ │ │ ├── UnicodeCJK.js │ │ │ ├── UnicodeHangulKorean.js │ │ │ ├── UnicodeUtils.js │ │ │ ├── UnicodeUtilsExtra.js │ │ │ └── __tests__ │ │ │ │ ├── UnicodeBidi-test.js │ │ │ │ ├── UnicodeBidiDirection-test.js │ │ │ │ ├── UnicodeBidiService-test.js │ │ │ │ ├── UnicodeCJK-test.js │ │ │ │ ├── UnicodeHangulKorean-test.js │ │ │ │ ├── UnicodeUtils-test.js │ │ │ │ └── UnicodeUtilsExtra-test.js │ │ ├── useragent │ │ │ ├── UserAgent.js │ │ │ ├── VersionRange.js │ │ │ └── __tests__ │ │ │ │ ├── UserAgent-test.js │ │ │ │ └── VersionRange-test.js │ │ └── utils │ │ │ ├── __mocks__ │ │ │ └── nullthrows.js │ │ │ ├── __tests__ │ │ │ └── nullthrows-test.js │ │ │ └── nullthrows.js │ └── yarn.lock └── signedsource │ ├── LICENSE │ ├── __tests__ │ └── signedsource-test.js │ ├── index.js │ ├── package.json │ └── yarn.lock └── yarn.lock /.eslintignore: -------------------------------------------------------------------------------- 1 | packages/fbjs/flow/ 2 | packages/fbjs/lib/ 3 | node_modules 4 | # TODO: Fix warnings upstream so this output becomes useful 5 | packages/fbjs/src/ 6 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: 'hermes-eslint', 3 | extends: [ 4 | require.resolve('./packages/eslint-config-fbjs'), 5 | ], 6 | }; 7 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | ci: 7 | runs-on: ubuntu-latest 8 | strategy: 9 | fail-fast: false 10 | matrix: 11 | node-version: ['14', '16', '17'] 12 | cmd: [lint, "fbjs:build", "fbjs:test", "fbjs:flow", "preset:test", "signedsource:test"] 13 | steps: 14 | - uses: actions/checkout@v2 15 | - name: Use Node.js ${{ matrix.node-version }} 16 | uses: actions/setup-node@v2 17 | with: 18 | node-version: ${{ matrix.node-version }} 19 | cache: 'yarn' 20 | - name: Install dependencies 21 | run: yarn install --frozen-lockfile 22 | - name: Run ${{ matrix.cmd }} 23 | run: yarn run ${{ matrix.cmd }} 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | packages/fbjs/lib/* 4 | packages/fbjs/module-map.json 5 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | // Copyright 2004-present Facebook. All Rights Reserved. 2 | 3 | 'use strict'; 4 | 5 | module.exports = { 6 | singleQuote: true, 7 | trailingComma: 'all', 8 | bracketSpacing: false, 9 | jsxBracketSameLine: true, 10 | parser: 'flow', 11 | requirePragma: true, 12 | }; 13 | -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/facebook/fbjs/3d094a146b56e09836af1ef00c33810952585ead/.watchmanconfig -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | Facebook has adopted a Code of Conduct that we expect project participants to adhere to. Please [read the full text](https://code.facebook.com/codeofconduct) so that you can understand what actions will and will not be tolerated. 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Facebook Open Source Projects 2 | 3 | We want to make contributing to this project as easy and transparent as 4 | possible. 5 | 6 | ## Our Development Process 7 | 8 | This project is mainly for Facebook developers to ship dependencies to our 9 | other projects. Some of this code is synced out from internal repositories. 10 | 11 | ## Pull Requests 12 | 13 | Since this project's primary goal is to support Facebook projects and 14 | engineers, we may be unresponsive to community pull requests. In addition, 15 | since some of this code is synced out from internal locations, it can be 16 | difficult for us to accept PRs. We'll do our best to accomodate but we may not 17 | be able to accept all contributions. 18 | 19 | ## Contributor License Agreement ("CLA") 20 | 21 | In order to accept your pull request, 22 | we need you to submit a CLA. You only need to do this once to work on any of 23 | Facebook's open source projects. 24 | 25 | Complete your CLA here: 26 | 27 | ## Issues We use GitHub issues to track public bugs. 28 | 29 | Please ensure your 30 | description is clear and has sufficient instructions to be able to reproduce 31 | the issue. 32 | 33 | Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the 34 | safe disclosure of security bugs. In those cases, please go through the process 35 | outlined on that page and do not file a public issue. 36 | 37 | ## License 38 | 39 | By contributing to FBJS, you agree that your contributions will be licensed 40 | under the LICENSE file in the root directory of this source tree. 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2013-present, Facebook, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FBJS 2 | 3 | ## Purpose 4 | 5 | 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. 6 | 7 | For more information on how to build and use FBJS, click [here](https://github.com/facebook/fbjs/tree/main/packages/fbjs). This library includes a number of packages that can be accessed in the [packages](https://github.com/facebook/fbjs/tree/main/packages) folder. For more information on what each package does and how to run it, access the individual package from within the folder. 8 | 9 | **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. 10 | 11 | ## License 12 | 13 | FBJS and the other packages included here are MIT licensed, as found in the LICENSE file. 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fbjs-build", 3 | "private": true, 4 | "license": "MIT", 5 | "devDependencies": { 6 | "hermes-eslint": "^0.8.0", 7 | "eslint": "^8.19.0", 8 | "eslint-config-fbjs": "0.0.0", 9 | "eslint-plugin-babel": "^5.2.1", 10 | "eslint-plugin-ft-flow": "^2.0.1", 11 | "eslint-plugin-jsx-a11y": "^6.6.0", 12 | "eslint-plugin-react": "^7.30.1", 13 | "prettier": "^1.16.4" 14 | }, 15 | "scripts": { 16 | "prettier": "find . -name node_modules -prune -or -name dist -prune -or -name '*.js' -print | xargs prettier --write", 17 | "lint": "eslint .", 18 | "fbjs:build": "cd packages/fbjs && yarn && yarn run build", 19 | "fbjs:test": "cd packages/fbjs && yarn && yarn run test", 20 | "fbjs:flow": "cd packages/fbjs && yarn && yarn run flow", 21 | "preset:test": "cd packages/babel-preset-fbjs && yarn && yarn run test", 22 | "signedsource:test": "cd packages/signedsource && yarn && yarn run test" 23 | }, 24 | "prettier": { 25 | "requirePragma": true, 26 | "singleQuote": true, 27 | "trailingComma": "es5", 28 | "bracketSpacing": false, 29 | "jsxBracketSameLine": true 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packages/babel-preset-fbjs/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | -------------------------------------------------------------------------------- /packages/babel-preset-fbjs/.npmignore: -------------------------------------------------------------------------------- 1 | __tests__ 2 | node_modules 3 | npm-debug.log 4 | -------------------------------------------------------------------------------- /packages/babel-preset-fbjs/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [Unreleased] 2 | 3 | ## [2.1.4] - 2017-06-16 4 | 5 | ### Fixed 6 | - `inline-requires` works with named imports and no longer leaks paths after use. 7 | 8 | ## [2.1.3] - 2017-06-08 9 | 10 | ### Fixed 11 | - `inline-requires` will stop unintentionally using Flow declarations as bindings. 12 | 13 | ## [2.1.2] - 2017-05-02 14 | 15 | ### Fixed 16 | - `inline-requires` works better with other transforms (eg 'babel-plugin-transform-es2015-modules-commonjs'). 17 | 18 | ## [2.1.1] - 2017-04-26 19 | 20 | ### Fixed 21 | - `inline-requires` transform properly handles identifiers within functions whose definitions appear earlier in the file than the require call. 22 | 23 | ## [2.1.0] - 2016-10-07 24 | 25 | ### Added 26 | - Modules using `__DEV__` will have the declaration inlined for `.js.flow` file generation. 27 | 28 | ### Fixed 29 | - `typeof` imports are properly rewritten. 30 | 31 | 32 | ## [2.0.0] - 2016-05-25 33 | 34 | ### Added 35 | - More syntaxes are parsed for `.js.flow` file generation: `babel-plugin-syntax-class-properties` & `babel-plugin-syntax-jsx` 36 | - 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` 37 | - 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`. 38 | 39 | ### Fixed 40 | - Type imports are properly rewritten with the rewrite-modules transform. 41 | 42 | 43 | ## [1.0.0] - 2016-04-28 44 | 45 | ### Added 46 | - Initial release as a separate module. 47 | -------------------------------------------------------------------------------- /packages/babel-preset-fbjs/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2013-present, Facebook, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/babel-preset-fbjs/README.md: -------------------------------------------------------------------------------- 1 | # babel-preset-fbjs 2 | 3 | > Babel preset for Facebook projects. 4 | 5 | ## Install 6 | 7 | ```sh 8 | $ npm install --save-dev babel-preset-fbjs 9 | ``` 10 | 11 | ## Basic Usage 12 | 13 | ### Via `.babelrc` 14 | 15 | **.babelrc** 16 | 17 | ```json 18 | { 19 | "presets": ["fbjs"] 20 | } 21 | ``` 22 | 23 | ### Via CLI 24 | 25 | ```sh 26 | $ babel script.js --presets fbjs 27 | ``` 28 | 29 | ### Via Node API 30 | 31 | ```javascript 32 | require('@babel/core').transform('code', { 33 | presets: ['fbjs'] 34 | }); 35 | ``` 36 | 37 | ## Advanced Usage 38 | 39 | ```javascript 40 | require('@babel/core').transform('code', { 41 | presets: [ 42 | require('babel-preset-fbjs/configure')({ 43 | autoImport: true, 44 | inlineRequires: false, 45 | rewriteModules: {}, 46 | stripDEV: false 47 | } 48 | ] 49 | }); 50 | ``` 51 | -------------------------------------------------------------------------------- /packages/babel-preset-fbjs/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | module.exports = require('./configure'); 9 | -------------------------------------------------------------------------------- /packages/babel-preset-fbjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "babel-preset-fbjs", 3 | "version": "3.4.0", 4 | "description": "Babel preset for Facebook projects.", 5 | "repository": "facebook/fbjs", 6 | "license": "MIT", 7 | "main": "index.js", 8 | "scripts": { 9 | "test": "NODE_ENV=test jest" 10 | }, 11 | "dependencies": { 12 | "@babel/plugin-transform-class-properties": "^7.0.0", 13 | "@babel/plugin-transform-object-rest-spread": "^7.0.0", 14 | "@babel/plugin-syntax-class-properties": "^7.0.0", 15 | "@babel/plugin-syntax-flow": "^7.0.0", 16 | "@babel/plugin-syntax-jsx": "^7.0.0", 17 | "@babel/plugin-syntax-object-rest-spread": "^7.0.0", 18 | "@babel/plugin-transform-arrow-functions": "^7.0.0", 19 | "@babel/plugin-transform-block-scoped-functions": "^7.0.0", 20 | "@babel/plugin-transform-block-scoping": "^7.0.0", 21 | "@babel/plugin-transform-classes": "^7.0.0", 22 | "@babel/plugin-transform-computed-properties": "^7.0.0", 23 | "@babel/plugin-transform-destructuring": "^7.0.0", 24 | "@babel/plugin-transform-flow-strip-types": "^7.0.0", 25 | "@babel/plugin-transform-for-of": "^7.0.0", 26 | "@babel/plugin-transform-function-name": "^7.0.0", 27 | "@babel/plugin-transform-literals": "^7.0.0", 28 | "@babel/plugin-transform-member-expression-literals": "^7.0.0", 29 | "@babel/plugin-transform-modules-commonjs": "^7.0.0", 30 | "@babel/plugin-transform-object-super": "^7.0.0", 31 | "@babel/plugin-transform-parameters": "^7.0.0", 32 | "@babel/plugin-transform-property-literals": "^7.0.0", 33 | "@babel/plugin-transform-react-display-name": "^7.0.0", 34 | "@babel/plugin-transform-react-jsx": "^7.0.0", 35 | "@babel/plugin-transform-shorthand-properties": "^7.0.0", 36 | "@babel/plugin-transform-spread": "^7.0.0", 37 | "@babel/plugin-transform-template-literals": "^7.0.0", 38 | "babel-plugin-syntax-trailing-function-commas": "^7.0.0-beta.0" 39 | }, 40 | "devDependencies": { 41 | "@babel/core": "^7.0.0", 42 | "babel-plugin-tester": "^5.5.2", 43 | "jest-cli": "^23.6.0" 44 | }, 45 | "peerDependencies": { 46 | "@babel/core": "^7.0.0" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /packages/babel-preset-fbjs/plugins/__tests__/dev-declaration-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | /* eslint-disable max-len */ 11 | 12 | let babel = require('@babel/core'); 13 | let devDeclaration = require('../dev-declaration'); 14 | const validateOutputAst = require('../test-utils/validateOutputAst'); 15 | 16 | function transform(input) { 17 | const result = babel.transform(input, { 18 | plugins: ['@babel/plugin-syntax-flow', devDeclaration], 19 | }); 20 | validateOutputAst(result.ast); 21 | return result.code; 22 | } 23 | 24 | function compare(input, output) { 25 | var compiled = transform(input); 26 | expect(compiled).toEqual(output); 27 | } 28 | 29 | describe('dev-declaration', function() { 30 | 31 | it('should replace calls', () => { 32 | compare( 33 | `if (__DEV__) console.log();`, 34 | `declare var __DEV__: boolean; 35 | if (__DEV__) console.log();`); 36 | }); 37 | 38 | }); 39 | -------------------------------------------------------------------------------- /packages/babel-preset-fbjs/plugins/__tests__/dev-expression-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | /* eslint-disable max-len */ 11 | 12 | let babel = require('@babel/core'); 13 | let devExpression = require('../dev-expression'); 14 | const validateOutputAst = require('../test-utils/validateOutputAst'); 15 | 16 | function transform(input) { 17 | const result = babel.transform(input, { 18 | plugins: [devExpression], 19 | }); 20 | validateOutputAst(result.ast); 21 | return result.code; 22 | } 23 | 24 | function compare(input, output) { 25 | var compiled = transform(input); 26 | expect(compiled).toEqual(output); 27 | } 28 | 29 | var oldEnv; 30 | 31 | describe('dev-expression', function() { 32 | beforeEach(() => { 33 | oldEnv = process.env.NODE_ENV; 34 | process.env.NODE_ENV = ''; 35 | }); 36 | 37 | afterEach(() => { 38 | process.env.NODE_ENV = oldEnv; 39 | }); 40 | 41 | it('should replace __DEV__ in if', () => { 42 | compare( 43 | ` 44 | if (__DEV__) { 45 | console.log('foo') 46 | }`, 47 | `if (process.env.NODE_ENV !== "production") { 48 | console.log('foo'); 49 | }` 50 | ); 51 | }); 52 | 53 | it('should replace warning calls', () => { 54 | compare( 55 | "warning(condition, 'a %s b', 'c');", 56 | `process.env.NODE_ENV !== "production" ? warning(condition, 'a %s b', 'c') : void 0;` 57 | ); 58 | }); 59 | 60 | it('should replace invariant calls', () => { 61 | compare( 62 | "invariant(condition, 'a %s b', 'c');", 63 | `!condition ? process.env.NODE_ENV !== "production" ? invariant(false, 'a %s b', 'c') : invariant(false) : void 0;` 64 | ); 65 | }); 66 | }); 67 | -------------------------------------------------------------------------------- /packages/babel-preset-fbjs/plugins/__tests__/object-assign-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | /* eslint-disable max-len */ 11 | 12 | let babel = require('@babel/core'); 13 | let assign = require('../object-assign'); 14 | const validateOutputAst = require('../test-utils/validateOutputAst'); 15 | 16 | function transform(input) { 17 | const result = babel.transform(input, { 18 | plugins: [assign], 19 | }); 20 | validateOutputAst(result.ast); 21 | return result.code; 22 | } 23 | 24 | function compare(input, output) { 25 | var compiled = transform(input); 26 | expect(compiled).toEqual(output); 27 | } 28 | 29 | describe('object-assign', function() { 30 | 31 | it('should replace calls', () => { 32 | compare( 33 | `Object.assign({}, null);`, 34 | `var _assign = require("object-assign"); 35 | 36 | _assign({}, null);` 37 | ); 38 | }); 39 | 40 | it('does not make multiple assignments', () => { 41 | compare( 42 | `Object.assign({}, null); 43 | Object.assign(Object.prototype, null)`, 44 | `var _assign = require("object-assign"); 45 | 46 | _assign({}, null); 47 | 48 | _assign(Object.prototype, null);` 49 | ); 50 | }); 51 | 52 | it('should replace simple access', () => { 53 | compare( 54 | `var assign = Object.assign; 55 | assign({}, null);`, 56 | `var _assign = require("object-assign"); 57 | 58 | var assign = _assign; 59 | assign({}, null);` 60 | ); 61 | }); 62 | }); 63 | -------------------------------------------------------------------------------- /packages/babel-preset-fbjs/plugins/auto-importer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const MODULES = [ 11 | // Local Promise implementation. 12 | 'Promise', 13 | ]; 14 | 15 | /** 16 | * Automatically imports a module if its identifier is in the AST. 17 | */ 18 | module.exports = function autoImporter(babel) { 19 | const t = babel.types; 20 | 21 | function isAppropriateModule(name, scope, state) { 22 | const autoImported = state.autoImported; 23 | return MODULES.indexOf(name) !== -1 24 | && !autoImported.hasOwnProperty(name) 25 | && !scope.hasBinding(name, /*skip globals*/true); 26 | } 27 | 28 | return { 29 | pre() { 30 | // Cache per file to avoid calling `scope.hasBinding` several 31 | // times for the same module, which has already been auto-imported. 32 | this.autoImported = {}; 33 | }, 34 | 35 | visitor: { 36 | ReferencedIdentifier(path) { 37 | const node = path.node; 38 | const scope = path.scope; 39 | 40 | if (!isAppropriateModule(node.name, scope, this)) { 41 | return; 42 | } 43 | 44 | scope.getProgramParent().push({ 45 | id: t.identifier(node.name), 46 | init: t.callExpression( 47 | t.identifier('require'), 48 | [t.stringLiteral(node.name)] 49 | ), 50 | }); 51 | 52 | this.autoImported[node.name] = true; 53 | }, 54 | }, 55 | }; 56 | }; 57 | -------------------------------------------------------------------------------- /packages/babel-preset-fbjs/plugins/dev-declaration.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | module.exports = function(babel) { 11 | const t = babel.types; 12 | 13 | // We can't construct an identifier with a type annotation all in 1 fell swoop 14 | // so we have to create & mutate, then pass along. 15 | const DEV_IDENTIFIER = t.identifier('__DEV__'); 16 | DEV_IDENTIFIER.typeAnnotation = t.typeAnnotation(t.booleanTypeAnnotation()); 17 | const DEV_DECLARATION = t.declareVariable( 18 | DEV_IDENTIFIER 19 | ); 20 | 21 | return { 22 | pre() { 23 | this.usesDEV = false; 24 | }, 25 | 26 | visitor: { 27 | Identifier: { 28 | enter(path, file) { 29 | this.usesDEV = this.usesDEV || path.isIdentifier({name: '__DEV__'}); 30 | }, 31 | }, 32 | 33 | Program: { 34 | exit(path, file) { 35 | if (!this.usesDEV) { 36 | return; 37 | } 38 | 39 | // Add the declaration at the front of the body if we've used __DEV__. 40 | path.node.body.unshift(DEV_DECLARATION); 41 | }, 42 | }, 43 | }, 44 | }; 45 | }; 46 | -------------------------------------------------------------------------------- /packages/babel-preset-fbjs/plugins/object-assign.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | module.exports = function autoImporter(babel) { 11 | const t = babel.types; 12 | 13 | function getAssignIdent(path, file, state) { 14 | if (!state.id) { 15 | state.id = path.scope.generateUidIdentifier('assign'); 16 | path.scope.getProgramParent().push({ 17 | id: state.id, 18 | init: t.callExpression( 19 | t.identifier('require'), 20 | [t.stringLiteral('object-assign')] 21 | ), 22 | }); 23 | } 24 | return state.id; 25 | } 26 | 27 | return { 28 | pre() { 29 | // map from module to generated identifier 30 | this.id = null; 31 | }, 32 | 33 | visitor: { 34 | CallExpression(path, file) { 35 | if (path.get('callee').matchesPattern('Object.assign')) { 36 | // generate identifier and require if it hasn't been already 37 | var id = getAssignIdent(path, file, this); 38 | path.node.callee = id; 39 | } 40 | }, 41 | 42 | MemberExpression(path, file) { 43 | if (path.matchesPattern('Object.assign')) { 44 | var id = getAssignIdent(path, file, this); 45 | path.replaceWith(id); 46 | } 47 | }, 48 | }, 49 | }; 50 | }; 51 | -------------------------------------------------------------------------------- /packages/babel-preset-fbjs/plugins/test-utils/validateOutputAst.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const t = require('@babel/types'); 11 | 12 | module.exports = function validateOutputAst(ast) { 13 | const seenNodes = new Set(); 14 | t.traverseFast(ast, function enter(node) { 15 | if (seenNodes.has(node)) { 16 | throw new Error('Found a duplicate node in the output, which can cause' 17 | + ' undefined behavior in Babel.'); 18 | } 19 | seenNodes.add(node); 20 | }) 21 | } 22 | -------------------------------------------------------------------------------- /packages/eslint-config-fb-strict/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eslint-config-fb-strict", 3 | "version": "27.0.0", 4 | "description": "", 5 | "repository": "facebook/fbjs", 6 | "license": "MIT", 7 | "main": "index.js", 8 | "files": [ 9 | "index.js" 10 | ], 11 | "scripts": { 12 | "test": "echo \"Error: no test specified\" && exit 1" 13 | }, 14 | "dependencies": { 15 | "eslint-config-fbjs": "^4.0.0" 16 | }, 17 | "peerDependencies": { 18 | "hermes-eslint": ">=0.8.0", 19 | "eslint": "^8.0.0", 20 | "eslint-plugin-babel": "^5.3.1", 21 | "eslint-plugin-ft-flow": "^2.0.1", 22 | "eslint-plugin-jsx-a11y": "^6.6.0", 23 | "eslint-plugin-react": "^7.30.1" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /packages/eslint-config-fbjs-opensource/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [3.0.0] - 2022-07-11 2 | 3 | ### Changed 4 | - Updated dependencies 5 | - Switch `babel-eslint` for `@babel/eslint-parser` 6 | - Switch `eslint-plugin-flowtype` for `eslint-plugin-ft-flow` 7 | 8 | ## [2.0.1] - 2019-08-20 9 | 10 | ### Changed 11 | - Added peer dependencies for `eslint` (6.x). 12 | 13 | 14 | ## [2.0.0] - 2019-03-20 15 | 16 | ### Changed 17 | - Upgraded ESLint peer dependency. 18 | -------------------------------------------------------------------------------- /packages/eslint-config-fbjs-opensource/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2013-present, Facebook, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/eslint-config-fbjs-opensource/README.md: -------------------------------------------------------------------------------- 1 | # eslint-config-fbjs-opensource 2 | 3 | This configuration is a new ideal setup based on Facebook's internal configurations combined with the configurations that our open source projects are trending towards in a more modern code base. In particular, this is strongly based on Nuclide's ESLint rules. It has far more rules enabled than our other configuration and enforces a stricter style. 4 | 5 | ## Usage 6 | 7 | ### Install: 8 | 9 | #### `npm` 10 | ```sh 11 | npm install --save-dev eslint eslint-config-fbjs-opensource 12 | ``` 13 | 14 | #### `yarn` 15 | ```sh 16 | yarn add --dev eslint eslint-config-fbjs-opensource 17 | ``` 18 | 19 | ### Configure 20 | 21 | Add `extends: 'fbjs-opensource'` to your local `.eslintrc` 22 | 23 | #### Warning Configuration 24 | 25 | This package also comes with a *warning* version of the config. This can be used to make all rules that would normally be reported as errors to be reported as warnings. 26 | 27 | Use `extends: 'fbjs-opensource/warning'` in your `.eslintrc` 28 | -------------------------------------------------------------------------------- /packages/eslint-config-fbjs-opensource/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eslint-config-fbjs-opensource", 3 | "version": "3.0.0", 4 | "description": "", 5 | "author": "", 6 | "repository": "facebook/fbjs", 7 | "main": "index.js", 8 | "license": "MIT", 9 | "files": [ 10 | "CHANGELOG.md", 11 | "LICENSE", 12 | "README.md", 13 | "index.js", 14 | "warning.js" 15 | ], 16 | "dependencies": { 17 | "@babel/eslint-parser": "^7.18.2", 18 | "eslint-plugin-babel": "^5.3.1", 19 | "eslint-plugin-ft-flow": "^2.0.1", 20 | "eslint-plugin-jasmine": "^2.10.1", 21 | "eslint-plugin-prefer-object-spread": "^1.2.1", 22 | "eslint-plugin-react": "^7.30.1", 23 | "fbjs-eslint-utils": "^1.0.0" 24 | }, 25 | "peerDependencies": { 26 | "eslint": "^8.0.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /packages/eslint-config-fbjs-opensource/warning.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | let changeErrorLevel = require('fbjs-eslint-utils/change-error-level'); 11 | 12 | module.exports = changeErrorLevel(require('.'), 1); 13 | -------------------------------------------------------------------------------- /packages/eslint-config-fbjs/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [4.0.0] - 2022-07-11 2 | 3 | ### Changed 4 | - Updated dependencies 5 | - Switch `babel-eslint` for `hermes-eslint` 6 | - Switch `eslint-plugin-flowtype` for `eslint-plugin-ft-flow` 7 | 8 | ## [3.1.1] - 2019-08-20 9 | 10 | ### Changed 11 | - Added peer dependencies for `eslint` (6.x), `eslint-plugin-flowtype` (3.x, 4.x). 12 | 13 | 14 | ## [3.1.0] - 2019-03-20 15 | 16 | ### Removed 17 | - Removed peer dependency of `eslint-plugin-relay`. 18 | 19 | ### Changed 20 | - Upgraded ESLint and other peer dependencies. 21 | 22 | ## [2.0.1] - 2017-11-26 23 | 24 | ### Changed 25 | - Updated peer dependency of `eslint-plugin-relay` to allow a range. 26 | 27 | 28 | ## [2.0.0] - 2017-07-19 29 | 30 | ### Added 31 | - Includes `eslint-plugin-jsx-a11y` and `eslint-plugin-relay` 32 | 33 | ### Changed 34 | - Upgraded ESLint and other peer dependencies to latest versions. 35 | 36 | 37 | ## [1.1.1] - 2016-09-13 38 | 39 | ### Fixed 40 | - Added `'use strict'` to ensure the `strict` config works in Node.js v4.x 41 | 42 | ## [1.1.0] - 2016-09-07 43 | 44 | ### Added 45 | - `fbjs/strict` config, with the same rules enabled as the default config, with each warning upgraded to an error. 46 | 47 | ### Changed 48 | - Switched to use eslint-plugin-flowtype for Flow-related rules 49 | 50 | ## [1.0.0] - 2016-07-12 51 | 52 | ### Added 53 | - Initial import from fbjs-scripts 54 | - Synced out additional configuration, enabled several plugins 55 | -------------------------------------------------------------------------------- /packages/eslint-config-fbjs/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2013-present, Facebook, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/eslint-config-fbjs/README.md: -------------------------------------------------------------------------------- 1 | # eslint-config-fbjs 2 | 3 | For the most part, this configuration matches the ESLint configuration we have internally at Facebook. 4 | 5 | There are several exceptions: 6 | 7 | - **No special cases for projects.** Some projects have stricter lint rules. Those configurations are not present here. If you open source a project with different configuration, just specify the overrides in your own repository's `.eslintrc` 8 | - **No fb-specific rules.** We have a number of custom rules internally that are not synced out. We may do that in the future. This means there are several things which we will not catch here but will be caught in Phabricator. Beware of that when relying on this configuration as your only linting process. 9 | 10 | ## Usage 11 | 12 | ### Install: 13 | 14 | #### `npm` 15 | ```sh 16 | npm install --save-dev \ 17 | eslint-config-fbjs \ 18 | eslint-plugin-babel \ 19 | eslint-plugin-ft-flow \ 20 | eslint-plugin-jsx-a11y \ 21 | eslint-plugin-react \ 22 | eslint \ 23 | hermes-eslint 24 | ``` 25 | 26 | #### `yarn` 27 | ```sh 28 | yarn add --dev \ 29 | eslint-config-fbjs \ 30 | eslint-plugin-babel \ 31 | eslint-plugin-ft-flow \ 32 | eslint-plugin-jsx-a11y \ 33 | eslint-plugin-react \ 34 | eslint \ 35 | hermes-eslint 36 | ``` 37 | 38 | ### Configure 39 | 40 | Add `extends: 'fbjs'` to your local `.eslintrc` 41 | 42 | #### Strict Configuration 43 | 44 | This package also comes with a *strict* version of the config. This can be used to make all warnings be reported as errors. While this can be overly strict, it can be helpful to avoid the case where some CI configurations don't fail for warnings. 45 | 46 | Use `extends: fbjs/strict` in your `.eslintrc` 47 | -------------------------------------------------------------------------------- /packages/eslint-config-fbjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eslint-config-fbjs", 3 | "version": "4.0.0", 4 | "description": "", 5 | "repository": "facebook/fbjs", 6 | "license": "MIT", 7 | "main": "index.js", 8 | "files": [ 9 | "CHANGELOG.md", 10 | "LICENSE", 11 | "README.md", 12 | "index.js", 13 | "opensource/", 14 | "shared.js", 15 | "strict.js", 16 | "utils/" 17 | ], 18 | "scripts": { 19 | "test": "echo \"Error: no test specified\" && exit 1" 20 | }, 21 | "peerDependencies": { 22 | "hermes-eslint": ">=0.8.0", 23 | "eslint": "^8.0.0", 24 | "eslint-plugin-babel": "^5.3.1", 25 | "eslint-plugin-ft-flow": "^2.0.1", 26 | "eslint-plugin-jsx-a11y": "^6.6.0", 27 | "eslint-plugin-react": "^7.30.1" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/eslint-config-fbjs/scripts/check-rules.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | /** 9 | * Finds rules that are supported by ESLint but not defined in our config. 10 | */ 11 | 12 | var ourRules = new Set(Object.keys(require('..').rules)); 13 | var supportedRules = new Set(Object.keys(require('eslint/lib/load-rules')())); 14 | 15 | // Get plugins from package.json. Assume they're all in peerDependencies. 16 | var plugins = 17 | Object.keys(require('../package.json').peerDependencies) 18 | .filter((dep) => dep.startsWith('eslint-plugin')) 19 | .map((dep) => dep.replace('eslint-plugin-', '')); 20 | 21 | plugins.forEach((plugin) => { 22 | Object.keys(require(`eslint-plugin-${plugin}`).rules).forEach((rule) => { 23 | supportedRules.add(`${plugin}/${rule}`); 24 | }); 25 | }); 26 | 27 | var missing = new Set(); 28 | var extra = new Set(); 29 | 30 | ourRules.forEach((rule) => { 31 | if (!supportedRules.has(rule)) { 32 | extra.add(rule); 33 | } 34 | }); 35 | 36 | supportedRules.forEach((rule) => { 37 | if (!ourRules.has(rule)) { 38 | missing.add(rule); 39 | } 40 | }); 41 | 42 | console.log('missing', missing); 43 | console.log('extra', extra); 44 | -------------------------------------------------------------------------------- /packages/eslint-config-fbjs/strict.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | let changeErrorLevel = require('./utils/change-error-level'); 11 | 12 | module.exports = changeErrorLevel(require('.'), 2); 13 | -------------------------------------------------------------------------------- /packages/eslint-config-fbjs/utils/change-error-level.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | function isOff(rule) { 11 | return rule === 0 || rule === 'off'; 12 | } 13 | 14 | function changeErrorLevel(config, level) { 15 | // Clone the config so we don't mutate. 16 | config = JSON.parse(JSON.stringify(config)) 17 | 18 | Object.keys(config.rules).forEach((rule) => { 19 | let val = config.rules[rule]; 20 | if (Array.isArray(val)) { 21 | if (isOff(val[0])) { 22 | return; 23 | } 24 | val[0] = level; 25 | config.rules[rule] = level; 26 | return; 27 | } 28 | if (isOff(val)) { 29 | return; 30 | } 31 | config.rules[rule] = level; 32 | }); 33 | 34 | return config; 35 | } 36 | 37 | module.exports = changeErrorLevel; 38 | -------------------------------------------------------------------------------- /packages/fbjs-css-vars/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [1.0.2] - 2018-12-17 2 | 3 | ### Changed 4 | - Relicensed to MIT. 5 | 6 | 7 | ## [1.0.1] - 2017-07-18 8 | 9 | ### Fixed 10 | - Added `repository` field in `package.json` to fix issue with some tools. 11 | 12 | 13 | ## [1.0.0] - 2016-07-14 14 | 15 | ### Added 16 | - Initial release with variables used by Fixed Data Table and Draft. 17 | -------------------------------------------------------------------------------- /packages/fbjs-css-vars/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2013-present, Facebook, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/fbjs-css-vars/README.md: -------------------------------------------------------------------------------- 1 | # fbjs-css-vars 2 | 3 | This package exports a few of the CSS variables that we use in Facebook projects. This is not the full list we have internally but focused on making available the minimum set needed by our open source projects. 4 | 5 | ## Usage 6 | 7 | There are almost no use cases where a product will use this module. It will primarily be consumed by one of the following: 8 | 9 | ### `cssVar` 10 | 11 | This is a module that will read from the list we have here and return the corresponding value. Internally we transform this statically but we don't currently do that in our open source projects. 12 | 13 | ```js 14 | React.render( 15 |
, 16 | containerNode 17 | ); 18 | ``` 19 | 20 | ### CSS 21 | 22 | In order to directly sync out our internal CSS and have it parsed by browser, we need to apply some transforms like we do internally. One of those transforms will insert the variables we have available here. In the future we may make use of [CSS Variables](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_variables). 23 | 24 | ```css 25 | .class { 26 | background-color: var(fbui-white); 27 | } 28 | ``` 29 | 30 | ### Direct Usage 31 | 32 | We're just exporting a JS Object so usage is straightforward. 33 | 34 | ```js 35 | var fbCSSVars = require('fbjs-css-vars') 36 | 37 | console.log(fbCSSVars['fbui-white']); 38 | ``` 39 | -------------------------------------------------------------------------------- /packages/fbjs-css-vars/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | module.exports = { 9 | 'fbui-desktop-background-light': '#f6f7f8', 10 | 'fbui-desktop-text-placeholder': '#9197a3', 11 | 'fbui-desktop-text-placeholder-focused': '#bdc1c9', 12 | 'fbui-white': '#fff', 13 | 'scrollbar-face-active-color': '#7d7d7d', 14 | 'scrollbar-face-color': '#c2c2c2', 15 | 'scrollbar-face-margin': '4px', 16 | 'scrollbar-face-radius': '6px', 17 | 'scrollbar-size': '15px', 18 | 'scrollbar-size-large': '17px', 19 | 'scrollbar-track-color': 'rgba(255, 255, 255, 0.8)', 20 | }; 21 | -------------------------------------------------------------------------------- /packages/fbjs-css-vars/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fbjs-css-vars", 3 | "version": "1.0.2", 4 | "description": "This package exports a few of the CSS variables that we use in Facebook projects. This is not the full list we have internally but focused on making available the minimum set needed by our open source projects.", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "repository": "facebook/fbjs", 11 | "license": "MIT" 12 | } 13 | -------------------------------------------------------------------------------- /packages/fbjs-eslint-utils/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2013-present, Facebook, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/fbjs-eslint-utils/README.md: -------------------------------------------------------------------------------- 1 | # fbjs-eslint-utils 2 | 3 | A collection of shared utilities for our eslint configuration packages. 4 | 5 | See [eslint-config-fbjs](https://www.npmjs.com/package/eslint-config-fbjs) and [eslint-config-fbjs-opensource](https://www.npmjs.com/package/eslint-config-fbjs-opensource). 6 | -------------------------------------------------------------------------------- /packages/fbjs-eslint-utils/change-error-level.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | function isOff(rule) { 11 | return rule === 0 || rule === 'off'; 12 | } 13 | 14 | function changeErrorLevel(config, level) { 15 | // Clone the config so we don't mutate. 16 | config = JSON.parse(JSON.stringify(config)) 17 | 18 | Object.keys(config.rules).forEach((rule) => { 19 | let val = config.rules[rule]; 20 | if (Array.isArray(val)) { 21 | if (isOff(val[0])) { 22 | return; 23 | } 24 | val[0] = level; 25 | config.rules[rule] = level; 26 | return; 27 | } 28 | if (isOff(val)) { 29 | return; 30 | } 31 | config.rules[rule] = level; 32 | }); 33 | 34 | return config; 35 | } 36 | 37 | module.exports = changeErrorLevel; 38 | -------------------------------------------------------------------------------- /packages/fbjs-eslint-utils/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | throw new Error('This does not do anything. Require other modules.'); 9 | -------------------------------------------------------------------------------- /packages/fbjs-eslint-utils/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fbjs-eslint-utils", 3 | "version": "1.0.0", 4 | "description": "Shared utilities for our eslint configuration packages.", 5 | "author": "", 6 | "repository": "facebook/fbjs", 7 | "main": "index.js", 8 | "license": "MIT", 9 | "files": [ 10 | "LICENCE", 11 | "README.md", 12 | "change-error-level.js", 13 | "globals.js", 14 | "index.js", 15 | "shared.js" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /packages/fbjs-eslint-utils/shared.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | // This pattern will match these texts: 9 | // var Foo = require('Foo'); 10 | // var Bar = require('Foo').Bar; 11 | // var BarFoo = require(Bar + 'Foo'); 12 | // var {Bar, Foo} = require('Foo'); 13 | // import type {Bar, Foo} from 'Foo'; 14 | // Also supports 'let' and 'const'. 15 | const variableNamePattern = String.raw`\s*[a-zA-Z_$][a-zA-Z_$\d]*\s*`; 16 | const maxLenIgnorePattern = String.raw`^(?:var|let|const|import type)\s+` + 17 | '{?' + variableNamePattern + '(?:,' + variableNamePattern + ')*}?' + 18 | String.raw`\s*(?:=\s*require\(|from)[a-zA-Z_+./"'\s\d\-]+\)?[^;\n]*[;\n]`; 19 | 20 | 21 | module.exports = { 22 | maxLenIgnorePattern: maxLenIgnorePattern, 23 | }; 24 | -------------------------------------------------------------------------------- /packages/fbjs-scripts/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2013-present, Facebook, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/fbjs-scripts/README.md: -------------------------------------------------------------------------------- 1 | # fbjs-scripts 2 | 3 | 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`. 4 | 5 | ```js 6 | // before (fbjs@0.1.0) 7 | var invariant = require('fbjs/lib/invariant'); 8 | var devExpression = require('fbjs/scripts/babel/dev-expression'); 9 | 10 | // after (fbjs, fbjs-scripts@0.2.0) 11 | var invariant = require('fbjs/lib/invariant'); 12 | var devExpression = require('fbjs-scripts/babel/dev-expression'); 13 | ``` 14 | 15 | ## Why? 16 | 17 | 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. 18 | -------------------------------------------------------------------------------- /packages/fbjs-scripts/babel/default-options.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const assign = require('object-assign'); 11 | 12 | module.exports = function(options) { 13 | return { 14 | presets: [ 15 | require('babel-preset-fbjs/configure')({ 16 | rewriteModules: assign({ 17 | map: require('../third-party-module-map'), 18 | }, options.moduleOpts), 19 | }), 20 | ], 21 | plugins: options.plugins || [], 22 | }; 23 | }; 24 | -------------------------------------------------------------------------------- /packages/fbjs-scripts/gulp/shared/provides-module.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | module.exports = { 11 | regexp: /\r?\n \* \@providesModule (\S+)(?=\r?\n)/, 12 | }; 13 | -------------------------------------------------------------------------------- /packages/fbjs-scripts/gulp/strip-provides-module.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | var PluginError = require('plugin-error'); 11 | var through = require('through2'); 12 | var PM_REGEXP = require('./shared/provides-module').regexp; 13 | 14 | module.exports = function(opts) { 15 | function transform(file, enc, cb) { 16 | if (file.isNull()) { 17 | cb(null, file); 18 | return; 19 | } 20 | 21 | if (file.isStream()) { 22 | cb(new PluginError('module-map', 'Streaming not supported')); 23 | return; 24 | } 25 | 26 | // Get the @providesModule piece out of the file and save that. 27 | var contents = file.contents.toString().replace(PM_REGEXP, ''); 28 | file.contents = new Buffer(contents); 29 | this.push(file); 30 | cb(); 31 | } 32 | 33 | return through.obj(transform); 34 | }; 35 | -------------------------------------------------------------------------------- /packages/fbjs-scripts/jest/createCacheKeyFunction.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const crypto = require('crypto'); 11 | const fs = require('fs'); 12 | const path = require('path'); 13 | 14 | function getGlobalCacheKey(files, values) { 15 | const presetVersion = require('../package').dependencies['babel-preset-fbjs']; 16 | 17 | const chunks = [ 18 | process.env.NODE_ENV, 19 | process.env.BABEL_ENV, 20 | presetVersion, 21 | ...values, 22 | ...files.map(file => fs.readFileSync(file)), 23 | ]; 24 | 25 | return chunks 26 | .reduce( 27 | (hash, chunk) => hash.update('\0', 'utf-8').update(chunk || ''), 28 | crypto.createHash('md5') 29 | ) 30 | .digest('hex'); 31 | } 32 | 33 | function getCacheKeyFunction(globalCacheKey) { 34 | return (src, file, configString, options) => { 35 | // Jest 27 passes a single options bag which contains `configString` rather than as a separate argument 36 | options = options || configString; 37 | const {instrument, config} = options; 38 | const rootDir = config && config.rootDir; 39 | 40 | return crypto 41 | .createHash('md5') 42 | .update(globalCacheKey) 43 | .update('\0', 'utf8') 44 | .update(src) 45 | .update('\0', 'utf8') 46 | .update(rootDir ? path.relative(config.rootDir, file) : '') 47 | .update('\0', 'utf8') 48 | .update(instrument ? 'instrument' : '') 49 | .digest('hex'); 50 | }; 51 | } 52 | 53 | module.exports = (files = [], values = []) => { 54 | return getCacheKeyFunction(getGlobalCacheKey(files, values)); 55 | }; 56 | -------------------------------------------------------------------------------- /packages/fbjs-scripts/jest/environment.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | global.__DEV__ = true; 9 | -------------------------------------------------------------------------------- /packages/fbjs-scripts/jest/preprocessor.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const babel = require('@babel/core'); 11 | const createCacheKeyFunction = require('./createCacheKeyFunction'); 12 | const path = require('path'); 13 | 14 | module.exports = { 15 | process(src, filename) { 16 | const options = { 17 | presets: [ 18 | require('babel-preset-fbjs'), 19 | ], 20 | filename: filename, 21 | retainLines: true, 22 | }; 23 | return babel.transform(src, options).code; 24 | }, 25 | 26 | // Generate a cache key that is based on the contents of this file and the 27 | // fbjs preset package.json (used as a proxy for determining if the preset has 28 | // changed configuration at all). 29 | getCacheKey: createCacheKeyFunction([ 30 | __filename, 31 | path.join(path.dirname(require.resolve('babel-preset-fbjs')), 'package.json') 32 | ]), 33 | }; 34 | -------------------------------------------------------------------------------- /packages/fbjs-scripts/node/check-lib-requires.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | const assert = require('assert'); 11 | const fs = require('fs'); 12 | const path = require('path'); 13 | 14 | const EXTRACT_MODULE_NAME_REGEX = /'\.\/(.+)'/; 15 | 16 | let didError = false; 17 | 18 | // Make sure we have a lib to read files from. Take it as the first argument. 19 | assert( 20 | process.argv.length >= 3, 21 | 'Expected to receive an argument to a lib directory' 22 | ); 23 | 24 | const pathToLib = path.resolve(process.cwd(), process.argv[2]); 25 | 26 | fs.readdir(pathToLib, (err, files) => { 27 | files = files.filter((filename) => path.parse(filename).ext === '.js'); 28 | 29 | files.forEach((filename) => { 30 | const requirePath = path.join(pathToLib, filename); 31 | const moduleName = path.parse(filename).name; 32 | 33 | try { 34 | require(requirePath); 35 | } catch (e) { 36 | if (e.code === 'MODULE_NOT_FOUND') { 37 | const missingModule = e.toString().match(EXTRACT_MODULE_NAME_REGEX)[1]; 38 | console.error(moduleName, 'is missing a dependency:', missingModule); 39 | } else { 40 | console.error('UNKNOWN ERROR', e); 41 | } 42 | didError = true; 43 | } 44 | }); 45 | 46 | process.exit(didError ? 1 : 0); 47 | }); 48 | -------------------------------------------------------------------------------- /packages/fbjs-scripts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fbjs-scripts", 3 | "version": "3.0.1", 4 | "description": "A bundle of helpful scripts used in projects consuming fbjs.", 5 | "repository": "facebook/fbjs", 6 | "license": "MIT", 7 | "dependencies": { 8 | "@babel/core": "^7.1.5", 9 | "ansi-colors": "^1.0.1", 10 | "babel-preset-fbjs": "^3.2.0", 11 | "cross-spawn": "^5.1.0", 12 | "fancy-log": "^1.3.2", 13 | "object-assign": "^4.0.1", 14 | "plugin-error": "^0.1.2", 15 | "semver": "^5.1.0", 16 | "through2": "^2.0.0" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/fbjs-scripts/third-party-module-map.json: -------------------------------------------------------------------------------- 1 | { 2 | "cross-fetch": "cross-fetch", 3 | "fbjs-css-vars": "fbjs-css-vars", 4 | "isomorphic-fetch": "isomorphic-fetch", 5 | "object-assign": "object-assign", 6 | "promise": "promise", 7 | "promise/setimmediate/done": "promise/setimmediate/done", 8 | "promise/setimmediate/es6-extensions": "promise/setimmediate/es6-extensions", 9 | "setimmediate": "setimmediate", 10 | "ua-parser-js": "ua-parser-js" 11 | } 12 | -------------------------------------------------------------------------------- /packages/fbjs/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2013-present, Facebook, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/fbjs/flow/lib/dev.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | declare var __DEV__: boolean; 9 | -------------------------------------------------------------------------------- /packages/fbjs/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | throw new Error('The fbjs package should not be required without a full path.'); 11 | -------------------------------------------------------------------------------- /packages/fbjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fbjs", 3 | "version": "3.0.5", 4 | "description": "A collection of utility libraries used by other Facebook JS projects", 5 | "main": "index.js", 6 | "repository": "facebook/fbjs", 7 | "scripts": { 8 | "build": "gulp build", 9 | "postbuild": "node node_modules/fbjs-scripts/node/check-lib-requires.js lib", 10 | "lint": "eslint .", 11 | "prepare": "yarn run build", 12 | "pretest": "node node_modules/fbjs-scripts/node/check-dev-engines.js package.json", 13 | "test": "NODE_ENV=test jest", 14 | "test-babel-presets": "cd babel-preset && yarn install && yarn test", 15 | "flow": "flow check src" 16 | }, 17 | "devDependencies": { 18 | "@babel/core": "^7.1.5", 19 | "babel-preset-fbjs": "file:../babel-preset-fbjs", 20 | "del": "^2.2.0", 21 | "fbjs-scripts": "file:../fbjs-scripts", 22 | "flow-bin": "^0.99.0", 23 | "gulp": "^4.0.2", 24 | "gulp-babel": "^8.0.0", 25 | "gulp-flatten": "^0.4.0", 26 | "gulp-rename": "^2.0.0", 27 | "immutable": "^3.7.6", 28 | "jest-cli": "^23.6.0", 29 | "merge-stream": "^1.0.0" 30 | }, 31 | "license": "MIT", 32 | "files": [ 33 | "LICENSE", 34 | "README.md", 35 | "flow/", 36 | "index.js", 37 | "lib/", 38 | "module-map.json" 39 | ], 40 | "jest": { 41 | "automock": true, 42 | "modulePathIgnorePatterns": [ 43 | "/lib/", 44 | "/node_modules/" 45 | ], 46 | "rootDir": "", 47 | "setupFiles": [ 48 | "fbjs-scripts/jest/environment.js" 49 | ], 50 | "roots": [ 51 | "/src" 52 | ], 53 | "timers": "fake", 54 | "transform": { 55 | ".*": "fbjs-scripts/jest/preprocessor.js" 56 | }, 57 | "transformIgnorePatterns": [ 58 | "/node_modules/" 59 | ], 60 | "unmockedModulePathPatterns": [ 61 | "/node_modules/", 62 | "/src/(?!(__forks__/fetch.js$|fetch/))" 63 | ] 64 | }, 65 | "dependencies": { 66 | "cross-fetch": "^3.1.5", 67 | "fbjs-css-vars": "^1.0.0", 68 | "loose-envify": "^1.0.0", 69 | "object-assign": "^4.1.0", 70 | "promise": "^7.1.1", 71 | "setimmediate": "^1.0.5", 72 | "ua-parser-js": "^1.0.35" 73 | }, 74 | "devEngines": { 75 | "node": ">=4.x", 76 | "npm": ">=2.x" 77 | }, 78 | "browserify": { 79 | "transform": [ 80 | "loose-envify" 81 | ] 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /packages/fbjs/src/.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | .*/__tests__/.* 3 | 4 | [include] 5 | ../node_modules 6 | 7 | [libs] 8 | ../flow/lib 9 | 10 | [options] 11 | module.system=haste 12 | 13 | [version] 14 | ^0.99.0 15 | -------------------------------------------------------------------------------- /packages/fbjs/src/__forks__/Promise.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule Promise 8 | */ 9 | 10 | module.exports = require('promise'); 11 | -------------------------------------------------------------------------------- /packages/fbjs/src/__forks__/Promise.native.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Copyright (c) 2013-present, Facebook, Inc. 4 | * 5 | * This source code is licensed under the MIT license found in the 6 | * LICENSE file in the root directory of this source tree. 7 | * 8 | * This module wraps and augments the minimally ES6-compliant Promise 9 | * implementation provided by the promise npm package. 10 | * 11 | */ 12 | 13 | 'use strict'; 14 | 15 | var Promise = require('promise/setimmediate/es6-extensions'); 16 | require('promise/setimmediate/done'); 17 | 18 | /** 19 | * Handle either fulfillment or rejection with the same callback. 20 | */ 21 | Promise.prototype.finally = function(onSettled) { 22 | return this.then(onSettled, onSettled); 23 | }; 24 | 25 | module.exports = Promise; 26 | -------------------------------------------------------------------------------- /packages/fbjs/src/__forks__/SiteData.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule SiteData 8 | */ 9 | 10 | module.exports = { 11 | is_rtl: false, 12 | }; -------------------------------------------------------------------------------- /packages/fbjs/src/__forks__/Style.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule Style 8 | * @typechecks 9 | */ 10 | 11 | var getStyleProperty = require('getStyleProperty'); 12 | 13 | /** 14 | * @param {DOMNode} element [description] 15 | * @param {string} name Overflow style property name. 16 | * @return {boolean} True if the supplied ndoe is scrollable. 17 | */ 18 | function _isNodeScrollable(element, name) { 19 | var overflow = Style.get(element, name); 20 | return (overflow === 'auto' || overflow === 'scroll'); 21 | } 22 | 23 | /** 24 | * Utilities for querying and mutating style properties. 25 | */ 26 | var Style = { 27 | /** 28 | * Gets the style property for the supplied node. This will return either the 29 | * computed style, if available, or the declared style. 30 | * 31 | * @param {DOMNode} node 32 | * @param {string} name Style property name. 33 | * @return {?string} Style property value. 34 | */ 35 | get: getStyleProperty, 36 | 37 | /** 38 | * Determines the nearest ancestor of a node that is scrollable. 39 | * 40 | * NOTE: This can be expensive if used repeatedly or on a node nested deeply. 41 | * 42 | * @param {?DOMNode} node Node from which to start searching. 43 | * @return {?DOMWindow|DOMElement} Scroll parent of the supplied node. 44 | */ 45 | getScrollParent: function(node) { 46 | if (!node) { 47 | return null; 48 | } 49 | var ownerDocument = node.ownerDocument; 50 | while (node && node !== ownerDocument.body) { 51 | if (_isNodeScrollable(node, 'overflow') || 52 | _isNodeScrollable(node, 'overflowY') || 53 | _isNodeScrollable(node, 'overflowX')) { 54 | return node; 55 | } 56 | node = node.parentNode; 57 | } 58 | return ownerDocument.defaultView || ownerDocument.parentWindow; 59 | }, 60 | 61 | }; 62 | 63 | module.exports = Style; 64 | -------------------------------------------------------------------------------- /packages/fbjs/src/__forks__/TokenizeUtil.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule TokenizeUtil 8 | * @typechecks 9 | * @stub 10 | * @flow 11 | */ 12 | 13 | 'use strict'; 14 | 15 | // \u00a1-\u00b1\u00b4-\u00b8\u00ba\u00bb\u00bf 16 | // is latin supplement punctuation except fractions and superscript 17 | // numbers 18 | // \u2010-\u2027\u2030-\u205e 19 | // is punctuation from the general punctuation block: 20 | // weird quotes, commas, bullets, dashes, etc. 21 | // \u30fb\u3001\u3002\u3008-\u3011\u3014-\u301f 22 | // is CJK punctuation 23 | // \uff1a-\uff1f\uff01-\uff0f\uff3b-\uff40\uff5b-\uff65 24 | // is some full-width/half-width punctuation 25 | // \u2E2E\u061f\u066a-\u066c\u061b\u060c\u060d\uFD3e\uFD3F 26 | // is some Arabic punctuation marks 27 | // \u1801\u0964\u104a\u104b 28 | // is misc. other language punctuation marks 29 | var PUNCTUATION = ( 30 | '[.,+*?$|#{}()\'\\^\\-\\[\\]\\\\\\/!@%"~=<>_:;' + 31 | '\u30fb\u3001\u3002\u3008-\u3011\u3014-\u301f\uff1a-\uff1f\uff01-\uff0f' + 32 | '\uff3b-\uff40\uff5b-\uff65\u2E2E\u061f\u066a-\u066c\u061b\u060c\u060d' + 33 | '\uFD3e\uFD3F\u1801\u0964\u104a\u104b\u2010-\u2027\u2030-\u205e' + 34 | '\u00a1-\u00b1\u00b4-\u00b8\u00ba\u00bb\u00bf]' 35 | ); 36 | 37 | module.exports = { 38 | getPunctuation: (): string => PUNCTUATION, 39 | }; 40 | -------------------------------------------------------------------------------- /packages/fbjs/src/__forks__/URI.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule URI 8 | * @flow 9 | */ 10 | 11 | 'use strict'; 12 | 13 | class URI { 14 | _uri: string; 15 | 16 | constructor(uri: string) { 17 | this._uri = uri; 18 | } 19 | 20 | toString(): string { 21 | return this._uri; 22 | } 23 | } 24 | 25 | module.exports = URI; 26 | -------------------------------------------------------------------------------- /packages/fbjs/src/__forks__/__tests__/fetch-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @emails oncall+jsinfra 8 | */ 9 | 10 | 'use strict'; 11 | 12 | jest.unmock('fetch'); 13 | jest.mock('cross-fetch'); 14 | 15 | const fetchImpl = require('cross-fetch'); 16 | 17 | describe('fetch', function() { 18 | afterEach(() => { 19 | // Ensure the cached `fetch` module is cleared to test the other path. 20 | jest.resetModules(); 21 | }); 22 | 23 | it('works with global fetch', () => { 24 | const fetchMock = jest.fn(); 25 | 26 | global.fetch = fetchMock; 27 | const fetch = require('fetch'); 28 | fetch(); 29 | 30 | expect(fetchMock).toHaveBeenCalled(); 31 | expect(fetchImpl).not.toHaveBeenCalled(); 32 | 33 | delete global.fetch; 34 | }); 35 | 36 | it('uses ponyfill without global fetch', () => { 37 | // If node ever gets a global fetch, we'll start failing this case. 38 | expect(global.fetch).toBeUndefined(); 39 | 40 | const fetch = require('fetch'); 41 | fetch(); 42 | 43 | expect(fetchImpl).toHaveBeenCalled(); 44 | }); 45 | }); 46 | -------------------------------------------------------------------------------- /packages/fbjs/src/__forks__/cssVar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule cssVar 8 | */ 9 | 10 | const fbCSSVars = require('fbjs-css-vars'); 11 | const invariant = require('invariant'); 12 | 13 | /** 14 | * @param {string} name 15 | */ 16 | function cssVar(name) { 17 | invariant( 18 | Object.prototype.hasOwnProperty.call(fbCSSVars, name), 19 | 'Unknown key passed to cssVar: %s.', 20 | name 21 | ); 22 | 23 | return fbCSSVars[name]; 24 | } 25 | 26 | module.exports = cssVar; 27 | -------------------------------------------------------------------------------- /packages/fbjs/src/__forks__/cx.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule cx 8 | */ 9 | 10 | /** 11 | * This function is used to mark string literals representing CSS class names 12 | * so that they can be transformed statically. This allows for modularization 13 | * and minification of CSS class names. 14 | * 15 | * In static_upstream, this function is actually implemented, but it should 16 | * eventually be replaced with something more descriptive, and the transform 17 | * that is used in the main stack should be ported for use elsewhere. 18 | * 19 | * @param string|object className to modularize, or an object of key/values. 20 | * In the object case, the values are conditions that 21 | * determine if the className keys should be included. 22 | * @param [string ...] Variable list of classNames in the string case. 23 | * @return string Renderable space-separated CSS className. 24 | */ 25 | function cx(classNames) { 26 | if (typeof classNames == 'object') { 27 | return Object.keys(classNames) 28 | .filter(className => classNames[className]) 29 | .map(replace) 30 | .join(' '); 31 | } 32 | return Array.prototype.map.call(arguments, replace).join(' '); 33 | } 34 | 35 | function replace(str) { 36 | return str.replace(/\//g, '-'); 37 | } 38 | 39 | module.exports = cx; 40 | -------------------------------------------------------------------------------- /packages/fbjs/src/__forks__/fetch.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule fetch 8 | */ 9 | 10 | 'use strict'; 11 | 12 | // This hopefully supports the React Native case, which is already bringing along 13 | // its own fetch polyfill. That should exist on `global`. If that doesn't exist 14 | // then we'll try to ponyfill, which might not work correctly in all environments. 15 | if (global.fetch) { 16 | module.exports = global.fetch.bind(global); 17 | } else { 18 | module.exports = require('cross-fetch'); 19 | } 20 | -------------------------------------------------------------------------------- /packages/fbjs/src/__forks__/getUnboundedScrollPosition.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule getUnboundedScrollPosition 8 | * @typechecks 9 | */ 10 | 11 | 'use strict'; 12 | 13 | /** 14 | * Gets the scroll position of the supplied element or window. 15 | * 16 | * The return values are unbounded, unlike `getScrollPosition`. This means they 17 | * may be negative or exceed the element boundaries (which is possible using 18 | * inertial scrolling). 19 | * 20 | * @param {DOMWindow|DOMElement} scrollable 21 | * @return {object} Map with `x` and `y` keys. 22 | */ 23 | function getUnboundedScrollPosition(scrollable) { 24 | if (scrollable.Window && scrollable instanceof scrollable.Window) { 25 | return { 26 | x: scrollable.pageXOffset || scrollable.document.documentElement.scrollLeft, 27 | y: scrollable.pageYOffset || scrollable.document.documentElement.scrollTop 28 | }; 29 | } 30 | return { 31 | x: scrollable.scrollLeft, 32 | y: scrollable.scrollTop 33 | }; 34 | } 35 | 36 | module.exports = getUnboundedScrollPosition; 37 | -------------------------------------------------------------------------------- /packages/fbjs/src/__forks__/invariant.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule invariant 8 | * @flow 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const validateFormat = __DEV__ 14 | ? function(format: mixed): void { 15 | if (format === undefined) { 16 | throw new Error('invariant(...): Second argument must be a string.'); 17 | } 18 | } 19 | : function(format: mixed): void {}; 20 | 21 | /** 22 | * Use invariant() to assert state which your program assumes to be true. 23 | * 24 | * Provide sprintf-style format (only %s is supported) and arguments to provide 25 | * information about what broke and what you were expecting. 26 | * 27 | * The invariant message will be stripped in production, but the invariant will 28 | * remain to ensure logic does not differ in production. 29 | */ 30 | function invariant( 31 | condition: mixed, 32 | format: string, 33 | ...args: Array 34 | ): void { 35 | validateFormat(format); 36 | 37 | if (!condition) { 38 | let error; 39 | if (format === undefined) { 40 | error = new Error( 41 | 'Minified exception occurred; use the non-minified dev environment ' + 42 | 'for the full error message and additional helpful warnings.', 43 | ); 44 | } else { 45 | let argIndex = 0; 46 | error = new Error(format.replace(/%s/g, () => String(args[argIndex++]))); 47 | error.name = 'Invariant Violation'; 48 | } 49 | 50 | (error: any).framesToPop = 1; // Skip invariant's own stack frame. 51 | throw error; 52 | } 53 | } 54 | 55 | module.exports = invariant; 56 | -------------------------------------------------------------------------------- /packages/fbjs/src/__forks__/isEventSupported.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule isEventSupported 8 | */ 9 | 10 | 'use strict'; 11 | 12 | var ExecutionEnvironment = require('ExecutionEnvironment'); 13 | 14 | var useHasFeature; 15 | if (ExecutionEnvironment.canUseDOM) { 16 | useHasFeature = 17 | document.implementation && 18 | document.implementation.hasFeature && 19 | // always returns true in newer browsers as per the standard. 20 | // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature 21 | document.implementation.hasFeature('', '') !== true; 22 | } 23 | 24 | /** 25 | * Checks if an event is supported in the current execution environment. 26 | * 27 | * NOTE: This will not work correctly for non-generic events such as `change`, 28 | * `reset`, `load`, `error`, and `select`. 29 | * 30 | * Borrows from Modernizr. 31 | * 32 | * @param {string} eventNameSuffix Event name, e.g. "click". 33 | * @param {?boolean} capture Check if the capture phase is supported. 34 | * @return {boolean} True if the event is supported. 35 | * @internal 36 | * @license Modernizr 3.0.0pre (Custom Build) | MIT 37 | */ 38 | function isEventSupported(eventNameSuffix, capture) { 39 | if (!ExecutionEnvironment.canUseDOM || 40 | capture && !('addEventListener' in document)) { 41 | return false; 42 | } 43 | 44 | var eventName = 'on' + eventNameSuffix; 45 | var isSupported = eventName in document; 46 | 47 | if (!isSupported) { 48 | var element = document.createElement('div'); 49 | element.setAttribute(eventName, 'return;'); 50 | isSupported = typeof element[eventName] === 'function'; 51 | } 52 | 53 | if (!isSupported && useHasFeature && eventNameSuffix === 'wheel') { 54 | // This is the only way to test support for the `wheel` event in IE9+. 55 | isSupported = document.implementation.hasFeature('Events.wheel', '3.0'); 56 | } 57 | 58 | return isSupported; 59 | } 60 | 61 | module.exports = isEventSupported; 62 | -------------------------------------------------------------------------------- /packages/fbjs/src/__forks__/monitorCodeUse.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule monitorCodeUse 8 | */ 9 | 10 | 'use strict'; 11 | 12 | var invariant = require('invariant'); 13 | 14 | /** 15 | * Provides open-source compatible instrumentation for monitoring certain API 16 | * uses before we're ready to issue a warning or refactor. It accepts an event 17 | * name which may only contain the characters [a-z0-9_] and an optional data 18 | * object with further information. 19 | */ 20 | 21 | function monitorCodeUse(eventName, data) { 22 | invariant( 23 | eventName && !/[^a-z0-9_]/.test(eventName), 24 | 'You must provide an eventName using only the characters [a-z0-9_]' 25 | ); 26 | } 27 | 28 | module.exports = monitorCodeUse; 29 | -------------------------------------------------------------------------------- /packages/fbjs/src/__forks__/requestAnimationFrame.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule requestAnimationFrame 8 | */ 9 | 10 | module.exports = require('requestAnimationFramePolyfill'); 11 | -------------------------------------------------------------------------------- /packages/fbjs/src/__forks__/requestAnimationFramePolyfill.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule requestAnimationFramePolyfill 8 | */ 9 | 10 | var emptyFunction = require('emptyFunction'); 11 | var nativeRequestAnimationFrame = require('nativeRequestAnimationFrame'); 12 | 13 | var lastTime = 0; 14 | 15 | var requestAnimationFrame = 16 | nativeRequestAnimationFrame || 17 | function(callback) { 18 | var currTime = Date.now(); 19 | var timeDelay = Math.max(0, 16 - (currTime - lastTime)); 20 | lastTime = currTime + timeDelay; 21 | return global.setTimeout(function() { 22 | callback(Date.now()); 23 | }, timeDelay); 24 | }; 25 | 26 | // Works around a rare bug in Safari 6 where the first request is never invoked. 27 | requestAnimationFrame(emptyFunction); 28 | 29 | module.exports = requestAnimationFrame; 30 | -------------------------------------------------------------------------------- /packages/fbjs/src/__forks__/setImmediate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule setImmediate 8 | */ 9 | 10 | 'use strict'; 11 | 12 | // setimmediate adds setImmediate to the global. We want to make sure we export 13 | // the actual function. 14 | require('setimmediate') 15 | module.exports = global.setImmediate; 16 | -------------------------------------------------------------------------------- /packages/fbjs/src/__forks__/warning.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule warning 8 | */ 9 | 10 | 'use strict'; 11 | 12 | var emptyFunction = require('emptyFunction'); 13 | 14 | /** 15 | * Similar to invariant but only logs a warning if the condition is not met. 16 | * This can be used to log issues in development environments in critical 17 | * paths. Removing the logging code for production environments will keep the 18 | * same logic and follow the same code paths. 19 | */ 20 | 21 | 22 | function printWarning(format, ...args) { 23 | var argIndex = 0; 24 | var message = 'Warning: ' + format.replace(/%s/g, () => args[argIndex++]); 25 | if (typeof console !== 'undefined') { 26 | console.error(message); 27 | } 28 | try { 29 | // --- Welcome to debugging React --- 30 | // This error was thrown as a convenience so that you can use this stack 31 | // to find the callsite that caused this warning to fire. 32 | throw new Error(message); 33 | } catch (x) {} 34 | } 35 | 36 | var warning = __DEV__ 37 | ? function(condition, format, ...args) { 38 | if (format === undefined) { 39 | throw new Error( 40 | '`warning(condition, format, ...args)` requires a warning ' + 41 | 'message argument' 42 | ); 43 | } 44 | if (!condition) { 45 | printWarning(format, ...args); 46 | } 47 | } 48 | : emptyFunction; 49 | 50 | module.exports = warning; 51 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/ExecutionEnvironment.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule ExecutionEnvironment 8 | */ 9 | 10 | 'use strict'; 11 | 12 | const canUseDOM = !!( 13 | typeof window !== 'undefined' && 14 | window.document && 15 | window.document.createElement 16 | ); 17 | 18 | /** 19 | * Simple, lightweight module assisting with the detection and context of 20 | * Worker. Helps avoid circular dependencies and allows code to reason about 21 | * whether or not they are in a Worker, even if they never include the main 22 | * `ReactWorker` dependency. 23 | */ 24 | const ExecutionEnvironment = { 25 | 26 | canUseDOM: canUseDOM, 27 | 28 | canUseWorkers: typeof Worker !== 'undefined', 29 | 30 | canUseEventListeners: 31 | canUseDOM && !!(window.addEventListener || window.attachEvent), 32 | 33 | canUseViewport: canUseDOM && !!window.screen, 34 | 35 | isInWorker: !canUseDOM // For now, this is true - might change in the future. 36 | 37 | }; 38 | 39 | module.exports = ExecutionEnvironment; 40 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/Keys.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule Keys 8 | */ 9 | 10 | module.exports = { 11 | BACKSPACE: 8, 12 | TAB: 9, 13 | RETURN: 13, 14 | ALT: 18, 15 | ESC: 27, 16 | SPACE: 32, 17 | PAGE_UP: 33, 18 | PAGE_DOWN: 34, 19 | END: 35, 20 | HOME: 36, 21 | LEFT: 37, 22 | UP: 38, 23 | RIGHT: 39, 24 | DOWN: 40, 25 | DELETE: 46, 26 | COMMA: 188, 27 | PERIOD: 190, 28 | A: 65, 29 | Z: 90, 30 | ZERO: 48, 31 | NUMPAD_0: 96, 32 | NUMPAD_9: 105 33 | }; 34 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/PromiseMap.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule PromiseMap 8 | * @flow 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const Deferred = require('Deferred'); 14 | 15 | const invariant = require('invariant'); 16 | 17 | /** 18 | * A map of asynchronous values that can be get or set in any order. Unlike a 19 | * normal map, setting the value for a particular key more than once throws. 20 | * Also unlike a normal map, a key can either be resolved or rejected. 21 | */ 22 | class PromiseMap { 23 | _deferred: {[key:string]: Deferred}; 24 | 25 | constructor() { 26 | this._deferred = {}; 27 | } 28 | 29 | get(key: string): Promise { 30 | return getDeferred(this._deferred, key).getPromise(); 31 | } 32 | 33 | resolveKey(key: string, value: Tvalue): void { 34 | const entry = getDeferred(this._deferred, key); 35 | invariant(!entry.isSettled(), 'PromiseMap: Already settled `%s`.', key); 36 | entry.resolve(value); 37 | } 38 | 39 | rejectKey(key: string, reason: Treason): void { 40 | const entry = getDeferred(this._deferred, key); 41 | invariant(!entry.isSettled(), 'PromiseMap: Already settled `%s`.', key); 42 | entry.reject(reason); 43 | } 44 | } 45 | 46 | function getDeferred( 47 | entries: {[key: string]: Deferred}, 48 | key: string 49 | ): Deferred { 50 | if (!entries.hasOwnProperty(key)) { 51 | entries[key] = new Deferred(); 52 | } 53 | return entries[key]; 54 | } 55 | 56 | module.exports = PromiseMap; 57 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/TouchEventUtils.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule TouchEventUtils 8 | */ 9 | 10 | const TouchEventUtils = { 11 | /** 12 | * Utility function for common case of extracting out the primary touch from a 13 | * touch event. 14 | * - `touchEnd` events usually do not have the `touches` property. 15 | * http://stackoverflow.com/questions/3666929/ 16 | * mobile-sarai-touchend-event-not-firing-when-last-touch-is-removed 17 | * 18 | * @param {Event} nativeEvent Native event that may or may not be a touch. 19 | * @return {TouchesObject?} an object with pageX and pageY or null. 20 | */ 21 | extractSingleTouch: function(nativeEvent) { 22 | const touches = nativeEvent.touches; 23 | const changedTouches = nativeEvent.changedTouches; 24 | const hasTouches = touches && touches.length > 0; 25 | const hasChangedTouches = changedTouches && changedTouches.length > 0; 26 | 27 | return !hasTouches && hasChangedTouches ? changedTouches[0] : 28 | hasTouches ? touches[0] : 29 | nativeEvent; 30 | } 31 | }; 32 | 33 | module.exports = TouchEventUtils; 34 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/__tests__/isEmpty-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @emails oncall+jsinfra 8 | */ 9 | 10 | jest.mock('_shouldPolyfillES6Collection'); 11 | 12 | const isEmpty = require('isEmpty'); 13 | const _shouldPolyfillES6Collection = require('_shouldPolyfillES6Collection'); 14 | 15 | describe('isEmpty', () => { 16 | it('should return true for empty supported types', () => { 17 | expect(isEmpty(undefined)).toBe(true); 18 | expect(isEmpty(null)).toBe(true); 19 | expect(isEmpty(false)).toBe(true); 20 | expect(isEmpty(0)).toBe(true); 21 | expect(isEmpty('')).toBe(true); 22 | expect(isEmpty([])).toBe(true); 23 | expect(isEmpty({})).toBe(true); 24 | expect(isEmpty(Object.create(null))).toBe(true); 25 | }); 26 | 27 | it('should return false for non-empty supported types', () => { 28 | expect(isEmpty(1)).toBe(false); 29 | expect(isEmpty('0')).toBe(false); 30 | expect(isEmpty([1])).toBe(false); 31 | expect(isEmpty({a: 1})).toBe(false); 32 | }); 33 | 34 | it('should not allow maps and sets', () => { 35 | // Ensure that `Map` and `Set` use non-native polyfills 36 | _shouldPolyfillES6Collection.mockReturnValue(true); 37 | 38 | // Polyfilled 39 | expect(() => isEmpty(new Map())).toThrow(); 40 | expect(() => isEmpty(new Set())).toThrow(); 41 | 42 | // Native 43 | expect(() => isEmpty(new global.Map())).toThrow(); 44 | expect(() => isEmpty(new global.Set())).toThrow(); 45 | }); 46 | }); 47 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/__tests__/joinClasses-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @emails oncall+jsinfra 8 | */ 9 | 10 | 'use strict'; 11 | 12 | jest.unmock('joinClasses'); 13 | 14 | const joinClasses = require('joinClasses'); 15 | 16 | describe('joinClasses', function() { 17 | 18 | it('should return a single className', function() { 19 | expect(joinClasses('aaa')).toEqual('aaa'); 20 | }); 21 | 22 | it('should join two classes together', function() { 23 | const aaa = 'aaa'; 24 | const bbb = 'bbb'; 25 | expect(joinClasses(aaa, bbb)).toEqual('aaa bbb'); 26 | }); 27 | 28 | it('should join many classes together', function() { 29 | const aaa = 'aaa'; 30 | const bbb = 'bbb'; 31 | const ccc = 'ccc'; 32 | const ddd = 'ddd'; 33 | const eee = 'eee'; 34 | expect(joinClasses(aaa, bbb, ccc, ddd, eee)).toEqual('aaa bbb ccc ddd eee'); 35 | }); 36 | 37 | it('should omit undefined and empty classes', function() { 38 | const aaa = 'aaa'; 39 | let bbb; 40 | const ccc = null; 41 | const ddd = ''; 42 | const eee = 'eee'; 43 | expect(joinClasses(bbb)).toEqual(''); 44 | expect(joinClasses(bbb, bbb, bbb)).toEqual(''); 45 | expect(joinClasses(aaa, bbb, ccc, ddd, eee)).toEqual('aaa eee'); 46 | }); 47 | 48 | }); 49 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/__tests__/memoizeStringOnly-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @emails oncall+jsinfra 8 | */ 9 | 10 | 'use strict'; 11 | 12 | describe('memoizeStringOnly', function() { 13 | let memoizeStringOnly; 14 | 15 | beforeEach(function() { 16 | jest.resetModuleRegistry(); 17 | memoizeStringOnly = require('memoizeStringOnly'); 18 | }); 19 | 20 | it('should be transparent to callers', function() { 21 | const callback = function(string) { 22 | return string; 23 | }; 24 | const memoized = memoizeStringOnly(callback); 25 | 26 | expect(memoized('foo')).toEqual(callback('foo')); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/__tests__/sprintf-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @emails oncall+jsinfra 8 | */ 9 | 10 | jest 11 | .unmock('sprintf'); 12 | 13 | const sprintf = require('sprintf'); 14 | 15 | describe('sprintf', function() { 16 | 17 | it('works with %s', function() { 18 | expect(sprintf('aaa %s bbb %s ccc', '111', '222')) 19 | .toBe('aaa 111 bbb 222 ccc'); 20 | }); 21 | 22 | }); 23 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/_shouldPolyfillES6Collection.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule _shouldPolyfillES6Collection 8 | * @preventMunge 9 | * @flow 10 | */ 11 | 12 | /** 13 | * Checks whether a collection name (e.g. "Map" or "Set") has a native polyfill 14 | * that is safe to be used. 15 | */ 16 | function shouldPolyfillES6Collection(collectionName: string): boolean { 17 | const Collection = global[collectionName]; 18 | if (Collection == null) { 19 | return true; 20 | } 21 | 22 | // The iterator protocol depends on `Symbol.iterator`. If a collection is 23 | // implemented, but `Symbol` is not, it's going to break iteration because 24 | // we'll be using custom "@@iterator" instead, which is not implemented on 25 | // native collections. 26 | if (typeof global.Symbol !== 'function') { 27 | return true; 28 | } 29 | 30 | const proto = Collection.prototype; 31 | 32 | // These checks are adapted from es6-shim: https://fburl.com/34437854 33 | // NOTE: `isCallableWithoutNew` and `!supportsSubclassing` are not checked 34 | // because they make debugging with "break on exceptions" difficult. 35 | return Collection == null || 36 | typeof Collection !== 'function' || 37 | typeof proto.clear !== 'function' || 38 | new Collection().size !== 0 || 39 | typeof proto.keys !== 'function' || 40 | typeof proto.forEach !== 'function'; 41 | } 42 | 43 | module.exports = shouldPolyfillES6Collection; 44 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/camelize.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule camelize 8 | * @typechecks 9 | */ 10 | 11 | const _hyphenPattern = /-(.)/g; 12 | 13 | /** 14 | * Camelcases a hyphenated string, for example: 15 | * 16 | * > camelize('background-color') 17 | * < "backgroundColor" 18 | * 19 | * @param {string} string 20 | * @return {string} 21 | */ 22 | function camelize(string) { 23 | return string.replace(_hyphenPattern, function(_, character) { 24 | return character.toUpperCase(); 25 | }); 26 | } 27 | 28 | module.exports = camelize; 29 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/camelizeStyleName.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule camelizeStyleName 8 | * @typechecks 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const camelize = require('camelize'); 14 | 15 | const msPattern = /^-ms-/; 16 | 17 | /** 18 | * Camelcases a hyphenated CSS property name, for example: 19 | * 20 | * > camelizeStyleName('background-color') 21 | * < "backgroundColor" 22 | * > camelizeStyleName('-moz-transition') 23 | * < "MozTransition" 24 | * > camelizeStyleName('-ms-transition') 25 | * < "msTransition" 26 | * 27 | * As Andi Smith suggests 28 | * (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix 29 | * is converted to lowercase `ms`. 30 | * 31 | * @param {string} string 32 | * @return {string} 33 | */ 34 | function camelizeStyleName(string) { 35 | return camelize(string.replace(msPattern, 'ms-')); 36 | } 37 | 38 | module.exports = camelizeStyleName; 39 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/cancelAnimationFramePolyfill.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule cancelAnimationFramePolyfill 8 | */ 9 | 10 | /** 11 | * Here is the native and polyfill version of cancelAnimationFrame. 12 | * Please don't use it directly and use cancelAnimationFrame module instead. 13 | */ 14 | const cancelAnimationFrame = 15 | global.cancelAnimationFrame || 16 | global.webkitCancelAnimationFrame || 17 | global.mozCancelAnimationFrame || 18 | global.oCancelAnimationFrame || 19 | global.msCancelAnimationFrame || 20 | global.clearTimeout; 21 | 22 | module.exports = cancelAnimationFrame; 23 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/clamp.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule clamp 8 | * @flow 9 | * @typechecks 10 | */ 11 | 12 | /** 13 | * Clamps (or clips or confines) the value to be between min and max. 14 | */ 15 | function clamp(value: number, min: number, max: number): number { 16 | if (value < min) { 17 | return min; 18 | } 19 | if (value > max) { 20 | return max; 21 | } 22 | return value; 23 | } 24 | 25 | module.exports = clamp; 26 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/debounceCore.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule debounceCore 8 | * @typechecks 9 | */ 10 | 11 | /** 12 | * Invokes the given callback after a specified number of milliseconds have 13 | * elapsed, ignoring subsequent calls. 14 | * 15 | * For example, if you wanted to update a preview after the user stops typing 16 | * you could do the following: 17 | * 18 | * elem.addEventListener('keyup', debounce(this.updatePreview, 250), false); 19 | * 20 | * The returned function has a reset method which can be called to cancel a 21 | * pending invocation. 22 | * 23 | * var debouncedUpdatePreview = debounce(this.updatePreview, 250); 24 | * elem.addEventListener('keyup', debouncedUpdatePreview, false); 25 | * 26 | * // later, to cancel pending calls 27 | * debouncedUpdatePreview.reset(); 28 | * 29 | * @param {function} func - the function to debounce 30 | * @param {number} wait - how long to wait in milliseconds 31 | * @param {*} context - optional context to invoke the function in 32 | * @param {?function} setTimeoutFunc - an implementation of setTimeout 33 | * if nothing is passed in the default setTimeout function is used 34 | * @param {?function} clearTimeoutFunc - an implementation of clearTimeout 35 | * if nothing is passed in the default clearTimeout function is used 36 | */ 37 | function debounce(func, wait, context, setTimeoutFunc, clearTimeoutFunc) { 38 | setTimeoutFunc = setTimeoutFunc || setTimeout; 39 | clearTimeoutFunc = clearTimeoutFunc || clearTimeout; 40 | let timeout; 41 | 42 | function debouncer(...args) { 43 | debouncer.reset(); 44 | 45 | const callback = function() { 46 | func.apply(context, args); 47 | }; 48 | callback.__SMmeta = func.__SMmeta; 49 | timeout = setTimeoutFunc(callback, wait); 50 | } 51 | 52 | debouncer.reset = function() { 53 | clearTimeoutFunc(timeout); 54 | }; 55 | 56 | return debouncer; 57 | } 58 | 59 | module.exports = debounce; 60 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/dom/__tests__/getActiveElement-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | */ 8 | 9 | 'use strict'; 10 | 11 | jest.unmock('getActiveElement'); 12 | 13 | var getActiveElement = require('getActiveElement'); 14 | 15 | describe('getActiveElement', () => { 16 | it('returns body when there is no activeElement', () => { 17 | var element = getActiveElement(); 18 | expect(element.tagName).toEqual('BODY'); 19 | }); 20 | 21 | it('uses optional document parameter when provided', () => { 22 | var iframe = document.createElement('iframe'); 23 | document.body.appendChild(iframe); 24 | var iframeDocument = iframe.contentDocument; 25 | var element = getActiveElement(iframeDocument); 26 | try { 27 | expect(element.ownerDocument).toBe(iframeDocument); 28 | expect(element.ownerDocument).not.toBe(document); 29 | } finally { 30 | document.body.removeChild(iframe); 31 | } 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/dom/__tests__/isTextNode-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @emails oncall+ui_infra@fb.com 8 | */ 9 | 10 | var isTextNode = require('isTextNode'); 11 | 12 | describe('isTextNode', () => { 13 | it('should reject strings', () => { 14 | expect(isTextNode('')).toBe(false); 15 | expect(isTextNode('a real string')).toBe(false); 16 | }); 17 | it('should accept text nodes from DOM', () => { 18 | var span = document.createElement('span'); 19 | span.innerHTML = 'some text'; 20 | document.body.appendChild(span); 21 | var textnode = document.body.lastChild.firstChild.firstChild; 22 | try { 23 | expect(isTextNode(textnode)).toBe(true); 24 | } finally { 25 | document.body.removeChild(span); 26 | } 27 | }); 28 | it('should accept dynamically created text nodes', () => { 29 | var textnode = document.createTextNode('some more text'); 30 | expect(isTextNode(textnode)).toBe(true); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/dom/containsNode.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule containsNode 8 | * @flow 9 | */ 10 | 11 | const isTextNode = require('isTextNode'); 12 | 13 | /*eslint-disable no-bitwise */ 14 | 15 | /** 16 | * Checks if a given DOM node contains or is another DOM node. 17 | */ 18 | function containsNode(outerNode: ?Node, innerNode: ?Node): boolean { 19 | if (!outerNode || !innerNode) { 20 | return false; 21 | } else if (outerNode === innerNode) { 22 | return true; 23 | } else if (isTextNode(outerNode)) { 24 | return false; 25 | } else if (isTextNode(innerNode)) { 26 | return containsNode(outerNode, innerNode.parentNode); 27 | } else if ('contains' in outerNode) { 28 | return outerNode.contains(innerNode); 29 | } else if (outerNode.compareDocumentPosition) { 30 | return !!(outerNode.compareDocumentPosition(innerNode) & 16); 31 | } else { 32 | return false; 33 | } 34 | } 35 | 36 | module.exports = containsNode; 37 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/dom/focusNode.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule focusNode 8 | */ 9 | 10 | 'use strict'; 11 | 12 | /** 13 | * @param {DOMElement} node input/textarea to focus 14 | */ 15 | function focusNode(node) { 16 | // IE8 can throw "Can't move focus to the control because it is invisible, 17 | // not enabled, or of a type that does not accept the focus." for all kinds of 18 | // reasons that are too expensive and fragile to test. 19 | try { 20 | node.focus(); 21 | } catch(e) { 22 | } 23 | } 24 | 25 | module.exports = focusNode; 26 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/dom/getActiveElement.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule getActiveElement 8 | * @typechecks 9 | */ 10 | 11 | /* eslint-disable fb-www/typeof-undefined */ 12 | 13 | /** 14 | * Same as document.activeElement but wraps in a try-catch block. In IE it is 15 | * not safe to call document.activeElement if there is nothing focused. 16 | * 17 | * The activeElement will be null only if the document or document body is not 18 | * yet defined. 19 | * 20 | * @param {?DOMDocument} doc Defaults to current document. 21 | * @return {?DOMElement} 22 | */ 23 | function getActiveElement(doc) /*?DOMElement*/ { 24 | doc = doc || (typeof document !== 'undefined' ? document : undefined); 25 | if (typeof doc === 'undefined') { 26 | return null; 27 | } 28 | try { 29 | return doc.activeElement || doc.body; 30 | } catch (e) { 31 | return doc.body; 32 | } 33 | } 34 | 35 | module.exports = getActiveElement; 36 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/dom/getDocumentScrollElement.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule getDocumentScrollElement 8 | * @typechecks 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const isWebkit = 14 | typeof navigator !== 'undefined' && 15 | navigator.userAgent.indexOf('AppleWebKit') > -1; 16 | 17 | /** 18 | * Gets the element with the document scroll properties such as `scrollLeft` and 19 | * `scrollHeight`. This may differ across different browsers. 20 | * 21 | * NOTE: The return value can be null if the DOM is not yet ready. 22 | * 23 | * @param {?DOMDocument} doc Defaults to current document. 24 | * @return {?DOMElement} 25 | */ 26 | function getDocumentScrollElement(doc) { 27 | doc = doc || document; 28 | if (doc.scrollingElement) { 29 | return doc.scrollingElement; 30 | } 31 | return !isWebkit && doc.compatMode === 'CSS1Compat' ? 32 | doc.documentElement : 33 | doc.body; 34 | } 35 | 36 | module.exports = getDocumentScrollElement; 37 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/dom/getElementPosition.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule getElementPosition 8 | * @typechecks 9 | */ 10 | 11 | const getElementRect = require('getElementRect'); 12 | 13 | /** 14 | * Gets an element's position in pixels relative to the viewport. The returned 15 | * object represents the position of the element's top left corner. 16 | * 17 | * @param {DOMElement} element 18 | * @return {object} 19 | */ 20 | function getElementPosition(element) { 21 | const rect = getElementRect(element); 22 | return { 23 | x: rect.left, 24 | y: rect.top, 25 | width: rect.right - rect.left, 26 | height: rect.bottom - rect.top 27 | }; 28 | } 29 | 30 | module.exports = getElementPosition; 31 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/dom/getElementRect.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule getElementRect 8 | * @typechecks 9 | */ 10 | 11 | const containsNode = require('containsNode'); 12 | 13 | /** 14 | * Gets an element's bounding rect in pixels relative to the viewport. 15 | * 16 | * @param {DOMElement} elem 17 | * @return {object} 18 | */ 19 | function getElementRect(elem) { 20 | const docElem = elem.ownerDocument.documentElement; 21 | 22 | // FF 2, Safari 3 and Opera 9.5- do not support getBoundingClientRect(). 23 | // IE9- will throw if the element is not in the document. 24 | if (!('getBoundingClientRect' in elem) || !containsNode(docElem, elem)) { 25 | return { 26 | left: 0, 27 | right: 0, 28 | top: 0, 29 | bottom: 0 30 | }; 31 | } 32 | 33 | // Subtracts clientTop/Left because IE8- added a 2px border to the 34 | // element (see http://fburl.com/1493213). IE 7 in 35 | // Quicksmode does not report clientLeft/clientTop so there 36 | // will be an unaccounted offset of 2px when in quirksmode 37 | const rect = elem.getBoundingClientRect(); 38 | 39 | return { 40 | left: Math.round(rect.left) - docElem.clientLeft, 41 | right: Math.round(rect.right) - docElem.clientLeft, 42 | top: Math.round(rect.top) - docElem.clientTop, 43 | bottom: Math.round(rect.bottom) - docElem.clientTop 44 | }; 45 | } 46 | 47 | module.exports = getElementRect; 48 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/dom/getScrollPosition.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule getScrollPosition 8 | * @typechecks 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const getDocumentScrollElement = require('getDocumentScrollElement'); 14 | const getUnboundedScrollPosition = require('getUnboundedScrollPosition'); 15 | 16 | /** 17 | * Gets the scroll position of the supplied element or window. 18 | * 19 | * The return values are bounded. This means that if the scroll position is 20 | * negative or exceeds the element boundaries (which is possible using inertial 21 | * scrolling), you will get zero or the maximum scroll position, respectively. 22 | * 23 | * If you need the unbound scroll position, use `getUnboundedScrollPosition`. 24 | * 25 | * @param {DOMWindow|DOMElement} scrollable 26 | * @return {object} Map with `x` and `y` keys. 27 | */ 28 | function getScrollPosition(scrollable) { 29 | const documentScrollElement = getDocumentScrollElement(scrollable.ownerDocument || scrollable.document); 30 | if (scrollable.Window && scrollable instanceof scrollable.Window) { 31 | scrollable = documentScrollElement; 32 | } 33 | const scrollPosition = getUnboundedScrollPosition(scrollable); 34 | 35 | const viewport = 36 | scrollable === documentScrollElement ? 37 | scrollable.ownerDocument.documentElement : 38 | scrollable; 39 | 40 | const xMax = scrollable.scrollWidth - viewport.clientWidth; 41 | const yMax = scrollable.scrollHeight - viewport.clientHeight; 42 | 43 | scrollPosition.x = Math.max(0, Math.min(scrollPosition.x, xMax)); 44 | scrollPosition.y = Math.max(0, Math.min(scrollPosition.y, yMax)); 45 | 46 | return scrollPosition; 47 | } 48 | 49 | module.exports = getScrollPosition; 50 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/dom/getStyleProperty.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule getStyleProperty 8 | * @typechecks 9 | */ 10 | 11 | const camelize = require('camelize'); 12 | const hyphenate = require('hyphenate'); 13 | 14 | function asString(value) /*?string*/ { 15 | return value == null 16 | ? value 17 | : String(value); 18 | } 19 | 20 | function getStyleProperty(/*DOMNode*/ node, /*string*/ name) /*?string*/ { 21 | let computedStyle; 22 | 23 | // W3C Standard 24 | if (window.getComputedStyle) { 25 | // In certain cases such as within an iframe in FF3, this returns null. 26 | computedStyle = window.getComputedStyle(node, null); 27 | if (computedStyle) { 28 | return asString(computedStyle.getPropertyValue(hyphenate(name))); 29 | } 30 | } 31 | // Safari 32 | if (document.defaultView && document.defaultView.getComputedStyle) { 33 | computedStyle = document.defaultView.getComputedStyle(node, null); 34 | // A Safari bug causes this to return null for `display: none` elements. 35 | if (computedStyle) { 36 | return asString(computedStyle.getPropertyValue(hyphenate(name))); 37 | } 38 | if (name === 'display') { 39 | return 'none'; 40 | } 41 | } 42 | // Internet Explorer 43 | if (node.currentStyle) { 44 | if (name === 'float') { 45 | return asString(node.currentStyle.cssFloat 46 | || node.currentStyle.styleFloat); 47 | } 48 | return asString(node.currentStyle[camelize(name)]); 49 | } 50 | return asString(node.style && node.style[camelize(name)]); 51 | } 52 | 53 | module.exports = getStyleProperty; 54 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/dom/getViewportDimensions.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule getViewportDimensions 8 | * @flow 9 | * @typechecks 10 | */ 11 | 12 | type ViewportDimensions = {width: number, height: number}; 13 | 14 | function getViewportWidth(): number { 15 | let width; 16 | if (document.documentElement) { 17 | width = document.documentElement.clientWidth; 18 | } 19 | 20 | if (!width && document.body) { 21 | width = document.body.clientWidth; 22 | } 23 | 24 | return width || 0; 25 | } 26 | 27 | function getViewportHeight(): number { 28 | let height; 29 | if (document.documentElement) { 30 | height = document.documentElement.clientHeight; 31 | } 32 | 33 | if (!height && document.body) { 34 | height = document.body.clientHeight; 35 | } 36 | 37 | return height || 0; 38 | } 39 | 40 | /** 41 | * Gets the viewport dimensions including any scrollbars. 42 | */ 43 | function getViewportDimensions(): ViewportDimensions { 44 | return { 45 | width: window.innerWidth || getViewportWidth(), 46 | height: window.innerHeight || getViewportHeight(), 47 | }; 48 | } 49 | 50 | /** 51 | * Gets the viewport dimensions excluding any scrollbars. 52 | */ 53 | getViewportDimensions.withoutScrollbars = function(): ViewportDimensions { 54 | return { 55 | width: getViewportWidth(), 56 | height: getViewportHeight(), 57 | }; 58 | }; 59 | 60 | module.exports = getViewportDimensions; 61 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/dom/isNode.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule isNode 8 | * @typechecks 9 | */ 10 | 11 | /** 12 | * @param {*} object The object to check. 13 | * @return {boolean} Whether or not the object is a DOM node. 14 | */ 15 | function isNode(object) { 16 | var doc = object ? (object.ownerDocument || object) : document; 17 | var defaultView = doc.defaultView || window; 18 | return !!(object && ( 19 | typeof defaultView.Node === 'function' ? object instanceof defaultView.Node : 20 | typeof object === 'object' && 21 | typeof object.nodeType === 'number' && 22 | typeof object.nodeName === 'string' 23 | )); 24 | } 25 | 26 | module.exports = isNode; 27 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/dom/isTextNode.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule isTextNode 8 | * @typechecks 9 | */ 10 | 11 | const isNode = require('isNode'); 12 | 13 | /** 14 | * @param {*} object The object to check. 15 | * @return {boolean} Whether or not the object is a DOM text node. 16 | */ 17 | function isTextNode(object) { 18 | return isNode(object) && object.nodeType == 3; 19 | } 20 | 21 | module.exports = isTextNode; 22 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/emptyFunction.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule emptyFunction 8 | * @flow 9 | */ 10 | 11 | export type FunctionReturning<+T> = (...args: $ReadOnlyArray) => T; 12 | 13 | export type EmptyFunctionType = { 14 | (...args: $ReadOnlyArray): void, 15 | thatReturns: (x: T) => FunctionReturning, 16 | thatReturnsFalse: FunctionReturning, 17 | thatReturnsTrue: FunctionReturning, 18 | thatReturnsNull: FunctionReturning, 19 | thatReturnsThis: FunctionReturning, 20 | thatReturnsArgument: (x: T) => T, 21 | }; 22 | 23 | function makeEmptyFunction(arg: T): (...args: Array) => T { 24 | return function() { 25 | return arg; 26 | }; 27 | } 28 | 29 | /** 30 | * This function accepts and discards inputs; it has no side effects. This is 31 | * primarily useful idiomatically for overridable function endpoints which 32 | * always need to be callable, since JS lacks a null-call idiom ala Cocoa. 33 | */ 34 | const emptyFunction = function() {}; 35 | 36 | emptyFunction.thatReturns = makeEmptyFunction; 37 | emptyFunction.thatReturnsFalse = makeEmptyFunction(false); 38 | emptyFunction.thatReturnsTrue = makeEmptyFunction(true); 39 | emptyFunction.thatReturnsNull = makeEmptyFunction(null); 40 | emptyFunction.thatReturnsThis = function() { return this; }; 41 | emptyFunction.thatReturnsArgument = function(arg) { return arg; }; 42 | 43 | module.exports = (emptyFunction: EmptyFunctionType); 44 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/emptyObject.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule emptyObject 8 | */ 9 | 10 | 'use strict'; 11 | 12 | const emptyObject = {}; 13 | 14 | if (__DEV__) { 15 | Object.freeze(emptyObject); 16 | } 17 | 18 | module.exports = emptyObject; 19 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/flattenArray.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule flattenArray 8 | * @typechecks 9 | * @flow 10 | */ 11 | 12 | /** 13 | * Returns a flattened array that represents the DFS traversal of the supplied 14 | * input array. For example: 15 | * 16 | * var deep = ["a", ["b", "c"], "d", {"e": [1, 2]}, [["f"], "g"]]; 17 | * var flat = flattenArray(deep); 18 | * console.log(flat); 19 | * > ["a", "b", "c", "d", {"e": [1, 2]}, "f", "g"]; 20 | * 21 | * @see https://github.com/jonschlinkert/arr-flatten 22 | * @copyright 2014-2015 Jon Schlinkert 23 | * @license MIT 24 | */ 25 | function flattenArray(array: Array): Array { 26 | const result = []; 27 | flatten(array, result); 28 | return result; 29 | } 30 | 31 | function flatten(array: Array, result: Array): void { 32 | let length = array.length; 33 | let ii = 0; 34 | 35 | while (length--) { 36 | const current = array[ii++]; 37 | if (Array.isArray(current)) { 38 | flatten(current, result); 39 | } else { 40 | result.push(current); 41 | } 42 | } 43 | } 44 | 45 | module.exports = flattenArray; 46 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/getVendorPrefixedName.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule getVendorPrefixedName 8 | * @typechecks 9 | */ 10 | 11 | const ExecutionEnvironment = require('ExecutionEnvironment'); 12 | const UserAgent = require('UserAgent'); 13 | 14 | const camelize = require('camelize'); 15 | const invariant = require('invariant'); 16 | 17 | const memoized = {}; 18 | const prefixes = ['Webkit', 'ms', 'Moz', 'O']; 19 | const prefixRegex = new RegExp('^(' + prefixes.join('|') + ')'); 20 | const testStyle = 21 | ExecutionEnvironment.canUseDOM ? document.createElement('div').style : {}; 22 | 23 | function getWithPrefix(name) { 24 | for (let i = 0; i < prefixes.length; i++) { 25 | const prefixedName = prefixes[i] + name; 26 | if (prefixedName in testStyle) { 27 | return prefixedName; 28 | } 29 | } 30 | return null; 31 | } 32 | 33 | function guessVendorPrefixedNameFromUserAgent(name) { 34 | switch (name) { 35 | case 'lineClamp': 36 | if (UserAgent.isEngine('WebKit >= 315.14.2')) { 37 | return 'WebkitLineClamp'; 38 | } 39 | return null; 40 | default: 41 | return null; 42 | } 43 | } 44 | 45 | /** 46 | * @param {string} property Name of a css property to check for. 47 | * @return {?string} property name supported in the browser, or null if not 48 | * supported. 49 | */ 50 | function getVendorPrefixedName(property) { 51 | const name = camelize(property); 52 | if (memoized[name] === undefined) { 53 | const capitalizedName = name.charAt(0).toUpperCase() + name.slice(1); 54 | if (prefixRegex.test(capitalizedName)) { 55 | invariant( 56 | false, 57 | 'getVendorPrefixedName must only be called with unprefixed' + 58 | 'CSS property names. It was called with %s', property 59 | ); 60 | } 61 | if (ExecutionEnvironment.canUseDOM) { 62 | memoized[name] = 63 | (name in testStyle) ? name : getWithPrefix(capitalizedName); 64 | } else { 65 | memoized[name] = guessVendorPrefixedNameFromUserAgent(name); 66 | } 67 | } 68 | return memoized[name]; 69 | } 70 | 71 | module.exports = getVendorPrefixedName; 72 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/hyphenate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule hyphenate 8 | * @typechecks 9 | */ 10 | 11 | const _uppercasePattern = /([A-Z])/g; 12 | 13 | /** 14 | * Hyphenates a camelcased string, for example: 15 | * 16 | * > hyphenate('backgroundColor') 17 | * < "background-color" 18 | * 19 | * For CSS style names, use `hyphenateStyleName` instead which works properly 20 | * with all vendor prefixes, including `ms`. 21 | * 22 | * @param {string} string 23 | * @return {string} 24 | */ 25 | function hyphenate(string) { 26 | return string.replace(_uppercasePattern, '-$1').toLowerCase(); 27 | } 28 | 29 | module.exports = hyphenate; 30 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/hyphenateStyleName.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule hyphenateStyleName 8 | * @typechecks 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const hyphenate = require('hyphenate'); 14 | 15 | const msPattern = /^ms-/; 16 | 17 | /** 18 | * Hyphenates a camelcased CSS property name, for example: 19 | * 20 | * > hyphenateStyleName('backgroundColor') 21 | * < "background-color" 22 | * > hyphenateStyleName('MozTransition') 23 | * < "-moz-transition" 24 | * > hyphenateStyleName('msTransition') 25 | * < "-ms-transition" 26 | * 27 | * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix 28 | * is converted to `-ms-`. 29 | * 30 | * @param {string} string 31 | * @return {string} 32 | */ 33 | function hyphenateStyleName(string) { 34 | return hyphenate(string).replace(msPattern, '-ms-'); 35 | } 36 | 37 | module.exports = hyphenateStyleName; 38 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/isEmail.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule isEmail 8 | */ 9 | 10 | // good approximation of RFC 2822 11 | // http://www.regular-expressions.info/email.html 12 | var re = /^[\w!#\$%&'\*\+\/\=\?\^`\{\|\}~\-]+(:?\.[\w!#\$%&'\*\+\/\=\?\^`\{\|\}~\-]+)*@(?:[a-z0-9](?:[a-z0-9\-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9\-]*[a-z0-9])?$/i; 13 | 14 | function isEmail(email) { 15 | return re.test(email); 16 | } 17 | 18 | module.exports = isEmail; 19 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/isEmpty.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule isEmpty 8 | * @flow 9 | */ 10 | 11 | 'use strict'; 12 | 13 | /* eslint-disable fb-www/typeof-undefined */ 14 | /* eslint-disable no-unused-vars */ 15 | 16 | const invariant = require('invariant'); 17 | 18 | /** 19 | * Checks if a value is empty. 20 | */ 21 | function isEmpty(value: mixed): boolean { 22 | if (Array.isArray(value)) { 23 | return value.length === 0; 24 | } else if (typeof value === 'object') { 25 | if (value) { 26 | invariant( 27 | !isIterable(value) || value.size === undefined, 28 | 'isEmpty() does not support iterable collections.', 29 | ); 30 | for (const _ in value) { 31 | return false; 32 | } 33 | } 34 | return true; 35 | } else { 36 | return !value; 37 | } 38 | } 39 | 40 | function isIterable(value: any): boolean { 41 | if (typeof Symbol === 'undefined') { 42 | return false; 43 | } 44 | return value[Symbol.iterator]; 45 | } 46 | 47 | module.exports = isEmpty; 48 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/joinClasses.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule joinClasses 8 | * @flow 9 | * @typechecks static-only 10 | */ 11 | 12 | 'use strict'; 13 | 14 | /** 15 | * Combines multiple className strings into one. 16 | */ 17 | function joinClasses(className: mixed): string { 18 | let newClassName = ((className: any): string) || ''; 19 | const argLength = arguments.length; 20 | 21 | if (argLength > 1) { 22 | for (let index = 1; index < argLength; index++) { 23 | const nextClass = arguments[index]; 24 | if (nextClass) { 25 | newClassName = (newClassName ? newClassName + ' ' : '') + nextClass; 26 | } 27 | } 28 | } 29 | return newClassName; 30 | } 31 | 32 | module.exports = joinClasses; 33 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/memoizeStringOnly.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule memoizeStringOnly 8 | * @flow 9 | * @typechecks static-only 10 | */ 11 | 12 | 'use strict'; 13 | 14 | /** 15 | * Memoizes the return value of a function that accepts one string argument. 16 | */ 17 | function memoizeStringOnly(callback: (s: string) => T): (s: string) => T { 18 | const cache = {}; 19 | return function(string) { 20 | if (!cache.hasOwnProperty(string)) { 21 | cache[string] = callback.call(this, string); 22 | } 23 | return cache[string]; 24 | }; 25 | } 26 | 27 | module.exports = memoizeStringOnly; 28 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/nativeRequestAnimationFrame.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule nativeRequestAnimationFrame 8 | */ 9 | 10 | const nativeRequestAnimationFrame = 11 | global.requestAnimationFrame || 12 | global.webkitRequestAnimationFrame || 13 | global.mozRequestAnimationFrame || 14 | global.oRequestAnimationFrame || 15 | global.msRequestAnimationFrame; 16 | 17 | module.exports = nativeRequestAnimationFrame; 18 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/resolveImmediate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule resolveImmediate 8 | * @flow 9 | */ 10 | 11 | const resolvedPromise = Promise.resolve(); 12 | 13 | /** 14 | * An alternative to setImmediate based on Promise. 15 | */ 16 | function resolveImmediate(callback: () => any): void { 17 | resolvedPromise.then(callback).catch(throwNext); 18 | } 19 | 20 | function throwNext(error) { 21 | setTimeout(() => { 22 | throw error; 23 | }, 0); 24 | } 25 | 26 | module.exports = resolveImmediate; 27 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/shallowEqual.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule shallowEqual 8 | * @typechecks 9 | * @flow 10 | */ 11 | 12 | /*eslint-disable no-self-compare */ 13 | 14 | 'use strict'; 15 | 16 | const hasOwnProperty = Object.prototype.hasOwnProperty; 17 | 18 | /** 19 | * inlined Object.is polyfill to avoid requiring consumers ship their own 20 | * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is 21 | */ 22 | function is(x: mixed, y: mixed): boolean { 23 | // SameValue algorithm 24 | if (x === y) { // Steps 1-5, 7-10 25 | // Steps 6.b-6.e: +0 != -0 26 | // Added the nonzero y check to make Flow happy, but it is redundant 27 | return x !== 0 || y !== 0 || 1 / x === 1 / y; 28 | } else { 29 | // Step 6.a: NaN == NaN 30 | return x !== x && y !== y; 31 | } 32 | } 33 | 34 | /** 35 | * Performs equality by iterating through keys on an object and returning false 36 | * when any key has values which are not strictly equal between the arguments. 37 | * Returns true when the values of all keys are strictly equal. 38 | */ 39 | function shallowEqual(objA: mixed, objB: mixed): boolean { 40 | if (is(objA, objB)) { 41 | return true; 42 | } 43 | 44 | if (typeof objA !== 'object' || objA === null || 45 | typeof objB !== 'object' || objB === null) { 46 | return false; 47 | } 48 | 49 | const keysA = Object.keys(objA); 50 | const keysB = Object.keys(objB); 51 | 52 | if (keysA.length !== keysB.length) { 53 | return false; 54 | } 55 | 56 | // Test for A's keys different from B. 57 | for (let i = 0; i < keysA.length; i++) { 58 | if ( 59 | !hasOwnProperty.call(objB, keysA[i]) || 60 | !is(objA[keysA[i]], objB[keysA[i]]) 61 | ) { 62 | return false; 63 | } 64 | } 65 | 66 | return true; 67 | } 68 | 69 | module.exports = shallowEqual; 70 | -------------------------------------------------------------------------------- /packages/fbjs/src/core/sprintf.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule sprintf 8 | * @typechecks 9 | */ 10 | 11 | /** 12 | * Simple function for formatting strings. 13 | * 14 | * Replaces placeholders with values passed as extra arguments 15 | * 16 | * @param {string} format the base string 17 | * @param ...args the values to insert 18 | * @return {string} the replaced string 19 | */ 20 | function sprintf(format, ...args) { 21 | let index = 0; 22 | return format.replace(/%s/g, match => args[index++]); 23 | } 24 | 25 | module.exports = sprintf; 26 | -------------------------------------------------------------------------------- /packages/fbjs/src/core_windowless/__tests__/removeFromArray-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @emails oncall+jsinfra 8 | */ 9 | 10 | var removeFromArray = require('removeFromArray'); 11 | 12 | describe('removeFromArray', function() { 13 | it('should remove numbers from an array', function() { 14 | var a = [1, 2]; 15 | 16 | removeFromArray(a, 1); 17 | expect(a).toEqual([2]); 18 | removeFromArray(a, 2); 19 | expect(a).toEqual([]); 20 | }); 21 | 22 | it('should work when the given value is not in the array', function() { 23 | var a = [1, 2]; 24 | removeFromArray(a, 3); 25 | expect(a).toEqual([1, 2]); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /packages/fbjs/src/core_windowless/removeFromArray.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule removeFromArray 8 | * @typechecks 9 | * @flow 10 | */ 11 | 12 | /** 13 | * Removes an element from an array. 14 | */ 15 | function removeFromArray(array: Array, element: T): void { 16 | var index = array.indexOf(element); 17 | if (index !== -1) { 18 | array.splice(index, 1); 19 | } 20 | } 21 | 22 | module.exports = removeFromArray; 23 | -------------------------------------------------------------------------------- /packages/fbjs/src/crypto/__mocks__/base62.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | module.exports = require.requireActual('base62'); 11 | -------------------------------------------------------------------------------- /packages/fbjs/src/crypto/__mocks__/crc32.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | module.exports = require.requireActual('crc32'); 11 | -------------------------------------------------------------------------------- /packages/fbjs/src/crypto/__tests__/base62-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @emails oncall+relay 8 | */ 9 | 10 | 'use strict'; 11 | 12 | const base62 = require('base62'); 13 | 14 | describe('base62', () => { 15 | var samples = [ 16 | { 17 | input: 0, 18 | output: '0', 19 | }, 20 | { 21 | input: 1, 22 | output: '1', 23 | }, 24 | { 25 | input: 10, 26 | output: 'a', 27 | }, 28 | { 29 | input: 35, 30 | output: 'z', 31 | }, 32 | { 33 | input: 36, 34 | output: 'A', 35 | }, 36 | { 37 | input: 61, 38 | output: 'Z', 39 | }, 40 | { 41 | input: 62, 42 | output: '10', 43 | }, 44 | ]; 45 | 46 | it('computes base62 correctly', () => { 47 | samples.forEach(sample => { 48 | expect(base62(sample.input)).toBe(sample.output); 49 | }); 50 | }); 51 | }); 52 | -------------------------------------------------------------------------------- /packages/fbjs/src/crypto/__tests__/crc32-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @emails oncall+relay 8 | */ 9 | 10 | 'use strict'; 11 | 12 | var crc32 = require('crc32'); 13 | 14 | describe('crc32', () => { 15 | var samples = [ 16 | { 17 | input: '1234567890', 18 | output: 639479525, 19 | }, 20 | { 21 | input: 'CRC me!', 22 | output: 38028046, 23 | }, 24 | { 25 | input: '2733338650', 26 | output: -1561628646, 27 | }, 28 | ]; 29 | 30 | it('computes crc32 correctly', () => { 31 | samples.forEach(sample => { 32 | expect(crc32(sample.input)).toBe(sample.output); 33 | }); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /packages/fbjs/src/crypto/base62.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule base62 8 | * @flow 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const BASE62 = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; 14 | 15 | function base62(number: number): string { 16 | if (!number) { 17 | return '0'; 18 | } 19 | let string = ''; 20 | while (number > 0) { 21 | string = BASE62[number % 62] + string; 22 | number = Math.floor(number / 62); 23 | } 24 | return string; 25 | } 26 | 27 | module.exports = base62; 28 | -------------------------------------------------------------------------------- /packages/fbjs/src/datatransfer/PhotosMimeType.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule PhotosMimeType 8 | */ 9 | const PhotosMimeType = { 10 | isImage(mimeString) { 11 | return getParts(mimeString)[0] === 'image'; 12 | }, 13 | 14 | isJpeg(mimeString) { 15 | const parts = getParts(mimeString); 16 | return ( 17 | PhotosMimeType.isImage(mimeString) && 18 | // see http://fburl.com/10972194 19 | (parts[1] === 'jpeg' || parts[1] === 'pjpeg') 20 | ); 21 | }, 22 | }; 23 | 24 | function getParts(mimeString) { 25 | return mimeString.split('/'); 26 | } 27 | 28 | module.exports = PhotosMimeType; 29 | -------------------------------------------------------------------------------- /packages/fbjs/src/dom/BrowserSupportCore.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule BrowserSupportCore 8 | */ 9 | 10 | 11 | var getVendorPrefixedName = require('getVendorPrefixedName'); 12 | 13 | var BrowserSupportCore = { 14 | /** 15 | * @return {bool} True if browser supports css animations. 16 | */ 17 | hasCSSAnimations: function() { 18 | return !!getVendorPrefixedName('animationName'); 19 | }, 20 | 21 | /** 22 | * @return {bool} True if browser supports css transforms. 23 | */ 24 | hasCSSTransforms: function() { 25 | return !!getVendorPrefixedName('transform'); 26 | }, 27 | 28 | /** 29 | * @return {bool} True if browser supports css 3d transforms. 30 | */ 31 | hasCSS3DTransforms: function() { 32 | return !!getVendorPrefixedName('perspective'); 33 | }, 34 | 35 | /** 36 | * @return {bool} True if browser supports css transitions. 37 | */ 38 | hasCSSTransitions: function() { 39 | return !!getVendorPrefixedName('transition'); 40 | }, 41 | }; 42 | 43 | module.exports = BrowserSupportCore; 44 | -------------------------------------------------------------------------------- /packages/fbjs/src/dom/translateDOMPositionXY.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule translateDOMPositionXY 8 | * @typechecks 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const BrowserSupportCore = require('BrowserSupportCore'); 14 | 15 | const getVendorPrefixedName = require('getVendorPrefixedName'); 16 | 17 | const TRANSFORM = getVendorPrefixedName('transform'); 18 | const BACKFACE_VISIBILITY = getVendorPrefixedName('backfaceVisibility'); 19 | 20 | const translateDOMPositionXY = (function() { 21 | if (BrowserSupportCore.hasCSSTransforms()) { 22 | const ua = global.window ? global.window.navigator.userAgent : 'UNKNOWN'; 23 | const isSafari = (/Safari\//).test(ua) && !(/Chrome\//).test(ua); 24 | // It appears that Safari messes up the composition order 25 | // of GPU-accelerated layers 26 | // (see bug https://bugs.webkit.org/show_bug.cgi?id=61824). 27 | // Use 2D translation instead. 28 | if (!isSafari && BrowserSupportCore.hasCSS3DTransforms()) { 29 | return function(/*object*/ style, /*number*/ x, /*number*/ y) { 30 | style[TRANSFORM] = 'translate3d(' + x + 'px,' + y + 'px,0)'; 31 | style[BACKFACE_VISIBILITY] = 'hidden'; 32 | }; 33 | } else { 34 | return function(/*object*/ style, /*number*/ x, /*number*/ y) { 35 | style[TRANSFORM] = 'translate(' + x + 'px,' + y + 'px)'; 36 | }; 37 | } 38 | } else { 39 | return function(/*object*/ style, /*number*/ x, /*number*/ y) { 40 | style.left = x + 'px'; 41 | style.top = y + 'px'; 42 | }; 43 | } 44 | })(); 45 | 46 | module.exports = translateDOMPositionXY; 47 | -------------------------------------------------------------------------------- /packages/fbjs/src/fetch/__mocks__/fetch.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @noflow 8 | */ 9 | 10 | 'use strict'; 11 | 12 | var Deferred = require.requireActual('Deferred'); 13 | 14 | const fetch = jest.fn((uri: string, options: Object): Promise => { 15 | var deferred = new Deferred(); 16 | fetch.mock.deferreds.push(deferred); 17 | return deferred.getPromise(); 18 | }); 19 | 20 | fetch.mock.deferreds = []; 21 | 22 | module.exports = fetch; 23 | -------------------------------------------------------------------------------- /packages/fbjs/src/fetch/__mocks__/fetchWithRetries.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @noflow 8 | */ 9 | 10 | 'use strict'; 11 | 12 | var Deferred = require.requireActual('Deferred'); 13 | 14 | function fetchWithRetries(...args): Promise { 15 | var deferred = new Deferred(); 16 | fetchWithRetries.mock.calls.push(args); 17 | fetchWithRetries.mock.deferreds.push(deferred); 18 | return deferred.getPromise(); 19 | } 20 | 21 | fetchWithRetries.mock = { 22 | calls: [], 23 | deferreds: [], 24 | }; 25 | 26 | module.exports = fetchWithRetries; 27 | -------------------------------------------------------------------------------- /packages/fbjs/src/fetch/__tests__/fetchMock-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @emails oncall+relay 8 | */ 9 | 10 | 'use strict'; 11 | 12 | var Deferred = require('Deferred'); 13 | var fetch = require('fetch'); 14 | 15 | describe('fetchMock', () => { 16 | it('has a corresponding `Deferred` for each call to `fetch`', () => { 17 | expect(fetch.mock.calls.length).toBe(0); 18 | expect(fetch.mock.deferreds.length).toBe(0); 19 | var promise = fetch('//localhost', {}); 20 | expect(fetch.mock.calls.length).toBe(1); 21 | expect(fetch.mock.deferreds.length).toBe(1); 22 | var deferred = fetch.mock.deferreds[0]; 23 | expect(deferred instanceof Deferred).toBe(true); 24 | var mockCallback = jest.fn(); 25 | var mockResult = {}; 26 | expect(mockCallback).not.toBeCalled(); 27 | promise.then(mockCallback); 28 | deferred.resolve(mockResult); 29 | jest.runAllTimers(); 30 | expect(mockCallback).toBeCalledWith(mockResult); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/__tests__/compactArray-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @emails oncall+jsinfra 8 | * @flow 9 | */ 10 | 11 | jest 12 | .unmock('compactArray'); 13 | 14 | var compactArray = require('compactArray'); 15 | 16 | describe('compactArray', () => { 17 | 18 | it('filters both null and undefined', () => { 19 | var originalArray: Array = [1, 2, 3, null, 4, undefined, 5, 6]; 20 | var compactedArray: Array = compactArray(originalArray); 21 | expect(compactedArray).toEqual( 22 | [1, 2, 3, 4, 5, 6] 23 | ); 24 | }); 25 | 26 | }); 27 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/__tests__/concatAllArray-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @emails oncall+ui_infra@xmail.facebook.com 8 | */ 9 | 10 | jest 11 | .unmock('concatAllArray'); 12 | 13 | var concatAllArray = require('concatAllArray'); 14 | 15 | describe('concatAllArray', () => { 16 | 17 | it('concats an array of arrays', () => { 18 | expect( 19 | concatAllArray([[1, 7, 8], [5], [4, 3]], x => x) 20 | ).toEqual([1, 7, 8, 5, 4, 3]); 21 | }); 22 | 23 | it('ignores null and undefined', () => { 24 | expect( 25 | concatAllArray([null, undefined, [1], [2]], x => x) 26 | ).toEqual([1, 2]); 27 | }); 28 | 29 | it('throws for scalar values', () => { 30 | [false, true, 'b', 2].forEach(value => 31 | expect(() => concatAllArray([value], x => x)).toThrow( 32 | new TypeError( 33 | 'concatAllArray: All items in the array must be an array or null, ' + 34 | 'got "' + value + '" at index "0" instead' 35 | ) 36 | ) 37 | ); 38 | }); 39 | 40 | }); 41 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/__tests__/countDistinct-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @emails oncall+jsinfra 8 | * @flow 9 | */ 10 | 11 | jest 12 | .unmock('countDistinct'); 13 | 14 | var Immutable = require('immutable'); 15 | var countDistinct = require('countDistinct'); 16 | 17 | describe('countDistinct', () => { 18 | it('does not include duplicate items in the count', () => { 19 | var originalArray = [{id: 1}, {id: 2}, {id: 3}, {id: 1}, {id: 2}]; 20 | var count = countDistinct(originalArray, i => i.id); 21 | expect(count).toBe(3); 22 | }); 23 | 24 | it('defaults to identity selector', () => { 25 | var originalArray = [1, 2, 3, 4, 1, 2, 3]; 26 | var count = countDistinct(originalArray); 27 | expect(count).toBe(4); 28 | }); 29 | 30 | it('works with immutable iterables', () => { 31 | var iterable = Immutable.Iterable([1, 2, 3, 4, 1, 2, 3]); 32 | var count = countDistinct(iterable); 33 | expect(count).toBe(4); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/__tests__/distinctArray-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * @emails oncall+ui_infra 7 | */ 8 | 9 | 'use strict'; 10 | 11 | jest 12 | .unmock('distinctArray'); 13 | 14 | var distinctArray = require('distinctArray'); 15 | 16 | describe('distinctArray', () => 17 | it('returns the correct result', () => { 18 | expect( 19 | distinctArray([1, 2, 3]) 20 | ).toEqual( 21 | [1, 2, 3] 22 | ); 23 | 24 | expect( 25 | distinctArray([1, 1, 1, 2, 3]) 26 | ).toEqual( 27 | [1, 2, 3] 28 | ); 29 | 30 | expect( 31 | distinctArray([1, 2, 3, 1, 1]) 32 | ).toEqual( 33 | [1, 2, 3] 34 | ); 35 | 36 | expect( 37 | distinctArray([1, 1, 1]) 38 | ).toEqual( 39 | [1] 40 | ); 41 | 42 | expect( 43 | distinctArray([]) 44 | ).toEqual( 45 | [] 46 | ); 47 | 48 | expect( 49 | distinctArray(['a', 'b', 'c' ,'a', 1, 2, 'a', 1]) 50 | ).toEqual( 51 | ['a', 'b', 'c', 1, 2] 52 | ); 53 | }) 54 | ); 55 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/__tests__/equalsSet-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @emails oncall+jsinfra 8 | */ 9 | 10 | 'use strict'; 11 | 12 | jest.unmock('equalsSet'); 13 | 14 | var equalsSet = require('equalsSet'); 15 | 16 | describe('equalsSet', () => { 17 | it('returns true for empty sets', () => { 18 | var one = new Set(); 19 | var two = new Set(); 20 | expect(equalsSet(one, two)).toBe(true); 21 | expect(equalsSet(two, one)).toBe(true); 22 | }); 23 | 24 | it('returns true for sets that are equal', () => { 25 | var one = new Set(['a', 'b', 'c']); 26 | var two = new Set(['c', 'b', 'a', 'a']); 27 | expect(equalsSet(one, two)).toBe(true); 28 | expect(equalsSet(two, one)).toBe(true); 29 | }); 30 | 31 | it('returns true for sets that are equal with object values', () => { 32 | var foo = {}; 33 | var bar = {bar: 'bar'}; 34 | var one = new Set([foo, bar]); 35 | var two = new Set([bar, foo]); 36 | expect(equalsSet(one, two)).toBe(true); 37 | expect(equalsSet(two, one)).toBe(true); 38 | }); 39 | 40 | it('returns false for sets that have different lengths', () => { 41 | var one = new Set(['a']); 42 | var two = new Set(['a', 'b']); 43 | expect(equalsSet(one, two)).toBe(false); 44 | expect(equalsSet(two, one)).toBe(false); 45 | }); 46 | 47 | it('returns false for single element sets with different values', () => { 48 | var foo = {}; 49 | var bar = {}; 50 | var one = new Set([foo]); 51 | var two = new Set([bar]); 52 | expect(equalsSet(one, two)).toBe(false); 53 | expect(equalsSet(two, one)).toBe(false); 54 | }); 55 | 56 | it('returns false for multi element sets with different values', () => { 57 | var one = new Set(['a', 'b']); 58 | var two = new Set(['b', 'c']); 59 | expect(equalsSet(one, two)).toBe(false); 60 | expect(equalsSet(two, one)).toBe(false); 61 | }); 62 | }); 63 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/__tests__/everyObject-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @emails oncall+jsinfra 8 | */ 9 | 10 | 'use strict'; 11 | 12 | jest.unmock('everyObject'); 13 | 14 | var everyObject = require('everyObject'); 15 | 16 | describe('everyObject', function() { 17 | var mockObject; 18 | var mockCallback; 19 | 20 | beforeEach(() => { 21 | mockObject = {foo: 1, bar: 2, baz: 3}; 22 | mockCallback = jest.fn(); 23 | }); 24 | 25 | it('handles null', () => { 26 | everyObject(null, mockCallback); 27 | 28 | expect(mockCallback).not.toBeCalled(); 29 | }); 30 | 31 | it('returns true if all properties pass the test', () => { 32 | mockCallback.mockImplementation(() => true); 33 | var result = everyObject(mockObject, mockCallback); 34 | 35 | expect(result).toBeTruthy(); 36 | expect(mockCallback.mock.calls).toEqual([ 37 | [1, 'foo', mockObject], 38 | [2, 'bar', mockObject], 39 | [3, 'baz', mockObject] 40 | ]); 41 | }); 42 | 43 | it('returns false if any of the properties fail the test', () => { 44 | mockCallback.mockImplementation(() => false); 45 | var result = everyObject(mockObject, mockCallback); 46 | 47 | expect(result).toBeFalsy(); 48 | expect(mockCallback).toBeCalled(); 49 | }); 50 | 51 | it('returns immediately upon finding a property that fails the test', () => { 52 | mockCallback.mockImplementation(() => false); 53 | var result = everyObject(mockObject, mockCallback); 54 | 55 | expect(result).toBeFalsy(); 56 | expect(mockCallback.mock.calls.length).toEqual(1); 57 | }); 58 | }); 59 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/__tests__/everySet-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @emails oncall+jsinfra 8 | */ 9 | 10 | 'use strict'; 11 | 12 | jest.unmock('everySet'); 13 | 14 | var everySet = require('everySet'); 15 | 16 | describe('everySet', () => { 17 | it('returns true for empty sets', () => { 18 | var one = new Set(); 19 | var test = () => false; 20 | expect(everySet(one, test)).toBe(true); 21 | }); 22 | 23 | it('returns true when everything passes', () => { 24 | var one = new Set(['a', 'b', 'c']); 25 | var test = (value) => true; 26 | expect(everySet(one, test)).toBe(true); 27 | }); 28 | 29 | it('returns false when not everything passes', () => { 30 | var one = new Set(['a', 'b', 'c']); 31 | var test = (value) => value === 'a'; 32 | expect(everySet(one, test)).toBe(false); 33 | }); 34 | 35 | it('respects thisArg', () => { 36 | var one = new Set(['a', 'b', 'c']); 37 | var testSet = new Set(['a', 'b', 'c']); 38 | expect(() => everySet(one, testSet.has)).toThrow(); 39 | expect(everySet(one, testSet.has, testSet)).toBe(true); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/__tests__/filterObject-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @emails oncall+jsinfra 8 | */ 9 | 10 | 'use strict'; 11 | 12 | jest.unmock('filterObject'); 13 | 14 | var filterObject = require('filterObject'); 15 | 16 | describe('filterObject', () => { 17 | var mockObject; 18 | var mockCallback; 19 | 20 | beforeEach(() => { 21 | mockObject = { 22 | foo: 1, 23 | bar: 2, 24 | baz: 3 25 | }; 26 | mockCallback = jest.fn(); 27 | }); 28 | 29 | it('should accept null', () => { 30 | expect(filterObject(null, mockCallback)).toBeNull(); 31 | expect(mockCallback).not.toBeCalled(); 32 | }); 33 | 34 | it('should return true to create copy', () => { 35 | var filtered = filterObject(mockObject, mockCallback.mockImplementation( 36 | () => true 37 | )); 38 | 39 | expect(filtered).not.toBe(mockObject); 40 | expect(filtered).toEqual(mockObject); 41 | }); 42 | 43 | it('should return empty object for a falsey func', () => { 44 | var filtered = filterObject(mockObject, mockCallback.mockImplementation( 45 | () => false 46 | )); 47 | 48 | expect(filtered).toEqual({}); 49 | }); 50 | 51 | it('should filter based on value', () => { 52 | var filtered = filterObject(mockObject, mockCallback.mockImplementation( 53 | value => value > 1 54 | )); 55 | 56 | expect(filtered).toEqual({ 57 | bar: 2, 58 | baz: 3 59 | }); 60 | }); 61 | 62 | it('should filter based on key', () => { 63 | var filtered = filterObject(mockObject, mockCallback.mockImplementation( 64 | (value, key) => key[0] === 'b' 65 | )); 66 | 67 | expect(filtered).toEqual({ 68 | bar: 2, 69 | baz: 3 70 | }); 71 | }); 72 | }); 73 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/__tests__/flatMapArray-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @emails oncall+ui_infra@xmail.facebook.com 8 | */ 9 | 10 | jest 11 | .unmock('flatMapArray'); 12 | 13 | var flatMapArray = require('flatMapArray'); 14 | 15 | describe('flatMapArray', () => { 16 | 17 | it('flattens an array of arrays', () => { 18 | expect( 19 | flatMapArray([1, 2, 3], x => [x, x + 1]) 20 | ).toEqual([1, 2, 2, 3, 3, 4]); 21 | }); 22 | 23 | it('ignores null and undefined', () => { 24 | expect( 25 | flatMapArray([null, undefined, [1], [2]], x => x) 26 | ).toEqual([1, 2]); 27 | }); 28 | 29 | it('throws for scalar return values', () => { 30 | [false, true, 'b', 2].forEach(value => 31 | expect(() => flatMapArray([value], x => x)).toThrow( 32 | new TypeError( 33 | 'flatMapArray: Callback must return an array or null, ' + 34 | 'received "' + value + '" instead' 35 | ) 36 | ) 37 | ); 38 | }); 39 | 40 | }); 41 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/__tests__/groupArray-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @emails oncall+jsinfra 8 | */ 9 | 10 | jest.unmock('groupArray'); 11 | 12 | var groupArray = require('groupArray'); 13 | 14 | describe('groupArray', () => { 15 | it('should handle empty arrays', () => { 16 | var result = groupArray([], item => 'lol'); 17 | expect(Object.keys(result).length).toBe(0); 18 | }); 19 | 20 | it('should handle every item being in one group', () => { 21 | var items = ['hello', 'world', 'foo', 'bar']; 22 | var groupFn = item => 'lol'; 23 | 24 | var result = groupArray(items, groupFn); 25 | 26 | expect(Object.keys(result).length).toBe(1); 27 | expect(result.lol).toEqual(items); 28 | }); 29 | 30 | it('should handle every item being in a different group', () => { 31 | var items = ['hello', 'world', 'foo', 'bar']; 32 | var groupFn = item => 'group_' + item; 33 | 34 | var result = groupArray(items, groupFn); 35 | 36 | expect(Object.keys(result).length).toBe(items.length); 37 | expect(result.group_hello).toEqual(['hello']); 38 | expect(result.group_world).toEqual(['world']); 39 | expect(result.group_foo).toEqual(['foo']); 40 | expect(result.group_bar).toEqual(['bar']); 41 | }); 42 | 43 | it('should handle two items in the same group', () => { 44 | var items = ['hello', 'world', 'test']; 45 | var groupFn = item => item.length; 46 | 47 | var result = groupArray(items, groupFn); 48 | 49 | expect(Object.keys(result).length).toBe(2); 50 | expect(result[5]).toEqual(['hello', 'world']); 51 | expect(result[4]).toEqual(['test']); 52 | }); 53 | }); 54 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/__tests__/mapObject-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @emails oncall+jsinfra 8 | */ 9 | 10 | 'use strict'; 11 | 12 | jest.unmock('mapObject'); 13 | 14 | var mapObject = require('mapObject'); 15 | 16 | describe('mapObject', () => { 17 | var mockObject; 18 | var mockCallback; 19 | 20 | beforeEach(() => { 21 | mockObject = { 22 | foo: 1, 23 | bar: 2, 24 | baz: 3 25 | }; 26 | mockCallback = jest.fn(); 27 | }); 28 | 29 | it('should accept null', () => { 30 | expect(mapObject(null, mockCallback)).toBeNull(); 31 | expect(mockCallback).not.toBeCalled(); 32 | }); 33 | 34 | it('should return value to create copy', () => { 35 | var mapped = mapObject(mockObject, mockCallback.mockImplementation( 36 | value => value 37 | )); 38 | 39 | expect(mapped).not.toBe(mockObject); 40 | expect(mapped).toEqual(mockObject); 41 | }); 42 | 43 | it('should always retain keys', () => { 44 | var mapped = mapObject(mockObject, mockCallback.mockImplementation( 45 | () => null 46 | )); 47 | 48 | expect(mapped).toEqual({ 49 | foo: null, 50 | bar: null, 51 | baz: null 52 | }); 53 | }); 54 | 55 | it('should map values', () => { 56 | var mapped = mapObject(mockObject, mockCallback.mockImplementation( 57 | value => value * value 58 | )); 59 | 60 | expect(mapped).toEqual({ 61 | foo: 1, 62 | bar: 4, 63 | baz: 9 64 | }); 65 | }); 66 | 67 | it('should map keys', () => { 68 | var mapped = mapObject(mockObject, mockCallback.mockImplementation( 69 | (value, key) => key 70 | )); 71 | 72 | expect(mapped).toEqual({ 73 | foo: 'foo', 74 | bar: 'bar', 75 | baz: 'baz' 76 | }); 77 | }); 78 | }); 79 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/__tests__/maxBy-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * @emails oncall+ui_infra 7 | */ 8 | 9 | 'use strict'; 10 | 11 | jest 12 | .unmock('maxBy') 13 | .unmock('minBy'); 14 | 15 | var maxBy = require('maxBy'); 16 | 17 | describe('maxBy', () => 18 | it('returns the correct result', () => { 19 | expect( 20 | maxBy([3, 1, 4, 2], x => x) 21 | ).toBe(4); 22 | 23 | expect( 24 | maxBy([3, -1, 4, -2], x => x) 25 | ).toBe(4); 26 | 27 | expect( 28 | maxBy(['four', 'score', 'and', 'seven', 'years', 'ago'], x => x.length) 29 | ).toBe('score'); 30 | 31 | expect( 32 | maxBy([3, 1, 4, 2], x => x, (a, b) => -(a - b)) 33 | ).toBe(1); 34 | 35 | expect( 36 | maxBy([3, 1, 4, 2], x => x, () => 0) 37 | ).toBe(3); 38 | 39 | expect( 40 | maxBy([3, 1, 4, 2], x => undefined, () => 0) 41 | ).toBe(3); 42 | 43 | expect( 44 | maxBy([], x => x) 45 | ).toBe(undefined); 46 | 47 | expect( 48 | maxBy(['3', '1', 4, '2', 3, 1, '4', 2], x => +x) 49 | ).toBe(4); 50 | }) 51 | ); 52 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/__tests__/minBy-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * @emails oncall+ui_infra 7 | */ 8 | 9 | 'use strict'; 10 | 11 | jest.unmock('minBy'); 12 | 13 | var minBy = require('minBy'); 14 | 15 | describe('minBy', () => 16 | it('returns the correct result', () => { 17 | expect( 18 | minBy([3, 1, 4, 2], x => x) 19 | ).toBe(1); 20 | 21 | expect( 22 | minBy([3, -1, 4, -2], x => x) 23 | ).toBe(-2); 24 | 25 | expect( 26 | minBy(['four', 'score', 'and', 'seven', 'years', 'ago'], x => x.length) 27 | ).toBe('and'); 28 | 29 | expect( 30 | minBy([3, 1, 4, 2], x => x, (a, b) => -(a - b)) 31 | ).toBe(4); 32 | 33 | expect( 34 | minBy([3, 1, 4, 2], x => x, () => 0) 35 | ).toBe(3); 36 | 37 | expect( 38 | minBy([3, 1, 4, 2], x => undefined, () => 0) 39 | ).toBe(3); 40 | 41 | expect( 42 | minBy([], x => x) 43 | ).toBe(undefined); 44 | 45 | expect( 46 | minBy(['3', '1', 4, '2', 3, 1, '4', 2], x => +x) 47 | ).toBe('1'); 48 | }) 49 | ); 50 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/__tests__/partitionArray-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @emails oncall+ui_infra@xmail.facebook.com 8 | */ 9 | 10 | jest 11 | .unmock('partitionArray'); 12 | 13 | var partitionArray = require('partitionArray'); 14 | 15 | describe('partitionArray', () => { 16 | 17 | it('partitions an array based on a fn', () => { 18 | expect( 19 | partitionArray( 20 | [1, 2, 3, 4, 5, 6, 7, 8, 9], 21 | x => x > 5 22 | ) 23 | ).toEqual( 24 | [[6, 7, 8, 9], [1, 2, 3, 4, 5]] 25 | ); 26 | }); 27 | 28 | it('keeps the original order of items', () => { 29 | expect( 30 | partitionArray( 31 | [9, 7, 3, 1, 2, 4, 8, 5, 6], 32 | x => x < 5 33 | ) 34 | ).toEqual( 35 | [[3, 1, 2, 4], [9, 7, 8, 5, 6]] 36 | ); 37 | }); 38 | 39 | }); 40 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/__tests__/partitionObject-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-present Facebook. All Rights Reserved. 3 | * 4 | * @emails oncall+jsinfra 5 | */ 6 | 7 | jest 8 | .unmock('partitionObject'); 9 | 10 | var partitionObject = require('partitionObject'); 11 | 12 | describe('partitionObject', function() { 13 | 14 | it('should partition based on predicate', function() { 15 | var baseObject = {a: 42, b: 189, c: 67, d: 101}; 16 | expect(partitionObject(baseObject, x => x > 100)) 17 | .toEqual([{b: 189, d: 101}, {a: 42, c: 67}]); 18 | expect(partitionObject(baseObject, _ => false)) 19 | .toEqual([{}, baseObject]); 20 | expect(partitionObject(baseObject, _ => true)) 21 | .toEqual([baseObject, {}]); 22 | }); 23 | 24 | }); 25 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/__tests__/partitionObjectByKey-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-present Facebook. All Rights Reserved. 3 | * 4 | * @emails oncall+jsinfra 5 | */ 6 | 7 | jest 8 | .unmock('partitionObject') 9 | .unmock('partitionObjectByKey'); 10 | 11 | var partitionObjectByKey = require('partitionObjectByKey'); 12 | 13 | describe('partitionObjectByKey', function() { 14 | 15 | it('should partition some properties of an object', function() { 16 | var baseObject = {a: 'A', b: 'B', c: 'C'}; 17 | expect(partitionObjectByKey(baseObject, new Set(['a']))) 18 | .toEqual([{a: 'A'}, {b: 'B', c: 'C'}]); 19 | expect(partitionObjectByKey(baseObject, new Set(['a', 'b']))) 20 | .toEqual([{a: 'A', b: 'B'}, {c: 'C'}]); 21 | expect(partitionObjectByKey(baseObject, new Set())) 22 | .toEqual([{}, baseObject]); 23 | }); 24 | 25 | it('should ignore keys that do not exist in the source object', function() { 26 | var baseObject = {a: 'A', b: 'B', c: 'C'}; 27 | expect(partitionObjectByKey(baseObject, new Set(['a', 'd']))) 28 | .toEqual([{a: 'A'}, {b: 'B', c: 'C'}]); 29 | }); 30 | 31 | }); 32 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/__tests__/someObject-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @emails oncall+jsinfra 8 | */ 9 | 10 | 'use strict'; 11 | 12 | jest.unmock('someObject'); 13 | 14 | var someObject = require('someObject'); 15 | 16 | describe('someObject', function() { 17 | var mockObject; 18 | var mockCallback; 19 | 20 | beforeEach(() => { 21 | mockObject = {foo: 1, bar: 2, baz: 3}; 22 | mockCallback = jest.fn(); 23 | }); 24 | 25 | it('handles null', () => { 26 | someObject(null, mockCallback); 27 | 28 | expect(mockCallback).not.toBeCalled(); 29 | }); 30 | 31 | it('returns false if none of properties pass the test', () => { 32 | mockCallback.mockImplementation(() => false); 33 | var result = someObject(mockObject, mockCallback); 34 | 35 | expect(result).toBeFalsy(); 36 | expect(mockCallback.mock.calls).toEqual([ 37 | [1, 'foo', mockObject], 38 | [2, 'bar', mockObject], 39 | [3, 'baz', mockObject] 40 | ]); 41 | }); 42 | 43 | it('returns true if any of the properties passes the test', () => { 44 | mockCallback.mockImplementation(() => true); 45 | var result = someObject(mockObject, mockCallback); 46 | 47 | expect(result).toBeTruthy(); 48 | expect(mockCallback).toBeCalled(); 49 | }); 50 | 51 | it('returns immediately upon finding a property that passes the test', () => { 52 | mockCallback.mockImplementation(() => true); 53 | var result = someObject(mockObject, mockCallback); 54 | 55 | expect(result).toBeTruthy(); 56 | expect(mockCallback.mock.calls.length).toEqual(1); 57 | }); 58 | }); 59 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/__tests__/someSet-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @emails oncall+jsinfra 8 | */ 9 | 10 | 'use strict'; 11 | 12 | jest.unmock('someSet'); 13 | 14 | var someSet = require('someSet'); 15 | 16 | describe('someSet', () => { 17 | it('returns false for empty sets', () => { 18 | var one = new Set(); 19 | var test = () => true; 20 | expect(someSet(one, test)).toBe(false); 21 | }); 22 | 23 | it('returns true when everything passes', () => { 24 | var one = new Set(['a', 'b', 'c']); 25 | var test = (value) => true; 26 | expect(someSet(one, test)).toBe(true); 27 | }); 28 | 29 | it('returns true when one thing passes', () => { 30 | var one = new Set(['a', 'b', 'c']); 31 | var test = (value) => value === 'a'; 32 | expect(someSet(one, test)).toBe(true); 33 | }); 34 | 35 | it('returns false when nothing passes', () => { 36 | var one = new Set(['a', 'b', 'c']); 37 | var test = (value) => value === 'd'; 38 | expect(someSet(one, test)).toBe(false); 39 | }); 40 | 41 | it('respects thisArg', () => { 42 | var one = new Set(['a', 'b', 'c']); 43 | var testSet = new Set(['b']); 44 | expect(() => someSet(one, testSet.has)).toThrow(); 45 | expect(someSet(one, testSet.has, testSet)).toBe(true); 46 | }); 47 | }); 48 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/compactArray.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-present Facebook. All Rights Reserved. 3 | * 4 | * @providesModule compactArray 5 | * @typechecks 6 | * @flow 7 | */ 8 | 9 | 'use strict'; 10 | 11 | /** 12 | * Returns a new Array containing all the element of the source array except 13 | * `null` and `undefined` ones. This brings the benefit of strong typing over 14 | * `Array.prototype.filter`. 15 | */ 16 | function compactArray( 17 | array: Array 18 | ): Array { 19 | var result = []; 20 | for (var i = 0; i < array.length; ++i) { 21 | var elem = array[i]; 22 | if (elem != null) { 23 | result.push(elem); 24 | } 25 | } 26 | return result; 27 | } 28 | 29 | module.exports = compactArray; 30 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/concatAllArray.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule concatAllArray 8 | * @typechecks 9 | */ 10 | 11 | var push = Array.prototype.push; 12 | 13 | /** 14 | * Concats an array of arrays into a single flat array. 15 | * 16 | * @param {array} array 17 | * @return {array} 18 | */ 19 | function concatAllArray(array) { 20 | var ret = []; 21 | for (var ii = 0; ii < array.length; ii++) { 22 | var value = array[ii]; 23 | if (Array.isArray(value)) { 24 | push.apply(ret, value); 25 | } else if (value != null) { 26 | throw new TypeError( 27 | 'concatAllArray: All items in the array must be an array or null, ' + 28 | 'got "' + value + '" at index "' + ii + '" instead' 29 | ); 30 | } 31 | } 32 | return ret; 33 | } 34 | 35 | module.exports = concatAllArray; 36 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/countDistinct.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule countDistinct 8 | * @flow 9 | */ 10 | 11 | 'use strict'; 12 | 13 | var emptyFunction = require('emptyFunction'); 14 | 15 | /** 16 | * Returns the count of distinct elements selected from an array. 17 | */ 18 | function countDistinct( 19 | iter: Iterable, 20 | selector: (item: T1) => T2, 21 | ): number { 22 | selector = selector || emptyFunction.thatReturnsArgument; 23 | 24 | var set = new Set(); 25 | for (var val of iter) { 26 | set.add(selector(val)); 27 | } 28 | 29 | return set.size; 30 | } 31 | 32 | module.exports = countDistinct; 33 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/distinctArray.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule distinctArray 8 | * @flow 9 | */ 10 | 11 | /** 12 | * Returns the distinct elements of an iterable. The result is an array whose 13 | * elements are ordered by first occurrence. 14 | */ 15 | function distinctArray(xs: Iterable): Array { 16 | return Array.from(new Set(xs).values()); 17 | } 18 | 19 | module.exports = distinctArray; 20 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/equalsIterable.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule equalsIterable 8 | * @flow 9 | */ 10 | 11 | 'use strict'; 12 | 13 | const enumerate = require('enumerate'); 14 | 15 | /** 16 | * Checks if two iterables are equal. A custom areEqual function may be provided 17 | * as an optional third argument. 18 | */ 19 | function equalsIterable( 20 | one: Iterable, 21 | two: Iterable, 22 | areEqual?: ?(one: T, two: T) => boolean, 23 | ): boolean { 24 | if (one === two) { 25 | return true; 26 | } 27 | 28 | // We might be able to short circuit by using the size or length fields. 29 | var oneSize = maybeGetSize(one); 30 | var twoSize = maybeGetSize(two); 31 | if (oneSize != null && twoSize != null && oneSize !== twoSize) { 32 | return false; 33 | } 34 | 35 | // Otherwise use the iterators to check equality. Here we cannot use for-of 36 | // because we need to advance the iterators at the same time. 37 | var oneIterator = enumerate(one); 38 | var oneItem = oneIterator.next(); 39 | var twoIterator = enumerate(two); 40 | var twoItem = twoIterator.next(); 41 | var safeAreEqual = areEqual || referenceEquality; 42 | while (!(oneItem.done || twoItem.done)) { 43 | if (!safeAreEqual(oneItem.value, twoItem.value)) { 44 | return false; 45 | } 46 | oneItem = oneIterator.next(); 47 | twoItem = twoIterator.next(); 48 | } 49 | return oneItem.done === twoItem.done; 50 | } 51 | 52 | function maybeGetSize(o: any): ?number { 53 | if (o == null) { 54 | return null; 55 | } 56 | if (typeof o.size === 'number') { 57 | return o.size; 58 | } 59 | if (typeof o.length === 'number') { 60 | return o.length; 61 | } 62 | return null; 63 | } 64 | 65 | function referenceEquality(one: T, two: T): boolean { 66 | return one === two; 67 | } 68 | 69 | module.exports = equalsIterable; 70 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/equalsSet.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule equalsSet 8 | * @flow 9 | * @typechecks 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var everySet = require('everySet'); 15 | 16 | /** 17 | * Checks if two sets are equal 18 | */ 19 | function equalsSet(one: Set, two: Set): boolean { 20 | if (one.size !== two.size) { 21 | return false; 22 | } 23 | return everySet(one, value => two.has(value)); 24 | } 25 | 26 | module.exports = equalsSet; 27 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/everyObject.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule everyObject 8 | * @flow 9 | * @typechecks 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var hasOwnProperty = Object.prototype.hasOwnProperty; 15 | 16 | /** 17 | * Executes the provided `callback` once for each enumerable own property in the 18 | * object until it finds one where callback returns a falsy value. If such a 19 | * property is found, `everyObject` immediately returns false. Otherwise, it 20 | * returns true. 21 | * 22 | * The `callback` is invoked with three arguments: 23 | * 24 | * - the property value 25 | * - the property name 26 | * - the object being traversed 27 | * 28 | * Properties that are added after the call to `everyObject` will not be 29 | * visited by `callback`. If the values of existing properties are changed, the 30 | * value passed to `callback` will be the value at the time `everyObject` 31 | * visits them. Properties that are deleted before being visited are not 32 | * visited. 33 | */ 34 | function everyObject( 35 | object: ?Object, 36 | callback: (value: any, name: string, object: Object) => any, 37 | context?: any, 38 | ): boolean { 39 | for (var name in object) { 40 | if (hasOwnProperty.call(object, name)) { 41 | if (!callback.call(context, object[name], name, object)) { 42 | return false; 43 | } 44 | } 45 | } 46 | return true; 47 | } 48 | 49 | module.exports = everyObject; 50 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/everySet.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule everySet 8 | * @flow 9 | * @typechecks 10 | */ 11 | 12 | 'use strict'; 13 | 14 | /** 15 | * The everySet() method tests whether all elements in the given Set pass the 16 | * test implemented by the provided function. 17 | */ 18 | function everySet( 19 | set: Set, 20 | callback: (value: T, key: T, set: Set) => boolean, 21 | context?: any 22 | ): boolean { 23 | var iterator = set.entries(); 24 | var current = iterator.next(); 25 | while (!current.done) { 26 | var entry = current.value; 27 | if (!callback.call(context, entry[1], entry[0], set)) { 28 | return false; 29 | } 30 | current = iterator.next(); 31 | } 32 | return true; 33 | } 34 | 35 | module.exports = everySet; 36 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/filterObject.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule filterObject 8 | */ 9 | 10 | 'use strict'; 11 | 12 | var hasOwnProperty = Object.prototype.hasOwnProperty; 13 | 14 | /** 15 | * Executes the provided `callback` once for each enumerable own property in the 16 | * object and constructs a new object of all the values for which `callback` 17 | * returns a true value. The `callback` is invoked with three arguments: 18 | * 19 | * - the property value 20 | * - the property name 21 | * - the object being traversed 22 | * 23 | * Properties that are added after the call to `filterObject` will not be 24 | * visited by `callback`. If the values of existing properties are changed, the 25 | * value passed to `callback` will be the value at the time `filterObject` 26 | * visits them. Properties that are deleted before being visited are not 27 | * visited. 28 | * 29 | * @grep function objectFilter() 30 | * @grep function objFilter() 31 | * 32 | * @param {?object} object 33 | * @param {function} callback 34 | * @param {*} context 35 | * @return {?object} 36 | */ 37 | function filterObject(object, callback, context) { 38 | if (!object) { 39 | return null; 40 | } 41 | var result = {}; 42 | for (var name in object) { 43 | if (hasOwnProperty.call(object, name) && 44 | callback.call(context, object[name], name, object)) { 45 | result[name] = object[name]; 46 | } 47 | } 48 | return result; 49 | } 50 | 51 | module.exports = filterObject; 52 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/flatMapArray.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule flatMapArray 8 | * @flow 9 | * @typechecks 10 | */ 11 | 12 | var push = Array.prototype.push; 13 | 14 | /** 15 | * Applies a function to every item in an array and concatenates the resulting 16 | * arrays into a single flat array. 17 | * 18 | * @param {array} array 19 | * @param {function} fn 20 | * @return {array} 21 | */ 22 | function flatMapArray( 23 | array: Array, 24 | fn: (value: TValue, index: number) => Array, 25 | ): Array { 26 | var ret = []; 27 | for (var ii = 0; ii < array.length; ii++) { 28 | var result = fn.call(array, array[ii], ii); 29 | if (Array.isArray(result)) { 30 | push.apply(ret, result); 31 | } else if (result != null) { 32 | throw new TypeError( 33 | 'flatMapArray: Callback must return an array or null, ' + 34 | 'received "' + result + '" instead' 35 | ); 36 | } 37 | } 38 | return ret; 39 | } 40 | 41 | module.exports = flatMapArray; 42 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/forEachObject.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule forEachObject 8 | * @typechecks 9 | */ 10 | 11 | 'use strict'; 12 | 13 | var hasOwnProperty = Object.prototype.hasOwnProperty; 14 | 15 | /** 16 | * Executes the provided `callback` once for each enumerable own property in the 17 | * object. The `callback` is invoked with three arguments: 18 | * 19 | * - the property value 20 | * - the property name 21 | * - the object being traversed 22 | * 23 | * Properties that are added after the call to `forEachObject` will not be 24 | * visited by `callback`. If the values of existing properties are changed, the 25 | * value passed to `callback` will be the value at the time `forEachObject` 26 | * visits them. Properties that are deleted before being visited are not 27 | * visited. 28 | * 29 | * @param {?object} object 30 | * @param {function} callback 31 | * @param {*} context 32 | */ 33 | function forEachObject(object, callback, context) { 34 | for (var name in object) { 35 | if (hasOwnProperty.call(object, name)) { 36 | callback.call(context, object[name], name, object); 37 | } 38 | } 39 | } 40 | 41 | module.exports = forEachObject; 42 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/groupArray.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule groupArray 8 | * @typechecks 9 | */ 10 | 11 | 'use strict'; 12 | 13 | /** 14 | * Groups all items in the array using the specified function. An object will 15 | * be returned where the keys are the group names, and the values are arrays of 16 | * all the items in that group. 17 | * 18 | * @param {array} array 19 | * @param {function} fn Should return a string with a group name 20 | * @return {object} items grouped using fn 21 | */ 22 | function groupArray(array, fn) { 23 | var ret = {}; 24 | for (var ii = 0; ii < array.length; ii++) { 25 | var result = fn.call(array, array[ii], ii); 26 | if (!ret[result]) { 27 | ret[result] = []; 28 | } 29 | ret[result].push(array[ii]); 30 | } 31 | return ret; 32 | } 33 | 34 | module.exports = groupArray; 35 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/mapObject.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule mapObject 8 | */ 9 | 10 | 'use strict'; 11 | 12 | var hasOwnProperty = Object.prototype.hasOwnProperty; 13 | 14 | /** 15 | * Executes the provided `callback` once for each enumerable own property in the 16 | * object and constructs a new object from the results. The `callback` is 17 | * invoked with three arguments: 18 | * 19 | * - the property value 20 | * - the property name 21 | * - the object being traversed 22 | * 23 | * Properties that are added after the call to `mapObject` will not be visited 24 | * by `callback`. If the values of existing properties are changed, the value 25 | * passed to `callback` will be the value at the time `mapObject` visits them. 26 | * Properties that are deleted before being visited are not visited. 27 | * 28 | * @grep function objectMap() 29 | * @grep function objMap() 30 | * 31 | * @param {?object} object 32 | * @param {function} callback 33 | * @param {*} context 34 | * @return {?object} 35 | */ 36 | function mapObject(object, callback, context) { 37 | if (!object) { 38 | return null; 39 | } 40 | var result = {}; 41 | for (var name in object) { 42 | if (hasOwnProperty.call(object, name)) { 43 | result[name] = callback.call(context, object[name], name, object); 44 | } 45 | } 46 | return result; 47 | } 48 | 49 | module.exports = mapObject; 50 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/maxBy.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule maxBy 8 | * @flow 9 | */ 10 | 11 | var minBy = require('minBy'); 12 | 13 | var compareNumber = (a, b) => a - b; 14 | 15 | /** 16 | * Returns the maximum element as measured by a scoring function f. Returns the 17 | * first such element if there are ties. 18 | */ 19 | function maxBy( 20 | as: Iterable, 21 | f: (a: A) => B, 22 | compare?: ?((u: B, v: B) => number), 23 | ): ?A { 24 | compare = compare || (compareNumber: any); 25 | 26 | return minBy(as, f, (u, v) => (compare: any)(v, u)); 27 | } 28 | 29 | module.exports = maxBy; 30 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/minBy.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule minBy 8 | * @flow 9 | */ 10 | 11 | var compareNumber = (a, b) => a - b; 12 | 13 | /** 14 | * Returns the minimum element as measured by a scoring function f. Returns the 15 | * first such element if there are ties. 16 | */ 17 | function minBy( 18 | as: Iterable, 19 | f: (a: A) => B, 20 | compare?: ?((u: B, v: B) => number), 21 | ): ?A { 22 | compare = compare || (compareNumber: any); 23 | 24 | var minA = undefined; 25 | var minB = undefined; 26 | var seenFirst = false; 27 | for (var a of as) { 28 | var b = f(a); 29 | if (!seenFirst || compare(b, (minB: any)) < 0) { 30 | minA = a; 31 | minB = b; 32 | seenFirst = true; 33 | } 34 | } 35 | 36 | return minA; 37 | } 38 | 39 | module.exports = minBy; 40 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/partitionArray.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule partitionArray 8 | * @typechecks 9 | * @flow 10 | */ 11 | 12 | /** 13 | * Partitions an array given a predicate. All elements satisfying the predicate 14 | * are part of the first returned array, and all elements that don't are in the 15 | * second. 16 | */ 17 | function partitionArray( 18 | array: Array, 19 | predicate: (value: Tv, index: number, array: Array) => boolean, 20 | context?: any 21 | ): [Array, Array] { 22 | var first = []; 23 | var second = []; 24 | array.forEach((element, index) => { 25 | if (predicate.call(context, element, index, array)) { 26 | first.push(element); 27 | } else { 28 | second.push(element); 29 | } 30 | }); 31 | return [first, second]; 32 | } 33 | 34 | module.exports = partitionArray; 35 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/partitionObject.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-present Facebook. All Rights Reserved. 3 | * 4 | * @providesModule partitionObject 5 | * @typechecks 6 | * @flow 7 | */ 8 | 9 | 'use strict'; 10 | 11 | var forEachObject = require('forEachObject'); 12 | 13 | /** 14 | * Partitions an object given a predicate. All elements satisfying the predicate 15 | * are part of the first returned object, and all elements that don't are in the 16 | * second. 17 | */ 18 | function partitionObject( 19 | object: {[key: string]: Tv}, 20 | callback: (value: Tv, key: string, object: {[key: string]: Tv}) => boolean, 21 | context?: any 22 | ): [{[key: string]: Tv}, {[key: string]: Tv}] { 23 | var first = {}; 24 | var second = {}; 25 | forEachObject(object, (value, key) => { 26 | if (callback.call(context, value, key, object)) { 27 | first[key] = value; 28 | } else { 29 | second[key] = value; 30 | } 31 | }); 32 | return [first, second]; 33 | } 34 | 35 | module.exports = partitionObject; 36 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/partitionObjectByKey.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015-present Facebook. All Rights Reserved. 3 | * 4 | * @providesModule partitionObjectByKey 5 | * @typechecks 6 | * @flow 7 | */ 8 | 9 | 'use strict'; 10 | 11 | var partitionObject = require('partitionObject'); 12 | 13 | /** 14 | * Partitions the enumerable properties of an object into two objects, given a 15 | * whitelist `Set` for the first object. This is comparable to 16 | * `whitelistObjectKeys`, but eventually keeping all the keys. Returns a tuple 17 | * of objects `[first, second]`. 18 | */ 19 | function partitionObjectByKey( 20 | source: Object, 21 | whitelist: Set 22 | ): [Object, Object] { 23 | return partitionObject(source, (_, key) => whitelist.has(key)); 24 | } 25 | 26 | module.exports = partitionObjectByKey; 27 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/someObject.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule someObject 8 | * @flow 9 | * @typechecks 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var hasOwnProperty = Object.prototype.hasOwnProperty; 15 | 16 | /** 17 | * Executes the provided `callback` once for each enumerable own property in the 18 | * object until it finds one where callback returns a truthy value. If such a 19 | * property is found, `someObject` immediately returns true. Otherwise, it 20 | * returns false. 21 | * 22 | * The `callback` is invoked with three arguments: 23 | * 24 | * - the property value 25 | * - the property name 26 | * - the object being traversed 27 | * 28 | * Properties that are added after the call to `someObject` will not be 29 | * visited by `callback`. If the values of existing properties are changed, the 30 | * value passed to `callback` will be the value at the time `someObject` 31 | * visits them. Properties that are deleted before being visited are not 32 | * visited. 33 | */ 34 | function someObject( 35 | object: ?Object, 36 | callback: (value: any, name: string, object: Object) => any, 37 | context?: any, 38 | ): boolean { 39 | for (var name in object) { 40 | if (hasOwnProperty.call(object, name)) { 41 | if (callback.call(context, object[name], name, object)) { 42 | return true; 43 | } 44 | } 45 | } 46 | return false; 47 | } 48 | 49 | module.exports = someObject; 50 | -------------------------------------------------------------------------------- /packages/fbjs/src/functional/someSet.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule someSet 8 | * @flow 9 | * @typechecks 10 | */ 11 | 12 | 'use strict'; 13 | 14 | /** 15 | * The someSet() method tests whether some elements in the given Set pass the 16 | * test implemented by the provided function. 17 | */ 18 | function someSet( 19 | set: Set, 20 | callback: (value: T, key: T, set: Set) => boolean, 21 | context?: any 22 | ): boolean { 23 | var iterator = set.entries(); 24 | var current = iterator.next(); 25 | while (!current.done) { 26 | var entry = current.value; 27 | if (callback.call(context, entry[1], entry[0], set)) { 28 | return true; 29 | } 30 | current = iterator.next(); 31 | } 32 | return false; 33 | } 34 | 35 | module.exports = someSet; 36 | -------------------------------------------------------------------------------- /packages/fbjs/src/intl/Locale.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule Locale 8 | */ 9 | 10 | const SiteData = require('SiteData'); 11 | const ExecutionEnvironment = require('ExecutionEnvironment'); 12 | 13 | function isRTL() { 14 | if (!ExecutionEnvironment.canUseDOM) { 15 | return false; 16 | } else { 17 | return SiteData.is_rtl; 18 | } 19 | } 20 | 21 | var Locale = { 22 | isRTL: isRTL, 23 | }; 24 | 25 | module.exports = Locale; 26 | -------------------------------------------------------------------------------- /packages/fbjs/src/key-mirror/__tests__/keyMirror-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @emails react-core 8 | */ 9 | 10 | 'use strict'; 11 | 12 | jest.unmock('keyMirror'); 13 | 14 | var keyMirror = require('keyMirror'); 15 | 16 | describe('keyMirror', function() { 17 | it('should create an object with values matching keys provided', function() { 18 | var mirror = keyMirror({ 19 | foo: null, 20 | bar: true, 21 | "baz": {some: "object"}, 22 | qux: undefined 23 | }); 24 | expect('foo' in mirror).toBe(true); 25 | expect(mirror.foo).toBe('foo'); 26 | expect('bar' in mirror).toBe(true); 27 | expect(mirror.bar).toBe('bar'); 28 | expect('baz' in mirror).toBe(true); 29 | expect(mirror.baz).toBe('baz'); 30 | expect('qux' in mirror).toBe(true); 31 | expect(mirror.qux).toBe('qux'); 32 | }); 33 | 34 | it('should not use properties from prototypes', function() { 35 | function Klass() { 36 | this.useMeToo = true; 37 | } 38 | Klass.prototype.doNotUse = true; 39 | var instance = new Klass(); 40 | instance.useMe = true; 41 | 42 | var mirror = keyMirror(instance); 43 | 44 | expect('doNotUse' in mirror).toBe(false); 45 | expect('useMe' in mirror).toBe(true); 46 | expect('useMeToo' in mirror).toBe(true); 47 | }); 48 | 49 | it('should throw when a non-object argument is used', function() { 50 | [null, undefined, 0, 7, ['uno'], true, "string"].forEach(function(testVal) { 51 | expect(keyMirror.bind(null, testVal)).toThrow(); 52 | }); 53 | }); 54 | 55 | it('should work when "constructor" is a key', function() { 56 | var obj = {constructor: true}; 57 | expect(keyMirror.bind(null, obj)).not.toThrow(); 58 | var mirror = keyMirror(obj); 59 | expect('constructor' in mirror).toBe(true); 60 | }); 61 | }); 62 | -------------------------------------------------------------------------------- /packages/fbjs/src/key-mirror/keyMirror.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule keyMirror 8 | * @typechecks static-only 9 | * @flow 10 | */ 11 | 12 | 'use strict'; 13 | 14 | var invariant = require('invariant'); 15 | 16 | /** 17 | * Constructs an enumeration with keys equal to their value. 18 | * 19 | * For example: 20 | * 21 | * var COLORS = keyMirror({blue: null, red: null}); 22 | * var myColor = COLORS.blue; 23 | * var isColorValid = !!COLORS[myColor]; 24 | * 25 | * The last line could not be performed if the values of the generated enum were 26 | * not equal to their keys. 27 | * 28 | * Input: {key1: val1, key2: val2} 29 | * Output: {key1: key1, key2: key2} 30 | * 31 | * @param {object} obj 32 | * @return {object} 33 | */ 34 | var keyMirror = function(obj: T): $ObjMapi(K) => K> { 35 | var ret = {}; 36 | var key; 37 | invariant( 38 | obj instanceof Object && !Array.isArray(obj), 39 | 'keyMirror(...): Argument must be an object.' 40 | ); 41 | for (key in obj) { 42 | if (!obj.hasOwnProperty(key)) { 43 | continue; 44 | } 45 | ret[key] = key; 46 | } 47 | return ret; 48 | }; 49 | 50 | module.exports = keyMirror; 51 | -------------------------------------------------------------------------------- /packages/fbjs/src/key-mirror/keyOf.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule keyOf 8 | */ 9 | 10 | /** 11 | * Allows extraction of a minified key. Let's the build system minify keys 12 | * without losing the ability to dynamically use key strings as values 13 | * themselves. Pass in an object with a single key/val pair and it will return 14 | * you the string key of that single record. Suppose you want to grab the 15 | * value for a key 'className' inside of an object. Key/val minification may 16 | * have aliased that key to be 'xa12'. keyOf({className: null}) will return 17 | * 'xa12' in that case. Resolve keys you want to use once at startup time, then 18 | * reuse those resolutions. 19 | */ 20 | var keyOf = function(oneKeyObj) { 21 | var key; 22 | for (key in oneKeyObj) { 23 | if (!oneKeyObj.hasOwnProperty(key)) { 24 | continue; 25 | } 26 | return key; 27 | } 28 | return null; 29 | }; 30 | 31 | 32 | module.exports = keyOf; 33 | -------------------------------------------------------------------------------- /packages/fbjs/src/misc/getByPath.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule getByPath 8 | * @flow 9 | * @typechecks 10 | */ 11 | 12 | 'use strict'; 13 | 14 | /** 15 | * Get a value from an object based on the given path 16 | * 17 | * Usage example: 18 | * 19 | * var obj = { 20 | * a : { 21 | * b : 123 22 | * } 23 | * }; 24 | * 25 | * var result = getByPath(obj, ['a', 'b']); // 123 26 | * 27 | * You may also specify the path using an object with a path field 28 | * 29 | * var result = getByPath(obj, {path: ['a', 'b']}); // 123 30 | * 31 | * If the path doesn't exist undefined will be returned 32 | * 33 | * var result = getByPath(obj, ['x', 'y', 'z']); // undefined 34 | */ 35 | function getByPath( 36 | root: any/*?Object | Error*/, 37 | path: Array, 38 | fallbackValue?: any 39 | ): any { 40 | let current = root; 41 | for (let i = 0; i < path.length; i++) { 42 | const segment = path[i]; 43 | // Use 'in' to check entire prototype chain since immutable js records 44 | // use prototypes 45 | if (current && segment in current) { 46 | current = current[segment]; 47 | } else { 48 | return fallbackValue; 49 | } 50 | } 51 | return current; 52 | } 53 | 54 | module.exports = getByPath; 55 | -------------------------------------------------------------------------------- /packages/fbjs/src/misc/isInternationalPhoneNumber.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule isInternationalPhoneNumber 8 | * 9 | * Simple client-side validation of international phone numbers 10 | */ 11 | 12 | 13 | const US_NUMBER_RE = /^1\(?\d{3}\)?\d{7}$/; 14 | const NORWAY_NUMBER_RE = /^47\d{8}$/; 15 | const INTL_NUMBER_RE = /^\d{1,4}\(?\d{2,3}\)?\d{4,}$/; 16 | 17 | function isInternationalPhoneNumber(number) { 18 | number = number 19 | .replace(/[\-\s]+/g, '') // strip all spaces and hyphens 20 | .replace(/^\+?0{0,2}/, ''); // strip up to 2 leading 0s and + 21 | 22 | if (number.startsWith('0')) { 23 | return false; 24 | } 25 | 26 | if (number.startsWith('1')) { 27 | return US_NUMBER_RE.test(number); 28 | } 29 | 30 | if (number.startsWith('47')) { 31 | return NORWAY_NUMBER_RE.test(number); 32 | } 33 | 34 | return INTL_NUMBER_RE.test(number); 35 | } 36 | 37 | module.exports = isInternationalPhoneNumber; 38 | -------------------------------------------------------------------------------- /packages/fbjs/src/performance/__tests__/performanceNow-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | */ 8 | 9 | const performance = require('performance'); 10 | 11 | beforeEach(() => { 12 | jest.resetModules(); 13 | }); 14 | 15 | test('should use performance.now if available', () => { 16 | const PERFORMANCE_NOW = 123; 17 | performance.now = jest.fn(() => PERFORMANCE_NOW); 18 | 19 | const performanceNow = require('../performanceNow'); 20 | 21 | expect(performanceNow()).toEqual(PERFORMANCE_NOW); 22 | expect(performance.now).toHaveBeenCalled(); 23 | }); 24 | 25 | test('should fallback to custom implementation if performance.now is not available', () => { 26 | const TIME_1 = 1000; 27 | const TIME_2 = 1100; 28 | 29 | Date.now = jest.fn().mockReturnValueOnce(TIME_1).mockReturnValueOnce(TIME_2); 30 | performance.now = null; 31 | 32 | const performanceNow = require('../performanceNow'); 33 | 34 | expect(Date.now).toHaveBeenCalledTimes(1); 35 | expect(performanceNow()).toEqual(TIME_2 - TIME_1); 36 | expect(Date.now).toHaveBeenCalledTimes(2); 37 | }); 38 | -------------------------------------------------------------------------------- /packages/fbjs/src/performance/performance.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule performance 8 | * @typechecks 9 | */ 10 | 11 | 'use strict'; 12 | 13 | var ExecutionEnvironment = require('ExecutionEnvironment'); 14 | 15 | var performance; 16 | 17 | if (ExecutionEnvironment.canUseDOM) { 18 | performance = 19 | window.performance || 20 | window.msPerformance || 21 | window.webkitPerformance; 22 | } 23 | 24 | module.exports = performance || {}; 25 | -------------------------------------------------------------------------------- /packages/fbjs/src/performance/performanceNow.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule performanceNow 8 | * @typechecks 9 | */ 10 | 11 | const performance = require('performance'); 12 | 13 | const loadTime = Date.now(); 14 | 15 | /** 16 | * Detect if we can use `window.performance.now()` and gracefully fallback to 17 | * `Date.now()` if it doesn't exist. We need to support Firefox < 15 for now 18 | * because of Facebook's testing infrastructure. 19 | */ 20 | module.exports = performance.now 21 | ? () => performance.now() 22 | : () => Date.now() - loadTime; 23 | -------------------------------------------------------------------------------- /packages/fbjs/src/request/xhrSimpleDataSerializer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule xhrSimpleDataSerializer 8 | */ 9 | 10 | function xhrSimpleDataSerializer(data) { 11 | var uri = []; 12 | var key; 13 | for (key in data) { 14 | uri.push(encodeURIComponent(key) + '=' + encodeURIComponent(data[key])); 15 | } 16 | return uri.join('&'); 17 | } 18 | 19 | module.exports = xhrSimpleDataSerializer; 20 | -------------------------------------------------------------------------------- /packages/fbjs/src/struct/CircularBuffer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule CircularBuffer 8 | */ 9 | 10 | var invariant = require('invariant'); 11 | 12 | class CircularBuffer { 13 | constructor(size) { 14 | invariant( 15 | size > 0, 16 | 'Buffer size should be a positive integer' 17 | ); 18 | this._size = size; 19 | this._head = 0; 20 | this._buffer = []; 21 | } 22 | 23 | write(entry) { 24 | if (this._buffer.length < this._size) { 25 | this._buffer.push(entry); 26 | } else { 27 | this._buffer[this._head] = entry; 28 | this._head++; 29 | this._head %= this._size; 30 | } 31 | return this; 32 | } 33 | 34 | read() { 35 | return this._buffer.slice(this._head).concat( 36 | this._buffer.slice(0, this._head) 37 | ); 38 | } 39 | 40 | clear() { 41 | this._head = 0; 42 | this._buffer = []; 43 | return this; 44 | } 45 | } 46 | 47 | module.exports = CircularBuffer; 48 | -------------------------------------------------------------------------------- /packages/fbjs/src/stubs/ErrorUtils.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule ErrorUtils 8 | */ 9 | 10 | /* jslint unused:false */ 11 | 12 | if (global.ErrorUtils) { 13 | module.exports = global.ErrorUtils; 14 | } else { 15 | var ErrorUtils = { 16 | applyWithGuard(callback, context, args, onError, name) { 17 | return callback.apply(context, args); 18 | }, 19 | guard(callback, name) { 20 | return callback; 21 | }, 22 | }; 23 | 24 | module.exports = ErrorUtils; 25 | } 26 | -------------------------------------------------------------------------------- /packages/fbjs/src/stubs/__mocks__/ErrorUtils.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | var ErrorUtils = jest.genMockFromModule('ErrorUtils'); 11 | 12 | ErrorUtils.applyWithGuard.mockImplementation( 13 | (callback, context, args) => callback.apply(context, args) 14 | ); 15 | 16 | ErrorUtils.guard.mockImplementation(callback => callback); 17 | 18 | module.exports = ErrorUtils; 19 | -------------------------------------------------------------------------------- /packages/fbjs/src/unicode/README.md: -------------------------------------------------------------------------------- 1 | # Unicode JS Package 2 | 3 | This package contains implementations of data and algorithms provided by 4 | standards developed by the Unicode Consortium, including: 5 | * The Unicode Standard 6 | * Unicode Technical Reports 7 | * Unicode Technical Notes 8 | * Unicode Character Data (UCD) 9 | * Unicode Common Locale Data Repository (CLDR) 10 | 11 | Other string data/algorithm implementations should reside in other packages. 12 | -------------------------------------------------------------------------------- /packages/fbjs/src/unicode/__tests__/UnicodeBidiDirection-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @emails oncall+unicode, oncall+jsinfra 8 | */ 9 | 10 | jest.disableAutomock(); 11 | 12 | var Dir = require('UnicodeBidiDirection'); 13 | 14 | describe('UnicodeBidiDirection', function() { 15 | 16 | it('should be comparable with string values', function() { 17 | expect(Dir.NEUTRAL).toBe('NEUTRAL'); 18 | expect(Dir.LTR).toBe('LTR'); 19 | expect(Dir.RTL).toBe('RTL'); 20 | }); 21 | 22 | it('should fail on comparing distinct values', function() { 23 | expect(Dir.NEUTRAL).not.toBe(Dir.LTR); 24 | expect(Dir.NEUTRAL).not.toBe(Dir.RTL); 25 | expect(Dir.LTR).not.toBe(Dir.RTL); 26 | }); 27 | 28 | describe('isStrong', function() { 29 | 30 | it('should be negative for NEUTRAL', function() { 31 | expect(Dir.isStrong(Dir.NEUTRAL)).toBe(false); 32 | }); 33 | 34 | it('should be positive for LTR/RTL', function() { 35 | expect(Dir.isStrong(Dir.RTL)).toBe(true); 36 | expect(Dir.isStrong(Dir.LTR)).toBe(true); 37 | }); 38 | 39 | }); 40 | 41 | describe('getHTMLDir', function() { 42 | 43 | it('should not accept NEUTRAL', function() { 44 | expect(() => Dir.getHTMLDir(Dir.NEUTRAL)).toThrow(); 45 | }); 46 | 47 | it('should accept LTR/RTL', function() { 48 | expect(Dir.getHTMLDir(Dir.RTL)).toBe('rtl'); 49 | expect(Dir.getHTMLDir(Dir.LTR)).toBe('ltr'); 50 | }); 51 | 52 | }); 53 | 54 | describe('getHTMLDirIfDifferent', function() { 55 | 56 | it('should accept LTR/RTL', function() { 57 | expect(Dir.getHTMLDirIfDifferent(Dir.RTL, Dir.RTL)).toBe(null); 58 | expect(Dir.getHTMLDirIfDifferent(Dir.RTL, Dir.LTR)).toBe('rtl'); 59 | expect(Dir.getHTMLDirIfDifferent(Dir.LTR, Dir.RTL)).toBe('ltr'); 60 | expect(Dir.getHTMLDirIfDifferent(Dir.LTR, Dir.LTR)).toBe(null); 61 | }); 62 | 63 | }); 64 | 65 | }); 66 | -------------------------------------------------------------------------------- /packages/fbjs/src/unicode/__tests__/UnicodeUtilsExtra-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @emails oncall+unicode, oncall+jsinfra 8 | */ 9 | 10 | jest.disableAutomock(); 11 | 12 | var UnicodeUtilsExtra = require('UnicodeUtilsExtra'); 13 | 14 | describe('UnicodeUtilsExtra', function() { 15 | 16 | var str0 = ''; 17 | var str1 = 'be bold'; 18 | // UTF-16 encoding for 19 | var str2 = 'be \uD835\uDDEF\uD835\uDDFC\uD835\uDDF9\uD835\uDDF1'; 20 | 21 | 22 | describe('formatCodePoint', function() { 23 | 24 | function _expectFormatToBe(str, output) { 25 | expect(UnicodeUtilsExtra.formatCodePoint.call(null, str)) 26 | .toBe(output); 27 | } 28 | 29 | it('should convert ASCII characters correctly', function() { 30 | _expectFormatToBe(0, 'U+0000'); 31 | _expectFormatToBe(NaN, 'U+0000'); 32 | 33 | _expectFormatToBe(65, 'U+0041'); 34 | _expectFormatToBe(0x41, 'U+0041'); 35 | _expectFormatToBe('A'.charCodeAt(0), 'U+0041'); 36 | 37 | _expectFormatToBe(0x00FFFF, 'U+FFFF'); 38 | _expectFormatToBe(0x010000, 'U+10000'); 39 | _expectFormatToBe(0x0FFFFF, 'U+FFFFF'); 40 | _expectFormatToBe(0x100000, 'U+100000'); 41 | _expectFormatToBe(0x10FFFF, 'U+10FFFF'); 42 | }); 43 | 44 | }); 45 | 46 | 47 | describe('getCodePointsFormatted', function() { 48 | 49 | function _expectCodePointsToBe(str, output) { 50 | expect(UnicodeUtilsExtra.getCodePointsFormatted.call(null, str)) 51 | .toEqual(output); 52 | } 53 | 54 | it('should return an empty array on empty string', function() { 55 | _expectCodePointsToBe(str0, []); 56 | }); 57 | 58 | it('should convert non-surrogate Unicode characters correctly', function() { 59 | _expectCodePointsToBe(str1, 60 | ['U+0062', 'U+0065', 'U+0020', 61 | 'U+0062', 'U+006F', 'U+006C', 'U+0064']); 62 | }); 63 | 64 | it('should convert surrogate Unicode characters correctly', function() { 65 | _expectCodePointsToBe(str2, 66 | ['U+0062', 'U+0065', 'U+0020', 67 | 'U+1D5EF', 'U+1D5FC', 'U+1D5F9', 'U+1D5F1']); 68 | }); 69 | 70 | }); 71 | 72 | }); 73 | -------------------------------------------------------------------------------- /packages/fbjs/src/utils/__mocks__/nullthrows.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | 'use strict'; 9 | 10 | jest.unmock('nullthrows'); 11 | 12 | module.exports = require('nullthrows'); 13 | -------------------------------------------------------------------------------- /packages/fbjs/src/utils/__tests__/nullthrows-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @emails oncall+flow 8 | * @flow 9 | */ 10 | 11 | jest.disableAutomock(); 12 | var nullthrows = require('nullthrows'); 13 | 14 | describe('nullthrows', () => { 15 | it('exists', () => expect(typeof nullthrows).toBe('function')); 16 | 17 | it("Doesn't throw on non-nulls", () => { 18 | var obj = {}; 19 | expect(nullthrows(0)).toBe(0); 20 | expect(nullthrows("")).toBe(""); 21 | expect(nullthrows(obj)).toBe(obj); 22 | }); 23 | 24 | it("throws on null", () => { 25 | expect(() => nullthrows(null)).toThrow(); 26 | }); 27 | 28 | it("throws on undefined", () => { 29 | expect(() => nullthrows(undefined)).toThrow(); 30 | }); 31 | 32 | }); 33 | -------------------------------------------------------------------------------- /packages/fbjs/src/utils/nullthrows.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2013-present, Facebook, Inc. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | * 7 | * @providesModule nullthrows 8 | * @flow 9 | */ 10 | 11 | var nullthrows = function(x: ?T): T { 12 | if (x != null) { 13 | return x; 14 | } 15 | throw new Error("Got unexpected null or undefined"); 16 | }; 17 | 18 | module.exports = nullthrows; 19 | -------------------------------------------------------------------------------- /packages/signedsource/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2013-present, Facebook, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/signedsource/__tests__/signedsource-test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | const SignedSource = require('../index.js'); 9 | 10 | test('signFile', () => { 11 | expect( 12 | SignedSource.signFile(`# ${SignedSource.getSigningToken()}\ntest 1`) 13 | ).toEqual( 14 | `# @generated SignedSource<>\ntest 1` 15 | ); 16 | 17 | expect( 18 | SignedSource.signFile(`# ${SignedSource.getSigningToken()}\ntest 2`) 19 | ).toEqual( 20 | `# @generated SignedSource<<4c0c1ae4f5863c72731b2f543e830fd5>>\ntest 2` 21 | ); 22 | 23 | // re-sign a file 24 | expect( 25 | SignedSource.signFile(`# @generated SignedSource<>\nalready signed test`) 26 | ).toEqual( 27 | `# @generated SignedSource<<54e8ffafff15a19f858d95c9a13d5b1d>>\nalready signed test` 28 | ); 29 | }); 30 | 31 | test('isSigned', () => { 32 | const signedString = SignedSource.signFile( 33 | `# ${SignedSource.getSigningToken()}\ntest` 34 | ); 35 | 36 | expect(SignedSource.isSigned(signedString)).toBe(true); 37 | expect(SignedSource.isSigned(signedString + 'modified')).toBe(true); 38 | expect(SignedSource.isSigned('unsigned')).toBe(false); 39 | }); 40 | 41 | test('verifySignature', () => { 42 | const signedString = SignedSource.signFile( 43 | `# ${SignedSource.getSigningToken()}\ntest` 44 | ); 45 | expect(SignedSource.verifySignature(signedString)).toBe(true); 46 | expect(SignedSource.verifySignature(signedString + 'modified')).toBe(false); 47 | expect(() => { 48 | SignedSource.verifySignature('unsigned'); 49 | }).toThrow( 50 | 'SignedSource.verifySignature(...): Cannot verify signature of an unsigned file.' 51 | ); 52 | }); 53 | -------------------------------------------------------------------------------- /packages/signedsource/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "signedsource", 3 | "version": "2.0.0", 4 | "description": "This package exports utilities to sign and verify generated files.", 5 | "main": "index.js", 6 | "license": "MIT", 7 | "scripts": { 8 | "test": "jest" 9 | }, 10 | "files": [ 11 | "LICENSE", 12 | "index.js" 13 | ], 14 | "devDependencies": { 15 | "jest": "^23.6.0" 16 | } 17 | } 18 | --------------------------------------------------------------------------------