您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
왓챠 구독 해지 UI의 다크패턴을 제거하고 사용성을 개선합니다.
// ==UserScript== // @name 왓챠 구독 해지 UI 사용성 개선 // @description 왓챠 구독 해지 UI의 다크패턴을 제거하고 사용성을 개선합니다. // @namespace https://github.com/seocochan // @author seoco // @grant none // @version 0.1.0 // @license MIT // @supportURL https://github.com/seocochan/decision-to-leave-watcha/issues // @match https://watcha.com/* // @run-at document-idle // @require https://cdn.jsdelivr.net/npm/@violentmonkey/dom@2 // ==/UserScript== let currentPath = window.location.pathname; const pages = { '/settings': { isModified: false, handler() { const button = Array.from(document.getElementsByTagName('button')) .find(button => button.innerText === '해지 신청') const pElement = button ? button.closest('p') : null; if (!pElement) return; const liElement = Array.from(document.getElementsByTagName('a')) .find(a => a.getAttribute('href') === '/coupon/register') .closest('li'); const clone = liElement.cloneNode(true); const aElement = clone.getElementsByTagName('a')[0]; aElement.setAttribute('href', '/cancel/step1'); aElement.innerText = button.innerText; liElement.after(clone); pElement.remove(); this.isModified = true; } }, '/cancel/step2': { isModified: false, handler() { const buttons = Array.from(document.getElementsByTagName('button')); const [button1, button2] = buttons.filter(button => { const divs = button.getElementsByTagName('div'); return divs.length && [ '이용 자격 유지하기', '이용 자격 이대로 포기하기' ].includes(divs[0].innerText); }); if (!button1 || !button2) return; [button1.className, button2.className] = [button2.className, button1.className]; this.isModified = true; } }, }; const initPagesStates = () => { Object.values(pages).forEach(page => page.isModified = false); }; new MutationObserver((mutations, observer) => { const path = window.location.pathname; const page = pages[path]; if (!page) { currentPath = path; return; } if (path === currentPath && page.isModified) { return; } if (path !== currentPath) { initPagesStates(); } page.handler(); currentPath = path; }).observe(document.body, {childList: true, subtree: true});