您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
kone.gg 갤러리뷰
当前为
// ==UserScript== // @name kone Gallery View // @namespace http://tampermonkey.net/ // @version 1.0.1 // @description kone.gg 갤러리뷰 // @author arcjay // @match https://kone.gg/s/* // @icon https://www.google.com/s2/favicons?sz=64&domain=kone.gg // @grant none // @license GPL // ==/UserScript== //'use strict'; // /* 파라미터 */ const IS_STRICT_SQUARE_IMAGE_MODE = true; // true로 바꾸면 이미지사이즈가 300x300박스로 고정됨. const REMOVE_SIDE_BAR_MODE = false; // true시, 우측의 인기글 사이드바가 사라짐. /* 사이트의 셀렉터 변경될 경우 수정하기 */ /* VROW */ const SEL_VROWS_PARENT = 'main .grow .grow.flex-col .grow' const ARTICLES_SELECTOR = ".grow .grow div.relative.flex.w-full"; // VROW (selectorAll로 쓰임) const ARTICLES_WITHOUT_NOTICE_SELECTOR = ".grow .grow"; const VROW_SEL_RATE = ".col-span-1.text-xs.pt-0\\.5" const VROW_SEL_TITLE = '.col-span-12 .overflow-hidden.text-nowrap.text-ellipsis'; const VROW_SEL_PREVIEW_IMAGE = 'img'; const ATTACH_TARGET_SELECTOR = ".col-span-12"; // 결과 이미지를 append할 위치 /* IMAGE 크롤러 */ const CONTENT_MAIN_SELECTOR = '.prose-container' /* 수정할 일 없음 */ const IMAGE_WIDTH_SMALL = 150; const IMAGE_WIDTH_NORMAL = 200; const IMAGE_WIDTH_LARGE = 300; const IMAGE_WIDTH = IMAGE_WIDTH_LARGE; const SENSITIVE_WARN_IMG = false; // 민감성 포스팅 이미지를 비우선으로할지말지 표시유무 const FETCH_DELAY = 60; // 바꿀필요없음. 50이하로쓰면 봇감지될가능성높음0 const WIDTH_THRESHOLD = 1800; // 안쓰이는 변수 ( 적용할지말지고민하다 그냥 안씀 ) 당시의도 : px단위. 이 px보다 커야 이미지미리보기가 발생한다 /* 딜레이 */ const FIRST_DELAY = 1200; const OBSERVER_DELAY = 1200 window.addEventListener("load", ()=>setTimeout(()=>{extendContentWrapper();observeUrlChange(start)}, FIRST_DELAY)); function vrowToGallery(vrowObj) { const {$self , $newRate, $rate, $title, $img} = vrowObj; $self.classList.remove('w-full'); $self.classList.add('flex'); $self.classList.add('flex-col'); $self.classList.add('items-center'); $self.classList.add('justify-center'); $self.style.width='300px'; $self.style.height='300px'; $self.style.padding = '5px'; $self.children[0].classList.remove('grow'); $self.children[0].classList.remove('w-full'); const $newTitle = document.createElement('div'); $newTitle.style.overflow = 'hidden'; $newTitle.style.whiteSpace = 'nowrap'; $newTitle.style.textOverflow = 'ellipsis'; $newTitle.style.width='300px'; $newTitle.style.display = 'flex'; $newTitle.style.justifyContent = 'center'; $newTitle.append($title); $title.append($newRate); // toGallery() $img.classList.remove('max-w-50') $img.classList.remove('max-h-40') $img.style.width='280px'; $img.style.height='250px'; $self.replaceChildren($img,$newTitle,$rate) } async function start() { if (REMOVE_SIDE_BAR_MODE) removeRightSidebar(); const vrows = document.querySelectorAll(ARTICLES_SELECTOR); const $parent = document.body.querySelector(SEL_VROWS_PARENT); //$parent.style.display = 'flex'; //$parent.style={display:'flex',flexDirection:'row',flexWrap:'wrap'} $parent.classList.add('flex') $parent.classList.add('flex-wrap') $parent.classList.add('justify-center') console.log('parent', $parent, 'disp',$parent.style.display,$parent.classList) const vrowObjs = Array.from(vrows).map(vrow=>({$self:vrow, $img:vrow.querySelector(VROW_SEL_PREVIEW_IMAGE) ?? document.createElement('img'), $title:vrow.querySelector(VROW_SEL_TITLE), $rate:vrow.querySelector(VROW_SEL_RATE), $newRate : document.createElement('span'), $IMG_APPEND_TARGET : vrow.querySelector(ATTACH_TARGET_SELECTOR) })); vrowObjs.forEach(vrowToGallery); //const vrowsPromiseArray = Array.from(vrows).map((vrow, i) => imageFetchAndAttach(vrow, (i+1) * FETCH_DELAY)); const articles = document.querySelectorAll(ARTICLES_WITHOUT_NOTICE_SELECTOR); articles.forEach((article) => { article.style = "height: auto !important"; }); //vrowObjs.forEach(attachImage); function attachImage(vrowObj){ const {$img, $IMG_APPEND_TARGET} = vrowObj; //if ($img.width === 1000 && $img.height === 667) return; // 미방이미지는 attach하지않음 $IMG_APPEND_TARGET.append($img); } } async function imageFetchAndAttach(vrow, delay) { // 이미지 페칭해서 붙임. const $img = vrow.querySelector('img'); const $target = vrow.querySelector(ATTACH_TARGET_SELECTOR); attach($img) return; async function getImage(url){ const response = await fetch(url); const text = await response.text(); const html = new DOMParser().parseFromString(text, "text/html"); const articleContent = html.querySelector(CONTENT_MAIN_SELECTOR); const tableImage = articleContent.querySelector('tbody img'); const video = articleContent.querySelector('video'); let image; if(tableImage) { image = tableImage; } else if (video && video.width >300) { image = new Image(); image.src = video.poster; } else { const imageCandidates = articleContent.querySelectorAll('img'); image = Array.from(imageCandidates).find(image=>SENSITIVE_WARN_IMG || !(image.width===1000 && image.height===667)) ?? new Image(300, 300); } } function attach(image) { fitImageSizeAndAlter(image); const target = vrow.querySelector(ATTACH_TARGET_SELECTOR); if (target) { target.style.width = `${IMAGE_WIDTH}px`; target.before(image); } vrow.style.display='flex'; vrow.style.flexDirection='column'; vrow.style.justifyContent = 'space-between'; vrow.style.width=`${IMAGE_WIDTH}px` } } function fitImageSizeAndAlter(image) { const aspectRatio = image.height / image.width; image.style.display = 'block'; image.style.width = `${IMAGE_WIDTH}px`; image.style.height = `${aspectRatio * IMAGE_WIDTH}px`; if(IS_STRICT_SQUARE_IMAGE_MODE){ image.style.display = 'block'; image.style.objectFit = 'contain'; image.style.height = `${IMAGE_WIDTH}px`; } } function removeRightSidebar() { document.querySelector(".right-sidebar").style.display = "none"; } function extendContentWrapper() { const contentWrapper = document.querySelector("main>.max-w-7xl"); contentWrapper.classList.remove('max-w-7xl'); contentWrapper.style.maxWidth = '95dvw' contentWrapper.children[0].classList.remove('md:container'); } // const observeUrlChange = (func) => { func(); let oldHref = document.location.href; const body = document.querySelector('body'); const observer = new MutationObserver(mutations => { if (oldHref !== document.location.href) { oldHref = document.location.href; setTimeout(func, OBSERVER_DELAY); } }); observer.observe(body, { childList: true, subtree: true }); };