chrome 插件開發

寫在開頭: 至關有意思的UI界面,編碼實現,瀏覽速度.對於一天瀏覽器使用超過10個小時的人來講,可以定製本身的瀏覽器,是至關的具備誘惑力. 

Getting Started 
1:目前不支持標準發佈版本的Chrome插件擴展,不過也有消息立刻就開發了,對於咱們這個不是問題.4.0使用中 
2:建立一個所必要的文件夾,名字任意,用於存放所需文件,開發後,能夠經過Chrome打包提交 
3:manifest.json文件,存放描述信息,也能夠理解爲插件運行的總入口,使用JSON的格式進行定義 

  "name": "My First Extension", //程序名稱 
  "version": "1.0", //版本 
  "description": "The first extension that I made.",//描述 
  "browser_action": {//對瀏覽器的操做 
    "default_icon": "icon.png"//圖標 
  }, 
  "permissions": [ //權限,用於定義所需的網絡資源 
    "http://api.flickr.com/" 
  ] 

4:能夠在browser_action中對功能進行添加 
"popup": "popup.html"//指定點擊按鈕後觸發的行爲, 

5:彈出的html擴展名文件,進行編寫彈出窗編寫,容許使用Js and css,使用的時候注意HTML必須包含在文件夾內 
尤爲指出,其中可使用HTML5標準的元素 
插件包含的文件 
1:manifest 文件,2:任意個HTML文件,3:JavaScript文件,4:圖片Image文件 
打包後會被壓縮成特殊格式的zip文件,擴展名爲.crx 

background page :用於保存插件的主要邏輯, 
插件的邏輯分爲: page action,browser action兩種,,background.html文件的js同時控制兩種action 

action,能夠理解爲動做,也就是瀏覽器表現出來的行爲,如彈出窗同樣 
browser_action 包括 a tooltip, a badge, and a popup. 

能夠在Manifest文件中註冊所需的browser action,其中default_icon爲必須的,其餘均爲可選(or) 

UI部分 
Icon:大多圖片格式均可以,推薦使用19像素的正方形圖片,設置的方式分爲兩種,manifest文件內的default_icon,或者調用setIcon()方法 
Tooltip:設置manifest的default_title屬性,或調用setTitle()方法 
Badge:用於在圖標下顯示的字符,字數限制在4個字符一下,能夠經過setBadgeText() and setBadgeBackgroundColor()設置內容和背景色 
Popup:點擊後彈出的窗口.定義在manifest文件中,browser_action的popup屬性 

chrome.browserAction的經常使用方法,其中參數使用json對象,具體查看對應的API查詢key 

setBadgeBackgroundColor: 設置Badge背景色 
chrome.browserAction.setBadgeBackgroundColor(object details); 

setBadgeText:Badge內容 
chrome.browserAction.setBadgeText(object details) 

setIcon:設置圖標 
chrome.browserAction.setIcon(object details) 

shetTitle:設置Tooltip 
chrome.browserAction.setTitle(object details) 

browserAction的事件 
chrome.browserAction.onClicked.addListener(function(Tab tab) {...}); //將會在點擊圖標後觸發 
//這裏的參數,比Js多了一種類型 

2:爲插件提供對應的options選項頁面,在manifest文件中添加對應的options_page:選項,使用HTML 
"options_page": "options.html", 

所需的HTML能夠爲一個完整格式的HTML文檔,包含所需的html元素 

Override界面: 用於替換新tab界面,區別於默認的界面,在manifest文件中進行註冊 
"chrome_url_overrides": { 
    "newtab": "newtab.html" 
  }, 

Page Actions: 用於出如今指定頁面中的圖標 
"page_action": { 
    "default_icon": "icons/foo.png", // required 
    "default_title": "Do action",    // optional; shown in tooltip 
    "popup": "popup.html"            // optional 
  }, 
區別Browser action,page action並不包含badges,可是能夠控制page action是否顯示,經過調用 show() and hide() methods 

一樣對browser的建議也適用與page action; 

一些常見Page action的方法 
hide;  
chrome.pageAction.hide(integer tabId) 
setIcon 
chrome.pageAction.setIcon(object details) 
setTitle 
chrome.pageAction.setTitle(object details) 
show 
chrome.pageAction.show(integer tabId) 
事件,相似browser action的事件 
onClicked 
chrome.pageAction.onClicked.addListener(function(tab) {...}); 

Themes皮膚 
也是打包成標準的擴展組件,可是並不包含對應的JS和HTML代碼,只用主要的manifest.json文件進行設置 

  "version": "2.6", 
  "name": "camo theme", 
  "theme": { 
    "images" : { 
      "theme_frame" : "images/theme_frame_camo.png", 
      "theme_frame_overlay" : "images/theme_frame_stripe.png", 
      "theme_toolbar" : "images/theme_toolbar_camo.png", 
      "theme_ntp_background" : "images/theme_ntp_background_norepeat.png", 
      "theme_ntp_attribution" : "images/attribution.png" 
    }, 
    "colors" : { 
      "frame" : [71, 105, 91], 
      "toolbar" : [207, 221, 192], 
      "ntp_text" : [20, 40, 0], 
      "ntp_link" : [36, 70, 0], 
      "ntp_section" : [207, 221, 192], 
      "button_background" : [255, 255, 255] 
    }, 
    "tints" : { 
      "buttons" : [0.33, 0.5, 0.47] 
    }, 
    "properties" : { 
      "ntp_background_alignment" : "bottom" 
    } 
  } 


默認皮膚,能夠經過下面的連接進行查看 
http://src.chromium.org/viewvc/chrome/trunk/src/chrome/browser/browser_theme_provider.cc 

其中tints中,使用 Hue-Saturation-Lightness  灰度 飽和 亮度進行設置,值都是在0-1之間 

瀏覽器交互: Browser Interaction 
Bookmarks,Events,Tabs,Windows等 

Bookmarks,收藏夾,能夠建立,組織和管理收藏夾 
設置權限: manifest文件中 
"permissions": [ 
    "bookmarks" 
  ], 
收藏夾使用tree的形式保存對象,其中主要使用 BookmarkTreeNode對象進行訪問,經常使用的屬性有:index, title, and url. 

注:樹結構自己比較繁瑣一些,可使用下面方法參考進行訪問 
    function btnclick(){ 
    chrome.bookmarks.getTree(function(ass){ 
    console.log(ass[0].children[0]); 
          for(obj in ass[0].children[0].children){ 
          console.log(ass[0].children[0].children[obj].title); 
          } 
    }) 
    } 
建議先查看debug方法(ps:比較繁瑣,可是配合console.log比較方便查看對象結構) 

其中的id使用的也是自增,由0開始 
常見的方法  
create , get getChildren getTree move remove removeTree search update 
常見的事件 

常見的事件 
onChanged onChildrenReordered onCreated onMoved onRemoved 

使用的例子: 
chrome.bookmarks.onMoved.addListener(...) 
chrome.bookmarks.getTree(...) //具體請查看API 

Event事件的使用例子 
chrome.tabs.onCreated.addListener(function(tab) { 
  appendToLog('tabs.onCreated --' 
              + ' window: ' + tab.windowId 
              + ' tab: '    + tab.id 
              + ' index: '  + tab.index 
              + ' url: '    + tab.url); 
}); 
注意加載對應的permissions權限 tabs 
事件的所有操做方法: 
void addListener(function callback(...)) 
void removeListener(function callback(...)) 
bool hasListener(function callback(...)) 

Tabs  用於控制每一個標籤 , 調用時爲chrome.tabs 
常見的方法: 
captureVisibleTab connect create detectLanguage executeScript get getAllInWindow getSelected insertCSS move remove sendRequest update 

常見的事件: 
onAttached onCreated onDetached onMoved onRemoved onSelectionChanged onUpdated 

Windows  Chrome中的多窗口 

方法調用中可選的windowId參數,默認爲當前窗口 

調用對象: chrome.windows 

常見的方法: create get getAll getCurrent getLastFocused remove update 
常見的事件:onCreated onFocusChanged onRemoved 

Background Pages, 註冊在manifest文件中,用於保存長時間運行的腳本,運行在插件所在的進程中,多用於相似守護線程同樣的做用,用於狀態的更新 
獲取頁面的方式: 
var views = chrome.extension.getViews(); //獲取到的數組,經過循環或者索引獲得指定的view也就是js的windows對象,不過這裏只侷限配置在manifest中的html元素 
"background_page": "background.html", 

Content Scripts 用於對指定頁面的內容進行腳本調用 
一樣 須要在manifest文件中進行註冊 
  "content_scripts": [ 
    { 
      "matches": ["http://www.google.com/*"], 
      "css": ["mystyles.css"], 
      "js": ["jquery.js", "myscript.js"] 
    } 
  ], 
  
常見的屬性: 
matches, 字符串數組,根據制定的匹配模式進行對指定URL頁面的注入 
js:指定的腳本文件將會被注入到符合的頁面中去 可選 
css:須要被嵌入的css,可選 
run_at:用於設置什麼時候進行注入,默認爲document_idle,還有其餘的:document_start,document_end, 
all_frames:boolean 默認爲false 

使用的方式能夠參考官方文檔,不過注意並不能簡單的替換同名function來達到注入替換事件的效果,不過能夠直接使用document.getElementById獲取指定的dom組件,並進行修改. 
做用域的問題上: 對於原有的變量並不能訪問到,若是須要進行替換,須要進行完整的事件,變量進行從新聲明替換 
比較特殊的做用域:對於注入的代碼,將會有一個封閉的做用域,並不會與原有的進行衝突,當卻能夠修改頁面的DOM元素 javascript

Content script是在一個特殊環境中運行的,這個環境成爲isolated world(隔離環境)。它們能夠訪問所注入頁面的DOM,可是不能訪問裏面的任何javascript變量和函數。 對每一個content script來講,就像除了它本身以外再沒有其它腳本在運行。 反過來也是成立的: 頁面裏的javascript也不能訪問content script中的任何變量和函數。css

 

爲頁面元素添加插件內圖片的例子 
var imgURL = chrome.extension.getURL("images/myimage.png"); 
document.getElementById("someImage").src = imgURL; 

Cross-Origin XMLHttpRequest 跨站點的異步調用,用於使用插件訪問其餘網站的API 
分爲本地與外部數據兩種方面 

本地插件內數據:不須要設置權限 
var xhr = new XMLHttpRequest(); 
xhr.onreadystatechange = handleStateChange; // Implemented elsewhere. 
xhr.open("GET", chrome.extension.getURL('/config_resources/config.json'), true); 
xhr.send(); 
注:0表示本地請求成功 

外部網站,須要設置manifest文件中permissions,添加對應的網站地址,更多使用在插件內部功能上 
"permissions": [ 
    "http://www.google.com/" 
  ], 
對於匹配的URL也可使用模糊匹配 
"http://*.google.com/" 
"http://*/"  表示容許訪問全部的網站 ,這裏注意對https也要獨立的編寫 
內置的json轉換 JSON.parse(....);能夠用於將制定的字符串,轉換成所需的js對象 

再次提示,若是須要訪問其餘網站,必定注意添加權限permissions 

Message Passing 消息傳遞 

Simple one-time requests:發送一個簡單的json數據從一個content script發送到插件的background.html文件中,反之亦然 
chrome.extension.sendRequest() 或 chrome.tabs.sendRequest() methods 
可選的一個回調函數,能夠用於接收返回的內容 
如:定義在content script文件中 
chrome.extension.sendRequest({greeting: "hello"}, function(response) { 
  console.log(response.farewell); 
}); 
在background發送使用特殊一些,須要使用getSelected獲取選中的tab後,而後發送請求 
chrome.tabs.getSelected(null, function(tab) { 
  chrome.tabs.sendRequest(tab.id, {greeting: "hello"}, function(response) { 
    console.log(response.farewell); 
  }); 
}); 

接收的代碼爲: 
chrome.extension.onRequest.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"}); 
    else 
      sendResponse({}); // snub them. 
  }); 

Long-lived connections 長週期鏈接 
可以保持鏈接,持續的進行數據收發 
從content script 鏈接到background(插件)的代碼 
var port = chrome.extension.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"); 
}); 

若是要從background插件處發起鏈接,須要稍做修改,去獲取指定的id 
chrome.tabs.connect(tabId, {name: "knockknock"}). 
設置監聽鏈接的監聽器 
chrome.extension.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."}); 
  }); 
}); 

對應的監聽斷開方法Port.disconnect(),和對應的事件Port.onDisconnect 

Cross-extension messaging 跨插件消息 
主要使用chrome.extension.onRequestExternal or chrome.extension.onConnectExternal 
方法的細節與上述的鏈接事件一致 

這裏仍是提到一下跨站點Js攻擊的問題,少使用eval轉換返回的字符串,而建議使用專門的JSON.parse方法 

NPAPI Plugins 用於提供Js調用本地二進制代碼 ,建議最後使用,也許功能很強大. 

Autoupdating和Packaging章節略過 

由於Chrome開發自WebKit,因此能夠調用其特有的API 
V8 Js引擎也爲chrome提供了JSON對象 
能夠在插件內部集成所需的JS插件,如jQuery 

暫時結束,有空再研究...開始GWT2.0 html

相關文章
相關標籤/搜索