2015-10-28 88 views
1

我正在嘗試創建一個插件,允許用戶隨意查詢字典站點並查看所選單詞的定義。我一直在努力尋找一種方法來溝通頁面工作者,我必須訪問字典站點條目的DOM和用戶正在查看的主頁面。我知道頁面工作者能夠從DOM中提取定義,因爲我能夠看到記錄到控制檯的定義。我有問題讓postMessage和onMessage合作。我目前正在嘗試用iframe彌合差距,但也歡迎其他方法。Mozilla插件開發 - 在具有不同域的窗口之間進行通信

下面是我的一些代碼位...

index.js:

var getDefinition = "var def = document.getElementsByClassName('def-content');" + 
        "definition = def[0].textContent;" + 
        "word = document.getElementsByClassName('js-headword');" + 
        "word = word.textContent;" + 
        "self.port.emit('dialog', definition);" + 
        "var thiswin = document.getElementById('example').contentWindow;" + 
        "thiswin.postMessage(definition, '*');" 

currPage = require("sdk/page-mod").PageMod({ 
    include: "*", 
    contentScriptWhen: "ready", 
    contentScriptFile: [ 
     data.url("jquery.js"), 
     data.url("jquery-ui.min.js"), 
     data.url("define.js"), 
    ], 
    onMessage: function(message){ 
     console.log("received message"); 
    }, 
    onAttach: function(worker){ 
     workers.push(worker); 

     worker.on("message", function(definition){ 
      console.log("received message"); 
     }); 

     worker.port.on("dblclick", function(selected, thispage){ 
      newPage = require("sdk/page-worker").Page({ 
       contentURL: "http://dictionary.reference.com/browse/" + selected, 
       contentScriptWhen: "ready", 
       contentScriptFile: [ 
        data.url("jquery.js"), 
        data.url("jquery-ui.min.js"), 
        data.url("iframe.js") 
       ], 
       contentScript: getDefinition, 
       onMessage: function(message){ 
        console.log("received message"); 
       } 
      }); 
     }); 
    } 
}); 

define.js:

function calldictionary(definition){ 
    console.log("here comes calldictionary"); 
    console.log(definition); 
    $('div#definition').text(definition); 
    $('#define').dialog("open"); 
} 

function send(){ 
    var selected = getSelected(); 
    if (selected != ""){ 
     var mainwin = document.getElementById('example').contentWindow; 
     $('iframe#example').attr('src', 'http://dictionary.reference.com/browse/' + selected); 
     self.port.emit("dblclick", selected); 
    } 
} 

function getSelected() { 
    if (window.getSelection) { 
     return window.getSelection().toString(); 
    } else if (document.selection) { 
     return document.selection.createRange().text; 
    } 
    return ''; 
} 

$(window).dblclick(function() { 
    send(); 
}); 

window.addEventListener("message", function(event){ 
    if (event.origin == "dictionary.reference.com"){ 
    console.log("received message");} 
    }, false); 

回答

2

你經常開窗消息與content script messaging混合起來。試試這個:

index.js

var getDefinition = "var def = document.getElementsByClassName('def-content');" + 
        "definition = def[0].textContent;" + 
        "word = document.getElementsByClassName('js-headword');" + 
        "word = word.textContent;" + 
        "self.port.emit('dialog', definition);"; 

currPage = require("sdk/page-mod").PageMod({ 
    include: "*", 
    contentScriptWhen: "ready", 
    contentScriptFile: [ 
     data.url("jquery.js"), 
     data.url("jquery-ui.min.js"), 
     data.url("define.js"), 
    ], 
    onMessage: function(message){ 
     console.log("received message"); 
    }, 
    onAttach: function(worker){ 
     workers.push(worker); 

     worker.on("message", function(definition){ 
      console.log("received message"); 
     }); 

     worker.port.on("dblclick", function(selected, thispage){ 
      newPage = require("sdk/page-worker").Page({ 
       contentURL: "http://dictionary.reference.com/browse/" + selected, 
       contentScriptWhen: "ready", 
       contentScriptFile: [ 
        data.url("jquery.js"), 
        data.url("jquery-ui.min.js"), 
        data.url("iframe.js") 
       ], 
       contentScript: getDefinition, 
       onMessage: function(message){ 
        worker.postMessage(message); 
       } 
      }); 
     }); 
    } 
}); 

define.js:

function calldictionary(definition){ 
    console.log("here comes calldictionary"); 
    console.log(definition); 
    $('div#definition').text(definition); 
    $('#define').dialog("open"); 
} 

function send(){ 
    var selected = getSelected(); 
    if (selected != ""){ 
     self.port.emit("dblclick", selected); 
    } 
} 

function getSelected() { 
    if (window.getSelection) { 
     return window.getSelection().toString(); 
    } else if (document.selection) { 
     return document.selection.createRange().text; 
    } 
    return ''; 
} 

$(window).dblclick(function() { 
    send(); 
}); 

self.on("message", function(message){ 
    console.log("received message");} 
}); 
+0

太謝謝你了!這允許窗口相互通信,雖然我收到關於加載混合活動內容的警告。我曾希望我所設立的將會規避這一點,但顯然並非如此。我究竟做錯了什麼? – Vemonus

+1

這可能是您在define.js文件的「發送」函數中注入的iframe。你不需要iframe,這是頁面工作者的目的。我編輯了答案並刪除了該部分。 – cviejo

+0

我不確定哪一個,實際上。我假設它是定義從字典窗口傳遞到主窗口的地方。看起來問題可能是將數據從http傳輸到https的結果。有沒有辦法解決這個問題? – Vemonus

相關問題