viewsource

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

目前为 2019-11-06 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name viewsource
  3. // @name:vi viewsource
  4. // @namespace devs.forumvi.com
  5. // @description View and beautify page source. Shortcut: Alt+U.
  6. // @description:vi Định dạng và làm đẹp mã nguồn trang web. Phím tắt: Alt+U.
  7. // @version 3.2.4
  8. // @icon http://i.imgur.com/6yZMOeH.png
  9. // @author Zzbaivong
  10. // @oujs:author baivong
  11. // @license MIT; https://baivong.mit-license.org/license.txt
  12. // @match http://*/*
  13. // @match https://*/*
  14. // @resource js_beautify https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.10.2/beautify.min.js
  15. // @resource css_beautify https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.10.2/beautify-css.min.js
  16. // @resource html_beautify https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.10.2/beautify-html.min.js
  17. // @resource hljs https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/highlight.min.js
  18. // @resource dark https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/styles/atom-one-dark.min.css
  19. // @resource light https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/styles/atom-one-light.min.css
  20. // @require https://greasemonkey.github.io/gm4-polyfill/gm4-polyfill.js?v=a834d46
  21. // @noframes
  22. // @connect *
  23. // @supportURL https://github.com/lelinhtinh/Userscript/issues
  24. // @run-at document-idle
  25. // @grant GM.getResourceUrl
  26. // @grant GM_getResourceURL
  27. // @grant GM_addStyle
  28. // @grant GM.xmlHttpRequest
  29. // @grant GM_xmlhttpRequest
  30. // @grant GM.openInTab
  31. // @grant GM_openInTab
  32. // @grant GM_registerMenuCommand
  33. // ==/UserScript==
  34.  
  35. /* eslint-env worker, es6 */
  36. (function() {
  37. 'use strict';
  38.  
  39. /**
  40. * Color themes
  41. * @type {String} dark|light
  42. */
  43. const STYLE = 'dark';
  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) {
  62. // Alt+U
  63. e.preventDefault();
  64. viewsource();
  65. }
  66. };
  67.  
  68. return;
  69. }
  70.  
  71. urlbeautify = urlpage.replace(urlbeautify, '');
  72. urlbeautify = decodeURIComponent(urlbeautify);
  73.  
  74. var blobURL, worker;
  75.  
  76. blobURL = URL.createObjectURL(
  77. new Blob(
  78. [
  79. '(',
  80. function() {
  81. self.window = {};
  82.  
  83. self.onmessage = function(e) {
  84. var source = e.data.content;
  85.  
  86. importScripts(e.data.libs[0]);
  87. importScripts(e.data.libs[1]);
  88. importScripts(e.data.libs[2]);
  89. source = self.window.html_beautify(source, {
  90. indent_scripts: 'keep',
  91. });
  92.  
  93. importScripts(e.data.libs[3]);
  94. source = self.window.hljs.highlight('xml', source, true).value;
  95.  
  96. self.postMessage({
  97. source: source,
  98. });
  99. };
  100. }.toString(),
  101. ')()',
  102. ],
  103. {
  104. type: 'application/javascript',
  105. }
  106. )
  107. );
  108. worker = new Worker(blobURL);
  109.  
  110. worker.onmessage = function(e) {
  111. if (!e.data) return;
  112.  
  113. var fragment = doc.createDocumentFragment(),
  114. pre = doc.createElement('pre');
  115.  
  116. pre.innerHTML = e.data.source;
  117. pre.className = 'hljs xml';
  118.  
  119. fragment.appendChild(pre);
  120. doc.body.appendChild(fragment);
  121.  
  122. var attrUrl = doc.getElementsByClassName('hljs-attr');
  123. for (var j = 0; j < attrUrl.length; j++) {
  124. if (/\b(src|href\b)/.test(attrUrl[j].textContent)) {
  125. var link = attrUrl[j].nextSibling.nextSibling,
  126. url = link.textContent,
  127. quote = url.slice(0, 1);
  128.  
  129. if (quote !== "'" && quote !== '"') {
  130. quote = '';
  131. } else {
  132. url = url.slice(1, -1);
  133. }
  134.  
  135. link.innerHTML = quote + '<a href="' + url + '" target="_blank">' + url + '</a>' + quote;
  136. }
  137. }
  138. };
  139.  
  140. var js_beautify = GM.getResourceUrl('js_beautify'),
  141. css_beautify = GM.getResourceUrl('css_beautify'),
  142. html_beautify = GM.getResourceUrl('html_beautify'),
  143. hljs = GM.getResourceUrl('hljs');
  144.  
  145. GM.getResourceUrl(STYLE)
  146. .then(function(url) {
  147. return fetch(url);
  148. })
  149. .then(function(resp) {
  150. return resp.text();
  151. })
  152. .then(function(style) {
  153. GM_addStyle(
  154. '*{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}' +
  155. style + 'a{color:#29B6F6}a:hover,a:focus{color:#1E88E5}a:visited,a:active{color:#1565C0}'
  156. );
  157. });
  158.  
  159. GM.xmlHttpRequest({
  160. method: 'GET',
  161. url: urlbeautify,
  162. onload: function(response) {
  163. doc.title = 'beautify-source:' + urlbeautify;
  164.  
  165. Promise.all([js_beautify, css_beautify, html_beautify, hljs]).then(function(urls) {
  166. worker.postMessage({
  167. libs: urls,
  168. content: response.response,
  169. });
  170. });
  171.  
  172. var baseUrl,
  173. baseMatch = response.response.match(/<base\s+href="([^"]+)"\s?[^>]*>/),
  174. base = doc.createElement('base');
  175.  
  176. baseUrl = baseMatch ? baseMatch[1] : urlbeautify.replace(/[^/]*$/, '');
  177.  
  178. base.href = baseUrl;
  179. doc.head.appendChild(base);
  180. },
  181. });
  182. })();