-
-
Notifications
You must be signed in to change notification settings - Fork 546
Added support for drag/drop of images #282
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,18 +7,68 @@ let fileType; | |
| let pendingFiles = 0; | ||
| let formatSelected = false; | ||
|
|
||
| dropZone.addEventListener("dragover", () => { | ||
| dropZone.addEventListener("dragover", (e) => { | ||
| e.preventDefault(); | ||
| dropZone.classList.add("dragover"); | ||
| }); | ||
|
|
||
| dropZone.addEventListener("dragleave", () => { | ||
| dropZone.classList.remove("dragover"); | ||
| }); | ||
|
|
||
| dropZone.addEventListener("drop", () => { | ||
| dropZone.classList.remove("dragover"); | ||
| dropZone.addEventListener("drop", (e) => { | ||
| e.preventDefault(); | ||
| dropZone.classList.remove("dragover"); | ||
|
|
||
| const files = e.dataTransfer.files; | ||
|
|
||
| if (files.length === 0) { | ||
| console.warn("No files dropped — likely a URL or unsupported source."); | ||
| return; | ||
| } | ||
|
|
||
| for (const file of files) { | ||
| console.log("Handling dropped file:", file.name); | ||
| handleFile(file); | ||
| } | ||
| }); | ||
|
|
||
| // Extracted handleFile function for reusability in drag-and-drop and file input | ||
| function handleFile(file) { | ||
| const fileList = document.querySelector("#file-list"); | ||
|
|
||
| const row = document.createElement("tr"); | ||
| row.innerHTML = ` | ||
| <td>${file.name}</td> | ||
| <td><progress max="100"></progress></td> | ||
| <td>${(file.size / 1024).toFixed(2)} kB</td> | ||
| <td><a onclick="deleteRow(this)">Remove</a></td> | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: Consider avoiding inline event handlers. Use JavaScript to attach event listeners instead of inline onclick attributes to improve maintainability and separation of concerns. Suggested implementation: row.innerHTML = `
<td>${file.name}</td>
<td><progress max="100"></progress></td>
<td>${(file.size / 1024).toFixed(2)} kB</td>
<td><a class="delete-button" href="#">Remove</a></td>
`; // Attach event listener to the remove button to avoid inline onclick
const deleteButton = row.querySelector(".delete-button");
if (deleteButton) {
deleteButton.addEventListener("click", (event) => {
event.preventDefault();
deleteRow(deleteButton);
});
}Ensure that the deleteRow function is prepared to work with the element passed via the event listener. |
||
| `; | ||
|
|
||
| if (!fileType) { | ||
| fileType = file.name.split(".").pop(); | ||
| fileInput.setAttribute("accept", `.${fileType}`); | ||
| setTitle(); | ||
|
|
||
| fetch(`${webroot}/conversions`, { | ||
| method: "POST", | ||
| body: JSON.stringify({ fileType }), | ||
| headers: { "Content-Type": "application/json" }, | ||
| }) | ||
| .then((res) => res.text()) | ||
| .then((html) => { | ||
| selectContainer.innerHTML = html; | ||
| updateSearchBar(); | ||
| }) | ||
| .catch(console.error); | ||
| } | ||
|
|
||
| fileList.appendChild(row); | ||
| file.htmlRow = row; | ||
| fileNames.push(file.name); | ||
| uploadFile(file); | ||
| } | ||
|
|
||
| const selectContainer = document.querySelector("form .select_container"); | ||
|
|
||
| const updateSearchBar = () => { | ||
|
|
@@ -106,62 +156,9 @@ const updateSearchBar = () => { | |
|
|
||
| // Add a 'change' event listener to the file input element | ||
| fileInput.addEventListener("change", (e) => { | ||
| // Get the selected files from the event target | ||
| const files = e.target.files; | ||
|
|
||
| // Select the file-list table | ||
| const fileList = document.querySelector("#file-list"); | ||
|
|
||
| // Loop through the selected files | ||
| for (const file of files) { | ||
| // Create a new table row for each file | ||
| const row = document.createElement("tr"); | ||
| row.innerHTML = ` | ||
| <td>${file.name}</td> | ||
| <td><progress max="100"></progress></td> | ||
| <td>${(file.size / 1024).toFixed(2)} kB</td> | ||
| <td><a onclick="deleteRow(this)">Remove</a></td> | ||
| `; | ||
|
|
||
| if (!fileType) { | ||
| fileType = file.name.split(".").pop(); | ||
| fileInput.setAttribute("accept", `.${fileType}`); | ||
| setTitle(); | ||
|
|
||
| // choose the option that matches the file type | ||
| // for (const option of convertFromSelect.children) { | ||
| // console.log(option.value); | ||
| // if (option.value === fileType) { | ||
| // option.selected = true; | ||
| // } | ||
| // } | ||
|
|
||
| fetch(`${webroot}/conversions`, { | ||
| method: "POST", | ||
| body: JSON.stringify({ fileType: fileType }), | ||
| headers: { | ||
| "Content-Type": "application/json", | ||
| }, | ||
| }) | ||
| .then((res) => res.text()) | ||
| .then((html) => { | ||
| selectContainer.innerHTML = html; | ||
| updateSearchBar(); | ||
| }) | ||
| .catch((err) => console.log(err)); | ||
| } | ||
|
|
||
| // Append the row to the file-list table | ||
| fileList.appendChild(row); | ||
|
|
||
| //Imbed row into the file to reference later | ||
| file.htmlRow = row; | ||
|
|
||
|
|
||
| // Append the file to the hidden input | ||
| fileNames.push(file.name); | ||
|
|
||
| uploadFile(file); | ||
| handleFile(file); | ||
| } | ||
| }); | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚨 suggestion (security): Consider sanitizing file name content when inserting into innerHTML.
Encode or sanitize file names before inserting into innerHTML to prevent issues from unexpected characters.
Suggested implementation:
Ensure that the sanitizeHTML function is placed in an appropriate scope (outside of other functions if needed) so that it can be used throughout the file if similar sanitization is required elsewhere.