Internet Explorer 9: Секреты Pinned Sites

В предыдущих заметках я писал о дилеме между веб-приложениями и десктопными и почему IE9 – это хорошо, а также о том, что такое закрепленные (PinnedSites) и какая от них польза. Сегодня мы займемся техническими деталями.

Website-cсылки

Начнем с самих привязанных иконок. Что они собой представляют? Технически, они похожи, на обычные файлы веб-ссылок (.url) только с расширением .website и несколько другим наполнением. Внутри это текстовый файл, правда, его содержание вам наврядли много расскажет.

В свойствах вы можете отредактировать ссылку на стартовую страницы, всплывающую подсказку и поменять иконку:

Если залезть в реестр, можно узнать, что для запуска файлов .website (HKEY_CLASSES_ROOT\Microsoft.Website) запускается обычный IE9, но со специальными параметрами: "C:\Program Files\Internet Explorer\iexplore.exe" -w "%l" %*

Собственно, это все. Двигаемся дальше.

Настройки по умолчанию

По умолчанию привязанный (или закрепленный) сайт берет свои настройки непосредственно с той страницы, которую вы пытаетесь закрепить:

  • Название закрепленного сайта берется из названия страницы (head à title);
  • В качестве стартовой страницы берется текущая страница;
  • В качестве иконки берется favicon сайта;
  • Цвет для кнопок берется на основании анализа иконки — выделяется характерный цвет.

Такой набор настроек позволяет закрепить любой сайт и получить минимальную кастомизацию без каких бы то ни было действий со стороны владельца сайта.

Впрочем, это не всегда дает хороший и ожидаемый результат. Если проблемы с названием и стартовой страницей очевидны, то с иконкой и цветом все несколько хитрее.

Прежде всего, обычно иконки для страницы делаются размером 16x16px, не больше. Так как системные иконки Windows несколько большего размера (если не выставлено обратное), то для создания нужного размера у иконки появляется белый фон:

Аналогичные вещи происходят в панели задачи:

При этом, так как цвет для кнопок подбирается автоматически как максимально представленный в иконке, иногда получаются интересные неожиданные результаты:

Причем, обратите внимание, иконка слева от кнопок тоже имеет белую подложку.

Хорошая новость заключается в том, что все это легко поправимо.

Настройки Pinned Sites

Все настройки закрепленных сайтов можно разделить на две группы: статичные и динамичные. Первые настраиваются с помощью соответствующих тегов в заголовке страницы, вторые — с помощью JavaScript.

К статичным относятся:

  • Название приложения
  • Текст подсказки (tooltip)
  • Стартовая страница
  • Иконки
  • Цвет кнопок
  • Задачи всплывающего меню JumpList

Характер задания статичных настроек предполагает, что они будут меняться не очень часто. Но вы можете их поменять в любой момент, просто изменив соответствующие параметры на сайте — после перезагрузки приложения пользователь увидет обновленные настройки.

К динамичным относятся:

  • Название дополнительной категории ссылок и ее содержание
  • Всплывающие иконки веб-приложения
  • Активация иконки веб-приложения
  • Кнопки на превью веб-приложения в панели задач

Динамичные настройки задаются и меняются непосредственно в ходе работы приложения, то есть при открытом привязанном сайте. Категория и ее содержание остаются доступными и после закрытия приложения.

Начнем с базовых статичных настроек.

Базовые настройки

Базовые настройки задаются полностью с помощью meta- и link-тегов в заголовке страницы. Их нужно прописывать на всех страницах, с которых предполагается возможность загрепления сайта.

Название приложения. Название приложения используется при именовании иконки приложения и в качестве названия стартовой ссылки в меню JumpList. Если оно не задано, используется заголовок текущей страницы.

<meta name="application-name" content="IE9 Demos"/>

Текст подсказки. Подсказка показывается при наведении мыши на иконку в файловой системе и в стартовом меню (оно же Start, Пуск).

<meta name="msapplication-tooltip" content="IE9 Demos Tooltip"/>

Стартовая страница. Именно эта страница открывается при клике на иконку приложения. Допускаются адреса, требующие соединения по http, https и ftp. Если не указано, используется адрес текущей страницы.

<meta name="msapplication-starturl" content="http://mywebsite.ru/"/>

Цвет кнопок. Для задания цвета можно использовать как именованные значения, так и шестнадцатеричные (точно также как в CSS). Если цвет не задан, используется характерный цвет иконки.

<meta name="msapplication-navbutton-color" content="blue"/> 

Начальный размер окна. Для закрепленного сайта можно установить начальный размер окна браузера, в котором он будет открываться. Если пользователь самостоятельно изменит размеры окна, запомнится именно его выбор. Также учтите, что задается именно размер окна, а не сайта за вычетом рамки браузера.

<meta name="msapplication-window" content="width=800;height=600"/>

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

<link rel="shortcut icon" type="image/x-icon"     

      href="https://localhost:16435/favicon.ico" />

<link rel="icon" type="image/ico" href="favicon.ico">

На этом базовые настройки заканчиваются, а иконки мы рассмотрим несколько подробнее.

Подготовка иконок

Для того, чтобы задать обычную иконку сайта (favicon) достаточно подготовить одну картинку размером 16x16px. Если же переходить к закпрелению сайтов в операционной системе, то здесь такой маленькой картинки оказывается недостаточно.

В идеальном случае под сайт нужно подготовить несколько иконок разного размера, которые будут использовать в разных обстоятельствах:

  • 16х16 — для обычной favicon сайта, которая используется в адресной строке, на вкладке, и рядом со ссылкой на стартовую страницу в меню JumpList;
  • 24x24 — используется слева от кнопок ß/à, если не задана масштабируется иконка 32x32, если и этой нет — будет использована 16x16 на белой подложке;
  • 32х32 — используется в панели задач;
  • 48х48 и выше — используется в файловой системе (рабочий стол, проводник).

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

Также, в зависимости от используемого разрешения экрана используемый размер иконки может несколько варьироваться:

При подготовке иконок не забудьте о прозрачности. Рекомендую использовать 32-битную версию, в которой есть отдельный alpha-канал.

При подготовке иконок для JumpList, превью и всплываюших иконок правильный размер — 16х16px, при необходимости также используйте прозрачность.

СтруктураJumpList

JumpList — это всплывающее контекстное меню для приложений и сайтов, закрепленных в панели задач. Доступно по нажатию правой кнопки мыши или если потянуть иконку вверх.

Внутри меню состоит из нескольких блоков:

  • Системные команды. Включает закрытие окна, привязку и отвязку приложения, стартовую ссылку приложения. Вы можете задать как саму ссылку, так и текст названия и иконку.
  • Браузерные команды. Доступна только одна команда — открыть сайт в приватном режиме.
  • Задачи. Ссылки на основные разделы сайта или важные ресурсы, к которым вы хотите предоставить пользователям наиболее быстрый доступ. Вы можете задать до 5 команд.
  • Категории. Ссылки на дополнительные разделы или ресурсы сайта, могут динамически обновляться средствами JavaScript. Вы можете задать только одну категорию, а в ней до 20 ссылок.

Для задач и категорий вы задаете текст, ссылку и иконку.

Добавление задач в JumpList

Задачами в JumpList могут быть ссылки на основные разделы вашего ресурса или важные для пользователя функции вашего приложения, например, это могут быть ссылки на профайл пользователя или его личный ящик сообщений. Это может быть ссылка на поиск по сайту или свежие новости.

Всего вы можете добавить до 5-ти задач. Нажатие на каждую из задач будет приводить к открытию новой вкладки с соответствующей ссылкой.

Для добавления задач нужно использовать meta-тег следующего формата:

<meta name="msapplication-task"      

      content="name=Task 1;action-uri=http://host/Page1.html;

               icon-uri=http://host/icon1.ico" />

<meta name="msapplication-task"

       content="name=Task 2;action-uri=https://microsoft.com/Page2.html;

               icon-uri=http://host/icon2.ico" />

Ссылки не обязаны быть в одном домене. Задачи добавляются в меню в том же порядке, в котором они указаны на странице. Для каждой задачи вы можете определить свою собственную иконку.

Вот так, например, выглядит задание задач на странице Twitter:

<meta name="msapplication-task"

       content="name=New Tweet; action-uri=http://twitter.com/home;

                icon-uri=images/ie/tweet.ico" />

<meta name="msapplication-task"

       content="name=Messages; action-uri=http://twitter.com/inbox;

                icon-uri=images/ie/dm.ico" />

<meta name="msapplication-task"

       content="name=Mentions; action-uri=http://twitter.com/replies;

                icon-uri=images/ie/mentions.ico" />

<meta name="msapplication-task"

       content="name=Favorites; action-uri=http://twitter.com/favorites;

                icon-uri=images/ie/fav.ico" />

<meta name="msapplication-task"

       content="name=Search; action-uri=http://search.twitter.com;

                icon-uri=images/ie/search.ico" />

И совершенно аналогично список задач для Bing:

<meta name="msapplication-task"

       content="name=Weather;action-uri=/weather/?FORM=IE0006;

               icon-uri=/fd/s/a/sm_weather.ico" />

<meta name="msapplication-task"

       content="name=Finance;action-uri=/finance/?FORM=IE0006;

               icon-uri=/fd/s/a/sm_finance.ico" />

<meta name="msapplication-task"

       content="name=News;action-uri=/news/?FORM=IE0006;

               icon-uri=/fd/s/a/sm_news.ico" />

<meta name="msapplication-task"

       content="name=Maps;action-uri=/maps/?FORM=IE0006;

               icon-uri=/fd/s/a/sm_maps.ico"  />

<meta name="msapplication-task"

       content="name=Travel;action-uri=/travel/?FORM=IE0006;

               icon-uri=/fd/s/a/sm_travel.ico"  />

Обратите внимание, что вы можете задавать любые ссылки и, в частности, можете добавлять в них параметры GET-запроса, которые, например, можно отслеживать на сервере сбора статистики и аналитики посещений. Многие сервисы анализа посещаемости, например, Google Analytics позволяют отслеживать ссылки со специальными параметрами.

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

Определение поддержки функциональности и состояния браузера

Прежде, чем двигаться дальше в сторону динамичных настроек нужно разобраться с одной важной задачей: перед тем, как вызывать какие-то специфичные API из JavaScript, нужно убедиться, что браузер их поддерживает, а браузер с сайтом находится именно в закрепленном состоянии.

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

if (window.external.msIsSiteMode) {

     // Check if the website was launched from a pinned site.

     if (window.external.msIsSiteMode()) {

         // Site is running in pinned mode

     }

     else {

         // Site is not running in pinned mode

     }

} else {

     // Browser does not support pinned site mode

}

Однако есть важный нюанс: в IE9 beta есть известный баг с определением наличия нужного свойства, поэтому код выше правильный, но работать не будет. Сам баг, думаю, скоро будет исправлен.

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

try {

    if (window.external.msIsSiteMode()) {

         // Site is running in pinned mode

    }

    else {

         // Site is not running in pinned mode

    }

}

catch (e) {

     // Browser does not support pinned site mode

}

Либо вот такой немножко более хитрый вариант в виде функции:

checkPinnedSiteMode = function () {

     // return window.external.msIsSiteMode && window.external.msIsSiteMode());

     // workaround for beta

     return window.external && "msIsSiteMode" in window.external

            && window.external.msIsSiteMode();

};

или с присваиванием нужного значения переменной:

var isPinnedSiteMode =  window.external && "msIsSiteMode" in window.external

                        && window.external.msIsSiteMode();

Дальше остается только убедиться, что нужный режим поддерживается и браузер с сайтом находится в нужном состоянии — и вызывать тот или иной код.

Добавление категорий в JumpList

Собственно, категорию можно добавить только одну J Категория, в отличие от задач сайта, предполагает отображение потока некоторых характерных объектов.

Если у вас новостной сайт, это может быть поток новостей или поток самых важных новостей (аля «новость часа», или «новости с главной»). Если ваше веб-приложение предоставляет пользователю функционал по работе с какими-то документами (в общем смысле), это может быть поток последних документов, с которыми пользователь работал. Если ваш веб-сайт представляет собой социальную сеть, это может быть поток друзей пользователя, которые зашли в сеть.

Пользователь, соответственно, прямо из контекстного меню иконки приложения получает прямой доступ к этим объектам.

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

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

Итак, одна именованная категория, до 20-ти элементов. Категория и элементы добавляются через JavaScript на одной из открытых страниц вашего сайта. (Добавлять элементы может любая страница внутри вашего домена!)

Для демонстрации добавления категорий я буду использовать коллекцию элементов, зашитую в коде:

// Генерация или запрос коллекции новых писем

getNewEmailsCollection = function () {

   return [

      { name: "Invitation from Microsoft Connect",

         url: "http://mysite.ru/inbox/mail/1001" },

      { name: "Windows Phone 7 Device Update",

         url: "http://mysite.ru/inbox/mail/1000" },

      { name: "You have been nominated to receive...",

         url: "http://mysite.ru/inbox/mail/999" },

      { name: "Technet Flash: IE9 Beta is here",

         url: "http://mysite.ru/inbox/mail/998" },

      { name: "A New Kind of Science arrives on...",

         url: "http://mysite.ru/inbox/mail/997" },

      { name: "Re: hint в #ie9: чтобы форсировать...",

         url: "http://mysite.ru/inbox/mail/996" }

   ];

};

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

Для добавления категории нужно воспользоваться функцией msSiteModeCreateJumplist, для добавления элементов — msSiteModeAddJumpListItem, для очистки — msSiteModeClearJumplist, а для показа — msSiteModeShowJumplist.

В целом, работа с этими функциями выглядит следующим образом:

// Добавление категорий

addCategories = function () {

    if (isPinnedSiteMode) {

        window.external.msSiteModeCreateJumplist('Inbox');

        window.external.msSiteModeClearJumplist();

        var posts = getNewEmailsCollection();

        // JumpList заполняется снизу, поэтому в обратном порядке

        for (i = posts.length - 1; i >= 0; i--) {

            window.external.msSiteModeAddJumpListItem(posts[i].name,

                          posts[i].url, "/mail.ico");

        }

        window.external.msSiteModeShowJumplist();

    }

};

Обратите внимание, что элементы внутри категории в данном случае добавляются в обратном порядке, так как порядок наполнения противоположный тому, в каком порядке элементы перечислены в массиве.

Наполнение категории происходит снизу вверх. Соответственно, свежие новости или последние объекты, с которыми работал пользователь , легко добавляются вверх списка, а старые вытесняются.

Для каждого элемента вы задаете название, ссылку и иконку.

Дополнительная возможность, которая может вам пригодиться при некоторых сценариях (например, вы хотите синхронизировать список с состоянием каких-либо объектов внутри вашей системы) — вы можете отслеживать событие, когда пользователь удаляет те или иные категории. Для этого нужно подписаться на одно из событий:

document.addEventListener('mssitemodejumplistitemremoved', removed, false);

document.attachEvent('onmssitemodejumplistitemremoved', removed);

function removed(url) {

      // some action here

}

Важный технически момент: событие сработает не сразу, а в тот момент, когда осуществляется вызов функции msSiteModeShowJumplist.

Добавление всплывающих иконок

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

Для добавления иконки и очистки нужно использовать соответственно функции: msSiteModeSetIconOverlay и msSiteModeClearIconOverlay.

Работа с ними выглядит примерно вот так:

// Проверка почты и добавление всплывающей иконки

checkMailBox = function () {

    if (isPinnedSiteMode) {

        if (hasNewEmails()) {

            window.external.msSiteModeSetIconOverlay(

                            'https://localhost:16435/mail.ico', 'New Email');

        }

        else {

            window.external.msSiteModeClearIconOverlay();

        }

    }

};

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

