This repository has been archived on 2023-04-02. You can view files and clone it, but cannot push or open issues or pull requests.
Stairway-js/res/js/main.js

160 lines
5.6 KiB
JavaScript
Raw Normal View History

2021-05-30 05:29:24 +00:00
/*
* Stairway.js: a simple JavaScript privacy quiz
* Copyright © 2021 luca0N!
*
* This file is part of Stairway.js.
*
* Stairway.js is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Stairway.js is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Stairway.js. If not, see <https://www.gnu.org/licenses/>.
*
* E-mail contact: <luca0n@luca0n.com>.
*/
/*
* 2021-05-27
* by luca0N! <https://www.luca0n.com>
*/
2021-05-30 19:05:58 +00:00
let quiz, quizEl, mappedIds = [];
2021-05-30 05:42:35 +00:00
2021-05-30 05:29:24 +00:00
// Attach setUpStrings() to onReady() in order to execute the main code as soon as possible. This overwrites onReady().
onReady = setUpStrings;
/**
* Replaces dummy strings with localized messages.
* @since 2021-05-27
*/
function setUpStrings(){
// Hide JavaScript warning message.
document.getElementById('javascript-warning').style['display'] = 'none';
let warning = document.getElementById('warning');
warning.style['display'] = 'unset';
// Get JSON file which contains all of the challenges required.
sendGetRequest('privacy-quiz.en.json', function(text){
2021-05-30 19:05:58 +00:00
quiz = JSON.parse(text);
2021-05-30 05:29:24 +00:00
// Set up UI elements based on quiz metadata.
let quizTitle = document.getElementById('quiz-title');
quizTitle.innerText = quiz.title;
quizTitle.style['display'] = 'unset';
let quizAuthor = document.getElementById('quiz-author');
quizAuthor.innerText = quiz.publisher;
quizAuthor.style['display'] = 'unset';
let contents = quiz.contents;
2021-05-30 05:42:35 +00:00
quizEl = document.getElementById('quiz'); // quiz div element.
2021-05-30 05:29:24 +00:00
for (let x = 0; x < contents.length; x++){
//console.log(contents[x].title);
let itemDiv = document.createElement('div');
itemDiv.className = 'section-question';
let itemTitle = document.createElement('p');
itemTitle.innerText = contents[x].title;
itemTitle.className = 'question';
itemDiv.appendChild(itemTitle);
2021-05-30 18:52:40 +00:00
mappedIds[x] = [];
2021-05-30 05:29:24 +00:00
if (contents[x].type === 'multiple' || contents[x].type === 'single'){
// Generate a checkbox for each choice.
for (let y = 0; y < contents[x].choices.length; y++){
2021-05-30 18:52:40 +00:00
if (contents[x].choices.length != contents[x].ids.length){
2021-05-30 05:29:24 +00:00
console.error('Unable to add choice #' + (y + 1) + ' for question #' + (x + 1) + ': ' +
2021-05-30 18:52:40 +00:00
contents[x].choices.length > contents[x].ids.length ? 'missing ID(s)' : 'extra ID(s) found');
2021-05-30 05:29:24 +00:00
continue;
}
let questionInput = document.createElement('input');
questionInput.type = contents[x].type === 'multiple' ? 'checkbox' : 'radio';
if (contents[x].type === 'single')
questionInput.name = 'sec.' + x + '.chg'; // choice group
let currentId = 'sec.' + x + '.ch.' + y; // section, choice
questionInput.id = currentId;
let questionLabel = document.createElement('label');
questionLabel.htmlFor = currentId;
questionLabel.innerText = contents[x].choices[y];
2021-05-30 18:52:40 +00:00
mappedIds[x][y] = contents[x].ids[y];
2021-05-30 05:29:24 +00:00
itemDiv.append(questionInput);
itemDiv.append(questionLabel);
if (y < contents[x].choices.length)
itemDiv.append(document.createElement('br')); // Add a line break if this is not the last question.
}
if (contents[x].type === 'single'){
// This is a 'single' choice type question.
// Add a button that clears the current question selection.
let questionClear = document.createElement('button');
questionClear.innerText = 'Clear';
questionClear.onclick = function() {
for (let y = 0; y < contents[x].choices.length; y++) // Iterate through all input tags.
document.getElementById('sec.' + x + '.ch.' + y).checked = false; // Uncheck it.
}
itemDiv.append(questionClear); // Append the button to the item dit.
}
} else console.warn('Warning: unknown type "' + contents[x].type + '" for question #' + (x + 1));
2021-05-30 05:42:35 +00:00
quizEl.appendChild(itemDiv);
2021-05-30 05:29:24 +00:00
}
// Add the finish button.
let finish = document.createElement('button');
finish.innerText = 'Finish!';
finish.onclick = function(){
2021-05-30 19:05:58 +00:00
// Calculate the results.
let score = 0;
// Retrieve choices.
let contents = quiz.contents;
let choices = [];
for (let x = 0; x < contents.length; x++){
choices[x] = [];
for (let y = 0; y < contents[x].choices.length; y++){
let currentEl = document.getElementById('sec.' + x + '.ch.' + y); // current choice element
// Is it checked?
if (currentEl.checked){
// Get the ID
2021-05-30 19:31:16 +00:00
choices[x].push(mappedIds[x][y]);
2021-05-30 19:05:58 +00:00
score += quiz.reports[mappedIds[x][y]].points;
}
}
}
2021-05-30 19:31:16 +00:00
// Calculate the grade
let grade;
if (score > quiz.threshold['a.min'])
grade = 's';
else if (score > quiz.threshold['b.min'])
grade = 'a'
else if (score > quiz.threshold['c.min'])
grade = 'b'
else if (score > quiz.threshold['d.min'])
grade = 'c'
else if (score > quiz.threshold['e.min'])
grade = 'd'
else if (score > quiz.threshold['b.min'])
grade = 'e';
else grade = 'f';
// Display the grade X badge element (unset its 'none' display value)
document.getElementById('badge-' + grade).style['display'] = 'unset';
2021-05-30 05:42:35 +00:00
// Hide quiz and then show the results.
quizEl.style['display'] = 'none';
document.getElementById('results').style['display'] = 'unset';
2021-05-30 05:29:24 +00:00
}
2021-05-30 05:42:35 +00:00
quizEl.appendChild(finish);
2021-05-30 05:29:24 +00:00
warning.style['display'] = 'none';
});
}