3
25
2014
0

火狐开发者工具、Object.watch 以及地址栏图标

之前通过 userChrome.js 脚本把火狐的地址栏图标弄回来了,但是一直有这么个问题:打开一个会自动跳转的标签页,比如 t.co 或者登陆状态下的 Google 搜索结果时,首先会显示跳转前的网站的图标(这没问题),然后开始载入新页面了(这问题也不大),然后新页面是使用 HTTPS 的(比如 MDN),于是就会看到地址栏图标后边已经变成绿色、显示出了站点信息(如「Mozilla Foundation (US)」),但是图标仍旧是跳转前的图标

经过探索,我发现火狐在载入新页面时并不会及时更改网站的图标(即该 tab 对象的.image属性;大概是因为默认情况下,即标签页里那个图标,它会被「载入中」的图标取代),但是其它信息都会及时更改,这才造成了不一致。既然这段时间取不到网站的图标,那么用默认图标好了。但问题是,怎么知道地址栏的 URL 已经改变了呢?

我试过在urlbar上监听change事件。Firebug 在调试chrome://browser/content/browser.xul页面时说会有这么个事件,但是真正在 chrome 里运行时却发现没有这样的事件被触发。

还想到了通过 Object.watch 方法要监听tab.linkedBrowser.currentURI属性的更改,但是好像也没有被调用。也许那个 nsIURI 对象一直在那里,只是它的值在变而已。

期间还试过 addProgressListener。大概是用法不对,无果。

后来结合了以上两个方案,决定监听urlbar.value的更改。这下终于好用了。有点小坑的是,因为一直在尝试各种方案,没仔细看文档,结果没注意注册到.watch方法中的函数要返回实际要设置的属性值,把火狐地址栏搞坏掉了……

在调试过程中,浏览器控制台(取代了以前的「错误控制台」,快捷键还是Ctrl-Shift-J)比「代码片断速记器」好用(它实际上是火狐自带调试工具中的「Web 控制台」运行在 chrome 上的版本):

火狐的「浏览器控制台」

  • chrome 脚本中的console.log等日志会记录在浏览器控制台,并且可以按关键字过滤(比如我今天一直在用的userChrome
  • 浏览器控制台支持 Tab 补全
  • 代码片断速记器每次打开之后需要手动切换「在浏览器环境中执行」
  • 代码片断速记器中不支持选择即复制、中键点击即粘贴功能,不支持 GTK 自定义的编辑快捷键
  • 浏览器控制台中直接记录对象的话,点击之后会出现和代码片断速记器Ctrl-i快捷键一样的「对象查看器」

不过浏览器控制台不支持将日志中的对象直接在脚本中使用(Firebug 支持)。

哦还有,MozRepl 在开启 chrome 调试的时候,是连接到最后一个有焦点的火狐窗口的(而不一定是chrome://browser/content/browser.xul这个)。期间搞错了一次,发现里边竟然连gBrowser变量都没有 -_-|||

最后,辛辛苦苦接着出来的新版代码(其实没改多少):

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

  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';
    var identity = document.getElementById('identity-box');
    if('chromeUI'.indexOf(identity.className) != -1){
      // already has a pretty icon as list-style-image
      icon = '';
    }
    console.log('updateIcon', icon, tab.linkedBrowser.currentURI.spec, event);
    document.getElementById('page-proxy-favicon').src = icon;
    if('verifiedDomain'.indexOf(identity.className) != -1){
      var identityLabel = document.getElementById('identity-icon-labels');
      identityLabel.collapsed = false;

      var domain;
      try{
        domain = eTLDService.getBaseDomain(tab.linkedBrowser.currentURI);
      }catch(ex){ // NS_ERROR_HOST_IS_IP_ADDRESS
        domain = tab.linkedBrowser.currentURI.host;
      }

      document.getElementById('identity-icon-label').value = domain;
    }
  }

  var container = gBrowser.tabContainer;
  // includes TabSelect (.selected is modified)
  container.addEventListener("TabAttrModified", updateIcon, false);
  document.getElementById('urlbar').watch('value', function(prop, oldval, newval){
    console.log('urlbar value changed to ' + newval);
    document.getElementById('page-proxy-favicon').src = 'chrome://mozapps/skin/places/defaultFavicon.png';
    return newval;
  }, false);

  })();
}
Category: 火狐 | Tags: 火狐 userChrome
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
8
15
2011
14

userChrome 脚本:中键粘贴并搜索

Google 字典没了,但单词还是要查的。目前用的是沪江小D。实际上之前也一直在用它的划词查询书签。释义简单了点,但速度是足够快了。可是再也不能之前选中单词后点几下就能查到了(划词有时候会很烦,特别是与FireGuesture的搜索冲突的时候)。过了几天使用Ctrl-C来复制或者Ctrl-W来清除上一个词或者Ctrl-T打开新标签使用关键字搜索的日子,最终还是忍不住折腾了起来,最后终于写成以下脚本:

if(location == "chrome://browser/content/browser.xul"){
  var s = document.getElementById('searchbar');
  s.addEventListener('mousedown', function(e){
    if(e.button == 1){
      this.value = '';
    }
    return true;
  }, false);
  s.addEventListener('mouseup', function(e){
    if(e.button == 1){
      var where = e.altKey ? 'current' : 'tab';
    }
    setTimeout(function(){
      if(s.value){
        s.doSearch(s.value, where);
      }
    }, 100);
    return true;
  }, false);
}

使用方法:

先吐槽下:这使用方法可比脚本难找得多。我是边 Google 边摸索才弄明白的。

首先安装userChromeJS插件。火狐现在已经不再读取userChrome.js文件,所以需要这个插件。另外火狐5的话目前需要Add-on Compatibility Reporter这个插件。然后就是把代码粘贴到<firefox_profile>/chrome/userChrome.js文件里了。行家的话应该知道怎么单独文件之类的,我暂时就懒得研究了。

一切就绪后重启火狐。这时在搜索框点击鼠标中键就会将 X 剪贴板的内容粘贴到搜索框中并在新标签页中打开搜索。如果点击的时候按住Alt键的话,会在当时页面中打开。

最后,既然用到的 X 剪贴板,当然是不支持 Windows 了。(我还不会用Javascript操纵剪贴板。。。)

Category: 火狐 | Tags: 火狐 userChrome

Mastodon | Theme: Aeros 2.0 by TheBuckmaker.com