Событие pageMod для прослушивания ответа от панели

У меня есть два сценария контента:

  1. редактор аннотаций (панель)
  2. editField (модуль страницы)

Аддон сначала просит пользователя ввести текст во всплывающую панель, созданную annotationEditor. Это работает отлично. Текст возвращается в переменной annotationText. annotationText хранится как глобальная переменная savedText, так что editField имеет к ней доступ.

Затем я хочу, чтобы editField взял savedText и что-то с ним сделал (добавил его в поле ввода). Проблема заключается в том, что событие pageMod onAttach вызывается при загрузке страницы, а не после «сохранения текста». Я также не могу найти никаких других событий для PageMod Модуль. Так что worker.port.emit("editel", [this.annotationAnchor, savedText]) тоже не работает.

var annotationEditor = panels.Panel({
    width: 220,
    height: 220,
    contentURL: data.url('editor/annotation-editor.html'),
    contentScriptFile: data.url('editor/annotation-editor.js'),
    onMessage: function(annotationText) {
        if (annotationText) {
            // handleNewAnnotation(annotationText, this.annotationAnchor);
            savedText = annotationText;
            annotationEditor.hide();
        }
        annotationEditor.hide();
    },
    onShow: function() {
        this.postMessage('focus');
    }
});

var editField = pageMod.PageMod({
    include: ['*'],
    contentScriptWhen: 'ready',
    contentScriptFile: [data.url('jquery-1.8.3.min.js'), data.url('edit.js')],
    onAttach: function(worker) {
        worker.port.emit("editel", [this.annotationAnchor, savedText]);
    }
});

Попробуйте 2: Это ближе? Все еще не работает правильно. Я не получаю никаких сообщений в сценарии содержимого edit.js.

const tabs = require('sdk/tabs');
var editors = [];

function getEditor(tab) {
for (var i = editors.length; i--;)
    if (editors[i].tab===tab) return editors[i];
}

var annotationEditor = panels.Panel({
    width: 220,
    height: 220,
    contentURL: data.url('editor/annotation-editor.html'),
    contentScriptFile: data.url('editor/annotation-editor.js'),
    onMessage: function(annotationText) {
        if (annotationText) {
            var currentEditor = getEditor(tabs.activeTab);
            console.log(currentEditor)
            currentEditor.port.emit("editel",[this.annotationAnchor, annotationText]); 
            annotationEditor.hide();
        }
        annotationEditor.hide();
    },
    onShow: function() {
        this.postMessage('focus');
    }
});

var editField = pageMod.PageMod({
include: ['*'],
contentScriptWhen: 'ready',
contentScriptFile: [data.url('jquery-1.8.3.min.js'),
                    data.url('edit.js')],
onAttach: function(worker) {
    editors.push(worker);
    worker.on('detach', function () {
        detachWorker(this, selectors);
    });
}
});

Это регистрирует currentEditor как:

constructor {"contentScriptFile":["resource://jid1-kpzxxdxlwq8qkg-at-jetpack/widget/data/jquery-1.8.3.min.js","resource://jid1-kpzxxdxlwq8qkg-at-jetpack/widget/data/edit.js"],"contentScript":null,"port":{}}

Это выглядит правильно?

Также здесь находится скрипт контента - edit.js. Очевидно, сейчас это мало что дает. Первый шаг — заставить его перехватывать сообщение от main.js.

self.port.on("editEl", function(el) {
$(el[1]).val(el[0]);
});

person aturc    schedule 11.11.2014    source источник


Ответы (1)


Вам нужно сделать worker глобальной переменной. Затем выполните worker.port.emit в панели onMessage.


Изменить: лучший подход — создать массив рабочих процессов, как показано в этот пример в документации. Затем, чтобы позже найти работника текущей вкладки, вы можете сделать следующее:

const tabs = require('sdk/tabs');

var getWorker = function(tab) {
  for (var i = workers.length; i--;)
    if (workers[i].tab===tab) return workers[i];
}

var currentWorker = getWorker(tabs.activeTab);
person willlma    schedule 11.11.2014
comment
Итак, в основном вы говорите, что я объявляю рабочего как глобальную переменную, затем я определяю его в событии editField onAttach и, наконец, я вызываю его в событии annotationEditor onMessage? - person aturc; 12.11.2014
comment
Правильный. Но это очень наивный подход, так как у вас будет более одного работника. Документация для SDK очень хороша, и стоит прочитать их примеры. На той же странице, на которую вы ссылаетесь, есть отличный пример того, как управлять несколькими работниками. - person willlma; 12.11.2014
comment
Не могли бы вы взглянуть на вторую попытку в приведенном выше коде?! Спасибо - person aturc; 13.11.2014
comment
Любой шанс, что вы могли бы еще раз взглянуть на мой код. Я обновил его, чтобы попытаться включить ваши предложения. - person aturc; 13.11.2014
comment
Вы излучаете "editel", но слушаете "editEl" (заглавная Е). Строки должны быть идентичными. - person willlma; 13.11.2014
comment
Большое спасибо, что наконец-то это сделали! - person aturc; 14.11.2014