Новости

Yellow Leaf - Статті - Про сумісності Chrome-сумісних API розширень

  1. маніфест розширення
  2. об'єкт браузера
  3. BrowserAction API
  4. Notifications API
  5. Management API
  6. Каталоги розширень
  7. замість висновку

У браузера Google Chrome з самого початку його існування є досить зручне API для створення розширень. Поява великої кількості браузерів на тій же кодової базі зробило це API масовим. В результаті нове API розширень браузера Firefox під назвою WebExtensions заявлено як сумісний з Google Chrome, а в Microsoft Edge починаючи з Redstone 1 додана підтримка WebExtensions.

Здавалося б уніфікація API між браузерами повинна полегшити життя розробникам розширень, проте хороша ідея, як це часто буває, була зіпсована реалізацією. Автор цих рядків по роботі пов'язаний з розробкою одного браузерного розширення і бувально "на своїй шкурі" відчув "радість" від підтримки одним розширенням відразу декількох браузерів.

Все що написано нижче не претендує на заваніе істини в останній інстанції і є просто викладом особистого досвіду автора і, в певному сенсі, запрошенням до дискусії та обміну досвідом.

маніфест розширення

Будь-яке розширення починається з написання маніфесту. При написанні маніфесту розширення треба як мінімум вказати основний JS-файл. Для більшості браузерів опис виглядає приблизно так:

"Background": { "scripts": [ "background.js"], "persistent": false}

Однак для Microsoft Edge треба писати так:

"-Ms-preload": { "backgroundScript": "background.js"}

В якості альтернативи можна описати так:

"Background": { "page": "background.html", "persistent": true}

І вже в заголовку файлу "background.html" підключати "background.js". Цей спосіб працює у всіх браузерах, хоча для Chrome є deprecated і в майбутньому працювати перестане.

Є й інші відмінності в разрборе маніфесту різними браузерами. Крім того в Firefox є свої специфічні параметри, яких немає в інших браузерах. Наприклад гілка " applications ".

об'єкт браузера

Переходимо до розгляду власне API розширень. Розширення пишуться на javascript і велика частина логіки реалізується через виклик методів глобального об'єкта, що описує браузер. І тут розробника підстерігає перша проблема: ім'я об'єкта залежить від браузера:

  • Google Chrome: "chrome".
  • Mozilla Firefox: рекомендує використовувати "browser", проте можна використовувати і "chrome".
  • Opera: для основного функціоналу "chrome", для Opera-специфічних функцій - "opr".
  • Microsoft Edge: "msBrowser", об'єкт "chrome" ніби як доступний, але можливість його використання не досліджували в повній мірі.

Таким чином розробка розширення починається з написання "милиці" приблизно такого вигляду:

var browserObj = (function () {return window.msBrowser || window.browser || window.chrome;}) ();

Може бути на цьому відмінності закінчуються? Було б здорово, якщо так. Але на жаль відмінностей ще багато і розглянути всі в рамках невеликого матеріалу не вийде. Тому розглянемо тільки кілька характерних прикладів.

BrowserAction API

Припустимо наше розширення використовує API browserAction: кнопка на панелі браузера, при натисканні на яку з'являється спливаюче вікно з веб-сторінкою. У кнопки є глобальні властивості і властивості, прив'язані до певних вкладках. Розглянемо поведінку методу "browserObj.browserAction.setPopup" в залежності від браузера. Для початку типовий приклад використання:

var popupUrl = "popup.html"; browserObj.browserAction.setPopup ({popup: popupUrl});

Підводні камені криються в тому, як різні браузери обробляють параметр "popup" і які обмеження на нього накладають. Firefox дозволяє використовувати абсолютні і відносні шляхи. Причому можливе використання як вбудованих в розширення сторінок, так і зовнішніх URL. У Chrome і Opera можливо тільки використання внутрішніх сторінок.

Якщо спробувати вказати не абсолютний шлях до сторінки, а відносний то і тут є відмінності в поведінці: в Chrome і Opera відносні шляхи вважаються від кореневої директорії розширення, а в Firefox - від директорії, в якій розташований зазначений у маніфесті "background.html". Таким чином якщо у нас в маніфесті є такі рядки:

"Background": { "page": "html / background.html", "persistent": true}

А в коді такі:

var popupUrl = "popup.html"; browserObj.browserAction.setPopup ({popup: popupUrl});

Те для Chrome і Opera це буде еквівалентно:

var popupUrl = browserObj.runtime.getURL ( "popup.html"); browserObj.browserAction.setPopup ({popup: popupUrl});

А для Firefox:

var popupUrl = browserObj.runtime.getURL ( "html / popup.html"); browserObj.browserAction.setPopup ({popup: popupUrl});

Ще цікавіша ситуація буде якщо спробувати в якості "popupUrl" вказати абсолютний URL. Наприклад так:

var popupUrl = "http://ya.ru"; browserObj.browserAction.setPopup ({popup: popupUrl});

Firefox тут відпрацює нормально і відкриє вказаний URL у спливаючому вікні. А ось Chrome і Opera розкриють це так:

var popupUrl = browserObj.runtime.getURL ( "http://ya.ru"); browserObj.browserAction.setPopup ({popup: popupUrl});

Ну і зрозуміло ніякої зовнішній URL відкритий не буде. Виходить що розробники Firefox даючи розробнику розширення додаткові можливості порушили сумісність з Google Chrome.

