a random operate banner

/operate/ - Endchan Operations

Let us know what's up


New Reply on thread #29379
X
Max 20 files0 B total
[New Reply]

Index | Catalog | Banners | Logs
Posting mode: Reply [Return]


thumbnail of js.jpg
thumbnail of js.jpg
js jpg
(39.59 KB, 1280x720)
Userscripts are a way to add extra functionality to a site using Javascript.
To use them, add either the Violentmonkey or Tampermonkey extension to your browser.
https://violentmonkey.github.io/
https://www.tampermonkey.net/

> Where To Get Userscripts

GitHub Gists: https://gist.github.com/search?q=%3D%3DUserScript%3D%3D (Search for UserScript)
Greasy Fork: https://greasyfork.org/en

> Userscript Development Resources

How To Write A Userscript: https://simply-how.com/enhance-and-fine-tune-any-web-page-the-complete-user-scripts-guide
GM_* API: https://violentmonkey.github.io/api/gm/
thumbnail of stikstikstik.mp4
thumbnail of stikstikstik.mp4
stikstikst... mp4
(3.53 MB, 576x1024 h264)
This is a userscript that lets you view images and videos on hover.  It needs a few usability improvements, but it mostly works.

// UserScript
// @name        endchan.org media on hover
// @namespace   Violentmonkey Scripts
// @match       https://endchan.org/*/res/*.html*
// @grant       none
// @version     1.1
// @author      -
// @description Display media by hovering over it.
// /UserScript

function createHoverImageContainer() {
  const div = document.createElement("div")
  div.id = "hoverImage"
  const img = document.createElement("img")
  div.appendChild(img)
  return div
}

function createHoverVideoContainer() {
  const div = document.createElement("div")
  div.id = "hoverVideo"
  return div
}

function deriveVideoSrc(imgSrc) {
  const m = imgSrc.match(RegExp("/.media/(t_)(.*)-video(.*)"))
  const videoSrc = /.media/${m[2]}-video${m[3]}.${m[3]}
  return { src: videoSrc, type: video/${m[3]} }
}

function displayOnHover(ev) {
  const target = ev.target
  const parent = target.parentElement
  const hi = document.getElementById("hoverImage")
  const hii = hi.querySelector("img")
  const hv = document.getElementById("hoverVideo")

  //console.log(target, parent)
  if (target.tagName  "IMG" && parent.classList.contains("imgLink")) {
    hii.src = parent.href
    hi.classList.add("enabled")
  }
  if (target.tagName  "IMG" && parent.tagName  "SPAN") {
    hv.classList.add("enabled")
    const hvv = document.createElement("video")
    hvv.setAttribute("controls", "true")
    hvv.setAttribute("autoplay", "true")
    hv.appendChild(hvv)
    const r = deriveVideoSrc(target.src)
    hvvs = document.createElement("source")
    hvvs.type = r.type
    hvvs.src = https://endchan.org${r.src}
    hvv.append(hvvs)
    hvv.play()
  }
}

function hideOnLeave(ev) {
  const target = ev.target
  const parent = target.parentElement
  const hi = document.getElementById("hoverImage")
  const hii = hi.querySelector("img")
  const hv = document.getElementById("hoverVideo")

  //console.log(target, parent)
  if (target.tagName  "IMG" && parent.classList.contains("imgLink")) {
    hii.src = parent.href
    hi.classList.remove("enabled")
  }
  if (target.tagName  "IMG" && parent.tagName  "SPAN") {
    //hv.classList.remove("enabled")
    hvv = hv.querySelector("video")
    hv.classList.remove("enabled")
    hvv.remove()
  }
}

const css = `
#hoverImage {
  display: none;
  position: fixed;
  top: 0;
  right: 0;
}

#hoverImage.enabled {
  display: block;
}

#hoverImage img {
  max-width: 100vw;
  max-height: 100vh;
}

#hoverVideo {
  display: none;
  position: fixed;
  top: 0;
  right: 0;
}

#hoverVideo.enabled {
  display: block;
}

#hoverVideo video {
  max-width: 100vw;
  max-height: 100vh;
}
`

// Add CSS
let style = document.createElement("style");
style.type = "text/css";
style.appendChild(document.createTextNode(css));
document.head.appendChild(style);

// setup container for image
document.body.append(createHoverImageContainer())
document.body.append(createHoverVideoContainer())

// setup event handlers
document.addEventListener('mouseover', displayOnHover)
document.addEventListener('mouseout', hideOnLeave)



Version 1.2
- Works on both endchan.org and endchan.net.
- Fixed bug when overlapping hovered elements confused the script.


// UserScript
// @name        endchan.org media on hover
// @namespace   Violentmonkey Scripts
// @match       https://endchan.*/*/res/*.html
// @match       https://endchan.*/*/
// @grant       none
// @version     1.2
// @author      -
// @description Display media by hovering over it.
// /UserScript

function createHoverImageContainer() {
  const div = document.createElement("div")
  div.id = "hoverImage"
  const img = document.createElement("img")
  div.appendChild(img)
  return div
}

function createHoverVideoContainer() {
  const div = document.createElement("div")
  div.id = "hoverVideo"
  return div
}

function deriveVideoSrc(imgSrc) {
  const m = imgSrc.match(RegExp("/.media/(t_)(.*)-video(.*)"))
  const videoSrc = /.media/${m[2]}-video${m[3]}.${m[3]}
  return { src: videoSrc, type: video/${m[3]} }
}

function displayOnHover(ev) {
  const target = ev.target
  const parent = target.parentElement
  const hi = document.getElementById("hoverImage")
  const hii = hi.querySelector("img")
  const hv = document.getElementById("hoverVideo")

  //console.log(target, parent)
  if (target.tagName  "IMG" && parent.classList.contains("imgLink")) {
    hii.src = parent.href
    hi.classList.add("enabled")
  }
  if (target.tagName  "IMG" && parent.tagName  "SPAN") {
    hv.classList.add("enabled")
    const hvv = document.createElement("video")
    hvv.setAttribute("controls", "true")
    hvv.setAttribute("autoplay", "true")
    hv.appendChild(hvv)
    const r = deriveVideoSrc(target.src)
    hvvs = document.createElement("source")
    hvvs.type = r.type
    hvvs.src = ${r.src}
    hvv.append(hvvs)
    hvv.play()
  }
}

function hideOnLeave(ev) {
  const target = ev.target
  const parent = target.parentElement
  const hi = document.getElementById("hoverImage")
  const hii = hi.querySelector("img")
  const hv = document.getElementById("hoverVideo")

  //console.log(target, parent)
  if (target.tagName  "IMG" && parent.classList.contains("imgLink")) {
    hii.src = parent.href
    hi.classList.remove("enabled")
  }
  if (target.tagName  "IMG" && parent.tagName  "SPAN") {
    //hv.classList.remove("enabled")
    hvv = hv.querySelector("video")
    hv.classList.remove("enabled")
    hvv.remove()
  }
}

// https://stackoverflow.com/a/47460565
const css = `
#hoverImage {
  display: none;
  pointer-events: none;
  position: fixed;
  top: 0;
  right: 0;
}

#hoverImage.enabled {
  display: block;
}

#hoverImage img {
  max-width: 100vw;
  max-height: 100vh;
}

#hoverVideo {
  display: none;
  pointer-events: none;
  position: fixed;
  top: 0;
  right: 0;
}

#hoverVideo.enabled {
  display: block;
}

#hoverVideo video {
  max-width: 100vw;
  max-height: 100vh;
}
`

// Add CSS
let style = document.createElement("style");
style.type = "text/css";
style.appendChild(document.createTextNode(css));
document.head.appendChild(style);

// setup container for image
document.body.append(createHoverImageContainer())
document.body.append(createHoverVideoContainer())

// setup event handlers
document.addEventListener('mouseover', displayOnHover)
document.addEventListener('mouseout', hideOnLeave)


thumbnail of image.png
thumbnail of image.png
image png
(34.36 KB, 509x375)
thumbnail of image.png
thumbnail of image.png
image png
(27.72 KB, 519x255)
Userscript to add hoverable images / videos, post inlining, clipboard image pasting, keyboard shortcuts for spoiler, bold text, etc.
Adds various other things as well, and fixes some bugs on endchan (which might since have been fixed), such as posts by certain IDs not updating correctly, and post hiding
https://github.com/JacobSvenningsen/endchan-script



 >>/29385/
- It's interesting that we both decided to position the hovered media in the same spot (the top right).
- More interesting is that autoplay on the mp4 works for your script on the first try.
- I have to look into that to see what you did differently.
- I like the settings UI, too.
- I've never made a settings UI for any of my userscripts, but it's something that would be nice to have sometimes.


 >>/29388/
You learned something new. That's the most important part of it.
And next time you find something annoying about a website, you'll have a much easier time fixing it with a userscript too.

 >>/29389/
If new posts are loaded throug page auto refreshing, the script isn't applied, as it only runs once. That's what the MutationObserver handles.
Moreover, posts present on the page when you load the thread, and posts which gets added during auto-refresh, varies slightly.

thumbnail of Screenshot 2025-09-17 at 16-29-27 _jp_ - _faaag_ - Female Announcer and Alternative General #119.3.png
thumbnail of Screenshot 2025-09-17 at 16-29-27 _jp_ - _faaag_ - Female Announcer and Alternative General #119.3.png
Screenshot... png
(362.9 KB, 363x969)
I made a rough proof-of-concept that tries to fix tiktok embeds here.  The code is too long to post, so you can find it here:

https://git.vern.cc/gg/endchan-scripts

Example
 >>/jp/1507/
https://www.tiktok.com/@mina14504/video/7546151220046613776 [Embed]

It's really rough, but it does manage to successfully embed tiktok videos.


Скрипт на скрытие Капсодауна

Работает на Tampermonkey (как минимум).
Распространяется на основной домен, на magrathea, а также .onion'ы.

Ссылка::
https://pastebin.com/XcCnMUru

Спасибо bb-мочуху за бездействие ^^



Post(s) action:


Moderation Help
Scope:
Duration: Days

Ban Type:


0 replies | 0 file
New Reply on thread #29379
Max 20 files0 B total