Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ==UserScript==
- // @name Card Data
- // @namespace Violentmonkey Scripts
- // @match *://rentry.co/*
- // @match *://rentry.org/*
- // @match *://*catbox.moe/*
- // @grant none
- // @version 1.2
- // @author me :)
- // @description 8/17/2021, 5:50:10 PM
- // @require https://cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js
- // @grant GM_xmlhttpRequest
- // ==/UserScript==
- // Card Data Shower: This script shows a box of the json data for an NAI card
- // Hover over the card and press control to make the box appear
- // Hover over the box and press shift to make the box go away
- // Double click on the box to copy just the json data
- // things you might want to change
- const triggerKey = 17; // 17 is control
- const closeKey = 16; // 16 is shift
- const boxWidth = "800px";
- const boxHeight = "600px";
- const boxMargin = "-300px 0 0 -400px";
- const fontSize = "0.7em";
- // other constants
- const pngSignature = [137, 80, 78, 71, 13, 10, 26, 10];
- const chunkSignature = [116, 69, 88, 116];
- const chunkStart = 33; // beginning of the NAI data chunk
- const typeStart = chunkStart + 4;
- const dataStart = chunkStart + 8;
- jQuery.noConflict();
- jQuery( document ).ready(function( $ ) {
- var source; // identifying images by src
- // styles
- $("head").append(`
- <style>
- #follow {
- position: fixed;
- z-index: 100;
- top: 50%;
- left: 50%;
- margin: ${boxMargin};
- width: ${boxWidth};
- height: ${boxHeight};
- background-color: white;
- overflow: auto;
- border-style: solid;
- border-width: 3px;
- }
- #jsonData {
- font-size: ${fontSize};
- color: black;
- }
- #copyIndicator {
- opacity: 0;
- color: red;
- }
- .cardHeader {
- color: black;
- }
- .cardEntry {
- color: black;
- }
- .keyList {
- color: green;
- }
- </style>
- `);
- // wait until new images appear
- waitForKeyElements ("img[cardEvent!='set']", function() {
- $("img[cardEvent!='set']").on("mouseover",function() {
- source = this.src;
- if (source[0] == '/') {
- source = "https:" + source;
- }
- $(document).on("keydown",function(e) {
- if (e.keyCode == triggerKey) {
- getImageData(source);
- }
- });
- }).on("mouseleave",function() {
- $(document).off("keydown");
- });
- $("img").attr("cardEvent","set"); // stops repeated event assignment(?)
- });
- // Gets the data from the card and writes
- function getImageData(image) {
- return GM_xmlhttpRequest({
- method: "GET",
- url: image,
- responseType: "arraybuffer",
- onloadend: function(responseObject) {
- const byteArray = new Uint8Array(responseObject.response);
- if (arraysEqual(byteArray.slice(0,8), pngSignature) && arraysEqual(byteArray.slice(typeStart,typeStart+4), chunkSignature)) {
- $("#follow").remove();
- let dataLength = getLength(byteArray.slice(chunkStart,chunkStart + 4));
- jsonData = atob(String.fromCharCode(...byteArray.slice(dataStart + 8, dataStart+dataLength)));
- objData = JSON.parse(jsonData);
- // create the infobox and fill it up
- $("body").prepend("<div id='follow'></div>");
- $("#follow").prepend(`<h3 class="cardHeader">Entries</h3>`);
- for (let i = 0; i < objData.entries.length; i++) {
- $("#follow").append(`<p class="cardEntry">${objData.entries[i].text}</p>`);
- }
- $("#follow").append(`<h3 class="cardHeader">JSON Data</h3>`);
- $("#follow").append(`<p id='jsonData'> ${jsonData} <p>`);
- $("#follow").append(`<p id='copyIndicator'>json copied</p>`);
- followEvents();
- }
- }
- });
- }
- // Reads the 4 bytes as given in decimal and returns proper value for data length
- function getLength(lengthBytes) {
- var total = 0;
- for (let i = 0; i < lengthBytes.length; i++) {
- total += lengthBytes[i] * (256**(lengthBytes.length - i - 1));
- }
- return total;
- }
- // sets the event handlers for the infobox
- function followEvents() {
- $("#follow").on("mouseover", function() {
- $(document).on("keydown",function(e) {
- if (e.keyCode == closeKey) {
- $("#follow").remove();
- }
- });
- }).on("mouseleave", function() {
- $(document).off("keydown");
- }).on("dblclick", function() {
- navigator.clipboard.writeText($("#jsonData").text());
- $("#copyIndicator").css("opacity", 1);
- $("#copyIndicator").fadeTo("slow", 0);
- });
- }
- // checks if two (ordered) arrays are equal
- function arraysEqual(a, b) {
- if (a === b) return true;
- if (a == null || b == null) return false;
- if (a.length !== b.length) return false;
- for (var i = 0; i < a.length; ++i) {
- if (a[i] !== b[i]) return false;
- }
- return true;
- }
- // Gotten from https://gist.github.com/BrockA/2625891 ; for handling ajax stuff
- function waitForKeyElements (
- selectorTxt, /* Required: The jQuery selector string that
- specifies the desired element(s).
- */
- actionFunction, /* Required: The code to run when elements are
- found. It is passed a jNode to the matched
- element.
- */
- bWaitOnce, /* Optional: If false, will continue to scan for
- new elements even after the first match is
- found.
- */
- iframeSelector /* Optional: If set, identifies the iframe to
- search.
- */
- ) {
- var targetNodes, btargetsFound;
- if (typeof iframeSelector == "undefined")
- targetNodes = $(selectorTxt);
- else
- targetNodes = $(iframeSelector).contents ()
- .find (selectorTxt);
- if (targetNodes && targetNodes.length > 0) {
- btargetsFound = true;
- /*--- Found target node(s). Go through each and act if they
- are new.
- */
- targetNodes.each ( function () {
- var jThis = $(this);
- var alreadyFound = jThis.data ('alreadyFound') || false;
- if (!alreadyFound) {
- //--- Call the payload function.
- var cancelFound = actionFunction (jThis);
- if (cancelFound)
- btargetsFound = false;
- else
- jThis.data ('alreadyFound', true);
- }
- } );
- }
- else {
- btargetsFound = false;
- }
- //--- Get the timer-control variable for this selector.
- var controlObj = waitForKeyElements.controlObj || {};
- var controlKey = selectorTxt.replace (/[^\w]/g, "_");
- var timeControl = controlObj [controlKey];
- //--- Now set or clear the timer as appropriate.
- if (btargetsFound && bWaitOnce && timeControl) {
- //--- The only condition where we need to clear the timer.
- clearInterval (timeControl);
- delete controlObj [controlKey]
- }
- else {
- //--- Set a timer, if needed.
- if ( ! timeControl) {
- timeControl = setInterval ( function () {
- waitForKeyElements ( selectorTxt,
- actionFunction,
- bWaitOnce,
- iframeSelector
- );
- },
- 300
- );
- controlObj [controlKey] = timeControl;
- }
- }
- waitForKeyElements.controlObj = controlObj;
- }
- });
Add Comment
Please, Sign In to add comment