@tiptap/core 2.0.0-beta.159 → 2.0.0-beta.162

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.159",
4
+ "version": "2.0.0-beta.162",
5
5
  "homepage": "https://tiptap.dev",
6
6
  "keywords": [
7
7
  "tiptap",
@@ -26,23 +26,24 @@
26
26
  "dependencies": {
27
27
  "@types/prosemirror-commands": "^1.0.4",
28
28
  "@types/prosemirror-keymap": "^1.0.4",
29
- "@types/prosemirror-model": "^1.13.2",
29
+ "@types/prosemirror-model": "^1.16.0",
30
30
  "@types/prosemirror-schema-list": "^1.0.3",
31
31
  "@types/prosemirror-state": "^1.2.8",
32
32
  "@types/prosemirror-transform": "^1.1.5",
33
33
  "@types/prosemirror-view": "^1.19.2",
34
34
  "prosemirror-commands": "^1.1.12",
35
35
  "prosemirror-keymap": "^1.1.5",
36
- "prosemirror-model": "^1.15.0",
36
+ "prosemirror-model": "^1.16.1",
37
37
  "prosemirror-schema-list": "^1.1.6",
38
38
  "prosemirror-state": "^1.3.4",
39
39
  "prosemirror-transform": "^1.3.3",
40
- "prosemirror-view": "^1.23.3"
40
+ "prosemirror-view": "^1.23.5"
41
41
  },
42
42
  "repository": {
43
43
  "type": "git",
44
44
  "url": "https://github.com/ueberdosis/tiptap",
45
45
  "directory": "packages/core"
46
46
  },
47
- "gitHead": "8844627773ac1cfb0d01eaf1f52b3be937701b2d"
47
+ "sideEffects": false,
48
+ "gitHead": "7da4373a6aa27c549a536e82c429ec7313279590"
48
49
  }
@@ -306,7 +306,7 @@ export class ExtensionManager {
306
306
  editor,
307
307
  rules: inputRules,
308
308
  }),
309
- pasteRulesPlugin({
309
+ ...pasteRulesPlugin({
310
310
  editor,
311
311
  rules: pasteRules,
312
312
  }),
package/src/InputRule.ts CHANGED
@@ -33,7 +33,7 @@ export class InputRule {
33
33
  commands: SingleCommands,
34
34
  chain: () => ChainedCommands,
35
35
  can: () => CanCommands,
36
- }) => void
36
+ }) => void | null
37
37
 
38
38
  constructor(config: {
39
39
  find: InputRuleFinder,
@@ -44,7 +44,7 @@ export class InputRule {
44
44
  commands: SingleCommands,
45
45
  chain: () => ChainedCommands,
46
46
  can: () => CanCommands,
47
- }) => void,
47
+ }) => void | null,
48
48
  }) {
49
49
  this.find = config.find
50
50
  this.handler = config.handler
@@ -87,7 +87,7 @@ function run(config: {
87
87
  text: string,
88
88
  rules: InputRule[],
89
89
  plugin: Plugin,
90
- }): any {
90
+ }): boolean {
91
91
  const {
92
92
  editor,
93
93
  from,
@@ -148,7 +148,7 @@ function run(config: {
148
148
  state,
149
149
  })
150
150
 
151
- rule.handler({
151
+ const handler = rule.handler({
152
152
  state,
153
153
  range,
154
154
  match,
@@ -158,7 +158,7 @@ function run(config: {
158
158
  })
159
159
 
160
160
  // stop if there are no changes
161
- if (!tr.steps.length) {
161
+ if (handler === null || !tr.steps.length) {
162
162
  return
163
163
  }
164
164
 
package/src/Node.ts CHANGED
@@ -375,6 +375,16 @@ declare module '@tiptap/core' {
375
375
  parent: ParentConfig<NodeConfig<Options, Storage>>['code'],
376
376
  }) => NodeSpec['code']),
377
377
 
378
+ /**
379
+ * Whitespace
380
+ */
381
+ whitespace?: NodeSpec['whitespace'] | ((this: {
382
+ name: string,
383
+ options: Options,
384
+ storage: Storage,
385
+ parent: ParentConfig<NodeConfig<Options, Storage>>['whitespace'],
386
+ }) => NodeSpec['whitespace']),
387
+
378
388
  /**
379
389
  * Defining
380
390
  */
package/src/PasteRule.ts CHANGED
@@ -34,7 +34,7 @@ export class PasteRule {
34
34
  commands: SingleCommands,
35
35
  chain: () => ChainedCommands,
36
36
  can: () => CanCommands,
37
- }) => void
37
+ }) => void | null
38
38
 
39
39
  constructor(config: {
40
40
  find: PasteRuleFinder,
@@ -45,7 +45,7 @@ export class PasteRule {
45
45
  commands: SingleCommands,
46
46
  chain: () => ChainedCommands,
47
47
  can: () => CanCommands,
48
- }) => void,
48
+ }) => void | null,
49
49
  }) {
50
50
  this.find = config.find
51
51
  this.handler = config.handler
@@ -88,15 +88,14 @@ function run(config: {
88
88
  state: EditorState,
89
89
  from: number,
90
90
  to: number,
91
- rules: PasteRule[],
92
- plugin: Plugin,
93
- }): any {
91
+ rule: PasteRule,
92
+ }): boolean {
94
93
  const {
95
94
  editor,
96
95
  state,
97
96
  from,
98
97
  to,
99
- rules,
98
+ rule,
100
99
  } = config
101
100
 
102
101
  const { commands, chain, can } = new CommandManager({
@@ -104,6 +103,8 @@ function run(config: {
104
103
  state,
105
104
  })
106
105
 
106
+ const handlers: (void | null)[] = []
107
+
107
108
  state.doc.nodesBetween(from, to, (node, pos) => {
108
109
  if (!node.isTextblock || node.type.spec.code) {
109
110
  return
@@ -118,32 +119,36 @@ function run(config: {
118
119
  '\ufffc',
119
120
  )
120
121
 
121
- rules.forEach(rule => {
122
- const matches = pasteRuleMatcherHandler(textToMatch, rule.find)
122
+ const matches = pasteRuleMatcherHandler(textToMatch, rule.find)
123
123
 
124
- matches.forEach(match => {
125
- if (match.index === undefined) {
126
- return
127
- }
124
+ matches.forEach(match => {
125
+ if (match.index === undefined) {
126
+ return
127
+ }
128
128
 
129
- const start = resolvedFrom + match.index + 1
130
- const end = start + match[0].length
131
- const range = {
132
- from: state.tr.mapping.map(start),
133
- to: state.tr.mapping.map(end),
134
- }
129
+ const start = resolvedFrom + match.index + 1
130
+ const end = start + match[0].length
131
+ const range = {
132
+ from: state.tr.mapping.map(start),
133
+ to: state.tr.mapping.map(end),
134
+ }
135
135
 
136
- rule.handler({
137
- state,
138
- range,
139
- match,
140
- commands,
141
- chain,
142
- can,
143
- })
136
+ const handler = rule.handler({
137
+ state,
138
+ range,
139
+ match,
140
+ commands,
141
+ chain,
142
+ can,
144
143
  })
144
+
145
+ handlers.push(handler)
145
146
  })
146
147
  })
148
+
149
+ const success = handlers.every(handler => handler !== null)
150
+
151
+ return success
147
152
  }
148
153
 
149
154
  /**
@@ -151,65 +156,62 @@ function run(config: {
151
156
  * text that matches any of the given rules to trigger the rule’s
152
157
  * action.
153
158
  */
154
- export function pasteRulesPlugin(props: { editor: Editor, rules: PasteRule[] }): Plugin {
159
+ export function pasteRulesPlugin(props: { editor: Editor, rules: PasteRule[] }): Plugin[] {
155
160
  const { editor, rules } = props
156
161
  let isProseMirrorHTML = false
157
162
 
158
- const plugin = new Plugin({
159
- props: {
160
- handlePaste: (view, event) => {
161
- const html = event.clipboardData?.getData('text/html')
163
+ const plugins = rules.map(rule => {
164
+ return new Plugin({
165
+ props: {
166
+ handlePaste: (view, event) => {
167
+ const html = event.clipboardData?.getData('text/html')
162
168
 
163
- isProseMirrorHTML = !!html?.includes('data-pm-slice')
169
+ isProseMirrorHTML = !!html?.includes('data-pm-slice')
164
170
 
165
- return false
171
+ return false
172
+ },
166
173
  },
167
- },
168
- appendTransaction: (transactions, oldState, state) => {
169
- const transaction = transactions[0]
174
+ appendTransaction: (transactions, oldState, state) => {
175
+ const transaction = transactions[0]
170
176
 
171
- // stop if there is not a paste event
172
- if (!transaction.getMeta('paste') || isProseMirrorHTML) {
173
- return
174
- }
175
-
176
- // stop if there is no changed range
177
- const { doc, before } = transaction
178
- const from = before.content.findDiffStart(doc.content)
179
- const to = before.content.findDiffEnd(doc.content)
177
+ // stop if there is not a paste event
178
+ if (!transaction.getMeta('paste') || isProseMirrorHTML) {
179
+ return
180
+ }
180
181
 
181
- if (!isNumber(from) || !to || from === to.b) {
182
- return
183
- }
182
+ // stop if there is no changed range
183
+ const from = oldState.doc.content.findDiffStart(state.doc.content)
184
+ const to = oldState.doc.content.findDiffEnd(state.doc.content)
184
185
 
185
- // build a chainable state
186
- // so we can use a single transaction for all paste rules
187
- const tr = state.tr
188
- const chainableState = createChainableState({
189
- state,
190
- transaction: tr,
191
- })
186
+ if (!isNumber(from) || !to || from === to.b) {
187
+ return
188
+ }
192
189
 
193
- run({
194
- editor,
195
- state: chainableState,
196
- from: Math.max(from - 1, 0),
197
- to: to.b,
198
- rules,
199
- plugin,
200
- })
190
+ // build a chainable state
191
+ // so we can use a single transaction for all paste rules
192
+ const tr = state.tr
193
+ const chainableState = createChainableState({
194
+ state,
195
+ transaction: tr,
196
+ })
201
197
 
202
- // stop if there are no changes
203
- if (!tr.steps.length) {
204
- return
205
- }
198
+ const handler = run({
199
+ editor,
200
+ state: chainableState,
201
+ from: Math.max(from - 1, 0),
202
+ to: to.b,
203
+ rule,
204
+ })
206
205
 
207
- return tr
208
- },
206
+ // stop if there are no changes
207
+ if (!handler || !tr.steps.length) {
208
+ return
209
+ }
209
210
 
210
- // @ts-ignore
211
- isPasteRules: true,
211
+ return tr
212
+ },
213
+ })
212
214
  })
213
215
 
214
- return plugin
216
+ return plugins
215
217
  }
@@ -24,7 +24,7 @@ export function markInputRule(config: {
24
24
  const attributes = callOrReturn(config.getAttributes, undefined, match)
25
25
 
26
26
  if (attributes === false || attributes === null) {
27
- return
27
+ return null
28
28
  }
29
29
 
30
30
  const { tr } = state
@@ -24,7 +24,7 @@ export function markPasteRule(config: {
24
24
  const attributes = callOrReturn(config.getAttributes, undefined, match)
25
25
 
26
26
  if (attributes === false || attributes === null) {
27
- return
27
+ return null
28
28
  }
29
29
 
30
30
  const { tr } = state