// ==UserScript== // @name A Universal Script to Re-Enable the Selection and Copying // @name:zh-TW A Universal Script to Re-Enable the Selection and Copying // @name:zh-CN 通用脚本重开启选取复制 // @version 1.8.1.2 // @icon https://image.flaticon.com/icons/png/128/3848/3848147.png // @description Enables select, right-click, copy and drag on pages that disable them. Enhanced Feature: Alt Key HyperLink Text Selection // @description:zh-TW 破解鎖右鍵,解除禁止復制、剪切、選擇文本、右鍵菜單、文字複製、文字選取、圖片右鍵等限制。增強功能:Alt鍵超連結文字選取。 // @description:zh-CN 破解锁右键,解除禁止复制、剪切、选择文本、右键菜单、文字复制、文字选取、图片右键等限制。增强功能:Alt键超连结文字选取。 // @match http://*/* // @match https://*/* // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @grant GM_setValue // @grant GM_getValue // @grant GM_addValueChangeListener // @grant GM_listValues // @run-at document-start // @namespace https://greasyfork.org/users/371179 // @downloadURL none // ==/UserScript== (function $$() { 'use strict'; if (document == null || !document.documentElement) return window.requestAnimationFrame($$); // this is tampermonkey bug?? not sure //console.log('script at', location) function $nil() {} function isLatestBrowser(){ let res; try{ let o ={$nil}; o?.$nil(); o=null; o?.$nil(); res = true; }catch(e){} return !!res; } if(!isLatestBrowser()) throw 'Browser version before 2020-01-01 is not supported. Please update to the latest version.'; function isSupportAdvancedEventListener() { if ('_b1750' in $) return $._b1750 var prop = 0; document.createAttribute('z').addEventListener('nil', $nil, { get passive() { prop++; }, get once() { prop++; } }); return ($._b1750 = prop == 2); } function isSupportPassiveEventListener() { if ('_b1650' in $) return $._b1650 var prop = 0; document.createAttribute('z').addEventListener('nil', $nil, { get passive() { prop++; } }); return ($._b1650 = prop == 1); } function inIframe () { try { return window.self !== window.top; } catch (e) { return true; } } var getSelection = window.getSelection || Error()(), requestAnimationFrame = window.requestAnimationFrame || Error()(), getComputedStyle = window.getComputedStyle.bind(window) || Error()(); const $ = { utSelectionColorHack: 'msmtwejkzrqa', utTapHighlight: 'xfcklblvkjsj', utLpSelection: 'gykqyzwufxpz', utHoverBlock: 'meefgeibrtqx', //scc_emptyblock //utNonEmptyElm: 'ilkpvtsnwmjb', utNonEmptyElmPrevElm: 'jttkfplemwzo', utHoverTextWrap: 'oseksntfvucn', ksFuncReplacerNonFalse: '___dqzadwpujtct___', ksEventReturnValue: ' ___ndjfujndrlsx___', ksSetData: '___rgqclrdllmhr___', ksNonEmptyPlainText: '___grpvyosdjhuk___', eh_capture_passive: () => isSupportPassiveEventListener() ? ($._eh_capture_passive = ($._eh_capture_passive || { capture: true, passive: true })) : true, mAlert_DOWN: function() {}, //dummy function in case alert replacement is not valid mAlert_UP: function() {}, //dummy function in case alert replacement is not valid lpKeyPressing: false, lpKeyPressingPromise: Promise.resolve(), isNum: (d) => (d > 0 || d < 0 || d === 0), isAnySelection: function() { var sel = getSelection(); return !sel ? null : (typeof sel.isCollapsed == 'boolean') ? !sel.isCollapsed : (sel.toString().length > 0); }, createCSSElement: function(cssStyle, container) { var css = document.createElement('style'); //slope: DOM throughout css.type = 'text/css'; css.textContent = cssStyle; if (container) container.appendChild(css); return css; }, createFakeAlert: function(_alert) { if (typeof _alert != 'function') return null; function alert(msg) { alert.__isDisabled__() ? console.log("alert msg disabled: ", msg) : _alert.apply(this, arguments); }; alert.toString = () => "function alert() { [native code] }"; return alert; }, createFuncReplacer: function(originalFunc, pName, resFX) { resFX = function(ev) { var res = originalFunc.apply(this, arguments); if (!this || this[pName] != resFX) return res; // if this is null or undefined, or this.onXXX is not this function if (res === false) return; // return undefined when "return false;" originalFunc[$.ksFuncReplacerNonFalse] = true; this[pName] = originalFunc; // restore original return res; } resFX.toString = () => originalFunc.toString(); return resFX; }, listenerDisableAll: function(evt) { var elmNode = evt.target; var pName = 'on' + evt.type; evt = null; Promise.resolve().then(() => { while (elmNode && elmNode.nodeType > 0) { //i.e. HTMLDocument or HTMLElement var f = elmNode[pName]; if (typeof f == 'function' && f[$.ksFuncReplacerNonFalse] !== true) { var nf = $.createFuncReplacer(f, pName); nf[$.ksFuncReplacerNonFalse] = true; elmNode[pName] = nf; } elmNode = elmNode.parentNode; } }) }, onceCssHighlightSelection: () => { if (document.documentElement.hasAttribute($.utLpSelection)) return; $.onceCssHighlightSelection = null Promise.resolve().then(() => { var s = [...document.querySelectorAll('a,p,div,span,b,i,strong,li')].filter(elm => elm.childElementCount === 0); // randomly pick an element containing text only to avoid css style bug var elm = !s.length ? document.body : s[s.length >> 1]; return elm }).then(elm => { var selectionStyle = getComputedStyle(elm, ':selection'); if (/^rgba\(\d+,\s*\d+,\s*\d+,\s*0\)$/.test(selectionStyle.getPropertyValue('background-color'))) document.documentElement.setAttribute($.utSelectionColorHack, ""); return elm; }).then(elm => { var elmStyle = getComputedStyle(elm) if (/^rgba\(\d+,\s*\d+,\s*\d+,\s*0\)$/.test(elmStyle.getPropertyValue('-webkit-tap-highlight-color'))) document.documentElement.setAttribute($.utTapHighlight, ""); }) }, clipDataProcess: function(clipboardData) { if (!clipboardData) return; const evt = clipboardData[$.ksSetData]; //NOT NULL when preventDefault is called if (!evt || evt.clipboardData !== clipboardData) return; const plainText = clipboardData[$.ksNonEmptyPlainText]; //NOT NULL when setData is called with non empty input if (!plainText) return; //BOTH preventDefault and setData are called. if (evt.cancelable !== true || evt.defaultPrevented !== false) return; $.bypass = true; evt.preventDefault(); $.bypass = false; var trimedSelectionText = getSelection().toString().trim() if (trimedSelectionText) { //there is replacement data and the selection is not empty console.log({ msg: "copy event - clipboardData replacement is allowed and the selection is not empty", oldText: trimedSelectionText, newText: plainText, }) } else { //there is replacement data and the selection is empty console.log({ msg: "copy event - clipboardData replacement is allowed and the selection is empty", oldText: trimedSelectionText, newText: plainText, }) } }, enableSelectClickCopy: function() { $.eyEvts = ['keydown', 'keyup', 'copy', 'contextmenu', 'select', 'selectstart', 'dragstart', 'beforecopy']; //slope: throughout function isDeactivePreventDefault(evt) { if ($.bypass) return false; var j = $.eyEvts.indexOf(evt.type); switch (j) { case 6: if ($.enableDragging) return false; if (evt&&evt.target && evt.target.nodeType==1 && evt.target.hasAttribute('draggable')) { $.enableDragging = true; return false; } //if(evt.target.hasAttribute('draggable')&&evt.target!=window.getSelection().anchorNode)return false; return true; case 3: if (evt.target instanceof Element && (evt.target.textContent || "").trim().length === 0) return false; //exclude elements like video return true; case -1: return false; case 0: case 1: return (evt.keyCode == 67 && (evt.ctrlKey || evt.metaKey) && !evt.altKey && !evt.shiftKey && $.isAnySelection() === true); case 2: if (!('clipboardData' in evt && 'setData' in DataTransfer.prototype)) return true; // Event oncopy not supporting clipboardData if (evt.cancelable && evt.defaultPrevented === false) {} else return true; if (evt.clipboardData[$.ksSetData] && evt.clipboardData[$.ksSetData] != evt) return true; //in case there is a bug evt.clipboardData[$.ksSetData] = evt; $.clipDataProcess(evt.clipboardData); return true; //preventDefault in clipDataProcess default: return true; } } !(function($setData) { DataTransfer.prototype.setData = (function setData() { if (arguments[0] == 'text/plain' && typeof arguments[1] == 'string') { if (arguments[1].trim().length > 0) { this[$.ksNonEmptyPlainText] = arguments[1] } else if (this[$.ksNonEmptyPlainText]) { arguments[1] = this[$.ksNonEmptyPlainText] } } $.clipDataProcess(this) let res = $setData.apply(this, arguments) return res; }) })(DataTransfer.prototype.setData); Object.defineProperties(DataTransfer.prototype, { [$.ksSetData]: { //store the event value: null, writable: true, enumerable: false, configurable: true }, [$.ksNonEmptyPlainText]: { //store the text value: null, writable: true, enumerable: false, configurable: true } }) Event.prototype.preventDefault = (function(f) { function preventDefault() { if (!isDeactivePreventDefault(this)) f.call(this); } preventDefault.toString = () => f.toString(); return preventDefault; })(Event.prototype.preventDefault); Object.defineProperty(Event.prototype, "returnValue", { get() { return $.ksEventReturnValue in this ? this[$.ksEventReturnValue] : true; }, set(newValue) { if (newValue === false && !isDeactivePreventDefault(this)) this.preventDefault(); this[$.ksEventReturnValue] = newValue; }, enumerable: true, configurable: true }); for (var i = 2, eventsCount = $.eyEvts.length; i < eventsCount; i++) { document.addEventListener($.eyEvts[i], $.listenerDisableAll, true); // Capture Event; passive:false; expected occurrence COMPLETELY before Target Capture and Target Bubble } // userscript bug ? window.alert not working let window = null; try{ window = new Function('return window')(); }catch(e){} if(window){ let _alert = window.alert; //slope: temporary if (typeof _alert == 'function') { let _mAlert = $.createFakeAlert(_alert); if (_mAlert) { let clickBlockingTo = 0; _mAlert.__isDisabled__ = () => clickBlockingTo > +new Date; $.mAlert_DOWN = () => (clickBlockingTo = +new Date + 50); $.mAlert_UP = () => (clickBlockingTo = +new Date + 20); window.alert = _mAlert } _mAlert=null; } _alert=null; } window=null; }, lpCheckPointer: function(targetElm) { if (targetElm && targetElm.nodeType == 1 && targetElm.matches('*:hover')) { if (getComputedStyle(targetElm).getPropertyValue('cursor') == 'pointer' && targetElm.textContent) return true; } return false; }, eventCancel: function(evt, toPreventDefault) { $.bypass = true; !toPreventDefault || evt.preventDefault() evt.stopPropagation(); evt.stopImmediatePropagation(); $.bypass = false; }, lpHoverBlocks:[], lpKeyAltLastPressAt:0, lpKeyAltPressInterval:0, noPlayingVideo:function(){ // prevent poor video preformance let noPlaying =true; for(const video of document.querySelectorAll('video[src]')){ if(video.paused===false) noPlaying=false; } return noPlaying; }, lpKeyDown: function(evt) { if(!$.gm_lp_enable)return; const isAltPress= (evt.key == "Alt" && evt.altKey && !evt.ctrlKey && !evt.metaKey && !evt.shiftKey) if (isAltPress) { $.lpKeyAltLastPressAt=+new Date; let element=evt.target if($.lpKeyPressing == false && element && element.parentNode && !evt.repeat && $.noPlayingVideo()){ $.lpKeyPressing = true; $.cid_lpKeyPressing=setInterval(()=>{ if($.lpKeyAltLastPressAt+500<+new Date){ $.lpCancelKeyPressAlt(); } },137); const rootNode = $.rootHTML(element); if (rootNode) { let tmp_wmEty = null; let wmTextWrap = new WeakMap(); $.lpKeyPressingPromise = $.lpKeyPressingPromise.then(() => { for (const elm of $.lpHoverBlocks) { elm.removeAttribute($.utNonEmptyElmPrevElm) elm.removeAttribute($.utHoverTextWrap) } $.lpHoverBlocks.length=0; }).then(() => { tmp_wmEty = new WeakMap(); // 1,2,3.....: non-empty elm, -1:empty elm const s = [...rootNode.querySelectorAll('*:not(button, textarea, input, script, noscript, style, link, img, br)')].filter((elm) => elm.childElementCount === 0 && (elm.textContent || '').trim().length > 0) for (const elm of s) tmp_wmEty.set(elm, 1); return s; }).then((s) => { let laterArr = []; let promises = []; let promiseCallback = parentNode => { if (wmTextWrap.get(parentNode) !== null) return; const m = [...parentNode.children].some(elm => { const value = getComputedStyle(elm).getPropertyValue('z-index'); if (typeof value == 'string' && value.length > 0) return $.isNum(+value) return false }) wmTextWrap.set(parentNode, m) if (m) { $.lpHoverBlocks.push(parentNode); parentNode.setAttribute($.utHoverTextWrap, '') } }; for (const elm of s) { let qElm = elm; let qi = 1; while (true) { let pElm = qElm.previousElementSibling; let anyEmptyHover = false; while (pElm) { if (tmp_wmEty.get(pElm) > 0) break; if (!pElm.matches(`button, textarea, input, script, noscript, style, link, img, br`) && (pElm.textContent || '').length === 0 && pElm.clientWidth * pElm.clientHeight > 0) { laterArr.push(pElm); anyEmptyHover = true; } pElm = pElm.previousElementSibling; } if (anyEmptyHover && !wmTextWrap.has(qElm.parentNode)) { wmTextWrap.set(qElm.parentNode, null) promises.push(Promise.resolve(qElm.parentNode).then(promiseCallback)) } qElm = qElm.parentNode; if (!qElm || qElm === rootNode) break; qi++ if (tmp_wmEty.get(qElm) > 0) break; tmp_wmEty.set(qElm, qi) } } tmp_wmEty = null; Promise.all(promises).then(() => { promises.length = 0; promises = null; promiseCallback = null; for (const pElm of laterArr) { let parentNode = pElm.parentNode if (wmTextWrap.get(parentNode) === true) { $.lpHoverBlocks.push(pElm); pElm.setAttribute($.utNonEmptyElmPrevElm, ''); } } laterArr.length = 0; laterArr = null; wmTextWrap = null; }) }) } } }else if($.lpKeyPressing==true){ $.lpCancelKeyPressAlt(); } }, lpCancelKeyPressAlt:()=>{ $.lpKeyPressing = false; if($.cid_lpKeyPressing>0) $.cid_lpKeyPressing=clearInterval($.cid_lpKeyPressing) $.lpKeyPressingPromise = $.lpKeyPressingPromise.then(() => { for (const elm of $.lpHoverBlocks) { elm.removeAttribute($.utNonEmptyElmPrevElm) elm.removeAttribute($.utHoverTextWrap) } $.lpHoverBlocks.length=0; }) setTimeout(function(){ if($.lpMouseActive == 1){ $.lpMouseUpClear(); $.lpMouseActive=0; } },32); }, lpKeyUp: function(evt) { if(!$.gm_lp_enable)return; if ($.lpKeyPressing == true) { $.lpCancelKeyPressAlt(); } }, lpAltRoots:[], lpMouseDown: function(evt) { if(!$.gm_lp_enable)return; $.lpMouseActive = 0; if (evt.altKey && !evt.ctrlKey && !evt.metaKey && !evt.shiftKey && evt.button === 0 && $.noPlayingVideo()) { $.lpMouseActive = 1; $.eventCancel(evt, false); const rootNode = $.rootHTML(evt.target); $.lpAltRoots.push(rootNode); rootNode.setAttribute($.utLpSelection, ''); } }, lpMouseUpClear:function(){ for(const rootNode of $.lpAltRoots) rootNode.removeAttribute($.utLpSelection); $.lpAltRoots.length=0; if ($.onceCssHighlightSelection) window.requestAnimationFrame($.onceCssHighlightSelection); }, lpMouseUp: function(evt) { if(!$.gm_lp_enable)return; if ($.lpMouseActive == 1) { $.lpMouseActive = 2; $.eventCancel(evt, false); $.lpMouseUpClear(); } }, lpClick: function(evt) { if(!$.gm_lp_enable)return; if ($.lpMouseActive == 2) { $.eventCancel(evt, false); } }, lpEnable: function() { // this is an optional feature for modern browser // the built-in browser feature has already disabled the default event behavior, the coding is just to ensure no "tailor-made behavior" occuring. document.addEventListener('keydown', $.lpKeyDown, { capture: true, passive: true }) document.addEventListener('keyup', $.lpKeyUp, { capture: true, passive: true }) document.addEventListener('mousedown', $.lpMouseDown, { capture: true, passive: true }) document.addEventListener('mouseup', $.lpMouseUp, { capture: true, passive: true }) document.addEventListener('click', $.lpClick, { capture: true, passive: true }) }, rootHTML: (node) => { if (!node || !(node.nodeType > 0)) return null; if (!node.ownerDocument) return node; let rootNode = node.getRootNode ? node.getRootNode() : null if (!rootNode) { let pElm = node; while (pElm) { if (pElm.parentNode) pElm = pElm.parentNode; else break; } rootNode = pElm; } rootNode = rootNode.querySelector('html') || node.ownerDocument.documentElement || null; return rootNode }, mainEnableScript: () => { var cssStyleOnReady = ` html, html *, html *::before, html *::after, html *:hover, html *:link, html *:visited, html *:active, html *[style], html *[class]{ -khtml-user-select: auto !important; -moz-user-select: auto !important; -ms-user-select: auto !important; -webkit-touch-callout: default !important; -webkit-user-select: auto !important; user-select: auto !important; } *:hover>img[src]{pointer-events:auto !important;} [${$.utSelectionColorHack}] :not(input):not(textarea)::selection{ background-color: Highlight !important; color: HighlightText !important;} [${$.utSelectionColorHack}] :not(input):not(textarea)::-moz-selection{ background-color: Highlight !important; color: HighlightText !important;} [${$.utTapHighlight}] *{ -webkit-tap-highlight-color: rgba(0, 0, 0, 0.18) !important;} [${$.utHoverTextWrap}]>[${$.utNonEmptyElmPrevElm}]{pointer-events:none !important;} [${$.utHoverTextWrap}]>*{z-index:inherit !important;} html[${$.utLpSelection}] *:hover, html[${$.utLpSelection}] *:hover * { cursor:text !important;} html[${$.utLpSelection}] :not(input):not(textarea)::selection {background-color: rgba(255, 156, 179,0.5) !important;} html[${$.utLpSelection}] :not(input):not(textarea)::-moz-selection {background-color: rgba(255, 156, 179,0.5) !important;} img[${$.utHoverBlock}="4"]{display:none !important;} [${$.utHoverBlock}="7"]{padding:0 !important;overflow:hidden !important;} [${$.utHoverBlock}="7"]>img[${$.utHoverBlock}="4"]:first-child{ display:inline-block !important; position: relative !important; top: auto !important; left: auto !important; bottom: auto !important; right: auto !important; opacity: 0 !important; padding: 0 !important; margin: 0 !important; width: 100% !important; height: 100% !important; outline: 0 !important; border: 0 !important; box-sizing: border-box !important; transform: initial !important; user-select:none !important; z-index:1 !important; float: left !important; cursor:inherit !important; pointer-events:inherit !important; border-radius: inherit !important; background:none !important; } `.trim(); $.enableSelectClickCopy() $.createCSSElement(cssStyleOnReady, document.documentElement); }, mainEvents: (listenerPress, listenerRelease) => { document.addEventListener("mousedown", listenerPress, true); // Capture Event; (desktop) document.addEventListener("contextmenu", listenerPress, true); // Capture Event; (desktop&mobile) document.addEventListener("mouseup", listenerRelease, false); // Bubble Event; }, disableHoverBlock: () => { var nMap = new WeakMap() function elmParam(elm) { var mElm = nMap.get(elm); if (!mElm) nMap.set(elm, mElm = {}); return mElm; } function overlapArea(rect1, rect2) { let l1 = { x: rect1.left, y: rect1.top } let r1 = { x: rect1.right, y: rect1.bottom } let l2 = { x: rect2.left, y: rect2.top } let r2 = { x: rect2.right, y: rect2.bottom } // Area of 1st Rectangle let area1 = Math.abs(l1.x - r1.x) * Math.abs(l1.y - r1.y); // Area of 2nd Rectangle let area2 = Math.abs(l2.x - r2.x) * Math.abs(l2.y - r2.y); // Length of intersecting part i.e // start from max(l1.x, l2.x) of // x-coordinate and end at min(r1.x, // r2.x) x-coordinate by subtracting // start from end we get required // lengths let x_dist = Math.min(r1.x, r2.x) - Math.max(l1.x, l2.x); let y_dist = Math.min(r1.y, r2.y) - Math.max(l1.y, l2.y); let areaI = 0; if (x_dist > 0 && y_dist > 0) { areaI = x_dist * y_dist; } return { area1, area2, areaI }; } function redirectEvent(event, toElement) { toElement.dispatchEvent(new event.constructor(event.type, event)); if (event.type != 'wheel') event.preventDefault(); event.stopPropagation(); } const floatingBlockHover = new WeakMap(); let _nImgs = []; function nImgFunc() { for (const s of _nImgs) { if (s.lastTime + 800 < +new Date) { s.lastTime = +new Date; return s.elm } } let nImg = document.createElement('img'); nImg.setAttribute('title', ' '); nImg.setAttribute('alt', ' '); nImg.onerror = function() { if (this.parentNode != null) this.parentNode.removeChild(this) } nImg.setAttribute($.utHoverBlock, '4'); const handle = function(event) { if (this === event.target) { if (event.button != 2) redirectEvent(event, this.parentNode) Promise.resolve().then(() => { for (const s of _nImgs) { if (s.elm === this) { s.lastTime = +new Date } } }) } } nImg.addEventListener('click', handle, true); nImg.addEventListener('mousedown', handle, true); nImg.addEventListener('mouseup', handle, true); nImg.addEventListener('mousemove', handle, true); nImg.addEventListener('mouseover', handle, true); nImg.addEventListener('mouseout', handle, true); nImg.addEventListener('mouseenter', handle, true); nImg.addEventListener('mouseleave', handle, true); //nImg.addEventListener('wheel', handle, $.eh_capture_passive()); let resObj = { elm: nImg, lastTime: +new Date, cid_fade: 0 } _nImgs.push(resObj) return nImg; } const wmHoverUrl = new WeakMap(); let lastMouseEnterElm = null; let lastMouseEnterAt = 0; let lastMouseEnterCid = 0; function mouseEnter() { lastMouseEnterCid = 0; if (+new Date - lastMouseEnterAt < 30) { lastMouseEnterCid = setTimeout(mouseEnter, 82) return; } //if($.lpKeyPressing)return; const targetElm = lastMouseEnterElm Promise.resolve() .then(() => { if (targetElm && targetElm.parentNode) {} else { return; } if (floatingBlockHover.get(targetElm)) { let url = null if (targetElm.getAttribute($.utHoverBlock) == '7' && (url = wmHoverUrl.get(targetElm)) && targetElm.querySelector(`[${$.utHoverBlock}]`) == null) { let _nImg = nImgFunc(); if (_nImg.parentNode !== targetElm) { _nImg.setAttribute('src', url); targetElm.insertBefore(_nImg, targetElm.firstChild); } } return; } floatingBlockHover.set(targetElm, 1); return 1; }).then((ayRes) => { if (!ayRes) return; if (targetElm.nodeType != 1) return; if ("|SVG|IMG|HTML|BODY|VIDEO|AUDIO|BR|HEAD|NOSCRIPT|SCRIPT|STYLE|TEXTAREA|AREA|INPUT|FORM|BUTTON|".indexOf(`|${targetElm.nodeName}|`) >= 0) return; const targetArea = targetElm.clientWidth * targetElm.clientHeight if (targetArea > 0) {} else { return; } const targetCSS = getComputedStyle(targetElm) const targetBgImage = targetCSS.getPropertyValue('background-image'); let exec1 = null if (targetBgImage != 'none' && (exec1 = /^\s*url\s*\("?([^"\)]+\b(\.gif|\.png|\.jpeg|\.jpg|\.webp)\b[^"\)]*)"?\)\s*$/i.exec(targetBgImage))) { if ((targetElm.textContent || "").trim().length > 0) return; const url = exec1[1]; return url // console.log(targetBgImage,[...exec1]) } if (targetCSS.getPropertyValue('position') == 'absolute' && +targetCSS.getPropertyValue('z-index') > 0) {} else { return; } if ((targetElm.textContent || "").trim().length > 0) return; let possibleResults = []; for (const imgElm of document.querySelectorAll('img[src]')) { const param = elmParam(imgElm) if (!param.area) { const area = imgElm.clientWidth * imgElm.clientHeight if (area > 0) param.area = area; } if (param.area > 0) { if (targetArea > param.area * 0.9) possibleResults.push(imgElm) } } let i = 0; let j = 0; for (const imgElm of possibleResults) { const cmpVal = targetElm.compareDocumentPosition(imgElm) /* 1: The two nodes do not belong to the same document. 2: p1 is positioned after p2. 4: p1 is positioned before p2. 8: p1 is positioned inside p2. 16: p2 is positioned inside p1. 32: The two nodes has no relationship, or they are two attributes on the same element. */ if (cmpVal & 8 || cmpVal & 16) return; if (cmpVal & 2) j++; // I

p i++; } // before: j-1 after: j let indexBefore = j - 1; let indexAfter = j; if (indexBefore < 0) indexBefore = 0; if (indexAfter > possibleResults.length - 1) indexAfter = possibleResults.length - 1; // setTimeout(function(){ for (let i = indexBefore; i <= indexAfter; i++) { const s = possibleResults[i]; const { area1, area2, areaI } = overlapArea(targetElm.getBoundingClientRect(), s.getBoundingClientRect()) const criteria = area1 * 0.7 if (areaI > 0.9 * area2) { return s.getAttribute('src') } } // },1000); }).then((sUrl) => { if (typeof sUrl != 'string') return; //console.log(targetElm, targetElm.querySelectorAll('img').length) // console.log(313, evt.target, s) let _nImg = nImgFunc(); if (_nImg.parentNode !== targetElm) { _nImg.setAttribute('src', sUrl); targetElm.insertBefore(_nImg, targetElm.firstChild); wmHoverUrl.set(targetElm, sUrl); targetElm.setAttribute($.utHoverBlock, '7'); } }) } document.addEventListener('mouseenter', function(evt) { if(!$.gm_disablehover_enable) return; lastMouseEnterElm = evt.target lastMouseEnterAt = +new Date; if (!lastMouseEnterCid) lastMouseEnterCid = setTimeout(mouseEnter, 82) }, $.eh_capture_passive()) }, acrAuxDown: function(evt) { if(!$.gm_prevent_aux_click_enable) return; if (evt.button === 1 ){ let check = $.dmmMouseUpLast > $.dmmMouseDownLast && evt.timeStamp - $.dmmMouseUpLast < 40 $.dmmMouseDownLast = evt.timeStamp; if( check ) { $.eventCancel(evt, true); } } }, acrAuxUp: function(evt) { if(!$.gm_prevent_aux_click_enable) return; if (evt.button === 1 ){ let check = $.dmmMouseDownLast > $.dmmMouseUpLast && evt.timeStamp - $.dmmMouseDownLast < 40; $.dmmMouseUpLast = evt.timeStamp; if( check ) { $.dmmMouseUpCancel = evt.timeStamp; $.eventCancel(evt, true); } } }, acrAuxClick: function(evt) { if(!$.gm_prevent_aux_click_enable) return; if (evt.button === 1 ){ if( evt.timeStamp - $.dmmMouseUpCancel < 40 ) { $.eventCancel(evt, true); } } }, preventAuxClickRepeat:function(){ document.addEventListener('mousedown', $.acrAuxDown, { capture: true, passive: false }) document.addEventListener('mouseup', $.acrAuxUp, { capture: true, passive: false }) document.addEventListener('auxclick', $.acrAuxClick, { capture: true, passive: false }) }, MenuEnable: ( class MenuEnable{ constructor(textToEnable, textToDisable, callback, initalEnable){ this.textToEnable=textToEnable; this.textToDisable=textToDisable; this.callback=callback; this.gx=this.gx.bind(this); } unregister(){ (this.h>=0)?(GM_unregisterMenuCommand(this.h), (this.h=0)):0; } register(text){ if(typeof text == 'string') this.showText = text; text = this.showText; if(typeof text != 'string') return; this.h=GM_registerMenuCommand(text, this.gx); } a(o){ if(this.enabled===o.bEnable) return; this.enabled = o.bEnable; this.unregister(); let pr= 0 ; if($.gm_status_fn_store && $.gm_status_fn_store.indexOf(this)>=0){ let store = $.gm_status_fn_store let idx = store.indexOf(this) let count = store.length; if(idx>=0&&idx<=count-2){ console.log(idx, count) for(let jdx=idx+1;jdx { GM_setValue(gm_name, !!enabled); }); $.gm_status_fn_store.push($[menuEnableName]); $[menuEnableName].toggle(!!GM_getValue(gm_name)); } } } // $.holdingElm=null; $.mainEnableScript(); if (isSupportAdvancedEventListener()) $.lpEnable(); // top capture event for alt-click $.mainEvents( function(evt) { // $.holdingElm=evt.target; // console.log('down',evt.target) if ($.onceCssHighlightSelection) window.requestAnimationFrame($.onceCssHighlightSelection); if (evt.button == 2 || evt.type == "contextmenu") $.mAlert_DOWN(); }, function(evt) { // $.holdingElm=null; // console.log('up',evt.target) if (evt.button == 2) $.mAlert_UP(); if ($.enableDragging) { $.enableDragging = false; } } ); $.disableHoverBlock(); $.preventAuxClickRepeat(); console.log('userscript running - To Re-Enable Selection & Copying'); $.gm_status_fn("gm_lp_enable", "To Enable `Enhanced build-in Alt Text Selection`", "To Disable `Enhanced build-in Alt Text Selection`", ()=>{ // callback }); $.gm_status_fn("gm_disablehover_enable", "To Enable `Hover on Image`", "To Disable `Hover on Image`", ()=>{ // callback }); $.gm_status_fn("gm_prevent_aux_click_enable", "To Enable `Repetitive AuxClick Prevention`", "To Disable `Repetitive AuxClick Prevention`", ()=>{ // callback }); })();