Files
freelance_website/assets/js/breakpoints.min.js
T
2018-06-29 00:00:48 -07:00

351 lines
6.7 KiB
JavaScript

/* breakpoints.js v0.1-dev | @ajlkn | MIT licensed */
var breakpoints = (function() { "use strict"; var _ = {
/**
* List.
* @var {array}
*/
list: null,
/**
* Media cache.
* @var {object}
*/
media: {},
/**
* Events.
* @var {array}
*/
events: [],
/**
* Initialize.
* @param {array} list List.
*/
init: function(list) {
// Set list.
_.list = list;
// Add event listeners.
window.addEventListener('resize', _.poll);
window.addEventListener('orientationchange', _.poll);
window.addEventListener('load', _.poll);
window.addEventListener('fullscreenchange', _.poll);
},
/**
* Determines if a given query is active.
* @param {string} query Query.
* @return {bool} True if yes, false if no.
*/
active: function(query) {
var breakpoint, op, media,
a, x, y, units;
// Media for this query doesn't exist? Generate it.
if (!(query in _.media)) {
// Determine operator, breakpoint.
// Greater than or equal.
if (query.substr(0, 2) == '>=') {
op = 'gte';
breakpoint = query.substr(2);
}
// Less than or equal.
else if (query.substr(0, 2) == '<=') {
op = 'lte';
breakpoint = query.substr(2);
}
// Greater than.
else if (query.substr(0, 1) == '>') {
op = 'gt';
breakpoint = query.substr(1);
}
// Less than.
else if (query.substr(0, 1) == '<') {
op = 'lt';
breakpoint = query.substr(1);
}
// Not.
else if (query.substr(0, 1) == '!') {
op = 'not';
breakpoint = query.substr(1);
}
// Equal.
else {
op = 'eq';
breakpoint = query;
}
// Build media.
if (breakpoint && breakpoint in _.list) {
a = _.list[breakpoint];
// Range.
if (Array.isArray(a)) {
x = parseInt(a[0]);
y = parseInt(a[1]);
if (!isNaN(x))
units = a[0].substr(String(x).length);
else if (!isNaN(y))
units = a[1].substr(String(y).length);
else
return;
// Max only.
if (isNaN(x)) {
switch (op) {
// Greater than or equal (>= 0 / anything)
case 'gte':
media = 'screen';
break;
// Less than or equal (<= y)
case 'lte':
media = 'screen and (max-width: ' + y + units + ')';
break;
// Greater than (> y)
case 'gt':
media = 'screen and (min-width: ' + (y + 1) + units + ')';
break;
// Less than (< 0 / invalid)
case 'lt':
media = 'screen and (max-width: -1px)';
break;
// Not (> y)
case 'not':
media = 'screen and (min-width: ' + (y + 1) + units + ')';
break;
// Equal (<= y)
default:
media = 'screen and (max-width: ' + y + units + ')';
break;
}
}
// Min only.
else if (isNaN(y)) {
switch (op) {
// Greater than or equal (>= x)
case 'gte':
media = 'screen and (min-width: ' + x + units + ')';
break;
// Less than or equal (<= inf / anything)
case 'lte':
media = 'screen';
break;
// Greater than (> inf / invalid)
case 'gt':
media = 'screen and (max-width: -1px)';
break;
// Less than (< x)
case 'lt':
media = 'screen and (max-width: ' + (x - 1) + units + ')';
break;
// Not (< x)
case 'not':
media = 'screen and (max-width: ' + (x - 1) + units + ')';
break;
// Equal (>= x)
default:
media = 'screen and (min-width: ' + x + units + ')';
break;
}
}
// Min and max.
else {
switch (op) {
// Greater than or equal.
case 'gte':
media = 'screen and (min-width: ' + x + units + ')';
break;
// Less than or equal.
case 'lte':
media = 'screen and (max-width: ' + y + units + ')';
break;
// Greater than.
case 'gt':
media = 'screen and (min-width: ' + (y + 1) + units + ')';
break;
// Less than.
case 'lt':
media = 'screen and (max-width: ' + (x - 1) + units + ')';
break;
// Not.
case 'not':
media = 'screen and (max-width: ' + (x - 1) + units + '), screen and (min-width: ' + (y + 1) + units + ')';
break;
// Equal.
default:
media = 'screen and (min-width: ' + x + units + ') and (max-width: ' + y + units + ')';
break;
}
}
}
// String.
else {
// Missing a media type? Prefix with "screen".
if (a.charAt(0) == '(')
media = 'screen and ' + a;
// Otherwise, use as-is.
else
media = a;
}
}
// Cache.
_.media[query] = (media ? media : false);
}
return (
_.media[query] === false
? false
: window.matchMedia(_.media[query]).matches
);
},
/**
* Registers an event.
* @param {string} query Query.
* @param {function} handler Handler.
*/
on: function(query, handler) {
// Register event.
_.events.push({
query: query,
handler: handler,
state: false
});
// Query active *right now*? Call handler.
if (_.active(query))
(handler)();
},
/**
* Polls for events.
*/
poll: function() {
var i, e;
// Step through events.
for (i=0; i < _.events.length; i++) {
// Get event.
e = _.events[i];
// Active?
if (_.active(e.query)) {
// Hasn't been called yet?
if (!e.state) {
// Mark as called.
e.state = true;
// Call handler.
(e.handler)();
}
}
// Otherwise ...
else {
// Previously called?
if (e.state) {
// Unmark as called.
e.state = false;
}
}
}
},
}; function __(list) { _.init(list); }; __._ = _; __.on = function(query, handler) { _.on(query, handler); }; __.active = function(query) { return _.active(query); }; return __; })();
// UMD Wrapper (github.com/umdjs/umd/blob/master/returnExports.js | @umdjs + @nason)
(function(root, factory) {
// AMD.
if (typeof define === 'function' && define.amd)
define([], factory);
// Node.
else if (typeof exports === 'object')
module.exports = factory();
// Breakpoints global.
else
root.breakpoints = factory();
}(this, function() { return breakpoints; }));