update closing of streams

This commit is contained in:
Luke Pulverenti 2016-09-29 08:55:49 -04:00
parent d43c5874f2
commit 63d66a049a
78 changed files with 643 additions and 367 deletions

View file

@ -0,0 +1,43 @@
/*!
* headroom.js v0.7.0 - Give your page some headroom. Hide your header until you need it
* Copyright (c) 2014 Nick Williams - http://wicky.nillia.ms/headroom.js
* License: MIT
*/
(function(angular) {
if(!angular) {
return;
}
///////////////
// Directive //
///////////////
angular.module('headroom', []).directive('headroom', function() {
return {
restrict: 'EA',
scope: {
tolerance: '=',
offset: '=',
classes: '=',
scroller: '@'
},
link: function(scope, element) {
var options = {};
angular.forEach(Headroom.options, function(value, key) {
options[key] = scope[key] || Headroom.options[key];
});
if (options.scroller) {
options.scroller = angular.element(options.scroller)[0];
}
var headroom = new Headroom(element[0], options);
headroom.init();
scope.$on('destroy', function() {
headroom.destroy();
});
}
};
});
}(window.angular));

View file

@ -0,0 +1,7 @@
/*!
* headroom.js v0.7.0 - Give your page some headroom. Hide your header until you need it
* Copyright (c) 2014 Nick Williams - http://wicky.nillia.ms/headroom.js
* License: MIT
*/
!function(a){a&&a.module("headroom",[]).directive("headroom",function(){return{restrict:"EA",scope:{tolerance:"=",offset:"=",classes:"=",scroller:"@"},link:function(b,c){var d={};a.forEach(Headroom.options,function(a,c){d[c]=b[c]||Headroom.options[c]}),d.scroller&&(d.scroller=a.element(d.scroller)[0]);var e=new Headroom(c[0],d);e.init(),b.$on("destroy",function(){e.destroy()})}}})}(window.angular);

View file

