diff --git a/stable.user.js b/stable.user.js
index 4f47dba..dc8ea17 100755
--- a/stable.user.js
+++ b/stable.user.js
@@ -18,35 +18,11 @@
along with this program. If not, see .
------------------------------------------------------------------------- */
-// : Install info {{{
-
-// ===============================================================================
-// ===============================================================================
-//
-// HA EZT LÁTOD, ÉS TELEPÍTENI AKARTAD A SCRIPTET, AKKOR
-// NINCS USERSCRIPT KEZELŐ BŐVÍTMÉNYED.
-//
-// Telepíts egy userscript kezelőt, például a Tampermonkey-t:
-// https://www.tampermonkey.net/
-//
-// ===============================================================================
-//
-// IF YOU ARE SEEING THIS MESSAGE, AND YOU WANTED TO
-// INSTALL THIS SCRIPT, THEN YOU DON'T HAVE ANY USERSCRIPT
-// MANAGER INSTALLED.
-//
-// Install a userscript manager, for example Tampermonkey:
-// https://www.tampermonkey.net/
-//
-// ===============================================================================
-// ===============================================================================
-
-// : }}}
// : Script header {{{
// ==UserScript==
// @name Moodle/Elearning/KMOOC test help
-// @version 2.1.0.3
+// @version 9.9.9.9
// @description Online Moodle/Elearning/KMOOC test help
// @author MrFry
// @match https://elearning.uni-obuda.hu/*
@@ -90,8 +66,8 @@
function delVal(name) {
return GM_deleteValue(name)
}
- function openInTab(address, options) {
- GM_openInTab(address, options)
+ function openInTab(address) {
+ GM_openInTab(address, false)
}
function xmlhttpRequest(opts) {
GM_xmlhttpRequest(opts)
@@ -105,724 +81,11 @@
// : Constants and global variables {{{
- const logElementGetting = false
- const logEnabled = true
- const showErrors = true
- // forcing pages for testing. unless you test, do not set these to true!
- setVal('ISDEVEL', false)
- // only one of these should be true for testing
- const forceTestPage = false
- const forceResultPage = false
- const forceDefaultPage = false
-
var addEventListener // add event listener function
let serverAdress = 'https://qmining.frylabs.net/'
- let apiAdress = 'https://api.frylabs.net/'
- const ircAddress = 'https://kiwiirc.com/nextclient/irc.sub.fm/#qmining'
- const correctSource =
- 'https://qmining.frylabs.net/moodle-test-userscript/stable.user.js?up'
- const motdShowCount = 3 /* Ammount of times to show motd */
const messageOpacityDelta = 0.1
const minMessageOpacity = 0.2
- let infoExpireTime = 60 // Every n seconds basic info should be loaded from server
- var motd = ''
- var userSpecificMotd = undefined
- var lastestVersion = ''
- var subjInfo
-
- // array, where elems are added to shadow-root, but its position should be at target.
- var updatableElements = [] // { elem: ..., target: ... }
- var elementUpdaterInterval = -1
- const overlayElemUpdateInterval = 2 // seconds
-
- if (getVal('ISDEVEL')) {
- log('Moodle script running in developement mode!')
- infoExpireTime = 1
- serverAdress = 'http://localhost:8080/'
- apiAdress = 'http://localhost:8080/'
- }
-
- const currUrl = location.href.includes('file:///')
- ? 'https://elearning.uni-obuda.hu/'
- : location.href
-
- // : Localisation {{{
-
- const huTexts = {
- fatalError:
- 'Fatál error. Check console (f12). Kattints az üzenetre az összes kérdés/válaszért manuális kereséshez! (új böngésző tab-ban)',
- consoleErrorInfo:
- 'Itteni hibák 100% a moodle hiba. Kivéve, ha oda van írva hogy script error ;) Ha ilyesmi szerepel itt, akkor olvasd el a segítség szekciót! https://qmining.frylabs.net/manual?scriptcmd',
- freshStartWarning:
- '
Moodle teszt userscript:1.5.0 verzió: a script mostantól XMLHTTP kéréseket küld szerver fele! Erre a userscript futtató kiegészítőd is figyelmeztetni fog! Ha ez történik, a script rendes működése érdekében engedélyezd (Always allow domain)! Ha nem akarod, hogy ez történjen, akkor ne engedélyezd, vagy a menüben válaszd ki a "helyi fájl használata" opciót!
Elküldött adatok: minden teszt után a kérdés-válasz páros. Fogadott adatok: Az összes eddig ismert kérdés. Érdemes help-et elolvasni!!!
Ez az ablak frissités után eltűnik. Ha nem, akkor a visza gombbal próbálkozz.
',
- noResult:
- 'Nincs találat :( Kattints az üzenetre az összes kérdés/válaszért manuális kereséshez! (új böngésző tab-ban)',
- videoHelp: 'Miután elindítottad: Play/pause: space. Seek: Bal/jobb nyíl.',
- menuButtonText: 'Kérdések Menu',
- couldntLoadDataPopupMenuText:
- 'A kérdéseket nem lehetett beolvasni, ellenőrizd hogy elérhető-e a szerver',
- showGreetingOnEveryPage: 'Üdvözlő üzenet mutatása minden oldalon',
- close: 'Bezárás',
- help: 'Help',
- websiteBugreport: 'Weboldal',
- contribute: 'Bug report / Szavazás következő feature-re',
- ranklist: 'Ranklista',
- donate: 'Donate',
- retry: 'Újrapróbálás',
- dataEditor: 'Data editor',
- dataEditorTitle: 'Adatbázisban lévő kérdések szerkesztése',
- ircButton: 'IRC chat',
- ircButtonTitle: 'IRC chat',
- invalidPW: 'Hibás jelszó: ',
- search: 'Keresés ...',
- loading: 'Betöltés ...',
- login: 'Belépés',
- newPWTitle: 'Új jelszó új felhasználónak',
- pwRequest: 'Jelszó új felhasználónak',
- noServer: 'Nem elérhető a szerver!',
- 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`,
- 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 qmining weboldalról raktad fel. Könnyebb kezelhetőség szempontjából kérlek onnan telepítsd. Részletes leírás',
- versionUpdated: 'Verzió frissítve ',
- newVersionAvaible: 'Új verzió elérhető: ',
- userSpecifitMotdAvailable:
- 'Új üzeneted van, kattints 📬-ra bal alul megtekintéséhez!',
- scriptName: 'Moodle/Elearning/KMOOC segéd ',
- userMOTD: 'Felhasználó MOTD (ezt csak te látod):\n',
- motd: 'MOTD:\n',
- }
-
- var texts = huTexts
-
- // : }}}
-
- // : }}}
-
- // : HTML parsers {{{
-
- // : Basic processing helpers {{{
-
- function getTextPromisesFromNode(node) {
- return Array.from(node.childNodes).reduce((promises, elem) => {
- let img = elem
- if (elem.tagName !== 'IMG') {
- const t = elem.tagName ? elem.getElementsByTagName('img') : []
- if (t.length > 0) {
- img = t[0]
- }
- }
-
- let select = elem.tagName ? elem.getElementsByTagName('select') : []
- if (select.length > 0) {
- promises.push({ type: 'txt', val: '...', node: select[0] })
- return promises
- }
-
- if (img.tagName === 'IMG') {
- promises.push(
- new Promise(resolve => {
- digestMessage(getBase64Image(img)).then(res => {
- resolve({
- type: 'img',
- val: res,
- node: img,
- })
- })
- })
- )
- } else if (elem.tagName === undefined) {
- promises.push({ type: 'txt', val: elem.nodeValue, node: elem })
- } else {
- promises.push({ type: 'txt', val: elem.innerText, node: elem })
- }
-
- return promises
- }, [])
- }
-
- function makeTextFromElements(acc, item) {
- if (emptyOrWhiteSpace(item.val)) {
- return acc
- }
-
- if (item.type === 'img') {
- acc.push('[' + item.val + ']')
- } else {
- acc.push(item.val)
- }
- return acc
- }
-
- function getImagesFromElements(elements) {
- return elements.reduce((acc, element) => {
- if (element.type === 'img') {
- // FIXME: include check needed?
- if (!acc.includes(element.val)) {
- acc.push({ val: element.val, node: element.node })
- }
- }
- return acc
- }, [])
- }
-
- function getLegacyImageID(imgArray) {
- try {
- return imgArray.map(img => {
- if (!img.src.includes('brokenfile')) {
- let filePart = img.src.split('/')
- filePart = filePart[filePart.length - 1]
-
- // shorten string
- let result = ''
- let i = 0
- while (i < filePart.length && i < 30) {
- result += filePart[i]
- i++
- }
-
- return decodeURI(result)
- }
- })
- } catch (e) {
- log("Couldn't get images from result (old)")
- }
- }
-
- function getCurrentSubjectName() {
- if (logElementGetting) {
- log('getting current subjects name')
- }
- return document.getElementById('page-header').innerText.split('\n')[0] || ''
- }
-
- function uniq(a) {
- return [...new Set(a)]
- }
-
- // : }}}
-
- // : Test page processing functions {{{
-
- function handleQuiz() {
- const { removeMessage: removeLoadingMessage } = ShowMessage(
- texts.loadingAnswer
- )
-
- getQuizData()
- .then(readQuestions => {
- if (readQuestions.length === 0) {
- ShowMessage(
- texts.unableToParseTestQuestion,
-
- undefined,
- () => {
- OpenErrorPage({
- message: 'No result found',
- })
- }
- )
- return
- }
-
- const questions = readQuestions.map(question => {
- return {
- Q: question.question,
- possibleAnswers: question.possibleAnswers,
- data: question.data,
- }
- })
-
- const sentData = {
- questions: questions,
- subj: getCurrentSubjectName(),
- testUrl: currUrl,
- version: info().script.version,
- cid: getCid(),
- uid: getUid(),
- }
-
- log(sentData)
-
- post('ask', sentData).then(results => {
- removeLoadingMessage()
- ShowAnswers(
- results.map((res, i) => {
- return {
- answers: res.answers,
- question: readQuestions[i],
- }
- })
- )
- })
- })
- .catch(err => {
- warn(err)
- warn('Error in handleQuiz()')
- })
- }
-
- function getQuizData() {
- return new Promise(resolve => {
- // TODO: dropdown in question
- // TODO: get possible answers too
- const promises = []
- const questionNodes = Array.from(
- document.getElementsByTagName('form')[0].childNodes[0].childNodes
- )
-
- let i = 0
- while (
- i < questionNodes.length &&
- questionNodes[i].tagName === 'DIV' &&
- questionNodes[i].className !== 'submitbtns'
- ) {
- promises.push(getQuestionPromiseForSingleQuestion(questionNodes[i]))
- i++
- }
-
- Promise.all(promises)
- .then(result => {
- const errorsRemoved = result.reduce((acc, res) => {
- if (res.success) {
- acc.push(res)
- }
- return acc
- }, [])
- resolve(errorsRemoved)
- })
- .catch(err => {
- warn('Error in handleQuiz()')
- warn(err)
- })
- })
- }
-
- function getPossibleAnswersFromTest(node) {
- const promises = []
- let answerRoot = node.getElementsByClassName('answer')[0]
-
- if (!answerRoot) {
- answerRoot = node.getElementsByClassName('subquestion')[0]
- const options = Array.from(answerRoot.getElementsByTagName('option'))
- const possibleAnswers = options.reduce((acc, option) => {
- if (!emptyOrWhiteSpace(option.innerText)) {
- acc.push(option.innerText)
- }
- return acc
- }, [])
-
- return possibleAnswers
- } else if (answerRoot.tagName === 'DIV') {
- const answers = Array.from(answerRoot.childNodes)
-
- answers.forEach(answer => {
- if (answer.tagName) {
- promises.push(getTextPromisesFromNode(answer))
- }
- })
-
- return promises
- } else if (answerRoot.tagName === 'TABLE') {
- const answers = Array.from(answerRoot.childNodes[0].childNodes)
-
- answers.forEach(answer => {
- if (answer.tagName) {
- promises.push(
- getTextPromisesFromNode(answer.getElementsByClassName('text')[0])
- )
- // here elements with classname 'control' could be added too. Those should be a dropdown,
- // containing possible choices
- }
- })
-
- return promises
- }
- }
-
- function getImgNodesFromArray(arr) {
- return arr.reduce((acc, x) => {
- if (Array.isArray(x)) {
- x.forEach(y => {
- if (y.type === 'img') {
- acc.push(y.node)
- }
- })
- } else {
- if (x.type === 'img') {
- acc.push(x.node)
- }
- }
- return acc
- }, [])
- }
-
- function getQuestionPromiseForSingleQuestion(node) {
- return new Promise(resolve => {
- try {
- let qtextNode = node.getElementsByClassName('qtext')[0]
- if (!qtextNode) {
- qtextNode = node.getElementsByClassName('subquestion')[0]
- qtextNode = qtextNode.parentNode
- }
-
- const questionPromises = getTextPromisesFromNode(qtextNode)
- const possibleAnswerPromises = getPossibleAnswersFromTest(node)
-
- const unflattenedPossibleAnswerPromises = possibleAnswerPromises
- ? possibleAnswerPromises.map(x => {
- return Promise.all(x)
- })
- : []
-
- Promise.all([
- Promise.all(questionPromises),
- Promise.all(unflattenedPossibleAnswerPromises),
- ])
- .then(([question, possibleAnswerArray]) => {
- const questionText = removeUnnecesarySpaces(
- question.reduce(makeTextFromElements, []).join(' ')
- )
- const possibleAnswers = possibleAnswerArray.map(x => {
- return removeUnnecesarySpaces(
- x.reduce(makeTextFromElements, []).join(' ')
- )
- })
- let images = getImagesFromElements([
- ...question,
- ...possibleAnswerArray.reduce((acc, x) => {
- return [...acc, ...x]
- }, []),
- ])
- const imageNodes = getImgNodesFromArray([
- ...question,
- ...possibleAnswerArray,
- ])
- const data = getDataFromTest(images, getLegacyImageID(imageNodes))
-
- resolve({
- question: questionText,
- possibleAnswers,
- images,
- data,
- success: true,
- })
- })
- .catch(err => {
- warn('Error in getQuestionPromiseForSingleQuestion()')
- warn(err)
- resolve({ success: false })
- })
- } catch (err) {
- warn('Error in getQuestionPromiseForSingleQuestion()')
- warn(err)
- resolve({ success: false })
- }
- })
- }
-
- function getDataFromTest(hashedImages, legacyImages) {
- if (hashedImages.length > 0) {
- return {
- type: 'image',
- hashedImages: hashedImages.map(x => {
- return x.val
- }),
- images: legacyImages,
- }
- } else {
- return {
- type: 'simple',
- }
- }
- }
-
- // : }}}
-
- // : Result page processing functions {{{
-
- function getQuiz() {
- return new Promise(resolve => {
- const promises = []
- const questionNodes = Array.from(
- document.getElementsByTagName('form')[0].childNodes[0].childNodes
- )
-
- let i = 0
- while (i < questionNodes.length && questionNodes[i].tagName === 'DIV') {
- promises.push(getQuizFromNode(questionNodes[i]))
- i++
- }
-
- Promise.all(promises)
- .then(result => {
- const errorsRemoved = result.reduce((acc, res) => {
- if (res.success) {
- acc.push(res)
- }
- return acc
- }, [])
- resolve(errorsRemoved)
- })
- .catch(err => {
- warn('Error in getQuiz()')
- warn(err)
- })
- })
- }
-
- function getPromisesThatMeetsRequirements(getters, node) {
- let res
- Object.keys(getters).some(key => {
- const getter = getters[key]
- if (getter.requirement(node)) {
- try {
- res = getter.getterFunction(node)
- return true
- } catch (e) {
- log(`${key} failed`)
- }
- } else {
- log(`${key} did not pass`)
- }
- })
-
- return res
- }
-
- function getQuizFromNode(node) {
- return new Promise(resolve => {
- const questionPromises = getPromisesThatMeetsRequirements(
- questionGetters,
- node
- )
- const answerPromises = getPromisesThatMeetsRequirements(
- answerGetters,
- node
- )
- const possibleAnswers = getPossibleAnswers(node)
-
- if (!answerPromises || !questionPromises) {
- log('Answer or question array is empty, skipping question')
- resolve({ success: false })
- }
-
- Promise.all([Promise.all(questionPromises), Promise.all(answerPromises)])
- .then(([question, answer]) => {
- const questionText = question
- .reduce(makeTextFromElements, [])
- .join(' ')
- const answerText = answer.reduce(makeTextFromElements, []).join(' ')
- let images = getImagesFromElements([...question, ...answer])
-
- const result = {
- Q: removeUnnecesarySpaces(questionText),
- A: removeUnnecesarySpaces(answerText),
- data: getDataFromResultImages(images),
- success: true,
- }
- result.data.possibleAnswers = possibleAnswers
- resolve(result)
- })
- .catch(err => {
- warn('Error in getQuizFromNode()')
- warn(err)
- resolve({ success: false })
- })
- })
- }
-
- function getDataFromResultImages(images) {
- if (images && images.length > 0) {
- return {
- type: 'image',
- hashedImages: images.map(x => {
- return x.val
- }),
- }
- } else {
- return {
- type: 'simple',
- }
- }
- }
-
- const questionGetters = {
- getSimpleQuestion: {
- description: 'Basic question getter',
- requirement: node => {
- return node.getElementsByClassName('qtext').length > 0
- },
- getterFunction: node => {
- let question = node.getElementsByClassName('qtext')[0]
- return getTextPromisesFromNode(question)
- },
- },
- }
-
- const answerGetters = {
- getSimpleAnswer: {
- description: 'Basic answer getter',
- requirement: node => {
- return node.getElementsByClassName('rightanswer').length > 0
- },
- getterFunction: node => {
- let answer = node.getElementsByClassName('rightanswer')[0]
- return getTextPromisesFromNode(answer)
- },
- },
- noCorrect: {
- description: 'Gets correct answer, even if the correct is not shown',
- requirement: node => {
- return (
- node.getElementsByClassName('rightanswer').length === 0 &&
- node.getElementsByClassName('answer').length > 0
- )
- },
- getterFunction: node => {
- const possibleAnswers = getPossibleAnswers(node)
-
- if (getIfSolutionIsCorrect(node)) {
- if (possibleAnswers.length === 2) {
- return [
- {
- type: 'txt',
- val: possibleAnswers.find(x => {
- return x.selectedByUser === false
- }).text,
- },
- ]
- }
- } else {
- const state = node.getElementsByClassName('state')[0]
- // TODO: what if in english
- if (state && state.innerText === 'Hibás') {
- return false
- }
- return [
- {
- type: 'txt',
- val: possibleAnswers.find(x => {
- return x.selectedByUser === true
- }).text,
- },
- ]
- }
- },
- },
- getDropdownAnswer: {
- description: 'Dropdown answer getter',
- requirement: node => {
- return false
- },
- getterFunction: node => {
- // TODO dropdown kérdés.html
- return 'asd'
- },
- },
- getTextareaAnswer: {
- description: 'Get complex answer',
- requirement: node => {
- return false
- },
- getterFunction: node => {
- // TODO Ugrás... bug.html
- return 'asd'
- },
- },
- getDragBoxAnswer: {
- description: 'Get complex answer',
- requirement: node => {
- return false
- },
- getterFunction: node => {
- // TODO dragboxes
- return 'asd'
- },
- },
- }
-
- function getIfSolutionIsCorrect(node) {
- const gradeText = node.getElementsByClassName('grade')[0].innerText
- const stateText = node.getElementsByClassName('state')[0].innerText
- return !(stateText.includes('Helyes') || !gradeText.includes('0,00'))
- }
-
- function getPossibleAnswers(node) {
- const answerNodes = Array.from(
- node.getElementsByClassName('answer')[0].childNodes
- )
-
- return answerNodes.reduce((acc, answerNode) => {
- let selectedByUser
- if (answerNode.childNodes.length > 0) {
- selectedByUser = answerNode.childNodes[0].checked
- }
-
- const text = removeUnnecesarySpaces(answerNode.innerText)
-
- if (text !== '') {
- acc.push({
- text: text,
- selectedByUser: selectedByUser,
- })
- }
- return acc
- }, [])
- }
-
- function digestMessage(message) {
- return new Promise(resolve => {
- const encoder = new TextEncoder()
- const data = encoder.encode(message)
- const hash = crypto.subtle.digest('SHA-256', data).then(buf => {
- let res = String.fromCharCode.apply(null, new Uint8Array(buf))
- res = btoa(res)
- .replace(/=/g, '')
- .replace(/\+/g, '-')
- .replace(/\//g, '_')
- resolve(res)
- })
- })
- }
-
- function getBase64Image(img) {
- img.crossOrigin = 'Anonymous'
- let canvas = document.createElement('canvas')
- canvas.width = img.width
- canvas.height = img.height
- let ctx = canvas.getContext('2d')
- ctx.drawImage(img, 0, 0)
- let dataURL = canvas.toDataURL('image/png')
- img.crossOrigin = undefined
- return dataURL.replace(/^data:image\/(png|jpg);base64,/, '')
- }
-
- // : }}}
-
- // : Misc {{{
-
- function getVideo() {
- if (logElementGetting) {
- log('getting video stuff')
- }
- return document.getElementsByTagName('video')[0]
- }
-
- function getVideoElement() {
- if (logElementGetting) {
- log('getting video element')
- }
- return document.getElementById('videoElement').parentNode
- }
-
- // : }}}
// : }}}
@@ -919,174 +182,13 @@
const overlay = StealthOverlay()
- function createHoverOver(appendTo) {
- const overlayElement = document.createElement('div')
- overlay.append(overlayElement)
-
- updatableElements.push({ elem: overlayElement, target: appendTo })
-
- if (elementUpdaterInterval === -1) {
- elementUpdaterInterval = setInterval(() => {
- updatableElements.forEach(({ elem, target }) => {
- let currX, currY, currWidth, currHeight
- let { left, top, width, height } = target.getBoundingClientRect()
- left += window.scrollX
- top += window.scrollY
-
- SetStyle(elem, {
- pointerEvents: 'none',
- userSelect: 'none',
- position: 'absolute',
- zIndex: 999999,
- top: top + 'px',
- left: left + 'px',
- width: width + 'px',
- height: height - 10 + 'px',
- })
- })
- }, overlayElemUpdateInterval * 1000)
- }
-
- return overlayElement
- }
-
- function appendBelowElement(el, toAppend) {
- const rect = el.getBoundingClientRect()
- const correction = 8
- const left = rect.left + window.scrollX - correction
- const top = rect.top + window.scrollY - correction
-
- SetStyle(toAppend, {
- position: 'absolute',
- zIndex: 1,
- top: top + 'px',
- left: left + 'px',
- })
-
- overlay.appendChild(toAppend)
- }
-
// : }}}
- // : Main logic stuff {{{
-
- // : Main function {{{
-
- // window.addEventListener("load", () => {})
Main()
function Main() {
'use strict'
- log('Moodle / E-Learning script')
-
- if (document.readyState === 'loading') {
- document.addEventListener('DOMContentLoaded', Init)
- } else {
- Init()
- }
- }
-
- function AfterLoad() {
- const url = currUrl
-
- try {
- if (
- (url.includes('/quiz/') && url.includes('attempt.php')) ||
- forceTestPage
- ) {
- // if the current page is a test
- handleQuiz()
- } else if (
- (url.includes('/quiz/') && url.includes('review.php')) ||
- forceResultPage
- ) {
- // if the current window is a test-s result
- HandleResults(url)
- } else if (
- (!url.includes('/quiz/') &&
- !url.includes('review.php') &&
- !url.includes('.pdf')) ||
- forceDefaultPage
- ) {
- // if the current window is any other window than a quiz or pdf.
- HandleUI(url)
- }
- } catch (e) {
- ShowMessage(
- texts.fatalError,
-
- undefined,
- () => {
- OpenErrorPage(e)
- }
- )
-
- Exception(e, 'script error at main:')
- }
- if (url.includes('eduplayer')) {
- AddVideoHotkeys(url)
- } // adding video hotkeys
- log(texts.consoleErrorInfo)
- }
- // : }}}
-
- // : Loading {{{
- function HandleQminingSite(url) {
- try {
- const idInput = document.getElementById('cid')
- if (idInput) {
- idInput.value = getCid()
- }
- } catch (e) {
- warn('Error filling client ID input', e)
- }
- try {
- const sideLinks = document.getElementById('sideBarLinks')
- if (!sideLinks) {
- return
- }
- Array.from(sideLinks.childNodes).forEach(link => {
- link.addEventListener('mousedown', () => {
- FillFeedbackCID(url, link)
- })
- })
-
- FillFeedbackCID(
- url,
- document
- .getElementById('sideBarLinks')
- .getElementsByClassName('active')[0]
- )
- } catch (e) {
- warn('Error filling client ID input', e)
- }
- }
-
- function FillFeedbackCID(url, link) {
- try {
- if (link.id === 'feedback') {
- const cidSetInterval = setInterval(() => {
- const cid = document.getElementById('cid')
- if (cid) {
- cid.value = getCid() + '|' + info().script.version
- window.clearInterval(cidSetInterval)
- }
- }, 100)
- }
- } catch (e) {
- warn('Error filling client ID input', e)
- }
- }
-
- function Init() {
- const url = currUrl
-
- if (url.includes(serverAdress.split('/')[2])) {
- HandleQminingSite(url)
- return
- }
-
try {
addEventListener = (function() {
if (document.addEventListener) {
@@ -1100,445 +202,18 @@
}
})()
} catch (e) {
- Exception(e, 'script error at addEventListener:')
- }
- VersionActions()
- if (!url.includes('.pdf')) {
- ShowMenu()
- }
- ConnectToServer(AfterLoad)
- }
-
- function Auth(pw) {
- post('login', { pw: pw, script: true }).then(res => {
- if (res.result === 'success') {
- ConnectToServer(AfterLoad)
- clearAllMessages()
- resetMenu()
- } else {
- SafeGetElementById('infoMainDiv', elem => {
- elem.innerText = texts.invalidPW + pw
- })
- }
- })
- }
-
- function resetMenu() {
- SafeGetElementById('menuButtonDiv', elem => {
- elem.style.backgroundColor = '#262626'
- })
- SafeGetElementById('ircButton', elem => {
- elem.style.display = 'none'
- })
- SafeGetElementById('retryButton', elem => {
- elem.style.display = 'none'
- })
- SafeGetElementById('loginDiv', elem => {
- elem.style.display = 'none'
- })
- SafeGetElementById('infoMainDiv', elem => {
- elem.innerText = texts.loading
- })
- }
-
- function ConnectToServer(cwith) {
- clearAllMessages()
- GetXHRInfos()
- .then(inf => {
- if (inf.result === 'nouser') {
- NoUserAction()
- return
- }
- lastestVersion = inf.version.replace(/\n/g, '')
- motd = inf.motd
- if (getUid() !== inf.uid) {
- setVal('userId', inf.uid)
- }
- subjInfo = inf.subjinfo
- setVal('userId', inf.uid)
- userSpecificMotd = inf.userSpecificMotd
- if (userSpecificMotd) {
- overlay.querySelector('#mailButton').style.cursor = 'pointer'
- overlay.querySelector('#mailButton').innerText = userSpecificMotd.seen
- ? '📭'
- : '📬'
- }
-
- overlay.querySelector('#infoMainDiv').innerText = `${
- subjInfo.subjects
- } tárgy, ${subjInfo.questions} kérdés. User ID: ${getUid()}`
- // FIXME: if cwith() throws an unhandled error it sais server is not avaible
- cwith()
- })
- .catch(() => {
- NoServerAction()
- })
- }
-
- function NoUserAction() {
- SafeGetElementById('menuButtonDiv', elem => {
- elem.style.backgroundColor = '#44cc00'
- })
- SafeGetElementById('infoMainDiv', elem => {
- elem.innerText = texts.noUser
- if (getCid()) {
- elem.innerText += ` (${getCid()})`
- }
- })
- SafeGetElementById('loginDiv', elem => {
- elem.style.display = ''
- })
- }
-
- function NoServerAction() {
- SafeGetElementById('menuButtonDiv', elem => {
- elem.style.backgroundColor = 'red'
- })
- SafeGetElementById('infoMainDiv', elem => {
- elem.innerText = texts.noServer
- })
- SafeGetElementById('ircButton', elem => {
- elem.style.display = ''
- })
- SafeGetElementById('retryButton', elem => {
- elem.style.display = ''
- })
- log(texts.noServerConsoleMessage)
- }
-
- function VersionActions() {
- FreshStart()
- }
-
- // : }}}
-
- // : UI handling {{{
-
- function shouldShowMotd() {
- if (!emptyOrWhiteSpace(motd)) {
- var prevmotd = getVal('motd')
- if (prevmotd !== motd) {
- setVal('motdcount', motdShowCount)
- setVal('motd', motd)
- return true
- } else {
- var motdcount = getVal('motdcount')
- if (motdcount === undefined) {
- setVal('motdcount', motdShowCount)
- motdcount = motdShowCount
- }
-
- motdcount--
- if (motdcount > 0) {
- setVal('motdcount', motdcount)
- return true
- }
- }
- }
- }
-
- function HandleUI(url) {
- const newVersion = info().script.version !== getVal('lastVerson')
- const showMOTD = shouldShowMotd()
- const isNewVersionAvaible =
- lastestVersion !== undefined && info().script.version !== lastestVersion
-
- let timeout = null
- const greetMsg = []
-
- if (isNewVersionAvaible || newVersion || showMOTD) {
- greetMsg.push(texts.scriptName + info().script.version)
- }
- if (isNewVersionAvaible) {
- timeout = 5
- greetMsg.push(texts.newVersionAvaible + lastestVersion)
- timeout = undefined
- }
- if (userSpecificMotd && !userSpecificMotd.seen) {
- timeout = null
- greetMsg.push(texts.userSpecifitMotdAvailable)
- timeout = undefined
- }
- if (newVersion) {
- greetMsg.push(texts.versionUpdated + info().script.version)
- setVal('lastVerson', info().script.version) // setting lastVersion
- }
- if (!installedFromCorrectSource(correctSource)) {
- greetMsg.push(texts.reinstallFromCorrectSource)
- log(`update url:${info().script.updateURL}`)
- }
- if (showMOTD) {
- greetMsg.push(texts.motd + motd)
- timeout = null
+ console.log(e)
}
ShowMessage(
- greetMsg.join('\n'),
-
- timeout
- )
- }
-
- // : }}}
-
- // : Answering stuffs {{{
-
- function PrepareAnswers(result) {
- const { answers, question } = result
- if (answers.length > 0) {
- return answers.map(answer => {
- const { Q, A, data } = answer.q
- let msg = Q + '\n' + A
-
- // TODO: show 'képek sorrendben' if there are no new kind of image ids
- if (data.type === 'image') {
- question.images.forEach((img, i) => {
- const regex = new RegExp(`\\[${img.val}\\]`, 'g')
- msg = msg.replace(regex, '[' + i.toString() + ']')
- })
- }
-
- return {
- m: msg,
- p: answer.match,
- header:
- answer.detailedMatch.matchedSubjName +
- ' - ' +
- answer.detailedMatch.qdb,
- }
- })
- }
- }
-
- function addImageIdsToImageNodes(imgs) {
- imgs.images.forEach((img, i) => {
- const text = document.createElement('div')
- text.innerText = `[${i}]`
- SetStyle(text, {
- backgroundColor: '#333',
- borderRadius: '5px',
- color: 'white',
- opacity: 0.7,
- fontSize: '13px',
- })
- appendBelowElement(img.node, text)
- })
- }
-
- function ShowAnswers(results) {
- log(results)
- const answers = results.reduce((acc, res) => {
- const prepared = PrepareAnswers(res)
- addImageIdsToImageNodes(res.question)
- if (prepared) {
- acc.push(prepared)
- }
- return acc
- }, [])
-
- if (answers.length > 0) {
- ShowMessage(answers)
- } else {
- ShowMessage(
- texts.noResult,
-
- undefined,
- function() {
- OpenErrorPage({
- message: 'No result found',
- question: Array.isArray(answers[0])
- ? answers[0][0].replace(/"/g, '').replace(/:/g, '')
- : answers[0],
- })
- }
- )
- }
- }
-
- // : }}}
-
- // : Quiz saving {{{
-
- function HandleResults(url) {
- getQuiz().then(res => {
- SaveQuiz(res, ShowSaveQuizDialog) // saves the quiz questions and answers
- })
- }
-
- function ShowSaveQuizDialog(sendResult, sentData, newQuestions) {
- var msg = ''
- if (sendResult) {
- msg = 'Kérdések elküldve, katt az elküldött adatokért.'
- if (newQuestions > 0) {
- msg += ' ' + newQuestions + ' új kérdés'
- } else {
- msg += ' Nincs új kérdés'
- }
- } else {
- msg =
- 'Szerver nem elérhető, vagy egyéb hiba kérdések elküldésénél! (F12 -> Console)'
- }
- // showing a message wit the click event, and the generated page
- ShowMessage(
- msg,
-
- null,
- function() {
- let towrite = ''
- try {
- towrite += 'Elküldött adatok: ' + JSON.stringify(sentData)
- } catch (e) {
- towrite += 'Elküldött adatok: ' + sentData
- }
- document.write(towrite)
- document.close()
+ 'Ha ezt az üzeneted látod, akkor a scripted a greasyforkról frissült. Weboldalról is lehet telepíteni a scriptet, és hogy a greasyfork ne legyen egy felesleges kerülő, így innentől ott megszűnt a script. Kattints erre az üzenetre a weboldalról való script telepítés útmutatóhoz.',
+ undefined,
+ () => {
+ openInTab(serverAdress + 'manual.html#scriptreinstall')
}
)
}
- // saves the current quiz. questionData contains the active subjects questions
- function SaveQuiz(quiz, next) {
- try {
- let sentData = {}
- if (quiz.length === 0) {
- ShowMessage(texts.noParseableQuestionResult)
- return
- }
- try {
- sentData = {
- version: info().script.version,
- id: getCid(),
- quiz: quiz,
- location: currUrl,
- }
- try {
- sentData.subj = getCurrentSubjectName()
- } catch (e) {
- sentData.subj = 'NOSUBJ'
- log('unable to get subject name :c')
- }
- log('SENT DATA', sentData)
- post('isAdding', sentData).then(res => {
- next(res.success, sentData, res.totalNewQuestions)
- })
- } catch (e) {
- Exception(e, 'error at sending data to server.')
- }
- } catch (e) {
- Exception(e, 'script error at saving quiz')
- }
- }
-
- // : }}}
-
- // : Misc {{{
-
- // : Install source checker {{{
-
- function installedFromCorrectSource(source) {
- // https://qmining.frylabs.net/moodle-test-userscript/stable.user.js?up
- return info().script.updateURL === correctSource
- }
-
- // : }}}
-
- // : Version action functions {{{
-
- function FreshStart() {
- var firstRun = getVal('firstRun') // if the current run is the frst
- if (firstRun === undefined || firstRun === true) {
- setVal('firstRun', false)
- ShowHelp('firstRun') // showing help
- registerScript()
-
- document.write(texts.freshStartWarning)
- document.close()
- throw new Error('something, so this stuff stops')
- }
- }
-
- function registerScript() {
- try {
- // uncomment to re-register again every page refresh
- // setVal('registeredWithCid', false)
- // setVal('registeredWithUid', false)
-
- if (getVal('registeredWithCid')) {
- if (getVal('registeredWithUid')) {
- return
- } else if (!getUid()) {
- return
- }
- }
-
- setVal('registeredWithCid', true)
- if (getUid()) {
- setVal('registeredWithUid', true)
- }
-
- post('registerscript', {
- cid: getCid(),
- uid: getUid(),
- version: info().script.version,
- date: new Date(),
- installSource: info().script.updateURL,
- })
- } catch (err) {
- warn('Unexpected error while registering script')
- log(err)
- }
- }
-
- // : }}}
-
- // : Video hotkey stuff {{{
-
- // this function adds basic hotkeys for video controll.
- function AddVideoHotkeys(url) {
- var seekTime = 20
- document.addEventListener('keydown', function(e) {
- try {
- var video = getVideo()
- var keyCode = e.keyCode // getting keycode
- if (keyCode === 32) {
- // if the keycode is 32 (space)
- e.preventDefault() // preventing default action (space scrolles down)
- if (video.paused && video.buffered.length > 0) {
- video.play()
- } else {
- video.pause()
- }
- }
- if (keyCode === 39) {
- // rigth : 39
- video.currentTime += seekTime
- }
- if (keyCode === 37) {
- // left : 37
- video.currentTime -= seekTime
- }
- } catch (err) {
- log('Hotkey error.')
- log(err.message)
- }
- })
- var toadd = getVideoElement()
- var node = CreateNodeWithText(toadd, texts.videoHelp)
- node.style.margin = '5px 5px 5px 5px' // fancy margin
- }
-
- // : }}}
-
- // : }}}
-
- // : }}}
-
- // : Show message, and script menu stuff {{{
-
- function clearAllMessages() {
- overlay.querySelectorAll('#scriptMessage').forEach(x => x.remove())
- }
-
function getConvertedMessageNode(message) {
const messageNode = document.createElement('p')
const resultNode = document.createElement('p')
@@ -1570,7 +245,7 @@
function addOpacityChangeEvent(elem) {
if (!elem.id) {
- warn('element must have ID to add opacity change event!')
+ console.warn('element must have ID to add opacity change event!')
return
}
@@ -1945,390 +620,7 @@
},
}
} catch (e) {
- Exception(e, 'script error at showing message:')
- }
- }
-
- // shows a fancy menu
- function ShowMenu() {
- try {
- const appedtTo = overlay // will be appended here
- const menuButtonDiv = document.createElement('div')
- const id = 'menuButtonDiv'
- menuButtonDiv.setAttribute('id', id)
- SetStyle(menuButtonDiv, {
- width: '600px',
- // height: buttonHeight + 'px',
- top: window.innerHeight - 160 + 'px',
- left: '10px',
- zIndex: 999999,
- position: 'fixed',
- textAlign: 'center',
- padding: '0px',
- margin: '0px',
- background: '#262626',
- border: '3px solid #99f',
- borderRadius: '5px',
- opacity: getVal(`${id}_opacity`),
- })
- // ------------------------------------------------------------------
- // transparencity
- // ------------------------------------------------------------------
- addOpacityChangeEvent(menuButtonDiv)
-
- const xButton = CreateNodeWithText(menuButtonDiv, '❌', 'div')
- SetStyle(xButton, {
- cursor: 'pointer',
- position: 'absolute',
- right: '0px',
- display: 'inline',
- margin: '5px',
- })
- xButton.addEventListener('mousedown', e => {
- e.stopPropagation()
- menuButtonDiv.parentNode.removeChild(menuButtonDiv)
- })
-
- const mailButton = CreateNodeWithText(menuButtonDiv, '📭', 'div')
- mailButton.setAttribute('id', 'mailButton')
- SetStyle(mailButton, {
- fontSize: '30px',
- position: 'absolute',
- left: '0px',
- bottom: '0px',
- display: 'inline',
- margin: '5px',
- })
- mailButton.addEventListener('mousedown', e => {
- e.stopPropagation()
- if (userSpecificMotd && !userSpecificMotd.seen) {
- mailButton.innerText = '📭'
- post('infos', {
- userSpecificMotdSeen: true,
- })
- }
- if (!userSpecificMotd) {
- return
- }
- clearAllMessages()
- ShowMessage(
- 'Üzenet oldal készítéjétől (csak te látod):\n' + userSpecificMotd.msg
- )
- })
-
- var tbl = document.createElement('table')
- tbl.style.margin = '5px 5px 5px 5px'
- tbl.style.textAlign = 'left'
- tbl.style.width = '98%'
- menuButtonDiv.appendChild(tbl)
-
- var buttonRow = tbl.insertRow()
- var buttonCell = buttonRow.insertCell()
- buttonCell.style.textAlign = 'center'
-
- var buttonRow2 = tbl.insertRow()
- var buttonCell2 = buttonRow2.insertCell()
- buttonCell2.style.textAlign = 'center'
-
- let buttonStyle = {
- position: '',
- margin: '5px 5px 5px 5px',
- border: 'none',
- backgroundColor: '#333333',
- padding: '4px',
- borderRadius: '2px',
- color: '#ffffff',
- cursor: 'pointer',
- }
- // site link ----------------------------------------------------------------------------------------------------------------
-
- let siteLink = CreateNodeWithText(
- buttonCell,
- texts.websiteBugreport,
- 'button'
- )
- SetStyle(siteLink, buttonStyle)
-
- siteLink.addEventListener('click', function() {
- openInTab(serverAdress + 'menuClick', {
- active: true,
- })
- })
-
- // help button ----------------------------------------------------------------------------------------------------------------
- let helpButton = CreateNodeWithText(buttonCell, texts.help, 'button')
- SetStyle(helpButton, buttonStyle)
-
- helpButton.addEventListener('click', function() {
- ShowHelp()
- }) // adding clicktextNode
-
- // site link ----------------------------------------------------------------------------------------------------------------
-
- let contributeLink = CreateNodeWithText(
- buttonCell,
- texts.contribute,
- 'button'
- )
- SetStyle(contributeLink, buttonStyle)
-
- contributeLink.addEventListener('click', function() {
- openInTab(serverAdress + 'contribute?scriptMenu', {
- active: true,
- })
- })
-
- // pw request ----------------------------------------------------------------------------------------------------------------
-
- let pwRequest = CreateNodeWithText(buttonCell2, texts.pwRequest, 'button')
- pwRequest.title = texts.newPWTitle
- SetStyle(pwRequest, buttonStyle)
-
- pwRequest.addEventListener('click', function() {
- openInTab(serverAdress + 'pwRequest?scriptMenu', {
- active: true,
- })
- })
- // IRC ----------------------------------------------------------------------------------------------------------------
-
- let ircButton2 = CreateNodeWithText(
- buttonCell2,
- texts.ircButton,
- 'button'
- )
- ircButton2.title = texts.ircButtonTitle
- SetStyle(ircButton2, buttonStyle)
- ircButton2.addEventListener('click', function() {
- openInTab(serverAdress + 'irc?scriptMenu', {
- active: true,
- })
- })
- // Dataeditor ----------------------------------------------------------------------------------------------------------------
-
- let ranklistButton = CreateNodeWithText(
- buttonCell2,
- texts.ranklist,
- 'button'
- )
- SetStyle(ranklistButton, buttonStyle)
- ranklistButton.addEventListener('click', function() {
- openInTab(serverAdress + 'ranklist?scriptMenu', {
- active: true,
- })
- })
- // Dataeditor ----------------------------------------------------------------------------------------------------------------
-
- let dataEditorButton = CreateNodeWithText(
- buttonCell2,
- texts.dataEditor,
- 'button'
- )
- dataEditorButton.title = texts.dataEditorTitle
- SetStyle(dataEditorButton, buttonStyle)
- dataEditorButton.addEventListener('click', function() {
- openInTab(serverAdress + 'dataeditor?scriptMenu', {
- active: true,
- })
- })
-
- // donate link ----------------------------------------------------------------------------------------------------------------
- let donateLink = CreateNodeWithText(buttonCell, texts.donate, 'button')
- SetStyle(donateLink, buttonStyle)
-
- donateLink.addEventListener('click', function() {
- openInTab(serverAdress + 'donate?scriptMenu', {
- active: true,
- })
- })
-
- addEventListener(window, 'resize', function() {
- menuButtonDiv.style.top = window.innerHeight - 70 + 'px'
- })
-
- // INFO TABEL --------------------------------------------------------------------
- var itbl = document.createElement('table')
- SetStyle(itbl, {
- margin: '5px 5px 5px 5px',
- textAlign: 'left',
- width: '98%',
- })
- menuButtonDiv.appendChild(itbl)
- var ibuttonRow = tbl.insertRow()
- var ibuttonCell = ibuttonRow.insertCell()
- ibuttonCell.style.textAlign = 'center'
-
- // INFO DIV ---------------------------------------------------------------------------------
- let infoDiv = CreateNodeWithText(ibuttonCell, texts.loading, 'span')
- infoDiv.setAttribute('id', 'infoMainDiv')
- SetStyle(infoDiv, {
- color: '#ffffff',
- margin: '5px',
- })
-
- // login div ----------------------------------------------------------------------------------------------------------------
- const loginDiv = document.createElement('div')
- loginDiv.style.display = 'none'
- loginDiv.setAttribute('id', 'loginDiv')
- const loginButton = document.createElement('button')
- loginButton.innerText = texts.login
- const loginInput = document.createElement('input')
- loginInput.type = 'text'
- loginInput.style.width = '400px'
- loginInput.style.textAlign = 'center'
- loginDiv.appendChild(loginInput)
- loginDiv.appendChild(loginButton)
-
- SetStyle(loginButton, buttonStyle)
-
- loginButton.addEventListener('click', function() {
- Auth(loginInput.value)
- })
-
- ibuttonCell.appendChild(loginDiv)
-
- // irc button ----------------------------------------------------------------------------------------------------------------
- let ircButton = CreateNodeWithText(ibuttonCell, texts.ircButton, 'button')
- SetStyle(ircButton, buttonStyle)
- ircButton.style.display = 'none'
- ircButton.setAttribute('id', 'ircButton')
-
- ircButton.addEventListener('click', function() {
- openInTab(ircAddress, {
- active: true,
- })
- })
-
- // retry button ----------------------------------------------------------------------------------------------------------------
- let retryButton = CreateNodeWithText(ibuttonCell, texts.retry, 'button')
- SetStyle(retryButton, buttonStyle)
- retryButton.style.display = 'none'
- retryButton.setAttribute('id', 'retryButton')
-
- retryButton.addEventListener('click', function() {
- menuButtonDiv.style.background = '#262626'
- infoDiv.innerText = texts.loading
- retryButton.style.display = 'none'
- ircButton.style.display = 'none'
- ConnectToServer(AfterLoad)
- })
-
- // window resize event listener ---------------------------------------
- addEventListener(window, 'resize', function() {
- menuButtonDiv.style.top = window.innerHeight - 70 + 'px'
- })
-
- // APPEND EVERYTHING
- appedtTo.appendChild(menuButtonDiv)
-
- addEventListener(menuButtonDiv, 'mousedown', function(e) {
- if (e.which === 2) {
- menuButtonDiv.parentNode.removeChild(menuButtonDiv)
- }
- })
- } catch (e) {
- Exception(e, 'script error at showing menu:')
- }
- }
-
- // : }}}
-
- // : Generic utils {{{
-
- // : String utils 2 {{{
-
- function removeUnnecesarySpaces(toremove) {
- if (!toremove) {
- return ''
- }
-
- toremove = normalizeSpaces(toremove).replace(/\t/g, '')
- while (toremove.includes(' ')) {
- toremove = toremove.replace(/ {2}/g, ' ')
- }
- while (toremove.includes('\n\n')) {
- toremove = toremove.replace(/\n{2}/g, ' ')
- }
- return toremove.trim()
- }
-
- function normalizeSpaces(input) {
- assert(input)
-
- return input.replace(/\s/g, ' ')
- }
-
- function emptyOrWhiteSpace(value) {
- if (value === undefined) {
- return true
- }
-
- return (
- value
- .replace(/\n/g, '')
- .replace(/\t/g, '')
- .replace(/ /g, '')
- .replace(/\s/g, ' ') === ''
- )
- }
-
- // : }}}
-
- const specialChars = ['&', '\\+']
-
- const assert = val => {
- if (!val) {
- throw new Error('Assertion failed')
- }
- }
-
- function logHelper(logMethod, ...value) {
- if (logEnabled) {
- logMethod('[Moodle Script]: ', ...value)
- }
- }
-
- function warn(value) {
- logHelper(console.warn, value)
- }
-
- function log() {
- logHelper(console.log, ...arguments)
- }
-
- function Exception(e, msg) {
- log('------------------------------------------')
- log(msg)
- log(e.message)
- log('------------------------------------------')
- log(e.stack)
- log('------------------------------------------')
- }
-
- function getUid() {
- return getVal('userId')
- }
-
- function getCid() {
- let currId = getVal('clientId')
- if (currId) {
- return currId
- } else {
- currId = new Date()
- currId = currId.getTime() + Math.floor(Math.random() * 1000000000000)
- currId = currId.toString().split('')
- currId.shift()
- currId = '0' + currId.join('')
- setVal('clientId', currId)
- return currId
- }
- }
-
- function SafeGetElementById(id, next) {
- let element = overlay.querySelector('#' + id)
- if (element) {
- next(element)
- } else {
- log(`Unable to safe get element by id: ${id}`)
+ console.log(e)
}
}
@@ -2349,206 +641,4 @@
}
return paragraphElement
}
-
- function GetXHRInfos() {
- registerScript()
- const now = new Date().getTime()
- const lastCheck = getVal('lastInfoCheckTime')
- if (!lastCheck) {
- setVal('lastInfoCheckTime', now)
- }
-
- let lastInfo = { result: 'noLastInfo' }
- try {
- lastInfo = JSON.parse(getVal('lastInfo'))
- } catch (e) {
- if (showErrors) {
- warn(e)
- }
- }
-
- if (
- lastInfo.result !== 'success' ||
- now > lastCheck + infoExpireTime * 1000
- ) {
- return new Promise((resolve, reject) => {
- const url =
- apiAdress +
- 'infos?version=true&motd=true&subjinfo=true&cversion=' +
- info().script.version +
- '&cid=' +
- getCid()
-
- xmlhttpRequest({
- method: 'GET',
- url: url,
- crossDomain: true,
- xhrFields: { withCredentials: true },
- headers: {
- 'Content-Type': 'application/json',
- },
- onload: function(response) {
- try {
- setVal('lastInfoCheckTime', now)
- const res = JSON.parse(response.responseText)
- setVal('lastInfo', response.responseText)
- resolve(res)
- } catch (e) {
- log('Errro paring JSON in GetXHRInfos')
- log(response.responseText)
- log(e)
- reject(e)
- }
- },
- onerror: e => {
- log('Info get Error', e)
- reject(e)
- },
- })
- })
- } else {
- return new Promise((resolve, reject) => {
- try {
- resolve(lastInfo)
- } catch (e) {
- log('Errro paring JSON in GetXHRInfos, when using old data!')
- log(e)
- reject(e)
- }
- })
- }
- }
-
- function GetXHRQuestionAnswer(question) {
- log('QUESTIONS', question)
- return new Promise((resolve, reject) => {
- let url = apiAdress + 'ask?'
- let params = []
- Object.keys(question).forEach(key => {
- let val = question[key]
- if (typeof val !== 'string') {
- val = JSON.stringify(val)
- }
- params.push(key + '=' + encodeURIComponent(val))
- })
- url +=
- params.join('&') +
- '&cversion=' +
- info().script.version +
- '&cid=' +
- getCid()
-
- xmlhttpRequest({
- method: 'GET',
- url: url,
- onload: function(response) {
- try {
- let res = JSON.parse(response.responseText)
- resolve(res.result)
- } catch (e) {
- reject(e)
- }
- },
- onerror: e => {
- log('Errro paring JSON in GetXHRQuestionAnswer')
- log(e)
- reject(e)
- reject(e)
- },
- })
- })
- }
-
- function post(path, message) {
- if (typeof message === 'object') {
- message = JSON.stringify(message)
- }
- const url = apiAdress + path
- return new Promise((resolve, reject) => {
- xmlhttpRequest({
- method: 'POST',
- url: url,
- crossDomain: true,
- xhrFields: { withCredentials: true },
- data: message,
- headers: {
- 'Content-Type': 'application/json',
- },
- onerror: function(e) {
- log('Data send error', e)
- reject(e)
- },
- onload: resp => {
- try {
- const res = JSON.parse(resp.responseText)
- resolve(res)
- } catch (e) {
- log('Error paring JSON in post')
- log(resp.responseText)
- log(e)
- reject(e)
- }
- },
- })
- })
- }
-
- function OpenErrorPage(e) {
- const queries = []
- try {
- Object.keys(e).forEach(key => {
- if (e[key]) {
- queries.push(`${key}=${encodeURIComponent(e[key])}`)
- }
- })
- queries.push('version=' + encodeURIComponent(info().script.version))
- queries.push('uid=' + encodeURIComponent(getUid()))
- queries.push('cid=' + encodeURIComponent(getCid()))
- } catch (e) {
- Exception(e, 'error at setting error stack/msg link')
- }
- openInTab(serverAdress + 'lred?' + queries.join('&'), {
- active: true,
- })
- }
-
- // : }}}
-
- // : Help {{{
-
- // shows some neat help
- function ShowHelp(query) {
- let q = 'scriptMenu'
- if (query) {
- q = query
- }
- openInTab(serverAdress + `manual?${q}`, {
- active: true,
- })
- }
-
- // : }}}
-
- // I am not too proud to cry that He and he
- // Will never never go out of my mind.
- // All his bones crying, and poor in all but pain,
-
- // Being innocent, he dreaded that he died
- // Hating his God, but what he was was plain:
- // An old kind man brave in his burning pride.
-
- // The sticks of the house were his; his books he owned.
- // Even as a baby he had never cried;
- // Nor did he now, save to his secret wound.
-
- // Out of his eyes I saw the last light glide.
- // Here among the liught of the lording sky
- // An old man is with me where I go
-
- // Walking in the meadows of his son's eye
- // Too proud to cry, too frail to check the tears,
- // And caught between two nights, blindness and death.
-
- // O deepest wound of all that he should die
- // On that darkest day.
})() // eslint-disable-line