ãã®è¨äºã¯ç¾
éç¤ ã¢ããã³ãã«ã¬ã³ãã¼ 2024ã®7æ¥ç®ã®è¨äºã§ãã
qiita.com
6æ¥ç®ã®è¨äºã¯ できるだけWebPで画像をホスティングしたい、そんな私に捧げる話 - 羅針盤 技術航海日誌 ã§ããã
ããã«ã¡ã¯ãç¾
éç¤ã®æ£®å·ã§ãã
好ããªãã©ã¼ã¯ãã¼ã¹ã¨ãã¤ãã§ã好ããªãµãã¤ãã¼ã¯ã·ã§ãªã«ã§ããããããã
ååã¯WebPåã®è©±ã§ããããä»åã¯GitHubã§WebPããã¬ãã¥ã¼ãã話ã«ãªãã¾ãã
GitHubã¯2024å¹´12æç¾å¨ã¯WebPã®ãã¬ãã¥ã¼ã«å¯¾å¿ãã¦ãã¾ããã
ãªã«ã宿çãªçç±ã§ãããã®ã§ããããã

ã¾ãIssueãPull Requestã¯ææªããã§ããã ã§ã大éã®å·®åããã§ãã¯ããã®ã¯ãããã«ããã©ãã§ããåãããã

