Fix the issue that markdown editor often prompts for unsaved changes

This commit is contained in:
Robin Shen 2022-02-22 19:53:36 +08:00
parent 27295f65cd
commit e09b950825
12 changed files with 24 additions and 119 deletions

View File

@ -225,7 +225,14 @@ public class MarkdownEditor extends FormComponentPanel<String> {
container.add(new WebMarkupContainer("doMention").setVisible(getUserMentionSupport() != null));
edit.add(input = new TextArea<String>("input", Model.of(getModelObject())));
edit.add(input = new TextArea<String>("input", Model.of(getModelObject())) {
@Override
protected boolean shouldTrimInput() {
return MarkdownEditor.this.shouldTrimInput();
}
});
for (AttributeModifier modifier: getInputModifiers())
input.add(modifier);
@ -505,13 +512,7 @@ public class MarkdownEditor extends FormComponentPanel<String> {
explicit("param3")).toString();
String attachmentUploadUrl = attachmentUploadBehavior.getCallbackUrl().toString();
String autosaveKey = getAutosaveKey();
if (autosaveKey != null)
autosaveKey = "'" + JavaScriptEscape.escapeJavaScript(autosaveKey) + "'";
else
autosaveKey = "undefined";
String script = String.format("onedev.server.markdown.onDomReady('%s', %s, %d, %s, %d, %b, %b, '%s', %s);",
String script = String.format("onedev.server.markdown.onDomReady('%s', %s, %d, %s, %d, %b, %b, '%s');",
container.getMarkupId(),
actionCallback,
ATWHO_LIMIT,
@ -519,8 +520,7 @@ public class MarkdownEditor extends FormComponentPanel<String> {
getAttachmentSupport()!=null? getAttachmentSupport().getAttachmentMaxSize(): 0,
getUserMentionSupport() != null,
getReferenceSupport() != null,
JavaScriptEscape.escapeJavaScript(ProjectPathValidator.PATTERN.pattern()),
autosaveKey);
JavaScriptEscape.escapeJavaScript(ProjectPathValidator.PATTERN.pattern()));
response.render(OnDomReadyHeaderItem.forScript(script));
script = String.format("onedev.server.markdown.onLoad('%s');", container.getMarkupId());
@ -561,11 +561,6 @@ public class MarkdownEditor extends FormComponentPanel<String> {
return new ArrayList<>();
}
@Nullable
protected String getAutosaveKey() {
return null;
}
@Nullable
public BlobRenderContext getBlobRenderContext() {
return blobRenderContext;

View File

@ -27,10 +27,9 @@ onedev.server.markdown = {
},
onDomReady: function(containerId, callback, atWhoLimit, attachmentUploadUrl,
attachmentMaxSize, canMentionUser, canReferenceEntity,
projectPathPattern, autosaveKey) {
projectPathPattern) {
var $container = $("#" + containerId);
$container.data("callback", callback);
$container.data("autosaveKey", autosaveKey);
var $head = $container.children(".head");
var $body = $container.children(".body");
@ -109,12 +108,6 @@ onedev.server.markdown = {
}
render();
if (autosaveKey) {
var content = $input.val();
if (content.trim().length != 0)
localStorage.setItem(autosaveKey, content);
}
}, previewTimeout);
$input.doneEvents("keydown", function(e) {
@ -820,17 +813,6 @@ onedev.server.markdown = {
$preview.height(defaultHeight);
}
}
var autosaveKey = $container.data("autosaveKey");
if (autosaveKey) {
onedev.server.form.registerAutosaveKey($container.closest("form.leave-confirm"), autosaveKey);
var autosaveValue = localStorage.getItem(autosaveKey);
if (autosaveValue && $input.val() != autosaveValue) {
$input.val(autosaveValue);
$warning.show();
onedev.server.markdown.fireInputEvent($input);
}
}
},
onRendered: function(containerId, html) {
var $preview = $("#" + containerId + ">.body>.preview");

View File

@ -154,7 +154,6 @@ onedev.server = {
var $dirtyForms = $container.find(selector).addBack(selector);
if ($dirtyForms.length != 0) {
if (confirm("There are unsaved changes, do you want to discard and continue?")) {
onedev.server.form.clearAutosavings($dirtyForms);
return true;
} else {
return false;
@ -162,16 +161,6 @@ onedev.server = {
} else {
return true;
}
},
clearAutosavings: function($dirtyForms) {
$dirtyForms.each(function() {
var autosaveKey = $(this).data("autosaveKey");
if (autosaveKey)
localStorage.removeItem(autosaveKey);
});
},
registerAutosaveKey: function($form, autosaveKey) {
$form.data("autosaveKey", autosaveKey);
}
},
setupAutoSize: function() {
@ -871,10 +860,6 @@ onedev.server = {
if (e.keyCode == 27)
e.preventDefault();
});
window.onunload = function() {
onedev.server.form.clearAutosavings($("form.leave-confirm.dirty"));
};
},
onWindowLoad: function() {

View File

@ -1489,20 +1489,6 @@ public class ProjectBlobPage extends ProjectPage implements BlobRenderContext,
return state.problemReport;
}
@Override
public String getAutosaveKey() {
if (state.mode == Mode.ADD) {
return String.format("autosave:addBlob:%d:%s:%s",
getProject().getId(), state.blobIdent.revision, getNewPath());
} else if (state.mode == Mode.EDIT) {
return String.format("autosave:editBlob:%d:%s:%s:%s",
getProject().getId(), state.blobIdent.revision,
state.blobIdent.path, getProject().getBlob(state.blobIdent, true).getBlobId());
} else {
throw new IllegalStateException();
}
}
@Override
public RefUpdated uploadFiles(Collection<FileUpload> uploads, String directory, String commitMessage) {
Map<String, BlobContent> newBlobs = new HashMap<>();

View File

@ -135,7 +135,5 @@ public interface BlobRenderContext extends Serializable {
@Nullable
String getInitialNewPath();
String getAutosaveKey();
String appendRaw(String url);
}

View File

@ -80,8 +80,6 @@ public class CommitOptionPanel extends Panel {
private Form<?> form;
private final String autosaveKey;
public CommitOptionPanel(String id, BlobRenderContext context, @Nullable Provider<byte[]> newContentProvider) {
super(id);
@ -92,11 +90,6 @@ public class CommitOptionPanel extends Panel {
String oldPath = getOldPath();
if (oldPath != null)
oldPaths.add(oldPath);
if (context.getMode() != Mode.DELETE)
autosaveKey = context.getAutosaveKey();
else
autosaveKey = null;
}
@Nullable
@ -347,8 +340,6 @@ public class CommitOptionPanel extends Panel {
if (newCommitId != null) {
RefUpdated refUpdated = new RefUpdated(context.getProject(), refName, prevCommitId, newCommitId);
context.onCommitted(target, refUpdated);
if (autosaveKey != null)
target.appendJavaScript(String.format("localStorage.removeItem('%s');", autosaveKey));
target.appendJavaScript("$(window).resize();");
return true;
} else {

View File

@ -76,7 +76,6 @@ onedev.server.blobEdit = {
$form.parent().addClass("dirty");
else
$form.parent().removeClass("dirty");
$form.parent().data("autosaveKey", $form.data("autosaveKey"));
},
restoreFormFlags: function(formId) {
var $form = $("#" + formId);
@ -84,7 +83,6 @@ onedev.server.blobEdit = {
$form.addClass("dirty");
else
$form.removeClass("dirty");
$form.data("autosaveKey", $form.parent().data("autosaveKey"));
},
onNameChanging: function(containerId, addingFile, recreateCallback) {
var $body = $("#" + containerId + ">.blob-edit>.body");

View File

@ -22,14 +22,7 @@ public class MarkdownBlobEditPanel extends BlobEditPanel {
@Override
protected FormComponentPanel<byte[]> newEditor(String componentId, byte[] initialContent) {
return new MarkdownBlobEditor(componentId, context, initialContent) {
@Override
protected String getAutosaveKey() {
return context.getAutosaveKey();
}
};
return new MarkdownBlobEditor(componentId, context, initialContent);
}
}

View File

@ -38,7 +38,7 @@ import io.onedev.server.web.page.project.blob.render.BlobRenderContext;
import io.onedev.server.web.page.project.blob.render.BlobRenderContext.Mode;
@SuppressWarnings("serial")
abstract class MarkdownBlobEditor extends FormComponentPanel<byte[]> {
class MarkdownBlobEditor extends FormComponentPanel<byte[]> {
private final BlobRenderContext context;
@ -59,17 +59,17 @@ abstract class MarkdownBlobEditor extends FormComponentPanel<byte[]> {
add(input = new MarkdownEditor("input", Model.of(new String(getModelObject(), charset)),
false, context) {
@Override
protected String getAutosaveKey() {
return MarkdownBlobEditor.this.getAutosaveKey();
}
@Override
protected String renderMarkdown(String markdown) {
MarkdownManager manager = OneDev.getInstance(MarkdownManager.class);
return manager.process(manager.render(markdown), context.getProject(), context, false);
}
@Override
protected boolean shouldTrimInput() {
return false;
}
@Override
protected UserMentionSupport getUserMentionSupport() {
return new UserMentionSupport() {
@ -160,6 +160,4 @@ abstract class MarkdownBlobEditor extends FormComponentPanel<byte[]> {
}
}
protected abstract String getAutosaveKey();
}

View File

@ -6,7 +6,6 @@ import org.apache.wicket.markup.head.JavaScriptHeaderItem;
import org.apache.wicket.markup.head.OnLoadHeaderItem;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.form.FormComponentPanel;
import org.unbescape.javascript.JavaScriptEscape;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
@ -83,11 +82,10 @@ public class SourceEditPanel extends BlobEditPanel implements Positionable {
super.renderHead(response);
response.render(JavaScriptHeaderItem.forReference(new SourceEditResourceReference()));
String autosaveKey = JavaScriptEscape.escapeJavaScript(context.getAutosaveKey());
PlanarRange mark = BlobRendererer.getSourceRange(context.getPosition());
String script = String.format("onedev.server.sourceEdit.onWindowLoad('%s', %s, '%s');",
getEditor().getMarkupId(), mark != null? getJson(mark): "undefined", autosaveKey);
String script = String.format("onedev.server.sourceEdit.onWindowLoad('%s', %s);",
getEditor().getMarkupId(), mark != null? getJson(mark): "undefined");
response.render(OnLoadHeaderItem.forScript(script));
}

View File

@ -69,7 +69,6 @@ abstract class SourceFormComponent extends FormComponentPanel<byte[]> {
@Override
public void renderHead(IHeaderResponse response) {
super.renderHead(response);
String autosaveKey = JavaScriptEscape.escapeJavaScript(getContext().getAutosaveKey());
PlanarRange mark = BlobRendererer.getSourceRange(getContext().getPosition());
String jsonOfMark;
if (mark != null) {
@ -82,15 +81,14 @@ abstract class SourceFormComponent extends FormComponentPanel<byte[]> {
jsonOfMark = "undefined";
}
String script = String.format("onedev.server.sourceEdit.onDomReady("
+ "'%s', '%s', %s, '%s', %s, '%s', %b, '%s');",
+ "'%s', '%s', %s, '%s', %s, '%s', %b);",
getMarkupId(),
JavaScriptEscape.escapeJavaScript(getContext().getNewPath()),
jsonOfMark,
getSourceFormat().getIndentType(),
getSourceFormat().getTabSize(),
getSourceFormat().getLineWrapMode(),
getContext().getMode() == Mode.EDIT || getContext().getInitialNewPath() != null,
autosaveKey);
getContext().getMode() == Mode.EDIT || getContext().getInitialNewPath() != null);
response.render(OnDomReadyHeaderItem.forScript(script));
}

View File

@ -1,6 +1,5 @@
onedev.server.sourceEdit = {
onDomReady: function(containerId, filePath, mark, indentType, tabSize, lineWrapMode,
autoFocus, autosaveKey) {
onDomReady: function(containerId, filePath, mark, indentType, tabSize, lineWrapMode, autoFocus) {
var $container = $("#" + containerId);
var $sourceEdit = $container.children(".source-edit");
var $warning = $sourceEdit.children(".warning");
@ -40,18 +39,8 @@ onedev.server.sourceEdit = {
onedev.server.codemirror.bindShortcuts(cm);
var doneTimer;
cm.on("change", function() {
$sourceEdit.closest("form").addClass("dirty");
if (doneTimer)
clearTimeout(doneTimer);
doneTimer = setTimeout(function() {
var cm = $(".source-edit>.code>.CodeMirror")[0].CodeMirror;
var content = cm.doc.getValue();
if (content.trim().length != 0)
localStorage.setItem(autosaveKey, content);
cm = null;
}, 500);
});
$code.on("getViewState", function(e) {
@ -77,16 +66,10 @@ onedev.server.sourceEdit = {
$(window).resize();
});
},
onWindowLoad: function(containerId, mark, autosaveKey) {
onWindowLoad: function(containerId, mark) {
var $container = $("#" + containerId);
var $warning = $container.find(">.source-edit>.warning");
var cm = $(".source-edit>.code>.CodeMirror")[0].CodeMirror;
onedev.server.form.registerAutosaveKey($container.closest("form.leave-confirm"), autosaveKey);
var autosaveValue = localStorage.getItem(autosaveKey);
if (autosaveValue) {
cm.doc.setValue(autosaveValue);
$warning.show();
}
if (mark && onedev.server.viewState.getFromHistory() === undefined
&& onedev.server.viewState.carryOver === undefined) {