fix: prevent a bug for node views when pressing enter on iOS, fix #1214
This commit is contained in:
@@ -3,6 +3,7 @@ import { NodeSelection } from 'prosemirror-state'
|
||||
import { Node as ProseMirrorNode } from 'prosemirror-model'
|
||||
import { Editor as CoreEditor } from './Editor'
|
||||
import { Node } from './Node'
|
||||
import isiOS from './utilities/isiOS'
|
||||
import { NodeViewRendererProps } from './types'
|
||||
|
||||
interface NodeViewRendererOptions {
|
||||
@@ -176,22 +177,50 @@ export class NodeView<Component, Editor extends CoreEditor = CoreEditor> impleme
|
||||
}
|
||||
|
||||
ignoreMutation(mutation: MutationRecord | { type: 'selection', target: Element }) {
|
||||
if (mutation.type === 'selection') {
|
||||
if (!this.dom || !this.contentDOM) {
|
||||
return true
|
||||
}
|
||||
|
||||
// a leaf/atom node is like a black box for ProseMirror
|
||||
// and should be fully handled by the node view
|
||||
if (this.node.isLeaf) {
|
||||
return true
|
||||
}
|
||||
|
||||
// ProseMirror should handle any selections
|
||||
if (mutation.type === 'selection') {
|
||||
return false
|
||||
}
|
||||
|
||||
if (!this.contentDOM) {
|
||||
// try to prevent a bug on iOS that will break node views on enter
|
||||
// this is because ProseMirror can’t preventDispatch on enter
|
||||
// this will lead to a re-render of the node view on enter
|
||||
// see: https://github.com/ueberdosis/tiptap/issues/1214
|
||||
if (this.dom.contains(mutation.target) && mutation.type === 'childList' && isiOS()) {
|
||||
const changedNodes = [
|
||||
...Array.from(mutation.addedNodes),
|
||||
...Array.from(mutation.removedNodes),
|
||||
] as HTMLElement[]
|
||||
|
||||
// we’ll check if every changed node is contentEditable
|
||||
// to make sure it’s probably mutated by ProseMirror
|
||||
if (changedNodes.every(node => node.isContentEditable)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// we will allow mutation contentDOM with attributes
|
||||
// so we can for example adding classes within our node view
|
||||
if (this.contentDOM === mutation.target && mutation.type === 'attributes') {
|
||||
return true
|
||||
}
|
||||
|
||||
const contentDOMHasChanged = !this.contentDOM.contains(mutation.target)
|
||||
|| (this.contentDOM === mutation.target && mutation.type === 'attributes')
|
||||
// ProseMirror should handle any changes within contentDOM
|
||||
if (this.contentDOM.contains(mutation.target)) {
|
||||
return false
|
||||
}
|
||||
|
||||
return contentDOMHasChanged
|
||||
return true
|
||||
}
|
||||
|
||||
updateAttributes(attributes: {}) {
|
||||
|
||||
12
packages/core/src/utilities/isiOS.ts
Normal file
12
packages/core/src/utilities/isiOS.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
export default function isiOS(): boolean {
|
||||
return [
|
||||
'iPad Simulator',
|
||||
'iPhone Simulator',
|
||||
'iPod Simulator',
|
||||
'iPad',
|
||||
'iPhone',
|
||||
'iPod',
|
||||
].includes(navigator.platform)
|
||||
// iPad on iOS 13 detection
|
||||
|| (navigator.userAgent.includes('Mac') && 'ontouchend' in document)
|
||||
}
|
||||
Reference in New Issue
Block a user