Просмотр исходного кода

impl auto indent when pasting list items

Yuki Takei 8 лет назад
Родитель
Сommit
e813495438
1 измененных файлов с 44 добавлено и 2 удалено
  1. 44 2
      resource/js/components/PageEditor/PasteHelper.js

+ 44 - 2
resource/js/components/PageEditor/PasteHelper.js

@@ -1,7 +1,7 @@
 class PasteHelper {
 
   constructor() {
-    // https://regex101.com/r/7BN2fR/2
+    // https://regex101.com/r/7BN2fR/3
     this.indentAndMarkPattern = /^([ \t]*)(?:>|\-|\+|\*|\d+\.) /;
 
     this.pasteHandler = this.pasteHandler.bind(this);
@@ -63,21 +63,63 @@ class PasteHelper {
   adjustPastedData(indentAndMark, text) {
     let adjusted = null;
 
-    // e.g. '-item ...'
+    // list data (starts with indent and mark)
     if (text.match(this.indentAndMarkPattern)) {
       const indent = indentAndMark.match(this.indentAndMarkPattern)[1];
 
+      // splice to an array of line
       const lines = text.match(/[^\r\n]+/g);
+      // indent
       const replacedLines = lines.map((line) => {
         return indent + line;
       })
 
       adjusted = replacedLines.join('\n');
     }
+    // listful data
+    else if (this.isListfulData(text)) {
+      // do nothing (return null)
+    }
+    // not listful data
+    else {
+      // append `indentAndMark` at the beginning of all lines (except the first line)
+      const replacedText = text.replace(/(\r\n|\r|\n)/g, "$1" + indentAndMark);
+      // append `indentAndMark` to the first line
+      adjusted = indentAndMark + replacedText;
+    }
 
     return adjusted;
   }
 
+  /**
+   * evaluate whether `text` is list like data or not
+   * @param {string} text
+   */
+  isListfulData(text) {
+    // return false if includes at least one blank line
+    // see https://stackoverflow.com/a/16369725
+    if (text.match(/^\s*[\r\n]/m) != null) {
+      return false;
+    }
+
+    const lines = text.match(/[^\r\n]+/g);
+    // count lines that starts with indent and mark
+    let isListful = false;
+    let count = 0;
+    lines.forEach((line) => {
+      if (line.match(this.indentAndMarkPattern)) {
+        count++;
+      }
+      // ensure to be true if it is 50% or more
+      if (count >= lines.length / 2) {
+        isListful = true;
+        return;
+      }
+    });
+
+    return isListful;
+  }
+
 }
 
 // singleton pattern