Chrome/Edge拡張機能を作ってブログ記事のHTMLをチェックする

目次

背景

自分はプログラミング言語に関しては、基礎をある程度理解してから、使うときに使う部分だけ勉強するとうスタイルです。
知識の断片をつなぎ合わせてちゃんとプログラムを動作させられても必ずbest practiceとは限りません。
最近ブログの記事を書くにはHTMLをよく扱うようになって、Google Adsenseに申請するためにいろいろ調べたら、HTMLは意外と奥深いことが分かりました。
例えば<img>タグのalt属性、なくてもブラウザーが許してくれても検索インデックス作りに支障が出るとか、様々なルール・規範があります。
完璧さを追求しないとしても、分かる範囲で極力正しいコードを書こう!という自覚はありますが、人間はミスする動物ですので、ルールを守っているつもりでも忘れたりします。 あとでいちいちチェックするのも面倒ですし、すべてのミスを発見できるとも保証できません。

人間のしたくないことはコンピューターにさせよう!

ということで、ブログの記事のHTMLルールをチェックするブラウザー(Edge/Chrome)拡張機能を作成しました。
そのステップをここにメモしておきます。

何をなぜチェックするのか

<img>タグのalt(代替テキスト)属性が設置されているか

  • 重要度★★★★★
  • 理由
    • 検索エンジンにやさしい:
      画像だけなら、検索エンジンはどのような画像かを理解することができず、alt(代替テキスト)があれば、画像の内容や意味を理解することができる。
    • ページの閲覧者にやさしい:
      ネットの接続等の原因で、画像が表示されないときは代替テキストが表示されるので、閲覧者は画像を見られなくても文字である程度作者の意図をつかめる。
    • ページの作成者にやさしい:
      HTMLでページを編集するときに画像のプレビューがない場合は、altを事前に設定しておけば、後でもどのリンクがどの写真かが分かる。

つまりalt属性をつけることは三方よしであり、使わない理由がありません。
さらに、alt属性のない画像が記事にあると、Google Adsenseの審査に通りにくいという説があります。
本ブログもAdsenseに申請したときは「作成中のサイト」という理由で審査に通過できませんでしたが、alt属性を修正したところで通過できました。
運かもしれませんが、alt属性が原因だった可能性は十分あります。

<img>タグのtitle属性を設置しているか

  • 重要度★★★
  • 理由
    titleタグはaltタグほど重要ではなく、オプションのようですが、付けるとマウスを画像のうえに置いたとき(hover)にtitleの文字が表示されますので、便利です。
    やはり画像があると、これは何の画像なのかタイトルを付けるのが自然なことで、習慣として使っていきたいと思います。

<a> (Anchor アンカー)のtarget属性が_blankになっているか

  • 重要度★★★★
  • 理由
    target属性を_blankに設定すると、閲覧者がリンクをクリックしたときに、リンクが新しいTab或いはWindowで開かれます。
    逆に設定していないと、リンクが今のページで開かれてしまいます。
    どっちがいいかはある程度好みの問題ではあると思いますが、もし記事を読んでいる途中、リンクをクリックして別のページに飛んで、また今のページに戻りたいときは、戻りのボタンを押したりする必要があります。自分の場合は面倒に感じます。 さらにTabをたくさん開いているときが多くて、どのTabの戻りボタンを押したら戻れるのか、分からなくなったり、そのTabを間違えて閉じてしまったりすることがよくあるから、閲覧者の不必要な操作を減らすために、やはり新しいTabでリンクを開くのが良いのではないかと思います。

拡張機能の完成イメージ

拡張機能が有効の状態で、ブログの記事を開きます。
もし上記定義の問題点があれば、レポートを表示のうえ、記事ページで問題点を表示します。

エラーの表示方法

  • altを設置していない<img>:画像の枠線が赤いドットになる。
  • titleを設置していない<img>:画像が斜めになる。
  • target="_blank"になっていない<a>:リンクのの周りが赤いドットになる。

チェックレポートのイメージ

拡張機能によるページHTMLのチェックレポート


チェック前後のページ比較

拡張機能によるページHTMLのチェック前後比較


作る前にまず一般的な拡張機能の構成を理解しよう

拡張機能は一般的に以下のパーツの一部或いは全部で成り立っています。

1. manifest.json(必須)

拡張機能についての基本情報等を宣言するファイルです。
例えば、拡張機能の名前、バージョン、説明、アクセス権限、アイコン、含まれるスクリプト、どのURLを開けばどのスクリプトをinjectする等、拡張機能に関する情報や行動パターンを宣言します。

2. backgroundスクリプト(オプション)

一般的にbackground.jsというファイル名ですが、manifest.jsonで定義できます。
このスクリプトは特定なURLに依存せずに、拡張機能にとってグローバル的な存在です。
各ページのスクリプトと通信することでHub的な役割で活躍します。

3. Content Script(オプション)

ユーザーがある特定なページを開いたときに、そのページにContent Scriptを挿入(inject)することができます。
Content Scriptはそのページに既にあった他のスクリプトと互いにアクセスできませんが、DOMへのアクセスが可能です。
それによってページの情報を取得したり、ページの表示を変更したりすることができます。

4. Popup(オプション)

一般的にpopup.htmlとpopup.jsですが、名前はmanifest.jsonで定義可能です。
popupはブラウザーのツールバーにある拡張機能のアイコンをクリックしたときに表示され、開発者が定義した内容を表示したり、ユーザーからの入力を受け付けたりすることができます。

ブログ記事をチェックする拡張機能を作る

今回の拡張機能の構成

今回の拡張機能はできるだけシンプルにしたく、
manifest.jsonContent Scriptだけにしています。
エディターはVisual Studio Codeを使います。

  • フォルダー構成(./extは拡張機能のルートフォルダー):
