二把刀程序员编写火狐扩展限制自己对社交网站的访问

其实火狐本身有人开发了一个扩展叫做:

LeechBlock

可以完成这个事儿,而且可以选择星期几进行限制,就是觉得自己学学有意思还能个性化定制一下,所以呢……

说实在的自己就是二把刀,只会c,c++,和vc的最基本的东西,所以这个东西适合和我一样没啥基础的人看

这回完全是放假闲的,觉得自己上学的时候上人人和微博这样的社交网站太多了

chrome的性能好确实,但是默认安装C盘这一条让我很郁闷,所以选了firefox做开发,估计熟了差不多

如果有哪个高人不怕浪费时间不吝赐教,将万分感谢

火狐浏览器扩展的开发,首先要设置开发环境,其实网上那些推荐的火狐代码调试插件都不是很好用,因为大都用来调试的是网页代码,并非插件,所以我这样的二把刀说实话也没法推荐什么,所有的东西都是从网上那些firefox扩展开发的教程上面学来的。

第一步:开发环境

我的建议是安装一个Sublime Text 2,感觉很不错,黑色的底色非常适合写代码,颜色和字体也带来了不少便利

同时可以按ctrl+shift+j呼叫出火狐本身的错误控制台,这样在执行你的代码的时候就可以看到返回的错误了,如果看不到,试试清空列表。

网上很火的firedebug似乎显示不出扩展的错误,不知道为什么


第二步:建立文件夹

不同于那些高级的Microsoft VC++啥的帮你分好文件夹,你需要自己创建一个文件夹结构。

根目录文件夹随便起个名字吧,我这里叫做get_and_show,随便起的^_^

根目录文件夹下面包括:

  1. 文件夹:名称为chrome
  2. 文本文件:全名为chrome.manifest
  3. 文本文件:install.rdf

一会儿再说明这几个都用来干什么

进一步的chrome文件夹下面需要建立如下几个子文件夹

  1. 文件夹:名称为content
  2. 文件夹:名称为locale
  3. 文件夹:名称为skin

而locale文件夹下还有两个文件夹en-US和zh-CN

以上这个文件夹建立完了以后来解释一下他们的意义

chrome.manifest是Chrome注册的清单文件,主要有两个功能:

  1. 指定各种程序包的相对路径
  2. 指定扩展中的XUL文件叠加到哪个已有的XUL上

看一下chrome.manifest的代码

content restartfirefox chrome/content/
skin restartfirefox classic/1.0 chrome/skin/
locale restartfirefox en-US chrome/locale/en-US/
locale restartfirefox zh-CN chrome/locale/zh-CN/

style chrome://global/content/customizeToolbar.xul chrome://restartfirefox/skin/restartfirefox.css
style chrome://browser/content/browser.xul  chrome://restartfirefox/skin/restartfirefox.css

overlay chrome://browser/content/browser.xul chrome://restartfirefox/content/restartOverlay.xul

头4行就是指定我们自己程序包的相对路径的

例如第一行,这样定义了之后,如果要引用content目录下的a.xul文件,那么可以用chrome://restartfirefox/content/a.xul

同样呢,如果要引用skin目录下的b。css,则可以用chrome://restartfirefox/skin/b.css (但是说实在的,那个classic/1.0是什么确实不知道)

而指定叠加目标,指令为overlay,最后一行就是干这件事儿的

叠加restartOverlay.xul到browser.xul之上,这个restartOverlay.xul是我们自己编写的,而browser.xul则是火狐本身的一个文件,它们本身都是定义浏览器界面的。实际上firefox有一个扩展程序叫做DOM Inspector可以查看这个browser.xul文件,就能看到它是什么了


说完了chrome.manifest,再说install.rdf

说白了这是一个xml语法格式的文件,一定要放在这个位置,它负责整个扩展的安装,这是我的扩展的install.rdf的代码:

<?xml version="1.0"?>

<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">

	<Description about="urn:mozilla:install-manifest">

		<em:id>restart@restartfirefox.org</em:id>
		<em:version>0.1 </em:version>
		<em:type>2</em:type>

		<em:targetApplication>
			<Description>
				<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
				<em:minVersion>4.0</em:minVersion>
				<em:maxVersion>13.0</em:maxVersion>
			</Description>
		</em:targetApplication>
		<em:iconURL>chrome://restartfirefox/skin/icon.png</em:iconURL>
		<em:name>FireRestart(simplified)</em:name>
		<em:description>Restart Firefox quickly, for extension developers.
		Added a toolbarbutton to the customize ToolbarPalette, you can drag it to anywhere you like in the toolbar or addon bar. there is also a full version which had added a menuitem to the file menu.</em:description>
		<em:creator>JumuFENG</em:creator>
		<em:homepageURL>http://blog.csdn.net/z6482</em:homepageURL>
   <em:localized>
        <Description>
            <em:locale>zh-CN</em:locale>
	        <em:name>FireRestart(精简版)</em:name>
                <em:description>快速重启firefox,定制工具栏中添加了一个按钮,可手动移动到任何地方。完整版在文件菜单中增加了重新启动菜单项。</em:description>
                <em:creator>JumuFENG</em:creator>
                <em:homepageURL>http://blog.csdn.net/z6482</em:homepageURL>
        </Description>
    </em:localized>
        </Description>
</RDF>
由于这个扩展是我从blog.csdn.net/z6482这个博客上学来的,这个install.rdf就没变

原来就是控制火狐重启的这样一个功能,我们可以逐一修改这些参数改成自己需要的,看不懂的呢就暂时不用动了。

注意那个iconURL一项决定了安装界面中的图标。


接下来就看看chrome文件夹中的content文件夹中的内容,这也是这个扩展最核心的地方了

最简单的扩展包括一个.js文件和一个.xul文件,我们的扩展包括两个.js和一个.xul文件:

  1. loadtab.js
  2. restart.js
  3. restartOverlay.xul

这个xul文件定义了这个扩展在浏览器中的形式以及这个扩展调用的js文件。

可以看到,loadtab.js和restart.js这两个文件名在restartOverlay.xul文件中都出现了。

loadtab主要负责探测机主是否在访问社交网站以及对应的措施

restart则包含了单击工具栏上的扩展图标时的动作代码(这个对应了打开、关闭组织社交网站的功能,但是尚未实现,一开始在restart程序中的时候,这个按钮负责重启浏览器,想改造一下,暂时处在烂尾的状态)

下面给出loadtab.js的完整代码:

/*相应载入页面*/
var found = false;
var IntervalID1 = null;
var IntervalID2 = null;
function checkIfplay(url, IntervalID)//这个函数遍历所有的tab寻找对应url的网址
{
    var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
                     .getService(Components.interfaces.nsIWindowMediator);
    var browserEnumerator = wm.getEnumerator("navigator:browser");
 
  // Check each browser instance for our URL
    
    while (!found && browserEnumerator.hasMoreElements()) {
    var browserWin = browserEnumerator.getNext();
    var tabbrowser = browserWin.gBrowser;
 
    // Check each tab of this browser instance
    var numTabs = tabbrowser.browsers.length;
    for (var index = 0; index < numTabs; index++) {
      var currentBrowser = tabbrowser.getBrowserAtIndex(index);
      测试代码://
      //测试结果说明,这个currentBrowser.currentURI.spec是全称
      // currentBrowser.currentURI.host是首段
      //1-//
      //alert(currentBrowser.currentURI.spec);
      //2-//
      //alert(currentBrowser.currentURI.host);
      //
      if (url == currentBrowser.currentURI.host) {
 
        /*// The URL is already opened. Select this tab.
        tabbrowser.selectedTab = tabbrowser.tabContainer.childNodes[index];
 
        // Focus *this* browser-window
        browserWin.focus();*/
 
        found = true;
        break;
      }
      found = false;
    }
  }
 
  // Our URL isn't open. Open it now.
  if (!found) {
    /*var recentWindow = wm.getMostRecentWindow("navigator:browser");
    if (recentWindow) {
      // Use an existing browser window
      recentWindow.delayedOpenTab(url, null, null, null, null);
    }
    else {
      // No browser windows are open, so open a new one.
      window.open(url);
    }*/
    clearInterval(IntervalID);
  }
}
function callback1(){
    found = false;
    checkIfplay(KeepOutUrl1,IntervalID1);
    if(found){alert("趁早关了人人吧");}
}
function callback2(){
    found = false;
    checkIfplay(KeepOutUrl2,IntervalID2);
    if(found){alert("趁早关了微博吧");}
}

var myExtension = {
    init: function() {
        // The event can be DOMContentLoaded, pageshow, pagehide, load or unload.
        if(gBrowser) gBrowser.addEventListener("DOMContentLoaded", this.onPageLoad, false);
    },
    onPageLoad: function(aEvent) {
        var doc = aEvent.originalTarget; // doc is document that triggered the event
        var win = doc.defaultView; // win is the window for the doc
        // test desired conditions and do something
        // if (doc.nodeName == "#document") return; // only documents
        // if (win != win.top) return; //only top window.
        // if (win.frameElement) return; // skip iframes/frames
        // alert("page is loaded \n" +doc.location.href);
        if (doc.location.host == KeepOutUrl1)
        {
            alert("你开人人了!贱人,贱人,贱人!");
            //checkIfplay(KeepOutUrl1,null,1);
            //setTimeout("alert('10 second')",10000);
            IntervalID1 = setInterval(callback1,10000);
        }
        if (doc.location.host == KeepOutUrl2)
        {
            alert("你开微博了!贱人,贱人,贱人!");
            //checkIfplay(KeepOutUrl1,null,1);
            IntervalID2 = setInterval(callback2,10000);
        }
    }
}
window.addEventListener("load", function load(event){
    window.removeEventListener("load", load, false); //remove listener, no longer needed
    myExtension.init(); 
},false);

好吧还是N多的不和谐。

这段代码包含了三个重要的点。

第一,如何建立一个响应机制使得firefox知道有页面载入。这里热烈推荐一个网站MDN,这个页面有关于firefox对于标签页的详细操作:

