Allow 'edit anyway' option for non-text files

fixes #50
This commit is contained in:
joshuaboud 2022-10-26 17:37:56 -03:00
parent d70d66f650
commit f91fd9aea0
No known key found for this signature in database
GPG Key ID: 17EFB59E2A8BF50E

View File

@ -41,18 +41,18 @@ export class NavFile extends NavEntry {
* @param {Event} e
*/
handleEvent(e) {
switch(e.type){
switch (e.type) {
case "click":
if (this.double_click) {
if(this.timeout)
if (this.timeout)
clearTimeout(this.timeout);
this.double_click = false;
this.open();
return;
} else { // single click
this.double_click = true;
if(this.timeout)
clearTimeout(this.timeout)
if (this.timeout)
clearTimeout(this.timeout);
this.timeout = setTimeout(() => {
this.double_click = false;
}, 500);
@ -77,7 +77,7 @@ export class NavFile extends NavEntry {
return new Promise((resolve, reject) => {
var proc = cockpit.spawn(
["rm", "-f", this.path_str()],
{superuser: "try", err: "out"}
{ superuser: "try", err: "out" }
);
proc.done((data) => {
resolve();
@ -89,18 +89,19 @@ export class NavFile extends NavEntry {
}
async open() {
var proc_output = await cockpit.spawn(["file", "--mime-type", this.path_str()], {superuser: "try"});
var fields = proc_output.split(/:(?=[^:]+$)/); // ensure it's the last : with lookahead
var type = fields[1].trim();
if (/^text/.test(type) || /^inode\/x-empty$/.test(type) || this.stat["size"] === 0 || (/^application\/octet-stream/.test(type) && this.stat["size"] === 1)) {
this.show_edit_file_contents();
} else {
console.log("Unknown mimetype: " + type);
if (await this.nav_window_ref.modal_prompt.confirm("Can't open " + this.filename + " for editing.", "Download it instead?")) {
var download = new NavDownloader(this);
download.download();
async function isEditable(path, fileSize) {
if (fileSize === 0)
return true; // empty file always editable
const encoding = (await cockpit.spawn(["file", "-bL", "--mime-encoding", path], { superuser: "try" })).trim();
if (['us-ascii', 'utf-8'].includes(encoding))
return true;
if (fileSize === 1 && ['\n', '\t', ' '].includes(await cockpit.file(path).read()))
return true; // special case for empty file with newline, shows as `application/octet-stream; charset=binary`
return false;
}
if (await isEditable(this.path_str(), this.stat['size']) || await this.nav_window_ref.modal_prompt.confirm(`'${this.filename}' is not a text file. Open it anyway?`, "WARNING: this may lead to file corruption.", true)) {
this.show_edit_file_contents();
}
}
@ -109,7 +110,7 @@ export class NavFile extends NavEntry {
this.nav_window_ref.disable_buttons_for_editing();
var contents = "";
try {
contents = await cockpit.file(this.path_str(), {superuser: "try"}).read();
contents = await cockpit.file(this.path_str(), { superuser: "try" }).read();
} catch (e) {
this.nav_window_ref.enable_buttons();
this.nav_window_ref.modal_prompt.alert(e.message);
@ -145,7 +146,7 @@ export class NavFile extends NavEntry {
}
}
export class NavFileLink extends NavFile{
export class NavFileLink extends NavFile {
/**
*
* @param {string} path
@ -187,7 +188,7 @@ export class NavFileLink extends NavFile{
async open() {
var target_path = this.get_link_target_path();
var proc_output = await cockpit.spawn(["file", "--mime-type", target_path], {superuser: "try"});
var proc_output = await cockpit.spawn(["file", "--mime-type", target_path], { superuser: "try" });
var fields = proc_output.split(/:(?=[^:]+$)/); // ensure it's the last : with lookahead
var type = fields[1].trim();
@ -206,8 +207,8 @@ export class NavFileLink extends NavFile{
var target_path = this.get_link_target_path();
var contents = "";
try {
contents = await cockpit.file(target_path, {superuser: "try"}).read();
} catch(e) {
contents = await cockpit.file(target_path, { superuser: "try" }).read();
} catch (e) {
this.nav_window_ref.enable_buttons();
this.nav_window_ref.modal_prompt.alert(e.message);
return;