-
-
Save KevinBatdorf/fca19e1f3b749b5c57db8158f4850eff to your computer and use it in GitHub Desktop.
import { select, subscribe } from '@wordpress/data' | |
export function whenEditorIsReady() { | |
return new Promise((resolve) => { | |
const unsubscribe = subscribe(() => { | |
// This will trigger after the initial render blocking, before the window load event | |
// This seems currently more reliable than using __unstableIsEditorReady | |
if (select('core/editor').isCleanNewPost() || select('core/block-editor').getBlockCount() > 0) { | |
unsubscribe() | |
resolve() | |
} | |
}) | |
}) | |
} |
@KevinBatdorf: Awesome, needed this! Could be put into a npm
package.
Here a function that uses whenEditorIsReady
and also waits for the editor iframe becoming ready:
import whenEditorIsReady from './when-editor-is-ready.js';
async function getEditorIframe() {
await whenEditorIsReady();
const editorCanvasIframeElement = document.querySelector('[name="editor-canvas"]');
return new Promise((resolve) => {
if(!editorCanvasIframeElement.loading) {
// somehow the iframe has already loaded,
// skip waiting for onload event (won't be triggered)
resolve(editorCanvasIframeElement);
}
editorCanvasIframeElement.onload = () => {
resolve(editorCanvasIframeElement);
};
});
}
export default getEditorIframe;
Hi, How would you import that into a regular plugin javascript?
Import and Export doesnt work with enqueued scripts
thx!
@X-Raym: For those themes and plugins I would build the scripts, so those import
s is compiled.
Alternatively you can also enregister the when-editor-is-ready.js
and then enqueue the theme script, with the previously enregistered when-editor-is-ready
as a dependency. This will make WordPress first enqueue the when-editor-is-ready
script and then the theme script. You would not use import
in the theme script then, but rather check for the whenEditorIsReady
function being available (which it should be, when everything was correctly enregistered and enqueued).
You may still want to minify those script files (and enqueue the .min.js
variant, notably on production).
@strarsis Hi,
No compilation would be the best, so I can encapsulate the function in a more traditional JS with toher functions,
But you speak about theme script, but this is for Gutenberg Is Ready event, so it is on admin side, no theme script.
How would you enqueue this then?
Just putting
async function getEditorIframe() {
await whenEditorIsReady();
const editorCanvasIframeElement = document.querySelector('[name="editor-canvas"]');
return new Promise((resolve) => {
if(!editorCanvasIframeElement.loading) {
// somehow the iframe has already loaded,
// skip waiting for onload event (won't be triggered)
resolve(editorCanvasIframeElement);
console.log('ready')
}
editorCanvasIframeElement.onload = () => {
resolve(editorCanvasIframeElement);
};
});
}
function test_function( $hook ) {
wp_enqueue_script( 'my_custom_script', plugin_dir_url( __FILE__ ) . 'js/my-new-script.js', 100, null, true );
}
add_action( 'admin_enqueue_scripts', 'test_function' );
Doesnt do anything (note that the JS link is good of course, the php function is runnning etc. It is just the Javascript itself which doesnt work. Not exactly sure also where to plug my functions for when the editor is ready)
Instead of my_custom_script
you should name that helper script file something like gutenberg-when-editor-is-ready
.
Then you would add this script handle to the dependencies array for the admin script that uses whenEditorIsReady
:
function test_function( $hook ) {
wp_enqueue_script( 'gutenberg-when-editor-is-ready', plugin_dir_url( __FILE__ ) . 'js/my-new-script.js', [], null );
// (or at another place)
wp_enqueue_script( 'my-admin-script', plugin_dir_url( __FILE__ ) . 'js/my-admin-script.js', ['gutenberg-when-editor-is-ready'], null, true );
}
add_action( 'admin_enqueue_scripts', 'test_function' );
Additionally, the function signature of wp_enqueue_script
is,
wp_enqueue_script( string $handle, string $src = '', string[] $deps = array(), string|bool|null $ver = false, bool $in_footer = false )
,
so in your code example you probably passed some incorrect arguments to it.
so in your code example you probably passed some incorrect arguments to it.
I just quickly renamed things to have more clarity, but on my side it works (the script is loaded etc).
Your code uses two javascripts files, I was expecting to merge the event handler and my custom scripts into one js only, as I dont need the functions to be avalaible for other scripts. That's why I needed a version without import/export. This way to enqueue triggers the import/export error as well, and if I remove these statement, I still dont succeed to trigger my custom functions at editor ready.
I'm a bit confused by the javascript side of thing, I think I would need a full working exemple with console.log call at editor ready, something like that.
Thx for the help and explications anyway!
@X-Raym: Well, you can put that code just into a javascript file, together with the code that uses the function, and then enqueue it for editor.
const select = wp.data.select,
subscribe = wp.data.subscribe;
function whenEditorIsReady() {
return new Promise((resolve) => {
const unsubscribe = subscribe(() => {
// This will trigger after the initial render blocking, before the window load event
// This seems currently more reliable than using __unstableIsEditorReady
if (select('core/editor').isCleanNewPost() || select('core/block-editor').getBlockCount() > 0) {
unsubscribe()
resolve()
}
})
})
}
async function getEditorIframe() {
await whenEditorIsReady();
const editorCanvasIframeElement = document.querySelector('[name="editor-canvas"]');
return new Promise((resolve) => {
if(!editorCanvasIframeElement.loading) {
// somehow the iframe has already loaded,
// skip waiting for onload event (won't be triggered)
resolve(editorCanvasIframeElement);
}
editorCanvasIframeElement.onload = () => {
resolve(editorCanvasIframeElement);
};
});
}
// Wait for editor iframe becoming available (and editor becoming ready)
await getEditorIframe();
// your code here, when editor became available
@strarsis thx you very much for this more detailed code snippet!
It do return an error though:
```Uncaught SyntaxError: await is only valid in async functions, async generators and modules````
Ok I had to replace the last async call with
(async() => {
await getEditorIframe();
MyFunction()
})();
And also
document.querySelector('[name="editor-canvas"]');
by
document.querySelector('.edit-post-header-toolbar__left');
(cause the first one was undefined. I needed the toolbar anyway), cause I use this to print custom infos on the Gutenberg toolbar.
Seems to works with these fixes, many thx!
🤔 In latest Gutenberg it appears that no iframe
element is used anymore.
Use it like this: