4

我见过很多关于上下文菜单和双向通信的问题,看来我知道我的问题的答案......“你不能”,但无论如何我都会尝试。

在每个页面上都有一个由 page-mod 创建的模态 div。此模式旨在当用户将鼠标悬停在文本节点中的单词上以给出单词的翻译时显示。这完美地工作,我对 page-mod 没有任何问题。

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

我想用 SDK 做的事情是可能的,还是我必须撤消很多小时的工作才能让我的项目回到“老派”的做事方式,这样我才能让上下文菜单正常工作?

这就是我所拥有的(page-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();
        }
    });
};
4

1 回答 1

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的函数填充,如下所示:onAttach

        workers.push(worker);

        worker.on(
            'detach',
            function () {
                var index = workers.indexOf(worker);
                if (index >= 0) {
                    workers.splice(index, 1);
                }
            }
        );
于 2012-08-01T23:03:14.600 回答