Fix aria errors, minor tweaks

This commit is contained in:
Booteille 2024-11-27 05:19:05 +01:00
parent d4f671a519
commit 8eef94c68c
No known key found for this signature in database
GPG Key ID: 0AB6C6CA01272646
11 changed files with 85 additions and 66 deletions

View File

@ -39,7 +39,7 @@ document.addEventListener("DOMContentLoaded", () => {
passwordFormDOM.onsubmit = (event) => { passwordFormDOM.onsubmit = (event) => {
event.preventDefault(); event.preventDefault();
passwordFormDOM.classList.add("hidden"); hideNode(passwordFormDOM);
startDownload(); startDownload();
}; };
@ -48,14 +48,14 @@ document.addEventListener("DOMContentLoaded", () => {
const showZipContent = (zipFile, cardDOM) => { const showZipContent = (zipFile, cardDOM) => {
const zipContainerDOM = cardDOM.querySelector(".content .zip-container"); const zipContainerDOM = cardDOM.querySelector(".content .zip-container");
zipContainerDOM.classList.remove("hidden"); showNode(zipContainerDOM);
zipContainerDOM.querySelector(".action-show-zip").onclick = (event) => { zipContainerDOM.querySelector(".action-show-zip").onclick = (event) => {
event.target.classList.add("hidden"); hideNode(event.target);
const zipContentDOM = zipContainerDOM.querySelector(".zip-content"); const zipContentDOM = zipContainerDOM.querySelector(".zip-content");
zipContentDOM.classList.remove("hidden"); showNode(zipContentDOM);
document.body.style.cursor = "wait"; document.body.style.cursor = "wait";
@ -64,7 +64,7 @@ document.addEventListener("DOMContentLoaded", () => {
.andThen((job) => job.waitForCompletion()) .andThen((job) => job.waitForCompletion())
.map((job) => { .map((job) => {
job.archiveFiles.forEach((file) => { job.archiveFiles.forEach((file) => {
const itemDOM = zipContainerDOM const itemDOM = document
.querySelector("template#zip-item") .querySelector("template#zip-item")
.content.cloneNode(true).children[0]; .content.cloneNode(true).children[0];

View File

@ -31,14 +31,14 @@ const toggleHidden = () => {
if (invitationsListDOM.getAttribute("data-visibility") === "hidden") { if (invitationsListDOM.getAttribute("data-visibility") === "hidden") {
toggleButtonDOM.innerText = i18n.hideText; toggleButtonDOM.innerText = i18n.hideText;
itemsHiddenDOM.forEach((item) => item.classList.remove("hidden")); itemsHiddenDOM.forEach((item) => showNode(item));
invitationsListDOM.setAttribute("data-visibility", "shown"); invitationsListDOM.setAttribute("data-visibility", "shown");
} else { } else {
toggleButtonDOM.innerText = i18n.showText; toggleButtonDOM.innerText = i18n.showText;
itemsHiddenDOM.forEach((item) => { itemsHiddenDOM.forEach((item) => {
item.classList.add("hidden"); hideNode(item);
const checkbox = item.querySelector("input"); const checkbox = item.querySelector("input");
@ -157,7 +157,7 @@ const toggleVisibility = () => {
if (t.show) { if (t.show) {
itemDOM.setAttribute("data-visibility", 1); itemDOM.setAttribute("data-visibility", 1);
itemDOM.classList.remove("hidden"); showNode(itemDOM);
itemDOM itemDOM
.querySelector(".column.selection .icon.hide-source") .querySelector(".column.selection .icon.hide-source")
.remove(); .remove();
@ -169,7 +169,7 @@ const toggleVisibility = () => {
.querySelector(".invitations-list") .querySelector(".invitations-list")
.getAttribute("data-visibility") === "hidden" .getAttribute("data-visibility") === "hidden"
) { ) {
itemDOM.classList.add("hidden"); hideNode(itemDOM);
} }
itemDOM itemDOM

View File

@ -70,14 +70,15 @@ document.addEventListener("DOMContentLoaded", () => {
}; };
const clearZip = () => { const clearZip = () => {
zipZoneDOM.classList.add("hidden"); hideNode(zipZoneDOM);
zipZoneDOM.querySelector(".action-upload-zip").classList.remove("hidden"); showNode(zipZoneDOM.querySelector(".action-upload-zip"));
zipZoneDOM.querySelector(".zip-compressing").classList.add("hidden"); hideNode(zipZoneDOM.querySelector(".zip-compressing"));
hideNode(inputZipNameDOM);
zipZoneDOM.querySelector(".files-list").replaceChildren(); zipZoneDOM.querySelector(".files-list").replaceChildren();
inputZipNameDOM.classList.add("hidden");
archiveEntries = undefined; archiveEntries = undefined;
zipSize = 0;
mustZipDOM.checked = false; mustZipDOM.checked = false;
}; };
@ -176,7 +177,7 @@ document.addEventListener("DOMContentLoaded", () => {
} }
if (fileCardsDOM.querySelectorAll(".file-card.success").length > 0) { if (fileCardsDOM.querySelectorAll(".file-card.success").length > 0) {
uploadedZoneDOM.querySelector(".buttons").classList.remove("hidden"); showNode(uploadedZoneDOM.querySelector(".buttons"));
} }
return cardDOM; return cardDOM;
@ -191,7 +192,7 @@ document.addEventListener("DOMContentLoaded", () => {
if (!mustZipDOM.checked) { if (!mustZipDOM.checked) {
clearZip(); clearZip();
} else { } else {
inputZipNameDOM.classList.remove("hidden"); showNode(inputZipNameDOM);
} }
}; };
@ -237,7 +238,8 @@ document.addEventListener("DOMContentLoaded", () => {
password password
); );
} else { } else {
zipZoneDOM.classList.remove("hidden"); showNode(zipZoneDOM);
lufi lufi
.addFilesToArchive(files, archiveEntries) .addFilesToArchive(files, archiveEntries)
.andThen((entries) => { .andThen((entries) => {
@ -295,11 +297,11 @@ document.addEventListener("DOMContentLoaded", () => {
updateMailLinksButton(serverKey, true); updateMailLinksButton(serverKey, true);
if (fileCardsDOM.children.length === 0) { if (fileCardsDOM.children.length === 0) {
uploadedZoneDOM.classList.add("hidden"); hideNode(uploadedZoneDOM);
} }
if (fileCardsDOM.querySelectorAll(".file-card.success").length === 0) { if (fileCardsDOM.querySelectorAll(".file-card.success").length === 0) {
uploadedZoneDOM.querySelector(".buttons").classList.add("hidden"); hideNode(uploadedZoneDOM);
} }
}; };
@ -388,7 +390,7 @@ document.addEventListener("DOMContentLoaded", () => {
zipName, zipName,
password password
) => { ) => {
uploadedZoneDOM.classList.remove("hidden"); showNode(uploadedZoneDOM);
const serverUrl = new URL(ws_url.replace("/upload", "")); const serverUrl = new URL(ws_url.replace("/upload", ""));
serverUrl.protocol = serverUrl.protocol === "ws:" ? "http:" : "https:"; serverUrl.protocol = serverUrl.protocol === "ws:" ? "http:" : "https:";
@ -511,8 +513,8 @@ document.addEventListener("DOMContentLoaded", () => {
const uploadZip = () => { const uploadZip = () => {
document.body.style.cursor = "wait"; document.body.style.cursor = "wait";
zipZoneDOM.querySelector(".action-upload-zip").classList.add("hidden"); hideNode(zipZoneDOM.querySelector(".action-upload-zip"));
zipZoneDOM.querySelector(".zip-compressing").classList.remove("hidden"); showNode(zipZoneDOM.querySelector(".zip-compressing"));
const { zipName, deleteDays, shouldDeleteOnFirstView, password } = const { zipName, deleteDays, shouldDeleteOnFirstView, password } =
retrieveUploadParams(); retrieveUploadParams();
@ -522,9 +524,15 @@ document.addEventListener("DOMContentLoaded", () => {
.andThen((job) => { .andThen((job) => {
document.body.style.cursor = "auto"; document.body.style.cursor = "auto";
zipZoneDOM.querySelector(".action-close").onclick = () => {
job.terminate();
clearZip();
};
return job.waitForCompletion(); return job.waitForCompletion();
}) })
.andThen((job) => { .map((job) => {
// if '.zip-zone' is hidden, the zipping has been aborted // if '.zip-zone' is hidden, the zipping has been aborted
if (!zipZoneDOM.classList.contains("hidden")) { if (!zipZoneDOM.classList.contains("hidden")) {
addToast(i18n.enqueued.replace("XXX", zipName), "success"); addToast(i18n.enqueued.replace("XXX", zipName), "success");

View File

@ -1,4 +1,5 @@
<section class="about-section"> <section class="about-section">
<h1><%= l('About') %></h1>
<h3><%= l('What is Lufi?') %></h3> <h3><%= l('What is Lufi?') %></h3>
<p><%= l('Lufi is a free (as in free speech) file hosting software.') %></p> <p><%= l('Lufi is a free (as in free speech) file hosting software.') %></p>
<h3><%= l('Privacy') %></h3> <h3><%= l('Privacy') %></h3>

View File

@ -31,7 +31,7 @@
<table class="files-table"> <table class="files-table">
<thead> <thead>
<tr> <tr>
<th></th> <th><%= l('Action') %></th>
<th><%= l('File name') %></th> <th><%= l('File name') %></th>
<th><%= l('Download link') %></th> <th><%= l('Download link') %></th>
<th><%= l('Counter') %></th> <th><%= l('Counter') %></th>
@ -52,12 +52,12 @@
<tr class="item"> <tr class="item">
<td class="column selection"> <td class="column selection">
<div class="checkbox input-delete-on-first-view"> <div class="checkbox input-delete-on-first-view">
<input type="checkbox" autocomplete="off"> <input type="checkbox" autocomplete="off" aria-label="Select">
</div> </div>
</td> </td>
<td class="column name"></td> <td class="column name"></td>
<td class="column download"> <td class="column download">
<a class="icon-button icon download" href="#"></a> <a class="icon-button icon download" title="<%= l('Download') %>" href="#"></a>
</td> </td>
<td class="column counter"></td> <td class="column counter"></td>
<td class="column delete-at-first-view"> <td class="column delete-at-first-view">
@ -66,10 +66,10 @@
<td class="column created-at"></td> <td class="column created-at"></td>
<td class="column expires-at"></td> <td class="column expires-at"></td>
<td class="column deletion"> <td class="column deletion">
<button type="button" class="icon icon-button delete" href="#"></button> <button type="button" class="icon icon-button delete" title="<%= l('Delete') %>"></button>
</td> </td>
<td class="column mail"> <td class="column mail">
<a class="icon icon-button mail" href="#"></a> <a class="icon icon-button mail" title="<%= l('Mail') %>" href="#"></a>
</td> </td>
</tr> </tr>
</template> </template>

View File

@ -29,7 +29,7 @@
<section class="upload-zone"> <section class="upload-zone">
<form class="upload-form"> <form class="upload-form">
<div class="input-delete-after-days"> <div class="input-delete-after-days">
<button type="button" class="icon-button info-delete-after-days modal-button"></button> <button type="button" class="icon-button info-delete-after-days modal-button" title="<%= l('Important: more information on delays') %>"></button>
<select class="select-delete-after-days" id="delete-after-days" aria-label="Delay"> <select class="select-delete-after-days" id="delete-after-days" aria-label="Delay">
% for my $delay (qw/0 1 7 30 365/) { % for my $delay (qw/0 1 7 30 365/) {
@ -91,8 +91,8 @@
</div> </div>
<div class="hidden zip-zone card"> <div class="hidden zip-zone card" aria-hidden="true">
<button type="button" class="icon-button icon close action-close"></button> <button type="button" class="icon-button icon close action-close" title="<%= l('Close') %>"></button>
<div class="file-description"> <div class="file-description">
<p class="file-name">documents.zip</p> <p class="file-name">documents.zip</p>
@ -102,7 +102,7 @@
<ul class="files-list"></ul> <ul class="files-list"></ul>
<button type="button" class="button action-upload-zip"><%= l("Upload generated zip file") %></button> <button type="button" class="button action-upload-zip"><%= l("Upload generated zip file") %></button>
<div class="zip-compressing hidden"> <div class="zip-compressing hidden" aria-hidden="true">
<div class="icon-container pulse"> <div class="icon-container pulse">
<span class="icon archive"></span> <span class="icon archive"></span>
</div> </div>
@ -112,9 +112,9 @@
</form> </form>
</section> </section>
<section class="hidden uploaded-zone"> <section class="hidden uploaded-zone" aria-hidden="true">
<h1><%= l('Uploaded files') %></h1> <h1><%= l('Uploaded files') %></h1>
<header class="hidden buttons"> <header class="hidden buttons" aria-hidden="true">
<div class="actions-buttons upload-success"> <div class="actions-buttons upload-success">
<button type="button" class="button action-copy-links"><%= l('Copy all links to clipboard') %></button> <button type="button" class="button action-copy-links"><%= l('Copy all links to clipboard') %></button>
<a class="button action-mail-links" href="<%= url_for('/')->to_abs() %>m"><%= l('Send all links by email') %></a> <a class="button action-mail-links" href="<%= url_for('/')->to_abs() %>m"><%= l('Send all links by email') %></a>

View File

@ -28,13 +28,13 @@
<label for="guest_mail"> <label for="guest_mail">
<%= l('Email address of your guest') %> <%= l('Email address of your guest') %>
</label> </label>
<input name="guest_mail" type="email" placeholder="name@example.org" required> <input id="guest_mail" name="guest_mail" type="email" placeholder="name@example.org" required>
</div> </div>
<div class="input-text"> <div class="input-text">
<label for="expire_at"> <label for="expire_at">
<%= l('How many days would you like the invitation to be valid?') %> <%= l('How many days would you like the invitation to be valid?') %>
</label> </label>
<input name="expire_at" type="number" min="1" max="<%= stash('max_expire_at') %>" step="1" value="<%= stash('max_expire_at') %>" required> <input id="expire_at" name="expire_at" type="number" min="1" max="<%= stash('max_expire_at') %>" step="1" value="<%= stash('max_expire_at') %>" required>
</div> </div>
<button class="button" type="submit"><%= l('Send the invitation') %></button> <button class="button" type="submit"><%= l('Send the invitation') %></button>
</form> </form>

View File

@ -17,13 +17,13 @@
<table> <table>
<thead> <thead>
<tr> <tr>
<th></th> <th><%= l('Selection') %></th>
<th><%= l('Guest mail') %></th> <th><%= l('Guest mail') %></th>
<th><%= l('URL') %></th> <th><%= l('URL') %></th>
<th><%= l('Created at') %></th> <th><%= l('Created at') %></th>
<th><%= l('Expire at') %></th> <th><%= l('Expire at') %></th>
<th><%= l('Files sent at') %></th> <th><%= l('Files sent at') %></th>
<th></th> <th><%= l('Files') %></th>
</tr> </tr>
</thead> </thead>
<tbody class="invitations-list" data-visibility="hidden"> <tbody class="invitations-list" data-visibility="hidden">
@ -34,10 +34,10 @@
% my $class = ''; % my $class = '';
% $class = 'deleted' unless $e->is_valid; % $class = 'deleted' unless $e->is_valid;
% $class .= ' hidden' unless $e->show_in_list; % $class .= ' hidden' unless $e->show_in_list;
<tr id="row-<%= $e->token %>" class="item <%= $class %>" data-visibility="<%= ($e->show_in_list) ? 1 : 0 %>"> <tr id="row-<%= $e->token %>" class="item <%= $class %>" aria-hidden="<%= ($e->show_in_list) ? 'true' : 'false' %>" data-visibility="<%= ($e->show_in_list) ? 1 : 0 %>">
<td class="column selection"> <td class="column selection">
<div class="checkbox input-selection"> <div class="checkbox input-selection">
<input type="checkbox" data-token="<%= $e->token %>"> <input type="checkbox" data-token="<%= $e->token %>" aria-label="Select">
% unless ($e->show_in_list) { % unless ($e->show_in_list) {
<span class="icon hide-source" title="<%= l('This invitation is normally hidden') %>"></span> <span class="icon hide-source" title="<%= l('This invitation is normally hidden') %>"></span>
@ -70,7 +70,7 @@
<dialog class="modal files-info"> <dialog class="modal files-info">
<section> <section>
<header> <header>
<h1></h1> <h1><%= l('Files sent in invitation XX1 by XX2') %></h1>
</header> </header>
<div class="content"> <div class="content">

View File

@ -144,6 +144,16 @@
} }
}; };
const hideNode = (node) => {
node.classList.add("hidden");
node.setAttribute("aria-hidden", true);
}
const showNode = (node) => {
node.classList.remove("hidden");
node.setAttribute("aria-hidden", false);
}
document.addEventListener("DOMContentLoaded", () => { document.addEventListener("DOMContentLoaded", () => {
if (!"Notification" in window || typeof Notification === "undefined") { if (!"Notification" in window || typeof Notification === "undefined") {
return; return;

View File

@ -10,11 +10,11 @@
<form class="login-form" method="post" action="<%= url_for('login') %>"> <form class="login-form" method="post" action="<%= url_for('login') %>">
<div class="input-text login"> <div class="input-text login">
<label for="login"><%= l('Login') %></label> <label for="login"><%= l('Login') %></label>
<input type="text" name="login" autofocus required> <input type="text" id="login" name="login" autofocus required>
</div> </div>
<div class="input-text input-password"> <div class="input-text input-password">
<label for="password"><%= l('Password') %></label> <label for="password"><%= l('Password') %></label>
<input type="password" name="password" required> <input type="password" id="password" name="password" required>
</div> </div>
%= csrf_field %= csrf_field
<input name="redirect" value="<%= stash('redirect') %>" type="hidden"> <input name="redirect" value="<%= stash('redirect') %>" type="hidden">

View File

@ -63,10 +63,10 @@
<a class="button action-download" autofocus href="#"><%= l('Get the file')%></a> <a class="button action-download" autofocus href="#"><%= l('Get the file')%></a>
<div class="content"> <div class="content">
<div class="hidden zip-container"> <div class="hidden zip-container" aria-hidden="true">
<button type="button" class="button action-show-zip"><%= l('Show zip content') %></button> <button type="button" class="button action-show-zip"><%= l('Show zip content') %></button>
<div class="hidden zip-content"> <div class="hidden zip-content" aria-hidden="true">
<h2><%= l('Zip content:') %></h2> <h2><%= l('Zip content:') %></h2>
<ul> <ul>
</ul> </ul>