Skip to content

Commit

Permalink
refactor(lists): start refactoring lists code
Browse files Browse the repository at this point in the history
  • Loading branch information
bdbch committed Jun 13, 2023
1 parent d6c6dd8 commit 2281a22
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 40 deletions.
30 changes: 30 additions & 0 deletions packages/extension-list-item/src/helpers/getCurrentListItemPos.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { getNodeType } from '@tiptap/core'
import { EditorState } from '@tiptap/pm/state'
import { ResolvedPos } from 'prosemirror-model'

export const getCurrentListItemPos = (typeOrName: string, state: EditorState): ResolvedPos | undefined => {
const { $from } = state.selection
const nodeType = getNodeType(typeOrName, state.schema)

let currentNode = null
let currentDepth = $from.depth
let currentPos = $from.pos
let targetDepth: number | null = null

while (currentDepth > 0 && targetDepth === null) {
currentNode = $from.node(currentDepth)

if (currentNode.type === nodeType) {
targetDepth = currentDepth
} else {
currentDepth -= 1
currentPos -= 1
}
}

if (targetDepth === null) {
return
}

return state.doc.resolve(currentPos)
}
17 changes: 17 additions & 0 deletions packages/extension-list-item/src/helpers/hasListItemAfter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { EditorState } from '@tiptap/pm/state'

export const hasListItemAfter = (typeOrName: string, state: EditorState): boolean => {
const { $anchor } = state.selection

const $targetPos = state.doc.resolve($anchor.pos - $anchor.parentOffset - 2)

if ($targetPos.index() === $targetPos.parent.childCount - 1) {
return false
}

if ($targetPos.nodeAfter?.type.name !== typeOrName) {
return false
}

return true
}
17 changes: 17 additions & 0 deletions packages/extension-list-item/src/helpers/hasListItemBefore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { EditorState } from '@tiptap/pm/state'

export const hasListItemBefore = (typeOrName: string, state: EditorState): boolean => {
const { $anchor } = state.selection

const $targetPos = state.doc.resolve($anchor.pos - 2)

if ($targetPos.index() === 0) {
return false
}

if ($targetPos.nodeBefore?.type.name !== typeOrName) {
return false
}

return true
}
43 changes: 5 additions & 38 deletions packages/extension-list-item/src/helpers/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { getNodeAtPosition, getNodeType } from '@tiptap/core'
import { Node, NodeType } from '@tiptap/pm/model'
import { NodeType } from '@tiptap/pm/model'
import { EditorState } from '@tiptap/pm/state'

export * from './hasListItemAfter'
export * from './hasListItemBefore'
export * from './listItemhasSublist'

export const findListItemPos = (typeOrName: string | NodeType, state: EditorState) => {
const { $from } = state.selection
const nodeType = getNodeType(typeOrName, state.schema)
Expand Down Expand Up @@ -29,43 +33,6 @@ export const findListItemPos = (typeOrName: string | NodeType, state: EditorStat
return { $pos: state.doc.resolve(currentPos), depth: targetDepth }
}

export const hasPreviousListItem = (typeOrName: string, state: EditorState) => {
const listItemPos = findListItemPos(typeOrName, state)

if (!listItemPos) {
return false
}

const $item = state.doc.resolve(listItemPos.$pos.pos)
const $prev = state.doc.resolve(listItemPos.$pos.pos - 2)

const prevNode = $prev.node($item.depth)

if (!prevNode) {
return false
}

return prevNode.type.name === typeOrName
}

export const listItemHasSubList = (typeOrName: string, state: EditorState, node?: Node) => {
if (!node) {
return false
}

const nodeType = getNodeType(typeOrName, state.schema)

let hasSubList = false

node.descendants(child => {
if (child.type === nodeType) {
hasSubList = true
}
})

return hasSubList
}

export const getNextListDepth = (typeOrName: string, state: EditorState) => {
const listItemPos = findListItemPos(typeOrName, state)

Expand Down
21 changes: 21 additions & 0 deletions packages/extension-list-item/src/helpers/listItemhasSublist.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { getNodeType } from '@tiptap/core'
import { Node } from '@tiptap/pm/model'
import { EditorState } from '@tiptap/pm/state'

export const listItemHasSubList = (typeOrName: string, state: EditorState, node?: Node) => {
if (!node) {
return false
}

const nodeType = getNodeType(typeOrName, state.schema)

let hasSubList = false

node.descendants(child => {
if (child.type === nodeType) {
hasSubList = true
}
})

return hasSubList
}
4 changes: 2 additions & 2 deletions packages/extension-list-item/src/list-item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { NodeType } from '@tiptap/pm/model'
import { joinListItemBackward } from './commands/joinListItemBackward'
import { joinListItemForward } from './commands/joinListItemForward'
import {
findListItemPos, hasPreviousListItem, listItemHasSubList, nextListIsDeeper, nextListIsHigher,
findListItemPos, hasListItemBefore, listItemHasSubList, nextListIsDeeper, nextListIsHigher,
} from './helpers'

declare module '@tiptap/core' {
Expand Down Expand Up @@ -125,7 +125,7 @@ export const ListItem = Node.create<ListItemOptions>({
const previousListItemHasSubList = listItemHasSubList(this.name, editor.state, prevNode)

// if the previous item is a list item and doesn't have a sublist, join the list items
if (hasPreviousListItem(this.name, editor.state) && !previousListItemHasSubList) {
if (hasListItemBefore(this.name, editor.state) && !previousListItemHasSubList) {
return editor.commands.joinListItemBackward(this.name)
}

Expand Down

0 comments on commit 2281a22

Please sign in to comment.