Greasy Fork is available in English.

leetcode

leetcode plugin

  1. // ==UserScript==
  2. // @name leetcode
  3. // @namespace http://redswallow.me/blog
  4. // @version 0.1
  5. // @description leetcode plugin
  6. // @author redswallow
  7. // @include https://oj.leetcode.com/problems/*
  8. // @grant GM_addStyle
  9. // @grant GM_setValue
  10. // @grant GM_getValue
  11. // @run-at document-start
  12. // ==/UserScript==
  13.  
  14. // 延迟调用函数
  15. var call = function (f) {
  16. setTimeout.apply(this, [f].concat([0]).concat(Array.apply(Array, arguments).slice(1)));
  17. };
  18.  
  19. // 设置项
  20. var config = function () {
  21. var config = {}, storageKey = 'leetcode_plugin_config';
  22. var onputs = [];
  23. // 写入到内存
  24. var put = function (key, value) {
  25. onputs.map(function (f) { f(key, value, config[key]); });
  26. config[key] = value;
  27. return value;
  28. };
  29. // 从内存读取
  30. var get = function (key, value, type) {
  31. if (!(key in config)) return value;
  32. var val = config[key];
  33. if (typeof val === 'undefined') return value;
  34. if (type && (val === null || val.constructor !== type)) return value;
  35. return val;
  36. };
  37. // 读取到内存
  38. var read = function () {
  39. try { config = JSON.parse(GM_getValue(storageKey, '{}')); }
  40. catch (e) { config = {}; }
  41. };
  42. // 从内存写出
  43. var write = function () {
  44. GM_setValue(storageKey, JSON.stringify(config));
  45. };
  46. // 当内存配置被修改时调用
  47. var onput = function (f) {
  48. onputs.push(f);
  49. };
  50. // 初始化
  51. read();
  52. return {
  53. 'put': put,
  54. 'get': get,
  55. 'read': read,
  56. 'write': write,
  57. 'onput': onput,
  58. };
  59. };
  60.  
  61. var html = {
  62. 'acCheckbox' : '<div class="btn-group btn-group-sm" data-toggle="buttons"><label class="btn btn-default active"><input type="checkbox" checked>AC</label><label class="btn btn-default active"><input type="checkbox" checked>WA</label><label class="btn btn-default active"><input type="checkbox" checked>Undo</label></div>',
  63. 'difficultyCheckbox' : '<div class="btn-group btn-group-sm" data-toggle="buttons"><label class="btn btn-default active"><input type="checkbox" checked>Easy</label><label class="btn btn-default active"><input type="checkbox" checked>Medium</label><label class="btn btn-default active"><input type="checkbox" checked>Hard</label></div>',
  64. 'allBtn' : '<div class="btn btn-sm btn-default">All</div>',
  65. 'notAcBtn' : '<div class="btn btn-sm btn-default">!AC</div>',
  66. 'easyBtn' : '<div class="btn btn-sm btn-default">Easy</div>',
  67. 'mediumBtn' : '<div class="btn btn-sm btn-default">Medium</div>',
  68. 'hardBtn' : '<div class="btn btn-sm btn-default">Hard</div>'
  69. }
  70.  
  71. function init() {
  72. console.log("init");
  73. // 加载用户配置
  74. //config = config();
  75. var filterDiv = document.createElement('div');
  76. filterDiv.id = 'filter';
  77. filterDiv.setAttribute('class','row table-centered col-md-12');
  78. filterDiv.appendChild(document.createTextNode('Filter :'));
  79. /*
  80. var acCheckbox = document.createElement('span');
  81. acCheckbox.setAttribute('class','table-centered col-md-3');
  82. acCheckbox.innerHTML = html['acCheckbox'];
  83. var difficultyCheckbox = document.createElement('span');
  84. difficultyCheckbox.setAttribute('class','table-centered col-md-3');
  85. difficultyCheckbox.innerHTML = html['difficultyCheckbox'];
  86. filterDiv.appendChild(acCheckbox);
  87. filterDiv.appendChild(difficultyCheckbox);
  88. */
  89. // ac button
  90. var allBtn = document.createElement('span');
  91. allBtn.innerHTML = html['allBtn'];
  92. allBtn.onclick = function() {
  93. $('tbody tr').show();
  94. }
  95. filterDiv.appendChild(allBtn);
  96. var notAcBtn = document.createElement('span');
  97. notAcBtn.innerHTML = html['notAcBtn'];
  98. notAcBtn.onclick = function() {
  99. $('tbody tr').show();
  100. $('.ac').parent().parent().hide();
  101. }
  102. filterDiv.appendChild(notAcBtn);
  103. // end of not ac button
  104. // difficulty filter
  105. var easyProblems = $('tbody tr td:last-child[value=1]').parent();
  106. var mediumProblems = $('tbody tr td:last-child[value=2]').parent();
  107. var hardProblems = $('tbody tr td:last-child[value=3]').parent();
  108. var easyProblemsBtn = document.createElement('span');
  109. easyProblemsBtn.innerHTML = html['easyBtn'];
  110. easyProblemsBtn.onclick = function() {
  111. easyProblems.show();mediumProblems.hide();hardProblems.hide();
  112. }
  113. filterDiv.appendChild(easyProblemsBtn);
  114. var mediumProblemsBtn = document.createElement('span');
  115. mediumProblemsBtn.innerHTML = html['mediumBtn'];
  116. mediumProblemsBtn.onclick = function() {
  117. easyProblems.hide();mediumProblems.show();hardProblems.hide();
  118. }
  119. filterDiv.appendChild(mediumProblemsBtn);
  120. var hardProblemsBtn = document.createElement('span');
  121. hardProblemsBtn.innerHTML = html['hardBtn'];
  122. hardProblemsBtn.onclick = function() {
  123. easyProblems.hide();mediumProblems.hide();hardProblems.show();
  124. }
  125. filterDiv.appendChild(hardProblemsBtn);
  126. // end of difficulty filter
  127. var searchResultRowDiv = document.getElementById('searchResultRow');
  128. searchResultRowDiv.parentNode.insertBefore(filterDiv, searchResultRowDiv);
  129. }
  130.  
  131. if (document.body) call(init);
  132. else document.addEventListener('DOMContentLoaded', init);
  133.  
  134. GM_addStyle("#filter span {padding-left:5px; padding-right:5px;}");