mirror of
https://github.com/misterunknown/ifm.git
synced 2025-08-11 10:34:00 +02:00
removed some jquery code and replaced it with plain javascript
This commit is contained in:
241
build/libifm.php
241
build/libifm.php
@@ -841,34 +841,48 @@ function IFM( params ) {
|
|||||||
*/
|
*/
|
||||||
this.showModal = function( content, options ) {
|
this.showModal = function( content, options ) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var modal = $( document.createElement( 'div' ) )
|
var modal = document.createElement( 'div' );
|
||||||
.addClass( "modal fade" )
|
modal.classList.add( 'modal', 'fade' );
|
||||||
.attr( 'id', 'ifmmodal' )
|
modal.id = 'ifmmodal';
|
||||||
.attr( 'role', 'dialog' );
|
modal.attributes.role = 'dialog';
|
||||||
var modalDialog = $( document.createElement( 'div' ) )
|
var modalDialog = document.createElement( 'div' );
|
||||||
.addClass( "modal-dialog" )
|
modalDialog.classList.add( 'modal-dialog' );
|
||||||
.attr( 'role', 'document' );
|
modalDialog.attributes.role = 'document';
|
||||||
if( options.large == true ) modalDialog.addClass( 'modal-lg' );
|
if( options.large == true ) modalDialog.classList.add( 'modal-lg' );
|
||||||
var modalContent = $(document.createElement('div'))
|
var modalContent = document.createElement('div');
|
||||||
.addClass("modal-content")
|
modalContent.classList.add( 'modal-content' );
|
||||||
.append( content );
|
modalContent.innerHTML = content;
|
||||||
modalDialog.append( modalContent );
|
modalDialog.appendChild( modalContent );
|
||||||
modal.append( modalDialog );
|
modal.appendChild( modalDialog );
|
||||||
$( document.body ).append( modal );
|
document.body.appendChild( modal );
|
||||||
modal.on('hide.bs.modal', function () { $(this).remove(); });
|
modal.addEventListener( 'hide.bs.modal', function( e ) { console.log( e ); $(this).remove(); });
|
||||||
modal.on('shown.bs.modal', function () {
|
modal.addEventListener( 'shown.bs.modal', function( e ) {
|
||||||
|
console.log( e );
|
||||||
var formElements = $(this).find('input, button');
|
var formElements = $(this).find('input, button');
|
||||||
if( formElements.length > 0 ) {
|
if( formElements.length > 0 ) {
|
||||||
formElements.first().focus();
|
formElements.first().focus();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
modal.modal('show');
|
|
||||||
|
// For this we have to use jquery, because bootstrap modals depend on them. Even the bs.modal
|
||||||
|
// events require jquery, as they cannot be recognized by addEventListener()
|
||||||
|
$(modal)
|
||||||
|
.on( 'hide.bs.modal', function( e ) { $(this).remove(); })
|
||||||
|
.on( 'shown.bs.modal', function( e ) {
|
||||||
|
console.log( e );
|
||||||
|
var formElements = $(this).find('input, button');
|
||||||
|
if( formElements.length > 0 ) {
|
||||||
|
formElements.first().focus();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.modal('show');
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hides a bootstrap modal
|
* Hides a bootstrap modal
|
||||||
*/
|
*/
|
||||||
this.hideModal = function() {
|
this.hideModal = function() {
|
||||||
|
// Hide the modal via jquery to get the hide.bs.modal event triggered
|
||||||
$('#ifmmodal').modal('hide');
|
$('#ifmmodal').modal('hide');
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -966,8 +980,8 @@ function IFM( params ) {
|
|||||||
});
|
});
|
||||||
self.fileCache = data;
|
self.fileCache = data;
|
||||||
var newTBody = Mustache.render( self.templates.filetable, { items: data, config: self.config } );
|
var newTBody = Mustache.render( self.templates.filetable, { items: data, config: self.config } );
|
||||||
$( "#filetable tbody" ).remove();
|
var filetable = document.getElementById( 'filetable' );
|
||||||
$( "#filetable" ).append( $(newTBody) );
|
filetable.innerHTML = newTBody;
|
||||||
$( '.clickable-row' ).click( function( event ) {
|
$( '.clickable-row' ).click( function( event ) {
|
||||||
if( event.ctrlKey ) {
|
if( event.ctrlKey ) {
|
||||||
$( this ).toggleClass( 'selectedItem' );
|
$( this ).toggleClass( 'selectedItem' );
|
||||||
@@ -1031,14 +1045,13 @@ function IFM( params ) {
|
|||||||
var contextMenu = new BootstrapMenu( '.clickable-row', {
|
var contextMenu = new BootstrapMenu( '.clickable-row', {
|
||||||
fetchElementData: function( row ) {
|
fetchElementData: function( row ) {
|
||||||
var data = {};
|
var data = {};
|
||||||
var selectedItems = Array.prototype.slice.call( document.getElementsByClassName( 'selectedItem' ) );
|
|
||||||
data.selected =
|
data.selected =
|
||||||
Array.prototype.slice.call( document.getElementsByClassName( 'selectedItem' ) )
|
Array.prototype.slice.call( document.getElementsByClassName( 'selectedItem' ) )
|
||||||
.map( function(e){ return ifm.fileCache.find( x => x.guid == e.children[0].children[0].id ); } );
|
.map( function(e){ return ifm.fileCache.find( x => x.guid == e.children[0].children[0].id ); } );
|
||||||
data.clicked = self.fileCache.find( x => x.guid == row[0].children[0].children[0].id );
|
data.clicked = self.fileCache.find( x => x.guid == row[0].children[0].children[0].id );
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
actionGroups:[
|
actionsGroups:[
|
||||||
['edit', 'extract', 'rename'],
|
['edit', 'extract', 'rename'],
|
||||||
['copymove', 'download'],
|
['copymove', 'download'],
|
||||||
['delete']
|
['delete']
|
||||||
@@ -1051,7 +1064,7 @@ function IFM( params ) {
|
|||||||
},
|
},
|
||||||
iconClass: "icon icon-pencil",
|
iconClass: "icon icon-pencil",
|
||||||
isShown: function( data ) {
|
isShown: function( data ) {
|
||||||
return ( self.config.edit && data.clicked.eaction == "edit" );
|
return ( self.config.edit && data.clicked.eaction == "edit" && !data.selected.length );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
extract: {
|
extract: {
|
||||||
@@ -1061,7 +1074,7 @@ function IFM( params ) {
|
|||||||
},
|
},
|
||||||
iconClass: "icon icon-archive",
|
iconClass: "icon icon-archive",
|
||||||
isShown: function( data ) {
|
isShown: function( data ) {
|
||||||
return ( self.config.extract && data.clicked.eaction == "extract" );
|
return ( self.config.extract && data.clicked.eaction == "extract" && !data.selected.length );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
rename: {
|
rename: {
|
||||||
@@ -1070,7 +1083,7 @@ function IFM( params ) {
|
|||||||
self.showRenameFileDialog( data.clicked.name );
|
self.showRenameFileDialog( data.clicked.name );
|
||||||
},
|
},
|
||||||
iconClass: "icon icon-terminal",
|
iconClass: "icon icon-terminal",
|
||||||
isShown: function() { return self.config.rename; }
|
isShown: function( data ) { return ( self.config.rename && !data.selected.length ); }
|
||||||
},
|
},
|
||||||
copymove: {
|
copymove: {
|
||||||
name: function( data ) {
|
name: function( data ) {
|
||||||
@@ -1081,9 +1094,9 @@ function IFM( params ) {
|
|||||||
},
|
},
|
||||||
onClick: function( data ) {
|
onClick: function( data ) {
|
||||||
if( data.selected.length > 0 )
|
if( data.selected.length > 0 )
|
||||||
self.showCopyMoveDialog( data.selected.map(function( e ) { return e.name; }) );
|
self.showCopyMoveDialog( data.selected );
|
||||||
else
|
else
|
||||||
self.showCopyMoveDialog( data.clicked.name );
|
self.showCopyMoveDialog( data.clicked );
|
||||||
},
|
},
|
||||||
iconClass: "icon icon-folder-empty",
|
iconClass: "icon icon-folder-empty",
|
||||||
isShown: function() { return self.config.copymove; }
|
isShown: function() { return self.config.copymove; }
|
||||||
@@ -1232,7 +1245,7 @@ function IFM( params ) {
|
|||||||
*
|
*
|
||||||
* @params string name - name of the file
|
* @params string name - name of the file
|
||||||
*/
|
*/
|
||||||
this.editFile = function( name ) {
|
this.editFile = function( filename ) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: self.api,
|
url: self.api,
|
||||||
type: "POST",
|
type: "POST",
|
||||||
@@ -1240,7 +1253,7 @@ function IFM( params ) {
|
|||||||
data: ({
|
data: ({
|
||||||
api: "getContent",
|
api: "getContent",
|
||||||
dir: self.currentDir,
|
dir: self.currentDir,
|
||||||
filename: name
|
filename: filename
|
||||||
}),
|
}),
|
||||||
success: function( data ) {
|
success: function( data ) {
|
||||||
if( data.status == "OK" && data.data.content != null ) {
|
if( data.status == "OK" && data.data.content != null ) {
|
||||||
@@ -1429,16 +1442,12 @@ function IFM( params ) {
|
|||||||
error: function() { self.hideModal(); self.showMessage( "Error while fetching the folder tree.", "e" ) }
|
error: function() { self.hideModal(); self.showMessage( "Error while fetching the folder tree.", "e" ) }
|
||||||
});
|
});
|
||||||
$( '#copyButton' ).on( 'click', function() {
|
$( '#copyButton' ).on( 'click', function() {
|
||||||
items.forEach( function( item ) {
|
self.copyMove( items, $('#copyMoveTree .node-selected').data('path'), 'copy' );
|
||||||
self.copyMove( item.name, $('#copyMoveTree .node-selected').data('path'), 'copy' );
|
|
||||||
});
|
|
||||||
self.hideModal();
|
self.hideModal();
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
$( '#moveButton' ).on( 'click', function() {
|
$( '#moveButton' ).on( 'click', function() {
|
||||||
filenames.forEach( function( filename ) {
|
self.copyMove( items, $('#copyMoveTree .node-selected').data('path'), 'move' );
|
||||||
self.copyMove( item.name, $('#copyMoveTree .node-selected').data('path'), 'move' );
|
|
||||||
});
|
|
||||||
self.hideModal();
|
self.hideModal();
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
@@ -1455,34 +1464,38 @@ function IFM( params ) {
|
|||||||
* @params {string} destination - target directory
|
* @params {string} destination - target directory
|
||||||
* @params {string} action - action (copy|move)
|
* @params {string} action - action (copy|move)
|
||||||
*/
|
*/
|
||||||
this.copyMove = function( source, destination, action ) {
|
this.copyMove = function( sources, destination, action ) {
|
||||||
var id = self.generateGuid();
|
if( ! Array.isArray( sources ) )
|
||||||
self.task_add( { id: id, name: action.charAt(0).toUpperCase() + action.slice(1) + " " + source + " to " + destination } );
|
sources = [sources];
|
||||||
$.ajax({
|
sources.forEach( function( source ) {
|
||||||
url: self.api,
|
var id = self.generateGuid();
|
||||||
type: "POST",
|
self.task_add( { id: id, name: action.charAt(0).toUpperCase() + action.slice(1) + " " + source.name + " to " + destination } );
|
||||||
data: {
|
$.ajax({
|
||||||
dir: self.currentDir,
|
url: self.api,
|
||||||
api: "copyMove",
|
type: "POST",
|
||||||
action: action,
|
data: {
|
||||||
filename: source,
|
dir: self.currentDir,
|
||||||
destination: destination
|
api: "copyMove",
|
||||||
},
|
action: action,
|
||||||
dataType: "json",
|
filename: source.name,
|
||||||
success: function(data) {
|
destination: destination
|
||||||
if( data.status == "OK" ) {
|
},
|
||||||
self.showMessage( data.message, "s" );
|
dataType: "json",
|
||||||
} else {
|
success: function( data ) {
|
||||||
self.showMessage( data.message, "e" );
|
if( data.status == "OK" ) {
|
||||||
|
self.showMessage( data.message, "s" );
|
||||||
|
} else {
|
||||||
|
self.showMessage( data.message, "e" );
|
||||||
|
}
|
||||||
|
self.refreshFileTable();
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
self.showMessage( "General error occured.", "e" );
|
||||||
|
},
|
||||||
|
complete: function() {
|
||||||
|
self.task_done( id );
|
||||||
}
|
}
|
||||||
self.refreshFileTable();
|
});
|
||||||
},
|
|
||||||
error: function() {
|
|
||||||
self.showMessage( "General error occured.", "e" );
|
|
||||||
},
|
|
||||||
complete: function() {
|
|
||||||
self.task_done( id );
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1509,9 +1522,11 @@ function IFM( params ) {
|
|||||||
self.hideModal();
|
self.hideModal();
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
form.find('#extractCustomLocation').on( 'click', function(e) {
|
form.find('#extractCustomLocation')
|
||||||
$(e.target).prev().children().first().prop( 'checked', true );
|
.on( 'click', function(e) {
|
||||||
});
|
$(e.target).prev().children().first().prop( 'checked', true );
|
||||||
|
})
|
||||||
|
.on( 'keypress', self.preventEnter );
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2063,6 +2078,7 @@ function IFM( params ) {
|
|||||||
if( $(e.target).closest('input')[0] || $(e.target).closest('textarea')[0] )
|
if( $(e.target).closest('input')[0] || $(e.target).closest('textarea')[0] )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// global key events
|
||||||
switch( e.key ) {
|
switch( e.key ) {
|
||||||
case '/':
|
case '/':
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -2120,14 +2136,6 @@ function IFM( params ) {
|
|||||||
self.changeDirectory( '..' );
|
self.changeDirectory( '..' );
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
case 'l':
|
|
||||||
case 'ArrowRight':
|
|
||||||
e.preventDefault();
|
|
||||||
var item = $('.highlightedItem');
|
|
||||||
if( item.hasClass('isDir') )
|
|
||||||
self.changeDirectory( item.data( 'filename' ) );
|
|
||||||
return;
|
|
||||||
break;
|
|
||||||
case 'j':
|
case 'j':
|
||||||
case 'ArrowDown':
|
case 'ArrowDown':
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -2140,79 +2148,79 @@ function IFM( params ) {
|
|||||||
self.highlightItem('prev');
|
self.highlightItem('prev');
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// key events which need a highlighted item
|
||||||
|
var element = document.getElementsByClassName( 'highlightedItem' )[0];
|
||||||
|
if( ! element )
|
||||||
|
return;
|
||||||
|
item = self.fileCache.find( x => x.guid == element.children[0].children[0].id );
|
||||||
|
|
||||||
|
switch( e.key ) {
|
||||||
|
case 'l':
|
||||||
|
case 'ArrowRight':
|
||||||
|
e.preventDefault();
|
||||||
|
if( item.type == "dir" )
|
||||||
|
self.changeDirectory( item.name );
|
||||||
|
return;
|
||||||
|
break;
|
||||||
case 'Escape':
|
case 'Escape':
|
||||||
if( $(':focus').is( '.clickable-row td:first-child a:first-child' ) && $('.highlightedItem').length ) {
|
if( element.children[0].children[0] == document.activeElement ) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
$('.highlightedItem').removeClass( 'highlightedItem' );
|
element.classList.toggle( 'highlightedItem' );
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
case ' ': // todo: make it work only when noting other is focused
|
case ' ': // todo: make it work only when noting other is focused
|
||||||
case 'Enter':
|
case 'Enter':
|
||||||
if( $(':focus').is( '.clickable-row td:first-child a:first-child' ) ) {
|
if( element.children[0].children[0] == document.activeElement ) {
|
||||||
var trParent = $(':focus').parent().parent();
|
if( e.key == 'Enter' && element.classList.contains( 'isDir' ) ) {
|
||||||
if( e.key == 'Enter' && trParent.hasClass( 'isDir' ) ) {
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
self.changeDirectory( trParent.data( 'filename' ) );
|
self.changeDirectory( item.name );
|
||||||
} else if( e.key == ' ' && ! trParent.is( ':first-child' ) ) {
|
} else if( e.key == ' ' && item.name != ".." ) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
var item = $('.highlightedItem');
|
element.classList.toggle( 'selectedItem' );
|
||||||
if( item.is( 'tr' ) )
|
|
||||||
item.toggleClass( 'selectedItem' );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Some operations do not work if the highlighted item is the parent
|
||||||
* Some operations do not work if the highlighted item is the parent
|
// directory. In these cases the keybindings are ignored.
|
||||||
* directory. In these cases the keybindings are ignored.
|
if( item.name == ".." )
|
||||||
*/
|
|
||||||
if( $('.highlightedItem').data( 'filename' ) == ".." )
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
var selectedItems = Array.prototype.slice.call( document.getElementsByClassName( 'selectedItem' ) )
|
||||||
|
.map( function( e ) { return self.fileCache[e.children[0].children[0].id] } );
|
||||||
|
|
||||||
switch( e.key ) {
|
switch( e.key ) {
|
||||||
case 'Delete':
|
case 'Delete':
|
||||||
if( self.config.delete ) {
|
if( self.config.delete ) {
|
||||||
if( $('#filetable tr.selectedItem').length > 0 ) {
|
if( selectedItems.length > 0 ) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
self.showMultiDeleteDialog();
|
self.showMultiDeleteDialog();
|
||||||
} else {
|
} else
|
||||||
var item = $('.highlightedItem');
|
self.showDeleteFileDialog( item.name );
|
||||||
if( item.length )
|
|
||||||
self.showDeleteFileDialog( item.data( 'filename' ) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
case 'm':
|
case 'm':
|
||||||
if( self.config.copymove ) {
|
if( self.config.copymove ) {
|
||||||
var item = $('.highlightedItem');
|
self.showCopyMoveDialog( selectedItems );
|
||||||
if( item.length ) {
|
|
||||||
e.preventDefault();
|
|
||||||
self.showCopyMoveDialog( item.data( 'filename' ) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
if( self.config.edit ) {
|
if( self.config.edit && item.eaction == "edit" ) {
|
||||||
var item = $('.highlightedItem');
|
e.preventDefault();
|
||||||
if( item.length && ! item.hasClass( 'isDir' ) ) {
|
self.editFile( item.name );
|
||||||
e.preventDefault();
|
} else if( self.config.extract && item.eaction == "extract" ) {
|
||||||
var action = item.data( 'eaction' );
|
e.preventDefault();
|
||||||
switch( action ) {
|
self.showExtractFileDialog( item.name );
|
||||||
case 'extract':
|
|
||||||
self.showExtractFileDialog( item.data( 'filename' ) );
|
|
||||||
break;
|
|
||||||
case 'edit':
|
|
||||||
self.editFile( item.data( 'filename' ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
@@ -2262,8 +2270,7 @@ function IFM( params ) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.initApplication = function() {
|
this.initApplication = function() {
|
||||||
self.rootElement.html(
|
self.rootElement.innerHTML = Mustache.render(
|
||||||
Mustache.render(
|
|
||||||
self.templates.app,
|
self.templates.app,
|
||||||
{
|
{
|
||||||
showpath: "/",
|
showpath: "/",
|
||||||
@@ -2271,9 +2278,7 @@ function IFM( params ) {
|
|||||||
ftbuttons: function(){
|
ftbuttons: function(){
|
||||||
return ( self.config.edit || self.config.rename || self.config.delete || self.config.zipnload || self.config.extract );
|
return ( self.config.edit || self.config.rename || self.config.delete || self.config.zipnload || self.config.extract );
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
)
|
|
||||||
);
|
|
||||||
// bind static buttons
|
// bind static buttons
|
||||||
$("#refresh").click(function(){
|
$("#refresh").click(function(){
|
||||||
self.refreshFileTable();
|
self.refreshFileTable();
|
||||||
@@ -2322,7 +2327,7 @@ function IFM( params ) {
|
|||||||
$('#filedropoverlay').css( 'display', 'none' );
|
$('#filedropoverlay').css( 'display', 'none' );
|
||||||
});
|
});
|
||||||
// handle keystrokes
|
// handle keystrokes
|
||||||
$(document).on( 'keydown', self.handleKeystrokes );
|
document.onkeydown = self.handleKeystrokes;
|
||||||
// handle history manipulation
|
// handle history manipulation
|
||||||
window.onpopstate = self.historyPopstateHandler;
|
window.onpopstate = self.historyPopstateHandler;
|
||||||
// load initial file table
|
// load initial file table
|
||||||
@@ -2334,7 +2339,7 @@ function IFM( params ) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.init = function( id ) {
|
this.init = function( id ) {
|
||||||
self.rootElement = $('#'+id);
|
self.rootElement = document.getElementById( id );
|
||||||
this.initLoadConfig();
|
this.initLoadConfig();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
241
ifm.php
241
ifm.php
@@ -841,34 +841,48 @@ function IFM( params ) {
|
|||||||
*/
|
*/
|
||||||
this.showModal = function( content, options ) {
|
this.showModal = function( content, options ) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var modal = $( document.createElement( 'div' ) )
|
var modal = document.createElement( 'div' );
|
||||||
.addClass( "modal fade" )
|
modal.classList.add( 'modal', 'fade' );
|
||||||
.attr( 'id', 'ifmmodal' )
|
modal.id = 'ifmmodal';
|
||||||
.attr( 'role', 'dialog' );
|
modal.attributes.role = 'dialog';
|
||||||
var modalDialog = $( document.createElement( 'div' ) )
|
var modalDialog = document.createElement( 'div' );
|
||||||
.addClass( "modal-dialog" )
|
modalDialog.classList.add( 'modal-dialog' );
|
||||||
.attr( 'role', 'document' );
|
modalDialog.attributes.role = 'document';
|
||||||
if( options.large == true ) modalDialog.addClass( 'modal-lg' );
|
if( options.large == true ) modalDialog.classList.add( 'modal-lg' );
|
||||||
var modalContent = $(document.createElement('div'))
|
var modalContent = document.createElement('div');
|
||||||
.addClass("modal-content")
|
modalContent.classList.add( 'modal-content' );
|
||||||
.append( content );
|
modalContent.innerHTML = content;
|
||||||
modalDialog.append( modalContent );
|
modalDialog.appendChild( modalContent );
|
||||||
modal.append( modalDialog );
|
modal.appendChild( modalDialog );
|
||||||
$( document.body ).append( modal );
|
document.body.appendChild( modal );
|
||||||
modal.on('hide.bs.modal', function () { $(this).remove(); });
|
modal.addEventListener( 'hide.bs.modal', function( e ) { console.log( e ); $(this).remove(); });
|
||||||
modal.on('shown.bs.modal', function () {
|
modal.addEventListener( 'shown.bs.modal', function( e ) {
|
||||||
|
console.log( e );
|
||||||
var formElements = $(this).find('input, button');
|
var formElements = $(this).find('input, button');
|
||||||
if( formElements.length > 0 ) {
|
if( formElements.length > 0 ) {
|
||||||
formElements.first().focus();
|
formElements.first().focus();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
modal.modal('show');
|
|
||||||
|
// For this we have to use jquery, because bootstrap modals depend on them. Even the bs.modal
|
||||||
|
// events require jquery, as they cannot be recognized by addEventListener()
|
||||||
|
$(modal)
|
||||||
|
.on( 'hide.bs.modal', function( e ) { $(this).remove(); })
|
||||||
|
.on( 'shown.bs.modal', function( e ) {
|
||||||
|
console.log( e );
|
||||||
|
var formElements = $(this).find('input, button');
|
||||||
|
if( formElements.length > 0 ) {
|
||||||
|
formElements.first().focus();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.modal('show');
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hides a bootstrap modal
|
* Hides a bootstrap modal
|
||||||
*/
|
*/
|
||||||
this.hideModal = function() {
|
this.hideModal = function() {
|
||||||
|
// Hide the modal via jquery to get the hide.bs.modal event triggered
|
||||||
$('#ifmmodal').modal('hide');
|
$('#ifmmodal').modal('hide');
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -966,8 +980,8 @@ function IFM( params ) {
|
|||||||
});
|
});
|
||||||
self.fileCache = data;
|
self.fileCache = data;
|
||||||
var newTBody = Mustache.render( self.templates.filetable, { items: data, config: self.config } );
|
var newTBody = Mustache.render( self.templates.filetable, { items: data, config: self.config } );
|
||||||
$( "#filetable tbody" ).remove();
|
var filetable = document.getElementById( 'filetable' );
|
||||||
$( "#filetable" ).append( $(newTBody) );
|
filetable.innerHTML = newTBody;
|
||||||
$( '.clickable-row' ).click( function( event ) {
|
$( '.clickable-row' ).click( function( event ) {
|
||||||
if( event.ctrlKey ) {
|
if( event.ctrlKey ) {
|
||||||
$( this ).toggleClass( 'selectedItem' );
|
$( this ).toggleClass( 'selectedItem' );
|
||||||
@@ -1031,14 +1045,13 @@ function IFM( params ) {
|
|||||||
var contextMenu = new BootstrapMenu( '.clickable-row', {
|
var contextMenu = new BootstrapMenu( '.clickable-row', {
|
||||||
fetchElementData: function( row ) {
|
fetchElementData: function( row ) {
|
||||||
var data = {};
|
var data = {};
|
||||||
var selectedItems = Array.prototype.slice.call( document.getElementsByClassName( 'selectedItem' ) );
|
|
||||||
data.selected =
|
data.selected =
|
||||||
Array.prototype.slice.call( document.getElementsByClassName( 'selectedItem' ) )
|
Array.prototype.slice.call( document.getElementsByClassName( 'selectedItem' ) )
|
||||||
.map( function(e){ return ifm.fileCache.find( x => x.guid == e.children[0].children[0].id ); } );
|
.map( function(e){ return ifm.fileCache.find( x => x.guid == e.children[0].children[0].id ); } );
|
||||||
data.clicked = self.fileCache.find( x => x.guid == row[0].children[0].children[0].id );
|
data.clicked = self.fileCache.find( x => x.guid == row[0].children[0].children[0].id );
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
actionGroups:[
|
actionsGroups:[
|
||||||
['edit', 'extract', 'rename'],
|
['edit', 'extract', 'rename'],
|
||||||
['copymove', 'download'],
|
['copymove', 'download'],
|
||||||
['delete']
|
['delete']
|
||||||
@@ -1051,7 +1064,7 @@ function IFM( params ) {
|
|||||||
},
|
},
|
||||||
iconClass: "icon icon-pencil",
|
iconClass: "icon icon-pencil",
|
||||||
isShown: function( data ) {
|
isShown: function( data ) {
|
||||||
return ( self.config.edit && data.clicked.eaction == "edit" );
|
return ( self.config.edit && data.clicked.eaction == "edit" && !data.selected.length );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
extract: {
|
extract: {
|
||||||
@@ -1061,7 +1074,7 @@ function IFM( params ) {
|
|||||||
},
|
},
|
||||||
iconClass: "icon icon-archive",
|
iconClass: "icon icon-archive",
|
||||||
isShown: function( data ) {
|
isShown: function( data ) {
|
||||||
return ( self.config.extract && data.clicked.eaction == "extract" );
|
return ( self.config.extract && data.clicked.eaction == "extract" && !data.selected.length );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
rename: {
|
rename: {
|
||||||
@@ -1070,7 +1083,7 @@ function IFM( params ) {
|
|||||||
self.showRenameFileDialog( data.clicked.name );
|
self.showRenameFileDialog( data.clicked.name );
|
||||||
},
|
},
|
||||||
iconClass: "icon icon-terminal",
|
iconClass: "icon icon-terminal",
|
||||||
isShown: function() { return self.config.rename; }
|
isShown: function( data ) { return ( self.config.rename && !data.selected.length ); }
|
||||||
},
|
},
|
||||||
copymove: {
|
copymove: {
|
||||||
name: function( data ) {
|
name: function( data ) {
|
||||||
@@ -1081,9 +1094,9 @@ function IFM( params ) {
|
|||||||
},
|
},
|
||||||
onClick: function( data ) {
|
onClick: function( data ) {
|
||||||
if( data.selected.length > 0 )
|
if( data.selected.length > 0 )
|
||||||
self.showCopyMoveDialog( data.selected.map(function( e ) { return e.name; }) );
|
self.showCopyMoveDialog( data.selected );
|
||||||
else
|
else
|
||||||
self.showCopyMoveDialog( data.clicked.name );
|
self.showCopyMoveDialog( data.clicked );
|
||||||
},
|
},
|
||||||
iconClass: "icon icon-folder-empty",
|
iconClass: "icon icon-folder-empty",
|
||||||
isShown: function() { return self.config.copymove; }
|
isShown: function() { return self.config.copymove; }
|
||||||
@@ -1232,7 +1245,7 @@ function IFM( params ) {
|
|||||||
*
|
*
|
||||||
* @params string name - name of the file
|
* @params string name - name of the file
|
||||||
*/
|
*/
|
||||||
this.editFile = function( name ) {
|
this.editFile = function( filename ) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: self.api,
|
url: self.api,
|
||||||
type: "POST",
|
type: "POST",
|
||||||
@@ -1240,7 +1253,7 @@ function IFM( params ) {
|
|||||||
data: ({
|
data: ({
|
||||||
api: "getContent",
|
api: "getContent",
|
||||||
dir: self.currentDir,
|
dir: self.currentDir,
|
||||||
filename: name
|
filename: filename
|
||||||
}),
|
}),
|
||||||
success: function( data ) {
|
success: function( data ) {
|
||||||
if( data.status == "OK" && data.data.content != null ) {
|
if( data.status == "OK" && data.data.content != null ) {
|
||||||
@@ -1429,16 +1442,12 @@ function IFM( params ) {
|
|||||||
error: function() { self.hideModal(); self.showMessage( "Error while fetching the folder tree.", "e" ) }
|
error: function() { self.hideModal(); self.showMessage( "Error while fetching the folder tree.", "e" ) }
|
||||||
});
|
});
|
||||||
$( '#copyButton' ).on( 'click', function() {
|
$( '#copyButton' ).on( 'click', function() {
|
||||||
items.forEach( function( item ) {
|
self.copyMove( items, $('#copyMoveTree .node-selected').data('path'), 'copy' );
|
||||||
self.copyMove( item.name, $('#copyMoveTree .node-selected').data('path'), 'copy' );
|
|
||||||
});
|
|
||||||
self.hideModal();
|
self.hideModal();
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
$( '#moveButton' ).on( 'click', function() {
|
$( '#moveButton' ).on( 'click', function() {
|
||||||
filenames.forEach( function( filename ) {
|
self.copyMove( items, $('#copyMoveTree .node-selected').data('path'), 'move' );
|
||||||
self.copyMove( item.name, $('#copyMoveTree .node-selected').data('path'), 'move' );
|
|
||||||
});
|
|
||||||
self.hideModal();
|
self.hideModal();
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
@@ -1455,34 +1464,38 @@ function IFM( params ) {
|
|||||||
* @params {string} destination - target directory
|
* @params {string} destination - target directory
|
||||||
* @params {string} action - action (copy|move)
|
* @params {string} action - action (copy|move)
|
||||||
*/
|
*/
|
||||||
this.copyMove = function( source, destination, action ) {
|
this.copyMove = function( sources, destination, action ) {
|
||||||
var id = self.generateGuid();
|
if( ! Array.isArray( sources ) )
|
||||||
self.task_add( { id: id, name: action.charAt(0).toUpperCase() + action.slice(1) + " " + source + " to " + destination } );
|
sources = [sources];
|
||||||
$.ajax({
|
sources.forEach( function( source ) {
|
||||||
url: self.api,
|
var id = self.generateGuid();
|
||||||
type: "POST",
|
self.task_add( { id: id, name: action.charAt(0).toUpperCase() + action.slice(1) + " " + source.name + " to " + destination } );
|
||||||
data: {
|
$.ajax({
|
||||||
dir: self.currentDir,
|
url: self.api,
|
||||||
api: "copyMove",
|
type: "POST",
|
||||||
action: action,
|
data: {
|
||||||
filename: source,
|
dir: self.currentDir,
|
||||||
destination: destination
|
api: "copyMove",
|
||||||
},
|
action: action,
|
||||||
dataType: "json",
|
filename: source.name,
|
||||||
success: function(data) {
|
destination: destination
|
||||||
if( data.status == "OK" ) {
|
},
|
||||||
self.showMessage( data.message, "s" );
|
dataType: "json",
|
||||||
} else {
|
success: function( data ) {
|
||||||
self.showMessage( data.message, "e" );
|
if( data.status == "OK" ) {
|
||||||
|
self.showMessage( data.message, "s" );
|
||||||
|
} else {
|
||||||
|
self.showMessage( data.message, "e" );
|
||||||
|
}
|
||||||
|
self.refreshFileTable();
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
self.showMessage( "General error occured.", "e" );
|
||||||
|
},
|
||||||
|
complete: function() {
|
||||||
|
self.task_done( id );
|
||||||
}
|
}
|
||||||
self.refreshFileTable();
|
});
|
||||||
},
|
|
||||||
error: function() {
|
|
||||||
self.showMessage( "General error occured.", "e" );
|
|
||||||
},
|
|
||||||
complete: function() {
|
|
||||||
self.task_done( id );
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1509,9 +1522,11 @@ function IFM( params ) {
|
|||||||
self.hideModal();
|
self.hideModal();
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
form.find('#extractCustomLocation').on( 'click', function(e) {
|
form.find('#extractCustomLocation')
|
||||||
$(e.target).prev().children().first().prop( 'checked', true );
|
.on( 'click', function(e) {
|
||||||
});
|
$(e.target).prev().children().first().prop( 'checked', true );
|
||||||
|
})
|
||||||
|
.on( 'keypress', self.preventEnter );
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2063,6 +2078,7 @@ function IFM( params ) {
|
|||||||
if( $(e.target).closest('input')[0] || $(e.target).closest('textarea')[0] )
|
if( $(e.target).closest('input')[0] || $(e.target).closest('textarea')[0] )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// global key events
|
||||||
switch( e.key ) {
|
switch( e.key ) {
|
||||||
case '/':
|
case '/':
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -2120,14 +2136,6 @@ function IFM( params ) {
|
|||||||
self.changeDirectory( '..' );
|
self.changeDirectory( '..' );
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
case 'l':
|
|
||||||
case 'ArrowRight':
|
|
||||||
e.preventDefault();
|
|
||||||
var item = $('.highlightedItem');
|
|
||||||
if( item.hasClass('isDir') )
|
|
||||||
self.changeDirectory( item.data( 'filename' ) );
|
|
||||||
return;
|
|
||||||
break;
|
|
||||||
case 'j':
|
case 'j':
|
||||||
case 'ArrowDown':
|
case 'ArrowDown':
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -2140,79 +2148,79 @@ function IFM( params ) {
|
|||||||
self.highlightItem('prev');
|
self.highlightItem('prev');
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// key events which need a highlighted item
|
||||||
|
var element = document.getElementsByClassName( 'highlightedItem' )[0];
|
||||||
|
if( ! element )
|
||||||
|
return;
|
||||||
|
item = self.fileCache.find( x => x.guid == element.children[0].children[0].id );
|
||||||
|
|
||||||
|
switch( e.key ) {
|
||||||
|
case 'l':
|
||||||
|
case 'ArrowRight':
|
||||||
|
e.preventDefault();
|
||||||
|
if( item.type == "dir" )
|
||||||
|
self.changeDirectory( item.name );
|
||||||
|
return;
|
||||||
|
break;
|
||||||
case 'Escape':
|
case 'Escape':
|
||||||
if( $(':focus').is( '.clickable-row td:first-child a:first-child' ) && $('.highlightedItem').length ) {
|
if( element.children[0].children[0] == document.activeElement ) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
$('.highlightedItem').removeClass( 'highlightedItem' );
|
element.classList.toggle( 'highlightedItem' );
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
case ' ': // todo: make it work only when noting other is focused
|
case ' ': // todo: make it work only when noting other is focused
|
||||||
case 'Enter':
|
case 'Enter':
|
||||||
if( $(':focus').is( '.clickable-row td:first-child a:first-child' ) ) {
|
if( element.children[0].children[0] == document.activeElement ) {
|
||||||
var trParent = $(':focus').parent().parent();
|
if( e.key == 'Enter' && element.classList.contains( 'isDir' ) ) {
|
||||||
if( e.key == 'Enter' && trParent.hasClass( 'isDir' ) ) {
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
self.changeDirectory( trParent.data( 'filename' ) );
|
self.changeDirectory( item.name );
|
||||||
} else if( e.key == ' ' && ! trParent.is( ':first-child' ) ) {
|
} else if( e.key == ' ' && item.name != ".." ) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
var item = $('.highlightedItem');
|
element.classList.toggle( 'selectedItem' );
|
||||||
if( item.is( 'tr' ) )
|
|
||||||
item.toggleClass( 'selectedItem' );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Some operations do not work if the highlighted item is the parent
|
||||||
* Some operations do not work if the highlighted item is the parent
|
// directory. In these cases the keybindings are ignored.
|
||||||
* directory. In these cases the keybindings are ignored.
|
if( item.name == ".." )
|
||||||
*/
|
|
||||||
if( $('.highlightedItem').data( 'filename' ) == ".." )
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
var selectedItems = Array.prototype.slice.call( document.getElementsByClassName( 'selectedItem' ) )
|
||||||
|
.map( function( e ) { return self.fileCache[e.children[0].children[0].id] } );
|
||||||
|
|
||||||
switch( e.key ) {
|
switch( e.key ) {
|
||||||
case 'Delete':
|
case 'Delete':
|
||||||
if( self.config.delete ) {
|
if( self.config.delete ) {
|
||||||
if( $('#filetable tr.selectedItem').length > 0 ) {
|
if( selectedItems.length > 0 ) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
self.showMultiDeleteDialog();
|
self.showMultiDeleteDialog();
|
||||||
} else {
|
} else
|
||||||
var item = $('.highlightedItem');
|
self.showDeleteFileDialog( item.name );
|
||||||
if( item.length )
|
|
||||||
self.showDeleteFileDialog( item.data( 'filename' ) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
case 'm':
|
case 'm':
|
||||||
if( self.config.copymove ) {
|
if( self.config.copymove ) {
|
||||||
var item = $('.highlightedItem');
|
self.showCopyMoveDialog( selectedItems );
|
||||||
if( item.length ) {
|
|
||||||
e.preventDefault();
|
|
||||||
self.showCopyMoveDialog( item.data( 'filename' ) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
if( self.config.edit ) {
|
if( self.config.edit && item.eaction == "edit" ) {
|
||||||
var item = $('.highlightedItem');
|
e.preventDefault();
|
||||||
if( item.length && ! item.hasClass( 'isDir' ) ) {
|
self.editFile( item.name );
|
||||||
e.preventDefault();
|
} else if( self.config.extract && item.eaction == "extract" ) {
|
||||||
var action = item.data( 'eaction' );
|
e.preventDefault();
|
||||||
switch( action ) {
|
self.showExtractFileDialog( item.name );
|
||||||
case 'extract':
|
|
||||||
self.showExtractFileDialog( item.data( 'filename' ) );
|
|
||||||
break;
|
|
||||||
case 'edit':
|
|
||||||
self.editFile( item.data( 'filename' ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
@@ -2262,8 +2270,7 @@ function IFM( params ) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.initApplication = function() {
|
this.initApplication = function() {
|
||||||
self.rootElement.html(
|
self.rootElement.innerHTML = Mustache.render(
|
||||||
Mustache.render(
|
|
||||||
self.templates.app,
|
self.templates.app,
|
||||||
{
|
{
|
||||||
showpath: "/",
|
showpath: "/",
|
||||||
@@ -2271,9 +2278,7 @@ function IFM( params ) {
|
|||||||
ftbuttons: function(){
|
ftbuttons: function(){
|
||||||
return ( self.config.edit || self.config.rename || self.config.delete || self.config.zipnload || self.config.extract );
|
return ( self.config.edit || self.config.rename || self.config.delete || self.config.zipnload || self.config.extract );
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
)
|
|
||||||
);
|
|
||||||
// bind static buttons
|
// bind static buttons
|
||||||
$("#refresh").click(function(){
|
$("#refresh").click(function(){
|
||||||
self.refreshFileTable();
|
self.refreshFileTable();
|
||||||
@@ -2322,7 +2327,7 @@ function IFM( params ) {
|
|||||||
$('#filedropoverlay').css( 'display', 'none' );
|
$('#filedropoverlay').css( 'display', 'none' );
|
||||||
});
|
});
|
||||||
// handle keystrokes
|
// handle keystrokes
|
||||||
$(document).on( 'keydown', self.handleKeystrokes );
|
document.onkeydown = self.handleKeystrokes;
|
||||||
// handle history manipulation
|
// handle history manipulation
|
||||||
window.onpopstate = self.historyPopstateHandler;
|
window.onpopstate = self.historyPopstateHandler;
|
||||||
// load initial file table
|
// load initial file table
|
||||||
@@ -2334,7 +2339,7 @@ function IFM( params ) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.init = function( id ) {
|
this.init = function( id ) {
|
||||||
self.rootElement = $('#'+id);
|
self.rootElement = document.getElementById( id );
|
||||||
this.initLoadConfig();
|
this.initLoadConfig();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
241
src/ifm.js
241
src/ifm.js
@@ -26,34 +26,48 @@ function IFM( params ) {
|
|||||||
*/
|
*/
|
||||||
this.showModal = function( content, options ) {
|
this.showModal = function( content, options ) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var modal = $( document.createElement( 'div' ) )
|
var modal = document.createElement( 'div' );
|
||||||
.addClass( "modal fade" )
|
modal.classList.add( 'modal', 'fade' );
|
||||||
.attr( 'id', 'ifmmodal' )
|
modal.id = 'ifmmodal';
|
||||||
.attr( 'role', 'dialog' );
|
modal.attributes.role = 'dialog';
|
||||||
var modalDialog = $( document.createElement( 'div' ) )
|
var modalDialog = document.createElement( 'div' );
|
||||||
.addClass( "modal-dialog" )
|
modalDialog.classList.add( 'modal-dialog' );
|
||||||
.attr( 'role', 'document' );
|
modalDialog.attributes.role = 'document';
|
||||||
if( options.large == true ) modalDialog.addClass( 'modal-lg' );
|
if( options.large == true ) modalDialog.classList.add( 'modal-lg' );
|
||||||
var modalContent = $(document.createElement('div'))
|
var modalContent = document.createElement('div');
|
||||||
.addClass("modal-content")
|
modalContent.classList.add( 'modal-content' );
|
||||||
.append( content );
|
modalContent.innerHTML = content;
|
||||||
modalDialog.append( modalContent );
|
modalDialog.appendChild( modalContent );
|
||||||
modal.append( modalDialog );
|
modal.appendChild( modalDialog );
|
||||||
$( document.body ).append( modal );
|
document.body.appendChild( modal );
|
||||||
modal.on('hide.bs.modal', function () { $(this).remove(); });
|
modal.addEventListener( 'hide.bs.modal', function( e ) { console.log( e ); $(this).remove(); });
|
||||||
modal.on('shown.bs.modal', function () {
|
modal.addEventListener( 'shown.bs.modal', function( e ) {
|
||||||
|
console.log( e );
|
||||||
var formElements = $(this).find('input, button');
|
var formElements = $(this).find('input, button');
|
||||||
if( formElements.length > 0 ) {
|
if( formElements.length > 0 ) {
|
||||||
formElements.first().focus();
|
formElements.first().focus();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
modal.modal('show');
|
|
||||||
|
// For this we have to use jquery, because bootstrap modals depend on them. Even the bs.modal
|
||||||
|
// events require jquery, as they cannot be recognized by addEventListener()
|
||||||
|
$(modal)
|
||||||
|
.on( 'hide.bs.modal', function( e ) { $(this).remove(); })
|
||||||
|
.on( 'shown.bs.modal', function( e ) {
|
||||||
|
console.log( e );
|
||||||
|
var formElements = $(this).find('input, button');
|
||||||
|
if( formElements.length > 0 ) {
|
||||||
|
formElements.first().focus();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.modal('show');
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hides a bootstrap modal
|
* Hides a bootstrap modal
|
||||||
*/
|
*/
|
||||||
this.hideModal = function() {
|
this.hideModal = function() {
|
||||||
|
// Hide the modal via jquery to get the hide.bs.modal event triggered
|
||||||
$('#ifmmodal').modal('hide');
|
$('#ifmmodal').modal('hide');
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -151,8 +165,8 @@ function IFM( params ) {
|
|||||||
});
|
});
|
||||||
self.fileCache = data;
|
self.fileCache = data;
|
||||||
var newTBody = Mustache.render( self.templates.filetable, { items: data, config: self.config } );
|
var newTBody = Mustache.render( self.templates.filetable, { items: data, config: self.config } );
|
||||||
$( "#filetable tbody" ).remove();
|
var filetable = document.getElementById( 'filetable' );
|
||||||
$( "#filetable" ).append( $(newTBody) );
|
filetable.innerHTML = newTBody;
|
||||||
$( '.clickable-row' ).click( function( event ) {
|
$( '.clickable-row' ).click( function( event ) {
|
||||||
if( event.ctrlKey ) {
|
if( event.ctrlKey ) {
|
||||||
$( this ).toggleClass( 'selectedItem' );
|
$( this ).toggleClass( 'selectedItem' );
|
||||||
@@ -216,14 +230,13 @@ function IFM( params ) {
|
|||||||
var contextMenu = new BootstrapMenu( '.clickable-row', {
|
var contextMenu = new BootstrapMenu( '.clickable-row', {
|
||||||
fetchElementData: function( row ) {
|
fetchElementData: function( row ) {
|
||||||
var data = {};
|
var data = {};
|
||||||
var selectedItems = Array.prototype.slice.call( document.getElementsByClassName( 'selectedItem' ) );
|
|
||||||
data.selected =
|
data.selected =
|
||||||
Array.prototype.slice.call( document.getElementsByClassName( 'selectedItem' ) )
|
Array.prototype.slice.call( document.getElementsByClassName( 'selectedItem' ) )
|
||||||
.map( function(e){ return ifm.fileCache.find( x => x.guid == e.children[0].children[0].id ); } );
|
.map( function(e){ return ifm.fileCache.find( x => x.guid == e.children[0].children[0].id ); } );
|
||||||
data.clicked = self.fileCache.find( x => x.guid == row[0].children[0].children[0].id );
|
data.clicked = self.fileCache.find( x => x.guid == row[0].children[0].children[0].id );
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
actionGroups:[
|
actionsGroups:[
|
||||||
['edit', 'extract', 'rename'],
|
['edit', 'extract', 'rename'],
|
||||||
['copymove', 'download'],
|
['copymove', 'download'],
|
||||||
['delete']
|
['delete']
|
||||||
@@ -236,7 +249,7 @@ function IFM( params ) {
|
|||||||
},
|
},
|
||||||
iconClass: "icon icon-pencil",
|
iconClass: "icon icon-pencil",
|
||||||
isShown: function( data ) {
|
isShown: function( data ) {
|
||||||
return ( self.config.edit && data.clicked.eaction == "edit" );
|
return ( self.config.edit && data.clicked.eaction == "edit" && !data.selected.length );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
extract: {
|
extract: {
|
||||||
@@ -246,7 +259,7 @@ function IFM( params ) {
|
|||||||
},
|
},
|
||||||
iconClass: "icon icon-archive",
|
iconClass: "icon icon-archive",
|
||||||
isShown: function( data ) {
|
isShown: function( data ) {
|
||||||
return ( self.config.extract && data.clicked.eaction == "extract" );
|
return ( self.config.extract && data.clicked.eaction == "extract" && !data.selected.length );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
rename: {
|
rename: {
|
||||||
@@ -255,7 +268,7 @@ function IFM( params ) {
|
|||||||
self.showRenameFileDialog( data.clicked.name );
|
self.showRenameFileDialog( data.clicked.name );
|
||||||
},
|
},
|
||||||
iconClass: "icon icon-terminal",
|
iconClass: "icon icon-terminal",
|
||||||
isShown: function() { return self.config.rename; }
|
isShown: function( data ) { return ( self.config.rename && !data.selected.length ); }
|
||||||
},
|
},
|
||||||
copymove: {
|
copymove: {
|
||||||
name: function( data ) {
|
name: function( data ) {
|
||||||
@@ -266,9 +279,9 @@ function IFM( params ) {
|
|||||||
},
|
},
|
||||||
onClick: function( data ) {
|
onClick: function( data ) {
|
||||||
if( data.selected.length > 0 )
|
if( data.selected.length > 0 )
|
||||||
self.showCopyMoveDialog( data.selected.map(function( e ) { return e.name; }) );
|
self.showCopyMoveDialog( data.selected );
|
||||||
else
|
else
|
||||||
self.showCopyMoveDialog( data.clicked.name );
|
self.showCopyMoveDialog( data.clicked );
|
||||||
},
|
},
|
||||||
iconClass: "icon icon-folder-empty",
|
iconClass: "icon icon-folder-empty",
|
||||||
isShown: function() { return self.config.copymove; }
|
isShown: function() { return self.config.copymove; }
|
||||||
@@ -417,7 +430,7 @@ function IFM( params ) {
|
|||||||
*
|
*
|
||||||
* @params string name - name of the file
|
* @params string name - name of the file
|
||||||
*/
|
*/
|
||||||
this.editFile = function( name ) {
|
this.editFile = function( filename ) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: self.api,
|
url: self.api,
|
||||||
type: "POST",
|
type: "POST",
|
||||||
@@ -425,7 +438,7 @@ function IFM( params ) {
|
|||||||
data: ({
|
data: ({
|
||||||
api: "getContent",
|
api: "getContent",
|
||||||
dir: self.currentDir,
|
dir: self.currentDir,
|
||||||
filename: name
|
filename: filename
|
||||||
}),
|
}),
|
||||||
success: function( data ) {
|
success: function( data ) {
|
||||||
if( data.status == "OK" && data.data.content != null ) {
|
if( data.status == "OK" && data.data.content != null ) {
|
||||||
@@ -614,16 +627,12 @@ function IFM( params ) {
|
|||||||
error: function() { self.hideModal(); self.showMessage( "Error while fetching the folder tree.", "e" ) }
|
error: function() { self.hideModal(); self.showMessage( "Error while fetching the folder tree.", "e" ) }
|
||||||
});
|
});
|
||||||
$( '#copyButton' ).on( 'click', function() {
|
$( '#copyButton' ).on( 'click', function() {
|
||||||
items.forEach( function( item ) {
|
self.copyMove( items, $('#copyMoveTree .node-selected').data('path'), 'copy' );
|
||||||
self.copyMove( item.name, $('#copyMoveTree .node-selected').data('path'), 'copy' );
|
|
||||||
});
|
|
||||||
self.hideModal();
|
self.hideModal();
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
$( '#moveButton' ).on( 'click', function() {
|
$( '#moveButton' ).on( 'click', function() {
|
||||||
filenames.forEach( function( filename ) {
|
self.copyMove( items, $('#copyMoveTree .node-selected').data('path'), 'move' );
|
||||||
self.copyMove( item.name, $('#copyMoveTree .node-selected').data('path'), 'move' );
|
|
||||||
});
|
|
||||||
self.hideModal();
|
self.hideModal();
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
@@ -640,34 +649,38 @@ function IFM( params ) {
|
|||||||
* @params {string} destination - target directory
|
* @params {string} destination - target directory
|
||||||
* @params {string} action - action (copy|move)
|
* @params {string} action - action (copy|move)
|
||||||
*/
|
*/
|
||||||
this.copyMove = function( source, destination, action ) {
|
this.copyMove = function( sources, destination, action ) {
|
||||||
var id = self.generateGuid();
|
if( ! Array.isArray( sources ) )
|
||||||
self.task_add( { id: id, name: action.charAt(0).toUpperCase() + action.slice(1) + " " + source + " to " + destination } );
|
sources = [sources];
|
||||||
$.ajax({
|
sources.forEach( function( source ) {
|
||||||
url: self.api,
|
var id = self.generateGuid();
|
||||||
type: "POST",
|
self.task_add( { id: id, name: action.charAt(0).toUpperCase() + action.slice(1) + " " + source.name + " to " + destination } );
|
||||||
data: {
|
$.ajax({
|
||||||
dir: self.currentDir,
|
url: self.api,
|
||||||
api: "copyMove",
|
type: "POST",
|
||||||
action: action,
|
data: {
|
||||||
filename: source,
|
dir: self.currentDir,
|
||||||
destination: destination
|
api: "copyMove",
|
||||||
},
|
action: action,
|
||||||
dataType: "json",
|
filename: source.name,
|
||||||
success: function(data) {
|
destination: destination
|
||||||
if( data.status == "OK" ) {
|
},
|
||||||
self.showMessage( data.message, "s" );
|
dataType: "json",
|
||||||
} else {
|
success: function( data ) {
|
||||||
self.showMessage( data.message, "e" );
|
if( data.status == "OK" ) {
|
||||||
|
self.showMessage( data.message, "s" );
|
||||||
|
} else {
|
||||||
|
self.showMessage( data.message, "e" );
|
||||||
|
}
|
||||||
|
self.refreshFileTable();
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
self.showMessage( "General error occured.", "e" );
|
||||||
|
},
|
||||||
|
complete: function() {
|
||||||
|
self.task_done( id );
|
||||||
}
|
}
|
||||||
self.refreshFileTable();
|
});
|
||||||
},
|
|
||||||
error: function() {
|
|
||||||
self.showMessage( "General error occured.", "e" );
|
|
||||||
},
|
|
||||||
complete: function() {
|
|
||||||
self.task_done( id );
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -694,9 +707,11 @@ function IFM( params ) {
|
|||||||
self.hideModal();
|
self.hideModal();
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
form.find('#extractCustomLocation').on( 'click', function(e) {
|
form.find('#extractCustomLocation')
|
||||||
$(e.target).prev().children().first().prop( 'checked', true );
|
.on( 'click', function(e) {
|
||||||
});
|
$(e.target).prev().children().first().prop( 'checked', true );
|
||||||
|
})
|
||||||
|
.on( 'keypress', self.preventEnter );
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1248,6 +1263,7 @@ function IFM( params ) {
|
|||||||
if( $(e.target).closest('input')[0] || $(e.target).closest('textarea')[0] )
|
if( $(e.target).closest('input')[0] || $(e.target).closest('textarea')[0] )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// global key events
|
||||||
switch( e.key ) {
|
switch( e.key ) {
|
||||||
case '/':
|
case '/':
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -1305,14 +1321,6 @@ function IFM( params ) {
|
|||||||
self.changeDirectory( '..' );
|
self.changeDirectory( '..' );
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
case 'l':
|
|
||||||
case 'ArrowRight':
|
|
||||||
e.preventDefault();
|
|
||||||
var item = $('.highlightedItem');
|
|
||||||
if( item.hasClass('isDir') )
|
|
||||||
self.changeDirectory( item.data( 'filename' ) );
|
|
||||||
return;
|
|
||||||
break;
|
|
||||||
case 'j':
|
case 'j':
|
||||||
case 'ArrowDown':
|
case 'ArrowDown':
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -1325,79 +1333,79 @@ function IFM( params ) {
|
|||||||
self.highlightItem('prev');
|
self.highlightItem('prev');
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// key events which need a highlighted item
|
||||||
|
var element = document.getElementsByClassName( 'highlightedItem' )[0];
|
||||||
|
if( ! element )
|
||||||
|
return;
|
||||||
|
item = self.fileCache.find( x => x.guid == element.children[0].children[0].id );
|
||||||
|
|
||||||
|
switch( e.key ) {
|
||||||
|
case 'l':
|
||||||
|
case 'ArrowRight':
|
||||||
|
e.preventDefault();
|
||||||
|
if( item.type == "dir" )
|
||||||
|
self.changeDirectory( item.name );
|
||||||
|
return;
|
||||||
|
break;
|
||||||
case 'Escape':
|
case 'Escape':
|
||||||
if( $(':focus').is( '.clickable-row td:first-child a:first-child' ) && $('.highlightedItem').length ) {
|
if( element.children[0].children[0] == document.activeElement ) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
$('.highlightedItem').removeClass( 'highlightedItem' );
|
element.classList.toggle( 'highlightedItem' );
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
case ' ': // todo: make it work only when noting other is focused
|
case ' ': // todo: make it work only when noting other is focused
|
||||||
case 'Enter':
|
case 'Enter':
|
||||||
if( $(':focus').is( '.clickable-row td:first-child a:first-child' ) ) {
|
if( element.children[0].children[0] == document.activeElement ) {
|
||||||
var trParent = $(':focus').parent().parent();
|
if( e.key == 'Enter' && element.classList.contains( 'isDir' ) ) {
|
||||||
if( e.key == 'Enter' && trParent.hasClass( 'isDir' ) ) {
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
self.changeDirectory( trParent.data( 'filename' ) );
|
self.changeDirectory( item.name );
|
||||||
} else if( e.key == ' ' && ! trParent.is( ':first-child' ) ) {
|
} else if( e.key == ' ' && item.name != ".." ) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
var item = $('.highlightedItem');
|
element.classList.toggle( 'selectedItem' );
|
||||||
if( item.is( 'tr' ) )
|
|
||||||
item.toggleClass( 'selectedItem' );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Some operations do not work if the highlighted item is the parent
|
||||||
* Some operations do not work if the highlighted item is the parent
|
// directory. In these cases the keybindings are ignored.
|
||||||
* directory. In these cases the keybindings are ignored.
|
if( item.name == ".." )
|
||||||
*/
|
|
||||||
if( $('.highlightedItem').data( 'filename' ) == ".." )
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
var selectedItems = Array.prototype.slice.call( document.getElementsByClassName( 'selectedItem' ) )
|
||||||
|
.map( function( e ) { return self.fileCache[e.children[0].children[0].id] } );
|
||||||
|
|
||||||
switch( e.key ) {
|
switch( e.key ) {
|
||||||
case 'Delete':
|
case 'Delete':
|
||||||
if( self.config.delete ) {
|
if( self.config.delete ) {
|
||||||
if( $('#filetable tr.selectedItem').length > 0 ) {
|
if( selectedItems.length > 0 ) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
self.showMultiDeleteDialog();
|
self.showMultiDeleteDialog();
|
||||||
} else {
|
} else
|
||||||
var item = $('.highlightedItem');
|
self.showDeleteFileDialog( item.name );
|
||||||
if( item.length )
|
|
||||||
self.showDeleteFileDialog( item.data( 'filename' ) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
case 'm':
|
case 'm':
|
||||||
if( self.config.copymove ) {
|
if( self.config.copymove ) {
|
||||||
var item = $('.highlightedItem');
|
self.showCopyMoveDialog( selectedItems );
|
||||||
if( item.length ) {
|
|
||||||
e.preventDefault();
|
|
||||||
self.showCopyMoveDialog( item.data( 'filename' ) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
if( self.config.edit ) {
|
if( self.config.edit && item.eaction == "edit" ) {
|
||||||
var item = $('.highlightedItem');
|
e.preventDefault();
|
||||||
if( item.length && ! item.hasClass( 'isDir' ) ) {
|
self.editFile( item.name );
|
||||||
e.preventDefault();
|
} else if( self.config.extract && item.eaction == "extract" ) {
|
||||||
var action = item.data( 'eaction' );
|
e.preventDefault();
|
||||||
switch( action ) {
|
self.showExtractFileDialog( item.name );
|
||||||
case 'extract':
|
|
||||||
self.showExtractFileDialog( item.data( 'filename' ) );
|
|
||||||
break;
|
|
||||||
case 'edit':
|
|
||||||
self.editFile( item.data( 'filename' ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
break;
|
break;
|
||||||
@@ -1447,8 +1455,7 @@ function IFM( params ) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.initApplication = function() {
|
this.initApplication = function() {
|
||||||
self.rootElement.html(
|
self.rootElement.innerHTML = Mustache.render(
|
||||||
Mustache.render(
|
|
||||||
self.templates.app,
|
self.templates.app,
|
||||||
{
|
{
|
||||||
showpath: "/",
|
showpath: "/",
|
||||||
@@ -1456,9 +1463,7 @@ function IFM( params ) {
|
|||||||
ftbuttons: function(){
|
ftbuttons: function(){
|
||||||
return ( self.config.edit || self.config.rename || self.config.delete || self.config.zipnload || self.config.extract );
|
return ( self.config.edit || self.config.rename || self.config.delete || self.config.zipnload || self.config.extract );
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
)
|
|
||||||
);
|
|
||||||
// bind static buttons
|
// bind static buttons
|
||||||
$("#refresh").click(function(){
|
$("#refresh").click(function(){
|
||||||
self.refreshFileTable();
|
self.refreshFileTable();
|
||||||
@@ -1507,7 +1512,7 @@ function IFM( params ) {
|
|||||||
$('#filedropoverlay').css( 'display', 'none' );
|
$('#filedropoverlay').css( 'display', 'none' );
|
||||||
});
|
});
|
||||||
// handle keystrokes
|
// handle keystrokes
|
||||||
$(document).on( 'keydown', self.handleKeystrokes );
|
document.onkeydown = self.handleKeystrokes;
|
||||||
// handle history manipulation
|
// handle history manipulation
|
||||||
window.onpopstate = self.historyPopstateHandler;
|
window.onpopstate = self.historyPopstateHandler;
|
||||||
// load initial file table
|
// load initial file table
|
||||||
@@ -1519,7 +1524,7 @@ function IFM( params ) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.init = function( id ) {
|
this.init = function( id ) {
|
||||||
self.rootElement = $('#'+id);
|
self.rootElement = document.getElementById( id );
|
||||||
this.initLoadConfig();
|
this.initLoadConfig();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user