// ==UserScript==
// @name Pinterest Plus
// @namespace https://greasyfork.org/users/102866
// @description Show full size + working middle click to open new tab + open original image.
// @include https://*.pinterest.*/*
// @author TiLied
// @version 0.6.01
// @grant GM_openInTab
// @grant GM_listValues
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_deleteValue
// @require https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js
// @grant GM.openInTab
// @grant GM.listValues
// @grant GM.getValue
// @grant GM.setValue
// @grant GM.deleteValue
// @downloadURL none
// ==/UserScript==
class PinterestPlus
{
constructor()
{
console.log("Pinterest Plus v" + GM.info.script.version + " initialization");
this.urls = [""];
this._FirstTime();
this._SetCSS();
}
_SetCSS()
{
document.head.append("");
document.head.insertAdjacentHTML("beforeend", ``);
document.head.insertAdjacentHTML("beforeend", ``);
document.head.insertAdjacentHTML("beforeend", ``);
document.head.insertAdjacentHTML("beforeend", ``);
document.head.insertAdjacentHTML("beforeend", ``);
document.head.insertAdjacentHTML("beforeend", ``);
document.head.append("");
}
async _FirstTime()
{
if (this.HasValueGM("ppFullSize", false))
{
this.btnOn = await GM.getValue("ppFullSize");
}
//Console log prefs with value
console.log("*prefs:");
console.log("*-----*");
let vals = await GM.listValues();
//Find out that var in for block is not local... Seriously js?
for (let i = 0; i < vals.length; i++)
{
console.log("*" + vals[i] + ":" + await GM.getValue(vals[i]));
}
console.log("*-----*");
}
Main()
{
if (!document.URL.match("/pin/"))
return;
this.urls = [""];
let buttonDiv = document.createElement("div");
let buttonButton = document.createElement("button");
let buttonText = document.createTextNode("Full Size");
let parentDiv = document.querySelector("div[data-test-id='closeupActionBar']>div>div, div[data-test-id='UnauthBestPinCardBodyContainer']>div>div>div, div.UnauthStoryPinCloseupBody__container>div>div, div[data-test-id='CloseupDetails']");
if (typeof parentDiv === "undefined" || parentDiv == null)
{
console.error("parentDiv:", parentDiv);
return;
}
buttonButton.appendChild(buttonText);
buttonDiv.appendChild(buttonButton);
buttonButton.id = "myBtn";
parentDiv.appendChild(buttonDiv);
//
let queryCloseup = document.querySelector("div[data-test-id='CloseupMainPin'], div.reactCloseupScrollContainer");
if (typeof queryCloseup === "undefined" || queryCloseup == null || queryCloseup.length === 0)
{
console.error("div[data-test-id='pin']:first, div.reactCloseupScrollContainer:", queryCloseup);
return;
}
let div = document.querySelector("#pp_divFullSize");
if (div == null)
{
div = document.createElement("div");
div.id = "pp_divFullSize";
queryCloseup.prepend(div);
}
div.style.display = "none";
if (this.btnOn)
{
buttonButton.classList.add("ppTrue");
div.style.display = "grid";
}
this.Events(buttonButton);
this.Core(buttonButton);
this.UrlHandler();
}
Core(btn)
{
let time = Date.now();
let url = new URL(document.URL);
let regU = document.URL.match(/\/(\d+)\/|pin\/([\w].+\w+)\//);
let id = regU[1];
if (typeof id === "undefined")
id = regU[2];
if (typeof id === "undefined")
{
//TODO! not through request!
}
let urlRec = "https://" + url.host + "/resource/PinResource/get/?source_url=/pin/" + id + "/&data={%22options%22:{%22field_set_key%22:%22detailed%22,%22id%22:%22" + id + "%22},%22context%22:{}}&_=" + time;
fetch(urlRec)
.then((response) =>
{
return response.json();
})
.then((r) =>
{
if (r["resource_response"]["status"] === "success")
{
console.log(r["resource_response"]["data"]);
let pin = r["resource_response"]["data"];
if (pin["videos"] != null)
{
let k0 = Object.keys(pin["videos"]["video_list"])[0];
pp.urls[0] = pin["videos"]["video_list"][k0]["url"];
btn.setAttribute('title', "" + pin["videos"]["video_list"][k0]["width"] + "px x " + pin["videos"]["video_list"][k0]["height"] + "px")
return;
}
if (pin["story_pin_data"] != null)
{
let sp = pin["story_pin_data"]["pages"];
for (let i in sp)
{
if (pp.urls[0] === "")
{
pp.urls[0] = sp[i]["image"]["images"]["originals"]["url"];
continue;
}
pp.urls.push(sp[i]["image"]["images"]["originals"]["url"]);
}
return;
}
pp.urls[0] = pin["images"]["orig"]["url"];
btn.setAttribute("title", "" + pin["images"]["orig"]["width"] + "px x " + pin["images"]["orig"]["height"] + "px");
if (pp.btnOn)
pp.Show(pp.urls[0]);
return;
} else
{
console.error(r);
}
});
}
Events(btn)
{
btn.addEventListener('mousedown', async function (e)
{
if ((e.which === 3))
{
if (pp.btnOn)
{
GM.setValue("ppFullSize", false);
btn.classList.remove("ppTrue");
pp.btnOn = false;
} else
{
GM.setValue("ppFullSize", true);
btn.classList.add("ppTrue");
pp.btnOn = true;
}
//console.log("right");
}
if ((e.which === 1))
{
pp.Show(pp.urls[0]);
let _div = document.querySelector("#pp_divFullSize");
if (_div.style.display === "none")
_div.style.display = "grid";
else
_div.style.display = "none";
//console.log("left");
}
if ((e.which === 2))
{
for (let i in pp.urls)
{
GM.openInTab(pp.urls[i]);
}
//console.log("middle");
}
e.preventDefault();
});
}
Show(url)
{
let img = document.querySelector("#pp_img");
if (img != null)
{
img.setAttribute("src", url);
} else
{
img = document.createElement("img");
img.id = "pp_img";
img.setAttribute("src", url);
let _div = document.querySelector("#pp_divFullSize");
_div.prepend(img);
}
}
//Handler for url
UrlHandler()
{
this.oldHash = window.location.pathname;
this.Check;
let that = this;
let detect = function ()
{
if (that.oldHash !== window.location.pathname)
{
that.oldHash = window.location.pathname;
setTimeout(function () { pp.Main(); }, 1500);
}
};
this.Check = setInterval(function () { detect(); }, 250);
}
//Start
//async Methods/Functions GM_VALUE
async HasValueGM(nameVal, optValue)
{
let vals = await GM.listValues();
if (vals.length === 0)
{
if (optValue !== undefined)
{
GM.setValue(nameVal, optValue);
return true;
} else
{
return false;
}
}
if (typeof nameVal !== "string")
{
return alert("name of value: '" + nameVal + "' are not string");
}
for (let i = 0; i < vals.length; i++)
{
if (vals[i] === nameVal)
{
return true;
}
}
if (optValue !== undefined)
{
GM.setValue(nameVal, optValue);
return true;
} else
{
return false;
}
}
async DeleteValuesGM(nameVal)
{
let vals = await GM.listValues();
if (vals.length === 0 || typeof nameVal !== "string")
{
return;
}
switch (nameVal)
{
case "all":
for (let i = 0; i < vals.length; i++)
{
if (vals[i] !== "adm")
{
GM.deleteValue(vals[i]);
}
}
break;
case "old":
for (let i = 0; i < vals.length; i++)
{
if (vals[i] === "debug" || vals[i] === "debugA")
{
GM.deleteValue(vals[i]);
}
}
break;
default:
for (let i = 0; i < vals.length; i++)
{
if (vals[i] === nameVal)
{
GM.deleteValue(nameVal);
}
}
break;
}
}
async UpdateGM(what)
{
var gmVal;
switch (what)
{
case "options":
gmVal = JSON.stringify(options.values);
GM.setValue("pp_options", gmVal);
break;
default:
alert("class:Options.UpdateGM(" + what + "). default switch");
break;
}
}
//async Methods/Functions GM_VALUE
//End
}
let pp;
window.onload = function ()
{
pp = new PinterestPlus();
setTimeout(() =>
{
pp.Main();
console.log(pp);
}, 1250);
};