Nearly finished the Excel Password Remover revamp, Only the download is missing
Update commons.yml, excel-password-remover.yml, and 14 more files...
This commit is contained in:
@@ -52,6 +52,9 @@ source.code: "Source code"
|
|||||||
|
|
||||||
download.single: "Download"
|
download.single: "Download"
|
||||||
download.multiple: "Downloads"
|
download.multiple: "Downloads"
|
||||||
|
download.action.all: "Download All"
|
||||||
|
|
||||||
|
clear.all.files: "Clear all file(s)"
|
||||||
|
|
||||||
github: "GitHub Repository"
|
github: "GitHub Repository"
|
||||||
gitea: "Self-hosted Gitea Repository"
|
gitea: "Self-hosted Gitea Repository"
|
||||||
|
@@ -5,36 +5,36 @@ meta.description: >-
|
|||||||
Small web page from which you can easily remove a password from an Excel
|
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
|
worksheet. It works by leaving the task of editing the XML files on an Excel
|
||||||
document to your browser instead to keep everything local.
|
document to your browser instead to keep everything local.
|
||||||
article.subtitle: >-
|
#article.subtitle: >-
|
||||||
<a
|
# <a
|
||||||
href="https://github.com/aziascreations/Excel-Worksheet-Password-Remover"><i
|
# href="https://github.com/aziascreations/Excel-Worksheet-Password-Remover"><i
|
||||||
class="fab fa-github"></i> View on GitHub</a>
|
# class="fab fa-github"></i> View on GitHub</a>
|
||||||
intro.title: Introduction
|
#intro.title: Introduction
|
||||||
intro.p1: >-
|
#intro.p1: >-
|
||||||
This project aims to simplify the removal of passwords on Excel's Worksheet by
|
# 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
|
# leaving the task of editing the XML files on an Excel document to your
|
||||||
browser.
|
# browser.
|
||||||
working.title: Security & Internal workings
|
#working.title: Security & Internal workings
|
||||||
working.p1: >-
|
#working.p1: >-
|
||||||
In terms of security, your browser handles all the data without sending any of
|
# In terms of security, your browser handles all the data without sending any of
|
||||||
it to a central server like many web apps do.<br>This makes it, and your data,
|
# it to a central server like many web apps do.<br>This makes it, and your data,
|
||||||
as safe as your browser can be since it is the only potential point of failure
|
# as safe as your browser can be since it is the only potential point of failure
|
||||||
here.
|
# here.
|
||||||
working.p2: >-
|
#working.p2: >-
|
||||||
As for the internal workings, the only thing this tool does is extract the
|
# As for the internal workings, the only thing this tool does is extract the
|
||||||
content of the <code>.xlsx</code> file you gave it and removes the passwords
|
# content of the <code>.xlsx</code> file you gave it and removes the passwords
|
||||||
on any worksheets and makes a new file with all the changes.<br>Once all of
|
# on any worksheets and makes a new file with all the changes.<br>Once all of
|
||||||
that is done, the file is downloaded via a <a
|
# that is done, the file is downloaded via a <a
|
||||||
href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs">data
|
# href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs">data
|
||||||
URL</a>.
|
# URL</a>.
|
||||||
usage.title: Usage
|
#usage.title: Usage
|
||||||
usage.p1: >-
|
#usage.p1: >-
|
||||||
To use this tool you can either visit "<a
|
# To use this tool you can either visit "<a
|
||||||
href="https://aziascreations.github.io/Excel-Worksheet-Password-Remover">aziascreations.github.io/Excel-Worksheet-Password-Remover</a>"
|
# href="https://aziascreations.github.io/Excel-Worksheet-Password-Remover">aziascreations.github.io/Excel-Worksheet-Password-Remover</a>"
|
||||||
or download the repository and host the web page yourself.
|
# or download the repository and host the web page yourself.
|
||||||
demo.title: Demonstration video
|
#demo.title: Demonstration video
|
||||||
links.title: Links
|
#links.title: Links
|
||||||
content.link.demo: Demo hosted on GitHub
|
#content.link.demo: Demo hosted on GitHub
|
||||||
|
|
||||||
|
|
||||||
eula.1: "This tool should only be used with files you have the express permission to unlock."
|
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.title: "File Selection"
|
||||||
file.selection.1: "Drop your excel file(s) here or click on the buttons."
|
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 <span id=\"tmpl-success-password-count\">???</span> 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 !"
|
||||||
|
@@ -52,6 +52,9 @@ source.code: "Code source"
|
|||||||
|
|
||||||
download.single: "Téléchargement"
|
download.single: "Téléchargement"
|
||||||
download.multiple: "Téléchargements"
|
download.multiple: "Téléchargements"
|
||||||
|
download.action.all: "Tout télécharger"
|
||||||
|
|
||||||
|
clear.all.files: "Retirer fichier(s)"
|
||||||
|
|
||||||
github: "Dépôt GitHub"
|
github: "Dépôt GitHub"
|
||||||
gitea: "Dépôt Gitea auto-hébergé"
|
gitea: "Dépôt Gitea auto-hébergé"
|
||||||
|
@@ -6,31 +6,31 @@ meta.description: >-
|
|||||||
feuille de calcul Excel depuis votre navigateur web sans avoir à uploader le
|
feuille de calcul Excel depuis votre navigateur web sans avoir à uploader le
|
||||||
fichier sur internet. Cette application laisse votre navigateur modifier les
|
fichier sur internet. Cette application laisse votre navigateur modifier les
|
||||||
fichiers XML du fichier Excel afin de tout garder en local.
|
fichiers XML du fichier Excel afin de tout garder en local.
|
||||||
article.subtitle: >-
|
#article.subtitle: >-
|
||||||
<a
|
# <a
|
||||||
href="https://github.com/aziascreations/Excel-Worksheet-Password-Remover"><i
|
# href="https://github.com/aziascreations/Excel-Worksheet-Password-Remover"><i
|
||||||
class="fab fa-github"></i> Voir sur GitHub</a>
|
# class="fab fa-github"></i> Voir sur GitHub</a>
|
||||||
intro.title: Introduction
|
#intro.title: Introduction
|
||||||
intro.p1: >-
|
#intro.p1: >-
|
||||||
Ce projet vise à simplifier le processus de suppression des mots de passes sur
|
# 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.
|
# les "worksheet" d'Excel en laissant votre navigateur web s'en charger.
|
||||||
working.title: Sécurité & Fonctionnement
|
#working.title: Sécurité & Fonctionnement
|
||||||
working.p1: >-
|
#working.p1: >-
|
||||||
Cet outil charge le ficher que vous lui donnez en mémoire et travaille
|
# 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,
|
# directement dessus dans le navigateur web sans utiliser un serveur central,
|
||||||
vos données restent donc entièrement sur votre machine.
|
# vos données restent donc entièrement sur votre machine.
|
||||||
working.p2: >-
|
#working.p2: >-
|
||||||
Par sécurité, nous vous demandons quand même de n'utiliser cet outil qu'avec
|
# 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
|
# des fichiers pour lesquels vous avez été explicitement autorisés à enlever le
|
||||||
mot de passe.
|
# mot de passe.
|
||||||
usage.title: Utilisation
|
#usage.title: Utilisation
|
||||||
usage.p1: >-
|
#usage.p1: >-
|
||||||
Vous pouvez utiliser cet outil en allant sur "<a
|
# Vous pouvez utiliser cet outil en allant sur "<a
|
||||||
href="https://aziascreations.github.io/Excel-Worksheet-Password-Remover">aziascreations.github.io/Excel-Worksheet-Password-Remover</a>"
|
# href="https://aziascreations.github.io/Excel-Worksheet-Password-Remover">aziascreations.github.io/Excel-Worksheet-Password-Remover</a>"
|
||||||
ou en téléchargeant le dépôt et en hébergeant la page web vous-même.
|
# 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
|
#demo.title: Vidéo de démonstration
|
||||||
links.title: Liens
|
#links.title: Liens
|
||||||
content.link.demo: Démo hébergée sur GitHub
|
#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.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 <span class='t-bold'>aucune donnée n'est envoyée via Internet</span>.<br>
|
eula.2 : "Toute suppression de mot de passe se fait localement dans votre navigateur, et <span class='t-bold'>aucune donnée n'est envoyée via Internet</span>.<br>
|
||||||
@@ -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.title : "Sélection de fichier(s)"
|
||||||
file.selection.1 : "Déposez vos fichiers Excel ici ou cliquez sur les boutons."
|
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) : <span id=\"tmpl-success-password-count\">???</span>"
|
||||||
|
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 !"
|
||||||
|
@@ -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\rollup" nibblepoker-code.mjs --file nibblepoker-code.js
|
||||||
call "%~dp0node_modules\.bin\terser" nibblepoker-code.js -c -m -o nibblepoker-code.min.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
|
echo ^> static\resources\NibblePoker\js\nibblepoker-contributors.mjs
|
||||||
call "%~dp0node_modules\.bin\rollup" nibblepoker-contributors.mjs --file nibblepoker-contributors.js
|
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
|
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
|
echo ^> static\resources\NibblePoker\js\nibblepoker-splide.js
|
||||||
call "%~dp0node_modules\.bin\rollup" nibblepoker-splide.mjs --file 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
|
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
|
popd
|
||||||
|
|
||||||
|
|
||||||
|
@@ -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;
|
import {initCore} from "../../js/nibblepoker-core.mjs"
|
||||||
const excelWorksheetRegex = /^xl\/worksheets\/.*.xml$/gi;
|
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.
|
* Checks if the given filename appears to be for an Excel file.
|
||||||
* @param fileName {string} Filename to be checked
|
* @param fileName {string} Filename to be checked
|
||||||
* @returns {boolean} `true` if it appears to be an Excel file, `false` otherwise.
|
* @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;
|
return fileName.match(excelFileRegex) !== null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -16,43 +22,269 @@ function isExcelExtension(fileName) {
|
|||||||
{
|
{
|
||||||
initCore();
|
initCore();
|
||||||
|
|
||||||
var outputZip;
|
//let outputZip;
|
||||||
var outputZipFilename = "default-filename.error.zip";
|
//let outputZipFilename = "default-filename.error.zip";
|
||||||
var filesTotalCount = 0;
|
//let filesTotalCount = 0;
|
||||||
var filesProcessedCount = 0;
|
//let filesProcessedCount = 0;
|
||||||
var passwordsRemoved = 0;
|
//let passwordsRemoved = 0;
|
||||||
|
|
||||||
/** @type {string} */
|
/** @type {string} */
|
||||||
const appletId = "excel-password-remover";
|
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} */
|
/** @type {HTMLInputElement} */
|
||||||
const eFileInput = document.querySelector(`input[type=file]#${appletId}-input-file`);
|
const eFileInput = document.querySelector(`input[type=file]#${appletId}-input-file`);
|
||||||
|
/** @type {HTMLButtonElement} */
|
||||||
|
const eFileInputClearButton = document.querySelector(`button#${appletId}-input-file-reset`);
|
||||||
|
|
||||||
/*function acceptTerms() {
|
/** @type {HTMLElement} */
|
||||||
document.getElementById("warning").hidden = true;
|
const eResultEmptyText = document.querySelector(`#${appletId}-details-empty`);
|
||||||
document.getElementById("file-select").hidden = false;
|
/** @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 () {
|
window.onload = function () {
|
||||||
|
|
||||||
eFileInput.addEventListener('change', function(e) {
|
eFileDownloadAllButton.addEventListener("click", function() {
|
||||||
let fileCount = e.target.files.length;
|
|
||||||
|
|
||||||
console.log(fileCount);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/*console.log(eEulaContainer);
|
eFileClearButton.addEventListener("click", function() {
|
||||||
console.log(eEulaDontAskAgainOption);
|
while (eResultContainer.firstChild) {
|
||||||
console.log(eEulaAcceptButton);
|
eResultContainer.firstChild.remove();
|
||||||
eEulaAcceptButton.addEventListener("click", function() {
|
}
|
||||||
eEulaContainer.hidden = true;
|
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('<sheetProtection ');
|
||||||
|
|
||||||
|
if(startIndex === -1) {
|
||||||
|
// No password found.
|
||||||
|
excelFile.processedZipFile.file(fileKey, fileText);
|
||||||
|
console.debug("Analysed: "+fileKey);
|
||||||
|
} else {
|
||||||
|
// Removing the password.
|
||||||
|
let endIndex = 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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
/**
|
/**
|
||||||
* @param eTemplate {HTMLTemplateElement | string} The template to be cloned, or its ID.
|
* @param eTemplate {HTMLTemplateElement | string} The template to be cloned, or its ID.
|
||||||
* @param subParts {Object.<string, Node | string | number | boolean>}
|
* @param subParts {Object.<string, Node | string | number | boolean>}
|
||||||
* @param ignoreMissingParts {bool}
|
* @param ignoreMissingParts {boolean}
|
||||||
* @returns {Promise<DocumentFragment>}
|
* @returns {Promise<DocumentFragment>}
|
||||||
*/
|
*/
|
||||||
export function cloneTemplate(eTemplate,
|
export function cloneTemplate(eTemplate,
|
||||||
@@ -34,14 +34,22 @@ export function cloneTemplate(eTemplate,
|
|||||||
reject(`Unable to find sub-element with id '${key}' !`);
|
reject(`Unable to find sub-element with id '${key}' !`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ePart.removeAttribute('id');
|
||||||
|
|
||||||
if(value instanceof Node) {
|
if(value instanceof Node) {
|
||||||
|
ePart.innerHTML = "";
|
||||||
ePart.appendChild(value);
|
ePart.appendChild(value);
|
||||||
} else {
|
} else {
|
||||||
ePart.innerHTML += value;
|
ePart.innerHTML = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const childElements = eClone.querySelectorAll('*');
|
||||||
|
childElements.forEach(eChild => {
|
||||||
|
eChild.removeAttribute('id');
|
||||||
|
});
|
||||||
|
|
||||||
resolve(eClone);
|
resolve(eClone);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
// NibblePoker - UI Scripts
|
// NibblePoker - Mandatory Scripts
|
||||||
// Author: Herwin Bozet (@NibblePoker)
|
// Author: Herwin Bozet (@NibblePoker)
|
||||||
// License: Public Domain (This code)
|
// License: Public Domain (This code)
|
||||||
|
// Remark: This modules contains all the scripts that are globally required on this website
|
||||||
|
|
||||||
export const animationStepCount = 10;
|
export const animationStepCount = 10;
|
||||||
|
|
||||||
|
1
static/resources/Standalone/.gitignore
vendored
Normal file
1
static/resources/Standalone/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
jszip.min.js
|
@@ -10,13 +10,7 @@
|
|||||||
|
|
||||||
{{ render_paragraph(l10n("file.selection.1", applet_data.id, user_lang)) }}
|
{{ render_paragraph(l10n("file.selection.1", applet_data.id, user_lang)) }}
|
||||||
|
|
||||||
{{ render_file_input(applet_data.id + "-input-file", true, ".xlsx, .xlsm", true, true) }}
|
{{ render_file_input(applet_data.id + "-input-file", true, ".xlsx, .xlsm", true, true, user_lang) }}
|
||||||
|
|
||||||
<div id="{{ applet_data.id }}-errors">
|
|
||||||
<div class="bkgd-red t-bold t-center w-full r-l border p-xs">
|
|
||||||
⚠️ These styles require a special workaround to work properly ⚠️
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="{{ applet_data.id }}-details">
|
<section id="{{ applet_data.id }}-details">
|
||||||
@@ -25,8 +19,89 @@
|
|||||||
<div id="{{ applet_data.id }}-details-empty">
|
<div id="{{ applet_data.id }}-details-empty">
|
||||||
{{ render_paragraph(l10n("details.empty.1", applet_data.id, user_lang)) }}
|
{{ render_paragraph(l10n("details.empty.1", applet_data.id, user_lang)) }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="{{ applet_data.id }}-details-populated" hidden>
|
||||||
|
{{ render_button(
|
||||||
|
"<i class=\"fa-duotone fa-solid fa-floppy-disks mr-xs\"></i>" +
|
||||||
|
l10n("download.action.all", "commons", user_lang),
|
||||||
|
false, applet_data.id + "-files-download-all", "bkgd-green") }}
|
||||||
|
{{ render_button(
|
||||||
|
"<i class=\"fa-duotone fa-solid fa-trash mr-xs\"></i>" +
|
||||||
|
l10n("clear.all.files", "commons", user_lang),
|
||||||
|
false, applet_data.id + "-files-clear", "bkgd-orange") }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="{{ applet_data.id }}-result-container"></div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<template id="tmpl-success-root">
|
||||||
|
<div class="bkgd-grid10 w-full r-l border">
|
||||||
|
<table class="table-p-xxs table-v-center">
|
||||||
|
<tr>
|
||||||
|
<td rowspan="2" class="br bkgd-green bkgd-grid30 rl-l">
|
||||||
|
<i class="fa-duotone fa-solid fa-circle-check mx-s"></i>
|
||||||
|
</td>
|
||||||
|
<td class="w-full t-bold">
|
||||||
|
<span id="tmpl-success-filename">PlaceholderSuccessName.xlsx</span>
|
||||||
|
</td>
|
||||||
|
<td rowspan="2" class="bl bkgd-blue bkgd-grid30 rr-l">
|
||||||
|
<i class="fa-duotone fa-download mx-s"></i>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="t-italic">
|
||||||
|
<td>{{ l10n("result.success.count", applet_data.id, user_lang) }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template id="tmpl-warning-root">
|
||||||
|
<div class="bkgd-grid10 w-full r-l border">
|
||||||
|
<table class="table-p-xxs table-v-center">
|
||||||
|
<tr>
|
||||||
|
<td rowspan="2" class="br bkgd-orange bkgd-grid30 rl-l">
|
||||||
|
<i class="fa-duotone fa-solid fa-triangle-exclamation mx-s"></i>
|
||||||
|
</td>
|
||||||
|
<td class="w-full t-bold">
|
||||||
|
<span id="tmpl-warning-filename">PlaceholderWarningName.xlsx</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="t-italic">
|
||||||
|
<td>
|
||||||
|
<span id="tmpl-warning-message-extension">
|
||||||
|
{{ l10n("result.warning.extension", applet_data.id, user_lang) }}
|
||||||
|
</span>
|
||||||
|
<span id="tmpl-warning-message-no-password">
|
||||||
|
{{ l10n("result.warning.password", applet_data.id, user_lang) }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template id="tmpl-error-root">
|
||||||
|
<div class="bkgd-grid10 w-full r-l border">
|
||||||
|
<table class="table-p-xxs table-v-center">
|
||||||
|
<tr>
|
||||||
|
<td rowspan="2" class="br bkgd-red bkgd-grid30 rl-l">
|
||||||
|
<i class="fa-duotone fa-solid fa-hexagon-exclamation mx-s"></i>
|
||||||
|
</td>
|
||||||
|
<td class="w-full t-bold">
|
||||||
|
<span id="tmpl-error-filename">PlaceholderErrorName.xlsx</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr class="t-italic">
|
||||||
|
<td>
|
||||||
|
<span id="tmpl-error-message-jszip">
|
||||||
|
{{ l10n("result.error.jszip", applet_data.id, user_lang) }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
{% if is_standalone %}
|
{% if is_standalone %}
|
||||||
<section id="{{ applet_data.id }}-licenses">
|
<section id="{{ applet_data.id }}-licenses">
|
||||||
{{ render_h2(l10n("licenses.title", applet_data.id, user_lang)) }}
|
{{ render_h2(l10n("licenses.title", applet_data.id, user_lang)) }}
|
||||||
|
File diff suppressed because one or more lines are too long
@@ -10,10 +10,12 @@
|
|||||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
||||||
<link rel="alternate icon" href="/favicon.ico">
|
<link rel="alternate icon" href="/favicon.ico">
|
||||||
|
|
||||||
<!--<link rel="dns-prefetch" />-->
|
<!--<link rel="dns-prefetch" href="https://cdn.nibblepoker.lu/"/>-->
|
||||||
<link rel="prefetch" href="https://cdn.nibblepoker.lu/FontAwesomePro/6.5.1/webfonts/fa-brands-400.woff2" as="font" />
|
<link rel="preconnect" href="https://cdn.nibblepoker.lu/"/>
|
||||||
<link rel="prefetch" href="https://cdn.nibblepoker.lu/FontAwesomePro/6.5.1/webfonts/fa-duotone-900.woff2" as="font" />
|
|
||||||
<link rel="prefetch" href="https://cdn.nibblepoker.lu/FontAwesomePro/6.5.1/webfonts/fa-solid-900.woff2" as="font" />
|
<link rel="prefetch" href="https://cdn.nibblepoker.lu/FontAwesomePro/6.7.2/webfonts/fa-brands-400.woff2" as="font" />
|
||||||
|
<link rel="prefetch" href="https://cdn.nibblepoker.lu/FontAwesomePro/6.7.2/webfonts/fa-duotone-900.woff2" as="font" />
|
||||||
|
<link rel="prefetch" href="https://cdn.nibblepoker.lu/FontAwesomePro/6.7.2/webfonts/fa-solid-900.woff2" as="font" />
|
||||||
<link rel="prefetch" href="https://cdn.nibblepoker.lu/NibblePoker/StandardCSS/3px-tile-0.1.png" as="image" />
|
<link rel="prefetch" href="https://cdn.nibblepoker.lu/NibblePoker/StandardCSS/3px-tile-0.1.png" as="image" />
|
||||||
<link rel="prefetch" href="https://cdn.nibblepoker.lu/NibblePoker/StandardCSS/3px-tile-0.4.png" as="image" />
|
<link rel="prefetch" href="https://cdn.nibblepoker.lu/NibblePoker/StandardCSS/3px-tile-0.4.png" as="image" />
|
||||||
{% block extra_preloads %}{% endblock %}
|
{% block extra_preloads %}{% endblock %}
|
||||||
@@ -112,8 +114,6 @@
|
|||||||
</a>
|
</a>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<!--<script src="{{ url_for("static", filename="resources/NibblePoker/js/nibblepoker.min.js") }}"></script>-->
|
|
||||||
|
|
||||||
{% block extra_scripts %}{% endblock %}
|
{% block extra_scripts %}{% endblock %}
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
<button
|
<button
|
||||||
{% if button_id is not none %}id="{{ button_id }}" {% endif %}
|
{% if button_id is not none %}id="{{ button_id }}" {% endif %}
|
||||||
class="p-mxs r-s border b-light t-nowrap {{ button_extra_classes }}"
|
class="p-xs r-s border b-light t-nowrap {{ button_extra_classes }}"
|
||||||
{% if button_disabled %}disabled{% endif %}>
|
{% if button_disabled %}disabled{% endif %}>
|
||||||
{{ button_inner_html }}
|
{{ button_inner_html }}
|
||||||
</button>
|
</button>
|
@@ -1,7 +1,8 @@
|
|||||||
<div class="np-file-input-root-container">
|
<div class="np-file-input-root-container">
|
||||||
|
<!-- FIXME: Use the common renderer ! -->
|
||||||
{% if file_upload_button %}
|
{% if file_upload_button %}
|
||||||
<button id="{{ file_input_id }}-add" class="p-xs r-s border btn-primary">
|
<button id="{{ file_input_id }}-add" class="p-xs r-s border btn-primary">
|
||||||
<i class="fa-duotone fa-solid fa-cloud-arrow-up mr-xs"></i>
|
<i class="fa-duotone fa-solid fa-cloud-arrow-up mr-xxs"></i>
|
||||||
{% if file_multiple %}
|
{% if file_multiple %}
|
||||||
{{ l10n("file.drop.upload.multiple", "commons", user_lang) }}
|
{{ l10n("file.drop.upload.multiple", "commons", user_lang) }}
|
||||||
{% else %}
|
{% else %}
|
||||||
@@ -12,7 +13,7 @@
|
|||||||
|
|
||||||
{% if file_clear_button %}
|
{% if file_clear_button %}
|
||||||
<button id="{{ file_input_id }}-reset" class="p-xs r-s border btn-warning">
|
<button id="{{ file_input_id }}-reset" class="p-xs r-s border btn-warning">
|
||||||
{{ l10n("file.drop.clear", "commons", user_lang) }}
|
{{ "<i class=\"fa-duotone fa-solid fa-trash mr-xs\"></i>" + l10n("file.drop.clear", "commons", user_lang) }}
|
||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
from flask import render_template
|
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(
|
return render_template(
|
||||||
"elements/button.jinja",
|
"elements/button.jinja",
|
||||||
button_inner_html=inner_html,
|
button_inner_html=inner_html,
|
||||||
button_disabled=disabled,
|
button_disabled=disabled,
|
||||||
button_extra_classes="",
|
button_extra_classes=extra_classes,
|
||||||
button_id=id,
|
button_id=dom_id,
|
||||||
)
|
)
|
||||||
|
@@ -2,7 +2,7 @@ from flask import render_template
|
|||||||
|
|
||||||
|
|
||||||
def render_file_input(input_id: str, multiple: bool, accept: str = None,
|
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(
|
return render_template(
|
||||||
"elements/file-input.jinja",
|
"elements/file-input.jinja",
|
||||||
file_input_id=input_id,
|
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_accept=accept,
|
||||||
file_upload_button=upload_button,
|
file_upload_button=upload_button,
|
||||||
file_clear_button=clear_button,
|
file_clear_button=clear_button,
|
||||||
|
user_lang=user_lang,
|
||||||
)
|
)
|
||||||
|
Reference in New Issue
Block a user