您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
NEW Tumblr UI - READ DESCRIPTION. Linkifies all images in the tumblr dashboard and side-view streams. The script also displays the time-stamp of each post in the upper right corner.
当前为
// ==UserScript== // @name Tumblr Dashboard - clickable links to images and display time-stamps // @namespace tumblr_dashboard_linkify // @version 2.0.1 // @license GNU AGPLv3 // @description NEW Tumblr UI - READ DESCRIPTION. Linkifies all images in the tumblr dashboard and side-view streams. The script also displays the time-stamp of each post in the upper right corner. // @author marp // @homepageURL https://greasyfork.org/en/users/204542-marp // @include https://www.tumblr.com/dashboard // @include https://www.tumblr.com/dashboard/* // @include https://www.tumblr.com/likes // @include https://www.tumblr.com/likes/* // @run-at document-end // ==/UserScript== function nsResolver(prefix) { if (prefix === 'svg') { return 'http://www.w3.org/2000/svg'; } else { return null; } } function doNothing_tumblr_dashboard_linkify(event) { e.preventDefault(); return false; } function insertLinkElement(myDoc, wrapElement, linkTarget) { var newnode; var parentnode; newnode = myDoc.createElement("a"); newnode.setAttribute("href", linkTarget); newnode.setAttribute("target", "_blank"); newnode.addEventListener("click", doNothing_tumblr_dashboard_linkify, true); parentnode = wrapElement.parentNode; parentnode.replaceChild(newnode, wrapElement); newnode.appendChild(wrapElement); } function getHighResImageURL(imageElement) { var srcarray; var tmpstr; srcarray = imageElement.getAttribute("srcset").split(","); // QUICK AND DIRTY - assume largest image is the last in array... seems to be true for Tumblr... but might change... tmpstr = srcarray[srcarray.length-1].trim(); return tmpstr.substring(0, tmpstr.indexOf(" ")); } function createImageLinks(myDoc, myContext) { if (myDoc===null) myDoc= myContext; if (myDoc===null) return; if (myContext===null) myContext= myDoc; var matches; var tmpstr; // the img might be added as part of a whole pos (first expr) - or just the img or the div/img, in which case we need to check if the image is part of the correct hierarchy (second expr) matches=myDoc.evaluate(".//article[@aria-label]//button[@aria-label]//figure/div/img[@role='img' and @srcset and @sizes]" + " | " + "self::img[@role='img' and @srcset and @sizes and parent::div/parent::figure/ancestor::button[@aria-label]/ancestor::article[@aria-label]]" + " | " + "self::div/img[@role='img' and @srcset and @sizes and parent::div/parent::figure/ancestor::button[@aria-label]/ancestor::article[@aria-label]]", myContext, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); for(var i=0, el; (i<matches.snapshotLength); i++) { el=matches.snapshotItem(i); if (el) { try { // console.info("matched-element: ", el); tmpstr=getHighResImageURL(el); insertLinkElement(myDoc, el.parentNode, tmpstr); } catch (e) { console.warn("error: ", e); } } } } function displayDateTime(myDoc, myContext) { if (myDoc===null) myDoc= myContext; if (myDoc===null) return; if (myContext===null) myContext= myDoc; var matches; var singlematch; var singlenode; var moreoptionsnode; var permalinknode; var tmpstr; var newnode; matches=myDoc.evaluate(".//article[@aria-label]//header[@role='banner']", myContext, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); for(var i=0, el; (i<matches.snapshotLength); i++) { el=matches.snapshotItem(i); if (el) { try { // console.info("matched-element: ", el); // find the grandchild div that contains the "More Options" Ellipsis button // make sure that this div is the last child (if it is not then this script might have run already) singlematch = myDoc.evaluate("((./div/div)[last()])[.//button//svg:svg]", el, nsResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null); singlenode = singlematch.singleNodeValue; if (singlenode) { moreoptionsnode = singlenode; // find the permalink element - this has the timestamp as the title attribute (mouseover popup) singlematch = myDoc.evaluate("./a[@role='button' and @target='_blank' and @title]", el, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); singlenode = singlematch.singleNodeValue; if (singlenode) { permalinknode = singlenode; // get the class attrib of the "more options" div - we'll create a second div with same class tmpstr = moreoptionsnode.getAttribute("class"); // create new node with the timestamp text newnode = myDoc.createElement("div"); newnode.setAttribute("class", tmpstr); newnode.setAttribute("style", "font-size: 85%"); newnode.setAttribute("displaytimestampscript", "1"); // flag that this node was added my this script newnode.textContent = permalinknode.getAttribute("title"); moreoptionsnode.parentNode.appendChild(newnode); } } } catch (e) { console.warn("error: ", e); } } } } // create an observer instance and iterate through each individual new node var observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { mutation.addedNodes.forEach(function(addedNode) { createImageLinks(mutation.target.ownerDocument, addedNode); displayDateTime(mutation.target.ownerDocument, addedNode); }); mutation.removedNodes.forEach(function(removedNode) { // TUMBLR - OH NO YOU DON'T !! if (removedNode.hasAttribute("displaytimestampscript")) { mutation.target.insertBefore(removedNode, mutation.nextSibling); } }); }); }); // configuration of the observer var config = { attributes: false, childList: true, characterData: false, subtree: true }; // new twitter UI has few stable IDs - need to start very high with "root" node var singlematch = document.evaluate("//body[@id='tumblr']/div[@id='root']", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); //console.info("singlematch: ", singlematch); var rootnode = singlematch.singleNodeValue; //start the observer for new nodes observer.observe(rootnode, config); //process already loaded nodes (the initial posts before scrolling down for the first time) createImageLinks(document, rootnode); displayDateTime(document, rootnode);