Embedded Image Viewer

Embedds the clicked Image on the Current Site, so you can view it without loading the submission Page

Per 06-02-2023. Zie de nieuwste versie.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey, Greasemonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Userscripts.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een gebruikersscriptbeheerder nodig.

(Ik heb al een user script manager, laat me het downloaden!)

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

(Ik heb al een beheerder - laat me doorgaan met de installatie!)

// ==UserScript==
// @name        Embedded Image Viewer
// @namespace   Violentmonkey Scripts
// @match       *://*.furaffinity.net/browse/*
// @match       *://*.furaffinity.net/gallery/*
// @match       *://*.furaffinity.net/search/*
// @match       *://*.furaffinity.net/favorites/*
// @match       *://*.furaffinity.net/controls/favorites/*
// @match       *://*.furaffinity.net/controls/submissions/*
// @match       *://*.furaffinity.net/msg/submissions/*
// @exclude-match *://*.furaffinity.net/view/*
// @grant       none
// @version     1.1
// @author      Midori Dragon
// @description Embedds the clicked Image on the Current Site, so you can view it without loading the submission Page
// @icon        https://www.furaffinity.net/themes/beta/img/banners/fa_logo.png?v2
// @license     MIT
// ==/UserScript==

// jshint esversion: 8

let isShowing = false;
let notClosingElemsArr = [];

document.addEventListener("click", function(event) {
  if (isShowing && !notClosingElemsArr.includes(event.target.id)) {
    event.preventDefault();
    document.getElementById("embeddedElem").remove();
    isShowing = false;
  }
});

for (const figure of document.getElementsByTagName("figure")) {
  figure.addEventListener("click", function(event) {
    if (!event.ctrlKey && !event.target.id.includes("favbutton")) {
      if (event.target.href)
        return;
      else
      event.preventDefault();
      if (!isShowing)
        showImage(figure);
    }
  });
}

async function showImage(figure) {
  const ddmenu = document.getElementById("ddmenu");
  const imageID = figure.id.substring(figure.id.indexOf("-") + 1);
  const favdoc = await getHTML("https://www.furaffinity.net/view/" + imageID);

  await createElements(ddmenu, favdoc, imageID, figure);

  isShowing = true;
}

