UWorld Copy Unlocker

A new extension

Size

2.1 KB

Version

1.0.2

Created

Apr 2, 2026

Updated

13 days ago

1// ==UserScript==
2// @name		UWorld Copy Unlocker
3// @description		A new extension
4// @version		1.0.2
5// @match		https://*.apps.uworld.com/*
6// @icon		https://apps.uworld.com/courseapp/usmle/v48/favicon.ico
7// ==/UserScript==
8(function() {
9    'use strict';
10
11    function removeCopyRestrictions() {
12        console.log('[UWorld Copy Unlocker] Removing copy restrictions...');
13
14        // Remove user-select: none from all elements
15        const style = document.createElement('style');
16        style.id = 'uworld-copy-unlocker';
17        style.textContent = `
18            * {
19                -webkit-user-select: text !important;
20                -moz-user-select: text !important;
21                -ms-user-select: text !important;
22                user-select: text !important;
23            }
24        `;
25        document.head.appendChild(style);
26
27        // Remove copy/cut/paste event blockers
28        const events = ['copy', 'cut', 'paste', 'selectstart', 'contextmenu'];
29        events.forEach(eventName => {
30            document.addEventListener(eventName, function(e) {
31                e.stopImmediatePropagation();
32            }, true);
33        });
34
35        console.log('[UWorld Copy Unlocker] Copy restrictions removed successfully.');
36    }
37
38    function init() {
39        removeCopyRestrictions();
40
41        // Also run on DOM changes in case the app re-applies restrictions
42        const observer = new MutationObserver(debounce(() => {
43            const existing = document.getElementById('uworld-copy-unlocker');
44            if (!existing) {
45                console.log('[UWorld Copy Unlocker] Re-applying copy restrictions removal...');
46                removeCopyRestrictions();
47            }
48        }, 500));
49
50        observer.observe(document.body, { childList: true, subtree: true });
51    }
52
53    function debounce(fn, delay) {
54        let timer;
55        return function(...args) {
56            clearTimeout(timer);
57            timer = setTimeout(() => fn.apply(this, args), delay);
58        };
59    }
60
61    if (document.readyState === 'loading') {
62        document.addEventListener('DOMContentLoaded', init);
63    } else {
64        init();
65    }
66})();