Notifications API

У певних ситуаціях розширення може показувати сповіщення користувачеві використовуючи API notifications. Це API підтримується у всіх браузерах, але більша частина розширених опцій доступна тільки в Google Chrome. Хороша таблиця сумісності є в документації від розробників Mozilla.

На окрему увагу заслуговує той факт що браузер Opera при вказівці підтримуються опцій генерує помилку. Наприклад ви хочете показати оповіщення і на ньому ж кнопку налаштувань, щоб користувач міг відключити оповіщення надалі. Ви пишіть приблизно такий код:

chrome.notifications.create ( "checkfail", type: "basic", iconUrl: chrome.extension.getURL ( "data / plugin_logo.png"), title: chrome.i18n.getMessage ( "pluginTitle"), message: chrome. i18n.getMessage ( "checkFail", check_info), buttons: [{title: chrome.i18n.getMessage ( "notifyButtonSettings"), iconUrl: chrome.extension.getURL ( "data / notify_icon_settings.png")}]});

У Google Chrome все відмінно працює, а ось в Opera цей код призводить до помилки і наступні інструкції не виконуються, що може бути критично.

Management API

Ще одна цікава тема пов'язана з ідентифікаторами розширень. Припустимо що наше розширення має відомі проблеми при роботі з деякими іншими розширеннями. За ідеєю тут на допомогу повинен прийти management API, за допомогою якого можна перевірити наявність в браузері розширень з певними ідентифікаторами. Однак і тут є нюанси:

  1. Ідентифікатори розширенням присвоюються каталогами розширень і різняться від браузера до браузеру.
  2. Яндекс.браузер дозволяє ставити розширення як з Opera Addons, так і з Chrome Webstore. Відповідно в разі яндекс.браузер треба перевіряти два набору ідентифікаторів.
  3. Firefox через management API дозволяє управляти тільки темами, але не розширеннями. Та й для тих повертати не ідентифікатори з каталогу розширень, а згенеровані випадковим чином і актуальні тільки для поточної інсталяції браузера.

Відповідно універсального способу перевірки наявності певного розширення в системі немає. Для більшості розширень це не є проблемою, але в деяких ситуаціях це сильно ускладнює життя розробнику.

Каталоги розширень

Ну і якщо вже ми торкнулися теми каталогів розширень то значить пора розглянути їх докладніше, тим більше що більшість розширень в результаті пишуться для публікації у відповідних каталогах.

І тут теж є деякі відмінності, які слід мати на увазі:

  • Chrome Webstore: автоматична модерація протягом години, якихось особливих вимог до коду немає. Заливається звичайний zip-архів з файлами розширення.
  • Mozilla Addons: ручна модерація від години до тижня. Обфусцірований JS НЕ заборонений, але модератору необхідно надати исходник і інструкцію по збірці. Заливається звичайний zip-архів з файлами розширення.
  • Opera Addons: ручна модерація від доби до чотирьох місяців (можливо і довше, але автор цих рядків з великими термінами не стикався). Обфусцірований JS заборонений. Заливається звичайний zip-архів з файлами розширення.
  • Windows Store: сильно ускладнена збірка: необхідно використовувати NodeJS з модулями, доступними тільки для Windows, і далі ЕЦП за допомогою вбудованої в Windows утиліти ( Детальніше ).

Резюмуючи обмеження каталогів розширень:

  • Якщо є необхідність обфусціровать код то від підтримки Opera доведеться відмовитися. Плюс будуть додаткові складності з Firefox.
  • Повільність модераторів Opera позбавляє розробників можливості оперативно доставляти поновлення користувачам цього браузера.
  • Необхідність використання специфічних для windows інструментів для збірки розширення перед публікацією в Windows Store автоматично вимагає наявності ліцензії на відповідну ОС і ускладнює роботу користувачам інших ОС.
  • З огляду на ринкову частку Microsoft Edge і складність збирання розширень для публікації ряду розробників простіше буде відмовитися від моддержкі цього браузера.

замість висновку

Відмінностей і не відповідностей в реалізаціях вобщем-то схожих API дуже багато і детально розглядати їх все безглуздо. Важливо що відзначити сам факт їх існування. Радує що розробники Mozilla у своїй документації призводять таблиці сумісності хоча б для основних браузерів, проте це не відміняє необхідності ретельно тестувати роботу розширення у всіх браузерах, для яких планується підтримка.

Хоча подібна сегментація і ускладнює розробку розширень, автор цих рядків сподівається що з часом ситуація вирішитися сама собою: непопулярні API відімруть, у популярних основні особливості стабілізуються і стануть однаковим у всіх браузерах, а відмінності залишаться лише в зовсім дрібних деталях, не критичних для більшості розробників .

Уважаемые партнеры, если Вас заинтересовала наша продукция, мы готовы с Вами сотрудничать. Вам необходимо заполнить эту форму и отправить нам. Наши менеджеры в оперативном режиме обработают Вашу заявку, свяжутся с Вами и ответят на все интересующее Вас вопросы.

Или позвоните нам по телефонам: (048) 823-25-64

Организация (обязательно) *

Адрес доставки

Объем

Как с вами связаться:

Имя

Телефон (обязательно) *

Мобильный телефон

Ваш E-Mail

Дополнительная информация: