#javascript #notifications #service-worker #firefox-addon-webextensions #proxy-pattern
#javascript #уведомления #service-worker #firefox-addon-webextensions #прокси-шаблон
Вопрос:
Я хотел бы создать расширение для браузера, которое по своей сути проксирует registration.showNotification
функцию фильтрации на основе правил, установленных в аддоне. Проксирование window.Notification
тривиально, но у меня возникают проблемы даже с решением проблемы. Я знаю, что могу получить регистрацию работника службы, но переназначение showNotification
не кажется постоянным и, похоже, на самом деле не работает, за исключением случаев, когда я вызываю функцию через консоль.
Моя идея «последнего средства» (которая кажется сложной) — перехватывать и изменять входящие запросы для изменения showNotification
функции через window.postMessage
или что-то подобное — но я хочу, чтобы это было последним средством.
Есть ли какой-либо мыслимый способ сделать то, что я пытаюсь сделать здесь? Или, может быть, API, которого мне не хватает? Основываясь на моих исследованиях, пока я предполагаю, что нет. Я не самый опытный специалист в области JS, поэтому я подумал, что попробую ответить на этот вопрос. Я использую Firefox, если это имеет значение.
Комментарии:
1. какую версию Firefox вы используете?
showNotification
не работает до FF78
Ответ №1:
В магазине дополнений Firefox есть аналогичное расширение Service Worker Control, и вы можете найти его источник здесь, под лицензией MPL.
Теперь, более конкретно, я понимаю, что вы хотите перехватить или изменить showNotification
функцию, что может быть достигнуто с помощью чего-то похожего на приведенный ниже код (фрагмент, адаптированный из приведенного выше источника):
const showNotification_backup = ServiceWorkerRegistration.prototype.showNotification
function showNotification(title, options) {
const obj = { type: 'notification', isInjected }
try {
const sw = this.installing || this.waiting || this.active
obj.url = typeof sw === 'object' amp;amp; sw ? '' sw.scriptURL : undefined
} catch { }
try { obj.scope = '' this.scope } catch { }
try { obj.title = '' title } catch { }
try { obj.body = '' options.body } catch { }
send(obj)
return showNotification_backup.apply(this, arguments)
}
if (setupCondition) {
ServiceWorkerRegistration.prototype.showNotification = showNotification
} else {
exportFunction(showNotification, ServiceWorkerRegistration.prototype,
{ defineAs: 'showNotification' })
}
где exportFunction
является частью XPCOM API, таким образом изменяя прототип ServiceWorker.
Редактировать
Как упоминалось в комментариях, XPCOM
устарел и почти полностью устарел, оставляя вам только изменение прототипа регистрации service worker, как показано ниже:
let registrations = await navigator.serviceWorker.getRegistrations()
if (registrations.length > 0) {
Object.getPrototypeOf(registrations[0]).showNotification = showNotification
}
Это действительно напрямую изменяет метод цепочки прототипов, что не является хорошей практикой JS, однако, учитывая, что данная showNotification
функция применяет аргументы к исходной, она несколько расширяет ее.
Комментарии:
1. «XPCOM больше не доступен для использования расширениями Firefox. Вместо этого используйте WebExtensions. » Как неудачно!