AtCoderJudgeStatusNotifier

ジャッジの進行状況をデスクトップ通知で表示

  1. // ==UserScript==
  2. // @name AtCoderJudgeStatusNotifier
  3. // @namespace https://twitter.com/merom686
  4. // @version 1.0
  5. // @description ジャッジの進行状況をデスクトップ通知で表示
  6. // @author merom686
  7. // @match https://atcoder.jp/contests/*/submissions/me*
  8. // @grant GM_notification
  9. // @grant window.focus
  10. // ==/UserScript==
  11.  
  12. (function(){
  13. const cAC = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAALklEQVRYhe3OIQEAAAgDsAd9UNpBDMzE/NLpfoqAgICAgICAgICAgICAgMB34ABPc7yI0MaTwgAAAABJRU5ErkJggg==';
  14. const cWA = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAL0lEQVRYhe3OIQEAAAgDMBLSlG40gBg3E/Ornb6kEhAQEBAQEBAQEBAQEBAQSAcediCopjwhoTMAAAAASUVORK5CYII=';
  15. const cWJ = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAALElEQVRYhe3OoQEAAAwCIL/2/O0MC4FO2t5SBAQEBAQEBAQEBAQEBAQE1oEHZKaQiHWRRSkAAAAASUVORK5CYII=';
  16. let s0 = '';
  17. const observer = new MutationObserver(mutations => {
  18. for (const mutation of mutations) {
  19. for (let node of mutation.addedNodes) {
  20. if (node.tagName == 'SPAN') node = node.parentNode;
  21. if (node.tagName == 'TD') {
  22. const text = node.innerText;
  23. if (text == 'WJ') continue;
  24. const td = node.parentNode.getElementsByTagName('TD');
  25. const s1 = td[1].textContent + ' (' + td[0].textContent + ')\n\n' + text;
  26. if (s1 == s0) continue; else s0 = s1;
  27. GM_notification({
  28. title: 'AtCoderJudgeStatusNotifier',
  29. text: s1,
  30. image: text == 'AC' ? cAC : /[A-Z]/.test(text) ? cWA : cWJ,
  31. timeout: /[A-Z]/.test(text) ? 10000 : 2000,
  32. onclick: () => window.focus(),
  33. });
  34. }
  35. break;
  36. }
  37. }
  38. });
  39. observer.observe(document, {childList:true, subtree:true});
  40. })();

QingJ © 2025

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