2019-01-23T18:07:46Z

Firefox userChrome.js用ユーザスクリプトを作成する

Firefoxを使いやすくするため、タブのタイトルとURLをコピーしたかったけど、できなかったので自作してみた。

userChrome.jsとは

userChrome.jsはFirefoxのブラウザに対するユーザスクリプを実行する方法です。

Firefoxの拡張機能(WebExtensions)と同様にブラウザを制御できます。ですが、userChrome.jsは拡張機能よりも制約がゆるく細やかな制御が可能です。逆に言えば、拡張機能よりも危険です。

userChrome.jsの導入方法

下記Wikiのスクリプト導入法を参照してください。

※userChrome.jsは、正式な機能ではないため、バージョン毎に導入方法が変化しています。また、今後userChrome.jsが廃止される可能性があります。

コードを書くために

userChrome.jsのドキュメントは、特に存在しません(筆者は見つけられませんでした)。そのため、他人の書いた動作するソースコードを元に、求める機能を実現する必要があります。

また、Firefoxのバージョンによって動作しないコードもあります。バージョンアップ後動作しなくなる場合、動作に必要な機能がなくなっていたり、名称が変更していたりします。userChrome.jsそのものが、動作していなくなっていることもあります。

覚書(全般)

userChrome.jsを探す

ユーザスクリプトの設定

ファイルの先頭にユーザスクリプトの設定を記述する。

// ==UserScript==
// @name        スクリプト名.uc.js
// @description 機能の概要
// @version            1.0.0
// @include            main
// @charset            UTF-8
// ==/UserScript==

※日本語を使用する場合、charsetで文字コードを指定することで、文字コード問題の大半を回避できます。

ログ出力する

// 「console.logを表示する」参照
console.log('Hello World');

// アラーム
alert('Hello World');

console.logを表示する

ブラウザーツールボックスで確認する

  1. ブラウザーツールボックスを有効化する
    • [F12] > […] > [設定] > [詳細設定]
      • 「ブラウザーとアドオンのデバッグを有効化」をチェックする
      • 「リモートデバッガーを有効化」をチェックする
  2. ブラウザーツールボックスを開く
    • Ctrl + Alt + Shift + i
    • 「接続しますか?」を「OK」する
  3. コンソールタブを表示する
    • console.log出力が表示される
    • ただし、Firefoxの各種出力も表示される

覚書(アクション系)

コンテキストメニューを追加する

var menuItem = document.createElement("menuitem");
menuItem.setAttribute("id", "context-menu-item-id");
menuItem.setAttribute("label", "追加したメニューラベル");
menuItem.addEventListener('command', function() {
  console.log('追加したメニューラベルを選択しました。');
  alert('追加したメニューラベルを選択しました');
});
var contextMenu = document.getElementById("contentAreaContextMenu");
contextMenu.appendChild(menuItem, contextMenu.firstChild);

タブコンテキストメニューの末尾追加する

// 「コンテキストメニューを追加する」参照
var tabContextMenu = document.getElementById("tabContextMenu");
//var contextMenu = document.getElementById("contentAreaContextMenu");
tabContextMenu.appendChild(menuItem, tabContextMenu.firstChild);

タブコンテキストメニューに先頭追加する

// 「コンテキストメニューを追加する」参照
var tabContextMenu = document.getElementById("tabContextMenu");
tabContextMenu.insertBefore(menuItem, tabContextMenu.firstChild);

タブコンテキストメニューにセパレータを追加する

var menusSparator = document.createElement("menuseparator");
var tabContextMenu = document.getElementById("tabContextMenu");
tabContextMenu.appendChild(menusSparator, tabContextMenu.firstChild);

ツールチップを配置する

function createElement(tag, attrs) {
  const e = document.createElement(tag);
  if (attrs)
    Object.keys(attrs).forEach(key => e.setAttribute(key, attrs[key]));
  return e;
}
function onClick(event) {
  console.log('ツールチップをクリックしました。');
  alert('ツールチップをクリックしました。');
}

