1/** 2 * Plugin Name: Nobs ⢠Share Buttons 3 * Plugin URI: https://sharebuttons.social 4 * Author: Geoffrey Crofte 5 * Updated: 2.0.0 - No jQuery needed anymore. 6 */ 7; 8document.addEventListener("DOMContentLoaded", function(event) { 9 const formatParams = function( params ) { 10 return "?" + Object.keys(params).map(function(key){ 11 return key+"="+encodeURIComponent(params[key]) 12 }).join("&"); 13 }; 14 const serializeArray = function (form) { 15 var arr = []; 16 Array.prototype.slice.call(form.elements).forEach(function (field) { 17 if (!field.name || field.disabled || ['file', 'reset', 'submit', 'button'].indexOf(field.type) > -1) return; 18 if (field.type === 'select-multiple') { 19 Array.prototype.slice.call(field.options).forEach(function (option) { 20 if (!option.selected) return; 21 arr.push({ 22 name: field.name, 23 value: option.value 24 }); 25 }); 26 return; 27 } 28 if (['checkbox', 'radio'].indexOf(field.type) >-1 && !field.checked) return; 29 arr.push({ 30 name: field.name, 31 value: field.value 32 }); 33 }); 34 return arr; 35 }; 36 const nobs_format_number = function(num) { 37 if (typeof parseInt(num) !== 'NaN' ) { 38 if (num >= 1000000000) return parseInt(num / 1000000000) + "b"; 39 if (num >= 1000000) return parseInt(num / 1000000) + "m"; 40 if (num >= 1000) return parseInt(num / 1000) + "k"; 41 return num; 42 } else { 43 return 0; 44 } 45 }; 46 const nobs_count_type = function() { 47 if ( document.querySelector('.juiz_sps_counters.counters_both') ) { 48 return 'both'; 49 } else if ( document.querySelector('.juiz_sps_counters.counters_subtotal' ) ) { 50 return 'subtotal'; 51 } else if ( document.querySelector('.juiz_sps_counters.counters_total' ) ) { 52 return 'total'; 53 } 54 return 'nope'; 55 }; 56 let open_modal, 57 bookmark_it; 58 59 /* 60 var pinterest_url = https://api.pinterest.com/v1/urls/count.json?url=https://google.com; 61 // return : receiveCount({"url":"https://google.com","count":1}) 62 */ 63 if ( document.querySelector('.juiz_sps_counters') ) { 64 const nobs = document.querySelectorAll('.juiz_sps_counters'); 65 const nobs_plugin_url = document.querySelector('.juiz_sps_info_plugin_url').value; 66 const nobs_post_url = document.querySelector('.juiz_sps_info_permalink').value; 67 const nobs_post_id = document.querySelector('.juiz_sps_info_post_id').value; 68 69 // Reach each occurrence of a bar of buttons. 70 nobs.forEach(function(btnbar) { 71 let nobs_items = btnbar.querySelectorAll('.juiz_sps_item'); 72 let post_id = document.querySelector('.juiz_sps_links').getAttribute('data-post-id'); 73 let nobs_item_class = ''; 74 let nobs_total_count = 0; 75 76 if ( btnbar.classList.contains('counters_total') ) { 77 nobs_item_class = 'juiz_hidden_counter'; 78 } 79 80 if ( nobs_items === null ) { 81 return; 82 } 83 84 let to_send = { 85 'action': 'jsps-get-counters', 86 'jsps-get-counters-nonce': jsps.getCountersNonce, 87 'id': post_id 88 }; 89 90 // XHR Request. 91 let xhr = new XMLHttpRequest(); 92 93 // Setup our listener to process completed requests 94 xhr.onload = function () { 95 if (xhr.status >= 200 && xhr.status < 300) { 96 let data = JSON.parse( xhr.response ); 97 98 data = typeof data.data === "object" ? data.data[1] : {}; 99 100 nobs_items.forEach(function(item) { 101 if ( item.classList.contains('juiz_sps_totalcount_item') ) { 102 return; 103 } 104 105 let key = item.querySelector('button, a').getAttribute('data-nobs-key'); 106 107 if ( ! data[ key ] ) { 108 return; 109 } 110 111 let counter = document.createElement('span'); 112 counter.classList.add('juiz_sps_counter'); 113 if ( nobs_item_class !== '' ) { 114 counter.classList.add( nobs_item_class ); 115 } 116 counter.setAttribute('data-nobs-raw-count', data[ key ] ); 117 counter.textContent = nobs_format_number( parseInt( data[ key ] ) ); 118 item.prepend( counter ); 119 nobs_total_count = nobs_total_count + parseInt( data[ key ] ); 120 }); 121 122 // If btnbar ask for totalcount (both or total only)
123 // then displays total counter. 124 if ( ! btnbar.classList.contains('counters_subtotal') ) { 125 let total_counter = document.createElement('span'); 126 let total_number = document.createElement('span'); 127 let total_element = btnbar.querySelector('.juiz_sps_totalcount'); 128 let total_text = total_element.getAttribute('title'); 129 130 total_counter.classList.add('juiz_sps_total_text'); 131 total_counter.classList.add('juiz_sps_maybe_hidden_text'); 132 total_counter.textContent = total_text; 133 134 total_number.classList.add('juiz_sps_total_number'); 135 total_number.setAttribute('data-nobs-raw-count', nobs_total_count ); 136 total_number.textContent = nobs_format_number( nobs_total_count ); 137 138 // Append the total count 139 total_element.append( total_counter, total_number ); 140 total_element.setAttribute('title', total_text + ' ' + nobs_total_count ); 141 } 142 143 if ( parseInt( nobs_total_count ) === 0 ) { 144 if ( document.querySelectorAll('.juiz_sps_totalcount_item') ) { 145 document.querySelectorAll('.juiz_sps_totalcount_item').forEach(function(el) { 146 el.classList.add('juiz_sps_maybe_hidden_text'); 147 }); 148 } 149 } 150 } else { 151 console.warn('The request failed!'); 152 } 153 154 }; 155 156 xhr.open( 'GET', jsps.ajax_url + formatParams( to_send ) ); 157 xhr.send(); 158 }); 159 } 160 161 /** 162 * Count Increment. 163 */ 164 if ( document.querySelector('.juiz_sps_item') ) { 165 let buttons = document.querySelectorAll('.juiz_sps_item button, .juiz_sps_item a'); 166 167 buttons.forEach(function(button) { 168 button.addEventListener('click', function(e) { 169 // Avoid programmatic click duplicate the count. 170 let _event = e; 171 if ( e.clientX === 0 ) { 172 return; 173 } 174 175 // Do the prevention, then count. 176 e.preventDefault(); 177 let _this = this; 178 let network = _this.getAttribute('data-nobs-key'); 179 let post_id = document.querySelector('.juiz_sps_links').getAttribute('data-post-id'); 180 181 let to_send = { 182 'action': 'jsps-click-count', 183 'jsps-click-count-nonce': jsps.clickCountNonce, 184 'id': post_id, 185 'network': network 186 }; 187 188 // XHR Request. 189 let xhrcount = new XMLHttpRequest(); 190 191 // Setup our listener to process completed requests 192 xhrcount.onload = function () { 193 if (xhrcount.status >= 200 && xhrcount.status < 300) { 194 let data = JSON.parse( xhrcount.response ); 195 let net_items = document.querySelectorAll('.juiz_sps_link_' + network ); 196 197 if ( data.success === true && document.querySelector('.juiz_sps_counters') ) { 198 let subtotals = document.querySelector('.juiz_sps_link_' + network + ' .juiz_sps_counter'); 199 let total = document.querySelector('.juiz_sps_totalcount'); 200 let new_count = parseInt( data.data[2] ); 201 202 // If it has a counter already, increment 203 if ( subtotals ) { 204 net_items.forEach(function(el){ 205 if ( el.querySelector('.juiz_sps_counter') === null ) { 206 return; 207 } 208 el.querySelector('.juiz_sps_counter').innerHTML = nobs_format_number( new_count ); 209 }); 210 }
211 // Else build counters, by button. 212 else if ( nobs_count_type() === 'both' || nobs_count_type() === 'subtotal' ) { 213 let counter = document.createElement('span'); 214 counter.classList.add('juiz_sps_counter'); 215 counter.textContent = nobs_format_number( new_count ) 216 217 net_items.forEach(function(el) { 218 el.prepend( counter ); 219 }); 220 } 221 222 // If it has a global counter already, increment 223 if ( total ) { 224 let totals = document.querySelectorAll('.juiz_sps_totalcount'); 225 totals.forEach(function(tot){ 226 227 let nb = tot.querySelector('.juiz_sps_total_number'); 228 let currCount = nb.getAttribute('data-nobs-raw-count'); 229 nb.textContent = nobs_format_number( parseInt( currCount ) + 1 ); 230 nb.setAttribute('data-nobs-raw-count', parseInt( currCount ) + 1 ); 231 }); 232 } 233 // Else, build the total container with it. 234 else { 235 if ( nobs_count_type() === 'both' || nobs_count_type() === 'total' ) { 236 237 } 238 } 239 } else { 240 // Count not successful or no need to increase it visually. 241 // For now, do nothing about it. 242 } 243 } else { 244 console.warn( xhrcount, xhrcount.status ); 245 } 246 247 // Finally do the thing it was supposed to do. 248 if ( _this.href && _this.href !== '' && _this.href !== '#' && network !== 'mail' && network !== 'bookmark' ) { 249 if ( _this.target === '_blank') { 250 // Better than window.open() action. 251 let link = document.createElement('a'); 252 link.href = _this.href; 253 link.target = '_blank'; 254 link.id = 'nobs-temp'; 255 256 document.querySelector('body').prepend(link); 257 document.getElementById('nobs-temp').click(); 258 document.getElementById('nobs-temp').remove(); 259 // window.open( _this.href ); 260 } else { 261 document.location.href = _this.href; 262 } 263 } else { 264 switch ( network ) { 265 case 'bookmark': 266 bookmark_it(_event); 267 break; 268 case 'mail': 269 open_modal(_event); 270 break; 271 case 'print': 272 if ( window.print ) { 273 window.print(); 274 } 275 break; 276 case 'shareapi': 277 // Handled inline. Should be the count and async share without issue. 278 break; 279 default: 280 console.log('Ooops'); 281 } 282 } 283 }; 284 xhrcount.open( 'GET', jsps.ajax_url + formatParams( to_send ) ); 285 xhrcount.send(); 286 287 return false; 288 }); 289 }); 290 } 291 292 /** 293 * 294 * E-mail button 295 * 296 */ 297 if ( document.querySelector('.juiz_sps_link_mail') ) { 298 299 const email_buttons = document.querySelectorAll('.juiz_sps_link_mail'); 300 open_modal = function(event) { 301 302 event.preventDefault(); 303 304 if ( document.querySelector('.juiz-sps-modal') ) { 305 return; 306 } 307 let animation = 400; 308 let post_id = event.target.closest('.juiz_sps_links').getAttribute('data-post-id'); 309 let modalContent = '<div class="juiz-sps-modal-inside">' + 310 '<div class="juiz-sps-modal-header">' + 311 '<p id="juiz-sps-email-title" class="juiz-sps-modal-title">' + jsps.modalEmailTitle + '</p>' + 312 '</div>' + 313 '<div class="juiz-sps-modal-content">' + 314 '<form id="jsps-email-form" name="jsps-email" action="' + jsps.modalEmailAction + '" method="post" novalidate>' + 315 '<p class="juiz-sps-input-line">' + 316 '<label for="jsps-your-name">' + jsps.modalEmailName + '</label>' + 317 '<input type="text" id="jsps-your-name" name="jsps-your-name" aria-required="true" required="required" value="" autofocus>' + 318 '</p>' + 319 '<p class="juiz-sps-input-line">' + 320 '<label for="jsps-your-email">' + jsps.modalEmailYourEmail + '</label>' + 321 '<input type="email" id="jsps-your-email" name="jsps-your-email" aria-required="true" required="required" value="">' + 322 '</p>' + 323 '<p class="juiz-sps-input-line">' + 324 '<label for="jsps-friend-email">' + jsps.modalEmailFriendEmail + '</label>' + 325 '<input type="email" id="jsps-friend-email" name="jsps-friend-email" aria-required="true" required="required" value="">' + 326 '</p>' + 327 '<p class="juiz-sps-textarea-line">' + 328 '<label for="jsps-message">' + jsps.modalEmailMessage + ' <small>(' + jsps.modalEmailOptional + ')</small><span class="juiz-sps-label-info">' + jsps.modalEmailMsgInfo + '</span></label>' + 329 '<textarea id="jsps-message" name="jsps-message" cols="50" rows="7" aria-required="false"></textarea>' + 330 '</p>' + 331 '<div class="juiz-sps-submit-infos">' + 332 '<p class="juiz-sps-message-info"> ' + jsps.modalEmailInfo + '</p>' + 333 '<p class="juiz-sps-submit-line">' + 334 '<button type="submit" id="jsps-email-submit"><span class="juiz-sps-loader"></span><span class="juiz-sps-submit-txt">' + jsps.modalEmailSubmit + '</span></button>' + 335 '</p>' + 336 '</div>' + 337 '</form>' + 338 '</div>' + 339 '<button class="juiz-sps-close" type="button"><i class="juiz-sps-icon-close">Ã</i><span class="juiz-sps-hidden">' + jsps.modalClose + '</span></button>' + 340 '<div class="juiz-sps-modal-footer"><p>' + jsps.modalEmailFooter + '</p></div>' + 341 '</div>'; 342 let jsps_modal = document.createElement('div'); 343 const isValidEmail = function(email) { 344 const re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; 345 return re.test(email); 346 }; 347 348 // Modal attributes 349 jsps_modal.classList.add('juiz-social-post-sharer-modal'); 350 jsps_modal.classList.add('juiz-sps-modal'); 351 jsps_modal.setAttribute('aria-hidden', 'true'); 352 jsps_modal.setAttribute('role', 'dialog'); 353 jsps_modal.setAttribute('aria-labelledby', 'juiz-sps-email-title'); 354 jsps_modal.setAttribute('data-post-id', post_id); 355 356 document.querySelector('body').append( jsps_modal ); 357 358 let modal = document.querySelector('.juiz-sps-modal'); 359 modal.innerHTML = modalContent; 360 361 setTimeout(function(){ 362 modal.classList.add('jsps-modal-show'); 363 modal.setAttribute('aria-hidden', 'false'); 364 modal.querySelector('form > p:first-child input').focus(); 365 }, 10); 366 367 document.getElementById('jsps-friend-email').addEventListener('input', function() { 368 let val = this.value, 369 reg = /\s*(?:[;,]|$)\s*/, 370 count = 0, 371 phrase = ''; 372 373 val = val.split(reg); 374 375 val.forEach(function(email) { 376 count = isValidEmail(email) ? count + 1 : count; 377 }); 378 379 if ( document.querySelector('[for="jsps-friend-email"] span') ) { 380 document.querySelector('[for="jsps-friend-email"] span').remove(); 381 } 382 383 if (count === 0) return; 384 385 if (count > 1) { 386 phrase = jsps.modalRecipientNbs; 387 phrase = phrase.replace("{number}", count); 388 } else { 389 phrase = jsps.modalRecipientNb; 390 } 391 392 let countspan = document.createElement('span'); 393 countspan.innerHTML = phrase; 394 395 document.querySelector('[for="jsps-friend-email"]').append( countspan ); 396 }); 397 398 // On form SUBMIT. 399 document.getElementById('jsps-email-form').addEventListener('submit', function(e) { 400 401 e.preventDefault(); 402 403 let datas = serializeArray( this ), 404 modal = this.closest('.juiz-sps-modal'), 405 post_id = modal.getAttribute('data-post-id'), 406 loader = this.querySelector('.juiz-sps-loader'); 407 408 loader.classList.add('is-active') 409 loader.innerHTML = jsps.modalLoader; 410 411 var to_send = { 412 'action': 'jsps-email-friend', 413 'jsps-email-friend-nonce': jsps.modalEmailNonce, 414 'id': post_id, 415 'name': datas[0].value, 416 'email': datas[1].value, 417 'friend': datas[2].value, 418 'message': datas[3].value 419 }; 420 421 // XHR Request. 422 let xhrmod = new XMLHttpRequest(); 423 424 // Setup our listener to process completed requests 425 xhrmod.onload = function () { 426 if (xhrmod.status >= 200 && xhrmod.status < 300) { 427 let data = JSON.parse( xhrmod.response ); 428 if ( data.success === true ) { 429 430 let successmsg = document.createElement('div'); 431 successmsg.classList.add('juiz-sps-success'); 432 successmsg.classList.add('juiz-sps-message'); 433 434 modal.querySelector('.juiz-sps-modal-content').replaceChild( 435 successmsg, // new one 436 modal.querySelector('form') // old one 437 ); 438 439 modal.querySelector('.juiz-sps-success').innerHTML = '<svg width="130px" height="86px" viewBox="0 0 130 86" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><path d="M129.832519,0.8459473 C129.832031,0.8449707 129.831543,0.8439942 129.831055,0.8439942 C129.694336,0.6389161 129.493652,0.5002442 129.271484,0.4367676 C129.271484,0.4367676 129.271484,0.4367676 129.270996,0.4367676 C129.268066,0.4367676 129.268066,0.4348145 129.267578,0.435791 C129.265625,0.435791 129.265625,0.4338379 129.26416,0.4348144 C129.262695,0.4348144 129.262207,0.4348144 129.258301,0.4338378 C129.256836,0.4328612 129.255371,0.4328612 129.254883,0.4328612 C129.253906,0.4328612 129.252441,0.4318846 129.251465,0.4318846 C129.250976,0.4328612 129.251465,0.430908 129.247558,0.430908 C129.245117,0.430908 129.24414,0.4299314 129.24414,0.4299314 C129.242187,0.4318845 129.241211,0.4289548 129.239746,0.4289548 L129.239258,0.4289548 C129.237793,0.4279782 129.236816,0.4279782 129.23584,0.4279782 C129.234863,0.4279782 129.233886,0.4270016 129.232422,0.4270016 C129.226562,0.426025 129.229492,0.426025 129.229004,0.426025 C129.227539,0.4250484 129.226074,0.4240719 129.225586,0.4250484 C129.223632,0.4250484 129.223144,0.4250484 129.222168,0.4250484 C129.081054,0.3928218 128.93164,0.3918453 128.787597,0.4221187 L0.8061523,25.7277832 C0.3925781,25.8098145 0.074707,26.1428223 0.0112304,26.5588379 C-0.0517579,26.97583
43901 0.1533202,27.3879395 0.5239257,27.5891113 L38.7761841,48.296875 L44.2290039,84.748291 C44.2433472,84.8442383 44.2748413,84.9345703 44.3149414,85.0205078 C44.3240967,85.0400391 44.3364258,85.0568848 44.3468018,85.0759277 C44.3948975,85.1638183 44.4549561,85.243164 44.5269165,85.3127441 C44.5414429,85.3269043 44.5529175,85.3422851 44.5683594,85.3557129 C44.6381836,85.4157715 44.7144776,85.46875 44.800293,85.5080567 C44.8154908,85.5151368 44.8327027,85.5122071 44.8481446,85.5185547 C44.8656007,85.5256348 44.8774415,85.5400391 44.8955079,85.5461426 C45.0024415,85.583252 45.1108399,85.5998535 45.2177735,85.5998535 C45.3156739,85.5998535 45.4129029,85.5832519 45.5073243,85.5546875 C45.5412598,85.5444336 45.5709229,85.5253906 45.6035157,85.5117187 C45.652649,85.4909667 45.7036134,85.4753417 45.7495118,85.4465332 L72.343628,68.7521973 L98.4980469,85.442627 C98.6606446,85.5461426 98.8476563,85.5998536 99.0361328,85.5998536 C99.1445312,85.5998536 99.2539062,85.5822755 99.3588867,85.5461427 C99.6464844,85.4484864 99.8740234,85.2248536 99.9770508,84.9387208 L129.937012,1.7492677 C129.950195,1.7131349 129.961914,1.6760255 129.971191,1.6389161 C129.972656,1.6320802 129.97168,1.636963 129.97168,1.6359864 C129.98291,1.5891114 129.990723,1.5422364 129.995606,1.4943848 C130.01416,1.2980957 129.975586,1.0949707 129.873535,0.9123535 C129.86084,0.8898926 129.847168,0.8674316 129.833008,0.8459472 C129.832519,0.8459473 129.832519,0.8459473 129.832519,0.8459473 Z M3.9179688,27.1516113 L122.299317,3.7443847 L39.7011719,46.5227051 L3.9179688,27.1516113 Z M45.59729,80.3791504 L40.7855225,48.213623 L118.380859,8.0256347 L54.2226563,55.5783691 C54.1802369,55.6098632 54.1459351,55.6489257 54.1095582,55.685791 C54.0936891,55.7021484 54.0759889,55.7143555 54.0612184,55.7316894 C53.9859621,55.8193359 53.9310304,55.9199218 53.8900758,56.0270996 C53.8854371,56.0393066 53.8753053,56.0473633 53.8710939,56.0598144 L45.59729,80.3791504 Z M47.0717163,82.2556152 L55.3543091,57.9106445 L70.4785767,67.5620117 L47.0717163,82.2556152 Z M98.519043,83.0842285 L56.5800781,56.3205566 L126.938476,4.1721191 L98.519043,83.0842285 Z" fill="#FFF" fill-rule="nonzero"></path></g></svg>' + 440 '<p>' + data.data + '</p>' + 441 '</div>'; 442 } else if ( data.success === false ) { 443 if ( ! modal.querySelector('.juiz-sps-error') ) { 444 let errormsg = document.createElement('div'); 445 446 errormsg.classList.add('juiz-sps-error'); 447 errormsg.classList.add('juiz-sps-message'); 448 449 modal.querySelector('form').prepend( errormsg ); 450 451 modal.querySelector('.juiz-sps-error').innerHTML = data.data[1]; 452 } else { 453 modal.querySelector('.juiz-sps-error').innerHTML = data.data[1]; 454 } 455 456 loader.classList.remove('is-active'); 457 458 var temp = setInterval(function() { 459 loader.querySelector('img').remove(); 460 clearInterval(temp); 461 }, 300); 462 } 463 } else { 464 if ( modal.querySelector('.juiz-sps-error') ) { 465 modal.querySelector('.juiz-sps-error').remove(); 466 } 467 let errorContent = jsps.modalErrorGeneric + '<br><code style="font-size:.8em;">' + xhrmod.statusText + '(' + xhrmod.status + ')</code>'; 468 let errorMsg = document.createElement('div'); 469 470 errorMsg.classList.add('juiz-sps-error juiz-sps-message'); 471 errorMsg.innerHTML = errorContent; 472 473 modal.querySelector('form').append( errorMsg ); 474 loader.classList.remove('is-active'); 475 } 476 }; 477 xhrmod.open( 'GET', jsps.ajax_url + formatParams( to_send ) ); 478 xhrmod.send(); 479 480 return false;
481 }) 482 483 // On CLOSE button. 484 document.querySelector('.juiz-sps-close').addEventListener('click', function() { 485 modal.setAttribute('aria-hidden', 'true'); 486 modal.classList.remove('jsps-modal-show'); 487 temp = setInterval(function() { 488 modal.remove(); 489 }, 400); 490 return false; 491 }); 492 493 // On ESC key CLOSE the modal. 494 window.addEventListener('keyup', function(e) { 495 if (e.code !== "Escape") { 496 return; 497 } 498 if ( document.querySelector('.juiz-sps-modal[aria-hidden="false"]') ) { 499 document.querySelector('.juiz-sps-close').click(); 500 } 501 return; 502 }); 503 504 // Accessibility. 505 document.querySelector('.juiz-sps-close').addEventListener('blur', function() { 506 this.closest('.juiz-sps-modal').querySelector('form > p:first-child input').focus(); 507 return false; 508 }); 509 510 return false; 511 }; 512 } 513 514 /** 515 * 516 * Remove Print Button if API not supported. 517 * 518 */ 519 if ( ! window.print && document.querySelector('.juiz_sps_link_print') ) { 520 let print_btns = document.querySelectorAll('.juiz_sps_link_print'); 521 print_btns.forEach(function(el) { 522 el.remove(); 523 }); 524 } 525 526 /** 527 * 528 * Bookmark button 529 * 530 */ 531 if ( 532 ( 'addToHomescreen' in window && window.addToHomescreen.isCompatible ) || 533 ( window.sidebar && window.sidebar.addPanel ) || 534 ( window.external && ('AddFavorite' in window.external) ) || 535 (typeof chrome === 'undefined') || 536 (typeof chrome !== 'undefined') 537 ) { 538 bookmark_it = function(e) { 539 e.preventDefault(); 540 // Thanks to: 541 // https://www.thewebflash.com/how-to-add-a-cross-browser-add-to-favorites-bookmark-button-to-your-website/ 542 let bookmarkURL = window.location.href, 543 bookmarkTitle = document.title; 544 545 if ( 'addToHomescreen' in window && window.addToHomescreen.isCompatible ) { 546 // Mobile browsers 547 addToHomescreen({ autostart: false, startDelay: 0 }).show(true); 548 } 549 // Firefox version < 23 550 else if ( window.sidebar && window.sidebar.addPanel ) { 551 window.sidebar.addPanel(bookmarkTitle, bookmarkURL, ''); 552 } else if (window.external && ('AddFavorite' in window.external)) { 553 // IE Favorite 554 window.external.AddFavorite(bookmarkURL, bookmarkTitle); 555 } else { 556 // Other browsers (mostly all of them since 2019) 557 command = (/Mac/i.test(navigator.userAgent) ? 'Cmd' : 'Ctrl') + '+D'; 558 message = e.target.getAttribute('data-alert') || e.target.closest('a, button').getAttribute('data-alert'); 559 message = message.replace(/%s/, command); 560 alert( message ); 561 return false; 562 } 563 return false; 564 }; 565 } else { 566 if ( document.querySelector('.juiz_sps_link_bookmark') ) { 567 document.querySelectorAll('.juiz_sps_link_bookmark').forEach(function(el) { 568 el.remove(); 569 }); 570 } 571 } 572});
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.