2013-05-13 63 views
3

我有一個Safari瀏覽器擴展彈出窗口,需要與其全局頁面進行通信。從我正在使用的內容腳本將來自Safari瀏覽器擴展彈出窗口的郵件發送到全局頁面

safari.self.tab.dispatchMessage(name,data); 

要完成該操作。從popover我沒有找到辦法做到這一點。我知道我可以直接訪問全局頁面中的方法

safari.extension.globalPage.contentWindow 

但我的目標是重用已在內容腳本中使用過的代碼片段。我也爲插件的chrome版本做同樣的事情。

有代碼的小聰明代理從酥料餅的模擬

safari.self.tab.dispatchMessage(name,data); 

回答

3

說實話,在彈出窗口和注入腳本中使用不同的代碼可能會更容易。如果你真的想,你可以做這樣的事情:

function dispatchMessage(name, message) { 
    if (safari.self.tab) { 
     safari.self.tab.dispatchMessage(name, message); 
    } else if (safari.extension.globalPage.contentWindow) { 
     safari.extension.globalPage.contentWindow.handleMessage({name: name, message: message}); 
    } 
} 

然後,只需使用dispatchMessage('foo', 'bar')兩個你酥料餅和注入腳本。然而,這有點怪異,因爲消息事件對象通常包含更多的信息,而不僅僅是namemessage,並且您必須確保您的handleMessage函數實際上與在全局頁面中指定爲message事件偵聽器的函數相同。

+0

你是對的,你只需要忍受一個事實,即瀏覽器體系結構的某些方面是不同的,即使只是輕微的。 – 2013-05-14 16:26:12

2

一個簡單的方法來實現重用你的基於消息的內容腳本代碼在你的酥料餅是包裝在下面我將描述一個抽象函數的調用safari.self.tab.dispatchMessage ...

但首先,你需要一定要在你的全局頁單一命名處理函數來處理所有消息,像這樣:

function handleMessage(evt) { 
    switch (evt.name) { 
     case 'Message1': 
      // do something with evt.message 
     break; 
     case 'Message2': 
      // do something else with evt.message 
     break; 
    } 
} 

safari.application.addEventListener('message', handleMessage, false); 

如果你對每個不同的消息不同的處理器,或者如果您使用的是匿名函數,這種方法不行。現在

,是去你的酥料餅和內容腳本包裝功能很簡單:

function tellGlobalPage(msgName, msgData) { 
    if (safari.self instanceof SafariExtensionPopover) { 
     // this script is running in a popover 
     var fakeMsgEvt = { name: msgName, message: msgData }; 
     safari.extension.globalPage.contentWindow.handleMessage(fakeMsgEvt); 
    } else { 
     // this script is a content script 
     safari.self.tab.dispatchMessage(msgName, msgData); 
    } 
} 

然後代替safari.self.tab.dispatchMessage(name, data),您使用tellGlobalPage(name, data).

請注意,這個簡單的方法不處理帶有往返消息傳遞,其中彈出窗口或內容腳本將消息發送到全局頁面,並且全局頁面使用另一條消息進行回覆。還有其他方法可以解決這個問題。

+0

糟糕... Matt Swain在撰寫我的文章時發佈了相同的答案。 – canisbos 2013-05-14 16:35:52

相關問題