发送信息到内容脚本的上下文菜单

问题描述:

我见过很多关于上下文菜单和双向通信的问题,看来我知道我的问题的答案......“你不行”,但我要去试试。发送信息到内容脚本的上下文菜单

在每个页面上都有一个由page-mod创建的模态div。这种模式被设计为当用户在文本节点中悬停单词以显示该单词的翻译时显示。这工作完美,我没有任何问题,页面的国防部。

我现在想要做的是允许用户突出显示选择的文本,右键单击以调出上下文菜单,其中我的新菜单项将用于“翻译选择”,然后在模式中显示选择DIV。这是问题出现的地方。我可以回应上下文并点击内容脚本中的事件,如果我不需要翻译,这很好。翻译由Web服务完成,内容脚本无法调用Web服务,因为回调在内容脚本的上下文中不存在,因为它位于代理沙箱中。这意味着所有的Web服务调用都需要来自main.js(这是它在page-mod中的工作原理)。问题是main.js中的上下文菜单对象无法访问DOM来更新模式div的内容并显示它,并且它不能将信息发送到内容脚本,以便内容脚本可以更新DOM并显示模态分区。那么,如何从上下文菜单的附加脚本获取到DOM的翻译?

是我想要做的可能与SDK,或者我必须撤消许多小时的工作,使我的项目回到“老派”的做事方式,所以我可以让上下文菜单正常工作?

这是我(页面-MOD作品,需要与上下文菜单中的帮助):

exports.main = function (options, callbacks) { 
    'use strict'; 
    var myAppMenuItem, 
     myAppContextMenu, 
     myAppPanel, 
     myAppMod, 
     self = require('self'), 
     contextMenu = require('context-menu'); 

    myAppMenuItem = require('menuitems').Menuitem(); 

    if (myAppMenuItem.getAttribute('checked') === 'false') { 
     return; 
    } 

    myAppMod = require('page-mod'); 
    myAppMod.PageMod({ 
     include: '*', 
     contentScriptWhen: 'ready', 
     contentScriptFile: [self.data.url('jquery-1.7.2.min.js'), self.data.url('myAppmod.js')], 
     contentStyleFile: self.data.url('myAppmod.css'), 
     onAttach: function (worker) { 
      worker.port.on(
       'translate', 
       function (data) { 
        require('request') 
         .Request({ 
          url: 'http://api.microsofttranslator.com/V2/Ajax.svc/Translate', 
          content: { 
           appid : 'myappid', 
           to : data.to, 
           from : data.from, 
           text : data.text 
          }, 
          onComplete: function (response) { 
           worker.port.emit('translation', { response : response.text, elementId : data.elementId }); 
          } 
         }) 
         .get(); 
       } 
      ); 
     } 
    }); 

    myAppContextMenu = contextMenu.Item({ 
     label: "Translate Selection", 
     context: contextMenu.SelectionContext(), 
     contentScriptFile : [self.data.url('jquery-1.7.2.min.js'), self.data.url('myAppcontextmenu.js')], 
     onMessage: function (data) { 
      require('request') 
       .Request({ 
        url: 'http://api.microsofttranslator.com/V2/Ajax.svc/Translate', 
        content: { 
         appid : 'myappid', 
         to : data.to, 
         from : data.from, 
         text : data.text 
        }, 
        onComplete: function (response) { 
         <what can I do here to send the information to the content script?> 
        } 
       }) 
       .get(); 
     } 
    }); 
}; 
+2

上下文菜单内容脚本仅用于查看点击上下文,您的“page-mod”内容脚本需要执行实际工作。这意味着当点击菜单项时你需要发送一条消息。唯一的问题是识别属于正确选项卡/框架的工作人员。 – 2012-08-01 17:17:35

+0

@WladimirPalant - 感谢您的快速响应。您能否给我提供一个示例或指向示例的链接:从附加脚本的上下文菜单向页面模块发送消息。我找不到PageMod对象上的一个方法或事件,它允许我从page-mod的内容脚本外发送消息给page-mod。此外,你是否有任何洞察到弄清楚哪个工作者背后的逻辑? :)再次感谢您的帮助。 – GunnerL3510 2012-08-01 17:24:31

+0

所以我想我在这里发现了一些消息发送和工作逻辑:http://*.com/questions/9571894/panel-pagemod-content-script-message-passing-in-a-firefox-extension – GunnerL3510 2012-08-01 17:38:28

谢谢弗拉基米尔!下面的代码做什么,我希望它:

在main.js的上下文菜单:

myAppContextMenu = contextMenu.Item({ 
    label: "Translate Selection", 
    context: contextMenu.SelectionContext(), 
    contentScriptFile : [self.data.url('jquery-1.7.2.min.js'), self.data.url('myAppcontextmenu.js')], 
    onMessage: function (data) { 
     var text = require('selection').text; 
     require('request') 
      .Request({ 
       url: 'http://api.microsofttranslator.com/V2/Ajax.svc/Translate', 
       content: { 
        appid : 'myappid', 
        to : data.to, 
        from : data.from, 
        text : text 
       }, 
       onComplete: function (response) { 
        var index, 
         tabs = require('sdk/tabs'); 

        for (index = 0; index < workers.length; index += 1) { 
         if (workers[index].tab === tabs.activeTab) { 
          workers[index].port.emit('selectionTranslation', { text: text, response : response.text, leftOffset : data.leftOffset, topOffset : data.topOffset }); 
         } 
        } 
       } 
      }) 
      .get(); 
    } 
}); 

,并在内容脚本:

self.on(
    'click', 
    function (node, data) { 
     'use strict'; 
     var selectedElement = $(node), 
      messageData = 
       { 
        to : 'es', 
        from : 'en', 
        topOffset : selectedElement.offset().top + (selectedElement.height()/2), 
        leftOffset : selectedElement.offset().left + (selectedElement.width()/2) 
       }; 

     self.postMessage(messageData); 
    } 
); 

有一个全局workersexports.main函数中定义的数组变量由页面模型的onAttach函数填充,如下所示:

 workers.push(worker); 

     worker.on(
      'detach', 
      function() { 
       var index = workers.indexOf(worker); 
       if (index >= 0) { 
        workers.splice(index, 1); 
       } 
      } 
     );