Skip to content

Commit

Permalink
Fix non-file dragging bug #1037 (#1245)
Browse files Browse the repository at this point in the history
Signed off by @D3V-D.
  • Loading branch information
D3V-D authored May 4, 2024
1 parent 85a9d82 commit 9e25c75
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 18 deletions.
4 changes: 4 additions & 0 deletions www/css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@
padding-left: 1px !important;
}

.dragging-over * {
pointer-events: none;
}

.form-control {
margin-top: 2px;
}
Expand Down
95 changes: 77 additions & 18 deletions www/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -1521,17 +1521,11 @@ function displayFileSelect () {

// Set the main drop zone
if (!params.disableDragAndDrop) {
configDropZone.addEventListener('dragover', handleGlobalDragover);
configDropZone.addEventListener('dragleave', function () {
configDropZone.style.border = '';
});
// Also set a global drop zone (allows us to ensure Config is always displayed for the file drop)
globalDropZone.addEventListener('dragover', function (e) {
e.preventDefault();
if (configDropZone.style.display === 'none') document.getElementById('btnConfigure').click();
e.dataTransfer.dropEffect = 'link';
});
// Set a global drop zone, so that whole page is enabled for drag and drop
globalDropZone.addEventListener('dragover', handleGlobalDragover);
globalDropZone.addEventListener('dragleave', handleGlobalDragleave);
globalDropZone.addEventListener('drop', handleFileDrop);
globalDropZone.addEventListener('dragenter', handleGlobalDragenter);
}

if (isFireFoxOsNativeFileApiAvailable) {
Expand Down Expand Up @@ -1635,39 +1629,104 @@ document.getElementById('archiveFilesLbl').addEventListener('keydown', function
}
});

/** Drag and Drop handling for ZIM files */

// Keep track of entrance event so we only fire the correct leave event
var enteredElement;

function handleGlobalDragenter (e) {
e.preventDefault();
// Disable pointer-events on children so they don't interfere with dragleave events
globalDropZone.classList.add('dragging-over');
enteredElement = e.target;
}

function handleGlobalDragover (e) {
e.preventDefault();
e.dataTransfer.dropEffect = 'link';
configDropZone.style.border = '3px dotted red';

if (hasType(e.dataTransfer.types, 'Files') && !hasInvalidType(e.dataTransfer.types)) {
e.dataTransfer.dropEffect = 'link';
globalDropZone.classList.add('dragging-over');
globalDropZone.style.border = '3px dashed red';
document.getElementById('btnConfigure').click();
}
}

function handleGlobalDragleave (e) {
e.preventDefault();
globalDropZone.style.border = '';
if (enteredElement === e.target) {
globalDropZone.classList.remove('dragging-over');
// Only return to page if a ZIM is actually loaded
if (selectedArchive.isReady()) {
returnToCurrentPage();
}
}
}

function handleIframeDragover (e) {
e.preventDefault();
e.dataTransfer.dropEffect = 'link';
document.getElementById('btnConfigure').click();
if (hasType(e.dataTransfer.types, 'Files') && !hasInvalidType(e.dataTransfer.types)) {
globalDropZone.classList.add('dragging-over');
e.dataTransfer.dropEffect = 'link';
document.getElementById('btnConfigure').click();
}
}

function handleIframeDrop (e) {
e.stopPropagation();
e.preventDefault();
e.stopPropagation();
}

// Add type check for chromium browsers, since they count images on the same page as files
function hasInvalidType (typesList) {
for (var i = 0; i < typesList.length; i++) {
// Use indexOf() instead of startsWith() for IE11 support. Also, IE11 uses Text instead of text (and so does Opera).
// This is not comprehensive, but should cover most cases.
if (typesList[i].indexOf('image') === 0 || typesList[i].indexOf('text') === 0 || typesList[i].indexOf('Text') === 0|| typesList[i].indexOf('video') === 0) {
return true;
}
}
return false;
}

// IE11 doesn't support .includes(), so custom function to check for presence of types
function hasType (typesList, type) {
for (var i = 0; i < typesList.length; i++) {
if (typesList[i] === type) {
return true;
}
}
return false;
}

// Function to switch back to currently loaded page from config page after dragleave event
function returnToCurrentPage () {
document.getElementById('liConfigureNav').classList.remove('active');
document.getElementById('liHomeNav').classList.add('active');
uiUtil.tabTransitionToSection('home', params.showUIAnimations);
const welcomeText = document.getElementById('welcomeText');
welcomeText.style.display = 'none';
viewArticle.style.display = 'none';
}

async function handleFileDrop (packet) {
packet.stopPropagation();
packet.preventDefault();
configDropZone.style.border = '';
globalDropZone.style.border = '';
globalDropZone.classList.remove('dragging-over');
var files = packet.dataTransfer.files;
document.getElementById('selectInstructions').style.display = 'none';
document.getElementById('fileSelectionButtonContainer').style.display = 'none';
document.getElementById('downloadInstruction').style.display = 'none';
document.getElementById('selectorsDisplay').style.display = 'inline';
archiveFiles.value = null;

// value will be set to true if a folder is dropped then there will be no need to
// Value will be set to true if a folder is dropped then there will be no need to
// call the `setLocalArchiveFromFileList`
let loadZim = true;

// no previous file will be loaded in case of FileSystemApi
// No previous file will be loaded in case of FileSystemApi
if (params.isFileSystemApiSupported) loadZim = await abstractFilesystemAccess.handleFolderOrFileDropViaFileSystemAPI(packet);
else if (params.isWebkitDirApiSupported) {
const ret = await abstractFilesystemAccess.handleFolderOrFileDropViaWebkit(packet);
Expand Down

0 comments on commit 9e25c75

Please sign in to comment.