iOS: inserting any `createReactBlockSpec` block freezes the tab (infinite mutation⇄re-render loop; no `ignoreMutation` seam to fix it)
Mantenedores costumam responder em até 3 dias
Ninguém assumiu esta issue ainda.
Avaliação
- Dificuldade
- 4/5
- Tempo estimado
- 3-5 dias
- Facilidade para iniciantes
- 55/100
- Tipo de issue
- Bug
- Clareza
- Razoavelmente clara
- Status de atividade
- Ativa
- Stack de tecnologia
- react, typescript
Direção de pesquisa
Start at createReactBlockSpec and its ReactNodeViewRenderer(component, { className: "bn-react-node-view-renderer" }) call, then inspect how TipTap orders options.ignoreMutation and its mobile branch. Reproduce with touch emulation, a Mac-containing user agent, and a focused custom React block. Done means insertion no longer enters the synchronous mutation/re-render loop while native blocks and the mobile-keyboard behavior remain unaffected.
Escrita pelo modelo de indexação a partir do texto da issue.
Descrição
Summary
On iOS/iPadOS Safari, inserting a custom React block (createReactBlockSpec) into the editor while it is focused locks the main thread in an infinite loop. The tab freezes with no exception and no console output; iOS then kills it. Native blocks (paragraph, quote, heading…) are unaffected.
Verified on @blocknote/[email protected] and still present in the code of 0.54.0 (with @tiptap/[email protected] / 3.30.2).
Mechanism
@tiptap/core's NodeView.ignoreMutation has an iOS/Android branch (added for ueberdosis/tiptap#1971):
if (this.dom.contains(mutation.target) && mutation.type === "childList"
&& (isiOS() || isAndroid()) && this.editor.isFocused) {
const changedNodes = [...mutation.addedNodes, ...mutation.removedNodes];
if (changedNodes.every((node) => node.isContentEditable)) return false; // "do NOT ignore"
}
this.dom is the whole node view, so React mounting the block's own rendered content inside it also matches:
- React mounts the block component inside the node view →
childListmutation, added nodes contentEditable ignoreMutationreturnsfalse→ ProseMirror redraws the node view- React remounts → another
childListmutation → back to 2, forever
The loop is synchronous and reschedules in a microtask (processRootScheduleInMicrotask → flushSyncWorkAcrossRoots_impl → performSyncWorkOnRoot), so the thread never yields. A CPU profile at the freeze is dominated by appendChild/removeChild, ignoreMutation, and the React node-view teardown/rebuild cycle.
Why users can't work around it
TipTap consults this.options.ignoreMutation before the iOS branch — so a per-node-view override would fix it cleanly. But @blocknote/react hardcodes the renderer options:
ReactNodeViewRenderer(component, { className: "bn-react-node-view-renderer" })
createReactBlockSpec exposes no way to pass ignoreMutation through (same gap as ueberdosis/tiptap#1538). The only fix available today is patching @tiptap/core (we ship patch-package narrowing the branch's this.dom to this.contentDOM, which preserves the mobile-keyboard fix the branch exists for while excluding node-view chrome).
Reproduction (no device needed)
TipTap's isiOS() is platform ∈ {iPad, iPhone, iPod, …} || (navigator.userAgent.includes("Mac") && "ontouchend" in document) — so Chrome/Chromium with touch emulation enabled and any Mac-containing UA reproduces it exactly (e.g. CDP Emulation.setTouchEmulationEnabled or DevTools device toolbar):
- Editor with any
createReactBlockSpecblock registered, touch emulation on - Focus the editor, open the slash menu, insert the React block (keyboard Enter suffices — no tap involved)
- Main thread wedges:
1+1in the console never evaluates
Neither viewport width nor the mobile UA matters; touch capability alone flips isiOS()'s second clause. On a real iPhone navigator.platform === "iPhone" makes it unconditional.
Ask
Either:
- forward an
ignoreMutationoption fromcreateReactBlockSpecthrough toReactNodeViewRenderer, or - have BlockNote's renderer supply a default
ignoreMutationthat ignores mutations originating from the React-rendered part of the node view (everything outsidecontentDOM).
Happy to PR either direction if you have a preference. (We're also filing the underlying this.dom vs this.contentDOM question with TipTap, but BlockNote exposing the seam is what lets consumers fix this without vendor patches.)
- Linguagem predominante
- TypeScript
- Estrelas
- 10.2k
- Forks
- 772
- Merge médio
- 6d 17h
- PRs com merge (30d)
- 27
Preparar o ambiente
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de TypeCellOS/BlockNote
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 82/100
TypeCellOS/BlockNote#2949 · 1 comentário ·
Mantenedores costumam responder em até 3 dias
-
a11y
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 68/100
TypeCellOS/BlockNote#2855 ·
Mantenedores costumam responder em até 3 dias
-
a11y
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 62/100
TypeCellOS/BlockNote#2829 · 1 comentário ·
Mantenedores costumam responder em até 3 dias
-
a11y
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
TypeCellOS/BlockNote#2824 ·
Mantenedores costumam responder em até 3 dias
-
a11y
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 68/100
TypeCellOS/BlockNote#2811 ·
Mantenedores costumam responder em até 3 dias
Todas as issues de TypeCellOS/BlockNote
Issues semelhantes
-
triage
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 90/100
Mantenedores costumam responder em até 1 dia
-
bug
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 68/100
mermaid-js/mermaid-live-editor#2053 ·
Mantenedores costumam responder em até 1 dia
-
factory
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 82/100
jessepollak/home#1455 ·
Mantenedores costumam responder em até 1 dia
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 95/100
lingdojo/kana-dojo#31227 · 1 comentário · 5 reações ·
Mantenedores costumam responder em até 1 dia
-
mobile: device viewer shows dark status bar icons on its dark backdrop in light mode (Android)Aberta
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 92/100
appandflow/stim#1838 ·
Mantenedores costumam responder em até 1 dia