@hcaptcha/react-hcaptcha 1.4.1 → 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/esm/index.js CHANGED
@@ -1,34 +1,44 @@
1
1
  import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
2
2
  import _inheritsLoose from "@babel/runtime/helpers/inheritsLoose";
3
3
  import * as React from 'react';
4
- import { generateQuery } from "./utils.js"; // Create script to init hCaptcha
4
+ import { generateQuery } from "./utils.js";
5
+ var SCRIPT_ID = 'hcaptcha-api-script-id';
6
+ var HCAPTCHA_LOAD_FN_NAME = 'hcaptchaOnLoad'; // Prevent loading API script multiple times
5
7
 
6
- var onLoadListeners = [];
7
- var apiScriptRequested = false; // Generate hCaptcha API Script
8
+ var resolveFn;
9
+ var rejectFn;
10
+ var mountPromise = new Promise(function (resolve, reject) {
11
+ resolveFn = resolve;
12
+ rejectFn = reject;
13
+ }); // Generate hCaptcha API script
8
14
 
9
15
  var mountCaptchaScript = function mountCaptchaScript(params) {
10
16
  if (params === void 0) {
11
17
  params = {};
12
18
  }
13
19
 
14
- apiScriptRequested = true; // Create global onload callback
20
+ if (document.getElementById(SCRIPT_ID)) {
21
+ // API was already requested
22
+ return mountPromise;
23
+ } // Create global onload callback
15
24
 
16
- window.hcaptchaOnLoad = function () {
17
- // Iterate over onload listeners, call each listener
18
- onLoadListeners = onLoadListeners.filter(function (listener) {
19
- listener();
20
- return false;
21
- });
22
- };
23
25
 
26
+ window[HCAPTCHA_LOAD_FN_NAME] = resolveFn;
24
27
  var domain = params.apihost || "https://js.hcaptcha.com";
25
28
  delete params.apihost;
26
29
  var script = document.createElement("script");
27
- script.src = domain + "/1/api.js?render=explicit&onload=hcaptchaOnLoad";
30
+ script.id = SCRIPT_ID;
31
+ script.src = domain + "/1/api.js?render=explicit&onload=" + HCAPTCHA_LOAD_FN_NAME;
28
32
  script.async = true;
33
+
34
+ script.onerror = function (event) {
35
+ return rejectFn('script-error');
36
+ };
37
+
29
38
  var query = generateQuery(params);
30
39
  script.src += query !== "" ? "&" + query : "";
31
40
  document.head.appendChild(script);
41
+ return mountPromise;
32
42
  };
33
43
 
