1
0
mirror of https://github.com/misterunknown/ifm.git synced 2025-09-01 03:41:43 +02:00

new development version 2.2-dev

This commit is contained in:
Marco Dickert
2017-02-14 20:10:25 +01:00
parent f423253b85
commit 6892595c82
13 changed files with 1488 additions and 1262 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
.*.swp
*.zip

581
ifm.php

File diff suppressed because one or more lines are too long

14
src/ace/ace.js Normal file

File diff suppressed because one or more lines are too long

1
src/bootstrap-notify.min.js vendored Normal file

File diff suppressed because one or more lines are too long

6
src/bootstrap.min.css vendored Normal file

File diff suppressed because one or more lines are too long

7
src/bootstrap.min.js vendored Normal file

File diff suppressed because one or more lines are too long

2
src/ekko-lightbox.min.css vendored Normal file
View File

@@ -0,0 +1,2 @@
.ekko-lightbox-nav-overlay a:focus,.ekko-lightbox-nav-overlay a>:focus{outline:0}.ekko-lightbox-container{position:relative}.ekko-lightbox-container>div.ekko-lightbox-item{position:absolute;top:0;left:0;width:100%;transition:opacity .5s ease-in-out;opacity:1}.ekko-lightbox-nav-overlay{z-index:1;position:absolute;top:0;left:0;width:100%;height:100%;display:-ms-flexbox;display:flex}.ekko-lightbox-nav-overlay a{-ms-flex:1;flex:1;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;opacity:0;transition:opacity .5s;color:#fff;font-size:30px;z-index:1}.ekko-lightbox-nav-overlay a>*{-ms-flex-positive:1;flex-grow:1}.ekko-lightbox-nav-overlay a span{padding:0 30px}.ekko-lightbox-nav-overlay a:last-child span{text-align:right}.ekko-lightbox-nav-overlay a:hover{text-decoration:none}.ekko-lightbox a:hover{opacity:1;text-decoration:none}.ekko-lightbox .modal-footer{text-align:left}.ekko-lightbox-loader{position:absolute;top:0;left:0;bottom:0;right:0;width:100%;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;-ms-flex-align:center;align-items:center}.ekko-lightbox-loader>div{width:40px;height:40px;position:relative;text-align:center}.ekko-lightbox-loader>div>div{width:100%;height:100%;border-radius:50%;background-color:#fff;opacity:.6;position:absolute;top:0;left:0;animation:a 2s infinite ease-in-out}.ekko-lightbox-loader>div>div:last-child{animation-delay:-1s}@keyframes a{0%,to{transform:scale(0);-webkit-transform:scale(0)}50%{transform:scale(1);-webkit-transform:scale(1)}}
/*# sourceMappingURL=ekko-lightbox.min.css.map */

2
src/ekko-lightbox.min.js vendored Normal file

File diff suppressed because one or more lines are too long

106
src/fontello-embedded.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -1,15 +1,44 @@
// declare ifm object
if(!ifm) {
var ifm = {
IFM_SCFN: "<?=basename($_SERVER['SCRIPT_NAME'])?>", // IFM_SCFM = ifm script file name; used for querying via AJAX
config: jQuery.parseJSON('<?php echo json_encode(IFMConfig::getConstants()); ?>'), // serialize the PHP config array, so we can use it in JS too
editor: null, // global ace editor
fileChanged: false, // was our file edited?
currentDir: "", // this is the global variable for the current directory; it is used for AJAX requests
// --------------
// main functions
// --------------
refreshFileTable: function () {
// IFM - js app
function IFM() {
var self = this; // reference to ourself, because "this" does not work within callbacks
this.IFM_SCFN = "<?=basename($_SERVER['SCRIPT_NAME'])?>";
this.config = jQuery.parseJSON('<?php echo json_encode(IFMConfig::getConstants()); ?>'); // serialize the PHP config array, so we can use it in JS too
this.editor = null; // global ace editor
this.fileChanged = false; // flag for check if file was changed already
this.currentDir = ""; // this is the global variable for the current directory; it is used for AJAX requests
this.loadingAnim = '<div id="loadingAnim"><div class="blockG" id="rotateG_01"></div><div class="blockG" id="rotateG_02"></div><div class="blockG" id="rotateG_03"></div><div class="blockG" id="rotateG_04"></div><div class="blockG" id="rotateG_05"></div><div class="blockG" id="rotateG_06"></div><div class="blockG" id="rotateG_07"></div><div class="blockG" id="rotateG_08"></div></div>';
// modal functions
this.showModal = function( content, options = {} ) {
var modal = $( document.createElement( 'div' ) )
.addClass( "modal fade" )
.attr( 'id', 'ifmmodal' )
.attr( 'role', 'dialog' );
var modalDialog = $( document.createElement( 'div' ) )
.addClass( "modal-dialog" )
.attr( 'role', 'document' );
if( options.large == true ) modalDialog.addClass( 'modal-lg' );
var modalContent = $(document.createElement('div'))
.addClass("modal-content")
.append( content );
modalDialog.append( modalContent );
modal.append( modalDialog );
$( document.body ).prepend( modal );
modal.modal();
modal.on( 'hide.bs.modal', function () {
self.fileChanged = false;
self.editor = null;
$( this ).remove();
});
};
this.hideModal = function() {
$('#ifmmodal').modal('hide');
};
this.refreshFileTable = function () {
if(document.getElementById("multiseloptions"))$("#multiseloptions").remove();
var id=ifm.generateGuid();
ifm.task_add("Refresh", id);
@@ -18,13 +47,18 @@ if(!ifm) {
type: "POST",
data: "api=getFiles&dir="+ifm.currentDir,
dataType: "json",
success:
function(data) {
success: self.rebuildFileTable,
error: function(response) { ifm.showMessage("General error occured: No or broken response", "e"); },
complete: function() { self.task_done( id ); }
});
};
this.rebuildFileTable = function( data ) {
$("#filetable tbody tr").remove();
for(i=0;i<data.length;i++) {
var newrow = "<tr>";
var multisel = '';
if(ifm.config.multiselect == 1) {
if(self.config.multiselect == 1) {
multisel = '<input type="checkbox" ';
multisel += (!ifm.inArray(data[i].name, ["..", "."]))?'id="'+data[i].name+'" name="multisel"':'style="visibility:hidden"';
multisel += '>';
@@ -33,7 +67,7 @@ if(!ifm) {
newrow += '<td>'+multisel+'<a href="'+ifm.pathCombine(ifm.currentDir,data[i].name)+'"><span class="'+data[i].icon+'"></span> '+data[i].name+'</a></td>';
else
newrow += '<td>'+multisel+'<a onclick="ifm.changeDirectory(\''+data[i].name+'\')"><span class="'+data[i].icon+'"></span> '+data[i].name+'</a></td>'
if(ifm.config.download == 1) {
if(self.config.download == 1) {
if( data[i].type != "dir" )
newrow += '<td class="download-link">\
<form style="display:none;" id="fdownload'+i+'" method="post">\
@@ -51,8 +85,8 @@ if(!ifm) {
if(data[i].lastmodified) newrow += '<td>'+data[i].lastmodified+'</td>';
if(data[i].filesize) newrow += '<td>'+data[i].filesize+'</td>';
if(data[i].fileperms) {
newrow += '<td><input type="text" name="newperms" value="'+data[i].fileperms+'"';
if(ifm.config.chmod == 1)
newrow += '<td><input type="text" name="newperms" class="form-control" value="'+data[i].fileperms+'"';
if(self.config.chmod == 1)
newrow += ' onkeypress="ifm.changePermissions(event, \''+data[i].name+'\');"';
else
newrow += " readonly";
@@ -61,11 +95,11 @@ if(!ifm) {
}
if(data[i].owner) newrow += '<td>'+data[i].owner+'</td>';
if(data[i].group) newrow += '<td>'+data[i].group+'</td>';
if(ifm.inArray(1,[ifm.config.edit, ifm.config.rename, ifm.config.delete, ifm.config.zipnload, ifm.config.extract])) {
if(ifm.inArray(1,[self.config.edit, self.config.rename, self.config.delete, self.config.zipnload, self.config.extract])) {
newrow += '<td>';
if(data[i].type == "dir") {
if( data[i].name == ".." ) data[i].name = ".";
if(ifm.config.zipnload == 1) {
if(self.config.zipnload == 1) {
newrow += '<form method="post" style="display:inline-block;padding:0;margin:0;border:0;">\
<fieldset style="display:inline-block;padding:0;margin:0;border:0;">\
<input type="hidden" name="dir" value="'+ifm.currentDir+'">\
@@ -79,233 +113,218 @@ if(!ifm) {
}
}
else if(data[i].name.toLowerCase().substr(-4) == ".zip") {
if(ifm.config.extract == 1) newrow += '<a href="" onclick="ifm.extractFileDialog(\''+ifm.JSEncode(data[i].name)+'\');return false;"><span class="icon icon-archive" title="extract"></span></a>';
if(self.config.extract == 1) newrow += '<a href="" onclick="ifm.extractFileDialog(\''+ifm.JSEncode(data[i].name)+'\');return false;"><span class="icon icon-archive" title="extract"></span></a>';
}
else {
if(ifm.config.edit == 1) newrow += '<a onclick="ifm.showLoading();ifm.editFile(\''+ifm.JSEncode(data[i].name)+'\');return false;"><span class="icon icon-pencil" title="edit"></span></a>';
if(self.config.edit == 1) newrow += '<a onclick="ifm.showLoading();ifm.editFile(\''+ifm.JSEncode(data[i].name)+'\');return false;"><span class="icon icon-pencil" title="edit"></span></a>';
}
if(data[i].name != ".." && data[i].name != ".") {
if(ifm.config.rename == 1) newrow += '<a onclick="ifm.renameFileDialog(\''+ifm.JSEncode(data[i].name)+'\');return false;"><span class="icon icon-terminal" title="rename"></span></a>';
if(ifm.config.delete == 1) newrow += '<a onclick="ifm.deleteFileDialog(\''+ifm.JSEncode(data[i].name)+'\');return false;"><span class="icon icon-trash" title="delete"></span></a>';
if(self.config.rename == 1) newrow += '<a onclick="ifm.renameFileDialog(\''+ifm.JSEncode(data[i].name)+'\');return false;"><span class="icon icon-terminal" title="rename"></span></a>';
if(self.config.delete == 1) newrow += '<a onclick="ifm.deleteFileDialog(\''+ifm.JSEncode(data[i].name)+'\');return false;"><span class="icon icon-trash" title="delete"></span></a>';
}
newrow += '</td></tr>';
}
$("#filetable tbody").append(newrow);
}
// bind multiselect handler
if(ifm.config.multiselect == 1) {
if(self.config.multiselect == 1) {
$("input[name=multisel]").on("change", function(){ ifm.handleMultiSelect(); });
}
// bind Fancybox
//var piclinks = $('a[href$=".bmp"],a[href$=".gif"],a[href$=".jpg"],a[href$=".jpeg"],a[href$=".png"],a[href$=".BMP"],a[href$=".GIF"],a[href$=".JPG"],a[href$=".JPEG"],a[href$=".PNG"]');
//piclinks.attr('rel', 'fancybox').fancybox();
//var xOffset = 10;
//var yOffset = 30;
//piclinks.hover(function(e){this.t = this.title;this.title = "";var c = (this.t != "") ? "<br/>" + this.t : "";$("body").append("<p id='mdPicPreview'><img src='"+ this.href +"' alt='Image preview' />"+ c +"</p>");$("#mdPicPreview").css("top",(e.pageY - xOffset) + "px").css("left",(e.pageX + yOffset) + "px").fadeIn("fast");},function(){this.title = this.t;$("#mdPicPreview").remove();});
//piclinks.mousemove(function(e){$("#mdPicPreview").css("top",(e.pageY - xOffset) + "px").css("left",(e.pageX + yOffset) + "px");});
},
error: function(response) { ifm.showMessage("General error occured: No or broken response", "e"); },
complete: function() { ifm.task_done(id); }
});
},
changeDirectory: function(newdir) {
// todo: bootstrap-fancybox for images
};
this.changeDirectory = function( newdir ) {
$.ajax({
url: ifm.IFM_SCFN,
url: self.IFM_SCFN,
type: "POST",
data: ({
api: "getRealpath",
dir: ifm.pathCombine(ifm.currentDir, newdir)
dir: self.pathCombine( ifm.currentDir, newdir )
}),
dataType: "json",
success: function( data ){
ifm.currentDir = data.realpath;
ifm.refreshFileTable();
$("#currentDir").val(ifm.currentDir);
self.currentDir = data.realpath;
self.refreshFileTable();
$( "#currentDir" ).val( self.currentDir );
},
error: function() { ifm.showMessage("General error occured: No or broken response", "e"); }
error: function() { self.showMessage( "General error occured: No or broken response", "e" ); }
});
},
showFileForm: function () {
};
this.showFileForm = function () {
var filename = arguments.length > 0 ? arguments[0] : "newfile.txt";
var content = arguments.length > 1 ? arguments[1] : "";
var overlay = '<div class="modal fade" id="overlay" role="dialog" aria-labelledby="fileformLabel"><div class="modal-dialog" role="document"><div class="modal-content">';
overlay += '<form id="showFile"><div class="modal-header"><h4>' + ((arguments.length > 0)?'edit':'add') + ' file</h4></div>';
overlay += '<div class="modal-body"><fieldset><label>Filename:</label><input type="text" class="form-control" name="filename" value="'+filename+'" />';
overlay += '<div id="content" name="content">'+content+'</div></fieldset></div><div class="modal-footer"><button class="btn btn-success" onclick="ifm.saveFile();ifm.closeFileForm();return false;">Save';
overlay += '</button><button onclick="ifm.saveFile();return false;" class="btn btn-default">Save without closing</button>';
overlay += '<button class="btn btn-danger" onclick="$(\'#overlay\').modal(\'hide\');return false;">Close</button></div></form></div></div></div>';
$(document.body).prepend(overlay);
if(filename=="")$("#showFile input[name=filename]").focus();
else $("#showFile #content").focus();
$('#overlay').modal();
$("#overlay").on('hide.bs.modal', function () {
$(this).remove();
});
$('#overlay').on('remove', function () { ifm.editor = null; ifm.fileChanged = false; });
var overlay = '<form id="showFile">';
overlay += '<div class="modal-body"><fieldset><label>Filename:</label><input type="text" class="form-control" name="filename" value="'+filename+'" /><br>';
overlay += '<div id="content" name="content"></div></fieldset></div><div class="modal-footer"><button type="button" class="btn btn-default" onclick="ifm.saveFile();ifm.hideModal();return false;">Save';
overlay += '</button><button type="button" onclick="ifm.saveFile();return false;" class="btn btn-default">Save without closing</button>';
overlay += '<button type="button" class="btn btn-default" onclick="ifm.hideModal();return false;">Close</button></div></form>';
self.showModal( overlay, { large: true } );
$('#ifmmodal').on('remove', function () { self.editor = null; self.fileChanged = false; });
// Start ACE
//ifm.editor = ace.edit("content");
//ifm.editor.getSession().setValue(content);
//ifm.editor.focus();
//ifm.editor.on("change", function() { ifm.fileChanged = true; });
},
closeFileForm: function() {
ifm.fileChanged = false;
ifm.editor = null;
ifm.hideSaveQuestion();
ifm.removeOverlay();
},
removeOverlay: function() {
$('#overlay').remove();
},
createDirForm: function() {
$(document.body).prepend('<div class="overlay">\
<form id="createDir">\
self.editor = ace.edit("content");
self.editor.$blockScrolling = 'Infinity';
self.editor.getSession().setValue(content);
self.editor.focus();
self.editor.on("change", function() { self.fileChanged = true; });
};
this.createDirForm = function() {
self.showModal( '<form id="createDir">\
<div class="modal-body">\
<fieldset>\
<label>Directoy name:</label>\
<input type="text" name="dirname" value="" />\
<button onclick="ifm.createDir();$(\'.overlay\').remove();return false;">Save</button><button onclick="$(\'.overlay\').remove();return false;">Cancel</button>\
<input class="form-control" type="text" name="dirname" value="" />\
</fieldset>\
</form>\
</div>');
},
ajaxRequestDialog: function() {
$(document.body).prepend('<div class="overlay">\
<form id="ajaxrequest">\
</div>\
<div class="modal-footer">\
<button class="btn btn-default" type="button" onclick="ifm.createDir();ifm.hideModal();return false;">Save</button>\
<button type="button" class="btn btn-default" onclick="ifm.hideModal();return false;">Cancel</button>\
</div>\
</form>' );
};
this.ajaxRequestDialog = function() {
self.showModal( '<form id="ajaxrequest">\
<div class="modal-body">\
<fieldset>\
<label>URL</label><br>\
<input type="text" id="ajaxurl" required><br>\
<input class="form-control" type="text" id="ajaxurl" required><br>\
<label>Data</label><br>\
<textarea id="ajaxdata"></textarea><br>\
<textarea class="form-control" id="ajaxdata"></textarea><br>\
<label>Method</label><br>\
<input type="radio" name="arMethod" value="GET">GET</input><input type="radio" name="arMethod" value="POST" checked="checked">POST</input><br>\
<button onclick="ifm.ajaxRequest();return false;">Request</button>\
<button onclick="$(\'.overlay\').remove();return false;">Close</button><br>\
<button type="button" class="btn btn-success" onclick="ifm.ajaxRequest();return false;">Request</button>\
<button type="button" class="btn btn-default" onclick="ifm.hideModal();return false;">Close</button><br>\
<label>Response</label><br>\
<textarea id="ajaxresponse"></textarea>\
<textarea class="form-control" id="ajaxresponse"></textarea>\
</fieldset>\
</form>\
</div>');
},
ajaxRequest: function() {
ifm.showLoading();
};
this.ajaxRequest = function() {
$.ajax({
url : $("#ajaxurl").val(),
cache : false,
data : $('#ajaxdata').val().replace(/\n/g,"&"),
type : $('#ajaxrequest input[name=arMethod]:checked').val(),
success : function(response) { $("#ajaxresponse").text(response); },
error : function(e) { ifm.showMessage("Error: "+e, "e"); console.log(e); },
complete: function() { ifm.hideLoading(); }
error : function(e) { self.showMessage("Error: "+e, "e"); console.log(e); }
});
},
saveFile: function() {
var _content = ifm.editor.getValue();
};
this.saveFile = function() {
$.ajax({
url: ifm.IFM_SCFN,
url: self.IFM_SCFN,
type: "POST",
data: ({
api: "saveFile",
dir: ifm.currentDir,
dir: self.currentDir,
filename: $("#showFile input[name^=filename]").val(),
content: _content
content: ifm.editor.getValue()
}),
dataType: "json",
success: function( data ) {
if( data.status == "OK" ) {
ifm.showMessage("File successfully edited/created.", "s");
ifm.refreshFileTable();
} else ifm.showMessage("File could not be edited/created:"+data.message, "e");
self.showMessage( "File successfully edited/created.", "s" );
self.refreshFileTable();
} else self.showMessage( "File could not be edited/created:" + data.message, "e" );
},
error: function() { ifm.showMessage("General error occured", "e"); }
error: function() { self.showMessage( "General error occured", "e" ); }
});
ifm.fileChanged = false;
},
editFile: function(name) {
self.fileChanged = false;
};
this.editFile = function( name ) {
$.ajax({
url: ifm.IFM_SCFN,
url: self.IFM_SCFN,
type: "POST",
dataType: "json",
data: ({
api: "getContent",
dir: ifm.currentDir,
dir: self.currentDir,
filename: name
}),
success: function( data ) {
if( data.status == "OK" && data.data.content != null ) {
ifm.showFileForm(data.data.filename, data.data.content);
self.showFileForm( data.data.filename, data.data.content );
}
else if( data.status == "OK" && data.data.content == null ) {
ifm.showMessage("The content of this file cannot be fetched.", "e");
self.showMessage( "The content of this file cannot be fetched.", "e" );
}
else ifm.showMessage("Error: "+data.message, "e");
else self.showMessage( "Error: "+data.message, "e" );
},
error: function() { ifm.showMessage("This file can not be displayed or edited.", "e"); },
complete: function() { ifm.hideLoading(); }
error: function() { self.showMessage( "This file can not be displayed or edited.", "e" ); },
complete: function() { self.hideLoading(); }
});
},
deleteFileDialog: function(name) {
$(document.body).prepend('<div class="overlay">\
<form id="deleteFile">\
<fieldset>\
};
this.deleteFileDialog = function( name ) {
self.showModal( '<form id="deleteFile">\
<div class="modal-body">\
<label>Do you really want to delete the file '+name+'?\
<button onclick="ifm.deleteFile(\''+ifm.JSEncode(name)+'\');$(\'.overlay\').remove();return false;">Yes</button><button onclick="$(\'.overlay\').remove();return false;">No</button>\
</fieldset>\
</form>\
</div>');
},
deleteFile: function(name) {
</div><div class="modal-footer">\
<button type="button" class="btn btn-danger" onclick="ifm.deleteFile(\''+ifm.JSEncode(name)+'\');ifm.hideModal();return false;">Yes</button><button type="button" class="btn btn-default" onclick="ifm.hideModal();return false;">No</button>\
</div>\
</form>' );
};
this.deleteFile = function( name ) {
$.ajax({
url: ifm.IFM_SCFN,
url: self.IFM_SCFN,
type: "POST",
data: ({
api: "deleteFile",
dir: ifm.currentDir,
dir: self.currentDir,
filename: name
}),
dataType: "json",
success: function(data) {
if(data.status == "OK") {
ifm.showMessage("File successfully deleted", "s");
ifm.refreshFileTable();
} else ifm.showMessage("File could not be deleted", "e");
self.showMessage("File successfully deleted", "s");
self.refreshFileTable();
} else self.showMessage("File could not be deleted", "e");
},
error: function() { ifm.showMessage("General error occured", "e"); }
error: function() { self.showMessage("General error occured", "e"); }
});
},
createDir: function() {
};
this.createDir = function() {
$.ajax({
url: ifm.IFM_SCFN,
url: self.IFM_SCFN,
type: "POST",
data: ({
api: "createDir",
dir: ifm.currentDir,
dir: self.currentDir,
dirname: $("#createDir input[name^=dirname]").val()
}),
dataType: "json",
success: function(data){
if(data.status == "OK") {
ifm.showMessage("Directory sucessfully created.", "s");
ifm.refreshFileTable();
self.showMessage("Directory sucessfully created.", "s");
self.refreshFileTable();
}
else {
ifm.showMessage("Directory could not be created: "+data.message, "e");
self.showMessage("Directory could not be created: "+data.message, "e");
}
},
error: function() { ifm.showMessage("General error occured.", "e"); }
error: function() { self.showMessage("General error occured.", "e"); }
});
},
renameFileDialog: function(name) {
$(document.body).prepend('<div class="overlay">\
};
this.renameFileDialog = function(name) {
self.showModal( '<div class="modal-body">\
<form id="renameFile">\
<fieldset>\
<label>Rename '+name+' to:</label>\
<input type="text" name="newname" />\
<button onclick="ifm.renameFile(\''+ifm.JSEncode(name)+'\');$(\'.overlay\').remove();return false;">Rename</button><button onclick="$(\'.overlay\').remove();return false;">Cancel</button>\
<input class="form-control" type="text" name="newname" /><br>\
<button class="btn btn-default" onclick="ifm.renameFile(\''+ifm.JSEncode(name)+'\');ifm.hideModal();return false;">Rename</button><button class="btn btn-default" onclick="ifm.hideModal();return false;">Cancel</button>\
</fieldset>\
</form>\
</div>' );
},
renameFile: function(name) {
};
this.renameFile = function(name) {
$.ajax({
url: ifm.IFM_SCFN,
type: "POST",
@@ -324,69 +343,74 @@ if(!ifm) {
},
error: function() { ifm.showMessage("General error occured", "e"); }
});
},
extractFileDialog: function(name) {
};
this.extractFileDialog = function(name) {
var fuckWorkarounds="";
if(fuckWorkarounds.lastIndexOf(".") > 1)
fuckWorkarounds = name.substr(0,name.length-4);
else fuckWorkarounds = name;
$(document.body).prepend('<div class="overlay">\
self.showModal( '<div class="modal-body">\
<form id="extractFile">\
<fieldset>\
<label>Extract '+name+' to:</label>\
<button onclick="ifm.extractFile(\''+ifm.JSEncode(name)+'\', 0);$(\'.overlay\').remove();return false;">here</button>\
<button onclick="ifm.extractFile(\''+ifm.JSEncode(name)+'\', 1);$(\'.overlay\').remove();return false;">'+fuckWorkarounds+'/</button>\
<button onclick="$(\'.overlay\').remove();return false;">Cancel</button>\
<button type="button" class="btn btn-default" onclick="ifm.extractFile(\''+ifm.JSEncode(name)+'\', 0);ifm.hideModal();return false;">here</button>\
<button type="button" class="btn btn-default" onclick="ifm.extractFile(\''+ifm.JSEncode(name)+'\', 1);ifm.hideModal();return false;">'+fuckWorkarounds+'/</button>\
<button type="button" class="btn btn-default" onclick="ifm.hideModal();return false;">Cancel</button>\
</fieldset>\
</form>\
</div>');
},
extractFile: function(name, t) {
};
this.extractFile = function(name, t) {
var td = (t == 1)? name.substr(0,name.length-4) : "";
$.ajax({
url: ifm.IFM_SCFN,
url: self.IFM_SCFN,
type: "POST",
data: ({
api: "extractFile",
dir: ifm.currentDir,
dir: self.currentDir,
filename: name,
targetdir: td
}),
dataType: "json",
success: function(data) {
if(data.status == "OK") {
ifm.showMessage("File successfully extracted", "s");
ifm.refreshFileTable();
} else ifm.showMessage("File could not be extracted. Error: "+data.message, "e");
self.showMessage("File successfully extracted", "s");
self.refreshFileTable();
} else self.showMessage("File could not be extracted. Error: "+data.message, "e");
},
error: function() { ifm.showMessage("General error occured", "e"); }
error: function() { self.showMessage("General error occured", "e"); }
});
},
uploadFileDialog: function() {
$(document.body).prepend('<div class="overlay">\
<form id="uploadFile">\
};
this.uploadFileDialog = function() {
self.showModal( '<form id="uploadFile">\
<div class="modal-body">\
<fieldset>\
<label>Upload file</label><br>\
<input type="file" name="ufile" id="ufile"><br>\
<input class="file" type="file" name="ufile" id="ufile"><br>\
<label>new filename</label>\
<input type="text" name="newfilename"><br>\
<button onclick="ifm.uploadFile();$(\'.overlay\').remove();return false;">Upload</button>\
<button onclick="$(\'.overlay\').remove();return false;">Cancel</button>\
<input class="form-control" type="text" name="newfilename"><br>\
</fieldset>\
</form>\
</div>');
},
uploadFile: function() {
</div><div class="modal-footer">\
<button class="btn btn-default" onclick="ifm.uploadFile();ifm.hideModal();return false;">Upload</button>\
<button class="btn btn-default" onclick="ifm.hideModal();return false;">Cancel</button>\
</div>\
</form>');
};
this.uploadFile = function() {
var ufile = document.getElementById('ufile').files[0];
var data = new FormData();
var newfilename = $("#uploadFile input[name^=newfilename]").val();
data.append('api', 'uploadFile');
data.append('dir', ifm.currentDir);
data.append('dir', self.currentDir);
data.append('file', ufile);
data.append('newfilename', newfilename);
var id = ifm.generateGuid();
var id = self.generateGuid();
$.ajax({
url: ifm.IFM_SCFN,
url: self.IFM_SCFN,
type: "POST",
data: data,
processData: false,
@@ -394,60 +418,62 @@ if(!ifm) {
dataType: "json",
xhr: function(){
var xhr = $.ajaxSettings.xhr() ;
xhr.upload.onprogress = function(evt){ ifm.task_update(evt.loaded/evt.total*100,id); } ;
xhr.upload.onprogress = function(evt){ self.task_update(evt.loaded/evt.total*100,id); } ;
xhr.upload.onload = function(){ console.log('Uploading '+newfilename+' done.') } ;
return xhr ;
},
success: function(data) {
if(data.status == "OK") {
ifm.showMessage("File successfully uploaded", "s");
if(data.cd == ifm.currentDir) ifm.refreshFileTable();
} else ifm.showMessage("File could not be uploaded: "+data.message, "e");
self.showMessage("File successfully uploaded", "s");
if(data.cd == self.currentDir) self.refreshFileTable();
} else self.showMessage("File could not be uploaded: "+data.message, "e");
},
error: function() { ifm.showMessage("General error occured", "e"); },
complete: function() { ifm.task_done(id); }
error: function() { self.showMessage("General error occured", "e"); },
complete: function() { self.task_done(id); }
});
ifm.task_add("Upload "+ufile.name, id);
},
changePermissions: function(e, name) {
self.task_add("Upload "+ufile.name, id);
};
this.changePermissions = function(e, name) {
if(e.keyCode == '13')
$.ajax({
url: ifm.IFM_SCFN,
url: self.IFM_SCFN,
type: "POST",
data: ({
api: "changePermissions",
dir: ifm.currentDir,
dir: self.currentDir,
filename: name,
chmod: e.target.value
}),
dataType: "json",
success: function(data){
if(data.status == "OK") {
ifm.showMessage("Permissions successfully changed.", "s");
ifm.refreshFileTable();
self.showMessage("Permissions successfully changed.", "s");
self.refreshFileTable();
}
else {
ifm.showMessage("Permissions could not be changed: "+data.message, "e");
self.showMessage("Permissions could not be changed: "+data.message, "e");
}
},
error: function() { ifm.showMessage("General error occured.", "e"); }
error: function() { self.showMessage("General error occured.", "e"); }
});
},
remoteUploadDialog: function() {
$(document.body).prepend('<div class="overlay">\
<form id="uploadFile">\
};
this.remoteUploadDialog = function() {
self.showModal( '<form id="uploadFile">\
<div class="modal-body">\
<fieldset>\
<label>Remote upload URL</label><br>\
<input type="text" id="url" name="url" required><br>\
<input class="form-control" type="text" id="url" name="url" required><br>\
<label>Filename (required)</label>\
<input type="text" id="filename" name="filename" required><br>\
<input class="form-control" type="text" id="filename" name="filename" required><br>\
<label>Method</label>\
<input type="radio" name="method" value="curl" checked="checked">cURL<input type="radio" name="method" value="file">file</input><br>\
<button onclick="ifm.remoteUpload();$(\'.overlay\').remove();return false;">Upload</button>\
<button onclick="$(\'.overlay\').remove();return false;">Cancel</button>\
</fieldset>\
</form>\
</div>');
</fieldset><div class="modal-footer">\
<button type="button" class="btn btn-default" onclick="ifm.remoteUpload();ifm.hideModal();return false;">Upload</button>\
<button type="button" class="btn btn-default" onclick="ifm.hideModal();return false;">Cancel</button>\
</div>\
</form>' );
// guess the wanted filename, because it is required
// e.g http:/example.com/example.txt => filename: example.txt
$("#url").on("change keyup", function(){
@@ -455,8 +481,9 @@ if(!ifm) {
});
// if the filename input field was edited manually remove the event handler above
$("#filename").on("keyup", function() { $("#url").off(); });
},
remoteUpload: function() {
};
this.remoteUpload = function() {
var filename = $("#filename").val();
var id = ifm.generateGuid();
$.ajax({
@@ -480,44 +507,52 @@ if(!ifm) {
complete: function() { ifm.task_done(id); }
});
ifm.task_add("Remote upload: "+filename, id);
},
};
// --------------------
// additional functions
// --------------------
showMessage: function(m, t) {
var message = '<div id="mess"><div class="';
if(t == "e") message += "message_error";
else if(t == "s") message += "message_successful";
else message += "message";
message += '">'+m+'</div></div>';
$(document.body).prepend(message);
$("#mess").delay(2000).fadeOut('slow');
setTimeout(function() { // remove the message from the DOM after 3 seconds
$('#mess').remove();
}, 3000);
},
showLoading: function() {
this.showMessage = function(m, t) {
var msgType = (t == "e")?"danger":(t == "s")?"success":"info";
$.notify(
{ message: m },
{ type: msgType, delay: 5000, mouse_over: 'pause' }
);
// var message = '<div id="mess"><div class="';
// if(t == "e") message += "message_error";
// else if(t == "s") message += "message_successful";
// else message += "message";
// message += '">'+m+'</div></div>';
// $(document.body).prepend(message);
// $("#mess").delay(2000).fadeOut('slow');
// setTimeout(function() { // remove the message from the DOM after 3 seconds
// $('#mess').remove();
// }, 3000);
};
this.showLoading = function() {
var loading = '<div id="loading">'+ifm.loadingAnim+'</div>';
if(document.getElementById("loading")==null)$(document.body).prepend(loading);
},
hideLoading: function() {
};
this.hideLoading = function() {
$("#loading").remove();
},
pathCombine: function(a, b) {
};
this.pathCombine = function(a, b) {
if(a == "" && b == "") return "";
if(b[0] == "/") b = b.substring(1);
if(a == "") return b;
if(a[a.length-1] == "/") a = a.substring(0, a.length-1);
if(b == "") return a;
return a+"/"+b;
},
showSaveQuestion: function() {
};
this.showSaveQuestion = function() {
var a = '<div id="savequestion"><label>Do you want to save this file?</label><br><button onclick="ifm.saveFile();ifm.closeFileForm(); return false;">Save</button><button onclick="ifm.closeFileForm();return false;">Dismiss</button>';
$(document.body).prepend(a);
ifm.bindOverlayClickEvent();
},
hideSaveQuestion: function() { $("#savequestion").remove(); },
handleMultiSelect: function() {
self.bindOverlayClickEvent();
};
this.hideSaveQuestion = function() {
$("#savequestion").remove();
};
this.handleMultiSelect = function() {
var amount = $("input[name=multisel]:checked").length;
if(amount > 0) {
if(document.getElementById("multiseloptions")===null) {
@@ -536,8 +571,8 @@ if(!ifm) {
if(document.getElementById("multiseloptions")!==null)
$("#multiseloptions").remove();
}
},
multiDelete: function() {
};
this.multiDelete = function() {
var jel = $("input[name=multisel]:checked");
if(jel.length == 0) {
ifm.showMessage("No files chosen");
@@ -567,27 +602,27 @@ if(!ifm) {
},
error: function() { ifm.showMessage("General error occured", "e"); }
});
},
inArray: function(needle, haystack) {
};
this.inArray = function(needle, haystack) {
for(var i = 0; i < haystack.length; i++) { if(haystack[i] == needle) return true; } return false;
},
task_add: function(name,id) { // uFI stands for uploadFileInformation
};
this.task_add = function(name,id) { // uFI stands for uploadFileInformation
if(!document.getElementById("waitqueue")) {
$(document.body).prepend('<div id="waitqueue"></div>');
//$("#waitqueue").on("mouseover", function() { $(this).toggleClass("left"); });
}
$("#waitqueue").append('<div id="'+id+'" class="progress"><div class="progress-bar progress-bar-success progress-bar-striped active" role="progressbar" aria-valuenow="100" aria-valuemax="100" style="100%"></div>'+name+'</div>');
},
task_done: function(id) {
};
this.task_done = function(id) {
$("#"+id).remove();
if($("#waitqueue>div").length == 0) {
$("#waitqueue").remove();
}
},
task_update: function(progress, id) {
};
this.task_update = function(progress, id) {
$('#'+id+' .progress-bar').css('width', progress+'%').attr('aria-valuenow', progress);
},
generateGuid: function() {
};
this.generateGuid = function() {
var result, i, j;
result = '';
for(j=0; j<20; j++) {
@@ -595,32 +630,29 @@ if(!ifm) {
result = result + i;
}
return result;
},
JSEncode: function(s) {
};
this.JSEncode = function(s) {
return s.replace(/'/g, '\\x27').replace(/"/g, '\\x22');
},
};
// static button bindings and filetable initial filling
init: function() {
this.init = function() {
// fill file table
this.refreshFileTable();
// bind static buttons
$("#refresh").click(function(){
ifm.refreshFileTable();
self.refreshFileTable();
});
$("#createFile").click(function(){
ifm.showFileForm();
self.showFileForm();
});
$("#createDir").click(function(){
ifm.createDirForm();
self.createDirForm();
});
$("#upload").click(function(){
ifm.uploadFileDialog();
self.uploadFileDialog();
});
},
// ---------------
// further members
// ---------------
loadingAnim: '<div id="loadingAnim"><div class="blockG" id="rotateG_01"></div><div class="blockG" id="rotateG_02"></div><div class="blockG" id="rotateG_03"></div><div class="blockG" id="rotateG_04"></div><div class="blockG" id="rotateG_05"></div><div class="blockG" id="rotateG_06"></div><div class="blockG" id="rotateG_07"></div><div class="blockG" id="rotateG_08"></div></div>'
};
}
}
$(document).ready(function() {ifm.init()}); // init ifm
var ifm = new IFM();
ifm.init();

4
src/jquery.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -11,7 +11,7 @@
*/
class IFM {
const VERSION = '2.1';
const VERSION = '2.2-dev';
public function __construct() {
session_start();
@@ -70,11 +70,11 @@ class IFM {
print '<li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"><span class="icon icon-down-open"></span></a><ul class="dropdown-menu" role="menu">';
$options = false;
if( IFMConfig::remoteupload == 1 ) {
print '<li><a href="/fatfree/padlock/public/lang/de"><span class="icon icon-upload-cloud"></span> remote upload</a></li>';
print '<li><a onclick="ifm.remoteUploadDialog();return false;"><span class="icon icon-upload-cloud"></span> remote upload</a></li>';
$options = true;
}
if( IFMConfig::ajaxrequest == 1 ) {
print '<li><a href="/fatfree/padlock/public/lang/en"><span class="icon icon-link-ext"></span> ajax request</a></li>';
print '<li><a onclick="ifm.ajaxRequestDialog();return false;"><span class="icon icon-link-ext"></span> ajax request</a></li>';
$options = true;
}
if( !$options ) print '<li>No options available</li>';
@@ -103,10 +103,11 @@ class IFM {
</table>
</div>
<footer>IFM - improved file manager | ifm.php hidden | <a href="http://github.com/misterunknown/ifm">Visit the project on GitHub</a></footer>
<script>';?> @@@src/ace/ace.js@@@ <?php print '</script>
<script>';?> @@@src/jquery.min.js@@@ <?php print '</script>
<script>';?> @@@src/bootstrap.min.js@@@ <?php print '</script>
<script>';?> @@@src/bootstrap-notify.min.js@@@ <?php print '</script>
<script>';?> @@@src/ekko-lightbox.min.js@@@ <?php print '</script>
<script>';?> @@@src/ace.js@@@ <?php print '</script>
<script>';?> @@@src/ifm.js@@@ <?php print '</script>
</body>
</html>

View File

@@ -6,8 +6,16 @@ body {
font-size: 14pt;
}
#filetable tr td:nth-child(5) {
text-align: center;
}
#filetable tr td:nth-child(6) {
text-align: center;
}
#filetable tr td:last-child {
text-align: right;
}
a { cursor: pointer !important; }
div#content { width: 100%; height: 350px; }