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('Убийца'), this.blocks.header('Убийца'),
// text('Удаление активности выбранных пользователей'), // text('Удаление активности выбранных пользователей'),
this.blocks.fields.checkbox('activate', 'lightning', 'Активировать'), 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.checkbox('target', 'list', 'Отдельный список на удаление', 'Выбрать пользователей вручную'),
this.blocks.fields.dropdown('targetasdasd', 'promo', 'Какаято хуитень', 'Выбфывелей вручную', 'Тестирование всплывающей подсказки'),
modules.killer.list('asdasd'), modules.killer.list('asdasd'),
); );
} }
@ -122,7 +124,7 @@ class page {
*/ */
header(text = '') { header(text = '') {
/** /**
* Запись в группу (подразумевается выполнение в функции генерирующую группу) * Запись в группу (подразумевается выполнение в функции генерирующей группу)
* *
* @param {string} group Группа * @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; title.innerText = text;
// Запись содержимого заголовка из буфера // Запись содержимого заголовка из буфера
for (let element of buffer.children) for (let element of buffer.children) title.appendChild(element);
title.appendChild(element);
return true; return true;
} }
@ -166,7 +167,7 @@ class page {
*/ */
header_extra(left = '', center = '', right = '') { header_extra(left = '', center = '', right = '') {
/** /**
* Запись в группу (подразумевается выполнение в функции генерирующую группу) * Запись в группу (подразумевается выполнение в функции генерирующей группу)
* *
* @param {string} group Группа * @param {string} group Группа
* *
@ -175,11 +176,12 @@ class page {
return function (group) { return function (group) {
if (typeof group === 'string' && typeof left === 'string' && typeof center === 'string' && typeof right === 'string') { 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; title.getElementsByClassName('page_block_header_extra_left _header_extra_left')[0].innerText = left;
@ -294,22 +296,268 @@ class page {
* Поля * Поля
*/ */
fields: { 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-элемента настройки с кнопкой активации * Генерация HTML-элемента настройки с кнопкой активации
* *
* @param {string} id Идентификатор * @param {string} id Идентификатор
* @param {string|null} icon Иконка
* @param {string|null} name Название * @param {string|null} name Название
* @param {string|null} description Описание
* @param {string|null} hint Всплывающая подсказка (иконка с вопросительным знаком возле верхнего колонтинула)
* @param {string|null} onchange Код который выполняется после изменения состояния
* *
* @return {Function} Функция для выполнения в генераторе группы * @return {function} Функция для выполнения в генераторе группы
* *
* @todo 1. Добавить проверку на существование нижнего колонтинула и записывать перед ним, вместо конца блока * @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 Группа * @param {string} group Группа
* *
@ -319,37 +567,18 @@ class page {
if (typeof id === 'string' && typeof icon === 'string' && typeof core === 'object' && typeof group === 'string') { if (typeof id === 'string' && typeof icon === 'string' && typeof core === 'object' && typeof group === 'string') {
// Пройдена проверка входных параметров // Пройдена проверка входных параметров
// Инициализация блока return core.blocks.fields.macros(group, icon,
const block = document.getElementById('block_' + group); function (status, body, wrap, separator) {
wrap.addEventListener("input", fn => {
// Инициализация поля ввода
const input = wrap.getElementsByTagName('input')[0];
// Инициализация верхнего колонтинула блока if (settings.write(group + '_' + id, input.value)) {
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');
// Запуск анимации
settings.read(group + '_' + id).then(result => { 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'; if (typeof options === 'object' && options.length > 0) {
status.style.opacity = 1; // Инициализация элемента-списка для выбора значений автозаполнения
setTimeout(fn => { const datalist = document.createElement('datalist');
status.style.transition = '1.5s'; datalist.id = group + '_' + id + '_datalist';
status.style.opacity = 0;
}, 1000); for (const option of options) {
} // Перебор значений для автозаполнения поля
});
// Инициализация элемента со значением автозаполнения
const element = document.createElement('option');
element.setAttribute('value', option);
// Запись в список
datalist.appendChild(element);
} }
} }
});
// Инициализация разделителя кнопки активации // Инициализация элемента-иконки
let separator = document.createElement('div'); const label = document.createElement('div');
separator.classList.add('settings_separated_row_extra'); label.classList.add('ui_toggler_label');
separator.checked = result === true || result === 1 || result === '1' ? true : false;
// Инициализация кнопки активации // Инициализация названия
let button = document.createElement('div'); const header = document.createElement('div');
button.classList.add('ui_toggler_wrap'); header.classList.add('settings_separated_row_text');
// Инициализация элемента-иконки кнопки активации // Инициализация текста названия
let checkbox = document.createElement('div'); const colonic = document.createElement('div');
checkbox.classList.add('_ui_toggler', 'ui_toggler', '_settings_ienable'); colonic.classList.add('settings_separated_row_text_inner');
colonic.innerText = name !== undefined && typeof name === 'string' ? name : id;
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;
// Инициализация архитектуры // Инициализация архитектуры
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;
} }
);
}
// Инициализация архитектуры return false;
header.appendChild(title); };
wrap.appendChild(header); },
// Запись в блок /**
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; return false;