1(function (Drupal) { 2 3 /** 4 * Command to attach data using jQuery's data API. 5 * 6 * @param {Drupal.Ajax} [ajax] 7 * {@link Drupal.Ajax} object created by {@link Drupal.ajax}. 8 * @param {object} response 9 * The response from the Ajax request. 10 * @param {string} response.event_name 11 * The event name 12 * @param {object} response.data 13 * The value of the event. 14 */ 15 Drupal.AjaxCommands.prototype.gtagEvent = function (ajax, response) { 16 gtag('event', response.event_name, response.data) 17 } 18})(Drupal); 19; 20function ctSetCookie(cookies) 21{ 22 23 let useCookies, useAltCookies 24 25 if ('undefined' !== typeof ct_use_cookies) { 26 useCookies = ct_use_cookies; 27 } else { 28 useCookies = false; 29 } 30 31 if ('undefined' !== typeof ct_use_alt_cookies) { 32 useAltCookies = ct_use_alt_cookies; 33 } else { 34 useAltCookies = false 35 } 36 37 if (useCookies) { 38 if (useAltCookies && useAltCookies === 1) { 39 let xhr = new XMLHttpRequest(); 40 41 let json = JSON.stringify(cookies); 42 43 xhr.open("POST", '/admin/config/cleantalk/set_alt_cookies') 44 xhr.setRequestHeader('Content-type', 'application/json; charset=utf-8'); 45 46 xhr.send(json); 47 } else { 48 cookies.forEach( 49 function (e) { 50 let ctSecure = location.protocol === "https:" ? "; secure" : ""; 51 document.cookie = e.name + "=" + encodeURIComponent(e.value) + "; path=/; expires=0; samesite=lax" + ctSecure; 52 } 53 ) 54 } 55 } 56} 57; 58var d = new Date(), 59 ctTimeMs = new Date().getTime(), 60 ctMouseEventTimerFlag = true, //Reading interval flag 61 ctMouseData = "[", 62 ctMouseDataCounter = 0, 63 ctScrollCollected = false, 64 ctEventTokenInterval = null; 65 66ctSetCookie( 67 [ 68 { 69 'name' : 'ct_check_js', 70 'value' : ct_check_js_val 71 }, 72 { 73 'name' : 'ct_ps_timestamp', 74 'value' : Math.floor(new Date().getTime()/1000) 75 }, 76 { 77 'name' : 'ct_fkp_timestamp', 78 'value' : '0' 79 }, 80 { 81 'name' : 'ct_pointer_data', 82 'value' : '0' 83 }, 84 { 85 'name' : 'ct_timezone', 86 'value' : d.getTimezoneOffset()/60*(-1) 87 }, 88 { 89 'name' : 'apbct_antibot', 90 'value' : drupal_ac_antibot_cookie_value 91 }, 92 { 93 'name' : 'ct_has_scrolled', 94 'value' : false 95 } 96 ] 97); 98 99//Reading interval 100 101var ctMouseReadInterval = setInterval( 102 function () { 103 ctMouseEventTimerFlag = true; 104 }, 150 105); 106 107//Writting interval 108 109var ctMouseWriteDataInterval = setInterval( 110 function () { 111 if(typeof ct_use_alt_cookies !== "undefined" && ct_use_alt_cookies === 1) { 112 return; 113 } 114 var ctMouseDataToSend = ctMouseData.slice(0,-1).concat("]"); 115 ctSetCookie( 116 [ 117 { 118 'name' : 'ct_pointer_data', 119 'value' : ctMouseDataToSend 120 } 121 ] 122 ); 123 }, 1200 124); 125 126//Stop observing function 127 128function ctMouseStopData() 129{ 130 if(typeof window.addEventListener == "function") { 131 window.removeEventListener("mousemove", ctFunctionMouseMove); 132 } else { 133 window.detachEvent("onmousemove", ctFunctionMouseMove); 134 } 135 clearInterval(ctMouseReadInterval); 136 clearInterval(ctMouseWriteDataInterval); 137} 138 139//Logging mouse position each 300 ms 140 141var ctFunctionMouseMove = function output(event) 142{ 143 if (ctMouseEventTimerFlag == true) { 144 var mouseDate = new Date(); 145 ctMouseData += "[" + Math.round(event.pageY) + "," + Math.round(event.pageX) + "," + Math.round(mouseDate.getTime() - ctTimeMs) + "],"; 146 ctMouseDataCounter++; 147 ctMouseEventTimerFlag = false; 148 if(ctMouseDataCounter >= 100) { 149 ctMouseStopData(); 150 } 151 } 152}; 153 154/** 155 * Set scrolling cookie 156 */ 157function ctSetHasScrolled() 158{ 159 if(! ctScrollCollected ) { 160 ctSetCookie( 161 [ 162 { 163 'name' : 'ct_has_scrolled', 164 'value' : true 165 } 166 ] 167 ); 168 ctScrollCollected = true; 169 } 170} 171 172//Stop key listening function 173 174function ctKeyStopStopListening() 175{ 176 if (typeof window.addEventListener == "function") { 177 window.removeEventListener("mousedown", ctFunctionFirstKey); 178 window.removeEventListener("keydown", ctFunctionFirstKey); 179 } 180 else { 181 window.detachEvent("mousedown", ctFunctionFirstKey); 182 window.detachEvent("keydown", ctFunctionFirstKey); 183 } 184} 185 186//Writing first key press timestamp 187 188var ctFunctionFirstKey = function output(event) 189{ 190 var KeyTimestamp = Math.floor(new Date().getTime()/1000);
191 ctSetCookie( 192 [ 193 { 194 'name' : 'ct_fkp_timestamp', 195 'value' : KeyTimestamp 196 } 197 ] 198 ); 199 ctKeyStopStopListening(); 200}; 201 202if (typeof window.addEventListener == "function") { 203 window.addEventListener("mousemove", ctFunctionMouseMove); 204 window.addEventListener("mousedown", ctFunctionFirstKey); 205 window.addEventListener("keydown", ctFunctionFirstKey); 206 window.addEventListener("scroll", ctSetHasScrolled); 207} 208else { 209 window.attachEvent("onmousemove", ctFunctionMouseMove); 210 window.attachEvent("mousedown", ctFunctionFirstKey); 211 window.attachEvent("keydown", ctFunctionFirstKey); 212 window.attachEvent("scroll", ctSetHasScrolled); 213} 214 215function apbct_collect_visible_fields( form ) 216{ 217 218 // Get only fields 219 var inputs = [], 220 inputs_visible = '', 221 inputs_visible_count = 0, 222 inputs_invisible = '', 223 inputs_invisible_count = 0, 224 inputs_with_duplicate_names = []; 225 226 for(var key in form.elements){ 227 if(!isNaN(+key)) { 228 inputs[key] = form.elements[key]; 229 } 230 } 231 232 // Filter fields 233 inputs = inputs.filter( 234 function (elem) { 235 236 // Filter already added fields 237 if(inputs_with_duplicate_names.indexOf(elem.getAttribute('name')) !== -1 ) { 238 return false; 239 } 240 // Filter inputs with same names for type == radio 241 if(-1 !== ['radio', 'checkbox'].indexOf(elem.getAttribute("type"))) { 242 inputs_with_duplicate_names.push(elem.getAttribute('name')); 243 return false; 244 } 245 return true; 246 } 247 ); 248 249 // Visible fields 250 inputs.forEach( 251 function (elem, i, elements) { 252 // Unnecessary fields 253 if(elem.getAttribute("type") === "submit" // type == submit 254 || elem.getAttribute('name') === null 255 || elem.getAttribute('name') === 'ct_checkjs' 256 ) { 257 return; 258 } 259 // Invisible fields 260 if(getComputedStyle(elem).display === "none" // hidden 261 || getComputedStyle(elem).visibility === "hidden" // hidden 262 || getComputedStyle(elem).opacity === "0" // hidden 263 || elem.getAttribute("type") === "hidden" // type == hidden 264 ) { 265 if(elem.classList.contains("wp-editor-area") ) { 266 inputs_visible += " " + elem.getAttribute("name"); 267 inputs_visible_count++; 268 } else { 269 inputs_invisible += " " + elem.getAttribute("name"); 270 inputs_invisible_count++; 271 } 272 } 273 // Visible fields 274 else { 275 inputs_visible += " " + elem.getAttribute("name"); 276 inputs_visible_count++; 277 } 278 279 } 280 ); 281 282 inputs_invisible = inputs_invisible.trim(); 283 inputs_visible = inputs_visible.trim(); 284 285 return { 286 visible_fields : inputs_visible, 287 visible_fields_count : inputs_visible_count, 288 invisible_fields : inputs_invisible, 289 invisible_fields_count : inputs_invisible_count, 290 } 291 292} 293 294function apbct_visible_fields_set_cookie( visible_fields_collection ) 295{ 296 var collection = typeof visible_fields_collection === 'object' && visible_fields_collection !== null ? visible_fields_collection : {}; 297 298 ctSetCookie( 299 [ 300 { 301 'name' : 'apbct_visible_fields', 302 'value' : JSON.stringify(collection) 303 } 304 ] 305 ) 306} 307 308// Event token handler class. Get token and save it to the alternative sessions. 309 310class EventTokenHandler { 311 312 constructor(use_alt_cookies_option) { 313 this.token = null; 314 this.lsSavedFlagName = 'event_token_saved_to_alt_sessions'; 315 this.lsEVentTokenName = 'bot_detector_event_token'; 316 this.intervalValue = 1500; 317 this.init(use_alt_cookies_option); 318 } 319 320 init(use_alt_cookies_option){ 321 if ('undefined' !== typeof use_alt_cookies_option && use_alt_cookies_option) { 322 this.setNotSavedFlag(); 323 this.startListenTokenLS(); 324 } 325 } 326 327 328 setSavedFlag() 329 { 330 localStorage.setItem(this.lsSavedFlagName, '1'); 331 } 332 333 setNotSavedFlag() 334 { 335 localStorage.setItem(this.lsSavedFlagName, '0'); 336 } 337 338 isSaved() 339 { 340 let event_token_saved = localStorage.getItem(this.lsSavedFlagName); 341 return event_token_saved !== null && event_token_saved !== undefined && event_token_saved === '1'; 342 } 343 344 getEventToken() 345 { 346 let event_token = localStorage.getItem(this.lsEVentTokenName); 347 try { 348 event_token = event_token !== null ? JSON.parse(event_token) : false;
349 } catch (e) { 350 return false; 351 } 352 event_token = event_token.hasOwnProperty('value') ? event_token.value : false; 353 if (typeof event_token === 'string' && event_token.length === 64) { 354 return event_token; 355 } 356 return false; 357 } 358 359 setEventTokenCookie() 360 { 361 if (typeof this.token === 'string' && this.token.length === 64) { 362 ctSetCookie( 363 [ 364 { 365 'name': 'apbct_event_token', 366 'value': this.token 367 } 368 ] 369 ) 370 } 371 } 372 373 stopListenTokenLS() 374 { 375 clearInterval(this.intervalID); 376 } 377 378 startListenTokenLS() 379 { 380 this.intervalID = setInterval( this.intervalRun, this.intervalValue, this) 381 } 382 383 intervalRun(handler) 384 { 385 if ( !handler.isSaved() ) { 386 handler.token = handler.getEventToken(); 387 if ( handler.token ) { 388 handler.setEventTokenCookie(); 389 handler.setSavedFlag(); 390 handler.stopListenTokenLS(); 391 } 392 } 393 } 394} 395 396//Collect event token 397new EventTokenHandler(ct_use_alt_cookies); 398; 399/** 400 * @file 401 * Bootstrap Popovers. 402 */ 403 404var Drupal = Drupal || {}; 405 406(function ($, Drupal, Bootstrap) { 407 "use strict"; 408 409 var $document = $(document); 410 411 /** 412 * Extend the Bootstrap Popover plugin constructor class. 413 */ 414 Bootstrap.extendPlugin('popover', function (settings) { 415 return { 416 DEFAULTS: { 417 animation: !!settings.popover_animation, 418 autoClose: !!settings.popover_auto_close, 419 enabled: settings.popover_enabled, 420 html: !!settings.popover_html, 421 placement: settings.popover_placement, 422 selector: settings.popover_selector, 423 trigger: settings.popover_trigger, 424 title: settings.popover_title, 425 content: settings.popover_content, 426 delay: parseInt(settings.popover_delay, 10), 427 container: settings.popover_container 428 } 429 }; 430 }); 431 432 /** 433 * Bootstrap Popovers. 434 * 435 * @todo This should really be properly delegated if selector option is set. 436 */ 437 Drupal.behaviors.bootstrapPopovers = { 438 $activePopover: null, 439 attach: function (context) { 440 // Immediately return if popovers are not available. 441 if (!$.fn.popover || !$.fn.popover.Constructor.DEFAULTS.enabled) { 442 return; 443 } 444 445 var _this = this; 446 447 $document 448 .on('show.bs.popover', '[data-toggle=popover]', function () { 449 var $trigger = $(this); 450 var popover = $trigger.data('bs.popover'); 451 452 // Only keep track of clicked triggers that we're manually handling. 453 if (popover.options.originalTrigger === 'click') { 454 if (_this.$activePopover && _this.getOption('autoClose') && !_this.$activePopover.is($trigger)) { 455 _this.$activePopover.popover('hide'); 456 } 457 _this.$activePopover = $trigger; 458 } 459 }) 460 // Unfortunately, :focusable is only made available when using jQuery 461 // UI. While this would be the most semantic pseudo selector to use 462 // here, jQuery UI may not always be loaded. Instead, just use :visible 463 // here as this just needs some sort of selector here. This activates 464 // delegate binding to elements in jQuery so it can work it's bubbling 465 // focus magic since elements don't really propagate their focus events. 466 // @see https://www.drupal.org/project/bootstrap/issues/3013236 467 .on('focus.bs.popover', ':visible', function (e) { 468 var $target = $(e.target); 469 if (_this.$activePopover && _this.getOption('autoClose') && !_this.$activePopover.is($target) && !$target.closest('.popover.in')[0]) { 470 _this.$activePopover.popover('hide'); 471 _this.$activePopover = null; 472 } 473 }) 474 .on('click.bs.popover', function (e) { 475 var $target = $(e.target); 476 if (_this.$activePopover && _this.getOption('autoClose') && !$target.is('[data-toggle=popover]') && !$target.closest('.popover.in')[0]) { 477 _this.$activePopover.popover('hide'); 478 _this.$activePopover = null; 479 } 480 }) 481 .on('keyup.bs.popover', function (e) { 482 if (_this.$activePopover && _this.getOption('autoClose') && e.which === 27) { 483 _this.$activePopover.popover('hide'); 484 _this.$activePopover = null; 485 } 486 }) 487 ; 488 489 var elements = $(context).find('[data-toggle=popover]').toArray(); 490 for (var i = 0; i < elements.length; i++) { 491 var $element = $(elements[i]); 492 var options = $.extend({}, $.fn.popover.Constructor.DEFAULTS, $element.data()); 493 494 // Store the original trigger. 495 options.originalTrigger = options.trigger; 496 497 // If the trigger is "click", then we'll handle it manually here. 498 if (options.trigger === 'click') { 499 options.trigger = 'manual'; 500 } 501 502 // Retrieve content from a target element. 503 var target = options.target || $element.is('a[href^="#"]') && $element.attr('href'); 504 var $target = $document.find(target).clone(); 505 if (!options.content && $target[0]) { 506 $target.removeClass('visually-hidden hidden').removeAttr('aria-hidden'); 507 options.content = $target.wrap('<div/>').parent()[options.html ? 'html' : 'text']() || ''; 508 } 509 510 // Initialize the popover. 511 $element.popover(options); 512 513 // Handle clicks manually. 514 if (options.originalTrigger === 'click') { 515 // To ensure the element is bound multiple times, remove any 516 // previously set event handler before adding another one. 517 $element 518 .off('click.drupal.bootstrap.popover') 519 .on('click.drupal.bootstrap.popover', function (e) { 520 $(this).popover('toggle'); 521 e.preventDefault(); 522 e.stopPropagation(); 523 }) 524 ; 525 } 526 } 527 }, 528 detach: function (context) { 529 // Immediately return if popovers are not available. 530 if (!$.fn.popover || !$.fn.popover.Constructor.DEFAULTS.enabled) { 531 return; 532 } 533 534 // Destroy all popovers. 535 $(context).find('[data-toggle="popover"]') 536 .off('click.drupal.bootstrap.popover') 537 .popover('destroy') 538 ; 539 }, 540 getOption: function(name, defaultValue, element) { 541 var $element = element ? $(element) : this.$activePopover; 542 var options = $.extend(true, {}, $.fn.popover.Constructor.DEFAULTS, ($element && $element.data('bs.popover') || {}).options); 543 if (options[name] !== void 0) { 544 return options[name]; 545 } 546 return defaultValue !== void 0 ? defaultValue : void 0; 547 } 548 }; 549 550})(window.jQuery, window.Drupal, window.Drupal.bootstrap); 551; 552/** 553 * @file 554 * Bootstrap Tooltips. 555 */ 556 557var Drupal = Drupal || {}; 558 559(function ($, Drupal, Bootstrap) { 560 "use strict"; 561 562 /** 563 * Extend the Bootstrap Tooltip plugin constructor class. 564 */ 565 Bootstrap.extendPlugin('tooltip', function (settings) { 566 return { 567 DEFAULTS: { 568 animation: !!settings.tooltip_animation, 569 enabled: settings.tooltip_enabled, 570 html: !!settings.tooltip_html, 571 placement: settings.tooltip_placement, 572 selector: settings.tooltip_selector, 573 trigger: settings.tooltip_trigger, 574 delay: parseInt(settings.tooltip_delay, 10), 575 container: settings.tooltip_container 576 } 577 }; 578 }); 579 580 /** 581 * Bootstrap Tooltips. 582 * 583 * @todo This should really be properly delegated if selector option is set. 584 */ 585 Drupal.behaviors.bootstrapTooltips = { 586 attach: function (context) { 587 // Immediately return if tooltips are not available. 588 if (!$.fn.tooltip || !$.fn.tooltip.Constructor.DEFAULTS.enabled) { 589 return; 590 } 591 592 var elements = $(context).find('[data-toggle="tooltip"]').toArray(); 593 for (var i = 0; i < elements.length; i++) { 594 var $element = $(elements[i]); 595 var options = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, $element.data()); 596 $element.tooltip(options); 597 } 598 }, 599 detach: function (context) { 600 // Immediately return if tooltips are not available. 601 if (!$.fn.tooltip || !$.fn.tooltip.Constructor.DEFAULTS.enabled) { 602 return; 603 } 604 605 // Destroy all tooltips. 606 $(context).find('[data-toggle="tooltip"]').tooltip('destroy'); 607 } 608 }; 609 610})(window.jQuery, window.Drupal, window.Drupal.bootstrap); 611;
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.