PageSourceSearch

https://www.avanta-nsk.ru/wp-content/plugins/zakonnye-kuki/assets/js/forms.js?ver=1.0.4

js avanta-nsk.ru collected 2026-10-06 00:10:40 UTC 21,106 bytes, 468 lines download raw bytes

1(function () {
2  'use strict';
3  if (!window.ZKFormsCore || !window.zkFormsConfig) return;
4
5  var core = window.ZKFormsCore;
6  var cfg = window.zkFormsConfig;
7  var processedSignatures = new Set();
8  var BUILTIN_EXCLUDE_SELECTORS = ['#loginform', '#lostpasswordform', '#resetpassform'];
9
10  function sourceOf(form) {
11    if (form && form.id === 'registerform') return 'wordpress-registration';
12    var c = ' ' + String(form.className || '') + ' ';
13    if (c.indexOf(' wpcf7-form ') !== -1 || form.closest('.wpcf7')) return 'cf7';
14    if (c.indexOf(' wpforms-form ') !== -1 || form.closest('.wpforms-container')) return 'wpforms';
15    if (c.indexOf(' elementor-form ') !== -1 || form.closest('.elementor-form-fields-wrapper')) return 'elementor';
16    if (c.indexOf(' gform_wrapper ') !== -1 || form.closest('.gform_wrapper')) return 'gravity';
17    if (c.indexOf(' frm-show-form ') !== -1 || form.closest('.frm_forms')) return 'formidable';
18    if (c.indexOf(' forminator-custom-form ') !== -1 || form.closest('.forminator-ui')) return 'forminator';
19    if (c.indexOf(' fluent_form_') !== -1 || form.closest('.fluentform')) return 'fluent';
20    if (form.closest('.nf-form-cont')) return 'ninja';
21    return 'generic';
22  }
23
24  function labelText(input) {
25    var chunks = [];
26    if (input.labels) Array.prototype.forEach.call(input.labels, function (label) { chunks.push(label.textContent || ''); });
27    var closest = input.closest && input.closest('label');
28    if (closest) chunks.push(closest.textContent || '');
29    if (input.getAttribute('aria-label')) chunks.push(input.getAttribute('aria-label'));
30    if (input.placeholder) chunks.push(input.placeholder);
31    return chunks.join(' ');
32  }
33
34  function describeFields(form) {
35    return Array.prototype.map.call(form.querySelectorAll('input, textarea, select'), function (el) {
36      var type = (el.getAttribute('type') || el.tagName || 'text').toLowerCase();
37      if (el.tagName && el.tagName.toLowerCase() === 'textarea') type = 'textarea';
38      return {
39        type: type,
40        name: el.getAttribute('name') || '',
41        label: labelText(el),
42        required: !!(el.required || el.getAttribute('aria-required') === 'true')
43      };
44    });
45  }
46
47  function describeExistingConsents(form) {
48    return Array.prototype.map.call(form.querySelectorAll('input[type="checkbox"]'), function (el) {
49      return {
50        type: 'checkbox',
51        name: el.getAttribute('name') || '',
52        label: labelText(el),
53        required: !!(el.required || el.getAttribute('aria-required') === 'true'),
54        checked: !!el.checked,
55        element: el
56      };
57    });
58  }
59
60  function submitText(form) {
61    var btn = form.querySelector('button[type="submit"], input[type="submit"], button:not([type])');
62    if (!btn) return '';
63    return btn.value || btn.textContent || '';
64  }
65
66  function describeForm(form) {
67    var heading = '';
68    var labelled = form.getAttribute('aria-label') || '';
69    var titleEl = form.querySelector('h1,h2,h3,h4,.form-title,.wpforms-title,.gform_title');
70    if (titleEl) heading = titleEl.textContent || '';
71    var source = sourceOf(form);
72    var formId = form.getAttribute('data-formid') || form.id || form.getAttribute('name') || '';
73    if (source === 'ninja') {
74      var nfContainer = form.closest('.nf-form-cont');
75      if (nfContainer && nfContainer.getAttribute('data-form-id')) formId = nfContainer.getAttribute('data-form-id');
76    }
77    return {
78      source: source,
79      id: formId,
80      title: [labelled, heading].join(' '),
81      action: form.getAttribute('action') || '',
82      submitText: submitText(form),
83      fields: describeFields(form)
84    };
85  }
86
87  function selectorMatches(form) {
88    var result = { forced: false, excluded: false };
89    BUILTIN_EXCLUDE_SELECTORS.forEach(function (selector) {
90      try { if (form.matches(selector) || form.closest(selector)) result.excluded = true; } catch (e) {}
91    });
92    (cfg.forceSelectors || []).forEach(function (selector) {
93      try { if (form.matches(selector) || form.closest(selector)) result.forced = true; } catch (e) {}
94    });
95    (cfg.excludeSelectors || []).forEach(function (selector) {
96      try { if (form.matches(selector) || form.closest(selector)) result.excluded = true; } catch (e) {}
97    });
98    return result;
99  }
100
101  function applyDefaultBasis(profile) {
102    if (profile.purpose === 'contact' && cfg.defaultBasis === 'contract' && !profile.sensitiveRisk) {
103      profile.basis = 'contract';
104      profile.requiresPdConsent = false;
105      profile.reason = 'admin-default-contract';
106    }
107    return profile;
108  }
109
110  function normalizeUrl(url) {
111    try {
112      var u = new URL(url, window.location.href);
113      u.hash = '';
114      u.hostname = u.hostname.toLowerCase();
115      u.pathname = u.pathname === '/' ? '/' : u.pathname.replace(/\/+$/, '') + '/';
116      return u.toString();
117    } catch (e) { return ''; }
118  }
119
120  function existingHrefSet(form) {
121    var set = new Set();
122    Array.prototype.forEach.call(form.querySelectorAll('a[href]'), function (a) {
123      var n = normalizeUrl(a.href);
124      if (n) set.add(n);
125    });
126    return set;
127  }
128
129  function legalLinksFor(profile) {
130    var defs = [
131      {url: cfg.privacyPolicyUrl, label: 'Политика обработки персональных данных', kind: 'policy'},
132      {url: cfg.privacyNoticeUrl, label: 'Политика конфиденциальности', kind: 'notice'},
133      {url: cfg.consentUrl, label: 'Согласие на обработку персональных данных', kind: 'consent'}
134    ];
135    var seen = new Set();
136    return defs.filter(function (item) {
137      if (!item.url || (item.kind === 'consent' && profile.basis !== 'consent')) return false;
138      var n = normalizeUrl(item.url);
139      if (!n || seen.has(n)) return false;
140      seen.add(n); return true;
141    });
142  }
143
144  function insertNearSubmit(form, node) {
145    var submit = form.querySelector('button[type="submit"], input[type="submit"], button:not([type])');
146    if (submit && submit.parentNode) submit.parentNode.insertBefore(node, submit);
147    else form.appendChild(node);
148  }
149
150  function createLinks(profile, form) {
151    var links = legalLinksFor(profile);
152    var existing = existingHrefSet(form);
153    var wrap = document.createElement('div');
154    wrap.className = 'zk-form-legal-links';
155    links.forEach(function (item) {
156      var n = normalizeUrl(item.url);
157      if (existing.has(n)) return;
158      if (wrap.childNodes.length) wrap.appendChild(document.createTextNode(' · '));
159      var a = document.createElement('a');
160      a.href = item.url; a.target = '_blank'; a.rel = 'noopener noreferrer'; a.textContent = item.label;
161      wrap.appendChild(a);
162    });
163    return wrap.childNodes.length ? wrap : null;
164  }
165
166  function markExistingConsent(stateEntry, kind, makeRequired) {
167    if (!stateEntry || !stateEntry.field || !stateEntry.field.element) return;
168    var input = stateEntry.field.element;
169    if (makeRequired) {
170      input.required = true;
171      input.setAttribute('aria-required', 'true');
172    }
173    if (core.shouldClearPrecheckedConsent(stateEntry)) input.checked = false;
174    input.setAttribute('data-zk-consent-kind', kind);
175    input.setAttribute('data-zk-existing-consent', '1');
176  }
177
178  function upgradeExistingConsent(stateEntry, kind) {
179    markExistingConsent(stateEntry, kind, true);
180  }
181
182  function normalizePolicyCombined(stateEntry) {
183    if (!stateEntry || !stateEntry.combinedPolicy || !stateEntry.field || !stateEntry.field.element) return;
184    var input = stateEntry.field.element;
185    var label = input.closest('label');
186    if (!label && input.id) label = document.querySelector('label[for="' + CSS.escape(input.id) + '"]');
187    if (!label) return;
188    Array.prototype.slice.call(label.childNodes).forEach(function (child) {
189      if (child !== input) label.removeChild(child);
190    });
191    var span = document.createElement('span');
192    span.textContent = cfg.formConsentText || 'Я согласен на обработку персональных данных.';
193    label.appendChild(span);
194    label.setAttribute('data-zk-normalized-policy-consent', '1');
195  }
196
197  function checkboxDefinition(kind) {
198    if (kind === 'marketing') return {name:'zk_marketing_consent', text:cfg.marketingConsentText};
199    if (kind === 'spread') return {name:'zk_spread_consent', text:cfg.spreadConsentText};
200    return {name:'zk_pd_consent', text:cfg.formConsentText};
201  }
202
203  function addCheckbox(block, kind) {
204    var def = checkboxDefinition(kind);
205    var label = document.createElement('label');
206    label.className = 'zk-form-consent zk-form-consent--' + kind;
207    var input = document.createElement('input');
208    input.type = 'checkbox'; input.name = def.name; input.value = '1'; input.required = true;
209    input.setAttribute('aria-required', 'true'); input.setAttribute('data-zk-consent-kind', kind);
210    var span = document.createElement('span');
211    span.textContent = def.text || '';
212    label.appendChild(input); label.appendChild(span); block.appendChild(label);
213  }
214
215  function randomConsentId() {
216    var bytes = new Uint8Array(16);
217    if (window.crypto && window.crypto.getRandomValues) window.crypto.getRandomValues(bytes);
218    else for (var i = 0; i < bytes.length; i++) bytes[i] = Math.floor(Math.random() * 256);
219    return Array.prototype.map.call(bytes, function (b) { return b.toString(16).padStart(2, '0'); }).join('');
220  }
221
222  function ensureHiddenMeta(form, profile) {
223    var values = {
224      zk_consent_id: randomConsentId(),
225      zk_policy_version: cfg.policyVersion || '1.0',
226      zk_form_basis: profile.basis || 'none'
227    };
228    Object.keys(values).forEach(function (name) {
229      if (form.querySelector('input[name="' + name + '"]')) return;
230      var input = document.createElement('input'); input.type = 'hidden'; input.name = name; input.value = values[name];
231      form.appendChild(input);
232    });
233  }
234
235  function buildComplianceBlock(form, profile, state) {
236    var block = document.createElement('div');
237    block.className = 'zk-form-compliance';
238    block.setAttribute('data-zk-created', '1');
239    if (profile.requiresPdConsent && ['valid','optional'].indexOf(state.pd.state) === -1) addCheckbox(block, 'pd');
240    if (profile.requiresMarketingConsent && ['valid','optional'].indexOf(state.marketing.state) === -1) addCheckbox(block, 'marketing');
241    if (profile.requiresSpreadConsent && ['valid','optional'].indexOf(state.spread.state) === -1) addCheckbox(block, 'spread');
242    var links = createLinks(profile, form);
243    if (links) block.appendChild(links);
244    return block;
245  }
246
247  function appendMissingLegalNotice(form, profile) {
248    if (form.querySelector('.zk-form-compliance .zk-form-legal-links, .zk-form-legal-notice')) return;
249    var links = createLinks(profile, form);
250    if (!links) return;
251    links.classList.add('zk-form-legal-notice');
252    insertNearSubmit(form, links);
253  }
254
255  function ensureError(form, input) {
256    var old = form.querySelector('.zk-form-error');
257    if (old) old.remove();
258    var err = document.createElement('div');
259    err.className = 'zk-form-error'; err.setAttribute('role','alert');
260    err.textContent = 'Необходимо подтвердить требуемое согласие перед отправкой формы.';
261    if (input && input.closest('label')) input.closest('label').insertAdjacentElement('afterend', err);
262    else insertNearSubmit(form, err);
263  }
264
265  function syncExistingConsentProxies(form) {
266    if (!form) return;
267    var fields = Array.prototype.map.call(form.querySelectorAll('[data-zk-existing-consent="1"][data-zk-consent-kind]'), function (input) {
268      return {
269        kind: input.getAttribute('data-zk-consent-kind') || '',
270        name: input.getAttribute('name') || '',
271        checked: !!input.checked
272      };
273    });
274    var payload = core.existingConsentProxyPayload(fields);
275    var technical = {pd:'zk_pd_consent', marketing:'zk_marketing_consent', spread:'zk_spread_consent'};
276    Object.keys(technical).forEach(function (kind) {
277      var name = technical[kind];
278      var proxy = form.querySelector('input[data-zk-consent-proxy="' + kind + '"]');
279      if (!Object.prototype.hasOwnProperty.call(payload, name)) {
280        if (proxy) proxy.remove();
281        return;
282      }
283      if (!proxy) {
284        proxy = document.createElement('input');
285        proxy.type = 'hidden';
286        proxy.name = name;
287        proxy.setAttribute('data-zk-consent-proxy', kind);
288        form.appendChild(proxy);
289      }
290      proxy.value = payload[name];
291    });
292  }
293
294  function syncNinjaExtra(form) {
295    if (!form || sourceOf(form) !== 'ninja') return;
296    var container = form.closest('.nf-form-cont');
297    var formId = container && container.getAttribute('data-form-id');
298    var radio = window.nfRadio || (window.Backbone && window.Backbone.Radio);
299    if (!formId || !radio || typeof radio.channel !== 'function') return;
300    var channel = radio.channel('form-' + formId);
301    if (!channel || typeof channel.request !== 'function') return;
302    function checked(kind) {
303      var field = form.querySelector('[data-zk-consent-kind="' + kind + '"]');
304      return !!(field && field.checked);
305    }
306    function hidden(name) {
307      var input = form.querySelector('input[name="' + name + '"]');
308      return input ? input.value : '';
309    }
310    var extra = core.ninjaExtraPayload({pd:checked('pd'),marketing:checked('marketing'),spread:checked('spread')},{
311      consentId:hidden('zk_consent_id'), policyVersion:hidden('zk_policy_version'), basis:hidden('zk_form_basis')
312    });
313    Object.keys(extra).forEach(function (key) { channel.request('add:extra', key, extra[key]); });
314  }
315
316  function inventoryWarnings(form, descriptor, profile, state) {
317    var warnings = [];
318    try {
319      if (descriptor.action) {
320        var actionUrl = new URL(descriptor.action, window.location.href);
321        if (actionUrl.host && actionUrl.host !== window.location.host) warnings.push('external_endpoint');
322      }
323    } catch (e) {}
324    if (core.hasPrecheckedConsent(state)) warnings.push('prechecked_consent');
325    if (state.pd.state === 'combined' || state.marketing.state === 'combined') warnings.push('combined_marketing_consent');
326    if (profile.basis === 'manual' || profile.confidence === 'low') 
326warnings.push('manual_classification');
327    if (profile.sensitiveRisk) warnings.push('sensitive_fields');
328    if (profile.basis === 'consent' && (cfg.serverValidationSources || []).indexOf(descriptor.source) === -1) warnings.push('no_server_validation');
329    return warnings.filter(function (value, index, all) { return all.indexOf(value) === index; });
330  }
331
332  function reportInventory(form, descriptor, profile, state) {
333    if (!cfg.diagnostics || !cfg.inventoryAjaxUrl || !cfg.inventoryNonce || !window.fetch) return;
334    var fieldTypes = descriptor.fields.map(core.detectField).filter(function (value, index, all) { return all.indexOf(value) === index; });
335    var localSignature = [descriptor.source, descriptor.id, window.location.pathname, fieldTypes.join(','), profile.purpose, profile.basis, state.pd.state].join('|');
336    if (processedSignatures.has(localSignature)) return;
337    processedSignatures.add(localSignature);
338    var data = new FormData();
339    data.append('action', 'zk_report_form_inventory');
340    data.append('nonce', cfg.inventoryNonce);
341    data.append('source', descriptor.source || 'generic');
342    data.append('form_id', descriptor.id || '');
343    data.append('page_url', window.location.origin + window.location.pathname);
344    fieldTypes.forEach(function (type) { data.append('field_types[]', type); });
345    data.append('purpose', profile.purpose || 'service');
346    data.append('basis', profile.basis || 'none');
347    data.append('existing_pd', state.pd.state || 'none');
348    data.append('server_validation', (cfg.serverValidationSources || []).indexOf(descriptor.source) !== -1 ? '1' : '0');
349    inventoryWarnings(form, descriptor, profile, state).forEach(function (warning) { data.append('warnings[]', warning); });
350    window.setTimeout(function () {
351      fetch(cfg.inventoryAjaxUrl, {method:'POST', credentials:'same-origin', body:data}).catch(function () {});
352    }, 250);
353  }
354
355  function diagnostic(form, descriptor, profile, state) {
356    if (!cfg.diagnostics || form.querySelector('.zk-form-diagnostic')) return;
357    var box = document.createElement('div'); box.className = 'zk-form-diagnostic';
358    var lines = [
359      'Законные куки: форма обнаружена',
360      'Источник: ' + descriptor.source,
361      'Поля: ' + descriptor.fields.map(core.detectField).join(', '),
362      'Цель: ' + profile.purpose,
363      'Основание: ' + profile.basis,
364      'Согласие ПДн: ' + state.pd.state,
365      'Серверная проверка: ' + ((cfg.serverValidationSources || []).indexOf(descriptor.source) !== -1 ? 'да' : 'не подтверждена')
366    ];
367    lines.forEach(function (line) { var div = document.createElement('div'); div.textContent = line; box.appendChild(div); });
368    form.insertAdjacentElement('beforebegin', box);
369  }
370
371  function processForm(form) {
372    if (!form || form.nodeType !== 1 || form.tagName.toLowerCase() !== 'form') return;
373    if (core.processedFormIntact({
374      processed: form.dataset.zkFormProcessed === '1',
375      basis: form.dataset.zkFormBasis || '',
376      hasConsentKind: !!form.querySelector('[data-zk-consent-kind]'),
377      hasMeta: !!form.querySelector('input[name="zk_consent_id"]')
378    })) return;
379    var descriptor = describeForm(form);
380    var profile = applyDefaultBasis(core.classify(descriptor));
381    var matches = selectorMatches(form);
382    var state = core.detectExistingConsent(describeExistingConsents(form));
383    diagnostic(form, descriptor, profile, state);
384    reportInventory(form, descriptor, profile, state);
385    if (!core.shouldProcess(matches, profile, {fallbackEnabled: !!cfg.fallbackEnabled})) return;
386
387    ['pd','marketing','spread'].forEach(function (kind) {
388      if (state[kind].state === 'optional') upgradeExistingConsent(state[kind], kind);
389      else if (state[kind].state === 'valid') markExistingConsent(state[kind], kind, false);
390    });
391    if (state.pd.combinedPolicy) {
392      upgradeExistingConsent(state.pd, 'pd');
393      normalizePolicyCombined(state.pd);
394      state.pd.state = 'valid';
395    }
396
397    var needsBlock = (profile.requiresPdConsent && state.pd.state !== 'valid') ||
398      (profile.requiresMarketingConsent && state.marketing.state !== 'valid') ||
399      (profile.requiresSpreadConsent && state.spread.state !== 'valid');
400
401    if (needsBlock && !form.querySelector('.zk-form-compliance')) {
402      var block = buildComplianceBlock(form, profile, state);
403      insertNearSubmit(form, block);
404    } else {
405      appendMissingLegalNotice(form, profile);
406    }
407
408    ensureHiddenMeta(form, profile);
409    syncExistingConsentProxies(form);
410    syncNinjaExtra(form);
411    form.dataset.zkFormProcessed = '1';
412    form.dataset.zkFormSource = descriptor.source;
413    form.dataset.zkFormBasis = profile.basis;
414  }
415
416  function validateBeforeSubmit(event) {
417    var form = event.target;
418    if (!form || form.tagName.toLowerCase() !== 'form') return;
419    processForm(form);
420    syncExistingConsentProxies(form);
421    syncNinjaExtra(form);
422    var required = form.querySelectorAll('[data-zk-consent-kind][required]');
423    for (var i = 0; i < required.length; i++) {
424      if (!required[i].checked) {
425        event.preventDefault(); event.stopImmediatePropagation();
426        ensureError(form, required[i]); required[i].focus(); return;
427      }
428    }
429    var err = form.querySelector('.zk-form-error'); if (err) err.remove();
430  }
431
432  function scan(root) {
433    if (!root || !root.querySelectorAll) return;
434    if (root.tagName && root.tagName.toLowerCase() === 'form') process
434Form(root);
435    Array.prototype.forEach.call(root.querySelectorAll('form'), processForm);
436  }
437
438  function init() {
439    scan(document);
440    document.addEventListener('submit', validateBeforeSubmit, true);
441    document.addEventListener('change', function (event) {
442      var target = event.target;
443      if (!target || !target.matches || !target.matches('[data-zk-consent-kind]')) return;
444      var form = target.closest('form');
445      if (form) {
446        syncExistingConsentProxies(form);
447        syncNinjaExtra(form);
448      }
449    }, true);
450    if (window.MutationObserver) {
451      new MutationObserver(function (mutations) {
452        mutations.forEach(function (m) {
453          var targetForm = m.target && m.target.closest && m.target.closest('form');
454          if (targetForm) processForm(targetForm);
455          Array.prototype.forEach.call(m.addedNodes || [], function (node) {
456            if (node.nodeType !== 1) return;
457            var ownerForm = node.closest && node.closest('form');
458            if (ownerForm) processForm(ownerForm);
459            scan(node);
460          });
461        });
462      }).observe(document.documentElement, {childList:true, subtree:true});
463    }
464  }
465
466  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init);
467  else init();
468}());

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.