@exadel/esl
Version:
Exadel Smart Library (ESL) is the lightweight custom elements library that provide a set of super-flexible components
61 lines (60 loc) • 2.16 kB
JavaScript
import { SyntheticEventTarget } from '../../../esl-utils/dom/events';
import { ALL, NOT_ALL } from './media-query-const';
import { ESLMediaChangeEvent } from './media-query-base';
/**
* Simple media condition implementation
* @author Alexey Stsefanovich (ala'n)
*
* Wraps matchMedia instance
*/
export class MediaQueryCondition extends SyntheticEventTarget {
constructor(query, inverted = false) {
super();
this._inverted = inverted;
this._mq = matchMedia(query.trim() || 'all');
this._onChange = this._onChange.bind(this);
}
get matches() {
return this._inverted ? !this._mq.matches : this._mq.matches;
}
addEventListener(type, callback = type) {
super.addEventListener(type, callback);
if (this.getEventListeners('change').length > 1)
return;
if (typeof this._mq.addEventListener === 'function') {
this._mq.addEventListener('change', this._onChange);
}
else {
this._mq.addListener(this._onChange);
}
}
removeEventListener(type, callback = type) {
super.removeEventListener(type, callback);
if (this.hasEventListener())
return;
if (typeof this._mq.removeEventListener === 'function') {
this._mq.removeEventListener('change', this._onChange);
}
else {
this._mq.removeListener(this._onChange);
}
}
/** Optimize query. Can simplify query to {@link MediaQueryConstCondition} */
optimize() {
if (ALL.eq(this))
return this._inverted ? NOT_ALL : ALL;
if (NOT_ALL.eq(this))
return this._inverted ? ALL : NOT_ALL;
return this;
}
toString() {
const query = this._mq.media;
const inverted = this._inverted;
const complex = inverted && /\)[\s\w]+\(/.test(query);
return (inverted ? 'not ' : '') + (complex ? `(${query})` : query);
}
/** Handles query change and dispatches it on top level in case result value is changed */
_onChange() {
this.dispatchEvent(new ESLMediaChangeEvent(this._mq.matches));
}
}