Юзерскрипт: кроссбраузерно, кроссдоменно

    Разработка юзерскрипта HabrAjax преодолела свои очередные проблемы с кроссбраузерной поддержкой новых функций и создала плеяду статей (7 штук, ещё не опубликованных) по разным вопросам, связанным в основном с юзерскриптами и их кроссдоменным доступом. Все эти статьи нетривиальны, в интернете их темы освещаются частично, а некоторые не освещаются даже в описаниях багов браузеров (или автору неизвестны иноязычные решения). Статьи придётся выкладывать в произвольном порядке, потому что нет оснований как-либо их упорядочивать — каждая связана с другой лишь по тематике. Сейчас я приведу анонсы статей, без ссылок, чтобы сложить представление, о чём пойдёт речь в дальнейшем. Реализация — в HabrAjax, но там довольно много прикладного кода, не слишком хороший пример для демонстрации. Поэтому для каждой статьи будут коды с более адаптированными примерами, насколько возможно.

    Фикс-идея кроссбраузерности


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

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

    Требования к обмену данными у нас будут вовсе не такие ограниченные, как обычно принято. Обычно (для Оперы) считают, что мы можем написать функцию в скрипте на другом домене, и вся задача состоит в её выполнении во внедрённом скрипте. Часто мы не можем менять данные на чужом домене, а получить их — наша задача. Данные нужно извлекать:
    1) произвольные текстовые, которые допускается обрамлять скриптом JS и передавать как файл JS (чтобы их упаковать в юзерскрипт);
    2) вообще произвольные текстовые данные из другого файла без возможности обрамить чем-либо;
    3) любые хеши JSON — в другой домен.

    Первый случай возникает, когда нужно прочитать метаданные юзерскрипта в самом скрипте или при желании записать стили CSS без кодирования в строки JS. Кроссдоменности пока нет, но задача не совсем тривиальна, если хотим получить единый кроссбраузерный вид (в общем случае не решается — в Firefox недостаёт функций, а введённый в GreaseMonkey тип «xml» синтаксически несовместим с языком JS — другими словами, чуждый тип никак нельзя сделать кроссбраузерным). Получаем полурешения — кроссбраузерный вид для случая метаданных и Scriptish вместо GreaseMonkey, или необходимость чуть-чуть подправить файл на 2 символа для браузера Firefox сверх возможностей JS — тогда обеспечивается чтение не только метаданных, но и произвольных данных в файле *.user.js. Это, конечно, плохо, но таковы реалии совместимости юзерскриптов. Подробно проблема и возможные решения изложены в статье "Чтение многострочных данных в JS". Она выходит за рамки юзерскриптов, но именно в них, в юзерскриптах, имеет реальные шансы на решение.

    Обратим внимание, что эти неразрешимые проблемы возникают, когда пытаемся данные и скрипт упаковать в одном-единственном файле скрипта (юзерскрипта или простого скрипта). Если использовать 2 файла — проблемы уже нет, потому что данные из 2-го файла можем прочитать как текст или HTML (в комментарии HTML держать почти произвольный текст), а в первом держать только скрипты. Однако, однофайловое решение — это хороший тон работы с пользователем: ему предоставляется один файл, который надо просто «инсталлировать». Правда, несколько забываем о такой мелочи, что только Хром может инсталлировать юзерскрипт нативно; для Firefox нужен аддон GreaseMonkey или Scriptish, для Оперы — прописывание настроек для сайта в настройках браузера (значит, если новый компьютер — то новые заботы с чередой действий, а не просто «инсталлировать файл»). У неё аддон, подобный GreaseMonkey, находится в очень примитивном состоянии — требуется копировать скрипты в поле ввода аддона, не учитываются метаданные, поэтому его не упоминаем. Наконец, Safari тоже требует аддона (NinjaKit) и копирования тела файла юзерскрипта в редактор аддона. То есть, однофайловость + кроссбраузерность оказывается и без того сильно натянутой.

    Второй и третий случаи обмена данными — решаются внедрением юзерскрипта в недоступную разработчику область чужого домена. Здесь решение усложняется багами в 2 браузерах из 4. В статьях "Обход бага Хромиума по кроссдоменному обмену в юзерскриптах", "Кроссдоменный обмен данными в юзерскрипте в Опере" показано, что их можно преодолеть.

    Аддон вместо юзерскрипта для Оперы


    Мы их предупреждали, что не остановимся ни перед чем, лишь бы пользователю было хорошо? Предупреждали. А они что сделали? Массу настроек без возможности автоматизации. Теперь мы имеем моральное право удариться во все тяжкие — придумать алгоритм генерации аддона для Оперы, заменяющего юзерскрипт. Потому что автоматизировать создание аддона можно, а создание встроенного в Оперу юзерскрипта — нет. Получим вожделенное решение в виде одной кнопки «Инсталлировать» и даже место на сайте Оперы. Как сделать — в статье "Аддон для Opera из юзерскрипта".

    То же самое, кстати, и для Safari. Имеется NinjaKit — более близкий к возможностям GreaseMonkey аддон, но в него зачем-то вручную нужно копировать текст скрипта, и он не умеет полноценно поддерживать кроссдоменный запрос GM_XMLHTTPRequest. Всё это как-то несерьёзно; неизвестно, будет ли это поддержано. Проще тоже удариться в аддоны, решив заодно вопрос с иконками юзерскриптов, нормально решённый в Firefox и больше нигде не решённый (не считая аддонов): директива метаданных icon поддерживается, а иконы в списке скриптов — работают только в Firefox. Там требуется маленький квест по получению звания разработчика в глазах верховного держателя всех правил, поэтому всё вместе описано в статье "Аддон для Safari из юзерскрипта".

    Кроссбраузерные аддоны


    Раз мы с Оперой и Safari выкинуты в необходимость писать собственные аддоны, сильно отличающиеся по коду от юзерскрипта (не в том плане, что трудно собрать, а сильное различие в байтах), появляется очередная шальная мысль: ведь все аддоны всех браузеров построены по общим принципам — zip-архив, отличающийся своим расширением и ряд файлов с очень похожими функциями. А не сделать ли нам общий кроссбраузерный архив, в котором достаточно только переписать расширение? Если не будет конфликтов в именах файлов, то дело выполнимо — 4 витиеватых дорожки снова сольются в одну, а особенности реализации стерпит единый архив, включив избыточные браузерозависимые настройки. Сборщик архива снова упростится, заключаясь в ручной операции переименования расширения.

    Пробраться в чужой огород со своими юзерскриптами


    Кроссдоменные запросы метаданных — это полбеды. Она элементарно решается в 2 браузерах, трудно — в Опере. Но решение в Опере покажется лёгким, если познакомиться с полной бедой — обеспечением кроссдоменного обмена данными из фреймов сторонних сайтов. Чтение метаданных будет просто частным случаем и детской забавой с использованием той же техники обмена для Оперы (к сожалению, с BeforeScript у них, видимо, какой-то баг в юзерскриптах, не всегда работает). Как решена «полная беда» — описано в статье "Обход бага Хромиума по кроссдоменному обмену в юзерскриптах", а как воспользоваться решением для получения вкусных плодов из чужого огорода, хозяева которых не спешат через API ими делиться — в статье "Компактный размер кнопок Google Plus". И в самом деле, зачем тратить 70 пикселей по горизонтали, мучиться с отсутствием данных о количестве «лайков», когда чаще всего достаточно 24 пикселей на 1-2-3 цифры числа «лайков»? Зачем нам в дизайне своих страниц «говорящие» кнопки "+1"? Юзерскрипт решит все эти проблемы — дело за пользователем установить его. Опять восстаёт призрак Оперы и страшит тонной инструкций по настройкам — ура, не зря мы научились упаковывать скрипты в аддоны в прежних статьях.

    Это наиболее зрелищное дополнение юзерскрипта из сделанных в последней версии стоит проиллюстрировать. Кнопки Google+ необычно компактны благодаря юзерскрипту.
    (рис.1) (на Я-фотках, imageshack)

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

    А что же HabrAjax и где искать реализацию кроссдоменности?


    Если кратко, то в версии 0.81 он приобрёл такие возможности:
    * Прямые ссылки на личные страницы, чтобы добираться к ним не в 2-3 клика, а в один.

    (рис.2)

    * Проверка обновлений скрипта — периодически, не чаще раза в день (период настраивается) проверяет скрипт. Не беспокоит, если версия — минорная. (кроссдоменные технологии)

    (рис.3)

    * показ фич из метаданных — подсказывает, что в нём появилось нового, а также, новое на сервере при проверке. (кроссдоменные технологии)

    (рис.4)

    * стильную иконку в метаданных (ваще круть) (вон она там, вверху справа).
    * эти рамочки вокруг чекбоксов — напоминают о последних изменённых фичах.
    * настраиваемая макс. высота рисунков при принудительном кате (по умолчанию 120 с ZenComment). Высота аннотации (максимальная) — вдвое больше.
    * написать письмо, выделив цитату или имя автора — не нужно копировать их вручную (включается настройкой «цитатник-корректор»).
    * кнопка предпросмотра в почте.
    * компактные кнопки Google Plus (кроссдоменные технологии)
    * Небольшие изменения в стилях ZenComment — их версия (2.16) встроена и в HabrAjax. Его удобно использовать вместе со скриптами, но сделано всё для того, чтобы стили и скрипты были независимы. Необходимые (позарез необходимый минимум) стили прописаны в скриптах и занимают уйму (250) строк.

    Да, и насчёт скрипта — к тем, кто им уже пользуется — просьба поучаствовать в опросе — "В каком браузере вы используете скрипт HabrAjax?" (возможен множественный выбор вариантов). Он поможет увидеть картину того, в каких браузерах и ОС работает скрипт. Если есть 2 разных компьютера — пишите 2 голоса в опросе (из разных мест). Имеет значение и аддон для Firefox — ведь оказалось, что более гибкий аддон — Scriptish, потому что он позволяет написать кроссбраузерный многострочный текст директив метаданных (это будет освещено в статье "Чтение многострочных данных в JS").

    UPD 18:30: исправлен навязчивый баг с неправильными ссылками вокруг имени пользователя. Проверен в Опере, Fx, Chrome. (Опера оказалась хуже всего восприимчива к чтению DOM, выдавала баги непрописанности юзера.) Обновитесь, пожалуйста, кто успел скачать. Заодно, будет видна работа по чтению метаданных и показу того, что сделано в новой версии (Если нажать ссылку "Проверка обновлений".
    UPD2: Однако, много пользователей Хрома, начинает показывать опрос.
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 19

      +12
      Когда же вы со своим долбаным радикалом уже провалитесь в пропасть!
        +2
        А как же вежливая просьба перезалить на habrastorage.org? :)
          0
          Я нахожу его стабильным, если не перегружать запросами, а habrastorage.org периодически выдавали глюки картинок (типа горизонтального надреза вверху в 50 пикс. от края), это хуже. В чём конкретно претензия к Радикалу? Ещё лучше было бы «стабильный+ со статистикой просмотров. Кто такой знает?
            0
            Претензия в том, что на мало-мальски посещаемой странице все картинки на долгое время превращаются в тыкву. И прямые ссылки не помогут в этом случае.

            Стабильный хостинг — Яндекс-картинки. Там же есть небольшая статистика для публичных картинок (кол-во загрузок + 10 популярных реферреров).
            • НЛО прилетело и опубликовало эту надпись здесь
                0
                На Радикале статистики нет, её хотелось бы иметь. Вот, сейчас зарегистрировался на Яндексе, положу, как советуют, на Я-фотки. Публикую Радикал без рекламы (в ссылке html убирается), а привлекает меня его стабильность, измеряемая годами, и удобство интерфейса (и возможность размещать без пережатия). По опыту известно, что если публиковать лёгкие картинки, блокировки долго нет. Почти все статьи у меня здесь на Радикале :\… :)
                  0
                  У Яндекс-фоток большой недостаток в неумении нормально сжимать превью. Мой оригинал весит в 4 раза меньше, чем их превью, в 4 раза меньшее по площади. У Радикала похожее превью — 13К. Чтобы нормально работать с Яндексом, нужно вручную делать превью малого веса. ImageShack — то же самое, огромные превью. У Гугла тоже когда-то этим отличались. Как-то не вижу оснований перенести рисунки ни на один из этих хостингов.
                    0
                    Превью можно готовить вручную и потом разворачивать его в полноразмерную картинку. То есть, изначально готовить 2 изображения.

                    Есть хороший хостинг, заточенный под reddit — imgur. Очень устойчивый к количеству запросов, есть прямые линки и статистика просмотров. Рекомендую.
                      0
                      Да, он очень хороший, и проблемы тяжёлого превью не было, я его исследовал в рамках общего исследования хостингов, за исключение того, что на 80-м где-то изображении начинает закрывать старые и просить денег для раскрытия. Поэтому до какого-то предела им можно пользоваться. И, как видите, после всего этого пользуюсь Радикалом. Делать 2 превью — это раза в 3 больше работы плюс необходимость иметь под рукой редактор на компьютере.
              0
              (Добавил ссылки к рисункам на случай их незагрузки.)
              +3
              Хорошо бы, если б хабра-парсер радикаловские ссылки уничтожал.
                0
                {сжигал в аду по-тихому}
              0
              В Хроме 17.0.963.79 m ссылки на разделы моего профиля битые вида:
              habrahabr.ru/users/http://habrahabr.ru/users/guria//mail/
              habrahabr.ru/users/http://habrahabr.ru/users/guria//favorites/
              и тд
                0
                Не только в хроме. Автор это уже фиксит, скоро обещал апдейт.
                  0
                  баг в правом верхнем углу исправлен, выложил на USO, проверен на 3 браузерах. Заодно закачавшие версию 0.81 могут проверить, как работает проверка обновлений — ссылка в настройках. Будет сообщение:
                  Новое по сравнению с 0.81: исправление бага со ссылками вверху справа
                    0
                    Обновился через «проверка обновлений». Все прошло успешно. Бага теперь нет. Спасибо :)

                    // Firefox 11.0 // Greasemonkey 0.9.18 // Ubuntu 10.10
              • НЛО прилетело и опубликовало эту надпись здесь
                  +2
                  зачем вы это делаете? столько статей, столько труда, а выглядит как черт знает что!
                    0
                    Это концепт, на котором отрабатываются технологии.

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

                  Самое читаемое