view/base/web/js/invisible-captcha.js   A
last analyzed

Complexity

Total Complexity 29
Complexity/F 1.71

Size

Lines of Code 181
Function Count 17

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 92
c 0
b 0
f 0
dl 0
loc 181
rs 10
wmc 29
mnd 12
bc 12
fnc 17
bpm 0.7058
cpm 1.7058
noi 1
1
/**
2
 * Copyright (c) 2019. Volodymyr Hryvinskyi.  All rights reserved.
3
 * @author: <mailto:[email protected]>
4
 * @github: <https://github.com/hryvinskyi>
5
 */
6
7
define([
8
    'jquery',
9
    'ko',
10
    'uiComponent',
11
    './model/invisible-captcha'
12
], function ($, ko, Component, invisibleCaptcha) {
13
    'use strict';
14
15
    return Component.extend({
16
        defaults: {
17
            template: 'Hryvinskyi_InvisibleCaptcha/invisible-captcha',
18
            action: '',
19
            captchaId: '',
20
            lazyLoad: false
21
        },
22
        _initializedForms: [],
23
24
        /**
25
         * Initialization
26
         */
27
        initialize: function () {
28
            this._super();
29
            this._loadGoogleApi();
30
        },
31
32
        /**
33
         * Initialize Google ReCaptca Script
34
         *
35
         * @private
36
         */
37
        _loadGoogleApi: function () {
38
            var self = this;
39
40
            if (invisibleCaptcha.isApiLoad() === true) {
41
                $(window).trigger('recaptcha_api_ready_' + self.captchaId);
42
43
                return;
44
            }
45
46
            window.onloadCallbackGoogleRecapcha = function () {
47
                invisibleCaptcha.isApiLoaded(true);
48
                invisibleCaptcha.initializeForms.each(function (item) {
49
                    self._initializeTokenField(item.element, item.self);
50
                });
51
52
                $(window).trigger('recaptcha_api_ready_' + self.captchaId);
53
            };
54
55
            if (self.lazyLoad === false) {
56
                self._loadRecaptchaScript();
57
            }
58
        },
59
60
        /**
61
         * Load google recaptcha main script
62
         *
63
         * @private
64
         */
65
        _loadRecaptchaScript: function () {
66
            if (invisibleCaptcha.isApiLoaded() === false) {
67
                require([
68
                    'https://www.google.com/recaptcha/api.js?onload=onloadCallbackGoogleRecapcha&render=' + this.siteKey
69
                ]);
70
71
                invisibleCaptcha.isApiLoad(true);
72
            }
73
        },
74
75
        /**
76
         * Create form input token
77
         *
78
         * @private
79
         */
80
        _createToken: function (token, element, self) {
81
            $(element).find('[name="hryvinskyi_invisible_token"]').remove();
82
            var tokenField = $('<input type="hidden" name="hryvinskyi_invisible_token" />'),
83
                action = self.action;
84
85
            tokenField.val(token);
86
            tokenField.attr('data-action', action);
87
            $(element).append(tokenField);
88
            invisibleCaptcha.initializedForms.push(self.captchaId);
89
        },
90
91
        /**
92
         * Loads google API and triggers event, when loaded
93
         *
94
         * @private
95
         */
96
        _initializeTokenField: function (element, self) {
97
            if (invisibleCaptcha.initializedForms.indexOf(self.captchaId) === -1) {
98
                var execute = function () {
99
                    window.grecaptcha
100
                        .execute(self.siteKey, {action: self.action})
101
                        .then(function (token) {
102
                            $.proxy(self._createToken(token, element, self));
103
                        });
104
                };
105
106
                window.grecaptcha.ready(execute);
107
                setInterval(execute, 90 * 1000);
108
            }
109
        },
110
111
        /**
112
         * Initialize recaptcha
113
         *
114
         * @param {Dom} element
115
         * @param {Object} self
116
         */
117
        initializeCaptcha: function (element, self) {
118
            var form = $(element).closest('form');
119
120
            form.on('submit', function (e) {
0 ignored issues
show
Unused Code introduced by
The parameter e is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
121
                setTimeout(function () {
122
                    if (invisibleCaptcha.initializedForms.indexOf(self.captchaId) !== -1) {
123
                        invisibleCaptcha.initializedForms.remove(self.captchaId);
124
                    }
125
126
                    self._initializeTokenField(element, self);
127
                }, 0);
128
129
                return true;
130
            });
131
132
            if (self.lazyLoad === true) {
133
                form.on('focus blur change', ':input', $.proxy(self._loadRecaptchaScript, self));
134
135
                // Disable submit form
136
                form.on('click', ':submit', function (e) {
137
                    if (
138
                        !form.data('needSubmit') &&
139
                        (
140
                            invisibleCaptcha.isApiLoaded() === false ||
141
                            invisibleCaptcha.initializedForms().indexOf(self.captchaId) === -1
142
                        )
143
                    ) {
144
                        form.data('needSubmit', true);
145
                        e.preventDefault();
146
                    }
147
                });
148
149
                form.submit(function (e) {
150
                    if (
151
                        !form.data('needSubmit') &&
152
                        (
153
                            invisibleCaptcha.isApiLoaded() === false ||
154
                            invisibleCaptcha.initializedForms().indexOf(self.captchaId) === -1
155
                        )
156
                    ) {
157
                        form.data('needSubmit', true);
158
                        e.preventDefault();
159
                    }
160
                });
161
162
                // Submit form after recaptcha loaded
163
                invisibleCaptcha.initializedForms.subscribe(function (newValue) {
164
                    if (form.data('needSubmit') === true && newValue.indexOf(self.captchaId) !== -1 && invisibleCaptcha.isApiLoaded() === true) {
165
                        form.submit();
166
                        form.data('needSubmit', null);
167
                    }
168
                });
169
170
                if (form.attr('onsubmit') !== undefined) {
171
                    form.attr('onsubmit', form.attr('onsubmit').replace(/^.{13}/, ''));
172
                }
173
                form.removeClass('hryvinskyi-recaptcha-disabled-submit');
174
            }
175
176
            if ((invisibleCaptcha.isApiLoad() === true || self.lazyLoad === true) && invisibleCaptcha.isApiLoaded() !== true) {
177
                invisibleCaptcha.initializeForms.push({'element': element, self: self});
178
            } else if (invisibleCaptcha.isApiLoaded() === true) {
179
                self._initializeTokenField(element, self);
180
            } else {
181
                $(window).on('recaptcha_api_ready_' + self.captchaId, function () {
182
                    self._initializeTokenField(element, self);
183
                });
184
            }
185
        }
186
    });
187
});
188