https://developer.mozilla.org/en-US/docs/Code_snippets/Tabbed_browser

之中就有一部分如何建立一个EventListener来响应page loaded这样一个事件,从var myExtension到最后,完成了这个动作。

第二,如何解析出当前打开页面的url

这个文件中利用了两种方法,不知道是不是差不多。

第一就是在onPageLoad这个函数里,得到的那个doc变量是一个document(这玩意儿是什么我也不知道,貌似和vc里面的那个doc有点儿像?)

利用这个doc,采用代码doc.location.host就可以得到所打开网站的头一段网址,比如你打开了人人网,那么不管你的id是多少,返回的网址都是www.renren.com

第二就是在checkIfplay函数里面的currentBrowser变量,可以通过currentBrowser.currentURI.host也同样可以得到相同的效果!

这两种其实我都不是很清楚他们这些变量的结构,但是感觉功能上目前是实现了,理论吗交给专家吧

此外还要来看看restart.js的代码,这个代码目前能够实现的也是一个提取首段地址并显示的功能,这又是一个新的方式,这个方式我基本上琢磨明白了。

第三,就是如何定时检测打开的页面是否有我们不想打开的社交网站。js中有两个简单的定时器,有一个叫做setInterval()这个函数和VC里面的SetTimer差不多,不过它的第一个参数是函数名称,执行了这句代码之后,会按照第二个参数规定的毫秒数周期性的执行第一个参数表示的函数。在函数checkIfplay当中,首先取得了打开的标签页数目,然后设置了一个循环,遍历了所有标签页并依次提取首段地址,检查后确定bool变量found的值,并给后续程序提供参考,这里设计的是,如果发现这两个网站的任何一个打开,那么每隔10s就会提示你,关了吧……够残暴吧?你也可以选择更为残暴的方式例如直接关掉它或者干脆显示空白页,具体做法仍然参照:

https://developer.mozilla.org/en-US/docs/Code_snippets/Tabbed_browser

/* 测试全局变量 */
var KeepOutUrl1="www.renren.com";
var KeepOutUrl2="weibo.com";

var restartFirefox = {
// main restart logic
// 调试这一段代码,故意留一个错误,看看有什么错误
ourRestart : function() {

// 目的是想要获得当前窗口的url
// 结果却是获得了整个浏览器界面的url chrome://browser什么的
/*var urlnow = window.location.href;
alert(urlnow);*/

// 测试代码,关闭当前标签页
/*var tab = gBrowser.mCurrentTab;
if(tab) gBrowser.removeTab(tab);*/

// 测试代码,当前标签页网址获得
var currentDoc = gBrowser.contentDocument;
// var urlnow = currentDoc.location;
// alert(urlnow);
var urhost = currentDoc.location.host;
alert(urhost);
if (urhost == "www.renren.com")
{alert("renren");}

// switch不好用?不知道为啥
/*switch(urhost)
{
	alert("come to switch");
	case "www.renren.com":
	{
		alert("你打开的是人人");
	}
	break;
	case "weibo.com"
	{
		alert("你打开的是新浪微博");
	}
	break;
	default:
	{
		alert(urhost);
	}
}*/

}
};

这个gBrowser可以直接使用,利用它得到一个document之后剩下的就和上面一样了,这里尝试用一个switch不知道哪里写错了,总是失败。呵呵。

其实,这个响应函数可以通过控制一个bool变量来控制插件是否进行目前打开页面的检查,从而实现一个“开关”的功能!


最后,还有一些别的文件要说:

在locale文件夹中的en-US以及zh-CN文件夹里各有一个restart.dtd文件,内容差不多:

en-US中的:

<!ENTITY Restart "Restart">

zh-CN中的:

<!ENTITY Restart "重新启动">

表示的是各个实体的文字

这个Restart实体对应的就是界面定义的那个XUL中的“&Restart”

而,在skin文件夹中,里面有两个png的图片用作图标,分别是一个32x32的图片和一个16x16的图片,而另外一个css文件就是一个样式文件了,负责将这两个图标文件对应到按钮上去了:

/* ToolbarButton */
#restartfirefox-button {
  list-style-image: url("chrome://restartfirefox/skin/icon21.png");
}
/*这个#表示的是ID*/
/*下面的toolbar[iconsize="small"]表示的是具有该属性的,ID为#后面的,可以说是定义了大小两款图标,可以考虑*/
toolbar[iconsize="small"] #restartfirefox-button {
  list-style-image: url("chrome://restartfirefox/skin/iconsmall.png");
}

至此就全部结束了,要形成能够在浏览器上进行安装的xpi文件

需要做的,就只是选中get_and_show文件夹内部的三个文件,右键单击选择“发送到zip文件夹”

然后把生成的zip文件更名为xpi文件即可,文件名我用的是restart.xpi,用别的只要扩展名不变应该也一样

注意的是:不能用winRAR等软件进行压缩,我直接用win7自带的成功了,rar却不行,即使你选择了zip格式

似乎也不能对get_and_show这个大文件夹直接进行压缩,而是要分别选中三个,将它们压缩到一个文件中。

祝各位顺利……

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值