// ==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://greasyfork.org/scripts/422854-bubble-message.js // @include https://leetcode-cn.com/problems/* // @downloadURL none // ==/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(); }); })();