您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Save TODO Problems for CF, QOJ, and AtCoder
当前为
- // ==UserScript==
- // @name TODO Problem Manager
- // @namespace http://tampermonkey.net/
- // @version 0.2
- // @description Save TODO Problems for CF, QOJ, and AtCoder
- // @author jakao
- // @license MIT
- // @match *://qoj.ac/*
- // @match *://codeforces.com/contest/*
- // @match *://codeforces.com/gym/*
- // @match *://atcoder.jp/*
- // @grant GM_setValue
- // @grant GM_getValue
- // ==/UserScript==
- (function() {
- 'use strict';
- function getUrls() {
- return GM_getValue('savedUrls', {});
- }
- function saveUrls(urls) {
- GM_setValue('savedUrls', urls);
- }
- const modal = document.createElement('div');
- function createModal() {
- modal.id = 'urlModal';
- modal.style.position = 'fixed';
- modal.style.top = '50%';
- modal.style.left = '50%';
- modal.style.transform = 'translate(-50%, -50%)';
- modal.style.zIndex = '10000';
- modal.style.backgroundColor = '#fff';
- modal.style.border = '1px solid #ccc';
- modal.style.boxShadow = '0 4px 6px rgba(0, 0, 0, 0.1)';
- modal.style.padding = '20px';
- modal.style.width = '80%';
- modal.style.maxWidth = '600px';
- modal.style.maxHeight = '80%';
- modal.style.overflowY = 'auto';
- modal.style.display = 'none';
- document.body.appendChild(modal);
- }
- function displaySavedUrls() {
- const urls = getUrls();
- createModal();
- // 清空彈窗內容,保留 Close 按鈕
- modal.innerHTML = '<button style="position: absolute; top: 10px; right: 10px; background-color: #f50057; color: #fff; border: none; padding: 5px; cursor: pointer;" onclick="document.getElementById(\'urlModal\').style.display=\'none\';">Close</button>';
- modal.innerHTML += '<h2>Saved Problems</h2>';
- for (const domain in urls) {
- const domainSection = document.createElement('div');
- domainSection.innerHTML = `<h3>${domain}</h3>`;
- const urlList = document.createElement('ul');
- urls[domain].forEach((url, index) => {
- const listItem = document.createElement('li');
- listItem.innerHTML = `
- <button style="margin-left: 10px;">Delete</button>
- <a href="${url.link}" target="_blank">${url.name}</a>
- `;
- const deleteButton = listItem.querySelector('button');
- deleteButton.onclick = () => {
- deleteUrl(domain, index);
- };
- urlList.appendChild(listItem);
- });
- domainSection.appendChild(urlList);
- modal.appendChild(domainSection);
- }
- const saveButton = document.createElement('button');
- saveButton.textContent = 'Save Problem';
- saveButton.style.position = 'absolute';
- saveButton.style.top = '10px';
- saveButton.style.right = '70px';
- saveButton.style.backgroundColor = '#3D9140';
- saveButton.style.color = '#fff';
- saveButton.style.border = 'none';
- saveButton.style.padding = '5px';
- saveButton.style.cursor = 'pointer';
- saveButton.onclick = function() {
- addUrl();
- };
- modal.appendChild(saveButton);
- modal.style.display = 'block';
- }
- function deleteUrl(domain, index) {
- const urls = getUrls();
- if (urls[domain]) {
- urls[domain].splice(index, 1);
- if (urls[domain].length === 0) {
- delete urls[domain];
- }
- saveUrls(urls);
- displaySavedUrls();
- alert('URL deleted successfully!');
- }
- }
- function addUrl(){
- const currentProb = {
- "link": window.location.href,
- "name": window.location.href
- };
- const regexCF = /^https:\/\/codeforces\.com\/(gym|contest)\/\d+\/problem\/[A-Za-z0-9]+$/;
- const regexQOJ = /^https:\/\/qoj\.ac\/contest\/\d+\/problem\/[A-Za-z0-9]+$/;
- const regexAC = /^https:\/\/atcoder\.jp\/contests\/[^\/]+\/tasks\/[^\/]+$/;
- if (regexCF.test(currentProb.link)) {
- const parts = currentProb.link.split('/');
- currentProb.name = parts[4] + parts[6];
- }
- else if (regexQOJ.test(currentProb.link)) {
- const parts = currentProb.link.split('/');
- currentProb.name = parts[6];
- }
- else if (regexAC.test(currentProb.link)) {
- const parts = currentProb.link.split('/');
- currentProb.name = parts[6];
- }
- const domain = new URL(currentProb.link).hostname.split('.')[0];
- const urls = getUrls();
- if (!urls[domain]) {
- urls[domain] = [];
- }
- if (!urls[domain].some(item => item.link === currentProb.link)) {
- urls[domain].push(currentProb);
- saveUrls(urls);
- displaySavedUrls();
- alert('URL saved successfully!');
- } else {
- alert('URL is already saved.');
- }
- }
- function addViewButton() {
- const viewButton = document.createElement('button');
- viewButton.textContent = 'View Saved Problems';
- viewButton.style.position = 'fixed';
- viewButton.style.bottom = '10px';
- viewButton.style.right = '10px';
- viewButton.style.zIndex = '9999';
- viewButton.style.backgroundColor = '#3f51b5';
- viewButton.style.color = '#fff';
- viewButton.style.border = 'none';
- viewButton.style.padding = '10px';
- viewButton.style.cursor = 'pointer';
- viewButton.onclick = displaySavedUrls;
- document.body.appendChild(viewButton);
- }
- function init() {
- createModal();
- addViewButton();
- window.deleteUrl = deleteUrl;
- window.addUrl = addUrl;
- }
- init();
- })();