PageSourceSearch

https://serge.org/wp-content/themes/serge/js/third-party/stickkit.js?ver=1.0

js serge.org collected 2026-10-02 09:57:15 UTC 18,421 bytes, 418 lines download raw bytes

1/*!
2 * Theia Sticky Sidebar v1.7.0
3 * https://github.com/WeCodePixels/theia-sticky-sidebar
4 *
5 * Glues your website's sidebars, making them permanently visible while scrolling.
6 *
7 * Copyright 2013-2016 WeCodePixels and other contributors
8 * Released under the MIT license
9 */
10
11(function ($) {
12  
13    var NectarStickyState = function() {
14      this.scrollTop = $(document).scrollTop();
15      this.scrollLeft = $(document).scrollLeft();
16      this.bindEvents()
17    };
18    
19    NectarStickyState.prototype.bindEvents = function() {
20      
21      var that = this;
22      
23      $(document).on('scroll', function() {
24        that.scrollTop = $(document).scrollTop();
25        that.scrollLeft = $(document).scrollLeft();
26      });
27      
28    };
29    
30    var nectarStickyState = new NectarStickyState();
31    
32    $.fn.theiaStickySidebar = function (options) {
33        var defaults = {
34            'containerSelector': '',
35            'additionalMarginTop': 0,
36            'additionalMarginBottom': 0,
37            'updateSidebarHeight': true,
38            'minWidth': 0,
39            'disableOnResponsiveLayouts': true,
40            'sidebarBehavior': 'modern',
41            'defaultPosition': 'relative',
42            'namespace': 'TSS'
43        };
44        options = $.extend(defaults, options);
45
46        // Validate options
47        options.additionalMarginTop = parseInt(options.additionalMarginTop) || 0;
48        options.additionalMarginBottom = parseInt(options.additionalMarginBottom) || 0;
49
50        tryInitOrHookIntoEvents(options, this);
51
52        // Try doing init, otherwise hook into window.resize and document.scroll and try again then.
53        function tryInitOrHookIntoEvents(options, $that) {
54            var success = tryInit(options, $that);
55
56            if (!success) {
57                console.log('TSS: Body width smaller than options.minWidth. Init is delayed.');
58
59                $(document).on('scroll.' + options.namespace, function (options, $that) {
60                    return function (evt) {
61                        var success = tryInit(options, $that);
62
63                        if (success) {
64                            $(this).unbind(evt);
65                        }
66                    };
67                }(options, $that));
68                $(window).on('resize.' + options.namespace, function (options, $that) {
69                    return function (evt) {
70                        var success = tryInit(options, $that);
71
72                        if (success) {
73                            $(this).unbind(evt);
74                        }
75                    };
76                }(options, $that))
77            }
78        }
79
80        // Try doing init if proper conditions are met.
81        function tryInit(options, $that) {
82            if (options.initialized === true) {
83                return true;
84            }
85
86            if ($('body').width() < options.minWidth) {
87                return false;
88            }
89
90            init(options, $that);
91
92            return true;
93        }
94
95        // Init the sticky sidebar(s).
96        function init(options, $that) {
97            options.initialized = true;
98
99            // Add CSS
100            var existingStylesheet = $('#theia-sticky-sidebar-stylesheet-' + options.namespace);
101            if (existingStylesheet.length === 0) {
102                $('head').append($('<style id="theia-sticky-sidebar-stylesheet-' + options.namespace + '">.theiaStickySidebar:after {content: ""; display: table; clear: both;}</style>'));
103            }
104
105            $that.each(function () {
106                var o = {};
107
108                o.sidebar = $(this);
109                
110                // Save options
111                o.options = options || {};
112
113                // Get container
114                o.container = $(o.options.containerSelector);
115                if (o.container.length == 0) {
116                    o.container = o.sidebar.parent();
117                }
118
119                // Create sticky sidebar
120                o.sidebar.parents().css('-webkit-transform', 'none'); // Fix for WebKit bug - https://code.google.com/p/chromium/issues/detail?id=20574
121                o.sidebar.css({
122                    'position': o.options.defaultPosition,
123                    'overflow': 'visible',
124                    // The "box-sizing" must be set to "content-box" because we set a fixed height to this element when the sticky 
124sidebar has a fixed position.
125                    '-webkit-box-sizing': 'border-box',
126                    '-moz-box-sizing': 'border-box',
127                    'box-sizing': 'border-box'
128                });
129
130                // Get the sticky sidebar element. If none has been found, then create one.
131                o.stickySidebar = o.sidebar.find('.theiaStickySidebar');
132                if (o.stickySidebar.length == 0) {
133                    // Remove <script> tags, otherwise they will be run again when added to the stickySidebar.
134                    var javaScriptMIMETypes = /(?:text|application)\/(?:x-)?(?:javascript|ecmascript)/i;
135                    o.sidebar.find('script').filter(function (index, script) {
136                        return script.type.length === 0 || script.type.match(javaScriptMIMETypes);
137                    }).remove();
138
139                    o.stickySidebar = $('<div>').addClass('theiaStickySidebar').append(o.sidebar.children());
140                    o.sidebar.append(o.stickySidebar);
141                }
142
143                // Get existing top and bottom margins and paddings
144                o.marginBottom = parseInt(o.sidebar.css('margin-bottom'));
145                o.paddingTop = parseInt(o.sidebar.css('padding-top'));
146                o.paddingBottom = parseInt(o.sidebar.css('padding-bottom'));
147
148                // Add a temporary padding rule to check for collapsable margins.
149                var collapsedTopHeight = o.stickySidebar.offset().top;
150                var collapsedBottomHeight = o.stickySidebar.outerHeight();
151                o.stickySidebar.css('padding-top', 1);
152                o.stickySidebar.css('padding-bottom', 1);
153                collapsedTopHeight -= o.stickySidebar.offset().top;
154                collapsedBottomHeight = o.stickySidebar.outerHeight() - collapsedBottomHeight - collapsedTopHeight;
155                if (collapsedTopHeight == 0) {
156                    o.stickySidebar.css('padding-top', 0);
157                    o.stickySidebarPaddingTop = 0;
158                }
159                else {
160                    o.stickySidebarPaddingTop = 1;
161                }
162
163                if (collapsedBottomHeight == 0) {
164                    o.stickySidebar.css('padding-bottom', 0);
165                    o.stickySidebarPaddingBottom = 0;
166                }
167                else {
168                    o.stickySidebarPaddingBottom = 1;
169                }
170                
171                // Nectar addition - cache stuff
172                o.stickySidebarVisible = o.stickySidebar.is(":visible");
173                o.windowHeight = $(window).height();
174                // Nectar addition end
175                
176                // We use this to know whether the user is scrolling up or down.
177                o.previousScrollTop = null;
178
179                // Scroll top (value) when the sidebar has fixed position.
180                o.fixedScrollTop = 0;
181
182                // Set sidebar to default values.
183                resetSidebar();
184
185                o.onScroll = function (o) {
186
187                    
188                    // Stop if the sidebar isn't visible.
189                    //nectar addition of the ocm and search
190                    if (!o.stickySidebarVisible || $('.ocm-effect-wrap.material-ocm-open').length > 0 ) {
191                        return;
192                    }
193
194                    // Stop if the window is too small.
195                    /*if ($('body').width() < o.options.minWidth) {
196                        resetSidebar();
197                        return;
198                    } */
199                    
200                    // Stop if the sidebar width is larger than the container width (e.g. the theme is responsive and the sidebar is now below the content)
201                    if (o.options.disableOnResponsiveLayouts) {
202                        var sidebarWidth = o.sidebar.outerWidth(o.sidebar.css('float') == 'none');
203
204                        if (sidebarWidth + 50 > o.container.width()) {
205                            resetSidebar();
206                            return;
207                        }
208                    }
209
210                    var scrollTop = nectarStickyState.scrollTop;
211                    var position = 'static';
212                    
213                    var cachedOffsetTop = o.sidebar.offset().top;
214                    
215                    // If the user has scrolled down enough for the sidebar to be clipped at the top, then we can consider changing its position.
216                    if (scrollTop >= cachedOffsetTop + (o.paddingTop - o.options.additionalMarginTop)) {
217                        
218                        var cachedOuterHeight = o.stickySidebar.outerHeight();
219                    
220                        // The top and bottom offsets, used in various calculations.
221                        var offsetTop = o.paddingTop + options.additionalMarginTop;
222                        var offsetBottom = o.paddingBottom + o.marginBottom + options.additionalMarginBottom;
223
224                        // All top and bottom positions are relative to the window, not to the parent elemnts.
225                        var containerTop = cachedOffsetTop;
226                        var containerBottom = cachedOffsetTop + getClearedHeight(o.container);
227
228                        // The top and bottom offsets relative to the window screen top (zero) and bottom (window height).
229                        var windowOffsetTop = 0 + options.additionalMarginTop;
230                        var windowOffsetBottom;
231
232                        
233                        var sidebarSmallerThanWindow = (cachedOuterHeight + offsetTop + offsetBottom) < o.windowHeight;
234                        if (sidebarSmallerThanWindow) {
235                            windowOffsetBottom = windowOffsetTop + cachedOuterHeight;
236                        }
237                        else {
238                            windowOffsetBottom = o.windowHeight - o.marginBottom - o.paddingBottom - options.additionalMarginBottom;
239                        }
240
241                        var staticLimitTop = containerTop - scrollTop + o.paddingTop;
242                        var staticLimitBottom = containerBottom - scrollTop - o.paddingBottom - o.marginBottom;
243
244                        var top = o.stickySidebar.offset().top - scrollTop;
245                        var scrollTopDiff = o.previousScrollTop - scrollTop;
246
247                        // If the sidebar position is fixed, then it won't move up or down by itself. So, we manually adjust the top coordinate.
248                        if (o.stickySidebar.css('position') == 'fixed') {
249                            if (o.options.sidebarBehavior == 'modern') {
250                                top += scrollTopDiff;
251                            }
252                        }
253
254                        if (o.options.sidebarBehavior == 'stick-to-top') {
255                            top = options.additionalMarginTop;
256                        }
257
258                        if (o.options.sidebarBehavior == 'stick-to-bottom') {
259                            top = windowOffsetBottom - cachedOuterHeight;
260                        }
261
262                        if (scrollTopDiff > 0) { // If the user is scrolling up.
263                            top = Math.min(top, windowOffsetTop);
264                        }
265                        else { // If the user is scrolling down.
266                            top = Math.max(top, windowOffsetBottom - cachedOuterHeight);
267                        }
268
269                        top = Math.max(top, staticLimitTop);
270
271                        top = Math.min(top, staticLimitBottom - cachedOuterHeight);
272
273                        // If the sidebar is the same height as the container, we won't use fixed positioning.
274                        var sidebarSameHeightAsContainer = o.container.height() == cachedOuterHeight;
275
276                        if (!sidebarSameHeightAsContainer && top == windowOffsetTop) {
277                            position = 'fixed';
278                        }
279                        else if (!sidebarSameHeightAsContainer && top == windowOffsetBottom - cachedOuterHeight) {
280                            position = 'fixed';
281                        }
282                        else if (scrollTop + top - cachedOffsetTop - o.paddingTop <= options.additionalMarginTop) {
283                            // Stuck to the top of the page. No special behavior.
284                            position = 'static';
285                        }
286                        else {
287                            // Stuck to the bottom of the page.
288                            position = 'absolute';
289                        }
290                      
291                    }
292
293                    /*
294                     * Performance notice: It's OK to set these CSS values at each resize/scroll, even if they don't change.
295                     * It's way slower to first check if the values have changed.
296                     */
297                    if (position == 'fixed') {
298                        var scrollLeft = nectarStickyState.scrollLeft;
299
300                        o.stickySidebar.css({
301                            'position': 'fixed',
302                            'width': getWidthForObject(o.sidebar) + 'px',
303                            'transform': 'translateY(' + top + 'px)',
304                            'left': (o.sidebar.offset().left + parseInt(o.sidebar.css('padding-left')) - scrollLeft) + 'px',
305                            'top': '0px'
306                        });
307                    }
308                    else if (position == 'absolute') {
309                        var css = {};
310
311                        if (o.stickySidebar.css('position') != 'absolute') {
312                            css.position = 'absolute';
313                            css.transform = 'translateY(' + (scrollTop + top - o.sidebar.offset().top - o.stickySidebarPaddingTop - o.stickySidebarPaddingBottom) + 'px)';
314                            css.top = '0px';
315                        }
316
317                        css.width = getWidthForObject(o.stickySidebar) + 'px';
318                        css.left = '';
319
320                        o.stickySidebar.css(css);
321                    }
322                    else if (position == 'static') {
323                        resetSidebar();
324                    }
325
326                    if (position != 'static') {
327                        if (o.options.updateSidebarHeight == true) {
328                            o.sidebar.css({
329                                'min-height': o.stickySidebar.outerHeight() + o.stickySidebar.offset().top - o.sidebar.offset().top + o.paddingBottom
330                            });
331                        }
332                    }
333
334                    o.previousScrollTop = scrollTop;
335                };
336
337                // Initialize the sidebar's position.
338                o.onScroll(o);
339
340                // Recalculate the sidebar's position on every scroll and resize.
341                $(document).on('scroll.' + o.options.namespace, function (o) {
342                    return function () {
343                        o.onScroll(o);
344                    };
345                }(o));
346                // nectar addition end
347                $(window).on('load.' + o.options.namespace, function (o) {
348                  o.stickySidebarVisible = o.stickySidebar.is(":visible");
349                  o.windowHeight = $(window).height();
350                }(o));
351                // nectar addition end
352                $(window).on('resize.' + o.options.namespace, function (o) {
353                    return function () {
354                      // nectar addition end
355                        o.stickySidebarVisible = o.stickySidebar.is(":visible"); 
356                        o.windowHeight = $(window).height();
357                        // nectar addition end
358                        o.stickySidebar.css({'position': 'static'});
359                        o.onScroll(o);
360                    };
361                }(o));
362
363                // Recalculate the sidebar's position every time the sidebar changes its size.
364                if (typeof ResizeSensor !== 'undefined') {
365                    new ResizeSensor(o.stickySidebar[0], function (o) {
366                        return function () {
367                            o.onScroll(o);
368                        };
369                    }(o));
370                }
371
372                // Reset the sidebar to its default state
373                function resetSidebar() {
374                    o.fixedScrollTop = 0;
375                    o.sidebar.css({
376                        'min-height': '1px'
377                    });
378                    o.stickySidebar.css({
379                        'position': 'static',
380                        'width': '',
381                        'transform': 'none'
382                    });
383                }
384
385                // Get the height of a div as if its floated children were cleared. Note that this function fails if the floats are more than one level deep.
386                function getClearedHeight(e) {
387                    var height = e.height();
388
389                    e.children().each(function () {
390                        height = Math.max(height, $(this).height());
391                    });
392
393                    return height;
394                }
395            });
396        }
397
398        function getWidthForObject(object) {
399            var width;
400
401            try {
402                width = object[0].getBoundingClientRect().width;
403            }
404            catch (err) {
405            }
406
407            if (typeof width === "undefined") {
408                width = object.width();
409            }
410
411            return width;
412        }
413
414        return this;
415    }
416})(jQuery);
417
418//# sourceMappingURL=maps/theia-sticky-sidebar.js.map

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.