39
學習撰寫 Google Chrome Extension 阿修 (Justin Lee) www.lis186.com 2010/9/15

20100915 學習撰寫 Google Chrome Extension

Embed Size (px)

DESCRIPTION

Taipei Google Technology User Group於2010/9/15的Google Chrome Extension開發教學。

Citation preview

Page 1: 20100915 學習撰寫 Google Chrome Extension

學習撰寫Google Chrome Extension

阿修 (Justin Lee)www.lis186.com

2010/9/15

Page 2: 20100915 學習撰寫 Google Chrome Extension

請先下載範例檔http://db.tt/ibyqL61

Page 3: 20100915 學習撰寫 Google Chrome Extension

Chrome Extension

• 擴充Google Chrome的功能• 使用HTML,CSS和Javascript撰寫• 可使用任何Chrome支援的技術,如:XMLHttpRequest,JSON,HTML5

• 安裝後無須重新啓動• 自動更新

Page 4: 20100915 學習撰寫 Google Chrome Extension

開發工具

• Google Chrome • 開發人員工具• Javascript控制台• 文字編輯器(Mac OSX上推薦textmate)

•圖形處理軟體(畫icon用,非必要)

Page 5: 20100915 學習撰寫 Google Chrome Extension

Chrome Extension的架構

manifest檔

Browser Action或Page ActionContent Script

Background Page

必備:

至少有一項:

Page 6: 20100915 學習撰寫 Google Chrome Extension

Chrome Extension的通訊

Background Page

Window Content Script

Popup Page

popup

Browser ActionPage Action

message passing

match patternspermissions

Web Page Script

DOM

Page 7: 20100915 學習撰寫 Google Chrome Extension

Chrome Extension的通訊

Background Page

Window Content Script

Popup Page

popup

Browser ActionPage Action

message passing

match patternspermissions

Web Page Script

DOM

Page 8: 20100915 學習撰寫 Google Chrome Extension

Chrome Extension的通訊

Background Page

Window Content Script

Popup Page

popup

Browser ActionPage Action

message passing

match patternspermissions

Web Page Script

DOM

Page 9: 20100915 學習撰寫 Google Chrome Extension

Chrome Extension的架構

