diff --git a/app/scripts/maps/vk-photo-download.min.js.map b/app/scripts/maps/vk-photo-download.min.js.map index a98e51e..baeed51 100644 --- a/app/scripts/maps/vk-photo-download.min.js.map +++ b/app/scripts/maps/vk-photo-download.min.js.map @@ -1 +1 @@ -{"version":3,"sources":["node_modules/browser-pack/_prelude.js","app/scripts/modules/handlers.js","app/scripts/modules/photo-download.js","app/scripts/modules/storage.js","app/scripts/modules/template-css.js","app/scripts/modules/template-html.js","app/scripts/modules/templates.js","app/scripts/vk-photo-download.js","node_modules/downloadjs/download.js"],"names":[],"mappings":"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CAAC,YAAM;AACb,QAAA,IAAI,CAAC,SAAL,CAAe,GAAf,CAAmB,KAAI,CAAC,GAAL,CAAS,KAA5B;AACH,OAFS,EAEP,CAFO,CAAV;AAIA,MAAA,MAAM,CAAC,WAAP,CAAmB,IAAnB;AAEA,aAAO,IAAP;AACH,K,CAED;;;;gCACY;AACR,UAAI,KAAK,GAAG,QAAQ,CAAC,aAAT,CAAuB,OAAvB,CAAZ;AACA,MAAA,KAAK,CAAC,EAAN,GAAW,KAAK,GAAL,CAAS,QAApB;AACA,MAAA,KAAK,CAAC,WAAN,GAAoB,KAAK,eAAL,EAApB;AAEA,MAAA,QAAQ,CAAC,IAAT,CAAc,WAAd,CAA0B,KAA1B;AACH,K,CAED;;;;oCACgB;AACZ,aAAO,2BAAc,KAAK,GAAnB,EAAwB,KAAK,OAA7B,EAAsC,KAAK,KAA3C,CAAP;AACH,K,CAED;;;;sCACkB;AACd,aAAO,0BAAa,KAAK,GAAlB,EAAuB,KAAK,OAA5B,EAAqC,KAAK,KAA1C,CAAP;AACH;;;;;;;;;;;AC9IL;;;;AAGA,MAAM,CAAC,aAAP,GAAuB,IAAI,sBAAJ,CAAkB;AACrC,EAAA,QAAQ,EAAE;AAD2B,CAAlB,CAAvB;;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"../vk-photo-download.min.js","sourcesContent":["(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=\"function\"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error(\"Cannot find module '\"+i+\"'\");throw a.code=\"MODULE_NOT_FOUND\",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u=\"function\"==typeof require&&require,i=0;i this.PhotoDownload.state.settings = 'close',\r\n downloadModeHandler: this._downloadModeHandler.bind(this),\r\n showSizeHandler: this._showSizeHandler.bind(this),\r\n downloadEffect: this.tempClass.bind(this, this.sel.get('btn.download_effect'), this.timings.settings_open + 250, `.${this.sel.get('btn.icon')}`),\r\n loadedUrlsHandler: this._loadedUrlsHandler.bind(this),\r\n addloadedUrl: this._addloadedUrl.bind(this),\r\n }\r\n\r\n this.timers = {\r\n delay: null,\r\n open: null,\r\n };\r\n } // constructor\r\n\r\n // Устанавливает обработчики в кнопке\r\n setHandlers() {\r\n let wrap = this.PhotoDownload.wrap;\r\n if (!wrap) return false;\r\n\r\n let btn = wrap.querySelector('.' + this.sel.get('btn.btn'));\r\n\r\n this.set(btn, 'startTimer', 'mousedown');\r\n this.set(btn, 'checkTimer', 'mouseup');\r\n this.set(btn, 'checkTimer', 'mouseleave');\r\n this.set(btn, 'preventHandler', 'click');\r\n\r\n // Галочка закрытия настроек\r\n let btn_close = wrap.querySelector('.' + this.sel.get('sett.settings_close_ico'));\r\n this.set(btn_close, 'closeTimingSettings', 'click');\r\n\r\n // Обработчик изменения настройки режима скачивания (клика по кнопке)\r\n let download_mode = wrap.querySelector('.' + this.sel.get('sett.download_mode'));\r\n this.set(download_mode, 'downloadModeHandler', 'change');\r\n\r\n // Обработчик изменения настройки отображения размера картинки\r\n let size_mode = wrap.querySelector('.' + this.sel.get('sett.size_mode'));\r\n this.set(size_mode, 'showSizeHandler', 'change');\r\n\r\n // Обработчик изменения настройки запоминания URL скаченных картинок\r\n let loaded_urls_mode = wrap.querySelector('.' + this.sel.get('sett.loaded_urls_mode'));\r\n this.set(loaded_urls_mode, 'loadedUrlsHandler', 'change');\r\n }\r\n\r\n // Обновляет настройки в кнопке\r\n setSettingsState() {\r\n let wrap = this.PhotoDownload.wrap;\r\n if (!wrap) return false;\r\n\r\n // _download_mode\r\n let download_mode = this.PhotoDownload.settings.download_mode.toString();\r\n let download_mode_block = wrap.querySelector('.' + this.sel.get('sett.download_mode'));\r\n let download_mode_control = download_mode_block.querySelector(`input[value=${download_mode}]`);\r\n download_mode_control.checked = true;\r\n\r\n // _show_size\r\n let size_mode_control = wrap.querySelector('#' + this.sel.size_mode_control);\r\n size_mode_control.checked = this.PhotoDownload.settings.show_size;\r\n if (this.PhotoDownload.settings.show_size) {\r\n wrap.classList.remove(this.sel.non_size);\r\n } else {\r\n wrap.classList.add(this.sel.non_size);\r\n }\r\n\r\n // _loaded_urls\r\n let loaded_urls_mode_control = wrap.querySelector('#' + this.sel.loaded_urls_mode_control);\r\n loaded_urls_mode_control.checked = this.PhotoDownload.settings.loaded_urls;\r\n // Если разрешено \"Запоминать URL\", то разблокируем \"+ клики ПКМ\" и наоборот\r\n let loaded_urls_mode_key_control = wrap.querySelector('#' + this.sel.loaded_urls_mode_key_control);\r\n loaded_urls_mode_key_control.disabled = !this.PhotoDownload.settings.loaded_urls;\r\n // Применим состояние настройки\r\n loaded_urls_mode_key_control.checked = this.PhotoDownload.settings.loaded_urls_PKM;\r\n\r\n }\r\n\r\n // Обновляет визуальное состояние кнопки\r\n applyState() {\r\n let state = this.PhotoDownload.state;\r\n\r\n switch (state.settings) {\r\n case 'open_timing':\r\n this._openTimingSettings();\r\n break;\r\n\r\n case 'open':\r\n this._openSettings();\r\n break;\r\n\r\n case 'close':\r\n this._closeSettings();\r\n break;\r\n\r\n default:\r\n break;\r\n }\r\n }\r\n\r\n // Метод, реализующий режимы быстрого клика и удержания ЛКМ на кнопке\r\n _startTimer(e) {\r\n // Если нажата не ЛКМ - выходим\r\n if (e.which !== 1) {\r\n if (this.PhotoDownload.settings.loaded_urls_PKM &&\r\n this.PhotoDownload.settings.loaded_urls &&\r\n this.PhotoDownload.state.settings == 'close') {\r\n\r\n this._addloadedUrl(e);\r\n }\r\n\r\n return false;\r\n }\r\n\r\n // Настройки закрыты\r\n if (this.PhotoDownload.state.settings == 'close') {\r\n // Ставим таймер задержки на время, отведенное для быстрого клика\r\n this.timers.delay = setTimeout(() => {\r\n // Если таймер задержки не сброшен, запускаем состояние открытия настроек\r\n this.PhotoDownload.state.settings = 'open_timing';\r\n\r\n // И ставим таймер на время анимации открытия\r\n // Пока не выполнится этот таймер, вход в настройки можно отменить, отпустив ЛКМ\r\n this.timers.open = setTimeout(() => {\r\n // Если этот таймер не сброшен, входим в настройки\r\n this.PhotoDownload.state.settings = 'open';\r\n }, this.timings.open);\r\n\r\n }, this.timings.delay);\r\n\r\n // Настройки открыты\r\n } else if (this.PhotoDownload.state.settings == 'open') {\r\n // Убираем иконку шестеренки\r\n this.PhotoDownload.wrap.querySelector('.cog')\r\n .classList.remove(this.sel.draw, this.sel.draw_fill);\r\n\r\n setTimeout(() => {\r\n // Если за время, отведенное на быстрый клик, настройки еще открыты,\r\n // то закроем их\r\n if (this.PhotoDownload.state.settings == 'open') {\r\n this.PhotoDownload.state.settings = 'close';\r\n }\r\n }, this.timings.delay);\r\n\r\n }\r\n }\r\n\r\n _checkTimer(e) {\r\n // Если нажата не левая кнопка мыши, то выходим\r\n if (e.which !== 1) return false;\r\n\r\n // Если быстрый клин и настройки закрыты, то будет обработчик скачивания\r\n if (this.timers.delay && !this.timers.open && this.PhotoDownload.state.settings == 'close') {\r\n\r\n // Тут действие для простого клика\r\n // В зависимости от флага вешаем либо обработчик скачивания, либо открытия новой вкладки\r\n if (this.PhotoDownload.settings.download_mode) {\r\n this.set(e.currentTarget, ['downloadHandler', 'downloadEffect', 'addloadedUrl']);\r\n } else {\r\n this.set(e.currentTarget, ['newTabHandler', 'downloadEffect', 'addloadedUrl']);\r\n }\r\n }\r\n\r\n // Если быстрый клик и настройки открыты, то будет обработчик закрытия настроек\r\n if (this.timers.delay && !this.timers.open && this.PhotoDownload.state.settings == 'open') {\r\n this.PhotoDownload.state.settings = 'close';\r\n }\r\n\r\n // Долгий клик и настройки открыты\r\n if (this.timers.delay && this.timers.open && this.PhotoDownload.state.settings == 'open') {\r\n // // Здесь настройки должны быть уже открыты и для события клика, \r\n // // которое будет сразу после этого mouseup, блокируем действие\r\n this.set(e.currentTarget, 'preventHandler');\r\n }\r\n\r\n if (this.PhotoDownload.state.settings == 'open_timing') {\r\n this.set(e.currentTarget, 'preventHandler');\r\n this.PhotoDownload.state.settings = 'close';\r\n }\r\n\r\n // Обнуляем все таймеры для следующего раза\r\n clearTimeout(this.timers.delay);\r\n this.timers.delay = null;\r\n clearTimeout(this.timers.open);\r\n this.timers.open = null;\r\n }\r\n\r\n // Запуск открытия настроек\r\n _openTimingSettings() {\r\n this.PhotoDownload.wrap.classList.add(this.sel.icon_cog);\r\n this.PhotoDownload.wrap\r\n .querySelector('.cog')\r\n .classList.add(this.sel.draw);\r\n }\r\n\r\n // Настройки открыты\r\n _openSettings() {\r\n this._openTimingSettings();\r\n\r\n let open = () => {\r\n this.PhotoDownload.wrap.classList.add(this.sel.settings, this.sel.settings_open);\r\n setTimeout(() => {\r\n this.PhotoDownload.wrap\r\n .querySelector('.cog')\r\n .classList.add(this.sel.draw_fill);\r\n }, this.timings.settings_open);\r\n }\r\n\r\n if (this.PhotoDownload.settings.show_size) {\r\n open();\r\n } else {\r\n // Если сначала нужно выдвинуть кнопку\r\n this.PhotoDownload.wrap.classList.add(this.sel.slide_in);\r\n setTimeout(() => {\r\n open();\r\n }, this.timings.btn_transition_transform);\r\n }\r\n }\r\n\r\n // Запуск закрытия настроек\r\n _closeSettings() {\r\n let close = () => {\r\n this.PhotoDownload.wrap.classList.remove(this.sel.icon_cog);\r\n this.PhotoDownload.wrap.classList.remove(this.sel.settings);\r\n\r\n // if (!this.PhotoDownload.settings.show_size) {\r\n setTimeout(() => {\r\n this.PhotoDownload.wrap.classList.remove(this.sel.slide_in);\r\n }, this.timings.btn_transition_transform);\r\n // }\r\n }\r\n\r\n this.PhotoDownload.wrap\r\n .querySelector('.cog')\r\n .classList.remove(this.sel.draw, this.sel.draw_fill);\r\n this.PhotoDownload.wrap.classList.remove(this.sel.settings_open);\r\n\r\n setTimeout(() => {\r\n close();\r\n }, this.timings.settings_open);\r\n }\r\n\r\n // Установить один или несколько обработчиков на элемент\r\n // Если на элементе были другие обработчики - они удаляются\r\n // В итоге на элементе гарантировано только переданный набор обработчиков\r\n set(elem, handler_name, event_name = this.default_event_name) {\r\n if (!elem || !handler_name) return false;\r\n\r\n let result = true;\r\n\r\n // Удаляем все уже имеющиеся обработчики\r\n this.removeAll(elem, event_name);\r\n\r\n // Ставим нужные\r\n if (handler_name instanceof Array) {\r\n handler_name.forEach(name => {\r\n this.add(elem, name, event_name);\r\n });\r\n } else if (typeof handler_name === 'string') {\r\n this.add(elem, handler_name, event_name);\r\n } else {\r\n result = false;\r\n }\r\n\r\n return result;\r\n }\r\n\r\n // Добавить обработчик с переданным именем на элемент\r\n add(elem, handler_name, event_name = this.default_event_name) {\r\n if (!elem || !handler_name || !this.getHandler(handler_name)) return false;\r\n\r\n elem.addEventListener(event_name, this.getHandler(handler_name));\r\n\r\n return true;\r\n }\r\n\r\n // Удалить обработчик с переданным именем с элемента\r\n remove(elem, handler_name, event_name = this.default_event_name) {\r\n if (!elem || !handler_name || !this.getHandler(handler_name)) return false;\r\n\r\n elem.removeEventListener(event_name, this.getHandler(handler_name));\r\n\r\n return true;\r\n }\r\n\r\n // Удалить все обработчики с элемента\r\n removeAll(elem, event_name = this.default_event_name) {\r\n if (!elem) return false;\r\n\r\n for (let handler in this.handlers) {\r\n elem.removeEventListener(event_name, this.getHandler(handler));\r\n }\r\n\r\n return true;\r\n }\r\n\r\n // Получить имена всех обработчиков\r\n getHandlersNames() {\r\n return Object.keys(this.handlers);\r\n }\r\n\r\n // Получить объект всех функций-обработчиков\r\n getHandlers() {\r\n return this.handlers;\r\n }\r\n\r\n // Получить функцию-обработчик\r\n getHandler(handler_name) {\r\n return this.handlers[handler_name];\r\n }\r\n\r\n // === Служебные ===\r\n\r\n tempClass(class_name, timeout, elem) {\r\n if (elem instanceof Event) {\r\n elem = elem.currentTarget;\r\n } else if (typeof elem === 'string') {\r\n elem = document.querySelector(elem);\r\n } else if (elem === undefined) {\r\n elem = this;\r\n }\r\n\r\n elem.classList.remove(class_name);\r\n\r\n setTimeout(() => {\r\n elem.classList.add(class_name);\r\n }, 0);\r\n\r\n setTimeout(() => {\r\n elem.classList.remove(class_name);\r\n }, timeout);\r\n }\r\n\r\n // === Обработчики ===\r\n\r\n _addloadedUrl(e) {\r\n let url = e.currentTarget.href;\r\n this.PhotoDownload._addloadedUrl(url);\r\n }\r\n\r\n // Меняет настройку запоминания URL скаченных картинок\r\n _loadedUrlsHandler(e) {\r\n if (e.target.id === this.sel.loaded_urls_mode_control) {\r\n // Изменена настройка основного запоминания URL\r\n this.PhotoDownload.settings.loaded_urls = e.target.checked;\r\n } else if (e.target.id === this.sel.loaded_urls_mode_key_control) {\r\n // Изменена настройка дополнительного запоминания URL по ПКМ\r\n this.PhotoDownload.settings.loaded_urls_PKM = e.target.checked;\r\n }\r\n }\r\n\r\n // Меняет настройку показа разрешения картинки при наведении\r\n _showSizeHandler(e) {\r\n this.PhotoDownload.settings.show_size = e.target.checked;\r\n }\r\n\r\n // Меняет настройку режима скачивания\r\n _downloadModeHandler(e) {\r\n let value = e.target.value;\r\n\r\n if (value === 'true') {\r\n this.PhotoDownload.settings.download_mode = true;\r\n } else if (value === 'false') {\r\n this.PhotoDownload.settings.download_mode = false;\r\n }\r\n }\r\n\r\n // Отменяет действие браузера\r\n _preventHandler(e) {\r\n e.preventDefault();\r\n return false;\r\n }\r\n\r\n // Обработчик кнопки для режима открытия в новой вкладке\r\n _newTabHandler(e) {\r\n this.remove(e.currentTarget, 'newTabHandler');\r\n return true;\r\n }\r\n\r\n // Обработчик кнопки для режима скачивания\r\n _downloadHandler(e) {\r\n e.preventDefault();\r\n Download(e.currentTarget.href);\r\n\r\n this.remove(e.currentTarget, 'downloadHandler');\r\n return false;\r\n }\r\n}","import PhotoDownloadTemplates from './templates';\r\nimport HandlersManager from './handlers';\r\nimport SStorage from './storage';\r\n\r\nexport default class PhotoDownload {\r\n constructor(params = {}) {\r\n let that = this;\r\n\r\n // Ссылка, в которую обернута картинка, \r\n // здесь нужнв для триггера создания/обновления кнопки\r\n this.imgContainer_id = 'pv_photo';\r\n\r\n // Объект всех селекторов, использующихся в кнопке\r\n this.selectors = {\r\n _prefix: 'PhotoDownload_',\r\n // id контейнера кнопки\r\n photoDownload_id: 'PhotoDownload',\r\n // Контейнер, в котором находится картинка и элементы управления,\r\n // создавать кнопку будем в нем\r\n imgContainer_class: 'pv_image_wrap',\r\n // id, который добавится тегу style\r\n style_id: 'PhotoDownloadStyle',\r\n\r\n // Класс-флаг, вешается на #PhotoDownload когда нет данных о разрешении\r\n // или в настройках отключен показ размеров картинки\r\n non_size: 'non_size',\r\n // Класс-флаг, вешается для плавного opacity кнопки после создания\r\n ready: 'ready',\r\n\r\n slide_in: 'slide_in',\r\n\r\n settings: 'settings',\r\n settings_open: 'settings_open',\r\n\r\n draw: 'draw',\r\n draw_fill: 'draw_fill',\r\n icon_cog: 'icon_cog',\r\n\r\n download_mode_true: 'download_mode_true',\r\n download_mode_false: 'download_mode_false',\r\n\r\n size_mode_control: 'size_mode_control',\r\n\r\n loaded_urls_mode_control: 'loaded_urls_mode_control',\r\n loaded_urls_mode_key_control: 'loaded_urls_mode_key_control',\r\n loaded_urls_active: 'loaded_urls_active',\r\n\r\n sett: {\r\n settings_wrap: 'settings_wrap',\r\n settings: 'settings',\r\n settings_body: 'settings_body',\r\n download_mode: 'download_mode',\r\n size_mode: 'size_mode',\r\n loaded_urls_mode: 'loaded_urls_mode',\r\n settings_item: 'settings_item',\r\n settings_item_action: 'settings_item_action',\r\n\r\n settings_close_ico: 'settings_close_ico',\r\n settings_section: 'settings_section',\r\n settings_section_header: 'settings_section_header',\r\n },\r\n\r\n btn: {\r\n // Класс кнопки (тега a)\r\n btn: 'btn',\r\n // Класс блока иконки\r\n icon: 'icon',\r\n main_title_wrap: 'main_title_wrap',\r\n main_title_inner: 'main_title_inner',\r\n // Класс блока, в котором отображается разрешение картинки\r\n size: 'size',\r\n settings_title: 'settings_title',\r\n // Класс для эффекта скачивания на иконке стрелки\r\n download_effect: 'download_effect',\r\n },\r\n // Метод получения селектора\r\n get(sel) {\r\n sel = sel.split('.');\r\n let error = false;\r\n let res = this;\r\n\r\n // Если селектор на верхнем уровне объекта, он отдается как есть\r\n if (sel.length === 1) {\r\n res = this[sel];\r\n } else if (sel.length > 1) {\r\n // Иначе получаем селектор из вложенных уровней\r\n sel.forEach(part => {\r\n try {\r\n res = res[part];\r\n } catch (err) {\r\n error = true;\r\n }\r\n })\r\n\r\n // И если селектор существует, дописываем к нему префикс\r\n res = (error || !res) ? undefined : this._prefix + res;\r\n }\r\n\r\n return res;\r\n }\r\n };\r\n\r\n // Объект с описанием обработчиков\r\n this.triggers = {\r\n mouseover: [\r\n // Селектор ссылки, в которую обернута картинка в просмотрщике\r\n {\r\n type: 'id',\r\n selector: this.imgContainer_id,\r\n // При наведении на контейнер картинки, будем обновлять(создавать) кнопку\r\n handler: this._updateBtn,\r\n child: true,\r\n },\r\n // Селектор родительского блока кнопки\r\n {\r\n type: 'class',\r\n selector: this.selectors.get('btn.btn'),\r\n // При наведении на саму кнопку, будем обновлять в ней данные\r\n handler: this._updateBtn,\r\n child: true,\r\n },\r\n ], // Конец mouseover\r\n };\r\n\r\n // Настройки поведения кнопки\r\n this.settings = {\r\n // download_mode - флаг, задающий поведение клика по кнопке\r\n // Если true, то картинка будет скачиваться\r\n // Если false, то картинка будет открываться в новой вкладке\r\n _download_mode: params.download,\r\n get download_mode() {\r\n return this._download_mode;\r\n },\r\n set download_mode(val) {\r\n if (typeof val === 'boolean') {\r\n this._download_mode = val;\r\n that._saveSettings();\r\n\r\n let upd = that._updateBtn(document.querySelector('#' + that.imgContainer_id));\r\n if (upd === null) return null;\r\n\r\n that.handlers.setSettingsState();\r\n }\r\n }, // _download_mode\r\n\r\n // show_size - флаг, отвечающий за показ размеров картинки при наведении на кнопку,\r\n // и соответственно, за выезжающую анимацию при наведении.\r\n // Если true, то размеры показываются\r\n // Если false, то размеры скрыты\r\n _show_size: true,\r\n get show_size() {\r\n return this._show_size;\r\n },\r\n set show_size(val) {\r\n if (typeof val === 'boolean') {\r\n this._show_size = val;\r\n that._saveSettings();\r\n\r\n let upd = that._updateBtn(document.querySelector('#' + that.imgContainer_id));\r\n if (upd === null) return null;\r\n\r\n that.handlers.setSettingsState();\r\n }\r\n }, // _show_size\r\n\r\n // loaded_urls - флаг, отвечающий за отметку того, что текущая картинка уже была ранее скачена,\r\n // в виде желтой иконки стрелки\r\n _loaded_urls: true,\r\n get loaded_urls() {\r\n return this._loaded_urls;\r\n },\r\n set loaded_urls(val) {\r\n if (typeof val === 'boolean') {\r\n this._loaded_urls = val;\r\n that.handlers.setSettingsState();\r\n that._checkLoadedUrl(true);\r\n }\r\n }, // _loaded_urls\r\n\r\n _loaded_urls_PKM: true,\r\n get loaded_urls_PKM() {\r\n return this._loaded_urls_PKM;\r\n },\r\n set loaded_urls_PKM(val) {\r\n if (typeof val === 'boolean') {\r\n this._loaded_urls_PKM = val;\r\n that.handlers.setSettingsState();\r\n\r\n console.log('%c%s', (window.log_color) ? window.log_color.purple : '', '_loaded_urls_PKM: ' + val);\r\n }\r\n }, // _loaded_urls_PKM\r\n };\r\n\r\n // Объект для работы с ранее скаченными картинками\r\n this.loaded_urls = {\r\n _loaded_urls: [],\r\n // Добавить новый url в массив скаченных\r\n add(url) {\r\n if (typeof url === 'string' && !this.check(url)) {\r\n this._loaded_urls.push(url);\r\n that._saveLoadedUrls();\r\n that._checkLoadedUrl();\r\n\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n },\r\n // Проверить, есть ли этот url в скаченных\r\n check(url) {\r\n return this._loaded_urls.some(item => item === url);\r\n },\r\n // Получить массив скаченных url\r\n get() {\r\n return this._loaded_urls;\r\n },\r\n length() {\r\n return this.get().length;\r\n },\r\n // Установить новый массив скаченных url\r\n set(arr, storage = true) {\r\n if (arr instanceof Array) {\r\n this._loaded_urls = arr;\r\n\r\n if (storage) {\r\n that._saveLoadedUrls();\r\n that._checkLoadedUrl(true);\r\n }\r\n\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n },\r\n // Очистить массив скаченных url\r\n clear() {\r\n return this.set([]);\r\n }\r\n }; // _loaded_urls\r\n\r\n // Визуальное состояние кнопки\r\n this.state = {\r\n _settings: 'close',\r\n get settings() {\r\n return this._settings;\r\n },\r\n set settings(val) {\r\n if (typeof val === 'string') {\r\n this._settings = val;\r\n that._saveState();\r\n\r\n let upd = that._updateBtn(document.querySelector('#' + that.imgContainer_id));\r\n if (upd === null) return null;\r\n\r\n that.handlers.applyState();\r\n }\r\n }, // _settings\r\n }\r\n\r\n // Объект хранения таймингов для синхронизации контроллера и анимаций\r\n this.timings = {\r\n delay: 250,\r\n open: 600,\r\n settings_open: 350,\r\n fill: 100,\r\n btn_transition_opacity: 250,\r\n btn_transition_transform: 250,\r\n }\r\n\r\n // Здесь будет храниться элемент кнопки\r\n this.wrap = null;\r\n\r\n // Здесь будет храниться информация о текущей картинке\r\n this.image_data = null;\r\n\r\n // Создаем инстанс шаблонизатора верстки\r\n this.template = new PhotoDownloadTemplates({\r\n selectors: this.selectors,\r\n timings: this.timings,\r\n });\r\n\r\n // Создаем инстанс контроллера событий внутри кнопки\r\n this.handlers = new HandlersManager({\r\n PhotoDownload: this,\r\n selectors: this.selectors,\r\n timings: this.timings,\r\n });\r\n\r\n // Создаем инстанс хранилища\r\n this.storage = new SStorage({\r\n // 'PhotoDownload'\r\n name: this.selectors.photoDownload_id,\r\n default: {\r\n settings: this.settings,\r\n state: this.state,\r\n loaded_urls: [],\r\n }\r\n });\r\n\r\n\r\n // Точка входа\r\n this.init();\r\n }\r\n\r\n // Метод обновления данных в кнопке\r\n _updateBtn(elem) {\r\n if (!elem) return null;\r\n this.parent = elem.closest('.' + this.selectors.imgContainer_class);\r\n if (!this.parent) return null;\r\n\r\n // Если в родительском контейнере еще нет кнопки\r\n if (!this.parent.querySelector('#' + this.selectors.photoDownload_id)) {\r\n // то создадим ее\r\n this.wrap = this.template.createDownloadContainer(this.parent);\r\n\r\n // Применим состояние настроек\r\n this.handlers.setSettingsState();\r\n\r\n // Применим состояние кнопки\r\n this.handlers.applyState();\r\n\r\n // Повесим на нее обработчики\r\n this.handlers.setHandlers();\r\n }\r\n\r\n let btn = this.wrap.querySelector('.' + this.selectors.get('btn.btn'));\r\n\r\n // Получаем из недр ВК информацию о максимальной версии открытой в просмотрщике картинки\r\n this.image_data = window.Photoview.genData(window.cur.pvCurPhoto);\r\n\r\n // Проверим, не был ли новый url ранее уже скачен\r\n this._checkLoadedUrl();\r\n\r\n // Обновим ссылку в кнопке\r\n btn.href = this.image_data.src;\r\n\r\n // Установим информацию о размерах картинки, которая по ссылке\r\n this.template.setSize(this.wrap, this.image_data, this.settings.show_size);\r\n }\r\n\r\n // === LoadedUrl ===\r\n\r\n // Если разрешено в настройке, добавляет url в массив ранее скаченных\r\n _addloadedUrl(url) {\r\n if (this.settings.loaded_urls) {\r\n this.loaded_urls.add(url);\r\n }\r\n }\r\n\r\n // Обновляет отображение в кнопке, если это разрешено в насройках\r\n // и ее href есть в массиве ранее скаченных\r\n _checkLoadedUrl(immediate = false) {\r\n // immediate - флаг, при наличии которого изменение отобразится на кнопке немедленно,\r\n // иначе - только после переключения картинки.\r\n // Нужно для того, чтобы иконка не становилась желтой сразу под мышкой при скачивании,\r\n // но при переключении настройки \"Отмечать скаченные\", изменения отобразятся сразу\r\n if (!immediate) {\r\n if (!this.wrap) return;\r\n let btn = this.wrap.querySelector('.' + this.selectors.get('btn.btn'));\r\n if (!btn || (this.image_data.src === btn.href)) return;\r\n }\r\n\r\n let check = this.loaded_urls.check(this.image_data.src);\r\n this.template.setLoadedUrl(this.wrap, this.settings.loaded_urls, check);\r\n }\r\n\r\n // --- LoadedUrl ---\r\n\r\n // === Watcher ===\r\n\r\n // Установка на document слушателей типов событий, имеющихся в объекте обработчиков\r\n _initWatcher() {\r\n let types = Object.keys(this.triggers);\r\n types.forEach(type => document.addEventListener(type, this._watchTrigger.bind(this)))\r\n }\r\n\r\n // Метод, который вызывает нужный обработчик при нужном событии\r\n _watchTrigger(event) {\r\n // Смотрим, есть ли обработчики полученного типа события\r\n // На самом деле они всегда должны быть, но все же\r\n let triggers = this.triggers[event.type];\r\n if (triggers === undefined) return;\r\n\r\n // Берем элемент, на котором сработало событие\r\n let target = event.target;\r\n\r\n // Цикл по объекту обработчиков полученного типа события\r\n triggers.forEach(trigger => {\r\n // Ищем обработчик для цели события\r\n // Если вернется false, то не найден\r\n let compliance = this._checkComplianceTarget(target, trigger, event.type);\r\n\r\n // Если цели события нет в объекте обработчиков, но в обработчике указано, \r\n // что он может срабатывать на дочернем элементе\r\n if (!compliance && trigger.child) {\r\n // Попробуем найти родительский элемент цели, соответствующий селектору\r\n // из объекта обработчиков\r\n this._checkComplianceChild(target, trigger, event.type);\r\n }\r\n });\r\n }\r\n\r\n // Проверка на соответствие цели события с селекторами объекта триггеров\r\n _checkComplianceTarget(target, trigger, type) {\r\n\r\n if (type === 'click') {\r\n console.log('_checkComplianceTarget', {\r\n target,\r\n trigger\r\n });\r\n }\r\n\r\n let compliance = false;\r\n\r\n // Два отдельных условия для того, чтобы была возможность назначить\r\n // разные обработчики по id и по классу на один элемент, и они сработали оба\r\n if (trigger.type === 'id') {\r\n if (target.id === trigger.selector) {\r\n compliance = true;\r\n\r\n if (trigger.handler) {\r\n trigger.handler.call(this, target);\r\n }\r\n }\r\n }\r\n\r\n if (trigger.type === 'class') {\r\n if (target.classList.contains(trigger.selector)) {\r\n compliance = true;\r\n\r\n if (trigger.handler) {\r\n trigger.handler.call(this, target);\r\n }\r\n }\r\n }\r\n\r\n return compliance;\r\n }\r\n\r\n // Проверка на то, является ли цель события дочерним элементом селектора из объекта триггеров\r\n _checkComplianceChild(target, trigger, type) {\r\n\r\n if (type === 'click') {\r\n console.log('_checkComplianceChild', {\r\n target,\r\n trigger\r\n });\r\n }\r\n\r\n\r\n let parent = (trigger.type === 'id') ?\r\n target.closest('#' + trigger.selector) :\r\n target.closest('.' + trigger.selector);\r\n\r\n if (parent) {\r\n // Если да, запустим обработчик для родителя\r\n this._checkComplianceTarget(parent, trigger);\r\n }\r\n }\r\n\r\n // --- Watcher ---\r\n\r\n // === Storage ===\r\n\r\n _saveSettings() {\r\n let res = this.storage.set('settings', this.settings);\r\n // console.log(res);\r\n }\r\n\r\n _saveState() {\r\n let res = this.storage.set('state', this.state);\r\n // console.log(res);\r\n }\r\n\r\n _saveLoadedUrls() {\r\n let res = this.storage.set('loaded_urls', this.loaded_urls);\r\n // console.log(res);\r\n }\r\n\r\n _restoreStorage() {\r\n let storage = this.storage.getAll();\r\n\r\n for (let storage_obj in storage) {\r\n for (let obj in storage[storage_obj]) {\r\n if (obj.charAt(0) === '_') {\r\n this[storage_obj][obj] = storage[storage_obj][obj];\r\n }\r\n }\r\n }\r\n\r\n this._updateBtn(document.querySelector('#' + this.imgContainer_id));\r\n }\r\n\r\n // --- Storage ---\r\n\r\n\r\n // Точка входа\r\n init() {\r\n console.clear();\r\n console.log('%c%s', (window.log_color) ? window.log_color.blue : '', 'PhotoDownload: Init');\r\n\r\n // Добавляем стили PhotoDownload\r\n this.template.injectCSS();\r\n\r\n // Восстанавливаем сохраненное в LocalStorage состояние\r\n this._restoreStorage();\r\n\r\n // Инициализируем обработчики глобальных событий на document\r\n this._initWatcher();\r\n }\r\n}","export default class SStorage {\r\n constructor(params = {}) {\r\n this.name = params.name;\r\n this.default = params.default;\r\n\r\n this.init();\r\n }\r\n\r\n set(key, val) {\r\n if (val === undefined) return false;\r\n let tmp = JSON.parse(localStorage.getItem(this.name));\r\n tmp[key] = val;\r\n localStorage.setItem(this.name, JSON.stringify(tmp));\r\n\r\n return tmp;\r\n }\r\n\r\n get(key) {\r\n let tmp = JSON.parse(localStorage.getItem(this.name));\r\n\r\n return tmp[key];\r\n }\r\n\r\n getAll() {\r\n let tmp = JSON.parse(localStorage.getItem(this.name));\r\n\r\n return tmp;\r\n }\r\n\r\n remove(key) {\r\n let tmp = JSON.parse(localStorage.getItem(this.name));\r\n delete tmp[key];\r\n localStorage.setItem(this.name, JSON.stringify(tmp));\r\n\r\n return tmp;\r\n }\r\n\r\n clear() {\r\n localStorage.removeItem(this.name);\r\n }\r\n\r\n // Метод подготовки\r\n prepareStorage() {\r\n if (localStorage.getItem(this.name) == null) {\r\n localStorage.setItem(this.name, JSON.stringify(this.default));\r\n\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n\r\n init() {\r\n this.prepareStorage();\r\n }\r\n}","export default function(sel, timings, icons) {\r\n\r\n return /* css */ `\r\n #${sel.photoDownload_id} {\r\n background-color: transparent;\r\n border-top-left-radius: 0;\r\n color: #C3CFE0;\r\n display: flex;\r\n flex-direction: column;\r\n position: absolute;\r\n bottom: 0;\r\n left: 100%;\r\n opacity: 0;\r\n transform: translate3d(-38px, 0, 1px);\r\n will-change: transform, opacity;\r\n transition: opacity ${timings.btn_transition_opacity}ms ease-in-out, transform ${timings.btn_transition_transform}ms ease-in-out !important;\r\n }\r\n\r\n /* При наведении на блок картинки в просмотрщике */\r\n .${sel.imgContainer_class}:hover #${sel.photoDownload_id}.${sel.ready} {\r\n opacity: .3;\r\n }\r\n /* При наведении на wrap кнопки */\r\n .${sel.imgContainer_class} #${sel.photoDownload_id}.${sel.ready}:hover {\r\n opacity: .8;\r\n }\r\n /* Если размер картинки должен отображаться */\r\n #${sel.photoDownload_id}.${sel.ready}:not(.${sel.non_size}):hover {\r\n transform: translate3d(-100%, 0, 1px);\r\n }\r\n\r\n /* Если размер картинки не должен отображаться, в кнопке будет всегда слово \"Настройки\" */\r\n #${sel.photoDownload_id}.${sel.non_size} .${sel.get('btn.main_title_inner')} {\r\n transform: translate3d(0, -29px, 1px);\r\n }\r\n\r\n /* Выдвинуть кнопку при наличии slide_in */\r\n #${sel.photoDownload_id}.${sel.ready}.${sel.slide_in} {\r\n opacity: .8;\r\n transform: translate3d(-100%, 0, 1px);\r\n }\r\n\r\n .${sel.get('btn.btn')} {\r\n display: flex;\r\n align-items: center;\r\n position: relative;\r\n padding: 10px;\r\n background-color: #000;\r\n border-top-left-radius: 4px;\r\n color: #C3CFE0 !important;\r\n }\r\n\r\n .${sel.get('btn.btn')}:hover {\r\n text-decoration: none;\r\n }\r\n\r\n .${sel.get('btn.icon')} {\r\n background-image: url('${icons.get('white', 'arrow')}');\r\n background-size: contain;\r\n background-repeat: no-repeat;\r\n height: 18px;\r\n width: 18px;\r\n position: relative;\r\n }\r\n\r\n /* Эффект скачивания */\r\n .${sel.get('btn.icon')}:before {\r\n content: '';\r\n background-image: url('${icons.get('white', 'arrow')}');\r\n background-size: contain;\r\n background-repeat: no-repeat;\r\n height: 90%;\r\n width: 90%;\r\n position: absolute;\r\n left: 50%;\r\n top: 50%;\r\n opacity: .8;\r\n will-change: transform, opacity;\r\n transform: translate(-50%, -50%);\r\n transition: transform ${timings.settings_open - 100}ms cubic-bezier(.22,.73,.43,.65), opacity ${timings.settings_open}ms cubic-bezier(.38,.75,.46,1) !important;\r\n }\r\n\r\n .${sel.get('btn.icon')}.${sel.get('btn.download_effect')}:before {\r\n transition: transform ${timings.settings_open + 100}ms cubic-bezier(.5,.69,.2,1.6), opacity ${timings.settings_open + 100}ms ease-in-out !important;\r\n transform: translate(-50%, -50%) scale3d(2, 2, 2);\r\n opacity: .1;\r\n }\r\n\r\n .${sel.get('btn.btn')}:hover .${sel.get('btn.icon')},\r\n .${sel.get('btn.btn')}:hover .${sel.get('btn.icon')}:before {\r\n background-image: url('${icons.get('green', 'arrow')}');\r\n }\r\n\r\n /* Отметка о ранее скаченной картинке */\r\n .${sel.get('btn.btn')}.${sel.get('loaded_urls_active')} .${sel.get('btn.icon')},\r\n .${sel.get('btn.btn')}.${sel.get('loaded_urls_active')} .${sel.get('btn.icon')}:before {\r\n background-image: url('${icons.get('yellow', 'arrow')}');\r\n }\r\n\r\n #${sel.photoDownload_id} .${sel.get('btn.size')} {\r\n color: ${icons._colors.grey} !important;\r\n flex-grow: 1;\r\n text-align: center;\r\n height: 15px;\r\n }\r\n\r\n /* Для открытых настроек */\r\n #${sel.photoDownload_id}.${sel.ready}.${sel.settings} {\r\n opacity: .8 !important;\r\n transform: translate3d(-100%, 0, 1px);\r\n }\r\n\r\n #${sel.photoDownload_id}.${sel.settings} .${sel.get('btn.btn')} {\r\n border-top-left-radius: 0;\r\n }\r\n\r\n #${sel.photoDownload_id}.${sel.settings} .${sel.get('btn.btn')}:before {\r\n content: '';\r\n position: absolute;\r\n top: -1px;\r\n left: 50%;\r\n transform: translateX(-50%);\r\n width: calc(100% - 20px);\r\n height: 1px;\r\n background-color: rgba(255, 255, 255, .1);\r\n }\r\n\r\n .${sel.get('btn.main_title_wrap')} {\r\n flex-grow: 1;\r\n height: 14px;\r\n overflow: hidden;\r\n text-align: center;\r\n user-select: none;\r\n }\r\n\r\n #${sel.get('photoDownload_id')} .${sel.get('btn.main_title_inner')} {\r\n will-change: transform;\r\n transition: transform ${timings.settings_open}ms ease-out !important;\r\n }\r\n\r\n .${sel.get('btn.main_title_inner')} * {\r\n margin-bottom: 14px;\r\n }\r\n\r\n /* Для открытых настроек показываем слово \"Настройки\" */\r\n #${sel.photoDownload_id}.${sel.ready}.${sel.settings_open} .${sel.get('btn.main_title_inner')} {\r\n transform: translate3d(0, -29px, 1px);\r\n }\r\n\r\n /* Спрятать иконку стрелки при наличии icon_cog */\r\n #${sel.photoDownload_id}.${sel.ready}.${sel.icon_cog} .${sel.get('btn.icon')}, \r\n #${sel.photoDownload_id}.${sel.ready}.${sel.icon_cog} .${sel.get('btn.icon')}:before {\r\n background-image: none;\r\n }\r\n\r\n #${sel.photoDownload_id}:not(.${sel.settings}) .${sel.get('sett.settings_wrap')} {\r\n height: 0;\r\n overflow: hidden;\r\n }\r\n\r\n #${sel.photoDownload_id}.${sel.ready}.${sel.settings} .${sel.get('sett.settings_wrap')} {\r\n height: auto;\r\n }\r\n\r\n #${sel.photoDownload_id}.${sel.ready} .${sel.get('sett.settings')} {\r\n position: relative;\r\n background-color: #000;\r\n border-top-left-radius: 4px;\r\n font-size: 12px;\r\n width: 150px;\r\n will-change: transform;\r\n transform: translate3d(0, 100%, 1px);\r\n transition: transform ${timings.settings_open}ms ease-out !important;\r\n user-select: none;\r\n }\r\n\r\n /* Выдвинуть настройки вверх при наличии settings_open */\r\n #${sel.photoDownload_id}.${sel.ready}.${sel.settings_open} .${sel.get('sett.settings')} {\r\n transform: translate3d(0, 0%, 1px);\r\n }\r\n \r\n .${sel.get('sett.settings_body')} {\r\n padding: 0 10px;\r\n }\r\n\r\n .${sel.get('sett.settings_body')} ul {\r\n padding: 5px 0;\r\n margin: 0;\r\n list-style: none;\r\n display: flex;\r\n flex-direction: column;\r\n }\r\n\r\n .${sel.get('sett.settings_item')} {\r\n display: flex;\r\n align-items: center;\r\n position: relative;\r\n cursor: pointer;\r\n }\r\n\r\n .${sel.get('sett.settings_item')}:not(:last-child) {\r\n margin-bottom: 5px;\r\n }\r\n\r\n .${sel.get('sett.settings_item')} input[type=radio],\r\n .${sel.get('sett.settings_item')} input[type=checkbox] {\r\n margin: 0;\r\n display: none;\r\n }\r\n\r\n .${sel.get('sett.settings_item_action')} {\r\n display: flex;\r\n align-items: center;\r\n width: 100%;\r\n min-height: 18px;\r\n padding-left: 20px;\r\n cursor: pointer;\r\n background-size: 14px 14px;\r\n background-repeat: no-repeat;\r\n background-position: 0 center;\r\n }\r\n\r\n /* Иконки для радиокнопок */\r\n input[type=radio] + .${sel.get('sett.settings_item_action')} {\r\n background-image: url('${icons.get('white', 'circle')}');\r\n }\r\n input[type=radio]:not([disabled]) + .${sel.get('sett.settings_item_action')}:hover {\r\n background-image: url('${icons.get('green', 'circle')}');\r\n }\r\n input[type=radio]:checked + .${sel.get('sett.settings_item_action')} {\r\n background-image: url('${icons.get('white', 'check_circle')}');\r\n }\r\n input[type=radio]:not([disabled]):checked + .${sel.get('sett.settings_item_action')}:hover {\r\n background-image: url('${icons.get('green', 'check_circle')}');\r\n }\r\n\r\n /* Иконки для чекбоксов */\r\n input[type=checkbox] + .${sel.get('sett.settings_item_action')} {\r\n background-image: url('${icons.get('white', 'square')}');\r\n }\r\n input[type=checkbox]:not([disabled]) + .${sel.get('sett.settings_item_action')}:hover {\r\n background-image: url('${icons.get('green', 'square')}');\r\n }\r\n input[type=checkbox]:checked + .${sel.get('sett.settings_item_action')} {\r\n background-image: url('${icons.get('white', 'check_square')}');\r\n }\r\n input[type=checkbox]:not([disabled]):checked + .${sel.get('sett.settings_item_action')}:hover {\r\n background-image: url('${icons.get('green', 'check_square')}');\r\n }\r\n\r\n input[disabled] + .${sel.get('sett.settings_item_action')} {\r\n opacity: .4;\r\n cursor: default;\r\n }\r\n\r\n /* Иконка шестеренки */\r\n #${sel.get('photoDownload_id')} .cog {\r\n width: 18px;\r\n height: 18px;\r\n transform: rotate(30deg);\r\n opacity: 0;\r\n }\r\n\r\n #${sel.photoDownload_id}.${sel.ready}.${sel.icon_cog} .${sel.get('btn.icon')} .cog {\r\n opacity: 1;\r\n }\r\n\r\n #${sel.get('photoDownload_id')} .cog .cog_circle {\r\n fill: none;\r\n fill-opacity: 0;\r\n stroke-width: 25;\r\n }\r\n\r\n #${sel.get('photoDownload_id')} .cog .cog_path {\r\n fill: none;\r\n fill-opacity: 0;\r\n stroke-width: 25;\r\n stroke-dasharray: 1669;\r\n stroke-dashoffset: 1669;\r\n transition: stroke-dashoffset ${timings.settings_open}ms linear, fill-opacity ${timings.fill}ms ease-out !important;\r\n }\r\n\r\n #${sel.get('photoDownload_id')} .cog.${sel.draw} .cog_path {\r\n transition: stroke-dashoffset ${timings.open}ms linear, fill-opacity ${timings.fill}ms ease-out !important;\r\n stroke-dashoffset: 0;\r\n }\r\n\r\n #${sel.photoDownload_id}.${sel.ready} .cog.${sel.draw_fill} .cog_path {\r\n fill: #00b75a;\r\n fill-opacity: 1;\r\n }\r\n\r\n #${sel.photoDownload_id}.${sel.ready} .cog.${sel.draw_fill} .cog_circle {\r\n fill: #000;\r\n stroke-width: 15;\r\n fill-opacity: 1;\r\n }\r\n\r\n /* === Для настроек с секциями === */\r\n\r\n /* Галочка вверху слева, закрывающая настройки */\r\n .${sel.get('sett.settings_close_ico')} {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n z-index: 10;\r\n background-image: url('${icons.get('white', 'ok')}');\r\n background-size: 16px 16px;\r\n background-position: center;\r\n background-repeat: no-repeat;\r\n padding: 6px 10px;\r\n width: 18px;\r\n height: 18px;\r\n cursor: pointer;\r\n }\r\n\r\n .${sel.get('sett.settings_close_ico')}:hover {\r\n background-image: url('${icons.get('green', 'ok')}');\r\n }\r\n\r\n /* Секция настроек */\r\n .${sel.get('sett.settings_section')}:last-child {\r\n padding-bottom: 5px;\r\n }\r\n\r\n /* При ховере на секцию, но не на заголовок, заголовку давать зеленый цвет */\r\n .${sel.get('sett.settings_section')}:hover .${sel.get('sett.settings_section_header')} {\r\n color: ${icons._colors.green} !important;\r\n }\r\n .${sel.get('sett.settings_section')} .${sel.get('sett.settings_section_header')}:hover {\r\n color: ${icons._colors.grey} !important;\r\n }\r\n\r\n /* При ховере на секцию, но не на заголовок, подчеркиванию заголовка давать зеленый цвет */\r\n .${sel.get('sett.settings_section')}:hover .${sel.get('sett.settings_section_header')}:after {\r\n background-color: ${icons._colors.green};\r\n opacity: .3;\r\n }\r\n .${sel.get('sett.settings_section')} .${sel.get('sett.settings_section_header')}:hover:after {\r\n background-color: ${icons._colors.white};\r\n opacity: .1;\r\n }\r\n\r\n /* Заголовок секции настроек */\r\n #${sel.photoDownload_id} .${sel.get('sett.settings_section_header')} {\r\n position: relative;\r\n cursor: default;\r\n font-weight: bold;\r\n min-height: 30px;\r\n display: flex;\r\n justify-content: flex-end;\r\n align-items: center;\r\n transition: color ${timings.fill}ms ease-out !important;\r\n }\r\n\r\n /* Черта под заколовком секции настроек */\r\n .${sel.get('sett.settings_section_header')}:after {\r\n content: '';\r\n position: absolute;\r\n bottom: 0;\r\n left: 50%;\r\n transform: translateX(-50%);\r\n width: calc(100% - 0px);\r\n height: 1px;\r\n background-color: ${icons._colors.white};\r\n opacity: .1;\r\n }\r\n\r\n `;\r\n}","export default function(sel, timings, icons) {\r\n\r\n return /* html */ `\r\n
\r\n
\r\n
\r\n\r\n
\r\n\r\n \r\n
\r\n
Режим клика
\r\n\r\n
    \r\n
  • \r\n \r\n \r\n
  • \r\n
  • \r\n \r\n \r\n
  • \r\n
\r\n
\r\n \r\n \r\n
\r\n
Размер изображения
\r\n\r\n
    \r\n
  • \r\n \r\n \r\n
  • \r\n
\r\n
\r\n\r\n \r\n
\r\n
Отмечать скаченные
\r\n\r\n
    \r\n
  • \r\n \r\n \r\n
  • \r\n\r\n
  • \r\n \r\n \r\n \r\n
  • \r\n
\r\n
\r\n\r\n
\r\n
\r\n\r\n
\r\n\r\n \r\n
\r\n ${icons.get('green', 'cog', false)}\r\n
\r\n
\r\n
\r\n
\r\n
Настройки
\r\n
\r\n
\r\n
\r\n `;\r\n}","import template_html from './template-html';\r\nimport template_css from './template-css';\r\n\r\n// Класс для шаблонизации верстки кнопки и ее стилей\r\nexport default class PhotoDownloadTemplates {\r\n constructor(params = {}) {\r\n // Переданный объект селекторов\r\n this.sel = params.selectors;\r\n\r\n // Переданный объект таймингов\r\n this.timings = params.timings;\r\n\r\n // Объект, генерирующий разноцветные иконки\r\n this.icons = {\r\n _colors: {\r\n green: '#00B75A',\r\n red: '#F92672',\r\n white: '#FFFFFF',\r\n yellow: '#FFC000',\r\n black: '#000000',\r\n grey: '#C3CFE0',\r\n },\r\n _prefix: 'data:image/svg+xml;charset=utf-8,',\r\n _template: {\r\n /* html */\r\n arrow: `\r\n \r\n `,\r\n /* html */\r\n ok: `\r\n \r\n `,\r\n /* html */\r\n cog: `\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n `,\r\n /* html */\r\n circle: `\r\n \r\n `,\r\n /* html */\r\n check_circle: `\r\n \r\n `,\r\n /* html */\r\n square: `\r\n \r\n `,\r\n /* html */\r\n check_square: `\r\n \r\n `,\r\n },\r\n _temp(template, color) {\r\n let _template = this._template[template] ? this._template[template] : this._template.arrow;\r\n return _template.replace(/\\{\\{.*\\}\\}/gm, color ? color : 'white');\r\n },\r\n get(color, template, url = true) {\r\n let _color = this._colors[color] ? this._colors[color] : color;\r\n let svg = this._temp(template, _color).replace(/[\\s]{2,}/gm, ' ');\r\n return url ? this._prefix + encodeURIComponent(svg) : svg;\r\n }\r\n };\r\n } // constructor\r\n\r\n\r\n setLoadedUrl(wrap, setting_active, check) {\r\n if (!wrap) return null;\r\n\r\n let btn = wrap.querySelector('.' + this.sel.get('btn.btn'));\r\n let icon = btn.querySelector('.' + this.sel.get('btn.icon'));\r\n\r\n if (setting_active && check) {\r\n btn.classList.add(this.sel.get('loaded_urls_active'));\r\n icon.title = 'Это изображение уже было скачено ранее';\r\n } else {\r\n btn.classList.remove(this.sel.get('loaded_urls_active'));\r\n icon.title = '';\r\n }\r\n }\r\n\r\n // Метод для отображения размеров картинки в кнопке\r\n setSize(wrap, image_data, non_size) {\r\n let size = wrap.querySelector('.' + this.sel.get('btn.size'));\r\n\r\n if (image_data.width && image_data.height) {\r\n if (non_size) {\r\n wrap.classList.remove(this.sel.non_size);\r\n } else {\r\n wrap.classList.add(this.sel.non_size);\r\n }\r\n\r\n size.textContent = `${image_data.width}x${image_data.height}`;\r\n } else {\r\n wrap.classList.add(this.sel.non_size);\r\n size.textContent = '';\r\n }\r\n }\r\n\r\n // Метод создания контейнера с кнопкой\r\n createDownloadContainer(parent) {\r\n let wrap = document.createElement('div');\r\n wrap.id = this.sel.photoDownload_id;\r\n\r\n // Заполнение контейнера внутренними элементами\r\n wrap.innerHTML = this.getInnerElems();\r\n\r\n setTimeout(() => {\r\n wrap.classList.add(this.sel.ready);\r\n }, 0);\r\n\r\n parent.appendChild(wrap);\r\n\r\n return wrap;\r\n }\r\n\r\n // Метод добавления на страницу стилей, необходимых для работы PhotoDownload\r\n injectCSS() {\r\n let style = document.createElement('style');\r\n style.id = this.sel.style_id;\r\n style.textContent = this.getStyleContent();\r\n\r\n document.head.appendChild(style);\r\n }\r\n\r\n // Метод, генерирующий верстку самой кнопки\r\n getInnerElems() {\r\n return template_html(this.sel, this.timings, this.icons);\r\n }\r\n\r\n // Метод, шаблонизирующий стили кнопки\r\n getStyleContent() {\r\n return template_css(this.sel, this.timings, this.icons);\r\n }\r\n}","import PhotoDownload from './modules/photo-download';\r\n\r\n\r\nwindow.photoDownload = new PhotoDownload({\r\n download: true\r\n});","//download.js v4.2, by dandavis; 2008-2016. [MIT] see http://danml.com/download.html for tests/usage\n// v1 landed a FF+Chrome compat way of downloading strings to local un-named files, upgraded to use a hidden frame and optional mime\n// v2 added named files via a[download], msSaveBlob, IE (10+) support, and window.URL support for larger+faster saves than dataURLs\n// v3 added dataURL and Blob Input, bind-toggle arity, and legacy dataURL fallback was improved with force-download mime and base64 support. 3.1 improved safari handling.\n// v4 adds AMD/UMD, commonJS, and plain browser support\n// v4.1 adds url download capability via solo URL argument (same domain/CORS only)\n// v4.2 adds semantic variable names, long (over 2MB) dataURL support, and hidden by default temp anchors\n// https://github.com/rndme/download\n\n(function (root, factory) {\n\tif (typeof define === 'function' && define.amd) {\n\t\t// AMD. Register as an anonymous module.\n\t\tdefine([], factory);\n\t} else if (typeof exports === 'object') {\n\t\t// Node. Does not work with strict CommonJS, but\n\t\t// only CommonJS-like environments that support module.exports,\n\t\t// like Node.\n\t\tmodule.exports = factory();\n\t} else {\n\t\t// Browser globals (root is window)\n\t\troot.download = factory();\n }\n}(this, function () {\n\n\treturn function download(data, strFileName, strMimeType) {\n\n\t\tvar self = window, // this script is only for browsers anyway...\n\t\t\tdefaultMime = \"application/octet-stream\", // this default mime also triggers iframe downloads\n\t\t\tmimeType = strMimeType || defaultMime,\n\t\t\tpayload = data,\n\t\t\turl = !strFileName && !strMimeType && payload,\n\t\t\tanchor = document.createElement(\"a\"),\n\t\t\ttoString = function(a){return String(a);},\n\t\t\tmyBlob = (self.Blob || self.MozBlob || self.WebKitBlob || toString),\n\t\t\tfileName = strFileName || \"download\",\n\t\t\tblob,\n\t\t\treader;\n\t\t\tmyBlob= myBlob.call ? myBlob.bind(self) : Blob ;\n\t \n\t\tif(String(this)===\"true\"){ //reverse arguments, allowing download.bind(true, \"text/xml\", \"export.xml\") to act as a callback\n\t\t\tpayload=[payload, mimeType];\n\t\t\tmimeType=payload[0];\n\t\t\tpayload=payload[1];\n\t\t}\n\n\n\t\tif(url && url.length< 2048){ // if no filename and no mime, assume a url was passed as the only argument\n\t\t\tfileName = url.split(\"/\").pop().split(\"?\")[0];\n\t\t\tanchor.href = url; // assign href prop to temp anchor\n\t\t \tif(anchor.href.indexOf(url) !== -1){ // if the browser determines that it's a potentially valid url path:\n \t\tvar ajax=new XMLHttpRequest();\n \t\tajax.open( \"GET\", url, true);\n \t\tajax.responseType = 'blob';\n \t\tajax.onload= function(e){ \n\t\t\t\t download(e.target.response, fileName, defaultMime);\n\t\t\t\t};\n \t\tsetTimeout(function(){ ajax.send();}, 0); // allows setting custom ajax headers using the return:\n\t\t\t return ajax;\n\t\t\t} // end if valid url?\n\t\t} // end if url?\n\n\n\t\t//go ahead and download dataURLs right away\n\t\tif(/^data:([\\w+-]+\\/[\\w+.-]+)?[,;]/.test(payload)){\n\t\t\n\t\t\tif(payload.length > (1024*1024*1.999) && myBlob !== toString ){\n\t\t\t\tpayload=dataUrlToBlob(payload);\n\t\t\t\tmimeType=payload.type || defaultMime;\n\t\t\t}else{\t\t\t\n\t\t\t\treturn navigator.msSaveBlob ? // IE10 can't do a[download], only Blobs:\n\t\t\t\t\tnavigator.msSaveBlob(dataUrlToBlob(payload), fileName) :\n\t\t\t\t\tsaver(payload) ; // everyone else can save dataURLs un-processed\n\t\t\t}\n\t\t\t\n\t\t}else{//not data url, is it a string with special needs?\n\t\t\tif(/([\\x80-\\xff])/.test(payload)){\t\t\t \n\t\t\t\tvar i=0, tempUiArr= new Uint8Array(payload.length), mx=tempUiArr.length;\n\t\t\t\tfor(i;i this.PhotoDownload.state.settings = 'close',\r\n downloadModeHandler: this._downloadModeHandler.bind(this),\r\n showSizeHandler: this._showSizeHandler.bind(this),\r\n downloadEffect: this.tempClass.bind(this, this.sel.get('btn.download_effect'), this.timings.settings_open + 250, `.${this.sel.get('btn.icon')}`),\r\n loadedUrlsHandler: this._loadedUrlsHandler.bind(this),\r\n addLoadedUrl: this._addLoadedUrl.bind(this),\r\n clearLoadedUrls: () => this.PhotoDownload.loaded_urls.clear(),\r\n }\r\n\r\n this.timers = {\r\n delay: null,\r\n open: null,\r\n };\r\n } // constructor\r\n\r\n // Устанавливает обработчики в кнопке\r\n setHandlers() {\r\n let wrap = this.PhotoDownload.wrap;\r\n if (!wrap) return false;\r\n\r\n let btn = wrap.querySelector('.' + this.sel.get('btn.btn'));\r\n\r\n this.set(btn, 'startTimer', 'mousedown');\r\n this.set(btn, 'checkTimer', 'mouseup');\r\n this.set(btn, 'checkTimer', 'mouseleave');\r\n this.set(btn, 'preventHandler', 'click');\r\n\r\n // Галочка закрытия настроек\r\n let btn_close = wrap.querySelector('.' + this.sel.get('sett.settings_close_ico'));\r\n this.set(btn_close, 'closeTimingSettings', 'click');\r\n\r\n // Обработчик изменения настройки режима скачивания (клика по кнопке)\r\n let download_mode = wrap.querySelector('.' + this.sel.get('sett.download_mode'));\r\n this.set(download_mode, 'downloadModeHandler', 'change');\r\n\r\n // Обработчик изменения настройки отображения размера картинки\r\n let size_mode = wrap.querySelector('.' + this.sel.get('sett.size_mode'));\r\n this.set(size_mode, 'showSizeHandler', 'change');\r\n\r\n // Обработчик изменения настройки запоминания URL скаченных картинок\r\n let loaded_urls_mode = wrap.querySelector('.' + this.sel.get('sett.loaded_urls_mode'));\r\n this.set(loaded_urls_mode, 'loadedUrlsHandler', 'change');\r\n\r\n let loaded_urls_mode_clear_control = wrap.querySelector('#' + this.sel.get('loaded_urls_mode_clear_control'));\r\n this.set(loaded_urls_mode_clear_control, 'clearLoadedUrls', 'click');\r\n }\r\n\r\n // Обновляет настройки в кнопке\r\n setSettingsState() {\r\n let wrap = this.PhotoDownload.wrap;\r\n if (!wrap) return false;\r\n\r\n // _download_mode\r\n let download_mode = this.PhotoDownload.settings.download_mode.toString();\r\n let download_mode_block = wrap.querySelector('.' + this.sel.get('sett.download_mode'));\r\n let download_mode_control = download_mode_block.querySelector(`input[value=${download_mode}]`);\r\n download_mode_control.checked = true;\r\n\r\n // _show_size\r\n let size_mode_control = wrap.querySelector('#' + this.sel.size_mode_control);\r\n size_mode_control.checked = this.PhotoDownload.settings.show_size;\r\n if (this.PhotoDownload.settings.show_size) {\r\n wrap.classList.remove(this.sel.non_size);\r\n } else {\r\n wrap.classList.add(this.sel.non_size);\r\n }\r\n\r\n // _loaded_urls\r\n let loaded_urls_mode_control = wrap.querySelector('#' + this.sel.loaded_urls_mode_control);\r\n loaded_urls_mode_control.checked = this.PhotoDownload.settings.loaded_urls;\r\n // Если разрешено \"Запоминать URL\", то разблокируем \"+ клики ПКМ\" и наоборот\r\n let loaded_urls_mode_key_control = wrap.querySelector('#' + this.sel.loaded_urls_mode_key_control);\r\n loaded_urls_mode_key_control.disabled = !this.PhotoDownload.settings.loaded_urls;\r\n // Применим состояние настройки\r\n loaded_urls_mode_key_control.checked = this.PhotoDownload.settings.loaded_urls_PKM;\r\n\r\n }\r\n\r\n // Обновляет визуальное состояние кнопки\r\n applyState() {\r\n let state = this.PhotoDownload.state;\r\n\r\n switch (state.settings) {\r\n case 'open_timing':\r\n this._openTimingSettings();\r\n break;\r\n\r\n case 'open':\r\n this._openSettings();\r\n break;\r\n\r\n case 'close':\r\n this._closeSettings();\r\n break;\r\n\r\n default:\r\n break;\r\n }\r\n }\r\n\r\n // Метод, реализующий режимы быстрого клика и удержания ЛКМ на кнопке\r\n _startTimer(e) {\r\n // Если нажата не ЛКМ - выходим\r\n if (e.which !== 1) {\r\n if (this.PhotoDownload.settings.loaded_urls_PKM &&\r\n this.PhotoDownload.settings.loaded_urls &&\r\n this.PhotoDownload.state.settings == 'close') {\r\n\r\n this._addLoadedUrl(e);\r\n }\r\n\r\n return false;\r\n }\r\n\r\n // Настройки закрыты\r\n if (this.PhotoDownload.state.settings == 'close') {\r\n // Ставим таймер задержки на время, отведенное для быстрого клика\r\n this.timers.delay = setTimeout(() => {\r\n // Если таймер задержки не сброшен, запускаем состояние открытия настроек\r\n this.PhotoDownload.state.settings = 'open_timing';\r\n\r\n // И ставим таймер на время анимации открытия\r\n // Пока не выполнится этот таймер, вход в настройки можно отменить, отпустив ЛКМ\r\n this.timers.open = setTimeout(() => {\r\n // Если этот таймер не сброшен, входим в настройки\r\n this.PhotoDownload.state.settings = 'open';\r\n }, this.timings.open);\r\n\r\n }, this.timings.delay);\r\n\r\n // Настройки открыты\r\n } else if (this.PhotoDownload.state.settings == 'open') {\r\n // Убираем иконку шестеренки\r\n this.PhotoDownload.wrap.querySelector('.cog')\r\n .classList.remove(this.sel.draw, this.sel.draw_fill);\r\n\r\n setTimeout(() => {\r\n // Если за время, отведенное на быстрый клик, настройки еще открыты,\r\n // то закроем их\r\n if (this.PhotoDownload.state.settings == 'open') {\r\n this.PhotoDownload.state.settings = 'close';\r\n }\r\n }, this.timings.delay);\r\n\r\n }\r\n }\r\n\r\n _checkTimer(e) {\r\n // Если нажата не левая кнопка мыши, то выходим\r\n if (e.which !== 1) return false;\r\n\r\n // Если быстрый клин и настройки закрыты, то будет обработчик скачивания\r\n if (this.timers.delay && !this.timers.open && this.PhotoDownload.state.settings == 'close') {\r\n\r\n // Тут действие для простого клика\r\n // В зависимости от флага вешаем либо обработчик скачивания, либо открытия новой вкладки\r\n if (this.PhotoDownload.settings.download_mode) {\r\n this.set(e.currentTarget, ['downloadHandler', 'downloadEffect', 'addLoadedUrl']);\r\n } else {\r\n this.set(e.currentTarget, ['newTabHandler', 'downloadEffect', 'addLoadedUrl']);\r\n }\r\n }\r\n\r\n // Если быстрый клик и настройки открыты, то будет обработчик закрытия настроек\r\n if (this.timers.delay && !this.timers.open && this.PhotoDownload.state.settings == 'open') {\r\n this.PhotoDownload.state.settings = 'close';\r\n }\r\n\r\n // Долгий клик и настройки открыты\r\n if (this.timers.delay && this.timers.open && this.PhotoDownload.state.settings == 'open') {\r\n // // Здесь настройки должны быть уже открыты и для события клика, \r\n // // которое будет сразу после этого mouseup, блокируем действие\r\n this.set(e.currentTarget, 'preventHandler');\r\n }\r\n\r\n if (this.PhotoDownload.state.settings == 'open_timing') {\r\n this.set(e.currentTarget, 'preventHandler');\r\n this.PhotoDownload.state.settings = 'close';\r\n }\r\n\r\n // Обнуляем все таймеры для следующего раза\r\n clearTimeout(this.timers.delay);\r\n this.timers.delay = null;\r\n clearTimeout(this.timers.open);\r\n this.timers.open = null;\r\n }\r\n\r\n // Запуск открытия настроек\r\n _openTimingSettings() {\r\n this.PhotoDownload.wrap.classList.add(this.sel.icon_cog);\r\n this.PhotoDownload.wrap\r\n .querySelector('.cog')\r\n .classList.add(this.sel.draw);\r\n }\r\n\r\n // Настройки открыты\r\n _openSettings() {\r\n this._openTimingSettings();\r\n\r\n let open = () => {\r\n this.PhotoDownload.wrap.classList.add(this.sel.settings, this.sel.settings_open);\r\n setTimeout(() => {\r\n this.PhotoDownload.wrap\r\n .querySelector('.cog')\r\n .classList.add(this.sel.draw_fill);\r\n }, this.timings.settings_open);\r\n }\r\n\r\n if (this.PhotoDownload.settings.show_size) {\r\n open();\r\n } else {\r\n // Если сначала нужно выдвинуть кнопку\r\n this.PhotoDownload.wrap.classList.add(this.sel.slide_in);\r\n setTimeout(() => {\r\n open();\r\n }, this.timings.btn_transition_transform);\r\n }\r\n }\r\n\r\n // Запуск закрытия настроек\r\n _closeSettings() {\r\n let close = () => {\r\n this.PhotoDownload.wrap.classList.remove(this.sel.icon_cog);\r\n this.PhotoDownload.wrap.classList.remove(this.sel.settings);\r\n\r\n // if (!this.PhotoDownload.settings.show_size) {\r\n setTimeout(() => {\r\n this.PhotoDownload.wrap.classList.remove(this.sel.slide_in);\r\n }, this.timings.btn_transition_transform);\r\n // }\r\n }\r\n\r\n this.PhotoDownload.wrap\r\n .querySelector('.cog')\r\n .classList.remove(this.sel.draw, this.sel.draw_fill);\r\n this.PhotoDownload.wrap.classList.remove(this.sel.settings_open);\r\n\r\n setTimeout(() => {\r\n close();\r\n }, this.timings.settings_open);\r\n }\r\n\r\n // Установить один или несколько обработчиков на элемент\r\n // Если на элементе были другие обработчики - они удаляются\r\n // В итоге на элементе гарантировано только переданный набор обработчиков\r\n set(elem, handler_name, event_name = this.default_event_name) {\r\n if (!elem || !handler_name) return false;\r\n\r\n let result = true;\r\n\r\n // Удаляем все уже имеющиеся обработчики\r\n this.removeAll(elem, event_name);\r\n\r\n // Ставим нужные\r\n if (handler_name instanceof Array) {\r\n handler_name.forEach(name => {\r\n this.add(elem, name, event_name);\r\n });\r\n } else if (typeof handler_name === 'string') {\r\n this.add(elem, handler_name, event_name);\r\n } else {\r\n result = false;\r\n }\r\n\r\n return result;\r\n }\r\n\r\n // Добавить обработчик с переданным именем на элемент\r\n add(elem, handler_name, event_name = this.default_event_name) {\r\n if (!elem || !handler_name || !this.getHandler(handler_name)) return false;\r\n\r\n elem.addEventListener(event_name, this.getHandler(handler_name));\r\n\r\n return true;\r\n }\r\n\r\n // Удалить обработчик с переданным именем с элемента\r\n remove(elem, handler_name, event_name = this.default_event_name) {\r\n if (!elem || !handler_name || !this.getHandler(handler_name)) return false;\r\n\r\n elem.removeEventListener(event_name, this.getHandler(handler_name));\r\n\r\n return true;\r\n }\r\n\r\n // Удалить все обработчики с элемента\r\n removeAll(elem, event_name = this.default_event_name) {\r\n if (!elem) return false;\r\n\r\n for (let handler in this.handlers) {\r\n elem.removeEventListener(event_name, this.getHandler(handler));\r\n }\r\n\r\n return true;\r\n }\r\n\r\n // Получить имена всех обработчиков\r\n getHandlersNames() {\r\n return Object.keys(this.handlers);\r\n }\r\n\r\n // Получить объект всех функций-обработчиков\r\n getHandlers() {\r\n return this.handlers;\r\n }\r\n\r\n // Получить функцию-обработчик\r\n getHandler(handler_name) {\r\n return this.handlers[handler_name];\r\n }\r\n\r\n // === Служебные ===\r\n\r\n tempClass(class_name, timeout, elem) {\r\n if (elem instanceof Event) {\r\n elem = elem.currentTarget;\r\n } else if (typeof elem === 'string') {\r\n elem = document.querySelector(elem);\r\n } else if (elem === undefined) {\r\n elem = this;\r\n }\r\n\r\n elem.classList.remove(class_name);\r\n\r\n setTimeout(() => {\r\n elem.classList.add(class_name);\r\n }, 0);\r\n\r\n setTimeout(() => {\r\n elem.classList.remove(class_name);\r\n }, timeout);\r\n }\r\n\r\n // === Обработчики ===\r\n\r\n _addLoadedUrl(e) {\r\n let url = e.currentTarget.href;\r\n this.PhotoDownload._addLoadedUrl(url);\r\n }\r\n\r\n // Меняет настройку запоминания URL скаченных картинок\r\n _loadedUrlsHandler(e) {\r\n if (e.target.id === this.sel.loaded_urls_mode_control) {\r\n // Изменена настройка основного запоминания URL\r\n this.PhotoDownload.settings.loaded_urls = e.target.checked;\r\n } else if (e.target.id === this.sel.loaded_urls_mode_key_control) {\r\n // Изменена настройка дополнительного запоминания URL по ПКМ\r\n this.PhotoDownload.settings.loaded_urls_PKM = e.target.checked;\r\n }\r\n }\r\n\r\n // Меняет настройку показа разрешения картинки при наведении\r\n _showSizeHandler(e) {\r\n this.PhotoDownload.settings.show_size = e.target.checked;\r\n }\r\n\r\n // Меняет настройку режима скачивания\r\n _downloadModeHandler(e) {\r\n let value = e.target.value;\r\n\r\n if (value === 'true') {\r\n this.PhotoDownload.settings.download_mode = true;\r\n } else if (value === 'false') {\r\n this.PhotoDownload.settings.download_mode = false;\r\n }\r\n }\r\n\r\n // Отменяет действие браузера\r\n _preventHandler(e) {\r\n e.preventDefault();\r\n return false;\r\n }\r\n\r\n // Обработчик кнопки для режима открытия в новой вкладке\r\n _newTabHandler(e) {\r\n this.remove(e.currentTarget, 'newTabHandler');\r\n return true;\r\n }\r\n\r\n // Обработчик кнопки для режима скачивания\r\n _downloadHandler(e) {\r\n e.preventDefault();\r\n Download(e.currentTarget.href);\r\n\r\n this.remove(e.currentTarget, 'downloadHandler');\r\n return false;\r\n }\r\n}","import PhotoDownloadTemplates from './templates';\r\nimport HandlersManager from './handlers';\r\nimport SStorage from './storage';\r\n\r\nexport default class PhotoDownload {\r\n constructor(params = {}) {\r\n let that = this;\r\n\r\n // Ссылка, в которую обернута картинка, \r\n // здесь нужнв для триггера создания/обновления кнопки\r\n this.imgContainer_id = 'pv_photo';\r\n\r\n // Объект всех селекторов, использующихся в кнопке\r\n this.selectors = {\r\n _prefix: 'PhotoDownload_',\r\n // id контейнера кнопки\r\n photoDownload_id: 'PhotoDownload',\r\n // Контейнер, в котором находится картинка и элементы управления,\r\n // создавать кнопку будем в нем\r\n imgContainer_class: 'pv_image_wrap',\r\n // id, который добавится тегу style\r\n style_id: 'PhotoDownloadStyle',\r\n\r\n // Класс-флаг, вешается на #PhotoDownload когда нет данных о разрешении\r\n // или в настройках отключен показ размеров картинки\r\n non_size: 'non_size',\r\n // Класс-флаг, вешается для плавного opacity кнопки после создания\r\n ready: 'ready',\r\n\r\n slide_in: 'slide_in',\r\n\r\n settings: 'settings',\r\n settings_open: 'settings_open',\r\n\r\n draw: 'draw',\r\n draw_fill: 'draw_fill',\r\n icon_cog: 'icon_cog',\r\n\r\n download_mode_true: 'download_mode_true',\r\n download_mode_false: 'download_mode_false',\r\n\r\n size_mode_control: 'size_mode_control',\r\n\r\n loaded_urls_mode_control: 'loaded_urls_mode_control',\r\n loaded_urls_mode_key_control: 'loaded_urls_mode_key_control',\r\n loaded_urls_mode_clear_control: 'loaded_urls_mode_clear_control',\r\n loaded_urls_active: 'loaded_urls_active',\r\n\r\n sett: {\r\n settings_wrap: 'settings_wrap',\r\n settings: 'settings',\r\n settings_body: 'settings_body',\r\n download_mode: 'download_mode',\r\n size_mode: 'size_mode',\r\n loaded_urls_mode: 'loaded_urls_mode',\r\n settings_item: 'settings_item',\r\n settings_item_action: 'settings_item_action',\r\n\r\n settings_close_ico: 'settings_close_ico',\r\n settings_section: 'settings_section',\r\n settings_section_header: 'settings_section_header',\r\n },\r\n\r\n btn: {\r\n // Класс кнопки (тега a)\r\n btn: 'btn',\r\n // Класс блока иконки\r\n icon: 'icon',\r\n main_title_wrap: 'main_title_wrap',\r\n main_title_inner: 'main_title_inner',\r\n // Класс блока, в котором отображается разрешение картинки\r\n size: 'size',\r\n settings_title: 'settings_title',\r\n // Класс для эффекта скачивания на иконке стрелки\r\n download_effect: 'download_effect',\r\n },\r\n // Метод получения селектора\r\n get(sel) {\r\n sel = sel.split('.');\r\n let error = false;\r\n let res = this;\r\n\r\n // Если селектор на верхнем уровне объекта, он отдается как есть\r\n if (sel.length === 1) {\r\n res = this[sel];\r\n } else if (sel.length > 1) {\r\n // Иначе получаем селектор из вложенных уровней\r\n sel.forEach(part => {\r\n try {\r\n res = res[part];\r\n } catch (err) {\r\n error = true;\r\n }\r\n })\r\n\r\n // И если селектор существует, дописываем к нему префикс\r\n res = (error || !res) ? undefined : this._prefix + res;\r\n }\r\n\r\n return res;\r\n }\r\n };\r\n\r\n // Объект с описанием обработчиков\r\n this.triggers = {\r\n mouseover: [\r\n // Селектор ссылки, в которую обернута картинка в просмотрщике\r\n {\r\n type: 'id',\r\n selector: this.imgContainer_id,\r\n // При наведении на контейнер картинки, будем обновлять(создавать) кнопку\r\n handler: this._updateBtn,\r\n child: true,\r\n },\r\n // Селектор родительского блока кнопки\r\n {\r\n type: 'class',\r\n selector: this.selectors.get('btn.btn'),\r\n // При наведении на саму кнопку, будем обновлять в ней данные\r\n handler: this._updateBtn,\r\n child: true,\r\n },\r\n ], // Конец mouseover\r\n };\r\n\r\n // Настройки поведения кнопки\r\n this.settings = {\r\n // download_mode - флаг, задающий поведение клика по кнопке\r\n // Если true, то картинка будет скачиваться\r\n // Если false, то картинка будет открываться в новой вкладке\r\n _download_mode: params.download,\r\n get download_mode() {\r\n return this._download_mode;\r\n },\r\n set download_mode(val) {\r\n if (typeof val === 'boolean') {\r\n this._download_mode = val;\r\n that._saveSettings();\r\n\r\n let upd = that._updateBtn(document.querySelector('#' + that.imgContainer_id));\r\n if (upd === null) return null;\r\n\r\n that.handlers.setSettingsState();\r\n }\r\n }, // _download_mode\r\n\r\n // show_size - флаг, отвечающий за показ размеров картинки при наведении на кнопку,\r\n // и соответственно, за выезжающую анимацию при наведении.\r\n // Если true, то размеры показываются\r\n // Если false, то размеры скрыты\r\n _show_size: true,\r\n get show_size() {\r\n return this._show_size;\r\n },\r\n set show_size(val) {\r\n if (typeof val === 'boolean') {\r\n this._show_size = val;\r\n that._saveSettings();\r\n\r\n let upd = that._updateBtn(document.querySelector('#' + that.imgContainer_id));\r\n if (upd === null) return null;\r\n\r\n that.handlers.setSettingsState();\r\n }\r\n }, // _show_size\r\n\r\n // loaded_urls - флаг, отвечающий за отметку того, что текущая картинка уже была ранее скачена,\r\n // в виде желтой иконки стрелки\r\n _loaded_urls: true,\r\n get loaded_urls() {\r\n return this._loaded_urls;\r\n },\r\n set loaded_urls(val) {\r\n if (typeof val === 'boolean') {\r\n this._loaded_urls = val;\r\n that.handlers.setSettingsState();\r\n that._checkLoadedUrl(true);\r\n }\r\n }, // _loaded_urls\r\n\r\n _loaded_urls_PKM: true,\r\n get loaded_urls_PKM() {\r\n return this._loaded_urls_PKM;\r\n },\r\n set loaded_urls_PKM(val) {\r\n if (typeof val === 'boolean') {\r\n this._loaded_urls_PKM = val;\r\n that.handlers.setSettingsState();\r\n\r\n console.log('%c%s', (window.log_color) ? window.log_color.purple : '', '_loaded_urls_PKM: ' + val);\r\n }\r\n }, // _loaded_urls_PKM\r\n };\r\n\r\n // Объект для работы с ранее скаченными картинками\r\n this.loaded_urls = {\r\n _loaded_urls: [],\r\n // Добавить новый url в массив скаченных\r\n add(url) {\r\n if (typeof url === 'string' && !this.check(url)) {\r\n this._loaded_urls.push(url);\r\n that._saveLoadedUrls();\r\n that._checkLoadedUrl();\r\n\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n },\r\n // Проверить, есть ли этот url в скаченных\r\n check(url) {\r\n return this._loaded_urls.some(item => item === url);\r\n },\r\n // Получить массив скаченных url\r\n get() {\r\n return this._loaded_urls;\r\n },\r\n length() {\r\n return this.get().length;\r\n },\r\n // Установить новый массив скаченных url\r\n set(arr, storage = true) {\r\n if (arr instanceof Array) {\r\n this._loaded_urls = arr;\r\n\r\n if (storage) {\r\n that._saveLoadedUrls();\r\n that._checkLoadedUrl(true);\r\n }\r\n\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n },\r\n // Очистить массив скаченных url\r\n clear() {\r\n return this.set([]);\r\n }\r\n }; // _loaded_urls\r\n\r\n // Визуальное состояние кнопки\r\n this.state = {\r\n _settings: 'close',\r\n get settings() {\r\n return this._settings;\r\n },\r\n set settings(val) {\r\n if (typeof val === 'string') {\r\n this._settings = val;\r\n that._saveState();\r\n\r\n let upd = that._updateBtn(document.querySelector('#' + that.imgContainer_id));\r\n if (upd === null) return null;\r\n\r\n that.handlers.applyState();\r\n }\r\n }, // _settings\r\n }\r\n\r\n // Объект хранения таймингов для синхронизации контроллера и анимаций\r\n this.timings = {\r\n delay: 250,\r\n open: 600,\r\n settings_open: 350,\r\n fill: 100,\r\n btn_transition_opacity: 250,\r\n btn_transition_transform: 250,\r\n }\r\n\r\n // Здесь будет храниться элемент кнопки\r\n this.wrap = null;\r\n\r\n // Здесь будет храниться информация о текущей картинке\r\n this.image_data = null;\r\n\r\n // Создаем инстанс шаблонизатора верстки\r\n this.template = new PhotoDownloadTemplates({\r\n selectors: this.selectors,\r\n timings: this.timings,\r\n });\r\n\r\n // Создаем инстанс контроллера событий внутри кнопки\r\n this.handlers = new HandlersManager({\r\n PhotoDownload: this,\r\n selectors: this.selectors,\r\n timings: this.timings,\r\n });\r\n\r\n // Создаем инстанс хранилища\r\n this.storage = new SStorage({\r\n // 'PhotoDownload'\r\n name: this.selectors.photoDownload_id,\r\n default: {\r\n settings: this.settings,\r\n state: this.state,\r\n loaded_urls: [],\r\n }\r\n });\r\n\r\n\r\n // Точка входа\r\n this.init();\r\n }\r\n\r\n // Метод обновления данных в кнопке\r\n _updateBtn(elem) {\r\n if (!elem) return null;\r\n this.parent = elem.closest('.' + this.selectors.imgContainer_class);\r\n if (!this.parent) return null;\r\n\r\n // Если в родительском контейнере еще нет кнопки\r\n if (!this.parent.querySelector('#' + this.selectors.photoDownload_id)) {\r\n // то создадим ее\r\n this.wrap = this.template.createDownloadContainer(this.parent);\r\n\r\n // Применим состояние настроек\r\n this.handlers.setSettingsState();\r\n\r\n // Применим состояние кнопки\r\n this.handlers.applyState();\r\n\r\n // Повесим на нее обработчики\r\n this.handlers.setHandlers();\r\n }\r\n\r\n let btn = this.wrap.querySelector('.' + this.selectors.get('btn.btn'));\r\n\r\n // Получаем из недр ВК информацию о максимальной версии открытой в просмотрщике картинки\r\n this.image_data = window.Photoview.genData(window.cur.pvCurPhoto);\r\n\r\n // Проверим, не был ли новый url ранее уже скачен\r\n this._checkLoadedUrl();\r\n\r\n // Обновим ссылку в кнопке\r\n btn.href = this.image_data.src;\r\n\r\n // Установим информацию о размерах картинки, которая по ссылке\r\n this.template.setSize(this.wrap, this.image_data, this.settings.show_size);\r\n }\r\n\r\n // === LoadedUrl ===\r\n\r\n // Если разрешено в настройке, добавляет url в массив ранее скаченных\r\n _addLoadedUrl(url) {\r\n if (this.settings.loaded_urls) {\r\n this.loaded_urls.add(url);\r\n }\r\n }\r\n\r\n // Обновляет отображение в кнопке, если это разрешено в насройках\r\n // и ее href есть в массиве ранее скаченных\r\n _checkLoadedUrl(immediate = false) {\r\n // immediate - флаг, при наличии которого изменение отобразится на кнопке немедленно,\r\n // иначе - только после переключения картинки.\r\n // Нужно для того, чтобы иконка не становилась желтой сразу под мышкой при скачивании,\r\n // но при переключении настройки \"Отмечать скаченные\", изменения отобразятся сразу\r\n if (!immediate) {\r\n if (!this.wrap) return;\r\n let btn = this.wrap.querySelector('.' + this.selectors.get('btn.btn'));\r\n if (!btn || (this.image_data.src === btn.href)) return;\r\n }\r\n\r\n let check = this.loaded_urls.check(this.image_data.src);\r\n this.template.setLoadedUrl(this.wrap, this.settings.loaded_urls, check);\r\n }\r\n\r\n // --- LoadedUrl ---\r\n\r\n // === Watcher ===\r\n\r\n // Установка на document слушателей типов событий, имеющихся в объекте обработчиков\r\n _initWatcher() {\r\n let types = Object.keys(this.triggers);\r\n types.forEach(type => document.addEventListener(type, this._watchTrigger.bind(this)))\r\n }\r\n\r\n // Метод, который вызывает нужный обработчик при нужном событии\r\n _watchTrigger(event) {\r\n // Смотрим, есть ли обработчики полученного типа события\r\n // На самом деле они всегда должны быть, но все же\r\n let triggers = this.triggers[event.type];\r\n if (triggers === undefined) return;\r\n\r\n // Берем элемент, на котором сработало событие\r\n let target = event.target;\r\n\r\n // Цикл по объекту обработчиков полученного типа события\r\n triggers.forEach(trigger => {\r\n // Ищем обработчик для цели события\r\n // Если вернется false, то не найден\r\n let compliance = this._checkComplianceTarget(target, trigger, event.type);\r\n\r\n // Если цели события нет в объекте обработчиков, но в обработчике указано, \r\n // что он может срабатывать на дочернем элементе\r\n if (!compliance && trigger.child) {\r\n // Попробуем найти родительский элемент цели, соответствующий селектору\r\n // из объекта обработчиков\r\n this._checkComplianceChild(target, trigger, event.type);\r\n }\r\n });\r\n }\r\n\r\n // Проверка на соответствие цели события с селекторами объекта триггеров\r\n _checkComplianceTarget(target, trigger, type) {\r\n\r\n if (type === 'click') {\r\n console.log('_checkComplianceTarget', {\r\n target,\r\n trigger\r\n });\r\n }\r\n\r\n let compliance = false;\r\n\r\n // Два отдельных условия для того, чтобы была возможность назначить\r\n // разные обработчики по id и по классу на один элемент, и они сработали оба\r\n if (trigger.type === 'id') {\r\n if (target.id === trigger.selector) {\r\n compliance = true;\r\n\r\n if (trigger.handler) {\r\n trigger.handler.call(this, target);\r\n }\r\n }\r\n }\r\n\r\n if (trigger.type === 'class') {\r\n if (target.classList.contains(trigger.selector)) {\r\n compliance = true;\r\n\r\n if (trigger.handler) {\r\n trigger.handler.call(this, target);\r\n }\r\n }\r\n }\r\n\r\n return compliance;\r\n }\r\n\r\n // Проверка на то, является ли цель события дочерним элементом селектора из объекта триггеров\r\n _checkComplianceChild(target, trigger, type) {\r\n\r\n if (type === 'click') {\r\n console.log('_checkComplianceChild', {\r\n target,\r\n trigger\r\n });\r\n }\r\n\r\n\r\n let parent = (trigger.type === 'id') ?\r\n target.closest('#' + trigger.selector) :\r\n target.closest('.' + trigger.selector);\r\n\r\n if (parent) {\r\n // Если да, запустим обработчик для родителя\r\n this._checkComplianceTarget(parent, trigger);\r\n }\r\n }\r\n\r\n // --- Watcher ---\r\n\r\n // === Storage ===\r\n\r\n _saveSettings() {\r\n let res = this.storage.set('settings', this.settings);\r\n // console.log(res);\r\n }\r\n\r\n _saveState() {\r\n let res = this.storage.set('state', this.state);\r\n // console.log(res);\r\n }\r\n\r\n _saveLoadedUrls() {\r\n let res = this.storage.set('loaded_urls', this.loaded_urls);\r\n // console.log(res);\r\n }\r\n\r\n _restoreStorage() {\r\n let storage = this.storage.getAll();\r\n\r\n for (let storage_obj in storage) {\r\n for (let obj in storage[storage_obj]) {\r\n if (obj.charAt(0) === '_') {\r\n this[storage_obj][obj] = storage[storage_obj][obj];\r\n }\r\n }\r\n }\r\n\r\n this._updateBtn(document.querySelector('#' + this.imgContainer_id));\r\n }\r\n\r\n // --- Storage ---\r\n\r\n\r\n // Точка входа\r\n init() {\r\n console.clear();\r\n console.log('%c%s', (window.log_color) ? window.log_color.blue : '', 'PhotoDownload: Init');\r\n\r\n // Добавляем стили PhotoDownload\r\n this.template.injectCSS();\r\n\r\n // Восстанавливаем сохраненное в LocalStorage состояние\r\n this._restoreStorage();\r\n\r\n // Инициализируем обработчики глобальных событий на document\r\n this._initWatcher();\r\n }\r\n}","export default class SStorage {\r\n constructor(params = {}) {\r\n this.name = params.name;\r\n this.default = params.default;\r\n\r\n this.init();\r\n }\r\n\r\n set(key, val) {\r\n if (val === undefined) return false;\r\n let tmp = JSON.parse(localStorage.getItem(this.name));\r\n tmp[key] = val;\r\n localStorage.setItem(this.name, JSON.stringify(tmp));\r\n\r\n return tmp;\r\n }\r\n\r\n get(key) {\r\n let tmp = JSON.parse(localStorage.getItem(this.name));\r\n\r\n return tmp[key];\r\n }\r\n\r\n getAll() {\r\n let tmp = JSON.parse(localStorage.getItem(this.name));\r\n\r\n return tmp;\r\n }\r\n\r\n remove(key) {\r\n let tmp = JSON.parse(localStorage.getItem(this.name));\r\n delete tmp[key];\r\n localStorage.setItem(this.name, JSON.stringify(tmp));\r\n\r\n return tmp;\r\n }\r\n\r\n clear() {\r\n localStorage.removeItem(this.name);\r\n }\r\n\r\n // Метод подготовки\r\n prepareStorage() {\r\n if (localStorage.getItem(this.name) == null) {\r\n localStorage.setItem(this.name, JSON.stringify(this.default));\r\n\r\n return true;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n\r\n init() {\r\n this.prepareStorage();\r\n }\r\n}","export default function(sel, timings, icons) {\r\n\r\n return /* css */ `\r\n #${sel.photoDownload_id} {\r\n background-color: transparent;\r\n border-top-left-radius: 0;\r\n color: #C3CFE0;\r\n display: flex;\r\n flex-direction: column;\r\n position: absolute;\r\n bottom: 0;\r\n left: 100%;\r\n opacity: 0;\r\n transform: translate3d(-38px, 0, 1px);\r\n will-change: transform, opacity;\r\n transition: opacity ${timings.btn_transition_opacity}ms ease-in-out, transform ${timings.btn_transition_transform}ms ease-in-out !important;\r\n }\r\n\r\n /* При наведении на блок картинки в просмотрщике */\r\n .${sel.imgContainer_class}:hover #${sel.photoDownload_id}.${sel.ready} {\r\n opacity: .3;\r\n }\r\n /* При наведении на wrap кнопки */\r\n .${sel.imgContainer_class} #${sel.photoDownload_id}.${sel.ready}:hover {\r\n opacity: .8;\r\n }\r\n /* Если размер картинки должен отображаться */\r\n #${sel.photoDownload_id}.${sel.ready}:not(.${sel.non_size}):hover {\r\n transform: translate3d(-100%, 0, 1px);\r\n }\r\n\r\n /* Если размер картинки не должен отображаться, в кнопке будет всегда слово \"Настройки\" */\r\n #${sel.photoDownload_id}.${sel.non_size} .${sel.get('btn.main_title_inner')} {\r\n transform: translate3d(0, -29px, 1px);\r\n }\r\n\r\n /* Выдвинуть кнопку при наличии slide_in */\r\n #${sel.photoDownload_id}.${sel.ready}.${sel.slide_in} {\r\n opacity: .8;\r\n transform: translate3d(-100%, 0, 1px);\r\n }\r\n\r\n .${sel.get('btn.btn')} {\r\n display: flex;\r\n align-items: center;\r\n position: relative;\r\n padding: 10px;\r\n background-color: #000;\r\n border-top-left-radius: 4px;\r\n color: #C3CFE0 !important;\r\n }\r\n\r\n .${sel.get('btn.btn')}:hover {\r\n text-decoration: none;\r\n }\r\n\r\n .${sel.get('btn.icon')} {\r\n background-image: url('${icons.get('white', 'arrow')}');\r\n background-size: contain;\r\n background-repeat: no-repeat;\r\n height: 18px;\r\n width: 18px;\r\n position: relative;\r\n }\r\n\r\n /* Эффект скачивания */\r\n .${sel.get('btn.icon')}:before {\r\n content: '';\r\n background-image: url('${icons.get('white', 'arrow')}');\r\n background-size: contain;\r\n background-repeat: no-repeat;\r\n height: 90%;\r\n width: 90%;\r\n position: absolute;\r\n left: 50%;\r\n top: 50%;\r\n opacity: .8;\r\n will-change: transform, opacity;\r\n transform: translate(-50%, -50%);\r\n transition: transform ${timings.settings_open - 100}ms cubic-bezier(.22,.73,.43,.65), opacity ${timings.settings_open}ms cubic-bezier(.38,.75,.46,1) !important;\r\n }\r\n\r\n .${sel.get('btn.icon')}.${sel.get('btn.download_effect')}:before {\r\n transition: transform ${timings.settings_open + 100}ms cubic-bezier(.5,.69,.2,1.6), opacity ${timings.settings_open + 100}ms ease-in-out !important;\r\n transform: translate(-50%, -50%) scale3d(2, 2, 2);\r\n opacity: .1;\r\n }\r\n\r\n .${sel.get('btn.btn')}:hover .${sel.get('btn.icon')},\r\n .${sel.get('btn.btn')}:hover .${sel.get('btn.icon')}:before {\r\n background-image: url('${icons.get('green', 'arrow')}');\r\n }\r\n\r\n /* Отметка о ранее скаченной картинке */\r\n .${sel.get('btn.btn')}.${sel.get('loaded_urls_active')} .${sel.get('btn.icon')},\r\n .${sel.get('btn.btn')}.${sel.get('loaded_urls_active')} .${sel.get('btn.icon')}:before {\r\n background-image: url('${icons.get('yellow', 'arrow')}');\r\n }\r\n\r\n #${sel.photoDownload_id} .${sel.get('btn.size')} {\r\n color: ${icons._colors.grey} !important;\r\n flex-grow: 1;\r\n text-align: center;\r\n height: 15px;\r\n }\r\n\r\n /* Для открытых настроек */\r\n #${sel.photoDownload_id}.${sel.ready}.${sel.settings} {\r\n opacity: .8 !important;\r\n transform: translate3d(-100%, 0, 1px);\r\n }\r\n\r\n #${sel.photoDownload_id}.${sel.settings} .${sel.get('btn.btn')} {\r\n border-top-left-radius: 0;\r\n }\r\n\r\n #${sel.photoDownload_id}.${sel.settings} .${sel.get('btn.btn')}:before {\r\n content: '';\r\n position: absolute;\r\n top: -1px;\r\n left: 50%;\r\n transform: translateX(-50%);\r\n width: calc(100% - 20px);\r\n height: 1px;\r\n background-color: rgba(255, 255, 255, .1);\r\n }\r\n\r\n .${sel.get('btn.main_title_wrap')} {\r\n flex-grow: 1;\r\n height: 14px;\r\n overflow: hidden;\r\n text-align: center;\r\n user-select: none;\r\n }\r\n\r\n #${sel.get('photoDownload_id')} .${sel.get('btn.main_title_inner')} {\r\n will-change: transform;\r\n transition: transform ${timings.settings_open}ms ease-out !important;\r\n }\r\n\r\n .${sel.get('btn.main_title_inner')} * {\r\n margin-bottom: 14px;\r\n }\r\n\r\n /* Для открытых настроек показываем слово \"Настройки\" */\r\n #${sel.photoDownload_id}.${sel.ready}.${sel.settings_open} .${sel.get('btn.main_title_inner')} {\r\n transform: translate3d(0, -29px, 1px);\r\n }\r\n\r\n /* Спрятать иконку стрелки при наличии icon_cog */\r\n #${sel.photoDownload_id}.${sel.ready}.${sel.icon_cog} .${sel.get('btn.icon')}, \r\n #${sel.photoDownload_id}.${sel.ready}.${sel.icon_cog} .${sel.get('btn.icon')}:before {\r\n background-image: none;\r\n }\r\n\r\n #${sel.photoDownload_id}:not(.${sel.settings}) .${sel.get('sett.settings_wrap')} {\r\n height: 0;\r\n overflow: hidden;\r\n }\r\n\r\n #${sel.photoDownload_id}.${sel.ready}.${sel.settings} .${sel.get('sett.settings_wrap')} {\r\n height: auto;\r\n }\r\n\r\n #${sel.photoDownload_id}.${sel.ready} .${sel.get('sett.settings')} {\r\n position: relative;\r\n background-color: #000;\r\n border-top-left-radius: 4px;\r\n font-size: 12px;\r\n width: 150px;\r\n will-change: transform;\r\n transform: translate3d(0, 100%, 1px);\r\n transition: transform ${timings.settings_open}ms ease-out !important;\r\n user-select: none;\r\n }\r\n\r\n /* Выдвинуть настройки вверх при наличии settings_open */\r\n #${sel.photoDownload_id}.${sel.ready}.${sel.settings_open} .${sel.get('sett.settings')} {\r\n transform: translate3d(0, 0%, 1px);\r\n }\r\n \r\n .${sel.get('sett.settings_body')} {\r\n padding: 0 10px;\r\n }\r\n\r\n .${sel.get('sett.settings_body')} ul {\r\n padding: 5px 0;\r\n margin: 0;\r\n list-style: none;\r\n display: flex;\r\n flex-direction: column;\r\n }\r\n\r\n .${sel.get('sett.settings_item')} {\r\n display: flex;\r\n align-items: center;\r\n position: relative;\r\n cursor: pointer;\r\n }\r\n\r\n .${sel.get('sett.settings_item')}:not(:last-child) {\r\n margin-bottom: 5px;\r\n }\r\n\r\n .${sel.get('sett.settings_item')} input[type=radio],\r\n .${sel.get('sett.settings_item')} input[type=checkbox] {\r\n margin: 0;\r\n display: none;\r\n }\r\n\r\n .${sel.get('sett.settings_item')} button {\r\n margin: 0 auto;\r\n background-color: transparent;\r\n font-size: 12px;\r\n padding: 2px;\r\n border: 1px solid;\r\n border-color: ${icons._colors.grey}; \r\n border-radius: 2px;\r\n width: 100%;\r\n cursor: pointer;\r\n }\r\n\r\n .${sel.get('sett.settings_item')} button:hover {\r\n color: ${icons._colors.green} !important;\r\n }\r\n\r\n .${sel.get('sett.settings_item')} button:active {\r\n border-color: ${icons._colors.green} !important;\r\n }\r\n\r\n .${sel.get('sett.settings_item_action')} {\r\n display: flex;\r\n align-items: center;\r\n width: 100%;\r\n min-height: 18px;\r\n padding-left: 20px;\r\n cursor: pointer;\r\n background-size: 14px 14px;\r\n background-repeat: no-repeat;\r\n background-position: 0 center;\r\n }\r\n\r\n /* Иконки для радиокнопок */\r\n input[type=radio] + .${sel.get('sett.settings_item_action')} {\r\n background-image: url('${icons.get('white', 'circle')}');\r\n }\r\n input[type=radio]:not([disabled]) + .${sel.get('sett.settings_item_action')}:hover {\r\n background-image: url('${icons.get('green', 'circle')}');\r\n }\r\n input[type=radio]:checked + .${sel.get('sett.settings_item_action')} {\r\n background-image: url('${icons.get('white', 'check_circle')}');\r\n }\r\n input[type=radio]:not([disabled]):checked + .${sel.get('sett.settings_item_action')}:hover {\r\n background-image: url('${icons.get('green', 'check_circle')}');\r\n }\r\n\r\n /* Иконки для чекбоксов */\r\n input[type=checkbox] + .${sel.get('sett.settings_item_action')} {\r\n background-image: url('${icons.get('white', 'square')}');\r\n }\r\n input[type=checkbox]:not([disabled]) + .${sel.get('sett.settings_item_action')}:hover {\r\n background-image: url('${icons.get('green', 'square')}');\r\n }\r\n input[type=checkbox]:checked + .${sel.get('sett.settings_item_action')} {\r\n background-image: url('${icons.get('white', 'check_square')}');\r\n }\r\n input[type=checkbox]:not([disabled]):checked + .${sel.get('sett.settings_item_action')}:hover {\r\n background-image: url('${icons.get('green', 'check_square')}');\r\n }\r\n\r\n input[disabled] + .${sel.get('sett.settings_item_action')} {\r\n opacity: .4;\r\n cursor: default;\r\n }\r\n\r\n /* Иконка шестеренки */\r\n #${sel.get('photoDownload_id')} .cog {\r\n width: 18px;\r\n height: 18px;\r\n transform: rotate(30deg);\r\n opacity: 0;\r\n }\r\n\r\n #${sel.photoDownload_id}.${sel.ready}.${sel.icon_cog} .${sel.get('btn.icon')} .cog {\r\n opacity: 1;\r\n }\r\n\r\n #${sel.get('photoDownload_id')} .cog .cog_circle {\r\n fill: none;\r\n fill-opacity: 0;\r\n stroke-width: 25;\r\n }\r\n\r\n #${sel.get('photoDownload_id')} .cog .cog_path {\r\n fill: none;\r\n fill-opacity: 0;\r\n stroke-width: 25;\r\n stroke-dasharray: 1669;\r\n stroke-dashoffset: 1669;\r\n transition: stroke-dashoffset ${timings.settings_open}ms linear, fill-opacity ${timings.fill}ms ease-out !important;\r\n }\r\n\r\n #${sel.get('photoDownload_id')} .cog.${sel.draw} .cog_path {\r\n transition: stroke-dashoffset ${timings.open}ms linear, fill-opacity ${timings.fill}ms ease-out !important;\r\n stroke-dashoffset: 0;\r\n }\r\n\r\n #${sel.photoDownload_id}.${sel.ready} .cog.${sel.draw_fill} .cog_path {\r\n fill: #00b75a;\r\n fill-opacity: 1;\r\n }\r\n\r\n #${sel.photoDownload_id}.${sel.ready} .cog.${sel.draw_fill} .cog_circle {\r\n fill: #000;\r\n stroke-width: 15;\r\n fill-opacity: 1;\r\n }\r\n\r\n /* === Для настроек с секциями === */\r\n\r\n /* Галочка вверху слева, закрывающая настройки */\r\n .${sel.get('sett.settings_close_ico')} {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n z-index: 10;\r\n background-image: url('${icons.get('white', 'ok')}');\r\n background-size: 16px 16px;\r\n background-position: center;\r\n background-repeat: no-repeat;\r\n padding: 6px 10px;\r\n width: 18px;\r\n height: 18px;\r\n cursor: pointer;\r\n }\r\n\r\n .${sel.get('sett.settings_close_ico')}:hover {\r\n background-image: url('${icons.get('green', 'ok')}');\r\n }\r\n\r\n /* Секция настроек */\r\n .${sel.get('sett.settings_section')}:last-child {\r\n padding-bottom: 5px;\r\n }\r\n\r\n /* При ховере на секцию, но не на заголовок, заголовку давать зеленый цвет */\r\n .${sel.get('sett.settings_section')}:hover .${sel.get('sett.settings_section_header')} {\r\n color: ${icons._colors.green} !important;\r\n }\r\n .${sel.get('sett.settings_section')} .${sel.get('sett.settings_section_header')}:hover {\r\n color: ${icons._colors.grey} !important;\r\n }\r\n\r\n /* При ховере на секцию, но не на заголовок, подчеркиванию заголовка давать зеленый цвет */\r\n .${sel.get('sett.settings_section')}:hover .${sel.get('sett.settings_section_header')}:after {\r\n background-color: ${icons._colors.green};\r\n opacity: .3;\r\n }\r\n .${sel.get('sett.settings_section')} .${sel.get('sett.settings_section_header')}:hover:after {\r\n background-color: ${icons._colors.white};\r\n opacity: .1;\r\n }\r\n\r\n /* Заголовок секции настроек */\r\n #${sel.photoDownload_id} .${sel.get('sett.settings_section_header')} {\r\n position: relative;\r\n cursor: default;\r\n font-weight: bold;\r\n min-height: 30px;\r\n display: flex;\r\n justify-content: flex-end;\r\n align-items: center;\r\n transition: color ${timings.fill}ms ease-out !important;\r\n }\r\n\r\n /* Черта под заколовком секции настроек */\r\n .${sel.get('sett.settings_section_header')}:after {\r\n content: '';\r\n position: absolute;\r\n bottom: 0;\r\n left: 50%;\r\n transform: translateX(-50%);\r\n width: calc(100% - 0px);\r\n height: 1px;\r\n background-color: ${icons._colors.white};\r\n opacity: .1;\r\n }\r\n\r\n `;\r\n}","export default function(sel, timings, icons) {\r\n\r\n return /* html */ `\r\n
\r\n
\r\n
\r\n\r\n
\r\n\r\n \r\n
\r\n
Режим клика
\r\n\r\n
    \r\n
  • \r\n \r\n \r\n
  • \r\n
  • \r\n \r\n \r\n
  • \r\n
\r\n
\r\n \r\n \r\n
\r\n
Размер изображения
\r\n\r\n
    \r\n
  • \r\n \r\n \r\n
  • \r\n
\r\n
\r\n\r\n \r\n
\r\n
Отмечать скаченные
\r\n\r\n
    \r\n
  • \r\n \r\n \r\n
  • \r\n\r\n
  • \r\n \r\n \r\n
  • \r\n\r\n
  • \r\n \r\n
  • \r\n
\r\n
\r\n\r\n
\r\n
\r\n\r\n
\r\n\r\n \r\n
\r\n ${icons.get('green', 'cog', false)}\r\n
\r\n
\r\n
\r\n
\r\n
Настройки
\r\n
\r\n
\r\n
\r\n `;\r\n}","import template_html from './template-html';\r\nimport template_css from './template-css';\r\n\r\n// Класс для шаблонизации верстки кнопки и ее стилей\r\nexport default class PhotoDownloadTemplates {\r\n constructor(params = {}) {\r\n // Переданный объект селекторов\r\n this.sel = params.selectors;\r\n\r\n // Переданный объект таймингов\r\n this.timings = params.timings;\r\n\r\n // Объект, генерирующий разноцветные иконки\r\n this.icons = {\r\n _colors: {\r\n green: '#00B75A',\r\n red: '#F92672',\r\n white: '#FFFFFF',\r\n yellow: '#FFC000',\r\n black: '#000000',\r\n grey: '#C3CFE0',\r\n },\r\n _prefix: 'data:image/svg+xml;charset=utf-8,',\r\n _template: {\r\n /* html */\r\n arrow: `\r\n \r\n `,\r\n /* html */\r\n ok: `\r\n \r\n `,\r\n /* html */\r\n cog: `\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n `,\r\n /* html */\r\n circle: `\r\n \r\n `,\r\n /* html */\r\n check_circle: `\r\n \r\n `,\r\n /* html */\r\n square: `\r\n \r\n `,\r\n /* html */\r\n check_square: `\r\n \r\n `,\r\n },\r\n _temp(template, color) {\r\n let _template = this._template[template] ? this._template[template] : this._template.arrow;\r\n return _template.replace(/\\{\\{.*\\}\\}/gm, color ? color : 'white');\r\n },\r\n get(color, template, url = true) {\r\n let _color = this._colors[color] ? this._colors[color] : color;\r\n let svg = this._temp(template, _color).replace(/[\\s]{2,}/gm, ' ');\r\n return url ? this._prefix + encodeURIComponent(svg) : svg;\r\n }\r\n };\r\n } // constructor\r\n\r\n\r\n setLoadedUrl(wrap, setting_active, check) {\r\n if (!wrap) return null;\r\n\r\n let btn = wrap.querySelector('.' + this.sel.get('btn.btn'));\r\n let icon = btn.querySelector('.' + this.sel.get('btn.icon'));\r\n\r\n if (setting_active && check) {\r\n btn.classList.add(this.sel.get('loaded_urls_active'));\r\n icon.title = 'Это изображение уже было скачено ранее';\r\n } else {\r\n btn.classList.remove(this.sel.get('loaded_urls_active'));\r\n icon.title = '';\r\n }\r\n }\r\n\r\n // Метод для отображения размеров картинки в кнопке\r\n setSize(wrap, image_data, non_size) {\r\n let size = wrap.querySelector('.' + this.sel.get('btn.size'));\r\n\r\n if (image_data.width && image_data.height) {\r\n if (non_size) {\r\n wrap.classList.remove(this.sel.non_size);\r\n } else {\r\n wrap.classList.add(this.sel.non_size);\r\n }\r\n\r\n size.textContent = `${image_data.width}x${image_data.height}`;\r\n } else {\r\n wrap.classList.add(this.sel.non_size);\r\n size.textContent = '';\r\n }\r\n }\r\n\r\n // Метод создания контейнера с кнопкой\r\n createDownloadContainer(parent) {\r\n let wrap = document.createElement('div');\r\n wrap.id = this.sel.photoDownload_id;\r\n\r\n // Заполнение контейнера внутренними элементами\r\n wrap.innerHTML = this.getInnerElems();\r\n\r\n setTimeout(() => {\r\n wrap.classList.add(this.sel.ready);\r\n }, 0);\r\n\r\n parent.appendChild(wrap);\r\n\r\n return wrap;\r\n }\r\n\r\n // Метод добавления на страницу стилей, необходимых для работы PhotoDownload\r\n injectCSS() {\r\n let style = document.createElement('style');\r\n style.id = this.sel.style_id;\r\n style.textContent = this.getStyleContent();\r\n\r\n document.head.appendChild(style);\r\n }\r\n\r\n // Метод, генерирующий верстку самой кнопки\r\n getInnerElems() {\r\n return template_html(this.sel, this.timings, this.icons);\r\n }\r\n\r\n // Метод, шаблонизирующий стили кнопки\r\n getStyleContent() {\r\n return template_css(this.sel, this.timings, this.icons);\r\n }\r\n}","import PhotoDownload from './modules/photo-download';\r\n\r\n\r\nwindow.photoDownload = new PhotoDownload({\r\n download: true\r\n});","//download.js v4.2, by dandavis; 2008-2016. [MIT] see http://danml.com/download.html for tests/usage\n// v1 landed a FF+Chrome compat way of downloading strings to local un-named files, upgraded to use a hidden frame and optional mime\n// v2 added named files via a[download], msSaveBlob, IE (10+) support, and window.URL support for larger+faster saves than dataURLs\n// v3 added dataURL and Blob Input, bind-toggle arity, and legacy dataURL fallback was improved with force-download mime and base64 support. 3.1 improved safari handling.\n// v4 adds AMD/UMD, commonJS, and plain browser support\n// v4.1 adds url download capability via solo URL argument (same domain/CORS only)\n// v4.2 adds semantic variable names, long (over 2MB) dataURL support, and hidden by default temp anchors\n// https://github.com/rndme/download\n\n(function (root, factory) {\n\tif (typeof define === 'function' && define.amd) {\n\t\t// AMD. Register as an anonymous module.\n\t\tdefine([], factory);\n\t} else if (typeof exports === 'object') {\n\t\t// Node. Does not work with strict CommonJS, but\n\t\t// only CommonJS-like environments that support module.exports,\n\t\t// like Node.\n\t\tmodule.exports = factory();\n\t} else {\n\t\t// Browser globals (root is window)\n\t\troot.download = factory();\n }\n}(this, function () {\n\n\treturn function download(data, strFileName, strMimeType) {\n\n\t\tvar self = window, // this script is only for browsers anyway...\n\t\t\tdefaultMime = \"application/octet-stream\", // this default mime also triggers iframe downloads\n\t\t\tmimeType = strMimeType || defaultMime,\n\t\t\tpayload = data,\n\t\t\turl = !strFileName && !strMimeType && payload,\n\t\t\tanchor = document.createElement(\"a\"),\n\t\t\ttoString = function(a){return String(a);},\n\t\t\tmyBlob = (self.Blob || self.MozBlob || self.WebKitBlob || toString),\n\t\t\tfileName = strFileName || \"download\",\n\t\t\tblob,\n\t\t\treader;\n\t\t\tmyBlob= myBlob.call ? myBlob.bind(self) : Blob ;\n\t \n\t\tif(String(this)===\"true\"){ //reverse arguments, allowing download.bind(true, \"text/xml\", \"export.xml\") to act as a callback\n\t\t\tpayload=[payload, mimeType];\n\t\t\tmimeType=payload[0];\n\t\t\tpayload=payload[1];\n\t\t}\n\n\n\t\tif(url && url.length< 2048){ // if no filename and no mime, assume a url was passed as the only argument\n\t\t\tfileName = url.split(\"/\").pop().split(\"?\")[0];\n\t\t\tanchor.href = url; // assign href prop to temp anchor\n\t\t \tif(anchor.href.indexOf(url) !== -1){ // if the browser determines that it's a potentially valid url path:\n \t\tvar ajax=new XMLHttpRequest();\n \t\tajax.open( \"GET\", url, true);\n \t\tajax.responseType = 'blob';\n \t\tajax.onload= function(e){ \n\t\t\t\t download(e.target.response, fileName, defaultMime);\n\t\t\t\t};\n \t\tsetTimeout(function(){ ajax.send();}, 0); // allows setting custom ajax headers using the return:\n\t\t\t return ajax;\n\t\t\t} // end if valid url?\n\t\t} // end if url?\n\n\n\t\t//go ahead and download dataURLs right away\n\t\tif(/^data:([\\w+-]+\\/[\\w+.-]+)?[,;]/.test(payload)){\n\t\t\n\t\t\tif(payload.length > (1024*1024*1.999) && myBlob !== toString ){\n\t\t\t\tpayload=dataUrlToBlob(payload);\n\t\t\t\tmimeType=payload.type || defaultMime;\n\t\t\t}else{\t\t\t\n\t\t\t\treturn navigator.msSaveBlob ? // IE10 can't do a[download], only Blobs:\n\t\t\t\t\tnavigator.msSaveBlob(dataUrlToBlob(payload), fileName) :\n\t\t\t\t\tsaver(payload) ; // everyone else can save dataURLs un-processed\n\t\t\t}\n\t\t\t\n\t\t}else{//not data url, is it a string with special needs?\n\t\t\tif(/([\\x80-\\xff])/.test(payload)){\t\t\t \n\t\t\t\tvar i=0, tempUiArr= new Uint8Array(payload.length), mx=tempUiArr.length;\n\t\t\t\tfor(i;i this.PhotoDownload.loaded_urls.clear(), } this.timers = { @@ -63,6 +64,9 @@ export default class HandlersManager { // Обработчик изменения настройки запоминания URL скаченных картинок let loaded_urls_mode = wrap.querySelector('.' + this.sel.get('sett.loaded_urls_mode')); this.set(loaded_urls_mode, 'loadedUrlsHandler', 'change'); + + let loaded_urls_mode_clear_control = wrap.querySelector('#' + this.sel.get('loaded_urls_mode_clear_control')); + this.set(loaded_urls_mode_clear_control, 'clearLoadedUrls', 'click'); } // Обновляет настройки в кнопке @@ -126,7 +130,7 @@ export default class HandlersManager { this.PhotoDownload.settings.loaded_urls && this.PhotoDownload.state.settings == 'close') { - this._addloadedUrl(e); + this._addLoadedUrl(e); } return false; @@ -175,9 +179,9 @@ export default class HandlersManager { // Тут действие для простого клика // В зависимости от флага вешаем либо обработчик скачивания, либо открытия новой вкладки if (this.PhotoDownload.settings.download_mode) { - this.set(e.currentTarget, ['downloadHandler', 'downloadEffect', 'addloadedUrl']); + this.set(e.currentTarget, ['downloadHandler', 'downloadEffect', 'addLoadedUrl']); } else { - this.set(e.currentTarget, ['newTabHandler', 'downloadEffect', 'addloadedUrl']); + this.set(e.currentTarget, ['newTabHandler', 'downloadEffect', 'addLoadedUrl']); } } @@ -353,9 +357,9 @@ export default class HandlersManager { // === Обработчики === - _addloadedUrl(e) { + _addLoadedUrl(e) { let url = e.currentTarget.href; - this.PhotoDownload._addloadedUrl(url); + this.PhotoDownload._addLoadedUrl(url); } // Меняет настройку запоминания URL скаченных картинок diff --git a/app/scripts/modules/photo-download.js b/app/scripts/modules/photo-download.js index af9d724..44b9019 100644 --- a/app/scripts/modules/photo-download.js +++ b/app/scripts/modules/photo-download.js @@ -43,6 +43,7 @@ export default class PhotoDownload { loaded_urls_mode_control: 'loaded_urls_mode_control', loaded_urls_mode_key_control: 'loaded_urls_mode_key_control', + loaded_urls_mode_clear_control: 'loaded_urls_mode_clear_control', loaded_urls_active: 'loaded_urls_active', sett: { @@ -341,7 +342,7 @@ export default class PhotoDownload { // === LoadedUrl === // Если разрешено в настройке, добавляет url в массив ранее скаченных - _addloadedUrl(url) { + _addLoadedUrl(url) { if (this.settings.loaded_urls) { this.loaded_urls.add(url); } diff --git a/app/scripts/modules/template-css.js b/app/scripts/modules/template-css.js index 667f689..147f406 100644 --- a/app/scripts/modules/template-css.js +++ b/app/scripts/modules/template-css.js @@ -208,6 +208,26 @@ export default function(sel, timings, icons) { display: none; } + .${sel.get('sett.settings_item')} button { + margin: 0 auto; + background-color: transparent; + font-size: 12px; + padding: 2px; + border: 1px solid; + border-color: ${icons._colors.grey}; + border-radius: 2px; + width: 100%; + cursor: pointer; + } + + .${sel.get('sett.settings_item')} button:hover { + color: ${icons._colors.green} !important; + } + + .${sel.get('sett.settings_item')} button:active { + border-color: ${icons._colors.green} !important; + } + .${sel.get('sett.settings_item_action')} { display: flex; align-items: center; diff --git a/app/scripts/modules/template-html.js b/app/scripts/modules/template-html.js index e93b0ae..bc07aff 100644 --- a/app/scripts/modules/template-html.js +++ b/app/scripts/modules/template-html.js @@ -46,10 +46,13 @@ export default function(sel, timings, icons) {
  • -
  • + +
  • + +
  • diff --git a/app/scripts/vk-photo-download.min.js b/app/scripts/vk-photo-download.min.js index 6e14865..6c439e3 100644 --- a/app/scripts/vk-photo-download.min.js +++ b/app/scripts/vk-photo-download.min.js @@ -49,7 +49,10 @@ function () { showSizeHandler: this._showSizeHandler.bind(this), downloadEffect: this.tempClass.bind(this, this.sel.get('btn.download_effect'), this.timings.settings_open + 250, ".".concat(this.sel.get('btn.icon'))), loadedUrlsHandler: this._loadedUrlsHandler.bind(this), - addloadedUrl: this._addloadedUrl.bind(this) + addLoadedUrl: this._addLoadedUrl.bind(this), + clearLoadedUrls: function clearLoadedUrls() { + return _this.PhotoDownload.loaded_urls.clear(); + } }; this.timers = { delay: null, @@ -81,6 +84,8 @@ function () { var loaded_urls_mode = wrap.querySelector('.' + this.sel.get('sett.loaded_urls_mode')); this.set(loaded_urls_mode, 'loadedUrlsHandler', 'change'); + var loaded_urls_mode_clear_control = wrap.querySelector('#' + this.sel.get('loaded_urls_mode_clear_control')); + this.set(loaded_urls_mode_clear_control, 'clearLoadedUrls', 'click'); } // Обновляет настройки в кнопке }, { @@ -147,7 +152,7 @@ function () { // Если нажата не ЛКМ - выходим if (e.which !== 1) { if (this.PhotoDownload.settings.loaded_urls_PKM && this.PhotoDownload.settings.loaded_urls && this.PhotoDownload.state.settings == 'close') { - this._addloadedUrl(e); + this._addLoadedUrl(e); } return false; @@ -188,9 +193,9 @@ function () { // Тут действие для простого клика // В зависимости от флага вешаем либо обработчик скачивания, либо открытия новой вкладки if (this.PhotoDownload.settings.download_mode) { - this.set(e.currentTarget, ['downloadHandler', 'downloadEffect', 'addloadedUrl']); + this.set(e.currentTarget, ['downloadHandler', 'downloadEffect', 'addLoadedUrl']); } else { - this.set(e.currentTarget, ['newTabHandler', 'downloadEffect', 'addloadedUrl']); + this.set(e.currentTarget, ['newTabHandler', 'downloadEffect', 'addLoadedUrl']); } } // Если быстрый клик и настройки открыты, то будет обработчик закрытия настроек @@ -370,11 +375,11 @@ function () { } // === Обработчики === }, { - key: "_addloadedUrl", - value: function _addloadedUrl(e) { + key: "_addLoadedUrl", + value: function _addLoadedUrl(e) { var url = e.currentTarget.href; - this.PhotoDownload._addloadedUrl(url); + this.PhotoDownload._addLoadedUrl(url); } // Меняет настройку запоминания URL скаченных картинок }, { @@ -496,6 +501,7 @@ function () { size_mode_control: 'size_mode_control', loaded_urls_mode_control: 'loaded_urls_mode_control', loaded_urls_mode_key_control: 'loaded_urls_mode_key_control', + loaded_urls_mode_clear_control: 'loaded_urls_mode_clear_control', loaded_urls_active: 'loaded_urls_active', sett: { settings_wrap: 'settings_wrap', @@ -795,8 +801,8 @@ function () { // Если разрешено в настройке, добавляет url в массив ранее скаченных }, { - key: "_addloadedUrl", - value: function _addloadedUrl(url) { + key: "_addLoadedUrl", + value: function _addLoadedUrl(url) { if (this.settings.loaded_urls) { this.loaded_urls.add(url); } @@ -1064,7 +1070,7 @@ exports.default = _default; function _default(sel, timings, icons) { return ( /* css */ - "\n #".concat(sel.photoDownload_id, " {\n background-color: transparent;\n border-top-left-radius: 0;\n color: #C3CFE0;\n display: flex;\n flex-direction: column;\n position: absolute;\n bottom: 0;\n left: 100%;\n opacity: 0;\n transform: translate3d(-38px, 0, 1px);\n will-change: transform, opacity;\n transition: opacity ").concat(timings.btn_transition_opacity, "ms ease-in-out, transform ").concat(timings.btn_transition_transform, "ms ease-in-out !important;\n }\n\n /* \u041F\u0440\u0438 \u043D\u0430\u0432\u0435\u0434\u0435\u043D\u0438\u0438 \u043D\u0430 \u0431\u043B\u043E\u043A \u043A\u0430\u0440\u0442\u0438\u043D\u043A\u0438 \u0432 \u043F\u0440\u043E\u0441\u043C\u043E\u0442\u0440\u0449\u0438\u043A\u0435 */\n .").concat(sel.imgContainer_class, ":hover #").concat(sel.photoDownload_id, ".").concat(sel.ready, " {\n opacity: .3;\n }\n /* \u041F\u0440\u0438 \u043D\u0430\u0432\u0435\u0434\u0435\u043D\u0438\u0438 \u043D\u0430 wrap \u043A\u043D\u043E\u043F\u043A\u0438 */\n .").concat(sel.imgContainer_class, " #").concat(sel.photoDownload_id, ".").concat(sel.ready, ":hover {\n opacity: .8;\n }\n /* \u0415\u0441\u043B\u0438 \u0440\u0430\u0437\u043C\u0435\u0440 \u043A\u0430\u0440\u0442\u0438\u043D\u043A\u0438 \u0434\u043E\u043B\u0436\u0435\u043D \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0430\u0442\u044C\u0441\u044F */\n #").concat(sel.photoDownload_id, ".").concat(sel.ready, ":not(.").concat(sel.non_size, "):hover {\n transform: translate3d(-100%, 0, 1px);\n }\n\n /* \u0415\u0441\u043B\u0438 \u0440\u0430\u0437\u043C\u0435\u0440 \u043A\u0430\u0440\u0442\u0438\u043D\u043A\u0438 \u043D\u0435 \u0434\u043E\u043B\u0436\u0435\u043D \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0430\u0442\u044C\u0441\u044F, \u0432 \u043A\u043D\u043E\u043F\u043A\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u043B\u043E\u0432\u043E \"\u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438\" */\n #").concat(sel.photoDownload_id, ".").concat(sel.non_size, " .").concat(sel.get('btn.main_title_inner'), " {\n transform: translate3d(0, -29px, 1px);\n }\n\n /* \u0412\u044B\u0434\u0432\u0438\u043D\u0443\u0442\u044C \u043A\u043D\u043E\u043F\u043A\u0443 \u043F\u0440\u0438 \u043D\u0430\u043B\u0438\u0447\u0438\u0438 slide_in */\n #").concat(sel.photoDownload_id, ".").concat(sel.ready, ".").concat(sel.slide_in, " {\n opacity: .8;\n transform: translate3d(-100%, 0, 1px);\n }\n\n .").concat(sel.get('btn.btn'), " {\n display: flex;\n align-items: center;\n position: relative;\n padding: 10px;\n background-color: #000;\n border-top-left-radius: 4px;\n color: #C3CFE0 !important;\n }\n\n .").concat(sel.get('btn.btn'), ":hover {\n text-decoration: none;\n }\n\n .").concat(sel.get('btn.icon'), " {\n background-image: url('").concat(icons.get('white', 'arrow'), "');\n background-size: contain;\n background-repeat: no-repeat;\n height: 18px;\n width: 18px;\n position: relative;\n }\n\n /* \u042D\u0444\u0444\u0435\u043A\u0442 \u0441\u043A\u0430\u0447\u0438\u0432\u0430\u043D\u0438\u044F */\n .").concat(sel.get('btn.icon'), ":before {\n content: '';\n background-image: url('").concat(icons.get('white', 'arrow'), "');\n background-size: contain;\n background-repeat: no-repeat;\n height: 90%;\n width: 90%;\n position: absolute;\n left: 50%;\n top: 50%;\n opacity: .8;\n will-change: transform, opacity;\n transform: translate(-50%, -50%);\n transition: transform ").concat(timings.settings_open - 100, "ms cubic-bezier(.22,.73,.43,.65), opacity ").concat(timings.settings_open, "ms cubic-bezier(.38,.75,.46,1) !important;\n }\n\n .").concat(sel.get('btn.icon'), ".").concat(sel.get('btn.download_effect'), ":before {\n transition: transform ").concat(timings.settings_open + 100, "ms cubic-bezier(.5,.69,.2,1.6), opacity ").concat(timings.settings_open + 100, "ms ease-in-out !important;\n transform: translate(-50%, -50%) scale3d(2, 2, 2);\n opacity: .1;\n }\n\n .").concat(sel.get('btn.btn'), ":hover .").concat(sel.get('btn.icon'), ",\n .").concat(sel.get('btn.btn'), ":hover .").concat(sel.get('btn.icon'), ":before {\n background-image: url('").concat(icons.get('green', 'arrow'), "');\n }\n\n /* \u041E\u0442\u043C\u0435\u0442\u043A\u0430 \u043E \u0440\u0430\u043D\u0435\u0435 \u0441\u043A\u0430\u0447\u0435\u043D\u043D\u043E\u0439 \u043A\u0430\u0440\u0442\u0438\u043D\u043A\u0435 */\n .").concat(sel.get('btn.btn'), ".").concat(sel.get('loaded_urls_active'), " .").concat(sel.get('btn.icon'), ",\n .").concat(sel.get('btn.btn'), ".").concat(sel.get('loaded_urls_active'), " .").concat(sel.get('btn.icon'), ":before {\n background-image: url('").concat(icons.get('yellow', 'arrow'), "');\n }\n\n #").concat(sel.photoDownload_id, " .").concat(sel.get('btn.size'), " {\n color: ").concat(icons._colors.grey, " !important;\n flex-grow: 1;\n text-align: center;\n height: 15px;\n }\n\n /* \u0414\u043B\u044F \u043E\u0442\u043A\u0440\u044B\u0442\u044B\u0445 \u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A */\n #").concat(sel.photoDownload_id, ".").concat(sel.ready, ".").concat(sel.settings, " {\n opacity: .8 !important;\n transform: translate3d(-100%, 0, 1px);\n }\n\n #").concat(sel.photoDownload_id, ".").concat(sel.settings, " .").concat(sel.get('btn.btn'), " {\n border-top-left-radius: 0;\n }\n\n #").concat(sel.photoDownload_id, ".").concat(sel.settings, " .").concat(sel.get('btn.btn'), ":before {\n content: '';\n position: absolute;\n top: -1px;\n left: 50%;\n transform: translateX(-50%);\n width: calc(100% - 20px);\n height: 1px;\n background-color: rgba(255, 255, 255, .1);\n }\n\n .").concat(sel.get('btn.main_title_wrap'), " {\n flex-grow: 1;\n height: 14px;\n overflow: hidden;\n text-align: center;\n user-select: none;\n }\n\n #").concat(sel.get('photoDownload_id'), " .").concat(sel.get('btn.main_title_inner'), " {\n will-change: transform;\n transition: transform ").concat(timings.settings_open, "ms ease-out !important;\n }\n\n .").concat(sel.get('btn.main_title_inner'), " * {\n margin-bottom: 14px;\n }\n\n /* \u0414\u043B\u044F \u043E\u0442\u043A\u0440\u044B\u0442\u044B\u0445 \u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A \u043F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u043C \u0441\u043B\u043E\u0432\u043E \"\u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438\" */\n #").concat(sel.photoDownload_id, ".").concat(sel.ready, ".").concat(sel.settings_open, " .").concat(sel.get('btn.main_title_inner'), " {\n transform: translate3d(0, -29px, 1px);\n }\n\n /* \u0421\u043F\u0440\u044F\u0442\u0430\u0442\u044C \u0438\u043A\u043E\u043D\u043A\u0443 \u0441\u0442\u0440\u0435\u043B\u043A\u0438 \u043F\u0440\u0438 \u043D\u0430\u043B\u0438\u0447\u0438\u0438 icon_cog */\n #").concat(sel.photoDownload_id, ".").concat(sel.ready, ".").concat(sel.icon_cog, " .").concat(sel.get('btn.icon'), ", \n #").concat(sel.photoDownload_id, ".").concat(sel.ready, ".").concat(sel.icon_cog, " .").concat(sel.get('btn.icon'), ":before {\n background-image: none;\n }\n\n #").concat(sel.photoDownload_id, ":not(.").concat(sel.settings, ") .").concat(sel.get('sett.settings_wrap'), " {\n height: 0;\n overflow: hidden;\n }\n\n #").concat(sel.photoDownload_id, ".").concat(sel.ready, ".").concat(sel.settings, " .").concat(sel.get('sett.settings_wrap'), " {\n height: auto;\n }\n\n #").concat(sel.photoDownload_id, ".").concat(sel.ready, " .").concat(sel.get('sett.settings'), " {\n position: relative;\n background-color: #000;\n border-top-left-radius: 4px;\n font-size: 12px;\n width: 150px;\n will-change: transform;\n transform: translate3d(0, 100%, 1px);\n transition: transform ").concat(timings.settings_open, "ms ease-out !important;\n user-select: none;\n }\n\n /* \u0412\u044B\u0434\u0432\u0438\u043D\u0443\u0442\u044C \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438 \u0432\u0432\u0435\u0440\u0445 \u043F\u0440\u0438 \u043D\u0430\u043B\u0438\u0447\u0438\u0438 settings_open */\n #").concat(sel.photoDownload_id, ".").concat(sel.ready, ".").concat(sel.settings_open, " .").concat(sel.get('sett.settings'), " {\n transform: translate3d(0, 0%, 1px);\n }\n \n .").concat(sel.get('sett.settings_body'), " {\n padding: 0 10px;\n }\n\n .").concat(sel.get('sett.settings_body'), " ul {\n padding: 5px 0;\n margin: 0;\n list-style: none;\n display: flex;\n flex-direction: column;\n }\n\n .").concat(sel.get('sett.settings_item'), " {\n display: flex;\n align-items: center;\n position: relative;\n cursor: pointer;\n }\n\n .").concat(sel.get('sett.settings_item'), ":not(:last-child) {\n margin-bottom: 5px;\n }\n\n .").concat(sel.get('sett.settings_item'), " input[type=radio],\n .").concat(sel.get('sett.settings_item'), " input[type=checkbox] {\n margin: 0;\n display: none;\n }\n\n .").concat(sel.get('sett.settings_item_action'), " {\n display: flex;\n align-items: center;\n width: 100%;\n min-height: 18px;\n padding-left: 20px;\n cursor: pointer;\n background-size: 14px 14px;\n background-repeat: no-repeat;\n background-position: 0 center;\n }\n\n /* \u0418\u043A\u043E\u043D\u043A\u0438 \u0434\u043B\u044F \u0440\u0430\u0434\u0438\u043E\u043A\u043D\u043E\u043F\u043E\u043A */\n input[type=radio] + .").concat(sel.get('sett.settings_item_action'), " {\n background-image: url('").concat(icons.get('white', 'circle'), "');\n }\n input[type=radio]:not([disabled]) + .").concat(sel.get('sett.settings_item_action'), ":hover {\n background-image: url('").concat(icons.get('green', 'circle'), "');\n }\n input[type=radio]:checked + .").concat(sel.get('sett.settings_item_action'), " {\n background-image: url('").concat(icons.get('white', 'check_circle'), "');\n }\n input[type=radio]:not([disabled]):checked + .").concat(sel.get('sett.settings_item_action'), ":hover {\n background-image: url('").concat(icons.get('green', 'check_circle'), "');\n }\n\n /* \u0418\u043A\u043E\u043D\u043A\u0438 \u0434\u043B\u044F \u0447\u0435\u043A\u0431\u043E\u043A\u0441\u043E\u0432 */\n input[type=checkbox] + .").concat(sel.get('sett.settings_item_action'), " {\n background-image: url('").concat(icons.get('white', 'square'), "');\n }\n input[type=checkbox]:not([disabled]) + .").concat(sel.get('sett.settings_item_action'), ":hover {\n background-image: url('").concat(icons.get('green', 'square'), "');\n }\n input[type=checkbox]:checked + .").concat(sel.get('sett.settings_item_action'), " {\n background-image: url('").concat(icons.get('white', 'check_square'), "');\n }\n input[type=checkbox]:not([disabled]):checked + .").concat(sel.get('sett.settings_item_action'), ":hover {\n background-image: url('").concat(icons.get('green', 'check_square'), "');\n }\n\n input[disabled] + .").concat(sel.get('sett.settings_item_action'), " {\n opacity: .4;\n cursor: default;\n }\n\n /* \u0418\u043A\u043E\u043D\u043A\u0430 \u0448\u0435\u0441\u0442\u0435\u0440\u0435\u043D\u043A\u0438 */\n #").concat(sel.get('photoDownload_id'), " .cog {\n width: 18px;\n height: 18px;\n transform: rotate(30deg);\n opacity: 0;\n }\n\n #").concat(sel.photoDownload_id, ".").concat(sel.ready, ".").concat(sel.icon_cog, " .").concat(sel.get('btn.icon'), " .cog {\n opacity: 1;\n }\n\n #").concat(sel.get('photoDownload_id'), " .cog .cog_circle {\n fill: none;\n fill-opacity: 0;\n stroke-width: 25;\n }\n\n #").concat(sel.get('photoDownload_id'), " .cog .cog_path {\n fill: none;\n fill-opacity: 0;\n stroke-width: 25;\n stroke-dasharray: 1669;\n stroke-dashoffset: 1669;\n transition: stroke-dashoffset ").concat(timings.settings_open, "ms linear, fill-opacity ").concat(timings.fill, "ms ease-out !important;\n }\n\n #").concat(sel.get('photoDownload_id'), " .cog.").concat(sel.draw, " .cog_path {\n transition: stroke-dashoffset ").concat(timings.open, "ms linear, fill-opacity ").concat(timings.fill, "ms ease-out !important;\n stroke-dashoffset: 0;\n }\n\n #").concat(sel.photoDownload_id, ".").concat(sel.ready, " .cog.").concat(sel.draw_fill, " .cog_path {\n fill: #00b75a;\n fill-opacity: 1;\n }\n\n #").concat(sel.photoDownload_id, ".").concat(sel.ready, " .cog.").concat(sel.draw_fill, " .cog_circle {\n fill: #000;\n stroke-width: 15;\n fill-opacity: 1;\n }\n\n /* === \u0414\u043B\u044F \u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A \u0441 \u0441\u0435\u043A\u0446\u0438\u044F\u043C\u0438 === */\n\n /* \u0413\u0430\u043B\u043E\u0447\u043A\u0430 \u0432\u0432\u0435\u0440\u0445\u0443 \u0441\u043B\u0435\u0432\u0430, \u0437\u0430\u043A\u0440\u044B\u0432\u0430\u044E\u0449\u0430\u044F \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438 */\n .").concat(sel.get('sett.settings_close_ico'), " {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 10;\n background-image: url('").concat(icons.get('white', 'ok'), "');\n background-size: 16px 16px;\n background-position: center;\n background-repeat: no-repeat;\n padding: 6px 10px;\n width: 18px;\n height: 18px;\n cursor: pointer;\n }\n\n .").concat(sel.get('sett.settings_close_ico'), ":hover {\n background-image: url('").concat(icons.get('green', 'ok'), "');\n }\n\n /* \u0421\u0435\u043A\u0446\u0438\u044F \u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A */\n .").concat(sel.get('sett.settings_section'), ":last-child {\n padding-bottom: 5px;\n }\n\n /* \u041F\u0440\u0438 \u0445\u043E\u0432\u0435\u0440\u0435 \u043D\u0430 \u0441\u0435\u043A\u0446\u0438\u044E, \u043D\u043E \u043D\u0435 \u043D\u0430 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A, \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0443 \u0434\u0430\u0432\u0430\u0442\u044C \u0437\u0435\u043B\u0435\u043D\u044B\u0439 \u0446\u0432\u0435\u0442 */\n .").concat(sel.get('sett.settings_section'), ":hover .").concat(sel.get('sett.settings_section_header'), " {\n color: ").concat(icons._colors.green, " !important;\n }\n .").concat(sel.get('sett.settings_section'), " .").concat(sel.get('sett.settings_section_header'), ":hover {\n color: ").concat(icons._colors.grey, " !important;\n }\n\n /* \u041F\u0440\u0438 \u0445\u043E\u0432\u0435\u0440\u0435 \u043D\u0430 \u0441\u0435\u043A\u0446\u0438\u044E, \u043D\u043E \u043D\u0435 \u043D\u0430 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A, \u043F\u043E\u0434\u0447\u0435\u0440\u043A\u0438\u0432\u0430\u043D\u0438\u044E \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0430 \u0434\u0430\u0432\u0430\u0442\u044C \u0437\u0435\u043B\u0435\u043D\u044B\u0439 \u0446\u0432\u0435\u0442 */\n .").concat(sel.get('sett.settings_section'), ":hover .").concat(sel.get('sett.settings_section_header'), ":after {\n background-color: ").concat(icons._colors.green, ";\n opacity: .3;\n }\n .").concat(sel.get('sett.settings_section'), " .").concat(sel.get('sett.settings_section_header'), ":hover:after {\n background-color: ").concat(icons._colors.white, ";\n opacity: .1;\n }\n\n /* \u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A \u0441\u0435\u043A\u0446\u0438\u0438 \u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A */\n #").concat(sel.photoDownload_id, " .").concat(sel.get('sett.settings_section_header'), " {\n position: relative;\n cursor: default;\n font-weight: bold;\n min-height: 30px;\n display: flex;\n justify-content: flex-end;\n align-items: center;\n transition: color ").concat(timings.fill, "ms ease-out !important;\n }\n\n /* \u0427\u0435\u0440\u0442\u0430 \u043F\u043E\u0434 \u0437\u0430\u043A\u043E\u043B\u043E\u0432\u043A\u043E\u043C \u0441\u0435\u043A\u0446\u0438\u0438 \u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A */\n .").concat(sel.get('sett.settings_section_header'), ":after {\n content: '';\n position: absolute;\n bottom: 0;\n left: 50%;\n transform: translateX(-50%);\n width: calc(100% - 0px);\n height: 1px;\n background-color: ").concat(icons._colors.white, ";\n opacity: .1;\n }\n\n ") + "\n #".concat(sel.photoDownload_id, " {\n background-color: transparent;\n border-top-left-radius: 0;\n color: #C3CFE0;\n display: flex;\n flex-direction: column;\n position: absolute;\n bottom: 0;\n left: 100%;\n opacity: 0;\n transform: translate3d(-38px, 0, 1px);\n will-change: transform, opacity;\n transition: opacity ").concat(timings.btn_transition_opacity, "ms ease-in-out, transform ").concat(timings.btn_transition_transform, "ms ease-in-out !important;\n }\n\n /* \u041F\u0440\u0438 \u043D\u0430\u0432\u0435\u0434\u0435\u043D\u0438\u0438 \u043D\u0430 \u0431\u043B\u043E\u043A \u043A\u0430\u0440\u0442\u0438\u043D\u043A\u0438 \u0432 \u043F\u0440\u043E\u0441\u043C\u043E\u0442\u0440\u0449\u0438\u043A\u0435 */\n .").concat(sel.imgContainer_class, ":hover #").concat(sel.photoDownload_id, ".").concat(sel.ready, " {\n opacity: .3;\n }\n /* \u041F\u0440\u0438 \u043D\u0430\u0432\u0435\u0434\u0435\u043D\u0438\u0438 \u043D\u0430 wrap \u043A\u043D\u043E\u043F\u043A\u0438 */\n .").concat(sel.imgContainer_class, " #").concat(sel.photoDownload_id, ".").concat(sel.ready, ":hover {\n opacity: .8;\n }\n /* \u0415\u0441\u043B\u0438 \u0440\u0430\u0437\u043C\u0435\u0440 \u043A\u0430\u0440\u0442\u0438\u043D\u043A\u0438 \u0434\u043E\u043B\u0436\u0435\u043D \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0430\u0442\u044C\u0441\u044F */\n #").concat(sel.photoDownload_id, ".").concat(sel.ready, ":not(.").concat(sel.non_size, "):hover {\n transform: translate3d(-100%, 0, 1px);\n }\n\n /* \u0415\u0441\u043B\u0438 \u0440\u0430\u0437\u043C\u0435\u0440 \u043A\u0430\u0440\u0442\u0438\u043D\u043A\u0438 \u043D\u0435 \u0434\u043E\u043B\u0436\u0435\u043D \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0430\u0442\u044C\u0441\u044F, \u0432 \u043A\u043D\u043E\u043F\u043A\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u043B\u043E\u0432\u043E \"\u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438\" */\n #").concat(sel.photoDownload_id, ".").concat(sel.non_size, " .").concat(sel.get('btn.main_title_inner'), " {\n transform: translate3d(0, -29px, 1px);\n }\n\n /* \u0412\u044B\u0434\u0432\u0438\u043D\u0443\u0442\u044C \u043A\u043D\u043E\u043F\u043A\u0443 \u043F\u0440\u0438 \u043D\u0430\u043B\u0438\u0447\u0438\u0438 slide_in */\n #").concat(sel.photoDownload_id, ".").concat(sel.ready, ".").concat(sel.slide_in, " {\n opacity: .8;\n transform: translate3d(-100%, 0, 1px);\n }\n\n .").concat(sel.get('btn.btn'), " {\n display: flex;\n align-items: center;\n position: relative;\n padding: 10px;\n background-color: #000;\n border-top-left-radius: 4px;\n color: #C3CFE0 !important;\n }\n\n .").concat(sel.get('btn.btn'), ":hover {\n text-decoration: none;\n }\n\n .").concat(sel.get('btn.icon'), " {\n background-image: url('").concat(icons.get('white', 'arrow'), "');\n background-size: contain;\n background-repeat: no-repeat;\n height: 18px;\n width: 18px;\n position: relative;\n }\n\n /* \u042D\u0444\u0444\u0435\u043A\u0442 \u0441\u043A\u0430\u0447\u0438\u0432\u0430\u043D\u0438\u044F */\n .").concat(sel.get('btn.icon'), ":before {\n content: '';\n background-image: url('").concat(icons.get('white', 'arrow'), "');\n background-size: contain;\n background-repeat: no-repeat;\n height: 90%;\n width: 90%;\n position: absolute;\n left: 50%;\n top: 50%;\n opacity: .8;\n will-change: transform, opacity;\n transform: translate(-50%, -50%);\n transition: transform ").concat(timings.settings_open - 100, "ms cubic-bezier(.22,.73,.43,.65), opacity ").concat(timings.settings_open, "ms cubic-bezier(.38,.75,.46,1) !important;\n }\n\n .").concat(sel.get('btn.icon'), ".").concat(sel.get('btn.download_effect'), ":before {\n transition: transform ").concat(timings.settings_open + 100, "ms cubic-bezier(.5,.69,.2,1.6), opacity ").concat(timings.settings_open + 100, "ms ease-in-out !important;\n transform: translate(-50%, -50%) scale3d(2, 2, 2);\n opacity: .1;\n }\n\n .").concat(sel.get('btn.btn'), ":hover .").concat(sel.get('btn.icon'), ",\n .").concat(sel.get('btn.btn'), ":hover .").concat(sel.get('btn.icon'), ":before {\n background-image: url('").concat(icons.get('green', 'arrow'), "');\n }\n\n /* \u041E\u0442\u043C\u0435\u0442\u043A\u0430 \u043E \u0440\u0430\u043D\u0435\u0435 \u0441\u043A\u0430\u0447\u0435\u043D\u043D\u043E\u0439 \u043A\u0430\u0440\u0442\u0438\u043D\u043A\u0435 */\n .").concat(sel.get('btn.btn'), ".").concat(sel.get('loaded_urls_active'), " .").concat(sel.get('btn.icon'), ",\n .").concat(sel.get('btn.btn'), ".").concat(sel.get('loaded_urls_active'), " .").concat(sel.get('btn.icon'), ":before {\n background-image: url('").concat(icons.get('yellow', 'arrow'), "');\n }\n\n #").concat(sel.photoDownload_id, " .").concat(sel.get('btn.size'), " {\n color: ").concat(icons._colors.grey, " !important;\n flex-grow: 1;\n text-align: center;\n height: 15px;\n }\n\n /* \u0414\u043B\u044F \u043E\u0442\u043A\u0440\u044B\u0442\u044B\u0445 \u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A */\n #").concat(sel.photoDownload_id, ".").concat(sel.ready, ".").concat(sel.settings, " {\n opacity: .8 !important;\n transform: translate3d(-100%, 0, 1px);\n }\n\n #").concat(sel.photoDownload_id, ".").concat(sel.settings, " .").concat(sel.get('btn.btn'), " {\n border-top-left-radius: 0;\n }\n\n #").concat(sel.photoDownload_id, ".").concat(sel.settings, " .").concat(sel.get('btn.btn'), ":before {\n content: '';\n position: absolute;\n top: -1px;\n left: 50%;\n transform: translateX(-50%);\n width: calc(100% - 20px);\n height: 1px;\n background-color: rgba(255, 255, 255, .1);\n }\n\n .").concat(sel.get('btn.main_title_wrap'), " {\n flex-grow: 1;\n height: 14px;\n overflow: hidden;\n text-align: center;\n user-select: none;\n }\n\n #").concat(sel.get('photoDownload_id'), " .").concat(sel.get('btn.main_title_inner'), " {\n will-change: transform;\n transition: transform ").concat(timings.settings_open, "ms ease-out !important;\n }\n\n .").concat(sel.get('btn.main_title_inner'), " * {\n margin-bottom: 14px;\n }\n\n /* \u0414\u043B\u044F \u043E\u0442\u043A\u0440\u044B\u0442\u044B\u0445 \u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A \u043F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u043C \u0441\u043B\u043E\u0432\u043E \"\u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438\" */\n #").concat(sel.photoDownload_id, ".").concat(sel.ready, ".").concat(sel.settings_open, " .").concat(sel.get('btn.main_title_inner'), " {\n transform: translate3d(0, -29px, 1px);\n }\n\n /* \u0421\u043F\u0440\u044F\u0442\u0430\u0442\u044C \u0438\u043A\u043E\u043D\u043A\u0443 \u0441\u0442\u0440\u0435\u043B\u043A\u0438 \u043F\u0440\u0438 \u043D\u0430\u043B\u0438\u0447\u0438\u0438 icon_cog */\n #").concat(sel.photoDownload_id, ".").concat(sel.ready, ".").concat(sel.icon_cog, " .").concat(sel.get('btn.icon'), ", \n #").concat(sel.photoDownload_id, ".").concat(sel.ready, ".").concat(sel.icon_cog, " .").concat(sel.get('btn.icon'), ":before {\n background-image: none;\n }\n\n #").concat(sel.photoDownload_id, ":not(.").concat(sel.settings, ") .").concat(sel.get('sett.settings_wrap'), " {\n height: 0;\n overflow: hidden;\n }\n\n #").concat(sel.photoDownload_id, ".").concat(sel.ready, ".").concat(sel.settings, " .").concat(sel.get('sett.settings_wrap'), " {\n height: auto;\n }\n\n #").concat(sel.photoDownload_id, ".").concat(sel.ready, " .").concat(sel.get('sett.settings'), " {\n position: relative;\n background-color: #000;\n border-top-left-radius: 4px;\n font-size: 12px;\n width: 150px;\n will-change: transform;\n transform: translate3d(0, 100%, 1px);\n transition: transform ").concat(timings.settings_open, "ms ease-out !important;\n user-select: none;\n }\n\n /* \u0412\u044B\u0434\u0432\u0438\u043D\u0443\u0442\u044C \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438 \u0432\u0432\u0435\u0440\u0445 \u043F\u0440\u0438 \u043D\u0430\u043B\u0438\u0447\u0438\u0438 settings_open */\n #").concat(sel.photoDownload_id, ".").concat(sel.ready, ".").concat(sel.settings_open, " .").concat(sel.get('sett.settings'), " {\n transform: translate3d(0, 0%, 1px);\n }\n \n .").concat(sel.get('sett.settings_body'), " {\n padding: 0 10px;\n }\n\n .").concat(sel.get('sett.settings_body'), " ul {\n padding: 5px 0;\n margin: 0;\n list-style: none;\n display: flex;\n flex-direction: column;\n }\n\n .").concat(sel.get('sett.settings_item'), " {\n display: flex;\n align-items: center;\n position: relative;\n cursor: pointer;\n }\n\n .").concat(sel.get('sett.settings_item'), ":not(:last-child) {\n margin-bottom: 5px;\n }\n\n .").concat(sel.get('sett.settings_item'), " input[type=radio],\n .").concat(sel.get('sett.settings_item'), " input[type=checkbox] {\n margin: 0;\n display: none;\n }\n\n .").concat(sel.get('sett.settings_item'), " button {\n margin: 0 auto;\n background-color: transparent;\n font-size: 12px;\n padding: 2px;\n border: 1px solid;\n border-color: ").concat(icons._colors.grey, "; \n border-radius: 2px;\n width: 100%;\n cursor: pointer;\n }\n\n .").concat(sel.get('sett.settings_item'), " button:hover {\n color: ").concat(icons._colors.green, " !important;\n }\n\n .").concat(sel.get('sett.settings_item'), " button:active {\n border-color: ").concat(icons._colors.green, " !important;\n }\n\n .").concat(sel.get('sett.settings_item_action'), " {\n display: flex;\n align-items: center;\n width: 100%;\n min-height: 18px;\n padding-left: 20px;\n cursor: pointer;\n background-size: 14px 14px;\n background-repeat: no-repeat;\n background-position: 0 center;\n }\n\n /* \u0418\u043A\u043E\u043D\u043A\u0438 \u0434\u043B\u044F \u0440\u0430\u0434\u0438\u043E\u043A\u043D\u043E\u043F\u043E\u043A */\n input[type=radio] + .").concat(sel.get('sett.settings_item_action'), " {\n background-image: url('").concat(icons.get('white', 'circle'), "');\n }\n input[type=radio]:not([disabled]) + .").concat(sel.get('sett.settings_item_action'), ":hover {\n background-image: url('").concat(icons.get('green', 'circle'), "');\n }\n input[type=radio]:checked + .").concat(sel.get('sett.settings_item_action'), " {\n background-image: url('").concat(icons.get('white', 'check_circle'), "');\n }\n input[type=radio]:not([disabled]):checked + .").concat(sel.get('sett.settings_item_action'), ":hover {\n background-image: url('").concat(icons.get('green', 'check_circle'), "');\n }\n\n /* \u0418\u043A\u043E\u043D\u043A\u0438 \u0434\u043B\u044F \u0447\u0435\u043A\u0431\u043E\u043A\u0441\u043E\u0432 */\n input[type=checkbox] + .").concat(sel.get('sett.settings_item_action'), " {\n background-image: url('").concat(icons.get('white', 'square'), "');\n }\n input[type=checkbox]:not([disabled]) + .").concat(sel.get('sett.settings_item_action'), ":hover {\n background-image: url('").concat(icons.get('green', 'square'), "');\n }\n input[type=checkbox]:checked + .").concat(sel.get('sett.settings_item_action'), " {\n background-image: url('").concat(icons.get('white', 'check_square'), "');\n }\n input[type=checkbox]:not([disabled]):checked + .").concat(sel.get('sett.settings_item_action'), ":hover {\n background-image: url('").concat(icons.get('green', 'check_square'), "');\n }\n\n input[disabled] + .").concat(sel.get('sett.settings_item_action'), " {\n opacity: .4;\n cursor: default;\n }\n\n /* \u0418\u043A\u043E\u043D\u043A\u0430 \u0448\u0435\u0441\u0442\u0435\u0440\u0435\u043D\u043A\u0438 */\n #").concat(sel.get('photoDownload_id'), " .cog {\n width: 18px;\n height: 18px;\n transform: rotate(30deg);\n opacity: 0;\n }\n\n #").concat(sel.photoDownload_id, ".").concat(sel.ready, ".").concat(sel.icon_cog, " .").concat(sel.get('btn.icon'), " .cog {\n opacity: 1;\n }\n\n #").concat(sel.get('photoDownload_id'), " .cog .cog_circle {\n fill: none;\n fill-opacity: 0;\n stroke-width: 25;\n }\n\n #").concat(sel.get('photoDownload_id'), " .cog .cog_path {\n fill: none;\n fill-opacity: 0;\n stroke-width: 25;\n stroke-dasharray: 1669;\n stroke-dashoffset: 1669;\n transition: stroke-dashoffset ").concat(timings.settings_open, "ms linear, fill-opacity ").concat(timings.fill, "ms ease-out !important;\n }\n\n #").concat(sel.get('photoDownload_id'), " .cog.").concat(sel.draw, " .cog_path {\n transition: stroke-dashoffset ").concat(timings.open, "ms linear, fill-opacity ").concat(timings.fill, "ms ease-out !important;\n stroke-dashoffset: 0;\n }\n\n #").concat(sel.photoDownload_id, ".").concat(sel.ready, " .cog.").concat(sel.draw_fill, " .cog_path {\n fill: #00b75a;\n fill-opacity: 1;\n }\n\n #").concat(sel.photoDownload_id, ".").concat(sel.ready, " .cog.").concat(sel.draw_fill, " .cog_circle {\n fill: #000;\n stroke-width: 15;\n fill-opacity: 1;\n }\n\n /* === \u0414\u043B\u044F \u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A \u0441 \u0441\u0435\u043A\u0446\u0438\u044F\u043C\u0438 === */\n\n /* \u0413\u0430\u043B\u043E\u0447\u043A\u0430 \u0432\u0432\u0435\u0440\u0445\u0443 \u0441\u043B\u0435\u0432\u0430, \u0437\u0430\u043A\u0440\u044B\u0432\u0430\u044E\u0449\u0430\u044F \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438 */\n .").concat(sel.get('sett.settings_close_ico'), " {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 10;\n background-image: url('").concat(icons.get('white', 'ok'), "');\n background-size: 16px 16px;\n background-position: center;\n background-repeat: no-repeat;\n padding: 6px 10px;\n width: 18px;\n height: 18px;\n cursor: pointer;\n }\n\n .").concat(sel.get('sett.settings_close_ico'), ":hover {\n background-image: url('").concat(icons.get('green', 'ok'), "');\n }\n\n /* \u0421\u0435\u043A\u0446\u0438\u044F \u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A */\n .").concat(sel.get('sett.settings_section'), ":last-child {\n padding-bottom: 5px;\n }\n\n /* \u041F\u0440\u0438 \u0445\u043E\u0432\u0435\u0440\u0435 \u043D\u0430 \u0441\u0435\u043A\u0446\u0438\u044E, \u043D\u043E \u043D\u0435 \u043D\u0430 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A, \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0443 \u0434\u0430\u0432\u0430\u0442\u044C \u0437\u0435\u043B\u0435\u043D\u044B\u0439 \u0446\u0432\u0435\u0442 */\n .").concat(sel.get('sett.settings_section'), ":hover .").concat(sel.get('sett.settings_section_header'), " {\n color: ").concat(icons._colors.green, " !important;\n }\n .").concat(sel.get('sett.settings_section'), " .").concat(sel.get('sett.settings_section_header'), ":hover {\n color: ").concat(icons._colors.grey, " !important;\n }\n\n /* \u041F\u0440\u0438 \u0445\u043E\u0432\u0435\u0440\u0435 \u043D\u0430 \u0441\u0435\u043A\u0446\u0438\u044E, \u043D\u043E \u043D\u0435 \u043D\u0430 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A, \u043F\u043E\u0434\u0447\u0435\u0440\u043A\u0438\u0432\u0430\u043D\u0438\u044E \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0430 \u0434\u0430\u0432\u0430\u0442\u044C \u0437\u0435\u043B\u0435\u043D\u044B\u0439 \u0446\u0432\u0435\u0442 */\n .").concat(sel.get('sett.settings_section'), ":hover .").concat(sel.get('sett.settings_section_header'), ":after {\n background-color: ").concat(icons._colors.green, ";\n opacity: .3;\n }\n .").concat(sel.get('sett.settings_section'), " .").concat(sel.get('sett.settings_section_header'), ":hover:after {\n background-color: ").concat(icons._colors.white, ";\n opacity: .1;\n }\n\n /* \u0417\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A \u0441\u0435\u043A\u0446\u0438\u0438 \u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A */\n #").concat(sel.photoDownload_id, " .").concat(sel.get('sett.settings_section_header'), " {\n position: relative;\n cursor: default;\n font-weight: bold;\n min-height: 30px;\n display: flex;\n justify-content: flex-end;\n align-items: center;\n transition: color ").concat(timings.fill, "ms ease-out !important;\n }\n\n /* \u0427\u0435\u0440\u0442\u0430 \u043F\u043E\u0434 \u0437\u0430\u043A\u043E\u043B\u043E\u0432\u043A\u043E\u043C \u0441\u0435\u043A\u0446\u0438\u0438 \u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A */\n .").concat(sel.get('sett.settings_section_header'), ":after {\n content: '';\n position: absolute;\n bottom: 0;\n left: 50%;\n transform: translateX(-50%);\n width: calc(100% - 0px);\n height: 1px;\n background-color: ").concat(icons._colors.white, ";\n opacity: .1;\n }\n\n ") ); } @@ -1079,7 +1085,7 @@ exports.default = _default; function _default(sel, timings, icons) { return ( /* html */ - "\n
    \n
    \n
    \n\n
    \n\n \n
    \n
    \u0420\u0435\u0436\u0438\u043C \u043A\u043B\u0438\u043A\u0430
    \n\n
      \n
    • \n \n \n
    • \n
    • \n \n \n
    • \n
    \n
    \n \n \n
    \n
    \u0420\u0430\u0437\u043C\u0435\u0440 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F
    \n\n
      \n
    • \n \n \n
    • \n
    \n
    \n\n \n
    \n
    \u041E\u0442\u043C\u0435\u0447\u0430\u0442\u044C \u0441\u043A\u0430\u0447\u0435\u043D\u043D\u044B\u0435
    \n\n
      \n
    • \n \n \n
    • \n\n
    • \n \n \n \n
    • \n
    \n
    \n\n
    \n
    \n\n
    \n\n \n
    \n ").concat(icons.get('green', 'cog', false), "\n
    \n
    \n
    \n
    \n
    \u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438
    \n
    \n
    \n
    \n ") + "\n
    \n
    \n
    \n\n
    \n\n \n
    \n
    \u0420\u0435\u0436\u0438\u043C \u043A\u043B\u0438\u043A\u0430
    \n\n
      \n
    • \n \n \n
    • \n
    • \n \n \n
    • \n
    \n
    \n \n \n
    \n
    \u0420\u0430\u0437\u043C\u0435\u0440 \u0438\u0437\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F
    \n\n
      \n
    • \n \n \n
    • \n
    \n
    \n\n \n
    \n
    \u041E\u0442\u043C\u0435\u0447\u0430\u0442\u044C \u0441\u043A\u0430\u0447\u0435\u043D\u043D\u044B\u0435
    \n\n
      \n
    • \n \n \n
    • \n\n
    • \n \n \n
    • \n\n
    • \n \n
    • \n
    \n
    \n\n
    \n
    \n\n
    \n\n \n
    \n ").concat(icons.get('green', 'cog', false), "\n
    \n
    \n
    \n
    \n
    \u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438
    \n
    \n
    \n
    \n ") ); }