您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Let you collapse/expand threads on Komica
// ==UserScript== // @name Komica thread collapse // @version 1.0.7 // @description Let you collapse/expand threads on Komica // @author peng-devs // @match https://*.komica.org/*/*.htm* // @match https://*.komica1.org/*/*.htm* // @match https://*.komica2.net/*/*.htm* // @match https://*.komica2.cc/*/*.htm* // @exclude-match https://2cat.komica.org/* // @icon https://komica1.org/favicon.ico // @grant none // @allFrames true // @license MIT // @namespace https://greasyfork.org/users/57176 // ==/UserScript== (function() { 'use strict'; const NAME = 'Komica thread collapse'; function main() { console.log(`[${NAME}] Initializing...`); inject_custom_style(` .collapsed_thread { opacity: 0.5; } .thread-collapse-button { float: left; margin-right: 5px; } .thread.collapsed { display: none !important; } .thread.ngid-ngthread > .thread-collapse-button { display: none; } `); const storage = get_storage(); const threads = document.querySelectorAll('div.thread'); [...threads].forEach(thread => { const thread_collapse_button = create_thread_collapse_button(thread); thread.prepend(thread_collapse_button); const data_no = thread.getAttribute('data-no'); if (storage.includes(data_no)) { thread_collapse(thread); } }); console.log(`[${NAME}] Loaded`); } /// private function inject_custom_style(css) { const style = document.createElement("style"); document.head.append(style); style.dataset.source = NAME; style.innerHTML = css; } function get_storage() { return window.localStorage.getItem('collapsed_threads') || ''; } function save_to_storage(data_no) { let storage = get_storage(); if (storage.includes(data_no)) return; if ((storage.match(/,/g) || []).length > 100) { storage = storage.slice(storage.indexOf(',') + 1); } window.localStorage.setItem('collapsed_threads', `${storage}${data_no},`); } function remove_from_storage(data_no) { const storage = get_storage(); window.localStorage.setItem('collapsed_threads', storage.replaceAll(`${data_no},`, '')); } function get_thread(data_no, collapsed = false) { return document.querySelector(`div.${collapsed ? 'collapsed_thread' : 'thread'}[data-no="${data_no}"`); } function create_collapsed_thread(thread) { const data_no = thread.getAttribute('data-no'); const thread_collapse_button = create_thread_collapse_button(thread, true); const head = thread.querySelector('div.post-head').cloneNode(true); const hr = document.createElement('hr'); const collapsed_thread = document.createElement('div'); collapsed_thread.className = 'collapsed_thread'; collapsed_thread.setAttribute('data-no', data_no); collapsed_thread.appendChild(thread_collapse_button); collapsed_thread.appendChild(head); collapsed_thread.appendChild(hr); return collapsed_thread; } function thread_collapse(thread) { thread.classList.add('collapsed'); const collapsed_thread = create_collapsed_thread(thread); thread.before(collapsed_thread); const data_no = thread.getAttribute('data-no'); save_to_storage(data_no); console.log(`[${NAME}] thread ${data_no} collapsed`); } function thread_expand(thread) { thread.classList.remove('collapsed'); const collapsed_thread = thread.previousElementSibling; if (collapsed_thread?.classList.contains('collapsed_thread')) { collapsed_thread.remove(); } const data_no = thread.getAttribute('data-no'); remove_from_storage(data_no); console.log(`[${NAME}] thread ${data_no} expanded`); } function create_thread_collapse_button(thread, collapsed = false) { const thread_collapse_button = document.createElement('a'); thread_collapse_button.className = 'thread-collapse-button'; thread_collapse_button.innerText = `[${collapsed ? '+' : '–'}]`; thread_collapse_button.addEventListener( 'click', collapsed ? () => thread_expand(thread) : () => thread_collapse(thread) ); return thread_collapse_button; } main(); })();