前言 最新版本的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 ( )  {                  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