Skip to content

Commit

Permalink
Add support for block editor styles in WordPress 6.3
Browse files Browse the repository at this point in the history
Starting with WordPress 6.3, the block editor now loads in an iframe by default, and the script that previously added Tailwind Typography classes to the block editor is unable to do so as it is loaded outside of that iframe. However, the `block-editor.js` file should still be loaded outside of the iframe for all code meant to target block editor APIs.

Given the above, a second file—`tailwind-typography-classes.js`—has been created, containing only the code necessary to add Tailwind Typography classes to the block editor. It is enqueued using `enqueue_block_assets` with an `is_admin()` check to ensure it doesn’t run on the front end. The `tailwindTypographyClasses` JavaScript variable is now populated via `wp_add_inline_script()`.
  • Loading branch information
gregsullivan committed Aug 15, 2023
1 parent 65a54c6 commit 55a0316
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 112 deletions.
108 changes: 10 additions & 98 deletions javascript/block-editor.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
/* global wp, tailwindTypographyClasses */
/* global wp */

/**
* This file is loaded only by the block editor.
* Block editor modifications
*
* This file is loaded only by the block editor. Use it to modify the block
* editor via its APIs.
*
* The JavaScript code you place here will be processed by esbuild, and the
* output file will be created at `../theme/js/block-editor.min.js` and
Expand All @@ -12,102 +15,11 @@
*/

wp.domReady(() => {
/**
* Block editor modifications
*/

/* Add any custom modifications between this line and the "stop editing" line. */

// Add your own block editor modifications here. For example, you could
// register a block style:
// Add block editor modifications here. For example, you could register a
// block style:
//
// wp.blocks.registerBlockStyle( 'core/paragraph', {
// name: 'indent',
// label: 'Indent',
// wp.blocks.registerBlockStyle( 'core/quote', {
// name: 'fancy-quote',
// label: 'Fancy Quote',
// } );

/* That's all, stop editing! */

/*
* Add the necessary Tailwind Typography classes to the block editor.
* For details, please see the comments below.
*/
addTypographyClasses();
});

/**
* Tailwind Typography support from _tw
*
* The code below adds your front-end post title and Tailwind Typography
* classes to the block editor.
*
* Because Gutenberg’s `isEditorReady` function remains unstable,
* we’ll use an interval to watch for the arrival of the elements we need.
*/
function addTypographyClasses() {
const editorLoadedInterval = setInterval(function () {
// Wait until both the post title and post content blocks are present.
if (
document.getElementsByClassName('wp-block-post-title').length &&
document.getElementsByClassName('wp-block-post-content').length
) {
// Add the `entry-title` class to the post title block.
document
.getElementsByClassName('wp-block-post-title')[0]
.classList.add('entry-title');

// Add the Tailwind Typography modifiers to the post content block.
document
.getElementsByClassName('wp-block-post-content')[0]
.classList.add(...tailwindTypographyClasses);

// Add mutation observers to both blocks.
['.wp-block-post-title', '.wp-block-post-content'].forEach(
(className) => {
mutationObserver.observe(
document.querySelector(className),
{
attributes: true,
attributeFilter: ['class'],
}
);
}
);

// Stop the interval.
clearInterval(editorLoadedInterval);
}
}, 100);
}

/**
* We need to ensure the class names we add are added again if the React
* component is updated, removing them in the process. The mutation observer
* below will check for the needed classes and add them if they’ve been
* removed.
*/
const mutationObserver = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
const classList = mutation.target.classList;

// Check whether the mutated element is a post title or post content
// block.
if (classList.contains('wp-block-post-title')) {
// Check whether the `entry-title` class is present.
if (!classList.contains('entry-title')) {
// Add the `entry-title` class.
classList.add('entry-title');
}
} else if (classList.contains('wp-block-post-content')) {
// Check whether all the Tailwind Typography modifiers are present.
if (
!tailwindTypographyClasses.every((className) =>
classList.contains(className)
)
) {
// Add the Tailwind Typography modifiers.
classList.add(...tailwindTypographyClasses);
}
}
});
});
8 changes: 5 additions & 3 deletions javascript/script.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
/**
* The JavaScript code you place here will be processed by esbuild, and the
* output file will be created at `../theme/js/script.min.js` and enqueued by
* default in `../theme/functions.php`.
* Front-end JavaScript
*
* The JavaScript code you place here will be processed by esbuild. The output
* file will be created at `../theme/js/script.min.js` and enqueued in
* `../theme/functions.php`.
*
* For esbuild documentation, please see:
* https://esbuild.github.io/
Expand Down
100 changes: 100 additions & 0 deletions javascript/tailwind-typography-classes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/* global wp, tailwindTypographyClasses */

/**
* Tailwind Typography support from _tw
*
* The code below adds your front-end post title and Tailwind Typography
* classes to the block editor.
*
* You should not edit this file. If you would like to use JavaScript to
* modify the block editor, please use the `block-editor.js` file instead.
*
* The JavaScript code you place here will be processed by esbuild. The output
* file will be created at `../theme/js/tailwind-typography-classes.min.js` and
* enqueued in `../theme/functions.php`.
*
* For esbuild documentation, please see:
* https://esbuild.github.io/
*/

