UserScript:ワンポイント
ページにワンポイントの画像を追加する
code:script.js
(() => {
'use strict';
// --- Configuration ---
const MODE_ID = '__one__';
const MAIN_MENU_TITLE = 'ワンポイント';
const SUB_MENU_TITLE = 'ワンポイント補助';
const LIST_URL = '/api/table/suto3/UserScript:ワンポイント/list.csv';
const MAIN_ICON = '/api/pages/suto3/user-03/icon';
const SUB_ICON = '/api/pages/suto3/user-04/icon';
// const IMAGE_URL_REGEX = /(https?:\/\/[\w\-\.\/?\,\#\:\u3000-\u30FE\u4E00-\u9FA0\uFF01-\uFFE3\\]+)\.(jpg|jpeg|gif|png|webp|svg)/i;
const IMAGE_URL_REGEX = /(https?:\/\/[\w\-\.\/?\#\:\%\u3000-\u30FE\u4E00-\u9FA0\uFF01-\uFFE3\\]+)\.(jpg|jpeg|gif|png|webp|svg)/i;
// --- DOM Manipulation ---
const changeStyle = (css) => {
let style = document.getElementById(MODE_ID);
if (!style) {
style = document.createElement('style');
style.id = MODE_ID;
document.head.appendChild(style);
}
style.textContent = css;
};
const removeStyle = () => {
const style = document.getElementById(MODE_ID);
if (style) style.remove();
};
// --- CSS Generators ---
const getCssTemplate = (type) => {
switch (type) {
case 1:
return (url) => `
.page {
background-image:
linear-gradient(to right, var(--assort-color, white), 70%, transparent, 90%, transparent),
url("${url}");
background-repeat: no-repeat , repeat-y;
background-attachment: fixed , scroll;
background-position: center top, right top;
background-size: 100% auto, 50% auto;
}
`;
case 2:
return (url) => `
.page {
background-image:
linear-gradient(to right, var(--assort-color, white), 70%, transparent, 90%, transparent),
url("${url}");
background-repeat: no-repeat, no-repeat;
background-attachment: fixed, fixed;
background-position: center top, center top;
background-size: 100% auto, 100% auto;
}`;
case 3:
return (url) => `
.page {
background-image:
linear-gradient(to bottom, transparent, 0%, transparent, 20%, var(--assort-color, white), 40%, var(--assort-color, white), 70%, transparent, 90%, transparent), url("${url}");
background-repeat: no-repeat, repeat-y;
background-attachment: fixed, scroll;
background-position: center top, center top;
background-size: 100% auto, 100% auto;
}`;
default:
throw new Error(Invalid style type: ${type});
}
};
// --- Utility ---
const choice = (arr) => {
if (!arr || arr.length === 0) return null;
return arrMath.floor(Math.random() * arr.length);
};
// --- Data Fetching ---
const fetchImageLists = new Promise((resolve, reject) => {
fetch(LIST_URL)
.then(res => res.ok ? res.text() : Promise.reject(new Error('Network response was not ok')))
.then(text => resolve(text.split('\n').slice(1).map(line => line.replace(/^,/, "")).filter(Boolean)))
.catch(reject);
});
// --- Menu Setup ---
scrapbox.PageMenu.addMenu({
title: MAIN_MENU_TITLE,
image: MAIN_ICON,
onClick: async () => {
scrapbox.PageMenu(MAIN_MENU_TITLE).addItem({ title: 'Now loading...', onClick: () => {} });
try {
const lines = await fetchImageLists;
const urls = lines.map(line => {
const name = 'unknown', url = '' = line.split(',');
const cleanedUrl = url.replace(/[\\]/g, "");
return { name, url: cleanedUrl };
})
.filter(item => IMAGE_URL_REGEX.test(item.url));
scrapbox.PageMenu(MAIN_MENU_TITLE).removeAllItems();
scrapbox.PageMenu(MAIN_MENU_TITLE).addItem({ title: '消す', onClick: removeStyle });
urls.forEach(item => {
scrapbox.PageMenu(MAIN_MENU_TITLE).addItem({
title: item.name,
onClick: () => changeStyle(getCssTemplate(1)(item.url)),
});
});
const imageUrls = urls.map(item => item.url);
if (imageUrls.length > 0) {
scrapbox.PageMenu(MAIN_MENU_TITLE).addItem({
title: 'ランダム',
onClick: () => changeStyle(getCssTemplate(1)(choice(imageUrls))),
});
}
} catch (err) {
console.error('Failed to build main menu:', err);
scrapbox.PageMenu(MAIN_MENU_TITLE).removeAllItems();
scrapbox.PageMenu(MAIN_MENU_TITLE).addItem({
title: '❌ 取得失敗',
onClick: () => alert('リストの取得に失敗しました。'),
});
}
},
});
scrapbox.PageMenu.addMenu({
title: SUB_MENU_TITLE,
image: SUB_ICON,
});
const addManualMenuItem = (title, styleType) => {
scrapbox.PageMenu(SUB_MENU_TITLE).addItem({
title,
onClick: () => {
const imageUrl = prompt('画像URLを入力してください');
if (!imageUrl) return; // Cancelled
if (IMAGE_URL_REGEX.test(imageUrl)) {
changeStyle(getCssTemplate(styleType)(imageUrl));
} else {
alert('無効なURLです。画像ファイルのURLを入力してください。');
}
},
});
};
scrapbox.PageMenu(SUB_MENU_TITLE).addItem({ title: '消す', onClick: removeStyle });
addManualMenuItem('ワンポイント1', 1);
addManualMenuItem('ワンポイント2', 2);
addManualMenuItem('ワンポイント3', 3);
// --- Export for testing ---
if (typeof module !== 'undefined' && module.exports) {
module.exports = {
MODE_ID,
IMAGE_URL_REGEX,
changeStyle,
removeStyle,
getCssTemplate,
choice,
};
}
})();
UserCSS:ページ
アイコン画像
https://svg-hosting.vercel.app/api/svg?url=https://scrapbox.io/api/code/suto3/snowman/s01.svg
以下はダークテーマに対応していない
アイコン画像1
https://gyazo.com/374de20e6cae168b155e87cf7a6d0737
アイコン画像2
https://gyazo.com/f21247f531de8607fb8662368d103ea6
table:listx
ラベル URL
ハク https://i.gyazo.com/de07fbaab5c961dc7fd3720ba956bbd3.png
ビーバーくん https://i.gyazo.com/5a9b6f8b965613bcc39d3b77afa59dc7.png
apple https://i.gyazo.com/d26e06b3a997e18050145c8dd72cdb17.png
Scrapbox https://i.gyazo.com/7057219f5b20ca8afd122945b72453d3.png
suto3 https://i.gyazo.com/1e3180e3bcab79cd1187b3c24e0e2758.png
alert https://i.gyazo.com/50af8c8a81261a3fe4f55da12d54deb6.png
はてな https://i.gyazo.com/6a642ed251fcd05cb1ad04be8b6a63fb.png
注意 https://i.gyazo.com/2f95a48883d5af0a524da6b30e543851.png
重要 https://i.gyazo.com/f8a54d718c1d838bc4b562bd9fed5326.png
WIP https://i.gyazo.com/3dda4ae1009f4cc995bfdc249256e1b6.png
わかる https://i.gyazo.com/a11194372c3360d4176feb6ca4ed528a.png
table:list
ラベル URL コメント
1 サンタ衣装のふーこさん https://i.gyazo.com/cf0694afc84942148f79c67b4df4d1be.png ふーこさん
2 サンタ衣装のましろさん https://i.gyazo.com/15a000710dfc69c3b8b75cbcd1df6599.png ましろさん
3 サンタ衣装のひよりさん https://i.gyazo.com/4647aaf2ee0cdb72a2556a5b6cef9b7c.png ひよりさん
4 コルセットスカートのふーこさん https://i.gyazo.com/e75528ee087d6bab9cf5f6e168f361a7.png
5 マジシャンましろさん https://i.gyazo.com/ef9ead5cecd3848b1a83c4ff200483e3.png
6 コルセットスカートのひよりさん https://i.gyazo.com/773076671263b4110fd88dd3acb1e1a9.png
7 コルセットスカートのましろさん https://i.gyazo.com/89e6a4f1dec3eea1c3d7366b5e2551b0.png
8 セーラー服のふーこさん https://i.gyazo.com/2839655d6f5772b5ee57620c028b794f.png
9 セーラー服のましろさん https://i.gyazo.com/ab64a525d8eb6a660a19422fd476e503.png
10 セーラー服のひよりさん https://i.gyazo.com/2a47ab88ff90697be1d54688483e6abd.png
11 SVG表示のテスト https://plantuml-proxy.vercel.app/svg/https://scrapbox.io/api/code/suto3/PlantUML:付箋っぽい書き方/sticky.pu#.svg
12 Python Cheat Sheet https://plantuml-proxy.vercel.app/svg/https://scrapbox.io/api/code/suto3scratchpad/python-cheat-sheet/cs01.pu#.svg
UserCSS.icon
UserScript.icon