Apple 中Safari 實(shí)戰(zhàn) 擴(kuò)展開(kāi)發(fā)
本文將詳細(xì)介紹 Safari 5 中的這項(xiàng)新功能 , 并通過(guò)一個(gè)簡(jiǎn)單的例子來(lái)完整介紹 Safari 擴(kuò)展的開(kāi)發(fā) / 部署流程及相關(guān)技術(shù)細(xì)節(jié)。
Safari 擴(kuò)展的相關(guān)背景介紹
當(dāng)我們談到瀏覽器的擴(kuò)展時(shí) , 很容易被問(wèn)到的問(wèn)題是我們?yōu)槭裁匆o瀏覽器寫(xiě)擴(kuò)展呢 ? 它能給我們帶來(lái)什么好處或者便利 ? Safari 的擴(kuò)展和其他瀏覽器的擴(kuò)展有什么異同 ? 下面 , 讓我們嘗試著回答這些問(wèn)題。
目前 , 基于瀏覽器的應(yīng)用越來(lái)越多,而我們每天黏在瀏覽器上的時(shí)間也越來(lái)越長(zhǎng),看新聞 , 泡 BBS, 搜索技術(shù)文檔 等等。對(duì)于這樣一個(gè)每天都要和它長(zhǎng)時(shí)間打交道的東西,如何和它和睦相處無(wú)疑是很重要的。而如果能把它打造成完全符合你個(gè)人需求的,適合你個(gè)人使用習(xí)慣 , 為你度身定做的軟件,那將會(huì)使你的生活更美好些,讓你的工作也更有效率些。
那么,Safari 擴(kuò)展具體能為我們提供哪些方面的便利呢 ? 請(qǐng)參考下面這幅圖 :
從這副圖能夠看出 , 我們可以擴(kuò)展 Safari 的如下幾個(gè)部分 :
1、我們能夠在工具條上添加自己所需要的按鈕
2、我們能夠添加自己所需要的擴(kuò)展工具條
3、可以對(duì)頁(yè)面內(nèi)容做混搭 (Mashup) 或自定義的修改
4、可以對(duì)指定內(nèi)容添加上下文相關(guān)菜單
好吧 , 看上去覆蓋的功能面挺多 , 但還是不夠直觀 ? 讓我來(lái)針對(duì)每條分別舉一個(gè)直觀點(diǎn)的例子吧 :
1、我們可以在工具條上添加一個(gè)”GMail” 按鈕 , 可定時(shí)檢查新郵件并在圖標(biāo)上顯示出新郵件的數(shù)量
2、可以添加一個(gè)新的工具條 , 滾動(dòng)顯示當(dāng)前的 Twitter 或者新浪微博里的信息 , 或者滾動(dòng)顯示每日單詞 ( 我愛(ài)背單詞 )
3、對(duì)頁(yè)面做一些增值混搭 , 按自己的喜好重新排版網(wǎng)頁(yè)布局 , 或者自動(dòng)過(guò)濾廣告
4、當(dāng)用戶(hù)選定了頁(yè)面中的一些內(nèi)容后 , 在右鍵的上下文菜單中添加一個(gè)”我要分享”選項(xiàng) , 可以將所選的內(nèi)容分享到其他 SNS ( 例如 : 開(kāi)心 / 豆瓣等 )
是不是覺(jué)得有點(diǎn)意思了呢 ? 當(dāng)然你也許已經(jīng)有了更好的主意或是更有趣的點(diǎn)子 , 趕緊動(dòng)手打造你自己的瀏覽器吧 !
Safari 擴(kuò)展開(kāi)發(fā)的準(zhǔn)備工作
下面讓我們來(lái)看一下開(kāi)發(fā) Safari 擴(kuò)展都需要做些什么準(zhǔn)備工作吧。 首先 , 開(kāi)發(fā) Safari 擴(kuò)展是免費(fèi)的 , 這和開(kāi)發(fā) iPhone 應(yīng)用不同。 在 iTunes 上發(fā)布 iPhone 應(yīng)用需要參加 iPhone Developer Program ( 個(gè)人用戶(hù)每年 $99, 企業(yè)用戶(hù)為每年 $299)。 而開(kāi)發(fā) Safari 擴(kuò)展只需要在 Apple 網(wǎng)站上免費(fèi)注冊(cè)一個(gè) Apple ID, 獲取到你自己的開(kāi)發(fā)者證書(shū)就可以了 ( 我們?cè)谙旅鏁?huì)詳細(xì)介紹這個(gè)步驟 )。 開(kāi)發(fā) Safari 擴(kuò)展 , 也不需要你學(xué)習(xí)什么新的技術(shù)或是新的編程語(yǔ)言 , 只要你具有標(biāo)準(zhǔn)的 HTML/CSS/JavaScript 相關(guān)技術(shù)就可以了。 讓我們開(kāi)始吧 !
啟用擴(kuò)展功能
在 Safari 5 缺省狀態(tài)下擴(kuò)展功能是關(guān)閉的 , 用戶(hù)需要手工開(kāi)啟這項(xiàng)功能。 打開(kāi) Safari 菜單中的”編輯”, 再點(diǎn)擊”偏好設(shè)置”菜單選項(xiàng) , 在”高級(jí)”這個(gè)選項(xiàng)頁(yè)中勾選底部的”在菜單中顯示開(kāi)發(fā)菜單”選項(xiàng) ( 圖二 )。
然后就能從 Safari 的頂級(jí)菜單看到一個(gè)獨(dú)立的”開(kāi)發(fā)”菜單項(xiàng) ( 圖三 ), 從中選擇”啟用擴(kuò)展”就大功告成了 !
接下來(lái)同樣在”開(kāi)發(fā)”菜單中選擇”顯示擴(kuò)展創(chuàng)建器 (Show Extension Builder)”, 就能打開(kāi) Safari 為開(kāi)發(fā)人員準(zhǔn)備的擴(kuò)展開(kāi)發(fā)功能了 ( 圖四 ), 點(diǎn)擊左下角的”+”按鈕就能創(chuàng)建一個(gè)新擴(kuò)展或是打開(kāi)一個(gè)已存在的擴(kuò)展項(xiàng)目 我們?cè)诘谌糠种性賮?lái)詳細(xì)介紹這部分的功能。
讓我們回到 Safari 菜單中的”編輯”里的”偏好設(shè)置”菜單選項(xiàng) , 這時(shí)我們就能在”高級(jí)”的選項(xiàng)頁(yè)旁邊看到新增的”擴(kuò)展”選項(xiàng)頁(yè)了 ( 圖五 )。 由于現(xiàn)在尚未安裝任何擴(kuò)展 , 所以當(dāng)前列表是空的 , 讓我們?cè)谔砑恿藬U(kuò)展之后再回來(lái)看看發(fā)生了什么變化。
注冊(cè) Apple ID 并獲取 Safari 擴(kuò)展開(kāi)發(fā)的簽名證書(shū)
接下來(lái)的工作是 , 作為一個(gè) Safari 擴(kuò)展的開(kāi)發(fā)者 , 你需要去 Apple 的網(wǎng)站上注冊(cè)一個(gè)免費(fèi)的 Apple ID (http://developer.apple.com/programs/safari/), 此處步驟省略 , 請(qǐng)跟隨 Apple 注冊(cè)向?qū)е鸩酵瓿杉纯?. 接著使用這個(gè) Apple ID 登錄 Safari 開(kāi)發(fā)者網(wǎng)站 , 創(chuàng)建一個(gè)開(kāi)發(fā)中要使用的簽名證書(shū) (https://developer.apple.com/safari/certificates /index.action), 選擇左邊標(biāo)簽頁(yè)的第二個(gè)標(biāo)簽 (Request Certificates)
需要注意的是 , 在 Windows 和 Mac 上面的申請(qǐng)證書(shū)步驟略有不同,本文中將以 Mac 環(huán)境為例 , Windows 環(huán)境中的步驟請(qǐng)跟隨網(wǎng)站上的申請(qǐng)向?qū)е鸩酵瓿杉纯伞?/p>
在所用的開(kāi)發(fā)機(jī)上安裝簽名證書(shū)
同樣需要注意的是 , 在 Windows 和 Mac 上的簽名證書(shū)步驟也略有不同。 在 Windows 環(huán)境下直接點(diǎn)擊生成的證書(shū)文件 , 系統(tǒng)即可自動(dòng)安裝好此證書(shū)。 而 Mac 環(huán)境下簽名證書(shū)的步驟是個(gè)向?qū)н^(guò)程 , 本文寫(xiě)作時(shí) , 在選擇證書(shū)安裝分類(lèi)時(shí) , 在 Mac 下應(yīng)選擇”登錄”而不是”系統(tǒng)”分類(lèi)。 而在 Windows 環(huán)境下有時(shí)候 Safari 不能正常識(shí)別出安裝好的簽名證書(shū) , 請(qǐng)參看官方網(wǎng)站的相關(guān)指引做相應(yīng)的修改。
如何制作 Safari 擴(kuò)展
好了 , 通過(guò)上面兩部分的介紹 , 相信您已經(jīng)對(duì) Safari 擴(kuò)展有了個(gè)大致的了解 , 也為此準(zhǔn)備好了開(kāi)發(fā)環(huán)境。 在動(dòng)手編寫(xiě)第一個(gè)擴(kuò)展前 , 讓我們先來(lái)了解一下 Safari 擴(kuò)展的框架結(jié)構(gòu)及相應(yīng)開(kāi)發(fā)工具吧。
Safari 擴(kuò)展框架結(jié)構(gòu)
我們知道 , 在 Safari 擴(kuò)展中 , 我們可以如下幾個(gè)部分來(lái)提供擴(kuò)展功能 :
工具欄按鈕
擴(kuò)展工具條
上下文關(guān)聯(lián)菜單
注入 (JavaScript) 腳本
注入樣式表單
而 Safari 擴(kuò)展框架中其實(shí)是存在了一條分割線 , 將整個(gè)體系結(jié)構(gòu)分為了兩個(gè)部分 :
Safari 應(yīng)用層 : 包含工具條按鈕 , 擴(kuò)展工具條 , 頁(yè)面標(biāo)簽 , 頁(yè)面窗口 , 上下文菜單等
頁(yè)面內(nèi)容層 : 包含修改頁(yè)面內(nèi)容的 JavaScript 和 CSS
而這兩部分不能直接調(diào)用對(duì)方的代碼 , 需要通過(guò)給對(duì)方發(fā)送消息 , 再由對(duì)方的消息處理方法來(lái)調(diào)用所需的代碼。 當(dāng)然 , 不是每一個(gè) Safari 擴(kuò)展都需要做這樣的消息調(diào)用 , 例如簡(jiǎn)單的”關(guān)閉網(wǎng)頁(yè)”按鈕擴(kuò)展就不需要和頁(yè)面內(nèi)容層交互 , 也就不需要消息調(diào)用及代理等處理邏輯了。
Safari 擴(kuò)展開(kāi)發(fā)工具介紹
接下來(lái)我們來(lái)看一下 Apple 為我們提供的開(kāi)發(fā)工具 , 不是 XCode 這樣的大家伙 , 也不是讓你從零開(kāi)始完全手工編寫(xiě)所有的代碼文件 , 部署腳本和打包程序。 Apple 在 Safari 5 里內(nèi)嵌了一個(gè)叫做”擴(kuò)展創(chuàng)建器”的工具來(lái)簡(jiǎn)化開(kāi)發(fā) / 打包及部署步驟。 打開(kāi) Safari, 選擇”開(kāi)發(fā)”菜單 , 再選擇”顯示擴(kuò)展創(chuàng)建器”就能看到它了。
讓我們拿本文中下面即將提供的”CloseOtherTabs”這個(gè)示例來(lái)分析一下擴(kuò)展創(chuàng)建器里面的內(nèi)容 :
前面的三部分比較簡(jiǎn)單,分別是
1) 擴(kuò)展信息 : 包括此擴(kuò)展的顯示名稱(chēng) , 作者 , 描述等
2) 擴(kuò)展詳細(xì)信息 : 包含此擴(kuò)展的唯一標(biāo)識(shí)以及將來(lái)檢查升級(jí)時(shí)所需的清單文件
3) 擴(kuò)展版本。
4) “擴(kuò)展網(wǎng)站訪問(wèn)”是用來(lái)控制此擴(kuò)展可訪問(wèn)哪些網(wǎng)址 , 可選的訪問(wèn)級(jí)別有”無(wú)”, “部分”及”全部”三種 , 分別對(duì)應(yīng)對(duì)所有網(wǎng)址均無(wú)權(quán)限 , 對(duì)指定的部分網(wǎng)址 ( 支持通配符 ) 具有權(quán)限 , 和對(duì)所有網(wǎng)址都有權(quán)限。
5) “擴(kuò)展全局頁(yè)面” 這個(gè)頁(yè)面文件比較重要 , 全局頁(yè)面顧名思義是個(gè)掌控全局的頁(yè)面 , 但是它又比較特殊 , 位于 Safari 應(yīng)用層而不是頁(yè)面內(nèi)容層 , 而且此頁(yè)面不是用來(lái)顯示給終端用戶(hù)的。 如果你對(duì) Safari 擴(kuò)展中這兩個(gè)層還有所印象的話 , 應(yīng)該記得這兩層是不能直接調(diào)用對(duì)方的 , 必須通過(guò)消息代理來(lái)間接調(diào)用。 那我們?yōu)槭裁匆羞@個(gè)全局頁(yè)面呢 ? 簡(jiǎn)單的原因是這里面可以存儲(chǔ)一些公共的代碼從而避免多個(gè)代碼副本 , 而深一層的原因是將代碼放入全局頁(yè)面有利于提高用戶(hù)使用時(shí)的性能 ! 為什么會(huì)提升性能 ? 我們知道 , 在瀏覽器中我們可以開(kāi)多個(gè)窗口 , 每個(gè)窗口又可以開(kāi)多個(gè)標(biāo)簽頁(yè) , 每個(gè)標(biāo)簽頁(yè)中才對(duì)應(yīng)著你訪問(wèn)的網(wǎng)站。 如果你將一些比較耗時(shí)的 JavaScript 代碼放入了工具條的擴(kuò)展文件中 , 那么每開(kāi)一個(gè)新窗口 , 這段代碼都要載入一次。 而如果你將耗時(shí)的 JavaScript 代碼放入了修改網(wǎng)頁(yè)內(nèi)容的嵌入腳本中 , 那么每開(kāi)一個(gè)標(biāo)簽頁(yè) , 這段代碼都會(huì)重新載入一次 , 無(wú)疑這將會(huì)極大的降低網(wǎng)頁(yè)載入速度。 而將這些 JavaScript 代碼放入全局頁(yè)面 , 那么它只會(huì)被載入一次 , 以后再開(kāi)新窗口 / 新標(biāo)簽頁(yè) , 都無(wú)需重新載入。
6) “擴(kuò)展 Chrome” 在這里你能夠創(chuàng)建你的工具欄 , 上下文關(guān)聯(lián)菜單 , 以及工具欄上的按鈕。 你可以隨時(shí)點(diǎn)擊”New Bar”或者”New Context Menu Item”來(lái)新增一個(gè)條目并填寫(xiě)相應(yīng)信息。
7) “加入的擴(kuò)展內(nèi)容” 這里包含的就是對(duì)”頁(yè)面內(nèi)容層”進(jìn)行擴(kuò)展的相應(yīng)文件 (JavaScript/CSS) 了 , 我們可以在這里遍歷頁(yè)面的 DOM 樹(shù) , 修改其中的內(nèi)容 , 改變頁(yè)面的布局等等。
8) “擴(kuò)展設(shè)置” 最后的這部分就是你想此擴(kuò)展里使用的一些參數(shù) , 方便用戶(hù)進(jìn)行個(gè)性化自定義。
那么,這么多的設(shè)置,擴(kuò)展創(chuàng)建器最終將它們保存在了什么地方 ? 讓我們看看這個(gè)”CloseOtherTabs”擴(kuò)展的文件結(jié)構(gòu)
真的非常簡(jiǎn)單 , 只有三個(gè)文件 :
1) global.html 包含當(dāng)用戶(hù)點(diǎn)擊”關(guān)閉”按鈕時(shí)所需的 JavaScript 處理代碼
2) Info.plist 包含了上面擴(kuò)展創(chuàng)建器中所有的參數(shù)設(shè)置
3) close.png 顯示在工具欄中的”關(guān)閉”圖標(biāo)
實(shí)戰(zhàn) Safari 擴(kuò)展的開(kāi)發(fā) / 打包 / 安裝 / 發(fā)布
看到這里 , 也許你已經(jīng)開(kāi)始著急了 , 什么時(shí)候才開(kāi)始開(kāi)發(fā)我們的第一個(gè) Safari 擴(kuò)展啊 ! 別急 , 其實(shí)此時(shí)你已經(jīng)具備了寫(xiě)一個(gè)簡(jiǎn)單 Safari 擴(kuò)展所需的大部分知識(shí)。 讓我們動(dòng)手實(shí)現(xiàn)它吧 !
首先 , 描述一下這個(gè)擴(kuò)展所實(shí)現(xiàn)的功能 : 我們將提供一個(gè)位于工具欄中的”關(guān)閉其他”按鈕 , 用戶(hù)點(diǎn)擊了此按鈕后會(huì)關(guān)閉除當(dāng)前頁(yè)面外的其他標(biāo)簽頁(yè)。 當(dāng)然 , Safari 瀏覽器其實(shí)已經(jīng)提供了別的方式來(lái)完成這個(gè)功能 , 你可以按住”Alt”鍵 (Mac 上按”Option”鍵 ) 之后點(diǎn)擊當(dāng)前標(biāo)簽頁(yè)的”x”圖標(biāo)也可關(guān)閉其他所有標(biāo)簽頁(yè)。 在此 , 我們通過(guò)嘗試寫(xiě)一個(gè)工具欄按鈕的 Safari 擴(kuò)展來(lái)實(shí)現(xiàn)相同的功能從而達(dá)到練手的目的。
開(kāi)發(fā) CloseOtherTabs 擴(kuò)展
首先是打開(kāi) Safari 中的擴(kuò)展創(chuàng)建器 , 點(diǎn)擊左下角的”+”按鈕并選擇”新建擴(kuò)展”, 然后在彈出的窗口中為新擴(kuò)展選擇一個(gè)保存目錄。 在這里我們把它命名為”CloseOtherTabs”, 點(diǎn)擊保存。 你將會(huì)發(fā)現(xiàn)在上一步選擇的保存目錄中新創(chuàng)建了一個(gè)叫”CloseOtherTabs.safariextension”的文件夾 , 里面只包含有一個(gè)含有基本信息的 Info.plist 文件 , 這里先暫且把它放在一邊 , 等我們完成其他文件之后再來(lái)完善它。
接著是為這個(gè)擴(kuò)展提供一個(gè)工具欄按鈕圖標(biāo) , 在此我們?yōu)樗峁┮粋€(gè) 11*11 像素的 png 文件 , 并將它保存在”CloseOtherTabs.safariextension”文件夾中。
最后 , 此擴(kuò)展的重頭戲來(lái)了 , 我們需要為它寫(xiě)一個(gè)全局頁(yè)面 ( 為什么是全局頁(yè)面而不是工具欄頁(yè)面的原因前面已說(shuō)明 , 這樣可以減少不必要的反復(fù)加載從而提高性能 ), 并在里面實(shí)現(xiàn)所需的功能。 主要代碼如下 :
- // Register for the validate and command events.
- safari.application.addEventListener("command", performCommand, false);
- safari.application.addEventListener("validate", validateCommand, false);
- function performCommand(event)
- {
- if (event.command != "close-other-tabs")
- return;
- // return if there are no more tabs to close
- if (event.target.browserWindow.tabs.length < 2)
- return;
- // Close others tab except the current one in the target's window.
- var myTabs = event.target.browserWindow.tabs;
- var currentTab = event.target.browserWindow.activeTab;
- for (var i = 0; i < myTabs.length; ++i) {
- var tab = myTabs[i];
- if (currentTab == tab){
- //do nothing for current tab
- }else{
- tab.close();
- }
- }
- }
- function validateCommand(event)
- {
- if (event.command !== "close-other-tabs")
- return;
- // Disable the button if there are only 1 tab available.
- eventevent.target.disabled = event.target.browserWindow.tabs.length < 2;
- }
小結(jié):Apple 中Safari 實(shí)戰(zhàn) 擴(kuò)展開(kāi)發(fā)的內(nèi)容介紹完了,希望本文對(duì)你有所幫助。
轉(zhuǎn)自 http://safarix.net/safari-extension-development-practice