` );
- expect( toHTMLString( create( { element } ) ) ).toEqual( HTML );
+ expect( toHTMLString( { value: create( { element } ) } ) ).toEqual( HTML );
} );
it( 'should extract recreate HTML 2', () => {
const HTML = 'one two 🍒test three';
const element = createNode( `
${ HTML }
` );
- expect( toHTMLString( create( { element } ) ) ).toEqual( HTML );
+ expect( toHTMLString( { value: create( { element } ) } ) ).toEqual( HTML );
} );
it( 'should extract recreate HTML 3', () => {
const HTML = '';
const element = createNode( `
${ HTML }
` );
- expect( toHTMLString( create( { element } ) ) ).toEqual( HTML );
+ expect( toHTMLString( { value: create( { element } ) } ) ).toEqual( HTML );
} );
it( 'should extract recreate HTML 4', () => {
const HTML = 'two 🍒';
const element = createNode( `
${ HTML }
` );
- expect( toHTMLString( create( { element } ) ) ).toEqual( HTML );
+ expect( toHTMLString( { value: create( { element } ) } ) ).toEqual( HTML );
} );
it( 'should extract recreate HTML 5', () => {
const HTML = 'If you want to learn more about how to build additional blocks, or if you are interested in helping with the project, head over to the GitHub repository.';
const element = createNode( `
${ HTML }
` );
- expect( toHTMLString( create( { element } ) ) ).toEqual( HTML );
+ expect( toHTMLString( { value: create( { element } ) } ) ).toEqual( HTML );
} );
it( 'should extract recreate HTML 6', () => {
const HTML = '
one
two
three
';
const element = createNode( `
${ HTML }
` );
const multilineTag = 'li';
+ const multilineWrapperTags = [ 'ul', 'ol' ];
+ const value = create( { element, multilineTag, multilineWrapperTags } );
+ const result = toHTMLString( { value, multilineTag, multilineWrapperTags } );
- expect( toHTMLString( create( { element, multilineTag } ), 'li' ) ).toEqual( HTML );
+ expect( result ).toEqual( HTML );
} );
it( 'should serialize neighbouring formats of same type', () => {
const HTML = 'aa';
const element = createNode( `
${ HTML }
` );
- expect( toHTMLString( create( { element } ) ) ).toEqual( HTML );
+ expect( toHTMLString( { value: create( { element } ) } ) ).toEqual( HTML );
} );
it( 'should serialize neighbouring same formats', () => {
@@ -81,6 +84,6 @@ describe( 'toHTMLString', () => {
const element = createNode( `
${ HTML }
` );
const expectedHTML = 'aa';
- expect( toHTMLString( create( { element } ) ) ).toEqual( expectedHTML );
+ expect( toHTMLString( { value: create( { element } ) } ) ).toEqual( expectedHTML );
} );
} );
diff --git a/packages/rich-text/src/to-dom.js b/packages/rich-text/src/to-dom.js
index 018869337c533c..319e8b61ee1377 100644
--- a/packages/rich-text/src/to-dom.js
+++ b/packages/rich-text/src/to-dom.js
@@ -58,13 +58,8 @@ function getNodeByPath( node, path ) {
};
}
-function createEmpty( type ) {
+function createEmpty() {
const { body } = document.implementation.createHTMLDocument( '' );
-
- if ( type ) {
- return body.appendChild( body.ownerDocument.createElement( type ) );
- }
-
return body;
}
@@ -110,11 +105,46 @@ function remove( node ) {
return node.parentNode.removeChild( node );
}
-export function toDom( value, multilineTag ) {
+function padEmptyLines( { element, createLinePadding, multilineWrapperTags } ) {
+ const length = element.childNodes.length;
+ const doc = element.ownerDocument;
+
+ for ( let index = 0; index < length; index++ ) {
+ const child = element.childNodes[ index ];
+
+ if ( child.nodeType === TEXT_NODE ) {
+ if ( length === 1 && ! child.nodeValue ) {
+ // Pad if the only child is an empty text node.
+ element.appendChild( createLinePadding( doc ) );
+ }
+ } else {
+ if (
+ multilineWrapperTags &&
+ ! child.previousSibling &&
+ multilineWrapperTags.indexOf( child.nodeName.toLowerCase() ) !== -1
+ ) {
+ // Pad the line if there is no content before a nested wrapper.
+ element.insertBefore( createLinePadding( doc ), child );
+ }
+
+ padEmptyLines( { element: child, createLinePadding, multilineWrapperTags } );
+ }
+ }
+}
+
+export function toDom( {
+ value,
+ multilineTag,
+ multilineWrapperTags,
+ createLinePadding,
+} ) {
let startPath = [];
let endPath = [];
- const tree = toTree( value, multilineTag, {
+ const tree = toTree( {
+ value,
+ multilineTag,
+ multilineWrapperTags,
createEmpty,
append,
getLastChild,
@@ -123,27 +153,18 @@ export function toDom( value, multilineTag ) {
getText,
remove,
appendText,
- onStartIndex( body, pointer, multilineIndex ) {
+ onStartIndex( body, pointer ) {
startPath = createPathToNode( pointer, body, [ pointer.nodeValue.length ] );
-
- if ( multilineIndex !== undefined ) {
- startPath = [ multilineIndex, ...startPath ];
- }
},
- onEndIndex( body, pointer, multilineIndex ) {
+ onEndIndex( body, pointer ) {
endPath = createPathToNode( pointer, body, [ pointer.nodeValue.length ] );
-
- if ( multilineIndex !== undefined ) {
- endPath = [ multilineIndex, ...endPath ];
- }
- },
- onEmpty( body ) {
- const br = body.ownerDocument.createElement( 'br' );
- br.setAttribute( 'data-mce-bogus', '1' );
- body.appendChild( br );
},
} );
+ if ( createLinePadding ) {
+ padEmptyLines( { element: tree, createLinePadding, multilineWrapperTags } );
+ }
+
return {
body: tree,
selection: { startPath, endPath },
@@ -160,9 +181,20 @@ export function toDom( value, multilineTag ) {
* tree to.
* @param {string} multilineTag Multiline tag.
*/
-export function apply( value, current, multilineTag ) {
+export function apply( {
+ value,
+ current,
+ multilineTag,
+ multilineWrapperTags,
+ createLinePadding,
+} ) {
// Construct a new element tree in memory.
- const { body, selection } = toDom( value, multilineTag );
+ const { body, selection } = toDom( {
+ value,
+ multilineTag,
+ multilineWrapperTags,
+ createLinePadding,
+ } );
applyValue( body, current );
diff --git a/packages/rich-text/src/to-html-string.js b/packages/rich-text/src/to-html-string.js
index 6cb87705e189b9..1965419bdd552e 100644
--- a/packages/rich-text/src/to-html-string.js
+++ b/packages/rich-text/src/to-html-string.js
@@ -7,6 +7,7 @@ import {
escapeAttribute,
isValidAttributeName,
} from '@wordpress/escape-html';
+import deprecated from '@wordpress/deprecated';
/**
* Internal dependencies
@@ -16,15 +17,34 @@ import { toTree } from './to-tree';
/**
* Create an HTML string from a Rich Text value. If a `multilineTag` is
- * provided, text separated by two new lines will be wrapped in it.
+ * provided, text separated by a line separator will be wrapped in it.
*
- * @param {Object} value Rich text value.
- * @param {string} multilineTag Multiline tag.
+ * @param {Object} $1 Named argements.
+ * @param {Object} $1.value Rich text value.
+ * @param {string} $1.multilineTag Multiline tag.
+ * @param {Array} $1.multilineWrapperTags Tags where lines can be found if
+ * nesting is possible.
*
* @return {string} HTML string.
*/
-export function toHTMLString( value, multilineTag ) {
- const tree = toTree( value, multilineTag, {
+export function toHTMLString( { value, multilineTag, multilineWrapperTags } ) {
+ // Check other arguments for backward compatibility.
+ if ( value === undefined ) {
+ deprecated( 'wp.richText.toHTMLString positional parameters', {
+ version: '4.4',
+ alternative: 'named parameters',
+ plugin: 'Gutenberg',
+ } );
+
+ value = arguments[ 0 ];
+ multilineTag = arguments[ 1 ];
+ multilineWrapperTags = arguments[ 2 ];
+ }
+
+ const tree = toTree( {
+ value,
+ multilineTag,
+ multilineWrapperTags,
createEmpty,
append,
getLastChild,
@@ -38,8 +58,8 @@ export function toHTMLString( value, multilineTag ) {
return createChildrenHTML( tree.children );
}
-function createEmpty( type ) {
- return { type };
+function createEmpty() {
+ return {};
}
function getLastChild( { children } ) {
diff --git a/packages/rich-text/src/to-tree.js b/packages/rich-text/src/to-tree.js
index b40c04846b8b1c..d599db049ff9aa 100644
--- a/packages/rich-text/src/to-tree.js
+++ b/packages/rich-text/src/to-tree.js
@@ -2,8 +2,11 @@
* Internal dependencies
*/
-import { split } from './split';
import { getFormatType } from './get-format-type';
+import {
+ LINE_SEPARATOR,
+ OBJECT_REPLACEMENT_CHARACTER,
+} from './special-characters';
function fromFormat( { type, attributes, object } ) {
const formatType = getFormatType( type );
@@ -38,56 +41,87 @@ function fromFormat( { type, attributes, object } ) {
};
}
-export function toTree( value, multilineTag, settings ) {
- if ( multilineTag ) {
- const { createEmpty, append } = settings;
- const tree = createEmpty();
-
- split( value, '\u2028' ).forEach( ( piece, index ) => {
- append( tree, toTree( piece, null, {
- ...settings,
- tag: multilineTag,
- multilineIndex: index,
- } ) );
- } );
-
- return tree;
- }
-
- const {
- tag,
- multilineIndex,
- createEmpty,
- append,
- getLastChild,
- getParent,
- isText,
- getText,
- remove,
- appendText,
- onStartIndex,
- onEndIndex,
- onEmpty,
- } = settings;
+export function toTree( {
+ value,
+ multilineTag,
+ multilineWrapperTags,
+ createEmpty,
+ append,
+ getLastChild,
+ getParent,
+ isText,
+ getText,
+ remove,
+ appendText,
+ onStartIndex,
+ onEndIndex,
+} ) {
const { formats, text, start, end } = value;
const formatsLength = formats.length + 1;
- const tree = createEmpty( tag );
+ const tree = createEmpty();
+ const multilineFormat = { type: multilineTag };
- append( tree, '' );
+ let lastSeparatorFormats;
+ let lastCharacterFormats;
+ let lastCharacter;
+
+ // If we're building a multiline tree, start off with a multiline element.
+ if ( multilineTag ) {
+ append( append( tree, { type: multilineTag } ), '' );
+ lastCharacterFormats = lastSeparatorFormats = [ multilineFormat ];
+ } else {
+ append( tree, '' );
+ }
for ( let i = 0; i < formatsLength; i++ ) {
const character = text.charAt( i );
- const characterFormats = formats[ i ];
- const lastCharacterFormats = formats[ i - 1 ];
+ let characterFormats = formats[ i ];
+
+ // Set multiline tags in queue for building the tree.
+ if ( multilineTag ) {
+ if ( character === LINE_SEPARATOR ) {
+ characterFormats = lastSeparatorFormats = ( characterFormats || [] ).reduce( ( accumulator, format ) => {
+ if ( character === LINE_SEPARATOR && multilineWrapperTags.indexOf( format.type ) !== -1 ) {
+ accumulator.push( format );
+ accumulator.push( multilineFormat );
+ }
+
+ return accumulator;
+ }, [ multilineFormat ] );
+ } else {
+ characterFormats = [ ...lastSeparatorFormats, ...( characterFormats || [] ) ];
+ }
+ }
let pointer = getLastChild( tree );
+ // Set selection for the start of line.
+ if ( lastCharacter === LINE_SEPARATOR ) {
+ let node = pointer;
+
+ while ( ! isText( node ) ) {
+ node = getLastChild( node );
+ }
+
+ if ( onStartIndex && start === i ) {
+ onStartIndex( tree, node );
+ }
+
+ if ( onEndIndex && end === i ) {
+ onEndIndex( tree, node );
+ }
+ }
+
if ( characterFormats ) {
characterFormats.forEach( ( format, formatIndex ) => {
if (
pointer &&
lastCharacterFormats &&
- format === lastCharacterFormats[ formatIndex ]
+ format === lastCharacterFormats[ formatIndex ] &&
+ // Do not reuse the last element if the character is a
+ // line separator.
+ ( character !== LINE_SEPARATOR ||
+ characterFormats.length - 1 !== formatIndex )
) {
pointer = getLastChild( pointer );
return;
@@ -105,17 +139,25 @@ export function toTree( value, multilineTag, settings ) {
} );
}
- // If there is selection at 0, handle it before characters are inserted.
-
- if ( onStartIndex && start === 0 && i === 0 ) {
- onStartIndex( tree, pointer, multilineIndex );
+ // No need for further processing if the character is a line separator.
+ if ( character === LINE_SEPARATOR ) {
+ lastCharacterFormats = characterFormats;
+ lastCharacter = character;
+ continue;
}
- if ( onEndIndex && end === 0 && i === 0 ) {
- onEndIndex( tree, pointer, multilineIndex );
+ // If there is selection at 0, handle it before characters are inserted.
+ if ( i === 0 ) {
+ if ( onStartIndex && start === 0 ) {
+ onStartIndex( tree, pointer );
+ }
+
+ if ( onEndIndex && end === 0 ) {
+ onEndIndex( tree, pointer );
+ }
}
- if ( character !== '\ufffc' ) {
+ if ( character !== OBJECT_REPLACEMENT_CHARACTER ) {
if ( character === '\n' ) {
pointer = append( getParent( pointer ), { type: 'br', object: true } );
// Ensure pointer is text node.
@@ -128,16 +170,15 @@ export function toTree( value, multilineTag, settings ) {
}
if ( onStartIndex && start === i + 1 ) {
- onStartIndex( tree, pointer, multilineIndex );
+ onStartIndex( tree, pointer );
}
if ( onEndIndex && end === i + 1 ) {
- onEndIndex( tree, pointer, multilineIndex );
+ onEndIndex( tree, pointer );
}
- }
- if ( onEmpty && text.length === 0 ) {
- onEmpty( tree );
+ lastCharacterFormats = characterFormats;
+ lastCharacter = character;
}
return tree;
diff --git a/test/e2e/specs/__snapshots__/deprecated-node-matcher.test.js.snap b/test/e2e/specs/__snapshots__/deprecated-node-matcher.test.js.snap
index a0cc53a6c18113..d36c990c04c37d 100644
--- a/test/e2e/specs/__snapshots__/deprecated-node-matcher.test.js.snap
+++ b/test/e2e/specs/__snapshots__/deprecated-node-matcher.test.js.snap
@@ -8,6 +8,6 @@ exports[`Deprecated Node Matcher should insert block with children source 1`] =
exports[`Deprecated Node Matcher should insert block with node source 1`] = `
"
-
test
+
test
"
`;
diff --git a/test/e2e/specs/blocks/__snapshots__/list.test.js.snap b/test/e2e/specs/blocks/__snapshots__/list.test.js.snap
index 9f2a208d343965..dbc0bee94158fd 100644
--- a/test/e2e/specs/blocks/__snapshots__/list.test.js.snap
+++ b/test/e2e/specs/blocks/__snapshots__/list.test.js.snap
@@ -16,6 +16,16 @@ exports[`List can be converted to paragraphs 1`] = `
"
`;
+exports[`List can be converted when nested to paragraphs 1`] = `
+"
+
one
+
+
+
+
two
+"
+`;
+
exports[`List can be created by converting a paragraph 1`] = `
"
test
@@ -80,6 +90,12 @@ exports[`List should create paragraph on split at end and merge back with conten
"
`;
+exports[`List should split indented list item 1`] = `
+"
+
one
two
three
+"
+`;
+
exports[`List should split into two with paragraph and merge lists 1`] = `
"
one
two
diff --git a/test/e2e/specs/blocks/list.test.js b/test/e2e/specs/blocks/list.test.js
index 5c112b83454ee5..f28196cfbdffab 100644
--- a/test/e2e/specs/blocks/list.test.js
+++ b/test/e2e/specs/blocks/list.test.js
@@ -97,6 +97,21 @@ describe( 'List', () => {
expect( await getEditedPostContent() ).toMatchSnapshot();
} );
+ it( 'can be converted when nested to paragraphs', async () => {
+ await insertBlock( 'List' );
+ await page.keyboard.type( 'one' );
+ await page.keyboard.press( 'Enter' );
+ // Pointer device is needed. Shift+Tab won't focus the toolbar.
+ // To do: fix so Shift+Tab works.
+ await page.mouse.move( 200, 300, { steps: 10 } );
+ await page.mouse.move( 250, 350, { steps: 10 } );
+ await page.click( 'button[aria-label="Indent list item"]' );
+ await page.keyboard.type( 'two' );
+ await convertBlock( 'Paragraph' );
+
+ expect( await getEditedPostContent() ).toMatchSnapshot();
+ } );
+
it( 'can be created by converting a quote', async () => {
await insertBlock( 'Quote' );
await page.keyboard.type( 'one' );
@@ -155,4 +170,20 @@ describe( 'List', () => {
expect( await getEditedPostContent() ).toMatchSnapshot();
} );
+
+ it( 'should split indented list item', async () => {
+ await insertBlock( 'List' );
+ await page.keyboard.type( 'one' );
+ await page.keyboard.press( 'Enter' );
+ // Pointer device is needed. Shift+Tab won't focus the toolbar.
+ // To do: fix so Shift+Tab works.
+ await page.mouse.move( 200, 300, { steps: 10 } );
+ await page.mouse.move( 250, 350, { steps: 10 } );
+ await page.click( 'button[aria-label="Indent list item"]' );
+ await page.keyboard.type( 'two' );
+ await page.keyboard.press( 'Enter' );
+ await page.keyboard.type( 'three' );
+
+ expect( await getEditedPostContent() ).toMatchSnapshot();
+ } );
} );
From 489fe169dad7df1700dea26a6a9dce3fbde14936 Mon Sep 17 00:00:00 2001
From: Ryan Welcher
Date: Tue, 30 Oct 2018 07:26:38 -0400
Subject: [PATCH 10/98] Adds aria-label to links that open in new windows
(#11063)
---
packages/format-library/src/link/inline.js | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/packages/format-library/src/link/inline.js b/packages/format-library/src/link/inline.js
index 6ab3198c25a0d8..95fb1eb4045252 100644
--- a/packages/format-library/src/link/inline.js
+++ b/packages/format-library/src/link/inline.js
@@ -1,7 +1,7 @@
/**
* WordPress dependencies
*/
-import { __ } from '@wordpress/i18n';
+import { sprintf, __ } from '@wordpress/i18n';
import { Component, createRef } from '@wordpress/element';
import {
ExternalLink,
@@ -26,7 +26,16 @@ import PositionedAtSelection from './positioned-at-selection';
const stopKeyPropagation = ( event ) => event.stopPropagation();
-function createLinkFormat( { url, opensInNewWindow } ) {
+/**
+ * Generates the format object that will be applied to the link text.
+ *
+ * @param {string} url The href of the link.
+ * @param {boolean} opensInNewWindow Whether this link will open in a new window.
+ * @param {Object} text The text that is being hyperlinked.
+ *
+ * @return {Object} The final format object.
+ */
+function createLinkFormat( { url, opensInNewWindow, text } ) {
const format = {
type: 'core/link',
attributes: {
@@ -35,8 +44,12 @@ function createLinkFormat( { url, opensInNewWindow } ) {
};
if ( opensInNewWindow ) {
+ // translators: accessibility label for external links, where the argument is the link text
+ const label = sprintf( __( '%s (opens in a new tab)' ), text ).trim();
+
format.attributes.target = '_blank';
format.attributes.rel = 'noreferrer noopener';
+ format.attributes[ 'aria-label' ] = label;
}
return format;
@@ -139,7 +152,7 @@ class InlineLinkUI extends Component {
// Apply now if URL is not being edited.
if ( ! isShowingInput( this.props, this.state ) ) {
- onChange( applyFormat( value, createLinkFormat( { url, opensInNewWindow } ) ) );
+ onChange( applyFormat( value, createLinkFormat( { url, opensInNewWindow, text: value.text } ) ) );
}
}
@@ -152,7 +165,7 @@ class InlineLinkUI extends Component {
const { isActive, value, onChange, speak } = this.props;
const { inputValue, opensInNewWindow } = this.state;
const url = prependHTTP( inputValue );
- const format = createLinkFormat( { url, opensInNewWindow } );
+ const format = createLinkFormat( { url, opensInNewWindow, text: value.text } );
event.preventDefault();
From 0e83c98b817b4fd1c65a62eb9b993394cc9b54fa Mon Sep 17 00:00:00 2001
From: Timothy Jacobs
Date: Tue, 30 Oct 2018 08:12:19 -0400
Subject: [PATCH 11/98] API Fetch: Handle 204 Response Code (#11208)
Fixes #11179. Previously, API Fetch would try to always get the response body
as JSON, even if the Response Status Code indicated that an empty response body
was expected.
---
packages/api-fetch/src/index.js | 4 ++++
packages/api-fetch/src/test/index.js | 10 ++++++++++
2 files changed, 14 insertions(+)
diff --git a/packages/api-fetch/src/index.js b/packages/api-fetch/src/index.js
index 50ba344be9d6d7..c8e12a5a8ecc91 100644
--- a/packages/api-fetch/src/index.js
+++ b/packages/api-fetch/src/index.js
@@ -55,6 +55,10 @@ function apiFetch( options ) {
const parseResponse = ( response ) => {
if ( parse ) {
+ if ( response.status === 204 ) {
+ return null;
+ }
+
return response.json ? response.json() : Promise.reject( response );
}
diff --git a/packages/api-fetch/src/test/index.js b/packages/api-fetch/src/test/index.js
index 47aa4d2303e14f..220a618f17a3db 100644
--- a/packages/api-fetch/src/test/index.js
+++ b/packages/api-fetch/src/test/index.js
@@ -74,6 +74,16 @@ describe( 'apiFetch', () => {
} );
} );
+ it( 'should return null if response has no content status code', () => {
+ window.fetch.mockReturnValue( Promise.resolve( {
+ status: 204,
+ } ) );
+
+ return apiFetch( { path: '/random' } ).catch( ( body ) => {
+ expect( body ).toEqual( null );
+ } );
+ } );
+
it( 'should not try to parse the response', () => {
window.fetch.mockReturnValue( Promise.resolve( {
status: 200,
From db728b7f37272c6e1e9c17eb848db179f8183c89 Mon Sep 17 00:00:00 2001
From: Tammie Lister
Date: Tue, 30 Oct 2018 12:35:53 +0000
Subject: [PATCH 12/98] Try different block descriptions (#10971)
---
package-lock.json | 1 +
packages/block-library/src/archives/index.js | 2 +-
packages/block-library/src/audio/index.js | 2 +-
packages/block-library/src/button/index.js | 2 +-
.../block-library/src/categories/index.js | 2 +-
packages/block-library/src/classic/index.js | 2 +-
packages/block-library/src/code/index.js | 2 +-
packages/block-library/src/cover/index.js | 2 +-
.../block-library/src/embed/core-embeds.js | 33 +++++++++++++++++++
packages/block-library/src/embed/index.js | 2 +-
packages/block-library/src/file/index.js | 2 +-
packages/block-library/src/gallery/index.js | 2 +-
packages/block-library/src/heading/index.js | 2 +-
packages/block-library/src/html/index.js | 2 +-
packages/block-library/src/image/index.js | 2 +-
.../src/latest-comments/index.js | 2 +-
packages/block-library/src/list/index.js | 2 +-
.../block-library/src/media-text/index.js | 2 ++
packages/block-library/src/more/index.js | 2 +-
packages/block-library/src/nextpage/index.js | 2 +-
packages/block-library/src/paragraph/index.js | 2 +-
packages/block-library/src/pullquote/index.js | 2 +-
packages/block-library/src/quote/index.js | 2 +-
packages/block-library/src/separator/index.js | 2 +-
packages/block-library/src/shortcode/index.js | 2 +-
packages/block-library/src/spacer/index.js | 2 +-
packages/block-library/src/table/index.js | 2 +-
packages/block-library/src/verse/index.js | 2 +-
packages/block-library/src/video/index.js | 2 +-
29 files changed, 62 insertions(+), 26 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 06884a98691237..ed71b4aeeb4313 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2443,6 +2443,7 @@
"requires": {
"@babel/runtime": "^7.0.0",
"@wordpress/data": "file:packages/data",
+ "@wordpress/deprecated": "file:packages/deprecated",
"@wordpress/escape-html": "file:packages/escape-html",
"lodash": "^4.17.10",
"rememo": "^3.0.0"
diff --git a/packages/block-library/src/archives/index.js b/packages/block-library/src/archives/index.js
index e978f7d6403415..8dfca64a8823cd 100644
--- a/packages/block-library/src/archives/index.js
+++ b/packages/block-library/src/archives/index.js
@@ -14,7 +14,7 @@ export const name = 'core/archives';
export const settings = {
title: __( 'Archives' ),
- description: __( 'Display a monthly archive of your site’s Posts.' ),
+ description: __( 'Display a monthly archive of your posts.' ),
icon: ,
diff --git a/packages/block-library/src/audio/index.js b/packages/block-library/src/audio/index.js
index 3161bb22e61c08..51a307102397d9 100644
--- a/packages/block-library/src/audio/index.js
+++ b/packages/block-library/src/audio/index.js
@@ -17,7 +17,7 @@ export const name = 'core/audio';
export const settings = {
title: __( 'Audio' ),
- description: __( 'Embed an audio file and a simple audio player.' ),
+ description: __( 'Embed a simple audio player.' ),
icon: ,
diff --git a/packages/block-library/src/button/index.js b/packages/block-library/src/button/index.js
index 24531e39eb42ae..5dddccfa760ca6 100644
--- a/packages/block-library/src/button/index.js
+++ b/packages/block-library/src/button/index.js
@@ -64,7 +64,7 @@ const colorsMigration = ( attributes ) => {
export const settings = {
title: __( 'Button' ),
- description: __( 'Want visitors to click to subscribe, buy, or read more? Get their attention with a button.' ),
+ description: __( 'Prompt visitors to take action with a custom button.' ),
icon: ,
diff --git a/packages/block-library/src/categories/index.js b/packages/block-library/src/categories/index.js
index a51d734c33072c..ab9c198eff4615 100644
--- a/packages/block-library/src/categories/index.js
+++ b/packages/block-library/src/categories/index.js
@@ -14,7 +14,7 @@ export const name = 'core/categories';
export const settings = {
title: __( 'Categories' ),
- description: __( 'Display a list of all your site’s categories.' ),
+ description: __( 'Display a list of all categories.' ),
icon: ,
diff --git a/packages/block-library/src/classic/index.js b/packages/block-library/src/classic/index.js
index a8fd64e08daa0e..e30d7fa75eada5 100644
--- a/packages/block-library/src/classic/index.js
+++ b/packages/block-library/src/classic/index.js
@@ -15,7 +15,7 @@ export const name = 'core/freeform';
export const settings = {
title: _x( 'Classic', 'block title' ),
- description: __( 'It’s the classic WordPress editor and it’s a block! Drop the editor right in.' ),
+ description: __( 'Use the classic WordPress editor.' ),
icon: ,
diff --git a/packages/block-library/src/code/index.js b/packages/block-library/src/code/index.js
index badc677610aaeb..cb304079e1e2c7 100644
--- a/packages/block-library/src/code/index.js
+++ b/packages/block-library/src/code/index.js
@@ -18,7 +18,7 @@ export const name = 'core/code';
export const settings = {
title: __( 'Code' ),
- description: __( 'Add text that respects your spacing and tabs -- perfect for displaying code.' ),
+ description: __( 'Display code snippets that respect your spacing and tabs.' ),
icon: ,
diff --git a/packages/block-library/src/cover/index.js b/packages/block-library/src/cover/index.js
index 4004dfa17bdb84..b282c5c7aeb8ee 100644
--- a/packages/block-library/src/cover/index.js
+++ b/packages/block-library/src/cover/index.js
@@ -83,7 +83,7 @@ const VIDEO_BACKGROUND_TYPE = 'video';
export const settings = {
title: __( 'Cover' ),
- description: __( 'Add a full-width image or video, and layer text over it — great for headers.' ),
+ description: __( 'Add an image or video with a text overlay — great for headers.' ),
icon: ,
diff --git a/packages/block-library/src/embed/core-embeds.js b/packages/block-library/src/embed/core-embeds.js
index 004166d227c2fa..a38c47d5be21bd 100644
--- a/packages/block-library/src/embed/core-embeds.js
+++ b/packages/block-library/src/embed/core-embeds.js
@@ -31,6 +31,7 @@ export const common = [
title: 'Twitter',
icon: embedTwitterIcon,
keywords: [ 'tweet' ],
+ description: __( 'Embed a tweet' ),
},
patterns: [ /^https?:\/\/(www\.)?twitter\.com\/.+/i ],
},
@@ -40,6 +41,7 @@ export const common = [
title: 'YouTube',
icon: embedYouTubeIcon,
keywords: [ __( 'music' ), __( 'video' ) ],
+ description: __( 'Embed a YouTube video' ),
},
patterns: [ /^https?:\/\/((m|www)\.)?youtube\.com\/.+/i, /^https?:\/\/youtu\.be\/.+/i ],
},
@@ -48,6 +50,7 @@ export const common = [
settings: {
title: 'Facebook',
icon: embedFacebookIcon,
+ description: __( 'Embed a Facebook post' ),
},
patterns: [ /^https?:\/\/www\.facebook.com\/.+/i ],
},
@@ -57,6 +60,7 @@ export const common = [
title: 'Instagram',
icon: embedInstagramIcon,
keywords: [ __( 'image' ) ],
+ description: __( 'Embed an Instagram post' ),
},
patterns: [ /^https?:\/\/(www\.)?instagr(\.am|am\.com)\/.+/i ],
},
@@ -67,6 +71,7 @@ export const common = [
icon: embedWordPressIcon,
keywords: [ __( 'post' ), __( 'blog' ) ],
responsive: false,
+ description: __( 'Embed a WordPress post' ),
},
},
{
@@ -75,6 +80,7 @@ export const common = [
title: 'SoundCloud',
icon: embedAudioIcon,
keywords: [ __( 'music' ), __( 'audio' ) ],
+ description: __( 'Embed SoundCloud content' ),
},
patterns: [ /^https?:\/\/(www\.)?soundcloud\.com\/.+/i ],
},
@@ -84,6 +90,7 @@ export const common = [
title: 'Spotify',
icon: embedSpotifyIcon,
keywords: [ __( 'music' ), __( 'audio' ) ],
+ description: __( 'Embed Spotify content' ),
},
patterns: [ /^https?:\/\/(open|play)\.spotify\.com\/.+/i ],
},
@@ -93,6 +100,7 @@ export const common = [
title: 'Flickr',
icon: embedFlickrIcon,
keywords: [ __( 'image' ) ],
+ description: __( 'Embed Flickr content' ),
},
patterns: [ /^https?:\/\/(www\.)?flickr\.com\/.+/i, /^https?:\/\/flic\.kr\/.+/i ],
},
@@ -102,6 +110,7 @@ export const common = [
title: 'Vimeo',
icon: embedVimeoIcon,
keywords: [ __( 'video' ) ],
+ description: __( 'Embed a Vimeo video' ),
},
patterns: [ /^https?:\/\/(www\.)?vimeo\.com\/.+/i ],
},
@@ -113,6 +122,7 @@ export const others = [
settings: {
title: 'Animoto',
icon: embedVideoIcon,
+ description: __( 'Embed an Animoto video' ),
},
patterns: [ /^https?:\/\/(www\.)?(animoto|video214)\.com\/.+/i ],
},
@@ -121,6 +131,7 @@ export const others = [
settings: {
title: 'Cloudup',
icon: embedContentIcon,
+ description: __( 'Embed Cloudup content' ),
},
patterns: [ /^https?:\/\/cloudup\.com\/.+/i ],
},
@@ -129,6 +140,7 @@ export const others = [
settings: {
title: 'CollegeHumor',
icon: embedVideoIcon,
+ description: __( 'Embed CollegeHumor content' ),
},
patterns: [ /^https?:\/\/(www\.)?collegehumor\.com\/.+/i ],
},
@@ -137,6 +149,7 @@ export const others = [
settings: {
title: 'Dailymotion',
icon: embedVideoIcon,
+ description: __( 'Embed a Dailymotion video' ),
},
patterns: [ /^https?:\/\/(www\.)?dailymotion\.com\/.+/i ],
},
@@ -145,6 +158,7 @@ export const others = [
settings: {
title: 'Funny or Die',
icon: embedVideoIcon,
+ description: __( 'Embed Funny or Die content' ),
},
patterns: [ /^https?:\/\/(www\.)?funnyordie\.com\/.+/i ],
},
@@ -153,6 +167,7 @@ export const others = [
settings: {
title: 'Hulu',
icon: embedVideoIcon,
+ description: __( 'Embed Hulu content' ),
},
patterns: [ /^https?:\/\/(www\.)?hulu\.com\/.+/i ],
},
@@ -161,6 +176,7 @@ export const others = [
settings: {
title: 'Imgur',
icon: embedPhotoIcon,
+ description: __( 'Embed Imgur content' ),
},
patterns: [ /^https?:\/\/(.+\.)?imgur\.com\/.+/i ],
},
@@ -169,6 +185,7 @@ export const others = [
settings: {
title: 'Issuu',
icon: embedContentIcon,
+ description: __( 'Embed Issuu content' ),
},
patterns: [ /^https?:\/\/(www\.)?issuu\.com\/.+/i ],
},
@@ -177,6 +194,7 @@ export const others = [
settings: {
title: 'Kickstarter',
icon: embedContentIcon,
+ description: __( 'Embed Kickstarter content' ),
},
patterns: [ /^https?:\/\/(www\.)?kickstarter\.com\/.+/i, /^https?:\/\/kck\.st\/.+/i ],
},
@@ -185,6 +203,7 @@ export const others = [
settings: {
title: 'Meetup.com',
icon: embedContentIcon,
+ description: __( 'Embed Meetup.com content' ),
},
patterns: [ /^https?:\/\/(www\.)?meetu(\.ps|p\.com)\/.+/i ],
},
@@ -194,6 +213,7 @@ export const others = [
title: 'Mixcloud',
icon: embedAudioIcon,
keywords: [ __( 'music' ), __( 'audio' ) ],
+ description: __( 'Embed Mixcloud content' ),
},
patterns: [ /^https?:\/\/(www\.)?mixcloud\.com\/.+/i ],
},
@@ -202,6 +222,7 @@ export const others = [
settings: {
title: 'Photobucket',
icon: embedPhotoIcon,
+ description: __( 'Embed a Photobucket image' ),
},
patterns: [ /^http:\/\/g?i*\.photobucket\.com\/.+/i ],
},
@@ -210,6 +231,7 @@ export const others = [
settings: {
title: 'Polldaddy',
icon: embedContentIcon,
+ description: __( 'Embed Polldaddy content' ),
},
patterns: [ /^https?:\/\/(www\.)?polldaddy\.com\/.+/i ],
},
@@ -218,6 +240,7 @@ export const others = [
settings: {
title: 'Reddit',
icon: embedRedditIcon,
+ description: __( 'Embed a Reddit thread' ),
},
patterns: [ /^https?:\/\/(www\.)?reddit\.com\/.+/i ],
},
@@ -226,6 +249,7 @@ export const others = [
settings: {
title: 'ReverbNation',
icon: embedAudioIcon,
+ description: __( 'Embed ReverbNation content' ),
},
patterns: [ /^https?:\/\/(www\.)?reverbnation\.com\/.+/i ],
},
@@ -234,6 +258,7 @@ export const others = [
settings: {
title: 'Screencast',
icon: embedVideoIcon,
+ description: __( 'Embed Screencast content' ),
},
patterns: [ /^https?:\/\/(www\.)?screencast\.com\/.+/i ],
},
@@ -242,6 +267,7 @@ export const others = [
settings: {
title: 'Scribd',
icon: embedContentIcon,
+ description: __( 'Embed Scribd content' ),
},
patterns: [ /^https?:\/\/(www\.)?scribd\.com\/.+/i ],
},
@@ -250,6 +276,7 @@ export const others = [
settings: {
title: 'Slideshare',
icon: embedContentIcon,
+ description: __( 'Embed Slideshare content' ),
},
patterns: [ /^https?:\/\/(.+?\.)?slideshare\.net\/.+/i ],
},
@@ -258,6 +285,7 @@ export const others = [
settings: {
title: 'SmugMug',
icon: embedPhotoIcon,
+ description: __( 'Embed SmugMug content' ),
},
patterns: [ /^https?:\/\/(www\.)?smugmug\.com\/.+/i ],
},
@@ -287,6 +315,7 @@ export const others = [
} );
},
} ],
+ description: __( 'Embed Speaker Deck content' ),
},
patterns: [ /^https?:\/\/(www\.)?speakerdeck\.com\/.+/i ],
},
@@ -295,6 +324,7 @@ export const others = [
settings: {
title: 'TED',
icon: embedVideoIcon,
+ description: __( 'Embed a TED video' ),
},
patterns: [ /^https?:\/\/(www\.|embed\.)?ted\.com\/.+/i ],
},
@@ -303,6 +333,7 @@ export const others = [
settings: {
title: 'Tumblr',
icon: embedTumbrIcon,
+ description: __( 'Embed a Tumblr post' ),
},
patterns: [ /^https?:\/\/(www\.)?tumblr\.com\/.+/i ],
},
@@ -312,6 +343,7 @@ export const others = [
title: 'VideoPress',
icon: embedVideoIcon,
keywords: [ __( 'video' ) ],
+ description: __( 'Embed a VideoPress video' ),
},
patterns: [ /^https?:\/\/videopress\.com\/.+/i ],
},
@@ -320,6 +352,7 @@ export const others = [
settings: {
title: 'WordPress.tv',
icon: embedVideoIcon,
+ description: __( 'Embed a WordPress.tv video' ),
},
patterns: [ /^https?:\/\/wordpress\.tv\/.+/i ],
},
diff --git a/packages/block-library/src/embed/index.js b/packages/block-library/src/embed/index.js
index 4331e331c555dd..7bf859a002373d 100644
--- a/packages/block-library/src/embed/index.js
+++ b/packages/block-library/src/embed/index.js
@@ -15,7 +15,7 @@ export const name = 'core/embed';
export const settings = getEmbedBlockSettings( {
title: _x( 'Embed', 'block title' ),
- description: __( 'The Embed block allows you to easily add videos, images, tweets, audio, and other content to your post or page.' ),
+ description: __( 'Embed videos, images, tweets, audio, and other content from external sources.' ),
icon: embedContentIcon,
// Unknown embeds should not be responsive by default.
responsive: false,
diff --git a/packages/block-library/src/file/index.js b/packages/block-library/src/file/index.js
index 51252abf205803..7f26a4abc025e4 100644
--- a/packages/block-library/src/file/index.js
+++ b/packages/block-library/src/file/index.js
@@ -23,7 +23,7 @@ export const name = 'core/file';
export const settings = {
title: __( 'File' ),
- description: __( 'Add a link to a file that visitors can download.' ),
+ description: __( 'Add a link to a downloadable file.' ),
icon: ,
diff --git a/packages/block-library/src/gallery/index.js b/packages/block-library/src/gallery/index.js
index 1b24c82461ab66..e347c806d2af37 100644
--- a/packages/block-library/src/gallery/index.js
+++ b/packages/block-library/src/gallery/index.js
@@ -69,7 +69,7 @@ export const name = 'core/gallery';
export const settings = {
title: __( 'Gallery' ),
- description: __( 'Display multiple images in an elegantly organized tiled layout.' ),
+ description: __( 'Display multiple images in a rich gallery.' ),
icon: ,
category: 'common',
keywords: [ __( 'images' ), __( 'photos' ) ],
diff --git a/packages/block-library/src/heading/index.js b/packages/block-library/src/heading/index.js
index 4772818bd238d4..6f98add18effe0 100644
--- a/packages/block-library/src/heading/index.js
+++ b/packages/block-library/src/heading/index.js
@@ -64,7 +64,7 @@ export const name = 'core/heading';
export const settings = {
title: __( 'Heading' ),
- description: __( 'Introduce topics and help visitors (and search engines!) understand how your content is organized.' ),
+ description: __( 'Introduce new sections and organize content to help visitors (and search engines) understand the structure of your content.' ),
icon: ,
diff --git a/packages/block-library/src/html/index.js b/packages/block-library/src/html/index.js
index 5243df8962f49c..c7307aa53e9b49 100644
--- a/packages/block-library/src/html/index.js
+++ b/packages/block-library/src/html/index.js
@@ -13,7 +13,7 @@ export const name = 'core/html';
export const settings = {
title: __( 'Custom HTML' ),
- description: __( 'Add your own HTML (and view it right here as you edit!).' ),
+ description: __( 'Add custom HTML code and preview it as you edit.' ),
icon: ,
diff --git a/packages/block-library/src/image/index.js b/packages/block-library/src/image/index.js
index 00ea17c772cfe8..83a022388d35dc 100644
--- a/packages/block-library/src/image/index.js
+++ b/packages/block-library/src/image/index.js
@@ -103,7 +103,7 @@ const schema = {
export const settings = {
title: __( 'Image' ),
- description: __( 'They’re worth 1,000 words! Insert a single image.' ),
+ description: __( 'Insert an image to make a visual statement.' ),
icon: ,
diff --git a/packages/block-library/src/latest-comments/index.js b/packages/block-library/src/latest-comments/index.js
index 61310f4ebda144..d7420744d0011d 100644
--- a/packages/block-library/src/latest-comments/index.js
+++ b/packages/block-library/src/latest-comments/index.js
@@ -14,7 +14,7 @@ export const name = 'core/latest-comments';
export const settings = {
title: __( 'Latest Comments' ),
- description: __( 'Show a list of your site’s most recent comments.' ),
+ description: __( 'Display a list of your most recent comments.' ),
icon: ,
diff --git a/packages/block-library/src/list/index.js b/packages/block-library/src/list/index.js
index c5683dc5fe82db..e7c38a543f56b3 100644
--- a/packages/block-library/src/list/index.js
+++ b/packages/block-library/src/list/index.js
@@ -60,7 +60,7 @@ export const name = 'core/list';
export const settings = {
title: __( 'List' ),
- description: __( 'Numbers, bullets, up to you. Add a list of items.' ),
+ description: __( 'Create a bulleted or numbered list.' ),
icon: ,
category: 'common',
keywords: [ __( 'bullet list' ), __( 'ordered list' ), __( 'numbered list' ) ],
diff --git a/packages/block-library/src/media-text/index.js b/packages/block-library/src/media-text/index.js
index 14a3a3281f0936..d82d86228091e2 100644
--- a/packages/block-library/src/media-text/index.js
+++ b/packages/block-library/src/media-text/index.js
@@ -26,6 +26,8 @@ export const name = 'core/media-text';
export const settings = {
title: __( 'Media & Text' ),
+ description: __( 'Set media and words side-by-side media for a richer layout.' ),
+
icon: ,
category: 'layout',
diff --git a/packages/block-library/src/more/index.js b/packages/block-library/src/more/index.js
index a42f1025723c0d..9334ed2e0941c2 100644
--- a/packages/block-library/src/more/index.js
+++ b/packages/block-library/src/more/index.js
@@ -25,7 +25,7 @@ export const name = 'core/more';
export const settings = {
title: _x( 'More', 'block name' ),
- description: __( 'Want to show only part of this post on your blog’s home page? Insert a "More" block where you want the split.' ),
+ description: __( 'Want to show only an excerpt of this post on your home page? Use this block to define where you want the separation.' ),
icon: ,
diff --git a/packages/block-library/src/nextpage/index.js b/packages/block-library/src/nextpage/index.js
index f5d35e4eb3073c..02114bd72c0788 100644
--- a/packages/block-library/src/nextpage/index.js
+++ b/packages/block-library/src/nextpage/index.js
@@ -11,7 +11,7 @@ export const name = 'core/nextpage';
export const settings = {
title: __( 'Page break' ),
- description: __( 'This block allows you to set break points on your post. Visitors of your blog are then presented with content split into multiple pages.' ),
+ description: __( 'Separate your content into a multi-page experience.' ),
icon: ,
diff --git a/packages/block-library/src/paragraph/index.js b/packages/block-library/src/paragraph/index.js
index 6465c43e48391c..e315f551cc9f3f 100644
--- a/packages/block-library/src/paragraph/index.js
+++ b/packages/block-library/src/paragraph/index.js
@@ -77,7 +77,7 @@ export const name = 'core/paragraph';
export const settings = {
title: __( 'Paragraph' ),
- description: __( 'Add some basic text.' ),
+ description: __( 'Start with the building block of all narrative.' ),
icon: ,
diff --git a/packages/block-library/src/pullquote/index.js b/packages/block-library/src/pullquote/index.js
index 3693fc2db2190e..1dc6126394678a 100644
--- a/packages/block-library/src/pullquote/index.js
+++ b/packages/block-library/src/pullquote/index.js
@@ -57,7 +57,7 @@ export const settings = {
title: __( 'Pullquote' ),
- description: __( 'Highlight a quote from your post or page by displaying it as a graphic element.' ),
+ description: __( 'Give special visual emphasis to a quote from your text.' ),
icon: ,
diff --git a/packages/block-library/src/quote/index.js b/packages/block-library/src/quote/index.js
index bd226c2bc9a7f3..a87b0dba274534 100644
--- a/packages/block-library/src/quote/index.js
+++ b/packages/block-library/src/quote/index.js
@@ -40,7 +40,7 @@ export const name = 'core/quote';
export const settings = {
title: __( 'Quote' ),
- description: __( 'Maybe someone else said it better -- add some quoted text.' ),
+ description: __( 'Give quoted text visual emphasis. "In quoting others, we cite ourselves." — Julio Cortázar' ),
icon: ,
category: 'common',
keywords: [ __( 'blockquote' ) ],
diff --git a/packages/block-library/src/separator/index.js b/packages/block-library/src/separator/index.js
index a85576d97b3ad1..f077d6533413de 100644
--- a/packages/block-library/src/separator/index.js
+++ b/packages/block-library/src/separator/index.js
@@ -10,7 +10,7 @@ export const name = 'core/separator';
export const settings = {
title: __( 'Separator' ),
- description: __( 'Insert a horizontal line where you want to create a break between ideas.' ),
+ description: __( 'Create a break between ideas or sections with a horizontal separator.' ),
icon: ,
diff --git a/packages/block-library/src/shortcode/index.js b/packages/block-library/src/shortcode/index.js
index e5fd517798d6cc..06464c52e7082e 100644
--- a/packages/block-library/src/shortcode/index.js
+++ b/packages/block-library/src/shortcode/index.js
@@ -13,7 +13,7 @@ export const name = 'core/shortcode';
export const settings = {
title: __( 'Shortcode' ),
- description: __( 'Add a shortcode -- a WordPress-specific snippet of code written between square brackets.' ),
+ description: __( 'Insert additional custom elements with a WordPress shortcode.' ),
icon: ,
diff --git a/packages/block-library/src/spacer/index.js b/packages/block-library/src/spacer/index.js
index 6b66cf4eadd533..12f362b40f623e 100644
--- a/packages/block-library/src/spacer/index.js
+++ b/packages/block-library/src/spacer/index.js
@@ -17,7 +17,7 @@ export const name = 'core/spacer';
export const settings = {
title: __( 'Spacer' ),
- description: __( 'Add an element with empty space and custom height.' ),
+ description: __( 'Add white space between blocks and customize its height.' ),
icon: ,
diff --git a/packages/block-library/src/table/index.js b/packages/block-library/src/table/index.js
index a3fb8d91590f8b..aff5c7ca5be8cb 100644
--- a/packages/block-library/src/table/index.js
+++ b/packages/block-library/src/table/index.js
@@ -77,7 +77,7 @@ export const name = 'core/table';
export const settings = {
title: __( 'Table' ),
- description: __( 'Insert a table -- perfect for sharing charts and data.' ),
+ description: __( 'Insert a table — perfect for sharing charts and data.' ),
icon: ,
category: 'formatting',
diff --git a/packages/block-library/src/verse/index.js b/packages/block-library/src/verse/index.js
index c5072386553c80..e70bc44550735c 100644
--- a/packages/block-library/src/verse/index.js
+++ b/packages/block-library/src/verse/index.js
@@ -16,7 +16,7 @@ export const name = 'core/verse';
export const settings = {
title: __( 'Verse' ),
- description: __( 'A block for haiku? Why not? Blocks for all the things! (See what we did here?)' ),
+ description: __( 'Insert poetry. Use special spacing formats. Or quote song lyrics.' ),
icon: ,
diff --git a/packages/block-library/src/video/index.js b/packages/block-library/src/video/index.js
index 8947158c467814..ac20d15dcaa336 100644
--- a/packages/block-library/src/video/index.js
+++ b/packages/block-library/src/video/index.js
@@ -17,7 +17,7 @@ export const name = 'core/video';
export const settings = {
title: __( 'Video' ),
- description: __( 'Embed a video file and a simple video player.' ),
+ description: __( 'Embed a video from your media library or upload a new one.' ),
icon: ,
From 646c531dda07411ad204c523c45431daba03d9af Mon Sep 17 00:00:00 2001
From: Riad Benguella
Date: Tue, 30 Oct 2018 13:46:31 +0100
Subject: [PATCH 13/98] Fix multiselecting blocks using shift + arrow (#11237)
* Fix multiselecting blocks using shift + arrow
* Test multiple shift + arrows selections
* Fix end2end test failures
---
.../editor/src/components/block-list/block.js | 12 +++-
.../src/components/block-toolbar/index.js | 70 +++++--------------
test/e2e/specs/multi-block-selection.test.js | 42 ++++++++++-
3 files changed, 71 insertions(+), 53 deletions(-)
diff --git a/packages/editor/src/components/block-list/block.js b/packages/editor/src/components/block-list/block.js
index 30b3806aad5bd0..1213d1c424453e 100644
--- a/packages/editor/src/components/block-list/block.js
+++ b/packages/editor/src/components/block-list/block.js
@@ -93,6 +93,12 @@ export class BlockListBlock extends Component {
if ( this.props.isSelected && ! prevProps.isSelected ) {
this.focusTabbable( true );
}
+
+ // When triggering a multi-selection,
+ // move the focus to the wrapper of the first selected block.
+ if ( this.props.isFirstMultiSelected && ! prevProps.isFirstMultiSelected ) {
+ this.wrapperNode.focus();
+ }
}
setBlockListRef( node ) {
@@ -314,7 +320,11 @@ export class BlockListBlock extends Component {
deleteOrInsertAfterWrapper( event ) {
const { keyCode, target } = event;
- if ( target !== this.wrapperNode || this.props.isLocked ) {
+ if (
+ ! this.props.isSelected ||
+ target !== this.wrapperNode ||
+ this.props.isLocked
+ ) {
return;
}
diff --git a/packages/editor/src/components/block-toolbar/index.js b/packages/editor/src/components/block-toolbar/index.js
index de34bf2747ec25..511ed1d7da0536 100644
--- a/packages/editor/src/components/block-toolbar/index.js
+++ b/packages/editor/src/components/block-toolbar/index.js
@@ -2,8 +2,7 @@
* WordPress Dependencies
*/
import { withSelect } from '@wordpress/data';
-import { Component, createRef, Fragment } from '@wordpress/element';
-import { focus } from '@wordpress/dom';
+import { Fragment } from '@wordpress/element';
/**
* Internal Dependencies
@@ -14,63 +13,32 @@ import BlockControls from '../block-controls';
import BlockFormatControls from '../block-format-controls';
import BlockSettingsMenu from '../block-settings-menu';
-class BlockToolbar extends Component {
- constructor() {
- super( ...arguments );
- this.container = createRef();
+function BlockToolbar( { blockClientIds, isValid, mode } ) {
+ if ( blockClientIds.length === 0 ) {
+ return null;
}
- componentDidMount() {
- if ( this.props.blockClientIds.length > 1 ) {
- this.focusContainer();
- }
- }
-
- componentDidUpdate( prevProps ) {
- if (
- prevProps.blockClientIds.length <= 1 &&
- this.props.blockClientIds.length > 1
- ) {
- this.focusContainer();
- }
- }
-
- focusContainer() {
- const tabbables = focus.tabbable.find( this.container.current );
- if ( tabbables.length ) {
- tabbables[ 0 ].focus();
- }
- }
-
- render() {
- const { blockClientIds, isValid, mode } = this.props;
-
- if ( blockClientIds.length === 0 ) {
- return null;
- }
-
- if ( blockClientIds.length > 1 ) {
- return (
-