Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/stefan-niedermann/nextcloud-deck.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Niedermann <info@niedermann.it>2020-12-02 11:53:13 +0300
committerStefan Niedermann <info@niedermann.it>2020-12-02 11:53:13 +0300
commitcbd46ad5e693bdeff7e2cbd49ea0cf75f10a8056 (patch)
tree34175fd6241bfbcc54de80720ee50e9878461399
parent3cc27df32e010aaf68be8e9e135f3ed25baa9f36 (diff)
Move list auto continuation to own class
Signed-off-by: Stefan Niedermann <info@niedermann.it>
-rw-r--r--markdown/src/main/java/it/niedermann/android/markdown/markwon/MarkwonMarkdownEditor.java79
-rw-r--r--markdown/src/main/java/it/niedermann/android/markdown/markwon/textwatcher/AutoContinuationTextWatcher.java117
2 files changed, 120 insertions, 76 deletions
diff --git a/markdown/src/main/java/it/niedermann/android/markdown/markwon/MarkwonMarkdownEditor.java b/markdown/src/main/java/it/niedermann/android/markdown/markwon/MarkwonMarkdownEditor.java
index 887b35620..1e4a1fba7 100644
--- a/markdown/src/main/java/it/niedermann/android/markdown/markwon/MarkwonMarkdownEditor.java
+++ b/markdown/src/main/java/it/niedermann/android/markdown/markwon/MarkwonMarkdownEditor.java
@@ -1,8 +1,6 @@
package it.niedermann.android.markdown.markwon;
import android.content.Context;
-import android.text.Editable;
-import android.text.TextWatcher;
import android.util.AttributeSet;
import androidx.annotation.NonNull;
@@ -11,11 +9,8 @@ import androidx.appcompat.widget.AppCompatEditText;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
-import java.util.concurrent.Executors;
-
import io.noties.markwon.Markwon;
import io.noties.markwon.editor.MarkwonEditor;
-import io.noties.markwon.editor.MarkwonEditorTextWatcher;
import io.noties.markwon.editor.handler.EmphasisEditHandler;
import io.noties.markwon.editor.handler.StrongEmphasisEditHandler;
import it.niedermann.android.markdown.MarkdownEditor;
@@ -24,18 +19,10 @@ import it.niedermann.android.markdown.markwon.handler.CodeBlockEditHandler;
import it.niedermann.android.markdown.markwon.handler.CodeEditHandler;
import it.niedermann.android.markdown.markwon.handler.HeadingEditHandler;
import it.niedermann.android.markdown.markwon.handler.StrikethroughEditHandler;
+import it.niedermann.android.markdown.markwon.textwatcher.AutoContinuationTextWatcher;
public class MarkwonMarkdownEditor extends AppCompatEditText implements MarkdownEditor {
- private static final String CHECKBOX_UNCHECKED_MINUS = "- [ ]";
- private static final String CHECKBOX_UNCHECKED_MINUS_TRAILING_SPACE = CHECKBOX_UNCHECKED_MINUS + " ";
- private static final String CHECKBOX_UNCHECKED_STAR = "* [ ]";
- private static final String CHECKBOX_UNCHECKED_STAR_TRAILING_SPACE = CHECKBOX_UNCHECKED_STAR + " ";
- private static final String CHECKBOX_CHECKED_MINUS = "- [x]";
- private static final String CHECKBOX_CHECKED_STAR = "* [x]";
-
- private static final int lengthCheckbox = 6;
-
private final MutableLiveData<CharSequence> unrenderedText$ = new MutableLiveData<>();
public MarkwonMarkdownEditor(@NonNull Context context) {
@@ -59,29 +46,8 @@ public class MarkwonMarkdownEditor extends AppCompatEditText implements Markdown
.useEditHandler(new HeadingEditHandler())
.build();
- MarkwonEditorTextWatcher originalWatcher = MarkwonEditorTextWatcher.withPreRender(editor, Executors.newSingleThreadExecutor(), this);
-
- // intercept behavior of the original MarkwonEditorTextWatcher.
- addTextChangedListener(new TextWatcher() {
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
- originalWatcher.beforeTextChanged(s, start, count, after);
- }
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- if (count == 1 && s.charAt(start) == '\n') {
- autoContinueCheckboxListsOnEnter(s, start, count);
- }
- originalWatcher.onTextChanged(s, start, before, count);
-// unrenderedText$.setValue(s.toString());
- }
-
- @Override
- public void afterTextChanged(Editable s) {
- originalWatcher.afterTextChanged(s);
- }
- });
+ // addTextChangedListener(MarkwonEditorTextWatcher.withPreRender(editor, Executors.newSingleThreadExecutor(), this));
+ addTextChangedListener(new AutoContinuationTextWatcher(editor, this));
}
@Override
@@ -94,43 +60,4 @@ public class MarkwonMarkdownEditor extends AppCompatEditText implements Markdown
public LiveData<CharSequence> getMarkdownString() {
return unrenderedText$;
}
-
- private boolean autoContinueCheckboxListsOnEnter(@NonNull CharSequence originalSequence, int start, int count) {
- final CharSequence s = originalSequence.subSequence(0, originalSequence.length());
- final int startOfLine = getStartOfLine(s, start);
- final String line = s.subSequence(startOfLine, start).toString();
-
- if (line.equals(CHECKBOX_UNCHECKED_MINUS_TRAILING_SPACE) || line.equals(CHECKBOX_UNCHECKED_STAR_TRAILING_SPACE)) {
- setSelection(startOfLine + 1);
- setNewText(new StringBuilder(s).replace(startOfLine, startOfLine + lengthCheckbox + 1, "\n"), startOfLine + 1);
- return true;
- } else if (lineStartsWithCheckbox(line, false)) {
- setNewText(new StringBuilder(s).insert(start + count, CHECKBOX_UNCHECKED_MINUS_TRAILING_SPACE), start + lengthCheckbox + 1);
- return true;
- } else if (lineStartsWithCheckbox(line, true)) {
- setNewText(new StringBuilder(s).insert(start + count, CHECKBOX_UNCHECKED_STAR_TRAILING_SPACE), start + lengthCheckbox + 1);
- return true;
- }
- return false;
- }
-
- private void setNewText(@NonNull StringBuilder newText, int selection) {
- setMarkdownString(newText.toString());
- unrenderedText$.setValue(newText.toString());
- setSelection(selection);
- }
-
- private static int getStartOfLine(@NonNull CharSequence s, int cursorPosition) {
- int startOfLine = cursorPosition;
- while (startOfLine > 0 && s.charAt(startOfLine - 1) != '\n') {
- startOfLine--;
- }
- return startOfLine;
- }
-
- private static boolean lineStartsWithCheckbox(@NonNull String line, boolean starAsLeadingCharacter) {
- return starAsLeadingCharacter
- ? line.startsWith(CHECKBOX_UNCHECKED_STAR) || line.startsWith(CHECKBOX_CHECKED_STAR)
- : line.startsWith(CHECKBOX_UNCHECKED_MINUS) || line.startsWith(CHECKBOX_CHECKED_MINUS);
- }
}
diff --git a/markdown/src/main/java/it/niedermann/android/markdown/markwon/textwatcher/AutoContinuationTextWatcher.java b/markdown/src/main/java/it/niedermann/android/markdown/markwon/textwatcher/AutoContinuationTextWatcher.java
new file mode 100644
index 000000000..55a446f3f
--- /dev/null
+++ b/markdown/src/main/java/it/niedermann/android/markdown/markwon/textwatcher/AutoContinuationTextWatcher.java
@@ -0,0 +1,117 @@
+package it.niedermann.android.markdown.markwon.textwatcher;
+
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+
+import java.util.concurrent.Executors;
+
+import io.noties.markwon.editor.MarkwonEditor;
+import io.noties.markwon.editor.MarkwonEditorTextWatcher;
+import it.niedermann.android.markdown.markwon.MarkwonMarkdownEditor;
+
+/**
+ * Automatically continues lists and checkbox lists when pressing enter
+ */
+public class AutoContinuationTextWatcher implements TextWatcher {
+
+ private static final String TAG = AutoContinuationTextWatcher.class.getSimpleName();
+
+ private static final String CHECKBOX_CHECKED_DASH = "- [x]";
+ private static final String CHECKBOX_CHECKED_STAR = "* [x]";
+ private static final String CHECKBOX_CHECKED_PLUS = "+ [x]";
+ private static final String CHECKBOX_UNCHECKED_DASH = "- [ ]";
+ private static final String CHECKBOX_UNCHECKED_STAR = "* [ ]";
+ private static final String CHECKBOX_UNCHECKED_PLUS = "+ [ ]";
+ private static final String CHECKBOX_UNCHECKED_DASH_TRAILING_SPACE = CHECKBOX_UNCHECKED_DASH + " ";
+ private static final String CHECKBOX_UNCHECKED_STAR_TRAILING_SPACE = CHECKBOX_UNCHECKED_STAR + " ";
+ private static final String CHECKBOX_UNCHECKED_PLUS_TRAILING_SPACE = CHECKBOX_UNCHECKED_PLUS + " ";
+
+ private static final int CHECKBOX_TRAILING_SPACE_LENGTH = 6;
+
+ private final MarkwonEditorTextWatcher originalWatcher;
+ private final MarkwonMarkdownEditor editText;
+
+ public AutoContinuationTextWatcher(@NonNull MarkwonEditor editor, @NonNull MarkwonMarkdownEditor editText) {
+ this.editText = editText;
+ originalWatcher = MarkwonEditorTextWatcher.withPreRender(editor, Executors.newSingleThreadExecutor(), editText);
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ originalWatcher.beforeTextChanged(s, start, count, after);
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ if (count == 1 && s.charAt(start) == '\n') {
+ autoContinueCheckboxListsOnEnter(s, start, count);
+ }
+ originalWatcher.onTextChanged(s, start, before, count);
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ originalWatcher.afterTextChanged(s);
+ }
+
+ /**
+ * @return added characters in front of the current line (can be negative)
+ */
+ private int autoContinueCheckboxListsOnEnter(@NonNull CharSequence originalSequence, int start, int count) {
+ final CharSequence s = originalSequence.subSequence(0, originalSequence.length());
+ final int startOfLine = getStartOfLine(s, start);
+ final String line = s.subSequence(startOfLine, start).toString();
+
+ if (line.equals(CHECKBOX_UNCHECKED_DASH_TRAILING_SPACE) || line.equals(CHECKBOX_UNCHECKED_STAR_TRAILING_SPACE)) {
+ editText.setSelection(startOfLine + 1);
+ setNewText(new StringBuilder(s).replace(startOfLine, startOfLine + CHECKBOX_TRAILING_SPACE_LENGTH + 1, "\n"), startOfLine + 1);
+ return CHECKBOX_TRAILING_SPACE_LENGTH * -1;
+ } else if (lineStartsWithCheckbox(line, EListType.DASH)) {
+ setNewText(new StringBuilder(s).insert(start + count, CHECKBOX_UNCHECKED_DASH_TRAILING_SPACE), start + CHECKBOX_TRAILING_SPACE_LENGTH + 1);
+ return CHECKBOX_TRAILING_SPACE_LENGTH;
+ } else if (lineStartsWithCheckbox(line, EListType.STAR)) {
+ setNewText(new StringBuilder(s).insert(start + count, CHECKBOX_UNCHECKED_STAR_TRAILING_SPACE), start + CHECKBOX_TRAILING_SPACE_LENGTH + 1);
+ return CHECKBOX_TRAILING_SPACE_LENGTH;
+ } else if (lineStartsWithCheckbox(line, EListType.PLUS)) {
+ setNewText(new StringBuilder(s).insert(start + count, CHECKBOX_UNCHECKED_PLUS_TRAILING_SPACE), start + CHECKBOX_TRAILING_SPACE_LENGTH + 1);
+ return CHECKBOX_TRAILING_SPACE_LENGTH;
+ }
+ return 0;
+ }
+
+ private void setNewText(@NonNull StringBuilder newText, int selection) {
+ editText.setMarkdownString(newText.toString());
+ editText.setSelection(selection);
+ }
+
+ private static int getStartOfLine(@NonNull CharSequence s, int cursorPosition) {
+ int startOfLine = cursorPosition;
+ while (startOfLine > 0 && s.charAt(startOfLine - 1) != '\n') {
+ startOfLine--;
+ }
+ return startOfLine;
+ }
+
+ private static boolean lineStartsWithCheckbox(@NonNull String line, @NonNull EListType listType) {
+ switch (listType) {
+ case STAR:
+ return line.startsWith(CHECKBOX_UNCHECKED_STAR) || line.startsWith(CHECKBOX_CHECKED_STAR);
+ case DASH:
+ return line.startsWith(CHECKBOX_UNCHECKED_DASH) || line.startsWith(CHECKBOX_CHECKED_DASH);
+ case PLUS:
+ return line.startsWith(CHECKBOX_UNCHECKED_PLUS) || line.startsWith(CHECKBOX_CHECKED_PLUS);
+ default:
+ Log.w(TAG, "List type " + listType + " is not supported.");
+ return false;
+ }
+ }
+
+ private enum EListType {
+ STAR,
+ DASH,
+ PLUS
+ }
+}