Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix matchMedia not present, legacy browsers require a polyfill on Mocha unittest #166

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
12 changes: 9 additions & 3 deletions dist/enquire.js
@@ -1,6 +1,6 @@
/*!
* enquire.js v2.1.6 - Awesome Media Queries in JavaScript
* Copyright (c) 2017 Nick Williams - http://wicky.nillia.ms/enquire.js
* enquire.js v2.1.8 - Awesome Media Queries in JavaScript
* Copyright (c) 2017 Nick Williams - github.com/jojo5716/enquire.js
* License: MIT */


Expand Down Expand Up @@ -114,7 +114,13 @@ var isArray = Util.isArray;
*/
function MediaQueryDispatch () {
if(!window.matchMedia) {
throw new Error('matchMedia not present, legacy browsers require a polyfill');
window.matchMedia = function() {
return {
matches: false,
addListener: function() {},
removeListener: function() {}
};
};
}

this.queries = {};
Expand Down
322 changes: 322 additions & 0 deletions dist/enquire.js-unittest-fix
@@ -0,0 +1,322 @@
/*!
* enquire.js-unittest-fix v2.1.7 - Awesome Media Queries in JavaScript
* Copyright (c) 2017 Nick Williams - github.com/jojo5716/enquire.js
* License: MIT */


(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.enquire = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
var QueryHandler = require(3);
var each = require(4).each;

/**
* Represents a single media query, manages it's state and registered handlers for this query
*
* @constructor
* @param {string} query the media query string
* @param {boolean} [isUnconditional=false] whether the media query should run regardless of whether the conditions are met. Primarily for helping older browsers deal with mobile-first design
*/
function MediaQuery(query, isUnconditional) {
this.query = query;
this.isUnconditional = isUnconditional;
this.handlers = [];
this.mql = window.matchMedia(query);

var self = this;
this.listener = function(mql) {
// Chrome passes an MediaQueryListEvent object, while other browsers pass MediaQueryList directly
self.mql = mql.currentTarget || mql;
self.assess();
};
this.mql.addListener(this.listener);
}

MediaQuery.prototype = {

constuctor : MediaQuery,

/**
* add a handler for this query, triggering if already active
*
* @param {object} handler
* @param {function} handler.match callback for when query is activated
* @param {function} [handler.unmatch] callback for when query is deactivated
* @param {function} [handler.setup] callback for immediate execution when a query handler is registered
* @param {boolean} [handler.deferSetup=false] should the setup callback be deferred until the first time the handler is matched?
*/
addHandler : function(handler) {
var qh = new QueryHandler(handler);
this.handlers.push(qh);

this.matches() && qh.on();
},

/**
* removes the given handler from the collection, and calls it's destroy methods
*
* @param {object || function} handler the handler to remove
*/
removeHandler : function(handler) {
var handlers = this.handlers;
each(handlers, function(h, i) {
if(h.equals(handler)) {
h.destroy();
return !handlers.splice(i,1); //remove from array and exit each early
}
});
},

/**
* Determine whether the media query should be considered a match
*
* @return {Boolean} true if media query can be considered a match, false otherwise
*/
matches : function() {
return this.mql.matches || this.isUnconditional;
},

/**
* Clears all handlers and unbinds events
*/
clear : function() {
each(this.handlers, function(handler) {
handler.destroy();
});
this.mql.removeListener(this.listener);
this.handlers.length = 0; //clear array
},

/*
* Assesses the query, turning on all handlers if it matches, turning them off if it doesn't match
*/
assess : function() {
var action = this.matches() ? 'on' : 'off';

each(this.handlers, function(handler) {
handler[action]();
});
}
};

module.exports = MediaQuery;

},{"3":3,"4":4}],2:[function(require,module,exports){
var MediaQuery = require(1);
var Util = require(4);
var each = Util.each;
var isFunction = Util.isFunction;
var isArray = Util.isArray;

/**
* Allows for registration of query handlers.
* Manages the query handler's state and is responsible for wiring up browser events
*
* @constructor
*/
function MediaQueryDispatch () {
if(!window.matchMedia) {
window.matchMedia = function() {
return {
matches: false,
addListener: function() {},
removeListener: function() {}
};
};
}

this.queries = {};
this.browserIsIncapable = !window.matchMedia('only all').matches;
}

MediaQueryDispatch.prototype = {

constructor : MediaQueryDispatch,

/**
* Registers a handler for the given media query
*
* @param {string} q the media query
* @param {object || Array || Function} options either a single query handler object, a function, or an array of query handlers
* @param {function} options.match fired when query matched
* @param {function} [options.unmatch] fired when a query is no longer matched
* @param {function} [options.setup] fired when handler first triggered
* @param {boolean} [options.deferSetup=false] whether setup should be run immediately or deferred until query is first matched
* @param {boolean} [shouldDegrade=false] whether this particular media query should always run on incapable browsers
*/
register : function(q, options, shouldDegrade) {
var queries = this.queries,
isUnconditional = shouldDegrade && this.browserIsIncapable;

if(!queries[q]) {
queries[q] = new MediaQuery(q, isUnconditional);
}

//normalise to object in an array
if(isFunction(options)) {
options = { match : options };
}
if(!isArray(options)) {
options = [options];
}
each(options, function(handler) {
if (isFunction(handler)) {
handler = { match : handler };
}
queries[q].addHandler(handler);
});

return this;
},

/**
* unregisters a query and all it's handlers, or a specific handler for a query
*
* @param {string} q the media query to target
* @param {object || function} [handler] specific handler to unregister
*/
unregister : function(q, handler) {
var query = this.queries[q];

if(query) {
if(handler) {
query.removeHandler(handler);
}
else {
query.clear();
delete this.queries[q];
}
}

return this;
}
};

module.exports = MediaQueryDispatch;

},{"1":1,"4":4}],3:[function(require,module,exports){
/**
* Delegate to handle a media query being matched and unmatched.
*
* @param {object} options
* @param {function} options.match callback for when the media query is matched
* @param {function} [options.unmatch] callback for when the media query is unmatched
* @param {function} [options.setup] one-time callback triggered the first time a query is matched
* @param {boolean} [options.deferSetup=false] should the setup callback be run immediately, rather than first time query is matched?
* @constructor
*/
function QueryHandler(options) {
this.options = options;
!options.deferSetup && this.setup();
}

QueryHandler.prototype = {

constructor : QueryHandler,

/**
* coordinates setup of the handler
*
* @function
*/
setup : function() {
if(this.options.setup) {
this.options.setup();
}
this.initialised = true;
},

/**
* coordinates setup and triggering of the handler
*
* @function
*/
on : function() {
!this.initialised && this.setup();
this.options.match && this.options.match();
},

/**
* coordinates the unmatch event for the handler
*
* @function
*/
off : function() {
this.options.unmatch && this.options.unmatch();
},

/**
* called when a handler is to be destroyed.
* delegates to the destroy or unmatch callbacks, depending on availability.
*
* @function
*/
destroy : function() {
this.options.destroy ? this.options.destroy() : this.off();
},

/**
* determines equality by reference.
* if object is supplied compare options, if function, compare match callback
*
* @function
* @param {object || function} [target] the target for comparison
*/
equals : function(target) {
return this.options === target || this.options.match === target;
}

};

module.exports = QueryHandler;

},{}],4:[function(require,module,exports){
/**
* Helper function for iterating over a collection
*
* @param collection
* @param fn
*/
function each(collection, fn) {
var i = 0,
length = collection.length,
cont;

for(i; i < length; i++) {
cont = fn(collection[i], i);
if(cont === false) {
break; //allow early exit
}
}
}

/**
* Helper function for determining whether target object is an array
*
* @param target the object under test
* @return {Boolean} true if array, false otherwise
*/
function isArray(target) {
return Object.prototype.toString.apply(target) === '[object Array]';
}

/**
* Helper function for determining whether target object is a function
*
* @param target the object under test
* @return {Boolean} true if function, false otherwise
*/
function isFunction(target) {
return typeof target === 'function';
}

module.exports = {
isFunction : isFunction,
isArray : isArray,
each : each
};

},{}],5:[function(require,module,exports){
var MediaQueryDispatch = require(2);
module.exports = new MediaQueryDispatch();

},{"2":2}]},{},[5])(5)
});
6 changes: 3 additions & 3 deletions dist/enquire.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.