Skip to content

Commit

Permalink
RichText: fix format placeholder (#11102)
Browse files Browse the repository at this point in the history
* Fix format placeholder

* Unduplicate logic
  • Loading branch information
ellatrix authored Oct 30, 2018
1 parent 35c02bc commit 393f5ba
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 14 deletions.
18 changes: 11 additions & 7 deletions packages/rich-text/src/apply-format.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@
* External dependencies
*/

import { find, reject } from 'lodash';
import { find } from 'lodash';

/**
* Internal dependencies
*/

import { normaliseFormats } from './normalise-formats';
import { insert } from './insert';
import { ZERO_WIDTH_NO_BREAK_SPACE } from './special-characters';

/**
* Apply a format object to a Rich Text value from the given `startIndex` to the
Expand Down Expand Up @@ -56,10 +54,16 @@ export function applyFormat(
const previousFormat = newFormats[ startIndex - 1 ] || [];
const hasType = find( previousFormat, { type: format.type } );

return insert( { formats, text, start, end }, {
formats: hasType ? [ reject( previousFormat, { type: format.type } ) ] : [ [ ...previousFormat, format ] ],
text: ZERO_WIDTH_NO_BREAK_SPACE,
} );
return {
formats,
text,
start,
end,
formatPlaceholder: {
index: startIndex,
format: hasType ? undefined : format,
},
};
}
} else {
for ( let index = startIndex; index < endIndex; index++ ) {
Expand Down
12 changes: 6 additions & 6 deletions packages/rich-text/src/test/apply-format.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import deepFreeze from 'deep-freeze';
*/

import { applyFormat } from '../apply-format';
import { ZERO_WIDTH_NO_BREAK_SPACE } from '../special-characters';
import { getSparseArrayLength } from './helpers';

describe( 'applyFormat', () => {
Expand Down Expand Up @@ -61,16 +60,17 @@ describe( 'applyFormat', () => {
end: 0,
};
const expected = {
formats: [ [ a2 ], , , , , [ a ], [ a ], [ a ], , , , , , , ],
text: `${ ZERO_WIDTH_NO_BREAK_SPACE }one two three`,
start: 1,
end: 1,
...record,
formatPlaceholder: {
format: a2,
index: 0,
},
};
const result = applyFormat( deepFreeze( record ), a2 );

expect( result ).toEqual( expected );
expect( result ).not.toBe( record );
expect( getSparseArrayLength( result.formats ) ).toBe( 4 );
expect( getSparseArrayLength( result.formats ) ).toBe( 3 );
} );

it( 'should apply format on existing format if selection is collapsed', () => {
Expand Down
1 change: 1 addition & 0 deletions packages/rich-text/src/to-dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ export function toDom( {
onEndIndex( body, pointer ) {
endPath = createPathToNode( pointer, body, [ pointer.nodeValue.length ] );
},
isEditableTree: true,
} );

if ( createLinePadding ) {
Expand Down
24 changes: 23 additions & 1 deletion packages/rich-text/src/to-tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { getFormatType } from './get-format-type';
import {
LINE_SEPARATOR,
OBJECT_REPLACEMENT_CHARACTER,
ZERO_WIDTH_NO_BREAK_SPACE,
} from './special-characters';

function fromFormat( { type, attributes, object } ) {
Expand Down Expand Up @@ -55,8 +56,9 @@ export function toTree( {
appendText,
onStartIndex,
onEndIndex,
isEditableTree,
} ) {
const { formats, text, start, end } = value;
const { formats, text, start, end, formatPlaceholder } = value;
const formatsLength = formats.length + 1;
const tree = createEmpty();
const multilineFormat = { type: multilineTag };
Expand All @@ -73,6 +75,22 @@ export function toTree( {
append( tree, '' );
}

function setFormatPlaceholder( pointer, index ) {
if ( isEditableTree && formatPlaceholder && formatPlaceholder.index === index ) {
const parent = getParent( pointer );

if ( formatPlaceholder.format === undefined ) {
pointer = getParent( parent );
} else {
pointer = append( parent, fromFormat( formatPlaceholder.format ) );
}

pointer = append( pointer, ZERO_WIDTH_NO_BREAK_SPACE );
}

return pointer;
}

for ( let i = 0; i < formatsLength; i++ ) {
const character = text.charAt( i );
let characterFormats = formats[ i ];
Expand Down Expand Up @@ -146,6 +164,8 @@ export function toTree( {
continue;
}

pointer = setFormatPlaceholder( pointer, 0 );

// If there is selection at 0, handle it before characters are inserted.
if ( i === 0 ) {
if ( onStartIndex && start === 0 ) {
Expand All @@ -169,6 +189,8 @@ export function toTree( {
}
}

pointer = setFormatPlaceholder( pointer, i + 1 );

if ( onStartIndex && start === i + 1 ) {
onStartIndex( tree, pointer );
}
Expand Down
6 changes: 6 additions & 0 deletions test/e2e/specs/__snapshots__/rich-text.test.js.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`RichText should apply formatting when selection is collapsed 1`] = `
"<!-- wp:paragraph -->
<p>Some <strong>bold</strong>.</p>
<!-- /wp:paragraph -->"
`;

exports[`RichText should apply formatting with access shortcut 1`] = `
"<!-- wp:paragraph -->
<p><del>test</del></p>
Expand Down
13 changes: 13 additions & 0 deletions test/e2e/specs/rich-text.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,17 @@ describe( 'RichText', () => {

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

it( 'should apply formatting when selection is collapsed', async () => {
await clickBlockAppender();
await page.keyboard.type( 'Some ' );
// All following characters should now be bold.
await pressWithModifier( META_KEY, 'b' );
await page.keyboard.type( 'bold' );
// All following characters should no longer be bold.
await pressWithModifier( META_KEY, 'b' );
await page.keyboard.type( '.' );

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

0 comments on commit 393f5ba

Please sign in to comment.