PageSourceSearch

https://jenshartmann.eu/wp-content/plugins/frymo/inc/elementor/assets/js/frymo-revocation-button.js?ver=1.42.0

js jenshartmann.eu collected 2026-10-07 05:49:29 UTC 16,585 bytes, 423 lines download raw bytes

1/**
2 * Revocation button widget frontend handler.
3 */
4var FRMRevocationButtonHandler = function ($scope, $) {
5    var readyClass = 'frymo-revocation-button-js-ready';
6    var isEditor = $('body').hasClass('elementor-editor-active');
7    var modalWasOpen = $scope.data('frymo-revocation-modal-open') === true;
8    var $modal = $scope.find('.frymo-revocation-form-modal');
9    var $button = $scope.find('.frymo-show-revocation-form');
10    var $form = $scope.find('form.frymo-revocation-form');
11    var isPopup = $modal.data('display') !== 'inline';
12
13    if ($scope.hasClass(readyClass)) {
14        if (!isEditor) {
15            return;
16        }
17
18        $button.off('click');
19        $form.off('submit');
20        $scope.off('.frymoRevocationCaptcha');
21        $modal.off('.revocationModal');
22        $modal.find('.frymo-contact-form-wrapper').off('.revocationModal');
23        $modal.find('.frymo-contact-form-close').off('.revocationModal');
24    }
25
26    $scope.addClass(readyClass);
27
28    if (isPopup) {
29        $button.on('click', function (e) {
30            e.preventDefault();
31            e.stopPropagation();
32            showModal();
33        });
34    }
35
36    function moveModalToBody() {
37        if (!isPopup || !$modal.length || $modal.parent().is('body')) {
38            return;
39        }
40
41        $modal.appendTo(document.body);
42    }
43
44    function showModal() {
45        if (!isPopup) {
46            return;
47        }
48
49        $scope.data('frymo-revocation-modal-open', true);
50        moveModalToBody();
51        $modal.css({ display: 'flex' });
52
53        $modal.find('.frymo-contact-form-wrapper').off('.revocationModal').on('click.revocationModal', function (e) {
54            e.stopPropagation();
55        });
56
57        $modal.off('.revocationModal').on('click.revocationModal', function (e) {
58            e.stopPropagation();
59            hideModal();
60        });
61
62        $modal.find('.frymo-contact-form-close').off('.revocationModal').on('click.revocationModal', function (e) {
63            e.stopPropagation();
64            hideModal();
65        });
66    }
67
68    function hideModal() {
69        if (!isPopup) {
70            return;
71        }
72
73        $scope.data('frymo-revocation-modal-open', false);
74        $modal.off('.revocationModal');
75        $modal.find('.frymo-contact-form-wrapper').off('.revocationModal');
76        $modal.find('.frymo-contact-form-close').off('.revocationModal');
77        $modal.css({ display: 'none' });
78    }
79
80    function submitRevocationForm() {
81        $form.addClass('frymo-loading');
82        $form.find('.frymo-form-field.error').removeClass('error');
83        $form.find('.field-error-message').text('');
84        $form.find('.form-messages').empty();
85
86        var form_fields = {};
87        $.each($form.serializeArray(), function (index, item) {
88            var $fieldWrap = $form.find('[name="' + item.name + '"]').closest('.frymo-form-field');
89            if (!$fieldWrap.length) {
90                return;
91            }
92
93            if (form_fields[item.name]) {
94                form_fields[item.name].value += '\n' + item.value;
95                return;
96            }
97            form_fields[item.name] = {
98                value: item.value,
99                type: $fieldWrap.data('type') || '',
100                required: $fieldWrap.data('required') || ''
101            };
102        });
103
104        var data = new FormData();
105        data.append('action', 'frymo_revocation_submit');
106
107        var nonce = $form.find('[name="frymo_revocation_nonce"]').val();
108        if (nonce) {
109            data.append('frymo_revocation_nonce', nonce);
110        }
111
112        $.each(['object_post_id', 'template_id', 'element_id', 'page_url'], function (i, hiddenName) {
113            var val = $form.find('[name="' + hiddenName + '"]').val();
114            if (val) {
115                data.append(hiddenName, val);
116            }
117        });
118
119        $.each(form_fields, function (fieldName, fieldData) {
120            data.append('form_fields[' + fieldName + '][value]', fieldData.value);
121            data.append('form_fields[' + fieldName + '][type]', fieldData.type || '');
122            data.append('form_fields[' + fieldName + '][required]', fieldData.required || '');
123        });
124
125        if (typeof frymo === 'undefined' || !frymo || !frymo.ajaxurl) {
126            $form.find('.form-messages').append('<div class="error">Form cannot be submitted. Please refresh the page.</div>');
127            $form.removeClass('frymo-loading');
128            return;
129        }
130
131        $.ajax({
132            url: frymo.ajaxurl,
133            method: 'POST',
134            data: data,
135            processData: false,
136            contentType: false
137        })
138            .always(function () {
139                $form.removeClass('frymo-loading');
140            })
141            .fail(function () {
142                $form.find('.form-messages').append('<div class="error">Server error</div>');
143            })
144            .done(function (response) {
145                if (!response || typeof response.data !== 'object') {
146                    $form.find('.form-messages').append('<div class="error">Invalid response. Please try again.</div>');
147                    return;
148                }
149
150                var messages = response.data.messages || [];
151                $.each(messages, function (index, item) {
152                    $form.find('.form-messages').append('<div class="' + item.type + '">' + item.text + '</div>');
153                    if (item.field) {
154                        var $field = $form.find('[name="' + item.field + '"]').closest('.frymo-form-field');
155                        $field.addClass('error');
156                        $field.find('.field-error-message').text(item.text);
157                    } else if (item.type === 'error' && item.text) {
158                        var $mathCaptcha = $form.find('.frymo-math-captcha');
159                        if ($mathCaptcha.length && window.frymoIsCaptchaErrorMessage(item.text)) {
160                            $mathCaptcha.addClass('error').find('.field-error-message').text(item.text);
161                            regenerateCaptcha($mathCaptcha);
162                        }
163                        $form.find('.frymo-altcha, .frymo-friendlycaptcha, .frymo-recaptcha-v3').addClass('error').find('.field-error-message').text(item.text);
164                    }
165                });
166
167                if (response.success === true) {
168                    $form.addClass('is-success-hide');
169                    $form.find('.frymo-contact-form-submission-content').attr('aria-hidden', 'true').stop(true, true).slide
169Up(250);
170                }
171            });
172    }
173
174    function regenerateCaptcha($captchaField) {
175        if (isEditor) {
176            return;
177        }
178
179        var $input = $captchaField.find('.frymo-captcha-input');
180        var $question = $captchaField.find('.frymo-captcha-question');
181        var $hiddenId = $captchaField.find('input[name="frymo_captcha_id"]');
182        var $errorMessage = $captchaField.find('.field-error-message');
183
184        $input.val('');
185        $errorMessage.text('');
186        $captchaField.removeClass('error');
187        $question.text('...');
188
189        var ajaxUrl = (typeof frymo !== 'undefined' && frymo && frymo.ajaxurl) ? frymo.ajaxurl : '';
190        if (!ajaxUrl) {
191            $question.text(window.frymoCaptchaString('loadError'));
192            return;
193        }
194
195        $.post(ajaxUrl, { action: 'frymo_regenerate_captcha' }, function (response) {
196            if (response && response.success && response.data && response.data.question !== undefined && response.data.captcha_id !== undefined) {
197                $question.text(response.data.question);
198                $hiddenId.val(response.data.captcha_id);
199            } else {
200                $question.text(window.frymoCaptchaString('loadError'));
201            }
202        }).fail(function () {
203            $question.text(window.frymoCaptchaString('loadError'));
204        });
205    }
206
207    function initMathCaptcha() {
208        var $captchaFields = $scope.find('.frymo-math-captcha');
209        if (!$captchaFields.length) {
210            return;
211        }
212
213        if (!isEditor) {
214            $captchaFields.each(function () {
215                regenerateCaptcha($(this));
216            });
217        }
218
219        $scope.off('click.frymoRevocationCaptcha', '.frymo-captcha-refresh');
220        $scope.on('click.frymoRevocationCaptcha', '.frymo-captcha-refresh', function (e) {
221            e.preventDefault();
222            regenerateCaptcha($(this).closest('.frymo-math-captcha'));
223        });
224    }
225
226    function initAltcha() {
227        if (isEditor) {
228            return;
229        }
230
231        $scope.find('.frymo-altcha').each(function () {
232            var $wrapper = $(this);
233            var widgetEl = $wrapper[0].querySelector('altcha-widget');
234            if (!widgetEl) {
235                return;
236            }
237
238            var $tokenInput = $wrapper.find('.altcha-token-input');
239
240            widgetEl.addEventListener('statechange', function (ev) {
241                if (ev.detail && ev.detail.state === 'verified' && ev.detail.payload) {
242                    $tokenInput.val(ev.detail.payload);
243                    $wrapper.removeClass('error').find('.field-error-message').text('');
244                } else if (ev.detail && ev.detail.state === 'error') {
245                    $wrapper.addClass('error');
246                    $wrapper.find('.field-error-message').text(window.frymoCaptchaString('verificationFailed'));
247                } else if (ev.detail && ev.detail.state === 'expired') {
248                    $tokenInput.val('');
249                    $wrapper.addClass('error');
250                    $wrapper.find('.field-error-message').text(window.frymoCaptchaString('verificationExpired'));
251                }
252            });
253
254            widgetEl.addEventListener('verified', function (ev) {
255                if (ev.detail && ev.detail.payload) {
256                    $tokenInput.val(ev.detail.payload);
257                    $wrapper.removeClass('error').find('.field-error-message').text('');
258                }
259            });
260        });
261    }
262
263    function initFriendlyCaptcha() {
264        if (isEditor) {
265            return;
266        }
267
268        $scope.find('.frymo-friendlycaptcha .frc-captcha[data-sitekey]').each(function () {
269            var $widget = $(this);
270            var $tokenInput = $widget.closest('.frymo-friendlycaptcha').find('.frc-captcha-response-input');
271
272            $widget[0].addEventListener('frc:widget.complete', function (event) {
273                if (event.detail && event.detail.response) {
274                    $tokenInput.val(event.detail.response);
275                    $widget.closest('.frymo-friendlycaptcha').removeClass('error').find('.field-error-message').text('');
276                }
277            });
278
279            $widget[0].addEventListener('frc:widget.error', function () {
280                $widget.closest('.frymo-friendlycaptcha').addClass('error');
281            });
282
283            $widget[0].addEventListener('frc:widget.expire', function () {
284                $tokenInput.val('');
285                $widget.closest('.frymo-friendlycaptcha').find('.field-error-message').text(window.frymoCaptchaString('verificationExpired'));
286            });
287        });
288    }
289
290    function validateCaptchaBeforeSubmit() {
291        $form.find('.frymo-math-captcha, .frymo-altcha, .frymo-friendlycaptcha, .frymo-recaptcha-v3').removeClass('error').find('.field-error-message').text('');
292
293        var $recaptchaV3 = $form.find('.frymo-recaptcha-v3');
294        var $tokenInput = $recaptchaV3.find('.recaptcha-v3-token-input[data-site-key]');
295        var needsRecaptchaToken = $tokenInput.length && (!$tokenInput.val() || $tokenInput.val() === 'demo_recaptcha_v3_token');
296
297        if (needsRecaptchaToken) {
298            if (typeof grecaptcha === 'undefined') {
299                $recaptchaV3.addClass('error').find('.field-error-message').text(window.frymoCaptchaString('recaptchaNotLoaded'));
300                return false;
301            }
302
303            var siteKey = $tokenInput.data('site-key');
304            grecaptcha.ready(function () {
305                grecaptcha.execute(siteKey, { action: 'submit' }).then(function (token) {
306                    $tokenInput.val(token);
307                    submitRevocationForm();
308                }, function () {
309                    $recaptchaV3.addClass('error').find('.field-error-message').text(window.frymoCaptchaString('verificationFailed'));
310                });
311            });
312            return 'pending';
313        }
314
315        var $altcha = $form.find('.frymo-altcha');
316        if ($altcha.length) {
317            var altchaToken = $altcha.find('.altcha-token-input').val();
318            if (!altchaToken || altchaToken === 'demo_altcha_token') {
319                $altcha.addClass('error').find('.field-error-message').text(window.frymoCaptchaString('waitForVerification'));
320                return false;
321            }
322        }
323
324        var $frc = $form.find('.frymo-friendlycaptcha .frc-captcha[data-sitekey]');
325        if ($frc.length) {
326            var frcToken = $frc.closest('.frymo-friendlycaptcha').find('.frc-captcha-response-input').val();
327            if (!frcToken || frcToken === 'demo_frc_token') {
328                $frc.closest('.frymo-friendlycaptcha').addClass('error').find('.field-error-message').text(window.frymoCaptchaString('waitForVerification'));
329                return false;
330            }
331        }
332
333        var $mathCaptcha = $form.find('.frymo-math-captcha');
334        if ($mathCaptcha.length) {
335            var mathAnswer = $mathCaptcha.find('.frymo-captcha-input').val();
336            if (!mathAnswer || mathAnswer.trim() === '') {
337                $mathCaptcha.addClass('error').find('.field-error-message').text(window.frymoCaptchaString('solveMathProblem'));
338                return false;
339            }
340        }
341
342        return true;
343    }
344
345    $form.on('submit', function (e) {
346        if (isEditor) {
347            return false;
348        }
349        e.preventDefault();
350        e.stopPropagation();
351
352        var captchaResult = validateCaptchaBeforeSubmit();
353        if (captchaResult === false || captchaResult === 'pending') {
354            return false;
355        }
356
357        submitRevocationForm();
358        return false;
359    });
360
361    setTimeout(function () {
362        initMathCaptcha();
363        initAltcha();
364        initFriendlyCaptcha();
365    }, 200);
366
367    if (isEditor) {
368        var elementId = $scope.attr('data-id');
369        var editorEventNamespace = '.frymoRevocation' + elementId;
370        var modalEditorSections = ['section_settings', 'section_modal_styles'];
371        var messageEditorSections = ['section_messages', 'messages_styles'];
372
373        function shouldKeepModalOpen(sectionName) {
374            return isPopup && (modalWasOpen || (sectionName && (modalEditorSections.indexOf(sectionName) !== -1 || messageEditorSections.indexOf(sectionName) !== -1)));
375        }
376
377        function updateEditorMessagesPreview(sectionName) {
378            var shouldShowMessages = sectionName && messageEditorSections.indexOf(sectionName) !== -1;
379            $form.toggleClass('editor-show-messages', !!shouldShowMessages);
380        }
381
382        var activeSection = elementor.getPanelView().getCurrentPageView().activeSection;
383        updateEditorMessagesPreview(activeSection);
384        if (shouldKeepModalOpen(activeSection)) {
385            showModal();
386        }
387
388        elementor.channels.editor.off('section:activated' + editorEventNamespace);
389        elementor.channels.editor.on('section:activated' + editorEventNamespace, function (sectionName, editor) {
390            var editedElement = editor.getOption('editedElementView');
391            if (!editedElement || String(editedElement.model.get('id')) !== String(elementId)) {
392                return;
393            }
394            updateEditorMessagesPreview(sectionName);
395            if (shouldKeepModalOpen(sectionName)) {
396                showModal();
397            }
398        });
399    } else if (modalWasOpen) {
400        showModal();
401    }
402};
403
404(function ($) {
405    var widgetSelectors = '.elementor-widget-frymo-revocation-button';
406
407    function bootRevocationButtons($root) {
408        $root.find(widgetSelectors).each(function () {
409            FRMRevocationButtonHandler($(this), $);
410        });
411    }
412
413    $(window).on('elementor/frontend/init', function () {
414        elementorFrontend.hooks.addAction('frontend/element_ready/frymo-revocation-button.default', FRMRevocationButtonHandler);
415    });
416
417    $(function () {
418        bootRevocationButtons($(document));
419        setTimeout(function () {
420            bootRevocationButtons($(document));
421        }, 500);
422    });
423})(jQuery);

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.