您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Add direct links to the picture to the Google Image Search results.
- // ==UserScript==
- // @name Google Images direct links 2
- // @version 2.5.1
- // @description Add direct links to the picture to the Google Image Search results.
- // @namespace Google
- // @author Benjamin Philipp <dev [at - please don't spam] benjamin-philipp.com>
- // @include /^https?:\/\/(www\.)?google\.[a-z\.]{2,5}\/search.*tbm=isch.*/
- // @include /^https?:\/\/(www\.)?google\.[a-z\.]{2,5}\/search.*udm=2.*/
- // @require https://openuserjs.org/src/libs/sizzle/GM_config.js
- // @run-at document-start
- // @grant GM_xmlhttpRequest
- // @grant GM_getValue
- // @grant GM_setValue
- // @grant GM_registerMenuCommand
- // @grant GM_openInTab
- // @connect *
- // ==/UserScript==
- /* eslint no-unused-vars: "off", no-implicit-globals: "off", curly: "off" */
- /* globals GM_config, trustedTypes */
- var updateInterval = 1000;
- var maxtries = 100;
- var selector = `.rg_di.rg_bx a.rg_l img:not(.linksdone),
- #islrg div.isv-r a.wXeWr.islib img:not(.linksdone),
- div#res div#rso h3 a g-img img:not(.linksdone),
- div#islmp div.islrc a[role="button"] img:not(.linksdone)
- `;
- var idle = true;
- GM_config.init(
- {
- 'id': 'MyConfig',
- 'title': GM_info.script.name + ' Settings',
- 'fields': {
- 'newTabByDefault': {
- 'label': '<b>Open Links in new tab by default</b> <br /><i>ON:</i> Opens images in new tab; hold <kbd>Ctrl</kbd> to open directly <br /><i>OFF:</i> Opens images directly; hold <kbd>Ctrl</kbd> to open in new tab',
- 'type': 'checkbox',
- 'default': true
- },
- 'openInBackground': {
- 'label': '<b>Open new tabs in the background (without activating them)</b>',
- 'type': 'checkbox',
- 'default': false
- },
- 'uncropImages': {
- 'label': '<b>Uncrop images</b> <br /><i>Google crops most preview images slightly. Turning this setting on will show the thumbnails uncropped</i>',
- 'type': 'checkbox',
- 'default': false
- },
- 'uncropOnHover': {
- 'label': '<b>Uncrop on hover</b> <br /><i>Show the full thumbnail on mouse hover</i>',
- 'type': 'checkbox',
- 'default': true
- },
- 'noRadius': {
- 'label': '<b>Remove round corners</b> <br /><i>remove the "rounded corners" (CSS: border-radius) effect. Some thumbnails seem to have actually rounded corners baked in, we can\'t do anything about those</i>',
- 'type': 'checkbox',
- 'default': true
- }
- },
- 'css': `
- #MyConfig .field_label{
- font-weight: normal;
- font-size: 13px;
- }
- #MyConfig kbd{
- border: 1px solid #ccc;
- background: #eee;
- border-radius: 3px;
- padding: 1px 3px;
- font-family: consolas, monospace;
- }`,
- 'events': {
- 'init': setClasses,
- 'save': setClasses
- }
- });
- function setClasses(){
- console.log(document.body);
- document.body.classList.toggle("nocrop", GM_config.get("uncropImages"));
- document.body.classList.toggle("nocropHover", GM_config.get("uncropOnHover"));
- document.body.classList.toggle("noRadius", GM_config.get("noRadius"));
- // console.log(GM_config.get("uncropImages"));
- // console.log(GM_config.get("uncropOnHover"));
- // console.log(GM_config.get("noRadius"));
- // console.log(document.body.classList);
- }
- GM_registerMenuCommand(GM_info.script.name + ' Settings', function(){
- GM_config.open();
- });
- // Custom TrustedTypes handling: Google's policies are giving us trouble in some configs.
- var needsTrustedHTML = false;
- var passThroughFunc = function(string, sink) {
- return string;
- };
- var TTPName = "toast";
- var TP = {createHTML: passThroughFunc, createScript: passThroughFunc, createScriptURL: passThroughFunc};
- try{
- if(typeof window.isSecureContext !== 'undefined' && window.isSecureContext){
- if (window.trustedTypes && window.trustedTypes.createPolicy){
- if(trustedTypes.defaultPolicy){
- console.log("TT Default Policy exists");
- TP = trustedTypes.defaultPolicy; // Is the default policy permissive enough? If it already exists, best not to overwrite it
- }
- else{
- TP = window.trustedTypes.createPolicy(TTPName, TP);
- }
- console.log("TP is now", TP);
- needsTrustedHTML = true;
- }
- else{
- console.log("Uh-oh");
- }
- }
- }catch(e){
- console.log(e);
- }
- function updatePage()
- {
- if(document.querySelector("#directLinkStyles") == null){
- // console.log("TP:", TP);
- let c = document.createElement("STYLE");
- c.id = "directLinkStyles";
- c.innerHTML = trustedHTML(`
- .linkToTarget{
- box-shadow: 3px 5px 10px rgba(0,0,0,0.5);
- cursor: default;
- position: absolute;
- right:0; top:0;
- opacity: 0;
- background-color: rgba(255,255,255,0.5);
- transition: background-color 0.5s, opacity 0.5s
- }
- .failed .linkToTargetlink{
- color: rgba(230,100,100)!important;
- }
- a:hover .linkToTarget{
- opacity: 0.6;
- }
- a:hover .linkToTarget:hover{
- opacity: 1;
- }
- .linksdone:hover .linkToTarget{
- cursor: pointer;
- }
- .linkToTargetLink{
- color: rgba(155,177,233, 1)!important;
- font-size: 22pt;
- display: block;
- font-weight: bold;
- text-decoration: none!important;
- transition: color 0.5s, font-size 0.5s, padding 0.5s;
- }
- .temp .linkToTargetLink{
- color: rgba(200,200,200)!important;
- }
- .linkToTargetLink:hover{
- color: rgba(155,177,233, 1)!important;
- padding:8px;
- font-size: 30pt;
- }
- body.nocrop div#islmp div#islrg div.islrc div.isv-r a.islib,
- body.nocrop a .F0uyec,
- body.nocrop a img,
- body.nocrop .mNsIhb .YQ4gaf,
- body.nocrop .H8Rx8c img,
- body.nocropHover div#islmp div#islrg div.islrc div.isv-r a.islib:hover,
- body.nocropHover a .F0uyec:hover,
- body.nocropHover a:hover img,
- body.nocropHover .mNsIhb .YQ4gaf:hover,
- body.nocropHover .H8Rx8c img:hover{
- overflow: visible;
- z-index: 100;
- object-fit: contain;
- }
- body.noRadius a .F0uyec,
- body.noRadius div .eA0Zlc.mkpRId,
- body.noRadius div .cC9Rib{
- border-radius: 0;
- }
- </style>`);
- document.querySelector("head").appendChild(c);
- }
- document.querySelectorAll(selector).forEach(function(e){
- if(e.classList.contains("linksdone")) // Why is the selector not working??
- return;
- var c = document.createElement("DIV");
- c.className="linkToTarget";
- c.innerHTML = trustedHTML("<a class='linkToTargetLink'>↗️</a>");
- e.parentElement.appendChild(c);
- c.querySelector("a.linkToTargetLink").onclick = clickLink;
- e.classList.add("linksdone");
- });
- }
- function clickLink(e){
- e.stopPropagation();
- e.preventDefault();
- var t = e.target;
- waitForLink(t, e);
- return false;
- }
- function waitForLink(t, e){
- var tp = t.parentElement.closest("a");
- console.log(tp);
- var imin = tp.href.indexOf("imgurl=");
- var openInNew = e.which==2;
- if(GM_config.get("newTabByDefault")){
- if(!e.ctrlKey)
- openInNew = true;
- }
- else{
- if(e.ctrlKey)
- openInNew = true;
- }
- if(imin<0)
- {
- var $e = tp;
- var restries = tp.getAttribute("resTries")?tp.getAttribute("resTries")*1+1:1;
- if(restries==1){
- $e.click();
- // tp.querySelector("img")?.click();
- tp.querySelector("img").click();
- setTimeout(function(){
- $e.click();
- }, 200);
- // $(tp).find("img").contextmenu();
- // $(tp).trigger({
- // type: 'mousedown',
- // which: 2
- // });
- // waitfor("#islsp a[aria-label='Close']", function(o){
- // $(o).click(); // somehow doesn't close the details view either
- // });
- }
- // #Sva75c > div.A8mJGd.NDuZHe.OGftbe-N7Eqid-H9tDt > div.LrPjRb > div.AQyBn > div.tvh9oe.BIB1wf > c-wiz > div > div > div > div > div.v6bUne.qmmlRd > div.p7sI2.PUxBg > a > img.sFlh5c.pT0Scc.iPVvYb
- // console.log("try", restries);
- tp.setAttribute("resTries", restries);
- if(tp.getAttribute("resTries")*1>=maxtries){
- console.log("This Link won't come up with a good fragment: " + tp.querySelector("img").src);
- tp.classList.add("linksdone");
- tp.classList.add("failed");
- tp.querySelector(".linkToTarget span").innerHTML = TP.createHTML("x");
- return true;
- }
- if(!tp.classList.contains("linkswait")){
- tp.classList.add("linkswait");
- tp.querySelector(".linkToTarget").classList.add("temp");
- tp.querySelector(".linkToTarget span").innerHTML = TP.createHTML("...");
- }
- // console.log("Not ready");
- setTimeout(function(){
- console.log("try again");
- waitForLink(t, e);
- }, 200);
- return true;
- }
- else{
- console.log("got link");
- var linkconts = tp.href.substr(imin+7);
- var piclink = linkconts.substr(0,linkconts.indexOf("&"));
- var reflink = linkconts.substr(linkconts.indexOf("imgrefurl=")+10);
- reflink = decodeURIComponent(reflink.substr(0, reflink.indexOf("&")));
- piclink = decodeURIComponent(piclink);
- tp.classList.remove("linkswait");
- let tl = tp.querySelector(".linkToTarget");
- if(tl){
- tl.classList.remove("temp");
- tl.querySelector("a.linkToTargetLink").href = piclink;
- }
- else
- console.log("Link not found?", tp);
- tp.classList.add("linksdone");
- if(e.which == 3)
- return false; // Don't open new tab on right click
- // console.log("Background?", GM_config.get("openInBackground"));
- if(openInNew){
- GM_openInTab(piclink, {
- active: !GM_config.get("openInBackground"),
- insert: true,
- parent: true
- });
- }
- else{
- location.href = piclink;
- }
- }
- }
- function trustedHTML(string) {
- if (!needsTrustedHTML)
- return string;
- const TT = TP.createHTML(string);
- // console.log(typeof TT, TT);
- return TT;
- }
- setInterval(updatePage, updateInterval);
- updatePage();