123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- var QueryHandler = require('./QueryHandler');
- var each = require('./Util').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;
|