Advertisement
  1. Code
  2. Google Chrome

Робота з розширеннями Google Chrome

Scroll to top
Read Time: 11 min

() translation by (you can also view the original English article)

Ніде правди діти, Google Chrome мій улюблений браузер. Мені подобається його надійність і швидкість, він не падає (дуже часто) і добре виглядає. Є у нього і інші достоїнства. Факт, що розширення для нього можна побудувати тільки на HTML, CSS і JavaScript. Я завжди підтримую продукти, які відкриті для спільноти і Chrome є одним з них. Якщо вам потрібно щось, чого ще немає, ви можете розробити це самостійно.

В кінці цієї статті ви знайдете чинне розширення Chrome, яке використовує більшість методів, описаних нижче. Ви можете завантажити остаточний приклад по кнопці завантаження у верхній частині цієї сторінки.


Навіщо писати своє власне розширення

Я закликаю всіх використовувати кращі інструменти для раціоналізації робочих процесів. Програмне забезпечення повинно нам допомагати, ми не повинні з ним боротися. Розробка розширень / плагінів для вашого редактора або браузера допомагає не тільки вам, а й іншим програмістам, які рано чи пізно опиняться в тій же ситуації. Будь-яке упущення можна заповнити самостійно, а з Chrome це буде дуже просто. Моделювання середовища навколо ваших потреб є ключем до високопродуктивної праці.


Розробка і тестування ваших розширень

На щастя, є спосіб протестувати розширення, не завантажуючи його в інтернет-магазин Chrome. В адресному рядку вашого браузера введіть:

1
chrome://extensions

Переконайтеся, що ви вибрали Developer mode і натисніть кнопку Load unpacked extension ... І виберіть папку з жорсткого диска, яка містить файли розширень.

extensionspanelextensionspanelextensionspanel

Архітектура

Ось діаграма архітектури розширення Chrome:

architecturearchitecturearchitecture

Тепер давайте розглянемо кожен елемент архітектури.

Декларація (Manifest)

Точкою входу розширення є файл manifest.json. Він повинен містити дійсний об'єкт JSON. Наприклад:

1
{
2
    "name": "BrowserActionExtension",
3
    "version": "0.0.1",
4
    "manifest_version": 2,
5
    "browser_action": {
6
        "default_title": "That's the tool tip",
7
        "default_popup": "popup.html"
8
    }
9
}

Його властивостями будуть name, version і manifest_version. Version може бути від одного до чотирьох цілих чисел, розділених точками. Вона використовується системою автоматичного оновлення Google. Так він дізнається, коли оновлювати ваше розширення. Значення manifest_version має бути цілим числом 2.

У маніфесті можуть міститися інші властивості, в залежності від того, яке розширення вам потрібно, але я опишу тільки ті, які вважаю більш цікавими.

Background Pages (фонові сторінки)

У кожного розширення є невидима довідкова сторінка, яка запускається браузером. Існує два типи: постійні фонові сторінки та сторінки подій. Перші активні постійно. Другі тільки в разі потреби. Google заохочує розробників використовувати сторінки подій, оскільки це економить пам'ять і покращує загальну продуктивність браузера. Проте, треба знати, що це місце, де ви повинні помістити основний алгоритм і ініціалізацію. Зазвичай background page/script грає роль моста між іншими частинами розширення.

Ось як ви повинні описати це в manifest:

1
"background": {
2
    "scripts": ["background.js"],
3
    "persistent": false/true
4
}

Як ви могли здогадатися, якщо persistent властивість є false, ви використовуєте event pages. В іншому випадку ви працюєте з постійною фонової сторінкою.

Content Script (скрипт контенту)

Якщо потрібен доступ до DOM поточної сторінки, вам потрібно використовувати content script. Код запускається в контексті поточної веб-сторінки, що означає, що він буде виконаний при кожному оновленні. Для додавання скрипта використовуйте наступний синтаксис.

1
"content_scripts": [
2
    {
3
        "matches": ["https://*/*", "https://*/*"],
4
        "js": ["content.js"]
5
    }
6
]

Майте на увазі, що значення matches визначає, для яких сторінок буде використаний ваш скрипт. Детальніше про це matches patterns here.

User Interface (інтерфейс користувача)

Є кілька шляхів побудови UI вашого розширення. Ось чотири найвідоміших.

Browser Action

Для створення полігонів більшість розробників користується browser_action. Після його установки значок, що позначає розширення, буде поміщений в праву частину адресного рядка. Натиснувши на значку користувачі можуть відкрити спливаюче вікно, яке насправді є вмістом HTML-контенту.

browseractionbrowseractionbrowseraction

Дані файлу manifest повинні містити наступне:

1
"browser_action": {
2
    "default_icon": {
3
        "19": "icons/19x19.png",
4
        "38": "icons/38x38.png"
5
    },
6
    "default_title": "That's the tool tip",
7
    "default_popup": "popup.html"
8
}

default_title містить підказку, яка відображається, коли користувач вказує на значок. default_popup - це фактично файл HTML, який завантажується всередині спливаючого вікна. Існує також значок, який ви можете розмістити над своєю іконою. Ви можете зробити це всередині background script. Наприклад:

1
chrome.browserAction.setBadgeText({text: "yeah"});

Це код для створення зображення вище.

Page Action

Властивість page_action схоже на browser action, але значок відображається всередині адресного рядка:

pageactionpageactionpageaction

Цікаво, що ваш значок спочатку приховано, тому ви повинні вирішити, коли його показувати. Наприклад, на зображенні значок RSS буде відображатися тільки в тому випадку, якщо поточна сторінка містить посилання на RSS-канал Якщо вам потрібно постійно бачити значок, використовуйте browser_action безпосередньо.

Щоб додати page action, пропишіть наступний код в manifest:

1
"page_action": {
2
    "default_icon": {
3
        "19": "images/icon19.png",
4
        "38": "images/icon38.png"
5
    },
6
    "default_title": "Google Mail",
7
    "default_popup": "popup.html"
8
}

На відміну від browser action, page action значка не має.

DeveloperTools

Я багато використовую DeveloperTools і добре, що у Chrome є метод поповнення цих інструментів. По-перше, вам потрібно додати HTML-сторінку, яка буде завантажена при відкритті панелі:

1
"devtools_page": "devtools.html"

Не потрібно поміщати HTML-код всередині сторінки, крім посилання у файлі JavaScript, який буде створювати вкладку:

1
<script src="devtools.js"></script>;

Потім додайте наступний код всередині файлу devtools.js:

1
chrome.devtools.panels.create(
2
    "TheNameOfYourExtension", 
3
    "img/icon16.png", 
4
    "index.html",
5
    function() {
6
7
    }
8
);

Тепер цей код додасть нову вкладку з ім'ям TheNameOfYourExtension, і як тільки ви натиснете на неї, браузер завантажить index.html всередині DeveloperTools.

Omnibox

omnibox - це ключове слово, яке відображається всередині адресного рядка Chrome. Наприклад, при додаванні в manifest наступного властивості:

1
"omnibox": { "keyword" : "yeah" }

А потім додайте наступний код в свій background script:

1
chrome.omnibox.onInputChanged.addListener(function(text, suggest) {
2
    suggest([
3
      {content: text + " one", description: "the first one"},
4
      {content: text + " number two", description: "the second entry"}
5
    ]);
6
});
7
chrome.omnibox.onInputEntered.addListener(function(text) {
8
    alert('You just typed "' + text + '"');
9
});

Ви повинні мати можливість ввести yeah в адресний рядок. Потім ви побачите наступне:

omniboxomniboxomnibox

Натискання на вкладку призведе до появи екрану:

omnibox2omnibox2omnibox2

Звичайно, використовуючи API chrome.omnibox, ви можете зловити вхід користувача і відреагувати на нього.

APIs

Є безліч різних речей, які ви можете зробити в своєму розширенні. Наприклад, отримати доступ до закладок або історії користувача. Ви можете переміщати, створювати вкладки або навіть змінювати розмір головного вікна. Я настійно рекомендую вивчити documentation, щоб краще зрозуміти, як виконати ці завдання.

Ви повинні знати, що не всі API доступні в кожній частині вашого розширення. Наприклад, ваш content script не отримає доступ до chrome.devtools.panels або скрипт на вкладці DeveloperTools не прочитаєте DOM сторінки. Тому не дивуйтеся, якщо щось не працює.

Messaging (обмін повідомленнями)

Як я вже згадував, у вас не буде доступу до всіх API, які ви хочете використовувати. В такому випадку ви повинні використовувати передачу повідомлень. Існує два типи повідомлень - одноразові запити і довгоживучі сполуки.

One-Time Requests (одноразові запити)

Цей тип зв'язку на один раз. Тобто, ви відправляєте повідомлення і чекаєте відповіді. Наприклад, ви можете помістити наступний код в свій background script:

1
chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
2
    switch(request.type) {
3
        case "dom-loaded":
4
            alert(request.data.myProperty);
5
        break;
6
    }
7
    return true;
8
});

Потім використовуйте код нижче в вашому content script:

1
window.addEventListener("load", function() {
2
    chrome.extension.sendMessage({
3
        type: "dom-loaded", 
4
        data: {
5
            myProperty: "value"
6
        }
7
    });
8
}, true);

Так ви можете отримати інформацію про DOM поточної сторінки і використовувати її у своєму фоновому скрипті, який зазвичай не має доступу до цих даних.

Long-Lived Connections (довгоживучі сполуки)

Це тип повідомлень, якщо вам потрібен постійний канал зв'язку. Усередині content script пропишіть наступний код:

1
var port = chrome.runtime.connect({name: "my-channel"});
2
port.postMessage({myProperty: "value"});
3
port.onMessage.addListener(function(msg) {
4
    // do some stuff here

5
});

А в background script використовуйте це:

1
chrome.runtime.onConnect.addListener(function(port) {
2
    if(port.name == "my-channel"){
3
        port.onMessage.addListener(function(msg) {
4
            // do some stuff here

5
        });
6
    }
7
});

Override Pages (перевизначити сторінки)

Перевизначення сторінок хороший спосіб настройки браузера. Ви також можете замінити в Chrome деякі сторінки за замовчуванням. Наприклад, створити свою власну сторінку історії. Для цього додайте наступний фрагмент коду:

1
"chrome_url_overrides" : {
2
    "<page to override>;": "custom.html"
3
}

Можливими значеннями для <page to override> будуть bookmarks, history і newtab. Здорово, якщо у вас є свіжа сторінка new tab.


Приклад розширення

На завершення я вирішив включити простий приклад, щоб ви могли краще зрозуміти всю картину. У цьому прикладі використовується більшість речей, які я описав, щоб встановити колір фону #F00 для всіх розділів на поточній сторінці. Не соромтеся завантажити вихідний код по кнопці у верхній частині цієї статті.

Файл manifest

Починаю з файлу manifest:

1
{
2
    "name": "BrowserExtension",
3
    "version": "0.0.1",
4
    "manifest_version": 2,
5
    "description" : "Description ...",
6
    "icons": { "16": "icons/16x16.png", "48": "icons/48x48.png", "128": "icons/128x128.png" },
7
    "omnibox": { "keyword" : "yeah" },
8
    "browser_action": {
9
        "default_icon": { "19": "icons/19x19.png", "38": "icons/38x38.png" },
10
        "default_title": "That's the tool tip",
11
        "default_popup": "browseraction/popup.html"
12
    },
13
    "background": {
14
        "scripts": ["background.js"],
15
        "persistent": false
16
    },
17
    "chrome_url_overrides" : {
18
        "newtab": "newtab/newtab.html"
19
    },
20
    "content_scripts": [{
21
        "matches": ["http://*/*", "https://*/*"],
22
        "js": ["content.js"]
23
    }],
24
    "devtools_page": "devtools/devtools.html"
25
}

Обов'язково потрібно впорядкувати файли в папках. Зверніть увагу на властивість version. Ви повинні оновлювати його кожен раз при завантаженні розширення в веб-магазин.

Background Script

1
// omnibox

2
chrome.omnibox.onInputChanged.addListener(function(text, suggest) {
3
    suggest([
4
      {content: "color-divs", description: "Make everything red"}
5
    ]);
6
});
7
chrome.omnibox.onInputEntered.addListener(function(text) {
8
    if(text == "color-divs") colorDivs();
9
});
10
11
// listening for an event / one-time requests

12
// coming from the popup

13
chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
14
    switch(request.type) {
15
        case "color-divs":
16
            colorDivs();
17
        break;
18
    }
19
    return true;
20
});
21
22
// listening for an event / long-lived connections

23
// coming from devtools

24
chrome.extension.onConnect.addListener(function (port) {
25
    port.onMessage.addListener(function (message) {
26
        switch(port.name) {
27
            case "color-divs-port":
28
                colorDivs();
29
            break;
30
        }
31
    });
32
});
33
34
// send a message to the content script

