IMDB Copy Buttons V2

Buttons

当前为 2018-12-02 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name IMDB Copy Buttons V2
  3. // @namespace http://kmcgurty.com/
  4. // @version 1.2.1
  5. // @description Buttons
  6. // @author Kmcgurty
  7. // @match https://www.imdb.com/title/*
  8. // @match https://www.imdb.com/name/*
  9. // @connect omdbapi.com
  10. // @grant GM_addStyle
  11. // @grant GM_setClipboard
  12. // @grant GM_xmlhttpRequest
  13. // ==/UserScript==
  14.  
  15. //~README~
  16. //
  17. //to use the "Reveal original titles" feature, you need to get an API key from OMDB.
  18. //you can get that from here: http://www.omdbapi.com/apikey.aspx
  19. //select "FREE! (1,000 daily limit)"
  20. //use is "For a personal IMDB.com userscript"
  21. //input your email and follow the instructions given.
  22. //insert the key you receive inbetween the quotations below (ex. var API_KEY = "ab123c4d";)
  23.  
  24. var API_KEY = "";
  25.  
  26. //- You can ignore everything below here -
  27.  
  28. var cssTransitionTime = 750;
  29. var OMDB_ERROR = false;
  30.  
  31. GM_addStyle(`.copybutton:active,.revealoriginalnamesbutton:active{background-color:#ccc3ac}.copybutton{font-size:13px;padding:0;margin:0 0 0 2px;width:50px;height:18px;position:relative;overflow:hidden}.copybutton::before{content:"Copy";position:absolute;left:7px}.copybutton::after{content:"Copied";position:absolute;left:2px;top:15px;pointer-events:none}.copybutton::after,.copybutton::before{transition:all ${cssTransitionTime*.35}ms}.copybutton.clicked::after{top:-1px}.copybutton.unclicked::after{top:18px}.copybutton.clicked::before{top:-18px}.copybutton.unclicked::before{top:-1px}.copybutton:focus{outline:0}#yearbutton::before{content:"+Year";left:4px}#idbutton::before{content:"ID";left:15px}.itemprop .copybutton{margin-left:5px}.revealoriginalnamesbutton{font-size:13px;padding:0;margin:0 0 0 5px;height:18px}.revealoriginalnamesbutton::before{content:"Reveal Original Titles"}.countwrapper{font-size:16px;padding-top:10px}`);
  32.  
  33. (function main(){
  34. addTitleButtons();
  35. addOtherButtons();
  36.  
  37. if(window.location.href.match("/name/")) {
  38. relocateAltNames();
  39. }
  40. })();
  41.  
  42. function revealOriginalName(element, id){
  43. GM_xmlhttpRequest({
  44. method: "GET",
  45. url: `https://www.omdbapi.com/?i=${id}&apikey=${API_KEY}`,
  46. onload: function(res) {
  47. var response = JSON.parse(res.responseText);
  48.  
  49. if(response.Response != "False"){
  50. var originalTitle = response.Title;
  51. if(originalTitle != undefined){
  52. var span = document.createElement("span");
  53. span.setAttribute("class", "originaltitle");
  54. var text = document.createTextNode(" - " + originalTitle);
  55. span.appendChild(text)
  56.  
  57. if(element.textContent != originalTitle && !element.parentNode.querySelector(".originaltitle")){
  58. element.parentNode.appendChild(span);
  59. updateCounter();
  60. }
  61. }
  62. } else {
  63. if(!OMDB_ERROR && response.Error != "Error getting data."){
  64. OMDB_ERROR = true;
  65. alert(response.Error);
  66. } else {
  67. console.log(response.Error, "Movie ID: " + id, element);
  68. }
  69. }
  70. },
  71. onerror: function(err, a, b){
  72. alert("Error in making the request: ", err, a, b);
  73. }
  74. });
  75. }
  76.  
  77. function updateCounter(){
  78. var parent = document.querySelector(".revealoriginalnamesbutton").parentNode;
  79.  
  80. //init the html if not created already
  81. if(parent.querySelector(".count") == null){
  82. var wrapper = document.createElement("span");
  83. wrapper.setAttribute("class", "countwrapper");
  84. var text = document.createTextNode("Matches found: ");
  85. wrapper.appendChild(text);
  86. var span = document.createElement("span");
  87. span.setAttribute("class", "count");
  88. span.appendChild(document.createTextNode("0"));
  89. wrapper.appendChild(span);
  90. parent.appendChild(wrapper);
  91. }
  92.  
  93. var count = parseInt(parent.querySelector(".count").innerHTML);
  94. parent.querySelector(".count").innerHTML = count + 1;
  95. }
  96.  
  97. function addTitleButtons(){
  98. var title = document.querySelector("h3[itemprop='name'], h1 [class='itemprop']");
  99.  
  100. var titleButton = createButton(title.childNodes[0].textContent.trim());
  101. title.appendChild(titleButton);
  102.  
  103. if(window.location.href.match("/title/")){
  104. var yearButton = createButton(title.textContent.replace(/ +\n +/, " ").trim());
  105. yearButton.setAttribute("id", "yearbutton");
  106. title.appendChild(yearButton);
  107.  
  108. var altTitle = title.nextSibling;
  109. if(altTitle.textContent.trim()){
  110. var altButton = createButton(altTitle.textContent.replace(/ +\n +/, " ").trim());
  111. altTitle.parentNode.insertBefore(altButton, altTitle.nextSibling.nextSibling);
  112. }
  113. }
  114.  
  115. var IDButton = createButton(window.location.pathname.split('/')[2]);
  116. IDButton.setAttribute("id", "idbutton");
  117. title.appendChild(IDButton);
  118. }
  119.  
  120. function addOtherButtons(){
  121. var toAppend = document.querySelectorAll(".itemprop a, .crew_list a, .writers_list a, .filmo-row b");
  122.  
  123. for(var i = 0; i < toAppend.length; i++){
  124. var copyButton = createButton(toAppend[i].textContent.trim());
  125.  
  126. if(window.location.href.match("/title/")){
  127. var td = document.createElement("td");
  128. td.appendChild(copyButton);
  129.  
  130. toAppend[i].parentElement.parentElement.appendChild(td);
  131. } else if(window.location.href.match("/name/")) {
  132. toAppend[i].parentElement.querySelector(".year_column").appendChild(copyButton);
  133. }
  134. }
  135.  
  136.  
  137. //reveal original name button + event listener
  138. //h2 containing "Filmography" doesn't have an id, this is a workaround to get that element
  139. var h2ToAppend = document.evaluate("//h2[contains(., 'Filmography')]", document, null, XPathResult.ANY_TYPE, null).iterateNext();
  140.  
  141. if(h2ToAppend){
  142. var button = document.createElement('button');
  143. button.setAttribute("class", "revealoriginalnamesbutton linkasbutton-secondary");
  144. h2ToAppend.appendChild(button);
  145.  
  146. button.addEventListener("click", function(){
  147. var elements = document.querySelectorAll(".filmo-category-section b a");
  148. var ids = [];
  149.  
  150. for(var i = 0; i < elements.length; i++){
  151. var href = elements[i].href.split("/");
  152. ids[i] = href[4];
  153. }
  154.  
  155. for(i = 0; i < ids.length; i++){
  156. var error = revealOriginalName(elements[i], ids[i]);
  157. }
  158. });
  159. }
  160. }
  161.  
  162. function relocateAltNames(){
  163. var altNames = document.querySelector("#details-akas");
  164. if(altNames){
  165. var names = altNames.textContent.replace(/\n|Alternate Names:\W +/gm, "").trim().split(" | ").join(", ");
  166.  
  167. var h4 = document.createElement("h4");
  168. h4.setAttribute("class", "inline");
  169. var text = document.createTextNode("Alternative names:");
  170. h4.appendChild(text);
  171.  
  172. var altNamesDiv = document.createElement("div");
  173. altNamesDiv.setAttribute("class", "alt-names txt-block");
  174. altNamesDiv.appendChild(h4)
  175. text = document.createTextNode(names);
  176. altNamesDiv.appendChild(text);
  177.  
  178. var copyButton = createButton(names);
  179. altNamesDiv.appendChild(copyButton);
  180.  
  181. document.querySelector("#overview-top").appendChild(altNamesDiv);
  182. }
  183. }
  184.  
  185. function createButton(copytext){
  186. var button = document.createElement('button');
  187. button.setAttribute("class", "copybutton linkasbutton-secondary unclicked");
  188. button.setAttribute("data-copytext", copytext);
  189.  
  190. button.addEventListener("click", function(e){
  191. GM_setClipboard(e.target.getAttribute("data-copytext"));
  192. e.target.setAttribute("class", "copybutton linkasbutton-secondary clicked");
  193.  
  194. setTimeout(function(){
  195. e.target.setAttribute("class", "copybutton linkasbutton-secondary unclicked");
  196. }, cssTransitionTime);
  197. });
  198.  
  199. return button;
  200. }