microwave/firefox/pages/panel/index.js

1059 lines
56 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use strict'
/**
* Страница настроек ВКонтакте
*/
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=ЗНАЧЕНИЕ)
*/
this.id = 'microwave';
/**
* Инициализация
*/
this.init = function () {
// Инициализация кнопки в боковом меню
this.button();
}
/**
* Инициализация кнопки в боковом меню
*/
this.button = function () {
if (document.getElementById('l_mw') instanceof HTMLElement) return;
// Инициализация оболочки кнопки
const li = document.createElement('li');
li.id = 'l_mw';
// Инициализация ссылки кнопки
const a = document.createElement('a');
a.classList.add('left_row');
a.href = '/settings?act=notify';
a.setAttribute('type', 'button');
a.addEventListener('click', this.generate, this);
// Инициализация иконки кнопки
const div = document.createElement('div');
div.classList.add('LeftMenu__icon');
// Инициализация svg иконки
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svg.setAttribute('fill', 'none');
svg.setAttribute('height', '20');
svg.setAttribute('viewBox', '0 0 20 20');
svg.setAttribute('width', '20');
svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
// Инициализация path для svg
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
path.setAttribute('clip-rule', 'evenodd');
path.setAttribute('d', 'M10 7.75a1.25 1.25 0 1 1 0-2.5 1.25 1.25 0 0 1 0 2.5zM7.25 6.5a2.75 2.75 0 1 1 5.5 0 2.75 2.75 0 0 1-5.5 0zm-.5 7.25c0-.42.23-.83.8-1.17A4.81 4.81 0 0 1 10 12c1.03 0 1.88.23 2.45.58.57.34.8.75.8 1.17 0 .3-.1.44-.22.54-.14.11-.4.21-.78.21h-4.5c-.39 0-.64-.1-.78-.21-.12-.1-.22-.25-.22-.54zM10 10.5c-1.22 0-2.37.27-3.23.8-.88.53-1.52 1.37-1.52 2.45 0 .7.28 1.3.78 1.71.48.39 1.1.54 1.72.54h4.5c.61 0 1.24-.15 1.72-.54.5-.4.78-1 .78-1.71 0-1.08-.64-1.92-1.52-2.45-.86-.53-2-.8-3.23-.8zm4-5.59c.06-.4.44-.7.85-.64a2.5 2.5 0 0 1-.35 4.98.75.75 0 0 1 0-1.5 1 1 0 0 0 .14-1.99.75.75 0 0 1-.63-.85zM15.76 10a.75.75 0 0 0 0 1.5c1.16 0 1.75.67 1.75 1.25 0 .22-.07.41-.19.55-.1.12-.24.2-.46.2a.75.75 0 0 0 0 1.5c1.43 0 2.15-1.21 2.15-2.25 0-1.71-1.6-2.75-3.25-2.75zM5 10.75a.75.75 0 0 0-.75-.75C2.61 10 1 11.04 1 12.75 1 13.79 1.72 15 3.15 15a.75.75 0 0 0 0-1.5.57.57 0 0 1-.47-.2.86.86 0 0 1-.18-.55c0-.58.6-1.25 1.75-1.25.41 0 .75-.34.75-.75zm.14-6.47a.75.75 0 0 1 .22 1.48 1 1 0 0 0 .14 1.99.75.75 0 1 1 0 1.5 2.5 2.5 0 0 1-.36-4.97z');
path.setAttribute('fill', 'currentColor');
path.setAttribute('fill-rule', 'evenodd');
// Инициализация текста кнопки
const text = document.createElement('span');
text.classList.add('left_label', 'inl_bl');
text.innerText = 'Микроволновка';
// Инициализация оболочки количества уведомлений
const notifications = document.createElement('span');
notifications.classList.add('left_count_wrap', 'fl_r', 'left_void');
// Инициализация текста количества уведомлений
const amount = document.createElement('span');
amount.classList.add('inl_bl', 'left_count_sign');
// Инициализация оболочки кнопки настроек
const settings = document.createElement('div');
settings.classList.add('left_settings');
settings.setAttribute('onclick', 'menuSettings(0)');
// Инициализация кнопки настроек
const button = document.createElement('div');
button.classList.add('left_settings_inner');
// Генерация архитектуры
settings.appendChild(button);
notifications.appendChild(amount);
svg.appendChild(path);
div.appendChild(svg);
a.appendChild(div);
a.appendChild(text);
a.appendChild(notifications);
li.appendChild(a);
li.appendChild(settings);
// Запись в документ
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
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(
'test2',
'settings',
panel.blocks.fields.text('asdasdasd', 'lightning', 'Активировать', 'asdasdasdasd', 'Тестирование всплывающей подсказки', 'text', 0, 8, 'фффф', 'сюда писать')
// panel.blocks.fields.button('account_key', 'friend', 'Аккаунт', 'Анонимный режим ограничивает возможности', 'Аутентификация через аккаунт ВКонтакте', 'dropdown', 'Будет сгенерирован ключ доступа ВКонтакте', 'Подключить', function () {
// alert('ура!');
// })
);
panel.blocks.generate(
'test',
'menu',
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, type = 'settings', ...functions) {
if (typeof id === 'string' && typeof type === 'string' && typeof functions === 'object') {
// Пройдена проверка входных параметров
// Инициализация названия идентификатора элемента
const name = 'block_' + id;
// Проверка на существование (защита от дубликатов)
if (document.getElementById(name) instanceof HTMLElement) return ++errors;
if (type === 'settings') {
// Блок: "настройки"
// Инициализация оболочки
let block = document.createElement('div');
block.id = name;
block.classList.add('page_block', 'clear_fix');
// Инициализация верхнего колонтинула
let header = document.createElement('h2');
header.classList.add('page_block_h2');
// Инициализация заголовка
let title = document.createElement('div');
title.classList.add('page_block_header');
title.innerText = id;
// Инициализация статуса
let status = document.createElement('div');
status.classList.add('page_block_saved');
status.innerText = 'Изменения сохранены';
// Инициализация оболочки содержимого
let main = document.createElement('div');
main.classList.add('settings_panel', 'clear_fix', 'settings_' + panel.id, 'settings_section_' + panel.id);
// Инициализация архитектуры
title.appendChild(status);
header.appendChild(title);
block.appendChild(header);
block.appendChild(main);
// Запись в документ
panel.body().appendChild(block);
} else if (type === 'menu') {
// Блок: "меню"
// Инициализация оболочки
const block = document.createElement('div');
block.id = name;
block.classList.add('GamesCatalogHead', 'page_block');
// Запись в документ
panel.body().appendChild(block);
} else return ++errors;
// Инициализация счётчика ошибок
let errors = 0;
functions.forEach(function (entry) {
// Перебор переданных функций
// Вызов функции
if (typeof entry === 'function' && !entry(id, type)) ++errors;
});
return errors;
}
},
/**
* Запись верхнего колонтинула оболочки в формате меню
*
* @return {Function} Функция для выполнения в генераторе группы
*/
menu() {
/**
* Запись в группу (подразумевается выполнение в функции генерирующей группу)
*
* @param {string} group Группа
* @param {string} type Тип группы
*
* @return {bool} Статус выполнения
*/
return function (group, type = 'menu') {
if (typeof group === 'string' && type === 'menu') {
// Пройдена проверка входных параметров
// Инициализация блока куда надо записать заголовок
const block = document.getElementById('block_' + group);
// Инициализация верхнего колонтинула
const header = document.createElement('h2');
header.classList.add('page_block_h2');
// Инициализация меню
const menu = document.createElement('ul');
menu.id = 'block_' + group + '_menu';
menu.classList.add('ui_tabs', 'clear_fix', 'ui_tabs_header', 'GamesCatalogNav');
// Инициализация баланса
const money = document.createElement('a');
money.classList.add('GamesCatalogNav__balanceLink');
money.innerText = 'Баланс: 0 рублей';
// Инициализация ползунка
const slider = document.createElement('div');
slider.classList.add('ui_tabs_slider', '_ui_tabs_slider');
// Запись в документ
menu.appendChild(money);
menu.appendChild(slider);
header.appendChild(menu);
block.appendChild(header);
return true;
}
return false;
};
},
/**
* Запись верхнего колонтинула оболочки
*
* @param {string} text Название вкладки
* @param {Function} onclick Событие при нажатии на кнопку открытия вкладки
*
* @return {Function} Функция для выполнения в генераторе группы
*/
tab(text = '', onclick) {
/**
* Запись в группу (подразумевается выполнение в функции генерирующей группу)
*
* @param {string} group Группа
* @param {string} type Тип группы
*
* @return {bool} Статус выполнения
*/
return function (group, type = 'menu') {
if (typeof group === 'string' && type === 'menu' && typeof text === 'string' && typeof onclick === 'function') {
// Пройдена проверка входных параметров
// Инициализация блока куда надо записать заголовок
const menu = document.getElementById('block_' + group + '_menu');
if (menu instanceof HTMLElement) {
// Найдено меню
// Инициализация кнопки
const button = document.createElement('li');
button.classList.add('games_tab_catalog');
// Инициализация меню
const link = document.createElement('a');
link.classList.add('ui_tab', 'ui_tab_sel');
link.setAttribute('type', 'button');
link.innerText = text ?? 'Без названия';
link.addEventListener('click', onclick);
// Запись в документ
button.appendChild(link);
// Инициализация списка вкладок
const list = menu.getElementsByTagName('li');
// Запись кнопки после других, либо запись первой кнопки
if (list instanceof HTMLCollection && list.length > 0) list[list.length - 1].insertAdjacentElement('afterend', button);
else menu.insertAdjacentElement('afterbegin', button);
return true;
}
}
return false;
};
},
/**
* Поля
*/
fields: {
macroses: {
/**
* Шаблон для инициализации элемента-строки
*
* @param {string} group Группа
* @param {string} type Тип группы
* @param {string|null} icon Иконка
* @param {function} content Функция которая будет обрабатывать содержимое макроса
*
* @return {mixed} Результат работы content()
*/
row(group, type = 'settings', icon, content) {
// Инициализация блока
const block = document.getElementById('block_' + group);
// Инициализация головного элемента оболочки для содержимого, и элемента со статусом
let header, main, status;
if (type === 'settings') {
// Блок: "настройки"
// Запись головного элемента блока
header = block.getElementsByClassName('page_block_header')[0];
// Запись оболочки для содержимого блока
main = block.getElementsByClassName('settings_panel clear_fix settings_' + panel.id + ' settings_section_' + panel.id)[0];
// Запись элемента со статусом
status = header.getElementsByClassName('page_block_saved')[0];
} else if (type === 'menu') {
// Блок: "меню"
// Запись головного элемента блока
header = block.getElementsByClassName('page_block_h2')[0];
// Запись оболочки для содержимого блока
main = block.getElementsByClassName('settings_panel')[0];
if (typeof main === 'undefined' && header instanceof HTMLElement) {
// Не найдена оболочка для содержимого блока
// Инициализация элемента-оболочки для содержимого блока
const element = document.createElement('div');
element.classList.add('settings_panel');
// Запись в документ
header.insertAdjacentElement('afterend', element);
// Запись тела содержимого блока
main = element;
}
}
// Инициализация оболочки строки
const wrap = document.createElement('div');
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, main, wrap, separator);
},
dropdown(active, rows) {
if (typeof active === 'string' && typeof rows === 'object') {
// Пройдена проверка входных параметров
// Инициализация оболочки
const wrap = document.createElement('div');
wrap.classList.add('privacy_dropdown', 'privacy_dropdown_mail', 'pdd_ralign');
wrap.setAttribute('style', 'opacity: 1; display: none;');
// Инициализация списка строк
const list = document.createElement('div');
list.classList.add('rows', 'rows__flex');
wrap.setAttribute('style', 'font-size: 13px;');
// Инициализация головной строки
const header = document.createElement('div');
header.classList.add('header');
wrap.setAttribute('onclick', 'Privacy.hide(-1)');
// Инициализация активной строки (выбранного параметра)
const active = document.createElement('div');
active.classList.add('header_label');
active.innerHTML = active;
// Инициализация основной группы строк
const body = document.createElement('div');
body.classList.add('body', 'body__flex');
body.setAttribute('role', 'list');
body.setAttribute('aria-labelledby', 'privacy_who_can_view');
for (const row in rows) {
// Перебор строк для генерации списка
// Инициализация кнопки
const button = document.createElement('button');
}
}
return null;
}
},
/**
* Генерация HTML-элемента настройки с кнопкой активации
*
* @param {string} id Идентификатор
* @param {string|null} icon Иконка
* @param {string|null} name Название
* @param {string|null} description Описание
* @param {string|null} hint Всплывающая подсказка (иконка с вопросительным знаком возле верхнего колонтинула)
* @param {string|null} onchange Код который выполняется после изменения состояния
*
* @return {function} Функция для выполнения в генераторе группы
*
* @todo 1. Добавить проверку на существование нижнего колонтинула и записывать перед ним, вместо конца блока
*/
checkbox(id, icon, name, description, hint, onchange) {
/**
* Запись в группу (подразумевается выполнение в функции генерирующей группу)
*
* @param {string} group Группа
* @param {string} type Тип группы
*
* @return {bool} Статус выполнения
*/
return function (group, type = 'settings') {
if (typeof id === 'string' && typeof group === 'string') {
// Пройдена проверка входных параметров
return panel.blocks.fields.macros(group, icon,
function (status, body, wrap, separator) {
wrap.addEventListener("click", fn => {
// Инициализация кнопки
const button = wrap.getElementsByClassName('ui_toggler')[0];
if (button.classList.contains('on')) {
// Активирована
if (settings.write(group + '_' + id, false)) {
// Записан статус активации
// Запуск анимации и переход в состояние деактивации
button.classList.remove('on');
settings.read(group + '_' + id).then(result => {
if (result === false) {
// Сохранены изменения
// Запуск анимации
status.style.transition = '0.5s';
status.style.opacity = 1;
setTimeout(fn => {
status.style.transition = '1.5s';
status.style.opacity = 0;
}, 1000);
}
});
}
} else {
// Деактивирована
if (settings.write(group + '_' + id, true)) {
// Записан статус активации
// Запуск анимации и переход в состояние активации
button.classList.add('on');
settings.read(group + '_' + id).then(result => {
if (result === true) {
// Сохранены изменения
// Запуск анимации
status.style.transition = '0.5s';
status.style.opacity = 1;
setTimeout(fn => {
status.style.transition = '1.5s';
status.style.opacity = 0;
}, 1000);
}
});
}
}
});
// Инициализация кнопки активации
const button = document.createElement('div');
button.classList.add('ui_toggler_wrap');
// Инициализация элемента-иконки
const checkbox = document.createElement('div');
checkbox.classList.add('_ui_toggler', 'ui_toggler', '_settings_ienable');
if (typeof onchange === 'string') checkbox.setAttribute('onchange', onchange);
settings.read(group + '_' + id).then(result => {
// Получены данные о значении настройки
// Запись состояния
if (result) checkbox.classList.add('on');
});
// Инициализация элемента-иконки
const label = document.createElement('div');
label.classList.add('ui_toggler_label');
// Инициализация названия
const header = document.createElement('div');
header.classList.add('settings_separated_row_text');
// Инициализация текста названия
const colonic = document.createElement('div');
colonic.classList.add('settings_separated_row_text_inner');
colonic.innerText = name !== undefined && typeof name === 'string' ? name : id;
// Инициализация архитектуры
button.appendChild(checkbox);
separator.appendChild(button);
wrap.appendChild(separator);
header.appendChild(colonic);
if (typeof hint === 'string') {
// Получена подсказка
// Инициализация текста-подсказки
const question = document.createElement('span');
question.classList.add('hint_icon');
question.setAttribute('data-title', hint);
question.setAttribute('onmouseover', 'showHint(this);');
// Инициализация архитектуры
colonic.appendChild(question);
}
if (description !== undefined && typeof description === 'string') {
// Получено описание
// Инициализация текста описания
const text = document.createElement('div');
text.classList.add('settings_separated_row_hint');
text.innerText = description;
// Инициализация архитектуры
colonic.appendChild(text);
}
// Инициализация архитектуры
wrap.appendChild(header);
// Запись в блок
body.appendChild(wrap);
return true;
}
);
}
return false;
};
},
/**
* Генерация HTML-элемента настройки с полем для ввода текста
*
* @param {string} id Идентификатор
* @param {string|null} icon Иконка
* @param {string|null} name Название
* @param {string|null} description Описание
* @param {string|null} hint Всплывающая подсказка (иконка с вопросительным знаком возле верхнего колонтинула)
* @param {string|null} field Тип поля для ввода (HTML-категории: text, password, email, number)
* @param {number|null} min Ограничение по минимальному количеству символов
* @param {number|null} max Ограничение по максимальному количеству символов
* @param {string|null} title Текст выводимый во всплывающем окне при наведении курсора
* @param {string|null} placeholder Текст отображаемый в поле для ввода если оно пустое
* @param {string|null} pattern Шаблон значений которые позволено вводить в поле
* @param {boolean|null} readonly Запретить редактирование
* @param {boolean|null} spellcheck Использовать проверку орфографии
* @param {object|null} options Массив со строками для автозаполнения поля
* @param {string|null} onchange Код который выполняется после изменения состояния
* @param {string|null} oninput Код который выполняется при вводе текста
*
* @return {function} Функция для выполнения в генераторе группы
*
* @todo 1. Добавить проверку на существование нижнего колонтинула и записывать перед ним, вместо конца блока
*/
text(id, icon, name, description, hint, field = 'text', min = 0, max = 100, title, placeholder, pattern, readonly, spellcheck, options, onchange, oninput) {
/**
* Запись в группу (подразумевается выполнение в функции генерирующей группу)
*
* @param {string} group Группа
* @param {string} type Тип группы
*
* @return {bool} Статус выполнения
*/
return function (group, type = 'settings') {
if (typeof id === 'string' && typeof icon === 'string' && typeof group === 'string') {
// Пройдена проверка входных параметров
return panel.blocks.fields.macroses.row(group, type, icon,
function (status, body, wrap, separator) {
if (type === 'settings') wrap.addEventListener("input", fn => {
// Инициализация поля ввода
const input = wrap.getElementsByTagName('input')[0];
if (settings.write(group + '_' + id, input.value)) {
// Записано значение поля
// Запуск анимации
settings.read(group + '_' + id).then(result => {
if (result === input.value) {
// Сохранены изменения
// Запуск анимации
status.style.transition = '0.5s';
status.style.opacity = 1;
setTimeout(fn => {
status.style.transition = '1.5s';
status.style.opacity = 0;
}, 1000);
}
});
}
});
// Инициализация элемента для ввода текста
const input = document.createElement('input');
input.classList.add('dark');
input.setAttribute('type', field);
input.setAttribute(field === 'number' ? 'min' : 'minlength', min);
input.setAttribute(field === 'number' ? 'max' : 'maxlength', max);
if (typeof title === 'string') input.setAttribute('title', title);
if (typeof placeholder === 'string') input.setAttribute('placeholder', placeholder);
if (typeof pattern === 'string') input.setAttribute('pattern', pattern);
if (readonly === true) input.setAttribute('readonly', readonly);
if (spellcheck === true) input.setAttribute('spellcheck', spellcheck);
input.setAttribute('list', group + '_' + id + '_datalist');
settings.read(group + '_' + id).then(result => {
// Получены данные о значении настройки
// Запись значения в поле
if (result) input.value = result;
});
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');
datalist.id = group + '_' + id + '_datalist';
for (const option of options) {
// Перебор значений для автозаполнения поля
// Инициализация элемента со значением автозаполнения
const element = document.createElement('option');
element.setAttribute('value', option);
// Запись в список
datalist.appendChild(element);
}
}
// Инициализация элемента-иконки
const label = document.createElement('div');
label.classList.add('ui_toggler_label');
// Инициализация названия
const header = document.createElement('div');
header.classList.add('settings_separated_row_text');
// Инициализация текста названия
const colonic = document.createElement('div');
colonic.classList.add('settings_separated_row_text_inner');
colonic.innerText = name !== undefined && typeof name === 'string' ? name : id;
// Инициализация архитектуры
separator.appendChild(input);
if (typeof datalist === 'object') separator.appendChild(datalist);
wrap.appendChild(separator);
header.appendChild(colonic);
if (typeof hint === 'string') {
// Получена подсказка
// Инициализация текста-подсказки
const question = document.createElement('span');
question.classList.add('hint_icon');
question.setAttribute('data-title', hint);
question.setAttribute('onmouseover', 'showHint(this);');
// Инициализация архитектуры
colonic.appendChild(question);
}
if (description !== undefined && typeof description === 'string') {
// Получено описание
// Инициализация текста описания
const text = document.createElement('div');
text.classList.add('settings_separated_row_hint');
text.innerText = description;
// Инициализация архитектуры
colonic.appendChild(text);
}
// Инициализация архитектуры
wrap.appendChild(header);
// Запись в блок
body.appendChild(wrap);
return true;
}
);
}
return false;
};
},
/**
* Генерация HTML-элемента настройки с всплывающим списком
*
* @param {string} id Идентификатор
* @param {string|null} icon Иконка
* @param {string|null} name Название
* @param {string|null} description Описание
* @param {string|null} hint Всплывающая подсказка (иконка с вопросительным знаком возле верхнего колонтинула)
* @param {string|null} type
* @param {string|null} button
* @param {object|null} options Массив со строками для автозаполнения поля
* @param {string|null} onclick
* @param {string|null} onchange Код который выполняется после изменения состояния
* @param {string|null} oninput Код который выполняется при вводе текста
*
* @return {function} Функция для выполнения в генераторе группы
*
* @todo 1. Добавить проверку на существование нижнего колонтинула и записывать перед ним, вместо конца блока
*/
button(id, icon, name, description, hint, type = 'dropdown', title, value = 'Выбрать', onclick, onchange, oninput) {
/**
* Запись в группу (подразумевается выполнение в функции генерирующей группу)
*
* @param {string} group Группа
*
* @return {bool} Статус выполнения
*/
return function (group) {
if (typeof id === 'string' && typeof icon === 'string' && typeof group === 'string') {
// Пройдена проверка входных параметров
return panel.blocks.fields.macroses.row(group, icon,
function (status, body, wrap, separator) {
wrap.addEventListener("input", fn => {
// Инициализация поля ввода
const input = wrap.getElementsByTagName('input')[0];
if (settings.write(group + '_' + id, input.value)) {
// Записано значение поля
// Запуск анимации
settings.read(group + '_' + id).then(result => {
if (result === input.value) {
// Сохранены изменения
// Запуск анимации
status.style.transition = '0.5s';
status.style.opacity = 1;
setTimeout(fn => {
status.style.transition = '1.5s';
status.style.opacity = 0;
}, 1000);
}
});
}
});
// Инициализация элемента-кнопки
const button = document.createElement('a');
button.innerText = value;
if (typeof onchange === 'string') button.setAttribute('onchange', onchange);
if (typeof oninput === 'string') button.setAttribute('oninput', oninput);
if (type === 'dropdown') {
// Инициализация всплывающего списка
// Инициализация элемента-кнопки
button.setAttribute('onclick', 'return Privacy.show(this, event, \'mail\');' + typeof onclick === 'string' ? ' ' + onclick : '');
// Инициализация элемента-списка
const dropdown = panel.blocks.fields.macroses.dropdown();
// Инициализация архитектуры
separator.appendChild(button);
} else if (type === 'popup') {
// Инициализация всплывающего окна
// Инициализация элемента-кнопки
button.setAttribute('href', '#');
button.setAttribute('onclick', 'return Settings.showGroupMessagesNotifyBox(event, \'settings\');' + typeof onclick === 'string' ? ' ' + onclick : '');
// Инициализация архитектуры
separator.appendChild(button);
} else if (type === 'button') {
// Инициализация кнопки
// Инициализация элемента-кнопки
if (typeof onclick === 'string') button.setAttribute('onclick', onclick);
// Инициализация архитектуры
separator.appendChild(button);
}
// Инициализация элемента-иконки
const label = document.createElement('div');
label.classList.add('ui_toggler_label');
// Инициализация названия
const header = document.createElement('div');
header.classList.add('settings_separated_row_text');
// Инициализация текста названия
const colonic = document.createElement('div');
colonic.classList.add('settings_separated_row_text_inner');
colonic.innerText = name !== undefined && typeof name === 'string' ? name : id;
// Инициализация архитектуры
separator.appendChild(button);
wrap.appendChild(separator);
header.appendChild(colonic);
if (typeof hint === 'string') {
// Получена подсказка
// Инициализация текста-подсказки
const question = document.createElement('span');
question.classList.add('hint_icon');
question.setAttribute('data-title', hint);
question.setAttribute('onmouseover', 'showHint(this);');
// Инициализация архитектуры
colonic.appendChild(question);
}
if (description !== undefined && typeof description === 'string') {
// Получено описание
// Инициализация текста описания
const text = document.createElement('div');
text.classList.add('settings_separated_row_hint');
text.innerText = description;
// Инициализация архитектуры
colonic.appendChild(text);
}
// Инициализация архитектуры
wrap.appendChild(header);
// Запись в блок
body.appendChild(wrap);
return true;
}
);
}
return false;
};
}
}
}
/**
* Найти оболочку
*
* @return {HTMLElement} Оболочка
*/
static body() {
return document.getElementById('wrap3');
}
/**
* Найти боковое меню
*
* @returns {HTMLElement} Меню
*/
static menu() {
return document.getElementById('side_bar_inner');
}
/**
* Очистка оболочки от HTML-элементов ВКонтакте
*/
static clean() {
// Инициализация тела оболочки
let main = panel.body();
// Очистка тела оболочки
main.innerHTML = null;
}
}
// Запуск выполнения
new panel().init();