代码片段高亮

选择代码片段后点击图标弹出新窗口显示语法高亮美化与格式化后的代码与字数统计

当前为 2022-01-08 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Highlight Every Code
  3. // @name:zh-CN 代码片段高亮
  4. // @name:zh-TW 程式碼片斷高亮
  5. // @namespace hoothin
  6. // @version 2.0.1
  7. // @description Add a icon to popup a window that allows syntax highlighting and beautify and word count of source code snippets on current page
  8. // @description:zh-CN 选择代码片段后点击图标弹出新窗口显示语法高亮美化与格式化后的代码与字数统计
  9. // @description:zh-TW 選擇程式碼片段後點選圖示彈出新視窗顯示語法高亮美化與格式化後的程式碼與字數統計
  10. // @author Hoothin
  11. // @grant GM_registerMenuCommand
  12. // @grant GM.registerMenuCommand
  13. // @grant unsafeWindow
  14. // @compatible chrome
  15. // @compatible firefox
  16. // @license MIT License
  17. // @contributionURL https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=rixixi@sina.com&item_name=Greasy+Fork+donation
  18. // @contributionAmount 1
  19. // @include *
  20. // ==/UserScript==
  21.  
  22. (function() {
  23. 'use strict';
  24. var codeIcon=document.createElement("img");
  25. var codes, selStr, scrollX, scrollY, customInput=false;
  26. var _unsafeWindow=(typeof unsafeWindow=='undefined'? window : unsafeWindow);
  27. codeIcon.style.cssText="position:fixed;z-index:99999;cursor:pointer;transition:opacity 0.5s ease-in-out 0s;opacity:0;border:5px solid rgba(0, 0, 0, 0.2);border-radius:10px;";
  28. codeIcon.title="Show this code snippet";
  29. codeIcon.src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAYAgMAAACD0OXYAAAACVBMVEX7+/swMDBTU1MLxgsCAAAAJElEQVQI12MIBYEAGLUKBBbAqAUMQICgAoAqoBQ95JaCnASjAAgXMdk3d5HTAAAAAElFTkSuQmCC";
  30. codeIcon.onmousedown=highlight;
  31.  
  32. document.addEventListener('DOMMouseScroll', function(o) {
  33. hideIcon();
  34. });
  35. document.addEventListener('wheel', function(o) {
  36. hideIcon();
  37. });
  38. document.addEventListener('mousewheel', function(o) {
  39. hideIcon();
  40. });
  41. document.addEventListener('mouseover', function(o) {
  42. if(o.target.nodeName!="PRE" && o.target.nodeName!="CODE")return;
  43. if(o.target.offsetWidth && o.target.offsetWidth<100)return;
  44. selStr=o.target.innerText;
  45. if(!selStr)return;
  46. codes=selStr.replace(/&/g, "&amp;").replace(/\</g,"&lt;").replace(/\>/g,"&gt;");
  47. document.body.appendChild(codeIcon);
  48. let pos=getMousePos(o);
  49. scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
  50. scrollY = document.documentElement.scrollTop || document.body.scrollTop;
  51. let top=o.target.offsetTop-scrollY;
  52. let left=o.target.offsetLeft-scrollX;
  53. codeIcon.style.opacity=0.9;
  54. codeIcon.style.top=top+"px";
  55. codeIcon.style.left=left+"px";
  56. });
  57. document.addEventListener('mousedown', function(o) {
  58. hideIcon();
  59. });
  60. document.addEventListener('mouseup', function(o) {
  61. if (o.button === 0 && (o.ctrlKey || o.altKey || o.metaKey || o.shiftKey)) {
  62. //var customInputKey=(o.ctrlKey && o.shiftKey);
  63. setTimeout(function(){
  64. selStr=document.getSelection().toString();
  65. codes=selStr.replace(/&/g, "&amp;").replace(/\</g,"&lt;").replace(/\>/g,"&gt;");
  66. if(!codes){
  67. return;
  68. }
  69. document.body.appendChild(codeIcon);
  70. let pos=getMousePos(o);
  71. let clientH=(document.documentElement && document.documentElement.clientHeight) || 0;
  72. let clientW=(document.documentElement && document.documentElement.clientWidth) || 0;
  73. let top=pos.y>clientH-50?(pos.y-30):(pos.y+20);
  74. let left=pos.x>clientW-50?(pos.x-30):(pos.x+20);
  75. codeIcon.style.opacity=0.9;
  76. codeIcon.style.top=top+"px";
  77. codeIcon.style.left=left+"px";
  78. },1);
  79. }
  80. },false);
  81.  
  82. function highlight(){
  83. if(customInput){
  84. selStr=prompt("Input code here","");
  85. if(!selStr)return;
  86. codes=selStr.replace(/&/g, "&amp;").replace(/\</g,"&lt;").replace(/\>/g,"&gt;");
  87. }
  88. let html='<title>Code Snippet</title>'+
  89. '<link rel="stylesheet" href="https://cdn.rawgit.com/google/code-prettify/master/styles/sons-of-obsidian.css"/>'+
  90. '<script>var code,codeStr;window.onload=function(){code=document.querySelector("#code");codeStr=code.innerHTML.replace(/&amp;/g, "&").replace(/&(nbsp;|amp;|#39;|quot;)/g, "&amp;$1");prettyPrint();'+
  91. 'document.querySelector("body>a:nth-child(1)").onclick=function(){'+
  92. 'code.innerHTML=js_beautify('+
  93. 'codeStr.replace(/&gt;/g, \'>\').replace(/&lt;/g, \'<\').replace(/\'(\\\\\'|[^\'])*?\'/g, function(word){'+
  94. 'return word.replace(/>/g, \'&gt;\').replace(/</g, \'&lt;\');}'+
  95. ').replace(/\"(\\\\\"|[^\"])*?\"/g, function(word){'+
  96. 'return word.replace(/>/g, \'&gt;\').replace(/</g, \'&lt;\');}'+
  97. '));code.className=\'prettyprint linenums\';prettyPrint();return false;'+
  98. '};}</script>'+
  99. '<script src="https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.js?skin=sons-of-obsidian"></script>'+
  100. '<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.6.4/beautify.min.js"></script>'+
  101. '<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.6.4/beautify-html.min.js"></script>'+
  102. '<script src="https://cdnjs.cloudflare.com/ajax/libs/js-beautify/1.6.4/beautify-css.min.js"></script>'+
  103. 'Code formatting: <a href="#">Javaspcript</a> '+
  104. '<a href="#" onclick="code.innerHTML=html_beautify(codeStr);code.className=\'prettyprint linenums\';prettyPrint();return false;">Html</a> '+
  105. '<a href="#" onclick="code.innerHTML=css_beautify(codeStr);code.className=\'prettyprint linenums\';prettyPrint();return false;">Css</a> '+
  106. '<a href="#" onclick="code.innerHTML=codeStr;code.className=\'prettyprint linenums\';prettyPrint();return false;">Raw</a> <b style="color:red">('+selStr.replace(/\s/g,"").length+' words)</b>'+
  107. '<pre id="code" class="prettyprint linenums" style="word-wrap: break-word; white-space: pre-wrap;border: 1px solid rgb(136, 136, 204);border-radius: 8px;">' + codes + "</pre>";
  108.  
  109. let c = _unsafeWindow.open("", "_blank", "width=750, height=400, location=0, resizable=1, menubar=0, scrollbars=0");
  110. c.document.write(html);
  111. c.document.close();
  112. }
  113. function hideIcon(){
  114. codeIcon.style.opacity=0;
  115. customInput=false;
  116. if(codeIcon.parentNode)codeIcon.parentNode.removeChild(codeIcon);
  117. }
  118. function getMousePos(event) {
  119. var e = event || window.event;
  120. scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
  121. scrollY = document.documentElement.scrollTop || document.body.scrollTop;
  122. var x = (e.pageX || e.clientX) - scrollX;
  123. var y = (e.pageY || e.clientY) - scrollY;
  124. return { 'x': x, 'y': y };
  125. }
  126. var _GM_registerMenuCommand=GM_registerMenuCommand||(typeof GM!='undefined' && GM.registerMenuCommand);
  127. if(!_GM_registerMenuCommand)_GM_registerMenuCommand=(s,f)=>{};
  128. _GM_registerMenuCommand("Highlight", ()=>{
  129. selStr=document.getSelection().toString();
  130. codes=selStr.replace(/&/g, "&amp;").replace(/\</g,"&lt;").replace(/\>/g,"&gt;");
  131. if(!codes){
  132. customInput=true;
  133. }
  134. highlight();
  135. });
  136. })();