;(function() { var StdLib = {}; window.StdLib = StdLib; var KEYBOARD = { ESC: 27 }; (function() { var local = {}; function cache(name, key, value) { if (value === undefined) { var c = local[name]; if (c === undefined) { return null; } value = c[key]; return value === undefined ? null : value; } if (local[name] === undefined) { local[name] = {}; } local[name][key] = value; return value; } StdLib.cache = cache; })(); var object = { merge: function(target, input) { var output = {}; var keys = Object.keys(target); for (var i = 0; i < keys.length; i++) { var key = keys[i]; if (input.hasOwnProperty(key)) { output[key] = input[key]; } else { output[key] = target[key]; } } return output; }, copy: function(obj) { if(typeof(obj) != "object") { return obj; } if(!obj) { return obj; } var res = (obj instanceof Array) ? [] : {}; for (var i in obj) { if(obj.hasOwnProperty(i)) { res[i] = object.copy(obj[i]); } } return res; } }; var store = { create: function(state) { state = state || {}; var subscribers = []; return { subscribe: function(subscriber) { subscribers.push(subscriber); }, setState: function(parts) { state = StdLib.object.copy(state); state = StdLib.object.merge(state, parts); for (var i = 0; i < subscribers.length; i++) { subscribers[i](state); } }, getState: function() { return state; }, do: function() { for (var i = 0; i < subscribers.length; i++) { subscribers[i](state); } } }; } }; function сookie(name) { var value = null; if (document.cookie && document.cookie !== '') { var cookies = document.cookie.split(';'); for (var i = 0; i < cookies.length; i++) { var cookie = cookies[i].trim(); if (cookie.substring(0, name.length + 1) === (name + '=')) { value = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return value; } function Http() {} Http.prototype.post = function(config) { return this.request({ method: 'POST', body: config.body, url: config.url, headers: config.headers, success: config.success, error: config.error, withCredentials: config.withCredentials }); }; Http.prototype.request = function(config) { var xhr = new XMLHttpRequest(); var method = config.method; var url = config.url; var body = config.body; var headers = config.headers; var success = config.success; var error = config.error; var withCredentials = config.withCredentials; if (withCredentials) { xhr.withCredentials = true; } xhr.open(method, url); if (headers) { Object.keys(headers).forEach(function(key) { xhr.setRequestHeader(key, headers[key]); }); } if (body) { xhr.send(body); } else { xhr.send(); } xhr.onreadystatechange = function() { if (xhr.readyState === 4 && xhr.status === 200) { success && success(xhr.responseText); } else { error && error(xhr); } }; }; function ModalFacade(container, settings) { settings = settings || {}; this.id = ModalFacade.id(); this.autoControl = settings.autoControl === undefined ? true : settings.autoControl; this.onClose = settings.onClose; this.container = container; this.cross = container.querySelector('.js-modal-close'); this.modal = container.querySelector('.js-modal-popup'); this.overlay = container.querySelector('.js-modal-overlay'); this.keyupHandler = this.keyupHandler.bind(this); this.closeClickHandler = this.closeClickHandler.bind(this); this.overlayClickHandler = this.overlayClickHandler.bind(this); } ModalFacade.id = function() { if (!ModalFacade.counter) { ModalFacade.counter = 0; } ModalFacade.counter++; return ModalFacade.counter; }; ModalFacade.lock = null; ModalFacade.prototype.keyupHandler = function(e) { if (e.keyCode === StdLib.KEYBOARD.ESC) { this.autoControl ? this.close() : this.onClose && this.onClose(); } }; ModalFacade.prototype.closeClickHandler = function(e) { this.autoControl ? this.close() : this.onClose && this.onClose(); }; ModalFacade.prototype.overlayClickHandler = function(e) { if (!this.modal.contains(e.target)) { this.autoControl ? this.close() : this.onClose && this.onClose(); } }; ModalFacade.prototype.darken = function() { this.modal.classList.add('modal-popup--darken'); }; ModalFacade.prototype.light = function() { this.modal.classList.remove('modal-popup--darken'); }; ModalFacade.prototype.open = function() { if (ModalFacade.lock) { return false; } ModalFacade.lock = this.id; var self = this; this.overlay.classList.add('show'); StdLib.element.animate({ duration: 300, timing: function(fraction) { return Math.pow(fraction, 2); }, draw: function(value) { self.overlay.style.opacity = value; }, done: function() { self.modal.classList.add('show'); StdLib.element.animate({ duration: 300, timing: function(fraction) { return Math.pow(fraction, 2); }, draw: function(value) { self.modal.style.opacity = value; self.modal.style.transform = 'translateY(' + -(100 * (1 - value)) + '%)'; }, done: function() { document.addEventListener('keyup', self.keyupHandler); self.cross.addEventListener('click', self.closeClickHandler); self.overlay.addEventListener('click', self.overlayClickHandler); } }); } }); return true; }; ModalFacade.prototype.close = function() { if (ModalFacade.lock !== this.id) { return false; } var self = this; StdLib.element.animate({ duration: 300, timing: function(fraction) { return Math.pow(fraction, 2); }, draw: function(value) { self.modal.style.transform = 'translateY(-' + Math.round(100 * value) + '%)'; self.modal.style.opacity = 1 - value; }, done: function() { self.modal.classList.remove('show'); StdLib.element.animate({ duration: 300, timing: function(fraction) { return Math.pow(fraction, 2); }, draw: function(value) { self.overlay.style.opacity = 1 - value; }, done: function() { self.overlay.classList.remove('show'); ModalFacade.lock = null; } }); } }); document.removeEventListener('keyup', this.keyupHandler); this.cross.removeEventListener('click', this.closeClickHandler); this.overlay.removeEventListener('click', this.overlayClickHandler); return true; }; function demensions(element) { var prev = {}; var props = Object.keys(demensions.styles); for (var i = 0; i < props.length; i++) { var prop = props[i]; var value = demensions.styles[prop]; prev[prop] = element.style[prop]; element.style[prop] = value; } var result = { width: element.offsetWidth, height: element.offsetHeight }; for (var i = 0; i < props.length; i++) { var prop = props[i]; element.style[prop] = prev[prop]; } return result; } demensions.styles = { display: 'block', position: 'absolute', visibility: 'hidden', height: 'auto', width: '100%' }; var element = { demensions: demensions, animate: function(options) { var requestAnimationFrame = ( window.requestAnimationFrame || window.msRequestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame ); var start = performance.now(); requestAnimationFrame(function animate(time) { var timeFraction = (time - start) / options.duration; if (timeFraction > 1) { timeFraction = 1; } var progress = options.timing(timeFraction); options.draw(progress); if (timeFraction < 1) { requestAnimationFrame(animate); } else { requestAnimationFrame(function() { options.done && options.done(); }); } }); }, delayer: { delay: function(element, value) { element.style.transitionDelay = value + 'ms'; }, free: function(element) { setTimeout(function() { element.style.transitionDelay = '0ms'; }, 300); } } }; function isTouchDevice() { return 'ontouchstart' in document.documentElement; }; StdLib.isTouchDevice = isTouchDevice; StdLib.element = element; StdLib.store = store; StdLib.object = object; StdLib.сookie = сookie; StdLib.Http = Http; StdLib.ModalFacade = ModalFacade; StdLib.KEYBOARD = KEYBOARD; })();