diff --git a/firefox/pages/panel/index.js b/firefox/pages/panel/index.js index 4e95b3f..61fc2c7 100644 --- a/firefox/pages/panel/index.js +++ b/firefox/pages/panel/index.js @@ -4,6 +4,56 @@ * Страница настроек ВКонтакте */ class panel { + + /** + * Иконки ВКонтакте для полей + */ + static icons = { + lightning: 'icon_type_ienable', + sound: 'icon_type_isounds', + text: 'icon_type_itexts', + bell: 'icon_type_notification', + group: 'icon_type_group_messages ', + message: 'icon_type_message', + reminder: 'icon_type_message_reminders', + like: 'icon_type_like', + repost: 'icon_type_repost', + comment: 'icon_type_comment', + discussion: 'icon_type_discussions', + wall: 'icon_type_wall', + reply: 'icon_type_story_reply', + question: 'icon_type_story_question', + voting: 'icon_type_voting', + clips: 'icon_type_clips', + mention: 'icon_type_mention', + follow: 'icon_type_follow', + friend: 'icon_type_friend_found', + invite: 'icon_type_invite_group', + tag: 'icon_type_photo_tag', + birthday: 'icon_type_birthday', + event: 'icon_type_event', + group: 'icon_type_group', + promo: 'icon_type_feed_promo', + advice: 'icon_type_advice', + post: 'icon_type_new_post', + private: 'icon_type_private_post', + gift: 'icon_type_gift', + app: 'icon_type_invite_app', + live: 'icon_type_live', + playlists: 'icon_type_video_playlists', + podcast: 'icon_type_podcast', + ads: 'icon_type_ads', + achievements: 'icon_type_content_achievements', + services: 'icon_type_services', + installation: 'icon_type_service_installation', + bookmarks: 'icon_type_bookmarks', + box: 'icon_type_market_orders', + announcement: 'icon_type_tear_off_flyer_fill_blue', + hearts: 'icon_type_hearts_2_circle_fill_twilight', + email: 'icon_type_email', + clock: 'icon_type_clock' + }; + constructor() { /** * Идентификатор (https://vk.com/settings?act=ЗНАЧЕНИЕ) @@ -18,50 +68,6 @@ class panel { this.button(); } - /** - * Сгенерировать панель управления - * - * Рекурсивно проверяет открытие страницы "Игры" - * - * @return {bool} Метод выполнен без ошибок? - */ - this.generate = function () { - // Генерация уникального идентификатора для элемента загрузки - const id = Math.random().toString(36).replace(/[^A-z]+ /g, '').slice(2); - - // Инициализация элемента загрузки (пока что просто проверочный) - const loading = document.createElement('div'); - loading.id = id; - loading.style.display = 'none'; - - // Запись в документ - panel.body().appendChild(loading); - - function check(iterator = 0) { - // Инициализация оболочки страницы "Игры" - - if (window.location.pathname === '/apps' && !(document.getElementById(id) instanceof HTMLElement)) { - // Загружена страница "Игры" (или перезагружена) - - // Инициализация страницы - panel.clean(); - - panel.blocks.group( - 'test', - panel.blocks.menu(), - panel.blocks.tab('Тест', function () { alert('хихи') }) - ); - - return true; - } - else if (iterator > 300) return false; - else setTimeout(check, 100, ++iterator); - } - - // Запуск проверки - check(); - } - /** * Инициализация кнопки в боковом меню */ @@ -70,13 +76,13 @@ class panel { // Инициализация оболочки кнопки const li = document.createElement('li'); - li.id = 'l_mw' + li.id = 'l_mw'; // Инициализация ссылки кнопки const a = document.createElement('a'); a.classList.add('left_row'); + a.href = '/settings?act=notify'; a.setAttribute('type', 'button'); - a.setAttribute('onclick', "return nav.go(document.getElementById('l_ap').firstElementChild, event, { noback: true, params: { _ref: 'left_nav' } });"); a.addEventListener('click', this.generate, this); // Инициализация иконки кнопки @@ -134,13 +140,164 @@ class panel { // Запись в документ panel.menu().getElementsByClassName('more_div l_main')[0].insertAdjacentElement('beforebegin', li); } + + /** + * Сгенерировать панель управления + * + * Рекурсивно проверяет открытие страницы "Игры" + * + * @return {bool} Метод выполнен без ошибок? + */ + this.generate = function () { + // Генерация уникального идентификатора для загрузки первой страницы + const first = Math.random().toString(36).replace(/[^A-z]+ /g, '').slice(2); + + // Инициализация элемента загрузки (пока что просто проверочный) + const loading = document.createElement('div'); + loading.id = first; + loading.style.display = 'none'; + + // Запись в документ + document.getElementById('wrap3').appendChild(loading); + + // Генерация уникального идентификатора для элемента загрузки страницы "Игры" + const games = Math.random().toString(36).replace(/[^A-z]+ /g, '').slice(2); + + // Инициализация элемента загрузки (пока что просто проверочный) + const script = document.createElement('script'); + script.textContent = ` + // Инициализация кнопки\r + button = document.getElementById('l_mw'); + + if (button instanceof HTMLElement) { + // Найдена кнопка\r + + // Переход на страницу \"Настройка уведомлений\" для получения CSS\r + button.id = 'ui_rmenu_notifications'; + nav.go(button.firstElementChild); + + // Генерация уникального идентификатора для элемента загрузки\r + const id = Math.random().toString(36).replace(/[^A-z]+ /g, '').slice(2); + + // Инициализация элемента загрузки (пока что просто проверочный)\r + const loading = document.createElement('div'); + loading.id = id; + loading.style.display = 'none'; + + // Запись в документ\r + document.getElementById('wrap3').appendChild(loading); + + function check(iterator = 0) { + // Инициализация оболочки страницы "Игры"\r + + console.log(window.location.pathname === '/settings', !(document.getElementById(id) instanceof HTMLElement)); + + if (window.location.pathname === '/settings' && !(document.getElementById(id) instanceof HTMLElement)) { + // Загружена страница "Игры" (или перезагружена)\r + + // Инициализация элемента загрузки (пока что просто проверочный)\r + const loading = document.createElement('div'); + loading.id = '${games}'; + loading.style.display = 'none'; + + // Запись в документ\r + document.getElementById('wrap3').appendChild(loading); + + // Переход на страницу \"Игры\" для получения CSS\r + button.id = 'l_mw'; + nav.go(document.getElementById('l_ap').firstElementChild, null, { noback: true, params: { _ref: 'left_nav' } }); + + return true; + } + else if (iterator > 300) return false; + else setTimeout(check, 100, ++iterator); + } + + // Запуск проверки\r + check(); + } + `; + + // Запись в документ + panel.body().appendChild(script); + + function check(iterator = 0) { + // Инициализация оболочки страницы "Игры" + + if (window.location.pathname === '/apps' && !(document.getElementById(games) instanceof HTMLElement) && !(document.getElementById(first) instanceof HTMLElement)) { + // Загружена страница "Игры" (или перезагружена) + + // Инициализация страницы + panel.clean(); + + panel.blocks.generate( + 'test', + panel.blocks.menu(), + panel.blocks.tab('Тест', function () { alert('хихи') }), + panel.blocks.fields.text('asdasdasd', 'lightning', 'Активировать', 'asdasdasdasd', 'Тестирование всплывающей подсказки', 'text', 0, 8, 'фффф', 'сюда писать') + ); + + panel.blocks.generate( + 'test2', + panel.blocks.menu(), + panel.blocks.tab('Тест', function () { alert('хихи') }), + panel.blocks.fields.text('asdasdasd', 'lightning', 'Активировать', 'asdasdasdasd', 'Тестирование всплывающей подсказки', 'text', 0, 8, 'фффф', 'сюда писать') + ); + + return true; + } + else if (iterator > 300) return false; + else setTimeout(check, 100, ++iterator); + } + + // Запуск проверки + check(); + } } - - /** * Блоки */ static blocks = { + /** + * Генерация HTML-элемента-оболочки + * + * @param {string} id Идентификатор + * @param {...function} functions Содержимое + * + * @return {integer} Количество ошибок + */ + generate(id, ...functions) { + if (typeof id === 'string' && typeof functions === 'object') { + // Пройдена проверка входных параметров + + // Инициализация названия идентификатора элемента + const name = 'block_' + id; + + // Поиск блока с данным идентификатором + if (document.getElementById(name) instanceof HTMLElement) return errors; + + // Инициализация оболочки + const block = document.createElement('div'); + block.id = name; + block.classList.add('GamesCatalogHead', 'page_block'); + + // Запись в документ + panel.body().appendChild(block); + + // Инициализация счётчика ошибок + let errors = 0; + + functions.forEach(function (entry) { + // Перебор переданных функций + + // Вызов функции + if (typeof entry === 'function' && !entry(id)) ++errors; + }); + + return errors; + } + }, + /** * Запись верхнего колонтинула оболочки в формате меню * @@ -247,46 +404,6 @@ class panel { }; }, - /** - * Генерация HTML-элемента-оболочки - * - * @param {string} id Идентификатор - * @param {...function} functions Содержимое - * - * @return {integer} Количество ошибок - */ - group(id, ...functions) { - if (typeof id === 'string' && typeof functions === 'object') { - // Пройдена проверка входных параметров - - // Инициализация названия идентификатора элемента - const name = 'block_' + id; - - // Поиск блока с данным идентификатором - if (document.getElementById(name) instanceof HTMLElement) return errors; - - // Инициализация оболочки - const block = document.createElement('div'); - block.id = name; - block.classList.add('GamesCatalogHead', 'page_block'); - - // Запись в документ - panel.body().appendChild(block); - - // Инициализация счётчика ошибок - let errors = 0; - - functions.forEach(function (entry) { - // Перебор переданных функций - - // Вызов функции - if (typeof entry === 'function' && !entry(id)) ++errors; - }); - - return errors; - } - }, - /** * Поля */ @@ -303,25 +420,38 @@ class panel { // Инициализация блока const block = document.getElementById('block_' + group); - // Инициализация головного элемента блока - const header = block.getElementsByClassName('page_block_header')[0]; + // Инициализация оболочки для содержимого блока + let body = block.getElementsByClassName('settings_panel')[0]; - // Инициализация элемента со статусом - const status = header.getElementsByClassName('page_block_saved')[0]; + if (typeof body === 'undefined') { + // Не найдена оболочка для содержимого блока - // Инициализация тела блока - const body = block.getElementsByClassName('settings_panel clear_fix settings_' + this.core.id + ' settings_section_' + this.core.id)[0]; + // Инициализация верхнего колонтинула блока (подразумевается) + const head = block.getElementsByClassName('page_block_h2')[0]; - // Инициализация оболочки кнопки активации + if (head instanceof HTMLElement) { + // Инициализация элемента-оболочки для содержимого блока + const element = document.createElement('div'); + element.classList.add('settings_panel'); + + // Запись в документ + head.insertAdjacentElement('afterend', element); + + // Запись тела содержимого блока + body = element; + } + } + + // Инициализация оболочки строки const wrap = document.createElement('div'); - wrap.classList.add('settings_separated_row', this.core.icons[icon] ?? this.core.icons['lightning'], 'settings_separated_row_iconed'); + wrap.classList.add('settings_separated_row', panel.icons[icon] ?? panel.icons['lightning'], 'settings_separated_row_iconed'); // Инициализация разделителя const separator = document.createElement('div'); separator.classList.add('settings_separated_row_extra'); // Генерация содержимого строки - return content(status, body, wrap, separator); + return content(body, wrap, separator); }, dropdown(active, rows) { @@ -381,9 +511,6 @@ class panel { * @todo 1. Добавить проверку на существование нижнего колонтинула и записывать перед ним, вместо конца блока */ checkbox(id, icon, name, description, hint, onchange) { - // Инициализация ядра - const core = this.core; - /** * Запись в группу (подразумевается выполнение в функции генерирующей группу) * @@ -392,10 +519,10 @@ class panel { * @return {bool} Статус выполнения */ return function (group) { - if (typeof id === 'string' && typeof core === 'object' && typeof group === 'string') { + if (typeof id === 'string' && typeof group === 'string') { // Пройдена проверка входных параметров - return core.blocks.fields.macros(group, icon, + return panel.blocks.fields.macros(group, icon, function (status, body, wrap, separator) { wrap.addEventListener("click", fn => { // Инициализация кнопки @@ -548,9 +675,6 @@ class panel { * @todo 1. Добавить проверку на существование нижнего колонтинула и записывать перед ним, вместо конца блока */ text(id, icon, name, description, hint, type = 'text', min = 0, max = 100, title, placeholder, pattern, readonly, spellcheck, options, onchange, oninput) { - // Инициализация ядра - const core = this.core; - /** * Запись в группу (подразумевается выполнение в функции генерирующей группу) * @@ -559,11 +683,11 @@ class panel { * @return {bool} Статус выполнения */ return function (group) { - if (typeof id === 'string' && typeof icon === 'string' && typeof core === 'object' && typeof group === 'string') { + if (typeof id === 'string' && typeof icon === 'string' && typeof group === 'string') { // Пройдена проверка входных параметров - return core.blocks.fields.macros(group, icon, - function (status, body, wrap, separator) { + return panel.blocks.fields.macroses.row(group, icon, + function (body, wrap, separator) { wrap.addEventListener("input", fn => { // Инициализация поля ввода const input = wrap.getElementsByTagName('input')[0]; @@ -609,7 +733,6 @@ class panel { if (typeof onchange === 'string') input.setAttribute('onchange', onchange); if (typeof oninput === 'string') input.setAttribute('oninput', oninput); - if (typeof options === 'object' && options.length > 0) { // Инициализация элемента-списка для выбора значений автозаполнения const datalist = document.createElement('datalist'); @@ -706,9 +829,6 @@ class panel { * @todo 1. Добавить проверку на существование нижнего колонтинула и записывать перед ним, вместо конца блока */ button(id, icon, name, description, hint, type = 'dropdown', value = 'Выбрать', onclick, onchange, oninput) { - // Инициализация ядра - const core = this.core; - /** * Запись в группу (подразумевается выполнение в функции генерирующей группу) * @@ -717,10 +837,10 @@ class panel { * @return {bool} Статус выполнения */ return function (group) { - if (typeof id === 'string' && typeof icon === 'string' && typeof core === 'object' && typeof group === 'string') { + if (typeof id === 'string' && typeof icon === 'string' && typeof group === 'string') { // Пройдена проверка входных параметров - return core.blocks.fields.macroses.row(group, icon, + return panel.blocks.fields.macroses.row(group, icon, function (status, body, wrap, separator) { wrap.addEventListener("input", fn => { // Инициализация поля ввода @@ -759,7 +879,8 @@ class panel { button.setAttribute('onclick', 'return Privacy.show(this, event, \'mail\');' + typeof onclick === 'string' ? ' ' + onclick : ''); // Инициализация элемента-списка - const dropdown = core.blocks.fields.macroses.dropdown(); + const dropdown = panel.blocks.fields.macroses.dropdown(); + // Инициализация архитектуры