34
44
  var HCaptcha = /*#__PURE__*/function (_React$Component) {
@@ -65,7 +75,7 @@ var HCaptcha = /*#__PURE__*/function (_React$Component) {
65
75
  var _proto = HCaptcha.prototype;
66
76
 
67
77
  _proto.componentDidMount = function componentDidMount() {
68
- //Once captcha is mounted intialize hCaptcha - hCaptcha
78
+ // Once captcha is mounted intialize hCaptcha - hCaptcha
69
79
  var _this$props = this.props,
70
80
  apihost = _this$props.apihost,
71
81
  assethost = _this$props.assethost,
@@ -80,13 +90,8 @@ var HCaptcha = /*#__PURE__*/function (_React$Component) {
80
90
  var isApiReady = this.state.isApiReady;
81
91
 
82
92
  if (!isApiReady) {
83
- //Check if hCaptcha has already been loaded, if not create script tag and wait to render captcha
84
- if (apiScriptRequested) {
85
- return;
86
- } // Only create the script tag once, use a global variable to track
87
-
88
-
89
- mountCaptchaScript({
93
+ // Check if hCaptcha has already been loaded, if not create script tag and wait to render captcha
94
+ var mountParams = {
90
95
  apihost: apihost,
91
96
  assethost: assethost,
92
97
  endpoint: endpoint,
@@ -97,9 +102,9 @@ var HCaptcha = /*#__PURE__*/function (_React$Component) {
97
102
  reportapi: reportapi,
98
103
  sentry: sentry,
99
104
  custom: custom
100
- }); // Add onload callback to global onload listeners
105
+ }; // Only create the script tag once, use a global promise to track
101
106
 
102
- onLoadListeners.push(this.handleOnLoad);
107
+ mountCaptchaScript(mountParams).then(this.handleOnLoad)["catch"](this.handleError);
103
108
  } else {
104
109
  this.renderCaptcha();
105
110
  }
@@ -238,12 +243,11 @@ var HCaptcha = /*#__PURE__*/function (_React$Component) {
238
243
  var onError = this.props.onError;
239
244
  var captchaId = this.state.captchaId;
240
245
 
241
- if (!this.isReady()) {
242
- return;
246
+ if (this.isReady()) {
247
+ // If hCaptcha runs into error, reset captcha - hCaptcha
248
+ hcaptcha.reset(captchaId);
243
249
  }
244
250
 
245
- hcaptcha.reset(captchaId); // If hCaptcha runs into error, reset captcha - hCaptcha
246
-
247
251
  if (onError) onError(event);
248
252
  };
249
253
 
package/dist/index.js CHANGED
@@ -31,30 +31,41 @@ function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflec
31
31
 
32
32
  function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
33
33
 
34
- // Create script to init hCaptcha
35
- var onLoadListeners = [];
36
- var apiScriptRequested = false; // Generate hCaptcha API Script
34
+ var SCRIPT_ID = 'hcaptcha-api-script-id';
35
+ var HCAPTCHA_LOAD_FN_NAME = 'hcaptchaOnLoad'; // Prevent loading API script multiple times
36
+
37
+ var resolveFn;
38
+ var rejectFn;
39
+ var mountPromise = new Promise(function (resolve, reject) {
40
+ resolveFn = resolve;
41
+ rejectFn = reject;
42
+ }); // Generate hCaptcha API script
37
43
 
38
44
  var mountCaptchaScript = function mountCaptchaScript() {
39
45
  var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
40
- apiScriptRequested = true; // Create global onload callback
41
-
42
- window.hcaptchaOnLoad = function () {
43
- // Iterate over onload listeners, call each listener
44
- onLoadListeners = onLoadListeners.filter(function (listener) {
45
- listener();
46
- return false;
47
- });
48
- };
49
46
 
47
+ if (document.getElementById(SCRIPT_ID)) {
48
+ // API was already requested
49
+ return mountPromise;
50
+ } // Create global onload callback
51
+
52
+
53
+ window[HCAPTCHA_LOAD_FN_NAME] = resolveFn;
50
54
  var domain = params.apihost || "https://js.hcaptcha.com";
51
55
  delete params.apihost;
52
56
  var script = document.createElement("script");
53
- script.src = "".concat(domain, "/1/api.js?render=explicit&onload=hcaptchaOnLoad");
57
+ script.id = SCRIPT_ID;
58
+ script.src = "".concat(domain, "/1/api.js?render=explicit&onload=").concat(HCAPTCHA_LOAD_FN_NAME);
54
59
  script.async = true;
60
+
61
+ script.onerror = function (event) {
62
+ return rejectFn('script-error');
63
+ };
64
+
55
65
  var query = (0, _utils.generateQuery)(params);
56
66
  script.src += query !== "" ? "&".concat(query) : "";
57
67
  document.head.appendChild(script);
68
+ return mountPromise;
58
69
  };
59
70
 
60
71
  var HCaptcha = /*#__PURE__*/function (_React$Component) {
@@ -94,7 +105,7 @@ var HCaptcha = /*#__PURE__*/function (_React$Component) {
94
105
  (0, _createClass2["default"])(HCaptcha, [{
95
106
  key: "componentDidMount",
96
107
  value: function componentDidMount() {
97
- //Once captcha is mounted intialize hCaptcha - hCaptcha
108
+ // Once captcha is mounted intialize hCaptcha - hCaptcha
98
109
  var _this$props = this.props,
99
110
  apihost = _this$props.apihost,
100
111
  assethost = _this$props.assethost,
@@ -109,13 +120,8 @@ var HCaptcha = /*#__PURE__*/function (_React$Component) {
109
120
  var isApiReady = this.state.isApiReady;
110
121
 
111
122
  if (!isApiReady) {
112
- //Check if hCaptcha has already been loaded, if not create script tag and wait to render captcha
113
- if (apiScriptRequested) {
114
- return;
115
- } // Only create the script tag once, use a global variable to track
116
-
117
-
118
- mountCaptchaScript({
123
+ // Check if hCaptcha has already been loaded, if not create script tag and wait to render captcha
124
+ var mountParams = {
119
125
  apihost: apihost,
120
126
  assethost: assethost,
121
127
  endpoint: endpoint,
@@ -126,9 +132,9 @@ var HCaptcha = /*#__PURE__*/function (_React$Component) {
126
132
  reportapi: reportapi,
127
133
  sentry: sentry,
128
134
  custom: custom
129
- }); // Add onload callback to global onload listeners
135
+ }; // Only create the script tag once, use a global promise to track
130
136
 
131
- onLoadListeners.push(this.handleOnLoad);
137
+ mountCaptchaScript(mountParams).then(this.handleOnLoad)["catch"](this.handleError);
132
138
  } else {
133
139
  this.renderCaptcha();
134
140
  }
@@ -277,12 +283,11 @@ var HCaptcha = /*#__PURE__*/function (_React$Component) {
277
283
  var onError = this.props.onError;
278
284
  var captchaId = this.state.captchaId;
279
285
 
280
- if (!this.isReady()) {
281
- return;
286
+ if (this.isReady()) {
287
+ // If hCaptcha runs into error, reset captcha - hCaptcha
288
+ hcaptcha.reset(captchaId);
282
289
  }
283
290
 
284
- hcaptcha.reset(captchaId); // If hCaptcha runs into error, reset captcha - hCaptcha
285
-
286
291
  if (onError) onError(event);
287
292
  }
288
293
  }, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hcaptcha/react-hcaptcha",
3
- "version": "1.4.1",
3
+ "version": "1.4.2",
4
4
  "types": "types/index.d.ts",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/esm/index.js",
package/src/index.js CHANGED
@@ -1,34 +1,42 @@
1
1
  import * as React from 'react';
2
2
  import { generateQuery } from "./utils.js";
3
3
 
4
- // Create script to init hCaptcha
5
- let onLoadListeners = [];
6
- let apiScriptRequested = false;
7
-
8
- // Generate hCaptcha API Script
4
+ const SCRIPT_ID = 'hcaptcha-api-script-id';
5
+ const HCAPTCHA_LOAD_FN_NAME = 'hcaptchaOnLoad';
6
+
7
+ // Prevent loading API script multiple times
8
+ let resolveFn;
9
+ let rejectFn;
10
+ const mountPromise = new Promise((resolve, reject) => {
11
+ resolveFn = resolve;
12
+ rejectFn = reject;
13
+ });
14
+
15
+ // Generate hCaptcha API script
9
16
  const mountCaptchaScript = (params={}) => {
10
- apiScriptRequested = true;
17
+ if (document.getElementById(SCRIPT_ID)) {
18
+ // API was already requested
19
+ return mountPromise;
20
+ }
21
+
11
22
  // Create global onload callback
12
- window.hcaptchaOnLoad = () => {
13
- // Iterate over onload listeners, call each listener
14
- onLoadListeners = onLoadListeners.filter(listener => {
15
- listener();
16
- return false;
17
- });
18
- };
23
+ window[HCAPTCHA_LOAD_FN_NAME] = resolveFn;
19
24
 
20
25
  const domain = params.apihost || "https://js.hcaptcha.com";
21
26
  delete params.apihost;
22
27
 
23
28
  const script = document.createElement("script");
24
- script.src = `${domain}/1/api.js?render=explicit&onload=hcaptchaOnLoad`;
29
+ script.id = SCRIPT_ID;
30
+ script.src = `${domain}/1/api.js?render=explicit&onload=${HCAPTCHA_LOAD_FN_NAME}`;
25
31
  script.async = true;
32
+ script.onerror = (event) => rejectFn('script-error');
26
33
 
27
34
  const query = generateQuery(params);
28
35
  script.src += query !== ""? `&${query}` : "";
29
36
 
30
37
  document.head.appendChild(script);
31
- }
38
+ return mountPromise;
39
+ };
32
40
 
33
41
 
34
42
  class HCaptcha extends React.Component {
@@ -62,17 +70,12 @@ class HCaptcha extends React.Component {
62
70
  }
63
71
  }
64
72
 
65
- componentDidMount () { //Once captcha is mounted intialize hCaptcha - hCaptcha
73
+ componentDidMount () { // Once captcha is mounted intialize hCaptcha - hCaptcha
66
74
  const { apihost, assethost, endpoint, host, imghost, languageOverride:hl, reCaptchaCompat, reportapi, sentry, custom } = this.props;
67
75
  const { isApiReady } = this.state;
68
76
 
69
- if (!isApiReady) { //Check if hCaptcha has already been loaded, if not create script tag and wait to render captcha
70
- if (apiScriptRequested) {
71
- return;
72
- }
73
-
74
- // Only create the script tag once, use a global variable to track
75
- mountCaptchaScript({
77
+ if (!isApiReady) { // Check if hCaptcha has already been loaded, if not create script tag and wait to render captcha
78
+ const mountParams = {
76
79
  apihost,
77
80
  assethost,
78
81
  endpoint,
@@ -83,10 +86,12 @@ class HCaptcha extends React.Component {
83
86
  reportapi,
84
87
  sentry,
85
88
  custom
86
- });
89
+ };
87
90
 
88
- // Add onload callback to global onload listeners
89
- onLoadListeners.push(this.handleOnLoad);
91
+ // Only create the script tag once, use a global promise to track
92
+ mountCaptchaScript(mountParams)
93
+ .then(this.handleOnLoad)
94
+ .catch(this.handleError);
90
95
  } else {
91
96
  this.renderCaptcha();
92
97
  }
@@ -214,11 +219,11 @@ class HCaptcha extends React.Component {
214
219
  const { onError } = this.props;
215
220
  const { captchaId } = this.state;
216
221
 
217
- if (!this.isReady()) {
218
- return;
222
+ if (this.isReady()) {
223
+ // If hCaptcha runs into error, reset captcha - hCaptcha
224
+ hcaptcha.reset(captchaId);
219
225
  }
220
226
 
221
- hcaptcha.reset(captchaId) // If hCaptcha runs into error, reset captcha - hCaptcha
222
227
  if (onError) onError(event);
223
228
  }
224
229