Paste and Go 3の貼り付けて移動ボタンをロケーションバーに格納する

FirefoxPaste and Go 3をインストールするとツールバーに「貼り付けて移動」ボタンを追加できるようになりますが、大きくてダサいのでロケーションバーに入れるuserChrome.jsスクリプトを書きました。

拡張の要素の調べ方はいつものようにDOM Inspector(chrome://browser/content/browser.xulを開く)と userChromeお試し用スクリプト - Griever を使ってグリグリやりました。

画像右の#pg2-pasteandgo-toolbar-buttonをそのままロケーションバーにいれると大きいまま、widthは変えられるがheightが無理。style.listStyleImage = 'url(chrome://pasteandgo2/skin/go-button-16.png)'しても具合がわるいので、移動ボタンと同じようにimage要素にonclickで作成。

// ==UserScript==
// @name           PasteAndGo3p.uc.js
// @namespace      http://d.hatena.ne.jp/Cherenkov/
// @description    貼り付けて移動ボタンをロケーションバーに格納する
// @include        chrome://browser/content/browser.xul
// ==/UserScript==

(function() {

var pg = document.createElement('image');
pg.setAttribute("onclick", "pg2_PasteAndGo()");
pg.style.listStyleImage = 'url(chrome://pasteandgo2/skin/go-button-16.png)';
document.getElementById('urlbar-icons').appendChild(pg);

})();

Stylishを拡張して編集しやすくする「stylishEditButton.uc.js」

userChromeJS1.1 + Stylish 1.0.3 + Firefox 3.5で動作確認。

編集するたびに一々アドオンまで行くのが面倒なので、ポップアップメニューに編集ボタンを付けた。*1

使い方

「stylishEditButton.uc.js」はFirefox拡張のuserChrome.js用のスクリプトなので、userChrome.js(0.8か1.1)が必要。インストール方法はこちら=>超簡単にuserChrome.jsのインストールを説明する - Cherenkovの暗中模索にっき

download

stylishEditButton.uc.js  (github:139796)

// ==UserScript==
// @name           stylishEditButton.uc.js
// @namespace      http://d.hatena.ne.jp/Cherenkov/
// @description    http://d.hatena.ne.jp/Cherenkov/20090703/p1
// @include        chrome://browser/content/browser.xul
// ==/UserScript==
(function(){
function contextEdit(event) {
  var item = document.evaluate('//*[@class="style-menu-item"]', stylishPopup, null, 7, null);
  var btn = document.evaluate('//*[@class="stylishEditBtn"]', stylishPopup, null, 7, null);
  if(item.snapshotLength == btn.snapshotLength)
    return false;
  if(event.type == "popupshowing") {
    var style = Components.classes["@userstyles.org/style;1"]
                          .getService(Components.interfaces.stylishStyle)
                          .findForUrl(stylishCommon.cleanURI(content.document.location.href), false, 0, {});
    for(var i = 0; i < item.snapshotLength; i++) {
      var editBtn = document.createElement("menuitem");
      editBtn.setAttribute("class", "stylishEditBtn");
      editBtn.setAttribute("id", style[i].id);
      editBtn.setAttribute("label", "edit " + style[i].name);
      editBtn.addEventListener("command", function() {
        stylishCommon.openEditForId(this.id);
      }, false);
      item.snapshotItem(i).parentNode.insertBefore(editBtn, item.snapshotItem(i).nextSibling);
    }
  } else {
    for(var i = 0; i<btn.snapshotLength; i++)
      btn.snapshotItem(i).parentNode.removeChild(btn.snapshotItem(i));
  }
}
var stylishPopup = document.getElementById("stylish-popup");
stylishPopup.addEventListener("popupshowing", contextEdit, false);
stylishPopup.addEventListener("popuphiding", contextEdit, false);
})();

解説

  • Components.classes["@userstyles.org/style;1"].getService(Components.interfaces.stylishStyle).findForUrl(stylishCommon.cleanURI(content.document.location.href), false, 0, {});でアドオンのcomponentsフォルダにあるstylishStyle.jsのfindForUrlメソッドを使っている。urlから適用されるStyle情報を持ってきてくれる。
  • 今回編集したようなXULのポップアップメニューは独立したところにある。それを発見しやすくするにはFirebugのHTMLタブのクリックしてメニューを開いて「変更を強調表示」、「変更をスクロールして表示」にチェックをいれてから、当該のコンテキストメニューを開くとスクロールされて強調表示されるので発見しやすい。

まとめ

教えてもらって気づいた、ポップアップメニューで右クリックすると編集できた。デモまでして恥ずかしいけど、これでも結構勉強になったのでガンバリます。

*1:Stylishは1系から使い始めた

サイドバーブックマークのスクロール位置を記憶するuserChromeスクリプト

なにこれ

Firefox3系はサイドバーブックマークを一度閉じるとスクロールした位置を忘れる。これをなんとかする。

このスクリプトを動作させるにはFirefoxアドオンの「userChrome.js」とサイドバーに対応している「Alice0775さんのSub-Script Loader」が必須です。
userChrome.jsのインストール方法はこちら 超簡単にuserChrome.jsのインストールを説明する - Cherenkovの暗中模索にっき

// ==UserScript==
// @name           remember sidebar scroll position
// @namespace      http://d.hatena.ne.jp/Cherenkov/
// @description    http://d.hatena.ne.jp/Cherenkov/20090616/p1
// @include        chrome://browser/content/bookmarks/bookmarksPanel.xul
// ==/UserScript==

(function(){
  var gPrefService = Components.classes[
        "@mozilla.org/preferences-service;1"].
            getService( Components.interfaces.nsIPrefBranch);
  document.getElementById("bookmarks-view-children").addEventListener("scroll", function() {
    var getRow = document.getElementById("bookmarks-view").boxObject.getFirstVisibleRow();
    gPrefService.setIntPref("userChrome.bookmarksPanel.rowPosition", getRow);
  },false);

  var pos = gPrefService.getIntPref("userChrome.bookmarksPanel.rowPosition");
  document.getElementById("bookmarks-view").boxObject.scrollToRow(pos);
})();

使い方

userChrome.jsとAlice0775さんのSub-Script Loaderをインストールしてから、ダウンロードしたrememberSidebarScrollPosition.uc.jsをuserChrome.jsと同じ場所(プロファイルのchromeフォルダ)に置く。

解説

ブックマークサイドバーをスクロールするたびに「設定システム」(about:configのやつ)にスクロールした後の最初の行の値を保存している。サイドバーを開くたびにbookmarksPanel.xulがロードされuc.jsが実行されスクロールされる。

感想

  • 最初browser.xulsidebar開閉のwatchポイントをつくってbookmarksPanel.xulと連携しようとしたけど失敗。次にbroadcasterで出来るか調べたけどよくわからない。じっと考えてこれになった。
  • userChromeJS 1.1でも問題ない。サブスクリプトローダは必要。
  • All-in-One Sidebarは使わない。

Firefox起動時に「前回終了時のタブを復元」と「指定したページを開く」

Firefoxの設定で以下2点を個別に実行することは出来るのですが、両方をあわせて実現することが出来ません。

  1. 前回のタブを復元
  2. (開いていないならば)指定したページ(複数)を開く

http://q.hatena.ne.jp/1244461867

1はFirefoxの機能のオプションの一般 Firefoxを起動するとき「前回終了時のウィンドウとタブを表示する」を設定してもらうとして、2はuserChrome.jsで対処するようにしてみた。



startupOpenPages.uc.jsで保存

// ==UserScript==
// @name           startupOpenPages
// @namespace      http://d.hatena.ne.jp/Cherenkov/
// @include        chrome://browser/content/browser.xul
// ==/UserScript==

(function(){

function open() {
  gBrowser.addTab("http://tv.yahoo.co.jp/vhf/sizu/realtime.html");
  gBrowser.addTab("http://www3.nict.go.jp/cgi-bin/JST.pl");
  gBrowser.addTab("http://dictionary.goo.ne.jp/");
}
setTimeout(open,0);

})();

新しいウィンドウを立ち上げるたびに指定したページが開きますけどね・・。

ダウンロード

startupOpenPages.uc.js (http://gist.github.com/127941)


なお2を単体で行う方法はホームページの欄に「http://www.google.co.jp|http://www.yahoo.co.jp」のように「|(パイプ)」で繋ぐ。

「右側(左側)のタブをすべて閉じる」を再び改造

以前書いた Tab Mix Plusの「右側(左側)のタブをすべて閉じる」ボタンを改造 - Cherenkovの暗中模索にっき を再び改造。Tab Mix Plusに依存する部分を無くした。このスクリプトだけで右側(左側)のタブをすべて閉じることができる。

ソースコード

http://gist.github.com/118130
rawからダウンロード。

感想

  • Tab Mix Plusと同じ振る舞いをしていると思う。いい感じ。
  • 添削おねがいします。
  • Menu Editorが原因ではまったりした。chrome環境ではうまく動くのに、普通のページで動かないときはsetTimeout(func,0)してみるといい。
  • gomitaさんのFireGesturesのソースやuserChrome.jsの記事が参考になりました。感謝。

Tab Mix Plusの「右側(左側)のタブをすべて閉じる」ボタンを改造

Tab Mix Plusで「右側・左側のタブをすべて閉じるボタン」を表示したときの右側・左側の配置が逆だと思う。しょっちゅう押し間違える*1のでボタンを作った。




最新版は一番下のタイプ。

ソースコード

tab-close_LR_button.uc.jsで保存。

// ==UserScript==
// @name           tab-close_LR_button
// @namespace      http://d.hatena.ne.jp/Cherenkov/
// @description    http://d.hatena.ne.jp/Cherenkov/20090526/p1
// @include        chrome://browser/content/browser.xul
// ==/UserScript==

(function() {

  var tabContextMenu = document.getAnonymousElementByAttribute(gBrowser, "anonid", "tabContextMenu");

  function contextEdit(){
    var L_btn = document.createElement("button");
    L_btn.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAANCAIAAAArLKlOAAAABnRSTlMA%2FwCjALHDmqA%2BAAABgklEQVR4nGP8v3gjA4ngpas5Ey65W2YaOSd2YYrfs9KZN28eC1Y9Xc9u7M%2Bf%2Fv37dwYLNzSz0pKSZGVl0W1byfo9YM08Xl7eBQsWsLKyIkvN%2F%2F22rKxMSEgoKCgIYdsRBaHp06crKChMnTpVWlr669evv3%2F%2F9l05GyLLy8trYmIyZ86cqqoqDQ0NqLayS0de7XmVn59vZmYGEeHm5j5w4ACaW16%2Ffv3mzRvNs7dZGu%2Be379%2Ff35%2Bvp%2BfHzMzM64QgoDdu3c7OTkxMDAwubq6CgoKHj9%2B%2FPHjx%2Fj1vHv3buvWrTkCcgwMDIyQeFvH9WfhwoVOTk7Jyck8PDwMDAx%2F%2F%2F69desWMzPz379%2F37x5c%2B7cuUOHDsXHx%2Ft9YkBog4AJb%2B4dOnQoLi7O19f3x48f3t7eampqrKysIiIiGhoakX%2B54SpR4q1ARMm%2F13%2FixIkbN25MSUnh5uaeZecDlfuL4mD06FY8enmCidNhecGenp6vX7%2Fi8icjnjS5huNXyA82rFIAVHuVVG1mytAAAAAASUVORK5CYII%3D");
    L_btn.addEventListener("command", function() {
      closeTabs("left");
    }, false);
    var R_btn = document.createElement("button");
    R_btn.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAANCAIAAAArLKlOAAAABnRSTlMAAAAAAABupgeRAAABWUlEQVR4nJWQv4uCYBjHn%2B4lUKRF2trbXNzzpS2C6NdamGM4SEP9CUJTW1tSDiI0RIS0NURL4BwVKBKEEm2GS8jd4MHFdXl3n%2FH5vp%2Fnxwue58H%2FeVMUxbKs50AUxcPh8NJrNBoY4%2BcXGONCodDv93%2BeVqvVaJru9XqKojwGyWRyPB6nUqlyuazr%2BjctsdvtBoOBLMuqqpqm6ft%2BFPi%2BbxgGRVHn83k4HDqO0263c7ncl1qtVi%2BXy3ss2%2B2W5%2FlutxspKLredV2GYV5%2BAEAmkymVSkEQeJ4nCAICgOVySRBEPp8nSTLGPJ1Os9ksCIJms5mISvP5fDKZcBzHsmw6nUYIhWGYzWYRQgBwu91Go9FqteJ5vl6vA0DisZ%2Bmafv9%2Fnq93u%2F34%2FFoGAZBEIvFQlVVjuM6nU7MLp8Ui8XNZtNqtSRJsm37dyECY1ypVNbr9V%2BFiOl0GpN%2BAJS%2FqroH3r3AAAAAAElFTkSuQmCC");
    R_btn.addEventListener("command", function() {
      closeTabs("right");
    }, false);

    var hbox = document.createElement("hbox");
    hbox.setAttribute("align","center");
    hbox.appendChild(L_btn);
    hbox.appendChild(R_btn);
    tabContextMenu.appendChild(hbox);

    //必要がないときは消える。
    tabContextMenu.addEventListener("popupshowing", function() {
      var aTab = (document.popupNode.localName == "tabs") ? gBrowser.mCurrentTab : gBrowser.mContextTab;
      if(aTab.previousSibling == null)
        L_btn.setAttribute("style","display:none");
      else
        L_btn.setAttribute("style","display:inline");
      if(aTab.nextSibling == null)
        R_btn.setAttribute("style","display:none");
      else
        R_btn.setAttribute("style","display:inline");
    }, false);
  }

  function closeTabs(LeftRight) {
    var aTab = (document.popupNode.localName == "tabs") ? gBrowser.mCurrentTab : gBrowser.mContextTab;
    var pos = aTab._tPos;

    //コンテキストメニューを開いたタブをアクティブにして、
    //タブを消す際にチラチラ表示されるのを防ぐ。
    if(pos!=gBrowser.mCurrentTab._tPos)
      gBrowser.selectedTab = gBrowser.mTabs[pos];

    var start = (LeftRight == "left") ? pos - 1 : gBrowser.mTabs.length - 1;
    var stop = (LeftRight == "left") ? 0 : pos + 1;
    for(var i = start; i >= stop; i--) {
      gBrowser.removeTab(gBrowser.mTabs[i]);
    }
    tabContextMenu.hidePopup();
  }

//Menu Editor対策
setTimeout(function(){contextEdit()},0);

})();

更新履歴

20090528
ボタンが押せないときは非表示にするようにした。
20090611
Tab Mix Plusに依存する部分を無くした。

使い方

問題点

  • ボタンを小さくしたいけどwidthがうまくいかない。hbox、buttonに対してsetAttribute("width",50)やsetAttribute("style","width:50px!important;")もダメ。
  • コードを書いていて途中までsetTimeout(run,0);無くても動いてたのになぜ。バックアップとってなくてわからなくなった・・。

追記:アドオンのMenu Editorを無効にすればsetTimeoutしなくても動くことを確認した。

  • コンテキストを開くたびにdataスキーム読み込むのはどうなんだ。

感想

Firebugさんありがとう。

*1:Menu Editorを無効化したとき

ブックマークツールバーのボタンに好きなfaviconを使う

3.5 Beta 4で動作確認。

このLDRに登録するブックマークレットがださいので作った。

  • 余計なアドオンは入れたくない。
  • bookmarks.html/jsonを書き換える方法はめんどくさい。
  • userChrome.cssからはfaviconを設定できるが、labelの非表示ができない。できた。(下の追記にリンク)

のでuserChrome.jsを使った。

userChrome.jsのインストールはコチラ→超簡単にuserChrome.jsのインストールを説明する - Cherenkovの暗中模索にっき




はてなアイコンと仲良しになった!

注意

本家やAlice0775氏のサブスクリプトローダを使っている人はボタンの名前が日本語だと動かないので、uc.jsファイルをUCJSFilesフォルダにいれるか、ボタンの名前をアルファベットだけにする必要があります。例えば「livedoor Readerに登録」を「addLDR」にする。

ソースコード

// ==UserScript==
// @name           bookmarklet favicon
// @namespace      http://d.hatena.ne.jp/Cherenkov/
// @include        chrome://browser/content/browser.xul
// ==/UserScript==

(function(){
var b = document.getElementById("bookmarksBarContent").getElementsByTagName('toolbarbutton');
for(var i=0;i<b.length;i++) {
  if(b[i].label=="addLDR") {
    b[i].label = "";
    b[i].setAttribute("style","list-style-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABnRSTlMA3ADcANwpVcdiAAAA9UlEQVR4nGO8c%2BeO2xJlBuLArpi7jIq1%2F4lUDQEs%2F%2F%2BSpB6m4UEHuoRCBXYNTAy%2FGRh%2BM3DKOUL4jIyMEPaDDgaIFBpi%2BfeHgYGBQTRwP0SDbB7CSxApDCehiiJz%2FxOj4fFUKIND2lHEZz8WP%2Fz%2FwwBBUHVSUM8Ie%2ByHSyEjdA1CrvvZJR0ZGBiezkUoejoXwcXiByGn%2FVj9AOWKh%2F0XD%2FuPDMTD%2FrOJOfzHAaDByibmCDdJwHY%2Fv81%2BiMivV%2Bj%2BZhT1xZeWXm9mZGBg%2BP%2F%2FPwMDAyMjIwPBtCTi9R%2BNzXRi0t3%2FfxnwI0ZGRkZGxv9%2FGU5MugsAfNu0706eS60AAAAASUVORK5CYII%3D')");
  }
  if(b[i].label=="livedoor Reader") {
    b[i].label = "";
  }
  if(b[i].label=="Tumblr") {
    b[i].label = "";
    b[i].setAttribute("style","list-style-image:url('http://assets.tumblr.com/images/favicon.gif')");
  }
}
})();

bookmarklet_favicon.uc.jsで保存。

使い方

labelにボタンの名前を入れて、list-style-imageのところにfaviconのURLを入れる。上の"addLDR"の例ではdataスキームを使って画像を埋め込んでいる。

画像データのdataスキーム化は The data: URI kitchen などを使う。



追記

ofkさんのページをそのままに、「livedoor Readerに登録」と「tumblr」のインポート用HTMLを作ってみた。

<!DOCTYPE NETSCAPE-Bookmark-file-1>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
<DL>
<DT><A HREF="javascript:location.href='http://reader.livedoor.com/subscribe/'+location.href" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABnRSTlMA3ADcANwpVcdiAAAA9UlEQVR4nGO8c%2BeO2xJlBuLArpi7jIq1%2F4lUDQEs%2F%2F%2BSpB6m4UEHuoRCBXYNTAy%2FGRh%2BM3DKOUL4jIyMEPaDDgaIFBpi%2BfeHgYGBQTRwP0SDbB7CSxApDCehiiJz%2FxOj4fFUKIND2lHEZz8WP%2Fz%2FwwBBUHVSUM8Ie%2ByHSyEjdA1CrvvZJR0ZGBiezkUoejoXwcXiByGn%2FVj9AOWKh%2F0XD%2FuPDMTD%2FrOJOfzHAaDByibmCDdJwHY%2Fv81%2BiMivV%2Bj%2BZhT1xZeWXm9mZGBg%2BP%2F%2FPwMDAyMjIwPBtCTi9R%2BNzXRi0t3%2FfxnwI0ZGRkZGxv9%2FGU5MugsAfNu0706eS60AAAAASUVORK5CYII%3D">LDR登録</A>
<DT><A HREF="javascript:var%20d=document,w=window,e=w.getSelection,k=d.getSelection,x=d.selection,s=(e?e():(k)?k():(x?x.createRange().text:0)),f='http://www.tumblr.com/share',l=d.location,e=encodeURIComponent,p='?v=3&u='+e(l.href)%20+'&t='+e(d.title)%20+'&s='+e(s),u=f+p;try{if(!/^(.*\.)?tumblr[^.]*$/.test(l.host))throw(0);tstbklt();}catch(z){a%20=function(){if(!w.open(u,'t','toolbar=0,resizable=0,status=1,width=450,height=430'))l.href=u;};if(/Firefox/.test(navigator.userAgent))setTimeout(a,0);else%20a();}void(0)" ICON="data:image/gif;base64,R0lGODlhEAAQAOZuAD9cdyA3TT5bdkBdeCA3Tj1adTZSbCI6VEFeeUtphDhVb0VjfiM7UjdTbiE4T0dlgEhmgjxYc0lnglZfajRQazlVcENgezpWcbrAxzxZdDtYcyM6UT5adSQ7UkRhfDNPaUhlgUJgezlWcDdUbsDJ1FBpgSI5UCE5UL3EzlZtgz1ZdOHh5UFfepadpt%2Fi6Ofo7cDI0is8TVljbjtXcj9JVi8%2FUTZSbbS6w3CHnTdTbThUbkVifTpXckdlgUlmgkdkgEpngzZTbSs6Sr%2FI0TpXcV9wgkZkf2V6j0JfejRJXjNMYzhPZUBbdDtYckFbc46hsuHm7D1YcWZ%2FlkRifUZkgCI6UUpogzVJXrvEzkhmgThUb4WZrOHl7EVifqu0v72%2Fxba9xipDYENhfEZjf0lngyg0QkpohDRQajVRax82TUtphd%2Ff4%2Bvu8yg%2FWP%2F%2F%2FwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAG4ALAAAAAAQABAAAAfYgG5tg4SFhYIHZooJao2OjWEdbT4SZJZQbE6KZoxqkg8PPSBbbGxllZZAVgxtCwtjT1ylMjhSIFkQEKxiHh6lv2wwTEZUPxttCCxIQy6lGBgtNVM7XccAAANRKKVlSVdLIRYWVW0FBRwCJGwvZdgDAwgIJm1NGhERWCtrZecC%2FgAn2lQQceECmDVrJmg4UiJDBhUO2jQYoUOLF4QYixDhMSOigY82UtzA%2BIWGAgUVCLQ5QwGNSyUxJpQpIyRIjgYqD3z4cKZnz5Yu0Rwg4CaN0aNIAygN4CYQADs%3D">tumblr</A>
</DL>

使い方

  1. favicon.shtml←これを保存。*1ブックマークの管理 - HTMLからインポート。
  2. ブックマークのどこかに追加されるので、それをブックマークツールバーD&D。プロパティで名前を消す。

後からプロパティでボタンのアドレスを替えるとfaviconは無効になるので注意。
htmlを開いてリンクをD&Dfaviconもセットで追加されるかやってみたけどキャッシュが表示されたりうまくいかなかった。インポートが確実。


追記2
このブックマークレットを引き継ぐときは、Firefoxの「履歴とブックマークの管理」で「バックアップ」ではなく「HTMLとしてエクスポート」を使って引越しファイルをつくる。理由は「バックアップ」をして生成されるJSONファイルにはICON情報が無い。
結局何度も試行錯誤する羽目になってuserChrome.cssでやったほうがいい気がしてくる。


追記3

結論

userChrome.cssでやるべき。

#bookmarksBarContent > [label="pandora"]{
	list-style-image: url("http://www.pandora.tv/favicon.ico") !important;
}
#bookmarksBarContent > [label="pandora"] > .toolbarbutton-text {
	display: none !important;
}

/* ブックマークツールバーのボタンやアイコンの空白をなくす */
#bookmarksBarContent,
#bookmarksBarContent toolbarbutton,
#bookmarksBarContent .toolbarbutton-icon{
	margin: 0 !important;
}

*1:shtmlになっているのは気にしない。広告が付かないようにするため。