您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Linkifies all images in the Twitter Home stream. These links point to the :orig version while the stream content is modified to use the :small variant to increase performance.
当前为
- // ==UserScript==
- // @name Twitter Home - clickable links to images
- // @namespace twitter_home_linkify
- // @version 1.0.0
- // @license GNU AGPLv3
- // @description Linkifies all images in the Twitter Home stream. These links point to the :orig version while the stream content is modified to use the :small variant to increase performance.
- // @author marp
- // hhhhomepageURL
- // @include https://twitter.com/
- // @include https://twitter.com/*
- // @include https://pbs.twimg.com/media/*
- // @exclude https://twitter.com/settings
- // @exclude https://twitter.com/settings/*
- // @run-at document-end
- // ==/UserScript==
- function createImageLinks(myDoc, myContext) {
- //console.info("createImageLinks: ", myContext);
- if (myDoc===null) myDoc= myContext;
- if (myDoc===null) return;
- if (myContext===null) myContext= myDoc;
- var matches;
- var tmpstr;
- matches=myDoc.evaluate("//div[contains(@class,'AdaptiveMedia-photoContainer')]/img",
- 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=getCleanImageURL(el.getAttribute("src"), false);
- // console.info("cleanurl: ", tmpstr);
- // only need ":small" variant for tream/thumbnail display (save bandwidth and increase performance)
- el.setAttribute("src", tmpstr+":small");
- // create dorect link to ":orig" image - best way to access by opening in new tab via "middle-click")
- insertLinkElement(myDoc, el, tmpstr+":orig", getFilename(tmpstr));
- } catch (e) { console.warn("error: ", e); }
- }
- }
- }
- function insertLinkElement(myDoc, wrapElement, linkTarget, downloadName) {
- var newnode;
- var parentnode;
- newnode = myDoc.createElement("a");
- newnode.setAttribute("href", linkTarget);
- newnode.setAttribute("target", "_blank");
- newnode.setAttribute("download", downloadName);
- parentnode = wrapElement.parentNode;
- parentnode.replaceChild(newnode, wrapElement);
- newnode.appendChild(wrapElement);
- }
- function getCleanImageURL(imageurl) {
- var pos;
- var pos2;
- pos = imageurl.toLowerCase().lastIndexOf(":");
- pos2 = imageurl.toLowerCase().indexOf("/");
- if (pos >= 0 && pos > pos2) {
- return imageurl.substring(0, pos);
- } else {
- return imageurl;
- }
- }
- function getFilename(imageurl) {
- return getCleanImageURL(imageurl).substring(imageurl.toLowerCase().lastIndexOf("/")+1);
- }
- // Two very different actions depending on if this is on twitter.com or twing.com
- if (window.location.href.includes('pbs.twimg.com/media')){
- var image;
- var url;
- image = document.querySelector('img');
- url = image.src;
- insertLinkElement(document, image, getCleanImageURL(url)+":orig", getFilename(url));
- }
- else
- {
- // 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);
- });
- });
- });
- // configuration of the observer
- // NOTE: subtree is false as the wanted nodes are direct children of <ol id="posts"> -> notable performance improvement
- var config = { attributes: false, childList: true, characterData: false, subtree: false };
- // pass in the target node (<ol> element contains all dashboard posts), as well as the observer options
- var postsmatch = document.evaluate("//ol[@id='stream-items-id']", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
- //console.info("postsmatch: ", postsmatch);
- var postsnode = postsmatch.singleNodeValue;
- //console.info("postsnode: ", postsnode);
- //process already loaded nodes (the initial posts before scrolling down for the first time)
- createImageLinks(document, postsnode);
- //start the observer for new nodes
- observer.observe(postsnode, config);
- }