Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inline formats such as bold, italic, bold-italic, code does not work well with inline-embeds. #41

Open
wooolfgang opened this issue Jul 14, 2020 · 0 comments

Comments

@wooolfgang
Copy link

wooolfgang commented Jul 14, 2020

For my particular use-case, using quill-markdown-shortcuts with quill-mentions causes a bug. The bug will also happen if you have custom inline-embeds, or default ones such as images, etc.

Steps to reproduce:

  • Open code-sandbox -- the editor here uses quill-markdown-shortcuts and quill-mentions
  • Create a mention blot (use @{USER_HERE}) and then after the blot and within the current line, use markdown shortcuts such as bold ({WORD}), italics ({WORD}), etc.
  • As you can see, there's an issue with the deleting/replacing of the text with the correct format.

The issue is caused by this line in particular

    const startIndex = lineStart + match.index

    if (text.match(/^([*_ \n]+)$/g)) return

     setTimeout(() => {
         this.quill.deleteText(startIndex, annotatedText.length)
         this.quill.insertText(startIndex, matchedText, {bold: true, italic: true})
         this.quill.format('bold', false)
    }, 0)

The calculations for startIndex is not correct when there are inline-embed blots before the matchedText and within the current line. Inline-embeds will only have length === 1, causing an issue with the markdown-shortcut plugin once the editor has non-text contents.

I have a solution that fixes this issue, but I'm not sure if this is best one. I would like to know anyone's thoughts, or if they came up with more elegant solutions. Thanks!

 getStartIndex (annotatedText) {
    const wholeText = this.quill.getText()
    const embedsCountBeforeText = this.getInlineEmbedsBeforeText(annotatedText)
    const startIndex = wholeText.indexOf(annotatedText) + embedsCountBeforeText
    return startIndex
  }

  /**
   * @description -- This counts the number of inline embeds (image|imageLoading|mention)
   * before a matched text within the current line
   * @param {String} annotatedText
   * @returns {Number}
   */
  getInlineEmbedsBeforeText (annotatedText) {
    const contents = this.quill.getContents()
    let count = 0
    let startCount = false
    let matchedIndex = 0

    if (contents.ops.length <= 1) {
      return count
    }

    for (let i = contents.ops.length - 1; i >= 0; i--) {
      const content = contents.ops[i]

      // If the annotatedText matches within the text, start the count
      if (typeof content.insert === 'string' && content.insert.includes(annotatedText)) {
        startCount = true
        matchedIndex = i
      }
      // If an inline embed is matched before the annotatedText and within the current line, increment
      if (startCount &&
        (content.insert.mention || content.insert.image || content.insert.imageLoading)) {
        count += 1
      }
      // If the content is not within the current line, end the count
      if (
        startCount &&
        typeof content.insert === 'string' &&
        content.insert.includes('↵') &&
        matchedIndex !== i
      ) {
        startCount = false
        break
      }
    }

    return count
  }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant