2013-05-28 39 views
3

我想使用他們的sdk做一個Firefox插件,但我不知道如何讓我的js腳本進行通信。我們的目標是製作一個女巫形式的面板,其中有3個複選框,選中時可以隱藏/顯示活動選項卡上的某些元素。火狐插件腳本之間的通信sdk - self.port不存在

下面是腳本: main.js:

var data = require("sdk/self").data; 

var painel1 = require("sdk/panel").Panel({ 
    width: 215, 
    height: 160, 
    contentURL: data.url("painelDestroyer.html"), 
    contentScriptFile: [data.url("jquery.js"),data.url("panel.js")] 
}); 

require("sdk/widget").Widget({ 
    id: "open-form-btn", 
    label: "Clear", 
    contentURL: data.url("mozico.png"), 
    panel: painel1 
}); 

// Attach a content script to the current active tab 
let worker = require("sdk/tabs").activeTab.attach({ 
    contentScriptFile: data.url("clear.js") 
}); 


painel1.port.on("show-tag",function(tag){ 
    worker.port.emit("show-tag", {tag:tag}); 
    console.log("worker emited"); 
}); 

painel1.port.on("hide-tag",function(tag){ 
    worker.port.emit("clear-tag", {tag:tag}); 
    console.log("worker emited"); 
}); 

painel.js:

$("#imgD").click(function() { 
    if ($(this).is(":checked")) { 
     panel.port.emit("clear-tag","img"); 
     console.log("panel emited"); 
    } else { 
     panel.port.emit("show-tag","img"); 
     console.log("panel emited"); 
    } 
}); 
$("#aD").click(function() { 
    if ($(this).is(":checked")) { 
     panel.port.emit("clear-tag","a"); 
     console.log("panel emited"); 
    } else { 
     panel.port.emit("show-tag","a"); 
     console.log("panel emited"); 
    } 
}); 
$("#iframeD").click(function() { 
    if ($(this).is(":checked")) { 
     panel.port.emit("clear-tag","iframe"); 
     console.log("panel emited"); 
    } else { 
     panel.port.emit("show-tag","iframe"); 
     console.log("panel emited"); 
    } 
}); 

clear.js:

function tagHide (tag, hide) { 
    $(tag).each(function() { 
     if (hide === false) { 
      $(this).css({ 
       "visibility": "visible" 
      }); 
     } else { 
      $(this).css({ 
       "visibility": "hidden" 
      }); 
     } 
    }); 
} 

self.port.on('show-tag', function(tag) { 
    tagHide(tag, false); 
}); 
self.port.on('clear-tag', function(tag) { 
    tagHide(tag, true); 
}); 

問題:如何讓我這個工作,如何溝通這3個腳本?我的猜測是,我必須從painel.js發送消息到main.js,然後發送到clean.js,但我該怎麼做?如何在clean.js或painel.js中收到消息? 我不斷收到painel.js中不存在的self.port。

回答

5

的問題是,你想從模塊腳本而不是內容腳本訪問和修改頁面的內容。在模塊腳本的範圍內沒有windowdocument,如the documentation中所述。因此,jQuery的$將不會在您的附加腳本中使用任何東西。

您需要將attach另一個內容腳本添加到當前選項卡。然後,您可以通過向其工作端口發送消息來顯示/隱藏頁面上的元素,這與您的附加模塊腳本和麪板腳本之間的通信方式類似。

// Attach a content script to the current active tab 
let worker = require("sdk/tabs").activeTab.attach({ 
    contentScriptFile: data.url("tabscript.js") 
}); 
// Send it a message 
worker.port.emit("show-tag", tag); 

你會然後移動tagHide功能爲活動選項卡的內容腳本,並把一些端口聽衆在那裏。這樣,附加腳本可以發出一些消息,並使內容腳本適當地調用tagHide

注意:您可能最好使用page-mod而不是附加到選項卡。最後,當用戶導航到不同的頁面時,您可能不希望手動附加腳本,因此全局PageMod(include: "*")是一個簡單的解決方案。不過,在轉發郵件時,您需要確保將目標標籤的工作人員作爲目標。因此,您需要跟蹤所有這些工作人員和clean them up when the worker is detached(使用worker.on('detach', callback)。最後,您應該遍歷所有當前連接的工作人員,並找到工作人員附加到當前活動選項卡的頁面(通過比較每個worker.tabtabs.activeTab) 。

或者,你可以簡單地將命令直接插入到標籤頁中,如在Attaching Content Scripts to Tabs中所示的JavaScript。我覺得這很難看,並且不允許你在內容腳本中保留某些狀態(頁面上的變量保留在命令中)你可能需要更復雜的腳本

UPDATE 1:至於你的updat編輯問題,答案是very well documented in the SDK guides。你只需要使用一個self.port.on聽衆綁定:

self.port.on('show-tag', function(tag) { 
    tagHide(tag, false); 
}); 
self.port.on('clear-tag', function(tag) { 
    tagHide(tag); 
}); 

在另一方面,當前的代碼永遠只能與當前活動標籤工作時附加開始。很可能,活動選項卡會發生變化,您需要將您的內容腳本隨着時間推移到其他選項卡中。看到我以前的筆記,你如何可以管理所有這些腳本的工作人員。

+0

但是我該如何在「show-tag」和「hide-tag」之間切換,因爲它是由面板中的js定義的? 我需要將pannel.js文件中的port.emiter添加到附加腳本,然後添加到內容腳本中嗎?如從面板發送「1」或「2」到附加腳本,然後將其重新發送到內容腳本以對頁面執行操作?因爲我需要使用面板腳本來決定它是「1」還是「2」(在本例中爲「顯示」或「隱藏」)。 –

+0

是的,您需要讓您的附加腳本將該命令從面板的內容腳本「轉發」到該選項卡的內容腳本。例如,在[Annotator教程](https://addons.mozilla.org/en-US/developers/docs/sdk/1.14/dev-guide/tutorials/annotator/overview.html)中,「左鍵單擊」從小部件內容腳本通過'main.js'轉發到'page-mod'內容腳本上的'activate/deactivate'消息。 –

+0

@GiovanniDiToro我更新了我的答案。 –