Repository: marktext/marktext
File: src/muya/lib/contentState/inputCtrl.js (JavaScript)

Code before:
      if (startBlock.functionType === 'languageInput') {
        // fix #918.
        if (startOutmostBlock === endOutmostBlock && !endBlock.nextSibling) {
          this.removeBlocks(startBlock, endBlock, false)
          endBlock.text = ''
        } else if (startOutmostBlock !== endOutmostBlock) {
          const preBlock = this.getParent(startBlock)
          const pBlock = this.createBlock('p')
          this.removeBlocks(startBlock, endBlock)
          startBlock.functionType = 'paragraphContent'
          this.appendChild(pBlock, startBlock)
          this.insertBefore(pBlock, preBlock)
          this.removeBlock(preBlock)
        } else {
          this.removeBlocks(startBlock, endBlock)
        }
      } else if (startBlock.functionType === 'paragraphContent' &&
        start.key === end.key && oldStart.key === start.key && oldEnd.key !== end.key) {
        // GH#2269: The end block will lose all soft-lines when removing multiple paragraphs and `oldEnd`
        //          includes soft-line breaks. The normal text from `oldEnd` is moved into the `start`
        //          block but the remaining soft-lines (separated by \n) not. We have to append the
        //          remaining text (soft-lines) to the new start block.
        const endParagraph = document.querySelector(`#${oldEnd.key}`)
        if (endParagraph) {
          text += '\n' + getTextContent(endParagraph, [CLASS_OR_ID.AG_MATH_RENDER, CLASS_OR_ID.AG_RUBY_RENDER])
        }
        this.removeBlocks(startBlock, endBlock)
      } else {
        this.removeBlocks(startBlock, endBlock)
      }
      if (this.blocks.length === 1) {
        needRenderAll = true
      }
      needRender = true
    }

    // auto pair (not need to auto pair in math block)
    if (block && (block.text !== text || notEqual)) {
      if (
        start.key === end.key &&
        start.offset === end.offset &&
        event.type === 'input'
      ) {
        const { offset } = start
        const { autoPairBracket, autoPairMarkdownSyntax, autoPairQuote } = this.muya.options
        const inputChar = text.charAt(+offset - 1)
        const preInputChar = text.charAt(+offset - 2)
        const prePreInputChar = text.charAt(+offset - 3)
        const postInputChar = text.charAt(+offset)

        if (/^delete/.test(event.inputType)) {

Review comment (performance):
It is not recommended to use too many DOM APIs(querySelector), which will cause performance penalties. how about use `endBlock` like this:

```js
if (endBlock && endBlock.text.indexOf('\n')) {
    text += endBlock.text.replace(/^.*(?=\n)/, '')
}
```

Code after:
      if (startBlock.functionType === 'languageInput') {
        // fix #918.
        if (startOutmostBlock === endOutmostBlock && !endBlock.nextSibling) {
          this.removeBlocks(startBlock, endBlock, false)
          endBlock.text = ''
        } else if (startOutmostBlock !== endOutmostBlock) {
          const preBlock = this.getParent(startBlock)
          const pBlock = this.createBlock('p')
          this.removeBlocks(startBlock, endBlock)
          startBlock.functionType = 'paragraphContent'
          this.appendChild(pBlock, startBlock)
          this.insertBefore(pBlock, preBlock)
          this.removeBlock(preBlock)
        } else {
          this.removeBlocks(startBlock, endBlock)
        }
      } else if (startBlock.functionType === 'paragraphContent' &&
        start.key === end.key && oldStart.key === start.key && oldEnd.key !== end.key) {
        // GH#2269: The end block will lose all soft-lines when removing multiple paragraphs and `oldEnd`
        //          includes soft-line breaks. The normal text from `oldEnd` is moved into the `start`
        //          block but the remaining soft-lines (separated by \n) not. We have to append the
        //          remaining text (soft-lines) to the new start block.
        const matchBreak = /(?<=.)\n./.exec(endBlock.text)
        if (matchBreak && matchBreak.index > 0) {
          // Skip if end block is fully selected and the cursor is in the next line (e.g. via keyboard).
          const lineOffset = matchBreak.index
          if (oldEnd.offset <= lineOffset) {
            text += endBlock.text.substring(lineOffset)
          }
        }
        this.removeBlocks(startBlock, endBlock)
      } else {
        this.removeBlocks(startBlock, endBlock)
      }
      if (this.blocks.length === 1) {
        needRenderAll = true
      }
      needRender = true
    }

    // auto pair (not need to auto pair in math block)
    if (block && (block.text !== text || notEqual)) {
      if (
        start.key === end.key &&
        start.offset === end.offset &&
        event.type === 'input'
      ) {
        const { offset } = start
        const { autoPairBracket, autoPairMarkdownSyntax, autoPairQuote } = this.muya.options
        const inputChar = text.charAt(+offset - 1)
        const preInputChar = text.charAt(+offset - 2)