Google Chrome Extensions: швидкий перекладач своїми руками

image

Нещодавно помітив, що нехай мій англійська не так вже й поганий, я все одно досить часто відволікаюся на переклад окремих незнайомих слів. І так як мені набридло кожен раз витрачати на це свій час я вирішив написати розширення-перекладач. Можна сказати:
Але такі вже є!
Так, є, але, по-перше, я раніше не писав розширення для браузерів і хотів спробувати, по-друге, створювати щось самому завжди веселіше ніж користуватися готовим. Так що кому це цікаво так само як і мені — ласкаво просимо під кат.

А саму статтю я вирішив написати, бо багато інформацію доводилося збирати по частинах з далеких куточків інтернету, і я вирішив трохи об'єднати.

Отже, здаємо у фізичних ближче до каміна відкриваємо Notepad++, VS Code або будь-який інший зручний редактор і починаємо.

1. Підготовка необхідних файлів
Нам знадобляться:

  1. Manifest.json — тут буде зберігатися версія нашого розширення, назва, список використовуваних файлів дозволу.
  2. Popup.html — це обличчя нашого розширення, тут ми напишемо popup-станічку, яка буде відображатись при натисканні на іконку нашого розширення
  3. Background.html — це все фонові процеси нашого розширення.
  4. 4 іконки: 16х16, 36х36, 48х48, 128х128 — це іконка вашого додатки, хром і сам може підганяти іконку під потрібний розмір, але ви можете виставити різні іконки і в залежності від цього вони будуть різними в контекстному меню, біля адресного рядка, меню розширень і т. д.
Відразу невелика виноска про те, як завантажувати розширення в gogle chrome:
  1. Зберігаємо всі файли розширення в окрему папку
  2. Відкриваємо Google Chrome -> Опції -> Налаштування -> Розширення

  3. Ставимо галочку режим розробника, натискаємо завантажити розпакований розширення.
    image
  4. Вказуємо шлях до папки з розширенням, натискаємо ОК

2. Притча про маніфесті і popup
І створив програміст маніфест і програміст побачив, що це добре.
Наш manifest.json повинен виглядати приблизно так:
{
"manifest_version": 2,

"name": "Translator",
"version": "1.0",

"icons": {
"16": "16x16.png",
"32": "32x32.png",
"48": "48x48.png",
"128": "128x128.png"
},

"permissions": [
"http://translate.yandex.net/*",
"contextMenus"
],

"browser_action": {
"default_title": "Open translator",
"default_icon": "48x48.png",
"default_popup": "popup.html"
},

"background": {
"page": "background.html"
}
}


Тепер по-порядку:

  • manifest_version — версія нашого маніфесту, зараз актуальна 2 версія.
  • name — назва розширення
  • version — версія розширення, тут повинні бути лише цифри, але в будь-якому форматі: 1.0 або 1.0.0.1 або 1.1.2, можна писати як більше подобається.
  • icons — список іконок нашого розширення
  • permissions — дозволу нашого розширення, посилання дає доступ до певного ресурсу, contextMenus дає доступ до контекстного меню.
  • browser_action: default_title — текст, який буде з'являтися при наведенні мишки на іконку розширення, default_icon — іконка програми за замовчуванням, default_popup — popup-віконце за замовчуванням.
  • background — тут можна підключити фонову сторінку, якщо вона є або фонові скрипти.
З маніфестом розібралися, тепер можна перейти і до більш цікавого заняття. Перед тим як ми почнемо створювати View нашого розширення — нам потрібно завантажити додаткові файли всіх кольорів і забарвлень. Взагалі це необов'язково і хто-то може написати розширення на чистому JS, без сторонніх стилів, але я мені захотілося використовувати Jquery, Bootstrap.

Я вирішив особливо не морочитися з зовнішнім виглядом і швиденько сверстал більш-менш симпатичне віконечко пристойно виглядає перекладача.

