Skip to content

Duplicating CTA / Page Attachment block crashes browser #3467

@spacedmonkey

Description

@spacedmonkey

Bug Description

In the stories editor, there when a block is a selected, a context menu icon appears in the toolbar that looks like this.

Screenshot from 2019-10-08 16-42-39

If a CTA block is selected and the duplicate block is selected, the browser becomes unresponsive and sometimes crashes.

There might be some infinite loop, perhaps caused by some faulty React hook somewhere.

Expected Behaviour

Block should fail to duplicate or at least a warning about duplicate CTA blocks is shown.

Steps to reproduce

  1. Create new story in editor
  2. Create a second page
  3. Insert CTA block.
  4. Select CTA block.
  5. Click three dots in top toolbar.
  6. Select duplicate block.

Screenshots

Screenshot from 2019-10-08 16-56-13

If the browser doesn't crash, then two CTA blocks are shown.

Additional context

  • WordPress version: 5.3
  • Plugin version: 1.3
  • Gutenberg plugin version (if applicable):
  • AMP plugin template mode:
  • PHP version:
  • OS: Ubuntu 18.04
  • Browser: Chrome 77.0.3865.75 (Official Build) (64-bit)
  • Device: Dell XPS 13

Acceptance criteria

  • AC1: Duplicating a CTA block should not cause the browser to lag / crash
  • AC2: Duplicating a Page Attachment block should not cause the browser to lag / crash

Implementation brief

Reason for crashing

When either a CTA or a Page Attachment block is present on a Page, enforcing the block to be the last block on the Page is triggered. If there are more than one CTA / Page Attachment blocks then this causes the logic to be triggered infinitely since only one block can be the last block:

useEffect( () => {
if ( childrenOrder.length <= 1 ) {
return;
}
const ctaBlock = getCallToActionBlock( clientId );
const attachmentBlock = getPageAttachmentBlock( clientId );
let blockToMove = null;
if ( ctaBlock ) {
blockToMove = ctaBlock;
} else if ( attachmentBlock ) {
blockToMove = attachmentBlock;
}
if ( blockToMove ) {
// If the either CTA or Attachment is not the last block, move it there.
if ( childrenOrder[ childrenOrder.length - 1 ] !== blockToMove.clientId ) {
moveBlockToPosition( blockToMove.clientId, clientId, clientId, childrenOrder.length - 1 );
}
}
}, [ childrenOrder, clientId, moveBlockToPosition ] );

Suggested solution

If more than one CTA/Page Attachment blocks are detected then before enforcing the block to be the last, two things should happen:

  • The extra block(s) should be removed.
  • A snackbar notice is displayed to let know about the block being removed.

We could add an additional condition to the same useEffect hook that enforces the CTA/Attachment block to be the last, to only run if there is only one CTA or one Page Attachment block. Additionally, we can add another useEffect which removes the extra block(s) if detected which can also display a snackbar notice saying that the block was removed since each Page can have only 1 CTA block or 1 Attachment block.

QA testing instructions

  1. Create a new story
  2. Add a new page
  3. Add a CTA block
  4. In the block toolbar, click on the three dots and then on "Duplicate"
    -> Verify that block is not duplicated, but a warning message appears in the bottom left.
  5. Add a new page
  6. Add a Page Attachment block
  7. In the block toolbar, click on the three dots and then on "Duplicate"
    -> Verify that block is not duplicated, but a warning message appears in the bottom left.

Demo

https://www.youtube.com/watch?v=iItTJkcF7Qg&feature=youtu.be

Changelog entry

  • Prevent duplicating CTA or Page Attachment blocks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions