Skip to content

Commit

Permalink
Merge pull request #1556 from jadu/QU-4501
Browse files Browse the repository at this point in the history
Qu 4501
  • Loading branch information
Stanton authored Sep 12, 2024
2 parents 0740207 + 70c9524 commit 81292e4
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 0 deletions.
14 changes: 14 additions & 0 deletions js/DropZone/DropZoneComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,20 @@ class DropZoneComponent {
input.value = '';
input.type = '';
input.type = 'file';

let rawFiles = this.instanceManager.getFiles(id);
const dataTransfer = new DataTransfer();
let wasFile = false;
for (let i = 0; i < rawFiles.length; i++) {
if (rawFiles[i].raw instanceof File){
dataTransfer.items.add(rawFiles[i].raw);
wasFile = true;
}
}
if (wasFile){
// this guard exists as some js tests do not provide a file type as the input value.
input.files = dataTransfer.files;
}
});

// visually hide input - this should ideally be done in the CSS also to prevent a
Expand Down
43 changes: 43 additions & 0 deletions tests/js/web/DropZone/DropZoneComponentTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,49 @@ describe('DropZoneComponent', () => {
expect($fileInput.val()).to.equal('');
});

it('should retain the input node files on change', () => {
// we need to explicitly set type="file" here. Originally it is configured as type="text" presumably to avoid the same security issue explained below
$fileInput = $('<input type="file" id="fileInput" value="foo">');
const change = new Event('change');
const getDTFileList = (fileInput, ...appendFiles) => {
const dataTransfer = new DataTransfer();
if (fileInput.files && fileInput.files.length > 0) {
// add all our File objects to prepopulate the DataTransfer
for (let i = 0; i < fileInput.files.length; i++) {
dataTransfer.items.add(fileInput.files[i]);
}
}
appendFiles.forEach((appendFile)=>{
dataTransfer.items.add(appendFile);
});
return dataTransfer.files;
}
/**
* There is actually no way to programatically add a File object to Input.files other than to duplicate the DataTransfer process...
* This is due to strict browser security measures. Yes it is a bit of a hack, but there are simply no other options for initalising our input.
* Feel free to refactor this should a future version of ES add this functionality in some way.
*/
const file = new File(['Lorem ipsum dolor'], 'example.txt', { type: 'text/plain' });
$fileInput[0].files = getDTFileList($fileInput[0], file);

let rawFiles = [];
for (let i = 0; i < $fileInput[0].files.length; i++) {
$fileInput[0].files[i]
rawFiles.push({'raw': $fileInput[0].files[i]})
}

instanceManager.getFiles.returns(rawFiles);
dropZoneComponent.processInputNode($fileInput[0], 0, options.showInputNode);
$fileInput[0].dispatchEvent(change);
//debugger;
const dataTransferFile = getDTFileList($fileInput[0])[0];
const inputFile = $fileInput[0].files[0];
expect(inputFile.name).to.equal(dataTransferFile.name);
expect(inputFile.lastModified).to.equal(dataTransferFile.lastModified);
expect(inputFile.size).to.equal(dataTransferFile.size);
expect(inputFile.type).to.equal(dataTransferFile.type);
});

it('should not hide the input if specified in options', () => {
const options = { showInputNode: true, inputNodeId: 'fileInput' };
const display = $fileInput.css('display');
Expand Down

0 comments on commit 81292e4

Please sign in to comment.