SO - Code line nums

Show line numbers next to code in question

目前为 2014-06-10 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name SO - Code line nums
  3. // @namespace http://mdev.me/
  4. // @description Show line numbers next to code in question
  5. // @include http://*stackoverflow.com/questions/*
  6. // @version 6
  7. // @grant none
  8. // ==/UserScript==
  9.  
  10. var styles = document.createElement('link');
  11. styles.rel = 'stylesheet';
  12. styles.type = 'text/css';
  13. styles.href = 'http://mdev.me/SOcln.css';
  14. document.querySelector('head').appendChild(styles);
  15.  
  16. var initLines = function() {
  17. var codeBlocks = N('body').findAll('#question pre, .answer pre, .wmd-preview pre');
  18. O(codeBlocks).loop(function(n){
  19. n = N(n);
  20. if(n.hasClass('mdevLinesEnabled') || n.hasClass('mdevLinesDisabled'))
  21. {
  22. n.removeClass('mdevLinesEnabled');n.removeClass('mdevLinesDisabled');
  23. N(n.find('.mdevLineBox')).remove();
  24. N(n.find('.mdevLinesToggle')).remove();
  25. n.n.style.paddingLeft = '';
  26. }
  27. n.n.style.position = 'relative';
  28. var codeEl = n.find("code");
  29. if(!codeEl) return;
  30. var codeH = codeEl.offsetHeight;
  31. var span = N(codeEl).find("span");
  32. var spanH = 17;
  33. var lineNoOffset = 1;
  34. if(span)
  35. {
  36. spanH = span.offsetHeight;
  37. var spanLines = span.innerHTML.match(/\r?\n/g);
  38. spanLines = spanLines ? spanLines.length+1 : 1;
  39. spanH = spanH/spanLines;
  40. if(N(span).find('span')) span = N(span).find('span');
  41. var m = null
  42. if(m = span.innerHTML.match(/^#Line:(\d+)/))
  43. {
  44. lineNoOffset = D(m[1]).toInt();
  45. }
  46. }
  47. else
  48. {
  49. spanH = parseInt(N(codeEl).getCompStyle('lineHeight'));
  50. if(m = codeEl.innerHTML.match(/^#Line:(\d+)/))
  51. {
  52. lineNoOffset = D(m[1]).toInt();
  53. }
  54. }
  55. var firstSpan = N(codeEl).find("span");
  56. var lastSpan = N(codeEl).findAll("span");
  57. lastSpan = lastSpan[lastSpan.length-1];
  58. var lines = Math.floor(codeH/spanH);
  59. if(firstSpan.innerHTML.match(/^\s*\r?\n\s*$/)) lines++;
  60. if(lastSpan.innerHTML.match(/^\s*\r?\n\s*$/)) lines++;
  61. if(lines>5)
  62. {
  63. n.addClass('mdevLinesEnabled');
  64. var lineBox = document.createElement('div');
  65. lineBox.className = 'mdevLineBox';
  66. lineBox.style.visibility = 'hidden';
  67. var lineNosAdded = 0;
  68. while(lineNosAdded<lines && lineNosAdded<200)
  69. {
  70. var lineNo = document.createElement('span');
  71. lineNo.className = 'mdevLineNo';
  72. lineNo.innerHTML = lineNosAdded+lineNoOffset;
  73. lineBox.appendChild(lineNo);
  74. lineNosAdded++;
  75. }
  76. n.n.appendChild(lineBox);
  77. var linesToggle = document.createElement('div');
  78. linesToggle.className = 'mdevLinesToggle';
  79. linesToggle.innerHTML = '#L';
  80. linesToggle.style.cursor = 'pointer';
  81. n.n.appendChild(linesToggle);
  82. disableSelection(linesToggle);
  83. addEvent(linesToggle,'click',function(e){
  84. var toggleLines = function(showHide){
  85. var pre = N(this).parent();
  86. var box = N(this).prev('div','mdevLineBox');
  87. var show = df(showHide,'string')&&showHide=='show';
  88. var hide = df(showHide,'string')&&showHide=='hide';
  89. var override = show||hide;
  90. show = (override&&show) || (!override&&N(box).getCompStyle('visibility')!='visible');
  91. hide = (override&&hide) || (!override&&N(box).getCompStyle('visibility')=='visible');
  92. if(show)
  93. {
  94. pre.style.paddingLeft = box.offsetWidth+10+"px";
  95. box.style.visibility = 'visible';
  96. }
  97. else if(hide)
  98. {
  99. pre.style.paddingLeft = "5px";
  100. box.style.visibility = 'hidden';
  101. }
  102. }
  103. var disable = function() {
  104. var pre = N(this).parent();
  105. toggleLines.call(this,'hide');
  106. N(pre).removeClass('mdevLinesEnabled');
  107. N(pre).addClass('mdevLinesDisabled');
  108. }
  109. if(e.shiftKey)
  110. {
  111. var show = N(N(this).prev('div','mdevLineBox')).getCompStyle('visibility')!='visible';
  112. O(N('#question').findAll('pre.mdevLinesEnabled')).loop(function(pre) {
  113. var that = N(pre).find('.mdevLinesToggle');
  114. if(e.ctrlKey) disable.call(that);
  115. else toggleLines.call(that,show?'show':'hide');
  116. })
  117. }
  118. else if(e.ctrlKey)
  119. {
  120. disable.call(this);
  121. }
  122. else toggleLines.call(this);
  123. })
  124. }
  125. });
  126. }
  127. var initScript = function() {
  128. addEvent(window,'load',function() {
  129. initLines();
  130. })
  131. }
  132. function disableSelection(target)
  133. {
  134. if (typeof target.onselectstart!="undefined")
  135. target.onselectstart=function(){return false}
  136. else if (typeof target.style.MozUserSelect!="undefined")
  137. target.style.MozUserSelect="none"
  138. else
  139. target.onmousedown=function(){return false}
  140. target.style.cursor = "default"
  141. }
  142. var scriptTag = document.createElement('script');
  143. scriptTag.type = 'text/javascript';
  144. scriptTag.src = 'https://gf.qytechs.cn/scripts/1780-so-code-line-nums-prot-min-js-utility/code/SO%20-%20Code%20line%20nums%20%28protminjs%20utility%29.js';
  145. scriptTag.onreadystatechange=function(){if(this.readyState=='complete')initScript();}
  146. scriptTag.onload = initScript;
  147. document.body.appendChild(scriptTag);
  148. window.initLines = initLines;

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址