我已经看到很多关于上下文菜单和双向沟通的问题,似乎我知道我的问题的答案......“你不能”,但我还是要尝试。
在每个页面上都有一个由page-mod创建的模态div。此模式旨在显示当用户将鼠标悬停在文本节点中的单词上以提供单词的翻译时。这非常有效,我对page-mod没有任何问题。
我现在想要做的是允许用户突出显示一系列文本,右键单击以显示上下文菜单,其中我的新菜单项将是“翻译选择”,然后在模态div中显示选择。这是问题开始的地方。我可以响应上下文并单击内容脚本中的事件,如果我不需要进行翻译,这很好。转换由Web服务完成,内容脚本无法调用Web服务,因为回调在内容脚本的上下文中不存在,因为它位于代理沙箱中。这意味着所有Web服务调用都需要来自main.js(这是它在page-mod中的工作方式)。问题是main.js中的context-menu对象无法访问DOM来更新modal div的内容并显示它,并且它无法向内容脚本发送信息,因此内容脚本可以更新DOM并显示模态div。那么如何从上下文菜单的附加脚本转换到DOM?
我想用SDK做什么,或者我是否必须撤消许多小时的工作才能让我的项目回到“旧学校”的做事方式,这样我才能让上下文菜单正常工作?
这就是我所拥有的(页面模块工作,需要上下文菜单的帮助):
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();
}
});
};
答案 0 :(得分:3)
感谢弗拉迪米尔!以下代码执行我想要的操作:
在上下文菜单的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);
}
);
在workers
函数中定义了一个全局exports.main
数组变量,该变量由页面mod的onAttach
函数填充,如下所示:
workers.push(worker);
worker.on(
'detach',
function () {
var index = workers.indexOf(worker);
if (index >= 0) {
workers.splice(index, 1);
}
}
);