PageSourceSearch

https://pisatelicrimea.ru/wp-content/plugins/juiz-social-post-sharer/assets/js/juiz-social-post-sharer.js

js pisatelicrimea.ru collected 2026-10-02 08:15:07 UTC 29,507 bytes, 572 lines download raw bytes

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.