@ -0,0 +1,348 @@
/*!
* headroom.js v0.7.0 - Give your page some headroom. Hide your header until you need it
* Copyright (c) 2014 Nick Williams - http://wicky.nillia.ms/headroom.js
* License: MIT
*/
(function (window, document) {
'use strict';
/* exported features */
var requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame;
/**
* Handles debouncing of events via requestAnimationFrame
* @see http://www.html5rocks.com/en/tutorials/speed/animations/
* @param {Function} callback The callback to handle whichever event
*/
function Debouncer(callback) {
this.callback = callback;
this.ticking = false;
}
Debouncer.prototype = {
constructor: Debouncer,
/**
* dispatches the event to the supplied callback
* @private
*/
update: function () {
this.callback && this.callback();
this.ticking = false;
},
/**
* ensures events don't get stacked
* @private
*/
requestTick: function () {
if (!this.ticking) {
requestAnimationFrame(this.rafCallback || (this.rafCallback = this.update.bind(this)));
this.ticking = true;
}
},
/**
* Attach this as the event listeners
*/
handleEvent: function () {
this.requestTick();
}
};
/**
* Check if object is part of the DOM
* @constructor
* @param {Object} obj element to check
*/
function isDOMElement(obj) {
return obj && typeof window !== 'undefined' && (obj === window || obj.nodeType);
}
/**
* Helper function for extending objects
*/
function extend(object /*, objectN ... */) {
if (arguments.length <= 0) {
throw new Error('Missing arguments in extend function');
}
var result = object || {},
key,
i;
for (i = 1; i < arguments.length; i++) {
var replacement = arguments[i] || {};
for (key in replacement) {
// Recurse into object except if the object is a DOM element
if (typeof result[key] === 'object' && !isDOMElement(result[key])) {
result[key] = extend(result[key], replacement[key]);
}
else {
result[key] = result[key] || replacement[key];
}
}
}
return result;
}
/**
* Helper function for normalizing tolerance option to object format
*/
function normalizeTolerance(t) {
return t === Object(t) ? t : { down: t, up: t };
}
var supportsCaptureOption = false;
try {
var opts = Object.defineProperty({}, 'capture', {
get: function () {
supportsCaptureOption = true;
}
});
window.addEventListener("test", null, opts);
} catch (e) { }
function addEventListenerWithOptions(target, type, handler, options) {
var optionsOrCapture = options;
if (!supportsCaptureOption) {
optionsOrCapture = options.capture;
}
target.addEventListener(type, handler, optionsOrCapture);
}
function removeEventListenerWithOptions(target, type, handler, options) {
var optionsOrCapture = options;
if (!supportsCaptureOption) {
optionsOrCapture = options.capture;
}
target.removeEventListener(type, handler, optionsOrCapture);
}
/**
* UI enhancement for fixed headers.
* Hides header when scrolling down
* Shows header when scrolling up
* @constructor
* @param {DOMElement} elem the header element
* @param {Object} options options for the widget
*/
function Headroom(elems, options) {
options = extend(options, Headroom.options);
this.lastKnownScrollY = 0;
this.elems = elems;
this.debouncer = new Debouncer(this.update.bind(this));
this.tolerance = normalizeTolerance(options.tolerance);
this.classes = options.classes;
this.offset = options.offset;
this.scroller = options.scroller;
this.initialised = false;
this.onPin = options.onPin;
this.onUnpin = options.onUnpin;
}
Headroom.prototype = {
constructor: Headroom,
/**
* Initialises the widget
*/
init: function () {
for (var i = 0, length = this.elems.length; i < length; i++) {
this.elems[i].classList.add(this.classes.initial);
}
this.attachEvent();
return this;
},
add: function (elem) {
elem.classList.add(this.classes.initial);
this.elems.push(elem);
},
remove: function (elem) {
var classes = this.classes;
elem.classList.remove(classes.unpinned, classes.pinned, classes.initial);
var i = this.elems.indexOf(elem);
if (i != -1) {
this.elems.splice(i, 1);
}
},
/**
* Unattaches events and removes any classes that were added
*/
destroy: function () {
var classes = this.classes;
this.initialised = false;
for (var i = 0, length = this.elems.length; i < length; i++) {
this.elems[i].classList.remove(classes.unpinned, classes.pinned, classes.initial);
}
removeEventListenerWithOptions(this.scroller, 'scroll', this.debouncer, {
capture: false,
passive: true
});
},
/**
* Attaches the scroll event
* @private
*/
attachEvent: function () {
if (!this.initialised) {
this.lastKnownScrollY = this.getScrollY();
this.initialised = true;
addEventListenerWithOptions(this.scroller, 'scroll', this.debouncer, {
capture: false,
passive: true
});
this.debouncer.handleEvent();
}
},
/**
* Unpins the header if it's currently pinned
*/
unpin: function () {
var classes = this.classes;
for (var i = 0, length = this.elems.length; i < length; i++) {
var classList = this.elems[i].classList;
if (classList.contains(classes.pinned) || !classList.contains(classes.unpinned)) {
classList.add(classes.unpinned);
classList.remove(classes.pinned);
this.onUnpin && this.onUnpin.call(this);
}
}
},
/**
* Pins the header if it's currently unpinned
*/
pin: function () {
var classes = this.classes;
for (var i = 0, length = this.elems.length; i < length; i++) {
var classList = this.elems[i].classList;
if (classList.contains(classes.unpinned)) {
classList.remove(classes.unpinned);
classList.add(classes.pinned);
this.onPin && this.onPin.call(this);
}
}
},
/**
* Gets the Y scroll position
* @see https://developer.mozilla.org/en-US/docs/Web/API/Window.scrollY
* @return {Number} pixels the page has scrolled along the Y-axis
*/
getScrollY: function () {
var pageYOffset = this.scroller.pageYOffset;
if (pageYOffset !== undefined) {
return pageYOffset;
}
var scrollTop = this.scroller.scrollTop;
if (scrollTop !== undefined) {
return scrollTop;
}
return (document.documentElement || document.body).scrollTop;
},
/**
* determines if the tolerance has been exceeded
* @param {int} currentScrollY the current scroll y position
* @return {bool} true if tolerance exceeded, false otherwise
*/
toleranceExceeded: function (currentScrollY, direction) {
return Math.abs(currentScrollY - this.lastKnownScrollY) >= this.tolerance[direction];
},
/**
* determine if it is appropriate to unpin
* @param {int} currentScrollY the current y scroll position
* @param {bool} toleranceExceeded has the tolerance been exceeded?
* @return {bool} true if should unpin, false otherwise
*/
shouldUnpin: function (currentScrollY, toleranceExceeded) {
var scrollingDown = currentScrollY > this.lastKnownScrollY,
pastOffset = currentScrollY >= this.offset;
return scrollingDown && pastOffset && toleranceExceeded;
},
/**
* determine if it is appropriate to pin
* @param {int} currentScrollY the current y scroll position
* @param {bool} toleranceExceeded has the tolerance been exceeded?
* @return {bool} true if should pin, false otherwise
*/
shouldPin: function (currentScrollY, toleranceExceeded) {
var scrollingUp = currentScrollY < this.lastKnownScrollY,
pastOffset = currentScrollY <= this.offset;
return (scrollingUp && toleranceExceeded) || pastOffset;
},
/**
* Handles updating the state of the widget
*/
update: function () {
var currentScrollY = this.getScrollY(),
scrollDirection = currentScrollY > this.lastKnownScrollY ? 'down' : 'up',
toleranceExceeded = this.toleranceExceeded(currentScrollY, scrollDirection);
if (currentScrollY < 0) { // Ignore bouncy scrolling in OSX
return;
}
if (this.shouldUnpin(currentScrollY, toleranceExceeded)) {
this.unpin();
}
else if (this.shouldPin(currentScrollY, toleranceExceeded)) {
this.pin();
}
this.lastKnownScrollY = currentScrollY;
}
};
/**
* Default options
* @type {Object}
*/
Headroom.options = {
tolerance: {
up: 0,
down: 0
},
offset: 0,
scroller: window,
classes: {
pinned: 'headroom--pinned',
unpinned: 'headroom--unpinned',
initial: 'headroom'
}
};
window.Headroom = Headroom;
}(window, document));

