viewsource

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

当前为 2019-10-12 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name viewsource
  3. // @namespace devs.forumvi.com
  4. // @description View and beautify page source. Shortcut: Alt+U.
  5. // @version 3.2.1
  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.xmlHttpRequest
  27. // @grant GM_xmlhttpRequest
  28. // @grant GM.openInTab
  29. // @grant GM_openInTab
  30. // @grant GM_registerMenuCommand
  31. // ==/UserScript==
  32.  
  33. /* eslint-env worker, es6 */
  34. (function () {
  35. 'use strict';
  36.  
  37. /**
  38. * Color themes
  39. * @type {String} dark|light
  40. */
  41. const STYLE = 'dark';
  42.  
  43.  
  44. /* === DO NOT CHANGE === */
  45.  
  46. var doc = document,
  47. urlpage = location.href,
  48. urlbeautify = 'https://lelinhtinh.github.io/Userscript/?beautify-source=';
  49.  
  50. if (!/^application\/(xhtml+xml|xml|rss+xml)|text\/(html|xml)$/.test(doc.contentType)) return;
  51.  
  52. if (urlpage.indexOf(urlbeautify) !== 0) {
  53. var viewsource = function () {
  54. if (urlpage.indexOf(urlbeautify) === 0) return;
  55. GM.openInTab(urlbeautify + encodeURIComponent(urlpage), false);
  56. };
  57.  
  58. GM_registerMenuCommand('Beautify Page Source', viewsource, 'u');
  59. doc.onkeydown = function (e) {
  60. if (e.which === 85 && e.altKey) { // Alt+U
  61. e.preventDefault();
  62. viewsource();
  63. }
  64. };
  65.  
  66. return;
  67. }
  68.  
  69. urlbeautify = urlpage.replace(urlbeautify, '');
  70. urlbeautify = decodeURIComponent(urlbeautify);
  71.  
  72. var blobURL, worker;
  73.  
  74. blobURL = URL.createObjectURL(new Blob(['(',
  75. function () {
  76. self.window = {};
  77.  
  78. self.onmessage = function (e) {
  79. var source = e.data.content;
  80.  
  81. importScripts(e.data.libs[0]);
  82. importScripts(e.data.libs[1]);
  83. importScripts(e.data.libs[2]);
  84. source = self.window.html_beautify(source, {
  85. indent_scripts: 'keep'
  86. });
  87.  
  88. importScripts(e.data.libs[3]);
  89. source = self.window.hljs.highlight('xml', source, true).value;
  90.  
  91. self.postMessage({
  92. source: source
  93. });
  94. };
  95.  
  96. }.toString(),
  97. ')()'
  98. ], {
  99. type: 'text/javascript'
  100. }));
  101. worker = new Worker(blobURL);
  102.  
  103. worker.onmessage = function (e) {
  104. if (!e.data) return;
  105.  
  106. var fragment = doc.createDocumentFragment(),
  107. pre = doc.createElement('pre');
  108.  
  109. pre.innerHTML = e.data.source;
  110. pre.className = 'hljs xml';
  111.  
  112. fragment.appendChild(pre);
  113. doc.body.appendChild(fragment);
  114.  
  115. var attrUrl = doc.getElementsByClassName('hljs-attr');
  116. for (var j = 0; j < attrUrl.length; j++) {
  117. if (/\b(src|href\b)/.test(attrUrl[j].textContent)) {
  118. var link = attrUrl[j].nextSibling.nextSibling,
  119. url = link.textContent,
  120. quote = url.slice(0, 1);
  121.  
  122. if (quote !== '\'' && quote !== '"') {
  123. quote = '';
  124. } else {
  125. url = url.slice(1, -1);
  126. }
  127.  
  128. link.innerHTML = quote + '<a href="' + url + '" target="_blank">' + url + '</a>' + quote;
  129. }
  130. }
  131. };
  132.  
  133. var js_beautify = GM.getResourceUrl('js_beautify'),
  134. css_beautify = GM.getResourceUrl('css_beautify'),
  135. html_beautify = GM.getResourceUrl('html_beautify'),
  136. hljs = GM.getResourceUrl('hljs');
  137.  
  138. GM.getResourceUrl(STYLE).then(function (url) {
  139. return fetch(url);
  140. }).then(function (resp) {
  141. return resp.text();
  142. }).then(function (style) {
  143. 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);
  144. });
  145.  
  146. GM.xmlHttpRequest({
  147. method: 'GET',
  148. url: urlbeautify,
  149. onload: function (response) {
  150. doc.title = 'beautify-source:' + urlbeautify;
  151.  
  152. Promise.all([js_beautify, css_beautify, html_beautify, hljs]).then(function (urls) {
  153. worker.postMessage({
  154. libs: urls,
  155. content: response.response
  156. });
  157. });
  158.  
  159. var baseUrl,
  160. baseMatch = response.response.match(/<base\s+href="([^"]+)"\s?[^>]*>/),
  161. base = doc.createElement('base');
  162.  
  163. baseUrl = baseMatch ? baseMatch[1] : urlbeautify.replace(/[^/]*$/, '');
  164.  
  165. base.href = baseUrl;
  166. doc.head.appendChild(base);
  167. }
  168. });
  169.  
  170. }());