async function createElements(ddmenu, favdoc, imageID, figure) {
  const margin = 20;
  const favlink = await getfavlink(favdoc);

  let embeddedElem = document.createElement("div");
  embeddedElem.id = "embeddedElem";
  embeddedElem.style.position = "fixed";
  embeddedElem.style.zIndex = "999999";
  embeddedElem.style.width = window.innerWidth + "px";
  embeddedElem.style.height = window.innerHeight + "px";
  embeddedElem.style.background = "rgba(30,33,38,.65)";

  let backgroundElem = document.createElement("div");
  backgroundElem.id = "embeddedBackgroundElem";
  notClosingElemsArr.push(backgroundElem.id);
  backgroundElem.style.position = "fixed";
  backgroundElem.style.display = "flex";
  backgroundElem.style.flexDirection = "column";
  backgroundElem.style.left = "50%";
  backgroundElem.style.transform = "translate(-50%, 0%)";
  backgroundElem.style.marginTop = margin + "px";
  backgroundElem.style.padding = margin + "px";
  backgroundElem.style.background = "rgba(30,33,38,.90)";
  backgroundElem.style.borderRadius = "10px";

  let submissionContainer = document.createElement("a");
  submissionContainer.id = "embeddedSubmissionContainer";
  notClosingElemsArr.push(submissionContainer.id);
  submissionContainer.href = favdoc.querySelector('meta[property="og:url"]').content;

  let submissionImg = favdoc.getElementById("submissionImg");
  submissionImg.id = "embeddedSubmissionImg";
  notClosingElemsArr.push(submissionImg.id);
  submissionImg.removeAttribute("data-fullview-src");
  submissionImg.removeAttribute("data-preview-src");
  submissionImg.style.maxWidth = "inherit";
  submissionImg.style.maxHeight = "inherit";
  submissionImg.style.maxWidth = window.innerWidth - margin * 2 + "px";
  submissionImg.style.maxHeight = window.innerHeight - ddmenu.clientHeight - 38 * 2 - margin * 2 - 100 + "px";
  submissionImg.style.borderRadius = "10px";
  submissionContainer.appendChild(submissionImg);

  backgroundElem.appendChild(submissionContainer);

  let buttonsContainer = document.createElement("div");
  buttonsContainer.id = "embeddedButtonsContainer";
  notClosingElemsArr.push(buttonsContainer.id);
  buttonsContainer.style.marginTop = "20px";
  buttonsContainer.style.marginLeft = "20px";
  buttonsContainer.style.marginRight = "20px";

  let favButton = document.createElement("a");
  favButton.id = "embeddedFavButton";
  notClosingElemsArr.push(favButton.id);
  favButton.type = "button";
  favButton.className = "button standard mobile-fix";
  if (favlink.includes("unfav"))
    favButton.textContent = "-Fav";
  else
    favButton.textContent = "+Fav";
  favButton.style.marginLeft = "4px";
  favButton.style.marginRight = "4px";
  favButton.onclick = function() {
    favButton.textContent = "...";
    favImage(figure, favlink);
  };
  buttonsContainer.appendChild(favButton);

  let downloadButton = document.createElement("a");
  downloadButton.id = "embeddedDownloadButton";
  notClosingElemsArr.push(downloadButton.id);
  downloadButton.type = "button";
  downloadButton.className = "button standard mobile-fix";
  downloadButton.textContent = "Download";
  downloadButton.style.marginLeft = "4px";
  downloadButton.style.marginRight = "4px";
  const downloadLink = await getDownloadLink(favdoc);
  downloadButton.href = downloadLink;
  downloadButton.download = downloadLink.substring(downloadLink.lastIndexOf("/") + 1);
  buttonsContainer.appendChild(downloadButton);

  let closeButton = document.createElement("a");
  closeButton.id = "embeddedCloseButton";
  notClosingElemsArr.push(closeButton.id);
  closeButton.type = "button";
  closeButton.className = "button standard mobile-fix";
  closeButton.textContent = "Close";
  closeButton.style.marginLeft = "4px";
  closeButton.style.marginRight = "4px";
  closeButton.onclick = function() {
    ddmenu.removeChild(embeddedElem);
    isShowing = false;
  };
  buttonsContainer.appendChild(closeButton);

  backgroundElem.appendChild(buttonsContainer);

  embeddedElem.appendChild(backgroundElem);

  ddmenu.appendChild(embeddedElem);
}

async function favImage(figure, favlink) {
  if (!figure)
    return;

  let footer = document.getElementById("footer");
  let iframe = document.createElement("iframe");
  iframe.id = "favIFrame";
  iframe.src = favlink;
  iframe.style.display = "none";
  iframe.addEventListener("load", async function() {
    let favdoc = iframe.contentDocument;
    footer.removeChild(iframe);
    let imageLink = figure.childNodes[0].childNodes[0].childNodes[0].href;
    favlink = await getfavlink(favdoc);
    changeFavButtonLink(favlink, figure);
  });
  footer.appendChild(iframe);
}

async function changeFavButtonLink(favlink, figure) {
  let embeddedFavButton = document.getElementById("embeddedFavButton");
  if (favlink.includes("unfav"))
    embeddedFavButton.textContent = "-Fav";
  else
    embeddedFavButton.textContent = "+Fav";
  embeddedFavButton.onclick = function() {
    embeddedFavButton.textContent = "...";
    favImage(figure, favlink);
  };

  let favButton = figure.querySelector('[type="button"][class="button standard mobile-fix"]');
  if (favButton) {
    if (favlink.includes("unfav")) {
      favButton.textContent = "-Fav";
      favButton.value = "-Fav";
    }
    else {
      favButton.textContent = "+Fav";
      favButton.value = "-Fav";
    }
    favButton.onclick = function() {
      favButton.textContent = "...";
      favImage(figure, favlink);
    };
  }
}

async function getfavlink(subdoc) {
  let buttons = subdoc.querySelectorAll('a[class="button standard mobile-fix"]');
  for (const button of buttons)
    if (button.textContent.includes("Fav") && button.textContent.length <= 4)
      return button.href;
}

async function getDownloadLink(subdoc) {
  let buttons = subdoc.querySelectorAll('a[class="button standard mobile-fix"]');
  for (const button of buttons)
    if (button.textContent.includes("Download"))
      return button.href;
}

async function getHTML(url) {
  try {
    const response = await fetch(url);
    const html = await response.text();
    const parser = new DOMParser();
    const doc = parser.parseFromString(html, "text/html");
    return doc;
  } catch (error) {
    console.error(error);
  }
}