我试图为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;行显示以显示文件,不同的事件(卸载,命令,点击),但也无法找出任何这些方法。
任何提示?
答案 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中,用你需要的数据发出信号。