Compare commits

..

3 Commits

View File

@ -4,6 +4,56 @@
* Страница настроек ВКонтакте * Страница настроек ВКонтакте
*/ */
class panel { 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() { constructor() {
/** /**
* Идентификатор (https://vk.com/settings?act=ЗНАЧЕНИЕ) * Идентификатор (https://vk.com/settings?act=ЗНАЧЕНИЕ)
@ -18,50 +68,6 @@ class panel {
this.button(); 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'); const li = document.createElement('li');
li.id = 'l_mw' li.id = 'l_mw';
// Инициализация ссылки кнопки // Инициализация ссылки кнопки
const a = document.createElement('a'); const a = document.createElement('a');
a.classList.add('left_row'); a.classList.add('left_row');
a.href = '/settings?act=notify';
a.setAttribute('type', 'button'); 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); a.addEventListener('click', this.generate, this);
// Инициализация иконки кнопки // Инициализация иконки кнопки
@ -134,13 +140,164 @@ class panel {
// Запись в документ // Запись в документ
panel.menu().getElementsByClassName('more_div l_main')[0].insertAdjacentElement('beforebegin', li); 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 = { 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 block = document.getElementById('block_' + group);
// Инициализация головного элемента блока // Инициализация оболочки для содержимого блока
const header = block.getElementsByClassName('page_block_header')[0]; let body = block.getElementsByClassName('settings_panel')[0];
// Инициализация элемента со статусом if (typeof body === 'undefined') {
const status = header.getElementsByClassName('page_block_saved')[0]; // Не найдена оболочка для содержимого блока
// Инициализация тела блока // Инициализация верхнего колонтинула блока (подразумевается)
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'); 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'); const separator = document.createElement('div');
separator.classList.add('settings_separated_row_extra'); separator.classList.add('settings_separated_row_extra');
// Генерация содержимого строки // Генерация содержимого строки
return content(status, body, wrap, separator); return content(body, wrap, separator);
}, },
dropdown(active, rows) { dropdown(active, rows) {
@ -381,9 +511,6 @@ class panel {
* @todo 1. Добавить проверку на существование нижнего колонтинула и записывать перед ним, вместо конца блока * @todo 1. Добавить проверку на существование нижнего колонтинула и записывать перед ним, вместо конца блока
*/ */
checkbox(id, icon, name, description, hint, onchange) { checkbox(id, icon, name, description, hint, onchange) {
// Инициализация ядра
const core = this.core;
/** /**
* Запись в группу (подразумевается выполнение в функции генерирующей группу) * Запись в группу (подразумевается выполнение в функции генерирующей группу)
* *
@ -392,10 +519,10 @@ class panel {
* @return {bool} Статус выполнения * @return {bool} Статус выполнения
*/ */
return function (group) { 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) { function (status, body, wrap, separator) {
wrap.addEventListener("click", fn => { wrap.addEventListener("click", fn => {
// Инициализация кнопки // Инициализация кнопки
@ -548,9 +675,6 @@ class panel {
* @todo 1. Добавить проверку на существование нижнего колонтинула и записывать перед ним, вместо конца блока * @todo 1. Добавить проверку на существование нижнего колонтинула и записывать перед ним, вместо конца блока
*/ */
text(id, icon, name, description, hint, type = 'text', min = 0, max = 100, title, placeholder, pattern, readonly, spellcheck, options, onchange, oninput) { 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 {bool} Статус выполнения
*/ */
return function (group) { 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, return panel.blocks.fields.macroses.row(group, icon,
function (status, body, wrap, separator) { function (body, wrap, separator) {
wrap.addEventListener("input", fn => { wrap.addEventListener("input", fn => {
// Инициализация поля ввода // Инициализация поля ввода
const input = wrap.getElementsByTagName('input')[0]; const input = wrap.getElementsByTagName('input')[0];
@ -609,7 +733,6 @@ class panel {
if (typeof onchange === 'string') input.setAttribute('onchange', onchange); if (typeof onchange === 'string') input.setAttribute('onchange', onchange);
if (typeof oninput === 'string') input.setAttribute('oninput', oninput); if (typeof oninput === 'string') input.setAttribute('oninput', oninput);
if (typeof options === 'object' && options.length > 0) { if (typeof options === 'object' && options.length > 0) {
// Инициализация элемента-списка для выбора значений автозаполнения // Инициализация элемента-списка для выбора значений автозаполнения
const datalist = document.createElement('datalist'); const datalist = document.createElement('datalist');
@ -706,9 +829,6 @@ class panel {
* @todo 1. Добавить проверку на существование нижнего колонтинула и записывать перед ним, вместо конца блока * @todo 1. Добавить проверку на существование нижнего колонтинула и записывать перед ним, вместо конца блока
*/ */
button(id, icon, name, description, hint, type = 'dropdown', value = 'Выбрать', onclick, onchange, oninput) { 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 {bool} Статус выполнения
*/ */
return function (group) { 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) { function (status, body, wrap, separator) {
wrap.addEventListener("input", fn => { wrap.addEventListener("input", fn => {
// Инициализация поля ввода // Инициализация поля ввода
@ -759,7 +879,8 @@ class panel {
button.setAttribute('onclick', 'return Privacy.show(this, event, \'mail\');' + typeof onclick === 'string' ? ' ' + onclick : ''); 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();
// Инициализация архитектуры // Инициализация архитектуры