TweetDeck Image Assistant

Download/Share Images Faster

当前为 2017-05-18 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name TweetDeck Image Assistant
  3. // @namespace http://ejew.in/
  4. // @version 0.3
  5. // @description Download/Share Images Faster
  6. // @author EntranceJew
  7. // @match https://tweetdeck.twitter.com/*
  8. // @require https://cdn.rawgit.com/eligrey/FileSaver.js/5ed507ef8aa53d8ecfea96d96bc7214cd2476fd2/FileSaver.min.js
  9. // @noframes
  10. // @grant none
  11. // ==/UserScript==
  12. /*
  13. 0.3 - gif support wasn't that hard
  14. 0.2 - removed debug prints, updated mimes, added video download link, instant-spice now grabs videos
  15. 0.1 - initial version
  16. */
  17.  
  18. (function() {
  19. 'use strict';
  20. var wait_for_zoom_delay = 300;
  21.  
  22. var tool_icon = '<li class="tweet-action-item pull-left margin-r--13 margin-l--1">';
  23. tool_icon += '<a class="js-show-tip tweet-action position-rel" href="#" rel="spice" title="" data-original-title="Spice It Up">';
  24. tool_icon += '<i class="icon icon-home icon-home-toggle txt-center"></i> <span class="is-vishidden"> Spice </span>';
  25. tool_icon += '</a> </li>';
  26.  
  27. var mime_db = {
  28. jpeg: "image/jpeg",
  29. jpg: "image/jpeg",
  30. gif: "image/gif",
  31. webp: "image/webp",
  32. mp4: "video/mp4",
  33. m3u8: "application/x-mpegURL",
  34. undefined: "text/plain"
  35. };
  36. // http://stackoverflow.com/a/2091331
  37. function getQueryVariable(str, variable) {
  38. var query = str.substring(1);
  39. var vars = query.split('&');
  40. for (var i = 0; i < vars.length; i++) {
  41. var pair = vars[i].split('=');
  42. if (decodeURIComponent(pair[0]) == variable) {
  43. return decodeURIComponent(pair[1]);
  44. }
  45. }
  46. console.log('Query variable %s not found', variable);
  47. }
  48.  
  49. function detect_mime(url){
  50. return mime_db[ /(?:\.([^.]+))?$/.exec(url)[1] ];
  51. }
  52.  
  53. function get_img_data( url, on_load ) {
  54. var xhr = new XMLHttpRequest();
  55. xhr.open("GET", url);
  56. xhr.responseType = "blob";
  57. xhr.onload = on_load;
  58. xhr.send();
  59. }
  60.  
  61. function download_now( url ){
  62. get_img_data( url, function( e ){
  63. var img_name = url.substring( url.lastIndexOf('/')+1 );
  64. var the_blob = new Blob([this.response], {type: detect_mime(url)});
  65. saveAs( the_blob, img_name.replace(/:orig$/, "") );
  66. });
  67. }
  68.  
  69. function nice_url( url, replacement ){
  70. replacement = replacement || ":orig";
  71. var bg = url;
  72. bg = bg.replace('url(','').replace(')','').replace(/\"/gi, "");
  73. bg = bg.replace(/:thumb$/, "");
  74. bg = bg.replace(/:small$/, "");
  75. bg = bg.replace(/:medium$/, "");
  76. bg = bg.replace(/:large$/, "");
  77. return bg;
  78. }
  79.  
  80. setInterval(function(){
  81. $('.stream-item:not([data-ejew])').each(function(){
  82. var grand_dad = $( this );
  83.  
  84. /*
  85. // for appending to the dropdown menu if we wanted that
  86. var tool_bar = grand_dad.find('.js-dropdown-content > ul');
  87. tool_bar.prepend('<li class="is-selectable"><a href="#" data-action="ejew">Spice it up</a></li>');
  88. */
  89.  
  90. // find all the images and store their links in data
  91. var images = [];
  92. grand_dad.find('.js-media-image-link, .js-media .media-image').each( function(i, el){
  93. images.push( nice_url( $( el ).css('background-image'), ":orig" ) );
  94. });
  95. grand_dad.data('ejew-imgs', images);
  96.  
  97. // make an instance of the toolbar button
  98. var new_tool = $( tool_icon );
  99. new_tool.on('click', function(){
  100. if( grand_dad.find('.is-video').length ){
  101. // video spotted
  102. var anchor = grand_dad.find('.js-media-image-link');
  103. anchor.attr('target', '');
  104. anchor.attr('src', '#');
  105. anchor.click();
  106. setTimeout( function(){
  107. $('.js-embeditem').each(function(){
  108. var iframe_src = $( this ).find( 'iframe' ).attr('src');
  109. var vid_url = getQueryVariable( iframe_src, 'video_url' );
  110. download_now( vid_url );
  111. $('.icon-close').click();
  112. });
  113. }, wait_for_zoom_delay);
  114. } else if( grand_dad.find('.is-gif').length ){
  115. // gif spotted
  116. download_now( grand_dad.find('video.js-media-gif').attr('src') );
  117. } else {
  118. // images I guess
  119. var imgs = grand_dad.data('ejew-imgs');
  120. for( var i = 0; i < imgs.length; i++ ){
  121. download_now( imgs[i] );
  122. }
  123. }
  124. });
  125. // attach
  126. grand_dad.find('ul.tweet-actions > li:nth-last-child(2)').before( new_tool );
  127.  
  128. // prevent loading up this element again
  129. grand_dad.attr('data-ejew', 'in');
  130. });
  131.  
  132. // make it so that you can copy image source from previews
  133. $('img.media-img:not([data-ejew])').each(function(){
  134. $( this ).attr('src', nice_url( $( this ).attr('src') ) );
  135. $( this ).attr('data-ejew', 'in');
  136. });
  137. // provide a download source link in zoomable previews for videos
  138. $('.js-embeditem:not([data-ejew])').each(function(){
  139. var iframe_src = $( this ).find( 'iframe' ).attr('src');
  140. var vid_url = getQueryVariable( iframe_src, 'video_url' );
  141. var dl_link = $( '<a href="#">Download Source</a>' );
  142. dl_link.on('click', function(){
  143. download_now( vid_url );
  144. });
  145. $(".med-origlink").after( dl_link );
  146. $( this ).attr('data-ejew', 'in');
  147. });
  148. }, 300);
  149. })();