@tiptap/core 2.0.0-beta.196 → 2.0.0-beta.197

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tiptap/core",
3
3
  "description": "headless rich text editor",
4
- "version": "2.0.0-beta.196",
4
+ "version": "2.0.0-beta.197",
5
5
  "homepage": "https://tiptap.dev",
6
6
  "keywords": [
7
7
  "tiptap",
@@ -24,13 +24,13 @@
24
24
  "dist"
25
25
  ],
26
26
  "dependencies": {
27
- "prosemirror-commands": "1.3.0",
28
- "prosemirror-keymap": "1.2.0",
29
- "prosemirror-model": "1.18.1",
30
- "prosemirror-schema-list": "1.2.0",
31
- "prosemirror-state": "1.4.1",
32
- "prosemirror-transform": "1.6.0",
33
- "prosemirror-view": "1.26.2"
27
+ "prosemirror-commands": "^1.3.1",
28
+ "prosemirror-keymap": "^1.2.0",
29
+ "prosemirror-model": "^1.18.1",
30
+ "prosemirror-schema-list": "^1.2.2",
31
+ "prosemirror-state": "^1.4.1",
32
+ "prosemirror-transform": "^1.7.0",
33
+ "prosemirror-view": "^1.28.2"
34
34
  },
35
35
  "repository": {
36
36
  "type": "git",
@@ -1,5 +1,7 @@
1
- import { MarkType } from 'prosemirror-model'
1
+ import { MarkType, ResolvedPos } from 'prosemirror-model'
2
+ import { EditorState, Transaction } from 'prosemirror-state'
2
3
 
4
+ import { isTextSelection } from '../helpers'
3
5
  import { getMarkAttributes } from '../helpers/getMarkAttributes'
4
6
  import { getMarkType } from '../helpers/getMarkType'
5
7
  import { RawCommands } from '../types'
@@ -15,6 +17,45 @@ declare module '@tiptap/core' {
15
17
  }
16
18
  }
17
19
 
20
+ function canSetMark(state: EditorState, tr: Transaction, newMarkType: MarkType) {
21
+ const { selection } = tr
22
+ let cursor: ResolvedPos | null = null
23
+
24
+ if (isTextSelection(selection)) {
25
+ cursor = selection.$cursor
26
+ }
27
+
28
+ if (cursor) {
29
+ const currentMarks = state.storedMarks ?? cursor.marks()
30
+
31
+ // There can be no current marks that exclude the new mark
32
+ return !!newMarkType.isInSet(currentMarks) || !currentMarks.some(mark => mark.type.excludes(newMarkType))
33
+ }
34
+
35
+ const { ranges } = selection
36
+
37
+ return ranges.some(({ $from, $to }) => {
38
+ let someNodeSupportsMark = $from.depth === 0 ? state.doc.inlineContent && state.doc.type.allowsMarkType(newMarkType) : false
39
+
40
+ state.doc.nodesBetween($from.pos, $to.pos, (node, _pos, parent) => {
41
+ // If we already found a mark that we can enable, return false to bypass the remaining search
42
+ if (someNodeSupportsMark) {
43
+ return false
44
+ }
45
+
46
+ if (node.isInline) {
47
+ const parentAllowsMarkType = !parent || parent.type.allowsMarkType(newMarkType)
48
+ const currentMarksAllowMarkType = !!newMarkType.isInSet(node.marks) || !node.marks.some(otherMark => otherMark.type.excludes(newMarkType))
49
+
50
+ someNodeSupportsMark = parentAllowsMarkType && currentMarksAllowMarkType
51
+ }
52
+ return !someNodeSupportsMark
53
+ })
54
+
55
+ return someNodeSupportsMark
56
+ })
57
+
58
+ }
18
59
  export const setMark: RawCommands['setMark'] = (typeOrName, attributes = {}) => ({ tr, state, dispatch }) => {
19
60
  const { selection } = tr
20
61
  const { empty, ranges } = selection
@@ -42,6 +83,7 @@ export const setMark: RawCommands['setMark'] = (typeOrName, attributes = {}) =>
42
83
  // we know that we have to merge its attributes
43
84
  // otherwise we add a fresh new mark
44
85
  if (someHasMark) {
86
+
45
87
  node.marks.forEach(mark => {
46
88
  if (type === mark.type) {
47
89
  tr.addMark(trimmedFrom, trimmedTo, type.create({
@@ -58,5 +100,5 @@ export const setMark: RawCommands['setMark'] = (typeOrName, attributes = {}) =>
58
100
  }
59
101
  }
60
102
 
61
- return true
103
+ return canSetMark(state, tr, type)
62
104
  }