mirror of
https://gitlab.com/MrFry/moodle-test-userscript
synced 2025-04-01 20:22:48 +02:00
Error handling, showing more messages to user, localisation improvements
This commit is contained in:
parent
771b37d59f
commit
84cd7ffc58
1 changed files with 295 additions and 191 deletions
364
stable.user.js
364
stable.user.js
|
@ -81,12 +81,12 @@
|
||||||
// : Constants and global variables {{{
|
// : Constants and global variables {{{
|
||||||
|
|
||||||
const logElementGetting = false
|
const logElementGetting = false
|
||||||
const log = true
|
const logEnabled = true
|
||||||
const showErrors = true
|
const showErrors = true
|
||||||
// forcing pages for testing. unless you test, do not set these to true!
|
// forcing pages for testing. unless you test, do not set these to true!
|
||||||
setVal('ISDEVEL', true)
|
setVal('ISDEVEL', true)
|
||||||
// only one of these should be true for testing
|
// only one of these should be true for testing
|
||||||
const forceTestPage = false
|
const forceTestPage = true
|
||||||
const forceResultPage = false
|
const forceResultPage = false
|
||||||
const forceDefaultPage = false
|
const forceDefaultPage = false
|
||||||
|
|
||||||
|
@ -149,12 +149,24 @@
|
||||||
search: 'Keresés ...',
|
search: 'Keresés ...',
|
||||||
loading: 'Betöltés ...',
|
loading: 'Betöltés ...',
|
||||||
login: 'Belépés',
|
login: 'Belépés',
|
||||||
requestPWInsteadOfLogin: 'Jelszó igénylés',
|
requestPWInsteadOflogin: 'Jelszó igénylés',
|
||||||
newPWTitle: 'Új jelszó új felhasználónak',
|
newPWTitle: 'Új jelszó új felhasználónak',
|
||||||
pwRequest: 'Jelszó új felhasználónak',
|
pwRequest: 'Jelszó új felhasználónak',
|
||||||
noServer: 'Nem elérhető a szerver!',
|
noServer: 'Nem elérhető a szerver!',
|
||||||
noUser: 'Nem vagy bejelentkezve!',
|
noUser: 'Nem vagy bejelentkezve!',
|
||||||
noServerConsoleMessage: `Nem elérhető a szerver, vagy kis eséllyel kezeletlen hiba történt! Ha elérhető a weboldal, akkor ott meg bírod nézni a kérdéseket itt: ${serverAdress}legacy`,
|
noServerConsoleMessage: `Nem elérhető a szerver, vagy kis eséllyel kezeletlen hiba történt! Ha elérhető a weboldal, akkor ott meg bírod nézni a kérdéseket itt: ${serverAdress}legacy`,
|
||||||
|
noParseableQuestionResult:
|
||||||
|
'A tesztben nem találhatók kérdések, amit fel lehet dolgozni, vagy hiba történt feldolgozásuk közben',
|
||||||
|
unableToParseTestQuestion:
|
||||||
|
'Hiba történt a kérdések beolvasása közben :/ Kattints az üzenetre a manuális kereséshez (új böngésző tab-ban)',
|
||||||
|
loadingAnswer: 'Válaszok betöltése ...',
|
||||||
|
reinstallFromCorrectSource:
|
||||||
|
'Scriptet nem a weboldalról raktad fel. PLS reinstall <a href="https://qmining.frylabs.net/manual.html#reinstallfromqmining">aaaaaaaaa</a>', // TODO: new text
|
||||||
|
versionUpdated: 'Verzió frissítve ',
|
||||||
|
newVersionAvaible: 'Új verzió elérhető: ',
|
||||||
|
scriptName: 'Moodle/Elearning/KMOOC segéd ',
|
||||||
|
userMOTD: 'Felhasználó MOTD (ezt csak te látod):\n',
|
||||||
|
motd: 'MOTD:\n',
|
||||||
}
|
}
|
||||||
|
|
||||||
var texts = huTexts
|
var texts = huTexts
|
||||||
|
@ -189,17 +201,17 @@
|
||||||
return promises
|
return promises
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeTextFromElements(item) {
|
function makeTextFromElements(acc, item) {
|
||||||
// TODO!
|
if (emptyOrWhiteSpace(item.val)) {
|
||||||
// if (emptyOrWhiteSpace(item)) {
|
return acc
|
||||||
// return ''
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
if (item.type === 'img') {
|
if (item.type === 'img') {
|
||||||
return '[' + item.val + ']'
|
acc.push('[' + item.val + ']')
|
||||||
} else {
|
} else {
|
||||||
return item.val
|
acc.push(item.val)
|
||||||
}
|
}
|
||||||
|
return acc
|
||||||
}
|
}
|
||||||
|
|
||||||
function getImagesFromElements(elements) {
|
function getImagesFromElements(elements) {
|
||||||
|
@ -213,7 +225,7 @@
|
||||||
|
|
||||||
function getCurrentSubjectName() {
|
function getCurrentSubjectName() {
|
||||||
if (logElementGetting) {
|
if (logElementGetting) {
|
||||||
Log('getting current subjects name')
|
log('getting current subjects name')
|
||||||
}
|
}
|
||||||
return document.getElementById('page-header').innerText.split('\n')[0] || ''
|
return document.getElementById('page-header').innerText.split('\n')[0] || ''
|
||||||
}
|
}
|
||||||
|
@ -227,9 +239,30 @@
|
||||||
// : Test page processing functions {{{
|
// : Test page processing functions {{{
|
||||||
|
|
||||||
function handleQuiz() {
|
function handleQuiz() {
|
||||||
getQuizData().then(res => {
|
const { removeMessage: removeLoadingMessage } = ShowMessage({
|
||||||
const promises = []
|
m: texts.loadingAnswer,
|
||||||
|
isSimple: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
getQuizData()
|
||||||
|
.then(res => {
|
||||||
|
if (res.length === 0) {
|
||||||
|
ShowMessage(
|
||||||
|
{
|
||||||
|
m: texts.unableToParseTestQuestion,
|
||||||
|
isSimple: true,
|
||||||
|
},
|
||||||
|
undefined,
|
||||||
|
() => {
|
||||||
|
OpenErrorPage({
|
||||||
|
message: 'No result found',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const promises = []
|
||||||
res.forEach(question => {
|
res.forEach(question => {
|
||||||
promises.push(
|
promises.push(
|
||||||
GetXHRQuestionAnswer({
|
GetXHRQuestionAnswer({
|
||||||
|
@ -245,10 +278,14 @@
|
||||||
return PrepareAnswers(result)
|
return PrepareAnswers(result)
|
||||||
})
|
})
|
||||||
|
|
||||||
// TODO: new lines in answers
|
removeLoadingMessage()
|
||||||
ShowAnswers(answers, res[0].question)
|
ShowAnswers(answers, res[0].question)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
.catch(err => {
|
||||||
|
warn(err)
|
||||||
|
warn('Error in handleQuiz()')
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function getQuizData() {
|
function getQuizData() {
|
||||||
|
@ -271,8 +308,14 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
Promise.all(promises)
|
Promise.all(promises)
|
||||||
.then(res => {
|
.then(result => {
|
||||||
resolve(res)
|
const errorsRemoved = result.reduce((acc, res) => {
|
||||||
|
if (res.success) {
|
||||||
|
acc.push(res)
|
||||||
|
}
|
||||||
|
return acc
|
||||||
|
}, [])
|
||||||
|
resolve(errorsRemoved)
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
console.warn('Error in handleQuiz()')
|
console.warn('Error in handleQuiz()')
|
||||||
|
@ -314,6 +357,7 @@
|
||||||
|
|
||||||
function getQuestionPromiseForSingleQuestion(node) {
|
function getQuestionPromiseForSingleQuestion(node) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
|
try {
|
||||||
const qtextNode = node.getElementsByClassName('qtext')[0]
|
const qtextNode = node.getElementsByClassName('qtext')[0]
|
||||||
|
|
||||||
const questionPromises = getTextPromisesFromNode(qtextNode)
|
const questionPromises = getTextPromisesFromNode(qtextNode)
|
||||||
|
@ -330,9 +374,13 @@
|
||||||
Promise.all(unflattenedPossibleAnswerPromises),
|
Promise.all(unflattenedPossibleAnswerPromises),
|
||||||
])
|
])
|
||||||
.then(([question, possibleAnswerArray]) => {
|
.then(([question, possibleAnswerArray]) => {
|
||||||
const questionText = question.map(makeTextFromElements).join(' ')
|
const questionText = removeUnnecesarySpaces(
|
||||||
|
question.reduce(makeTextFromElements, []).join(' ')
|
||||||
|
)
|
||||||
const possibleAnswers = possibleAnswerArray.map(x => {
|
const possibleAnswers = possibleAnswerArray.map(x => {
|
||||||
return removeUnnecesarySpaces(x.map(makeTextFromElements).join(' '))
|
return removeUnnecesarySpaces(
|
||||||
|
x.reduce(makeTextFromElements, []).join(' ')
|
||||||
|
)
|
||||||
})
|
})
|
||||||
let images = getImagesFromElements([
|
let images = getImagesFromElements([
|
||||||
...question,
|
...question,
|
||||||
|
@ -348,12 +396,19 @@
|
||||||
possibleAnswers,
|
possibleAnswers,
|
||||||
images,
|
images,
|
||||||
data,
|
data,
|
||||||
|
success: true,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
console.warn('Error in getQuestionPromiseForSingleQuestion()')
|
warn('Error in getQuestionPromiseForSingleQuestion()')
|
||||||
console.warn(err)
|
warn(err)
|
||||||
|
resolve({ success: false })
|
||||||
})
|
})
|
||||||
|
} catch (err) {
|
||||||
|
warn('Error in getQuestionPromiseForSingleQuestion()')
|
||||||
|
warn(err)
|
||||||
|
resolve({ success: false })
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -389,11 +444,17 @@
|
||||||
|
|
||||||
Promise.all(promises)
|
Promise.all(promises)
|
||||||
.then(result => {
|
.then(result => {
|
||||||
resolve(result)
|
const errorsRemoved = result.reduce((acc, res) => {
|
||||||
|
if (res.success) {
|
||||||
|
acc.push(res)
|
||||||
|
}
|
||||||
|
return acc
|
||||||
|
}, [])
|
||||||
|
resolve(errorsRemoved)
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
console.warn('Error in getQuiz()')
|
warn('Error in getQuiz()')
|
||||||
console.warn(err)
|
warn(err)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -407,10 +468,10 @@
|
||||||
res = getter.getterFunction(node)
|
res = getter.getterFunction(node)
|
||||||
return true
|
return true
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Log(`${key} failed`)
|
log(`${key} failed`)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log(`${key} did not pass`)
|
log(`${key} did not pass`)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -429,14 +490,16 @@
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!answerPromises || !questionPromises) {
|
if (!answerPromises || !questionPromises) {
|
||||||
Log('Answer or question array is empty, skipping question')
|
log('Answer or question array is empty, skipping question')
|
||||||
resolve({ success: false })
|
resolve({ success: false })
|
||||||
}
|
}
|
||||||
|
|
||||||
Promise.all([Promise.all(questionPromises), Promise.all(answerPromises)])
|
Promise.all([Promise.all(questionPromises), Promise.all(answerPromises)])
|
||||||
.then(([question, answer]) => {
|
.then(([question, answer]) => {
|
||||||
const questionText = question.map(makeTextFromElements).join(' ')
|
const questionText = question
|
||||||
const answerText = answer.map(makeTextFromElements).join(' ')
|
.reduce(makeTextFromElements, [])
|
||||||
|
.join(' ')
|
||||||
|
const answerText = answer.reduce(makeTextFromElements, []).join(' ')
|
||||||
let images = getImagesFromElements([...question, ...answer])
|
let images = getImagesFromElements([...question, ...answer])
|
||||||
// images = uniq(images)
|
// images = uniq(images)
|
||||||
|
|
||||||
|
@ -448,8 +511,9 @@
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
console.warn('Error in getQuizFromNode()')
|
warn('Error in getQuizFromNode()')
|
||||||
console.warn(err)
|
warn(err)
|
||||||
|
resolve({ success: false })
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -545,6 +609,16 @@
|
||||||
return 'asd'
|
return 'asd'
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
getDragBoxAnswer: {
|
||||||
|
description: 'Get complex answer',
|
||||||
|
requirement: node => {
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
getterFunction: node => {
|
||||||
|
// TODO dragboxes
|
||||||
|
return 'asd'
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
function getIfSolutionIsCorrect(node) {
|
function getIfSolutionIsCorrect(node) {
|
||||||
|
@ -606,14 +680,14 @@
|
||||||
|
|
||||||
function getVideo() {
|
function getVideo() {
|
||||||
if (logElementGetting) {
|
if (logElementGetting) {
|
||||||
Log('getting video stuff')
|
log('getting video stuff')
|
||||||
}
|
}
|
||||||
return document.getElementsByTagName('video')[0]
|
return document.getElementsByTagName('video')[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
function getVideoElement() {
|
function getVideoElement() {
|
||||||
if (logElementGetting) {
|
if (logElementGetting) {
|
||||||
Log('getting video element')
|
log('getting video element')
|
||||||
}
|
}
|
||||||
return document.getElementById('videoElement').parentNode
|
return document.getElementById('videoElement').parentNode
|
||||||
}
|
}
|
||||||
|
@ -767,18 +841,13 @@
|
||||||
|
|
||||||
// : Main function {{{
|
// : Main function {{{
|
||||||
|
|
||||||
let timerStarted = false
|
|
||||||
|
|
||||||
// window.addEventListener("load", () => {})
|
// window.addEventListener("load", () => {})
|
||||||
Main()
|
Main()
|
||||||
|
|
||||||
function Main() {
|
function Main() {
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
// https://qmining.frylabs.net/moodle-test-userscript/stable.user.js?up
|
log('Moodle / E-Learning script')
|
||||||
console.log('Moodle / E-Learning script')
|
|
||||||
console.time('main')
|
|
||||||
timerStarted = true
|
|
||||||
|
|
||||||
if (document.readyState === 'loading') {
|
if (document.readyState === 'loading') {
|
||||||
document.addEventListener('DOMContentLoaded', Init)
|
document.addEventListener('DOMContentLoaded', Init)
|
||||||
|
@ -829,19 +898,7 @@
|
||||||
if (url.includes('eduplayer')) {
|
if (url.includes('eduplayer')) {
|
||||||
AddVideoHotkeys(url)
|
AddVideoHotkeys(url)
|
||||||
} // adding video hotkeys
|
} // adding video hotkeys
|
||||||
Log(texts.consoleErrorInfo)
|
log(texts.consoleErrorInfo)
|
||||||
|
|
||||||
if (timerStarted) {
|
|
||||||
console.log('Moodle Test Script run time:')
|
|
||||||
console.timeEnd('main')
|
|
||||||
timerStarted = false
|
|
||||||
}
|
|
||||||
|
|
||||||
if (forceTestPage || forceResultPage || forceDefaultPage) {
|
|
||||||
if (overlay.querySelector('#scriptMessage')) {
|
|
||||||
overlay.querySelector('#scriptMessage').style.background = 'green'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// : }}}
|
// : }}}
|
||||||
|
|
||||||
|
@ -963,7 +1020,7 @@
|
||||||
NoUserAction()
|
NoUserAction()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
lastestVersion = inf.version
|
lastestVersion = inf.version.replace(/\n/g, '')
|
||||||
motd = inf.motd
|
motd = inf.motd
|
||||||
userSpecificMotd = inf.userSpecificMotd
|
userSpecificMotd = inf.userSpecificMotd
|
||||||
subjInfo = inf.subjinfo
|
subjInfo = inf.subjinfo
|
||||||
|
@ -1008,7 +1065,7 @@
|
||||||
SafeGetElementById('retryButton', elem => {
|
SafeGetElementById('retryButton', elem => {
|
||||||
elem.style.display = ''
|
elem.style.display = ''
|
||||||
})
|
})
|
||||||
Log(texts.noServerConsoleMessage)
|
log(texts.noServerConsoleMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
function VersionActions() {
|
function VersionActions() {
|
||||||
|
@ -1018,23 +1075,14 @@
|
||||||
// : }}}
|
// : }}}
|
||||||
|
|
||||||
// : UI handling {{{
|
// : UI handling {{{
|
||||||
function HandleUI(url) {
|
|
||||||
// FIXME: normal string building with localisation :/
|
|
||||||
var newVersion = false // if the script is newer than last start
|
|
||||||
|
|
||||||
try {
|
function shouldShowMotd() {
|
||||||
newVersion = info().script.version !== getVal('lastVerson')
|
|
||||||
} catch (e) {
|
|
||||||
Log('Some weird error trying to set new verison')
|
|
||||||
}
|
|
||||||
|
|
||||||
let showMOTD = false
|
|
||||||
if (!emptyOrWhiteSpace(motd)) {
|
if (!emptyOrWhiteSpace(motd)) {
|
||||||
var prevmotd = getVal('motd')
|
var prevmotd = getVal('motd')
|
||||||
if (prevmotd !== motd) {
|
if (prevmotd !== motd) {
|
||||||
showMOTD = true
|
|
||||||
setVal('motdcount', motdShowCount)
|
setVal('motdcount', motdShowCount)
|
||||||
setVal('motd', motd)
|
setVal('motd', motd)
|
||||||
|
return true
|
||||||
} else {
|
} else {
|
||||||
var motdcount = getVal('motdcount')
|
var motdcount = getVal('motdcount')
|
||||||
if (motdcount === undefined) {
|
if (motdcount === undefined) {
|
||||||
|
@ -1044,51 +1092,61 @@
|
||||||
|
|
||||||
motdcount--
|
motdcount--
|
||||||
if (motdcount > 0) {
|
if (motdcount > 0) {
|
||||||
showMOTD = true
|
|
||||||
setVal('motdcount', motdcount)
|
setVal('motdcount', motdcount)
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function HandleUI(url) {
|
||||||
|
var newVersion = false // if the script is newer than last start
|
||||||
|
|
||||||
|
try {
|
||||||
|
newVersion = info().script.version !== getVal('lastVerson')
|
||||||
|
} catch (e) {
|
||||||
|
log('Some weird error trying to set new verison')
|
||||||
|
}
|
||||||
|
|
||||||
|
const showMOTD = shouldShowMotd()
|
||||||
const showUserSpecificMOTD = !!userSpecificMotd
|
const showUserSpecificMOTD = !!userSpecificMotd
|
||||||
|
|
||||||
let isNewVersionAvaible =
|
let isNewVersionAvaible =
|
||||||
lastestVersion !== undefined && info().script.version !== lastestVersion
|
lastestVersion !== undefined && info().script.version !== lastestVersion
|
||||||
var greetMsg = '' // message to show at the end
|
let timeout = null
|
||||||
var timeout = null // the timeout. if null, it wont be hidden
|
const greetMsg = []
|
||||||
|
|
||||||
if (isNewVersionAvaible || newVersion || showMOTD || showUserSpecificMOTD) {
|
if (isNewVersionAvaible || newVersion || showMOTD || showUserSpecificMOTD) {
|
||||||
greetMsg =
|
greetMsg.push(texts.scriptName + info().script.version)
|
||||||
'Moodle/Elearning/KMOOC segéd v. ' + info().script.version + '. '
|
|
||||||
}
|
}
|
||||||
if (isNewVersionAvaible) {
|
if (isNewVersionAvaible) {
|
||||||
timeout = 5
|
timeout = 5
|
||||||
greetMsg += 'Új verzió elérhető: ' + lastestVersion
|
greetMsg.push(texts.newVersionAvaible + lastestVersion)
|
||||||
timeout = undefined
|
timeout = undefined
|
||||||
}
|
}
|
||||||
if (newVersion) {
|
if (newVersion) {
|
||||||
greetMsg += 'Verzió frissítve ' + info().script.version + '-re.'
|
greetMsg.push(texts.versionUpdated + info().script.version)
|
||||||
setVal('lastVerson', info().script.version) // setting lastVersion
|
setVal('lastVerson', info().script.version) // setting lastVersion
|
||||||
}
|
}
|
||||||
if (!installedFromCorrectSource(correctSource)) {
|
if (!installedFromCorrectSource(correctSource)) {
|
||||||
greetMsg +=
|
greetMsg.push(texts.reinstallFromCorrectSource)
|
||||||
'\nScriptet nem a weboldalról raktad fel. PLS reinstall (a href = ...)'
|
|
||||||
}
|
}
|
||||||
if (showMOTD) {
|
if (showMOTD) {
|
||||||
greetMsg += '\nMOTD:\n' + motd
|
greetMsg.push(texts.motd + motd)
|
||||||
timeout = null
|
timeout = null
|
||||||
}
|
}
|
||||||
if (showUserSpecificMOTD) {
|
if (showUserSpecificMOTD) {
|
||||||
greetMsg += '\nFelhasználó MOTD (ezt csak te látod):\n' + userSpecificMotd
|
greetMsg.push(texts.userMOTD + userSpecificMotd)
|
||||||
timeout = null
|
timeout = null
|
||||||
}
|
}
|
||||||
|
|
||||||
ShowMessage(
|
ShowMessage(
|
||||||
{
|
{
|
||||||
m: greetMsg,
|
m: greetMsg.join('\n'),
|
||||||
isSimple: true,
|
isSimple: true,
|
||||||
},
|
},
|
||||||
timeout
|
timeout
|
||||||
) // showing message. If "m" is empty it wont show it, thats how showSplash works.
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// : }}}
|
// : }}}
|
||||||
|
@ -1103,7 +1161,8 @@
|
||||||
let msg = res.q.Q + '\n'
|
let msg = res.q.Q + '\n'
|
||||||
|
|
||||||
// TODO: remove this maybe?
|
// TODO: remove this maybe?
|
||||||
msg += res.q.A.replace(/, /g, '\n') // adding answer
|
// msg += res.q.A.replace(/, /g, '\n')
|
||||||
|
msg += res.q.A
|
||||||
|
|
||||||
if (res.q.data.type === 'image') {
|
if (res.q.data.type === 'image') {
|
||||||
msg +=
|
msg +=
|
||||||
|
@ -1192,7 +1251,11 @@
|
||||||
try {
|
try {
|
||||||
let sentData = {}
|
let sentData = {}
|
||||||
if (quiz.length === 0) {
|
if (quiz.length === 0) {
|
||||||
throw new Error('quiz length is zero!')
|
ShowMessage({
|
||||||
|
m: texts.noParseableQuestionResult,
|
||||||
|
isSimple: true,
|
||||||
|
})
|
||||||
|
return
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
sentData = {
|
sentData = {
|
||||||
|
@ -1204,7 +1267,7 @@
|
||||||
sentData.subj = getCurrentSubjectName()
|
sentData.subj = getCurrentSubjectName()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
sentData.subj = 'NOSUBJ'
|
sentData.subj = 'NOSUBJ'
|
||||||
Log('unable to get subject name :c')
|
log('unable to get subject name :c')
|
||||||
}
|
}
|
||||||
console.log('SENT DATA', sentData)
|
console.log('SENT DATA', sentData)
|
||||||
SendXHRMessage('isAdding', sentData).then(res => {
|
SendXHRMessage('isAdding', sentData).then(res => {
|
||||||
|
@ -1225,8 +1288,9 @@
|
||||||
// : Install source checker {{{
|
// : Install source checker {{{
|
||||||
|
|
||||||
function installedFromCorrectSource(source) {
|
function installedFromCorrectSource(source) {
|
||||||
|
// https://qmining.frylabs.net/moodle-test-userscript/stable.user.js?up
|
||||||
// TODO: test this
|
// TODO: test this
|
||||||
return info().script.updateURL === correctSource
|
return info().script.updateURL === correctSource && false
|
||||||
}
|
}
|
||||||
|
|
||||||
// : }}}
|
// : }}}
|
||||||
|
@ -1274,8 +1338,8 @@
|
||||||
video.currentTime -= seekTime
|
video.currentTime -= seekTime
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Log('Hotkey error.')
|
log('Hotkey error.')
|
||||||
Log(err.message)
|
log(err.message)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
var toadd = getVideoElement()
|
var toadd = getVideoElement()
|
||||||
|
@ -1295,9 +1359,37 @@
|
||||||
overlay.querySelectorAll('#scriptMessage').forEach(x => x.remove())
|
overlay.querySelectorAll('#scriptMessage').forEach(x => x.remove())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getConvertedMessageNode(message) {
|
||||||
|
const messageNode = document.createElement('p')
|
||||||
|
const resultNode = document.createElement('p')
|
||||||
|
messageNode.innerHTML = message.replace(/\n/g, '</br>')
|
||||||
|
|
||||||
|
Array.from(messageNode.childNodes).forEach(node => {
|
||||||
|
if (node.tagName === 'A') {
|
||||||
|
let linkNode = document.createElement('span')
|
||||||
|
SetStyle(linkNode, {
|
||||||
|
color: 'lightblue',
|
||||||
|
textDecoration: 'underline',
|
||||||
|
cursor: 'pointer',
|
||||||
|
})
|
||||||
|
linkNode.innerText = node.innerText
|
||||||
|
linkNode.addEventListener('mousedown', e => {
|
||||||
|
e.stopPropagation()
|
||||||
|
openInTab(node.href, {
|
||||||
|
active: true,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
resultNode.appendChild(linkNode)
|
||||||
|
} else {
|
||||||
|
resultNode.appendChild(node)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return resultNode
|
||||||
|
}
|
||||||
|
|
||||||
// shows a message with "msg" text, "matchPercent" tip and transp, and "timeout" time
|
// shows a message with "msg" text, "matchPercent" tip and transp, and "timeout" time
|
||||||
function ShowMessage(msgItem, timeout, funct) {
|
function ShowMessage(msgItem, timeout, funct) {
|
||||||
// TODO: simple message not selectable
|
|
||||||
// msgItem help:
|
// msgItem help:
|
||||||
// [ [ {}{}{}{} ] [ {}{}{} ] ]
|
// [ [ {}{}{}{} ] [ {}{}{} ] ]
|
||||||
// msgItem[] <- a questions stuff
|
// msgItem[] <- a questions stuff
|
||||||
|
@ -1349,18 +1441,23 @@
|
||||||
top: startFromTop + 'px',
|
top: startFromTop + 'px',
|
||||||
left: (window.innerWidth - width) / 2 + 'px',
|
left: (window.innerWidth - width) / 2 + 'px',
|
||||||
opacity: '1',
|
opacity: '1',
|
||||||
cursor: 'move',
|
cursor: funct ? 'pointer' : 'move',
|
||||||
})
|
})
|
||||||
mainDiv.setAttribute('id', 'scriptMessage')
|
mainDiv.setAttribute('id', 'scriptMessage')
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
// moving msg
|
// moving msg
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
|
const movingEnabled = !funct
|
||||||
let isMouseDown = false
|
let isMouseDown = false
|
||||||
let offset = [0, 0]
|
let offset = [0, 0]
|
||||||
let mousePosition
|
let mousePosition
|
||||||
|
if (movingEnabled) {
|
||||||
mainDiv.addEventListener('mousedown', e => {
|
mainDiv.addEventListener('mousedown', e => {
|
||||||
isMouseDown = true
|
isMouseDown = true
|
||||||
offset = [mainDiv.offsetLeft - e.clientX, mainDiv.offsetTop - e.clientY]
|
offset = [
|
||||||
|
mainDiv.offsetLeft - e.clientX,
|
||||||
|
mainDiv.offsetTop - e.clientY,
|
||||||
|
]
|
||||||
})
|
})
|
||||||
mainDiv.addEventListener('mouseup', e => {
|
mainDiv.addEventListener('mouseup', e => {
|
||||||
isMouseDown = false
|
isMouseDown = false
|
||||||
|
@ -1375,6 +1472,7 @@
|
||||||
mainDiv.style.top = mousePosition.y + offset[1] + 'px'
|
mainDiv.style.top = mousePosition.y + offset[1] + 'px'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const xButton = CreateNodeWithText(null, '❌', 'div')
|
const xButton = CreateNodeWithText(null, '❌', 'div')
|
||||||
SetStyle(xButton, {
|
SetStyle(xButton, {
|
||||||
|
@ -1382,6 +1480,7 @@
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
right: '0px',
|
right: '0px',
|
||||||
display: 'inline',
|
display: 'inline',
|
||||||
|
margin: '3px',
|
||||||
})
|
})
|
||||||
xButton.addEventListener('mousedown', e => {
|
xButton.addEventListener('mousedown', e => {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
|
@ -1395,16 +1494,15 @@
|
||||||
var simpleMessageParagrapg = document.createElement('p') // new paragraph
|
var simpleMessageParagrapg = document.createElement('p') // new paragraph
|
||||||
simpleMessageParagrapg.style.margin = defMargin // fancy margin
|
simpleMessageParagrapg.style.margin = defMargin // fancy margin
|
||||||
|
|
||||||
var mesageNode = document.createElement('p') // new paragraph
|
const mesageNode = getConvertedMessageNode(simpleMessageText)
|
||||||
mesageNode.innerHTML = simpleMessageText.replace(/\n/g, '</br>')
|
|
||||||
simpleMessageParagrapg.appendChild(mesageNode)
|
simpleMessageParagrapg.appendChild(mesageNode)
|
||||||
mesageNode.addEventListener('mousedown', e => {
|
mesageNode.addEventListener('mousedown', e => {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
})
|
})
|
||||||
// TODO: edit this margin to make simple message draggable
|
|
||||||
SetStyle(mesageNode, {
|
SetStyle(mesageNode, {
|
||||||
margin: '10px 0px',
|
margin: '10px 100px',
|
||||||
cursor: 'auto',
|
cursor: funct ? 'pointer' : 'auto',
|
||||||
})
|
})
|
||||||
|
|
||||||
Array.from(mesageNode.getElementsByTagName('a')).forEach(anchorElem => {
|
Array.from(mesageNode.getElementsByTagName('a')).forEach(anchorElem => {
|
||||||
|
@ -1491,7 +1589,7 @@
|
||||||
})
|
})
|
||||||
|
|
||||||
SetStyle(questionTextElement, {
|
SetStyle(questionTextElement, {
|
||||||
cursor: 'auto',
|
cursor: funct ? 'pointer' : 'auto',
|
||||||
})
|
})
|
||||||
|
|
||||||
questionTextElement.setAttribute('id', 'questionTextElement')
|
questionTextElement.setAttribute('id', 'questionTextElement')
|
||||||
|
@ -1636,6 +1734,13 @@
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Exception(e, 'script error at showing message:')
|
Exception(e, 'script error at showing message:')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
messageElement: mainDiv,
|
||||||
|
removeMessage: () => {
|
||||||
|
mainDiv.parentNode.removeChild(mainDiv)
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// shows a fancy menu
|
// shows a fancy menu
|
||||||
|
@ -1668,6 +1773,7 @@
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
right: '0px',
|
right: '0px',
|
||||||
display: 'inline',
|
display: 'inline',
|
||||||
|
margin: '5px',
|
||||||
})
|
})
|
||||||
xButton.addEventListener('mousedown', e => {
|
xButton.addEventListener('mousedown', e => {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
|
@ -1836,7 +1942,7 @@
|
||||||
const clientId = getVal('clientId')
|
const clientId = getVal('clientId')
|
||||||
if (clientId && clientId.toString()[0] !== '0') {
|
if (clientId && clientId.toString()[0] !== '0') {
|
||||||
loginInput.value = clientId || ''
|
loginInput.value = clientId || ''
|
||||||
loginButton.innerText = texts.requestPWInsteadOfLogin
|
loginButton.innerText = texts.requestPWInsteadOflogin
|
||||||
}
|
}
|
||||||
loginDiv.appendChild(loginInput)
|
loginDiv.appendChild(loginInput)
|
||||||
loginDiv.appendChild(loginButton)
|
loginDiv.appendChild(loginButton)
|
||||||
|
@ -1845,7 +1951,7 @@
|
||||||
|
|
||||||
loginInput.addEventListener('keyup', e => {
|
loginInput.addEventListener('keyup', e => {
|
||||||
if (e.target.value === clientId) {
|
if (e.target.value === clientId) {
|
||||||
loginButton.innerText = texts.requestPWInsteadOfLogin
|
loginButton.innerText = texts.requestPWInsteadOflogin
|
||||||
} else if (e.target.value !== '') {
|
} else if (e.target.value !== '') {
|
||||||
loginButton.innerText = texts.login
|
loginButton.innerText = texts.login
|
||||||
}
|
}
|
||||||
|
@ -1914,7 +2020,6 @@
|
||||||
// : String utils 2 {{{
|
// : String utils 2 {{{
|
||||||
|
|
||||||
function removeUnnecesarySpaces(toremove) {
|
function removeUnnecesarySpaces(toremove) {
|
||||||
// TODO: check if this doesnt kill if question / answer is empty
|
|
||||||
if (!toremove) {
|
if (!toremove) {
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
|
@ -1959,19 +2064,31 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Log(value) {
|
function logHelper(logMethod, value) {
|
||||||
if (log) {
|
if (logEnabled) {
|
||||||
console.log(value)
|
if (typeof value === 'string') {
|
||||||
|
logMethod('[Moodle Script]: ' + value)
|
||||||
|
} else {
|
||||||
|
logMethod(value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function warn(value) {
|
||||||
|
logHelper(console.warn, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
function log(value) {
|
||||||
|
logHelper(console.log, value)
|
||||||
|
}
|
||||||
|
|
||||||
function Exception(e, msg) {
|
function Exception(e, msg) {
|
||||||
Log('------------------------------------------')
|
log('------------------------------------------')
|
||||||
Log(msg)
|
log(msg)
|
||||||
Log(e.message)
|
log(e.message)
|
||||||
Log('------------------------------------------')
|
log('------------------------------------------')
|
||||||
Log(e.stack)
|
log(e.stack)
|
||||||
Log('------------------------------------------')
|
log('------------------------------------------')
|
||||||
}
|
}
|
||||||
|
|
||||||
function GetId() {
|
function GetId() {
|
||||||
|
@ -1994,7 +2111,7 @@
|
||||||
if (element) {
|
if (element) {
|
||||||
next(element)
|
next(element)
|
||||||
} else {
|
} else {
|
||||||
Log(`Unable to safe get element by id: ${id}`)
|
log(`Unable to safe get element by id: ${id}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2058,14 +2175,14 @@
|
||||||
setVal('lastInfo', response.responseText)
|
setVal('lastInfo', response.responseText)
|
||||||
resolve(res)
|
resolve(res)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Log('Errro paring JSON in GetXHRInfos')
|
log('Errro paring JSON in GetXHRInfos')
|
||||||
Log(response.responseText)
|
log(response.responseText)
|
||||||
Log(e)
|
log(e)
|
||||||
reject(e)
|
reject(e)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onerror: e => {
|
onerror: e => {
|
||||||
Log('Info get Error', e)
|
log('Info get Error', e)
|
||||||
reject(e)
|
reject(e)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -2075,8 +2192,8 @@
|
||||||
try {
|
try {
|
||||||
resolve(lastInfo)
|
resolve(lastInfo)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Log('Errro paring JSON in GetXHRInfos, when using old data!')
|
log('Errro paring JSON in GetXHRInfos, when using old data!')
|
||||||
Log(e)
|
log(e)
|
||||||
reject(e)
|
reject(e)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -2107,26 +2224,14 @@
|
||||||
onload: function(response) {
|
onload: function(response) {
|
||||||
try {
|
try {
|
||||||
let res = JSON.parse(response.responseText)
|
let res = JSON.parse(response.responseText)
|
||||||
// FIXME: check if res is a valid answer array
|
|
||||||
// res.json({
|
|
||||||
// result: r,
|
|
||||||
// success: true
|
|
||||||
// })
|
|
||||||
// ERROR:
|
|
||||||
// res.json({
|
|
||||||
// message: `Invalid question :(`,
|
|
||||||
// result: [],
|
|
||||||
// recievedData: JSON.stringify(req.query),
|
|
||||||
// success: false
|
|
||||||
// })
|
|
||||||
resolve(res.result)
|
resolve(res.result)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
reject(e)
|
reject(e)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onerror: e => {
|
onerror: e => {
|
||||||
Log('Errro paring JSON in GetXHRQuestionAnswer')
|
log('Errro paring JSON in GetXHRQuestionAnswer')
|
||||||
Log(e)
|
log(e)
|
||||||
reject(e)
|
reject(e)
|
||||||
reject(e)
|
reject(e)
|
||||||
},
|
},
|
||||||
|
@ -2135,7 +2240,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function SendXHRMessage(path, message) {
|
function SendXHRMessage(path, message) {
|
||||||
// message = SUtils.RemoveSpecialChars(message) // TODO: check this
|
|
||||||
if (typeof message === 'object') {
|
if (typeof message === 'object') {
|
||||||
message = JSON.stringify(message)
|
message = JSON.stringify(message)
|
||||||
}
|
}
|
||||||
|
@ -2151,7 +2255,7 @@
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
},
|
},
|
||||||
onerror: function(e) {
|
onerror: function(e) {
|
||||||
Log('Data send error', e)
|
log('Data send error', e)
|
||||||
reject(e)
|
reject(e)
|
||||||
},
|
},
|
||||||
onload: resp => {
|
onload: resp => {
|
||||||
|
@ -2159,9 +2263,9 @@
|
||||||
const res = JSON.parse(resp.responseText)
|
const res = JSON.parse(resp.responseText)
|
||||||
resolve(res)
|
resolve(res)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Log('Error paring JSON in SendXHRMessage')
|
log('Error paring JSON in SendXHRMessage')
|
||||||
Log(resp.responseText)
|
log(resp.responseText)
|
||||||
Log(e)
|
log(e)
|
||||||
reject(e)
|
reject(e)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue