diff --git a/resources/js/components/fieldtypes/GroupFieldtype.vue b/resources/js/components/fieldtypes/GroupFieldtype.vue index 883fe337d04..3d4186ed8b7 100644 --- a/resources/js/components/fieldtypes/GroupFieldtype.vue +++ b/resources/js/components/fieldtypes/GroupFieldtype.vue @@ -106,7 +106,16 @@ export default { }, toggleCollapsed() { - this.isCollapsed = !this.isCollapsed; + if (! this.isCollapsed) { + this.isCollapsed = true; + return; + } + + // Expanding: defer the reveal by one frame so the nested Bard editor is + // shown after the click, not during it. Revealing a ProseMirror editor in + // the same trusted click as a pending rich-text copy crashes the tab on + // Chrome/Edge >= 148 (a renderer CFI abort). See statamic/cms#14946. + requestAnimationFrame(() => (this.isCollapsed = false)); }, toggleFullScreen() { diff --git a/resources/js/components/fieldtypes/bard/BardFieldtype.vue b/resources/js/components/fieldtypes/bard/BardFieldtype.vue index d2933bfe17c..c279e58f2ef 100644 --- a/resources/js/components/fieldtypes/bard/BardFieldtype.vue +++ b/resources/js/components/fieldtypes/bard/BardFieldtype.vue @@ -633,15 +633,21 @@ export default { }, expandSet(id) { - if (this.config.collapse === 'accordion') { - this.collapsed = Object.keys(this.meta.existing).filter((v) => v !== id); - return; - } + // Defer the reveal by one frame so the nested Bard editor is shown + // after the click, not during it. Revealing a ProseMirror editor in + // the same trusted click as a pending rich-text copy crashes the tab + // on Chrome/Edge >= 148 (a renderer CFI abort). See statamic/cms#14946. + requestAnimationFrame(() => { + if (this.config.collapse === 'accordion') { + this.collapsed = Object.keys(this.meta.existing).filter((v) => v !== id); + return; + } - if (this.collapsed.includes(id)) { - var index = this.collapsed.indexOf(id); - this.collapsed.splice(index, 1); - } + if (this.collapsed.includes(id)) { + var index = this.collapsed.indexOf(id); + this.collapsed.splice(index, 1); + } + }); }, collapseAll() { @@ -649,7 +655,10 @@ export default { }, expandAll() { - this.collapsed = []; + // Defer the reveal one frame — same reason as expandSet() (statamic/cms#14946). + requestAnimationFrame(() => { + this.collapsed = []; + }); }, toggleCollapseSets() { diff --git a/resources/js/components/fieldtypes/replicator/Replicator.vue b/resources/js/components/fieldtypes/replicator/Replicator.vue index 085eafa56f7..fb8e761d6be 100644 --- a/resources/js/components/fieldtypes/replicator/Replicator.vue +++ b/resources/js/components/fieldtypes/replicator/Replicator.vue @@ -313,15 +313,21 @@ export default { }, expandSet(id) { - if (this.config.collapse === 'accordion') { - this.collapsed = this.value.map((v) => v._id).filter((v) => v !== id); - return; - } + // Defer the reveal by one frame so a nested Bard editor is shown + // after the click, not during it. Revealing a ProseMirror editor in + // the same trusted click as a pending rich-text copy crashes the tab + // on Chrome/Edge >= 148 (a renderer CFI abort). See statamic/cms#14946. + requestAnimationFrame(() => { + if (this.config.collapse === 'accordion') { + this.collapsed = this.value.map((v) => v._id).filter((v) => v !== id); + return; + } - if (this.collapsed.includes(id)) { - var index = this.collapsed.indexOf(id); - this.collapsed.splice(index, 1); - } + if (this.collapsed.includes(id)) { + var index = this.collapsed.indexOf(id); + this.collapsed.splice(index, 1); + } + }); }, collapseAll() { @@ -329,7 +335,10 @@ export default { }, expandAll() { - this.collapsed = []; + // Defer the reveal one frame — same reason as expandSet() (statamic/cms#14946). + requestAnimationFrame(() => { + this.collapsed = []; + }); }, toggleFullscreen() {