Added translate to english

This commit is contained in:
Arsen Mirzaev Tatyano-Muradovich 2022-11-11 21:54:10 +10:00
parent 7815b0c348
commit 95cf0b5c1f
3 changed files with 559 additions and 113 deletions

1
compile.sh Normal file
View File

@ -0,0 +1 @@
web-ext -s firefox run -f "C:\Program Files\Firefox Developer Edition\firefox.exe" -p "C:\Users\Пользователь\AppData\Roaming\Mozilla\Firefox\Profiles\development" --profile-create-if-missing --keep-profile-changes --verbose

View File

@ -0,0 +1,52 @@
{
"extensionName": {
"message": "Menu demo",
"description": "Name of the extension."
},
"extensionDescription": {
"message": "Demonstrates the menus API.",
"description": "Description of the add-on."
},
"menuItemSelectionLogger": {
"message": "Log '%s' to the browser console",
"description": "Title of context menu item that logs the selected text when clicked."
},
"menuItemRemoveMe": {
"message": "Remove me!",
"description": "Title of context menu item that removes itself when clicked."
},
"menuItemGreenify": {
"message": "Greenify",
"description": "Title of context menu item that adds a green border when clicked."
},
"menuItemBluify": {
"message": "Bluify",
"description": "Title of context menu item that adds a green border when clicked."
},
"menuItemCheckMe": {
"message": "Check me",
"description": "Title of context menu item when the item is checked."
},
"menuItemUncheckMe": {
"message": "Uncheck me",
"description": "Title of context menu item when the item is unchecked."
},
"menuItemOpenSidebar": {
"message": "Open sidebar",
"description": "Title of context menu item that opens a sidebar."
},
"menuItemToolsMenu": {
"message": "Click me!",
"description": "Title of tools menu item."
}
}

View File

