Chrome-linker. Творим аналог Linkification для Google Chrome

    Тут описывается создание первой версии. О свежей версии можно прочесть здесь.



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

    Как известно, какую неделю назад, вышла первая версия Google Chrome (dev), которая поддерживает расширения. И, несмотря на то, что API еще не доделано и сильно глючит, я решил быстренько слепить расширение, которое бы реализовывало функциональность Linkification'a.

    Далее следует описание процесса создания расширения и ссылка на результат.



    Насколько я разузнал, расширения в Google Chrome состоят:
    1. manifest.json — обязательный файл описания расширения и ссылок на другие файлы.
    2. toolstrip-ов — хтмл-файлов описывающих кнопки, которые показываются внизу хрома.
    3. content-script-ов — javascript-файлов, которые управляют содержанием вебстраниц.
    4. других любых файлов, которые вы хотите использовать, вроде картинок, хтмл-страниц для попап-окошек и тд.

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

    Эта версия расширения состоит из 2 файлов, это файл манифеста и javascript контент-скрипт, который при загрузки страницы берет весь текст на ней и заменяет текстовые ссылки на хтмльные.

    Файл манифеста выглядет так:

    {
    "content_scripts": [
    {
    "js": [
    "linky.js"
    ],
    "matches": [
    "",
    "http://*/*",
    "https://*/*"
    ]
    }
    ],
    "description": "Extension that converts text urls into real html links",
    "name": "Chrome-linker",
    "version": "0.1"
    }



    Кроме неинтересного описания, имени, и версии, присутствует

    "content_scripts": [
    {
    "js": [
    "linky.js"
    ],
    "matches": [
    "file:///*",
    "http://*/*",
    "https://*/*"
    ]
    }
    ],


    Здесь описано какой js файл нужно грузить, а так же совпадения для адресов. Я написал 3, file, http, и https, возможно нужно будет добавить. Кстати, написать "*" нельзя, ругается.

    Второй файл — javascript, который меняет все текстовые ссылки на настоящие. Его я украл из userjs.org, и выглядет оно так:

    var urlRegex = /\b(((https?|ftp|irc|file|s?news):\/\/|(mailto|s?news):)[^\s\"<>\{\}\'\(\)]*)/g;
    //^^^Medium version
    //var urlRegex = /\b(((https?):\/\/)[^\s\"<>\{\}\'\(\)]*)/g;
    //^^^Small version

    //Set this to a class name if you want it to use a style from a stylesheet.
    var linkClass='';
    var preCreatedA=null;

    var elms = document.evaluate('//body//text()[not(ancestor::a)][not(ancestor::script)][not(ancestor::style)]', document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
    for (var i = 0, elm; elm = elms.snapshotItem(i); i++) {
    linkifyNode(elm,document);
    }

    function linkifyNode(node,mydoc){
    var i,tmpData,foundPos,matchedText,middleText,endText,v;
    var newLinkElement,linkTextNode,skip=0;
    if(node){
    if (node.data){
    tmpData=node.data;
    foundPos=tmpData.search(urlRegex);
    if (foundPos>=0){
    matchedText=RegExp.$1;
    middleText=node.splitText(foundPos);
    middleText.deleteData(0,matchedText.length);
    if (preCreatedA){
    newLinkElement=preCreatedA.cloneNode(false);
    } else{
    newLinkElement=mydoc.createElement('a');
    newLinkElement.setAttribute('target','_blank');
    if (linkClass!=''){
    newLinkElement.setAttribute('class',linkClass);
    }
    preCreatedA=newLinkElement.cloneNode(false);
    }
    newLinkElement.setAttribute('href',matchedText);
    linkTextNode=mydoc.createTextNode(matchedText);
    newLinkElement.appendChild(linkTextNode);
    node.parentNode.insertBefore(newLinkElement,middleText);
    v=node.parentNode.style.display;
    //Check if we have a block element, and if not, flash it to
    //avoid the redraw bug.
    if (v!='block'){
    node.parentNode.style.display='none';
    node.parentNode.style.display=v;
    }
    skip=1;
    }
    }
    }
    return skip;
    }


    Я удалил оттуда всякие window.body.onload потому что контентскрипты выполняются после загрузки документа.

    Чтобы проверить как всё работает, в настройках шортката к хрому в путь нужно добавить --load-extension=«C:\Users\Alex\Desktop\chrome-linker» где последнее, конечно, путь к папке с файлами. При перезапуске, хром загрузил расширение, и зайдя на типичный варезный сайт с ссылками подсветил все рапидшарные линки. Ура. Осталось собрать расширение в crx файл и выложить на свободу.

    Здесь очень просто описан этот процесс. Нужно скачать питон 2.6, скачать скрипт для сборки отсюда и выполнить:

    C:\Users\Alex\Downloads>chromium_extension.py --indir=c:\Users\Alex\Desktop\chrome-linker --outfile=chrome-linker.crx
    [INFO] Generated extension ID: 23C7C890C288943A468C4316563B9E9712A22ED4
    [INFO] created extension package chrome-linker.crx
    [INFO] chrome-linker.crx contents:
    [INFO] linky.js
    [INFO] manifest.json


    Готово, в моей папке download появился файлик chrome-linker.crx. Его вы можете скачать с моей домашней страницы: вот он!

    После установки, зайдите на chrome://extensions/. Вы должны увидеть примерно следущее:

    image

    Ура! Теперь все урлы будут линками.

    UPD 1. ID в манифесте указывать не нужно, он генерится скриптом сборки, извиняюсь за дезинформацию.

    ,UPD 2. Вероятнее всего, что коммуникация с контент-скриптами глючила у меня из-за моей же криворукости. Расширение Subscript от гугла работает нормально, используя общение между тулстрипами и контент-скриптами. Так что вскоре сделаю новую версию и опишу в новом посте

    П.С. 1. Когда выйдет АПИ, я сделаю новую версию с нормальным интерфейсов, если конечно кто-то захочет.
    П.С. 2. По делу пишите в коменты, об опечатках в личку, о том что я ужасный писатель я и так знаю.
    Поделиться публикацией

    Похожие публикации

    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

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

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

      +1
      Круто. Попробовал на релизной версии 2.0.172.28. Работает!
        0
        На релизной работают расширения? Не знал. Но параметр --enable-extensions пришлось указывать, да?
          +1
          Ничего не указал. Всё из коробки.
          Вначале ввёл chrome://extensions/ — есть такая
          потом кликнул скачал само расширение. Кликнул — ничего. Ещё 2 раза.
          Потом открываю chrome://extensions/ — пишет есть одно расширение и ещё 2 установить не удалось, так как такое уже существует.
          Ну и на тестовую страницу — работает.
        +1
        У меня тоже на релизной поставилось. Но почему-то всё время пишет:
        Errors
        Could not install extension from 'C:\Users\Administrator\AppData\Local\Google\Chrome\User Data\Default\Extensions\23C7C890C288943A468C4316563B9E9712A22ED4'. Existing version is already up to date.

        Хотя на тестовой странице ссылки заработали.

        Получается, что просто нет кнопки Удалить.

        P.S. Ушёл писать расширение для Chrome =)
          +1
          напишите синхронизацию букмарков, пожалуйста!
          П.С. если что, пишите в личку, потрындим, обменяемся опытом.
            +1
            >Получается, что просто нет кнопки Удалить.
            вроде на chrome://extensions есть кнопка uninstall?
              +1
              Кнопка Должна быть, но по какой то причине он не может её отобразить. Подозреваю это из-за того, что он при заходе на chrome://extensions пытается установить плагин опять (Ваш который). Пока курю доки…

                0
                странный он! ну может у меня косяк какой. я почти не понимаю как там всё работает.

                оффтоп- а не клёво ли что расширения в хроме ставятся без перезагрузки? :-)
              0
              блин, у меня кидает Manifest is missing or invalid.
              +1
              Спасибо, жаль нету расшерений для delicious и RSS.
                0
                Есть тестовое расширение которое делает кнопку Subscribe и добавляет рсс с выбранного сайта в гуглридер. И вообще сейчас они начнут плодится, не переживайте!
                  0
                  delicious.com/help/bookmarklets
                  подписка на RSS в Google Reader -> идем Settings->Goodies, там ссылочка «Subscribe...», перетаскиваем ее в toolbar
                    0
                    Спасибо, но хотелось бы полноценного решения такого как официальный аддон к ФФ
                  0
                  Каждому свое, но я бы посоветовал в качестве прототипа Fetch Text Url, так как Вы сами можете мышкой выделить текст и открыть как ссылку, а Linkification, насколько я понял, не опознает урлы вида habrahabr.ru/blogs/google_chrome/60826/ (поправьте если не так).
                    0
                    Вы правы. Но если мне приходится выделять текст то мне уже и не трудно его перенести мышкой в место табов (и страница откроется).
                  • НЛО прилетело и опубликовало эту надпись здесь
                    • НЛО прилетело и опубликовало эту надпись здесь
                        0
                        Вы слишком быстрый! =))
                        0
                        Скачиваете Channel Changer, запускаете и переставляете переключатель на «Dev». Потом можно ждать пока Хром сам обновится, или же зайти в About и нажать Update. Предупреждаю — Dev версия крэшится, а назад на Stable вернутся сможете только удалив Хром и поставив заного.
                          0
                          на самом деле можно и без сноса… если память не изменяет, в реестре надо сменить текущую версию на более старую и обновиться с стэйбл-ветки
                            0
                            Не знал про этот финт, спасибо!
                        0
                        Кстати, возможно я использую не самую лучшую функцию для замены ссылок. Если у кого-то есть идеи и предложения, то мои уши открыты :-)
                          0
                          под линухом что то не хочет устанавливаться :(
                          • НЛО прилетело и опубликовало эту надпись здесь
                              0
                              Клёво! только удобней было бы в тексте прям ссылку на crx писать, а то вряд ли людям интересно то, как я делал расширение =))
                              0
                              Спасибо!
                                0
                                Когда переходил с FF на Chrome, поначалу нехватало некоторых плугинов. Но, как оказалось, большинство из них можно заменить букмарклетами.

                                Чтобы открывать выделенный текст в новом табе, используя его как ссылку, добавил на панель закладок следующий букмарклет:
                                javascript:q = "" + (window.getSelection ? window.getSelection() : document.getSelection ? document.getSelection() : document.selection.createRange().text); if (q) { m=q.match(/^\s*(\w+:\/\/)?(.*?)\s*$/); u = (m[1] || "") + m[2]; window.open(u); }; void 0

                                Многие простые плугины можно заменить букмарклетами. К сожелению, с более сложными (Firebug, WebDeveloper toolbar, ...) такой фокус не прокатит.
                                  0
                                  Сорри, там «h t t p: / /» в кавычках. Это часть кода чтобы добавлять http в начале, если выделенный текст — это адрес сайта без протокола.
                                    0
                                    угу. кстати говоря, ту функцию что я использую можно засунуть и в букмарклет. тогда одно нажатие — и все ссылки на страницы стали правильными. может быть даже удобней, чем плагин инсталить.
                                    0
                                    Обновилась тестовая версия браузера Google Chrome до номера 3.0.189.0.

                                    Что в ней нового:

                                    1. Исправления вылетов и улучшенная стабильность.

                                    2. Обновился V8 до 1.2.8.

                                    3. Временно отключены расширения в режиме инкогнито.

                                    4. Исправления в истории.

                                    5. Прекращена поддержка всех расширений не имеющих подписи.
                                      0
                                      А где теперь расширение?
                                      Ссылка уже нерабочая :(

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

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