Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Editor: Trigger reusable blocks autocomplete when options generated #14915

Merged
merged 1 commit into from
Apr 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is currently (no) 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