View file

@ -0,0 +1,7 @@
/*!
* headroom.js v0.7.0 - Give your page some headroom. Hide your header until you need it
* Copyright (c) 2014 Nick Williams - http://wicky.nillia.ms/headroom.js
* License: MIT
*/
!function(a,b){"use strict";function c(a){this.callback=a,this.ticking=!1}function d(b){return b&&"undefined"!=typeof a&&(b===a||b.nodeType)}function e(a){if(arguments.length<=0)throw new Error("Missing arguments in extend function");var b,c,f=a||{};for(c=1;c<arguments.length;c++){var g=arguments[c]||{};for(b in g)f[b]="object"!=typeof f[b]||d(f[b])?f[b]||g[b]:e(f[b],g[b])}return f}function f(a){return a===Object(a)?a:{down:a,up:a}}function g(a,b){b=e(b,g.options),this.lastKnownScrollY=0,this.elem=a,this.debouncer=new c(this.update.bind(this)),this.tolerance=f(b.tolerance),this.classes=b.classes,this.offset=b.offset,this.scroller=b.scroller,this.initialised=!1,this.onPin=b.onPin,this.onUnpin=b.onUnpin,this.onTop=b.onTop,this.onNotTop=b.onNotTop}var h={bind:!!function(){}.bind,classList:"classList"in b.documentElement,rAF:!!(a.requestAnimationFrame||a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame)};a.requestAnimationFrame=a.requestAnimationFrame||a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame,c.prototype={constructor:c,update:function(){this.callback&&this.callback(),this.ticking=!1},requestTick:function(){this.ticking||(requestAnimationFrame(this.rafCallback||(this.rafCallback=this.update.bind(this))),this.ticking=!0)},handleEvent:function(){this.requestTick()}},g.prototype={constructor:g,init:function(){return g.cutsTheMustard?(this.elem.classList.add(this.classes.initial),setTimeout(this.attachEvent.bind(this),100),this):void 0},destroy:function(){var a=this.classes;this.initialised=!1,this.elem.classList.remove(a.unpinned,a.pinned,a.top,a.initial),this.scroller.removeEventListener("scroll",this.debouncer,!1)},attachEvent:function(){this.initialised||(this.lastKnownScrollY=this.getScrollY(),this.initialised=!0,this.scroller.addEventListener("scroll",this.debouncer,!1),this.debouncer.handleEvent())},unpin:function(){var a=this.elem.classList,b=this.classes;(a.contains(b.pinned)||!a.contains(b.unpinned))&&(a.add(b.unpinned),a.remove(b.pinned),this.onUnpin&&this.onUnpin.call(this))},pin:function(){var a=this.elem.classList,b=this.classes;a.contains(b.unpinned)&&(a.remove(b.unpinned),a.add(b.pinned),this.onPin&&this.onPin.call(this))},top:function(){var a=this.elem.classList,b=this.classes;a.contains(b.top)||(a.add(b.top),a.remove(b.notTop),this.onTop&&this.onTop.call(this))},notTop:function(){var a=this.elem.classList,b=this.classes;a.contains(b.notTop)||(a.add(b.notTop),a.remove(b.top),this.onNotTop&&this.onNotTop.call(this))},getScrollY:function(){return void 0!==this.scroller.pageYOffset?this.scroller.pageYOffset:void 0!==this.scroller.scrollTop?this.scroller.scrollTop:(b.documentElement||b.body.parentNode||b.body).scrollTop},getViewportHeight:function(){return a.innerHeight||b.documentElement.clientHeight||b.body.clientHeight},getDocumentHeight:function(){var a=b.body,c=b.documentElement;return Math.max(a.scrollHeight,c.scrollHeight,a.offsetHeight,c.offsetHeight,a.clientHeight,c.clientHeight)},getElementHeight:function(a){return Math.max(a.scrollHeight,a.offsetHeight,a.clientHeight)},getScrollerHeight:function(){return this.scroller===a||this.scroller===b.body?this.getDocumentHeight():this.getElementHeight(this.scroller)},isOutOfBounds:function(a){var b=0>a,c=a+this.getViewportHeight()>this.getScrollerHeight();return b||c},toleranceExceeded:function(a,b){return Math.abs(a-this.lastKnownScrollY)>=this.tolerance[b]},shouldUnpin:function(a,b){var c=a>this.lastKnownScrollY,d=a>=this.offset;return c&&d&&b},shouldPin:function(a,b){var c=a<this.lastKnownScrollY,d=a<=this.offset;return c&&b||d},update:function(){var a=this.getScrollY(),b=a>this.lastKnownScrollY?"down":"up",c=this.toleranceExceeded(a,b);this.isOutOfBounds(a)||(a<=this.offset?this.top():this.notTop(),this.shouldUnpin(a,c)?this.unpin():this.shouldPin(a,c)&&this.pin(),this.lastKnownScrollY=a)}},g.options={tolerance:{up:0,down:0},offset:0,scroller:a,classes:{pinned:"headroom--pinned",unpinned:"headroom--unpinned",top:"headroom--top",notTop:"headroom--not-top",initial:"headroom"}},g.cutsTheMustard="undefined"!=typeof h&&h.rAF&&h.bind&&h.classList,a.Headroom=g}(window,document);

