Gutenberg コードリーディングメモ

Gutenberg本体のコードを読む上で、とっかかりになりそうな部分をメモ。

registerBlockType()

https://github.com/WordPress/gutenberg/blob/master/blocks/api/registration.js#L51

色々バリデーションが書いてあって、最終的には

return blocks[ name ] = settings;

でローカル変数 blocks に第1引数(name)をキー、第2引数(settings)を値として追加する。

setAttributes()

BlockListBlock というブロックで定義されている。

https://github.com/WordPress/gutenberg/blob/master/editor/components/block-list/block.js#L184-L203

setAttributes( attributes ) {
  const { block, onChange } = this.props;
  const type = getBlockType( block.name );
  onChange( block.uid, attributes );

  const metaAttributes = reduce( attributes, ( result, value, key ) => {
    if ( get( type, [ 'attributes', key, 'source' ] ) === 'meta' ) {
      result[ type.attributes[ key ].meta ] = value;
    }

    return result;
  }, {} );

  if ( size( metaAttributes ) ) {
    this.props.onMetaChange( {
      ...this.props.meta,
      ...metaAttributes,
    } );
  }
}

ここではBlockListBlockがpropsに持っているonChange()メソッドが重要。

https://github.com/WordPress/gutenberg/blob/master/editor/components/block-list/block.js#L465

onChange( uid, attributes ) {
  dispatch( updateBlockAttributes( uid, attributes ) );
},

onChangeはStoreをdispatchする。属性の設定処理の本体はreducerにある。

https://github.com/WordPress/gutenberg/blob/master/editor/store/reducer.js#L129

case 'UPDATE_BLOCK_ATTRIBUTES':
  // Ignore updates if block isn't known
  if ( ! state[ action.uid ] ) {
    return state;
  }

  // Consider as updates only changed values
  const nextAttributes = reduce( action.attributes, ( result, value, key ) => {
    if ( value !== result[ key ] ) {
      // Avoid mutating original block by creating shallow clone
      if ( result === state[ action.uid ].attributes ) {
        result = { ...result };
      }

      result[ key ] = value;
    }

    return result;
  }, state[ action.uid ].attributes );

  // Skip update if nothing has been changed. The reference will
  // match the original block if `reduce` had no changed values.
  if ( nextAttributes === state[ action.uid ].attributes ) {
    return state;
  }

  // Otherwise merge attributes into state
  return {
    ...state,
    [ action.uid ]: {
      ...state[ action.uid ],
      attributes: nextAttributes,
    },
};

Gutenbergのコードを読むなら、ある程度Flux(およびその実装であるRedux)については理解しておく必要がある。

コメントをどうぞ

コメントを残す