Advertisement
Guest User

qab2

a guest
Jun 14th, 2018
592
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.09 KB | None | 0 0
  1. // ==UserScript==
  2. // @name webnovel.com skip video ads mobile
  3. // @namespace http://forum.novelupdates.com/
  4. // @version 5
  5. // @run-at document-end
  6. // @match http://m.webnovel.com/book/*
  7. // @match https://m.webnovel.com/book/*
  8. // @license MIT
  9. // ==/UserScript==
  10.  
  11.  
  12. //-------------------------------------------------------------------------------------------------------------------
  13. // Thanks go to shadofx for modifying the desktop version (v4) of this script
  14. // to work on mobile. This can be found at
  15. // https://openuserjs.org/scripts/shadofx/webnovel.com_skip_video_ads_mobile/source
  16. //-------------------------------------------------------------------------------------------------------------------
  17.  
  18. // How frequently this script should check for new chapters.
  19. //
  20. // The amount is in milliseconds.
  21. const INTERVAL_CHAPTER_CHECK = 1000;
  22.  
  23. // When a token is not ready yet, this is how much time we should wait
  24. // before trying again.
  25. //
  26. // The amount is in milliseconds.
  27. const INTERVAL_TOKEN_CHECK = 1000;
  28.  
  29. function getCookie(name) {
  30. var value = "; " + document.cookie;
  31. var parts = value.split("; " + name + "=");
  32. if (parts.length == 2) return parts.pop().split(";").shift();
  33. }
  34.  
  35. /**
  36. * Check for new chapters and try to remove the adwall from them.
  37. */
  38. function main() {
  39. Array.from(
  40. // Locked chapters.
  41. document.querySelectorAll('.j_chapterWrapper')
  42. ).filter((item)=>item.querySelector('.cha-txt').classList.contains('cha-txt-hide'))
  43. .forEach((lock) => {
  44. // Element with the chapter content.
  45. const contentElement = lock.querySelector('.cha-txt');
  46.  
  47. // Remove this class so this chapter won't be processed the next time
  48. // `main` is called.
  49. contentElement.classList.remove('cha-txt-hide');
  50.  
  51. // Remove the video.
  52. const v = lock.querySelector('.cha-watch-ad');
  53. if(v) v.remove();
  54.  
  55. contentElement.style.opacity = '0.1';
  56.  
  57. // Get the ID for the series ("book").
  58. //
  59. // Some chapters have the `data-bid` property, but not all of themw.
  60. // That's why it's better to just get this from the URL.
  61. const bid = window.location.href.split('/book/')[1].split('/')[0];
  62.  
  63. // Get the ID for the chapter.
  64. const cid = lock.dataset.chapterid;
  65.  
  66. //Get the csrf token
  67. const csrf = getCookie("_csrfToken");
  68.  
  69. // alert(`https://m.webnovel.com/ajax/chapter/getChapterContentToken?bookId=${bid}&chapterId=${cid}&_csrfToken=${csrf}`);
  70.  
  71. // Both ID are required.
  72. if (!bid || !cid || !csrf) {
  73. return;
  74. }
  75.  
  76. return fetch(
  77. `https://m.webnovel.com/ajax/chapter/getChapterContentToken?bookId=${bid}&chapterId=${cid}&_csrfToken=${csrf}`
  78. , {credentials: "same-origin"})
  79. .then(resp => resp.json())
  80. .then(data => {
  81. return data.data.token
  82. })
  83. .then(token => encodeURIComponent(token))
  84. .then(token => new Promise((resolve) => {
  85. // The raw body of the chapter.
  86. //
  87. // It will be plain text, so we must manually build the HTML for it.
  88. let content = '';
  89.  
  90. // Try to get the content of the chapter, and fulfill the promise once
  91. // we have it.
  92. //
  93. // This function will retry until it succeeds.
  94. function tick() {
  95. if (token != '') {
  96. const url = `https://m.webnovel.com/ajax/chapter/getChapterContentByToken?token=${token}&_csrfToken=${csrf}`;
  97. fetch(url, {credentials: "same-origin"})
  98. .then(resp => resp.json())
  99. .then((data) => {
  100. content = data.data.content.trim();
  101.  
  102. if (content) {
  103. resolve(content);
  104. } else {
  105. setTimeout(tick, INTERVAL_TOKEN_CHECK);
  106. }
  107. })
  108. .catch((err) => {
  109. console.error(err.stack);
  110. tick();
  111. });
  112. }
  113. }
  114.  
  115. tick();
  116. }))
  117. .then((content) => {
  118. // Build the HTML for the chapter content.
  119. //
  120. // For now we only split on line breaks and wrap each piece
  121. // with "<p></p>" tags.
  122. const chapterHtml = content
  123. .split('\n')
  124. .map(p => p.trim())
  125. .filter(p => !!p)
  126. .map(p => `<p>${p}</p>`)
  127. .join('');
  128.  
  129. // Update the chapter content and turn opacity back to 100%.
  130. contentElement.innerHTML = chapterHtml;
  131. contentElement.style.opacity = '1';
  132. })
  133. .catch((err) => {
  134. console.error(err.stack);
  135. });
  136. });
  137. }
  138.  
  139. // Since Qidian may load new chapters without refreshing the page, we must
  140. // continuously check for new chapters in the page.
  141. setInterval(main, INTERVAL_CHAPTER_CHECK);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement