Mon 21 Jul 22:43:21 CEST 2025
This commit is contained in:
parent
510ca50d8a
commit
b1ed0107c7
395
js/ui/webui/file.js
Normal file
395
js/ui/webui/file.js
Normal file
|
@ -0,0 +1,395 @@
|
|||
FileDialog = {
|
||||
locked : false,
|
||||
lock : function () {
|
||||
if (FileDialog.locked) return false;
|
||||
FileDialog.locked=true;
|
||||
return true;
|
||||
},
|
||||
unlock : function () { FileDialog.locked=false },
|
||||
refreshFileDialog : function (handle) {
|
||||
var lastselect;
|
||||
console.log('refreshFileDialog',handle.dir);
|
||||
handle.list(handle.dir, function (res) {
|
||||
if (Utils.isError(res)) {
|
||||
return handle.onerror(res);
|
||||
}
|
||||
var input=$('#fileDialogListFileName');
|
||||
if (res && res.status==0) {
|
||||
var list = $('#fileDialogList');
|
||||
list.empty();
|
||||
var entries=res.dirs;
|
||||
if (handle.mode=='Open' || handle.mode=='Load') entries=entries.concat(res.files);
|
||||
$('#fileDialogListLabel').html(handle.dir);
|
||||
entries.forEach(function (entry) {
|
||||
if (entry.name[0]=='.' && entry.name!='..') return;
|
||||
var listentry = $('<p/>',{
|
||||
class:'nav-entry '+(entry.dir?'nav-entry-directory':'nav-entry-file'),
|
||||
style:'cursor: pointer'
|
||||
}).append('<span>'+entry.name+'</span>').appendTo(list);
|
||||
if (entry.dir)
|
||||
listentry.bind('click',function () {
|
||||
if (entry.name=='..')
|
||||
handle.dir = handle.dir.replace(/(\/[^\/]+)$/,'');
|
||||
else
|
||||
handle.dir += ((handle.dir=='/'?'':'/')+entry.name);
|
||||
handle.dir=handle.dir||'/';
|
||||
handle.selected=entry.name;
|
||||
FileDialog.refreshFileDialog(handle);
|
||||
});
|
||||
else {
|
||||
listentry.bind('click',function () {
|
||||
if (lastselect) $(lastselect).removeClass('nav-selected');
|
||||
$(listentry).addClass('nav-selected');
|
||||
lastselect=listentry;
|
||||
handle.selected=entry.name;
|
||||
input.val(entry.name);
|
||||
});
|
||||
}
|
||||
return entry;
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
dialog : function (title, mode, dir, filename, fs, callback) {
|
||||
if (!FileDialog.lock()) return;
|
||||
var handle={selected:filename, dir:dir, mode:mode, list:fs.list};
|
||||
var html='<div><b>'+title+
|
||||
'</b><br><hr><div style="word-wrap: break-word;"id="fileDialogListLabel"></div>';
|
||||
html += '<input id="fileDialogListFileName" style="width:97%; height-max:400px; margin-top:5px;" value="'+filename+'">';
|
||||
html += '<div id="fileDialogList">';
|
||||
html += '</div></div>';
|
||||
var input,options
|
||||
handle.onerror=function (err) {
|
||||
// Fallback: Browser file dialog
|
||||
console.log('dialog',err);
|
||||
options.close();
|
||||
FileDialog.unlock();
|
||||
if (callback) callback(null,null,err);
|
||||
};
|
||||
setTimeout(function () { FileDialog.refreshFileDialog(handle); input=$('#fileDialogListFileName'); },1);
|
||||
popup.custom(options={content:html,default_btns:{ok:mode}},function (reply) {
|
||||
FileDialog.unlock();
|
||||
if (reply.proceed) {
|
||||
filename=input.val();
|
||||
if (callback) callback(handle.dir,filename);
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
if (!Config.wex) Config.wex={http:'http://localhost:11111' };
|
||||
if (!Config.workdir) Config.workdir='/';
|
||||
|
||||
// FS APi using the WEX server
|
||||
FS = {
|
||||
list : async function (dir,cb) {
|
||||
var result;
|
||||
function handler (response) {
|
||||
if (Utils.isError(response)) {
|
||||
if (cb) cb(response);
|
||||
return;
|
||||
}
|
||||
if (!Utils.isObject(response) || response.status!=0) {
|
||||
result=response;
|
||||
if (cb) cb(result);
|
||||
return;
|
||||
}
|
||||
var dirs=response.reply.filter(function (entry) { return entry.dir })
|
||||
.sort(function (a,b) { return a.name<b.name?-1:1 }),
|
||||
files=response.reply.filter(function (entry) { return !entry.dir })
|
||||
.sort(function (a,b) { return a.name<b.name?-1:1 });
|
||||
result = {dirs:dirs,files:files,status:response.status};
|
||||
if (cb) cb(result);
|
||||
}
|
||||
{
|
||||
if (cb) {
|
||||
Utils.POST(FS.url,{
|
||||
command: 'list',
|
||||
dir: dir,
|
||||
},handler,false);
|
||||
} else {
|
||||
return new Promise (function (resolve,reject) {
|
||||
cb=resolve;
|
||||
Utils.POST(FS.url,{
|
||||
command: 'list',
|
||||
dir: dir,
|
||||
},handler,false);
|
||||
})
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
load : async function(dir,file,mimetype,cb) {
|
||||
var result;
|
||||
if (typeof mimetype == 'function') { cb=mimetype; mimetype='text' };
|
||||
if (mimetype != 'binary') mimetype='text';
|
||||
function handler(response) {
|
||||
if (Utils.isError(response)) {
|
||||
if (cb) cb(response);
|
||||
return;
|
||||
}
|
||||
if (!Utils.isObject(response) || response.status!=0) {
|
||||
result=response;
|
||||
if (cb) cb(result);
|
||||
return;
|
||||
}
|
||||
result=response;
|
||||
if (mimetype=='binary' && typeof result.reply=='string') result.reply=Buffer.from(result.reply,'binary');
|
||||
if (cb) cb(result);
|
||||
}
|
||||
{
|
||||
if (cb) Utils.POST(FS.url,{
|
||||
command: 'load',
|
||||
dir: dir,
|
||||
file: file,
|
||||
mimetype : mimetype,
|
||||
},handler,false);
|
||||
else return new Promise (function (resolve,reject) {
|
||||
cb=resolve;
|
||||
Utils.POST(FS.url,{
|
||||
command: 'load',
|
||||
dir: dir,
|
||||
file: file,
|
||||
mimetype : mimetype,
|
||||
},handler,false);
|
||||
})
|
||||
}
|
||||
return result;
|
||||
},
|
||||
save : async function(dir,file,data,mimetype,cb) {
|
||||
var result;
|
||||
if (typeof mimetype == 'function') { cb=mimetype; mimetype='text' };
|
||||
if (mimetype != 'binary') mimetype='text';
|
||||
function handler(response) {
|
||||
if (Utils.isError(response)) {
|
||||
if (cb) cb(response);
|
||||
return;
|
||||
}
|
||||
result=response;
|
||||
if (cb) cb(result);
|
||||
}
|
||||
// console.log(data.length);
|
||||
{
|
||||
if (cb) Utils.POST(FS.url,{
|
||||
command: 'save',
|
||||
dir : dir,
|
||||
file : file,
|
||||
data : data,
|
||||
mimetype : mimetype||'text',
|
||||
},handler,false);
|
||||
else return new Promise (function (resolve,reject) {
|
||||
cb=resolve;
|
||||
Utils.POST(FS.url,{
|
||||
command: 'save',
|
||||
dir : dir,
|
||||
file : file,
|
||||
data : data,
|
||||
mimetype : mimetype,
|
||||
},handler,false)
|
||||
})
|
||||
}
|
||||
return result;
|
||||
},
|
||||
shell : async function (exec,dir,cb) {
|
||||
var result;
|
||||
function handler(response) {
|
||||
result=response;
|
||||
if (cb) cb(result);
|
||||
}
|
||||
{
|
||||
if (cb) Utils.POST(FS.url,{
|
||||
command: 'shell',
|
||||
exec: exec,
|
||||
dir: FS.workdir,
|
||||
},handler,false);
|
||||
else return new Promise (function (resolve,reject) {
|
||||
cb=resolve;
|
||||
Utils.POST(FS.url,{
|
||||
command: 'shell',
|
||||
exec: exec,
|
||||
dir: FS.workdir,
|
||||
},handler,false);
|
||||
})
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
url : Config.wex.url||Config.wex.http,
|
||||
workdir : Config.workdir||'/',
|
||||
workdirs : [],
|
||||
|
||||
// GUI API
|
||||
API : {
|
||||
loadFile: function loadFile(mimetype,callback,workdirCustom) {
|
||||
if (typeof callback == 'string') { workdirCustom=callback; callback=undefined; }
|
||||
var api = FS, workdir=(workdirCustom?FS.workdirs[workdirCustom]||FS.workdir1:FS.workdir1)||FS.workdir;
|
||||
FileDialog.dialog('Open','Open',
|
||||
workdir,'',api,function (dir,filename,err) {
|
||||
if (err) {
|
||||
console.log('FS.loadFile',err);
|
||||
if (callback) callback(err);
|
||||
return;
|
||||
}
|
||||
if (workdirCustom) FS.workdirs[workdirCustom]=dir;
|
||||
else FS.workdir1=dir;
|
||||
api.load(dir,filename,mimetype, function (result) {
|
||||
if (Utils.isError(result) || result.status!=0) return;
|
||||
if (callback) callback(result.reply,filename,dir);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
saveFile: function saveFile(data, filename, mimetype, callback, workdirCustom) {
|
||||
if (typeof callback == 'string') { workdirCustom=callback; callback=undefined; }
|
||||
var api = FS, workdir=(workdirCustom?FS.workdirs[workdirCustom]||FS.workdir1:FS.workdir1)||FS.workdir;
|
||||
FileDialog.dialog('Save','Save',
|
||||
workdir,filename,api,function (dir,filename,err) {
|
||||
if (err) {
|
||||
console.log('FS.saveFile',err);
|
||||
if (callback) callback(err);
|
||||
return;
|
||||
}
|
||||
if (workdirCustom) FS.workdirs[workdirCustom]=dir;
|
||||
else FS.workdir1=dir;
|
||||
api.save(dir,filename,data,mimetype, function (stat) {
|
||||
if (callback) callback(stat,filename,dir);
|
||||
})
|
||||
});
|
||||
},
|
||||
|
||||
importFile: function importFile(mimetype,callback) {
|
||||
var api = FS;
|
||||
FileDialog.dialog('Load Data','Load',
|
||||
FS.workdir2||FS.workdir,'',api,function (dir,filename) {
|
||||
FS.workdir2=dir;
|
||||
api.load(dir,filename,mimetype, function (result) {
|
||||
if (Utils.isError(result) || result.status!=0) return;
|
||||
if (callback) callback(result.reply,filename,dir);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
exportFile:function exportFile(data, filename, mimetype, callback) {
|
||||
var api = FS;
|
||||
FileDialog.dialog('Save Data','Save',
|
||||
FS.workdir2||FS.workdir,filename,api,function (dir,filename) {
|
||||
FS.workdir2=dir;
|
||||
api.save(dir,filename,data,mimetype, function (stat) {
|
||||
if (callback) callback(stat,filename,dir);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
selectDirectory: function selectFile(title,callback, workdirCustom) {
|
||||
if (typeof callback == 'string') { workdirCustom=callback; callback=undefined; }
|
||||
var api = FS, workdir=(workdirCustom?FS.workdirs[workdirCustom]||FS.workdir2||FS.workdir1:FS.workdir2)||FS.workdir;;
|
||||
FileDialog.dialog(title||'Select Directory','Open',
|
||||
workdir,'',api,function (dir,filename) {
|
||||
if (workdirCustom) FS.workdirs[workdirCustom]=dir;
|
||||
else FS.workdir2=dir;
|
||||
if (callback) callback(filename,dir);
|
||||
});
|
||||
},
|
||||
selectFile: function selectFile(title,callback, workdirCustom) {
|
||||
if (typeof callback == 'string') { workdirCustom=callback; callback=undefined; }
|
||||
var api = FS, workdir=(workdirCustom?FS.workdirs[workdirCustom]||FS.workdir2||FS.workdir1:FS.workdir2)||FS.workdir;;
|
||||
FileDialog.dialog(title||'Select File','Open',
|
||||
workdir,'',api,function (dir,filename) {
|
||||
if (workdirCustom) FS.workdirs[workdirCustom]=dir;
|
||||
else FS.workdir2=dir;
|
||||
if (callback) callback(filename,dir);
|
||||
});
|
||||
},
|
||||
},
|
||||
version : '1.2.5L',
|
||||
}
|
||||
|
||||
PATH = {
|
||||
basename : function (path,extension) {
|
||||
if (path[path.length-1]=='/') return '/';
|
||||
return extension?
|
||||
path.split('/').reverse()[0].replace(RegExp(extension.replace(/\./,'\\.')+'$'),'')
|
||||
:
|
||||
path.split('/').reverse()[0];
|
||||
},
|
||||
dirname : function (path) {
|
||||
var el=path.split('/');
|
||||
el.pop();
|
||||
return el.join('/');
|
||||
},
|
||||
|
||||
extension : function (file) {
|
||||
return file.replace(/^[^\.]+\./,'');
|
||||
}
|
||||
}
|
||||
|
||||
function loadFile (cb,binary) {
|
||||
if (Config.workdir) {
|
||||
// Try WEX service?
|
||||
return FS.API.loadFile(binary?'binary':'text',function (result,file) {
|
||||
if (Utils.isError(result)) {
|
||||
Config.workdir='';
|
||||
return nativeDialog();
|
||||
}
|
||||
if (cb) cb(result,file);
|
||||
})
|
||||
}
|
||||
function nativeDialog() {
|
||||
var input = document.createElement('input');
|
||||
input.type = 'file';
|
||||
input.onchange = function (e) {
|
||||
// getting a hold of the file reference
|
||||
var file = e.target.files[0];
|
||||
|
||||
// setting up the reader
|
||||
var reader = new FileReader();
|
||||
if (binary)
|
||||
reader.readAsArrayBuffer(file);
|
||||
else
|
||||
reader.readAsText(file,'UTF-8');
|
||||
|
||||
// here we tell the reader what to do when it's done reading...
|
||||
reader.onload = function (readerEvent) {
|
||||
var content = readerEvent.target.result; // this is the content!
|
||||
// console.log( content );
|
||||
if (binary)
|
||||
cb(new Uint8Array(content),input.files[0].name);
|
||||
else
|
||||
cb(content,input.files[0].name)
|
||||
}
|
||||
}
|
||||
input.click();
|
||||
}
|
||||
nativeDialog();
|
||||
}
|
||||
|
||||
function saveFile(data, filename, mimetype, callback) {
|
||||
if (Config.workdir) {
|
||||
// Try WEX service?
|
||||
return FS.API.saveFile(data, filename, mimetype||'text',function (stat,filename) {
|
||||
if (Utils.isError(stat)) {
|
||||
return nativeDialog();
|
||||
}
|
||||
callback(filename)
|
||||
})
|
||||
}
|
||||
function nativeDialog() {
|
||||
var file = new Blob([data], {type: mimetype});
|
||||
if (window.navigator.msSaveOrOpenBlob) // IE10+
|
||||
window.navigator.msSaveOrOpenBlob(file, filename);
|
||||
else { // Others
|
||||
var a = document.createElement("a"),
|
||||
url = URL.createObjectURL(file);
|
||||
a.href = url;
|
||||
a.download = filename;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
setTimeout(function() {
|
||||
document.body.removeChild(a);
|
||||
window.URL.revokeObjectURL(url);
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user