@ -83,8 +83,10 @@ class page {
this.blocks.header('Убийца'),
// text('Удаление активности выбранных пользователей'),
this.blocks.fields.checkbox('activate', 'lightning', 'Активировать'),
this.blocks.fields.checkbox('list', 'lightning', 'Заблокированные ВКонтакте', 'Удалять тех кто находится в списке заблокированных ВКонтакте'),
this.blocks.fields.text('asdasdasd', 'lightning', 'Активировать', 'asdasdasdasd', 'Тестирование всплывающей подсказки', 'text', 0, 8, 'фффф', 'сюда писать'),
this.blocks.fields.checkbox('list', 'group', 'Заблокированные ВКонтакте', 'Удалять тех кто находится в списке заблокированных ВКонтакте', 'Тестирование всплывающей подсказки'),
this.blocks.fields.checkbox('target', 'list', 'Отдельный список на удаление', 'Выбрать пользователей вручную'),
this.blocks.fields.dropdown('targetasdasd', 'promo', 'Какаято хуитень', 'Выбфывелей вручную', 'Тестирование всплывающей подсказки'),
modules.killer.list('asdasd'),
);
}
@ -122,7 +124,7 @@ class page {
*/
header(text = '') {
/**
* Запись в группу (подразумевается выполнение в функции генерирующую группу)
* Запись в группу (подразумевается выполнение в функции генерирующей группу)
*
* @param {string} group Группа
*
@ -133,20 +135,19 @@ class page {
// Пройдена проверка входных параметров
// Инициализация блока куда надо записать заголовок
let block = document.getElementById('block_' + group);
const block = document.getElementById('block_' + group);
// Инициализация оболочки заголовка
let title = block.getElementsByTagName('h2')[0].getElementsByClassName('page_block_header')[0];
const title = block.getElementsByTagName('h2')[0].getElementsByClassName('page_block_header')[0];
// Запись содержимого в буфер
let buffer = title.cloneNode(true);
const buffer = title.cloneNode(true);
// Запись заголовка
title.innerText = text;
// Запись содержимого заголовка из буфера
for (let element of buffer.children)
title.appendChild(element);
for (let element of buffer.children) title.appendChild(element);
return true;
}
@ -166,7 +167,7 @@ class page {
*/
header_extra(left = '', center = '', right = '') {
/**
* Запись в группу (подразумевается выполнение в функции генерирующую группу)
* Запись в группу (подразумевается выполнение в функции генерирующей группу)
*
* @param {string} group Группа
*
@ -175,11 +176,12 @@ class page {
return function (group) {
if (typeof group === 'string' && typeof left === 'string' && typeof center === 'string' && typeof right === 'string') {
// Пройдена проверка входных параметров
// Инициализация блока
let block = document.getElementById('block_' + group);
const block = document.getElementById('block_' + group);
// Инициализация оболочки заголовка
let title = block.getElementsByTagName('h2')[0].getElementsByClassName('page_block_header')[0];
const title = block.getElementsByTagName('h2')[0].getElementsByClassName('page_block_header')[0];
// Запись заголовков
title.getElementsByClassName('page_block_header_extra_left _header_extra_left')[0].innerText = left;
@ -294,22 +296,268 @@ class page {
* Поля
*/
fields: {
macroses: {
/**
* Шаблон для инициализации элементов строки с полем
*
* @param {string} group Группа
* @param {string|null} icon Иконка
* @param {function} content Функция которая будет обрабатывать содержимое макроса
*/
row(group, icon, content) {
// Инициализация блока
const block = document.getElementById('block_' + group);
// Инициализация головного элемента блока
const header = block.getElementsByClassName('page_block_header')[0];
// Инициализация элемента со статусом
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 wrap = document.createElement('div');
wrap.classList.add('settings_separated_row', this.core.icons[icon] ?? this.core.icons['lightning'], 'settings_separated_row_iconed');
// Инициализация разделителя
const separator = document.createElement('div');
separator.classList.add('settings_separated_row_extra');
// Генерация содержимого строки
return content(status, body, 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} Функция для выполнения в генераторе группы
* @return {function} Функция для выполнения в генераторе группы
*
* @todo 1. Добавить проверку на существование нижнего колонтинула и записывать перед ним, вместо конца блока
*/
checkbox(id, icon, name, description) {
checkbox(id, icon, name, description, hint, onchange) {
// Инициализация ядра
let core = this.core;
const core = this.core;
/**
* Запись в группу (подразумевается выполнение в функции генерирующую группу)
* Запись в группу (подразумевается выполнение в функции генерирующей группу)
*
* @param {string} group Группа
*
* @return {bool} Статус выполнения
*/
return function (group) {
if (typeof id === 'string' && typeof core === 'object' && typeof group === 'string') {
// Пройдена проверка входных параметров
return core.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} type Тип поля для ввода (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, type = 'text', min = 0, max = 100, title, placeholder, pattern, readonly, spellcheck, options, onchange, oninput) {
// Инициализация ядра
const core = this.core;
/**
* Запись в группу (подразумевается выполнение в функции генерирующей группу)
*
* @param {string} group Группа
*
@ -319,37 +567,18 @@ class page {
if (typeof id === 'string' && typeof icon === 'string' && typeof core === 'object' && typeof group === 'string') {
// Пройдена проверка входных параметров
// Инициализация блока
const block = document.getElementById('block_' + group);
return core.blocks.fields.macros(group, icon,
function (status, body, wrap, separator) {
wrap.addEventListener("input", fn => {
// Инициализация поля ввода
const input = wrap.getElementsByTagName('input')[0];
// Инициализация верхнего колонтинула блока
const header = block.getElementsByClassName('page_block_header')[0];
// Инициализация элемента со статусом
const status = header.getElementsByClassName('page_block_saved')[0];
// Инициализация тела блока
const 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');
if (settings.write(group + '_' + id, input.value)) {
// Записано значение поля
// Запуск анимации
settings.read(group + '_' + id).then(result => {
if (result === false) {
if (result === input.value) {
// Сохранены изменения
// Запуск анимации
@ -362,91 +591,255 @@ class page {
}
});
}
} else {
// Деактивирована
if (settings.write(group + '_' + id, true)) {
// Записан статус активации
});
// Запуск анимации и переход в состояние активации
button.classList.add('on');
// Инициализация элемента для ввода текста
const input = document.createElement('input');
input.classList.add('dark');
input.setAttribute('type', type);
input.setAttribute(type === 'number' ? 'min' : 'minlength', min);
input.setAttribute(type === '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 => {
// Получены данные о значении настройки
settings.read(group + '_' + id).then(result => {
if (result === true) {
// Сохранены изменения
// Запись значения в поле
if (result) input.value = result;
});
if (typeof onchange === 'string') input.setAttribute('onchange', onchange);
if (typeof oninput === 'string') input.setAttribute('oninput', oninput);
// Запуск анимации
status.style.transition = '0.5s';
status.style.opacity = 1;
setTimeout(fn => {
status.style.transition = '1.5s';
status.style.opacity = 0;
}, 1000);
}
});
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);
}
}
});
// Инициализация разделителя кнопки активации
let separator = document.createElement('div');
separator.classList.add('settings_separated_row_extra');
separator.checked = result === true || result === 1 || result === '1' ? true : false;
// Инициализация элемента-иконки
const label = document.createElement('div');
label.classList.add('ui_toggler_label');
// Инициализация кнопки активации
let button = document.createElement('div');
button.classList.add('ui_toggler_wrap');
// Инициализация названия
const header = document.createElement('div');
header.classList.add('settings_separated_row_text');
// Инициализация элемента-иконки кнопки активации
let checkbox = document.createElement('div');
checkbox.classList.add('_ui_toggler', 'ui_toggler', '_settings_ienable');
settings.read(group + '_' + id).then(result => {
// Получены данные о значении настройки
// Запись состояния
if (result)
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;
// Инициализация текста названия
const colonic = document.createElement('div');
colonic.classList.add('settings_separated_row_text_inner');
colonic.innerText = name !== undefined && typeof name === 'string' ? name : id;
// Инициализация архитектуры
title.appendChild(text);
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;
}
);
}
// Инициализация архитектуры
header.appendChild(title);
wrap.appendChild(header);
return false;
};
},
// Запись в блок
body.appendChild(wrap);
/**
* Генерация 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', value = 'Выбрать', onclick, onchange, oninput) {
// Инициализация ядра
const core = this.core;
return true;
});
/**
* Запись в группу (подразумевается выполнение в функции генерирующей группу)
*
* @param {string} group Группа
*
* @return {bool} Статус выполнения
*/
return function (group) {
if (typeof id === 'string' && typeof icon === 'string' && typeof core === 'object' && typeof group === 'string') {
// Пройдена проверка входных параметров
return core.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 = core.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;