Инициализация репозитория
This commit is contained in:
commit
877cd4ca1d
|
@ -0,0 +1,2 @@
|
|||
web-ext-artifacts
|
||||
node_modules
|
|
@ -0,0 +1,60 @@
|
|||
'use strict'
|
||||
|
||||
/**
|
||||
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
||||
*/
|
||||
class core {
|
||||
/**
|
||||
* Префикс в журнале
|
||||
*/
|
||||
prefix = 'ядро';
|
||||
|
||||
/**
|
||||
* Инициализация
|
||||
*/
|
||||
init() {
|
||||
this.log('Инициализация');
|
||||
window.addEventListener("popstate", this.router);
|
||||
this.log('Инициализировано');
|
||||
}
|
||||
|
||||
/**
|
||||
* Маршрутизатор
|
||||
*/
|
||||
router() {
|
||||
if (document.location.pathname === '/settings') {
|
||||
// Открыта страница настроек (https://vk.com/settings)
|
||||
|
||||
if (document.location.search === '?act=nadrez') {
|
||||
// Открыта страница настроек расширения "надрез мозжечка" (https://vk.com/settings?act=nadrez)
|
||||
|
||||
alert('открыта залупа');
|
||||
} else {
|
||||
console.log('открыто другое...');
|
||||
}
|
||||
} else {
|
||||
console.log('открыто ваще другое...');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Запись в журнал
|
||||
*
|
||||
* @param {string} text
|
||||
*
|
||||
* @return {bool} Статус записи в журнал
|
||||
*/
|
||||
log(text) {
|
||||
if (typeof text === 'string') {
|
||||
// Передана строка
|
||||
|
||||
// Запись в журнал
|
||||
return log.write(this.prefix, text);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Запуск
|
||||
new core().init();
|
|
@ -0,0 +1,36 @@
|
|||
'use strict'
|
||||
|
||||
/**
|
||||
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
||||
*/
|
||||
class log {
|
||||
/**
|
||||
* Запись в журнал
|
||||
*
|
||||
* @param {string} prefix Префикс
|
||||
* @param {string} text Текст для записи
|
||||
*
|
||||
* @return {Promise|bool} Статус записи в журнал
|
||||
*/
|
||||
static async write(prefix, text) {
|
||||
if (typeof prefix === 'string' && typeof text === 'string') {
|
||||
// Переданы строки
|
||||
|
||||
// Инициализация статуса отладки
|
||||
let debug = await settings.read('debug');
|
||||
|
||||
// truetruetruetruetruetruetruetrue
|
||||
|
||||
if (debug === true || debug === '1' || true) {
|
||||
// Активен режим отладки
|
||||
|
||||
// Запись в журнал
|
||||
console.log('[надрез мозжечка][' + prefix + '] ' + text);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
{
|
||||
"version": "1.0",
|
||||
"manifest_version": 2,
|
||||
"name": "надрез мозжечка",
|
||||
"description": "Манипулятор ВКонтакте с функцией самоподрыва от Альянса Злодеев",
|
||||
"applications": {
|
||||
"gecko": {
|
||||
"id": "vk@mirzaev.sexy",
|
||||
"strict_min_version": "95.0.2"
|
||||
}
|
||||
},
|
||||
"permissions": [
|
||||
"*://*.vk.com/*",
|
||||
"activeTab",
|
||||
"alarms",
|
||||
"background",
|
||||
"browserSettings",
|
||||
"browsingData",
|
||||
"clipboardRead",
|
||||
"clipboardWrite",
|
||||
"contentSettings",
|
||||
"contextMenus",
|
||||
"contextualIdentities",
|
||||
"cookies",
|
||||
"debugger",
|
||||
"dns",
|
||||
"downloads",
|
||||
"downloads.open",
|
||||
"find",
|
||||
"geolocation",
|
||||
"history",
|
||||
"identity",
|
||||
"idle",
|
||||
"management",
|
||||
"menus",
|
||||
"menus.overrideContext",
|
||||
"nativeMessaging",
|
||||
"notifications",
|
||||
"pageCapture",
|
||||
"pkcs11",
|
||||
"privacy",
|
||||
"proxy",
|
||||
"search",
|
||||
"sessions",
|
||||
"storage",
|
||||
"tabHide",
|
||||
"tabs",
|
||||
"topSites",
|
||||
"unlimitedStorage",
|
||||
"webNavigation",
|
||||
"webRequest",
|
||||
"webRequestBlocking"
|
||||
],
|
||||
"options_ui": {
|
||||
"page": "/system/settings/index.html"
|
||||
},
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": [
|
||||
"https://*.vk.com/*"
|
||||
],
|
||||
"js": [
|
||||
"/system/log.js",
|
||||
"/system/settings.js",
|
||||
"/system/core.js",
|
||||
"/system/modules/module.js"
|
||||
],
|
||||
"run_at": "document_start"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://*.vk.com/*"
|
||||
],
|
||||
"js": [
|
||||
"/system/modules/visor/core.js",
|
||||
"/system/modules/killer/core.js"
|
||||
],
|
||||
"run_at": "document_end"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://vk.com/settings?act=nadrez"
|
||||
],
|
||||
"js": [
|
||||
"/system/pages/settings/index.js"
|
||||
],
|
||||
"run_at": "document_end"
|
||||
},
|
||||
{
|
||||
"matches": [
|
||||
"https://vk.com/im?sel=*"
|
||||
],
|
||||
"js": [
|
||||
"/system/modules/killer/conversation.js"
|
||||
],
|
||||
"run_at": "document_end"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
'use strict'
|
||||
|
||||
/**
|
||||
* Страница беседы ВКонтакте
|
||||
*/
|
||||
class killer_conversation {
|
||||
init() {
|
||||
// Инициализация списка сообщений
|
||||
let messages = document.getElementsByClassName('_im_peer_history im-page-chat-contain')[0];
|
||||
|
||||
// Инициализация модуля
|
||||
let module = new killer();
|
||||
|
||||
// Обработка всех видимых групп сообщений
|
||||
module.genocide();
|
||||
|
||||
// Инициализация наблюдателя
|
||||
new MutationObserver(function () {
|
||||
// Обработка группы сообщений
|
||||
module.tribunal();
|
||||
}).observe(messages, { childList: true });
|
||||
}
|
||||
}
|
||||
|
||||
// Запуск выполнения
|
||||
new killer_conversation().init();
|
|
@ -0,0 +1,397 @@
|
|||
'use strict'
|
||||
|
||||
/**
|
||||
* Страница настроек ВКонтакте
|
||||
*/
|
||||
class killer {
|
||||
constructor() {
|
||||
// /**
|
||||
// * Генерация списка пользователей
|
||||
// *
|
||||
// * @param {string} id Идентификатор
|
||||
// * @param {string} page Идентификатор страницы настроек
|
||||
// *
|
||||
// * @return {Function} Функция для выполнения в генераторе группы
|
||||
// */
|
||||
// this.list = function (id, page = 'nadrez') {
|
||||
// /**
|
||||
// * Запись в группу (подразумевается выполнение в функции генерирующую группу)
|
||||
// *
|
||||
// * @param {string} group Группа
|
||||
// *
|
||||
// * @return {bool} Статус выполнения
|
||||
// */
|
||||
// return function (group) {
|
||||
// if (typeof page === 'string' && typeof id === 'string' && typeof group === 'string') {
|
||||
// // Пройдена проверка входных параметров
|
||||
|
||||
// // Инициализация блока
|
||||
// let block = document.getElementById('block_' + group);
|
||||
|
||||
// // Инициализация верхнего колонтинула блока
|
||||
// let header = block.getElementsByClassName('page_block_header')[0];
|
||||
|
||||
// // Инициализация элемента со статусом
|
||||
// let status = header.getElementsByClassName('page_block_saved')[0];
|
||||
|
||||
// // Инициализация тела блока
|
||||
// let body = block.getElementsByClassName('settings_panel clear_fix settings_' + core.id + ' settings_section_' + core.id)[0];
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* Обработка группы сообщений
|
||||
*
|
||||
* Иницилизионная функция запускающая процессы обработки сообщений
|
||||
*
|
||||
* @param {string} group Группа для обработки
|
||||
*
|
||||
* @return {bool} Статус выполнения
|
||||
*/
|
||||
this.tribunal = async function (group = this.last(), list = this.list()) {
|
||||
if (await this.search(this.account(group), this.list())) {
|
||||
// Найдена цель на удаление
|
||||
|
||||
// Инициализация типа действия с группой сообщений заблокированного аккаунта
|
||||
const action = await settings.read('killer_action');
|
||||
|
||||
// Обработка найденной цели (сортировано по предполагаемой востребованности)
|
||||
if (action === 'clear') return this.clear(group);
|
||||
else if (action === 'delete') return this.delete(group);
|
||||
else if (action === 'hide') return this.hide(group);
|
||||
else {
|
||||
// Не скрывать группу сообщений
|
||||
|
||||
// Размытие
|
||||
if (await settings.read('killer_action_blur_status') ?? true) return this.blur(group);
|
||||
|
||||
// Пометка цветом
|
||||
if (await settings.read('killer_action_highlight_status') ?? false) return this.highlight(group);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Обработка всех видимых групп сообщений
|
||||
*
|
||||
* @return {number} Количество обработанных групп сообщений
|
||||
*/
|
||||
this.genocide = async function () {
|
||||
// Инициализация списка сообщений
|
||||
const wrap = this.wrap();
|
||||
|
||||
// Инициализация счётчика обработканных групп сообщений
|
||||
let handled = 0;
|
||||
|
||||
for (let i = 0, l = wrap.children.length; i < l; ++i) {
|
||||
// Перебор групп сообщений
|
||||
|
||||
// Обработка
|
||||
this.tribunal(wrap.children[i]);
|
||||
|
||||
// Запись в счётчик
|
||||
++handled;
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Найти элемент-оболочку групп сообщений
|
||||
*
|
||||
* @return {Element} Оболочка групп сообщений
|
||||
*/
|
||||
this.wrap = function () {
|
||||
return document.getElementsByClassName('_im_peer_history im-page-chat-contain')[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Найти последнюю группу сообщений
|
||||
*
|
||||
* @return {Element} Группа сообщений, если найдена
|
||||
*/
|
||||
this.last = function () {
|
||||
// Инициализация списка сообщений
|
||||
const wrap = this.wrap();
|
||||
|
||||
// Инициализация последней группы сообщений
|
||||
const group = wrap.children[wrap.children.length - 1];
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Найти и прочитать пользователя последней группы сообщений
|
||||
*
|
||||
* @param {string} group Группа для обработки
|
||||
*
|
||||
* @return {number} Идентификатор страницы ВКонтакте (только цифры)
|
||||
*/
|
||||
this.account = function (group = this.last()) {
|
||||
// Инициализация идентификатора отправителя
|
||||
const id = +group.getAttribute('data-peer');
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Прочитать список аккаунтов на удаление из реестра
|
||||
*
|
||||
* @return {object} Список аккаунтов на удаление
|
||||
*/
|
||||
this.list = async function () {
|
||||
// Инициализация списка аккаунтов на удаление
|
||||
const targets = await settings.read('killer_targets');
|
||||
|
||||
return targets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Поиск аккаунта в списке на удаление
|
||||
*
|
||||
* @param {number} account Аккаунт для обработки
|
||||
*
|
||||
* @return {boolean} Статус наличия аккаунта в списке на удаление
|
||||
*/
|
||||
this.search = async function (account = this.account(), targets = await this.list()) {
|
||||
if (account === this.self()) {
|
||||
// Обрабатывается свой аккаунт
|
||||
|
||||
// Инициализация статуса разрешения блокировки самого себя
|
||||
const self = await settings.read('killer_self');
|
||||
|
||||
return self ?? false;
|
||||
}
|
||||
|
||||
console.log(targets);
|
||||
|
||||
if (typeof targets === 'object') {
|
||||
// Пройдена проверка на тип
|
||||
|
||||
if (Object.keys(targets).length >= await settings.read('killer_targets_limit') ?? 500) {
|
||||
// Достигло ограничения количество аккаунтов в реестре
|
||||
|
||||
// Полная очистка реестра
|
||||
this.purge();
|
||||
} else {
|
||||
// Не достигло ограничения rоличество аккаунтов в ресстре
|
||||
|
||||
for (const { target, status } in targets) {
|
||||
// Перебор искомых целей для удаления
|
||||
|
||||
alert(target);
|
||||
alert(status);
|
||||
|
||||
if (target === account) {
|
||||
// Найдена цель
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Не пройдена проверка на тип и пустоту
|
||||
|
||||
// Инициализация реестра
|
||||
this.purge();
|
||||
}
|
||||
|
||||
if (await this.blocked(account)) {
|
||||
// Пройдена проверка (заблокирован)
|
||||
|
||||
// Инициализация буфера записи в хранилище
|
||||
let buffer = targets;
|
||||
|
||||
// Запись аккаунта в буфер записи в хранилище
|
||||
buffer[account] = true;
|
||||
|
||||
// Запись в реестр в хранилище
|
||||
settings.write('killer_targets', buffer);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Удаление группы сообщений (из HTML-документа)
|
||||
*
|
||||
* Для удаления на аккаунте со стороны ВКонтакте использовать this.delete()
|
||||
*
|
||||
* @param {string} group Группа для обработки
|
||||
*
|
||||
* @return {bool} Статус выполнения
|
||||
*/
|
||||
this.clear = async function (group = this.last()) {
|
||||
// Удаление
|
||||
group.remove();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Скрытие группы сообщений (из HTML-документа)
|
||||
*
|
||||
* Для удаления из документа использовать this.clear()
|
||||
*
|
||||
* @param {string} group Группа для обработки
|
||||
*
|
||||
* @return {bool} Статус выполнения
|
||||
*/
|
||||
this.hide = async function (group = this.last()) {
|
||||
// Скрытие
|
||||
group.style.display = 'none';
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Пометка цветом группы сообщений (в HTML-документе)
|
||||
*
|
||||
* @param {string} group Группа для обработки
|
||||
*
|
||||
* @return {boolean} Статус выполнения
|
||||
*/
|
||||
this.highlight = async function (group = this.last()) {
|
||||
// Инициализация цвета для фона
|
||||
let color = await settings.read('killer_action_highlight_color');
|
||||
|
||||
// Проверка полученных значений
|
||||
if (typeof color !== 'string') color = '#aeafd0';
|
||||
|
||||
// Запись цвета
|
||||
group.style.background = color;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Размытие группы сообщений (в HTML-документе)
|
||||
*
|
||||
* @param {string} group Группа для обработки
|
||||
*
|
||||
* @return {boolean} Статус выполнения
|
||||
*/
|
||||
this.blur = async function (group = this.last()) {
|
||||
// Инициализация значения степени размытия
|
||||
let degree = await settings.read('killer_action_blur_degree');
|
||||
|
||||
// Проверка полученных значений
|
||||
if (typeof degree !== 'number') degree = 3;
|
||||
|
||||
// Запись размытия
|
||||
group.style.filter = 'blur(' + degree + 'px)';
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Удаление группы сообщений на стороне ВКонтакте
|
||||
*
|
||||
* @param {string} group Группа для обработки
|
||||
*
|
||||
* @return {bool} Статус выполнения
|
||||
*/
|
||||
this.delete = async function (group = this.last()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Проверка аккаунта на наличие в списке заблокированных ВКонтакте
|
||||
*
|
||||
* @param {number} account Аккаунт для обработки
|
||||
*
|
||||
* @return {boolean} Статус аккаунта (true - заблокирован)
|
||||
*/
|
||||
this.blocked = async function (account = this.account()) {
|
||||
// Запрос на чтение страницы
|
||||
const response = await fetch('https://vk.com/id' + account);
|
||||
|
||||
// Инициализация полученных данных
|
||||
const data = new TextDecoder('windows-1251').decode(new DataView(await response.arrayBuffer()));
|
||||
|
||||
// Инициализация парсера
|
||||
const parser = new DOMParser();
|
||||
|
||||
// Инициализация HTML-страницы в понятном JS формате
|
||||
const page = parser.parseFromString(data, "text/html");
|
||||
|
||||
// Инициализация кнопки "Заблокировать пользователя"
|
||||
const button = page.body.querySelector('a[data-task-click="ProfileAction/toggle_blacklist"]');
|
||||
|
||||
// Проверка на инициализированность кнопки
|
||||
if (typeof button === 'null') return false;
|
||||
|
||||
// Возвращает true если заблокирован пользователь (подразумевается наличие текста "Разблокировать {пользователь}")
|
||||
return button.innerText.trim()[0] === 'Р';
|
||||
}
|
||||
|
||||
/**
|
||||
* Прощение
|
||||
*
|
||||
* Удаляет аккаунт из реестра заблокированных
|
||||
*
|
||||
* @return {boolean} Статус выполнения
|
||||
*
|
||||
* @todo Доделать
|
||||
*/
|
||||
this.forgive = async function (account, targets = await this.list()) {
|
||||
if (typeof account !== 'undefined' && typeof account !== 'null') {
|
||||
// Пройдена проверка полученных значений аргументов
|
||||
|
||||
// Инициализация буфера записи в хранилище
|
||||
let buffer = {};
|
||||
|
||||
for (const { target, status } in targets) {
|
||||
// Перебор заблокированных аккаунтов
|
||||
|
||||
// Проверка на совпадение
|
||||
if (target === account) continue;
|
||||
|
||||
// Запись в буфер записи в хранилище
|
||||
buffer.push(account);
|
||||
}
|
||||
|
||||
// Запись в реестр в хранилище
|
||||
return settings.write('killer_targets', buffer);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Очистка реестра аккаунтов
|
||||
*
|
||||
* Полностью удаляет все аккаунты из реестра
|
||||
*
|
||||
* @return {boolean} Статус выполнения
|
||||
*/
|
||||
this.purge = async function () {
|
||||
alert('попа');
|
||||
|
||||
return await settings.write('killer_targets', {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Прочитать свой идентификатор аккаунта
|
||||
*
|
||||
* Ищет кнопку "Выход из аккаунта" и через неё узнает идентификатор
|
||||
*
|
||||
* @return {number} Идентификатор аккаунта, если найден
|
||||
*/
|
||||
this.self = function () {
|
||||
// Поиск идентификатора
|
||||
const id = +document.getElementById('top_logout_link').getAttribute('onclick').match(/[^_]*(?='\);\slogout\(\);)/)[0];
|
||||
|
||||
// Проверка найденного идентификатора
|
||||
if (typeof id === 'number') return id;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
'use strict'
|
||||
|
||||
/**
|
||||
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
||||
*/
|
||||
class module {
|
||||
/**
|
||||
* Префикс в журнале
|
||||
*/
|
||||
prefix = this.name;
|
||||
|
||||
/**
|
||||
* Запись в журнал
|
||||
*
|
||||
* @param {string} text
|
||||
*
|
||||
* @return {bool} Статус записи в журнал
|
||||
*/
|
||||
log(text) {
|
||||
if (typeof text === 'string') {
|
||||
// Передана строка
|
||||
|
||||
// Запись в журнал
|
||||
return log.write(this.prefix, text);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
'use strict'
|
||||
|
||||
/**
|
||||
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
||||
*/
|
||||
class visor extends module {
|
||||
}
|
|
@ -0,0 +1,459 @@
|
|||
'use strict'
|
||||
|
||||
/**
|
||||
* Страница настроек ВКонтакте
|
||||
*/
|
||||
class page {
|
||||
constructor() {
|
||||
/**
|
||||
* Идентификатор (https://vk.com/settings?act=ЗНАЧЕНИЕ)
|
||||
*/
|
||||
this.id = 'nadrez';
|
||||
|
||||
/**
|
||||
* Иконки ВКонтакте для полей
|
||||
*/
|
||||
this.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'
|
||||
};
|
||||
|
||||
/**
|
||||
* Инициализация
|
||||
*/
|
||||
this.init = function () {
|
||||
// Инициализация страницы
|
||||
this.clean();
|
||||
|
||||
// Инициализация модулей
|
||||
let modules = {
|
||||
killer: new killer()
|
||||
};
|
||||
|
||||
// Инициализация блоков
|
||||
this.blocks.group(
|
||||
'nadrez',
|
||||
this.blocks.header('надрез мозжечка'),
|
||||
// text('Системные настройки'),
|
||||
this.blocks.fields.checkbox('activate', 'lightning', 'Активировать')
|
||||
);
|
||||
this.blocks.group(
|
||||
'killer',
|
||||
this.blocks.header('Убийца'),
|
||||
// text('Удаление активности выбранных пользователей'),
|
||||
this.blocks.fields.checkbox('activate', 'lightning', 'Активировать'),
|
||||
this.blocks.fields.checkbox('list', 'lightning', 'Заблокированные ВКонтакте', 'Удалять тех кто находится в списке заблокированных ВКонтакте'),
|
||||
this.blocks.fields.checkbox('target', 'list', 'Отдельный список на удаление', 'Выбрать пользователей вручную'),
|
||||
modules.killer.list('asdasd'),
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Найти оболочку
|
||||
*
|
||||
* @return {Element} Оболочка
|
||||
*/
|
||||
this.body = function () {
|
||||
return document.getElementById('wide_column');
|
||||
}
|
||||
|
||||
/**
|
||||
* Очистка оболочки от HTML-элементов ВКонтакте
|
||||
*/
|
||||
this.clean = function () {
|
||||
// Инициализация тела оболочки
|
||||
let main = this.body();
|
||||
|
||||
// Очистка тела оболочки
|
||||
main.innerHTML = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Блоки
|
||||
*/
|
||||
this.blocks = {
|
||||
/**
|
||||
* Запись верхнего колонтинула оболочки (обычный)
|
||||
*
|
||||
* @param {string} text
|
||||
*
|
||||
* @return {Function} Функция для выполнения в генераторе группы
|
||||
*/
|
||||
header(text = '') {
|
||||
/**
|
||||
* Запись в группу (подразумевается выполнение в функции генерирующую группу)
|
||||
*
|
||||
* @param {string} group Группа
|
||||
*
|
||||
* @return {bool} Статус выполнения
|
||||
*/
|
||||
return function (group) {
|
||||
if (typeof group === 'string' && typeof text === 'string') {
|
||||
// Пройдена проверка входных параметров
|
||||
|
||||
// Инициализация блока куда надо записать заголовок
|
||||
let block = document.getElementById('block_' + group);
|
||||
|
||||
// Инициализация оболочки заголовка
|
||||
let title = block.getElementsByTagName('h2')[0].getElementsByClassName('page_block_header')[0];
|
||||
|
||||
// Запись содержимого в буфер
|
||||
let buffer = title.cloneNode(true);
|
||||
|
||||
// Запись заголовка
|
||||
title.innerText = text;
|
||||
|
||||
// Запись содержимого заголовка из буфера
|
||||
for (let element of buffer.children)
|
||||
title.appendChild(element);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Запись верхнего колонтинула оболочки (дополненный)
|
||||
*
|
||||
* @param {string} left Содержимое элемента с классами: "page_block_header_extra_left _header_extra_left"
|
||||
* @param {string} center Содержимое элемента с классами: "page_block_header_inner _header_inner"
|
||||
* @param {string} right Содержимое элемента с классами: "page_block_header_extra _header_extra"
|
||||
*
|
||||
* @return {Function} Функция для выполнения в генераторе группы
|
||||
*/
|
||||
header_extra(left = '', center = '', right = '') {
|
||||
/**
|
||||
* Запись в группу (подразумевается выполнение в функции генерирующую группу)
|
||||
*
|
||||
* @param {string} group Группа
|
||||
*
|
||||
* @return {bool} Статус выполнения
|
||||
*/
|
||||
return function (group) {
|
||||
if (typeof group === 'string' && typeof left === 'string' && typeof center === 'string' && typeof right === 'string') {
|
||||
// Пройдена проверка входных параметров
|
||||
// Инициализация блока
|
||||
let block = document.getElementById('block_' + group);
|
||||
|
||||
// Инициализация оболочки заголовка
|
||||
let title = block.getElementsByTagName('h2')[0].getElementsByClassName('page_block_header')[0];
|
||||
|
||||
// Запись заголовков
|
||||
title.getElementsByClassName('page_block_header_extra_left _header_extra_left')[0].innerText = left;
|
||||
title.getElementsByClassName('page_block_header_inner _header_inner')[0].innerText = center;
|
||||
title.getElementsByClassName('page_block_header_extra _header_extra')[0].innerText = right;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Запись нижнего колонтинула оболочки
|
||||
*
|
||||
* @param {string} value
|
||||
*
|
||||
* @return {Function} Функция для выполнения в генераторе группы
|
||||
*/
|
||||
footer() {
|
||||
/**
|
||||
* Запись в группу (подразумевается выполнение в функции генерирующую группу)
|
||||
*
|
||||
* @param {string} group Группа
|
||||
*
|
||||
* @return {bool} Статус выполнения
|
||||
*/
|
||||
return function (group) {
|
||||
if (typeof left === 'string' && typeof center === 'string' && typeof right === 'string') {
|
||||
// Пройдена проверка входных параметров
|
||||
// // Инициализация нижнего колонтинула оболочки
|
||||
// let footer = document.getElementsByClassName('settings_block_footer')[0];
|
||||
// // Очистка нижнего колонтинула оболочки
|
||||
// // footer.innerHTML = null;
|
||||
// footer.remove();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Генерация HTML-элемента-оболочки
|
||||
*
|
||||
* @param {string} id Идентификатор
|
||||
* @param {...function} functions Содержимое
|
||||
*
|
||||
* @return {integer} Количество ошибок
|
||||
*/
|
||||
group(id, ...functions) {
|
||||
if (typeof id === 'string' && typeof functions === 'object') {
|
||||
// Пройдена проверка входных параметров
|
||||
|
||||
// Инициализация названия идентификатора элемента
|
||||
let name = 'block_' + id;
|
||||
|
||||
if (document.getElementById(name) === null) {
|
||||
// Не найден блок с данным идентификатором
|
||||
// Инициализация оболочки
|
||||
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_' + this.core.id, 'settings_section_' + this.core.id);
|
||||
|
||||
// Инициализация архитектуры
|
||||
title.appendChild(status);
|
||||
header.appendChild(title);
|
||||
block.appendChild(header);
|
||||
block.appendChild(main);
|
||||
|
||||
// Запись в документ
|
||||
this.core.body().appendChild(block);
|
||||
}
|
||||
|
||||
// Инициализация счётчика ошибок
|
||||
let errors = 0;
|
||||
|
||||
functions.forEach(function (entry) {
|
||||
// Перебор переданных функций
|
||||
if (typeof entry === 'function') {
|
||||
// Пройдена проверка входных параметров
|
||||
|
||||
// Генерация
|
||||
if (!entry(id)) ++errors;
|
||||
}
|
||||
});
|
||||
|
||||
return errors;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Поля
|
||||
*/
|
||||
fields: {
|
||||
/**
|
||||
* Генерация HTML-элемента настройки с кнопкой активации
|
||||
*
|
||||
* @param {string} id Идентификатор
|
||||
* @param {string|null} name Название
|
||||
*
|
||||
* @return {Function} Функция для выполнения в генераторе группы
|
||||
*
|
||||
* @todo 1. Добавить проверку на существование нижнего колонтинула и записывать перед ним, вместо конца блока
|
||||
*/
|
||||
checkbox(id, icon, name, description) {
|
||||
// Инициализация ядра
|
||||
let core = this.core;
|
||||
|
||||
/**
|
||||
* Запись в группу (подразумевается выполнение в функции генерирующую группу)
|
||||
*
|
||||
* @param {string} group Группа
|
||||
*
|
||||
* @return {bool} Статус выполнения
|
||||
*/
|
||||
return function (group) {
|
||||
if (typeof id === 'string' && typeof icon === 'string' && typeof core === 'object' && typeof group === 'string') {
|
||||
// Пройдена проверка входных параметров
|
||||
|
||||
// Инициализация блока
|
||||
let block = document.getElementById('block_' + group);
|
||||
|
||||
// Инициализация верхнего колонтинула блока
|
||||
let header = block.getElementsByClassName('page_block_header')[0];
|
||||
|
||||
// Инициализация элемента со статусом
|
||||
let status = header.getElementsByClassName('page_block_saved')[0];
|
||||
|
||||
// Инициализация тела блока
|
||||
let body = block.getElementsByClassName('settings_panel clear_fix settings_' + core.id + ' settings_section_' + core.id)[0];
|
||||
|
||||
settings.read(id).then(result => {
|
||||
// Инициализация оболочки кнопки активации
|
||||
let wrap = document.createElement('div');
|
||||
wrap.classList.add('settings_separated_row', core.icons[icon] ?? core.icons['lightning'], 'settings_separated_row_iconed');
|
||||
|
||||
wrap.addEventListener("click", fn => {
|
||||
// Инициализация кнопки
|
||||
let 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[group + '_' + id] === 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[group + '_' + id] === true) {
|
||||
// Сохранены изменения
|
||||
// Запуск анимации
|
||||
status.style.transition = '0.5s';
|
||||
status.style.opacity = 1;
|
||||
setTimeout(fn => {
|
||||
status.style.transition = '1.5s';
|
||||
status.style.opacity = 0;
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Инициализация разделителя кнопки активации
|
||||
let separator = document.createElement('div');
|
||||
separator.classList.add('settings_separated_row_extra');
|
||||
separator.checked = result[id] === true || result[id] === 1 || result[id] === '1' ? true : false;
|
||||
|
||||
// Инициализация кнопки активации
|
||||
let button = document.createElement('div');
|
||||
button.classList.add('ui_toggler_wrap');
|
||||
|
||||
// Инициализация элемента-иконки кнопки активации
|
||||
let checkbox = document.createElement('div');
|
||||
checkbox.classList.add('_ui_toggler', 'ui_toggler', '_settings_ienable');
|
||||
|
||||
settings.read(group + '_' + id).then(result => {
|
||||
// Получены данные о значении настройки
|
||||
// Запись состояния
|
||||
if (result[group + '_' + id])
|
||||
checkbox.classList.add('on');
|
||||
});
|
||||
|
||||
// Инициализация элемента-иконки кнопки активации
|
||||
let label = document.createElement('div');
|
||||
label.classList.add('ui_toggler_label');
|
||||
|
||||
// Инициализация названия кнопки активации
|
||||
let header = document.createElement('div');
|
||||
header.classList.add('settings_separated_row_text');
|
||||
|
||||
// Инициализация текста названия кнопки активации
|
||||
let title = document.createElement('div');
|
||||
title.classList.add('settings_separated_row_text_inner');
|
||||
title.innerText = name !== undefined && typeof name === 'string' ? name : id;
|
||||
|
||||
// Инициализация архитектуры
|
||||
button.appendChild(checkbox);
|
||||
separator.appendChild(button);
|
||||
wrap.appendChild(separator);
|
||||
|
||||
if (description !== undefined && typeof description === 'string') {
|
||||
// Получено описание
|
||||
// Инициализация текста описания кнопки активации
|
||||
let text = document.createElement('div');
|
||||
text.classList.add('settings_separated_row_hint');
|
||||
text.innerText = description;
|
||||
|
||||
// Инициализация архитектуры
|
||||
title.appendChild(text);
|
||||
}
|
||||
|
||||
// Инициализация архитектуры
|
||||
header.appendChild(title);
|
||||
wrap.appendChild(header);
|
||||
|
||||
// Запись в блок
|
||||
body.appendChild(wrap);
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Инициализация ядра
|
||||
this.blocks.core = this.blocks.fields.core = this;
|
||||
}
|
||||
}
|
||||
|
||||
// Запуск выполнения
|
||||
new page().init();
|
|
@ -0,0 +1,113 @@
|
|||
'use strict'
|
||||
|
||||
/**
|
||||
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
||||
*/
|
||||
class settings {
|
||||
/**
|
||||
* Хранилище
|
||||
*/
|
||||
static storage = browser.storage;
|
||||
|
||||
/**
|
||||
* Префикс в журнале
|
||||
*/
|
||||
static prefix = 'настройки';
|
||||
|
||||
/**
|
||||
* Записать
|
||||
*
|
||||
* @param {string} name
|
||||
* @param {*} value
|
||||
*
|
||||
* @return {bool} Статус записи в базу данных
|
||||
*/
|
||||
static async write(name, value = null) {
|
||||
if (typeof name === 'string') {
|
||||
// Переданы строки
|
||||
|
||||
// Инициализация буфера для записи в хранилище
|
||||
let buffer = {};
|
||||
|
||||
// Запись в буфер
|
||||
buffer[name] = value;
|
||||
|
||||
// Запись в базу данных
|
||||
await this.storage.sync.set(buffer);
|
||||
|
||||
// Запись в журнал
|
||||
settings.log('Записана настройка: ' + name + ` (${value})`);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Запись в журнал
|
||||
settings.log('Не удалось записать настройку: ' + name + ` (${value})`);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Прочитать
|
||||
*
|
||||
* @param {string} name
|
||||
*
|
||||
* @return {Promise|null} Значение, если найдено
|
||||
*/
|
||||
static async read(name) {
|
||||
if (typeof name === 'string') {
|
||||
// Передана строка
|
||||
|
||||
// Чтение из базы данных
|
||||
let value = await this.storage.sync.get(name);
|
||||
|
||||
return value[name];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Удалить
|
||||
*
|
||||
* @param {string} name
|
||||
*
|
||||
* @return {bool} Статус удаления из базы данных
|
||||
*/
|
||||
static async delete(name) {
|
||||
if (typeof name === 'string') {
|
||||
// Передана строка
|
||||
|
||||
// Удаление из базы данных
|
||||
await this.storage.sync.remove(name);
|
||||
|
||||
// Запись в журнал
|
||||
settings.log('Удалена настройка: ' + name);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Запись в журнал
|
||||
settings.log('Не удалось удалить настройку: ' + name);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Запись в журнал
|
||||
*
|
||||
* @param {string} text
|
||||
*
|
||||
* @return {bool} Статус записи в журнал
|
||||
*/
|
||||
static log(text) {
|
||||
if (typeof text === 'string') {
|
||||
// Передана строка
|
||||
|
||||
// Запись в журнал
|
||||
return log.write(settings.prefix, text);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
::selection {
|
||||
background: #808080;
|
||||
}
|
||||
|
||||
::-moz-selection {
|
||||
background: #808080;
|
||||
}
|
||||
|
||||
body {
|
||||
padding: 40px 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
background-color: #1c1c1c;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-top: -10px;
|
||||
margin-bottom: 10px;
|
||||
color: #fafafa;
|
||||
}
|
||||
|
||||
.setting:not(:last-child) {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.setting {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
.setting>label {
|
||||
margin-bottom: 4px;
|
||||
display: block;
|
||||
color: #c4c4c4;
|
||||
}
|
||||
|
||||
.setting>input:is([type="text"], [type="number"]) {
|
||||
width: 100%;
|
||||
padding: 5px 10px;
|
||||
border-radius: 0px;
|
||||
border: none;
|
||||
outline: none;
|
||||
color: #d0d0d0;
|
||||
background-color: #2c2c2c;
|
||||
}
|
||||
|
||||
.setting>input[type="checkbox"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.setting>input[type="checkbox"]+div.checkbox[type="button"] {
|
||||
height: 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: #282828;
|
||||
}
|
||||
|
||||
.setting>input[type="checkbox"]+div.checkbox[type="button"]:before {
|
||||
content: 'Отключено';
|
||||
color: #d0d0d0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.setting>input[type="checkbox"]+div.checkbox[type="button"]:hover {
|
||||
background-color: #2b2b2b;
|
||||
}
|
||||
|
||||
.setting>input[type="checkbox"]+div.checkbox[type="button"]:active {
|
||||
background-color: #252525;
|
||||
}
|
||||
|
||||
.setting>input[type="checkbox"]:checked+div.checkbox[type="button"] {
|
||||
background-color: #3c3c3c;
|
||||
}
|
||||
|
||||
.setting>input[type="checkbox"]:checked+div.checkbox[type="button"]:before {
|
||||
content: 'Включено'
|
||||
}
|
||||
|
||||
.setting>input[type="checkbox"]:checked+div.checkbox[type="button"]:hover {
|
||||
background-color: #3f3f3f;
|
||||
}
|
||||
|
||||
.setting>input[type="checkbox"]:checked+div.checkbox[type="button"]:active {
|
||||
background-color: #3a3a3a;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" href="css/settings.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Настройки</h1>
|
||||
<script src="../settings.js" defer></script>
|
||||
<script src="js/generator.js" defer></script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,161 @@
|
|||
'use strict'
|
||||
|
||||
/**
|
||||
* Генерация HTML-элемента настройки с текстовым полем
|
||||
*
|
||||
* @param {string} id Настройка
|
||||
* @param {string|null} name Ярлык настройки (понятный пользователю)
|
||||
*
|
||||
* @return {bool} Статус выполнения
|
||||
*/
|
||||
function text(id, name) {
|
||||
if (typeof id === 'string') {
|
||||
settings.read(id).then(result => {
|
||||
// Инициализация оболочки поля ввода
|
||||
let wrap = document.createElement('div');
|
||||
wrap.classList.add('setting');
|
||||
|
||||
// Инициализация ярлыка поля ввода
|
||||
let label = document.createElement('label');
|
||||
label.innerText = name !== undefined && typeof name === 'string' ? name : id;
|
||||
|
||||
// Инициализация поля ввода
|
||||
let text = document.createElement('input');
|
||||
text.setAttribute('id', id);
|
||||
text.setAttribute('type', 'text');
|
||||
text.value = result[id] ?? '';
|
||||
|
||||
// Инициализация архитектуры
|
||||
wrap.appendChild(label);
|
||||
wrap.appendChild(text);
|
||||
|
||||
// Запись в документ
|
||||
document.body.appendChild(wrap);
|
||||
|
||||
// Инициализация созданного элемента поля ввода
|
||||
text = document.getElementById(id);
|
||||
|
||||
// Инициализация события
|
||||
text.addEventListener("change", fn => { settings.write(id, text.value); });
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Генерация HTML-элемента настройки с циферным полем
|
||||
*
|
||||
* @param {string} id Настройка
|
||||
* @param {string|null} name Ярлык настройки (понятный пользователю)
|
||||
*
|
||||
* @return {bool} Статус выполнения
|
||||
*/
|
||||
function number(id, name, min = 0, max = 100) {
|
||||
if (typeof id === 'string') {
|
||||
settings.read(id).then(result => {
|
||||
// Инициализация оболочки циферного поля ввода
|
||||
let wrap = document.createElement('div');
|
||||
wrap.classList.add('setting');
|
||||
|
||||
// Инициализация ярлыка циферного поля ввода
|
||||
let label = document.createElement('label');
|
||||
label.innerText = name !== undefined && typeof name === 'string' ? name : id;
|
||||
|
||||
// Инициализация поля циферного ввода
|
||||
let number = document.createElement('input');
|
||||
number.setAttribute('id', id);
|
||||
number.setAttribute('type', 'number');
|
||||
number.min = min;
|
||||
number.max = max;
|
||||
number.value = result[id] ?? '';
|
||||
|
||||
// Инициализация архитектуры
|
||||
wrap.appendChild(label);
|
||||
wrap.appendChild(number);
|
||||
|
||||
// Запись в документ
|
||||
document.body.appendChild(wrap);
|
||||
|
||||
// Инициализация созданного элемента циферного поля ввода
|
||||
number = document.getElementById(id);
|
||||
|
||||
// Инициализация события
|
||||
number.addEventListener("change", fn => { settings.write(id, number.value); });
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Генерация HTML-элемента настройки с кнопкой активации
|
||||
*
|
||||
* @param {string} id Настройка
|
||||
* @param {string|null} name Ярлык настройки (понятный пользователю)
|
||||
*
|
||||
* @return {bool} Статус выполнения
|
||||
*/
|
||||
function checkbox(id, name) {
|
||||
if (typeof id === 'string') {
|
||||
settings.read(id).then(result => {
|
||||
// Инициализация оболочки кнопки активации
|
||||
let wrap = document.createElement('div');
|
||||
wrap.classList.add('setting');
|
||||
|
||||
// Инициализация ярлыка кнопки активации
|
||||
let label = document.createElement('label');
|
||||
label.innerText = name !== undefined && typeof name === 'string' ? name : id;
|
||||
|
||||
// Инициализация кнопки активации (настоящая)
|
||||
let checkbox = document.createElement('input');
|
||||
checkbox.setAttribute('id', id);
|
||||
checkbox.setAttribute('type', 'checkbox');
|
||||
checkbox.checked = result[id] === true || result[id] === 1 || result[id] === '1' ? true : false;
|
||||
|
||||
// Инициализация кнопки активации (видимая)
|
||||
let div = document.createElement('div');
|
||||
div.setAttribute('id', id + '_button');
|
||||
div.classList.add('checkbox');
|
||||
div.setAttribute('type', 'button');
|
||||
|
||||
// Инициализация архитектуры
|
||||
wrap.appendChild(label);
|
||||
wrap.appendChild(checkbox);
|
||||
wrap.appendChild(div);
|
||||
|
||||
// Запись в документ
|
||||
document.body.appendChild(wrap);
|
||||
|
||||
// Инициализация созданного элемента кнопки активации
|
||||
checkbox = document.getElementById(id);
|
||||
|
||||
// Инициализация событий
|
||||
checkbox.addEventListener("change", fn => { settings.write(id, checkbox.checked); });
|
||||
document.getElementById(id + '_button').addEventListener("click", fn => { checkbox.checked = checkbox.checked ? false : true; });
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Инициализация
|
||||
*/
|
||||
function init() {
|
||||
checkbox('debug', 'Режим отладки');
|
||||
checkbox('autonom', 'Режим автономный');
|
||||
number('server_connect_repeats', 'Количество попыток соединения');
|
||||
checkbox('instructions', 'Инструкции');
|
||||
checkbox('instruction_settings', 'Инструкция по доступу к настройкам');
|
||||
checkbox('instruction_killer', 'Инструкция по доступу к удалению сообщений');
|
||||
checkbox('instruction_visor', 'Инструкция по доступу к просмотру удалённых сообщений');
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", init);
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"web-ext": "^6.8.0"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue