viewsource

View and beautify page source. Shortcut: Alt+U.

当前为 2019-09-30 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name viewsource
  3. // @namespace devs.forumvi.com
  4. // @description View and beautify page source. Shortcut: Alt+U.
  5. // @version 3.2.0
  6. // @icon http://i.imgur.com/6yZMOeH.png
  7. // @author Zzbaivong
  8. // @oujs:author baivong
  9. // @license MIT; https://baivong.mit-license.org/license.txt
  10. // @match http://*/*
  11. // @match https://*/*
  12. // @resource js_beautify https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.10.2/beautify.min.js
  13. // @resource css_beautify https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.10.2/beautify-css.min.js
  14. // @resource html_beautify https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.10.2/beautify-html.min.js
  15. // @resource hljs https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/highlight.min.js
  16. // @resource dark https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/styles/atom-one-dark.min.css
  17. // @resource light https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/styles/atom-one-light.min.css
  18. // @require https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js?v=a834d46
  19. // @noframes
  20. // @connect *
  21. // @supportURL https://github.com/lelinhtinh/Userscript/issues
  22. // @run-at document-idle
  23. // @grant GM.getResourceUrl
  24. // @grant GM_getResourceURL
  25. // @grant GM_addStyle
  26. // @grant GM_getResourceText
  27. // @grant GM.xmlHttpRequest
  28. // @grant GM_xmlhttpRequest
  29. // @grant GM.openInTab
  30. // @grant GM_openInTab
  31. // @grant GM_registerMenuCommand
  32. // ==/UserScript==
  33.  
  34. /* eslint-env worker, es6 */
  35. (function () {
  36. 'use strict';
  37.  
  38. /**
  39. * Color themes
  40. * @type {String} dark|light
  41. */
  42. const STYLE = 'dark';
  43.  
  44.  
  45. /* === DO NOT CHANGE === */
  46.  
  47. var doc = document,
  48. urlpage = location.href,
  49. urlbeautify = 'https://lelinhtinh.github.io/Userscript/?beautify-source=';
  50.  
  51. if (!/^application\/(xhtml+xml|xml|rss+xml)|text\/(html|xml)$/.test(doc.contentType)) return;
  52.  
  53. if (urlpage.indexOf(urlbeautify) !== 0) {
  54. var viewsource = function () {
  55. if (urlpage.indexOf(urlbeautify) === 0) return;
  56. GM.openInTab(urlbeautify + encodeURIComponent(urlpage), false);
  57. };
  58.  
  59. GM_registerMenuCommand('Beautify Page Source', viewsource, 'u');
  60. doc.onkeydown = function (e) {
  61. if (e.which === 85 && e.altKey) { // Alt+U
  62. e.preventDefault();
  63. viewsource();
  64. }
  65. };
  66.  
  67. return;
  68. }
  69.  
  70. urlbeautify = urlpage.replace(urlbeautify, '');
  71. urlbeautify = decodeURIComponent(urlbeautify);
  72.  
  73. var blobURL, worker;
  74.  
  75. blobURL = URL.createObjectURL(new Blob(['(',
  76. function () {
  77. self.window = {};
  78.  
  79. self.onmessage = function (e) {
  80. var source = e.data.content;
  81.  
  82. importScripts(e.data.libs[0]);
  83. importScripts(e.data.libs[1]);
  84. importScripts(e.data.libs[2]);
  85. source = self.window.html_beautify(source, {
  86. indent_scripts: 'keep'
  87. });
  88.  
  89. importScripts(e.data.libs[3]);
  90. source = self.window.hljs.highlight('xml', source, true).value;
  91.  
  92. self.postMessage({
  93. source: source
  94. });
  95. };
  96.  
  97. }.toString(),
  98. ')()'
  99. ], {
  100. type: 'text/javascript'
  101. }));
  102. worker = new Worker(blobURL);
  103.  
  104. worker.onmessage = function (e) {
  105. if (!e.data) return;
  106.  
  107. var fragment = doc.createDocumentFragment(),
  108. pre = doc.createElement('pre');
  109.  
  110. pre.innerHTML = e.data.source;
  111. pre.className = 'hljs xml';
  112.  
  113. fragment.appendChild(pre);
  114. doc.body.appendChild(fragment);
  115.  
  116. var attrUrl = doc.getElementsByClassName('hljs-attr');
  117. for (var j = 0; j < attrUrl.length; j++) {
  118. if (/\b(src|href\b)/.test(attrUrl[j].textContent)) {
  119. var link = attrUrl[j].nextSibling.nextSibling,
  120. url = link.textContent,
  121. quote = url.slice(0, 1);
  122.  
  123. if (quote !== '\'' && quote !== '"') {
  124. quote = '';
  125. } else {
  126. url = url.slice(1, -1);
  127. }
  128.  
  129. link.innerHTML = quote + '<a href="' + url + '" target="_blank">' + url + '</a>' + quote;
  130. }
  131. }
  132. };
  133.  
  134. var js_beautify = GM.getResourceUrl('js_beautify'),
  135. css_beautify = GM.getResourceUrl('css_beautify'),
  136. html_beautify = GM.getResourceUrl('html_beautify'),
  137. hljs = GM.getResourceUrl('hljs'),
  138. style = GM_getResourceText(STYLE);
  139.  
  140. GM_addStyle('*{margin:0;padding:0}html{line-height:1em;background:#1d1f21;color:#c5c8c6}pre{white-space:pre-wrap;word-wrap:break-word;word-break:break-all}' + style);
  141.  
  142. GM.xmlHttpRequest({
  143. method: 'GET',
  144. url: urlbeautify,
  145. onload: function (response) {
  146. doc.title = 'beautify-source:' + urlbeautify;
  147.  
  148. Promise.all([js_beautify, css_beautify, html_beautify, hljs]).then(function (urls) {
  149. worker.postMessage({
  150. libs: urls,
  151. content: response.response
  152. });
  153. });
  154.  
  155. var baseUrl,
  156. baseMatch = response.response.match(/<base\s+href="([^"]+)"\s?[^>]*>/),
  157. base = doc.createElement('base');
  158.  
  159. baseUrl = baseMatch ? baseMatch[1] : urlbeautify.replace(/[^/]*$/, '');
  160.  
  161. base.href = baseUrl;
  162. doc.head.appendChild(base);
  163. }
  164. });
  165.  
  166. }());