AdvancedCustomFields / acf

Advanced Custom Fields
http://advancedcustomfields.com/
823 stars 168 forks source link

filter wysiwyg_tinymce_settings breaking #906

Open archoda opened 2 months ago

archoda commented 2 months ago

Describe the bug The ACF Block content doesn't update when i add custom WYSIWYG buttons. There's also no console errors.

Ive tried this the WYSIWYG editor on delayed initialization and default.

When I add the code below to trigger on the front-end, the 'Text' tab code view shows the correct HTML updates, but the 'Visual' tab and the WP Block HTML ( rendered and code editor view ) are not.

Caveat** If i tab over to the 'Text' view and manually change the content or even just a hard return, the editor and WP Block update and render properly.

To Reproduce Steps to reproduce the behavior:

  1. Add this js to the front-end during admin 'post' editing mode
  2. Wait for Gutenberg to load/render
  3. Select a block w/ the WYSIWYG editor in it.
  4. Enter any text, select a single word, click the 'Bold' button, notice the WYSIWYG editor bolds the text, but not the WP Block render view
  5. Next, click on same Block with a WYSIWYG editor in it, and click on any of the custom buttons, see the content change in the WYSIWYG editor, but not the WP Block render view although it should just like the default buttons like 'bold' would
  6. CAVEAT** ( See above in description ) and manual hard-return in the 'text' tab renders the WYSIWYG content correctly.

Expected behavior Expect that clicking on any of the custom buttons in the ACF fields in page or block will update the WP Gutenberg Block render template live like normal.

Screenshots or Video ...

Code

acf.add_filter('wysiwyg_tinymce_settings', ( mceInit, id, field ) => {

        // // mceInit.height = 50;
        // // mceInit.apply_source_formatting = true;
      // // mceInit.verify_html = false;
        mceInit.extended_valid_elements = "span[class|name|id]",
        mceInit.toolbar1 = `${ mceInit.toolbar1 }forecolor,custom-br-shortcode,custom-headline,custom-color-solid`;
        // mceInit.toolbar2 = '';
        mceInit.setup = (editor) => 
        {

            // editor.on('change', function(e) {
            //  console.log( 'Editor change triggered...' );
            //  document.getElementById( `#${ id }`).dispatchEvent( new Event( 'change') );
            // });

            editor.addButton('custom-br-shortcode', {
                type: 'listbox',
                text: 'Break',
                values: [
                    { text: 'BR: None', value: '' },
                    { text: 'BR: Mobile', value: '[br-m]' },
                    { text: 'BR: Mobile to Tablet', value: '[br-m-t]' },
                    { text: 'BR: Mobile to Desktop', value: '[br-m-d]' },
                    { text: 'BR: Tablet', value: '[br-t]' },
                    { text: 'BR: Tablet to Desktop', value: '[br-t-d]' },
                    { text: 'BR: Desktop', value: '[br-d]' },
                 ],
                onselect: function ( _event ) {
                    editor.insertContent( this.value() );
                 },
            });

            editor.addButton('custom-headline', {
                type: 'listbox',
                text: 'Headline',
                values: [
                    { text: 'H1', value: 'h1' },
                    { text: 'H2', value: 'h2' },
                 ],
                onselect: function ( _event ) {

                    const content = editor.getContent();
                    const contentSelect = editor.selection.getContent();
                    const contentUpdate = content.replace( editor.selection.getContent(), `<${ this.value() }>${ editor.selection.getContent() }</${ this.value() }>\n` );
                    editor.setContent( contentUpdate );
                 },
            });

            editor.addButton('custom-color-solid', {
                type: 'listbox',
                text: 'Color',
                values: [
                    { text: 'Default', value: '' },
                    { text: 'Green, Forrest', value: 'clr-green-forrest' },
                    { text: 'Green, Lime', value: 'clr-green-lime' },
                 ],
                onselect: function ( _event ) 
                {
                    const content = `<span class='${ this.value() }'>${ editor.selection.getContent() }</span>`;
                    editor.selection.setContent( content );
                 },
            });
        }

        return mceInit;

    });

Version Information:

Additional context

lgladdy commented 1 month ago

Hey @archoda,

Thanks for writing this up, unfortunately we're becoming very limited in what we can do with TinyMCE in the block editor - it's why we now warn users to avoid using the WYSIWYG field in blocks.

Most new WordPress versions add more custom event handlers which is interrupting how TinyMCE performs, and as a legacy library we expect these issues to get worse over the coming years.

You should be able to handle things like this by triggering a change event on any input in your block form, however. ACF Blocks currently listens for that to trigger the serialisation, and we expect that to continue through our rewrites.

We recommend users use <InnerBlocks /> to use the WordPress block editor native tools for WYSIWYG like content. You can restriction the blocks allowed inside with allowedBlocks to only allow paragraphs and images for example.

We will still take a look at your issue to see if there's anything we can do specifically in your case; but it will likely need you to fire the change event I think.