Compare commits

..

No commits in common. "eb4b4dfe9ca9e01f72a1d5b62a40b5dc0bc9e0ba" and "ea469f6995808712f09a73ffa93044f4ec2ce6e3" have entirely different histories.

7 changed files with 158 additions and 113 deletions

View File

@ -1,15 +0,0 @@
{
"env": {
"browser": true
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": 2021
},
"rules": {
"quotes": ["warn", "double"],
"semi": ["warn", "never"],
"indent": ["warn", 4],
"prettier/prettier": 0
}
}

9
README.md Normal file
View File

@ -0,0 +1,9 @@
## Collection of small userscripts
Tested with [Violentmonkey](https://violentmonkey.github.io/) & Gecko. Available on [Greasyfork](https://greasyfork.org/en/users/1033565-17ms).
* [4c-autohide.js](visual/4c-autohide.js)
* [4c-gallery.js](visual/4c-gallery.js)
* [4c-image-expander.js](visual/4c-image-expander.js)
* [y-image-expander.js](visual/y-image-expander.js)
* [y-media-downloader.js](download/y-media-downloader.js)

View File

@ -0,0 +1,43 @@
// ==UserScript==
// @name y-media-downloader
// @description General media downloader
// @author 17ms
// @license MIT License
// @namespace Violentmonkey Scripts
// @match *://ylilauta.org/*
// @version 1.0
// ==/UserScript==
function download(url) {
fetch(url, {
mode: "no-cors"
})
.then((response) => response.blob())
.then((blob) => {
let blob_url = window.URL.createObjectURL(blob)
let a = document.createElement("a")
a.download = url.split("/")[5]
a.href = blob_url
document.body.appendChild(a)
a.click()
a.remove()
})
}
function init() {
const links = Array.from(document.getElementsByClassName("jpg")).concat(
Array.from(document.getElementsByClassName("png"))
)
for (let i = 0; i < links.length; ++i) {
let url = links[i].href
download(url)
}
}
const activate_link = document.createElement("button")
const parent_element = document.getElementById("navbar")
activate_link.innerText = "⮶"
activate_link.style.fontSize = "30px"
activate_link.onclick = () => init()
parent_element.append(activate_link)

View File

@ -1,7 +1,8 @@
// ==UserScript== // ==UserScript==
// @name 4c-autohide // @name 4c-autohide
// @description Keyword based thread hider // @description Keyword based thread hider
// @author ae // @author 17ms
// @license MIT License
// @namespace Violentmonkey Scripts // @namespace Violentmonkey Scripts
// @match *://boards.4chan*.org/*/catalog // @match *://boards.4chan*.org/*/catalog
// @version 1.0 // @version 1.0

View File

@ -1,25 +1,17 @@
// ==UserScript== // ==UserScript==
// @name 4c-gallery // @name 4c-gallery
// @description Draggable image viewer // @description Draggable image viewer
// @author ae // @author 17ms
// @license MIT License
// @namespace Violentmonkey Scripts // @namespace Violentmonkey Scripts
// @match *://boards.4chan*.org/*/thread/* // @match *://boards.4chan*.org/*/thread/*
// @exclude *://boards.4chan*.org/*/catalog // @exclude *://boards.4chan*.org/*/catalog
// @version 1.3.2 // @version 1.2
// ==/UserScript== // ==/UserScript==
/* // Shortcuts: decrease size, increase size, previous image, next image, jump to the source hash (i.e. post)
Default shortcuts: const keys = ["-", "+", "j", "k", "i"]
"-" decrease window size const excludeWebm = true
"+" increase window size
"j" previous image
"k" next image
"i" jump to the source (i.e. post's hash)
"l" open the image to a new tab
*/
const keys = ["-", "+", "j", "k", "i", "l"]
const excludeWebm = true // not tested with webms enabled
const dragElement = (elem) => { const dragElement = (elem) => {
const handler = (e) => { const handler = (e) => {
@ -34,14 +26,13 @@ const dragElement = (elem) => {
const enableDragger = (e) => { const enableDragger = (e) => {
e = e || window.event e = e || window.event
e.preventDefault() e.preventDefault()
pos1 = pos3 - e.clientX pos1 = pos3 - e.clientX
pos2 = pos4 - e.clientY pos2 = pos4 - e.clientY
pos3 = e.clientX pos3 = e.clientX
pos4 = e.clientY pos4 = e.clientY
elem.style.top = elem.offsetTop - pos2 + "px" elem.style.top = (elem.offsetTop - pos2) + "px"
elem.style.left = elem.offsetLeft - pos1 + "px" elem.style.left = (elem.offsetLeft - pos1) + "px"
} }
const closeDragger = () => { const closeDragger = () => {
@ -78,28 +69,31 @@ const nextImg = () => {
imgElem.src = imgs[i].src imgElem.src = imgs[i].src
} }
// could probably be improved with proper css
const sizeUp = () => { const sizeUp = () => {
const newW = baseElem.clientWidth + 200 const e = document.getElementById("drGallery")
const newH = Math.round(newW * ratioMultiplier) const newW = e.clientWidth + 100
const newH = e.clientHeight + 90
if (newW > window.innerWidth) { if (newW > window.innerWidth || newH > window.innerHeight) {
return return
} }
baseElem.style.width = newW + "px" document.getElementById("drGallery").style.width = newW + "px"
baseElem.style.height = newH + "px" document.getElementById("drGallery").style.height = newH + "px"
} }
const sizeDown = () => { const sizeDown = () => {
const newW = baseElem.clientWidth - 200 const e = document.getElementById("drGallery")
const newH = Math.round(newW * ratioMultiplier) const newW = e.clientWidth - 100
const newH = e.clientHeight - 90
if (newW < 265 || newH < 240) { if (newW < 265 || newH < 240) {
return return
} }
baseElem.style.width = newW + "px" document.getElementById("drGallery").style.width = newW + "px"
baseElem.style.height = newH + "px" document.getElementById("drGallery").style.height = newH + "px"
} }
const moveToHash = () => { const moveToHash = () => {
@ -109,11 +103,6 @@ const moveToHash = () => {
window.location.href = url + hash window.location.href = url + hash
} }
const openToNew = () => {
const url = sources[i][0]
window.open(url, "_blank")
}
const preloadImgs = async () => { const preloadImgs = async () => {
for (let s of sources) { for (let s of sources) {
let img = new Image() let img = new Image()
@ -128,39 +117,27 @@ const keyUpEvent = async (e) => {
return return
} }
switch (e.key) { if (e.key === keys[0]) {
case keys[0]: sizeDown(document.getElementById("drGallery"))
sizeDown() } else if (e.key === keys[1]) {
break sizeUp(document.getElementById("drGallery"))
case keys[1]: } else if (e.key === keys[2]) {
sizeUp() prevImg()
break } else if (e.key === keys[3]) {
case keys[2]: nextImg()
prevImg() } else if (e.key === keys[4]) {
break moveToHash()
case keys[3]:
nextImg()
break
case keys[4]:
moveToHash()
break
case keys[5]:
openToNew()
break
} }
} }
const createElements = () => { const createElements = () => {
const limitElem = document.getElementsByClassName("boardBanner")[0] const limitElem = document.getElementsByClassName("boardBanner")[0]
const newNode = document.createElement("div") const newNode = document.createElement("div")
newNode.innerHTML = `<div id="drGallery" class="reply drDrag drag"> newNode.innerHTML = `<div id="drGallery" class="reply">
<div id="drHeader">Gallery</div> <div id="drHeader" class="drag drDrag">Gallery</div>
<div id="drContainer"><img id="drImg" src="" alt="" /></div> <div id="drContainer"><img id="drImg" src="" alt="" /></div>
</div>` </div>`
const initW = "265px"
const initH = Math.round(265 * ratioMultiplier) + "px"
const stylesheet = document.createElement("style") const stylesheet = document.createElement("style")
stylesheet.innerText = `#drGallery { stylesheet.innerText = `#drGallery {
position: absolute; position: absolute;
@ -168,28 +145,33 @@ const createElements = () => {
font-weight: bold; font-weight: bold;
text-align: center; text-align: center;
border: 1px solid black; border: 1px solid black;
width: ${initW}; width: 265px;
height: ${initH}; height: 240px;
min-width: ${initW}; min-width: 265px;
min-height: ${initH}; min-height: 240px;
max-width: 100%;
max-height: 100%;
margin: 0px;
display: none; display: none;
flex-direction: column;
} }
#drHeader { #drHeader {
z-index: 10;
min-height: max-content; min-height: max-content;
max-height: max-content;
padding: 5px; padding: 5px;
cursor: move;
} }
#drContainer { #drContainer {
width: inherit; width: inherit;
height: 100%; height: 85%;
position: relative; position: relative;
} }
#drContainer img { #drContainer img {
max-height: 100%;
max-width: 100%; max-width: 100%;
max-height: 98%;
width: auto; width: auto;
height: auto; height: auto;
position: absolute; position: absolute;
@ -202,17 +184,14 @@ const createElements = () => {
document.head.appendChild(stylesheet) document.head.appendChild(stylesheet)
document.body.insertBefore(newNode, limitElem) document.body.insertBefore(newNode, limitElem)
document.getElementsByClassName("navLinks desktop")[0].innerHTML += document.getElementsByClassName("navLinks desktop")[0].innerHTML += " [<a href='javascript:toggleGalleryVisibility()'>Gallery</a>]"
" [<a href='javascript:toggleGalleryVisibility()'>Gallery</a>]"
} }
const collectSources = () => { const collectSources = () => {
let sources = [] let sources = []
const fileDivs = document.getElementsByClassName("fileThumb") const fileDivs = document.getElementsByClassName("fileThumb")
const hashPrefix = document const hashPrefix = document.getElementsByClassName("postNum")[0].children[0].hash.slice(0, 3)
.getElementsByClassName("postNum")[0]
.children[0].hash.slice(0, 3)
for (let e of fileDivs) { for (let e of fileDivs) {
const s = e.href.split(".") const s = e.href.split(".")
@ -230,16 +209,15 @@ const collectSources = () => {
} }
window.toggleGalleryVisibility = () => { window.toggleGalleryVisibility = () => {
if (baseElem.style.display === "flex") { if (baseElem.style.display === "block") {
baseElem.style.display = "none" baseElem.style.display = "none"
document.removeEventListener("keyup", keyUpEvent, false) document.removeEventListener("keyup", keyUpEvent, false)
} else { } else {
baseElem.style.display = "flex" baseElem.style.display = "block"
document.addEventListener("keyup", keyUpEvent, false) document.addEventListener("keyup", keyUpEvent, false)
} }
} }
const ratioMultiplier = window.innerHeight / window.innerWidth
createElements() createElements()
let i = 0 let i = 0
@ -247,6 +225,7 @@ let imgs = []
const sources = collectSources() const sources = collectSources()
preloadImgs().then(() => console.log("4c-gallery: All images loaded")) preloadImgs().then(() => console.log("4c-gallery: All images loaded"))
const baseElem = document.getElementById("drGallery") const baseElem = document.getElementById("drGallery")
const imgElem = document.getElementById("drImg") const imgElem = document.getElementById("drImg")
dragElement(baseElem) dragElement(baseElem)

View File

@ -1,27 +1,26 @@
// ==UserScript== // ==UserScript==
// @name 4c-image-expander // @name 4c-image-expander
// @description General media expander // @description General media expander
// @author ae // @namespace Violentmonkey Scripts
// @namespace Violentmonkey Scripts // @match *://boards.4chan*.org/*/thread/*
// @match *://boards.4chan*.org/*/thread/* // @exclude *://boards.4chan*.org/*/catalog
// @exclude *://boards.4chan*.org/*/catalog // @version 1.0
// @version 1.0 // ==/UserScript==
// ==/UserScript==
window.toggleImgs = () => {
window.toggleImgs = () => { const data = document.getElementsByClassName("fileThumb")
const data = document.getElementsByClassName("fileThumb")
for (let i = 0; i < data.length; ++i) {
for (let i = 0; i < data.length; ++i) { let img_data = data[i].getElementsByTagName("img")
let img_data = data[i].getElementsByTagName("img") if (img_data[0].className === "fileDeletedRes retina") {
if (img_data[0].className === "fileDeletedRes retina") { continue
continue } else if (img_data.length === 1) {
} else if (img_data.length === 1) { ImageExpansion.expand(img_data[0])
ImageExpansion.expand(img_data[0]) } else {
} else { ImageExpansion.contract(img_data[1])
ImageExpansion.contract(img_data[1]) }
} }
} }
}
const parentElem = document.getElementsByClassName("navLinks desktop")[0]
const parentElem = document.getElementsByClassName("navLinks desktop")[0] parentElem.innerHTML += " [<a href='javascript:toggleImgs()'>Toggle</a>]"
parentElem.innerHTML += " [<a href='javascript:toggleImgs()'>Toggle</a>]"

View File

@ -0,0 +1,29 @@
// ==UserScript==
// @name y-image-expander
// @description General media expander
// @author 17ms
// @license MIT License
// @namespace Violentmonkey Scripts
// @match *://ylilauta.org/*
// @version 1.0
// ==/UserScript==
const toggleImages = () => {
const mediaJpg = document.querySelectorAll("a.jpg")
const mediaPng = document.querySelectorAll("a.png")
for (let i = 0; i < mediaJpg.length; ++i) {
mediaJpg[i].click()
}
for (let i = 0; i < mediaPng.length; ++i) {
mediaPng[i].click()
}
}
const activateLink = document.createElement("button")
const parentElem = document.getElementById("navbar")
activateLink.innerText = "Toggle"
activateLink.style.fontSize = "9px"
activateLink.onclick = () => toggleImages()
parentElem.append(activateLink)