PageSourceSearch

https://xwexi.globasa.net/user/themes/learn2/js/learn.js

js globasa.net collected 2026-10-01 11:42:02 UTC 11,180 bytes, 342 lines download raw bytes

1// Scrollbar Width function
2function getScrollBarWidth() {
3    var inner = document.createElement('p');
4    inner.style.width = "100%";
5    inner.style.height = "200px";
6
7    var outer = document.createElement('div');
8    outer.style.position = "absolute";
9    outer.style.top = "0px";
10    outer.style.left = "0px";
11    outer.style.visibility = "hidden";
12    outer.style.width = "200px";
13    outer.style.height = "150px";
14    outer.style.overflow = "hidden";
15    outer.appendChild(inner);
16
17    document.body.appendChild(outer);
18    var w1 = inner.offsetWidth;
19    outer.style.overflow = 'scroll';
20    var w2 = inner.offsetWidth;
21    if (w1 == w2) w2 = outer.clientWidth;
22
23    document.body.removeChild(outer);
24
25    return (w1 - w2);
26};
27
28function setMenuHeight() {
29    $('#sidebar .highlightable').height($('#sidebar').innerHeight() - $('#header-wrapper').height() - 40);
30}
31
32function fallbackMessage(action) {
33    var actionMsg = '';
34    var actionKey = (action === 'cut' ? 'X' : 'C');
35
36    if (/iPhone|iPad/i.test(navigator.userAgent)) {
37        actionMsg = 'No support :(';
38    }
39    else if (/Mac/i.test(navigator.userAgent)) {
40        actionMsg = 'Press ⌘-' + actionKey + ' to ' + action;
41    }
42    else {
43        actionMsg = 'Press Ctrl-' + actionKey + ' to ' + action;
44    }
45
46    return actionMsg;
47}
48
49// for the window resize
50$(window).resize(function() {
51    setMenuHeight();
52});
53
54// debouncing function from John Hann
55// http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
56(function($, sr) {
57
58    var debounce = function(func, threshold, execAsap) {
59        var timeout;
60
61        return function debounced() {
62            var obj = this, args = arguments;
63
64            function delayed() {
65                if (!execAsap)
66                    func.apply(obj, args);
67                timeout = null;
68            };
69
70            if (timeout)
71                clearTimeout(timeout);
72            else if (execAsap)
73                func.apply(obj, args);
74
75            timeout = setTimeout(delayed, threshold || 100);
76        };
77    }
78    // smartresize
79    jQuery.fn[sr] = function(fn) { return fn ? this.bind('resize', debounce(fn)) : this.trigger(sr); };
80
81})(jQuery, 'smartresize');
82
83
84jQuery(document).ready(function() {
85    var sidebarStatus = searchStatus = 'open';
86
87    // set the menu height
88    setMenuHeight();
89
90    jQuery('#overlay').on('click', function() {
91        jQuery(document.body).toggleClass('sidebar-hidden');
92        sidebarStatus = (jQuery(document.body).hasClass('sidebar-hidden') ? 'closed' : 'open');
93
94        return false;
95    });
96
97    jQuery('.scrollbar-inner').scrollbar();
98
99    jQuery('[data-sidebar-toggle]').on('click', function() {
100        jQuery(document.body).toggleClass('sidebar-hidden');
101        sidebarStatus = (jQuery(document.body).hasClass('sidebar-hidden') ? 'closed' : 'open');
102
103        return false;
104    });
105    jQuery('[data-clear-history-toggle]').on('click', function() {
106        sessionStorage.clear();
107        location.reload();
108        return false;
109    });
110    jQuery('[data-search-toggle]').on('click', function() {
111        if (sidebarStatus == 'closed') {
112            jQuery('[data-sidebar-toggle]').trigger('click');
113            jQuery(document.body).removeClass('searchbox-hidden');
114            searchStatus = 'open';
115
116            return false;
117        }
118
119        jQuery(document.body).toggleClass('searchbox-hidden');
120        searchStatus = (jQuery(document.body).hasClass('searchbox-hidden') ? 'closed' : 'open');
121
122        return false;
123    });
124
125    var ajax;
126    jQuery('[data-search-input]').on('input', function() {
127        var input = jQuery(this),
128            value = input.val(),
129            items = jQuery('[data-nav-id]');
130
131        items.removeClass('search-match');
132        if (!value.length) {
133            $('ul.topics').removeClass('searched');
134            items.css('display', 'block');
135            sessionStorage.removeItem('search-value');
136            $(".highlightable").unhighlight({ element: 'mark' })
137            return;
138        }
139
140        sessionStorage.setItem('search-value', value);
141        $(".highlightable").unhighlight({ element: 'mark' }).highlight(value, { element: 'mark' });
142
143        if (ajax && ajax.abort) ajax.abort();
144        ajax = jQuery.ajax({
145            url: input.data('search-input') + ':' + value
146        }).done(function(data) {
147            if (data && data.results && data.results.length) {
148                items.css('display', 'none');
149                $('ul.topics').addClass('searched');
150                data.results.forEach(function(navitem) {
151                    jQuery('[data-nav-id="' + navitem + '"]').css('display', 'block').addClass('search-match');
152                    jQuery('[data-nav-id="' + navitem + '"]').parents('li').css('display', 'block');
153                });
154            }
155            ;
156
157        });
158        jQuery('[data-search-clear]').on('click', function() {
159            jQuery('[data-search-input]').val('').trigger('input');
160            sessionStorage.removeItem('search-input');
161            $(".highlightable").unhighlight({ element: 'mark' })
162        });
163    });
164
165    if (sessionStorage.getItem('search-value')) {
166        jQuery(document.body).removeClass('searchbox-hidden');
167        jQuery('[data-search-input]').val(sessionStorage.getItem('search-value'));
168        jQuery('[data-search-input]').trigger('input');
169    }
170
171    // clipboard
172    var clipInit = false;
173    $('code').each(function() {
174        var code = $(this),
175            text = code.text();
176
177        if (text.length > 5) {
178            if (!clipInit) {
179                var text, clip = new Clipboard('.copy-to-clipboard', {
180                    text: function(trigger) {
181                        text = $(trigger).prev('code').text();
182                        return text.replace(/^\$\s/gm, '');
183                    }
184                });
185
186                var inPre;
187                clip.on('success', function(e) {
188                    e.clearSelection();
189                    inPre = $(e.trigger).parent().prop('tagName') == 'PRE';
190                    $(e.trigger).attr('aria-label', 'Copied to clipboard!').addClass('tooltipped tooltipped-' + (inPre ? 'w' : 's'));
191                });
192
193                clip.on('error', function(e) {
194                    inPre = $(e.trigger).parent().prop('tagName') == 'PRE';
195                    $(e.trigger).attr('aria-label', fallbackMessage(e.action)).addClass('tooltipped tooltipped-' + (inPre ? 'w' : 's'));
196                    $(document).one('copy', function(){
197                        $(e.trigger).attr('aria-label', 'Copied to clipboard!').addClass('tooltipped tooltipped-' + (inPre ? 'w' : 's'));
198                    });
199                });
200
201                clipInit = true;
202            }
203
204            code.after('<span class="copy-to-clipboard" title="Copy to clipboard" />');
205            code.next('.copy-to-clipboard').on('mouseleave', function() {
206                $(this).attr('aria-label', null).removeClass('tooltipped tooltipped-s tooltipped-w');
207            });
208        }
209    });
210    
211    // allow keyboard control for prev/next links
212    jQuery(function() {
213        jQuery('.nav-prev').click(function(){
214            location.href = jQuery(this).attr('href');
215        });
216        jQuery('.nav-next').click(function() {
217            location.href = jQuery(this).attr('href');
218        });
219    });
220
221    jQuery(document).keydown(function(e) {
222      // prev links - left arrow key
223      if(e.which == '37') {
224        jQuery('.nav.nav-prev').click();
225      }
226
227      // next links - right arrow key
228      if(e.which == '39') {
229        jQuery('.nav.nav-next').click();
230      }
231    });     
232
233});
234
235jQuery(window).on('load', function() {
236
237    function adjustForScrollbar() {
238        if ((parseInt(jQuery('#body-inner').height()) + 83) >= jQuery('#body').height()) {
239            jQuery('.nav.nav-next').css({ 'margin-right': getScrollBarWidth() });
240        } else {
241            jQuery('.nav.nav-next').css({ 'margin-right': 0 });
242        }
243    }
244
245    // adjust sidebar for scrollbar
246    adjustForScrollbar();
247
248    jQuery(window).smartresize(function() {
249        adjustForScrollbar();
250    });
251
252    // store this page in session
253    sessionStorage.setItem(jQuery('body').data('url'), 1);
254
255    // loop through the sessionStorage and see if something should be marked as visited
256    for (var url in sessionStorage) {
257        if (sessionStorage.getItem(url) == 1) jQuery('[data-nav-id="' + url + '"]').addClass('visited');
258    }
259
260
261    $(".highlightable").highlight(sessionStorage.getItem('search-value'), { element: 'mark' });
262});
263
264$(function() {
265    $('a[rel="lightbox"]').featherlight({
266        root: 'section#body'
267    });
268});
269
270jQuery.extend({
271    highlight: function(node, re, nodeName, className) {
272        if (node.nodeType === 3) {
273            var match = node.data.match(re);
274            if (match) {
275                var highlight = document.createElement(nodeName || 'span');
276                highlight.className = className || 'highlight';
277                var wordNode = node.splitText(match.index);
278                wordNode.splitText(match[0].length);
279                var wordClone = wordNode.cloneNode(true);
280                highlight.appendChild(wordClone);
281                wordNode.parentNode.replaceChild(highlight, wordNode);
282                return 1; //skip added node in parent
283            }
284        } else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children
285            !/(script|style)/i.test(node.tagName) && // ignore script and style nodes
286            !(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted
287            for (var i = 0; i < node.childNodes.length; i++) {
288                i += jQuery.highlight(node.childNodes[i], re, nodeName, className);
289            }
290        }
291        return 0;
292    }
293});
294
295jQuery.fn.unhighlight = function(options) {
296    var settings = {
297        className: 'highlight',
298        element: 'span'
299    };
300    jQuery.extend(settings, options);
301
302    return this.find(settings.element + "." + settings.className).each(function() {
303        var parent = this.parentNode;
304        parent.replaceChild(this.firstChild, this);
305        parent.normalize();
306    }).end();
307};
308
309jQuery.fn.highlight = function(words, options) {
310    var settings = {
311        className: 'highlight',
312        element: 'span',
313        caseSensitive: false,
314        wordsOnly: false
315    };
316    jQuery.extend(settings, options);
317
318    if (!words) { return; }
319
320    if (words.constructor === String) {
321        words = [words];
322    }
323    words = jQuery.grep(words, function(word, i) {
324        return word != '';
325    });
326    words = jQuery.map(words, function(word, i) {
327        return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
328    });
329    if (words.length == 0) { return this; }
330    ;
331
332    var flag = settings.caseSensitive ? "" : "i";
333    var pattern = "(" + words.join("|") + ")";
334    if (settings.wordsOnly) {
335        pattern = "\\b" + pattern + "\\b";
336    }
337    var re = new RegExp(pattern, flag);
338
339    return this.each(function() {
340        jQuery.highlight(this, re, settings.element, settings.className);
341    });
342};

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.