20100915 學習撰寫 google chrome extension

Post on 28-Jan-2015

146 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

DESCRIPTION

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

TRANSCRIPT

學習撰寫Google Chrome Extension

阿修 (Justin Lee)www.lis186.com

2010/9/15

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

Chrome Extension

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

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

開發工具

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

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

Chrome Extension的架構

manifest檔

Browser Action或Page ActionContent Script

Background Page

必備:

至少有一項:

Chrome Extension的通訊

Background Page

Window Content Script

Popup Page

popup

Browser ActionPage Action

message passing

match patternspermissions

Web Page Script

DOM

Chrome Extension的通訊

Background Page

Window Content Script

Popup Page

popup

Browser ActionPage Action

message passing

match patternspermissions

Web Page Script

DOM

Chrome Extension的通訊

Background Page

Window Content Script

Popup Page

popup

Browser ActionPage Action

message passing

match patternspermissions

Web Page Script

DOM

Chrome Extension的架構

.crx{manifest.json.html

.css

.js

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

other files

Chrome Extension API

• 新增使用者介面• Browser Actions

• Page Actions

• 與網頁或server互動• content script

• cross-origin XMLHttpRequests

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

• bookmarks

• history

• cookies

• 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.*

範例:現在天氣怎麼樣

顯示目前位置的氣象狀態

Manifest FileBackground PagePopup PageBrowser ActionOption Pagei18n

你可以學到:

功能:

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

Step2:取得目前位置

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

manifest.json

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>

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

lukhnos

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

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/前面要加上

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

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"; } });}...

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",...

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顯示詳細資訊

<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

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;}

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>...

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"); } }}...

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

.crx{manifest.json.html

.css

.js

.png, .jpg, .gif

_locales{en

zh_TW messages.json(zipped folder)

別忘了設定default_locale

{ "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

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" }}

...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

Step9:封裝擴充功能

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

擴充功能

Step10:上傳到Chrome Extensions Gallery

Q&A

Thank you!

top related