diff --git a/devel/testWrapper.js b/devel/testWrapper.js index 016f6cd..7e54981 100644 --- a/devel/testWrapper.js +++ b/devel/testWrapper.js @@ -23,8 +23,7 @@ // @version DEVEL // @description Online Moodle/Elearning/KMOOC test help // @author Yout -// @match https://elearning.uni-obuda.hu/main/* -// @match https://elearning.uni-obuda.hu/kmooc/* +// @match https://elearning.uni-obuda.hu/* // @match https://qmining.frylabs.net/* // @match http://qmining.frylabs.net/* // @match file:///* diff --git a/stable.user.js b/stable.user.js index cc84c88..0299549 100755 --- a/stable.user.js +++ b/stable.user.js @@ -46,7 +46,7 @@ // : Script header {{{ // ==UserScript== // @name Moodle/Elearning/KMOOC test help -// @version 2.1.1.7 +// @version 2.1.2.0 // @description Online Moodle/Elearning/KMOOC test help // @author MrFry // @match https://elearning.uni-obuda.hu/* @@ -152,29 +152,6 @@ ? 'https://elearning.uni-obuda.hu/' : location.href - const menuButtons = { - website: { - title: 'Weboldal', - onClick: () => { - openInTab(serverAdress + 'menuClick') - }, - }, - help: { - title: 'GYIK', - onClick: () => { - ShowHelp() - }, - }, - donate: { - title: 'Donate', - onClick: () => { - openInTab(serverAdress + '?donate=true', { - active: true, - }) - }, - }, - } - // : Localisation {{{ const huTexts = { @@ -925,7 +902,7 @@ } }, }, - getDropdownAnswer: { + /* getDropdownAnswer: { description: 'Dropdown answer getter', requirement: (node) => { return false @@ -953,8 +930,8 @@ getterFunction: (node) => { // TODO dragboxes return 'asd' - }, - }, + }, + },*/ } function getIfSolutionIsCorrect(node) { @@ -1156,7 +1133,8 @@ if (elementUpdaterInterval === -1) { elementUpdaterInterval = setInterval(() => { updatableElements.forEach(({ elem, target }) => { - let { left, top, width, height } = target.getBoundingClientRect() + let { left, top } = target.getBoundingClientRect() + const { width, height } = target.getBoundingClientRect() left += window.scrollX top += window.scrollY @@ -1387,14 +1365,13 @@ ? '📭' : '📬' } - overlay.querySelector( '#infoMainDiv' ).innerText = `${subjInfo.subjects.toLocaleString( 'hu' )} tárgy, ${subjInfo.questions.toLocaleString( 'hu' - )} kérdés. User ID: ${getUid()}` + )} kérdés.\nUser ID: ${getUid()}` // FIXME: if cwith() throws an unhandled error it sais server is not avaible cwith() }) @@ -1761,7 +1738,7 @@ Array.from(messageNode.childNodes).forEach((node) => { if (node.tagName === 'A') { - const linkNode = document.createElement('span') + let linkNode = document.createElement('span') SetStyle(linkNode, { color: 'lightblue', textDecoration: 'underline', @@ -1807,365 +1784,292 @@ }) } - // shows a message with "msg" text, "matchPercent" tip and transp, and "timeout" time + function addMoveEventListener(elem) { + let isMouseDown = false + let offset = [0, 0] + let mousePosition + elem.addEventListener('mousedown', (e) => { + isMouseDown = true + offset = [elem.offsetLeft - e.clientX, elem.offsetTop - e.clientY] + }) + elem.addEventListener('mouseup', () => { + isMouseDown = false + }) + elem.addEventListener('mousemove', (e) => { + if (isMouseDown) { + mousePosition = { + x: e.clientX, + y: e.clientY, + } + elem.style.left = mousePosition.x + offset[0] + 'px' + elem.style.top = mousePosition.y + offset[1] + 'px' + } + }) + } + function ShowMessage(msgItem, timeout, funct) { - // msgItem help: - // [ [ {}{}{}{} ] [ {}{}{} ] ] - // msgItem[] <- a questions stuff - // msgItem[][] <- a questions relevant answers array - // msgItem[][].p <- a questions precent - // msgItem[][].m <- a questions message - try { - let defMargin = '0px 5px' - let isSimpleMessage = false - let simpleMessageText = '' - if (typeof msgItem === 'string') { - simpleMessageText = msgItem - if (simpleMessageText === '') { - // if msg is empty - return - } - msgItem = [ - [ - { - m: simpleMessageText, - }, - ], - ] - isSimpleMessage = true + let isSimpleMessage = false + let simpleMessageText = '' + const movingEnabled = !funct + if (typeof msgItem === 'string') { + simpleMessageText = msgItem + if (simpleMessageText === '') { + // if msg is empty + return } + msgItem = [ + [ + { + m: simpleMessageText, + }, + ], + ] + isSimpleMessage = true + } + // ------------------------------------------------------------------------- + const id = 'scriptMessage' + const messageElem = document.createElement('div') + messageElem.setAttribute('id', id) + addOpacityChangeEvent(messageElem) + let width = window.innerWidth - window.innerWidth / 6 // with of the box + if (width > 900) { + width = 900 + } + SetStyle(messageElem, { + position: 'fixed', + zIndex: 999999, + color: '#fff', + textAlign: 'center', + border: '2px solid #f2cb05', + borderRadius: '0px', + backgroundColor: '#222426', + top: '30px', + left: (window.innerWidth - width) / 2 + 'px', + width: width + 'px', + opacity: getVal(`${id}_opacity`), + cursor: funct ? 'pointer' : 'move', + }) + if (funct) { + addEventListener(messageElem, 'click', funct) + } + if (movingEnabled) { + addMoveEventListener(messageElem) + } + addEventListener(window, 'resize', function () { + messageElem.style.left = (window.innerWidth - width) / 2 + 'px' + }) - const appedtTo = overlay // will be appended here - const startFromTop = 25 // top distance - let width = window.innerWidth - window.innerWidth / 6 // with of the box + let timeOut + if (timeout && timeout > 0) { + timeOut = setTimeout(function () { + messageElem.parentNode.removeChild(messageElem) + }, timeout * 1000) + } - const mainDiv = document.createElement('div') // the main divider, wich items will be attached to - const id = 'scriptMessage' - mainDiv.setAttribute('id', id) - if (funct) { - addEventListener(mainDiv, 'click', funct) - } - // lotsa crap style - SetStyle(mainDiv, { - position: 'fixed', - zIndex: 999999, - textAlign: 'center', - width: width + 'px', - padding: '0px', - color: '#ffffff', - border: '2px solid #f2cb05', - borderRadius: '0px', - backgroundColor: '#222426', - top: startFromTop + 'px', - left: (window.innerWidth - width) / 2 + 'px', - opacity: getVal(`${id}_opacity`), - cursor: funct ? 'pointer' : 'move', - }) - - // ------------------------------------------------------------------ - // transparencity - // ------------------------------------------------------------------ - addOpacityChangeEvent(mainDiv) - // ------------------------------------------------------------------ - // moving msg - // ------------------------------------------------------------------ - const movingEnabled = !funct - let isMouseDown = false - let offset = [0, 0] - let mousePosition - if (movingEnabled) { - mainDiv.addEventListener('mousedown', (e) => { - isMouseDown = true - offset = [ - mainDiv.offsetLeft - e.clientX, - mainDiv.offsetTop - e.clientY, - ] - }) - mainDiv.addEventListener('mouseup', () => { - isMouseDown = false - }) - mainDiv.addEventListener('mousemove', (e) => { - if (isMouseDown) { - mousePosition = { - x: e.clientX, - y: e.clientY, - } - mainDiv.style.left = mousePosition.x + offset[0] + 'px' - mainDiv.style.top = mousePosition.y + offset[1] + 'px' - } - }) - } - - const xButton = CreateNodeWithText(null, '❌', 'div') - SetStyle(xButton, { - cursor: 'pointer', - position: 'absolute', - right: '0px', - display: 'inline', - margin: '3px', - }) - xButton.addEventListener('mousedown', (e) => { - e.stopPropagation() - mainDiv.parentNode.removeChild(mainDiv) - }) - - // ------------------------------------------------------------------ - var matchPercent = msgItem[0][0].p - if (isSimpleMessage) { - mainDiv.appendChild(xButton) - var simpleMessageParagrapg = document.createElement('p') // new paragraph - simpleMessageParagrapg.style.margin = defMargin // fancy margin - - const mesageNode = getConvertedMessageNode(simpleMessageText) - - simpleMessageParagrapg.appendChild(mesageNode) - mesageNode.addEventListener('mousedown', (e) => { - e.stopPropagation() - }) - SetStyle(mesageNode, { - margin: '10px 100px', - cursor: funct ? 'pointer' : 'auto', - }) - - Array.from(mesageNode.getElementsByTagName('a')).forEach( - (anchorElem) => { - anchorElem.style.color = 'lightblue' - } - ) - - mainDiv.appendChild(simpleMessageParagrapg) // adding text box to main div - } else { - const headerRow = document.createElement('div') - headerRow.setAttribute('id', 'msgHeader') - SetStyle(headerRow, { - height: '20px', - userSelect: 'none', - }) - mainDiv.appendChild(headerRow) - - const headerText = CreateNodeWithText(headerRow, '', 'div') - headerText.title = 'Talált kérdés tárgy neve' - SetStyle(headerText, { - padding: '2px 5px', - textAlign: 'center', - display: 'inline', - }) - - headerRow.appendChild(xButton) - // if its a fucking complicated message - // TABLE SETUP ------------------------------------------------------------------------------------------------------------ - var table = document.createElement('table') - table.style.width = '100%' - // ROWS ----------------------------------------------------------------------------------------------------- - var rowOne = table.insertRow() // previous suggestion, question text, and prev question - var rowTwo = table.insertRow() // next question button - var rowThree = table.insertRow() // next suggetsion button - // CELLS ----------------------------------------------------------------------------------------------------- - // row one - const sideCellWidth = 30 - var numberTextCell = rowOne.insertCell() - SetStyle(numberTextCell, { - width: sideCellWidth + 'px', - }) - var questionCell = rowOne.insertCell() // QUESTION CELL - questionCell.setAttribute('id', 'questionCell') - questionCell.rowSpan = 3 - var prevQuestionCell = rowOne.insertCell() - SetStyle(prevQuestionCell, { - width: sideCellWidth + 'px', - }) - // row two - var percentTextCell = rowTwo.insertCell() - SetStyle(percentTextCell, { - width: sideCellWidth + 'px', - }) - var nextQuestionCell = rowTwo.insertCell() - SetStyle(nextQuestionCell, { - width: sideCellWidth + 'px', - }) - // row three - var prevSuggestionCell = rowThree.insertCell() - var nextSuggestionCell = rowThree.insertCell() - // adding finally - mainDiv.appendChild(table) - // PERCENT TEXT SETUP ----------------------------------------------------------------------------------------------------- - var percentTextBox = CreateNodeWithText(percentTextCell, '') - percentTextBox.setAttribute('id', 'percentTextBox') - percentTextBox.title = 'Egyezés %' - - if (matchPercent) { - // if match percent param is not null - percentTextBox.innerText = matchPercent + '%' - } - // NUMBER SETUP ----------------------------------------------------------------------------------------------------- - var numberTextBox = CreateNodeWithText(numberTextCell, '1.') - numberTextBox.setAttribute('id', 'numberTextBox') - numberTextBox.title = 'Lehetséges válasz index' - - // ANSWER NODE SETUP ------------------------------------------------------------------------------------------------------------- - var questionTextElement = CreateNodeWithText( - questionCell, - 'ur question goes here, mister OwO' - ) - - questionTextElement.addEventListener('mousedown', (e) => { - e.stopPropagation() - }) - - SetStyle(questionTextElement, { - cursor: funct ? 'pointer' : 'auto', - }) - - questionTextElement.setAttribute('id', 'questionTextElement') - - // BUTTON SETUP ----------------------------------------------------------------------------------------------------------- - var currItem = 0 - var currRelevantQuestion = 0 - - const GetRelevantQuestion = () => { - // returns the currItemth questions currRelevantQuestionth relevant question - return msgItem[currItem][currRelevantQuestion] - } - - const ChangeCurrItemIndex = (to) => { - currItem += to - if (currItem < 0) { - currItem = 0 - } - if (currItem > msgItem.length - 1) { - currItem = msgItem.length - 1 - } - currRelevantQuestion = 0 - } - - const ChangeCurrRelevantQuestionIndex = (to) => { - currRelevantQuestion += to - if (currRelevantQuestion < 0) { - currRelevantQuestion = 0 - } - if (currRelevantQuestion > msgItem[currItem].length - 1) { - currRelevantQuestion = msgItem[currItem].length - 1 - } - } - - const SetQuestionText = () => { - const relevantQuestion = GetRelevantQuestion() - if (relevantQuestion.header) { - headerText.innerText = relevantQuestion.header - } - questionTextElement.innerText = relevantQuestion.m - - if (currItem === 0 && currRelevantQuestion === 0) { - numberTextBox.innerText = currRelevantQuestion + 1 + '.' - } else { - numberTextBox.innerText = - currItem + 1 + './' + (currRelevantQuestion + 1) + '.' - } - if (relevantQuestion.p) { - percentTextBox.innerText = relevantQuestion.p + '%' - } - } - - const buttonStyle = { - color: 'white', - backgroundColor: 'transparent', - margin: '2px', - border: 'none', - fontSize: '30px', - cursor: 'pointer', - userSelect: 'none', - } - if (msgItem[currItem].length > 1) { - // PREV SUGG BUTTON ------------------------------------------------------------------------------------------------------------ - var prevSuggButton = CreateNodeWithText( - prevSuggestionCell, - '⬅️', - 'div' - ) - prevSuggButton.title = 'Előző lehetséges válasz' - SetStyle(prevSuggButton, buttonStyle) - - prevSuggButton.addEventListener('mousedown', function (e) { - e.stopPropagation() - ChangeCurrRelevantQuestionIndex(-1) - SetQuestionText() - }) - // NEXT SUGG BUTTON ------------------------------------------------------------------------------------------------------------ - var nextSuggButton = CreateNodeWithText( - nextSuggestionCell, - '➡️', - 'div' - ) - nextSuggButton.title = 'Következő lehetséges válasz' - SetStyle(nextSuggButton, buttonStyle) - - nextSuggButton.addEventListener('mousedown', function (e) { - e.stopPropagation() - ChangeCurrRelevantQuestionIndex(1) - SetQuestionText() - }) - } - // deciding if has multiple questions ------------------------------------------------------------------------------------------------ - if (msgItem.length === 1) { - SetQuestionText() - } else { - // if there are multiple items to display - // PREV QUESTION BUTTON ------------------------------------------------------------------------------------------------------------ - var prevButton = CreateNodeWithText(prevQuestionCell, '⬆️', 'div') - SetStyle(prevButton, buttonStyle) - prevButton.title = 'Előző kérdés' - - // event listener - prevButton.addEventListener('click', function () { - ChangeCurrItemIndex(-1) - SetQuestionText() - }) - // NEXT QUESTION BUTTON ------------------------------------------------------------------------------------------------------------ - var nextButton = CreateNodeWithText(nextQuestionCell, '⬇️', 'div') - SetStyle(nextButton, buttonStyle) - nextButton.title = 'Előző kérdés' - - // event listener - nextButton.addEventListener('click', function () { - ChangeCurrItemIndex(1) - SetQuestionText() - }) - SetQuestionText() + addEventListener(messageElem, 'mousedown', function (e) { + if (e.which === 2) { + messageElem.parentNode.removeChild(messageElem) + if (timeOut) { + clearTimeout(timeOut) } } - appedtTo.appendChild(mainDiv) // THE FINAL APPEND + }) - // setting some events - // addEventListener(window, 'scroll', function () { - // mainDiv.style.top = (pageYOffset + startFromTop) + 'px'; - // }) - addEventListener(window, 'resize', function () { - mainDiv.style.left = (window.innerWidth - width) / 2 + 'px' - }) - var timeOut - if (timeout && timeout > 0) { - // setting timeout if not zero or null - timeOut = setTimeout(function () { - mainDiv.parentNode.removeChild(mainDiv) - }, timeout * 1000) - } - // middle click close event listener - addEventListener(mainDiv, 'mousedown', function (e) { - if (e.which === 2) { - mainDiv.parentNode.removeChild(mainDiv) - if (timeOut) { - clearTimeout(timeOut) - } - } - }) - return { - messageElement: mainDiv, - removeMessage: () => { - mainDiv.parentNode.removeChild(mainDiv) + let currQuestionIndex = 0 + let currPossibleAnswerIndex = 0 + const getCurrMsg = () => { + return msgItem[currQuestionIndex][currPossibleAnswerIndex] + } + + // ------------------------------------------------------------------------- + + const sidesWidth = '10%' + const arrowStyle = { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + fontSize: '22px', + userSelect: 'none', + flex: 1, + } + const infoTextStyle = { + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + flex: 1, + } + + const childrenTree = { + header: { + style: { + display: getCurrMsg().header ? '' : 'none', + padding: '5px 0px', }, + }, + msgContainer: { + style: { + display: 'flex', + width: '100%', + padding: '5px 0px', + }, + children: { + leftSideDiv: { + style: { + display: isSimpleMessage ? 'none' : 'flex', + flexFlow: 'column', + width: sidesWidth, + }, + children: { + questionIndex: { + title: 'Kérdés sorszáma / talált válasz sorszáma', + style: infoTextStyle, + }, + matchPercent: { + title: 'Talált kérdés egyezés', + style: infoTextStyle, + }, + prevPossible: { + title: 'Előző lehetséges válasz', + style: Object.assign( + { + cursor: 'pointer', + }, + arrowStyle + ), + innerText: msgItem[currQuestionIndex].length > 1 ? '⬅️' : '', + onClick: (e) => { + e.stopPropagation() + if (currPossibleAnswerIndex > 0) { + currPossibleAnswerIndex-- + updateMessageText() + } + }, + }, + }, + }, + msgDiv: { + style: { + flex: '1', + whiteSpace: 'pre-line', + cursor: funct ? 'pointer' : 'auto', + }, + }, + rightSideDiv: { + style: { + display: isSimpleMessage ? 'none' : 'flex', + flexFlow: 'column', + width: sidesWidth, + }, + children: { + prevQuestion: { + title: 'Előző kérdés', + style: Object.assign( + { + cursor: msgItem.length > 1 ? 'pointer' : '', + }, + arrowStyle + ), + innerText: msgItem.length > 1 ? '⬆️' : '', + onClick: (e) => { + if (msgItem.length > 1) { + e.stopPropagation() + if (currQuestionIndex > 0) { + currQuestionIndex-- + updateMessageText() + } + } + }, + }, + nextQuestion: { + title: 'Következő kérdés', + style: Object.assign( + { + cursor: msgItem.length > 1 ? 'pointer' : '', + }, + arrowStyle + ), + innerText: msgItem.length > 1 ? '⬇️' : '', + onClick: (e) => { + if (msgItem.length > 1) { + e.stopPropagation() + if (currQuestionIndex < msgItem.length - 1) { + currQuestionIndex++ + updateMessageText() + } + } + }, + }, + nextPossible: { + title: 'Következő lehetséges válasz', + style: Object.assign( + { + cursor: 'pointer', + }, + arrowStyle + ), + innerText: msgItem[currQuestionIndex].length > 1 ? '➡️' : '', + onClick: (e) => { + e.stopPropagation() + if ( + currPossibleAnswerIndex < + msgItem[currQuestionIndex].length - 1 + ) { + currPossibleAnswerIndex++ + updateMessageText() + } + }, + }, + }, + }, + }, + }, + } + + const result = {} + createHtml(childrenTree, messageElem, result) + + // ------------------------------------------------------------------------- + + result.msgContainer.child.msgDiv.elem.addEventListener('mousedown', (e) => { + e.stopPropagation() + }) + + const updateMessageText = () => { + try { + result.header.elem.innerText = getCurrMsg().header + result.msgContainer.child.msgDiv.elem.innerText = getCurrMsg().m + + if (msgItem.length !== 1 || msgItem[0].length !== 1) { + result.msgContainer.child.leftSideDiv.child.questionIndex.elem.innerText = + (currQuestionIndex + 1).toString() + + './' + + (currPossibleAnswerIndex + 1) + + '.' + } + + result.msgContainer.child.leftSideDiv.child.matchPercent.elem.innerText = isNaN( + getCurrMsg().p + ) + ? '' + : getCurrMsg().p + '%' + + result.msgContainer.child.msgDiv.elem.innerText = getCurrMsg().m + } catch (e) { + console.warn('Error in message updating') + console.warn(e) } - } catch (e) { - Exception(e, 'script error at showing message:') + } + updateMessageText() + + // ------------------------------------------------------------------------- + + overlay.appendChild(messageElem) + + return { + messageElement: messageElem, + removeMessage: () => { + messageElem.parentNode.removeChild(messageElem) + }, } } @@ -2180,6 +2084,7 @@ width: '300px', height: '90px', position: 'fixed', + padding: '3px 0px', bottom: '30px', left: '10px', zIndex: 999999, @@ -2197,62 +2102,6 @@ }) addOpacityChangeEvent(scriptMenuDiv) - // X button -------------------------------------------------------------------- - const xButton = CreateNodeWithText(scriptMenuDiv, '❌', 'div') - SetStyle(xButton, { - position: 'absolute', - display: 'inline', - right: '0px', - margin: '5px', - cursor: 'pointer', - fontSize: '18px', - }) - - xButton.addEventListener('mousedown', (e) => { - e.stopPropagation() - scriptMenuDiv.parentNode.removeChild(scriptMenuDiv) - }) - - // Mail button ----------------------------------------------------------------- - const mailButton = CreateNodeWithText(scriptMenuDiv, '📭', 'div') - mailButton.setAttribute('id', 'mailButton') - SetStyle(mailButton, { - position: 'absolute', - display: 'inline', - left: '0px', - bottom: '0px', - margin: '5px', - fontSize: '30px', - }) - - 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 - ) - }) - - // ----------------------------------------------------------------------------- - // BUTTONS - // ----------------------------------------------------------------------------- - const buttonContainer = document.createElement('div') - SetStyle(buttonContainer, { - display: 'flex', - justifyContent: 'center', - }) - - scriptMenuDiv.appendChild(buttonContainer) - const buttonStyle = { position: '', margin: '3px', @@ -2263,89 +2112,158 @@ cursor: 'pointer', } - Object.keys(menuButtons).forEach((key) => { - const buttonData = menuButtons[key] - const button = CreateNodeWithText( - buttonContainer, - buttonData.title, - 'div' - ) - SetStyle(button, buttonStyle) - if (buttonData.onClick) { - button.addEventListener('click', function () { - buttonData.onClick() - }) - } - }) - // ----------------------------------------------------------------------------- - // Info text - // ----------------------------------------------------------------------------- - const infoDiv = CreateNodeWithText(scriptMenuDiv, texts.loading, 'div') - infoDiv.setAttribute('id', 'infoMainDiv') - SetStyle(infoDiv, { - color: '#ffffff', - margin: '0px 50px', - textAlign: 'center', - }) - // ----------------------------------------------------------------------------- - // Login stuff (if user is not logged in) - // ----------------------------------------------------------------------------- - const loginContainer = document.createElement('div') - scriptMenuDiv.appendChild(loginContainer) - loginContainer.setAttribute('id', 'loginDiv') - SetStyle(loginContainer, { - display: 'none', - margin: '0px 50px', - }) + const childrenTree = { + xButton: { + innerText: '❌', + style: { + position: 'absolute', + display: 'inline', + right: '0px', + margin: '5px', + cursor: 'pointer', + fontSize: '18px', + }, + onClick: () => { + scriptMenuDiv.parentNode.removeChild(scriptMenuDiv) + }, + }, + mailButton: { + id: 'mailButton', + innerText: '📭', + style: { + position: 'absolute', + display: 'inline', + left: '5px', + bottom: '15px', + margin: '5px', + fontSize: '30px', + }, + onClick: () => { + if (userSpecificMotd && !userSpecificMotd.seen) { + SafeGetElementById('mailButton', (elem) => { + elem.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 + ) + }, + }, + buttonContainer: { + style: { + display: 'flex', + justifyContent: 'center', + }, + children: { + website: { + innerText: 'Weboldal', + style: buttonStyle, + onClick: () => { + openInTab(serverAdress + '?menuClick') + }, + }, + help: { + innerText: 'Help', + style: buttonStyle, + onClick: () => { + ShowHelp() + }, + }, + donate: { + innerText: 'Donate', + style: buttonStyle, + onClick: () => { + openInTab(serverAdress + 'donate?scriptMenu', { + active: true, + }) + }, + }, + }, + }, + infoContainer: { + id: 'infoMainDiv', + innerText: texts.loading, + style: { + color: '#ffffff', + margin: '5px 50px', + textAlign: 'center', + }, + }, + loginContainer: { + id: 'loginDiv', + style: { + display: 'none', + margin: '0px 50px', + }, + children: { + loginInput: { + customElem: () => { + const loginInput = document.createElement('input') + loginInput.setAttribute('id', 'pwInput') + loginInput.type = 'text' + loginInput.placeholder = texts.pwHere + SetStyle(loginInput, { + width: '100%', + textAlign: 'center', + }) + return loginInput + }, + }, + loginButton: { + innerText: texts.login, + style: buttonStyle, + onClick: () => { + SafeGetElementById('pwInput', (elem) => { + Auth(elem.value) + }) + }, + }, + }, + }, + retryContainer: { + id: 'retryContainer', + style: { + display: 'none', + justifyContent: 'center', + }, + children: { + retryButton: { + innerText: texts.retry, + style: { + position: '', + padding: '0px 8px', + border: '1px solid #333', + borderRadius: '2px', + color: '#ffffff', + cursor: 'pointer', + }, + onClick: () => { + scriptMenuDiv.style.background = '#262626' + SafeGetElementById('infoMainDiv', (elem) => { + elem.innerText = texts.loading + }) + SafeGetElementById('retryContainer', (elem) => { + elem.style.display = 'none' + }) + ConnectToServer(AfterLoad) + }, + }, + }, + }, + } - const loginInput = document.createElement('input') - loginContainer.appendChild(loginInput) - loginInput.type = 'text' - loginInput.placeholder = texts.pwHere - SetStyle(loginInput, { - width: '100%', - textAlign: 'center', - }) - - const loginButton = document.createElement('div') - loginContainer.appendChild(loginButton) - loginButton.innerText = texts.login - SetStyle(loginButton, buttonStyle) - loginButton.addEventListener('click', function () { - Auth(loginInput.value) - }) - - // ----------------------------------------------------------------------------- - // Retry connection button (if server is not available) - // ----------------------------------------------------------------------------- - const retryContainer = CreateNodeWithText(scriptMenuDiv, '', 'div') - SetStyle(retryContainer, { - display: 'hidden', - justifyContent: 'center', - }) - retryContainer.style.display = 'none' - retryContainer.setAttribute('id', 'retryContainer') - - const retryButton = CreateNodeWithText(retryContainer, texts.retry, 'div') - retryContainer.appendChild(retryButton) - SetStyle(retryButton, { - position: '', - padding: '0px 8px', - border: '1px solid #333', - borderRadius: '2px', - color: '#ffffff', - cursor: 'pointer', - }) - retryButton.addEventListener('click', function () { - scriptMenuDiv.style.background = '#262626' - infoDiv.innerText = texts.loading - retryContainer.style.display = 'none' - ConnectToServer(AfterLoad) - }) - - // APPEND EVERYTHING + const result = {} + createHtml(childrenTree, scriptMenuDiv, result) overlay.appendChild(scriptMenuDiv) } catch (e) { Exception(e, 'script error at showing menu:') @@ -2460,6 +2378,49 @@ }) } + function createHtml(children, appendTo, result) { + try { + Object.keys(children).forEach((key) => { + const currElem = children[key] + const elem = currElem.customElem + ? currElem.customElem() + : document.createElement('div') + appendTo.appendChild(elem) + result[key] = { + elem: elem, + child: {}, + } + + if (!currElem.customElem) { + if (currElem.id) { + elem.setAttribute('id', currElem.id) + } + if (currElem.title) { + elem.title = currElem.title + } + if (currElem.innerText) { + elem.innerText = currElem.innerText + } + if (currElem.onClick) { + elem.addEventListener('mousedown', (e) => { + currElem.onClick(e) + }) + } + if (currElem.style) { + SetStyle(elem, currElem.style) + } + } + + if (currElem.children) { + createHtml(currElem.children, elem, result[key].child) + } + }) + } catch (e) { + console.warn('Error in createHtml') + console.warn(e) + } + } + function CreateNodeWithText(to, text, type) { var paragraphElement = document.createElement(type || 'p') // new paragraph var textNode = document.createTextNode(text)