結婚写真を撮影できるスタジオ検索サイト「Photorait」担当エンジニアの武田(@takedajs)です。
先日、自分が担当しているPhotoraitでスタジオを探し実際に結婚写真を撮影してきました。自分が携わってるサービスをユーザとして使うのは、感慨深いですね!一つ夢が叶いました涙
さて本題です。
最近Firefoxの大きなバージョンアップ(Firefox Quantum)があり、ページ読み込み速度の大幅な改善などありましたが、その一方で最新の開発手法(以下、WebExtensions)ではないFirefoxアドオンが利用できなくなりました。僕の場合、利用していたFirefoxアドオンが全て利用不可に。。。マジか。。。
そこで今回は、最新のFirefoxでも利用できる、作業ミスを減らすFirefoxアドオンを開発し公開しましたので紹介します!ターゲットユーザが少ないと思うので、かなりニッチなアドオンです笑
開発したアドオン
開発したFirefoxアドオン「TabColor」は、指定したキーワードが表示したページのURLに入ってる時、ブラウザのタブ全体を赤くするシンプルなアドオンです。
TabColor – Firefox 向けアドオン: https://addons.mozilla.org/ja/firefox/addon/tabcolor/
例えば、キーワードに「wikipedia」と入力します。
表示しているURLに「wikipedia」があると、正規表現でマッチさせ、このようにタブ全体を赤くします。
開発した理由
本番環境であることに気づかずに、間違えて作業してしまうミスをなくすためです。
Photoraitではユーザが撮影スタジオに資料請求や来店予約を行いたい時、サイト上のフォームから申込を行うことができます。申込される度に、該当の撮影スタジオ宛にメールが送られます。
フォームはユーザビリティ向上のために改修や機能追加をすることも多く、開発する度に正しく申込ができるかどうか開発環境でテストをしています。
もし、この時のテストを何かの間違いで開発環境ではなく本番環境で行ってしまった場合、撮影スタジオにテストで入力した情報(XSSテスト用の文字など)が送られてしまい、サイト運営の信頼に関わってきます。
以下に開発環境と本番環境のフォーム画面を並べてみました。URL以外に大きな違いがなく、開発環境かどうか一瞬で判断することができず、ミスが起きる可能性がありました。
左: 開発環境 右: 本番環境
(画像はセキュリティ的にURLが書いてあるアドレスバーを表示させていませんが、このときタブは赤く表示されていません。)
このような時に、TabColorを利用して本番環境だけ赤くすれば、本番環境でないことを一瞬で判断できるのでミスを限りなく0にできます。
実際に僕は、「タブ全体が赤くなる = 本番環境」とするように、以下のページが赤くなるキーワードをTabColorに登録しています。
・本番環境の公開サイトページ
・本番環境の管理画面ページ
・本番環境のphpMyAdmin
phpMyAdminは開発環境と本番環境でサイト自体のデザインを変えていますが、念のためタブ全体が赤くなるようにしています。
中身の説明
大まかにですが実装部分について説明していきます。WebExtensionsでは、様々な機能をもったJavaScript APIが提供されており、TabColorでも以下の2つのAPIを主に利用してます。
・storage API – キーワードを保存時に利用
・theme API – タブ全体を赤くする時に利用
ファイル構成
以下アドオンのファイル構成です。
% tree . ├── background.js /* タブを赤くする処理 */ ├── icons │ ├── tab_color_30.png │ └── tab_color_60.png ├── manifest.json ├── popup /* キーワード入力フォーム関連 */ │ ├── keyword_save.css │ ├── keyword_save.html │ └── keyword_save.js /* キーワード登録処理 */ └── tab_red.jpg
takedajs/TabColor: https://github.com/takedajs/TabColor
キーワード登録処理
keyword_save.jsでは、キーワードの登録処理を行っています。
・storageに保存されているキーワードがある場合、キーワードをvalueに設定してフォームを作成しています。
・フォームの保存ボタンが押下された時、storage内のキーワードを全て削除し、フォームに入力されているキーワードをstorageに保存しています。
keyword_save.js
//キーワードを登録するためのフォームを作成 var storage_keywords = []; browser.storage.local.get('value', function(items) { storage_keywords = items.value; }); window.setTimeout( function(){ // キーワード登録フォーム作成 for (var i=0; i < 10; i++) { var input = document.createElement("input"); input.setAttribute("type","text"); input.setAttribute("class","text"); // 登録されている要素がある場合 if (storage_keywords != undefined) { input.setAttribute("value", storage_keywords[i]); } document.getElementById("keywords").appendChild(input); } }, 300 ); // キーワードをストレージに保存 document.addEventListener("click", function(e) { if (e.target.classList.contains("save")) { // ストレージ内のデータを削除 browser.storage.local.remove("value"); var keywords = document.getElementsByClassName("text"); var array_keywords = []; for (var i = 0; i < keywords.length; i++) { array_keywords.push(keywords[i].value); } browser.storage.local.set({'value': array_keywords}, function() {}); browser.tabs.reload(); alert("Completion of registration"); } });
タブを赤くする処理
この処理の実装は試行錯誤しました。
試行錯誤①
当初TabColorは、WebExtensionsではなく古い開発手法であるAdd-on SDKを利用して開発しました。タブ全体を赤くする現在とは違い、該当するページのタブだけを赤くしていました。
これはXPCOMという仕組みを利用し、Firefoxのデザインを変更できるユーザのローカルファイルであるuserchrome.cssを上書くことで表現していました。ですが、WebExtensionsではXPCOMが利用不可になり、指定のタブだけ赤くすることを断念することに。
試行錯誤②
WebExtensionsで開発し直した当初は、以下のようにタブではなくサイトの左側を赤くする表現方法をとっていました。
Javascriptでbodyタグに以下のstyleを追加や削除するだけなので簡単に実装できます。
border-left: solid 15px red;
社内LT会でこの時のTabColorを紹介したのですが、「サイトのレイアウトが崩れるから使わない笑」との温かい声を多数頂いたので、「簡単な実装に逃げず、何とかしてタブを赤くしよう!!」とその日は枕を濡らしながら決意したのを今でも覚えています。
完成版
ローカルファイルのuserchrome.cssは上書けないので、代替案はないかと提供されているJavaScript API一覧を眺めたり、既に公開されているFirefoxで同様の実装をしているものはないか調査しました。その結果、テーマとして赤い背景を設定することで実装が可能であると分かりました。
テーマとは、ブラウザーのデザインを変えられるあのテーマです。
theme API を利用することで、自分が作成した画像をテーマとしてブラウザに設定できます。以下の赤い横長画像を設定することで、タブの背景だけ赤くなっているようにごまかしています。画像の高さは、タブの高さを何度も測って同じ高さになるように良い感じに設定しています。ちなみに、高さ32px x 幅2500px が良い感じでした。
background.jsでは、キーワードにマッチしたURLのページがアクティブになった時、先程説明した赤い横長画像をテーマとして設定しています。マッチしないURLのページがアクティブになった時は、テーマを削除しています。
background.js
// タブを赤く見せるテーマ const themes = { images: { headerURL: '../tab_red.jpg', }, colors: { accentcolor: '#F9F8F8', textcolor: 'black', } }; // タブが更新された時 browser.tabs.onUpdated.addListener((id, changeInfo, tab) => { url_match(tab); }); // タブがアクティブになった時 browser.tabs.onActivated.addListener((activeInfo) => { var active_tab = browser.tabs.get(activeInfo.tabId); active_tab.then((tab) => { url_match(tab); }) }); // テーマ設定、削除処理 function url_match(tab) { var storage_keywords = []; browser.storage.local.get('value', function(items) { storage_keywords = items.value; }); window.setTimeout( function(){ // 現在見ているページが、登録したキーワードに一致するか確認 var isMatch = false; for (var i = 0; i < storage_keywords.length; i++) { if (storage_keywords[i]) { var regexp = new RegExp(storage_keywords[i], 'i'); isMatch = regexp.test(tab.url); if (isMatch) { break; } } } if (isMatch) { browser.theme.update(themes); } else { browser.theme.reset(); } }, 300 ); }
まとめ
作業ミスを減らすために開発したFirefoxアドオン「TabColor」の紹介をしました。
本番環境の時だけタブの色が赤くなることで、一瞬で開発環境と本番環境の区別をつけることができます。
TabColorが初めてのFirefoxアドオン開発だったのですが、公式サイトが充実しているのと豊富なAPI提供のおかげで、想像していたより簡単にアドオンを作ることができました。
WebExtensionsで開発したFirefoxアドオンはChromeの機能拡張とも互換性があるみたいなので、次はChrome版のTabColorを作成してみたいと思います。社内の人達はほとんどChromeユーザなので、Chrome版開発したらみんな使ってくれると良いなー笑
Wedding Parkでは一緒に技術のウエディングパークを創っていくエンジニアを募集しています。
興味のある方はぜひ一度気軽にオフィスに遊びにきてください。
ブライダル業界のデジタルシフトを加速させるリードエンジニア候補募集!
参考
WebExtensions – Mozilla | MDN
https://developer.mozilla.org/ja/Add-ons/WebExtensions