@typex-core_defaultActions_caretMove.js

/*
 * @Author: caiwu
 * @Description: 光标移动功能
 * @CreateDate:
 * @LastEditor:
 * @LastEditTime: 2022-09-23 13:57:58
 */

/**
 * @description 水平移动
 * @export
 * @param {*} direction
 * @param {*} range
 * @param {*} event
 * @returns {*}
 */
export function horizontalMove (direction, range, event) {
  // 拼音输入法聚合输入的时候禁止光标的移动
  if (range.inputState.isComposing) return
  if (!range.collapsed && !event.shiftKey) {
    range.collapse(direction === 'left')
    return
  }
  console.log(11111111111);

  // const { shiftKey } = event
  // if (!range.collapsed && !shiftKey) {
  //   range.collapse(direction === 'left')
  // } else {
  return range.container.currentComponent.onCaretMove(direction, range, event)
  // }
}
/**
 * 垂直移动 垂直移动等效于水平移动N步的结果,关键点在于确定N
 * 这里通过光标位置回溯法,计算出最合适的N
 * @param {*} range
 * @param {*} direction
 * @param {*} shiftKey
 */
export function verticalMove (direction, range, event) {
  if (range.inputState.isComposing) return
  if (!range.collapsed && !event.shiftKey) {
    range.collapse(direction === 'up')
    return
  }
  const d = direction === 'up' ? 'left' : 'right'
  const initialCaretInfo = { ...range.caret.rect, block: range.container.block }
  const prevCaretInfo = { ...range.caret.rect, block: range.container.block }
  loop(range, d, initialCaretInfo, prevCaretInfo, false, event)
}
/**
 * 光标跨行判断
 * @param {*} initialCaretInfo
 * @param {*} prevCaretInfo
 * @param {*} currCaretInfo
 * @param {*} editor
 * @returns {Boolean}
 */
function isSameLine (initialCaretInfo, prevCaretInfo, currCaretInfo, direction) {
  // 当前光标位置和前一个位置所属块不一致则肯定发生跨行
  if (currCaretInfo.block !== prevCaretInfo.block) {
    return false
  }
  // 标识光标是否在同一行移动
  let sameLine = true
  // 判断自动折行(非结构层面的换行,如一行文字太长被浏览器自动换行的情况)
  if (
    (direction === 'left' && currCaretInfo.x > prevCaretInfo.x) ||
    (direction === 'right' && currCaretInfo.x < prevCaretInfo.x)
  ) {
    sameLine = false
  }
  //光标Y坐标和参考点相同说明光标还在本行,最理想的情况放在最后判断
  if (currCaretInfo.y === initialCaretInfo.y) {
    sameLine = true
  }
  return sameLine
}

/**
 * 循环执行函数
 * @param {*} range
 * @param {*} direction
 * @param {*} initialCaretInfo
 * @param {*} prevCaretInfo
 * @param {*} lineChanged
 * @param {*} shiftKey
 * @returns {*}
 */

function loop (range, direction, initialCaretInfo, prevCaretInfo, lineChanged = false, event) {
  if (range.collapsed) {
    range.d = 0
  }
  const { path } = horizontalMove(direction, range, event) || {}
  if (!path) return
  range.updateCaret(true)
  const currCaretInfo = { ...range.caret.rect, block: path.block }
  const currDistance = Math.abs(currCaretInfo.x - initialCaretInfo.x)
  if (currDistance === 0) return
  if (lineChanged) {
    const preDistance = Math.abs(prevCaretInfo.x - initialCaretInfo.x)
    // 标识前后光标是否在同一行
    const sameLine = isSameLine(initialCaretInfo, prevCaretInfo, currCaretInfo, direction)
    if (!(currDistance <= preDistance && sameLine)) {
      const d = direction === 'left' ? 'right' : 'left'
      horizontalMove(d, range, event)
      range.updateCaret(true)
      return
    }
  }
  if (currCaretInfo.x === prevCaretInfo.x && currCaretInfo.y === prevCaretInfo.y) return
  const sameLine = isSameLine(initialCaretInfo, prevCaretInfo, currCaretInfo, direction)
  if (!sameLine) {
    lineChanged = true
  }
  return loop(range, direction, initialCaretInfo, currCaretInfo, lineChanged, event)
}