Только, пожалуйста, не переусердствуйте с демонстрацией иконок на каждый чих ;)

Добавление подсветки

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

Чтобы подсветить иконку, когда она не в фокусе (пользователь переключился на другое окно), нужно вызвать функцию msSiteModeActivate, например, вот так:

onFinishedAnalysing = function () {

     // do something

     // ...

     if (isPinnedSiteMode) {

         window.external.msSiteModeActivate();

     }

};

Еще раз: не переусердствуйте ;)

Добавление иконок в превью

Наконец, мы добрались до добавления иконок в превью. С помощью этой функциональности в окошко превью вашей страницы в панели задач можно добавить управляющие элементы, которые позволят «удаленно» взаимодействовать с конкретной страницей, не переключаясь на нее.

Например, если на странице воспоизводится видео, можно добавить кнопки управления воспроизведением.

Максимум вы можете добавить в превью 7 кнопока, каждая из которых может посылать тут или иную команду на текущую страницу (на нажатия кнопок вешаются обработчики событий на JavaScript). Панель с кнопка в зависимости от контекста ОС может занимать меньше места, поэтому приоритезируйте кнопки слева направо.

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

Создание кнопки. Для создания кнопки следует использовать функцию msSiteModeAddThumbBarButton, которая возвращает Id сгенерированной кнопки:

var btn = window.external.msSiteModeAddThumbBarButton('mail.ico', 'Check Inbox');

Регистрация обработчика . Чтобы отследить момент нажати кнопки, необходимо подписаться на событие msthumbnailclick:

document.addEventListener('msthumbnailclick', function (btn) {

     alert("addeventlist:thumbnail btn id" + btn.buttonID);

}, false);

При регистрации необходимо указать обработчик (inline или ссылкой на функцию), в который передастся объект кнопки, в котором уже можно узнать Id и понять, какая именно кнопка нажата.

Демонстрация панели. Чтобы показать панель с кнопками используйте функцию msSiteModeShowThumbBar:

window.external.msSiteModeShowThumbBar();

Обновление состояния. Для обновления состояния кнопки доступна функция msSiteModeUpdateThumbBarButton, в которую надо передать Id кнопки и флаги разрешенности и видимости:

window.external.msSiteModeUpdateThumbBarButton(uiButtonID, fEnabled, fVisible)

Смена стиля. Чтобы сменить стиль кнопки, например, заменить кнопку “Play” на “Pause” и обратно, нужно определить соответствующие стили с помощью функции msSiteModeAddButtonStyle:

var playStyle = window.external.msSiteModeAddButtonStyle(playButton,

                     'http://mysite.ru/img/play.ico', 'Play');

var pauseStule = window.external.msSiteModeAddButtonStyle(playButton,

                     'http://mysite.ru/img/pause.ico', 'Pause');

Далее нужно применить тот или иной стиль с помощью функции msSiteModeShowButtonStyle:

window.external.msSiteModeShowButtonStyle(playButton, playStyle);

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

И, конечно, не забывайте проверять, что сайт находится в привязанном состоянии.

Привязка сайта в стартовое меню

Отдельная маленькая тема. Это можно делать программно с помощью функции msAddSiteMode. Только не забудьте проверить, что она доступна в браузере, иначе вывалится ошибка.

Плагины для добавления функции Pinned Site

Думаю, плагины для легкого добавления соответствующих функций в движки сайтов будут постепенно добавляться.К примеру, уже доступен соответствующий плагин для блогов на Wordpress.

IE9 Pinned Site for WordPress

http://wordpress.org/extend/plugins/ie9-pinned-site/

Плагин позволяет настраивать:

  • Имя закрепленного сайта, подсказку и стартовую страницу
  • Ссылки в JumpList для добавления новых постов, модерирования комментариев и загрузки файлов
  • Ссылки в JumpList для страниц, определеннных в сайте
  • Собственные ссылки в JumpList для постов, категорий или тегов