@advertol/context-media-query
Version:
Control zone visibility with CSS media query listeners.
565 lines (469 loc) • 14.1 kB
JavaScript
import { Context } from '@advertol/core';
function _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
function _inheritsLoose(subClass, superClass) {
subClass.prototype = Object.create(superClass.prototype);
subClass.prototype.constructor = subClass;
subClass.__proto__ = superClass;
}
/**
* Returns the first argument provided to it.
*/
function identity(val){
return val;
}
var identity_1 = identity;
/**
* Returns a function that gets a property of the passed object
*/
function prop(name){
return function(obj){
return obj[name];
};
}
var prop_1 = prop;
/**
* Safer Object.hasOwnProperty
*/
function hasOwn(obj, prop){
return Object.prototype.hasOwnProperty.call(obj, prop);
}
var hasOwn_1 = hasOwn;
var _hasDontEnumBug,
_dontEnums;
function checkDontEnum(){
_dontEnums = [
'toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'
];
_hasDontEnumBug = true;
for (var key in {'toString': null}) {
_hasDontEnumBug = false;
}
}
/**
* Similar to Array/forEach but works over object properties and fixes Don't
* Enum bug on IE.
* based on: http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
*/
function forIn(obj, fn, thisObj){
var key, i = 0;
// no need to check if argument is a real object that way we can use
// it for arrays, functions, date, etc.
//post-pone check till needed
if (_hasDontEnumBug == null) checkDontEnum();
for (key in obj) {
if (exec(fn, obj, key, thisObj) === false) {
break;
}
}
if (_hasDontEnumBug) {
var ctor = obj.constructor,
isProto = !!ctor && obj === ctor.prototype;
while (key = _dontEnums[i++]) {
// For constructor, if it is a prototype object the constructor
// is always non-enumerable unless defined otherwise (and
// enumerated above). For non-prototype objects, it will have
// to be defined on this object, since it cannot be defined on
// any prototype objects.
//
// For other [[DontEnum]] properties, check if the value is
// different than Object prototype value.
if (
(key !== 'constructor' ||
(!isProto && hasOwn_1(obj, key))) &&
obj[key] !== Object.prototype[key]
) {
if (exec(fn, obj, key, thisObj) === false) {
break;
}
}
}
}
}
function exec(fn, obj, key, thisObj){
return fn.call(thisObj, obj[key], key, obj);
}
var forIn_1 = forIn;
/**
* Similar to Array/forEach but works over object properties and fixes Don't
* Enum bug on IE.
* based on: http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation
*/
function forOwn(obj, fn, thisObj){
forIn_1(obj, function(val, key){
if (hasOwn_1(obj, key)) {
return fn.call(thisObj, obj[key], key, obj);
}
});
}
var forOwn_1 = forOwn;
/**
* Gets the "kind" of value. (e.g. "String", "Number", etc)
*/
function kindOf(val) {
return Object.prototype.toString.call(val).slice(8, -1);
}
var kindOf_1 = kindOf;
/**
* Check if value is from a specific "kind".
*/
function isKind(val, kind){
return kindOf_1(val) === kind;
}
var isKind_1 = isKind;
/**
*/
var isArray = Array.isArray || function (val) {
return isKind_1(val, 'Array');
};
var isArray_1 = isArray;
function containsMatch(array, pattern) {
var i = -1, length = array.length;
while (++i < length) {
if (deepMatches(array[i], pattern)) {
return true;
}
}
return false;
}
function matchArray(target, pattern) {
var i = -1, patternLength = pattern.length;
while (++i < patternLength) {
if (!containsMatch(target, pattern[i])) {
return false;
}
}
return true;
}
function matchObject(target, pattern) {
var result = true;
forOwn_1(pattern, function(val, key) {
if (!deepMatches(target[key], val)) {
// Return false to break out of forOwn early
return (result = false);
}
});
return result;
}
/**
* Recursively check if the objects match.
*/
function deepMatches(target, pattern){
if (target && typeof target === 'object' &&
pattern && typeof pattern === 'object') {
if (isArray_1(target) && isArray_1(pattern)) {
return matchArray(target, pattern);
} else {
return matchObject(target, pattern);
}
} else {
return target === pattern;
}
}
var deepMatches_1 = deepMatches;
/**
* Converts argument into a valid iterator.
* Used internally on most array/object/collection methods that receives a
* callback/iterator providing a shortcut syntax.
*/
function makeIterator(src, thisObj){
if (src == null) {
return identity_1;
}
switch(typeof src) {
case 'function':
// function is the first to improve perf (most common case)
// also avoid using `Function#call` if not needed, which boosts
// perf a lot in some cases
return (typeof thisObj !== 'undefined')? function(val, i, arr){
return src.call(thisObj, val, i, arr);
} : src;
case 'object':
return function(val){
return deepMatches_1(val, src);
};
case 'string':
case 'number':
return prop_1(src);
}
}
var makeIterator_ = makeIterator;
/**
* Array filter
*/
function filter(arr, callback, thisObj) {
callback = makeIterator_(callback, thisObj);
var results = [];
if (arr == null) {
return results;
}
var i = -1, len = arr.length, value;
while (++i < len) {
value = arr[i];
if (callback(value, i, arr)) {
results.push(value);
}
}
return results;
}
var filter_1 = filter;
/**
* @return {array} Array of unique items
*/
function unique(arr, compare){
compare = compare || isEqual;
return filter_1(arr, function(item, i, arr){
var n = arr.length;
while (++i < n) {
if ( compare(item, arr[i]) ) {
return false;
}
}
return true;
});
}
function isEqual(a, b){
return a === b;
}
var unique_1 = unique;
/**
* Array every
*/
function every(arr, callback, thisObj) {
callback = makeIterator_(callback, thisObj);
var result = true;
if (arr == null) {
return result;
}
var i = -1, len = arr.length;
while (++i < len) {
// we iterate over sparse items since there is no way to make it
// work properly on IE 7-8. see #64
if (!callback(arr[i], i, arr) ) {
result = false;
break;
}
}
return result;
}
var every_1 = every;
/**
* Array.indexOf
*/
function indexOf(arr, item, fromIndex) {
fromIndex = fromIndex || 0;
if (arr == null) {
return -1;
}
var len = arr.length,
i = fromIndex < 0 ? len + fromIndex : fromIndex;
while (i < len) {
// we iterate over sparse items since there is no way to make it
// work properly on IE 7-8. see #64
if (arr[i] === item) {
return i;
}
i++;
}
return -1;
}
var indexOf_1 = indexOf;
/**
* If array contains values.
*/
function contains(arr, val) {
return indexOf_1(arr, val) !== -1;
}
var contains_1 = contains;
/**
* Create slice of source array or array-like object
*/
function slice(arr, start, end){
var len = arr.length;
if (start == null) {
start = 0;
} else if (start < 0) {
start = Math.max(len + start, 0);
} else {
start = Math.min(start, len);
}
if (end == null) {
end = len;
} else if (end < 0) {
end = Math.max(len + end, 0);
} else {
end = Math.min(end, len);
}
var result = [];
while (start < end) {
result.push(arr[start++]);
}
return result;
}
var slice_1 = slice;
/**
* Return a new Array with elements common to all Arrays.
* - based on underscore.js implementation
*/
function intersection(arr) {
var arrs = slice_1(arguments, 1),
result = filter_1(unique_1(arr), function(needle){
return every_1(arrs, function(haystack){
return contains_1(haystack, needle);
});
});
return result;
}
var intersection_1 = intersection;
/**
* Array some
*/
function some(arr, callback, thisObj) {
callback = makeIterator_(callback, thisObj);
var result = false;
if (arr == null) {
return result;
}
var i = -1, len = arr.length;
while (++i < len) {
// we iterate over sparse items since there is no way to make it
// work properly on IE 7-8. see #64
if ( callback(arr[i], i, arr) ) {
result = true;
break;
}
}
return result;
}
var some_1 = some;
/**
* Return a new Array with elements that aren't present in the other Arrays.
*/
function difference(arr) {
var arrs = slice_1(arguments, 1),
result = filter_1(unique_1(arr), function(needle){
return !some_1(arrs, function(haystack){
return contains_1(haystack, needle);
});
});
return result;
}
var difference_1 = difference;
function _objectValues(obj) {
var values = [];
var keys = Object.keys(obj);
for (var k = 0; k < keys.length; k++) values.push(obj[keys[k]]);
return values;
}
function _objectEntries(obj) {
var entries = [];
var keys = Object.keys(obj);
for (var k = 0; k < keys.length; k++) entries.push([keys[k], obj[keys[k]]]);
return entries;
}
var MediaQueryContext =
/*#__PURE__*/
function (_Context) {
_inheritsLoose(MediaQueryContext, _Context);
/**
* @param {Object} contexts
*/
function MediaQueryContext(contexts) {
var _this;
_this = _Context.call(this) || this;
_this.contexts = _this.setupContexts(contexts);
_this.listen();
return _this;
}
/**
* @param {Object} contexts
*
* @return {Object}
*/
var _proto = MediaQueryContext.prototype;
_proto.setupContexts = function setupContexts(contexts) {
return _objectEntries(contexts).reduce(function (contexts, _ref) {
var _extends2;
var mediaQuery = _ref[0],
zones = _ref[1];
return _extends({}, contexts, (_extends2 = {}, _extends2[mediaQuery] = {
mediaQuery: window.matchMedia(mediaQuery),
zones: zones,
listener: null
}, _extends2));
}, {});
};
_proto.listen = function listen() {
var _this2 = this;
_objectValues(this.contexts).forEach(function (context) {
context.listener = function (mediaQuery) {
if (mediaQuery.matches || _this2.isAnyContextActive() === false) {
_this2.resolve();
}
};
context.mediaQuery.addListener(context.listener);
});
};
_proto.unlisten = function unlisten() {
_objectValues(this.contexts).forEach(function (context) {
context.mediaQuery.removeListener(context.listener);
});
};
/**
* @return {boolean}
*/
_proto.isAnyContextActive = function isAnyContextActive() {
return _objectValues(this.contexts).some(function (context) {
return context.mediaQuery.matches;
});
}
/**
* @param {string[]} zonesList
*/
;
_proto.calculate = function calculate(zonesList) {
var visibleZones = intersection_1(this.getVisibleZones(), zonesList);
var hiddenZones = difference_1(zonesList, visibleZones);
return {
hidden: hiddenZones,
visible: visibleZones
};
}
/**
* @return {string[]}
*/
;
_proto.getVisibleZones = function getVisibleZones() {
return _objectValues(this.contexts).reduce(function (zones, context) {
if (context.mediaQuery.matches) {
return [].concat(zones, context.zones);
}
return zones;
}, []);
};
_proto.destroy = function destroy() {
this.unlisten();
this.contexts = {};
};
return MediaQueryContext;
}(Context);
export default MediaQueryContext;
//# sourceMappingURL=index.esm.js.map