Разработка расширений для Safari от А до Я
Одним из нововведений, которое ожидало пользователей с выходом Safari 5 стала поддержка браузером расширений. Позже Apple запустила галерею расширений. Отметим, что Safari одним из последних среди популярных браузеров обзавелся поддержкой «экстеншенов» — Chrome и Firefox уже давно радуют своих пользователей плагинами. В этой статье речь пойдет о разработке расширений для Safari 5.
Для начала стоит понять «сферы влияния» расширений — это может быть тулбар, отдельная панель или же пункт в контекстном меню, которое открывается при правом клике мыши. Так же доступна возможность изменять веб-страницы.
Следовательно расширения Safari 5 не могут изменять панель инструментов браузера, затрагивать строку состояния и некоторые другие вещи, которые недоступны javascript. Таким образом выходит, что система расширений сафари ближе к Chrome, чем Jetpack или аддонам Firefox. И неудивительно, что портировать расширения хрома на сафари проще всего — некоторые разработчики это делают всего за 12 часов.
Каждое разрабатываемое расширение нужно подписывать своим сертификатом разработчика, который вам выдает Apple. Участие в программе разработчиков дополнений к Safari, она называется Safari Developer Program, бесплатное. После регистрации в сайдбаре справа можно будет перейти на страницу запроса сертификата.
Создаем файл запроса на сертификат в Keychain Access (Связка ключей), программа находится в «Утилитах»:
Созданный файл загружаем на портал разработчиков, для нас генерируется сертификат.
Загружаем сгенерированный сертификат.
После загрузки двойным кликом устанавливаем сертификат в Keychain Access. Готово!
Чтобы работать с расширениями необходимо включить их поддержку в Safari. Для этого пройдите в меню Safari → Настройки → Расширения и включите поддержку расширений. Так же во вкладке настроек «Дополнения» отметьте пункт Показать меню «Разработка» в строке меню.
Физически каждое расширение представляет из себя папку с расширением *.safariextension, в которой находится XML-подобный файл info.plist (метаданные вроде копирайта и версии расширения) и сами файлы расширения:
- «Глобальный» файл HTML, который загружается в память и исполняется Safari 5 при запуске установленного расширения.
- Файлы HTML, CSS, и javascript, которые задают разметку, стиль и вид тулбара расширения.
- Файлы CSS и javascript, которые могут модифицировать веб-страницу. Для таких файлов в info.plist задается домен сайта, с которым и будет проводиться модификация.
- Картинки, которые могут использоваться в тулбаре расширения или при модификации веб-страниц.
- Файл icon.png для иконки расширения, он будет отображаться в настроках сафари в разделе расширений.
- Файл settings.plist задает настройки расширения.
- Файлы HTML, но в принципе в них может быть что угодно, будь-то PDF с возможностью развернуть на весь экран или iframe.
В Safari 5 встроен удобный Конструктор расширений (Extension builder), он доступен через меню Safari → Разработка → Показать Конструктор расширений. Встроенный конструктор избавит вас от редактирования файлов info.plist и settings.plist, назначения глобальных файлов и другой «административной» работы. Вы сможете полностью концентрироваться на разработке расширения.
Взаимодействие между браузером и расширением происходит по нижеследующей схеме. Обратите внимание на компоненты расширения и порядок взаимодействия между ними:
Компоненты расширения очень хорошо изолированы друг от друга, это сделано в угоду безопасности.
Например, в файлах, отвечающих за дизайн тулбара вы не сможете вызвать какую-нибудь «плохую» функцию. В тоже время Apple позволяет использовать несколько proxy-объектов для связи между компонентами расширения.
Общение компонентов между собой происходит через специальную модель «вещателей-слушателей». Глобальный javascript (который используется в глобальной странице или тулбаре расширения) регистрирует сообщения в объекте safari.application. В свои скрипты вы можете добавить «метод-слушатель» через объект safari.self.tab для «прослушки» сообщений. Когда сценарию необходимо отправить сообщение другому компоненту, он сделает это при помощи специальной функции, которая передаст само сообщение и идентификатор (ключ).
Важно помнить, что когда вы в своем коде регистрируете «слушателя» сообщений, то он будет получать все сообщения, которые перенаправляются внутри расширения независимо от их назначения. Вот тут-то и пригодится идентификатор, который позволит определить кому предназначено сообщение. В качестве самого самообщения может выступать любая информация, но как правило это строка, либо массив с данными, которые вы получили в другом компоненте расширения.
Когда вы отправляете сообщение на объект tab proxy (см. рис. выше), то оно транслируется на все методы, которые прописаны в глобальных скриптах и тулбаре расширения и наоборот, — когда отправляете сообщение на объект webpage proxy, то сообщение транслируется на все методы-слушатели в ваших сценариях скриптов для изменения веб-страницы. Эта связь отмечена на схеме выше голубыми стрелками, область Extension.
Возможно, сначала такая система сообщений покажется вам сложной и непонятной, но она вполне естественна и работает хорошо. По прошествии небольшого времени вы привыкнете и оцените ее по достоинству. Однако, как и положено без ложки дегтя не обошлось — такая система proxy-объектов затрудняет работу с DOM, даже для обычного чтения придется извертется.
Глобальная HTML страница не обязательна, но она очень полезна если ваше расширение работает с контекстным меню или тулбаром. Такая страница загружается только однажды во время запуска браузера, либо при включении расширения в меню Safari или обновлении расширения. Глобальная страница не имеет доступа к веб-страницам, открытым в браузере, но она имеет доступ к API объекта safari.application. Если вам требуется, чтобы глобальная страница могла влиять на веб-сайты, то нужно использоваться систему сообщений, в своиих скриптах модификаций веб-страниц прописать соответствующие методы.
Глобальная страница никогда не видна пользователю и работает в фоне. Обычно она выполняет роль хаба между компонентами расширения — кнопки в тулбаре, пункты в контекстном меню могут отправлять сообщения глобальной странице, а та в свою очередь может отправлять сообщения скриптам для изменения содержимого веб-страниц.
Наверняка у вас уже появилась вопрос об отладке данной странице, ведь ее невозможно посмотреть через браузер. В конструкторе расширений, о котором я писал выше, есть возможность открыть глобальную страницу и провести отладку javascript.
Такие скрипты и стили CSS позволяют влиять на отображение конкретных веб-страниц. Команда разработчиков Safari предприняла неимоверные усилия, чтобы разработчикам расширений не пришлось писать слишком много кода. Например, для корректной работы вашего кода автоматически используется скрытое пространство имен (namespace), такой подход позволяет избежать некоторые конфликты.
CSS позволяет переопределить любые стили, заданные ранее на веб-странице. Таким образом через расширения вы можете менять внешний вид любых сайтов как угодно.
При помощи конструктора расширений можно указать когда нужно загружаться вашим JS/CSS — до загрузки стилей и скриптов веб-страницы или после. Стоит с особой осторожностью использовать такие возможности, особенно при размещении своих скриптов до загрузки скриптов веб-страницы. Могут возникнуть ситуации с бесконечным циклом, когда скрипты будут загружать сотни и тысячи раз «вешая» Safari. Так же обращайте внимание на iframe, они тоже могут заставить Safari загрузить скрипты заново.
Не пытайтесь «запхнуть» в расширение какой-нибудь JS-фреймворк. Множество кода только хзамедлит работу браузера — при открытии нового окна, вкладки или обновления страницы код каждый раз будет выполняться. К тому все возможности фреймворка вы использовать врят ли будете. Правильнее написать новый, чистый и оптимизированный под Webkit код.
Так же стоит учитывать, что ваш JS может работать только с тем доменом, который открыт в браузерер. Открыв Lapplebi.com, вы не сможете сделать XHR запрос на google. В таких случаях стоит воспользоваться глобальной страницей. В JS для модификации веб-страниц рекомендуется размещать код только для модификации тех самых страниц, минимум кода и это обеспечит быструю работу расширения — изменение внешнего вида, получение данных и манипуляций данными страницы, не более. К тому же ваши сценарии не будут иметь доступа к safari.application и будут серьезно ограничены в возможностях за пределами DOM.
- Дата: 25-06-2016, 21:36