The Wall Street Journal CN site Full Text Articles

Fetch the full text of The Wall Street Journal articles from the AMP version. I've identified an issue affecting iOS Safari users while reading articles on wsj.com. The font size may appear too large. As a temporary workaround, please use the font adjustment tool in the Safari address bar to increase or decrease the font size, then reset it to the original size. This should fix the issue. This bug is not present on cn.wsj.com. Thank you for your cooperation and understanding.

  1. // ==UserScript==
  2. // @name:zh-CN 中文华尔街日报付费墙移除、全文显示
  3. // @description:zh-CN 用户在访问华尔街日报网站时移除付费墙,让您免费阅读文章。
  4. // @name:zh-TW 中文華爾街日報付費牆移除、全文顯示
  5. // @description:zh-TW 用戶在訪問華爾街日報網站時移除付費牆,讓您免費閱讀文章。
  6. // @name The Wall Street Journal CN site Full Text Articles
  7. // @name:it The Wall Street Journal CN - Articoli con testo completo
  8. // @namespace iamfredchu
  9. // @version 0.0.13
  10. // @description Fetch the full text of The Wall Street Journal articles from the AMP version. I've identified an issue affecting iOS Safari users while reading articles on wsj.com. The font size may appear too large. As a temporary workaround, please use the font adjustment tool in the Safari address bar to increase or decrease the font size, then reset it to the original size. This should fix the issue. This bug is not present on cn.wsj.com. Thank you for your cooperation and understanding.
  11. // @description:it Mostra il testo completo degli articoli su The Wall Street Journal
  12. // @author Fred Chu
  13. // @match https://cn.wsj.com/articles/*
  14. // @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js
  15. // @inject-into content
  16. // @grant GM_xmlhttpRequest
  17. // @grant GM.xmlHttpRequest
  18. // @run-at document-end
  19. // @license GPL version 3 or any later version; http://www.gnu.org/copyleft/gpl.html
  20. // ==/UserScript==
  21.  
  22. function fetch(params) {
  23. return new Promise(function(resolve, reject) {
  24. params.onload = resolve;
  25. params.onerror = reject;
  26. GM.xmlHttpRequest(params);
  27. });
  28. }
  29.  
  30. (function() {
  31. 'use strict';
  32. const $body = $(document.body);
  33. const paywalled = $body.find("#cx-snippet-promotion");
  34.  
  35. if (!paywalled) {
  36. return;
  37. }
  38.  
  39. fetch({
  40. method: 'GET',
  41. url: location.protocol + '//' + location.host + '/amp/articles/' + location.pathname.split('/').pop(),
  42. }).then(function(responseDetails) {
  43. var r = responseDetails.responseText;
  44. r = r.replace(/<script/gi, '<div').replace(/script>/gi, 'div>');
  45. r = r.replace(/\?width=/gi, '?__=').replace(/<amp-img/gi, '<img').replace(/<.amp-img>/, '').replace(/amp-iframe/gi, 'iframe');
  46.  
  47. var data = $(r);
  48.  
  49. setTimeout(function(){
  50. let hasSnippet = $body.find('.wsj-snippet-body');
  51. let $preview = $body.find('article section').length ?
  52. $body.find('article section') :
  53. $body.find('.wsj-snippet-body');
  54.  
  55. $preview.replaceWith(data.find('section[subscriptions-section="content"]')
  56. .css('margin-bottom', '5rem')
  57. .css('color', 'var(--primary-text-color)')
  58. .css('font-family', 'var(--article-font-family)')
  59. .css('font-weight', 'var(--article-font-weight)')
  60. .css('line-height', 'calc(27 / 17)')
  61. .css('direction', 'var(--article-direction);')
  62. );
  63.  
  64. $body.find('[aria-label*="Listen"]').next().next().remove();
  65. $body.find('[aria-label*="What"]').remove();
  66. $body.find('#cx-snippet-overlay').length && $body.find('#cx-snippet-overlay').parent().remove();
  67. $body.find('.snippet-promotion, #cx-what-to-read-next').length && $body.find('.snippet-promotion, #cx-what-to-read-next').remove();
  68.  
  69. $body.find('.responsive-media').css('height', 'auto');
  70. $body.find('.responsive-media img').css({
  71. 'height': 'auto',
  72. 'width': 'auto',
  73. 'max-width': '100%',
  74. 'display': 'block',
  75. 'position': 'relative',
  76. });
  77.  
  78. $body.find('article section p').css('margin', '0 0 1em 0')
  79. .css('font-size', 'calc((17 / var(--article-base-font-size)) * var(--article-text-size-scale) * 1rem)');
  80.  
  81. const $videoWrapper = $('<div class="video-player"></div>');
  82. $videoWrapper.css('height', '225px');
  83. $body.find('.media-object-video iframe').css('max-width', '100%').removeClass('video-wrapper').wrap($videoWrapper);
  84.  
  85. $body.find('.media-object-podcast iframe').css('max-width', '100%');
  86. $body.find('.imageCaption').each(function() {
  87. var element = $(this);
  88. var parent = element.parent();
  89. var wrapper = $('<div class="wsj-article-caption"></div>');
  90. wrapper.append(element.html()).appendTo(parent);
  91. element.remove();
  92. }).find('.imageCredit').addClass('wsj-article-credit').prepend(' ');
  93. $body.find('.media-object').addClass('media-object-image');
  94. $body.find('.media-object img').css('height', 'auto');
  95. }, 3000);
  96. }).catch(error => {
  97. console.error(arguments);
  98. });
  99. })();