您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
將文章加入 tag 以方便整理,詳情請看該串一樓說明
// ==UserScript== // @name 巴哈 Vtuber 八卦串 tag 工具欄 // @namespace https://home.gamer.com.tw/homeindex.php?owner=qwert535286 // @version 0.8.2 // @description 將文章加入 tag 以方便整理,詳情請看該串一樓說明 // @author 笑翠鳥 // @icon https://www.google.com/s2/favicons?domain=gamer.com.tw // @match https://forum.gamer.com.tw/C.php?*bsn=60076*snA=6367604* // @match https://forum.gamer.com.tw/post1.php?*bsn=60076*snA=6367604* // @grant GM_addStyle // @grant GM_setValue // @grant GM_getValue // ==/UserScript== (async style => { GM_addStyle(style) async function process() { const customTags = new Set(await GM_getValue('customTags', [])) let $iframeEditor let $customGroup return { init() { $iframeEditor = document.getElementById('editor').contentWindow.document.body const groups = [ ['直播、預告、發推、新衣、活動、炎上、剪輯翻譯等新情報', ['Holo', '彩虹', 'VSPO', 'VShojo', 'VT箱', '個人勢', '歌勢', '中之人', '炎上', '集中串']], ['一般使用', ['創作', '梗圖', '油圖', '性癖', '拜票', '推廣文']], ['任何教學文、整理文等串內生態文', ['八卦串']], ['客製化標籤,輸入文字新增,用 , 隔開,再輸入一次刪除(不含 # 號)', [...customTags]] ] const isPost1 = location.href.includes('post1.php') const $target = document.querySelector(isPost1 ? '.postset_sign' : '.c-editor .option') $target.insertAdjacentHTML('beforeend', ` <div class="__vtuber-tags"> ${groups.map(([title, list]) => ` <div class="__title">${title}</div> <div class="__group">${this.getTagTmpls(list)}</div> `).join('\n')} <input type="${isPost1 ? 'hidden' : 'text'}" placeholder="按 Enter 送出" /> </div> `) const $panel = $target.querySelector('.__vtuber-tags') $customGroup = [...$panel.querySelectorAll('.__group')].at(-1) return [$iframeEditor, $panel] }, getTagTmpls(list) { const ctx = $iframeEditor.innerHTML return list.map(t => `<button type="button" aria-pressed="${ctx.includes(`<div>#${t}</div>`)}"><span>#</span>${t}</button>`).join('') }, togglePressed($tag) { $tag.setAttribute('aria-pressed', $tag.getAttribute('aria-pressed') !== 'true') }, updateCustom(values) { values .split(',') .reduce((acc, tag) => tag.trim() ? [...acc, tag.trim()] : acc, []) .forEach(tag => customTags.has(tag) ? customTags.delete(tag) : customTags.add(tag)) GM_setValue('customTags', [...customTags]) $customGroup.replaceChildren() $customGroup.insertAdjacentHTML('afterbegin', this.getTagTmpls([...customTags])) } } } const proc = await process() function send(e) { if (e.key !== 'Enter') return e.preventDefault() proc.updateCustom(e.target.value) e.target.value = '' } window.addEventListener('load', async () => { const [$iframeEditor, $panel] = proc.init() const $input = $panel.querySelector('input') $panel.addEventListener('click', ({ target }) => { if (target.tagName.toLowerCase() !== 'button') return const regexTag = new RegExp(`<(div|p)>${target.innerText}</(div|p)>`, 'g') const ctx = $iframeEditor.innerHTML regexTag.test(ctx) ? $iframeEditor.innerHTML = ctx.replace(regexTag, '') : $iframeEditor.insertAdjacentHTML('afterbegin', `<p>${target.innerText}</p>`) proc.togglePressed(target) }) $input.addEventListener('keydown', send) $input.addEventListener('compositionstart', () => $input.removeEventListener('keydown', send)) $input.addEventListener('compositionend', () => $input.addEventListener('keydown', send)) }) })(` .__vtuber-tags { margin-top: 16px; border-top: 2px solid #ececec; padding: 8px 0; text-align: left; font-size: 14px; } .__vtuber-tags > .__title { margin: 16px 0 8px; } .__vtuber-tags > .__group { display: flex; flex-wrap: wrap; gap: 6px; } .__vtuber-tags button { border: 1px solid transparent; border-radius: 4px; padding: 4px 8px; color: #464646; background: #d2d2d2; } .__vtuber-tags button:is(:hover, [aria-pressed="true"]) { color: white; } .__vtuber-tags button:hover { background: #11aac1; } .__vtuber-tags button[aria-pressed="true"] { background: #148aa4; } .__vtuber-tags button > span { padding-right: 2px; pointer-events: none; } .__vtuber-tags > input { box-sizing: border-box; margin-top: 8px; width: 100%; height: 40px; border: 1px solid #d9d9d9; border-radius: 4px; padding: 8px; } [data-theme="dark"] .__vtuber-tags { border-color: #444; } [data-theme="dark"] .__vtuber-tags > input { border-color: #444; color: #c6ccd2; background: #1C1C1C; } [data-theme="dark"] .__vtuber-tags button:not(:is(:hover, [aria-pressed="true"])) { border-color: #595959; color: #c6ccd2; background: #1C1C1C; } `)