│ tsconfig.json #TypeScript構成ファイル │ ├─ext │ │ manifest.json │ │ │ ├─js │ │ BloggerPageChecker.js #tscによる出力 │ │ tsconfig.tsbuildinfo #tscによる出力 │ │ │ └─res │ icon.png │ └─ts BloggerPageChecker.ts #Content Script
  • tsconfig.json(TypeScriptの設定ファイル)
{//outDirとinclude以外はデフォルトでOK "compilerOptions": { "incremental": true, "target": "ES2019", "module": "none", "outDir": "./ext/js", "strict": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true "include": [ "./ts/**/*" ] } }

manifest.json

{ "name": "Blogger Page Checker", "version": "1.0.0", "description": "ブログ記事をチェックするツールです。", "permissions": [], "host_permissions": [ "https://chishiki21.blogspot.com/*" //自分のブログへのアクセスを許可する ], "content_scripts": [ {//ブログのページを開くとBloggerPageChecker.jsを挿入し実行する "matches": [ "https://chishiki21.blogspot.com/*" ], "run_at":"document_start", "js": [ "./js/BloggerPageChecker.js" ] } ], "action": { "default_icon": "./res/icon.png" }, //拡張機能はVer 3にする、ChromeのVer 2サポートは2023/1で終了の予定 "manifest_version": 3 }

Content Script: BloggerPageChecker.ts

document.addEventListener("DOMContentLoaded", () => { //DOMがブラウザーにロードされてから実行、 //これがないとまだ存在しないエレメントにアクセスしようとしてしまう //ホスト名 let blogHostName = "chishiki21.blogspot.com"; if(document.URL=="https://"+blogHostName+"/"){ //Homeページなら何もしない return; } //debug用 console.log("content script loaded!"); //エラーチェックするターゲット=記事の本文部分,DevToolsで特定 let divPost = document.querySelector("div.post-body[id^='post-body-']") as HTMLDivElement; //各エラーを数える準備 let countANoTarget = 0; let countImgNoAlt = 0; let countImgNoTitle = 0; //<a>リンクを逐一チェック divPost.querySelectorAll("a").forEach((anchor: HTMLAnchorElement) => { if (anchor.childElementCount == 0&& !anchor.href.includes(document.URL) ) { //普通のテキストリンクだけが対象、ページ内リンクは対象外 if (anchor.target != "_blank") { //_blankが指定されていない場合は記録する countANoTarget++; SetElementBorder(anchor);//周りに赤いドット } } }); //<img>を逐一チェックしていく divPost.querySelectorAll("img").forEach((img: HTMLImageElement) => { if (img.alt == "") { //alt属性がついていない場合は記録する countImgNoAlt++; SetElementBorder(img);//周りに赤いドット } if (img.title == "") { //title属性がない場合は記録する countImgNoTitle++; img.style.transform = "rotate(5deg)";//画像を斜めにする } }); let countTotal = countANoTarget + countImgNoAlt + countImgNoTitle; if (countTotal > 0) { //エラーが1個でも発生すれば通知する let report = countTotal.toString() + "件のエラーが見つかりました:\n" + (countANoTarget > 0 ? "_blankのないリンク:" + countANoTarget.toString() + "件(赤いドット)\n" : "") + (countImgNoAlt > 0 ? "altなし画像:" + countImgNoAlt.toString() + "件(赤いドット)\n" : "") + (countImgNoTitle > 0 ? "titleなし画像:" + countImgNoTitle.toString() + "件(斜め)\n" : ""); alert(report); }else{ //エラーがない場合は通知しないが、Consoleに表示させる console.log("BloggerPageChecker.js: No error found!"); } }); //HTMLElementの周りに赤いドットを付けるメソッド function SetElementBorder(element: HTMLElement) { element.style.borderStyle = "dotted"; element.style.borderWidth = "5px"; element.style.borderColor = "red"; }

tscでコンパイルしてブラウザーで開く

  • tscコマンドでTypeScript(.ts)をJavaScript(.js)にコンパイルします。
  • ブラウザー(Chrome/Edge)のメニューバー→拡張機能を開きます。
  • 拡張機能管理画面でDeveloper ModeをOnにします。
  • Load Unpackedボタンで .\extフォルダーをロードします。
  • ブラウザーのツールバーに拡張機能のアイコンがロードされれば完了

その他の参考情報

TypeScriptを使う場合は@types/chromeを使うと便利

今回はchromeのAPIを使っていないため、@types/chromeをインストールしていませんが、入れておくとコーティングの際に自動完成機能が使えて非常に便利です。

npm install @types/chrome --save-dev

今から作る拡張機能はManifest V3で作りましょう

ChromeでのManifest V2拡張機能の使用は2023年1月で終了します。
(企業は2023/6まで)
意外とすぐですね、今から作る拡張機能は間違いなくManifest V3を選ぶべきです。
GoogleはV3への移行ガイドを出しています。リンクはこちらです。

ブラウザのDevToolsを活用しましょう

ChromeやEdgeでは、キーボードのF12を押したときにDevToolsを開くことができます。
DevToolsでDOMエレメントのpathを調べたり、属性等を変えてみたり、jsのコードを試したりすることができます。
DevToolsでいろいろ試してから実際に実装したほうが効率よいと言えます。
拡張機能を作るにはDevToolsはとても便利で必須です。

後書き

以上、Content Script1つだけのシンプルな拡張機能でした。
拡張機能はブラウザーが作ってくれたひとつのインターフェースです。自分のニーズに合わせてブラウザーを好きなようにカスタマイズすることができます。
今後の必要性に応じて、チェックする項目を増やしたり、表示方法を変えたり、少しずつ改良していきたいと思います。

コメント

このブログの人気の投稿

C# WebView2.ExecuteScriptAsync()のいくつかの使い方とDebug方法

C# 外部ライブラリを使わずに半角→全角カタカナ変換

C# WebView2を通じてWebサーバーなしでJavaScriptからローカルファイルを読み書き