前言

最新版本的Firefox 终于舍弃了鸡肋的xul布局,可以使用原生的html用作ui交互,插件界面中可以引入 bootstrap jQuery等库,大大简便了布局和高度自定义化,本文以一个随机自定义referer 实例来记录jpm 高级ui交互编程。

界面布局

ui 控件

官方api中提供的ui控件如下
1. ActionButton 动作按钮
2. ToggleButton 切换按钮
3. Frame 框架
4. Toolbar 工具栏
5. Sidebar 网站边栏
具体可以参考官方文档 https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/ui

panel

面板为点击图标或者Toolbar 弹出的页面,声明代码如下

1
2
3
4
5
6
7
var panel = panels.Panel({
width:420,
height:420,
contentURL: self.data.url("panel.html"),
contentScriptFile : [ self.data.url("js/jquery.js"),self.data.url("../lib/panel.js")],
onHide: handleHide
});

/data/panel.html 文件为布局内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="css/bootstrap.min.css" >
<style type="text/css">
.group {
margin-top:8px;
text-align:center;
}
</style>

</head>
<body>
<div class="container">
<div class="group">
<label>

<input type="checkbox" id="toggle" />开启

</label>

<span class="label label-info">referer 列表</span>

<div class="group">

<textarea class="form-control" rows="8" id="referer"></textarea>



<span class="label label-info">站点列表</span>

<div class="group">

<textarea class="form-control" rows="4" id="site"></textarea>



<div class="group">
<button type="button" class="btn btn-default" id="save" >保存</button>



</body>
</html>

效果如图

tab 新页面

panel 界面只适合弹出小型对话框,功能繁琐的页面则需要一个新全浏览器页面。

1
2
var tabs = require("sdk/tabs");
tabs.open(data.url("option.html"));

效果

事件响应

引入对应js文件之后就可以和网页一样写事件响应了,为了简便代码还可以引入jQuery库。

1
contentScriptFile : [ self.data.url("js/jquery.js"),self.data.url("../lib/panel.js")],

响应代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$(function() {
var btn_toggle = $("#toggle");
var btn_save = $("#save");
var text_data= $("#referer");
var text_site= $("#site");
//初始化界面
self.port.on("init", function(enable,referer,site) {
btn_toggle.attr("checked", enable);
text_data.val(referer);
text_site.val(site);
});
//切换事件
btn_toggle.click(function() {
//prefs['enable']= this.checked;
self.port.emit("toggle", this.checked);
});
//保存事件
btn_save.click(function() {
self.port.emit("save",text_data.val(),text_site.val());
});

});

ui控件与插件代码交互需要通过一个port对象,提供消息发送和接收,事件交互。
官方文档
https://developer.mozilla.org/en-US/Add-ons/SDK/Guides/Content_Scripts/port

当点击切换按钮时,对应的交互代码为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
panel.port.on("toggle", function(enable) {

prefs['enable'] = enable ;
if(enable){

btn_enable();
httpRequestObserver.register();
}
else{

btn_disable();
httpRequestObserver. unregister();
}
});

又如 main.js 中调用panel.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var  default_referer=[
'http://www.baidu.com',
'http://www.google.com',
'http://www.hao123.com'];

var default_site=['127.0.0.1'];
if (!ss.storage.referer){
//赋值
ss.storage.referer=default_referer;
}

if (!ss.storage.site){

ss.storage.site=default_site;
}
//取值
var strReferer=ss.storage.referer.join('\n');
var strSite=ss.storage.site.join('\n');
panel.port.emit("init",prefs['enable'],strReferer,strSite);

数据储存

数据储存的api sdk/simple-storage,可以自由存取各种数据对象。
官方demo

1
2
3
4
5
6
7
var ss = require("sdk/simple-storage");
ss.storage.myArray = [1, 1, 2, 3, 5, 8, 13];
ss.storage.myBoolean = true;
ss.storage.myNull = null;
ss.storage.myNumber = 3.1337;
ss.storage.myObject = { a: "foo", b: { c: true }, d: null };
ss.storage.myString = "O frabjous day!";

随机referer 实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
var { ToggleButton } = require('sdk/ui/button/toggle');
var panels = require("sdk/panel");
var self = require("sdk/self");
var prefs = require("sdk/simple-prefs").prefs;
var ss = require("sdk/simple-storage");
var {Cc, Ci} = require("chrome");
var httpRequestObserver =
{
observe: function(subject, topic, data)
{

if (topic == "http-on-modify-request") {
var httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
var host= httpChannel.originalURI.host;
//判断是否在站点列表中
if (ss.storage.site.indexOf(host) >= 0){

httpChannel.setRequestHeader("Referer", read_referer(), false);
}

}
},

get observerService() {
return Cc["@mozilla.org/observer-service;1"]
.getService(Ci.nsIObserverService);
},
//注册监听器
register: function()
{
this.observerService.addObserver(this, "http-on-modify-request", false);
},
//卸载
unregister: function()
{
this.observerService.removeObserver(this, "http-on-modify-request");
}
};

引用

1.https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/ui
2. https://developer.mozilla.org/en-US/Add-ons/SDK/Guides/Content_Scripts/port
3. https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/tabs
4. https://developer.mozilla.org/en-US/Add-ons/SDK/Guides/Content_Scripts/using_port
5. https://developer.mozilla.org/en-US/Add-ons/SDK/High-Level_APIs/simple-storage
6. https://developer.mozilla.org/en-US/docs/Setting_HTTP_request_headers