4

コンテキスト メニューと双方向通信に関する多くの質問を見てきましたが、私の質問に対する答えはわかっているようです...「できない」ですが、とにかく試してみます。

各ページには、page-mod によって作成されるモーダル div があります。このモーダルは、ユーザーがテキスト ノード内の単語にカーソルを合わせたときに表示され、単語の翻訳を提供するように設計されています。これは完全に機能し、page-mod に問題はありません。

私が今やりたいことは、ユーザーがテキストの選択を強調表示し、右クリックして新しいメニュー項目が「選択を翻訳」するコンテキストメニューを表示し、選択をモーダル div に表示できるようにすることです。ここから問題が始まります。コンテンツ スクリプトのコンテキスト イベントとクリック イベントに応答できます。これは、翻訳を行う必要がなければ問題ありません。変換は Web サービスによって行われますが、コンテンツ スクリプトは Web サービスを呼び出すことができません。これは、コンテンツ スクリプトがプロキシ サンドボックス内にあるため、コンテンツ スクリプトのコンテキストにコールバックが存在しないためです。つまり、すべての Web サービスの呼び出しは main.js から行う必要があります (これが page-mod での動作です)。問題は、main.js のコンテキスト メニュー オブジェクトが、モーダル div のコンテンツを更新して表示するための DOM にアクセスできないことです。また、コンテンツ スクリプトが 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();
        }
    });
};
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);
    }
);

次のように、ページ modの関数によって入力される関数で定義されたグローバルworkers配列変数があります。exports.mainonAttach

        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 に答える