GutenbergエディタのDOMを操作をしたい場合

WordPress

今までのエディタでは「tiny_mce_before_init」フィルタなどのフックでクラスを付与したり色々な設定を変更したりすることができました。

Gutenbergでは同様の方法をとることができません。

新たにDOMの構築後に実行するコールバックを登録する方法が提供されているため、それを利用することで様々なことが簡単に実現できます。

wp.domReady

@wordpress/dom-ready
Execute callback after the DOM is loaded. Installation Install the module npm install @wordpress/dom-ready –save This package assumes that your code will run in...
wp.domReady(function () {
    // editor root
    const target = document.getElementById('editor');

    // visual editor
    const editor = target.getElementsByClassName('edit-post-visual-editor');
    Array.prototype.forEach.call(editor, e => e.classList.add('article'));
});

上のようなコードでビジュアルエディタに「article」というクラスを付与することが可能です。

jQueryでの操作も可能です。

wp.domReady(function() {
    $('#editor .edit-post-visual-editor').addClass('article');
});

editor関連のコード

editorの起動

wp-admin/edit-form-blocks.php

$init_script = <<<JS
( function() {
   window._wpLoadBlockEditor = new Promise( function( resolve ) {
      wp.domReady( function() {
         resolve( wp.editPost.initializeEditor( 'editor', "%s", %d, %s, %s ) );
      } );
   } );
} )();
JS;

initializeEditor

wp-includes/js/dist/edit-post.js

function initializeEditor(id, postType, postId, settings, initialEdits) {
  var target = document.getElementById(id);
  var reboot = reinitializeEditor.bind(null, postType, postId, target, settings, initialEdits);
  Object(external_this_wp_blockLibrary_["registerCoreBlocks"])();
  Object(external_this_wp_data_["dispatch"])('core/nux').triggerGuide(['core/editor.inserter', 'core/editor.settings', 'core/editor.preview', 'core/editor.publish']);
  Object(external_this_wp_element_["render"])(Object(external_this_wp_element_["createElement"])(editor, {
    settings: settings,
    onError: reboot,
    postId: postId,
    postType: postType,
    initialEdits: initialEdits
  }), target);
}

render

wp-includes/js/dist/vendor/react-dom.js

render: function (element, container, callback) {
  return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
},

legacyRenderSubtreeIntoContainer

wp-includes/js/dist/vendor/react-dom.js

function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {
  // TODO: Ensure all entry points contain this check
  !isValidContainer(container) ? invariant(false, 'Target container is not a DOM element.') : void 0;

  {
    topLevelUpdateWarnings(container);
  }

  // TODO: Without `any` type, Flow says "Property cannot be accessed on any
  // member of intersection type." Whyyyyyy.
  var root = container._reactRootContainer;
  if (!root) {
    // Initial mount
    root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate);

...

  return getPublicRootInstance(root._internalRoot);
}

結局「initializeEditor」の第一引数のIDを持つ要素がエディタのターゲットになります。

コメント