bgmcard

not a card game

目前为 2014-09-09 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name bgmcard
  3. // @namespace bgm/uli
  4. // @description not a card game
  5. // @include http://bgm.tv/*/topic/*
  6. // @include http://bangumi.tv/*/topic/*
  7. // @include http://chii.in/*/topic/*
  8. // @version 0.1.1
  9. // @grant none
  10. // ==/UserScript==
  11.  
  12.  
  13. // card css
  14. var card_css = document.createElement("style");
  15. card_css.textContent = [
  16. ".card_container {position: absolute; transition: left 0.5s, right 0.5s, opacity 0.5s; width: 30em; margin: 1em 0 0 1em; padding: 0 1em; border-radius: 8px; z-index: 50; box-shadow: 2px 2px 5px #999; background-color: rgba(255,255,255,0.9); font-size: 13px; color: #444; border-left: 1em solid #F09199;}",
  17. ".card_container_inner {overflow: hidden; margin: 0 -1em; padding: 1em; border-radius: 8px; border-right: 1em solid rgba(255,255,255,0.9);}",
  18. ".card_content {white-space: pre-wrap; transition: all 0.5s ease; margin-left: 0; width: 30em; max-height: 20em; -moz-columns: auto 30em; -webkit-columns: auto 30em;}",
  19. ".card_cover {float: right; border-color: #C7C7C9 #A9A9AB #858486; border-width: 0 1px 1px 0; border-style: solid; max-width: 10em; max-height: 20em; margin: 0 0 0.5em 0.5em;}",
  20. ".card_link {color: #0084B4 !important;}",
  21. ".card_page {padding-right: 1em; border-top: 1px solid #AAA; display: block; transition: width 0.5s; color: transparent; line-height: 0;}",
  22. ".card_charging {color: #369CF8; font-size: 15px; font-style: italic; font-family: Georgia; padding: 1em 0;}"
  23. ].join("\n");
  24.  
  25. document.body.appendChild(card_css);
  26.  
  27.  
  28. var topmost_card = function(ele) {
  29. for (let x of document.querySelectorAll(".card_container")) {
  30. x.style.zIndex = "49";
  31. x.style.opacity = "0.8";
  32. }
  33. ele.style.zIndex = "50";
  34. ele.style.opacity = "1";
  35. };
  36.  
  37. var set_coordinate = function(ele, rect) {
  38. ele.style.left = window.scrollX + rect.right + "px";
  39. ele.style.top = window.scrollY + rect.top + "px";
  40. };
  41.  
  42.  
  43. // set card --have no card--> refine card -> charge card -> shooting
  44. // --already had--> release card -> shooting
  45.  
  46. var refine_card = function(doc, uri) {
  47.  
  48. var get_element = function(selectors) {
  49. var ele = doc.querySelector(selectors);
  50. if (ele) return ele;
  51. else {
  52. var blank_ele = document.createElement("div");
  53. blank_ele.href = "";
  54. return blank_ele;
  55. }
  56. };
  57.  
  58. var title = get_element(".nameSingle").textContent;
  59. var cover_src = get_element(".cover.thickbox").href;
  60. var info = get_element("#infobox").textContent;
  61. var sum_txt = get_element("#subject_summary, .detail").textContent;
  62.  
  63. var text_trim_join = function(str) {
  64. return str.split('\n').filter(String.trim).map(String.trim).join('\n');
  65. };
  66.  
  67. var card_txt = ['', text_trim_join(info), sum_txt].join('\n\n');
  68.  
  69. var title_link = document.createElement("a");
  70. title_link.className = "card_link";
  71. title_link.textContent = text_trim_join(title);
  72. title_link.href = uri;
  73.  
  74. var cover = document.createElement("img");
  75. cover.className = "card_cover";
  76. cover.src = cover_src;
  77.  
  78. var card = document.createElement("p");
  79. card.className = "card_content";
  80. card.textContent = card_txt;
  81.  
  82. var card_page = document.createElement("span");
  83. card_page.className = "card_page";
  84.  
  85. var container_inner = document.createElement("div");
  86. container_inner.className = "card_container_inner";
  87.  
  88. card.insertBefore(title_link, card.firstChild);
  89. card.insertBefore(cover, card.firstChild);
  90. container_inner.appendChild(card);
  91. container_inner.appendChild(card_page);
  92.  
  93. return [container_inner, card, card_page];
  94. };
  95.  
  96. var charge_card = function(uri, type, id_number) {
  97. var card_number = type.slice(0, 3) + "#" + id_number;
  98.  
  99. var card_charging = document.createElement("div");
  100. card_charging.className = "card_charging";
  101. card_charging.innerHTML = "Card <u>" + card_number + "</u> Charging...";
  102.  
  103. var container = document.createElement("div");
  104. container.className = "card_container";
  105. container.id = uri;
  106.  
  107. container.appendChild(card_charging);
  108.  
  109. return [container, card_charging];
  110. };
  111.  
  112. var release_card = function(evt, uri, page_total) {
  113. evt.preventDefault();
  114.  
  115. console.log(uri);
  116. var container = document.getElementById(uri);
  117. console.log(container);
  118. var tg_c = container.querySelector(".card_content");
  119. var tg_p = container.querySelector(".card_page");
  120.  
  121. tg_c.style.marginLeft = "0";
  122. tg_p.textContent = "1/" + page_total;
  123. tg_p.style.width = 1/page_total*100 + "%";
  124.  
  125. container.style.display = "block";
  126. var rect = evt.target.getBoundingClientRect();
  127. set_coordinate(container, rect);
  128. topmost_card(container);
  129. };
  130.  
  131.  
  132. var set_card = function(e, uri) {
  133. var ar = uri.split('/');
  134. var type = ar[ar.length-2];
  135. var id_number = ar[ar.length-1];
  136.  
  137. var set_card_exec = function(evt) {
  138. evt.preventDefault();
  139.  
  140. var [container, card_charging] = charge_card(uri, type, id_number);
  141. var rect = evt.target.getBoundingClientRect();
  142. set_coordinate(container, rect);
  143.  
  144. document.body.firstElementChild.appendChild(container);
  145. topmost_card(container);
  146.  
  147. var xhr = new XMLHttpRequest();
  148. xhr.onload = function() {
  149. var doc = this.responseXML;
  150.  
  151. var [container_inner, card, card_page] = refine_card(doc, uri, type);
  152. container.replaceChild(container_inner, container.firstChild);
  153.  
  154. //XXX if cover image is not loaded as soon as the card is appended
  155. //card.scrollWidth will be smaller than when the image is showed
  156. //need some placeholder or other fix
  157. var page_total = Math.floor(card.scrollWidth / (30*13));
  158. card_page.counter = 0;
  159. card_page.textContent = "1/" + page_total;
  160. card_page.style.width = 1/page_total*100 + "%";
  161.  
  162. container.addEventListener("click", function(ev) {
  163. var tg = ev.target;
  164. if (tg.className == "card_link") return;
  165.  
  166. if (tg.className != "card_container") {
  167. if (ev.currentTarget.style.zIndex == "49") {
  168. topmost_card(ev.currentTarget);
  169. return;
  170. }
  171.  
  172. var tg_c = ev.currentTarget.querySelector(".card_content");
  173. page_total = Math.floor(tg_c.scrollWidth / (30*13));
  174.  
  175. if (page_total == 1) return;
  176.  
  177. if (tg_c.style.marginLeft == '') tg_c.style.marginLeft = "0";
  178.  
  179. //XXX select text is also "click"
  180. var current_margin = parseInt(tg_c.style.marginLeft);
  181. var counter = card_page.counter;
  182. if (Math.floor(counter/(page_total-1)) % 2 == 0) {
  183. tg_c.style.marginLeft = current_margin - 31 + "em";
  184. } else {
  185. tg_c.style.marginLeft = current_margin + 31 + "em";
  186. }
  187. card_page.counter = card_page.counter + 1;
  188. if (Math.floor(card_page.counter/(page_total-1)) % 2 == 0)
  189. var pg_2 = card_page.counter%(page_total-1) + 1;
  190. else
  191. var pg_2 = page_total - card_page.counter%(page_total-1);
  192. card_page.style.width = pg_2/page_total*100 + "%";
  193. card_page.textContent = pg_2 + "/" + page_total;
  194. } else {
  195. ev.currentTarget.style.display = "none";
  196. }
  197. });
  198.  
  199. e.removeEventListener("click", set_card_exec);
  200. var release_card_c = function(evt) {
  201. return release_card(evt, uri, page_total);
  202. };
  203. e.addEventListener("click", release_card_c);
  204. };
  205.  
  206. xhr.timeout = 5000;
  207. xhr.ontimeout = function() {
  208. card_charging.textContent = "Shooting failed. Card charging too slow. Try again.";
  209. e.addEventListener("click", set_card_exec);
  210. };
  211.  
  212. xhr.open("GET", uri);
  213. xhr.responseType = "document";
  214. xhr.send();
  215. };
  216.  
  217.  
  218. e.addEventListener("click", set_card_exec);
  219. }
  220.  
  221.  
  222. var links = document.getElementsByTagName("a");
  223. for (let t of links) {
  224. if (/\/(subject|character|person)\/\d+$/.test(t.href)) {
  225. if (t.href != document.location.href) set_card(t, t.href);
  226. }
  227. }