Pull to refresh

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

Reading time 4 min
Views 2K
Тут описывается создание первой версии. О свежей версии можно прочесть здесь.



Недавно я перешел с фаерфокса на гугл хром в связи 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. По делу пишите в коменты, об опечатках в личку, о том что я ужасный писатель я и так знаю.
Tags:
Hubs:
+23
Comments 31
Comments Comments 31

Articles