IMDb details page links

Adds some links to IMDb details page

当前为 2015-09-19 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name IMDb details page links
  3. // @namespace IMDb.com
  4. // @description Adds some links to IMDb details page
  5. // @include *imdb.com/title/*
  6. // @require http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js
  7. // @require https://cdnjs.cloudflare.com/ajax/libs/jqModal/1.3.0/jqModal.min.js
  8. // @grant GM_getValue
  9. // @grant GM_setValue
  10. // @grant GM_registerMenuCommand
  11. // @grant GM_addStyle
  12. // @version 2.1.1
  13. // ==/UserScript==
  14.  
  15. // CHANGELOG
  16. // 2.1.1 - Use JSON instead of eval
  17. //
  18. // 2.1 - Add up/down for editing sites
  19. // 2.0 - Make links modifiable
  20. // 1.1 - Update URLs
  21.  
  22. // https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String/Trim
  23. if(!String.prototype.trim) {
  24. String.prototype.trim = function () {
  25. return this.replace(/^\s+|\s+$/g,'');
  26. };
  27. }
  28.  
  29. function defaultSites() {
  30. return [{title:"Google", url:"http://www.google.com/search?q={title} {year}"},
  31. {title:"Subtitles", url:"http://www.google.com/search?q={title} {year} subtitles"},
  32. {title:"YouTube", url:"http://www.youtube.com/results?search_query={title} {year}"},
  33. {title:"iCheckMovies", url:"http://www.icheckmovies.com/search/movies/?query={imdbid}"},
  34. {title:"RottenTomatoes", url:"http://www.rottentomatoes.com/search/?search={title}"},
  35. {title:"HDBits", url:"http://hdbits.org/browse2.php#film/dir=null&searchtype=film&actorfilm=film&search={imdbid}"},
  36. {title:"AsianDVDClub", url:"http://asiandvdclub.org/browse.php?search={imdbid}&descr=1"},
  37. {title:"PassThePopCorn", url:"http://passthepopcorn.me/torrents.php?searchstr={imdbid}"},
  38. {title:"KaraGarga", url:"http://karagarga.in/browse.php?incldead=&d=&sort=&search={imdbidn}&search_type=imdb"},
  39. {title:"Cinemageddon", url:"http://cinemageddon.net/browse.php?search={imdbid}&proj=0"},
  40. {title:"AsiaTorrents", url:"https://avistaz.to/torrents?in=1&search={title}&tags=&type=0&language=0&subtitle=0&discount=0&rip_type=0&video_quality=0&tv_type=0&uploader="},
  41. {title:"TehConnection", url:"http://tehconnection.eu/torrents.php?searchstr={title}"},
  42. {title:"WhatTheMovie", url:"http://whatthemovie.com/search?t=movie&q={imdbid}"},
  43. {title:"Mubi", url:"http://www.google.com/search?q=site:mubi.com {title} {year}"},
  44. {title:"ListAL", url:"http://www.google.com/search?q=site:listal.com {title} {year}"},
  45. {title:"HanCinema", url:"http://www.hancinema.net/googlesearch.php?cx=partner-pub-1612871806153672%3A2t41l1-gajp&cof=FORID%3A10&ie=ISO-8859-1&hl=en&q={title}"},
  46. {title:"Criticker", url:"http://www.criticker.com/?st=movies&h={imdbid}&g=Go"},
  47. {title:"iCM Highest Rated",url:"http://themagician.host56.com/highestrated/search/#search={imdbid}"}];
  48. }
  49.  
  50. /**
  51. * @brief Find header element
  52. * @return Header element or null if not found
  53. */
  54. function findHeader() {
  55. var $header = null;
  56. if(location.href.indexOf("reference") === -1 &&
  57. location.href.indexOf("combined") === -1) {
  58. var $overview = $("#overview-top");
  59. if($overview !== null) {
  60. $header = $overview.find(".header:first");
  61. }
  62. }
  63. else {
  64. $header = $("#tn15title");
  65. }
  66. return $header;
  67. }
  68.  
  69. function parseConstants() {
  70. var $header = findHeader();
  71. if($header.length === 0) {
  72. return null;
  73. }
  74. var matches = $header.text().replace(/(\r\n|\n|\r)/gm,"").match(/(.*)(?:[\s]+)(?:.*)\(.*([0-9]{4})/);
  75. var imdb_id = window.location.href.match(/(tt[0-9]+)/)[0];
  76. return {title: matches[1].trim(),
  77. year: matches[2].trim(),
  78. imdbid: imdb_id,
  79. imdbid_n: imdb_id.replace("tt", "")};
  80. }
  81.  
  82. var App = {
  83. links: [],
  84. init: function() {
  85. App.buildLinks();
  86. // Add modal
  87. GM_addStyle('.jqmWindow {display: none; position: absolute; font-family: verdana, arial, sans-serif; ' +
  88. 'background-color:#fff; color:#000; padding: 12px 30px; overflow-y: scroll; font-size: 14px} .jqmOverlay { background-color:#000 }');
  89. var cfgMainHtml = '<div id="dialog" class="jqmWindow"></div>';
  90. $(cfgMainHtml).css({
  91. top: '17%', left: '50%', marginLeft: '-425px', width: '850px', height: '450px'
  92. }).appendTo('body');
  93. $('#dialog').jqm();
  94. },
  95. buildLinks: function() {
  96. var sites = GM_getValue("sites");
  97. if(sites !== undefined && sites !== null) {
  98. sites = JSON.parse(sites);
  99. }
  100. else {
  101. GM_setValue("sites", JSON.stringify(defaultSites()));
  102. sites = defaultSites();
  103. }
  104. var $root = $("#pagecontent");
  105. $root.css("position", "relative");
  106. $("#linkbar").remove();
  107. var $c = $('<div></div>');
  108. $c.attr("id", "linkbar");
  109. $c.css({width: "150px", padding: "15px",
  110. textAlign: "right", position: "absolute", top: "8px",
  111. left: "-170px", backgroundColor: "#fff"});
  112. $root.append($c);
  113. // Render sites
  114. for(var i = 0; i < sites.length; ++i) {
  115. App.addSite(sites[i]);
  116. }
  117. },
  118. addSite: function(site) {
  119. var c = parseConstants();
  120. if(c === null) {
  121. return;
  122. }
  123. var url = site.url.replace("{title}", c.title)
  124. .replace("{year}", c.year)
  125. .replace("{imdbid}", c.imdbid)
  126. .replace("{imdbidn}", c.imdbid_n);
  127. var $root = $("#linkbar");
  128. var $link = $("<a></a>");
  129. $link.attr("href", url);
  130. $link.text(site.title);
  131. $link.css({display: "block", marginBottom: "2px"});
  132. $root.append($link);
  133. },
  134. displayEditor: function() {
  135. var sites = GM_getValue("sites");
  136. if(sites !== undefined) {
  137. sites = JSON.parse(sites);
  138. }
  139. var c = parseConstants();
  140. var out = '<div><p>{title} = ' + c.title + '</p>'
  141. + '<p>{year} = ' + c.year
  142. + ' {imdbid} = ' + c.imdbid
  143. + ' {imdbidn} = ' + c.imdbid_n + '</p><table>';
  144. var addRow = function(i, title, url) {
  145. return '<tr class="site-' + i + '"><td style="width: 6%"><a href="#" class="delete">Delete</a></td><td style="width: 18%"><input type="text" style="width: 100%" value="'
  146. + title + '"></td><td style="width: 62%"><input type="text" style="width: 100%" value="'
  147. + url + '"></td><td style="width: 14%; padding-left: 8px"><a href="#" class="up">Up</a> | <a href="#" class="down">Down</a></td></tr>';
  148. }
  149. for(var i = 0; i < sites.length; ++i) {
  150. out += addRow(i, sites[i].title, sites[i].url);
  151. }
  152. out += '</table><p><button id="add">Add new</button> <button id="restore">Restore defaults</button></p>';
  153. $("#dialog").html(out);
  154. $("#dialog").jqmShow();
  155. $("#dialog").on("change input paste", "tr[class^=site] input", App.saveEditor);
  156. $("#dialog").on("click", "a.delete", function(e){
  157. e.preventDefault();
  158. var response = window.confirm("Delete?");
  159. if(!response) {
  160. return;
  161. }
  162. $(this).parent().parent().remove();
  163. App.saveEditor();
  164. });
  165. $("#dialog").on("click", "a.up, a.down", function(e) {
  166. e.preventDefault();
  167. var $t = $(this);
  168. var $parent = $t.parent().parent();
  169. if($t.is(".up")) {
  170. $parent.insertBefore($parent.prev());
  171. }
  172. else {
  173. $parent.insertAfter($parent.next());
  174. }
  175. App.saveEditor();
  176. });
  177. $("#add", "#dialog").on("click", function() {
  178. var $table = $("table", "#dialog");
  179. $table.append(addRow($table.find("tr").length, '', ''));
  180. });
  181. $("#restore", "#dialog").on("click", function() {
  182. var response = window.confirm("Restore defaults? (This will remove all links!)");
  183. if(!response) {
  184. return;
  185. }
  186. GM_setValue("sites", JSON.stringify(defaultSites()));
  187. App.buildLinks();
  188. $("#dialog").jqmHide();
  189. });
  190. },
  191. saveEditor: function() {
  192. // Save result
  193. var $rows = $("tr", "#dialog");
  194. var mapped = $rows.map(function(index, elem){
  195. var $fields = $(elem).find("input");
  196. return {title: $fields.eq(0).val(), url: $fields.eq(1).val()};
  197. });
  198. GM_setValue("sites", JSON.stringify(mapped.get()));
  199. App.buildLinks();
  200. }
  201. };
  202.  
  203. $(window).ready(App.init);
  204.  
  205. GM_registerMenuCommand("Edit sites", App.displayEditor);