wp.domReady(() => {
// Add the necessary Tailwind Typography classes to the block editor.
addTypographyClasses();
});

/**
* Because Gutenberg’s `isEditorReady` function remains unstable,
* we’ll use an interval to watch for the arrival of the elements we need.
*/
function addTypographyClasses() {
const editorLoadedInterval = setInterval(function () {
// Wait until both the post title and post content blocks are present.
if (
document.getElementsByClassName('wp-block-post-title').length &&
document.getElementsByClassName('wp-block-post-content').length
) {
// Add the `entry-title` class to the post title block.
document
.getElementsByClassName('wp-block-post-title')[0]
.classList.add('entry-title');

// Add the Tailwind Typography modifiers to the post content block.
document
.getElementsByClassName('wp-block-post-content')[0]
.classList.add(...tailwindTypographyClasses);

// Add mutation observers to both blocks.
['.wp-block-post-title', '.wp-block-post-content'].forEach(
(className) => {
mutationObserver.observe(
document.querySelector(className),
{
attributes: true,
attributeFilter: ['class'],
}
);
}
);

// Stop the interval.
clearInterval(editorLoadedInterval);
} else if (document.getElementsByName('editor-canvas').length) {
// If the block editor has been loaded in an iframe, and this code
// is running outside of that iframe, stop the interval. (This code
// will run again inside the iframe.)
clearInterval(editorLoadedInterval);
}
}, 40);
}

/**
* We need to ensure the class names we add are added again if the React
* component is updated, removing them in the process. The mutation observer
* below will check for the needed classes and add them if they’ve been
* removed.
*/
const mutationObserver = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
const classList = mutation.target.classList;

// Check whether the mutated element is a post title or post content
// block.
if (classList.contains('wp-block-post-title')) {
// Check whether the `entry-title` class is present.
if (!classList.contains('entry-title')) {
// Add the `entry-title` class.
classList.add('entry-title');
}
} else if (classList.contains('wp-block-post-content')) {
// Check whether all the Tailwind Typography modifiers are present.
if (
!tailwindTypographyClasses.every((className) =>
classList.contains(className)
)
) {
// Add the Tailwind Typography modifiers.
classList.add(...tailwindTypographyClasses);
}
}
});
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"scripts": {
"development:tailwind:frontend": "npx tailwindcss --postcss -i ./tailwind/tailwind.css -c ./tailwind/tailwind.config.js -o ./theme/style.css",
"development:tailwind:editor": "cross-env _TW_TARGET=editor npx tailwindcss --postcss -i ./tailwind/tailwind.css -c ./tailwind/tailwind.config.js -o ./theme/style-editor.css",
"development:esbuild": "npx esbuild ./javascript/script.js ./javascript/block-editor.js --target=esnext --bundle --outdir=./theme/js --out-extension:.js=.min.js",
"development:esbuild": "npx esbuild ./javascript/script.js ./javascript/block-editor.js ./javascript/tailwind-typography-classes.js --target=esnext --bundle --outdir=./theme/js --out-extension:.js=.min.js",
"development": "run-p development:**",
"dev": "npm run development",
"watch:tailwind:frontend": "npm run development:tailwind:frontend -- --watch",
Expand Down
28 changes: 18 additions & 10 deletions theme/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -171,18 +171,26 @@ function _tw_enqueue_block_editor_script() {
add_action( 'enqueue_block_editor_assets', '_tw_enqueue_block_editor_script' );

/**
* Create a JavaScript array containing the Tailwind Typography classes from
* _TW_TYPOGRAPHY_CLASSES for use when adding Tailwind Typography support
* to the block editor.
* Enqueue the script necessary to support Tailwind Typography in the block
* editor, using an inline script to create a JavaScript array containing the
* Tailwind Typography classes from _S_TYPOGRAPHY_CLASSES.
*/
function _tw_admin_scripts() {
?>
<script>
tailwindTypographyClasses = '<?php echo esc_attr( _TW_TYPOGRAPHY_CLASSES ); ?>'.split(' ');
</script>
<?php
function _tw_enqueue_typography_script() {
if ( is_admin() ) {
wp_enqueue_script(
'_tw-typography',
get_template_directory_uri() . '/js/tailwind-typography-classes.min.js',
array(
'wp-blocks',
'wp-edit-post',
),
_TW_VERSION,
true
);
wp_add_inline_script( '_tw-typography', "tailwindTypographyClasses = '" . esc_attr( _TW_TYPOGRAPHY_CLASSES ) . "'.split(' ');", 'before' );
}
}
add_action( 'admin_print_scripts', '_tw_admin_scripts' );
add_action( 'enqueue_block_assets', '_tw_enqueue_typography_script' );

/**
* Add the Tailwind Typography classes to TinyMCE.
Expand Down

0 comments on commit 55a0316

Please sign in to comment.