.crx{manifest.json.html

.css

.js

.png, .jpg, .gif(zipped folder)

other files

Page 10: 20100915 學習撰寫 Google Chrome Extension

Chrome Extension API

• 新增使用者介面• Browser Actions

• Page Actions

• 與網頁或server互動• content script

• cross-origin XMLHttpRequests

• 操作瀏覽器的功能• windows, tabs

• bookmarks

• history

• cookies

Page 11: 20100915 學習撰寫 Google Chrome Extension

• chome.extension.*

• chrome.browerAction.*

• chrome.pageAction.*

• chrome.tabs.*

• chrome.windows.*

• chrome.bookmarks.*

Chrome Extension API

• chrome.cookies.*

• chrome.history.*

• chrome.contextMenus.*

• chome.i18n.*

• chrome.idle.*

Page 12: 20100915 學習撰寫 Google Chrome Extension

範例:現在天氣怎麼樣

顯示目前位置的氣象狀態

Manifest FileBackground PagePopup PageBrowser ActionOption Pagei18n

你可以學到:

功能:

Page 13: 20100915 學習撰寫 Google Chrome Extension

Step1:建立Browser Action UI

{ "name": "現在天氣怎麼樣", "version": "0.1", "description": "顯示所在地現在的天氣狀態", "icons": { "16": "images/icon_16.png", "32": "images/icon_32.png", "64": "images/icon_64.png", "128": "images/icon_128.png" }, "browser_action": { "default_icon": "images/loading.png", "default_title": "現在天氣怎麼樣" }}

manifest.json

Page 14: 20100915 學習撰寫 Google Chrome Extension

Step2:取得目前位置

{ "name": "現在天氣怎麼樣", "version": "0.2", "description": "顯示所在地現在的天氣狀態", "icons": { ... }, "background_page": "background.html", "permissions": [ "geolocation" ], "browser_action": { "default_icon": "images/loading.png", "default_title": "現在天氣怎麼樣" }}

manifest.json

Page 15: 20100915 學習撰寫 Google Chrome Extension

background.html<html><head><meta charset="utf-8" /><script>

var errorCode;var lat;var lng;

function getCurrentLocation(){ navigator.geolocation.getCurrentPosition(success, error);}

function success(position){ console.log(position); lat=Math.round(position.coords.latitude*1000000); lng=Math.round(position.coords.longitude*1000000);}

function error(msg){ console.log(msg); chrome.browserAction.setBadgeText({text:"?"}); errorCode="unable_to_locate_your_position";}

getCurrentLocation();

</script></head></html>

Page 16: 20100915 學習撰寫 Google Chrome Extension

『如果你寫程式沒用undocumented API,那一定是因為你的程式沒什麼了不起的功能。』

lukhnos

http://lukhnos.org/blog/zh/archives/581

Page 17: 20100915 學習撰寫 Google Chrome Extension

http://www.google.com/ig/api?hl={locale}&weather=,,,{lat},{lng}

Google’s secret Weather API

http://www.google.com/ig/api?hl=zh-tw&weather=,,,25060808,121485606

<?xml version="1.0"?><xml_api_reply version="1"><weather module_id="0" tab_id="0" mobile_row="0" mobile_zipped="1" row="0" section="0" > <forecast_information> <city data=""/> <postal_code data=""/> <latitude_e6 data="25060808"/> <longitude_e6 data="121485606"/> <forecast_date data="2010-09-15"/> <current_date_time data="2010-09-14 23:00:00 +0000"/> <unit_system data="SI"/> </forecast_information> <current_conditions> <condition data="多雲"/> <temp_f data="79"/> <temp_c data="26"/> <humidity data="濕度: 87%"/> <icon data="/ig/images/weather/cloudy.gif"/> <wind_condition data="風向: 公里/小時"/> </current_conditions> <forecast_conditions> <day_of_week data="週三"/> <low data="26"/> <high data="35"/> <icon data="/ig/images/weather/thunderstorm.gif"/> <condition data="晴午後短暫雷陣雨"/> </forecast_conditions> ...</weather></xml_api_reply>

http://img0.gmodules.com/前面要加上

Page 18: 20100915 學習撰寫 Google Chrome Extension

Step3:取得目前位置的天氣狀態

{ "name": "現在天氣怎麼樣", "version": "0.3", "description": "顯示所在地現在的天氣狀態", "icons": { ... }, "background_page": "background.html", "permissions": [ "http://www.google.com/ig/*", "http://img0.gmodules.com/ig/images/weather/", "geolocation" ], "browser_action": { ... }}

manifest.json

Page 19: 20100915 學習撰寫 Google Chrome Extension

background.html...var weatherXML;var current;...function success(position){ ... getWeather();}...function getWeather(){ console.log("http://www.google.com/ig/api?hl=zh_tw&weather=,,,"+lat+","+lng); $.get("http://www.google.com/ig/api?hl=zh_tw&weather=,,,"+lat+","+lng, function(data) { weatherXML=data; if($(weatherXML).find("weather current_conditions").length==1) { current={}; current.condition=$(weatherXML).find("current_conditions condition").attr("data"); current.temp_c=$(weatherXML).find("current_conditions temp_c").attr("data")+"℃"; current.temp_f=$(weatherXML).find("current_conditions temp_f").attr("data")+"℉"; current.humidity=$(weatherXML).find("current_conditions humidity").attr("data"); current.wind_condition=$(weatherXML).find("current_conditions wind_condition").attr("data"); current.icon="http://img0.gmodules.com"+$(weatherXML).find("current_conditions icon").attr("data"); console.log(current); chrome.browserAction.setBadgeText({text:current.temp_c}); chrome.browserAction.setIcon({path:current.icon}); } else { chrome.browserAction.setBadgeText({text:"?"}); errorCode="unable_to_load_data"; } });}...

Page 20: 20100915 學習撰寫 Google Chrome Extension

background.html...

function startRequest(){ getCurrentLocation(); }

function scheduleRequest() { var reqeustInterval = 1000 * 60 * 5; console.log("Scheduling request..."); window.setTimeout(startRequest, reqeustInterval);}startRequest();scheduleRequest();...

Step4:每五分鐘更新一次天氣manifest.json..."version": "0.4",...

Page 21: 20100915 學習撰寫 Google Chrome Extension

manifest.json

{ "name": "現在天氣怎麼樣", "version": "0.5", "description": "顯示所在地現在的天氣狀態", "icons": { ... }, "background_page": "background.html", "popup": "popup.html", "permissions": [ ... ], "browser_action": { "default_icon": "images/loading.png", "default_title": "現在天氣怎麼樣", "default_popup": "popup.html" }}

Step5:在popup顯示詳細資訊

Page 22: 20100915 學習撰寫 Google Chrome Extension

<html><head><meta charset="utf-8" /><script type="text/javascript" src="jquery.min.js"></script> <script>var current;var errorCode;function renderPage(){ current=chrome.extension.getBackgroundPage().current; errorCode =chrome.extension.getBackgroundPage().errorCode; if(current) { $("#temp").html('<img src='+current.icon+'>'+current.temp_c); $("#detail").html(current.condition+'<br>'+current.humidity+'<br>'+current.wind_condition); } else { switch(errorCode){ case "unable_to_locate_your_position": $("#current").html("無法確定目前所在位置。"); break; case "unable_to_load_data": $("#current").html("無法載入資料。"); break; default: $("#current").html("資料載入中..."); } }}</script></head><body onload="renderPage();"><div id="current" style="width: 160px"><div id="temp"></div><div id="detail"></div></div></body>

popup.html

Page 23: 20100915 學習撰寫 Google Chrome Extension

manifest.json..."version": "0.6",...

Step6:把popup裝飾一下

style.cssbody{ font-size: 14px; color: #333;}

img{ padding-right: 8px;}

#temp{ color: #333; font-size: 48px; font-family: Arial; text-shadow:3px 3px 3px #EEE;}

Page 24: 20100915 學習撰寫 Google Chrome Extension

manifest.json... "version": "0.6",... "options_page": "options.html",...

Step7:新增溫度單位切換選項

options.html...<body onload="restoreOption();"> 溫度單位<input type="radio" name="temp_mode" value="C" checked>攝氏 <input type="radio" name="temp_mode" value="F">華氏<br><button onclick="saveOption();">儲存</button><div id="status"></div></body>...

Page 25: 20100915 學習撰寫 Google Chrome Extension

options.html...function saveOption(){ if(localStorage["temperature_mode"] != $('input[name=temp_mode]:checked').val()) { localStorage["temperature_mode"] = $('input[name=temp_mode]:checked').val(); chrome.extension.getBackgroundPage().getWeather(); }

console.log(localStorage["temperature_mode"]); $("#status").html("儲存完成。<a href='javascript:window.close();'>按此關閉</a>");}

function restoreOption(){ var temp_mode=localStorage["temperature_mode"]; if(!temp_mode) { return; }else { switch(temp_mode) { case "C": $("input[name=temp_mode]")[0].checked=true; break;

case "F": $("input[name=temp_mode]")[1].checked=true; break;

default: console.log("error"); } }}...

Page 26: 20100915 學習撰寫 Google Chrome Extension

Step8:讓「歪果人」也看得懂(i18n)

.crx{manifest.json.html

.css

.js

.png, .jpg, .gif

_locales{en

zh_TW messages.json(zipped folder)

別忘了設定default_locale

Page 27: 20100915 學習撰寫 Google Chrome Extension

{ "extName": { "message": "現在天氣怎麼樣", "description":"擴充套件名稱" }, "extDescription": { "message": "顯示所在地現在的天氣狀態", "description":"擴充套件描述" }, "locale": { "message": "zh-tw", "description":"要傳送給Google Weather API的語系編碼" }, "loading": { "message": "資料載入中...", "description":"載入資料時的popup內容" }, "unable_to_load_data": { "message": "無法載入資料。", "description":"資料載入錯誤時的popup內容" }

...}

zh_tw/messages.json

{ "extName": { "message": "How is the weather now", "description":"擴充套件名稱" }, "extDescription": { "message": "Display current weather condition here.", "description":"擴充套件描述" }, "locale": { "message": "en", "description":"要傳送給Google Weather API的語系編碼" }, "loading": { "message": "Loading...", "description":"載入資料時的popup內容" }, "unable_to_load_data": { "message": "Unable to load data.", "description":"資料載入錯誤時的popup內容" } ...}

en/messages.json

Page 28: 20100915 學習撰寫 Google Chrome Extension

masifest.json

{ "name": "__MSG_extName__", "version": "1.0", "description": "__MSG_extDescription__", "default_locale": "zh_TW", "icons": { ... }, ... ], "browser_action": { "default_icon": "images/loading.png", "default_title": "__MSG_extName__", "default_popup": "popup.html" }}

Page 29: 20100915 學習撰寫 Google Chrome Extension

...var locale=chrome.i18n.getMessage("locale");...

function getWeather(){... $.get("http://www.google.com/ig/api?hl="+locale+"&weather=,,,"+lat+","+lng, function(data) {...}

background.html

...function renderPage(){ $("#temperature_scale").html(chrome.i18n.getMessage("temperature_scale")); $("#celsius").html(chrome.i18n.getMessage("celsius")); $("#fahrenheit").html(chrome.i18n.getMessage("fahrenheit")); $("#save").html(chrome.i18n.getMessage("save"));}</script></head><body onload="restoreOption();renderPage();"><span id="temperature_scale"></span><input type="radio" name="temp_mode" value="C" checked><span id="celsius"></span> <input type="radio" name="temp_mode" value="F"><span id="fahrenheit"></span><br><button onclick="saveOption();"><span id="save"></span></button><div id="status"></div></body>

options.html

Page 30: 20100915 學習撰寫 Google Chrome Extension

Step9:封裝擴充功能

{extName}.crx{extName}.pem 祕密金鑰

擴充功能

Page 31: 20100915 學習撰寫 Google Chrome Extension

Step10:上傳到Chrome Extensions Gallery

Page 32: 20100915 學習撰寫 Google Chrome Extension
Page 33: 20100915 學習撰寫 Google Chrome Extension
Page 34: 20100915 學習撰寫 Google Chrome Extension
Page 35: 20100915 學習撰寫 Google Chrome Extension
Page 36: 20100915 學習撰寫 Google Chrome Extension
Page 37: 20100915 學習撰寫 Google Chrome Extension
Page 38: 20100915 學習撰寫 Google Chrome Extension

Q&A

Page 39: 20100915 學習撰寫 Google Chrome Extension

Thank you!