View file

@ -0,0 +1,45 @@
/*!
* headroom.js v0.7.0 - Give your page some headroom. Hide your header until you need it
* Copyright (c) 2014 Nick Williams - http://wicky.nillia.ms/headroom.js
* License: MIT
*/
(function($) {
if(!$) {
return;
}
////////////
// Plugin //
////////////
$.fn.headroom = function(option) {
return this.each(function() {
var $this = $(this),
data = $this.data('headroom'),
options = typeof option === 'object' && option;
options = $.extend(true, {}, Headroom.options, options);
if (!data) {
data = new Headroom(this, options);
data.init();
$this.data('headroom', data);
}
if (typeof option === 'string') {
data[option]();
}
});
};
//////////////
// Data API //
//////////////
$('[data-headroom]').each(function() {
var $this = $(this);
$this.headroom($this.data());
});
}(window.Zepto || window.jQuery));

View file

@ -0,0 +1,7 @@
/*!
* headroom.js v0.7.0 - Give your page some headroom. Hide your header until you need it
* Copyright (c) 2014 Nick Williams - http://wicky.nillia.ms/headroom.js
* License: MIT
*/
!function(a){a&&(a.fn.headroom=function(b){return this.each(function(){var c=a(this),d=c.data("headroom"),e="object"==typeof b&&b;e=a.extend(!0,{},Headroom.options,e),d||(d=new Headroom(this,e),d.init(),c.data("headroom",d)),"string"==typeof b&&d[b]()})},a("[data-headroom]").each(function(){var b=a(this);b.headroom(b.data())}))}(window.Zepto||window.jQuery);