Latest repo

This commit is contained in:
Marc
2025-06-02 16:42:16 +00:00
parent 53ddf1a329
commit cde5fae175
27907 changed files with 3875388 additions and 1 deletions

1
node_modules/react-async-script/.eslintignore generated vendored Normal file
View File

@@ -0,0 +1 @@
lib/**

19
node_modules/react-async-script/.eslintrc.js generated vendored Normal file
View File

@@ -0,0 +1,19 @@
"use strict";
module.exports = {
extends: ["eslint:recommended", "prettier", "prettier/react"],
parserOptions: {
sourceType: "module",
ecmaVersion: "2018",
ecmaFeatures: {
jsx: true,
},
},
env: {
es6: true,
browser: true,
},
plugins: ["prettier"],
rules: {
"prettier/prettier": "error",
},
};

153
node_modules/react-async-script/CHANGELOG.md generated vendored Normal file
View File

@@ -0,0 +1,153 @@
v1.2.0 - Mon Jun 22 2020 15:36:00 PST
--------------------------------------
- Added support for optional attributes that can be added to the generated script tag [(#52)](https://github.com/dozoisch/react-async-script/pull/52)
- Update various dependencies (notably babel/react) [(#48)](https://github.com/dozoisch/react-async-script/pull/48)
v1.1.1 - Sun Jul 14 2019 11:14:00 PST
--------------------------------------
- Add node 12 to build [(#46)](https://github.com/dozoisch/react-async-script/pull/46)
v1.1.0 - Sun Jul 14 2019 10:19:00 PST
--------------------------------------
- Switch to Jest [(#45)](https://github.com/dozoisch/react-async-script/pull/45)
- Upgrade dependencies and add es module [(#44)](https://github.com/dozoisch/react-async-script/pull/44)
v1.0.1 - Sun 17 Apr 2019 19:14:00 PST
--------------------------------------
- Support for adding a script id attribute [(#43)](https://github.com/dozoisch/react-async-script/pull/43)
v1.0.0 - Fri 17 Aug 2018 17:32:00 PST
--------------------------------------
- React forward ref [(#37)](https://github.com/dozoisch/react-async-script/pull/37)
- Update to react 16.4.1 [(#37)](https://github.com/dozoisch/react-async-script/pull/37)
- Hoist non react statics [(#35)](https://github.com/dozoisch/react-async-script/pull/35)
- Updated Travis Node versions [(#36)](https://github.com/dozoisch/react-async-script/pull/36)
- Refactor to new HOC pattern [(#34)](https://github.com/dozoisch/react-async-script/pull/34)
- Remove old broken IE support [(#34)](https://github.com/dozoisch/react-async-script/pull/34)
- Add migration notes [(#40)](https://github.com/dozoisch/react-async-script/pull/40)
v0.11.1 - Sat, 4 Aug 2018 12:46:00 PST
--------------------------------------
- Remove babel-runtime peer dep [(#32)](https://github.com/dozoisch/react-async-script/pull/32)
- Readme updates [(#31)](https://github.com/dozoisch/react-async-script/pull/31)
v0.11.0 - Sun, 29 Jul 2018 11:58:00 PST
--------------------------------------
- Remove transform runtime [(#29)](https://github.com/dozoisch/react-async-script/pull/29)
- Added dynamic url capability [(#30)](https://github.com/dozoisch/react-async-script/pull/30)
v0.10.0 - Tue, 24 Jul 2018 14:40:00 PST
--------------------------------------
- Clean up use of Map to remove core-js polyfills [(#27)](https://github.com/dozoisch/react-async-script/pull/27)
v0.9.1 - Wed, 19 Apr 2017 6:05:00 PST
--------------------------------------
- Fixed issue where method was not bound properly [(#19)](https://github.com/dozoisch/react-async-script/pull/19)
v0.9.0 - Sun, 16 Apr 2017 4:12:00 PST
--------------------------------------
- Changed updated to react >=15.5 [(#18)](https://github.com/dozoisch/react-async-script/pull/18)
v0.8.0 - Thu, 23 Mar 2017 5:46:00 PST
--------------------------------------
- Added removeOnUnmount parameter [(#14)](https://github.com/dozoisch/react-async-script/pull/14)
v0.7.0 - Sat, 04 Mar 2017 6:37:00 PST
--------------------------------------
- Updated deps to react 15 and babel 6 [(#13)](https://github.com/dozoisch/react-async-script/pull/13)
- Go back to manual changelogs
v0.6.0 - Thu, 02 Jun 2016 01:18:21 GMT
--------------------------------------
- [0bc67b2](../../commit/0bc67b2) [fixed] typo in documentation [(#9)](https://github.com/dozoisch/react-async-script/pull/9)
v0.5.1 - Fri, 15 Jan 2016 13:21:01 GMT
--------------------------------------
- [65d1313](../../commit/65d1313) [added] old history to new changelog file
v0.5.0 - Thu, 15 Oct 2015 21:10:33 GMT
--------------------------------------
- [9059f9e](../../commit/9059f9e) [changed] travis to build only master & prs
- [52bb6d5](../../commit/52bb6d5) [changed] updated deps
- [4920f59](../../commit/4920f59) [changed] Build Tools to use babel
- [253dbf2](../../commit/253dbf2) [fixed] onLoad propname in readme
## 0.4.0
- Fixed issue with refs
- Bump all deps
## 0.3.2
- Bump deps
## 0.3.1
- Removed uncessary "use strict"
- Bump deps
## 0.3.0
- Added a way to expose child functions
## 0.2.2
- Fix instanciation when global object already exists
## 0.2.1
- Put runtime in deps and not dev-deps
## 0.2.0
- Back to es6 Map
## 0.1.2
- Added a small test
- Added some badges
- small fixes
## 0.1.1
- reverted es6 map back to plain object
## 0.1.0
- Added the composition function
- Added build files
- Added david-dm badge
- Initial readme

22
node_modules/react-async-script/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2017 Hugo Dozois
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

135
node_modules/react-async-script/README.md generated vendored Normal file
View File

@@ -0,0 +1,135 @@
# React Async Script Loader
[![Build Status][travis.img]][travis.url] [![npm version][npm.img]][npm.url] [![npm downloads][npm.dl.img]][npm.dl.url] [![Dependencies][deps.img]][deps.url]
**NOTE* - These are the docs for the upcoming `1.0.0` release - for `v0.11.1` documention go to tag here: [0.11.1](https://github.com/dozoisch/react-async-script/tree/v0.11.1)
A React HOC for loading 3rd party scripts asynchronously. This HOC allows you to wrap a component that needs 3rd party resources, like reCAPTCHA or Google Maps, and have them load the script asynchronously.
## Usage
#### Async Script HOC api
`makeAsyncScriptLoader(getScriptUrl, options)(Component)`
- `Component`: The *Component* to wrap.
- `getScriptUrl`: *string* or *function* that returns the full URL of the script tag.
- `options` *(optional)*:
- `attributes`: *object* : If the script needs attributes (such as `data-` attributes), then provide them as key/value pairs of strings and they will be added to the generated script tag.
- `callbackName`: *string* : If the script needs to call a global function when finished loading *(for example: `recaptcha/api.js?onload=callbackName`)*. Please provide the callback name here and it will be autoregistered on `window` for you.
- `globalName`: *string* : Can provide the name of the global that the script attaches to `window`. Async-script will pass this as a prop to the wrapped component. *(`props[globalName] = window[globalName]`)*
- `removeOnUnmount`: *boolean* **default=false** : If set to `true` removes the script tag when component unmounts.
- `scriptId`: *string* : If set, it adds the following id on the script tag.
#### HOC Component props
```js
const AsyncScriptComponent = makeAsyncScriptLoader(URL)(Component);
// ---
<AsyncScriptComponent asyncScriptOnLoad={callAfterScriptLoads} />
```
- `asyncScriptOnLoad`: *function* : called after script finishes loading. *using `script.onload`*
#### Ref and forwardRef
`react-async-script` uses react's `forwardRef` method to pass along the `ref` applied to the wrapped component.
If you pass a `ref` prop you'll have access to your wrapped components instance. See the tests for detailed example.
Simple Example:
```js
const AsyncHoc = makeAsyncScriptLoader(URL)(ComponentNeedsScript);
class DisplayComponent extends React.Component {
constructor(props) {
super(props);
this._internalRef = React.createRef();
}
componentDidMount() {
console.log("ComponentNeedsScript's Instance -", this._internalRef.current);
}
render() { return (<AsyncHoc ref={this._internalRef} />)}
}
```
##### Notes on Requirements
At least `React@16.4.1` is required due to `forwardRef` usage internally.
### Example
See https://github.com/dozoisch/react-google-recaptcha
```js
// recaptcha.js
export class ReCAPTCHA extends React.Component {
componentDidUpdate(prevProps) {
// recaptcha has loaded via async script
if (!prevProps.grecaptcha && this.props.grecaptcha) {
this.props.grecaptcha.render(this._container)
}
}
render() { return (
<div ref={(r) => this._container = r} />)
}
}
// recaptcha-wrapper.js
import makeAsyncScriptLoader from "react-async-script";
import { ReCAPTCHA } from "./recaptcha";
const callbackName = "onloadcallback";
const URL = `https://www.google.com/recaptcha/api.js?onload=${callbackName}&render=explicit`;
// the name of the global that recaptcha/api.js sets on window ie: window.grecaptcha
const globalName = "grecaptcha";
export default makeAsyncScriptLoader(URL, {
callbackName: callbackName,
globalName: globalName,
})(ReCAPTCHA);
// main.js
import ReCAPTCHAWrapper from "./recaptcha-wrapper.js"
const onLoad = () => console.log("script loaded")
React.render(
<ReCAPTCHAWrapper asyncScriptOnLoad={onLoad} />,
document.body
);
```
## Migration to 1.0
- Component is now passed as a second function call
- removeOnMount is now removeOnUnmount (typo fixed!)
- exposeFuncs is no longer needed as it's done automatically!
```diff
-export default makeAsyncScriptLoader(ReCAPTCHA, getURL, {
+export default makeAsyncScriptLoader(getURL, {
callbackName,
globalName,
- removeOnMount: initialOptions.removeOnMount || false,
+ removeOnUnmount: initialOptions.removeOnUnmount || false,
- exposeFuncs: ["getValue", "getWidgetId", "reset", "execute"],
-});
+})(ReCAPTCHA);
```
## Notes
Pre `1.0.0` and - `React < React@16.4.1` support details in [0.11.1](https://github.com/dozoisch/react-async-script/tree/v0.11.1).
---
[travis.img]: https://travis-ci.org/dozoisch/react-async-script.svg?branch=master
[travis.url]: https://travis-ci.org/dozoisch/react-async-script
[npm.img]: https://badge.fury.io/js/react-async-script.svg
[npm.url]: http://badge.fury.io/js/react-async-script
[npm.dl.img]: https://img.shields.io/npm/dm/react-async-script.svg
[npm.dl.url]: https://www.npmjs.com/package/react-async-script
[deps.img]: https://david-dm.org/dozoisch/react-async-script.svg
[deps.url]: https://david-dm.org/dozoisch/react-async-script

184
node_modules/react-async-script/jest.config.js generated vendored Normal file
View File

@@ -0,0 +1,184 @@
/* eslint-env node */
// For a detailed explanation regarding each configuration property, visit:
// https://jestjs.io/docs/en/configuration.html
module.exports = {
// All imported modules in your tests should be mocked automatically
// automock: false,
// Stop running tests after `n` failures
// bail: 0,
// Respect "browser" field in package.json when resolving modules
// browser: false,
// The directory where Jest should store its cached dependency information
// cacheDirectory: "/private/var/folders/_2/s04zgy_10ys_hdf7s78rfhlh0000gn/T/jest_dx",
// Automatically clear mock calls and instances between every test
// clearMocks: false,
// Indicates whether the coverage information should be collected while executing the test
// collectCoverage: false,
// An array of glob patterns indicating a set of files for which coverage information should be collected
// collectCoverageFrom: null,
// The directory where Jest should output its coverage files
// coverageDirectory: null,
// An array of regexp pattern strings used to skip coverage collection
// coveragePathIgnorePatterns: [
// "/node_modules/"
// ],
// A list of reporter names that Jest uses when writing coverage reports
// coverageReporters: [
// "json",
// "text",
// "lcov",
// "clover"
// ],
// An object that configures minimum threshold enforcement for coverage results
// coverageThreshold: null,
// A path to a custom dependency extractor
// dependencyExtractor: null,
// Make calling deprecated APIs throw helpful error messages
// errorOnDeprecated: false,
// Force coverage collection from ignored files using an array of glob patterns
// forceCoverageMatch: [],
// A path to a module which exports an async function that is triggered once before all test suites
// globalSetup: null,
// A path to a module which exports an async function that is triggered once after all test suites
// globalTeardown: null,
// A set of global variables that need to be available in all test environments
// globals: {},
// An array of directory names to be searched recursively up from the requiring module's location
// moduleDirectories: [
// "node_modules"
// ],
// An array of file extensions your modules use
// moduleFileExtensions: [
// "js",
// "json",
// "jsx",
// "ts",
// "tsx",
// "node"
// ],
// A map from regular expressions to module names that allow to stub out resources with a single module
// moduleNameMapper: {},
// An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
// modulePathIgnorePatterns: [],
// Activates notifications for test results
// notify: false,
// An enum that specifies notification mode. Requires { notify: true }
// notifyMode: "failure-change",
// A preset that is used as a base for Jest's configuration
// preset: null,
// Run tests from one or more projects
// projects: null,
// Use this configuration option to add custom reporters to Jest
// reporters: undefined,
// Automatically reset mock state between every test
// resetMocks: false,
// Reset the module registry before running each individual test
// resetModules: false,
// A path to a custom resolver
// resolver: null,
// Automatically restore mock state between every test
// restoreMocks: false,
// The root directory that Jest should scan for tests and modules within
// rootDir: null,
// A list of paths to directories that Jest should use to search for files in
// roots: [
// "<rootDir>"
// ],
// Allows you to use a custom runner instead of Jest's default test runner
// runner: "jest-runner",
// The paths to modules that run some code to configure or set up the testing environment before each test
// setupFiles: [],
// A list of paths to modules that run some code to configure or set up the testing framework before each test
// setupFilesAfterEnv: [],
// A list of paths to snapshot serializer modules Jest should use for snapshot testing
// snapshotSerializers: [],
// The test environment that will be used for testing
// testEnvironment: "jest-environment-jsdom",
// Options that will be passed to the testEnvironment
// testEnvironmentOptions: {},
// Adds a location field to test results
// testLocationInResults: false,
// The glob patterns Jest uses to detect test files
testMatch: ["**/test/**/*-spec.js?(x)"]
// An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
// testPathIgnorePatterns: [
// "/node_modules/"
// ],
// The regexp pattern or array of patterns that Jest uses to detect test files
// testRegex: [],
// This option allows the use of a custom results processor
// testResultsProcessor: null,
// This option allows use of a custom test runner
// testRunner: "jasmine2",
// This option sets the URL for the jsdom environment. It is reflected in properties such as location.href
// testURL: "http://localhost",
// Setting this value to "fake" allows the use of fake timers for functions such as "setTimeout"
// timers: "real",
// A map from regular expressions to paths to transformers
// transform: null,
// An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation
// transformIgnorePatterns: [
// "/node_modules/"
// ],
// An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them
// unmockedModulePathPatterns: undefined,
// Indicates whether each individual test should be reported during the run
// verbose: null,
// An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode
// watchPathIgnorePatterns: [],
// Whether to use watchman for file crawling
// watchman: true,
};

View File

@@ -0,0 +1,255 @@
"use strict";
exports.__esModule = true;
exports["default"] = makeAsyncScript;
var _react = require("react");
var _propTypes = _interopRequireDefault(require("prop-types"));
var _hoistNonReactStatics = _interopRequireDefault(require("hoist-non-react-statics"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
var SCRIPT_MAP = {}; // A counter used to generate a unique id for each component that uses the function
var idCount = 0;
function makeAsyncScript(getScriptURL, options) {
options = options || {};
return function wrapWithAsyncScript(WrappedComponent) {
var wrappedComponentName = WrappedComponent.displayName || WrappedComponent.name || "Component";
var AsyncScriptLoader =
/*#__PURE__*/
function (_Component) {
_inheritsLoose(AsyncScriptLoader, _Component);
function AsyncScriptLoader(props, context) {
var _this;
_this = _Component.call(this, props, context) || this;
_this.state = {};
_this.__scriptURL = "";
return _this;
}
var _proto = AsyncScriptLoader.prototype;
_proto.asyncScriptLoaderGetScriptLoaderID = function asyncScriptLoaderGetScriptLoaderID() {
if (!this.__scriptLoaderID) {
this.__scriptLoaderID = "async-script-loader-" + idCount++;
}
return this.__scriptLoaderID;
};
_proto.setupScriptURL = function setupScriptURL() {
this.__scriptURL = typeof getScriptURL === "function" ? getScriptURL() : getScriptURL;
return this.__scriptURL;
};
_proto.asyncScriptLoaderHandleLoad = function asyncScriptLoaderHandleLoad(state) {
var _this2 = this;
// use reacts setState callback to fire props.asyncScriptOnLoad with new state/entry
this.setState(state, function () {
return _this2.props.asyncScriptOnLoad && _this2.props.asyncScriptOnLoad(_this2.state);
});
};
_proto.asyncScriptLoaderTriggerOnScriptLoaded = function asyncScriptLoaderTriggerOnScriptLoaded() {
var mapEntry = SCRIPT_MAP[this.__scriptURL];
if (!mapEntry || !mapEntry.loaded) {
throw new Error("Script is not loaded.");
}
for (var obsKey in mapEntry.observers) {
mapEntry.observers[obsKey](mapEntry);
}
delete window[options.callbackName];
};
_proto.componentDidMount = function componentDidMount() {
var _this3 = this;
var scriptURL = this.setupScriptURL();
var key = this.asyncScriptLoaderGetScriptLoaderID();
var _options = options,
globalName = _options.globalName,
callbackName = _options.callbackName,
scriptId = _options.scriptId; // check if global object already attached to window
if (globalName && typeof window[globalName] !== "undefined") {
SCRIPT_MAP[scriptURL] = {
loaded: true,
observers: {}
};
} // check if script loading already
if (SCRIPT_MAP[scriptURL]) {
var entry = SCRIPT_MAP[scriptURL]; // if loaded or errored then "finish"
if (entry && (entry.loaded || entry.errored)) {
this.asyncScriptLoaderHandleLoad(entry);
return;
} // if still loading then callback to observer queue
entry.observers[key] = function (entry) {
return _this3.asyncScriptLoaderHandleLoad(entry);
};
return;
}
/*
* hasn't started loading
* start the "magic"
* setup script to load and observers
*/
var observers = {};
observers[key] = function (entry) {
return _this3.asyncScriptLoaderHandleLoad(entry);
};
SCRIPT_MAP[scriptURL] = {
loaded: false,
observers: observers
};
var script = document.createElement("script");
script.src = scriptURL;
script.async = true;
for (var attribute in options.attributes) {
script.setAttribute(attribute, options.attributes[attribute]);
}
if (scriptId) {
script.id = scriptId;
}
var callObserverFuncAndRemoveObserver = function callObserverFuncAndRemoveObserver(func) {
if (SCRIPT_MAP[scriptURL]) {
var mapEntry = SCRIPT_MAP[scriptURL];
var observersMap = mapEntry.observers;
for (var obsKey in observersMap) {
if (func(observersMap[obsKey])) {
delete observersMap[obsKey];
}
}
}
};
if (callbackName && typeof window !== "undefined") {
window[callbackName] = function () {
return _this3.asyncScriptLoaderTriggerOnScriptLoaded();
};
}
script.onload = function () {
var mapEntry = SCRIPT_MAP[scriptURL];
if (mapEntry) {
mapEntry.loaded = true;
callObserverFuncAndRemoveObserver(function (observer) {
if (callbackName) {
return false;
}
observer(mapEntry);
return true;
});
}
};
script.onerror = function () {
var mapEntry = SCRIPT_MAP[scriptURL];
if (mapEntry) {
mapEntry.errored = true;
callObserverFuncAndRemoveObserver(function (observer) {
observer(mapEntry);
return true;
});
}
};
document.body.appendChild(script);
};
_proto.componentWillUnmount = function componentWillUnmount() {
// Remove tag script
var scriptURL = this.__scriptURL;
if (options.removeOnUnmount === true) {
var allScripts = document.getElementsByTagName("script");
for (var i = 0; i < allScripts.length; i += 1) {
if (allScripts[i].src.indexOf(scriptURL) > -1) {
if (allScripts[i].parentNode) {
allScripts[i].parentNode.removeChild(allScripts[i]);
}
}
}
} // Clean the observer entry
var mapEntry = SCRIPT_MAP[scriptURL];
if (mapEntry) {
delete mapEntry.observers[this.asyncScriptLoaderGetScriptLoaderID()];
if (options.removeOnUnmount === true) {
delete SCRIPT_MAP[scriptURL];
}
}
};
_proto.render = function render() {
var globalName = options.globalName; // remove asyncScriptOnLoad from childProps
var _this$props = this.props,
asyncScriptOnLoad = _this$props.asyncScriptOnLoad,
forwardedRef = _this$props.forwardedRef,
childProps = _objectWithoutPropertiesLoose(_this$props, ["asyncScriptOnLoad", "forwardedRef"]); // eslint-disable-line no-unused-vars
if (globalName && typeof window !== "undefined") {
childProps[globalName] = typeof window[globalName] !== "undefined" ? window[globalName] : undefined;
}
childProps.ref = forwardedRef;
return (0, _react.createElement)(WrappedComponent, childProps);
};
return AsyncScriptLoader;
}(_react.Component); // Note the second param "ref" provided by React.forwardRef.
// We can pass it along to AsyncScriptLoader as a regular prop, e.g. "forwardedRef"
// And it can then be attached to the Component.
var ForwardedComponent = (0, _react.forwardRef)(function (props, ref) {
return (0, _react.createElement)(AsyncScriptLoader, _extends({}, props, {
forwardedRef: ref
}));
});
ForwardedComponent.displayName = "AsyncScriptLoader(" + wrappedComponentName + ")";
ForwardedComponent.propTypes = {
asyncScriptOnLoad: _propTypes["default"].func
};
return (0, _hoistNonReactStatics["default"])(ForwardedComponent, WrappedComponent);
};
}

View File

@@ -0,0 +1,244 @@
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
import { Component, createElement, forwardRef } from "react";
import PropTypes from "prop-types";
import hoistStatics from "hoist-non-react-statics";
var SCRIPT_MAP = {}; // A counter used to generate a unique id for each component that uses the function
var idCount = 0;
export default function makeAsyncScript(getScriptURL, options) {
options = options || {};
return function wrapWithAsyncScript(WrappedComponent) {
var wrappedComponentName = WrappedComponent.displayName || WrappedComponent.name || "Component";
var AsyncScriptLoader =
/*#__PURE__*/
function (_Component) {
_inheritsLoose(AsyncScriptLoader, _Component);
function AsyncScriptLoader(props, context) {
var _this;
_this = _Component.call(this, props, context) || this;
_this.state = {};
_this.__scriptURL = "";
return _this;
}
var _proto = AsyncScriptLoader.prototype;
_proto.asyncScriptLoaderGetScriptLoaderID = function asyncScriptLoaderGetScriptLoaderID() {
if (!this.__scriptLoaderID) {
this.__scriptLoaderID = "async-script-loader-" + idCount++;
}
return this.__scriptLoaderID;
};
_proto.setupScriptURL = function setupScriptURL() {
this.__scriptURL = typeof getScriptURL === "function" ? getScriptURL() : getScriptURL;
return this.__scriptURL;
};
_proto.asyncScriptLoaderHandleLoad = function asyncScriptLoaderHandleLoad(state) {
var _this2 = this;
// use reacts setState callback to fire props.asyncScriptOnLoad with new state/entry
this.setState(state, function () {
return _this2.props.asyncScriptOnLoad && _this2.props.asyncScriptOnLoad(_this2.state);
});
};
_proto.asyncScriptLoaderTriggerOnScriptLoaded = function asyncScriptLoaderTriggerOnScriptLoaded() {
var mapEntry = SCRIPT_MAP[this.__scriptURL];
if (!mapEntry || !mapEntry.loaded) {
throw new Error("Script is not loaded.");
}
for (var obsKey in mapEntry.observers) {
mapEntry.observers[obsKey](mapEntry);
}
delete window[options.callbackName];
};
_proto.componentDidMount = function componentDidMount() {
var _this3 = this;
var scriptURL = this.setupScriptURL();
var key = this.asyncScriptLoaderGetScriptLoaderID();
var _options = options,
globalName = _options.globalName,
callbackName = _options.callbackName,
scriptId = _options.scriptId; // check if global object already attached to window
if (globalName && typeof window[globalName] !== "undefined") {
SCRIPT_MAP[scriptURL] = {
loaded: true,
observers: {}
};
} // check if script loading already
if (SCRIPT_MAP[scriptURL]) {
var entry = SCRIPT_MAP[scriptURL]; // if loaded or errored then "finish"
if (entry && (entry.loaded || entry.errored)) {
this.asyncScriptLoaderHandleLoad(entry);
return;
} // if still loading then callback to observer queue
entry.observers[key] = function (entry) {
return _this3.asyncScriptLoaderHandleLoad(entry);
};
return;
}
/*
* hasn't started loading
* start the "magic"
* setup script to load and observers
*/
var observers = {};
observers[key] = function (entry) {
return _this3.asyncScriptLoaderHandleLoad(entry);
};
SCRIPT_MAP[scriptURL] = {
loaded: false,
observers: observers
};
var script = document.createElement("script");
script.src = scriptURL;
script.async = true;
for (var attribute in options.attributes) {
script.setAttribute(attribute, options.attributes[attribute]);
}
if (scriptId) {
script.id = scriptId;
}
var callObserverFuncAndRemoveObserver = function callObserverFuncAndRemoveObserver(func) {
if (SCRIPT_MAP[scriptURL]) {
var mapEntry = SCRIPT_MAP[scriptURL];
var observersMap = mapEntry.observers;
for (var obsKey in observersMap) {
if (func(observersMap[obsKey])) {
delete observersMap[obsKey];
}
}
}
};
if (callbackName && typeof window !== "undefined") {
window[callbackName] = function () {
return _this3.asyncScriptLoaderTriggerOnScriptLoaded();
};
}
script.onload = function () {
var mapEntry = SCRIPT_MAP[scriptURL];
if (mapEntry) {
mapEntry.loaded = true;
callObserverFuncAndRemoveObserver(function (observer) {
if (callbackName) {
return false;
}
observer(mapEntry);
return true;
});
}
};
script.onerror = function () {
var mapEntry = SCRIPT_MAP[scriptURL];
if (mapEntry) {
mapEntry.errored = true;
callObserverFuncAndRemoveObserver(function (observer) {
observer(mapEntry);
return true;
});
}
};
document.body.appendChild(script);
};
_proto.componentWillUnmount = function componentWillUnmount() {
// Remove tag script
var scriptURL = this.__scriptURL;
if (options.removeOnUnmount === true) {
var allScripts = document.getElementsByTagName("script");
for (var i = 0; i < allScripts.length; i += 1) {
if (allScripts[i].src.indexOf(scriptURL) > -1) {
if (allScripts[i].parentNode) {
allScripts[i].parentNode.removeChild(allScripts[i]);
}
}
}
} // Clean the observer entry
var mapEntry = SCRIPT_MAP[scriptURL];
if (mapEntry) {
delete mapEntry.observers[this.asyncScriptLoaderGetScriptLoaderID()];
if (options.removeOnUnmount === true) {
delete SCRIPT_MAP[scriptURL];
}
}
};
_proto.render = function render() {
var globalName = options.globalName; // remove asyncScriptOnLoad from childProps
var _this$props = this.props,
asyncScriptOnLoad = _this$props.asyncScriptOnLoad,
forwardedRef = _this$props.forwardedRef,
childProps = _objectWithoutPropertiesLoose(_this$props, ["asyncScriptOnLoad", "forwardedRef"]); // eslint-disable-line no-unused-vars
if (globalName && typeof window !== "undefined") {
childProps[globalName] = typeof window[globalName] !== "undefined" ? window[globalName] : undefined;
}
childProps.ref = forwardedRef;
return createElement(WrappedComponent, childProps);
};
return AsyncScriptLoader;
}(Component); // Note the second param "ref" provided by React.forwardRef.
// We can pass it along to AsyncScriptLoader as a regular prop, e.g. "forwardedRef"
// And it can then be attached to the Component.
var ForwardedComponent = forwardRef(function (props, ref) {
return createElement(AsyncScriptLoader, _extends({}, props, {
forwardedRef: ref
}));
});
ForwardedComponent.displayName = "AsyncScriptLoader(" + wrappedComponentName + ")";
ForwardedComponent.propTypes = {
asyncScriptOnLoad: PropTypes.func
};
return hoistStatics(ForwardedComponent, WrappedComponent);
};
}

55
node_modules/react-async-script/package.json generated vendored Normal file
View File

@@ -0,0 +1,55 @@
{
"name": "react-async-script",
"version": "1.2.0",
"description": "A composition mixin for loading scripts asynchronously for React",
"main": "lib/async-script-loader.js",
"module": "lib/esm/async-script-loader.js",
"scripts": {
"build": "rm -rf lib && npm run build:cjs && npm run build:esm",
"build:cjs": "babel src --out-dir lib",
"build:esm": "BABEL_ENV=esm babel src --out-dir lib/esm",
"lint": "eslint ./",
"pretty": "prettier --write src/*.js ./*.js test/*.js",
"test": "jest",
"test-watch": "jest --watch",
"prepare": "npm run build"
},
"repository": {
"type": "git",
"url": "https://github.com/dozoisch/react-async-script.git"
},
"keywords": [
"react",
"asynchronous",
"script-loader"
],
"author": "Hugo Dozois <hugo@dozoisch.com>",
"license": "MIT",
"bugs": {
"url": "https://github.com/dozoisch/react-async-script/issues"
},
"homepage": "https://github.com/dozoisch/react-async-script",
"devDependencies": {
"@babel/cli": "^7.6.4",
"@babel/core": "^7.6.4",
"@babel/preset-env": "^7.6.3",
"@babel/preset-react": "^7.6.3",
"@babel/register": "^7.6.2",
"babel-eslint": "^10.0.3",
"eslint": "6.6.0",
"eslint-config-prettier": "6.4.0",
"eslint-plugin-prettier": "3.1.1",
"jest": "^24.9.0",
"prettier": "^1.18.2",
"react": "^16.11.0",
"react-dom": "^16.11.0",
"react-is": "^16.11.0"
},
"peerDependencies": {
"react": ">=16.4.1"
},
"dependencies": {
"hoist-non-react-statics": "^3.3.0",
"prop-types": "^15.5.0"
}
}

View File

@@ -0,0 +1,202 @@
import { Component, createElement, forwardRef } from "react";
import PropTypes from "prop-types";
import hoistStatics from "hoist-non-react-statics";
let SCRIPT_MAP = {};
// A counter used to generate a unique id for each component that uses the function
let idCount = 0;
export default function makeAsyncScript(getScriptURL, options) {
options = options || {};
return function wrapWithAsyncScript(WrappedComponent) {
const wrappedComponentName =
WrappedComponent.displayName || WrappedComponent.name || "Component";
class AsyncScriptLoader extends Component {
constructor(props, context) {
super(props, context);
this.state = {};
this.__scriptURL = "";
}
asyncScriptLoaderGetScriptLoaderID() {
if (!this.__scriptLoaderID) {
this.__scriptLoaderID = "async-script-loader-" + idCount++;
}
return this.__scriptLoaderID;
}
setupScriptURL() {
this.__scriptURL =
typeof getScriptURL === "function" ? getScriptURL() : getScriptURL;
return this.__scriptURL;
}
asyncScriptLoaderHandleLoad(state) {
// use reacts setState callback to fire props.asyncScriptOnLoad with new state/entry
this.setState(
state,
() =>
this.props.asyncScriptOnLoad &&
this.props.asyncScriptOnLoad(this.state)
);
}
asyncScriptLoaderTriggerOnScriptLoaded() {
let mapEntry = SCRIPT_MAP[this.__scriptURL];
if (!mapEntry || !mapEntry.loaded) {
throw new Error("Script is not loaded.");
}
for (let obsKey in mapEntry.observers) {
mapEntry.observers[obsKey](mapEntry);
}
delete window[options.callbackName];
}
componentDidMount() {
const scriptURL = this.setupScriptURL();
const key = this.asyncScriptLoaderGetScriptLoaderID();
const { globalName, callbackName, scriptId } = options;
// check if global object already attached to window
if (globalName && typeof window[globalName] !== "undefined") {
SCRIPT_MAP[scriptURL] = { loaded: true, observers: {} };
}
// check if script loading already
if (SCRIPT_MAP[scriptURL]) {
let entry = SCRIPT_MAP[scriptURL];
// if loaded or errored then "finish"
if (entry && (entry.loaded || entry.errored)) {
this.asyncScriptLoaderHandleLoad(entry);
return;
}
// if still loading then callback to observer queue
entry.observers[key] = entry =>
this.asyncScriptLoaderHandleLoad(entry);
return;
}
/*
* hasn't started loading
* start the "magic"
* setup script to load and observers
*/
let observers = {};
observers[key] = entry => this.asyncScriptLoaderHandleLoad(entry);
SCRIPT_MAP[scriptURL] = {
loaded: false,
observers
};
let script = document.createElement("script");
script.src = scriptURL;
script.async = true;
for (let attribute in options.attributes) {
script.setAttribute(attribute, options.attributes[attribute]);
}
if (scriptId) {
script.id = scriptId;
}
let callObserverFuncAndRemoveObserver = func => {
if (SCRIPT_MAP[scriptURL]) {
let mapEntry = SCRIPT_MAP[scriptURL];
let observersMap = mapEntry.observers;
for (let obsKey in observersMap) {
if (func(observersMap[obsKey])) {
delete observersMap[obsKey];
}
}
}
};
if (callbackName && typeof window !== "undefined") {
window[callbackName] = () =>
this.asyncScriptLoaderTriggerOnScriptLoaded();
}
script.onload = () => {
let mapEntry = SCRIPT_MAP[scriptURL];
if (mapEntry) {
mapEntry.loaded = true;
callObserverFuncAndRemoveObserver(observer => {
if (callbackName) {
return false;
}
observer(mapEntry);
return true;
});
}
};
script.onerror = () => {
let mapEntry = SCRIPT_MAP[scriptURL];
if (mapEntry) {
mapEntry.errored = true;
callObserverFuncAndRemoveObserver(observer => {
observer(mapEntry);
return true;
});
}
};
document.body.appendChild(script);
}
componentWillUnmount() {
// Remove tag script
const scriptURL = this.__scriptURL;
if (options.removeOnUnmount === true) {
const allScripts = document.getElementsByTagName("script");
for (let i = 0; i < allScripts.length; i += 1) {
if (allScripts[i].src.indexOf(scriptURL) > -1) {
if (allScripts[i].parentNode) {
allScripts[i].parentNode.removeChild(allScripts[i]);
}
}
}
}
// Clean the observer entry
let mapEntry = SCRIPT_MAP[scriptURL];
if (mapEntry) {
delete mapEntry.observers[this.asyncScriptLoaderGetScriptLoaderID()];
if (options.removeOnUnmount === true) {
delete SCRIPT_MAP[scriptURL];
}
}
}
render() {
const globalName = options.globalName;
// remove asyncScriptOnLoad from childProps
let { asyncScriptOnLoad, forwardedRef, ...childProps } = this.props; // eslint-disable-line no-unused-vars
if (globalName && typeof window !== "undefined") {
childProps[globalName] =
typeof window[globalName] !== "undefined"
? window[globalName]
: undefined;
}
childProps.ref = forwardedRef;
return createElement(WrappedComponent, childProps);
}
}
// Note the second param "ref" provided by React.forwardRef.
// We can pass it along to AsyncScriptLoader as a regular prop, e.g. "forwardedRef"
// And it can then be attached to the Component.
const ForwardedComponent = forwardRef((props, ref) => {
return createElement(AsyncScriptLoader, { ...props, forwardedRef: ref });
});
ForwardedComponent.displayName = `AsyncScriptLoader(${wrappedComponentName})`;
ForwardedComponent.propTypes = {
asyncScriptOnLoad: PropTypes.func
};
return hoistStatics(ForwardedComponent, WrappedComponent);
};
}