kone.gg 갤러리뷰
当前为
// ==UserScript==
// @name kone Gallery View
// @namespace http://tampermonkey.net/
// @version 1.0
// @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 = 1000;
const OBSERVER_DELAY = 800
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 });
};