// ==UserScript== // @name A Universal Script to Re-Enable the Selection and Copying // @version 1.4.0 // @description Enables select, right-click, copy and drag on pages that disable them. // @include /^https?\:\/\// // @grant none // @run-at document-start // @namespace https://greasyfork.org/users/371179 // @downloadURL none // ==/UserScript== "use strict"; (function(usrScrDS) { function isDocumentObj(x) { return x && x.nodeType == 9 } function isHTMLElementObj(x) { return x && x.nodeType == 1 } function appendCssEnabler(container, cssStyle) { if (!isHTMLElementObj(container)) return; try { var css = document.createElement('style'); css.type = 'text/css'; css.innerHTML = cssStyle; container.appendChild(css); } catch (e) {} } // console.log('script at', location+"") if (document == null) return; if (!document.documentElement) return; var mKey = 'dqzadwpujtct'; var nonFalseFunc = '___nff_' + mKey + '___'; var rvSCC = '___returnValue_' + mKey + '___'; usrScrDS.utSelectionColorHack = 'msmtwejkzrqa'; var cssStyleOnReady = '*, body *, div, span, body *::before, body *::after, *:hover, *:link, *:visited, *:active , *[style], *[class]{' + '-webkit-touch-callout: default !important; -webkit-user-select: auto !important; ' + '-khtml-user-select: auto !important; -moz-user-select: auto !important; ' + '-ms-user-select: auto !important; user-select: auto !important;}' + 'html body *:hover>img[src]{pointer-events:auto;}' + '[' + usrScrDS.utSelectionColorHack + '] :not(input):not(textarea)::selection{ background-color: Highlight !important; color: HighlightText !important;}' + '[' + usrScrDS.utSelectionColorHack + '] :not(input):not(textarea)::-moz-selection{ background-color: Highlight !important; color: HighlightText !important;}'; //dummy function in case alert replacement is not valid usrScrDS.mAlert_DOWN = function() {} usrScrDS.mAlert_UP = function() {} function universaler(originalFunc, pName) { var uid = (+new Date) + "_" + pName var resFX = function(ev) { var func; var p = false; try { func = this[pName]; if (typeof func == 'function' && func.uid === uid) { p = true; } } catch (e) {} var res = originalFunc.apply(this, arguments); if (p) { if (res !== false) { originalFunc[nonFalseFunc] = true; this[pName] = originalFunc; return res; } } else { return res; } } resFX.toString = () => originalFunc.toString() resFX.uid = uid return resFX; } usrScrDS.evtListener_disableAll = function disableAll(event) { var elmNode = event.target while (elmNode && elmNode.nodeType > 0) { var pName = 'on' + event.type var f = elmNode[pName]; if (f && f[nonFalseFunc] !== true) { var nf = universaler(f, pName); nf[nonFalseFunc] = true; elmNode[pName] = nf; } elmNode = elmNode.parentNode; } } usrScrDS.isAnySelection = function anySelection() { var sel = (window.getSelection || function() {})(); if (!sel) return null; if (typeof sel.isCollapsed == 'boolean') return !sel.isCollapsed; return sel.toString().length > 0 } usrScrDS.productFakeAlert = function(_alert) { var _mAlert = null; if (_alert && typeof _alert == 'function') { _mAlert = function alert(msg) { setTimeout(() => { alert._click.isDisabled() ? console.log("alert msg disabled: ", msg) : _alert.apply(this, arguments) }, 9); }; _mAlert.toString = () => "function alert() { [native code] }" } return _mAlert } function enableSelectClickCopy() { var preventEventList01 = ['copy', 'contextmenu', 'select', 'selectstart', 'dragstart', 'beforecopy']; var isAnySelection = usrScrDS.isAnySelection Event.prototype.preventDefault = (function(f) { var eys = preventEventList01; return function preventDefault() { if (eys.indexOf(this.type) >= 0) return; if (this.type == 'keydown' || this.type == 'keyup') { if (this.ctrlKey && this.keyCode == 67 && !this.altKey && !this.shiftKey && isAnySelection() === true) return; } return f.apply(this); } })(Event.prototype.preventDefault); Event.prototype.preventDefault.toString = () => "function preventDefault() { [native code] }" var exs = preventEventList01; Object.defineProperty(Event.prototype, "returnValue", { get() { return rvSCC in this ? this[rvSCC] : true; }, set(newValue) { if (exs.indexOf(this.type) < 0 && newValue === false) this.preventDefault(); this[rvSCC] = newValue; }, enumerable: true, configurable: true }); var ezs = preventEventList01; var eventsCount = ezs.length; for (var i = 0; i < eventsCount; i++) { var event = ezs[i]; document.addEventListener(event, usrScrDS.evtListener_disableAll, true); } var _alert = window.alert if (_alert && typeof _alert == 'function') { var _mAlert = usrScrDS.productFakeAlert(_alert) if (_mAlert) { var clickLog = { isDisabled: function() { return this.status == 1 && this.last + 50 > +new Date; } } _mAlert._click = clickLog usrScrDS.mAlert_DOWN = function() { clickLog.last = +new Date; clickLog.status = 1; } usrScrDS.mAlert_UP = function() { clickLog.last = +new Date; clickLog.status = 0; } window.alert = _mAlert } } usrScrDS.trigger_cssHighlight = () => { usrScrDS.trigger_cssHighlight = null try { //firefox bug: some element, even body, gives wrong bg color -> choose random element on the page. var s = [...document.querySelectorAll('a,p,div,span,b,i,strong,li')].filter(elm => elm.childElementCount === 0); var elm = (!s.length) ? document.body : s[s.length >> 1]; var styles = window.getComputedStyle(elm, ':selection'); var bgColor = styles["backgroundColor"] if (/^rgba\(\d+,\s*\d+,\s*\d+,\s*0\)$/.test(bgColor)) document.documentElement.setAttribute(usrScrDS.utSelectionColorHack, ""); } catch (e) {} }; } enableSelectClickCopy() appendCssEnabler(document.documentElement, cssStyleOnReady); var cid_mouseup = 0; var alert_bypass_events_down = ["mousedown", "click", "dblclick", "contextmenu"]; var alert_bypass_eventFunc_down = function(evt) { if (usrScrDS.trigger_cssHighlight) window.requestAnimationFrame(usrScrDS.trigger_cssHighlight); if (evt.type != "contextmenu" && evt.which != 3) return; if (cid_mouseup > 0) { clearTimeout(cid_mouseup) cid_mouseup = 0; } usrScrDS.mAlert_DOWN(); } var alert_bypass_eventFunc_up = function(evt) { if (evt.which != 3) return; cid_mouseup = setTimeout(function() { usrScrDS.mAlert_UP(); }, 17); } alert_bypass_events_down.forEach(function(event) { document.addEventListener(event, alert_bypass_eventFunc_down, true); }) document.addEventListener("mouseup", alert_bypass_eventFunc_up, true); })({});