NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Innovación en material docente con Web Aumentada // @namespace http://tampermonkey.net/ // @version 4.0 // @description Script de web aumentada para la visualización de material docente // @author Paula Gonzalez Martinez // @match *://*/* // @license GPL-3.0-or-later // @grant none // ==/UserScript== (function() { 'use strict'; const currentURL = window.location.href; // Crear un overlayDiv para activar la división de pantalla const overlayDiv = document.createElement("div"); overlayDiv.className = "overlayDiv"; overlayDiv.style.fontFamily = "Arial"; overlayDiv.style.position = "fixed"; overlayDiv.style.bottom = "0"; overlayDiv.style.left = "0"; overlayDiv.style.width = "100%"; overlayDiv.style.height = "50px"; overlayDiv.style.backgroundColor = "rgba(237, 106, 90, 0.9)"; overlayDiv.style.color = "white"; overlayDiv.style.zIndex = "9999"; overlayDiv.style.display = "flex"; overlayDiv.style.alignItems = "center"; overlayDiv.style.justifyContent = "center"; overlayDiv.style.cursor = "pointer"; overlayDiv.innerHTML = `Haz click <b><u> aquí </u></b> para dividir la pantalla`; overlayDiv.addEventListener("click", divideScreen); // Añadir el overlayDiv al inicio del body document.body.insertBefore(overlayDiv, document.body.firstChild); // Controlador function divideScreen() { if (currentURL.includes("online-python.com")) { divideForOnlinePython(); } else { divideForGeneral(); } } // ------------------------------------------------------------------------------------------- // Funciones genericas // Dividir pantalla function divideForGeneral() { // Estilos generales const style = document.createElement("style"); applyStylesForGeneral(style); document.head.appendChild(style); const container = document.createElement("div"); container.className = "container"; const leftDiv = document.createElement("div"); leftDiv.className = "left-div"; while (document.body.firstChild) { leftDiv.appendChild(document.body.firstChild); } const rightDiv = document.createElement("div"); rightDiv.className = "right-div"; const restoreButton = document.createElement("button"); restoreButton.className = "restore-button"; restoreButton.textContent = "Cerrar"; restoreButton.addEventListener("mouseover", function() { restoreButton.style.backgroundColor = "#b71c1c"; }); restoreButton.addEventListener("mouseout", function() { restoreButton.style.backgroundColor = "#f44336"; }); restoreButton.addEventListener("click", function() { // Restaurar el contenido original del body while (leftDiv.firstChild) { document.body.appendChild(leftDiv.firstChild); } // Borrar el contenedor y restaurar el overlayDiv container.remove(); overlayDiv.style.display = "flex"; document.body.insertBefore(overlayDiv, document.body.firstChild); }); // Agregar el botón al rightDiv rightDiv.appendChild(restoreButton); // Agregar leftDiv y rightDiv al contenedor container.appendChild(leftDiv); container.appendChild(rightDiv); // Agregar el contenedor al body document.body.appendChild(container); // Ocultar el overlayDiv overlayDiv.style.display = "none"; setContentForGeneral(rightDiv); // Establecer y agregar los contenidos } // Establecer contenidos de la materia function setContentForGeneral(location){ const content = { units: [ { title: "Unidad 1 (Ejemplo)", sections: [ { sectionTitle: "Introducción", paragraph: `En este apartado se especifica el contenido de la sección 1. Puede poner texto en <b>negrita</b> para destacar las palabras clave, texto en <i>cursiva</i>, también puede <u>subrayar</u> palabras o cualquier etiqueta HTML que se desee.`, paragraphSummary: `Aquí puede introducir el resumen o las aclaraciones <b>más importantes</b> de la teoría...`, images: ["https://via.placeholder.com/150"] }, { sectionTitle: "Otra sección", paragraph: `Puede añadir tantas secciones como sea necesario. Si no es necesario, no es obligatorio poner un resumen ni una imagen.`, paragraphSummary: ``, images: [] } ], activities: [ { activity: "Este es un ejemplo de enunciado para una actividad relacionada con la teoría de esta unidad.", solution: "Se puede especificar también." }, { activity: "Otro ejemplo, en este caso sin indicar la solución.", solution: "" } ] }, { title: "Unidad 2 (Ejemplo)", sections: [ { sectionTitle: "Otra unidad", paragraph: `Introducir el contenido...`, paragraphSummary: `Resumen...`, images: [] } ], activities: [] } ] }; addContentForGeneral(location, content) } // Incorporar contenidos de la materia function addContentForGeneral(parent, content) { var contentDiv = document.createElement("div"); contentDiv.className = "content-div"; content.units.forEach((unit) => { // Titulo const title = document.createElement("h1"); title.className = "title"; title.textContent = unit.title; contentDiv.appendChild(title); // Secciones unit.sections.forEach((section, index) => { const sectionTitle = document.createElement('h2'); sectionTitle.className = "section-title"; sectionTitle.textContent = `${index + 1}. ${section.sectionTitle}`; contentDiv.appendChild(sectionTitle); const paragraph = document.createElement("p"); paragraph.className = "section-paragraph"; paragraph.innerHTML = section.paragraph; contentDiv.appendChild(paragraph); const paragraphSummary = document.createElement("p"); paragraphSummary.className = "section-paragraph-summary"; paragraphSummary.innerHTML = section.paragraphSummary; if(paragraphSummary.innerHTML != ""){ contentDiv.appendChild(paragraphSummary); } // Añadir imágenes de la sección section.images.forEach((imgSrc, imgIndex) => { const image = document.createElement("img"); image.className = "section-image"; image.src = imgSrc; image.alt = `Imagen ${imgIndex + 1} de la sección ${index + 1}`; contentDiv.appendChild(image); }); }); // Enunciados const activitiesDiv = document.createElement("div"); activitiesDiv.classList.add("activities-div"); activitiesDiv.className = "activity"; unit.activities.forEach((sentenceObj, index) => { const sentence = document.createElement('p'); sentence.className = "activity-sentence"; sentence.textContent = `Ejercicio ${index + 1}: ${sentenceObj.activity}`; const solution = document.createElement('p'); solution.className = "activity-solution"; solution.textContent = `Solución: ${sentenceObj.solution}`; activitiesDiv.appendChild(sentence); activitiesDiv.appendChild(solution); }); // Añadir los elementos creados al contenedor principal contentDiv.appendChild(activitiesDiv); }); parent.appendChild(contentDiv); } // Aplicar estilos a los elementos basados en su className function applyStylesForGeneral(styles) { styles.innerHTML = ` .container { font-family: Arial; color: #000000; display: flex; width: 100vw; height: 100vh; position: fixed; top: 0; left: 0; z-index: 9998; overflow: hidden; } .left-div { width: 50%; height: 100%; overflow: auto; position: relative; z-index: 10000; } .right-div { width: 50%; height: 100%; background-color: #f4f4f4; overflow: auto; position: relative; z-index: 10000; } .restore-button { position: absolute; top: 10px; right: 10px; z-index: 10001; // Asegura que esté encima de otros restoreButtonos en rightDiv display: inline-block; text-align: center; font-weight: 700; font-size: 15px; color: #ffffff; padding: 10px 20px; width: auto; border: none; border-radius: 5px; background-color: #f44336; box-shadow: none; cursor: pointer; transition: background-color 0.3s; } .content-div { font-family: Arial; color: #000000; margin: 45px; display: flex; flex-direction: column; border: none; } .title { color: #0747a1; font-size: 30px; font-weight: 700; text-align: center; margin: 20px auto 5px auto; padding: 0; border: 0; } .section-title { color: green; font-size: 22.5px; font-weight: 700; margin: 20px 0 0 0; border: 0; } .section-paragraph { color: black; font-size: 15px; text-align: justify; line-height: 30px; margin: 20px 0 0 0; } .section-paragraph-summary { color: #000000; font-size: 15px; font-style: italic; text-align: justify; line-height: 30px; margin: 5px 0 10px 0; padding: 5px 10px; background-color: thistle; border-radius: 5px; border: 1px solid #ccc; } .section-image { display: block; margin: 0 auto 20px auto; max-width: 70%; } .activity-sentence { color: darkred; font-size: 1em; font-weight: bold; } .activity-solution { color: darkgreen; font-size: 1em; } `; } // ------------------------------------------------------------------------------------------- // Funcion especifica let actualLevel = "1"; let activitiesActualLevel = []; let activityIndex = 0; let currentActivities = []; function divideForOnlinePython() { //FOP // Estilos específicos para online-python.com const style = document.createElement("style"); applyStylesForOnlinePython(style); document.head.appendChild(style); const leftDiv = document.createElement("div"); leftDiv.className = "left-div-fop"; // Mover el contenido original al leftDiv while (document.body.firstChild) { leftDiv.appendChild(document.body.firstChild); } const rightDiv = document.createElement("div"); rightDiv.className = "right-div-fop"; const restoreButton = document.createElement("button"); restoreButton.className = "restore-button-fop"; restoreButton.textContent = "Cerrar"; restoreButton.addEventListener("mouseover", function() { restoreButton.style.backgroundColor = "#b71c1c"; }); restoreButton.addEventListener("mouseout", function() { restoreButton.style.backgroundColor = "#f44336"; }); restoreButton.addEventListener("click", function() { // Restaurar el contenido original del body while (leftDiv.firstChild) { document.body.appendChild(leftDiv.firstChild); } // Borrar el contenedor y restaurar el overlayDiv leftDiv.remove(); rightDiv.remove(); overlayDiv.style.display = "flex"; document.body.insertBefore(overlayDiv, document.body.firstChild); }); // Agregar el botón al rightDiv rightDiv.appendChild(restoreButton); // Crear botones para los diferentes apartados const container = document.createElement("div"); container.className = "buttons-fop"; const options = ["Teoría", "Funciones", "Ejercicios"]; options.forEach(option => { const buttonOption = document.createElement("button"); buttonOption.className = "button-option-fop"; buttonOption.innerText = option; buttonOption.addEventListener("click", function() { // Mostrar un contenido u otro setContentForOnlinePython(option, rightDiv); }); container.appendChild(buttonOption); }); rightDiv.appendChild(container); // Indicaciones para empezar const help = document.createElement("div"); help.id = "starting-help"; const span = document.createElement("span"); span.textContent = "Selecciona un botón para empezar..."; help.appendChild(span); rightDiv.appendChild(help); // Añadir los panes al body document.body.appendChild(leftDiv); document.body.appendChild(rightDiv); // Ocultar el overlayDiv overlayDiv.style.display = "none"; } // Inicializar valores a mostrar en OnlinePython function deleteOldValues(option, parent, className){ if(document.getElementById("starting-help")){ document.getElementById("starting-help").remove(); } var buttons = Array.from(parent.getElementsByClassName("button-option-fop")); buttons.forEach(function(button) { button.classList.remove("button-selected-fop"); }); buttons.forEach(function(buttonSelected) { if(buttonSelected.textContent == option){ buttonSelected.classList.add("button-selected-fop"); } }); if(parent.getElementsByClassName(className).length > 0){ var elements = Array.from(parent.getElementsByClassName(className)); // Iterar sobre el array de elementos y eliminar cada uno elements.forEach(function(element) { element.parentNode.removeChild(element); }); } } // Mostrar contenido function addContentForOnlinePython(option, parent, content) { var contentDiv = document.createElement("div"); contentDiv.className = "content-div-fop"; switch(option){ case "Teoría": // Inicializacion deleteOldValues(option, parent, contentDiv.className); content.units.forEach((unit) => { // Titulo const title = document.createElement("h1"); title.className = "title-fop"; title.textContent = unit.title; contentDiv.appendChild(title); // Secciones unit.sections.forEach((section, index) => { const sectionTitle = document.createElement('h2'); sectionTitle.className = "section-title-fop"; sectionTitle.textContent = `${index + 1}. ${section.sectionTitle}`; contentDiv.appendChild(sectionTitle); const paragraph = document.createElement("p"); paragraph.className = "section-paragraph-fop"; paragraph.innerHTML = section.paragraph; contentDiv.appendChild(paragraph); const paragraphSummary = document.createElement("p"); paragraphSummary.className = "section-paragraph-summary-fop"; paragraphSummary.innerHTML = section.paragraphSummary; if(paragraphSummary.innerHTML != ""){ contentDiv.appendChild(paragraphSummary); } // Añadir imágenes de la sección section.images.forEach((imgSrc, imgIndex) => { const image = document.createElement("img"); image.className = "section-image-fop"; image.src = imgSrc; image.alt = `Imagen ${imgIndex + 1} de la sección ${index + 1}`; contentDiv.appendChild(image); }); }); }); parent.appendChild(contentDiv); break; case "Funciones": // Inicializacion deleteOldValues(option, parent, contentDiv.className); content.units.forEach((unit) => { // Titulo const title = document.createElement("h1"); title.className = "title-fop"; title.textContent = unit.title; contentDiv.appendChild(title); // Secciones unit.list.forEach((element) => { const sectionTitle = document.createElement('h2'); sectionTitle.className = "section-title-fop"; sectionTitle.textContent = element.type; contentDiv.appendChild(sectionTitle); const paragraph = document.createElement("p"); paragraph.className = "section-paragraph-fop"; paragraph.innerHTML = element.description; contentDiv.appendChild(paragraph); element.functionList.forEach((functionX) => { const x = document.createElement("span"); x.className = "function-fop"; x.innerHTML = functionX.function; contentDiv.appendChild(x); }); }); }); parent.appendChild(contentDiv); break; case "Ejercicios": // Inicializacion deleteOldValues(option, parent, "content-div-fop"); content.units.forEach(unit => { const title = document.createElement("h1"); title.className = "title-fop"; title.textContent = unit.title; contentDiv.appendChild(title); actualLevel = "1"; currentActivities = unit.activities; activitiesActualLevel = filterActivitiesByLevel(currentActivities, actualLevel); activityIndex = 0; const activityTitle = document.createElement("h2"); activityTitle.className = "section-title-fop"; activityTitle.id = "activity-title"; activityTitle.innerText = activitiesActualLevel[activityIndex].title; contentDiv.appendChild(activityTitle); const activitySentence = document.createElement("p"); activitySentence.id = "activity-text"; activitySentence.innerText = activitiesActualLevel[activityIndex].text; contentDiv.appendChild(activitySentence); const message = document.createElement("p"); message.id = "message-text"; contentDiv.appendChild(message); const previousNextButtons = document.createElement("div"); previousNextButtons.className = "previous-next-buttons"; const upDownButtons = document.createElement("div"); upDownButtons.className = "up-down-buttons"; const previous = document.createElement("button"); previous.id = "button-previous"; previous.innerText = "Anterior"; previous.onclick = function() { changeActivity(-1); }; previousNextButtons.appendChild(previous); const next = document.createElement("button"); next.id = "button-next"; next.innerText = "Siguiente"; next.onclick = function() { changeActivity(1); }; previousNextButtons.appendChild(next); const upLevel = document.createElement("button"); upLevel.id = "button-up"; upLevel.innerText = "Subir de nivel"; upLevel.onclick = function() { changeLevel(1); }; upDownButtons.appendChild(upLevel); const downLevel = document.createElement("button"); downLevel.id = "button-down"; downLevel.innerText = "Repasar nivel anterior"; downLevel.onclick = function() { changeLevel(-1); }; upDownButtons.appendChild(downLevel); contentDiv.appendChild(previousNextButtons); contentDiv.appendChild(upDownButtons); updateActivityButtons(); }); parent.appendChild(contentDiv); break; } } function filterActivitiesByLevel(activities, level) { return activities.filter(activity => activity.difficulty === level); } function changeActivity(direction) { activityIndex += direction; if (activityIndex < 0) { activityIndex = 0; } else if (activityIndex >= activitiesActualLevel.length) { activityIndex = activitiesActualLevel.length - 1; } document.getElementById("activity-title").innerText = activitiesActualLevel[activityIndex].title; document.getElementById("activity-text").innerText = activitiesActualLevel[activityIndex].text; document.getElementById("message-text").innerText = ""; // Limpiar mensaje updateActivityButtons(); } function changeLevel(direction) { const levels = ["1", "2", "3"]; let levelIndex = levels.indexOf(actualLevel) + direction; if (levelIndex < 0) { document.getElementById("message-text").innerText = "No hay ejercicios anteriores. Si continúas con dificultades consulta la teoría o pregúntale a tu profesor o profesora. ¡Ánimo!"; } else if (levelIndex >= levels.length) { document.getElementById("message-text").innerText = "Has llegado a lo más alto!!!"; } else { actualLevel = levels[levelIndex]; activityIndex = 0; // Resetear al primer ejercicio del nuevo nivel activitiesActualLevel = filterActivitiesByLevel(currentActivities, actualLevel); if (activitiesActualLevel.length > 0) { document.getElementById("activity-title").innerText = activitiesActualLevel[activityIndex].title; document.getElementById("activity-text").innerText = activitiesActualLevel[activityIndex].text; } else { document.getElementById("activity-title").innerText = "No hay actividades para este nivel."; document.getElementById("activity-text").innerText = ""; } document.getElementById("message-text").innerText = ""; // Limpiar mensaje updateActivityButtons(); } } function updateActivityButtons() { const previous = document.getElementById("button-previous"); const next = document.getElementById("button-next"); if (previous) { previous.disabled = activityIndex === 0; } if (next) { next.disabled = activityIndex === activitiesActualLevel.length - 1; } } function setContentForOnlinePython(option, location){ var content = ""; switch(option){ case "Teoría": content = { units: [ { title: "Unidad 1 (Ejemplo)", sections: [ { sectionTitle: "Introducción", paragraph: `En este apartado se especifica el contenido de la sección 1. Puede poner texto en <b>negrita</b> para destacar las palabras clave, texto en <i>cursiva</i>, también puede <u>subrayar</u> palabras o cualquier etiqueta HTML que se desee.`, paragraphSummary: `Aquí puede introducir el resumen o las aclaraciones <b>más importantes</b> de la teoría...`, images: ["https://via.placeholder.com/150"] }, { sectionTitle: "Otra sección", paragraph: `Puede añadir tantas secciones como sea necesario. Si no es necesario, no es obligatorio poner un resumen ni una imagen.`, paragraphSummary: ``, images: [] } ] }, { title: "Unidad 2 (Ejemplo)", sections: [ { sectionTitle: "Otra unidad", paragraph: `Introducir el contenido...`, paragraphSummary: `Resumen...`, images: [] } ] } ] }; break; case "Funciones": content = { units: [ { title: "Programación estructurada", list: [ { type: "Funciones matemáticas", description: ` Funciones para realizar operaciones matemáticas más complejas que la suma, resta, multiplicación, división, resto y porcentajes. <br> <b>¡Ojo!</b> Al principio del programa hay que añadir: <i>import math</i> para poder utilizar estas funciones. `, functionList: [ { function: `math.sqrt(x) // Raíz cuadrada <br> math.pow(x, y) // x elevado a y ` }, { function: `math.sen(x) // Seno <br> math.cos(x) // Coseno <br> math.tan(x) // Tangente ` }, { function: `math.exp(x) // Exponencial de x <br> math.log(x) // Logaritmo neperiano <br> math.log10(x) // Logaritmo en base 10 ` } ] }, { type: "Pedir datos a la persona usuaria", description: ` Función para pedir datos al usuario desde la terminal. `, functionList: [ { function: ` print("Introduce tu nombre: ") <br> nombre = <b>input()</b> <br> print("Hola ", nombre) ` }, { function: ` nombre = input("Introduce tu nombre: ") // Método abreviado<br> print("Hola ", nombre) ` } ] } ] } ] } break; case "Ejercicios": content = { units: [ { title: "Nombre de la unidad", activities: [ { title: "Ejercicio 1.1", text: "Enunciado del ejercicio...", difficulty: "1" }, { title: "Ejercicio 1.2", text: "Enunciado del ejercicio...", difficulty: "1" }, { title: "Ejercicio 1.3", text: "Enunciado del ejercicio...", difficulty: "1" }, { title: "Ejercicio 2.1", text: "Enunciado del ejercicio...", difficulty: "2" }, { title: "Ejercicio 2.2", text: "Enunciado del ejercicio...", difficulty: "2" }, { title: "Ejercicio 2.3", text: "Enunciado del ejercicio...", difficulty: "2" }, { title: "Ejercicio 3.1", text: "Enunciado del ejercicio...", difficulty: "3" }, { title: "Ejercicio 3.2", text: "Enunciado del ejercicio...", difficulty: "3" }, { title: "Ejercicio 3.3", text: "Enunciado del ejercicio...", difficulty: "3" } ] } ] }; break; } addContentForOnlinePython(option, location, content); } // Aplicar estilos de OnlinePython function applyStylesForOnlinePython(styles){ styles.innerHTML = ` body { display: flex; margin: 0; padding: 0; overflow: hidden; } #sidebar-right-ad, #sidebar-left-ad { display: none; } #starting-help>span { display: flex; justify-content: space-around; align-items: center; font-size: 30px; margin: 300px auto auto auto; } .left-div-fop { width: 50%; float: left; box-sizing: border-box; height: 100vh; overflow-y: auto; padding-right: 10px; } .right-div-fop { width: 50%; float: left; box-sizing: border-box; padding: 10px; height: 100vh; overflow-y: auto; border-left: 2px solid #ccc; } .right-div-fop textarea { width: 100%; height: calc(100vh - 20px); box-sizing: border-box; resize: none; } .restore-button-fop { position: absolute; top: 10px; right: 10px; z-index: 10001; display: inline-block; text-align: center; font-weight: 700; font-size: 15px; color: #ffffff; padding: 10px 20px; width: auto; border: none; border-radius: 5px; background-color: #f44336; box-shadow: none; cursor: pointer; } .button-option-fop { position: static; margin: 0 0 0 5px; display: inline-block; text-align: center; font-weight: 700; font-size: 15px; color: #ffffff; padding: 10px 20px; width: auto; border: none; border-radius: 5px; background-color: #4a9ae9; box-shadow: none; cursor: pointer; } .button-selected-fop { background-color: #0747a1; } .content-div-fop { font-family: Arial; color: #000000; margin: 45px; display: flex; flex-direction: column; border: none; } .title-fop { color: #0747a1; font-size: 30px; font-weight: 700; text-align: center; margin: 20px auto 5px auto; padding: 0; border: 0; } .section-title-fop { color: green; font-size: 22.5px; font-weight: 700; margin: 20px 0 0 0; border: 0; } .section-paragraph-fop { color: black; font-size: 15px; text-align: justify; line-height: 30px; margin: 20px 0 0 0; } .section-paragraph-summary-fop { color: #000000; font-size: 15px; font-style: italic; text-align: justify; line-height: 30px; margin: 5px 0 10px 0; padding: 5px 10px; background-color: thistle; border-radius: 5px; border: 1px solid #ccc; } .section-image-fop { display: block; margin: 0 auto 20px auto; max-width: 70%; } .activity-sentence-fop { color: darkred; font-size: 1em; font-weight: bold; } .activity-solution-fop { color: darkgreen; font-size: 1em; } span.function-fop { background-color: thistle; font-family: 'Courier New', Courier, monospace; color: #333; padding: 5px 10px; margin: 10px 0; border-radius: 3px; border: 1px solid #ccc; display: inline-block; } #message-text { color: darkred; font-size: 1em; font-weight: bold; } .previous-next-buttons { display: flex; flex-direction: row; margin: 20px 0 40px 0; } .up-down-buttons { display: flex; flex-direction: column; margin: 0 110px; } #button-up{ background-color: #558b2f; } #button-down{ background-color: #ef6c00; } .up-down-buttons>button { position: static; display: inline-block; text-align: center; font-weight: 700; font-size: 15px; color: #ffffff; padding: 10px 20px; width: auto; border: none; border-radius: 5px; background-color: #4a9ae9; box-shadow: none; cursor: pointer; margin: 0 0 10px 0; } #button-previous{ position: static; margin: 0; display: inline-block; text-align: center; font-weight: 700; font-size: 15px; color: #ffffff; padding: 10px 20px; width: auto; border: none; border-radius: 5px; background-color: darkslategray; box-shadow: none; cursor: pointer; } #button-next{ position: absolute; right: 55px; display: inline-block; text-align: center; font-weight: 700; font-size: 15px; color: #ffffff; padding: 10px 20px; width: auto; border: none; border-radius: 5px; background-color: darkslategray; box-shadow: none; cursor: pointer; } p#activity-text { margin: 20px 0; height: 300px; background-color: #dcedc8; padding: 15px; border-radius: 5px; color: #000000; font-size: 16px; text-align: justify; line-height: 30px; } `; } })();