Толик Панков
hex_laden
............ .................. ................
November 2020
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30

Толик Панков [userpic]
Делаем свое расширение для 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/delaem-svoe-rasshirenie-dlya-firefox-chast-ii-v-kotoroj-rabotaem-s-polzovatelskimi-nastrojkami-addona/