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,51 +296,115 @@ class page {
* Поля * Поля
*/ */
fields: { fields: {
macroses: {
/** /**
* Генерация HTML-элемента настройки с кнопкой активации * Шаблон для инициализации элементов строки с полем
*
* @param {string} id Идентификатор
* @param {string|null} name Название
*
* @return {Function} Функция для выполнения в генераторе группы
*
* @todo 1. Добавить проверку на существование нижнего колонтинула и записывать перед ним, вместо конца блока
*/
checkbox(id, icon, name, description) {
// Инициализация ядра
let core = this.core;
/**
* Запись в группу (подразумевается выполнение в функции генерирующую группу)
* *
* @param {string} group Группа * @param {string} group Группа
* * @param {string|null} icon Иконка
* @return {bool} Статус выполнения * @param {function} content Функция которая будет обрабатывать содержимое макроса
*/ */
return function (group) { row(group, icon, content) {
if (typeof id === 'string' && typeof icon === 'string' && typeof core === 'object' && typeof group === 'string') {
// Пройдена проверка входных параметров
// Инициализация блока // Инициализация блока
const block = document.getElementById('block_' + group); const block = document.getElementById('block_' + group);
// Инициализация верхнего колонтинула блока // Инициализация головного элемента блока
const header = block.getElementsByClassName('page_block_header')[0]; const header = block.getElementsByClassName('page_block_header')[0];
// Инициализация элемента со статусом // Инициализация элемента со статусом
const status = header.getElementsByClassName('page_block_saved')[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]; const body = block.getElementsByClassName('settings_panel clear_fix settings_' + this.core.id + ' settings_section_' + this.core.id)[0];
settings.read(id).then(result => {
// Инициализация оболочки кнопки активации // Инициализация оболочки кнопки активации
let wrap = document.createElement('div'); const wrap = document.createElement('div');
wrap.classList.add('settings_separated_row', core.icons[icon] ?? core.icons['lightning'], 'settings_separated_row_iconed'); 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} Функция для выполнения в генераторе группы
*
* @todo 1. Добавить проверку на существование нижнего колонтинула и записывать перед ним, вместо конца блока
*/
checkbox(id, icon, name, description, hint, onchange) {
// Инициализация ядра
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 => { wrap.addEventListener("click", fn => {
// Инициализация кнопки // Инициализация кнопки
let button = wrap.getElementsByClassName('ui_toggler')[0]; const button = wrap.getElementsByClassName('ui_toggler')[0];
if (button.classList.contains('on')) { if (button.classList.contains('on')) {
// Активирована // Активирована
@ -387,67 +453,394 @@ class page {
} }
}); });
// Инициализация разделителя кнопки активации
let separator = document.createElement('div');
separator.classList.add('settings_separated_row_extra');
separator.checked = result === true || result === 1 || result === '1' ? true : false;
// Инициализация кнопки активации // Инициализация кнопки активации
let button = document.createElement('div'); const button = document.createElement('div');
button.classList.add('ui_toggler_wrap'); button.classList.add('ui_toggler_wrap');
// Инициализация элемента-иконки кнопки активации // Инициализация элемента-иконки
let checkbox = document.createElement('div'); const checkbox = document.createElement('div');
checkbox.classList.add('_ui_toggler', 'ui_toggler', '_settings_ienable'); checkbox.classList.add('_ui_toggler', 'ui_toggler', '_settings_ienable');
if (typeof onchange === 'string') checkbox.setAttribute('onchange', onchange);
settings.read(group + '_' + id).then(result => { settings.read(group + '_' + id).then(result => {
// Получены данные о значении настройки // Получены данные о значении настройки
// Запись состояния // Запись состояния
if (result) if (result) checkbox.classList.add('on');
checkbox.classList.add('on');
}); });
// Инициализация элемента-иконки кнопки активации // Инициализация элемента-иконки
let label = document.createElement('div'); const label = document.createElement('div');
label.classList.add('ui_toggler_label'); label.classList.add('ui_toggler_label');
// Инициализация названия кнопки активации // Инициализация названия
let header = document.createElement('div'); const header = document.createElement('div');
header.classList.add('settings_separated_row_text'); header.classList.add('settings_separated_row_text');
// Инициализация текста названия кнопки активации // Инициализация текста названия
let title = document.createElement('div'); const colonic = document.createElement('div');
title.classList.add('settings_separated_row_text_inner'); colonic.classList.add('settings_separated_row_text_inner');
title.innerText = name !== undefined && typeof name === 'string' ? name : id; colonic.innerText = name !== undefined && typeof name === 'string' ? name : id;
// Инициализация архитектуры // Инициализация архитектуры
button.appendChild(checkbox); button.appendChild(checkbox);
separator.appendChild(button); separator.appendChild(button);
wrap.appendChild(separator); 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') { if (description !== undefined && typeof description === 'string') {
// Получено описание // Получено описание
// Инициализация текста описания кнопки активации // Инициализация текста описания
let text = document.createElement('div'); const text = document.createElement('div');
text.classList.add('settings_separated_row_hint'); text.classList.add('settings_separated_row_hint');
text.innerText = description; text.innerText = description;
// Инициализация архитектуры // Инициализация архитектуры
title.appendChild(text); colonic.appendChild(text);
} }
// Инициализация архитектуры // Инициализация архитектуры
header.appendChild(title);
wrap.appendChild(header); wrap.appendChild(header);
// Запись в блок // Запись в блок
body.appendChild(wrap); body.appendChild(wrap);
return true; 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 Группа
*
* @return {bool} Статус выполнения
*/
return function (group) {
if (typeof id === 'string' && typeof icon === 'string' && typeof core === 'object' && typeof group === 'string') {
// Пройдена проверка входных параметров
return core.blocks.fields.macros(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 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 => {
// Получены данные о значении настройки
// Запись значения в поле
if (result) input.value = result;
});
if (typeof onchange === 'string') input.setAttribute('onchange', onchange);
if (typeof oninput === 'string') input.setAttribute('oninput', oninput);
if (typeof options === 'object' && options.length > 0) {
// Инициализация элемента-списка для выбора значений автозаполнения
const datalist = document.createElement('datalist');
datalist.id = group + '_' + id + '_datalist';
for (const option of options) {
// Перебор значений для автозаполнения поля
// Инициализация элемента со значением автозаполнения
const element = document.createElement('option');
element.setAttribute('value', option);
// Запись в список
datalist.appendChild(element);
}
}
// Инициализация элемента-иконки
const label = document.createElement('div');
label.classList.add('ui_toggler_label');
// Инициализация названия
const header = document.createElement('div');
header.classList.add('settings_separated_row_text');
// Инициализация текста названия
const colonic = document.createElement('div');
colonic.classList.add('settings_separated_row_text_inner');
colonic.innerText = name !== undefined && typeof name === 'string' ? name : id;
// Инициализация архитектуры
separator.appendChild(input);
if (typeof datalist === 'object') separator.appendChild(datalist);
wrap.appendChild(separator);
header.appendChild(colonic);
if (typeof hint === 'string') {
// Получена подсказка
// Инициализация текста-подсказки
const question = document.createElement('span');
question.classList.add('hint_icon');
question.setAttribute('data-title', hint);
question.setAttribute('onmouseover', 'showHint(this);');
// Инициализация архитектуры
colonic.appendChild(question);
}
if (description !== undefined && typeof description === 'string') {
// Получено описание
// Инициализация текста описания
const text = document.createElement('div');
text.classList.add('settings_separated_row_hint');
text.innerText = description;
// Инициализация архитектуры
colonic.appendChild(text);
}
// Инициализация архитектуры
wrap.appendChild(header);
// Запись в блок
body.appendChild(wrap);
return true;
}
);
}
return false;
};
},
/**
* Генерация HTML-элемента настройки с всплывающим списком
*
* @param {string} id Идентификатор
* @param {string|null} icon Иконка
* @param {string|null} name Название
* @param {string|null} description Описание
* @param {string|null} hint Всплывающая подсказка (иконка с вопросительным знаком возле верхнего колонтинула)
* @param {string|null} type
* @param {string|null} button
* @param {object|null} options Массив со строками для автозаполнения поля
* @param {string|null} onclick
* @param {string|null} onchange Код который выполняется после изменения состояния
* @param {string|null} oninput Код который выполняется при вводе текста
*
* @return {function} Функция для выполнения в генераторе группы
*
* @todo 1. Добавить проверку на существование нижнего колонтинула и записывать перед ним, вместо конца блока
*/
button(id, icon, name, description, hint, type = 'dropdown', value = 'Выбрать', onclick, onchange, oninput) {
// Инициализация ядра
const core = this.core;
/**
* Запись в группу (подразумевается выполнение в функции генерирующей группу)
*
* @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;
}; };