35
var colorDivs = function() {
36
    chrome.tabs.getSelected(null, function(tab){
37
        chrome.tabs.sendMessage(tab.id, {type: "colors-div", color: "#F00"});
38
        // setting a badge

39
        chrome.browserAction.setBadgeText({text: "red!"});
40
    });
41
}

Перші кілька рядків відображають активність користувача в omnibox. Після цього я встановлюю одноразовий запит, який буде приймати повідомлення по значку browser action.

Наступний фрагмент являє собою довгострокову зв'язок з вкладкою devtools (для цього не обов'язково використовувати long-lived connection, я зробив це тільки для освітніх цілей). Використовуючи прослушку, я можу отримати введення користувача і відправити на content script, який має доступ до елементів DOM. Ключовим моментом тут був вибір вкладки, якої я хотів керувати, а потім відправити їй повідомлення. Нарешті, я помістив бейдж на значок розширення.

Browser Action

Займемося нашим popup.html файлом:

1
// popup.html
2
<script type="text/javascript" src="popup.js"></script>
3
<div style="width:200px">
4
    <button id="button">Color all the divs</button>
5
</div>

Потім створимо файл popup.js:

1
// popup.js

2
window.onload = function() {
3
    document.getElementById("button").onclick = function() {
4
        chrome.extension.sendMessage({
5
            type: "color-divs"
6
        });
7
    }
8
}

Вікно містить кнопку і як тільки користувач натискає на неї, йде повідомлення в background script.

DeveloperTools

1
window.onload = function() {
2
    var port = chrome.extension.connect({ name: "color-divs-port" });
3
    document.getElementById("button").onclick = function() {
4
        port.postMessage({ type: "color-divs"});
5
    }
6
}

Для DeveloperTools ми робимо майже те ж саме, що і у спливаючому вікні, єдина відмінність в тому, що використовується довгострокове з'єднання.

Content Script

1
chrome.extension.onMessage.addListener(function(message, sender, sendResponse) {
2
    switch(message.type) {
3
        case "colors-div":
4
            var divs = document.querySelectorAll("div");
5
            if(divs.length === 0) {
6
                alert("There are no any divs in the page.");
7
            } else {
8
                for(var i=0; i&lt;divs.length; i++) {
9
                    divs[i].style.backgroundColor = message.color;
10
                }
11
            }
12
        break;
13
    }
14
});

Скрипт вмісту прослуховує повідомлення, вибирає все div на поточній сторінці і змінює колір фону. Зверніть увагу на об'єкт, до якого я прикріплював listener. В content script це chrome.extension.onMessage.

Налаштування сторінки New Tab

Останнє, що робить це розширення, настройка сторінки new tab. Ми можемо зробити це просто, вказавши властивість newtab в файлі newtab/newtab.html:

1
"chrome_url_overrides" : {
2
    "newtab": "newtab/newtab.html"
3
}

Майте на увазі, це не буде реплікою new tab за замовчуванням. Ідея цієї функції полягає в додаванні зовсім інший функціональності. Ось, що сказано в Google:

Не намагайтеся переробляти сторінку New Tab. API для зміни версії сторінки New Tab - з верхніми сторінками, недавно закритими сторінками, порадами, фоновим зображенням теми ті інше - поки не існує.  Поки цього немає, вам краще спробувати зробити щось інше.


Debugging (налагодження)

При написанні розширення для Google Chrome ви, ймовірно, зіткнетеся з деякими проблемами. Добре, що ви можете використовувати консоль для виведення змінних, щоб допомогти в її налагодженні. Додавайте console.log в ваші background або content scripts. Однак це не буде працювати в скриптах, які запускаються в контексті інструментів розробника, використовуйте метод alert, який працює скрізь.


Висновок

На мій погляд, Chrome - один з кращих браузерів. Розробники в Google полегшують нам створення розширень, надаючи можливість робити їх в HTML, CSS і JavaScript.

Так, не без складнощів, але, як правило, ми можемо створювати цінні плагіни. Майте на увазі, що ця стаття не охоплює все, що пов'язано з розробкою розширень Chrome. Існують і інші корисні функції, такі як context menus, options pages і notifications. За більш детальною інформацією звертайтеся в documentation.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.