Skip to content

Commit

Permalink
Make it possible to undo prefix transforms (WordPress#11497)
Browse files Browse the repository at this point in the history
* Make it possible to undo prefix transforms

* Same for backticks

* Tests: Refactor tests to stop using META_KEY
  • Loading branch information
ellatrix authored and youknowriad committed Nov 19, 2018
1 parent 25b834e commit bad6c5a
Show file tree
Hide file tree
Showing 18 changed files with 251 additions and 68 deletions.
57 changes: 47 additions & 10 deletions docs/block-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,18 +124,18 @@ Block styles can be used to provide alternative styles to block. It works by add
// Register block styles.
styles: [
// Mark style as default.
{
name: 'default',
label: __( 'Rounded' ),
isDefault: true
{
name: 'default',
label: __( 'Rounded' ),
isDefault: true
},
{
name: 'outline',
label: __( 'Outline' )
{
name: 'outline',
label: __( 'Outline' )
},
{
name: 'squared',
label: __( 'Squared' )
{
name: 'squared',
label: __( 'Squared' )
},
],
```
Expand Down Expand Up @@ -413,6 +413,43 @@ transforms: {
```
{% end %}

A prefix transform is a transform that will be applied if the user prefixes some text in e.g. the paragraph block with a given pattern and a trailing space.

{% codetabs %}
{% ES5 %}
```js
transforms: {
from: [
{
type: 'prefix',
prefix: '?',
transform: function( content ) {
return createBlock( 'my-plugin/question', {
content,
} );
},
},
]
}
```
{% ESNext %}
```js
transforms: {
from: [
{
type: 'prefix',
prefix: '?',
transform( content ) {
return createBlock( 'my-plugin/question', {
content,
} );
},
},
]
}
```
{% end %}


#### parent (optional)

Expand Down
3 changes: 1 addition & 2 deletions packages/block-library/src/code/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ export const settings = {
transforms: {
from: [
{
type: 'pattern',
trigger: 'enter',
type: 'enter',
regExp: /^```$/,
transform: () => createBlock( 'core/code' ),
},
Expand Down
12 changes: 5 additions & 7 deletions packages/block-library/src/heading/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,18 +107,16 @@ export const settings = {
} );
},
},
{
type: 'pattern',
regExp: /^(#{2,6})\s/,
transform: ( { content, match } ) => {
const level = match[ 1 ].length;

...[ 2, 3, 4, 5, 6 ].map( ( level ) => ( {
type: 'prefix',
prefix: Array( level + 1 ).join( '#' ),
transform( content ) {
return createBlock( 'core/heading', {
level,
content,
} );
},
},
} ) ),
],
to: [
{
Expand Down
20 changes: 10 additions & 10 deletions packages/block-library/src/list/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,25 +110,25 @@ export const settings = {
} );
},
},
{
type: 'pattern',
regExp: /^[*-]\s/,
transform: ( { content } ) => {
...[ '*', '-' ].map( ( prefix ) => ( {
type: 'prefix',
prefix,
transform( content ) {
return createBlock( 'core/list', {
values: `<li>${ content }</li>`,
} );
},
},
{
type: 'pattern',
regExp: /^1[.)]\s/,
transform: ( { content } ) => {
} ) ),
...[ '1.', '1)' ].map( ( prefix ) => ( {
type: 'prefix',
prefix,
transform( content ) {
return createBlock( 'core/list', {
ordered: true,
values: `<li>${ content }</li>`,
} );
},
},
} ) ),
],
to: [
{
Expand Down
6 changes: 3 additions & 3 deletions packages/block-library/src/quote/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,9 @@ export const settings = {
} ),
},
{
type: 'pattern',
regExp: /^>\s/,
transform: ( { content } ) => {
type: 'prefix',
prefix: '>',
transform: ( content ) => {
return createBlock( 'core/quote', {
value: `<p>${ content }</p>`,
} );
Expand Down
3 changes: 1 addition & 2 deletions packages/block-library/src/separator/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ export const settings = {
transforms: {
from: [
{
type: 'pattern',
trigger: 'enter',
type: 'enter',
regExp: /^-{3,}$/,
transform: () => createBlock( 'core/separator' ),
},
Expand Down
8 changes: 4 additions & 4 deletions packages/editor/src/components/rich-text/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,12 @@ export class RichText extends Component {
this.savedContent = value;
this.patterns = getPatterns( {
onReplace,
multilineTag: this.multilineTag,
onCreateUndoLevel: this.onCreateUndoLevel,
valueToFormat: this.valueToFormat,
onChange: this.onChange,
} );
this.enterPatterns = getBlockTransforms( 'from' ).filter( ( { type, trigger } ) =>
type === 'pattern' && trigger === 'enter'
);
this.enterPatterns = getBlockTransforms( 'from' )
.filter( ( { type } ) => type === 'enter' );

this.state = {};

Expand Down
71 changes: 41 additions & 30 deletions packages/editor/src/components/rich-text/patterns.js
Original file line number Diff line number Diff line change
@@ -1,69 +1,80 @@
/**
* External dependencies
*/
import { filter } from 'lodash';

/**
* WordPress dependencies
*/
import { getBlockTransforms, findTransform } from '@wordpress/blocks';
import { remove, applyFormat, getTextContent } from '@wordpress/rich-text';

export function getPatterns( { onReplace, multiline, valueToFormat } ) {
const patterns = filter( getBlockTransforms( 'from' ), ( { type, trigger } ) => {
return type === 'pattern' && trigger === undefined;
} );
import {
remove,
applyFormat,
getTextContent,
getSelectionStart,
slice,
} from '@wordpress/rich-text';

export function getPatterns( { onReplace, valueToFormat, onCreateUndoLevel, onChange } ) {
const prefixTransforms = getBlockTransforms( 'from' )
.filter( ( { type } ) => type === 'prefix' );

return [
( record ) => {
if ( ! onReplace ) {
return record;
}

const start = getSelectionStart( record );
const text = getTextContent( record );
const transformation = findTransform( patterns, ( item ) => {
return item.regExp.test( text );
const characterBefore = text.slice( start - 1, start );

if ( ! /\s/.test( characterBefore ) ) {
return record;
}

const trimmedTextBefore = text.slice( 0, start ).trim();
const transformation = findTransform( prefixTransforms, ( { prefix } ) => {
return trimmedTextBefore === prefix;
} );

if ( ! transformation ) {
return record;
}

const result = text.match( transformation.regExp );

const block = transformation.transform( {
content: valueToFormat( remove( record, 0, result[ 0 ].length ) ),
match: result,
} );
const content = valueToFormat( slice( record, start, text.length ) );
const block = transformation.transform( content );

onCreateUndoLevel();
onReplace( [ block ] );

return record;
},
( record ) => {
if ( multiline ) {
const BACKTICK = '`';
const start = getSelectionStart( record );
const text = getTextContent( record );
const characterBefore = text.slice( start - 1, start );

// Quick check the text for the necessary character.
if ( characterBefore !== BACKTICK ) {
return record;
}

const text = getTextContent( record );
const textBefore = text.slice( 0, start - 1 );
const indexBefore = textBefore.lastIndexOf( BACKTICK );

// Quick check the text for the necessary character.
if ( text.indexOf( '`' ) === -1 ) {
if ( indexBefore === -1 ) {
return record;
}

const match = text.match( /`([^`]+)`/ );
const startIndex = indexBefore;
const endIndex = start - 2;

if ( ! match ) {
if ( startIndex === endIndex ) {
return record;
}

const start = match.index;
const end = start + match[ 1 ].length;
onChange( record );

record = remove( record, start, start + 1 );
record = remove( record, end, end + 1 );
record = applyFormat( record, { type: 'code' }, start, end );
record = remove( record, startIndex, startIndex + 1 );
record = remove( record, endIndex, endIndex + 1 );
record = applyFormat( record, { type: 'code' }, startIndex, endIndex );

return record;
},
Expand Down
12 changes: 12 additions & 0 deletions test/e2e/specs/__snapshots__/rich-text.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,15 @@ exports[`RichText should handle change in tag name gracefully 1`] = `
<h3></h3>
<!-- /wp:heading -->"
`;

exports[`RichText should transform backtick to code 1`] = `
"<!-- wp:paragraph -->
<p>A <code>backtick</code></p>
<!-- /wp:paragraph -->"
`;

exports[`RichText should transform backtick to code 2`] = `
"<!-- wp:paragraph -->
<p>A \`backtick\`</p>
<!-- /wp:paragraph -->"
`;
7 changes: 7 additions & 0 deletions test/e2e/specs/blocks/__snapshots__/code.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Code can be created by three backticks and enter 1`] = `
"<!-- wp:code -->
<pre class=\\"wp-block-code\\"><code>&lt;?php</code></pre>
<!-- /wp:code -->"
`;
13 changes: 13 additions & 0 deletions test/e2e/specs/blocks/__snapshots__/heading.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Separator can be created by prefixing existing content with number signs and a space 1`] = `
"<!-- wp:heading {\\"level\\":4} -->
<h4>4</h4>
<!-- /wp:heading -->"
`;

exports[`Separator can be created by prefixing number sign and a space 1`] = `
"<!-- wp:heading {\\"level\\":3} -->
<h3>3</h3>
<!-- /wp:heading -->"
`;
6 changes: 6 additions & 0 deletions test/e2e/specs/blocks/__snapshots__/list.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ exports[`List can be created by using an asterisk at the start of a paragraph bl
<!-- /wp:list -->"
`;
exports[`List can undo asterisk transform 1`] = `
"<!-- wp:paragraph -->
<p>1.</p>
<!-- /wp:paragraph -->"
`;
exports[`List should create paragraph on split at end and merge back with content 1`] = `
"<!-- wp:list -->
<ul><li>one</li></ul>
Expand Down
7 changes: 7 additions & 0 deletions test/e2e/specs/blocks/__snapshots__/separator.test.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Separator can be created by three dashes and enter 1`] = `
"<!-- wp:separator -->
<hr class=\\"wp-block-separator\\"/>
<!-- /wp:separator -->"
`;
23 changes: 23 additions & 0 deletions test/e2e/specs/blocks/code.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* Internal dependencies
*/
import {
clickBlockAppender,
getEditedPostContent,
newPost,
} from '../../support/utils';

describe( 'Code', () => {
beforeEach( async () => {
await newPost();
} );

it( 'can be created by three backticks and enter', async () => {
await clickBlockAppender();
await page.keyboard.type( '```' );
await page.keyboard.press( 'Enter' );
await page.keyboard.type( '<?php' );

expect( await getEditedPostContent() ).toMatchSnapshot();
} );
} );
Loading

0 comments on commit bad6c5a

Please sign in to comment.