Skip to content

Commit

Permalink
Editor: Trigger reusable blocks autocomplete when options generated (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
aduth authored and youknowriad committed Apr 17, 2019
1 parent a5a45ae commit e209cfb
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 14 deletions.
28 changes: 27 additions & 1 deletion packages/editor/src/components/autocompleters/block.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
/**
* External dependencies
*/
import { once } from 'lodash';

/**
* WordPress dependencies
*/
import { select } from '@wordpress/data';
import { select, dispatch } from '@wordpress/data';
import { createBlock } from '@wordpress/blocks';
import { BlockIcon } from '@wordpress/block-editor';

Expand Down Expand Up @@ -41,6 +46,25 @@ function defaultGetSelectedBlockName() {
return selectedBlockClientId ? getBlockName( selectedBlockClientId ) : null;
}

/**
* Triggers a fetch of reusable blocks, once.
*
* TODO: Reusable blocks fetching should be reimplemented as a core-data entity
* resolver, not relying on `core/editor` (see #7119). The implementation here
* is imperfect in that the options result will not await the completion of the
* fetch request and thus will not include any reusable blocks. This has always
* been true, but relied upon the fact the user would be delayed in typing an
* autocompleter search query. Once implemented using resolvers, the status of
* this request could be subscribed to as part of a promised return value using
* the result of `hasFinishedResolution`. There is currently reliable way to
* determine that a reusable blocks fetch request has completed.
*
* @return {Promise} Promise resolving once reusable blocks fetched.
*/
const fetchReusableBlocks = once( () => {
dispatch( 'core/editor' ).__experimentalFetchReusableBlocks();
} );

/**
* Creates a blocks repeater for replacing the current block with a selected block type.
*
Expand All @@ -57,6 +81,8 @@ export function createBlockCompleter( {
className: 'editor-autocompleters__block',
triggerPrefix: '/',
options() {
fetchReusableBlocks();

const selectedBlockName = getSelectedBlockName();
return getInserterItems( getBlockInsertionParentClientId() ).filter(
// Avoid offering to replace the current block with a block of the same type.
Expand Down
22 changes: 21 additions & 1 deletion packages/editor/src/components/autocompleters/test/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,29 @@ import { shallow } from 'enzyme';
* Internal dependencies
*/
import blockCompleter, { createBlockCompleter } from '../block';
import '../../../';

describe( 'block', () => {
it( 'should retrieve block options for current insertion point', () => {
let originalFetch;
beforeEach( () => {
originalFetch = window.fetch;
window.fetch = ( url ) => {
if ( ! /\/wp\/v2\/types\/wp_block(\?|$)/.test( url ) ) {
throw new Error( 'Unhandled fetch ' + url );
}

return Promise.resolve( {
status: 200,
json: () => Promise.resolve( [] ),
} );
};
} );

afterEach( () => {
window.fetch = originalFetch;
} );

it( 'should retrieve block options for current insertion point', async () => {
const expectedOptions = [ {}, {}, {} ];
const mockGetBlockInsertionParentClientId = jest.fn( () => 'expected-insertion-point' );
const mockGetInserterItems = jest.fn( () => expectedOptions );
Expand Down
13 changes: 1 addition & 12 deletions packages/editor/src/hooks/default-autocompleters.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
/**
* External dependencies
*/
import { clone, once } from 'lodash';
import { clone } from 'lodash';

/**
* WordPress dependencies
*/
import { addFilter } from '@wordpress/hooks';
import { getDefaultBlockName } from '@wordpress/blocks';
import { dispatch } from '@wordpress/data';

/**
* Internal dependencies
Expand All @@ -17,23 +16,13 @@ import { blockAutocompleter, userAutocompleter } from '../components';

const defaultAutocompleters = [ userAutocompleter ];

const fetchReusableBlocks = once( () => dispatch( 'core/editor' ).__experimentalFetchReusableBlocks() );

function setDefaultCompleters( completers, blockName ) {
if ( ! completers ) {
// Provide copies so filters may directly modify them.
completers = defaultAutocompleters.map( clone );
// Add blocks autocompleter for Paragraph block
if ( blockName === getDefaultBlockName() ) {
completers.push( clone( blockAutocompleter ) );

/*
* NOTE: This is a hack to help ensure reusable blocks are loaded
* so they may be included in the block completer. It can be removed
* once we have a way for completers to Promise options while
* store-based data dependencies are being resolved.
*/
fetchReusableBlocks();
}
}
return completers;
Expand Down

0 comments on commit e209cfb

Please sign in to comment.