From b2064cbbaf7e11ed4ddd616d1579a3bf952d2099 Mon Sep 17 00:00:00 2001 From: Herwin Bozet Date: Sat, 1 Mar 2025 18:27:13 +0100 Subject: [PATCH] Nearly finished the Excel Password Remover revamp, Only the download is missing Update commons.yml, excel-password-remover.yml, and 14 more files... --- data/strings/en/commons.yml | 3 + data/strings/en/excel-password-remover.yml | 68 ++-- data/strings/fr/commons.yml | 3 + data/strings/fr/excel-password-remover.yml | 58 ++-- scripts/compile-js-site.cmd | 8 + .../excel-password-remover.mjs | 290 ++++++++++++++++-- .../NibblePoker/js/nibblepoker-template.mjs | 12 +- .../NibblePoker/js/nibblepoker-ui.mjs | 3 +- static/resources/Standalone/.gitignore | 1 + .../applets/excel-password-remover.jinja | 89 +++++- templates/base_standalone.jinja | 17 +- templates/base_www.jinja | 12 +- templates/elements/button.jinja | 2 +- templates/elements/file-input.jinja | 5 +- website/renderers/button.py | 6 +- website/renderers/file_input.py | 3 +- 16 files changed, 465 insertions(+), 115 deletions(-) create mode 100644 static/resources/Standalone/.gitignore diff --git a/data/strings/en/commons.yml b/data/strings/en/commons.yml index 4de43f1..be21547 100644 --- a/data/strings/en/commons.yml +++ b/data/strings/en/commons.yml @@ -52,6 +52,9 @@ source.code: "Source code" download.single: "Download" download.multiple: "Downloads" +download.action.all: "Download All" + +clear.all.files: "Clear all file(s)" github: "GitHub Repository" gitea: "Self-hosted Gitea Repository" diff --git a/data/strings/en/excel-password-remover.yml b/data/strings/en/excel-password-remover.yml index eb2ebc6..f9cefda 100644 --- a/data/strings/en/excel-password-remover.yml +++ b/data/strings/en/excel-password-remover.yml @@ -5,36 +5,36 @@ meta.description: >- Small web page from which you can easily remove a password from an Excel worksheet. It works by leaving the task of editing the XML files on an Excel document to your browser instead to keep everything local. -article.subtitle: >- - View on GitHub -intro.title: Introduction -intro.p1: >- - This project aims to simplify the removal of passwords on Excel's Worksheet by - leaving the task of editing the XML files on an Excel document to your - browser. -working.title: Security & Internal workings -working.p1: >- - In terms of security, your browser handles all the data without sending any of - it to a central server like many web apps do.
This makes it, and your data, - as safe as your browser can be since it is the only potential point of failure - here. -working.p2: >- - As for the internal workings, the only thing this tool does is extract the - content of the .xlsx file you gave it and removes the passwords - on any worksheets and makes a new file with all the changes.
Once all of - that is done, the file is downloaded via a data - URL. -usage.title: Usage -usage.p1: >- - To use this tool you can either visit "aziascreations.github.io/Excel-Worksheet-Password-Remover" - or download the repository and host the web page yourself. -demo.title: Demonstration video -links.title: Links -content.link.demo: Demo hosted on GitHub +#article.subtitle: >- +# View on GitHub +#intro.title: Introduction +#intro.p1: >- +# This project aims to simplify the removal of passwords on Excel's Worksheet by +# leaving the task of editing the XML files on an Excel document to your +# browser. +#working.title: Security & Internal workings +#working.p1: >- +# In terms of security, your browser handles all the data without sending any of +# it to a central server like many web apps do.
This makes it, and your data, +# as safe as your browser can be since it is the only potential point of failure +# here. +#working.p2: >- +# As for the internal workings, the only thing this tool does is extract the +# content of the .xlsx file you gave it and removes the passwords +# on any worksheets and makes a new file with all the changes.
Once all of +# that is done, the file is downloaded via a data +# URL. +#usage.title: Usage +#usage.p1: >- +# To use this tool you can either visit "aziascreations.github.io/Excel-Worksheet-Password-Remover" +# or download the repository and host the web page yourself. +#demo.title: Demonstration video +#links.title: Links +#content.link.demo: Demo hosted on GitHub eula.1: "This tool should only be used with files you have the express permission to unlock." @@ -44,3 +44,11 @@ eula.3: "By using this tool, you accept full responsibility, and that it is prov file.selection.title: "File Selection" file.selection.1: "Drop your excel file(s) here or click on the buttons." + +details.title : "Result(s)" +details.empty.1 : "Your Excel files with their password removed will end up here." + +result.success.count: "Removed ??? password(s)" +result.warning.extension: "The file doesn't appear to be an Excel Worksheet !" +result.warning.password: "The Excel Worksheet didn't contain any password !" +result.error.jszip: "JSZip was unable to open the file !" diff --git a/data/strings/fr/commons.yml b/data/strings/fr/commons.yml index 1c4c8ff..93a5777 100644 --- a/data/strings/fr/commons.yml +++ b/data/strings/fr/commons.yml @@ -52,6 +52,9 @@ source.code: "Code source" download.single: "Téléchargement" download.multiple: "Téléchargements" +download.action.all: "Tout télécharger" + +clear.all.files: "Retirer fichier(s)" github: "Dépôt GitHub" gitea: "Dépôt Gitea auto-hébergé" diff --git a/data/strings/fr/excel-password-remover.yml b/data/strings/fr/excel-password-remover.yml index bd0db2f..1a7d663 100644 --- a/data/strings/fr/excel-password-remover.yml +++ b/data/strings/fr/excel-password-remover.yml @@ -6,31 +6,31 @@ meta.description: >- feuille de calcul Excel depuis votre navigateur web sans avoir à uploader le fichier sur internet. Cette application laisse votre navigateur modifier les fichiers XML du fichier Excel afin de tout garder en local. -article.subtitle: >- - Voir sur GitHub -intro.title: Introduction -intro.p1: >- - Ce projet vise à simplifier le processus de suppression des mots de passes sur - les "worksheet" d'Excel en laissant votre navigateur web s'en charger. -working.title: Sécurité & Fonctionnement -working.p1: >- - Cet outil charge le ficher que vous lui donnez en mémoire et travaille - directement dessus dans le navigateur web sans utiliser un serveur central, - vos données restent donc entièrement sur votre machine. -working.p2: >- - Par sécurité, nous vous demandons quand même de n'utiliser cet outil qu'avec - des fichiers pour lesquels vous avez été explicitement autorisés à enlever le - mot de passe. -usage.title: Utilisation -usage.p1: >- - Vous pouvez utiliser cet outil en allant sur "aziascreations.github.io/Excel-Worksheet-Password-Remover" - ou en téléchargeant le dépôt et en hébergeant la page web vous-même. -demo.title: Vidéo de démonstration -links.title: Liens -content.link.demo: Démo hébergée sur GitHub +#article.subtitle: >- +# Voir sur GitHub +#intro.title: Introduction +#intro.p1: >- +# Ce projet vise à simplifier le processus de suppression des mots de passes sur +# les "worksheet" d'Excel en laissant votre navigateur web s'en charger. +#working.title: Sécurité & Fonctionnement +#working.p1: >- +# Cet outil charge le ficher que vous lui donnez en mémoire et travaille +# directement dessus dans le navigateur web sans utiliser un serveur central, +# vos données restent donc entièrement sur votre machine. +#working.p2: >- +# Par sécurité, nous vous demandons quand même de n'utiliser cet outil qu'avec +# des fichiers pour lesquels vous avez été explicitement autorisés à enlever le +# mot de passe. +#usage.title: Utilisation +#usage.p1: >- +# Vous pouvez utiliser cet outil en allant sur "aziascreations.github.io/Excel-Worksheet-Password-Remover" +# ou en téléchargeant le dépôt et en hébergeant la page web vous-même. +#demo.title: Vidéo de démonstration +#links.title: Liens +#content.link.demo: Démo hébergée sur GitHub eula.1 : "Cet outil ne doit être utilisé qu'avec des fichiers pour lesquels vous avez l'autorisation de les déverrouiller." eula.2 : "Toute suppression de mot de passe se fait localement dans votre navigateur, et aucune donnée n'est envoyée via Internet.
@@ -39,3 +39,11 @@ eula.3 : "En utilisant cet outil, vous acceptez l'entière responsabilité de vo file.selection.title : "Sélection de fichier(s)" file.selection.1 : "Déposez vos fichiers Excel ici ou cliquez sur les boutons." + +details.title: "Résultat(s)" +details.empty.1 : "Vos fichiers Excel sans leurs mots de passe finiront ici." + +result.success.count: "Mot de passe(s) supprimé(s) : ???" +result.warning.extension: "Le fichier ne semble pas être une feuille de calcul Excel !" +result.warning.password: "La feuille de calcul Excel ne contenait aucun mot de passe !" +result.error.jszip: "JSZip n'a pas pu ouvrir le fichier !" diff --git a/scripts/compile-js-site.cmd b/scripts/compile-js-site.cmd index 3634b9b..cbfa938 100644 --- a/scripts/compile-js-site.cmd +++ b/scripts/compile-js-site.cmd @@ -22,6 +22,10 @@ echo ^> static\resources\NibblePoker\js\nibblepoker-code.mjs call "%~dp0node_modules\.bin\rollup" nibblepoker-code.mjs --file nibblepoker-code.js call "%~dp0node_modules\.bin\terser" nibblepoker-code.js -c -m -o nibblepoker-code.min.js +echo ^> static\resources\NibblePoker\js\nibblepoker-core.mjs +call "%~dp0node_modules\.bin\rollup" nibblepoker-core.mjs --file nibblepoker-core.js +call "%~dp0node_modules\.bin\terser" nibblepoker-core.js -c -m -o nibblepoker-core.min.js + echo ^> static\resources\NibblePoker\js\nibblepoker-contributors.mjs call "%~dp0node_modules\.bin\rollup" nibblepoker-contributors.mjs --file nibblepoker-contributors.js call "%~dp0node_modules\.bin\terser" nibblepoker-contributors.js -c -m -o nibblepoker-contributors.min.js @@ -33,6 +37,10 @@ call "%~dp0node_modules\.bin\terser" nibblepoker-debug.js -c -m -o nibblepoker-d echo ^> static\resources\NibblePoker\js\nibblepoker-splide.js call "%~dp0node_modules\.bin\rollup" nibblepoker-splide.mjs --file nibblepoker-splide.js call "%~dp0node_modules\.bin\terser" nibblepoker-splide.js -c -m -o nibblepoker-splide.min.js + +echo ^> static\resources\NibblePoker\js\nibblepoker-template.mjs +call "%~dp0node_modules\.bin\rollup" nibblepoker-template.mjs --file nibblepoker-template.js +call "%~dp0node_modules\.bin\terser" nibblepoker-template.js -c -m -o nibblepoker-template.min.js popd diff --git a/static/resources/NibblePoker/applets/excel-password-remover/excel-password-remover.mjs b/static/resources/NibblePoker/applets/excel-password-remover/excel-password-remover.mjs index fe61752..2728e61 100644 --- a/static/resources/NibblePoker/applets/excel-password-remover/excel-password-remover.mjs +++ b/static/resources/NibblePoker/applets/excel-password-remover/excel-password-remover.mjs @@ -1,14 +1,20 @@ -import {initCore} from "../../js/nibblepoker-core.mjs" +// Implied Globals: JSZip +if(JSZip == null) { + alert("JSZip isn't available !"); +} -const excelFileRegex = /^.*\.xls[xm]$/gi; -const excelWorksheetRegex = /^xl\/worksheets\/.*.xml$/gi; +import {initCore} from "../../js/nibblepoker-core.mjs" +import {cloneTemplate} from "../../js/nibblepoker-template.mjs" + +export const excelFileRegex = /^.*\.xls[xm]$/gi; +export const excelWorksheetRegex = /^xl\/worksheets\/.*.xml$/gi; /** * Checks if the given filename appears to be for an Excel file. * @param fileName {string} Filename to be checked * @returns {boolean} `true` if it appears to be an Excel file, `false` otherwise. */ -function isExcelExtension(fileName) { +export function isExcelExtension(fileName) { return fileName.match(excelFileRegex) !== null; } @@ -16,43 +22,269 @@ function isExcelExtension(fileName) { { initCore(); - var outputZip; - var outputZipFilename = "default-filename.error.zip"; - var filesTotalCount = 0; - var filesProcessedCount = 0; - var passwordsRemoved = 0; + //let outputZip; + //let outputZipFilename = "default-filename.error.zip"; + //let filesTotalCount = 0; + //let filesProcessedCount = 0; + //let passwordsRemoved = 0; /** @type {string} */ const appletId = "excel-password-remover"; - /** @type {HTMLElement} */ - const eEulaContainer = document.querySelector(`#${appletId}-eula`); - ///** @type {HTMLInputElement} */ - //const eEulaDontAskAgainOption = document.querySelector(`input#${appletId}-eula-remember`); - ///** @type {HTMLButtonElement} */ - //const eEulaAcceptButton = document.querySelector(`button#${appletId}-eula-accept`); - /** @type {HTMLInputElement} */ const eFileInput = document.querySelector(`input[type=file]#${appletId}-input-file`); + /** @type {HTMLButtonElement} */ + const eFileInputClearButton = document.querySelector(`button#${appletId}-input-file-reset`); - /*function acceptTerms() { - document.getElementById("warning").hidden = true; - document.getElementById("file-select").hidden = false; - }*/ + /** @type {HTMLElement} */ + const eResultEmptyText = document.querySelector(`#${appletId}-details-empty`); + /** @type {HTMLElement} */ + const eResultPopulatedText = document.querySelector(`#${appletId}-details-populated`); + + /** @type {HTMLElement} */ + const eResultContainer = document.querySelector(`#${appletId}-result-container`); + + /** @type {HTMLTemplateElement} */ + const eSuccessTemplate = document.querySelector(`template#tmpl-success-root`); + /** @type {HTMLTemplateElement} */ + const eWarningTemplate = document.querySelector(`template#tmpl-warning-root`); + /** @type {HTMLTemplateElement} */ + const eErrorTemplate = document.querySelector(`template#tmpl-error-root`); + + /** @type {HTMLButtonElement} */ + const eFileDownloadAllButton = document.querySelector(`button#${appletId}-files-download-all`); + /** @type {HTMLButtonElement} */ + const eFileClearButton = document.querySelector(`button#${appletId}-files-clear`); + + class ExcelFileData { + /** @type {File} */ + originalFile; + + /** @type {any} */ + processedZipFile; + + filesTotalCount = 0; + filesProcessedCount = 0; + passwordsRemoved = 0; + + constructor(originalFile) { + this.originalFile = originalFile; + } + + /** @returns {string} */ + getOutputName() { + let outputZipExtension = "." + this.originalFile.name.split(".").pop(); + let outputZipFilename = this.originalFile.name.substring(0, this.originalFile.name.length - outputZipExtension.length); + return outputZipFilename + "_no-password" + outputZipExtension; + } + } + + /** @type {ExcelFileData[]} */ + let rawWorksheetFiles = []; + + function onFileAddedToDom() { + eResultEmptyText.hidden = true; + eResultPopulatedText.hidden = false; + } + + function onFilesRemovedFromDom() { + eResultEmptyText.hidden = false; + eResultPopulatedText.hidden = true; + } + + /** + * @param excelFile {ExcelFileData} + */ + function onFileHavingPasswordRemoved(excelFile) { + console.debug(`Removed ${excelFile.passwordsRemoved} password(s) from '${excelFile.originalFile.name}'`); + + cloneTemplate( + eSuccessTemplate, + { + "tmpl-success-filename": excelFile.originalFile.name, + "tmpl-success-password-count": excelFile.passwordsRemoved + }, + true + ).then(eFragment => { + console.debug(eFragment); + + const uuid = crypto.randomUUID(); + console.debug(eFragment.children); + eFragment.children.id = uuid; + + eResultContainer.appendChild(eFragment); + onFileAddedToDom(); + }); + } + + /** + * @param excelFile {ExcelFileData} + */ + function onFileWithoutPasswords(excelFile) { + console.warn(`No password(s) were found in ${excelFile.originalFile.name} !`); + + cloneTemplate( + eWarningTemplate, + { + "tmpl-warning-filename": excelFile.originalFile.name, + "tmpl-warning-message-extension": "", + //"tmpl-warning-message-no-password": "", + }, + true + ).then(eFragment => { + console.debug(eFragment); + eResultContainer.appendChild(eFragment); + onFileAddedToDom(); + }); + } + + /** + * @param excelFile {ExcelFileData} + */ + function onFileWithInvalidExtension(excelFile) { + console.warn(`The given file '${excelFile.originalFile.name}' doesn't have an Excel extension`); + + cloneTemplate( + eWarningTemplate, + { + "tmpl-warning-filename": excelFile.originalFile.name, + //"tmpl-warning-message-extension": "", + "tmpl-warning-message-no-password": "", + }, + true + ).then(eFragment => { + console.debug(eFragment); + eResultContainer.appendChild(eFragment); + onFileAddedToDom(); + }); + } + + /** + * @param excelFile {ExcelFileData} + * @param error {any} + */ + function onExtractionFailure(excelFile, error) { + console.error("Failed to extract the content of the file in the browser ! ("+error.message+")"); + + cloneTemplate( + eErrorTemplate, + { + "tmpl-error-filename": excelFile.originalFile.name, + //"tmpl-error-message-jszip": "" + }, + true + ).then(eFragment => { + console.debug(eFragment); + eResultContainer.appendChild(eFragment); + onFileAddedToDom(); + }); + } window.onload = function () { - eFileInput.addEventListener('change', function(e) { - let fileCount = e.target.files.length; + eFileDownloadAllButton.addEventListener("click", function() { - console.log(fileCount); }); - /*console.log(eEulaContainer); - console.log(eEulaDontAskAgainOption); - console.log(eEulaAcceptButton); - eEulaAcceptButton.addEventListener("click", function() { - eEulaContainer.hidden = true; - });*/ + eFileClearButton.addEventListener("click", function() { + while (eResultContainer.firstChild) { + eResultContainer.firstChild.remove(); + } + onFilesRemovedFromDom(); + rawWorksheetFiles = []; + eFileInputClearButton.click(); + }); + + eFileInput.addEventListener('change', function(e) { + rawWorksheetFiles = []; + + for (let i = 0; i < e.target.files.length; i++) { + console.debug(e.target.files[i]); + rawWorksheetFiles.push(new ExcelFileData(e.target.files[i])); + } + + rawWorksheetFiles.forEach(excelFile => { + if(!isExcelExtension(excelFile.originalFile.name)) { + onFileWithInvalidExtension(excelFile); + return; + } + + JSZip.loadAsync(excelFile.originalFile).then(function(zip) { + console.group(`JSZip - ${excelFile.originalFile.name}`); + + excelFile.processedZipFile = new JSZip(); + excelFile.filesTotalCount = 0; + excelFile.filesProcessedCount = 0; + excelFile.passwordsRemoved = 0; + + for(const[fileKey, fileValue] of Object.entries(zip.files)) { + excelFile.filesTotalCount++; + + if(fileKey.match(excelWorksheetRegex)) { + console.debug("Checking: "+fileKey); + + fileValue.async("string").then(function(fileText) { + console.group(`JSZip - ${excelFile.originalFile.name} - ${fileKey}`); + + let startIndex = fileText.indexOf('', startIndex) + 2; + fileText = fileText.replace(fileText.substr(startIndex, endIndex-startIndex), ""); + excelFile.processedZipFile.file(fileKey, fileText); + console.debug("Processed: "+fileKey); + excelFile.passwordsRemoved++; + } + + excelFile.filesProcessedCount++; + + console.groupEnd(); + }); + } else { + // Other files. + console.debug("Ignoring: "+fileKey); + fileValue.async("string").then(function(fileText) { + console.group(`JSZip - ${excelFile.originalFile.name} - ${fileKey}`); + console.debug(`Copying as-is`); + + excelFile.processedZipFile.file(fileKey, fileText); + excelFile.filesProcessedCount++; + + console.groupEnd(); + }); + } + } + + console.debug("Waiting for all the files to be processed !"); + + function waitFilesBeingProcessed() { + console.debug("Processed "+excelFile.filesProcessedCount+" file(s) out of "+excelFile.filesTotalCount); + + if(excelFile.filesTotalCount !== excelFile.filesProcessedCount) { + setTimeout(waitFilesBeingProcessed, 50); + } else { + console.debug("Done, now switching the page !"); + if(excelFile.passwordsRemoved > 0) { + onFileHavingPasswordRemoved(excelFile); + } else { + onFileWithoutPasswords(excelFile); + } + } + } + + setTimeout(waitFilesBeingProcessed, 50); + + console.groupEnd(); + }, function (e) { + onExtractionFailure(excelFile, e); + }); + }); + + }); } } diff --git a/static/resources/NibblePoker/js/nibblepoker-template.mjs b/static/resources/NibblePoker/js/nibblepoker-template.mjs index 8b72547..42297d3 100644 --- a/static/resources/NibblePoker/js/nibblepoker-template.mjs +++ b/static/resources/NibblePoker/js/nibblepoker-template.mjs @@ -5,7 +5,7 @@ /** * @param eTemplate {HTMLTemplateElement | string} The template to be cloned, or its ID. * @param subParts {Object.} - * @param ignoreMissingParts {bool} + * @param ignoreMissingParts {boolean} * @returns {Promise} */ export function cloneTemplate(eTemplate, @@ -34,14 +34,22 @@ export function cloneTemplate(eTemplate, reject(`Unable to find sub-element with id '${key}' !`); } + ePart.removeAttribute('id'); + if(value instanceof Node) { + ePart.innerHTML = ""; ePart.appendChild(value); } else { - ePart.innerHTML += value; + ePart.innerHTML = value; } } } + const childElements = eClone.querySelectorAll('*'); + childElements.forEach(eChild => { + eChild.removeAttribute('id'); + }); + resolve(eClone); } }); diff --git a/static/resources/NibblePoker/js/nibblepoker-ui.mjs b/static/resources/NibblePoker/js/nibblepoker-ui.mjs index ced77d1..8a1f644 100644 --- a/static/resources/NibblePoker/js/nibblepoker-ui.mjs +++ b/static/resources/NibblePoker/js/nibblepoker-ui.mjs @@ -1,6 +1,7 @@ -// NibblePoker - UI Scripts +// NibblePoker - Mandatory Scripts // Author: Herwin Bozet (@NibblePoker) // License: Public Domain (This code) +// Remark: This modules contains all the scripts that are globally required on this website export const animationStepCount = 10; diff --git a/static/resources/Standalone/.gitignore b/static/resources/Standalone/.gitignore new file mode 100644 index 0000000..75003a4 --- /dev/null +++ b/static/resources/Standalone/.gitignore @@ -0,0 +1 @@ +jszip.min.js diff --git a/templates/applets/excel-password-remover.jinja b/templates/applets/excel-password-remover.jinja index cb9daae..398496a 100644 --- a/templates/applets/excel-password-remover.jinja +++ b/templates/applets/excel-password-remover.jinja @@ -10,13 +10,7 @@ {{ render_paragraph(l10n("file.selection.1", applet_data.id, user_lang)) }} - {{ render_file_input(applet_data.id + "-input-file", true, ".xlsx, .xlsm", true, true) }} - -
-
- ⚠️ These styles require a special workaround to work properly ⚠️ -
-
+ {{ render_file_input(applet_data.id + "-input-file", true, ".xlsx, .xlsm", true, true, user_lang) }}
@@ -25,8 +19,89 @@
{{ render_paragraph(l10n("details.empty.1", applet_data.id, user_lang)) }}
+ + + +
+ + + + + + {% if is_standalone %}
{{ render_h2(l10n("licenses.title", applet_data.id, user_lang)) }} diff --git a/templates/base_standalone.jinja b/templates/base_standalone.jinja index 8480b67..429b593 100644 --- a/templates/base_standalone.jinja +++ b/templates/base_standalone.jinja @@ -7,16 +7,17 @@ - - - - - - + + + + {{ get_standalone_common_headers() }} - + {% block extra_stylesheets %}{% endblock %} @@ -40,7 +41,7 @@ diff --git a/templates/base_www.jinja b/templates/base_www.jinja index 44e0ea1..46eec6c 100644 --- a/templates/base_www.jinja +++ b/templates/base_www.jinja @@ -10,10 +10,12 @@ - - - - + + + + + + {% block extra_preloads %}{% endblock %} @@ -112,8 +114,6 @@ - - {% block extra_scripts %}{% endblock %} diff --git a/templates/elements/button.jinja b/templates/elements/button.jinja index 9965b0d..1bcb8e4 100644 --- a/templates/elements/button.jinja +++ b/templates/elements/button.jinja @@ -1,6 +1,6 @@ \ No newline at end of file diff --git a/templates/elements/file-input.jinja b/templates/elements/file-input.jinja index 0b5b318..d8d4b8c 100644 --- a/templates/elements/file-input.jinja +++ b/templates/elements/file-input.jinja @@ -1,7 +1,8 @@
+ {% if file_upload_button %} {% endif %} diff --git a/website/renderers/button.py b/website/renderers/button.py index 9e522e9..7f9d9fa 100644 --- a/website/renderers/button.py +++ b/website/renderers/button.py @@ -1,11 +1,11 @@ from flask import render_template -def render_button(inner_html: str, disabled: bool = False, id: str = None) -> str: +def render_button(inner_html: str, disabled: bool = False, dom_id: str = None, extra_classes: str = "") -> str: return render_template( "elements/button.jinja", button_inner_html=inner_html, button_disabled=disabled, - button_extra_classes="", - button_id=id, + button_extra_classes=extra_classes, + button_id=dom_id, ) diff --git a/website/renderers/file_input.py b/website/renderers/file_input.py index a8990da..681f0c4 100644 --- a/website/renderers/file_input.py +++ b/website/renderers/file_input.py @@ -2,7 +2,7 @@ from flask import render_template def render_file_input(input_id: str, multiple: bool, accept: str = None, - upload_button: bool = False, clear_button: bool = False) -> str: + upload_button: bool = False, clear_button: bool = False, user_lang: str = "") -> str: return render_template( "elements/file-input.jinja", file_input_id=input_id, @@ -10,4 +10,5 @@ def render_file_input(input_id: str, multiple: bool, accept: str = None, file_accept=accept, file_upload_button=upload_button, file_clear_button=clear_button, + user_lang=user_lang, )