How to create a chrome extension
I. Giới thiệu Về cơ bản extension dựa trên nền tảng javascript cho phép add các functionnality vào chrome . Chúng ta có thể sử dụng javascript, html, css inject trực tiếp native code của webpage để đạt được một số chức năng mong muốn II. Nội Dung 2.1: Cấu trúc của môt extension Một ...
I. Giới thiệu
Về cơ bản extension dựa trên nền tảng javascript cho phép add các functionnality vào chrome . Chúng ta có thể sử dụng javascript, html, css inject trực tiếp native code của webpage để đạt được một số chức năng mong muốn
II. Nội Dung
2.1: Cấu trúc của môt extension
- Một extension có cấu trúc cơ bản như sau:
|----------locales | |------ en | | |------messages.json | |-------vi | |------messages.json |------------icons(*) |------------js | |---------background.js(*) | |---------contentscript.js(*) |----------popup | |----------popup.html | |----------popup.js |----------options |----------manifest.json(**)
(*)là thành phần quan trọng của nên có của một extension
(**) là thành phần bắt buộc phải có. nó định nghĩa tất cả quy tắc, quyền, lấy resource, etc... của extension
2.2 . manifest.json
Như đã nói ở trên, file manifest là file chưa thông tin quan trọng nhất về extension của bạn như name, description, các permission, content_security_policy extension cần. Nó được đinh nghĩa như sau:
{ "name": "__MSG_extName__", "description": "__MSG_extDesc__", "default_locale": "en", "content_scripts": [ { "matches": [ "http://*", "https://*"], "js": [ "contentscript.js"], "run_at": "document_start", "all_frames": true } ], "background": { "scripts": [ "background.js" ] }, "content_security_policy": "script-src 'self' https://ssl.google-analytics.com; object-src 'self'", "icons": { "128": "img/icon128.png", "16": "img/icon16.png", "48": "img/icon48.png" }, "manifest_version": 2, "page_action": { "default_icon": { "19": "img/icon19.png", "38": "img/icon38.png" }, "default_title": "xxxxxx" }, "permissions": ["tabs", "cookies", "contextMenus", "http://*/*", "https://*/*", "webRequest", "webRequestBlocking", "webNavigation"], "version": "2015.21.9.1", "web_accessible_resources": [ "*" ]
2.3 Locales
Có thể các bạn đã từng làm quen vấn đề đa ngôn ngữ khi viết một website sử dụng php, rails... hay trên các app mobile. Chrome extension cũng cho phép chúng ta có thể tạo đa ngôn ngữ thông qua folder locales. Trong locales sẽ là các thư mục là code name của các quốc gia như en,vi, ar, ru.... Để định nghĩa name, description sử dụng đã ngôn ngữ trong file manifest.json cần định nghĩa :
{ "name": "__MSG_extName__", "description": "__MSG_extDesc__", "default_locale": "en" }
và trong messages.json
{ "extName": { "message": "name” }, "extDesc": { "message": "description" } }
Việc này đặc biệt quan trọng cho SEO extension của bạn Bạn có thể định nghĩa bất kì string nào sử dụng i18n sau đó gọi ra bằng lệnh chrome.i18n.getMessage(“attribute”); Tuy nhiên i18n chỉ dc gọi trong js và css → ko dùng i18n trực tiếp trong html . không sao, mình vẫn có thể dùng dc bắng cách viết các thẻ html thêm một attibute ví dụ data-i18n. Sau đó viết 1 file js sử dụng sự kiện onload html đó làm thay đổi text của các element ta cần dung i18n. Ví dụ html mình có đoạn code sau:
<ul> <li data-i18n = "li_1"></li> <li data-i18n = "li_2"></li> <li data-i18n = "li_3"></li> <li data-i18n = "li_4"></li> <li data-i18n = "li_5"></li> <li data-i18n = "li_6"></li> </ul>
khi đó để sử dụng i18n ta cần dùng 1 đoạn script:
window.onload = function () { $('[data-i18n]').each(function() { var el = $(this); var name = $(this).attr("data-i18n") var resourceText = chrome.i18n.getMessage(name); el.text(resourceText); }); }
Tham khảo thêm tại https://developer.chrome.com/extensions/i18n
2.3. Contentscript:
Thành phần này vô cùng đặc biệt , nó là 1 file run bên trong context của webpage. Có nghĩa nếu extension muốn thay đổi, thực hiện chức năng gì(đổi text, thêm css vào các thẻ, delete các thẻ, etc...) với webpage thỳ phải thông qua file này.
Nó có thể được call file manifest (run khi extension được enable) or inject trực tiếp từ background.js thông qua hàm
chrome.tabs.executeScript(tab.id, { file: "contentscript.js" });
2.4 BrowserAction, Pageaction
BrowserAction: put icon vào google toolbar. PageAction: put icon vào trong thanh addressbar Cả 2 đều có các method gần tương tự nhau như onClicked(), getPopup(), setPopup(); Mặc định khi định nghĩa trong manifest khi click icon thỳ popup của extension sẽ được bật ra. Khác nhau cơ bản của 2 loại này là browserAction có thể set badge text bên dưới icon và enable, disable theo từng tab id. 2.5 Background
Thành phần chạy liên tục bên dưới của extension. Nó tồn tại trong suốt vòng đời của một extension. Gân như nó là 1 xương sống của extension. Nó hơi giống như controller trong mô hình MVC như truyền message qua lại giữa webpage và extension, qua lại giữa popup, option và background, qua lại giữa popup và contenscript. Từ background này có thể open các tab mong muốn, lưu dữ liệu tạm thời trên locaStorage or Storage.
Định nghĩa trong manifest như sau:
"background": { "scripts": ["background.js"] }, ...
2.6 message passing
Phần này đặc biệt quan trọng vì nó gần như là xương sống của extension. Có 3 cách để truyền message tham khảo ở: https://developer.chrome.com/extensions/messaging nhưng với mình dùng cách đơn giản nhất để tuyền message là one time-request. sử dụng
chrome.runtime.sendMessage({greeting: "hello"}, function(response) { console.log(response.farewell); });
để send message và
chrome.runtime.onMessage.addListener( function(request, sender, sendResponse) { console.log(sender.tab ? "from a content script:" + sender.tab.url : "from the extension"); if (request.greeting == "hello") sendResponse({farewell: "goodbye"}); });
để nhận message.
Background, contentscript có thể truyền rất nhiều request cho nhau nhưng rất đơn giản để phân biệt các request đó dựa vao các “key” mình định nghĩa.
Cách thứ 2 có thể dùng là long-live connection. Với cách này background sẽ mở 1 kênh truyền dữ liệu với name xác định, contenscript khi kết nối vào kênh này sẽ nhận dữ liệu trực tiếp từ background. Ví dụ gửi message:
var port = chrome.runtime.connect({name: "knockknock"}); port.postMessage({joke: "Knock knock"}); port.onMessage.addListener(function(msg) { if (msg.question == "Who's there?") port.postMessage({answer: "Madame"}); else if (msg.question == "Madame who?") port.postMessage({answer: "Madame... Bovary"}); });
và nhận message
chrome.runtime.onConnect.addListener(function(port) { console.assert(port.name == "knockknock"); port.onMessage.addListener(function(msg) { if (msg.joke == "Knock knock") port.postMessage({question: "Who's there?"}); else if (msg.answer == "Madame") port.postMessage({question: "Madame who?"}); else if (msg.answer == "Madame... Bovary") port.postMessage({question: "I don't get it."}); }); });
Cachs 3 là Cross-extension messaging. Với cách này ta có thể truyền gửi message từ các extension với nhau chứ ko đơn thuần truyền trong 1 extension nữa. sử dụng 2 method : runtime.onMessageExternal or runtime.onConnectExternal để truyền và gửi message.
2.7. Publish một extension lên chrome store
Chuẩn bị: 1 tài khoản gmail, 5$$để mua tài khoản develop, 1 extension đã dc zip( chú ý ko được mã hóa code và minimize code không sẽ ko vượt qua dc tester của goole)
Thực hiện: Vào trang dashboard của extension: https://chrome.google.com/webstore/developer/dashboard?authuser=1. Sau đó add new item.
- Phần upload ta upload file zip lên
- Phần detail : bạn điền description cho extension của bạn
- Phần screenshots: bạn có thể chụp ảnh hướng dẫn, video youtube và add vào đây. Sau khi lên google store nó sẽ hiện ra những ảnh or video đó
- Phần icon bạn upload icon 128x128.
- Phần category bạn chọn một loại category cho extension của mình ví dụ: Func, Social & Communication... Phần Visibility options bạn chọn private or pubic extension của bạn. Khi 1 extension được publish sẽ phải qua tester của google review. Bạn để public thì mọi người mới có thể cài thấy và cài extension
**III. Demo **
-Làm demo đơn giản xóa quảng cáo và các tin sponsored. Ý tưởng khi run extension sẽ ẩn các thẻ chứa quảng cáo và tin sponsored đi. khi disable thỳ show lại các thẻ đó.
Để extension vẫn block ads của facebook khi restart chrome, ta có thể lưu một flag vào localStorage: disable or enable để đánh dấu. Khi chrome dc restart or bật sẽ đọc trong localStorage để nhận biết có call hàm remove hay restore ads đó.
Tham khảo extension tại: https://chrome.google.com/webstore/detail/change-facebook-backgroun/gfehjfafmbljecleaghgbcbfiihmcaen?authuser=1 Và source code tại: https://bitbucket.org/asvenus/facebook-block-ads/src
**IV. Kết luận **
Để tạo môt extension và publish lên rất là đơn giản nhưng để làm được một extension hữu ích cho người sử dụng thy còn cần rất nhiều kiến thức mà trong thời gian cho phép mình chưa thể tìm hiểu hết được. Hy vọng trong các bài report tháng tới sẽ nghiên cứu và viết được mốt số extension hay ho (yaoming)