LeetCode Assistant

【使用前先看介绍/有问题可反馈】力扣助手 (LeetCode Assistant):为力扣页面增加辅助功能。

Från och med 2021-09-10. Se den senaste versionen.

// ==UserScript==
// @name         LeetCode Assistant
// @namespace    http://tampermonkey.net/
// @version      1.0.0
// @description  【使用前先看介绍/有问题可反馈】力扣助手 (LeetCode Assistant):为力扣页面增加辅助功能。
// @author       cc
// @require      https://cdn.bootcss.com/jquery/3.4.1/jquery.js
// @require      https://greatest.deepsurf.us/scripts/422854-bubble-message.js
// @include      https://leetcode-cn.com/problems/*
// ==/UserScript==

(function() {
  const bm = new BubbleMessage();
  var executing = false;

  function insertTextarea() {
    let textarea = document.createElement('textarea');
    textarea.setAttribute('id', 'leetcode-assistant-textarea');
    document.body.appendChild(textarea);
  }

  function executeCopy(value) {
    let textarea = document.getElementById('leetcode-assistant-textarea');
    textarea.value = value;
    textarea.setAttribute('value', value);
    textarea.select();
    document.execCommand('copy');
    bm.message({
      type: 'success',
      message: '复制成功',
      duration: 1500,
    });
  }

  function requestCode(qid) {
    let query = `
      query mySubmissionDetail($id: ID!) {
        submissionDetail(submissionId: $id) {
          id
          code
          runtime
          memory
          rawMemory
          statusDisplay
          timestamp
          lang
          passedTestCaseCnt
          totalTestCaseCnt
          sourceUrl
          question {
            titleSlug
            title
            translatedTitle
            questionId
            __typename
          }
          ... on GeneralSubmissionNode {
            outputDetail {
              codeOutput
              expectedOutput
              input
              compileError
              runtimeError
              lastTestcase
              __typename
            }
            __typename
          }
          submissionComment {
            comment
            flagType
            __typename
          }
          __typename
        }
      }`;
    $.ajax({
      url: 'https://leetcode-cn.com/graphql/',
      method: 'POST',
      contentType: 'application/json',
      data: JSON.stringify({
        operationName: 'mySubmissionDetail',
        query: query,
        variables: {
          id: qid
        },
      }),
    }).then(res => {
      executeCopy(res.data.submissionDetail.code);
    });
  }

  function insertCopyFunction() {
    let tbody = document.querySelector('.ant-table-tbody');
    let trs = [...tbody.querySelectorAll('tr')];
    let processTr = (tr) => {
      let qid = tr.dataset.rowKey;
      let cell = tr.querySelector(':nth-child(4)');
      cell.title = '点击复制代码'
      cell.style = 'cursor: pointer; color: #007aff';
      cell.addEventListener('click', function() {
        requestCode(qid);
      });
    }
    trs.forEach(processTr);
    let observer = new MutationObserver(function(mutations) {
      console.log(mutations);
      mutations.forEach((mutation) => {
        if (mutation.type == 'childList' && mutation.addedNodes.length == 1) {
          let tr = mutation.addedNodes[0];
          if (tr.tagName == 'TR')
            processTr(tr);
        }
      });
    });
    observer.observe(tbody, { childList: true, subtree: true });
    executing = false;
  }

  function listenHistoryState() {
    const _historyWrap = function(type) {
      const orig = history[type];
      const e = new Event(type);
      return function() {
          const rv = orig.apply(this, arguments);
          e.arguments = arguments;
          window.dispatchEvent(e);
          return rv;
        };
      };
    history.pushState = _historyWrap('pushState');
    window.addEventListener('pushState', () => {
      if (!executing) {
        executing = true;
        main();
      }
    });
  }

  function main() {
    if (location.href.match(/\/submissions\/$/)) {
      (function r() {
        if (document.querySelector('.ant-table-thead')) {
          insertCopyFunction();
        } else {
          setTimeout(r, 500);
        }
      })();
    } else {
      executing = false;
    }
  }

  window.addEventListener('load', () => {
    insertTextarea();
    listenHistoryState();
    main();
  });
})();