您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Download/Share Images Faster
当前为
- // ==UserScript==
- // @name TweetDeck Image Assistant
- // @namespace http://ejew.in/
- // @version 0.7
- // @description Download/Share Images Faster
- // @author EntranceJew
- // @match https://tweetdeck.twitter.com/*
- // @require https://cdn.rawgit.com/eligrey/FileSaver.js/5ed507ef8aa53d8ecfea96d96bc7214cd2476fd2/FileSaver.min.js
- // @noframes
- // @grant none
- // ==/UserScript==
- /*
- 0.7 - apparently getting gif sources works most reliably inside callbacks
- 0.6 - hotfix to prevent redundant page reloading with stream-media seek methods
- 0.5 - video links no longer destroy links, ctrl+click the timestamp to copy the tweet link, ctrl+click the link icon to prepare multi-image tweets for discord
- 0.4 - changed download icon, added copy links button, videos now don't flash their preview, videos no longer close your draft tweets panel
- 0.3 - gif support wasn't that hard
- 0.2 - removed debug prints, updated mimes, added video download link, instant-spice now grabs videos
- 0.1 - initial version
- */
- (function() {
- 'use strict';
- var tool_icon = '<li class="tweet-action-item pull-left margin-r--13 margin-l--1">';
- tool_icon += '<a class="js-show-tip tweet-action position-rel" href="#" rel="download" title="" data-original-title="Download">';
- tool_icon += '<i class="icon icon-attachment icon-attachment-toggle txt-center"></i> <span class="is-vishidden"> Download </span>';
- tool_icon += '</a> </li>';
- var link_icon = '<li class="tweet-action-item clipboard pull-left margin-r--13 margin-l--1">';
- link_icon += '<a class="js-show-tip tweet-action position-rel" href="#" rel="hotlink" title="" data-original-title="Hotlink">';
- link_icon += '<i class="icon icon-link icon-link-toggle txt-center"></i> <span class="is-vishidden"> Hotlink </span>';
- link_icon += '</a> </li>';
- var mime_db = {
- jpeg: "image/jpeg",
- jpg: "image/jpeg",
- gif: "image/gif",
- webp: "image/webp",
- mp4: "video/mp4",
- m3u8: "application/x-mpegURL",
- undefined: "text/plain"
- };
- function clipboard_data(html, el) {
- var tmpEl;
- if (typeof el !== "undefined") {
- // you may want some specific styling for your content - then provide a custom DOM node with classes, inline styles or whatever you want
- // just omit that argument for a default div container
- tmpEl = el;
- } else {
- tmpEl = document.createElement("div");
- // since we remove the element immediately we'd actually not have to style it - but IE 11 prompts us to confirm the clipboard interaction and until you click the confirm button, the element would show. so: still extra stuff for IE, as usual.
- tmpEl.style.opacity = 0;
- tmpEl.style.position = "absolute";
- tmpEl.style.pointerEvents = "none";
- tmpEl.style.zIndex = -1;
- }
- // fill it with your HTML
- tmpEl.innerHTML = html;
- // append the temporary node to the DOM
- document.body.appendChild(tmpEl);
- // select the newly added node
- var range = document.createRange();
- range.selectNode(tmpEl);
- window.getSelection().addRange(range);
- // copy
- document.execCommand("copy");
- // and remove the element immediately
- document.body.removeChild(tmpEl);
- }
- // http://stackoverflow.com/a/2091331
- function getQueryVariable(str, variable) {
- var query = str.substring(1);
- var vars = query.split('&');
- for (var i = 0; i < vars.length; i++) {
- var pair = vars[i].split('=');
- if (decodeURIComponent(pair[0]) == variable) {
- return decodeURIComponent(pair[1]);
- }
- }
- console.log('Query variable %s not found', variable);
- }
- function detect_mime(url){
- return mime_db[ /(?:\.([^.]+))?$/.exec(url)[1] ];
- }
- function get_img_data( url, on_load ) {
- var xhr = new XMLHttpRequest();
- xhr.open("GET", url);
- xhr.responseType = "blob";
- xhr.onload = on_load;
- xhr.send();
- }
- function download_now( url ){
- if( url.length ){
- get_img_data( url, function( e ){
- var img_name = url.substring( url.lastIndexOf('/')+1 );
- var the_blob = new Blob([this.response], {type: detect_mime(url)});
- saveAs( the_blob, img_name.replace(/:orig$/, "") );
- });
- }
- }
- function nice_url( url, replacement ){
- replacement = replacement || ":orig";
- var bg = url;
- bg = bg.replace('url(','').replace(')','').replace(/\"/gi, "");
- bg = bg.replace(/:thumb$/, "");
- bg = bg.replace(/:small$/, "");
- bg = bg.replace(/:medium$/, "");
- bg = bg.replace(/:large$/, "");
- return bg;
- }
- setInterval(function(){
- $('.stream-item:not([data-ejew])').each(function(){
- var grand_dad = $( this );
- /*
- // for appending to the dropdown menu if we wanted that
- var tool_bar = grand_dad.find('.js-dropdown-content > ul');
- tool_bar.prepend('<li class="is-selectable"><a href="#" data-action="ejew">Spice it up</a></li>');
- */
- // find all the images and store their links in data
- var sources = [];
- var media_type = 'idk';
- if( grand_dad.find('.is-video').length ){
- media_type = 'video';
- sources.push( function( e ){
- var anchor = grand_dad.find('.js-media-image-link');
- var o_target = anchor.attr('target');
- var o_src = anchor.attr('src');
- anchor.attr('target', '');
- anchor.attr('src', '#');
- anchor.click();
- var embeds = $('.js-embeditem');
- while( !embeds.length ){
- embeds = $('.js-embeditem');
- }
- var vid_url = '';
- embeds.each(function(){
- var iframe_src = $( this ).find( 'iframe' ).attr('src');
- vid_url = getQueryVariable( iframe_src, 'video_url' );
- $('.mdl-dismiss .icon-close').click();
- });
- anchor.attr('target', o_target);
- anchor.attr('src', o_src);
- if( vid_url.length ){
- return vid_url;
- }
- });
- } else if( grand_dad.find('.is-gif').length ){
- media_type = 'gif';
- sources.push( function(){
- return grand_dad.find('video.js-media-gif').attr('src');
- });
- } else {
- grand_dad.find('.js-media-image-link, .js-media .media-image').each( function(i, el){
- sources.push( nice_url( $( el ).css('background-image'), ":orig" ) );
- });
- if( sources.length ){
- media_type = 'image';
- }
- }
- var orig_link = grand_dad.find("a.txt-small.no-wrap[rel=\"url\"]");
- orig_link.on('click', function(e){
- if( e.ctrlKey ){
- e.preventDefault();
- clipboard_data( $( this ).attr("href") );
- }
- });
- grand_dad.data('ejew-sources', sources);
- grand_dad.data('direct-url', orig_link.attr("href"));
- var new_link = $( link_icon );
- new_link.on('click', function(e){
- var sources = grand_dad.data('ejew-sources');
- for( var i = 0; i < sources.length; i++ ){
- if( typeof( sources[i] ) != "string" ){
- sources[i] = sources[i]( this );
- }
- }
- var the_url = grand_dad.data('direct-url');
- if( e.ctrlKey && sources.length > 1){
- sources[0] = the_url;
- }
- if( sources.length ){
- clipboard_data( sources.join("\n") );
- } else {
- clipboard_data( the_url );
- }
- });
- // make an instance of the toolbar button
- var new_tool = $( tool_icon );
- new_tool.on('click', function(e){
- var sources = grand_dad.data('ejew-sources');
- for( var i = 0; i < sources.length; i++ ){
- var source = sources[i];
- if( typeof( source ) != "string" ){
- source = source( this );
- }
- download_now( source );
- }
- });
- // attach
- var attachment_point = grand_dad.find('ul.tweet-actions > li:nth-last-child(2)');
- attachment_point.before( new_tool );
- attachment_point.before( new_link );
- // prevent loading up this element again
- grand_dad.attr('data-ejew', 'in');
- });
- // make it so that you can copy image source from previews
- $('img.media-img:not([data-ejew])').each(function(){
- $( this ).attr('src', nice_url( $( this ).attr('src') ) );
- $( this ).attr('data-ejew', 'in');
- });
- // provide a download source link in zoomable previews for videos
- $('.js-embeditem:not([data-ejew])').each(function(){
- var iframe_src = $( this ).find( 'iframe' ).attr('src');
- var vid_url = getQueryVariable( iframe_src, 'video_url' );
- var dl_link = $( '<a href="#">Download Source</a>' );
- dl_link.on('click', function(){
- download_now( vid_url );
- });
- $(".med-origlink").after( dl_link );
- $( this ).attr('data-ejew', 'in');
- });
- }, 300);
- })();