try {
  var idname = 'id-name'
  CustomizableUI.createWidget({
    id: idname,
    type: 'custom',
    defaultArea: CustomizableUI.AREA_NAVBAR,  // ナビゲーション
//  defaultArea: CustomizableUI.AREA_TABSTRIP,// タブステップ
    onBuild: function(doc) {
      const props = {
        id: idname,
        class: 'toolbarbutton-1 chromeclass-toolbar-additional',
        label: 'ラベル',
        tooltiptext: 'ツールチップテキスト',
        image: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIj4KICAgIDxwYXRoIHN0cm9rZS13aWR0aD0iMjQiIGZpbGw9IiM1NTU1NTUiIHN0cm9rZT0iI2ZmZmZmZiIgZD0iTSA2IDQ4MCBsIDUwMCAwIGwgMCAtNjAgbCAtNTAgMCBsIDAgLTIyMCBsIC00MDAgMCBsIDAgMjIwIGwgLTUwIDAgeiIvPgogICAgPHBhdGggc3Ryb2tlLXdpZHRoPSIzMCIgZmlsbD0iIzQ0ODhmZiIgc3Ryb2tlPSIjZGRlZWZmIiBkPSJNIDI3MiAzMiBsIC0xNjAgMTMwIGwgMTYwIDEzMCBsIDAgLTc1IGwgNjAgMCBhIDYwIDYwIDAgMCAxIDAgMTIwIGwgLTIwIDAgbCAwIDExMCBsIDIwIDAgYSAxNzAgMTcwIDAgMCAwIDAgLTM0MCBsIC02MCAwIHoiLz4KPC9zdmc+'
        // BASE64で画像を埋め込み
      };
      let tooltipbtn = createElement('toolbarbutton', props);
      tooltipbtn.onclick = onClick;
      return tooltipbtn;
    }
  });
} catch (e) {}

覚書(イベント系)

簡易なイベント

マウスジェスチャ用ですが動作します。簡易の「戻る」「進む」などがあります。

新しいタブを開く

var url = 'https://www.yahoo.co.jp/';
gBrowser.addTrustedTab(url);

新しいタブを選択する(アクティブにする)

var url = 'https://www.yahoo.co.jp/';
gBrowser.selectedTab = gBrowser.addTrustedTab(url);

クリップボードにコピー

var text = 'Hello World';
var clipboard = Cc['@mozilla.org/widget/clipboardhelper;1'].getService(Ci.nsIClipboardHelper);
clipboard.copyString(text);

サンプル

作るもの

下記の機能を実現します。

  • タブコンテキストメニューからタイトルのコピー
  • タブコンテキストメニューからURLのコピー

タブメニュー

ソースコード

// ==UserScript==
// @name          CopyTabTitleUrl.uc.js
// @description   タブコンテキストメニューから選択しているタブのタイトルとURLをコピーする
// @include       main
// @charset       UTF-8
// @author        toshi(https://www.bugbugnow.net/)
// @license       MIT License
// @version       2
// @see           1 - 初版
// @see           2 - 「CopyTabTitleAndURL.uc.js」から名称変更
// ==/UserScript==

(function () {
  // タブのタイトルをコピー
  var mt = document.createElement("menuitem");
  mt.setAttribute("id", "context-copytab-title");
  mt.setAttribute("label", "タブのタイトルをコピー");
  mt.addEventListener('command', function() {
    var title = TabContextMenu.contextTab.linkedBrowser.contentTitle;
    var clipboard = Cc['@mozilla.org/widget/clipboardhelper;1']
                      .getService(Ci.nsIClipboardHelper);
    clipboard.copyString(title);
  });

  // タブのURLをコピー
  var mi = document.createElement("menuitem");
  mi.setAttribute("id", "context-copytab-url");
  mi.setAttribute("label", "タブのURLをコピー");
  mi.addEventListener('command', function() {
      var url = TabContextMenu.contextTab.linkedBrowser.currentURI.spec;
      var clipboard = Cc['@mozilla.org/widget/clipboardhelper;1']
                        .getService(Ci.nsIClipboardHelper);
      clipboard.copyString(url);
  });

  // セパレータ
  var ms = document.createElement("menuseparator");
  ms.setAttribute('id', 'context-copytab-sep');

  // メニューバーの最上部に要素を追加
  // タブのタイトルをコピー
  // タブのURLをコピー
  // セパレータ
  var tabContextMenu = document.getElementById("tabContextMenu");
  tabContextMenu.insertBefore(ms, tabContextMenu.firstChild);
  tabContextMenu.insertBefore(mi, tabContextMenu.firstChild);
  tabContextMenu.insertBefore(mt, tabContextMenu.firstChild);
}());

※プロファイルフォルダ内のchromeフォルダにCopyTabTitleUrl.uc.jsの名称で保存する

関連記事

  1. Firefox userChrome.js用ユーザスクリプトを作成する
  2. Firefox用WebExtensions拡張機能を作成する
  3. Chromeの拡張機能を作成する
  4. Firefox用WebExtensions拡張機能を国際化する
  5. Chrome、Firefox、Edgeの拡張機能を判定する
  6. Chrome、Firefox拡張機能のブラウザアクションでポップアップあり・なしを共存する
  7. Chrome、Firefoxの拡張機能にショートカットを実装
 コメントを書く