Homeunstuck

adds homestuck navigation and pages remaining

目前为 2016-04-18 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Homeunstuck
  3. // @namespace abrad45
  4. // @description adds homestuck navigation and pages remaining
  5. // @include http://www.mspaintadventures.com/*
  6. // @include http://mspaintadventures.com/*
  7. // @require https://code.jquery.com/jquery-2.2.3.min.js
  8. // @require https://cdnjs.cloudflare.com/ajax/libs/js-cookie/2.1.1/js.cookie.js
  9. // @version 2.0
  10. // @grant none
  11. // @history 1.0 20121125 - Initial Release
  12. // @history 1.0.1 20121202 - Modified `endings` to include page 7411, End of A6I4
  13. // @history 1.0.2 20121204 - Changed erroneous ending page number of A6I4 from 7441 to 7411
  14. // @history 1.0.3 20130113 - Modified `endings` to include page 7613, End of A6A5A1
  15. // @history 1.0.4 20130414 - Modified `endings` to remove page 7613, and add 7826 and 8135
  16. // @history 1.1 20130415 - Formatting Changes; Enabled Keyboard Navigation with Left/Right Arrows
  17. // @history 1.2 20130421 - Includes "You've not saved since comic ##" notification
  18. // @history 1.3 20160416 - We're back! Formatting, final update to `endings`, jquery version bump and switch from jquery-cookie to js-cookie.
  19. // @history 2.0 20160417 - Comments; Enabled Saving items as favorite pages for reference later. Fixed bugs on pages > 10000
  20.  
  21. // ==/UserScript==
  22.  
  23. $(function () {
  24. if (/s=6/.test(window.location.search)) {
  25. var faves = !!localStorage;
  26. var favoritesLSKey = 'homeunstuck-faves';
  27.  
  28. var URL = window.location.search;
  29. var comic = Number(URL.substr(URL.length - 6));
  30. var comicNumberLength = String(comic).length
  31. var urlRoot = URL.substr(0, URL.length - comicNumberLength);
  32. var firstPage = 1901;
  33. var lastPage = 10028;
  34.  
  35. if (!comic) {
  36. urlRoot = "?s=6&p=00";
  37. comic = firstPage;
  38. }
  39.  
  40. var nextURL = '/' + urlRoot + (+comic + 1);
  41. var prevURL = '/' + urlRoot + (+comic - 1);
  42.  
  43. // starting from the top so I can display nothing if there is no end to the current act
  44. var endings = [
  45. 2147, // End of Act I
  46. 2658, // End of Act II
  47. 3053, // End of Act III
  48. 3257, // End of Intermission 1
  49. 3888, // End of Act IV
  50. 4525, // End of Act V Act I
  51. 6010, // End of Act V
  52. 6012, // End of Intermission 2
  53. 6184, // End of Act VI Act I
  54. 6290, // End of Act VI Intermission 1
  55. 6566, // End of Act VI Act II
  56. 6716, // End of Act VI Intermission 2
  57. 7162, // End of Act VI Act III
  58. 7337, // End of Act VI Intermission 3
  59. 7339, // End of Act VI Act IV
  60. 7411, // End of Act VI Intermission 4
  61. 7826, // End of Act VI Act V
  62. 8135, // End of Act VI Intermission 5
  63. 8177, // End of Act VI Act VI Act I
  64. 8374, // End of Act VI Act VI Intermission 1
  65. 8430, // End of Act VI Act VI Act II
  66. 8752, // End of Act VI Act VI Intermission 2
  67. 8801, // End of Act VI Act VI Act III
  68. 8820, // End of Act VI Act VI Intermission 3
  69. 8843, // End of Act VI Act VI Act IV
  70. 9308, // End of Act VI Act VI Intermission 4
  71. 9348, // End of Act VI Act VI Act V
  72. 9986, // End of Act VI Act VI Intermission 5
  73. 10026, // End of Act VI Act VI Act VI
  74. 10028 // End of Act VI
  75. ];
  76.  
  77. // Find out which part of the story we're in
  78. var currentStorySection = endings.length;
  79. while(comic < endings[--currentStorySection]) {}
  80. // We've gone too far. Course correct!
  81. currentStorySection++;
  82.  
  83. // Add `#homeunstuck` for later appending
  84. $('table[width=600]')
  85. .first()
  86. .parent()
  87. .css('position', 'relative')
  88. .prepend(
  89. $('<div />', {
  90. 'id': 'homeunstuck',
  91. 'css': {
  92. 'position': 'absolute',
  93. 'left': '35px',
  94. 'width': '100px',
  95. }
  96. })
  97. );
  98.  
  99. // Put some arrows (and a favorites icon) in there
  100. $('#homeunstuck')
  101. .append(
  102. $('<a />', {
  103. 'id': 'homeunstuck-prev',
  104. 'href': prevURL,
  105. 'html': '&#8592;',
  106. 'css': {
  107. 'margin-right': '10px',
  108. 'text-decoration': 'none',
  109. }
  110. })
  111. ).append(
  112. $('<a />', {
  113. 'id': 'homeunstuck-next',
  114. 'href': nextURL,
  115. 'html': '&#8594;',
  116. 'css': { 'text-decoration': 'none' }
  117. })
  118. );
  119.  
  120. // Add in Faves if we can
  121. if (!!faves) {
  122. $('#homeunstuck-prev')
  123. .after(
  124. $('<a />', {
  125. 'id': 'homeunstuck-save',
  126. 'href': '#',
  127. 'html': getFavoriteIcon(comic),
  128. 'css': {
  129. 'margin-right': '10px',
  130. 'text-decoration': 'none',
  131. 'color': 'rgb(0, 0, 238)',
  132. }
  133. })
  134. );
  135. }
  136.  
  137. // You're not leaving homestuck with these arrows!
  138. if (comic === firstPage) {
  139. $('#homeunstuck-prev').remove();
  140. } else if(comic === lastPage) {
  141. $('#homeunstuck-next').remove();
  142. }
  143.  
  144. // Add pages left notice
  145. if (!isNaN(endings[currentStorySection] - comic)) {
  146. $('#homeunstuck')
  147. .append($('<div />', {
  148. 'text': endings[currentStorySection] - comic + ' left',
  149. 'id': 'homeunstuck_pages_left'
  150. })
  151. );
  152. }
  153.  
  154. // Cache some cookies
  155. var story = Cookies.get('s_cookie');
  156. var page = Cookies.get('p_cookie');
  157.  
  158. // If you have saved the game, and you're in Homestuck,
  159. // and you've not saved in more than 24 pages...
  160. if (
  161. !!story &&
  162. !!page &&
  163. Number(story) === 6 &&
  164. (comic - page.substr(-comicNumberLength) > 24)
  165. ) {
  166. // Tell the user that they forgot to save!
  167. $('#homeunstuck').append(
  168. $('<div />',
  169. {
  170. 'text': "You've not saved since comic " + Cookies.get('p_cookie').substr(-comicNumberLength),
  171. 'css': {
  172. 'color': '#900',
  173. 'font-weight': 'bold'
  174. }
  175. }
  176. )
  177. );
  178. }
  179.  
  180. // Enable keyboard navigation of Homestuck
  181. $(window).keyup(function (e) {
  182. if (e.which === 37) {
  183. window.location = prevURL; // left
  184. } else if (e.which === 39) {
  185. window.location = nextURL; // right
  186. } else if (e.which === 70) {
  187. $('#favorites-toggle').click(); // f (favorites)
  188. } else if (e.which === 83) {
  189. $('#homeunstuck-save').click(); // s (save)
  190. }
  191. });
  192.  
  193. $('#homeunstuck')
  194. .on('click', '#homeunstuck-save', function (e) {
  195. e.preventDefault();
  196. saveFavorite();
  197.  
  198. $(this).html(getFavoriteIcon(comic));
  199. updateFavoritesList();
  200. }).on('click', '#favorites-toggle', function () {
  201. var isFavoritesListVisible = !!$('#favorites-list').length;
  202.  
  203. $(this).text((isFavoritesListVisible ? "Show" : "Hide") + " Favorites");
  204.  
  205. if (!!isFavoritesListVisible) {
  206. $('#favorites-list').remove();
  207. } else {
  208. $('#favorites-toggle')
  209. .after($('<ol />', {
  210. 'id': 'favorites-list'
  211. })
  212. );
  213.  
  214. updateFavoritesList();
  215. }
  216. });
  217.  
  218. if (!!faves && !!numberOfFavorites()) {
  219. $('#homeunstuck')
  220. .after($('<div />', {
  221. 'id': favoritesLSKey,
  222. })
  223. ).append($('<button />', {
  224. 'id': 'favorites-toggle',
  225. 'text': 'Show Favorites',
  226. 'data': {
  227. 'state': 'hidden'
  228. }
  229. })
  230. );
  231. }
  232. }
  233.  
  234. function updateFavoritesList() {
  235. if (numberOfFavorites()) {
  236. $('#favorites-list').html('');
  237. var favorites = getLocalStorage();
  238. for (var page in favorites) {
  239. var item = favorites[page];
  240. $('#favorites-list').append(
  241. $('<li />').append($('<a />', {
  242. 'text': item.comic,
  243. 'title': item.title,
  244. 'href': urlRoot + item.comic
  245. }))
  246. );
  247. }
  248. }
  249. }
  250.  
  251. function getFavoriteIcon(page) {
  252. return (!!isFavorite(page) ? '&#9733;' : '&#9734;');
  253. }
  254.  
  255. function getComicTitle() {
  256. return $('font[size=6]').text().replace('\n', '') || "Error Occurred";
  257. }
  258.  
  259. function saveFavorite() {
  260. updateLocalStorage(comic, {
  261. "comic": comic,
  262. "title": getComicTitle(),
  263. });
  264. }
  265.  
  266. function updateLocalStorage(page, val) {
  267. var favorites = getLocalStorage(favoritesLSKey);
  268. if (!!favorites[page]) {
  269. // No longer a favorite
  270. delete favorites[page];
  271. } else {
  272. // Add this to favorites
  273. favorites[page] = val;
  274. }
  275.  
  276. setLocalStorage(favorites);
  277. }
  278.  
  279. function getLocalStorage() {
  280. return JSON.parse(localStorage.getItem(favoritesLSKey)) || {};
  281. }
  282.  
  283. function isFavorite(page) {
  284. var favorites = getLocalStorage(favoritesLSKey);
  285.  
  286. return !!favorites[page];
  287. }
  288.  
  289. function numberOfFavorites() {
  290. return Object.keys(getLocalStorage()).length;
  291. }
  292.  
  293. function setLocalStorage(val) {
  294. localStorage.setItem(favoritesLSKey, JSON.stringify(val));
  295. }
  296. });