PageSourceSearch

https://habitatireland.org/scripts/angular-recaptcha.js

js habitatireland.org collected 2026-10-07 15:38:11 UTC 14,862 bytes, 407 lines download raw bytes

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