This commit is contained in:
yoannchb-pro
2023-06-19 22:08:27 -04:00
parent 88088c0acf
commit 47b239ae54
23 changed files with 432 additions and 432 deletions
+4
View File
@@ -1,5 +1,9 @@
# CHANGELOG
## v1.0.3
- Removed the option `table formating` because it will now set to true by default
## v1.0.2
- Added `mode`
+13 -6
View File
@@ -2,7 +2,7 @@
href="https://www.flaticon.com/free-icons/mortarboard" target="_blank" rel="noopener noreferrer"
title="Mortarboard icons created by itim2101 - Flaticon" ><img src="./extension/icon.png" alt="Mortarboard icons created by itim2101 - Flaticon" width="150" style="display:block; margin:auto;"></a></p>
# MoodleGPT v1.0.2
# MoodleGPT v1.0.3
This extension allows you to hide CHAT-GPT in a Moodle quiz. You just need to enter <b>the code configured in the extension</b> on the keyboard and then click on the question you want to solve, and CHAT-GPT will automatically provide the answer. However, one needs to be careful because as we know, CHAT-GPT can make errors especially in calculations.
@@ -12,7 +12,7 @@ I'm actually waiting for a review of my extension. It should be available in som
## Summary
- [MoodleGPT v1.0.2](#moodlegpt-v102)
- [MoodleGPT v1.0.3](#moodlegpt-v103)
- [Chrome Webstore](#chrome-webstore)
- [Summary](#summary)
- [Disclaimer !](#disclaimer-)
@@ -24,6 +24,8 @@ I'm actually waiting for a review of my extension. It should be available in som
- [Remove injection](#remove-injection)
- [Mode](#mode)
- [Settings](#settings)
- [Internal Features](#internal-features)
- [Support table](#support-table)
- [Supported questions type](#supported-questions-type)
- [Select](#select)
- [Put in order question](#put-in-order-question)
@@ -101,7 +103,14 @@ Type back the <b>code</b> on the keyboard and the code will be removed from the
- <b>Mouseover effect</b>: you will need to hover (or click for select) the question response to complete it automaticaly.
<br/> ![Mouseover](./assets/mouseover.gif)
<br/> ![Mouseover2](./assets/mouseover2.gif)
- <b>Table formatting</b>: format table from the question to make it more readable for CHAT-GPT but cost more tokens (so if the question is too large it will make an error). Example of formatted table:
- <b>Infinite try</b>: click as much as you want on the question (don't forget to reset the question).
## Internal Features
### Support table
Table are formated from the question to make it more readable for CHAT-GPT. Example of formatted table output:
```
| id | name | birthDate | cars |
@@ -110,8 +119,6 @@ Type back the <b>code</b> on the keyboard and the code will be removed from the
| Person 2 | Yann | 19/01/2000 | no |
```
- <b>Infinite try</b>: click as much as you want on the question (don't forget to reset the question).
## Supported questions type
### Select
@@ -154,4 +161,4 @@ To know if the answer has been copied to the clipboard, you can look at the titl
## Test
To test the code, you can run the index.html file located in the <b>"test"</b> folder. Or a better solution is to install moodle locally.
To test the code, you can run the index.html file located in the <b>"test/fake-moodle"</b> folder. Or a better solution is to install moodle locally.
+1
View File
@@ -4,6 +4,7 @@
- [ ] Fixe `normalizeText` (line break are sometimes removed for nothing e.g: checkbox)
- [ ] Support math equation from image stocked in the `data-mathml` attribute
- [ ] Increment question when there is statement
## Priority: 3 (because hard to make)
+15 -19
View File
@@ -61,7 +61,8 @@
*/
function normalizeText(text) {
return text
.replace(/(\n\s*)+/gi, "\n")
.replace(/\n+/gi, "\n")
.replace(/(\n\s*\n)+/g, "\n") //remove useless white sapce from textcontent
.replace(/[ \t]+/gi, " ")
.toLowerCase()
.trim()
@@ -124,8 +125,7 @@
const lineSeparationSize = maxColumnsLength.reduce((a, b) => a + b) + tab[0].length * 3 + 1;
const lineSeparation = "\n" + Array(lineSeparationSize).fill("-").join("") + "\n";
const mappedTab = tab.map((line) => {
const mappedLine = line.map((content, index) => content.padEnd(maxColumnsLength[index], "\u00A0") //for no matching with \s
);
const mappedLine = line.map((content, index) => content.padEnd(maxColumnsLength[index], "\u00A0" /* For no matching with \s */));
return "| " + mappedLine.join(" | ") + " |";
});
const head = mappedTab.shift();
@@ -138,14 +138,12 @@
* @param question
* @returns
*/
function normalizeQuestion(config, questionContainer) {
let question = questionContainer.textContent;
if (config.table) {
//make table more readable for chat-gpt
const tables = questionContainer.querySelectorAll(".qtext table");
for (const table of tables) {
question = question.replace(table.textContent, "\n" + htmlTableToString(table) + "\n");
}
function createQuestion(config, questionContainer) {
let question = questionContainer.innerText;
/* Make tables more readable for chat-gpt */
const tables = questionContainer.querySelectorAll(".qtext table");
for (const table of tables) {
question = question.replace(table.innerText, "\n" + htmlTableToString(table) + "\n");
}
const finalQuestion = `Give a short response as possible for this question, reply in the following question langage and only show the result:
${question}
@@ -202,7 +200,7 @@
for (const option of options) {
const content = normalizeText(option.textContent);
const valide = correct[j].includes(content);
//if it's a put in order
/* Handle put in order question */
if (!isNaN(parseInt(content))) {
const content = normalizeText(option.parentNode
.closest("tr")
@@ -225,7 +223,7 @@
break;
}
}
//end put in order
/* End */
if (config.logs)
Logs.responseTry(content, valide);
if (valide) {
@@ -337,7 +335,7 @@
return;
event.preventDefault();
input.textContent = response.slice(0, ++index);
//put the cursor at the end
/* Put the cursor at the end of the typed text */
input.focus();
const range = document.createRange();
range.selectNodeContents(input);
@@ -362,12 +360,10 @@
* @returns
*/
function reply(config, hiddenButton, form, query) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
if (config.cursor)
hiddenButton.style.cursor = "wait";
(_a = form.querySelector(".accesshide")) === null || _a === void 0 ? void 0 : _a.remove();
const question = normalizeQuestion(config, form);
const question = createQuestion(config, form);
const inputList = form.querySelectorAll(query);
const response = yield getChatGPTResponse(config, question).catch((error) => ({
error,
@@ -436,7 +432,7 @@
* @returns
*/
function setUpMoodleGpt(config) {
//removing events
/* Removing events */
if (listeners.length > 0) {
for (const listener of listeners) {
if (config.cursor)
@@ -448,7 +444,7 @@
listeners.length = 0;
return;
}
//injection
/* Code injection */
const inputQuery = ["checkbox", "radio", "text", "number"]
.map((e) => `input[type="${e}"]`)
.join(",");
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -1,9 +1,9 @@
{
"manifest_version": 3,
"name": "MoodleGPT",
"version": "1.0.2",
"version": "1.0.3",
"description": "Hidden chat-gpt for your moodle quiz",
"permissions": ["activeTab", "tabs", "storage"],
"permissions": ["storage"],
"action": {
"default_icon": "icon.png",
"default_popup": "./popup/index.html"
-4
View File
@@ -79,10 +79,6 @@
<input id="mouseover" type="checkbox" />
<label for="mouseover">Mouseover effect</label>
</div>
<div class="line">
<input id="table" type="checkbox" checked />
<label for="table">Table formatting</label>
</div>
<div class="line">
<input id="infinite" type="checkbox" />
<label for="infinite">Infinite try</label>
+1 -3
View File
@@ -10,7 +10,6 @@ const inputsCheckbox = [
"typing",
"mouseover",
"infinite",
"table",
"timeout",
];
@@ -73,7 +72,7 @@ saveBtn.addEventListener("click", function () {
const [apiKey, code, model] = inputsText.map((selector) =>
document.querySelector("#" + selector).value.trim()
);
const [logs, title, cursor, typing, mouseover, infinite, table, timeout] =
const [logs, title, cursor, typing, mouseover, infinite, timeout] =
inputsCheckbox.map((selector) => {
const element = document.querySelector("#" + selector);
return element.checked && element.parentElement.style.display !== "none";
@@ -100,7 +99,6 @@ saveBtn.addEventListener("click", function () {
typing,
mouseover,
infinite,
table,
timeout,
mode: actualMode,
},
+1 -1
View File
@@ -1,4 +1,4 @@
const currentVersion = "1.0.2";
const currentVersion = "1.0.3";
const versionDisplay = document.querySelector("#version");
/**
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "moodlegpt",
"version": "1.0.2",
"version": "1.0.3",
"description": "This extension allows you to hide CHAT-GPT in a Moodle quiz.",
"scripts": {
"build": "rollup -c"
+2 -2
View File
@@ -29,7 +29,7 @@ function codeListener(config: Config) {
* @returns
*/
function setUpMoodleGpt(config: Config) {
//removing events
/* Removing events */
if (listeners.length > 0) {
for (const listener of listeners) {
if (config.cursor) listener.element.style.cursor = "initial";
@@ -40,7 +40,7 @@ function setUpMoodleGpt(config: Config) {
return;
}
//injection
/* Code injection */
const inputQuery = ["checkbox", "radio", "text", "number"]
.map((e) => `input[type="${e}"]`)
.join(",");
@@ -1,32 +1,30 @@
import Config from "../types/config";
import normalizeText from "../utils/normalize-text";
import htmlTableToString from "../utils/html-table-to-string";
/**
* Normalize the question and add sub informations
* @param langage
* @param question
* @returns
*/
function normalizeQuestion(config: Config, questionContainer: HTMLElement) {
let question = questionContainer.textContent;
if (config.table) {
//make table more readable for chat-gpt
const tables: NodeListOf<HTMLTableElement> =
questionContainer.querySelectorAll(".qtext table");
for (const table of tables) {
question = question.replace(
table.textContent,
"\n" + htmlTableToString(table) + "\n"
);
}
}
const finalQuestion = `Give a short response as possible for this question, reply in the following question langage and only show the result:
${question}
(If you have to choose between multiple results only show the corrects one, separate them with new line and take the same text as the question)`;
return normalizeText(finalQuestion);
}
export default normalizeQuestion;
import Config from "../types/config";
import normalizeText from "../utils/normalize-text";
import htmlTableToString from "../utils/html-table-to-string";
/**
* Normalize the question and add sub informations
* @param langage
* @param question
* @returns
*/
function createQuestion(config: Config, questionContainer: HTMLElement) {
let question = questionContainer.innerText;
/* Make tables more readable for chat-gpt */
const tables: NodeListOf<HTMLTableElement> =
questionContainer.querySelectorAll(".qtext table");
for (const table of tables) {
question = question.replace(
table.innerText,
"\n" + htmlTableToString(table) + "\n"
);
}
const finalQuestion = `Give a short response as possible for this question, reply in the following question langage and only show the result:
${question}
(If you have to choose between multiple results only show the corrects one, separate them with new line and take the same text as the question)`;
return normalizeText(finalQuestion);
}
export default createQuestion;
+1 -1
View File
@@ -21,7 +21,7 @@ function handleContentEditable(
event.preventDefault();
input.textContent = response.slice(0, ++index);
//put the cursor at the end
/* Put the cursor at the end of the typed text */
input.focus();
const range = document.createRange();
range.selectNodeContents(input);
+2 -2
View File
@@ -29,7 +29,7 @@ function handleSelect(
const content = normalizeText(option.textContent);
const valide = correct[j].includes(content);
//if it's a put in order
/* Handle put in order question */
if (!isNaN(parseInt(content))) {
const content = normalizeText(
(option.parentNode as HTMLElement)
@@ -56,7 +56,7 @@ function handleSelect(
break;
}
}
//end put in order
/* End */
if (config.logs) Logs.responseTry(content, valide);
+2 -4
View File
@@ -1,7 +1,7 @@
import Config from "../types/config";
import Logs from "../utils/logs";
import getChatGPTResponse from "./get-response";
import normalizeQuestion from "./normalize-question";
import createQuestion from "./create-question";
import handleRadioAndCheckbox from "./questions/radio-checkbox";
import handleSelect from "./questions/select";
import handleTextbox from "./questions/textbox";
@@ -25,9 +25,7 @@ async function reply(
) {
if (config.cursor) hiddenButton.style.cursor = "wait";
form.querySelector(".accesshide")?.remove();
const question = normalizeQuestion(config, form);
const question = createQuestion(config, form);
const inputList: NodeListOf<HTMLElement> = form.querySelectorAll(query);
const response = await getChatGPTResponse(config, question).catch(
-1
View File
@@ -8,7 +8,6 @@ type Config = {
cursor?: boolean;
logs?: boolean;
title?: boolean;
table?: boolean;
timeout?: boolean;
mode?: "autocomplete" | "question-to-answer" | "clipboard";
};
+5 -2
View File
@@ -26,8 +26,11 @@ function htmlTableToString(table: HTMLTableElement) {
"\n" + Array(lineSeparationSize).fill("-").join("") + "\n";
const mappedTab = tab.map((line) => {
const mappedLine = line.map(
(content, index) => content.padEnd(maxColumnsLength[index], "\u00A0") //for no matching with \s
const mappedLine = line.map((content, index) =>
content.padEnd(
maxColumnsLength[index],
"\u00A0" /* For no matching with \s */
)
);
return "| " + mappedLine.join(" | ") + " |";
});
+2 -1
View File
@@ -4,7 +4,8 @@
*/
function normalizeText(text: string) {
return text
.replace(/(\n\s*)+/gi, "\n")
.replace(/\n+/gi, "\n")
.replace(/(\n\s*\n)+/g, "\n") //remove useless white sapce from textcontent
.replace(/[ \t]+/gi, " ")
.toLowerCase()
.trim()
@@ -1,67 +1,67 @@
@font-face {
font-family: Segeo UI;
src: url(../../extension/fonts/Segoe\ UI.ttf);
}
* {
box-sizing: border-box;
padding: 0;
margin: 0;
font-family: "Segeo UI";
}
body {
display: flex;
align-items: center;
flex-direction: column;
padding: 1rem;
gap: 1rem;
}
h1 {
text-align: center;
}
.formulation {
width: 60%;
background-color: #e7f3f5;
padding: 1.5rem;
display: flex;
flex-direction: column;
gap: 1rem;
}
.inp {
margin-top: 0.5rem;
display: flex;
gap: 0.5rem;
align-items: center;
position: relative;
}
select {
position: absolute;
right: 0;
}
.editable {
background-color: #fff;
height: 10rem;
width: 100%;
resize: vertical;
overflow-y: auto;
white-space: pre-wrap;
padding: 0.5rem;
outline: none;
border: thin solid #000;
}
textarea {
outline: none;
padding: 0.5rem;
height: 10rem;
width: 100%;
resize: vertical;
white-space: pre-wrap;
overflow-y: auto;
}
@font-face {
font-family: Segeo UI;
src: url(../../../extension/fonts/Segoe\ UI.ttf);
}
* {
box-sizing: border-box;
padding: 0;
margin: 0;
font-family: "Segeo UI";
}
body {
display: flex;
align-items: center;
flex-direction: column;
padding: 1rem;
gap: 1rem;
}
h1 {
text-align: center;
}
.formulation {
width: 60%;
background-color: #e7f3f5;
padding: 1.5rem;
display: flex;
flex-direction: column;
gap: 1rem;
}
.inp {
margin-top: 0.5rem;
display: flex;
gap: 0.5rem;
align-items: center;
position: relative;
}
select {
position: absolute;
right: 0;
}
.editable {
background-color: #fff;
height: 10rem;
width: 100%;
resize: vertical;
overflow-y: auto;
white-space: pre-wrap;
padding: 0.5rem;
outline: none;
border: thin solid #000;
}
textarea {
outline: none;
padding: 0.5rem;
height: 10rem;
width: 100%;
resize: vertical;
white-space: pre-wrap;
overflow-y: auto;
}
+261 -261
View File
@@ -1,261 +1,261 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Moodle test</title>
<link rel="stylesheet" href="./css/style.css" />
</head>
<body>
<!-- checkbox -->
<section class="formulation">
<div class="qtext">
<p>Which words are animals ?</p>
</div>
<div>
<div class="inp">
<input type="checkbox" />
<label>a. Cat</label>
</div>
<div class="inp">
<input type="checkbox" />
<label>b. Dog</label>
</div>
<div class="inp">
<input type="checkbox" />
<label>c. Computer</label>
</div>
</div>
</section>
<!-- Radio -->
<section class="formulation">
<div class="qtext">
<p>What is the french president name ?</p>
</div>
<div>
<div class="inp">
<input type="radio" />
<label>Emmanuel Macron</label>
</div>
<div class="inp">
<input type="radio" />
<label>Jean Macron</label>
</div>
<div class="inp">
<input type="radio" />
<label>Yves Macron</label>
</div>
</div>
</section>
<!-- True or false -->
<section class="formulation">
<div class="qtext">
<p>The cat sometimes drink milk?</p>
</div>
<div>
<div class="inp">
<input type="radio" />
<label>True</label>
</div>
<div class="inp">
<input type="radio" />
<label>False</label>
</div>
</div>
</section>
<!-- Number -->
<section class="formulation">
<div class="qtext">
<p>What is the result of 17/20</p>
</div>
<div>
<input type="number" />
</div>
</section>
<!-- Select -->
<section class="formulation">
<div class="qtext">
<p>Choose the correct answer</p>
</div>
<div>
<div class="inp">
<table>
<tr>
<td class="text">
<p>I am a feline</p>
</td>
<td>
<select>
<option>Choose...</option>
<option>Cat</option>
<option>Dog</option>
<option>Cow</option>
</select>
</td>
</tr>
<tr>
<td class="text">
<p>I am a descendant of the wolf</p>
</td>
<td>
<select>
<option>Choose...</option>
<option>Cat</option>
<option>Dog</option>
<option>Cow</option>
</select>
</td>
</tr>
<tr>
<td class="text"><p>I produce milk</p></td>
<td>
<select>
<option>Choose...</option>
<option>Cat</option>
<option>Dog</option>
<option>Cow</option>
</select>
</td>
</tr>
</table>
</div>
</div>
</section>
<!-- Select Number -->
<section class="formulation">
<div class="qtext">
<p>
Put the three steps needed in a general sense for a computer program
to solve the problem in the correct order
</p>
</div>
<div>
<div class="inp">
<table>
<tr>
<td class="text">
<p>Understand the problem</p>
</td>
<td>
<select>
<option>Choose...</option>
<option>1</option>
<option>2</option>
<option>3</option>
</select>
</td>
</tr>
<tr>
<td class="text">
<p>Carry out the plan and write the actual code</p>
</td>
<td>
<select>
<option>Choose...</option>
<option>1</option>
<option>2</option>
<option>3</option>
</select>
</td>
</tr>
<tr>
<td class="text">
<p>Create a step-by-step plan for how you'll solve it</p>
</td>
<td>
<select>
<option>Choose...</option>
<option>1</option>
<option>2</option>
<option>3</option>
</select>
</td>
</tr>
</table>
</div>
</div>
</section>
<!-- Select Calc -->
<section class="formulation">
<div class="qtext">
<p>Solve those equations:</p>
</div>
<div>
<div class="inp">
<table>
<tr>
<td class="text">
<p>1. 5*5</p>
</td>
<td>
<select>
<option>Choose...</option>
<option>10</option>
<option>20</option>
<option>25</option>
</select>
</td>
</tr>
<tr>
<td class="text">
<p>2. 20 - 10</p>
</td>
<td>
<select>
<option>Choose...</option>
<option>10</option>
<option>20</option>
<option>25</option>
</select>
</td>
</tr>
<tr>
<td class="text"><p>3. 10+10</p></td>
<td>
<select>
<option>Choose...</option>
<option>10</option>
<option>20</option>
<option>25</option>
</select>
</td>
</tr>
</table>
</div>
</div>
</section>
<!-- Text -->
<section class="formulation">
<div class="qtext">
<p>Give me five diferences between a dog and a cat</p>
</div>
<div>
<textarea></textarea>
</div>
</section>
<!-- Clipboard -->
<section class="formulation">
<div class="qtext">
<p>
Gives a "reverseWorld" function in javascript which takes as a
parameter a word and flips it in the opposite direction
</p>
</div>
<div>
<div contenteditable="true" class="editable"></div>
</div>
</section>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Moodle test</title>
<link rel="stylesheet" href="./css/style.css" />
</head>
<body>
<!-- checkbox -->
<section class="formulation">
<div class="qtext">
<p>Which words are animals ?</p>
</div>
<div>
<div class="inp">
<input type="checkbox" />
<label>a. Cat</label>
</div>
<div class="inp">
<input type="checkbox" />
<label>b. Dog</label>
</div>
<div class="inp">
<input type="checkbox" />
<label>c. Computer</label>
</div>
</div>
</section>
<!-- Radio -->
<section class="formulation">
<div class="qtext">
<p>What is the french president name ?</p>
</div>
<div>
<div class="inp">
<input type="radio" />
<label>Emmanuel Macron</label>
</div>
<div class="inp">
<input type="radio" />
<label>Jean Macron</label>
</div>
<div class="inp">
<input type="radio" />
<label>Yves Macron</label>
</div>
</div>
</section>
<!-- True or false -->
<section class="formulation">
<div class="qtext">
<p>The cat sometimes drink milk?</p>
</div>
<div>
<div class="inp">
<input type="radio" />
<label>True</label>
</div>
<div class="inp">
<input type="radio" />
<label>False</label>
</div>
</div>
</section>
<!-- Number -->
<section class="formulation">
<div class="qtext">
<p>What is the result of 17/20</p>
</div>
<div>
<input type="number" />
</div>
</section>
<!-- Select -->
<section class="formulation">
<div class="qtext">
<p>Choose the correct answer</p>
</div>
<div>
<div class="inp">
<table>
<tr>
<td class="text">
<p>I am a feline</p>
</td>
<td>
<select>
<option>Choose...</option>
<option>Cat</option>
<option>Dog</option>
<option>Cow</option>
</select>
</td>
</tr>
<tr>
<td class="text">
<p>I am a descendant of the wolf</p>
</td>
<td>
<select>
<option>Choose...</option>
<option>Cat</option>
<option>Dog</option>
<option>Cow</option>
</select>
</td>
</tr>
<tr>
<td class="text"><p>I produce milk</p></td>
<td>
<select>
<option>Choose...</option>
<option>Cat</option>
<option>Dog</option>
<option>Cow</option>
</select>
</td>
</tr>
</table>
</div>
</div>
</section>
<!-- Select Number -->
<section class="formulation">
<div class="qtext">
<p>
Put the three steps needed in a general sense for a computer program
to solve the problem in the correct order
</p>
</div>
<div>
<div class="inp">
<table>
<tr>
<td class="text">
<p>Understand the problem</p>
</td>
<td>
<select>
<option>Choose...</option>
<option>1</option>
<option>2</option>
<option>3</option>
</select>
</td>
</tr>
<tr>
<td class="text">
<p>Carry out the plan and write the actual code</p>
</td>
<td>
<select>
<option>Choose...</option>
<option>1</option>
<option>2</option>
<option>3</option>
</select>
</td>
</tr>
<tr>
<td class="text">
<p>Create a step-by-step plan for how you'll solve it</p>
</td>
<td>
<select>
<option>Choose...</option>
<option>1</option>
<option>2</option>
<option>3</option>
</select>
</td>
</tr>
</table>
</div>
</div>
</section>
<!-- Select Calc -->
<section class="formulation">
<div class="qtext">
<p>Solve those equations:</p>
</div>
<div>
<div class="inp">
<table>
<tr>
<td class="text">
<p>1. 5*5</p>
</td>
<td>
<select>
<option>Choose...</option>
<option>10</option>
<option>20</option>
<option>25</option>
</select>
</td>
</tr>
<tr>
<td class="text">
<p>2. 20 - 10</p>
</td>
<td>
<select>
<option>Choose...</option>
<option>10</option>
<option>20</option>
<option>25</option>
</select>
</td>
</tr>
<tr>
<td class="text"><p>3. 10+10</p></td>
<td>
<select>
<option>Choose...</option>
<option>10</option>
<option>20</option>
<option>25</option>
</select>
</td>
</tr>
</table>
</div>
</div>
</section>
<!-- Text -->
<section class="formulation">
<div class="qtext">
<p>Give me five diferences between a dog and a cat</p>
</div>
<div>
<textarea></textarea>
</div>
</section>
<!-- Clipboard -->
<section class="formulation">
<div class="qtext">
<p>
Gives a "reverseWorld" function in javascript which takes as a
parameter a word and flips it in the opposite direction
</p>
</div>
<div>
<div contenteditable="true" class="editable"></div>
</div>
</section>
</body>
</html>
@@ -1,22 +1,21 @@
//to try in real moodle env
for (const option of document.querySelectorAll("option")) {
option.selected = false;
option.disabled = false;
option.closest("select").disabled = false;
}
for (const input of document.querySelectorAll(
'input[type="radio"], input[type="checkbox"]'
)) {
input.checked = false;
input.disabled = false;
}
for (const icon of document.querySelectorAll(".text-danger, .text-success")) {
icon.remove();
}
for (const feedback of document.querySelectorAll(".specificfeedback")) {
feedback.remove();
}
/* Reset real moodle inputs to try in real env */
for (const option of document.querySelectorAll("option")) {
option.selected = false;
option.disabled = false;
option.closest("select").disabled = false;
}
for (const input of document.querySelectorAll(
'input[type="radio"], input[type="checkbox"]'
)) {
input.checked = false;
input.disabled = false;
}
for (const icon of document.querySelectorAll(".text-danger, .text-success")) {
icon.remove();
}
for (const feedback of document.querySelectorAll(".specificfeedback")) {
feedback.remove();
}

Before

Width:  |  Height:  |  Size: 166 KiB

After

Width:  |  Height:  |  Size: 166 KiB

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB