Socket
Socket
Sign inDemoInstall

gumshoejs

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

gumshoejs - npm Package Compare versions

Comparing version 3.5.0 to 4.0.1

.github/contributing.md

390

gulpfile.js
/**
* Gulp Packages
* Settings
* Turn on/off build features
*/
// General
var gulp = require('gulp');
var fs = require('fs');
var del = require('del');
var lazypipe = require('lazypipe');
var plumber = require('gulp-plumber');
var flatten = require('gulp-flatten');
var tap = require('gulp-tap');
var rename = require('gulp-rename');
var header = require('gulp-header');
var footer = require('gulp-footer');
var watch = require('gulp-watch');
var livereload = require('gulp-livereload');
var package = require('./package.json');
var settings = {
clean: true,
scripts: true,
polyfills: true,
styles: true,
svgs: true,
copy: true,
reload: true
};
// Scripts and tests
var jshint = require('gulp-jshint');
var stylish = require('jshint-stylish');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var optimizejs = require('gulp-optimize-js');
// Docs
var markdown = require('gulp-markdown');
var fileinclude = require('gulp-file-include');
/**

@@ -37,14 +22,22 @@ * Paths to project folders

var paths = {
input: 'src/**/*',
input: 'src/',
output: 'dist/',
scripts: {
input: 'src/js/*',
output: 'dist/js/'
polyfills: '.polyfill.js',
output: 'dist/'
},
docs: {
input: 'src/docs/*.{html,md,markdown}',
output: 'docs/',
templates: 'src/docs/_templates/',
assets: 'src/docs/assets/**'
}
styles: {
input: 'src/sass/**/*.{scss,sass}',
output: 'dist/css/'
},
svgs: {
input: 'src/svg/*.svg',
output: 'dist/svg/'
},
copy: {
input: 'src/copy/**/*',
output: './'
},
reload: './'
};

@@ -58,14 +51,15 @@

var banner = {
full :
full:
'/*!\n' +
' * <%= package.name %> v<%= package.version %>: <%= package.description %>\n' +
' * <%= package.name %> v<%= package.version %>\n' +
' * <%= package.description %>\n' +
' * (c) ' + new Date().getFullYear() + ' <%= package.author.name %>\n' +
' * MIT License\n' +
' * <%= package.license %> License\n' +
' * <%= package.repository.url %>\n' +
' */\n\n',
min :
min:
'/*!' +
' <%= package.name %> v<%= package.version %>' +
' | (c) ' + new Date().getFullYear() + ' <%= package.author.name %>' +
' | MIT License' +
' | <%= package.license %> License' +
' | <%= package.repository.url %>' +

@@ -77,126 +71,248 @@ ' */\n'

/**
* Gulp Taks
* Gulp Packages
*/
// General
var {gulp, src, dest, watch, series, parallel} = require('gulp');
var del = require('del');
var flatmap = require('gulp-flatmap');
var lazypipe = require('lazypipe');
var rename = require('gulp-rename');
var header = require('gulp-header');
var package = require('./package.json');
// Scripts
var jshint = require('gulp-jshint');
var stylish = require('jshint-stylish');
var concat = require('gulp-concat');
var uglify = require('gulp-terser');
var optimizejs = require('gulp-optimize-js');
// Styles
var sass = require('gulp-sass');
var prefix = require('gulp-autoprefixer');
var minify = require('gulp-cssnano');
// SVGs
var svgmin = require('gulp-svgmin');
// BrowserSync
var browserSync = require('browser-sync');
/**
* Gulp Tasks
*/
// Remove pre-existing content from output folders
var cleanDist = function (done) {
// Make sure this feature is activated before running
if (!settings.clean) return done();
// Clean the dist folder
del.sync([
paths.output
]);
// Signal completion
return done();
};
// Repeated JavaScript tasks
var jsTasks = lazypipe()
.pipe(header, banner.full, {package: package})
.pipe(optimizejs)
.pipe(dest, paths.scripts.output)
.pipe(rename, {suffix: '.min'})
.pipe(uglify)
.pipe(optimizejs)
.pipe(header, banner.min, {package: package})
.pipe(dest, paths.scripts.output);
// Lint, minify, and concatenate scripts
gulp.task('build:scripts', ['clean:dist'], function() {
var jsTasks = lazypipe()
.pipe(header, banner.full, { package : package })
.pipe(optimizejs)
.pipe(gulp.dest, paths.scripts.output)
.pipe(rename, { suffix: '.min' })
.pipe(uglify)
.pipe(optimizejs)
.pipe(header, banner.min, { package : package })
.pipe(gulp.dest, paths.scripts.output);
var buildScripts = function (done) {
return gulp.src(paths.scripts.input)
.pipe(plumber())
.pipe(tap(function (file, t) {
if ( file.isDirectory() ) {
var name = file.relative + '.js';
return gulp.src(file.path + '/*.js')
.pipe(concat(name))
// Make sure this feature is activated before running
if (!settings.scripts) return done();
// Run tasks on script files
src(paths.scripts.input)
.pipe(flatmap(function(stream, file) {
// If the file is a directory
if (file.isDirectory()) {
// Setup a suffix variable
var suffix = '';
// If separate polyfill files enabled
if (settings.polyfills) {
// Update the suffix
suffix = '.polyfills';
// Grab files that aren't polyfills, concatenate them, and process them
src([file.path + '/*.js', '!' + file.path + '/*' + paths.scripts.polyfills])
.pipe(concat(file.relative + '.js'))
.pipe(jsTasks());
}
// Grab all files and concatenate them
// If separate polyfills enabled, this will have .polyfills in the filename
src(file.path + '/*.js')
.pipe(concat(file.relative + suffix + '.js'))
.pipe(jsTasks());
return stream;
}
}))
.pipe(jsTasks());
});
// Otherwise, process the file
return stream.pipe(jsTasks());
}));
// Signal completion
done();
};
// Lint scripts
gulp.task('lint:scripts', function () {
return gulp.src(paths.scripts.input)
.pipe(plumber())
var lintScripts = function (done) {
// Make sure this feature is activated before running
if (!settings.scripts) return done();
// Lint scripts
src(paths.scripts.input)
.pipe(jshint())
.pipe(jshint.reporter('jshint-stylish'));
});
// Remove pre-existing content from output folder
gulp.task('clean:dist', function () {
del.sync([
paths.output
]);
});
// Signal completion
done();
// Generate documentation
gulp.task('build:docs', ['compile', 'clean:docs'], function() {
return gulp.src(paths.docs.input)
.pipe(plumber())
.pipe(fileinclude({
prefix: '@@',
basepath: '@file'
};
// Process, lint, and minify Sass files
var buildStyles = function (done) {
// Make sure this feature is activated before running
if (!settings.styles) return done();
// Run tasks on all Sass files
src(paths.styles.input)
.pipe(sass({
outputStyle: 'expanded',
sourceComments: true
}))
.pipe(tap(function (file, t) {
if ( /\.md|\.markdown/.test(file.path) ) {
return t.through(markdown);
.pipe(prefix({
browsers: ['last 2 version', '> 0.25%'],
cascade: true,
remove: true
}))
.pipe(header(banner.full, { package : package }))
.pipe(dest(paths.styles.output))
.pipe(rename({suffix: '.min'}))
.pipe(minify({
discardComments: {
removeAll: true
}
}))
.pipe(header(fs.readFileSync(paths.docs.templates + '/_header.html', 'utf8')))
.pipe(footer(fs.readFileSync(paths.docs.templates + '/_footer.html', 'utf8')))
.pipe(gulp.dest(paths.docs.output));
});
.pipe(header(banner.min, { package : package }))
.pipe(dest(paths.styles.output));
// Copy distribution files to docs
gulp.task('copy:dist', ['compile', 'clean:docs'], function() {
return gulp.src(paths.output + '/**')
.pipe(plumber())
.pipe(gulp.dest(paths.docs.output + '/dist'));
});
// Signal completion
done();
// Copy documentation assets to docs
gulp.task('copy:assets', ['clean:docs'], function() {
return gulp.src(paths.docs.assets)
.pipe(plumber())
.pipe(gulp.dest(paths.docs.output + '/assets'));
});
};
// Remove prexisting content from docs folder
gulp.task('clean:docs', function () {
return del.sync(paths.docs.output);
});
// Optimize SVG files
var buildSVGs = function (done) {
// Spin up livereload server and listen for file changes
gulp.task('listen', function () {
livereload.listen();
gulp.watch(paths.input).on('change', function(file) {
gulp.start('default');
gulp.start('refresh');
// Make sure this feature is activated before running
if (!settings.svgs) return done();
// Optimize SVG files
src(paths.svgs.input)
.pipe(svgmin())
.pipe(dest(paths.svgs.output));
// Signal completion
done();
};
// Copy static files into output folder
var copyFiles = function (done) {
// Make sure this feature is activated before running
if (!settings.copy) return done();
// Copy static files
src(paths.copy.input)
.pipe(dest(paths.copy.output));
// Signal completion
done();
};
// Watch for changes to the src directory
var startServer = function (done) {
// Make sure this feature is activated before running
if (!settings.reload) return done();
// Initialize BrowserSync
browserSync.init({
server: {
baseDir: paths.reload
}
});
});
// Run livereload after file change
gulp.task('refresh', ['compile', 'docs'], function () {
livereload.changed();
});
// Signal completion
done();
};
// Reload the browser when files change
var reloadBrowser = function (done) {
if (!settings.reload) return done();
browserSync.reload();
done();
};
// Watch for changes
var watchSource = function (done) {
watch(paths.input, series(exports.default, reloadBrowser));
done();
};
/**
* Task Runners
* Export Tasks
*/
// Compile files
gulp.task('compile', [
'lint:scripts',
'clean:dist',
'build:scripts'
]);
// Default task
// gulp
exports.default = series(
cleanDist,
parallel(
buildScripts,
lintScripts,
buildStyles,
buildSVGs,
copyFiles
)
);
// Generate documentation
gulp.task('docs', [
'clean:docs',
'build:docs',
'copy:dist',
'copy:assets'
]);
// Compile files and generate docs (default)
gulp.task('default', [
'compile',
'docs'
]);
// Compile files and generate docs when something changes
gulp.task('watch', [
'listen',
'default'
]);
// Watch and reload
// gulp watch
exports.watch = series(
exports.default,
startServer,
watchSource
);
{
"name": "gumshoejs",
"version": "3.5.0",
"description": "A simple, framework-agnostic scrollspy script.",
"main": "./dist/js/gumshoe.min.js",
"author": {
"name": "Chris Ferdinandi",
"url": "http://gomakethings.com"
},
"license": "MIT",
"repository": {
"type": "git",
"url": "http://github.com/cferdinandi/gumshoe"
},
"devDependencies": {
"del": "^2.2.0",
"gulp": "^3.9.1",
"gulp-concat": "^2.6.0",
"gulp-file-include": "^0.14.0",
"gulp-flatten": "^0.3.1",
"gulp-footer": "^1.0.5",
"gulp-header": "^1.8.8",
"gulp-jshint": "^2.0.1",
"gulp-livereload": "^3.8.1",
"gulp-markdown": "^1.2.0",
"gulp-optimize-js": "^1.0.2",
"gulp-plumber": "^1.1.0",
"gulp-rename": "^1.2.2",
"gulp-tap": "^0.1.3",
"gulp-uglify": "^2.0.0",
"gulp-watch": "^4.3.9",
"jshint": "^2.9.4",
"jshint-stylish": "^2.2.1",
"lazypipe": "^1.0.1",
"node-fs": "^0.1.7"
}
"name": "gumshoejs",
"version": "4.0.1",
"description": "A simple, framework-agnostic scrollspy script.",
"main": "./dist/js/gumshoe.min.js",
"author": {
"name": "Chris Ferdinandi",
"url": "http://gomakethings.com"
},
"license": "MIT",
"repository": {
"type": "git",
"url": "http://github.com/cferdinandi/gumshoe"
},
"devDependencies": {
"gulp": "4.0.0",
"del": "3.0.0",
"lazypipe": "1.0.1",
"gulp-flatmap": "1.0.2",
"gulp-header": "2.0.5",
"gulp-rename": "1.4.0",
"jshint": "2.9.6",
"gulp-jshint": "2.1.0",
"jshint-stylish": "2.2.1",
"gulp-concat": "2.6.1",
"gulp-terser": "1.1.7",
"gulp-optimize-js": "1.1.0",
"gulp-sass": "4.0.2",
"gulp-cssnano": "2.1.3",
"gulp-autoprefixer": "6.0.0",
"gulp-svgmin": "2.1.0",
"browser-sync": "2.26.3"
}
}
# Gumshoe [![Build Status](https://travis-ci.org/cferdinandi/gumshoe.svg)](https://travis-ci.org/cferdinandi/gumshoe)
A simple, framework-agnostic scrollspy script. Gumshoe works great with [Smooth Scroll](https://github.com/cferdinandi/smooth-scroll).
A simple vanilla JS scrollspy script. Gumshoe works great with [Smooth Scroll](https://github.com/cferdinandi/smooth-scroll).
*See Gumshoe in action on Apple's [Swift.org website](https://swift.org/).*
**[View the Demo on CodePen &rarr;](https://codepen.io/cferdinandi/pen/aMvxKr)**
[Download Gumshoe](https://github.com/cferdinandi/gumshoe/archive/master.zip) / [View the demo](http://cferdinandi.github.io/gumshoe/)
<hr>
### Want to learn how to write your own vanilla JS plugins? Check out ["The Vanilla JS Guidebook"](https://gomakethings.com/vanilla-js-guidebook/) and level-up as a web developer. 🚀
### Want to learn how to write your own vanilla JS plugins? Check out my [Vanilla JS Pocket Guides](https://vanillajsguides.com/) or join the [Vanilla JS Academy](https://vanillajsacademy.com) and level-up as a web developer. 🚀

@@ -16,3 +14,2 @@ <hr>

## Getting Started

@@ -24,128 +21,304 @@

There are two versions of Gumshoe: the standalone version, and one that comes preloaded with polyfills for `closest()` and `CustomEvent()`, which are only supported in newer browsers.
If you're including your own polyfills or don't want to enable this feature for older browsers, use the standalone version. Otherwise, use the version with polyfills.
**Direct Download**
You can [download the files directly from GitHub](https://github.com/cferdinandi/gumshoe/archive/master.zip).
```html
<script src="dist/js/gumshoe.js"></script>
<script src="path/to/gumshoe.polyfills.min.js"></script>
```
### 2. Add the markup to your HTML.
**CDN**
You can also use the [jsDelivr CDN](https://cdn.jsdelivr.net/gh/cferdinandi/gumshoe/dist/). I recommend linking to a specific version number or version range to prevent major updates from breaking your site. Gumshoe uses semantic versioning.
```html
<nav data-gumshoe-header>
<ul data-gumshoe>
<li class="active"><a class="active" href="#eenie">Eenie</a></li>
<li><a href="#meanie">Meanie</a></li>
<li><a href="#minnie">Minnie</a></li>
<li><a href="#moe">Moe</a></li>
</ul>
</nav>
<!-- Always get the latest version -->
<!-- Not recommended for production sites! -->
<script src="https://cdn.jsdelivr.net/gh/cferdinandi/gumshoe/dist/gumshoe.polyfills.min.js"></script>
<!-- Get minor updates and patch fixes within a major version -->
<script src="https://cdn.jsdelivr.net/gh/cferdinandi/gumshoe@4/dist/gumshoe.polyfills.min.js"></script>
<!-- Get patch fixes within a minor version -->
<script src="https://cdn.jsdelivr.net/gh/cferdinandi/gumshoe@4.0/dist/gumshoe.polyfills.min.js"></script>
<!-- Get a specific version -->
<script src="https://cdn.jsdelivr.net/gh/cferdinandi/gumshoe@4.0.0/dist/gumshoe.polyfills.min.js"></script>
```
Add the `[data-gumshoe]` attribute to the navigation list that Gumshoe should watch.
### 2. Add the markup to your HTML.
If you're using a fixed header, add the `[data-gumshoe-header]` attribute and Gumshoe will automatically offset its calculations based on the header's height and distance from the top of the page. If you have multiple fixed headers, add `[data-gumshoe-header]` to the last one in the markup.
The only thing Gumshoe needs to work is a list of anchor links. They can be ordered or unordered, inline or unstyled, or even nested.
```html
<ul id="my-awesome-nav">
<li><a href="#eenie">Eenie</a></li>
<li><a href="#meenie">Meenie</a></li>
<li><a href="#miney">Miney</a></li>
<li><a href="#mo">Mo</a></li>
</ul>
```
### 3. Initialize Gumshoe.
In the footer of your page, after the content, initialize Gumshoe by passing in a selector for the navigation links that should be detected as the user scrolls.
```html
<script>
gumshoe.init();
var spy = new Gumshoe('#my-awesome-nav a');
</script>
```
In the footer of your page, after the content, initialize Gumshoe. And that's it, you're done. Nice work!
### 4. Add styling.
Gumshoe adds the `.active` class to the list item (`<li></li>`) and content for the active link, but does not include any styling.
Add styles to your CSS as desired. And that's it, you're done. Nice work!
## Installing with Package Managers
```css
#my-awesome-nav a.active {
font-weight: bold;
}
```
You can install Gumshoe with your favorite package manager.
**[View a Demo on CodePen &rarr;](https://codepen.io/cferdinandi/pen/aMvxKr)**
* **NPM:** `npm install cferdinandi/gumshoe`
* **Bower:** `bower install https://github.com/cferdinandi/gumshoe.git`
* **Component:** `component install cferdinandi/gumshoe`
*__Note:__ you can customize the class names with [user options](#options-and-settings).*
## Working with the Source Files
## Nested navigation
If you would prefer, you can work with the development code in the `src` directory using the included [Gulp build system](http://gulpjs.com/). This compiles, lints, and minifies code.
If you have a nested navigation menu with multiple levels, Gumshoe can also apply an `.active` class to the parent list items of the currently active link.
### Dependencies
Make sure these are installed first.
```html
<ul id="my-awesome-nav">
<li><a href="#eenie">Eenie</a></li>
<li>
<a href="#meenie">Meenie</a>
<ul>
<li><a href="#hickory">Hickory</a></li>
<li><a href="#dickory">Dickory</a></li>
<li><a href="#doc">Doc</a></li>
</ul>
</li>
<li><a href="#miney">Miney</a></li>
<li><a href="#mo">Mo</a></li>
</ul>
```
* [Node.js](http://nodejs.org)
* [Gulp](http://gulpjs.com) `sudo npm install -g gulp`
Set `nested` to `true` when instantiating Gumshoe. You can also customize the class name.
### Quick Start
```js
var spy = new Gumshoe('#my-awesome-nav a', {
nested: true,
nestedClass: 'active-parent'
});
```
1. In bash/terminal/command line, `cd` into your project directory.
2. Run `npm install` to install required files.
3. When it's done installing, run one of the task runners to get going:
* `gulp` manually compiles files.
* `gulp watch` automatically compiles files and applies changes using [LiveReload](http://livereload.com/).
**[Try nested navigation on CodePen &rarr;](https://codepen.io/cferdinandi/pen/JzYVxj)**
## Catching reflows
## Options and Settings
If the content that's linked to by your navigation has different layouts at different viewports, Gumshoe will need to detect these changes and update some calculations behind-the-scenes.
Set `reflow` to `true` to enable this (it's off by default).
```js
var spy = new Gumshoe('#my-awesome-nav a', {
reflow: true
});
```
## Accounting for fixed headers
If you have a fixed header on your page, you may want to offset when a piece of content is considered "active."
The `offset` user setting accepts either a number, or a function that returns a number. If you need to dynamically calculate dimensions, a function is the preferred method.
Here's an example that automatically calculates a header's height and offsets by that amount.
```js
// Get the header
var header = document.querySelector('#my-header');
// Initialize Gumshoe
var spy = new Gumshoe('#my-awesome-nav a', {
offset: function () {
return header.getBoundingClientRect().height;
}
});
```
**[Try using an offset on CodePen &rarr;](https://codepen.io/cferdinandi/pen/eXpLqo)**
## API
Gumshoe includes smart defaults and works right out of the box. But if you want to customize things, it also has a robust API that provides multiple ways for you to adjust the default options and settings.
### Global Settings
### Options and Settings
You can pass options and callbacks into Gumshoe through the `init()` function:
You can pass options into Gumshoe when instantiating.
```javascript
gumshoe.init({
selector: '[data-gumshoe] a', // Default link selector (must use a valid CSS selector)
selectorHeader: '[data-gumshoe-header]', // Fixed header selector (must use a valid CSS selector)
container: window, // The element to spy on scrolling in (must be a valid DOM Node)
offset: 0, // Distance in pixels to offset calculations
activeClass: 'active', // Class to apply to active navigation link and its parent list item
scrollDelay: false, // Wait until scrolling has stopped before updating the navigation
callback: function (nav) {} // Callback to run after setting active link
var spy = new Gumshoe('#my-awesome-nav a', {
// Active classes
navClass: 'active', // applied to the nav list item
contentClass: 'active', // applied to the content
// Nested navigation
nested: false, // if true, add classes to parents of active link
nestedClass: 'active', // applied to the parent items
// Offset & reflow
offset: 0, // how far from the top of the page to activate a content area
reflow: false, // if true, listen for reflows
// Event support
events: true // if true, emit custom events
});
```
***Note:*** *The `scrollDelay` option can be useful in preventing the elements of your navigation from being highlighted and unhighlighted in rapid succession when quickly scrolling (e.g., with [Smooth Scroll](https://github.com/cferdinandi/smooth-scroll)) through a page with many navigation items (e.g. a long document with a table of contents in the sidebar).*
### Custom Events
### Use Gumshoe events in your own scripts
Gumshoe emits two custom events:
You can also call Gumshoe events in your own scripts.
- `gumshoeActivate` is emitted when a link is activated.
- `gumshoeDeactivate` is emitted when a link is deactivated.
#### setDistances()
Recalculate the height of document, the height of the fixed header, and how far navigation targets are from the top of the document.
Both events are emitted on the list item and bubble up. You can listen for them with the `addEventListener()` method. The `event.detail` object includes the `link` and `content` elements, and the `settings` for the current instantiation.
```js
// Listen for activate events
document.addEventListener('gumshoeActivate', function (event) {
// The list item
var li = event.target;
// The link
var link = event.detail.link;
// The content
var content = event.detail.content;
}, false);
```
### Methods
Gumshoe also exposes several public methods.
#### setup()
Setups all of the calculations Gumshoe needs behind-the-scenes. If you dynamically add navigation items to the DOM after Gumshoe is instantiated, you can run this method to update the calculations.
**Example**
```javascript
gumshoe.setDistances();
var spy = new Gumshoe('#my-awesome-nav a');
spy.setup();
```
#### getCurrentNav()
Determine which navigation element is currently active and add active classes.
#### detect()
Activate the navigation link that's content is currently in the viewport.
**Example**
```javascript
gumshoe.getCurrentNav();
var spy = new Gumshoe('#my-awesome-nav a');
spy.detect();
```
#### destroy()
Destroy the current `gumshoe.init()`. This is called automatically during the init function to remove any existing initializations.
Destroy the current instantiation of Gumshoe.
**Example**
```javascript
gumshoe.destroy();
var spy = new Gumshoe('#my-awesome-nav a');
spy.destroy();
```
#### init()
Reinitialize Gumshoe. This is called automatically when you instantiate your `new Gumshoe` object, but can be used to reinitialize your instance after running `destroy()`.
**Example**
```javascript
var spy = new Gumshoe('#my-awesome-nav a');
spy.destroy();
// Some time later...
spy.init({
// New options
});
```
## Working with the Source Files
If you would prefer, you can work with the development code in the `src` directory using the included [Gulp build system](http://gulpjs.com/). This compiles, lints, and minifies code.
### Dependencies
Make sure these are installed first.
* [Node.js](http://nodejs.org)
* [Gulp](http://gulpjs.com) `sudo npm install -g gulp`
### Quick Start
1. In bash/terminal/command line, `cd` into your project directory.
2. Run `npm install` to install required files.
3. When it's done installing, run one of the task runners to get going:
* `gulp` manually compiles files.
* `gulp watch` automatically compiles files when changes are made and applies changes using [LiveReload](http://livereload.com/).
## Migrating to Gumshoe 4 from Older Versions
Gumshoe 4 is a ground-up rewrite.
### New Features
- Multiple instantiations can be run with different settings for each.
- An active class is now added to the content as well.
- Nested navigation is now supported.
- Offsets can be dynamically calculated instead of set just once at initialization.
- Special and non-Roman characters can now be used in anchor links and IDs.
- Custom events provide a more flexible way to react to DOM changes.
### Breaking Changes
- Gumshoe must now be instantiated as a new object (`new Gumshoe()`) instead of being initialized `gumshoe.init()`.
- Callback methods have been removed in favor of events.
- Automatic header offsetting has been removed.
## Browser Compatibility
Gumshoe works in all modern browsers, and IE 10 and above. You can extend browser support back to IE 9 with the [classList.js polyfill](https://github.com/eligrey/classList.js/).
Gumshoe works in all modern browsers, and IE 9 and above.
### Polyfills
Support back to IE9 requires polyfills for `closest()` and `CustomEvent()`. Without them, support starts with Edge.
## How to Contribute
Use the included polyfills version of Gumshoe, or include your own.
Please review the [contributing guidelines](CONTRIBUTING.md).
## License
The code is available under the [MIT License](LICENSE.md).

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc