MarkIt ハイライター
これは、Web ページ上の重要なテキストを強調表示できる Chrome 拡張機能のリンクです。 1 分後、1 週間後、または 1 年後にこのページに再度アクセスしてください。データは常にそこにあります。
テクノロジー
- (バニラ) JavaScript
- Google API
特徴
- 任意のテキストを強調表示し、Command+K を押して自動的に保存します。
- ユーザーは、Command+Shift+A という 1 つの簡単なコマンドで、任意の URL に保存されているハイライトをクリアできます。
- すべてのデバイス間で同期 - ラップトップでテキストをハイライト表示し、次に携帯電話で同じ Web ページを見ると、ハイライトがそこに表示されます (両方で Chrome にログインしている場合)。
私の保存されたデータ構造 (オブジェクト)
highlights = {
google.com: {
text1: ["query selector", index, note, color]
text2: ["query selector", index, note, color]
},
yahoo.com: {
text3: ["query selector", index, note, color],
text4: ["query selector", index, note, color]
},
https://developer.mozilla.org/en-US/docs/Web/API/document/execCommand: {
"When an HTML document has been switched to designMode, its document object exposes an execCommand": ["p.summary", 20],
"A DOMString specifying the name of the command to execute. See Commands for a list of possible commands.": ["p", 0, "example note", #CFFFDF]
}
}
仕組み
すべてのページにロードされる 2 つのスクリプトがあります。 1 つ目は、特定のイベントをリッスンする background.js です。イベント Command+K は、ブラウザーにスクリプトを挿入する関数 (injection_script.js) をトリガーし、選択したテキストを強調表示します。
ハイライトするには、マウスをテキストの上にドラッグし、Command+K キーを押します。これにより、他のいくつかの関数を呼び出す関数がトリガーされます。イベントの順序:
- 選択したテキストを取得します
- デザイン モードを「オン」にして、DOM に一時的な変更を加えられるようにします。
- 背景がすでにハイライトされている場合は、ハイライトを削除する必要があります。
- テキストを囲む <span> タグを選択し、style.backgroundColor = traditional (ハイライトを削除) を設定します。
- ストレージから「ハイライト」オブジェクトを取得します -
chrome.storage.get()
- すべてのキー (保存されたハイライト) をループして一致するキーを探し、ストレージから削除します。
- それ以外の場合は、テキストを <span> で囲み、背景色を適用します。
- ページ更新時: ストレージから「ハイライト」を取得します。
- アクティブな URL のデータがない場合は、キーを現在の URL に設定し、値を空のオブジェクト (aol.com: {}) に設定します。
- 存在する場合は、ハイライト データ構造をストレージから取得します (chrome.storage.get())
- 選択したテキストの有効なクエリ セレクター値を取得して割り当てます (これは、後で DOM をクエリし、ハイライトを適用するために使用されます。明確にするために、上記のオブジェクト構造を参照してください)。
- ハイライトされたテキストの親要素にクラス名がある場合は、文字列「element.className」(「p.firstParagraph」、「h2.sectionHeader」など)を格納します。
- クラス名がない場合は、文字列「element」(「p」、「h2」、「li」など)を格納します。
- キー (強調表示されたテキスト) に値 (2 つの値を含む配列 - 1 つ目はクエリ セレクター、2 つ目は親要素内で選択されたテキストが出現した場所のインデックス) を指定します。
- 文字列のインデックスを保存するのは、テキストとクエリ セレクターのみを保存した場合、ページを更新してハイライトを適用すると、「p」タグの下で「the」が強調表示されたとします。 「p」タグが強調表示されます。 IndexOf 値を追加すると、インデックスが DOM と一致することを確認してからハイライトを適用できるため、正しい単語にハイライトを適用することになります。
- chrome.storage.set() を使用して、新しいハイライトされたテキストを含む更新されたハイライト変数を保存します。
- デザインモードを「オフ」にする
各ページで実行される 2 番目の JavaScript ファイルは content_script.js です。 「ハイライト」と呼ばれる保存されたオブジェクトがあるかどうかを確認します。そうでない場合は、ユーザーが何も強調表示していないことを意味します。次に、空のオブジェクトを作成し、Chrome に保存します。
「ハイライト」オブジェクトが見つかった場合は、アクティブな URL のデータが保存されているかどうかを確認します。存在しない場合、スクリプトは戻ります。
URL にハイライトが保存されている場合:
- applyHighlights() 関数の実行
- 「ハイライト」オブジェクトとアクティブな URL という 2 つのパラメータを取ります。
- 保存されたオブジェクトのキーをループします (キーは保存されたハイライトですが、それらのキーの値は querySelector 値とindexOf 値を含む配列です)。
- document.body.querySelectorAll() を実行して、一致するすべてのノードの配列を取得します
- 返された各ノードをループし、innerHTML にオブジェクト キー (強調表示されたテキスト) に一致する「文字列」が含まれ、かつ同じ IndexOf 値がある場合: 1. 一致するテキストを <span> タグでラップする .replace() 関数を実行します。背景色のインライン スタイル属性
- 補足: 当初はすべての DOM ノードを再帰的に調べて一致をチェックしていましたが、querySelector 値を保存し、一致するノードのみの HTML 値を保存された値と比較する方が大幅に高速になりました。
次のバージョンへのアップグレード
- ハイライトした特定の文字列を保存します
- 「jQuery.com から jQuery ライブラリをダウンロードします。」
- 2 番目の「jQuery」を強調表示すると、保存された値は最初のインスタンスのものになります。
- これは、保存したindexOf値が最初の一致後に返されるためです。
- PLAN - スパンタグ後のインデックスのカウントを開始します
- ブロック要素全体をハイライト表示することはできません (ハイライトを h2 から ap タグにドラッグすると、h2 のみが登録されます)
- 進行中: ユーザーがハイライトの色を選択できるようにします
- ページのハイライトの数と実際のハイライトを拡張機能 Popup.html に表示します。
- 制限事項/特殊なケース: 電子メール、PDF
- すべてのサイトに許可をリクエストします。一部のサイトが「*」アクセスをブロックしているもの (cnn.com)
- ある要素で「jQuery」を強調表示すると、別の要素で再度強調表示され、2 番目の要素が最初の要素をオーバーライドします (キーが同じであるため)。
- 親要素がインラインタグの場合、innertext/htmlのindexOfが登録されないか(-1)、インラインタグの終わりでハイライトが終了します。spanタグのインデックスを見つけて、そこでindexOfを開始します。
- 折りたたみモード - ドキュメントを折りたたんで、保存されているハイライトの親要素のみを表示します。
解決された問題
- インライン要素タグ (a、em、st など) にまたがるハイライトの保存
- 以前は、innerText を保存していたため、インライン タグの前のテキストのみが保存されていました。
- 代わりに innerHTML を保存することで解決しました
- この変更によって生じた問題は、innerText のindexOf を保存していたため、「p」タグなどのテキスト要素内の標準テキストにハイライトが再適用されることでした。ただし、indexOf はタグ内の各文字をカウントするため、インライン要素の周囲の項目の場合は異なります。
- これを解決するために、ユーザーが再度アクセスしているページにハイライトを適用するときに、innerText.indexOf 値と innerHTML.indexOf 値を比較し、それぞれを一致するノードと比較します。
- ダブルクリックしてセクションをハイライトすると、indexOf 値が登録されないため、アプリはハイライトを再適用できませんでした。
- それを解決するために、.toString() メソッドと .trim() メソッドをindexOf(...) に追加しました。
- < a > タグを強調表示すると、ページの読み込み時にリンクが削除されます。
将来のアップグレード
## サンプル画像
エッジケース
- クラス名が変わった場合
- 解決策: クラス名が DOM に存在しない場合は、クエリ セレクターからクラス名を削除し、要素タグ ノードだけを検索します。
- コンテンツがボタンによって非表示になっている場合、ハイライトは on_load で検索されるため登録されず、コンテンツはブラウザーのイベント後にのみ表示されます (これが電子メールでは機能しない理由です)
誰かがpopup.html上のすべてのハイライトにアクセスできるようにする ユーザーがハイライトの色を変更できるようにする インライン要素のハイライトのバグを修正する