// ==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
// ==/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);
})({});