RReverser's

Ingvar Stepanyan

JavaScript developer, speaker and reverse engineer. D2D programmer. Sometimes human.


Эмуляция фич IE9 в Opera

Доброго времени суток!

Трудные времена прошли, и, после долгих препираний, меня таки уговорили написать топик о своем расширении для Opera.

Итак, с чего же все началось. В Internet Explorer 9 появилось несколько интересных фич, которые меня как любителя альтернативных браузеров сильно задели. Одна из таких — Site Pinning (возможность закреплять страницы вместе с собственными меню на таскбаре Windows 7 и впоследствии открывать их, получать на них уведомления с сайтов в виде изменения фавиконов и прочее).

Разумеется, для реализации такой функции без нативной поддержки браузера не обойтись, но все же хотелось сделать эмулятор, который выжмет с этих возможностей сайта максимум.

Как это сделано «у них»

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

  • <meta name="application-name" content="IE9 Demos"/>
    Название приложения
  • <meta name="msapplication-tooltip" content="IE9 Demos Tooltip"/>
    Всплывающая подсказка
  • <meta name="msapplication-starturl" content="http://mywebsite.ru/"/>
    Стартовая страница
  • <meta name="msapplication-task" content="name=New Tweet;action-uri=http://twitter.com/home;icon-uri=images/ie/tweet.ico" />
    Пункт меню (по одному такому тегу на описание каждого пункта меню; здесь name — текст пункта меню, action-uri — собственно ссылка, icon-uri — иконка)

Понятно, что парсинг этих мета-тегов и представление структуры меню не составляет труда. Немного также придется повозиться на стороне яваскрипта. Для управления нам понадобятся следующие методы window.external:

  • msIsSiteMode — определяет, является ли сайт закрепленным, и, соответственно, можно ли ним управлять с помощью яваскрипта; установим в нашем расширении это значение всегда в true
  • msSiteModeCreateJumplist — создает группу меню
  • msSiteModeClearJumplist — очищает lbyfvbxtcrb добавленные группы
  • msSiteModeAddJumpListItem — добавляет пункт меню
  • msSiteModeSetIconOverlay — добавляет оверлей для иконки страницы, например, иконку сообщения; в нашем случае он будет просто временно заменять фавикон
  • msSiteModeAddThumbBarButton — добавляет кнопку для управления содержимым на сайте (например, для проигрывания медиа)
  • msSiteModeUpdateThumbBarButton — динамически определяет активность и видимость кнопки
  • msSiteModeAddButtonStyle — создает «стиль», который определяет иконку и подсказку для кнопки
  • msSiteModeShowButtonStyle — применяет созданный стиль для кнопки

Разработка

Пускай расширение будет в виде всплывающего окна, которое будет отображать структуру меню и элементы управления для открытых вкладок. Также должна быть возможность закреплять меню для последующего доступа к ним даже при закрытых сайтах.

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

(function () {  
    opera.contexts.toolbar.addItem(opera.contexts.toolbar.createItem({
        title: 'LikeIE9',
        icon: 'icon18.png',
        popup: {
            href: 'popup.html',
            width: 270,
            height: 350
        }
    }));
    var connCount = 0;
    opera.extension.onconnect = function (event) {
        event.source.postMessage({
            name: 'new',
            content: connCount++
        })
    };
    opera.extension.onmessage = function (event) {
        opera.extension.broadcastMessage(event.data)
    };
})()
Как можно увидеть, сообщения имеют структуру {name: «название сообщения (тип), content: „содержимое“, ну и дополнительные поля при необходимости}
Также фоновый скрипт будет служить ретранслятором сообщений, полученных от всех привязаных к нему скриптом (popup-а и встроенных), так как все другие скрипты могут общаться напрямую только с ним.

Встроенный скрипт получился побольше по размеру, но функции его довольно просты — парсинг вышеописанных meta-тегов, создание html-кода раздела в меню popup-а и эмуляция объекта window.external с также вышеописанными функциями для обеспечения динамического управления меню, добавления элементов управления (кнопок), а также изменения иконки страницы.

Наконец, в собственно всплывающем окне происходит получение сообщений со сгенерированными html-кодами разделов меню от встроенных скриптов, сохранение/удаление этих самых разделов в localStorage при нажатии на соответствующую галочку, а также первичная обработка нажатий (уведомление контент-скрипта) на созданные элементы управления.

Должен также заметить, что „опрос“ контент-скриптов происходит при вызове всплывающего окна. Это было сделано для учета динамически созданных элементов, а также открытия/закрытия вкладок.

Результат

Итак, само расширение доступно здесь: https://addons.opera.com/addons/extensions/details/likeie9/. На момент опубликования статьи его количество закачек превысило 14k, что, думаю, неплохо для первого раза.

Потестировать можно на любых поддерживаемых сайтах — например, на нашем Хабре или же на официальных примерах от Microsoft.

Ниже некоторые скрины:

В общем пока все, если есть любые вопросы/замечания — обращайтесь, с радостью отвечу.

comments powered by Disqus