Google Chrome extension to save number of like and dislike at last visit time for each problems and show them on problem list page. - zuqqhi2/leetcode-show-numlike zuqqhi2/leetcode-show-numlike - GitHub |
manifest.json と app.js の中身を以下のように書いて、「パッケージ化されていない拡張機能を読み込む」から拡張機能をインストールすれば、LeetCode の問題のリストページにアクセスした際にダイアログボックスが表示されます。$ tree zuqqhi2-ext-test/ zuqqhi2-ext-test/ ├── app.js └── manifest.json 0 directories, 2 files
{ "name": "Zuqqhi2ExtTest", "version": "0.1.0", "manifest_version": 2, "description": "Test.", "content_scripts": [{ "matches": ["https://leetcode.com/problemset/all/*"], "js": ["app.js"], "css": [] }], "permissions": [] }
上記のサンプルも今回作ったものでも permissions には何も指定していないですが、permissions については以下のサイトにまとまっていました。alert('Test');
拡張機能が特別な権限を必要とする際には permission キーを使用します。このキーには文字列の配列を指定し、各文字列がパーミッションを要求します。 permissions - Mozilla | MDN - |
ページが表示されてからも処理に使う要素が表示されるまで待つようにしています。待たない場合は要素がなくてエラーになってしまうので。 以下のコードの部分で問題のリストページでは MutationObserver で要素が表示されるのを待っているのですが、個別の問題のページでは MutationObserver がうまく動かなかったので setInterval で適当に 500 ミリ秒ごとに要素が表示されるか見て、要素が表示されていれば LocalStorage に Like/Dislike 数を保存して終了する形になっています。 例えば個別の問題のページでは、Like/Dislike ボタンの要素を取得するのに(仕方なく)「btn__r7r7」クラスを指定しているので、個別の問題のページがちょっとでも修正されるとクラスが見つからなくて動かなくなると思います。// Common functions function loadProblemInfo() { // Clean or initialize localStorage var problem_info = {} if (localStorage.getItem('zuqqhi2-leetcode-show-numlike')) { try { problem_info = JSON.parse(localStorage.getItem('zuqqhi2-leetcode-show-numlike')) } catch (e) { localStorage.removeItem('zuqqhi2-leetcode-show-numlike') localStorage.setItem('zuqqhi2-leetcode-show-numlike', '{}') } } else { localStorage.setItem('zuqqhi2-leetcode-show-numlike', '{}') } return problem_info }
// Problem list page (Show number of like and dislike) var observer = undefined if (document.location.href.startsWith('https://leetcode.com/problemset/all/')) { observer = new MutationObserver(() => { const elems = document.querySelectorAll(".question-list-base > .question-list-table > .table > .reactable-data > tr") if (elems.length > 0) { ... observer.disconnect() } }) const targetNode = document.getElementsByClassName('question-list-base')[0] observer.observe( targetNode, {childList: true, subtree: true} ) // Each problem page (Save number of like and dislike) // Note: MutationOberser doesn't work on this page. So, just using setInterval function. } else { observer = () => { const elems = document.querySelectorAll(".btn__r7r7") if (elems.length === 4) { ... } } const observation = () => { console.log('zuqqhi2-leetcode-show-numlike: under observation...') const targetNode = document.getElementsByClassName('btn__r7r7')[0] if (targetNode !== undefined) { console.log('zuqqhi2-leetcode-show-numlike: observation is finished') observer() return true } else { return false } } const interval_id = setInterval(() => { if (observation()) { clearInterval(interval_id); } }, 500) }