popup.html
<!DOCTYPE html>
<html>
<head>
<script src="jquery.js"></script>
<script src="popup.js"></script>
<script src="bootstrap.js"></script>
<link rel="stylesheet" href="bootstrap.css">
<link rel="stylesheet" href="bootstrap-theme.css">
<link rel="stylesheet" href="popup.css">
</head>
<body>
<header>
<img id="logo" src="mixx.png">
</header>

<div id="wrapper">
<div class="li">
<input id="input" class="form-control">
</div>
<div class="li" style="margin-bottom: 10px;">
<button id="btn_submit" type="submit" class="btn btn-default" style="margin-top: 10px;">Перевести</button>
</div>
</div>

<footer id="options" role="button">
<label id="result"></label>
</footer>

</body>
</html>


Не знаю, наскільки особисто ти, читачу, підкований в html, js і css, але на даному рівні я не ставлю за мету пояснити тобі принципи цих мов, все що я використовую і не пояснюю досить примітивно і легко гуглится.

Стилі зовсім не обов'язкові, можна обійтися і без них, але з ними все виглядає трохи доброзичливішим і красивіше.

Створимо файл popup.css і додамо трохи стилів:

popup.css
body
{
min-width: 250px;
margin: 0px;
font-family: Segoe UI, Arial, sans-serif;
font-size: 13px;
background-color: #f8f6f2;
}

header
{
height: 45px;
margin-bottom: 40px;
border-bottom: 1px solid #e1ddd8;
}

#logo
{
display: block;
position: relative;
top: 15px;
margin: 0px auto;
}

#wrapper
{
padding: 0px 20px;
}

footer
{
cursor: pointer;
padding: 10px 35px;
border-top: 1px solid #e1ddd8;
}

footer:hover
{
background: linear-gradient(to bottom, rgba(70, 50, 0, 0.1), rgba(70, 50, 0, 0.1));
}

.li
{
list-style-type: none;
border-top: 1px dashed #a5a4a1;
}

label
{
vertical-align: middle;
}


Тепер наше розширення повинно виглядати приблизно так:

image
Тепер можна переходити до самої логіці перекладача, створюємо файл popup.js
$(document).ready(function(){

$('#btn_submit').click(function(e){ /* Функція почне свою роботу, як тільки користувач клинет по кнопці з id = "btn_submit" */

translate($('#input').val());
});
});


function translate(input) {

var url = "https://translate.yandex.net/api/v1.5/tr.json/translate"; /* Зверніть увагу, що посилання по новому апі яндекса, починаючи з версії 1.5 будується інакше, ніж раніше */

var key = "trnsl.1.1.20170124T214153Z.11b2724899c0a9fc.6d5c7e3a02107ce1349d21bbc6dc9dd4a86dc62a"; /* це ключ вашого додатку, який можна отримати на офіційному сайті яндекса, без нього апі працювати <b>не буде!</b> https://tech.yandex.ru/keys/get/?service=trnsl (отримання ключа)*/

var parent = /[а-яеЕ]/i;

var language = (parent.test(input))? 'ru-en':'uk-ua';

$.getJSON(url, {lang: language, key key, text: input}, function(res){ /* Відповіддю ми отримуємо масив */
$('#result').text("");
for (var i in res.text) {
$('#result').text($('#result').text() + res.text[i] + " ");
}
});
}


Збережемо і завантажимо наше розширення в хром. Іноді кнопка оновити розширення не допомагає і тоді потрібно видалити розширення і завантажити заново.

Перевіряємо роботу, у нас повинно вийти щось подібне:

image
Начебто вже непогано постаралися, але чогось не вистачає. Додамо реакцію на клавішу Enter.

Додаємо код popup.js
$("#input").keyup(function(event){
if(event.keyCode == 13){ /* 13 - віртуальний код клавіші Enter
$("#btn_submit").click();
}
});


Перевіряємо і бачимо, що тепер можна натискати enter, а не клацати по кнопці. Але потрібно додати ще мінімум одну функцію, яка присутня в більшості перекладачів — це копіювання перекладеного тексту в буфер.

Додаємо код popup.js
var options = document.getElementById("options");
if(options) {
options.addEventListener. ("click", function() /* Починаємо чекати кліка по панелі footer */
{
var range = document.createRange(); */ Вертає новий об'єкт Range. */
var value = document.querySelector("#result"); /* Селектор вибирає елемент з id = "result" */
range.selectNode(value); /* Вибір елемента */
window.getSelection().addRange(range); 

try { 
var successful = document.execCommand('copy'); 
var msg = successful ? 'successful' : 'unsuccessful'; 
console.log('Copy email command was' + msg);

} catch(err) {
console.log('Oops, unable to copy'); 
}
window.getSelection().removeAllRanges();
});


Ну що, начебто непогано постаралися над view, тепер у нас є непоганий перекладач, більш того написаний нами! Але не всіх задовольнить такий результат, для таких невтомних шукачів пригод, які намагаються довести інструмент якщо не до досконалості, але хоча б зробити його максимально зручним — не зупинимося на цьому!

Сага про background.js
Перекладач це, звичайно, добре, але адже брати, копіювати і вставляти текст — теж важко, тому нам потрібно зробити так, щоб наше розширення переводило і той текст, який ми виділимо.

Background.html — фонова сторінка і одна з її можливостей — додавати пункт у контекстне меню. У сам background.html ми лише підключаємо скрипти, вони нам і потрібні.

background.js
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="jquery.js"></script>
<script src="background.js"></script>
</head>


А ось з background.js вже більше повеселитися. Створюємо пункт нашої програми в меню:

Додаємо в background.js
chrome.contextMenus.create({
'title': 'Перевести з Translator', /* Текст пункти меню */
'contexts':['selection'], /* Тип пункту меню */
'onclick': function() {} /* Запам'ятайте це місце, замість цієї функції ми будемо вставляти код переказу */
}
});


Тепер коли ми перезагрузим розширення і виділивши який-небудь текст клацнемо правою кнопкою миші — ми побачимо, що в контекстному меню з'явився новий пункт:

image
Тепер потрібно придумати як перекладати цей текст. Спочатку я намагався зробити так, щоб при такому способі перекладу відкривалося наше popup-віконце і переклад був там, але зіткнувся з тим, що Google обмежив можливість відкриття віконця тільки коли користувач натисне на іконку. Тоді я взяв у руки меч вирішив зробити переклад в контекстному меню, як це зроблено в Яндекс браузер:

image
Але так і не зміг знайти інформацію про те як подібним чином змінити контекстне меню. Відкривати нові вкладки я не хочу, тому тут ми з вами трохи схалявим.

В background.js на місце старої порожній функції вставте цей рядок:

Вставити код в background.js
translate(info.selectionText);


І окремо додайте функцію translate:

Вставити код в background.js
function translate(input) {

var url = "https://translate.yandex.net/api/v1.5/tr.json/translate";

var key = "trnsl.1.1.20170124T214153Z.11b2724899c0a9fc.6d5c7e3a02107ce1349d21bbc6dc9dd4a86dc62a";

var parent = /[а-яеЕ]/i;

var language = (parent.test(input))? 'ru-en':'uk-ua';

$.getJSON(url, {lang: language, key key, text: input}, function(res){
alert(res.text);
});
}


Перевіримо роботу і побачимо, що коли ми виділяємо текст і натискаємо в контекстному меню команду перевести, з'являється ось таке віконце:

image
Ну ось і все, друзі! Якщо хтось підкаже найкращий спосіб реалізації перекладу за допомогою контекстного меню — буду радий почути.



За інформацію про реалізації подібних речей висловлюю свою подяку статтями на Habrahabr і відповідей на StackOverflow.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.