viewsource

Viewsource for Firefox, like Chrome

目前为 2016-04-06 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name viewsource
  3. // @namespace devs.forumvi.com
  4. // @description Viewsource for Firefox, like Chrome
  5. // @version 2.3.3
  6. // @icon http://i.imgur.com/6yZMOeH.png
  7. // @author Zzbaivong
  8. // @match *
  9. // @resource light https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.3.0/styles/github-gist.min.css
  10. // @resource dark https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.3.0/styles/monokai-sublime.min.css
  11. // @require https://greasyfork.org/scripts/18530-beautify-html/code/beautify-html.js?version=117787
  12. // @require https://greasyfork.org/scripts/18531-beautify-js/code/beautify-js.js?version=117786
  13. // @require https://greasyfork.org/scripts/18528-beautify-css/code/beautify-css.js?version=117789
  14. // @require https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.3.0/highlight.min.js
  15. // @noframes
  16. // @supportURL https://github.com/baivong/Userscript/issues
  17. // @run-at document-end
  18. // @grant GM_addStyle
  19. // @grant GM_getResourceText
  20. // @grant GM_xmlhttpRequest
  21. // @grant GM_registerMenuCommand
  22. // ==/UserScript==
  23.  
  24. (function () {
  25.  
  26. 'use strict';
  27.  
  28. var theme = 'light', // light|dark
  29.  
  30. win = window,
  31. urlpage = win.top.location.href,
  32. doc = document,
  33. wrapcontent = doc.documentElement,
  34. content = doc.body;
  35.  
  36. function scrollByDragging(container, disableH, disableV) {
  37.  
  38. function mouseUp(e) {
  39. if (e.which !== 3) return;
  40.  
  41. window.removeEventListener('mousemove', mouseMove, true);
  42. container.style.cursor = 'default';
  43. }
  44.  
  45. function mouseDown(e) {
  46. if (e.which !== 3) return;
  47.  
  48. pos = {
  49. x: e.clientX,
  50. y: e.clientY
  51. };
  52.  
  53. window.addEventListener('mousemove', mouseMove, true);
  54. container.style.cursor = 'move';
  55. }
  56.  
  57. function mouseMove(e) {
  58. if (!disableH) container.scrollLeft -= (-pos.x + (pos.x = e.clientX));
  59. if (!disableV) container.scrollTop -= (-pos.y + (pos.y = e.clientY));
  60. }
  61.  
  62. var pos = {
  63. x: 0,
  64. y: 0
  65. };
  66.  
  67. container.oncontextmenu = function (e) {
  68. e.preventDefault();
  69. };
  70.  
  71. container.addEventListener('mousedown', mouseDown, false);
  72. window.addEventListener('mouseup', mouseUp, false);
  73.  
  74. }
  75.  
  76. function removeEvents(ele, attr) {
  77. var events = 'onafterprint onbeforeprint onbeforeunload onerror onhashchange onload onmessage onoffline ononline onpagehide onpageshow onpopstate onresize onstorage onunload onblur onchange oncontextmenu onfocus oninput oninvalid onreset onsearch onselect onsubmit onkeydown onkeypress onkeyup onclick ondblclick ondrag ondragend ondragenter ondragleave ondragover ondragstart ondrop onmousedown onmousemove onmouseout onmouseover onmouseup onmousewheel onscroll onwheel oncopy oncut onpaste onerror onshow ontoggle'.split(' '),
  78. x;
  79. for (x in events) {
  80. var _event = events[x];
  81. ele[_event] = null;
  82. if (attr) {
  83. ele.removeAttribute(_event);
  84. }
  85. }
  86. }
  87.  
  88. function viewsource() {
  89. GM_xmlhttpRequest({
  90. method: 'GET',
  91. url: urlpage,
  92. onload: function (response) {
  93.  
  94. removeEvents(win);
  95. removeEvents(doc);
  96. removeEvents(wrapcontent, true);
  97. removeEvents(content, true);
  98.  
  99. var txt = html_beautify(response.response);
  100.  
  101. doc.head.innerHTML = '';
  102. content.innerHTML = '';
  103. content.removeAttribute('id');
  104. content.removeAttribute('class');
  105. content.removeAttribute('style');
  106. doc.title = 'view-source:' + urlpage;
  107.  
  108. GM_addStyle(GM_getResourceText(theme) + 'html,body,pre{margin:0;padding:0}.hljs{overflow:hidden;word-wrap:normal!important;white-space:pre!important;padding-left:4em;line-height:100%}.hljs::before{content:attr(data-lines);position:absolute;color:#d2d2d2;text-align:right;width:3.5em;left:-.5em;border-right:1px solid rgba(221, 221, 221, 0.36);padding-right:.5em}');
  109.  
  110. var output = doc.createElement('PRE');
  111. output.setAttribute('class', 'xml');
  112. output.textContent = txt;
  113.  
  114. content.appendChild(output);
  115.  
  116. hljs.highlightBlock(output);
  117.  
  118. var lines = txt.split('\n'),
  119. l = '';
  120. lines = lines ? lines.length : 0;
  121. for (var i = 0; i < lines; i++) {
  122. l += (i + 1) + '\n';
  123. }
  124.  
  125. output.setAttribute('data-lines', l);
  126. //output.style.width = output.scrollWidth + 'px';
  127.  
  128. scrollByDragging(output, false, true);
  129. scrollByDragging(content, true);
  130. scrollByDragging(wrapcontent, true);
  131.  
  132. var attrUrl = doc.getElementsByClassName('hljs-attr');
  133. for (var j = 0; j < attrUrl.length; j++) {
  134. if (/\b(src|href\b)/.test(attrUrl[j].textContent)) {
  135. var link = attrUrl[j].nextSibling.nextSibling;
  136. var url = link.textContent.slice(1, -1);
  137. link.innerHTML = '<a href="' + url + '" target="_blank">' + url + '</a>';
  138. }
  139. }
  140.  
  141. }
  142. });
  143. }
  144.  
  145. GM_registerMenuCommand('View source', viewsource, 'm');
  146.  
  147. if (doc.contentType === 'text/html' && doc.URL === urlpage) {
  148. win.onkeydown = function (e) {
  149.  
  150. // Ctrl + M
  151. if (e.which === 77 && e.ctrlKey) {
  152. e.preventDefault();
  153.  
  154. viewsource();
  155. }
  156. };
  157. }
  158. }());