Firefox扩展:请参阅XUL文件中bootstrap.js中定义的对象

时间:2015-10-27 02:01:07

标签: firefox firefox-addon xul

我试图为a Firefox extension I use做出贡献,但我不知道我在做什么:)

我有一个由XUL文档驱动的对话框,用于从用户那里收集一些数据。这一切都很好,很好。但是当用户确认对话框时,我需要调用在我的bootstrap.js文件中定义的对象上定义的函数。可以直接做吗?例如,在XUL文件中:

<prefpanes id="my-pane" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
  <script>
    function myCallback() {
      PassFF.myAction(); // PassFF is undefined here
    };
  </script>
  <prefpane>
    <button id="my-button" oncommand="myCallback();" />
  </prefpane>
</prefpanes>

如果这不可能,我可以在首次打开文档时注册回调吗?像这样:

var dialog = window.openDialog("chrome://passff/content/mypane.xul",
                               "my_pane_name",
                               "chrome,titlebar,toolbar,modal");
dialog.addEventListener('close', function(event) {
  PassFF.myAction(); // PassFF is defined here, but the event doesn't fire
});

我尝试过将我的XUL文档中的bootstrap.js脚本导入另一个script标记,添加另一个&#34;内容&#34;行显示以显示文件,不同的事件(卸载,命令,点击),但也无法找出任何这些方法。

任何提示?

1 个答案:

答案 0 :(得分:1)

您可以使用平台观察员机制。

这是&#34; signals.js&#34;文件(模块):

let EXPORTED_SYMBOLS = ["addSignalListener", "removeSignalListener", "emitSignal", "signalNamePrefix"];


const {utils:Cu, classes:Cc, interfaces:Ci, results:Cr} = Components;


function genUUID () {
  let uuidgen = Cc["@mozilla.org/uuid-generator;1"].createInstance(Ci.nsIUUIDGenerator);
  if (!uuidgen) throw new Error("no UUID generator available!");
  return uuidgen.generateUUID().toString().replace(/[^-a-z0-9]/ig, "");
}


const signalNamePrefix = "signal-"+genUUID()+"-";
const obs = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);


let observers = {};

function addSignalListener (name, cback) {
  if (typeof(name) !== "string" || !name) throw new Error("invalid signal name");
  if (typeof(cback) !== "function") throw new Error("callback function expected");
  // check if already here
  if (cback in observers) {
    let names = observers[cback];
    if (name in names) return; // nothing to do
  } else {
    observers[cback] = {};
  }
  let observer = {
    observe: function (subject, topic, data) {
      topic = topic.substr(signalNamePrefix.length); // remove prefix
      if (data && data.length) {
        try {
          data = JSON.parse(data);
        } catch (e) {
          Cu.reportError(e);
          return;
        }
      } else {
        data = null;
      }
      cback(topic, data);
    },
  };
  obs.addObserver(observer, signalNamePrefix+name, false);
  observers[cback][name] = observer;
}


function removeSignalListener (name, cback) {
  if (typeof(name) !== "string" || !name) throw new Error("invalid signal name");
  if (typeof(cback) !== "function") throw new Error("callback function expected");
  // find observer
  let names = observers[cback];
  if (names === undefined) return; // nothing to do
  if (!(name in names)) return; // nothing to do
  try { obs.removeObserver(observers[cback][name], name); } catch (e) {}
}


function emitSignal (name, data) {
  if (typeof(name) !== "string" || !name) throw new Error("invalid signal name");
  data = (typeof(data) === "undefined" ? null : (data !== null ? JSON.stringify(data) : null));
  obs.notifyObservers(null, signalNamePrefix+name, data);
}

样本使用:

Components.utils.import("chrome://myext/content/signals.js");

dump(signalNamePrefix+"\n");
addSignalListener("mysignal", function (signame, data) {
  dump("MYSIGNAL("+signame+"): "+data+"\n");
  for (let [k, v] of Iterator(data)) dump(" ["+k+"]=["+v+"]\n");
});

emitSignal("mysignal", {any:42, data:[669], here:"wow!"});

这里只需导入&#34; signals.js&#34;在你的&#34; bootstrap.js&#34;中,添加信号监听器。然后导入&#34; signals.js&#34;在你的对话框js中,用你需要的数据发出信号。

相关问题