UNPKG

@bigfishtv/cockpit

Version:

189 lines (142 loc) 5.15 kB
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** * BreadcrumbHandler * @module Components/BreadCrumbHandler */ import $ from 'jquery'; import throttle from 'lodash/throttle'; var headerBuffer = -5; // px, appromixate size before title is shown var scrollThrottle = 150; var $window = $(window); function animateScroll(position) { var time = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 500; var ease = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'linear'; var callback = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : function () {}; $('html, body').animate({ scrollTop: position }, time, ease, callback); } /** * Breadcrumb handler class, uses jquery to look at nested breadcrumb data tags and dispatches updates all subscribed callbacks. * Typically, one instance of this class is created in the global scope so it can be referenced easily */ var BreadcrumbHandler = function () { function BreadcrumbHandler() { var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; _classCallCheck(this, BreadcrumbHandler); window.breadcrumbs = { addCallback: this.addCallback.bind(this), removeCallback: this.removeCallback.bind(this), scrollTo: this.scrollTo.bind(this), update: this.update.bind(this) }; this.breadcrumbs = []; this.callbacks = []; this.currentElement = null; this.headerHeight = config.headerHeight || 90; $window.scroll(throttle(this.handleScroll.bind(this), scrollThrottle)); } /** * Called by something that wants to subscribe to updates * @param {Function} callback */ BreadcrumbHandler.prototype.addCallback = function addCallback(callback) { this.callbacks.push(callback); }; /** * Called by something that wants to unsubscribe from updates * @param {Function} callback */ BreadcrumbHandler.prototype.removeCallback = function removeCallback(callback) { this.callbacks = this.callbacks.filter(function (cb) { return cb !== callback; }); }; /** * Called when a new breadcrumb wrapper comes into view, dispatches updates to all subscribed callbacks * @param {jQueryDOM} elem The element currently in view */ BreadcrumbHandler.prototype.newFocus = function newFocus(elem) { if (elem == this.currentElement) return;else this.currentElement = elem; var trail = this.getCurrentTrail(elem); for (var _iterator = this.callbacks, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { var _ref; if (_isArray) { if (_i >= _iterator.length) break; _ref = _iterator[_i++]; } else { _i = _iterator.next(); if (_i.done) break; _ref = _i.value; } var callback = _ref; callback(trail); } }; /** * Gets * @param {jQueryDOM} elem The element to get the breadcrumb trail from * @return {Object[]} Returns a trail as an array of objects containg title url and elem */ BreadcrumbHandler.prototype.getCurrentTrail = function getCurrentTrail(elem) { if (!elem) { return []; } var $elem = $(elem); var trail = [{ title: $elem.attr('data-breadcrumb') || 'Untitled', url: $elem.attr('data-breadcrumb-url'), elem: elem }]; $elem.parents('[data-breadcrumb]').each(function (i, crumb) { var $crumb = $(crumb); trail.push({ title: $crumb.attr('data-breadcrumb') || 'Untitled', url: $crumb.attr('data-breadcrumb-url'), elem: crumb }); }); trail.reverse(); return trail; }; /** * Called on breadcrumb trail segment click, smooth scrolls to relevant section * @param {jQueryDOM} breadcrumb element to scroll to */ BreadcrumbHandler.prototype.scrollTo = function scrollTo(breadcrumb) { var scrollTop = $window.scrollTop(); var offsetY = $(breadcrumb).offset().top - this.headerHeight - headerBuffer - 1; if (scrollTop == offsetY) return; $('[data-breadcrumb-focus]').removeAttr('data-breadcrumb-focus'); animateScroll(offsetY, 500, 'swing', function () { if (!breadcrumb.active) $(breadcrumb).attr('data-breadcrumb-focus', ''); }); }; BreadcrumbHandler.prototype.update = function update() { this.currentElement = null; this.handleScroll(); }; /** * Called on (throttled) scroll change, gets most visible breadcrumb */ BreadcrumbHandler.prototype.handleScroll = function handleScroll() { var currentElement = null; var threshold = $window.scrollTop() + this.headerHeight - headerBuffer; $($('[data-breadcrumb]').get().reverse()).each(function (i, crumb) { var $crumb = $(crumb); var top = $crumb.offset().top; var bottom = top + $crumb.height(); if (threshold >= top && threshold < bottom) { currentElement = crumb; return false; } }); this.newFocus(currentElement); }; /** * Inits breadcrumb handler by calling handleScroll */ BreadcrumbHandler.prototype.init = function init() { this.handleScroll(); }; return BreadcrumbHandler; }(); export { BreadcrumbHandler as default };