484 Views
December 14, 24
スライド概要
忘年会議2024でお話ししたスライドです。
https://bonenkaigi.connpass.com/event/330155/
以下は作った拡張機能の紹介動画です。
https://www.nicovideo.jp/user/134113088/series/487379
ニコニコ動画用UserScriptを Chrome拡張機能に移植した話 2024/12/14 @忘年会議2024 LT DNEK(でぃーねっく)
自己紹介 DNEK(でぃーねっく) 個人でソフトウェア開発・運営 主にモバイルアプリ、Webサイト 京大マイコンクラブ(KMC)所属 競プロ , esolang, code golf 9月 PFN主催第1回MN-Core Challengeで10位 AtCoder 1695 X: @dnek_ HP: dnek.net
https://dnek.net より DNEKの製作物一覧
本題
ニコ動画用ブラウザ拡張 サイバー攻撃でニコ動が作り直された →なくなった機能を拡張機能で再現 紹介動画も作った 「ブラウザ内最大化」が一番人気 公式は「モニター全画面」のみ 最初は「UserScript」の形で提供 → 後日「Chrome拡張機能」にも対応 ブラウザ内最大化適用前後
今回話すこと 「UserScript」「Chrome拡張機能」とは何か? cf. 「解決策をひとつ増やそう!Chrome拡張機能作成のススメ」 by 前川さん @合同勉強会2023冬 Chrome拡張機能のミニマルな実装のチュートリアル なぜ「UserScript」→「Chrome拡張機能」の順で実装したのか? どのように移植したのか?
UserScriptとは ウェブページで実行されるカスタムJavaScript ( *.user.js ) 導入方法 1. Chromeウェブストア等でスクリプト管理ツールをインストール 2. 管理ツールにスクリプトをインストール Greasy Fork等の配布サイトで入手(コードは公開) 管理ツールのエディタで直書き(入手した物も編集可能)
Chrome拡張機能とは Google Chromeをカスタマイズするアドオン スクリプト管理ツールもこれ 導入方法 Chromeウェブストアからインストール 開発者モードでプロジェクトディレクトリを読み込む
UserScript vs Chrome拡張機能 対応 管理 開発者 ストア 構成 ブラウザ ツール 登録料 掲載情報 審査 UserScript 1ファイル ほぼ全部 必要 無料 基本不要 ない Chrome 内容次第 Chromium 不要 初回 画像など ある 拡張機能 で増える ベース※ 5USD 色々必須 ※ 一部API対応やマニフェストの必須項目等の違いがある → UserScriptは開発者に優しい、Chrome拡張は一般利用者に優しい
DNEKの状況 HOTなうちに、誰(公式含む)よりも早く作りたい 全ブラウザに対応したい ブラウザ拡張機能を作るのは初めて → まずは早い、広い、楽なUserScriptから
UserScriptの書き方 ヘッダーコメントとJavaScriptを書く @grant で GM_* 関数等が使える よく使うもの / GM_setValue US専用ストレージで値を取得/保存 GM_addStyle CSS追加 GM_getValue
UserScript → Chrome拡張機能 8/6(ニコ動再開翌日)よりUserScriptを順次公開 8/9 紹介動画1本目をニコ動に投稿 概ね好評(3本で計1.3万再生以上) 数ヶ月経過 「配布サイトがわかりにくい」等不満の声 作れば使ってもらえる需要は見込めた → 満を持してChrome拡張機能を実装
Chrome拡張機能の構成
で色々定義
必要に応じてjsやhtmlファイルを置く
今回はウェブページで実行される
content.js があれば良さそう
manifest.json
{
manifest.json
}
"name": "nicovideo-player-expander",
"version": "3.3",
"manifest_version": 3,
"description": "ニコニコ動画の(略)",
"content_scripts": [
{
"matches": [
"https://www.nicovideo.jp/watch/*"
],
"js": [
"content.js"
]
}
],
"permissions": [
"storage"
],
"icons": {
"128": "icons/icon_128.png"
}
GM関数のラッパーを書く
GM_getValue
/ GM_setValue
APIの chrome.storage.local を使う
manifestで storage を許可する
get の返り値に気を付ける
GM_addStyle 普通のjsを書く
→ ラッパーの後ろにUserScriptのjsを
コピペすれば完成
content.js
// GM functions
const GM_getValue =
async (key, defaultValue) => (
await chrome.storage.local.get({
[key]: defaultValue
})
)[key];
const GM_setValue =
async (key, newValue) =>
chrome.storage.local.set({
[key]: newValue
});
const GM_addStyle = (content) => {
const styleEl =
document.createElement('style');
styleEl.textContent = content;
document.body.appendChild(styleEl);
return styleEl;
};
// ここにUserScriptのjsをコピペ
(async () => {
let a = await GM_getValue('hoge', 0);
// ...
})();
苦労(?)した話 何故か content.js 内で chrome.storage を使えないと勘違い していた わざわざService Worker内で chrome.storage を呼び content.js と通信する遠回りなコードを実装していた 昨日このスライドを書いている途中で勘違いに気付いた 直したらラッパーがめっちゃシンプルになった → このLTの準備をしたおかげで学びを得た(?)
まとめ 状況、やる気に応じた方法で拡張機能を作ろう 拡張機能で快適なニコニコライフ まずは拡張機能の紹介動画を見てください
終わり