mirror of
https://gitlab.com/MrFry/moodle-test-userscript
synced 2025-04-01 20:22:48 +02:00
Merge branch 'patch-1' into 'master'
Added the stealthy overlay, no version number change yet See merge request MrFry/moodle-test-userscript!2
This commit is contained in:
commit
6da775af3e
1 changed files with 101 additions and 13 deletions
112
stable.user.js
112
stable.user.js
|
@ -31,6 +31,7 @@
|
|||
// @match https://qmining.frylabs.net/*
|
||||
// @match http://qmining.frylabs.net/*
|
||||
// @noframes
|
||||
// @run-at document-start
|
||||
// @grant GM_getResourceText
|
||||
// @grant GM_info
|
||||
// @grant GM_getValue
|
||||
|
@ -38,6 +39,7 @@
|
|||
// @grant GM_deleteValue
|
||||
// @grant GM_xmlhttpRequest
|
||||
// @grant GM_openInTab
|
||||
// @grant unsafeWindow
|
||||
// @license GNU General Public License v3.0 or later
|
||||
// @supportURL qmining.frylabs.net
|
||||
// @contributionURL qmining.frylabs.net
|
||||
|
@ -208,6 +210,86 @@
|
|||
// all dom getting stuff are in this sections, so on
|
||||
// moodle dom change, stuff breaks here
|
||||
|
||||
//Stealth by An0 with love
|
||||
function StealthOverlay() { //call this before the document scripts
|
||||
const document = window.document;
|
||||
|
||||
const neverEqualPlaceholder = Symbol(`never equal`); //block probing for undefined values in the hooks
|
||||
let shadowRootHost = neverEqualPlaceholder;
|
||||
let shadowRootNewHost = neverEqualPlaceholder;
|
||||
|
||||
const apply = Reflect.apply; //save some things in case they get hooked (only for unsafe contexts)
|
||||
|
||||
|
||||
if(unsafeWindow.Error.hasOwnProperty('stackTraceLimit')) {
|
||||
Reflect.defineProperty(unsafeWindow.Error, 'stackTraceLimit', { value: undefined, writable: false, enumerable: false, configurable: false });
|
||||
}
|
||||
|
||||
const shadowGetHandler = { apply: (target, thisArg, argumentsList) => apply(target, (thisArg === shadowRootHost) ? shadowRootNewHost : thisArg, argumentsList) };
|
||||
|
||||
const original_attachShadow = unsafeWindow.Element.prototype.attachShadow;
|
||||
const attachShadowProxy = new Proxy(original_attachShadow, shadowGetHandler);
|
||||
unsafeWindow.Element.prototype.attachShadow = attachShadowProxy;
|
||||
|
||||
const getShadowRootProxy = new Proxy(Object.getOwnPropertyDescriptor(unsafeWindow.Element.prototype, 'shadowRoot').get, shadowGetHandler);
|
||||
Object.defineProperty(unsafeWindow.Element.prototype, 'shadowRoot', { get: getShadowRootProxy });
|
||||
|
||||
const getHostHandler = { apply: function() { let result = apply(...arguments); return (result === shadowRootNewHost) ? shadowRootHost : result; } };
|
||||
const getHostProxy = new Proxy(Object.getOwnPropertyDescriptor(unsafeWindow.ShadowRoot.prototype, 'host').get, getHostHandler);
|
||||
Object.defineProperty(unsafeWindow.ShadowRoot.prototype, 'host', { get: getHostProxy });
|
||||
|
||||
|
||||
const shadowRootSetInnerHtml = Object.getOwnPropertyDescriptor(ShadowRoot.prototype, 'innerHTML').set;
|
||||
const documentFragmentGetChildren = Object.getOwnPropertyDescriptor(DocumentFragment.prototype, 'children').get;
|
||||
const documentGetBody = Object.getOwnPropertyDescriptor(Document.prototype, 'body').get;
|
||||
const nodeAppendChild = Node.prototype.appendChild;
|
||||
|
||||
const overlay = document.createElement('div');
|
||||
overlay.style.cssText = "position:absolute;left:0;top:0";
|
||||
|
||||
const addOverlay = () => {
|
||||
shadowRootHost = apply(documentGetBody, document, []);
|
||||
const shadowRoot = apply(original_attachShadow, shadowRootHost, [{mode:'closed'}]);
|
||||
apply(shadowRootSetInnerHtml, shadowRoot, [`<div><slot></slot></div>`]);
|
||||
shadowRootNewHost = apply(documentFragmentGetChildren, shadowRoot, [])[0];
|
||||
apply(nodeAppendChild, shadowRoot, [overlay]);
|
||||
};
|
||||
|
||||
if (!document.body) {
|
||||
document.addEventListener('DOMContentLoaded', addOverlay);
|
||||
}
|
||||
else {
|
||||
addOverlay();
|
||||
}
|
||||
return overlay;
|
||||
}
|
||||
|
||||
const overlay = StealthOverlay();
|
||||
|
||||
|
||||
function createHoverOver(target) {
|
||||
const overlayElement = document.createElement('div');
|
||||
overlayElement.style.cssText = "position:fixed; pointer-events: none; user-select: none; z-index:10000";
|
||||
overlay.append(overlayElement);
|
||||
let currX, currY, currWidth, currHeight;
|
||||
const copyBoundingRect = () => {
|
||||
let { x, y, width, height } = target.getBoundingClientRect();
|
||||
if(x !== currX) { overlayElement.style.left = x + 'px'; currX = x; }
|
||||
if(y !== currY) { overlayElement.style.top = y + 'px'; currY = y; }
|
||||
if(width !== currWidth) { overlayElement.style.width = width + 'px'; currWidth = width; }
|
||||
if(height !== currHeight) { overlayElement.style.height = height + 'px'; currHeight = height; }
|
||||
};
|
||||
copyBoundingRect();
|
||||
const interval = setInterval(copyBoundingRect, 30);
|
||||
overlayElement.destroy = () => {
|
||||
clearInterval(interval);
|
||||
overlayElement.remove();
|
||||
};
|
||||
return overlayElement;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class QuestionsPageModell {
|
||||
GetAllQuestionsDropdown () {
|
||||
if (logElementGetting) { Log('getting dropdown question') }
|
||||
|
@ -681,8 +763,13 @@
|
|||
console.time('main')
|
||||
timerStarted = true
|
||||
|
||||
if(document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', Init)
|
||||
}
|
||||
else {
|
||||
Init()
|
||||
}
|
||||
}
|
||||
|
||||
function AfterLoad () {
|
||||
const url = location.href // eslint-disable-line
|
||||
|
@ -716,8 +803,8 @@
|
|||
}
|
||||
|
||||
if (forceTestPage || forceResultPage || forceDefaultPage) {
|
||||
if (document.getElementById('scriptMessage')) {
|
||||
document.getElementById('scriptMessage').style.background = 'green'
|
||||
if (overlay.querySelector('#scriptMessage')) {
|
||||
overlay.querySelector('#scriptMessage').style.background = 'green'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -852,7 +939,7 @@
|
|||
lastestVersion = inf.version
|
||||
motd = inf.motd
|
||||
subjInfo = inf.subjinfo
|
||||
document.getElementById('infoMainDiv').innerText = `${subjInfo.subjects} tárgy, ${subjInfo.questions} kérdés. Felh #${inf.uid}`
|
||||
overlay.querySelector('#infoMainDiv').innerText = `${subjInfo.subjects} tárgy, ${subjInfo.questions} kérdés. Felh #${inf.uid}`
|
||||
// FIXME: if cwith() throws an unhandled error it sais server is not avaible
|
||||
cwith()
|
||||
}).catch(() => {
|
||||
|
@ -1299,7 +1386,12 @@
|
|||
if (results[0].match === 100) { // if the result is 100% correct
|
||||
if (type !== 'radio' || toColor.length === 1) { // FIXME why not radio
|
||||
for (let i = 0; i < toColor.length; i++) { // going through "toColor"
|
||||
answers[toColor[i]].style.backgroundColor = '#8cff66'
|
||||
let highlight = createHoverOver(answers[toColor[i]]);
|
||||
Object.assign(highlight.style, {
|
||||
border: "7px solid rgba(100, 240, 100, 0.8)",
|
||||
borderRadius: "10px",
|
||||
margin: "-13px 0 0 -8px"
|
||||
});
|
||||
}
|
||||
}
|
||||
} // and coloring the correct index
|
||||
|
@ -1328,11 +1420,7 @@
|
|||
|
||||
// : Minor UI stuff {{{
|
||||
function ClearAllMessages () {
|
||||
let elem = document.getElementById('scriptMessage')
|
||||
while (elem) {
|
||||
elem.parentNode.removeChild(elem)
|
||||
elem = document.getElementById('scriptMessage')
|
||||
}
|
||||
overlay.querySelectorAll('#scriptMessage').forEach(x => x.remove())
|
||||
}
|
||||
|
||||
// shows a message with "msg" text, "matchPercent" tip and transp, and "timeout" time
|
||||
|
@ -1360,7 +1448,7 @@
|
|||
isSimpleMessage = true
|
||||
}
|
||||
|
||||
var appedtTo = document.body // will be appended here
|
||||
var appedtTo = overlay // will be appended here
|
||||
var width = window.innerWidth - window.innerWidth / 6 // with of the box
|
||||
var startFromTop = 25 // top distance
|
||||
|
||||
|
@ -1551,7 +1639,7 @@
|
|||
// shows a fancy menu
|
||||
function ShowMenu () {
|
||||
try {
|
||||
var appedtTo = document.body // will be appended here
|
||||
var appedtTo = overlay // will be appended here
|
||||
|
||||
// mainDiv.style.left = (window.innerWidth - width) / 2 + 'px';
|
||||
|
||||
|
@ -1763,7 +1851,7 @@
|
|||
}
|
||||
|
||||
function SafeGetElementById (id, next) {
|
||||
let element = document.getElementById(id)
|
||||
let element = overlay.querySelector('#' + id)
|
||||
if (element) {
|
||||
next(element)
|
||||
} else {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue