mirror of
https://github.com/gchq/CyberChef.git
synced 2025-04-20 23:06:16 -04:00
Folders can now be dropped into the CyberChef input
This commit is contained in:
parent
cdde7166cf
commit
dd6eae52ef
1 changed files with 89 additions and 2 deletions
|
@ -905,7 +905,7 @@ class InputWaiter {
|
||||||
*
|
*
|
||||||
* @param {event} e
|
* @param {event} e
|
||||||
*/
|
*/
|
||||||
inputDrop(e) {
|
async inputDrop(e) {
|
||||||
// This will be set if we're dragging an operation
|
// This will be set if we're dragging an operation
|
||||||
if (e.dataTransfer.effectAllowed === "move")
|
if (e.dataTransfer.effectAllowed === "move")
|
||||||
return false;
|
return false;
|
||||||
|
@ -917,8 +917,95 @@ class InputWaiter {
|
||||||
// Dropped text is handled by the editor itself
|
// Dropped text is handled by the editor itself
|
||||||
if (e.dataTransfer.getData("Text")) return;
|
if (e.dataTransfer.getData("Text")) return;
|
||||||
|
|
||||||
|
// Dropped files
|
||||||
if (e?.dataTransfer?.files?.length > 0) {
|
if (e?.dataTransfer?.files?.length > 0) {
|
||||||
this.loadUIFiles(e.dataTransfer.files);
|
let files = [];
|
||||||
|
|
||||||
|
// Handling the files as FileSystemEntry objects allows us to open directories,
|
||||||
|
// but relies on a function that may be deprecated in future.
|
||||||
|
if (Object.prototype.hasOwnProperty.call(DataTransferItem.prototype, "webkitGetAsEntry")) {
|
||||||
|
const fileEntries = await this.getAllFileEntries(e.dataTransfer.items);
|
||||||
|
// Read all FileEntry objects into File objects
|
||||||
|
files = await Promise.all(fileEntries.map(async fe => await this.getFile(fe)));
|
||||||
|
} else {
|
||||||
|
files = e.dataTransfer.files;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.loadUIFiles(files);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {DataTransferItemList} dataTransferItemList
|
||||||
|
* @returns {FileSystemEntry[]}
|
||||||
|
*/
|
||||||
|
async getAllFileEntries(dataTransferItemList) {
|
||||||
|
const fileEntries = [];
|
||||||
|
// Use BFS to traverse entire directory/file structure
|
||||||
|
const queue = [];
|
||||||
|
// Unfortunately dataTransferItemList is not iterable i.e. no forEach
|
||||||
|
for (let i = 0; i < dataTransferItemList.length; i++) {
|
||||||
|
// Note webkitGetAsEntry a non-standard feature and may change
|
||||||
|
// Usage is necessary for handling directories
|
||||||
|
queue.push(dataTransferItemList[i].webkitGetAsEntry());
|
||||||
|
}
|
||||||
|
while (queue.length > 0) {
|
||||||
|
const entry = queue.shift();
|
||||||
|
if (entry.isFile) {
|
||||||
|
fileEntries.push(entry);
|
||||||
|
} else if (entry.isDirectory) {
|
||||||
|
queue.push(...await this.readAllDirectoryEntries(entry.createReader()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fileEntries;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all the entries (files or sub-directories) in a directory by calling
|
||||||
|
* readEntries until it returns empty array
|
||||||
|
*
|
||||||
|
* @param {FileSystemDirectoryReader} directoryReader
|
||||||
|
* @returns {FileSystemEntry[]}
|
||||||
|
*/
|
||||||
|
async readAllDirectoryEntries(directoryReader) {
|
||||||
|
const entries = [];
|
||||||
|
let readEntries = await this.readEntriesPromise(directoryReader);
|
||||||
|
while (readEntries.length > 0) {
|
||||||
|
entries.push(...readEntries);
|
||||||
|
readEntries = await this.readEntriesPromise(directoryReader);
|
||||||
|
}
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrap readEntries in a promise to make working with readEntries easier.
|
||||||
|
* readEntries will return only some of the entries in a directory
|
||||||
|
* e.g. Chrome returns at most 100 entries at a time
|
||||||
|
*
|
||||||
|
* @param {FileSystemDirectoryReader} directoryReader
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
async readEntriesPromise(directoryReader) {
|
||||||
|
try {
|
||||||
|
return await new Promise((resolve, reject) => {
|
||||||
|
directoryReader.readEntries(resolve, reject);
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
log.error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a FileEntry and returns it as a File object
|
||||||
|
* @param {FileEntry} fileEntry
|
||||||
|
* @returns {File}
|
||||||
|
*/
|
||||||
|
async getFile(fileEntry) {
|
||||||
|
try {
|
||||||
|
return new Promise((resolve, reject) => fileEntry.file(resolve, reject));
|
||||||
|
} catch (err) {
|
||||||
|
log.error(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue