こんにちは、虎の穴ラボのH.Kです。
虎の穴ラボ Advent Calendar 2020 - Qiita 11日目の記事になります。
10日目は山田さんがコンテナイメージの脆弱性診断ツール Trivyの記事を書いているので、読んでみてください。
toranoana-lab.hatenablog.com
12日目はY.FさんのGraphQLのN+1問題についての記事です。
先日、JavaのAPIリファレンス(https://docs.oracle.com/javase/jp/14/docs/api/)の「日本語<-->英語」と「各バージョン」を簡単に移動できるChrome拡張機能作って公開しました。
そこで今回は、Chrome拡張の公開方法と上記拡張機能の実装についてを紹介したいと思います。
作るきっかけとしては以下のツイートからです。
chromeプラグインとして、(open)JDKのjavadocのJDKバージョンや言語を変更できるプラグインないかな
— 翳川翔 ヲタク/プログラム言語 学生;趣味プログラマ niconico/GINZA→(Re) (@kakerigawa) 2020年11月14日
jdk7とか6のが引っかかった際にjdk8とか11とかに飛びたいこととかen_USを見たいことあるけどURLを単純にいじるだけだとうまく行かないバージョンのペアがあるからプラグインがほしい
🔻ちなみに作った拡張機能はこちら!🔻 chrome.google.com
🔻使用イメージ🔻
🔻Githubリポジトリ🔻
github.com
Chrome拡張の作成方法については、以下の記事をご覧ください。
【目次】
Chrome拡張の一般公開手順
以下の手順で一般公開することができます。
- Googleのアカウント作成
- GoogleアカウントのDeveloper登録(要クレジットカード&5ドル)
- 作った拡張の申請
- Googleによる審査
- 公開
本記事ではGoogleのアカウント作成については割愛します。
GoogleアカウントのDeveloper登録
以下のリンクから開発者登録ができます。
なお、2020/12/4時点でクレジットカードで5ドルの支払いが必要です。
https://chrome.google.com/u/0/webstore/devconsole/register
規約とポリシーを確認後、登録料の支払いのリンクを押下します。
クレジットカード情報などの必要情報を入力していけば、最終的に5ドルの支払いとなり、Developer登録が完了します。
ちなみに、2020/11/25のレートですと、日本円で533円でした。(レートはカード会社等によります。)
アカウントを登録したら、まずメールアドレスを登録しましょう。
メールアドレスはChrome拡張の公開の際に必要となるので、先に入れたほうが楽です。
以下のリンク(管理コンソール)より、アカウントに遷移し、必須項目を入力し、更新します。
https://chrome.google.com/webstore/devconsole
作った拡張の申請
次に作った拡張の公開申請をします。
利用者の情報を使用するような拡張だと、審査に時間がかかるようですが、見た目を変更するだけの拡張では1日~2日程度で公開されることが多いようです。
注意点として修正して再公開する場合は、審査ももう一度必要になるので、できる限り完璧な状態で申請をしたほうが良いです。
作った拡張機能をZIPに固める
フォルダ直下にmanifest.json
を配置して、フォルダごとZIP形式で固めます。
manifest.json
でdeclarativeContent
などをpermissions
に追加していると、なぜその権限が必要か説明を求められます。
不要な権限は予め削除しておきましょう。
アイテムを登録する
先程の管理者コンソール(https://chrome.google.com/webstore/devconsole)から新しいアイテムを押下します。
表示されたポップアップに、ZIPをアップロードします。
アップロードするとmanifest.json
の内容からパッケージタイトルとパッケージ概要が表示されているはずです。
問題がある(Chrome拡張機能のフォーマットに則っていない)場合は、ここで失敗するので、manifest.json
を修正してやり直してください。
あとは必要事項を入力していきます。
プライバシーについても必須項目を入力していきます。
価格と販売 / 配布地域については、今回の目的は一般公開のため以下のように設定します。
ここまで入力が終わったら上部にある「下書きとして保存する」を押下します。
入力に問題がある場合、「下書きとして保存する」の右側に「公開できない理由」というボタンが表示されるので、そこに書かれた理由をもとに修正していきます。
修正が完了すると「審査のため送信」ボタンが活性化されるので、押下して進めていくと、審査の申請が完了します。
Googleによる審査
ここは基本的にお祈りするだけです。
果報は寝て待てと言いますが、審査完了の通知は来ないので、定期的に開発者コンソールから公開されているか確認する必要があります。
公開
審査のところでも書いた通り、通知は来ず、公開されます。
お疲れさまでした、おめでとうございます!!
実装について
実装に関してやっていることは少なく、大きくわけると以下の3点です。
- 現在のURLがAPIドキュメントか判定する
- 現在のURLから遷移するURLを作成する
- 遷移先のURLを別タブで開く
実装の全容はGitHubリポジトリを確認していただければと思います。
現在のURLがAPIドキュメントか判定する
manifest.json
のbackgroundに定義したscripts(今回はbackground.js
というファイル名)にて、現在のURLがAPIドキュメントのホストか判定する処理を実装しました。
chrome.runtime.onInstalled.addListener(function() { chrome.declarativeContent.onPageChanged.removeRules(undefined, function() { chrome.declarativeContent.onPageChanged.addRules([{ conditions: [new chrome.declarativeContent.PageStateMatcher({pageUrl: {hostEquals: 'docs.oracle.com'},}) ], actions: [new chrome.declarativeContent.ShowPageAction()] }]); }); });
上記で、docs.oracle.com
がホストの場合のみ拡張機能が有効になります。
現在のURLから遷移するURLを作成する
まずJavaのAPIドキュメントのURLをjava.langString
クラスの日本語ページを例に取り見ていきましょう。
バージョン以外の差分を整理すると以下のようになります。
バージョン | docsパス | モジュールパス |
---|---|---|
6〜7 | なし | なし |
8〜9 | あり | なし |
10〜14 | あり | あり |
こうして整理するとモジュールシステムが導入されたタイミングはJava SE 9なのに、リファレンス側がそれに対応できたのはJava SE 11からといった点や、Java SE 7まではフレームありだとSPAのような動きをする点など、バージョン間の違いも少し面白いです。
上記の表をもとにURLを組み立てていくのですが、Java SE 8のドキュメントからJava SE 14のドキュメントに遷移する場合などのモジュールの逆引きが厄介でした。
ドキュメントを探したのですが、クラスとモジュールのマッピングが記載された資料を見つけることはできませんでした。
そのため、スクレイピングを行い、マッピングを自作することにしました。
GASを使ったスクレイピング
GASを使ったスクレイピングの実装は以下の記事を参考にしています。
function getMovieRanking() { var host = 'https://docs.oracle.com/javase/jp/14/docs/api/'; var topHtml = getPageHtml(host + 'index.html'); var tbodys = Parser.data(topHtml).from('<tbody>').to('</tbody>').iterate(); for(var i = tbodys.length-1; i >= 0; i--){ // java.base/module-summary.html">java.base var links = Parser.data(tbodys[i]).from('<a href="').to('</a>').iterate(); for(var j = 0; j<links.length; j++){ var targetModuleName = links[j].split(">")[1]; var modulePage = ''; try{ modulePage = getPageHtml(host + targetModuleName + '/module-summary.html'); }catch (error){ continue; } var modulePageTbodys = Parser.data(modulePage).from('<tbody>').to('</tbody>').iterate(); for(var k = 0; k<modulePageTbodys.length; k++){ var moduleLinks = Parser.data(modulePageTbodys[i]).from('<a href="').to('</a>').iterate(); for(var l = 0; l<moduleLinks.length; l++){ try{ var packagePath = moduleLinks[l].split(">")[1].split('.').join('/'); Utilities.sleep(500);// 負荷をかけすぎないようにする output(packagePath, targetModuleName); }catch (error){ continue; } } } } } } function getPageHtml(url){ return UrlFetchApp.fetch(url).getContentText('UTF-8'); } function output(packagePath, targetModuleName){ console.log(packagePath + ': "' + targetModuleName + '",'); }
これでjava/lang/String: "java.base"
のようなマッピングを作ることができました。
(少し不要なマッピングもできてしまいますが、手動で削除しました。)
遷移先のURLを別タブで開く
ここまでできれば遷移するのみです!
以下のようにして別タブで開くようにします。
chrome.tabs.create({ url: URLを作成するメソッド })
まとめ
この記事は12/4に書いているのですが、本日、Java SE 15の日本語ドキュメントが出たみたいです。
(対応しなきゃ……。)
今回初めて拡張機能を公開してみましたが、基本的に日本語でも問題なく、公開申請は非常に簡単にできるなと感じました。
また何かアイデアがあれば、新しい拡張機能を作ってみたいと思います。
P.S.
カジュアル面談
弊社エンジニアと1on1で話せます、カジュアル面談も現在受付中です!こちらも是非ご検討ください。
yumenosora.connpass.com
その他採用情報
虎の穴ラボでの開発に少しでも興味を持っていただけた方は、採用説明会やカジュアル面談という場でもっと深くお話しすることもできます。ぜひお気軽に申し込みいただければ幸いです。
カジュアル面談では虎の穴ラボのエンジニアが、開発プロセスの内容であったり、「今期何見ました?」といったオタクトークから業務の話まで何でもお応えします。
カジュアル面談や採用情報はこちらをご確認ください。
yumenosora.co.jp