Skip to content
This repository has been archived by the owner on Mar 9, 2024. It is now read-only.

Tinymce in text widget #275

Merged
merged 11 commits into from
Nov 10, 2023
37 changes: 30 additions & 7 deletions src/wp-admin/js/widgets/text-widgets.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ wp.textWidgets = ( function( $ ) {
});

// Note that syncInput cannot be re-used because it will be destroyed with each widget-updated event.
fieldInput.val( control.syncContainer.find( '.sync-input.' + fieldName ).val() );
fieldInput.val( control.syncContainer.querySelector( '.sync-input.' + fieldName ).value );
});
},

Expand Down Expand Up @@ -216,7 +216,7 @@ wp.textWidgets = ( function( $ ) {
};

// Just-in-time force-update the hidden input fields.
control.syncContainer.closest( '.widget' ).find( '[name=savewidget]:first' ).on( 'click', function onClickSaveButton() {
control.syncContainer.closest( '.widget' ).querySelector( '[name=savewidget]' ).addEventListener( 'click', function onClickSaveButton() {
triggerChangeIfDirty();
});

Expand All @@ -235,12 +235,18 @@ wp.textWidgets = ( function( $ ) {

// The user has disabled TinyMCE.
if ( typeof window.tinymce === 'undefined' ) {
wp.oldEditor.initialize( id, {
quicktags: true,
mediaButtons: true
});

return;
}

// Destroy any existing editor so that it can be re-initialized after a widget-updated event.
if ( tinymce.get( id ) ) {
restoreTextMode = tinymce.get( id ).isHidden();
wp.oldEditor.remove( id );
}

// Add or enable the `wpview` plugin.
Expand All @@ -254,6 +260,14 @@ wp.textWidgets = ( function( $ ) {
}
} );

wp.oldEditor.initialize( id, {
tinymce: {
wpautop: true
},
quicktags: true,
mediaButtons: true
} );

/**
* Show a pointer, focus on dismiss, and speak the contents for a11y.
*
Expand Down Expand Up @@ -367,17 +381,26 @@ wp.textWidgets = ( function( $ ) {
var widgetForm, idBase, widgetControl, widgetId, animatedCheckDelay = 50, renderWhenAnimationDone, fieldContainer, syncContainer;
widgetForm = widgetContainer.find( '> .widget-inside > .form, > .widget-inside > form' ); // Note: '.form' appears in the customizer, whereas 'form' on the widgets admin screen.

idBase = widgetContainer.find( '.id_base' ).val();
if ( widgetContainer instanceof jQuery ) {
widgetContainer = widgetContainer[0];
}

idBase = widgetContainer.querySelector( '.id_base' ).value;
if ( -1 === component.idBases.indexOf( idBase ) ) {
return;
}

// Prevent initializing already-added widgets.
widgetId = widgetForm.find( '.widget-id' ).val();
widgetId = widgetContainer.querySelector( '.widget-id' ).value;
if ( component.widgetControls[ widgetId ] ) {
return;
}

// Bypass using TinyMCE when widget is in legacy mode.
if ( ! widgetContainer.querySelector( '.visual' ).value ) {
return;
}

/*
* Create a container element for the widget control fields.
* This is inserted into the DOM immediately before the .widget-content
Expand All @@ -389,8 +412,8 @@ wp.textWidgets = ( function( $ ) {
* components", the JS template is rendered outside of the normal form
* container.
*/
fieldContainer = $( '<div></div>' );
syncContainer = widgetContainer.find( '.widget-content:first' );
fieldContainer = document.createElement( 'div' );
syncContainer = widgetContainer.querySelector( '.widget-content' );
syncContainer.before( fieldContainer );

widgetControl = new component.TextWidgetControl({
Expand All @@ -407,7 +430,7 @@ wp.textWidgets = ( function( $ ) {
* with TinyMCE being able to set contenteditable on it.
*/
renderWhenAnimationDone = function() {
if ( ! widgetContainer.hasClass( 'open' ) ) {
if ( ! widgetContainer.querySelector( 'details' ).hasAttribute( 'open' ) ) {
setTimeout( renderWhenAnimationDone, animatedCheckDelay );
} else {
widgetControl.initializeEditor();
Expand Down
17 changes: 17 additions & 0 deletions src/wp-includes/script-loader.php
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,23 @@ function wp_default_packages_inline_scripts( $scripts ) {
),
'after'
);

// Loading the old editor and its config to ensure the classic block works as expected.
$scripts->add_inline_script(
'editor',
'window.wp.oldEditor = window.wp.editor;',
'after'
);

// wp-editor module is exposed as window.wp.editor
// Problem: there is quite some code expecting window.wp.oldEditor object available under window.wp.editor
// Solution: fuse the two objects together to maintain backward compatibility
// For more context, see https://github.com/WordPress/gutenberg/issues/33203
$scripts->add_inline_script(
'wp-editor',
'Object.assign( window.wp.editor, window.wp.oldEditor );',
'after'
);
}

/**
Expand Down
Loading