Делаем свое расширение для Firefox. Часть II. В которой работаем с пользовательскими настройками адд
function saveSettings()
{
var scriptAddr = document.getElementById("script").value;
scriptAddr = scriptAddr.trim();
if (scriptAddr != "")
{
if (window.confirm('Save script address ' +
scriptAddr + '? Are you sure?'))
{
browser.storage.local.set({
server_settings: {script_addr: scriptAddr}
});
window.alert('Settings saved!');
}
else
{
document.getElementById("script").value = curAddr;
}
}
}
Что тут делается:
1. Сначала в переменную
scriptAddr
записывается значение текстового поля с id=script
, т.е. того поля, куда можно ввести адрес скрипта.2. Функцией
trim()
обрезаем начальные и конечные пробелы, вдруг их пользователь навводит.3. Если
scriptAddr
не пустая строка, то запрашиваем у пользователя подтверждение сохранения функцией window.confirm()
Функция выведет на экран окошко с текстом, заданным в качестве ее аргумента и кнопками "Да" и "Нет". Если нажата "Да", функция вернет true
, если "Нет" - false
.
Подробности: "Взаимодействие: alert, prompt, confirm"
4. Если отвечено да, то пользуемся API Firefox'а, а именно функцией
browser.storage.local.set(object)
, которой, в данном случае, передается объект, содержащий объект server_settings
, содержащий единственный параметр script_addr
. Значение script_addr
устанавливаем из переменной scriptAddr
. Далее сообщаем пользователю, что настройки сохранены (window.alert('Settings saved!');
)Подробности и примеры работы с локальным хранилищем: StorageArea.get()
5. Если было отвечено "Нет", то восстанавливаем значение текстового поля:
document.getElementById("script").value = curAddr;
В конце js-файла, после всех функций, подключаем обработчик события (слушатель) для события "click" кнопки с id ==
save
:document.getElementById("save").addEventListener("click", saveSettings);
Внимание! Функции
addEventListener
имя функции-обработчика передается без круглых скобокdocument.getElementById("save").addEventListener("click", saveSettings()); //неправильно
Если добавить скобки, то код функции
saveSettings
просто однократно выполнится, когда дойдет очередь до addEventListener
Да, ошибка детская, но искать потом концы довольно муторно.
Если на странице
about:debugging
нажать кнопку "Исследовать" рядом с нашим расширением, то откроется инструментарий отладки:
Можно сразу же перейти в отладчик и нажать ESC, что откроет консоль внизу.

В отладке всплывающих окон есть одно неудобство. Если в процессе куда-то кликнуть, то окно закроется, а весь код, вывод отладочной консоли и прочее скроются, и все опять придется отлаживать сначала. Это можно предотвратить, кликнув по меню из трех точек в правом верхнем углу, и выбрать пункт "Отключить автоскрытие всплывающих окон".

Рекомендую делать это временно, после выбора пункта сразу начать отладку, и никуда со вкладки инструментария отладки особо не уходить, потому что автоскрытие отключается у всего и везде глобально (само меню после отключения автоскрытия свернется обратно в три точки). Я так по неопытности куда-то накликал и завесил весь браузер с концами, хорошо, тестовый профиль создал. Пришлось потом искать именно этот профиль в Process Explorer, чтоб аккуратно прибить.
Очень полезной командой является
console.log (что_вывести_на_консоль);
С ее помощью удобно выводить значения переменных, вставив ее в нужное место в коде. Установим слушатель на событие
DOMContentLoaded
объекта document
. Событие срабатывает, когда весь документ загружен и разобран браузером, т.е. страница окончательно загрузилась и отображена.document.addEventListener('DOMContentLoaded', bodyLoad);
Создадим функцию
bodyLoad
:function bodyLoad()
{
loadSettings();
}
В ней пока вызывается одна функция -
loadSettings
:function loadSettings()
{
var gettingItem = browser.storage.local.get('server_settings');
gettingItem.then(onGot, onGotError);
}
В ней мы вызываем функцию
browser.storage.local.get
с параметром, в котором говорим ей, что искать.Подробности и примеры работы с локальным хранилищем: StorageArea.get()
А вот возвращает нам функция не объект, что казалось бы логично, а промис - объект, представляющий результат завершения асинхронной операции.
Очень советую почитать ниже по ссылке подробности про промисы, и постараться хотя бы частично понять, как это работает, потому что javascript в отличии от нормальных языков типа C#, PHP или хоть bash с perl, очень любит эту самую асинхронность, и промисы далее полезут пачками, даже в таком, казалось бы, несложном проекте.
Подробности: Использование промисов
Но сейчас и правда ничего сложного делать не придется. С помощью ключевого слова
then
передаем две функции. Одна сработает, если произойдет какая-то ошибка, а во второй будем обрабатывать успешный результат.Обработка ошибки:
function onGotError(error)
{
window.alert(`Error: ${error}`);
}
Получение настройки:
function onGot(item)
{
if (isEmptyObject(item))
{
curAddr = defAddr;
}
else
{
if (item.server_settings.script_addr == '')
{
curAddr = defAddr;
}
else
{
curAddr = item.server_settings.script_addr;
}
}
document.getElementById("script").value = curAddr;
}
1. Если объект пустой, присваиваем текущему адресу адрес по умолчанию.
2. Если нет, проверяем не является ли поле объекта
item.server_settings.script_addr
пустой строкой. Да, поступаем, как в пункте 1.3. Если строка не пустая, присваиваем текущему адресу значение
item.server_settings.script_addr
.4. Записываем значение текущего адреса в текстовое поле с id
script
:document.getElementById("script").value = curAddr;
Устанавливаем слушатель на событие "click" кнопки с id
restore
:document.getElementById("restore").addEventListener("click", restoreDefaults);
function restoreDefaults()
{
if (window.confirm('Restore defaults?'))
{
curAddr = defAddr;
document.getElementById("script").value = defAddr;
browser.storage.local.set({
server_settings: {script_addr: defAddr}
});
}
}
1. Спрашиваем у пользователя подтверждение с помощью
window.confirm
.2. Присваиваем адрес по умолчанию текущему адресу и текстовому полю с id
script
3. Используем
browser.storage.local.set
, чтобы сохранить значение.Начало
Продолжение
Это репост с сайта http://tolik-punkoff.com
Оригинал: http://tolik-punkoff.com/2019/10/02/dela