ãã¡ã¼ã£ãã100åè¿ããã¡ã¤ã«ããã£ã¦ã100åè¿ã Binary file not shown. ã表示ããã¦ãã¬ãã¥ã¼ã¨ã¯ä½ããWebPã¨ã¯ãªãã ã£ãã®ããèããããããç»é¢ã§ãã
GitHubä¸ã§ãã¡ã¤ã«å·®åã®WebPããã¬ãã¥ã¼ããæ¹æ³
å°ãæã¦ãã®ã§å¤ä¼ã¿ã«Chrome Extensionä½ãã¾ããã ãããããã¤ã§ãã
ãã¼ã¿æãåãã¨ãã¯ãã¦ãªãã®ã§å®å¿ãã¦ä½¿ã£ã¦ãã ãããï¼ãã¶ãï¼
æ¬å½ã¯GitHubä¸ã®Public Repositoryã§å ¬éãããã¨ãããªãã§ããããªããã³ããããã¦æ å ±ã¶ã£ãæãã¦å人æ å ±ããã¼ã¯ã¦ã§ãã§è²©å£²ããã¯ãã¼ã³ããã£ã±ãåºã¦ãããå«ã ãªã... ã¨æã£ã¦ç¾æç¹ã®ã³ã¼ãã®ä¸é¨ãããã¤ã¾ãã§åºãã¦ããã¾ãã
ã³ã¼ãæç
vite.config.ts
Viteã§ãã«ããããã®ã§ãªãã¨ãªãCRXJS使ãã¾ããã 使ããªãã¦ãè¯ãã¨æãã¾ãã
npm i @crxjs/vite-plugin@2.0.0-beta.28 -D
import { defineConfig } from "vitest/config"; import { crx } from "@crxjs/vite-plugin"; import manifest from "./manifest.json"; // TODO: åã¨ã©ã¼ç´ã export default defineConfig({ plugins: [crx({ manifest })], rollupOptions: { input: { background: "src/background.ts", content: "src/content.ts", }, }, });
manifest.json
æ¬å½ã¯å¯¾è±¡ã®ãã¹ããã£ã¨å¶éãããã£ãã®ã§ããï¼/commits/ 以ä¸ã¨ãï¼ã GitHubä¸ã®é·ç§»ãHistory APIãããã£ã¦ãããããã³ã¼ããçºç«ããªããªãã®ã§GitHubãã¡ã¤ã³ã§æå¹ã«ãªãããã«ãã¾ããã
"content_scripts": [ { "js": ["src/content.ts"], "matches": ["https://github.com/*"] } ], "background": { "service_worker": "src/background.ts", "type": "module" }, "permissions": ["activeTab", "scripting"]
background.ts
ã¢ã¤ã³ã³ã¯ãªãã¯ã§ãçºç«ããæ¹ãããããªã¨æã£ããã§ããããããããããããªããããããªãã
chrome.action.onClicked.addListener((tab) => {
chrome.scripting.executeScript({
target: { tabId: tab.id || 0 },
files: ["content.ts"],
});
});
content.ts
(a) URLå¥ã§ã®ãã¸ãã¯é·ç§»
HTMLã®æ§é ãåãã¼ã¸ã§ç°ãªãã®ã§ã ç¾å¨ã®URLã«åããã¦éã颿°ãå®è¡ãã¦ã¾ãã
function runMain() { const url = window.location.href; if (url.match(/\/blob\/.*\.webp$/)) { handleBlobWebpPage(); } else if (url.match(/\/files$/)) { handleFilesPage(); } else if (url.match(/\/commits\//)) { handleFilesPage(); } else if (url.match(/\/commit\//)) { handleCommitPage(); } }
(b) ãã«ãªã¯ã®diffãã¼ã¸åããã¸ãã¯
// diff files page. (e.g. commit diff, pull-request diff) function handleFilesPage() {[f:id:compasscorp:20241206182736p:plain] /* (1) */ const divList = document.querySelectorAll( 'div[data-file-type=".webp"][data-details-container-group="file"]', ); divList.forEach((div) => { /* (2) */ const webpLinkList = Array.from( div .querySelector('details-menu[role="menu"]') ?.querySelectorAll('a[rel="nofollow"]') ?? [], ).filter((a) => a.href.endsWith(".webp")); if (!webpLinkList.length) { return; } /* (3) */ const emptyDiv = div.querySelector("div.empty"); if (!emptyDiv) { return; } const webpLink = webpLinkList[0]; if (!_isValidImageDomain(webpLink.href)) { return; } replaceToImageTag(emptyDiv, webpLink.href, "WebP Image"); }); }
ä¸è¨ã³ã¼ãã® (1) ã§ã¯æåã® const divList = ... ã§ Binary not shown. ãé¨åãã¾ã¨ããã³ã³ããdivãåå¾ãã¦ãã¾ãã

divãããããã«ã¼ãåãã¦ã
(2) ã§ã¯ ... ãæ¼ä¸ããéã® View file ã®URLï¼WebPãã¡ã¤ã«ã¸ã®ãªã³ã¯ï¼ãåå¾ãã¦ãã¾ããï¼åã¯é½åä¸é
åã«ãã¡ãã£ã¦ãã¾ãããåä¸ãã¼ã¿ãæ³å®ï¼

(3) ã§ã¯ä»¶ã® Binary file nowe shown. ã®é¨åãç´æ¥åå¾ãã¦ãã¦ããããimgã¿ã°ã«æ¸ãæãã¦ã¾ãã
_isValidImageDomain(url) ã¯ç¸å¯¾ãã¹ or HTTP(s)ã® github.com ãã©ãããå¤å®ãã¦ã¾ãã
(c) ã¨ã³ããªãã¤ã³ã
èµ·åæã®å¦çã¯ãå ç¨ã®(a)ã®å¦çãå®è¡ãããã®ã«ãªãã¾ãã ç´URLé·ç§»æã®ããã«ä¸å(a)ãå®è¡ãã¦ããã®å¾ã« MutationObserver ã§URLã®é·ç§»ãæ¤ç¥ãã¦ãrunMainãå®è¡ããããã«ãã¦ã¾ãã ï¼é·ç§»ç´å¾ã«å®è¡ããã¨DOMãæ§ç¯ãããåï¼ã«å®è¡ããã¡ããã®ã§éã«setTimeoutã¤ãã¦ã¾ãï¼
const intervalMs = 1000; function init() { runMain(); // watch for url change. (e.g. history api) let lastUrl = location.href; new MutationObserver(() => { const currentUrl = location.href; if (currentUrl !== lastUrl) { lastUrl = currentUrl; setTimeout(runMain, intervalMs); } }).observe(document, { subtree: true, childList: true }); } window.onload = init;
ãªãã¸ããªã¯ç¡ããã©ãã¿ãªãã¾ããã®ã¢ãã¤ä¿®æ£ããããå¾ ã¡ãã¦ããã¾ãã