PageSourceSearch

https://tshirtgirl.net/JavaScript/angular-recaptcha.js

js tshirtgirl.net collected 2026-09-27 14:36:10 UTC 15,364 bytes, 416 lines download raw bytes

1/**
2 * @license angular-recaptcha build:2018-05-09
3 * https://github.com/vividcortex/angular-recaptcha
4 * Copyright (c) 2018 VividCortex
5 **/
6
7/*global angular, Recaptcha */ (function (ng) {
8    'use strict';
9
10    ng.module('vcRecaptcha', []);
11
12}(angular));
13
14/*global angular */ (function (ng) {
15    'use strict';
16
17    function throwNoKeyException() {
18        throw new Error('You need to set the "key" attribute to your public reCaptcha key. If you don\'t have a key, please get one from https://www.google.com/recaptcha/admin/create');
19    }
20
21    var app = ng.module('vcRecaptcha');
22
23    /**
24     * An angular service to wrap the reCaptcha API
25     */
26    app.provider('vcRecaptchaService', function () {
27        var provider = this;
28        var config = {};
29        provider.onLoadFunctionName = 'vcRecaptchaApiLoaded';
30
31        /**
32         * Sets the reCaptcha configuration values which will be used by default is not specified in a specific directive instance.
33         *
34         * @since 2.5.0
35         * @param defaults  object which overrides the current defaults object.
36         */
37        provider.setDefaults = function (defaults) {
38            ng.copy(defaults, config);
39        };
40
41        /**
42         * Sets the reCaptcha key which will be used by default is not specified in a specific directive instance.
43         *
44         * @since 2.5.0
45         * @param siteKey  the reCaptcha public key (refer to the README file if you don't know what this is).
46         */
47        provider.setSiteKey = function (siteKey) {
48            config.key = siteKey;
49        };
50
51        /**
52         * Sets the reCaptcha theme which will be used by default is not specified in a specific directive instance.
53         *
54         * @since 2.5.0
55         * @param theme  The reCaptcha theme.
56         */
57        provider.setTheme = function (theme) {
58            config.theme = theme;
59        };
60
61        /**
62         * Sets the reCaptcha stoken which will be used by default is not specified in a specific directive instance.
63         *
64         * @since 2.5.0
65         * @param stoken  The reCaptcha stoken.
66         */
67        provider.setStoken = function (stoken) {
68            config.stoken = stoken;
69        };
70
71        /**
72         * Sets the reCaptcha size which will be used by default is not specified in a specific directive instance.
73         *
74         * @since 2.5.0
75         * @param size  The reCaptcha size.
76         */
77        provider.setSize = function (size) {
78            config.size = size;
79        };
80
81        /**
82         * Sets the reCaptcha type which will be used by default is not specified in a specific directive instance.
83         *
84         * @since 2.5.0
85         * @param type  The reCaptcha type.
86         */
87        provider.setType = function (type) {
88            config.type = type;
89        };
90
91        /**
92         * Sets the reCaptcha language which will be used by default is not specified in a specific directive instance.
93         *
94         * @param lang  The reCaptcha language.
95         */
96        provider.setLang = function (lang) {
97            config.lang = lang;
98        };
99
100        /**
101         * Sets the reCaptcha badge position which will be used by default if not specified in a specific directive instance.
102         *
103         * @param badge  The reCaptcha badge position.
104         */
105        provider.setBadge = function (badge) {
106            config.badge = badge;
107        };
108
109        /**
110         * Sets the reCaptcha configuration values which will be used by default is not specified in a specific directive instance.
111         *
112         * @since 2.5.0
113         * @param onLoadFunctionName  string name which overrides the name of the onload function. Should match what is in the recaptcha script querystring onload value.
114         */
115        provider.setOnLoadFunctionName = function (onLoadFunctionName) {
116            provider.onLoadFunctionName = onLoadFunctionName;
117        };
118
119        provider.$get = ['$rootScope', '$window', '$q', '$document', '$interval', function ($rootScope, $window, $q, $document, $interval) {
120            var deferred = $q.defer(),
121                promise = deferred.promise,
122                instances = {}, recaptcha;
123
124            $window.vcRecaptchaApiLoadedCallback = $window.vcRecaptchaApiLoadedCallback || [];
125
126            var callback = function () {
127                recaptcha = $window.grecaptcha;
128                deferred.resolve(recaptcha);
129            };
130
131            $window.vcRecaptchaApiLoadedCallback.push(callback);
132
133            $window[provider.onLoadFunctionName] = function () {
134                $window.vcRecaptchaApiLoadedCallback.forEach(function (callback) {
135                    callback();
136                });
137            };
138
139
140            function getRecaptcha() {
141                if (!!recaptcha) {
142                    return $q.when(recaptcha);
143                }
144
145                return promise;
146            }
147
148            function validateRecaptchaInstance() {
149                if (!recaptcha) {
150                    throw new Error('reCaptcha has not been loaded yet.');
151                }
152            }
153
154            function isRenderFunctionAvailable() {
155                return ng.isFunction(($window.grecaptcha || {}).render);
156            }
157
158
159            // Check if grecaptcha.render is not defined already.
160            if (isRenderFunctionAvailable()) {
161                callback();
162            } else if ($window.document.querySelector('script[src^="https://www.google.com/recaptcha/api.js"]')) {
163                // wait for script to be loaded.
164                var intervalWait = $interval(function () {
165                    if (isRenderFunctionAvailable()) {
166                        $interval.cancel(intervalWait);
167                        callback();
168                    }
169                }, 25);
170            } else {
171                // Generate link on demand
172                var script = $window.document.createElement('script');
173                script.async = true;
174                script.defer = true;
175                script.src = 'https://www.google.com/recaptcha/api.js?onload=' + provider.onLoadFunctionName + '&render=explicit';
176                $document.find('body')[0].appendChild(script);
177            }
178
179            return {
180
181                /**
182                 * Creates a new reCaptcha object
183                 *
184                 * @param elm  the DOM element where to put the captcha
185                 * @param conf the captcha object configuration
186                 * @throws NoKeyException    if no key is provided in the provider config or the directive instance (via attribute)
187                 */
188                create: function (elm, conf) {
189
190                    conf.sitekey = conf.key || config.key;
191                    conf.theme = conf.theme || config.theme;
192                    conf.stoken = conf.stoken || config.stoken;
193                    conf.size = conf.size || config.size;
194                    conf.type = conf.type || config.type;
195                    conf.hl = conf.lang || config.lang;
196                    conf.badge = conf.badge || config.badge;
197
198                    if (!conf.sitekey) {
199                        throwNoKeyException();
200                    }
201                    return getRecaptcha().then(function (recaptcha) {
202                        var widgetId = recaptcha.render(elm, conf);
203                        instances[widgetId] = elm;
204                        return widgetId;
205                    });
206                },
207
208                /**
209                 * Reloads the reCaptcha
210                 */
211                reload: function (widgetId) {
212                    validateRecaptchaInstance();
213
214                    recaptcha.reset(widgetId);
215
216                    // Let everyone know this widget has been reset.
217                    $rootScope.$broadcast('reCaptchaReset', widgetId);
218                },
219
220                /**
221                 * Executes the reCaptcha
222                 */
223                execute: function (widgetId) {
224                    validateRecaptchaInstance();
225                    console.log(new Date());
226                    recaptcha.execute(widgetId);
227                },
228
229                /**
230                 * Get/Set reCaptcha language
231                 */
232                useLang: function (widgetId, lang) {
233                    var instance = instances[widgetId];
234
235                    if (instance) {
236                        var iframe = instance.querySelector('iframe');
237                        if (lang) {
238                            // Setter
239                            if (iframe && iframe.src) {
240                                var s = iframe.src;
241                                if (/[?&]hl=/.test(s)) {
242                                    s = s.replace(/([?&]hl=)\w+/, '$1' + lang);
243                                } else {
244                                    s += ((s.indexOf('?') === -1) ? '?' : '&') + 'hl=' + lang;
245                                }
246
247                                iframe.src = s;
248                            }
249                        } else {
250                            // Getter
251                            if (iframe && iframe.src && /[?&]hl=\w+/.test(iframe.src)) {
252                                return iframe.src.replace(/.+[?&]hl=(\w+)([^\w].+)?/, '$1');
253                            } else {
254                                return null;
255                            }
256                        }
257                    } else {
258                        throw new Error('reCaptcha Widget ID not exists', widgetId);
259                    }
260                },
261
262                /**
263                 * Gets the response from the reCaptcha widget.
264                 *
265                 * @see https://developers.google.com/recaptcha/docs/display#js_api
266                 *
267                 * @returns {String}
268                 */
269                getResponse: function (widgetId) {
270                    validateRecaptchaInstance();
271                    var resp = recaptcha.getResponse(widgetId);
272                    return resp;
273                },
274
275                /**
276                 * Gets reCaptcha instance and configuration
277                 */
278                getInstance: function (widgetId) {
279                    return instances[widgetId];
280                },
281
282                /**
283                 * Destroy reCaptcha instance.
284                 */
285                destroy: function (widgetId) {
286                    delete instances[widgetId];
287                }
288            };
289
290        }];
291    });
292
293}(angular));
294
295/*global angular, Recaptcha */ (function (ng) {
296    'use strict';
297
298    var app = ng.module('vcRecaptcha');
299
300    app.directive('vcRecaptcha', ['$document', '$timeout', 'vcRecaptchaService', function ($document, $timeout, vcRecaptcha) {
301
302        return {
303            restrict: 'A',
304            require: "?^^form",
305            scope: {
306                response: '=?ngModel',
307                key: '=?',
308                stoken: '=?',
309                theme: '=?',
310                size: '=?',
311                type: '=?',
312                lang: '=?',
313                badge: '=?',
314                tabindex: '=?',
315                required: '=?',
316                onCreate: '&',
317                onSuccess: '&',
318                onExpire: '&'
319            },
320            link: function (scope, elm, attrs, ctrl) {
321                scope.widgetId = null;
322
323                if (ctrl && ng.isDefined(attrs.required)) {
324                    scope.$watch('required', validate);
325                }
326
327                var removeCreationListener = scope.$watch('key', function (key) {
328                    var callback = function (gRecaptchaResponse) {
329                        // Safe $apply
330                        $timeout(function () {
331                            scope.response = gRecaptchaResponse;
332                            validate();
333
334                            // Notify about the response availability
335                            scope.onSuccess({
336                                response: gRecaptchaResponse,
337                                widgetId: scope.widgetId
338                            });
339                        });
340                    };
341
342                    vcRecaptcha.create(elm[0], {
343
344                        callback: callback,
345                        key: key,
346                        stoken: scope.stoken || attrs.stoken || null,
347                        theme: scope.theme || attrs.theme || null,
348                        type: scope.type || attrs.type || null,
349                        lang: scope.lang || attrs.lang || null,
350                        tabindex: scope.tabindex || attrs.tabindex || null,
351                        size: scope.size || attrs.size || null,
352                        badge: scope.badge || attrs.badge || null,
353                        'expired-callback': expired
354
355                    }).then(function (widgetId) {
356                        // The widget has been created
357                        validate();
358                        scope.widgetId = widgetId;
359                        scope.onCreate({
360                            widgetId: widgetId
361                        });
362
363                        scope.$on('$destroy', destroy);
364
365                        scope.$on('reCaptchaReset', function (event, resetWidgetId) {
366                            if (ng.isUndefined(resetWidgetId) || widgetId === resetWidgetId) {
367                                scope.response = "";
368                                validate();
369                            }
370                        })
371
372                    });
373
374                    // Remove this listener to avoid creating the widget more than once.
375                    removeCreationListener();
376                });
377
378                function destroy() {
379                    if (ctrl) {
380                        // reset the validity of the form if we were removed
381                        ctrl.$setValidity('recaptcha', null);
382                    }
383
384                    cleanup();
385                }
386
387                function expired() {
388                    // Safe $apply
389                    $timeout(function () {
390                        scope.response = "";
391                        validate();
392
393                        // Notify about the response availability
394                        scope.onExpire({
395                            widgetId: scope.widgetId
396                        });
397                    });
398                }
399
400                function validate() {
401                    if (ctrl) {
402                        ctrl.$setValidity('recaptcha', scope.required === false ? null : Boolean(scope.response));
403                    }
404                }
405
406                function cleanup() {
407                    vcRecaptcha.destroy(scope.widgetId);
408
409                    // removes elements reCaptcha added.
410                    ng.element($document[0].querySelectorAll('.pls-container')).parent().remove();
411                }
412            }
413        };
414    }]);
415
416}(angular));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.