PageSourceSearch

https://campaignlegal.org/themes/custom/ts_calc/js/jquery.smoothscroll.js?tltwez

js campaignlegal.org collected 2026-09-24 08:40:11 UTC 10,219 bytes, 357 lines download raw bytes

1/*!
2 * jQuery Smooth Scroll - v2.2.0 - 2017-05-05
3 * https://github.com/kswedberg/jquery-smooth-scroll
4 * Copyright (c) 2017 Karl Swedberg
5 * Licensed MIT
6 */
7
8(function(factory) {
9  if (typeof define === 'function' && define.amd) {
10    // AMD. Register as an anonymous module.
11    define(['jquery'], factory);
12  } else if (typeof module === 'object' && module.exports) {
13    // CommonJS
14    factory(require('jquery'));
15  } else {
16    // Browser globals
17    factory(jQuery);
18  }
19}(function($) {
20
21  var version = '2.2.0';
22  var optionOverrides = {};
23  var defaults = {
24    exclude: [],
25    excludeWithin: [],
26    offset: 0,
27
28    // one of 'top' or 'left'
29    direction: 'top',
30
31    // if set, bind click events through delegation
32    //  supported since jQuery 1.4.2
33    delegateSelector: null,
34
35    // jQuery set of elements you wish to scroll (for $.smoothScroll).
36    //  if null (default), $('html, body').firstScrollable() is used.
37    scrollElement: null,
38
39    // only use if you want to override default behavior
40    scrollTarget: null,
41
42    // automatically focus the target element after scrolling to it
43    autoFocus: false,
44
45    // fn(opts) function to be called before scrolling occurs.
46    // `this` is the element(s) being scrolled
47    beforeScroll: function() {},
48
49    // fn(opts) function to be called after scrolling occurs.
50    // `this` is the triggering element
51    afterScroll: function() {},
52
53    // easing name. jQuery comes with "swing" and "linear." For others, you'll need an easing plugin
54    // from jQuery UI or elsewhere
55    easing: 'swing',
56
57    // speed can be a number or 'auto'
58    // if 'auto', the speed will be calculated based on the formula:
59    // (current scroll position - target scroll position) / autoCoeffic
60    speed: 400,
61
62    // coefficient for "auto" speed
63    autoCoefficient: 2,
64
65    // $.fn.smoothScroll only: whether to prevent the default click action
66    preventDefault: true
67  };
68
69  var getScrollable = function(opts) {
70    var scrollable = [];
71    var scrolled = false;
72    var dir = opts.dir && opts.dir === 'left' ? 'scrollLeft' : 'scrollTop';
73
74    this.each(function() {
75      var el = $(this);
76
77      if (this === document || this === window) {
78        return;
79      }
80
81      if (document.scrollingElement && (this === document.documentElement || this === document.body)) {
82        scrollable.push(document.scrollingElement);
83
84        return false;
85      }
86
87      if (el[dir]() > 0) {
88        scrollable.push(this);
89      } else {
90        // if scroll(Top|Left) === 0, nudge the element 1px and see if it moves
91        el[dir](1);
92        scrolled = el[dir]() > 0;
93
94        if (scrolled) {
95          scrollable.push(this);
96        }
97        // then put it back, of course
98        el[dir](0);
99      }
100    });
101
102    if (!scrollable.length) {
103      this.each(function() {
104        // If no scrollable elements and <html> has scroll-behavior:smooth because
105        // "When this property is specified on the root element, it applies to the viewport instead."
106        // and "The scroll-behavior property of the … body element is *not* propagated to the viewport."
107        // → https://drafts.csswg.org/cssom-view/#propdef-scroll-behavior
108        if (this === document.documentElement && $(this).css('scrollBehavior') === 'smooth') {
109          scrollable = [this];
110        }
111
112        // If still no scrollable elements, fall back to <body>,
113        // if it's in the jQuery collection
114        // (doing this because Safari sets scrollTop async,
115        // so can't set it to 1 and immediately get the value.)
116        if (!scrollable.length && this.nodeName === 'BODY') {
117          scrollable = [this];
118        }
119      });
120    }
121
122    // Use the first scrollable element if we're calling firstScrollable()
123    if (opts.el === 'first' && scrollable.length > 1) {
124      scrollable = [scrollable[0]];
125    }
126
127    return scrollable;
128  };
129
130  var rRelative = /^([\-\+]=)(\d+)/;
131
132  $.fn.extend({
133    scrollable: function(dir) {
134      var scrl = getScrollable.call(this, {dir: dir});
135
136      return this.pushStack(scrl);
137    },
138    firstScrollable: function(dir) {
139      var scrl = getScrollable.call(this, {el: 'first', dir: dir});
140
141      return this.pushStack(scrl);
142    },
143
144    smoothScroll: function(options, extra) {
145      options = options || {};
146
147      if (options === 'options') {
148        if (!extra) {
149          return this.first().data('ssOpts');
150        }
151
152        return this.each(function() {
153          var $this = $(this);
154          var opts = $.extend($this.data('ssOpts') || {}, extra);
155
156          $(this).data('ssOpts', opts);
157        });
158      }
159
160      var opts = $.extend({}, $.fn.smoothScroll.defaults, options);
161
162      var clickHandler = function(event) {
163        var escapeSelector = function(str) {
164          return str.replace(/(:|\.|\/)/g, '\\$1');
165        };
166
167        var link = this;
168        var $link = $(this);
169        var thisOpts = $.extend({}, opts, $link.data('ssOpts') || {});
170        var exclude = opts.exclude;
171        var excludeWithin = thisOpts.excludeWithin;
172        var elCounter = 0;
173        var ewlCounter = 0;
174        var include = true;
175        var clickOpts = {};
176        var locationPath = $.smoothScroll.filterPath(location.pathname);
177        var linkPath = $.smoothScroll.filterPath(link.pathname);
178        var hostMatch = location.hostname === link.hostname || !link.hostname;
179        var pathMatch = thisOpts.scrollTarget || (linkPath === locationPath);
180        var thisHash = escapeSelector(link.hash);
181
182        if (thisHash && !$(thisHash).length) {
183          include = false;
184        }
185
186        if (!thisOpts.scrollTarget && (!hostMatch || !pathMatch || !thisHash)) {
187          include = false;
188        } else {
189          while (include && elCounter < exclude.length) {
190            if ($link.is(escapeSelector(exclude[elCounter++]))) {
191              include = false;
192            }
193          }
194
195          while (include && ewlCounter < excludeWithin.length) {
196            if ($link.closest(excludeWithin[ewlCounter++]).length) {
197              include = false;
198            }
199          }
200        }
201
202        if (include) {
203          if (thisOpts.preventDefault) {
204            event.preventDefault();
205          }
206
207          $.extend(clickOpts, thisOpts, {
208            scrollTarget: thisOpts.scrollTarget || thisHash,
209            link: link
210          });
211
212          $.smoothScroll(clickOpts);
213        }
214      };
215
216      if (options.delegateSelector !== null) {
217        this
218        .off('click.smoothscroll', options.delegateSelector)
219        .on('click.smoothscroll', options.delegateSelector, clickHandler);
220      } else {
221        this
222        .off('click.smoothscroll')
223        .on('click.smoothscroll', clickHandler);
224      }
225
226      return this;
227    }
228  });
229
230  var getExplicitOffset = function(val) {
231    var explicit = {relative: ''};
232    var parts = typeof val === 'string' && rRelative.exec(val);
233
234    if (typeof val === 'number') {
235      explicit.px = val;
236    } else if (parts) {
237      explicit.relative = parts[1];
238      explicit.px = parseFloat(parts[2]) || 0;
239    }
240
241    return explicit;
242  };
243
244  var onAfterScroll = function(opts) {
245    var $tgt = $(opts.scrollTarget);
246
247    if (opts.autoFocus && $tgt.length) {
248      $tgt[0].focus();
249
250      if (!$tgt.is(document.activeElement)) {
251        $tgt.prop({tabIndex: -1});
252        $tgt[0].focus();
253      }
254    }
255
256    opts.afterScroll.call(opts.link, opts);
257  };
258
259  $.smoothScroll = function(options, px) {
260    if (options === 'options' && typeof px === 'object') {
261      return $.extend(optionOverrides, px);
262    }
263    var opts, $scroller, speed, delta;
264    var explicitOffset = getExplicitOffset(options);
265    var scrollTargetOffset = {};
266    var scrollerOffset = 0;
267    var offPos = 'offset';
268    var scrollDir = 'scrollTop';
269    var aniProps = {};
270    var aniOpts = {};
271
272    if (explicitOffset.px) {
273      opts = $.extend({link: null}, $.fn.smoothScroll.defaults, optionOverrides);
274    } else {
275      opts = $.extend({link: null}, $.fn.smoothScroll.defaults, options || {}, optionOverrides);
276
277      if (opts.scrollElement) {
278        offPos = 'position';
279
280        if (opts.scrollElement.css('position') === 'static') {
281          opts.scrollElement.css('position', 'relative');
282        }
283      }
284
285      if (px) {
286        explicitOffset = getExplicitOffset(px);
287      }
288    }
289
290    scrollDir = opts.direction === 'left' ? 'scrollLeft' : scrollDir;
291
292    if (opts.scrollElement) {
293      $scroller = opts.scrollElement;
294
295      if (!explicitOffset.px && !(/^(?:HTML|BODY)$/).test($scroller[0].nodeName)) {
296        scrollerOffset = $scroller[scrollDir]();
297      }
298    } else {
299      $scroller = $('html, body').firstScrollable(opts.direction);
300    }
301
302    // beforeScroll callback function must fire before calculating offset
303    opts.beforeScroll.call($scroller, opts);
304
305    scrollTargetOffset = explicitOffset.px ? explicitOffset : {
306      relative: '',
307      px: ($(opts.scrollTarget)[offPos]() && $(opts.scrollTarget)[offPos]()[opts.direction]) || 0
308    };
309
310    aniProps[scrollDir] = scrollTargetOffset.relative + (scrollTargetOffset.px + scrollerOffset + opts.offset);
311
312    speed = opts.speed;
313
314    // automatically calculate the speed of the scroll based on distance / coefficient
315    if (speed === 'auto') {
316
317      // $scroller[scrollDir]() is position before scroll, aniProps[scrollDir] is position after
318      // When delta is greater, speed will be greater.
319      delta = Math.abs(aniProps[scrollDir] - $scroller[scrollDir]());
320
321      // Divide the delta by the coefficient
322      speed = delta / opts.autoCoefficient;
323    }
324
325    aniOpts = {
326      duration: speed,
327      easing: opts.easing,
328      complete: function() {
329        onAfterScroll(opts);
330      }
331    };
332
333    if (opts.step) {
334      aniOpts.step = opts.step;
335    }
336
337    if ($scroller.length) {
338      $scroller.stop().animate(aniProps, aniOpts);
339    } else {
340      onAfterScroll(opts);
341    }
342  };
343
344  $.smoothScroll.version = version;
345  $.smoothScroll.filterPath = function(string) {
346    string = string || '';
347
348    return string
349      .replace(/^\//, '')
350      .replace(/(?:index|default).[a-zA-Z]{3,4}$/, '')
351      .replace(/\/$/, '');
352  };
353
354  // default options
355  $.fn.smoothScroll.defaults = defaults;
356
357}));

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.