From f3dde5a41b454d5e77c703081cbc8af24cff94a4 Mon Sep 17 00:00:00 2001 From: iseulde Date: Tue, 19 Feb 2019 15:18:47 +0100 Subject: [PATCH 01/18] Add objects and lineFormats --- .../src/components/rich-text/index.js | 1 - packages/rich-text/README.md | 1 - packages/rich-text/src/apply-format.js | 15 +-- packages/rich-text/src/change-list-type.js | 20 ++- packages/rich-text/src/concat.js | 24 +++- packages/rich-text/src/create.js | 120 +++++++----------- .../rich-text/src/get-last-child-index.js | 8 +- .../rich-text/src/get-parent-line-index.js | 6 +- packages/rich-text/src/indent-list-items.js | 24 ++-- .../rich-text/src/insert-line-separator.js | 10 +- packages/rich-text/src/insert-object.js | 7 +- packages/rich-text/src/insert.js | 10 +- packages/rich-text/src/join.js | 6 +- packages/rich-text/src/normalise-formats.js | 8 +- packages/rich-text/src/outdent-list-items.js | 14 +- packages/rich-text/src/remove-format.js | 10 +- packages/rich-text/src/replace.js | 9 +- packages/rich-text/src/slice.js | 12 +- packages/rich-text/src/split.js | 10 +- .../src/test/__snapshots__/to-dom.js.snap | 11 +- .../rich-text/src/test/change-list-type.js | 27 ++-- packages/rich-text/src/test/concat.js | 6 + packages/rich-text/src/test/create.js | 2 + .../src/test/get-last-child-index.js | 12 +- .../src/test/get-parent-line-index.js | 8 +- packages/rich-text/src/test/helpers/index.js | 94 ++++++++++++-- .../rich-text/src/test/indent-list-items.js | 84 ++++++------ .../src/test/insert-line-separator.js | 28 +++- packages/rich-text/src/test/insert-object.js | 9 +- packages/rich-text/src/test/insert.js | 12 ++ packages/rich-text/src/test/join.js | 10 +- .../rich-text/src/test/outdent-list-items.js | 76 +++++------ packages/rich-text/src/test/replace.js | 14 ++ packages/rich-text/src/test/slice.js | 8 ++ packages/rich-text/src/test/split.js | 44 +++++++ packages/rich-text/src/to-dom.js | 4 - packages/rich-text/src/to-html-string.js | 5 +- packages/rich-text/src/to-tree.js | 55 ++++---- packages/rich-text/src/toggle-format.js | 5 +- 39 files changed, 507 insertions(+), 322 deletions(-) diff --git a/packages/block-editor/src/components/rich-text/index.js b/packages/block-editor/src/components/rich-text/index.js index 5b91674b9a6733..be8d4c6c1ecc5d 100644 --- a/packages/block-editor/src/components/rich-text/index.js +++ b/packages/block-editor/src/components/rich-text/index.js @@ -984,7 +984,6 @@ export class RichText extends Component { return toHTMLString( { value, multilineTag: this.multilineTag, - multilineWrapperTags: this.multilineWrapperTags, } ); } diff --git a/packages/rich-text/README.md b/packages/rich-text/README.md index 0ac85d85b640d1..9e187b88f8f79f 100644 --- a/packages/rich-text/README.md +++ b/packages/rich-text/README.md @@ -332,7 +332,6 @@ provided, text separated by a line separator will be wrapped in it. - **$1** `Object`: Named argements. - **$1.value** `Object`: Rich text value. - **$1.multilineTag** `[string]`: Multiline tag. -- **$1.multilineWrapperTags** `[Array]`: Tags where lines can be found if nesting is possible. **Returns** diff --git a/packages/rich-text/src/apply-format.js b/packages/rich-text/src/apply-format.js index 8134cd8d742a99..a3d7b3835b952e 100644 --- a/packages/rich-text/src/apply-format.js +++ b/packages/rich-text/src/apply-format.js @@ -23,12 +23,12 @@ import { normaliseFormats } from './normalise-formats'; * @return {Object} A new value with the format applied. */ export function applyFormat( - { formats, text, start, end }, + value, format, - startIndex = start, - endIndex = end + startIndex = value.start, + endIndex = value.end ) { - const newFormats = formats.slice( 0 ); + const newFormats = value.formats.slice( 0 ); // The selection is collapsed. if ( startIndex === endIndex ) { @@ -55,10 +55,7 @@ export function applyFormat( const hasType = find( previousFormat, { type: format.type } ); return { - formats, - text, - start, - end, + ...value, formatPlaceholder: hasType ? undefined : format, }; } @@ -68,7 +65,7 @@ export function applyFormat( } } - return normaliseFormats( { formats: newFormats, text, start, end } ); + return normaliseFormats( { ...value, formats: newFormats } ); } function applyFormats( formats, index, format ) { diff --git a/packages/rich-text/src/change-list-type.js b/packages/rich-text/src/change-list-type.js index 1dfc0406573636..ace21d12c78dda 100644 --- a/packages/rich-text/src/change-list-type.js +++ b/packages/rich-text/src/change-list-type.js @@ -20,12 +20,12 @@ import { getParentLineIndex } from './get-parent-line-index'; * @return {Object} The changed value. */ export function changeListType( value, newFormat ) { - const { text, formats, start, end } = value; + const { text, lineFormats, start, end } = value; const startingLineIndex = getLineIndex( value, start ); - const startLineFormats = formats[ startingLineIndex ] || []; - const endLineFormats = formats[ getLineIndex( value, end ) ] || []; + const startLineFormats = lineFormats[ startingLineIndex ] || []; + const endLineFormats = lineFormats[ getLineIndex( value, end ) ] || []; const startIndex = getParentLineIndex( value, startingLineIndex ); - const newFormats = formats.slice( 0 ); + const newLineFormats = lineFormats.slice(); const startCount = startLineFormats.length - 1; const endCount = endLineFormats.length - 1; @@ -36,16 +36,16 @@ export function changeListType( value, newFormat ) { continue; } - if ( ( newFormats[ index ] || [] ).length <= startCount ) { + if ( ( newLineFormats[ index ] || [] ).length <= startCount ) { break; } - if ( ! newFormats[ index ] ) { + if ( ! newLineFormats[ index ] ) { continue; } changed = true; - newFormats[ index ] = newFormats[ index ].map( ( format, i ) => { + newLineFormats[ index ] = newLineFormats[ index ].map( ( format, i ) => { return i < startCount || i > endCount ? format : newFormat; } ); } @@ -55,9 +55,7 @@ export function changeListType( value, newFormat ) { } return normaliseFormats( { - text, - formats: newFormats, - start, - end, + ...value, + lineFormats: newLineFormats, } ); } diff --git a/packages/rich-text/src/concat.js b/packages/rich-text/src/concat.js index 9f14091f9b1c87..04b3533145614a 100644 --- a/packages/rich-text/src/concat.js +++ b/packages/rich-text/src/concat.js @@ -3,6 +3,25 @@ */ import { normaliseFormats } from './normalise-formats'; +import { create } from './create'; + +/** + * Concats a pair of rich text values. Not that this mutates `a` and does NOT + * normalise formats! + * + * @param {Object} a Value to mutate. + * @param {Object} b Value to add read from. + * + * @return {Object} `a`, mutated. + */ +export function concatPair( a, b ) { + a.formats = a.formats.concat( b.formats ); + a.lineFormats = a.lineFormats.concat( b.lineFormats ); + a.objects = a.objects.concat( b.objects ); + a.text += b.text; + + return a; +} /** * Combine all Rich Text values into one. This is similar to @@ -13,8 +32,5 @@ import { normaliseFormats } from './normalise-formats'; * @return {Object} A new value combining all given records. */ export function concat( ...values ) { - return normaliseFormats( values.reduce( ( accumlator, { formats, text } ) => ( { - text: accumlator.text + text, - formats: accumlator.formats.concat( formats ), - } ) ) ); + return normaliseFormats( values.reduce( concatPair, create() ) ); } diff --git a/packages/rich-text/src/create.js b/packages/rich-text/src/create.js index d1c1e47d4df064..d2d33df48125f7 100644 --- a/packages/rich-text/src/create.js +++ b/packages/rich-text/src/create.js @@ -10,6 +10,7 @@ import { select } from '@wordpress/data'; import { isEmpty } from './is-empty'; import { isFormatEqual } from './is-format-equal'; import { createElement } from './create-element'; +import { concatPair } from './concat'; import { LINE_SEPARATOR, OBJECT_REPLACEMENT_CHARACTER, @@ -22,7 +23,12 @@ import { const { TEXT_NODE, ELEMENT_NODE } = window.Node; function createEmptyValue() { - return { formats: [], text: '' }; + return { + formats: [], + lineFormats: [], + objects: [], + text: '', + }; } function simpleFindKey( object, value ) { @@ -120,6 +126,8 @@ export function create( { if ( typeof text === 'string' && text.length > 0 ) { return { formats: Array( text.length ), + lineFormats: Array( text.length ), + objects: Array( text.length ), text, }; } @@ -291,10 +299,12 @@ function createFromElement( { const text = filterString( node.nodeValue ); range = filterRange( node, range, filterString ); accumulateSelection( accumulator, node, range, { text } ); - accumulator.text += text; // Create a sparse array of the same length as `text`, in which // formats can be added. accumulator.formats.length += text.length; + accumulator.lineFormats.length += text.length; + accumulator.objects.length += text.length; + accumulator.text += text; continue; } @@ -312,8 +322,7 @@ function createFromElement( { if ( type === 'br' ) { accumulateSelection( accumulator, node, range, createEmptyValue() ); - accumulator.text += '\n'; - accumulator.formats.length += 1; + concatPair( accumulator, create( { text: '\n' } ) ); continue; } @@ -323,22 +332,10 @@ function createFromElement( { type, attributes: getAttributes( { element: node } ), } ); - - let format; - - if ( newFormat ) { - // Reuse the last format if it's equal. - if ( isFormatEqual( newFormat, lastFormat ) ) { - format = lastFormat; - } else { - format = newFormat; - } - } - - let value; + const format = isFormatEqual( newFormat, lastFormat ) ? lastFormat : newFormat; if ( multilineWrapperTags && multilineWrapperTags.indexOf( type ) !== -1 ) { - value = createFromMultilineElement( { + const value = createFromMultilineElement( { element: node, range, multilineTag, @@ -346,65 +343,43 @@ function createFromElement( { currentWrapperTags: [ ...currentWrapperTags, format ], isEditableTree, } ); - format = undefined; - } else { - value = createFromElement( { - element: node, - range, - multilineTag, - multilineWrapperTags, - isEditableTree, - } ); + + accumulateSelection( accumulator, node, range, value ); + concatPair( accumulator, value ); + continue; } - const text = value.text; - const start = accumulator.text.length; + const value = createFromElement( { + element: node, + range, + multilineTag, + multilineWrapperTags, + isEditableTree, + } ); accumulateSelection( accumulator, node, range, value ); // Don't apply the element as formatting if it has no content. - if ( isEmpty( value ) && format && ! format.attributes ) { + if ( isEmpty( value ) && ! format.attributes ) { continue; } - const { formats } = accumulator; - - if ( format && format.attributes && text.length === 0 ) { - format.object = true; - accumulator.text += OBJECT_REPLACEMENT_CHARACTER; - - if ( formats[ start ] ) { - formats[ start ].unshift( format ); - } else { - formats[ start ] = [ format ]; - } - } else { - accumulator.text += text; - accumulator.formats.length += text.length; - - let i = value.formats.length; - - // Optimise for speed. - while ( i-- ) { - const formatIndex = start + i; - - if ( format ) { - if ( formats[ formatIndex ] ) { - formats[ formatIndex ].push( format ); - } else { - formats[ formatIndex ] = [ format ]; - } - } - - if ( value.formats[ i ] ) { - if ( formats[ formatIndex ] ) { - formats[ formatIndex ].push( ...value.formats[ i ] ); - } else { - formats[ formatIndex ] = value.formats[ i ]; - } - } - } + if ( format.attributes && value.text.length === 0 ) { + concatPair( accumulator, { + formats: [ , ], + lineFormats: [ , ], + objects: [ format ], + text: OBJECT_REPLACEMENT_CHARACTER, + } ); + continue; } + + concatPair( accumulator, { + ...value, + formats: Array.from( value.formats, ( formats ) => + formats ? [ format, ...formats ] : [ format ] + ), + } ); } return accumulator; @@ -459,17 +434,18 @@ function createFromMultilineElement( { isEditableTree, } ); - // Multiline value text should be separated by a double line break. + // Multiline value text should be separated by a line separator. if ( index !== 0 || currentWrapperTags.length > 0 ) { const formats = currentWrapperTags.length > 0 ? [ currentWrapperTags ] : [ , ]; - accumulator.formats = accumulator.formats.concat( formats ); + + accumulator.formats.length += 1; + accumulator.lineFormats = accumulator.lineFormats.concat( formats ); + accumulator.objects.length += 1; accumulator.text += LINE_SEPARATOR; } accumulateSelection( accumulator, node, range, value ); - - accumulator.formats = accumulator.formats.concat( value.formats ); - accumulator.text += value.text; + concatPair( accumulator, value ); } return accumulator; diff --git a/packages/rich-text/src/get-last-child-index.js b/packages/rich-text/src/get-last-child-index.js index 976051b10c0a3e..11699c92f9ca18 100644 --- a/packages/rich-text/src/get-last-child-index.js +++ b/packages/rich-text/src/get-last-child-index.js @@ -12,8 +12,8 @@ import { LINE_SEPARATOR } from './special-characters'; * * @return {Array} The index of the last child. */ -export function getLastChildIndex( { text, formats }, lineIndex ) { - const lineFormats = formats[ lineIndex ] || []; +export function getLastChildIndex( { text, lineFormats }, lineIndex ) { + const currentLineFormats = lineFormats[ lineIndex ] || []; // Use the given line index in case there are no next children. let childIndex = lineIndex; @@ -24,11 +24,11 @@ export function getLastChildIndex( { text, formats }, lineIndex ) { continue; } - const formatsAtIndex = formats[ index ] || []; + const formatsAtIndex = lineFormats[ index ] || []; // If the amout of formats is equal or more, store it, then return the // last one if the amount of formats is less. - if ( formatsAtIndex.length >= lineFormats.length ) { + if ( formatsAtIndex.length >= currentLineFormats.length ) { childIndex = index; } else { return childIndex; diff --git a/packages/rich-text/src/get-parent-line-index.js b/packages/rich-text/src/get-parent-line-index.js index bd3f72de965196..3151bc355cd0ff 100644 --- a/packages/rich-text/src/get-parent-line-index.js +++ b/packages/rich-text/src/get-parent-line-index.js @@ -14,8 +14,8 @@ import { LINE_SEPARATOR } from './special-characters'; * * @return {Array} The parent list line index. */ -export function getParentLineIndex( { text, formats }, lineIndex ) { - const startFormats = formats[ lineIndex ] || []; +export function getParentLineIndex( { text, lineFormats }, lineIndex ) { + const startFormats = lineFormats[ lineIndex ] || []; let index = lineIndex; @@ -24,7 +24,7 @@ export function getParentLineIndex( { text, formats }, lineIndex ) { continue; } - const formatsAtIndex = formats[ index ] || []; + const formatsAtIndex = lineFormats[ index ] || []; if ( formatsAtIndex.length === startFormats.length - 1 ) { return index; diff --git a/packages/rich-text/src/indent-list-items.js b/packages/rich-text/src/indent-list-items.js index 1a61bd7db15360..84ca90513e157e 100644 --- a/packages/rich-text/src/indent-list-items.js +++ b/packages/rich-text/src/indent-list-items.js @@ -14,8 +14,8 @@ import { getLineIndex } from './get-line-index'; * * @return {boolean} The line index. */ -function getTargetLevelLineIndex( { text, formats }, lineIndex ) { - const startFormats = formats[ lineIndex ] || []; +function getTargetLevelLineIndex( { text, lineFormats }, lineIndex ) { + const startFormats = lineFormats[ lineIndex ] || []; let index = lineIndex; @@ -24,7 +24,7 @@ function getTargetLevelLineIndex( { text, formats }, lineIndex ) { continue; } - const formatsAtIndex = formats[ index ] || []; + const formatsAtIndex = lineFormats[ index ] || []; // Return the first line index that is one level higher. If the level is // lower or equal, there is no result. @@ -52,10 +52,10 @@ export function indentListItems( value, rootFormat ) { return value; } - const { text, formats, start, end } = value; + const { text, lineFormats, end } = value; const previousLineIndex = getLineIndex( value, lineIndex ); - const formatsAtLineIndex = formats[ lineIndex ] || []; - const formatsAtPreviousLineIndex = formats[ previousLineIndex ] || []; + const formatsAtLineIndex = lineFormats[ lineIndex ] || []; + const formatsAtPreviousLineIndex = lineFormats[ previousLineIndex ] || []; // The the indentation of the current line is greater than previous line, // then the line cannot be furter indented. @@ -63,7 +63,7 @@ export function indentListItems( value, rootFormat ) { return value; } - const newFormats = formats.slice(); + const newFormats = lineFormats.slice(); const targetLevelLineIndex = getTargetLevelLineIndex( value, lineIndex ); for ( let index = lineIndex; index < end; index++ ) { @@ -74,12 +74,12 @@ export function indentListItems( value, rootFormat ) { // Get the previous list, and if there's a child list, take over the // formats. If not, duplicate the last level and create a new level. if ( targetLevelLineIndex ) { - const targetFormats = formats[ targetLevelLineIndex ] || []; + const targetFormats = lineFormats[ targetLevelLineIndex ] || []; newFormats[ index ] = targetFormats.concat( ( newFormats[ index ] || [] ).slice( targetFormats.length - 1 ) ); } else { - const targetFormats = formats[ previousLineIndex ] || []; + const targetFormats = lineFormats[ previousLineIndex ] || []; const lastformat = targetFormats[ targetFormats.length - 1 ] || rootFormat; newFormats[ index ] = targetFormats.concat( @@ -90,9 +90,7 @@ export function indentListItems( value, rootFormat ) { } return normaliseFormats( { - text, - formats: newFormats, - start, - end, + ...value, + lineFormats: newFormats, } ); } diff --git a/packages/rich-text/src/insert-line-separator.js b/packages/rich-text/src/insert-line-separator.js index e273c9eea9ac48..ee1fc9554ea969 100644 --- a/packages/rich-text/src/insert-line-separator.js +++ b/packages/rich-text/src/insert-line-separator.js @@ -24,15 +24,17 @@ export function insertLineSeparator( ) { const beforeText = getTextContent( value ).slice( 0, startIndex ); const previousLineSeparatorIndex = beforeText.lastIndexOf( LINE_SEPARATOR ); - const previousLineSeparatorFormats = value.formats[ previousLineSeparatorIndex ]; - let formats = [ , ]; + const previousLineSeparatorFormats = value.lineFormats[ previousLineSeparatorIndex ]; + let lineFormats = [ , ]; if ( previousLineSeparatorFormats ) { - formats = [ previousLineSeparatorFormats ]; + lineFormats = [ previousLineSeparatorFormats ]; } const valueToInsert = { - formats, + formats: [ , ], + lineFormats, + objects: [ , ], text: LINE_SEPARATOR, }; diff --git a/packages/rich-text/src/insert-object.js b/packages/rich-text/src/insert-object.js index fcdfc6f897c2dd..a8c22cb93d81ff 100644 --- a/packages/rich-text/src/insert-object.js +++ b/packages/rich-text/src/insert-object.js @@ -25,11 +25,10 @@ export function insertObject( endIndex ) { const valueToInsert = { + formats: [ , ], + lineFormats: [ , ], + objects: [ formatToInsert ], text: OBJECT_REPLACEMENT_CHARACTER, - formats: [ [ { - ...formatToInsert, - object: true, - } ] ], }; return insert( value, valueToInsert, startIndex, endIndex ); diff --git a/packages/rich-text/src/insert.js b/packages/rich-text/src/insert.js index cf46305240fb70..a7cd8554587a49 100644 --- a/packages/rich-text/src/insert.js +++ b/packages/rich-text/src/insert.js @@ -19,11 +19,13 @@ import { normaliseFormats } from './normalise-formats'; * @return {Object} A new value with the value inserted. */ export function insert( - { formats, text, start, end }, + value, valueToInsert, - startIndex = start, - endIndex = end + startIndex = value.start, + endIndex = value.end ) { + const { formats, lineFormats, objects, text } = value; + if ( typeof valueToInsert === 'string' ) { valueToInsert = create( { text: valueToInsert } ); } @@ -32,6 +34,8 @@ export function insert( return normaliseFormats( { formats: formats.slice( 0, startIndex ).concat( valueToInsert.formats, formats.slice( endIndex ) ), + lineFormats: lineFormats.slice( 0, startIndex ).concat( valueToInsert.lineFormats, lineFormats.slice( endIndex ) ), + objects: objects.slice( 0, startIndex ).concat( valueToInsert.objects, objects.slice( endIndex ) ), text: text.slice( 0, startIndex ) + valueToInsert.text + text.slice( endIndex ), start: index, end: index, diff --git a/packages/rich-text/src/join.js b/packages/rich-text/src/join.js index 7784b5962ca536..bdc24b59f3c41f 100644 --- a/packages/rich-text/src/join.js +++ b/packages/rich-text/src/join.js @@ -20,8 +20,10 @@ export function join( values, separator = '' ) { separator = create( { text: separator } ); } - return normaliseFormats( values.reduce( ( accumlator, { formats, text } ) => ( { - text: accumlator.text + separator.text + text, + return normaliseFormats( values.reduce( ( accumlator, { formats, lineFormats, objects, text } ) => ( { formats: accumlator.formats.concat( separator.formats, formats ), + lineFormats: accumlator.lineFormats.concat( separator.lineFormats, lineFormats ), + objects: accumlator.objects.concat( separator.objects, objects ), + text: accumlator.text + separator.text + text, } ) ) ); } diff --git a/packages/rich-text/src/normalise-formats.js b/packages/rich-text/src/normalise-formats.js index 533df66933886a..72c04f818f9a4f 100644 --- a/packages/rich-text/src/normalise-formats.js +++ b/packages/rich-text/src/normalise-formats.js @@ -13,13 +13,13 @@ import { isFormatEqual } from './is-format-equal'; /** * Normalises formats: ensures subsequent equal formats have the same reference. * - * @param {Object} value Value to normalise formats of. + * @param {Object} value Value to normalise formats of. * * @return {Object} New value with normalised formats. */ -export function normaliseFormats( { formats, text, start, end } ) { +export function normaliseFormats( value ) { const refs = []; - const newFormats = formats.map( ( formatsAtIndex ) => + const newFormats = value.formats.map( ( formatsAtIndex ) => formatsAtIndex.map( ( format ) => { const equalRef = find( refs, ( ref ) => isFormatEqual( ref, format ) @@ -35,5 +35,5 @@ export function normaliseFormats( { formats, text, start, end } ) { } ) ); - return { formats: newFormats, text, start, end }; + return { ...value, formats: newFormats }; } diff --git a/packages/rich-text/src/outdent-list-items.js b/packages/rich-text/src/outdent-list-items.js index 3a493caa9b03a8..f78c3cdff38e11 100644 --- a/packages/rich-text/src/outdent-list-items.js +++ b/packages/rich-text/src/outdent-list-items.js @@ -16,16 +16,16 @@ import { getLastChildIndex } from './get-last-child-index'; * @return {Object} The changed value. */ export function outdentListItems( value ) { - const { text, formats, start, end } = value; + const { text, lineFormats, start, end } = value; const startingLineIndex = getLineIndex( value, start ); // Return early if the starting line index cannot be further outdented. - if ( formats[ startingLineIndex ] === undefined ) { + if ( lineFormats[ startingLineIndex ] === undefined ) { return value; } - const newFormats = formats.slice( 0 ); - const parentFormats = formats[ getParentLineIndex( value, startingLineIndex ) ] || []; + const newFormats = lineFormats.slice( 0 ); + const parentFormats = lineFormats[ getParentLineIndex( value, startingLineIndex ) ] || []; const endingLineIndex = getLineIndex( value, end ); const lastChildIndex = getLastChildIndex( value, endingLineIndex ); @@ -52,9 +52,7 @@ export function outdentListItems( value ) { } return normaliseFormats( { - text, - formats: newFormats, - start, - end, + ...value, + lineFormats: newFormats, } ); } diff --git a/packages/rich-text/src/remove-format.js b/packages/rich-text/src/remove-format.js index be1c92ace7fd43..0e75efee2fd636 100644 --- a/packages/rich-text/src/remove-format.js +++ b/packages/rich-text/src/remove-format.js @@ -23,12 +23,12 @@ import { normaliseFormats } from './normalise-formats'; * @return {Object} A new value with the format applied. */ export function removeFormat( - { formats, text, start, end }, + value, formatType, - startIndex = start, - endIndex = end + startIndex = value.start, + endIndex = value.end ) { - const newFormats = formats.slice( 0 ); + const newFormats = value.formats.slice( 0 ); // If the selection is collapsed, expand start and end to the edges of the // format. @@ -54,7 +54,7 @@ export function removeFormat( } } - return normaliseFormats( { formats: newFormats, text, start, end } ); + return normaliseFormats( { ...value, formats: newFormats } ); } function filterFormats( formats, index, formatType ) { diff --git a/packages/rich-text/src/replace.js b/packages/rich-text/src/replace.js index 110fc186bd6386..788b476e42f962 100644 --- a/packages/rich-text/src/replace.js +++ b/packages/rich-text/src/replace.js @@ -20,11 +20,12 @@ import { normaliseFormats } from './normalise-formats'; * * @return {Object} A new value with replacements applied. */ -export function replace( { formats, text, start, end }, pattern, replacement ) { +export function replace( { formats, lineFormats, objects, text, start, end }, pattern, replacement ) { text = text.replace( pattern, ( match, ...rest ) => { const offset = rest[ rest.length - 2 ]; let newText = replacement; let newFormats; + let newObjects; if ( typeof newText === 'function' ) { newText = replacement( match, ...rest ); @@ -32,9 +33,11 @@ export function replace( { formats, text, start, end }, pattern, replacement ) { if ( typeof newText === 'object' ) { newFormats = newText.formats; + newObjects = newText.objects; newText = newText.text; } else { newFormats = Array( newText.length ); + newObjects = Array( newText.length ); if ( formats[ offset ] ) { newFormats = newFormats.fill( formats[ offset ] ); @@ -42,6 +45,8 @@ export function replace( { formats, text, start, end }, pattern, replacement ) { } formats = formats.slice( 0, offset ).concat( newFormats, formats.slice( offset + match.length ) ); + lineFormats = lineFormats.slice( 0, offset ).concat( Array( newText.length ), lineFormats.slice( offset + match.length ) ); + objects = objects.slice( 0, offset ).concat( newObjects, objects.slice( offset + match.length ) ); if ( start ) { start = end = offset + newText.length; @@ -50,5 +55,5 @@ export function replace( { formats, text, start, end }, pattern, replacement ) { return newText; } ); - return normaliseFormats( { formats, text, start, end } ); + return normaliseFormats( { formats, lineFormats, objects, text, start, end } ); } diff --git a/packages/rich-text/src/slice.js b/packages/rich-text/src/slice.js index bb4313dd61309a..25323946a7264d 100644 --- a/packages/rich-text/src/slice.js +++ b/packages/rich-text/src/slice.js @@ -10,16 +10,20 @@ * @return {Object} A new extracted value. */ export function slice( - { formats, text, start, end }, - startIndex = start, - endIndex = end + value, + startIndex = value.start, + endIndex = value.end ) { + const { formats, lineFormats, objects, text } = value; + if ( startIndex === undefined || endIndex === undefined ) { - return { formats, text }; + return { ...value }; } return { formats: formats.slice( startIndex, endIndex ), + lineFormats: lineFormats.slice( startIndex, endIndex ), + objects: objects.slice( startIndex, endIndex ), text: text.slice( startIndex, endIndex ), }; } diff --git a/packages/rich-text/src/split.js b/packages/rich-text/src/split.js index a300c3ccbcca4a..030cbe5ad74cb0 100644 --- a/packages/rich-text/src/split.js +++ b/packages/rich-text/src/split.js @@ -15,7 +15,7 @@ import { replace } from './replace'; * * @return {Array} An array of new values. */ -export function split( { formats, text, start, end }, string ) { +export function split( { formats, lineFormats, objects, text, start, end }, string ) { if ( typeof string !== 'string' ) { return splitAtSelection( ...arguments ); } @@ -26,6 +26,8 @@ export function split( { formats, text, start, end }, string ) { const startIndex = nextStart; const value = { formats: formats.slice( startIndex, startIndex + substring.length ), + lineFormats: lineFormats.slice( startIndex, startIndex + substring.length ), + objects: objects.slice( startIndex, startIndex + substring.length ), text: substring, }; @@ -50,16 +52,20 @@ export function split( { formats, text, start, end }, string ) { } function splitAtSelection( - { formats, text, start, end }, + { formats, lineFormats, objects, text, start, end }, startIndex = start, endIndex = end ) { const before = { formats: formats.slice( 0, startIndex ), + lineFormats: lineFormats.slice( 0, startIndex ), + objects: objects.slice( 0, startIndex ), text: text.slice( 0, startIndex ), }; const after = { formats: formats.slice( endIndex ), + lineFormats: lineFormats.slice( endIndex ), + objects: objects.slice( endIndex ), text: text.slice( endIndex ), start: 0, end: 0, diff --git a/packages/rich-text/src/test/__snapshots__/to-dom.js.snap b/packages/rich-text/src/test/__snapshots__/to-dom.js.snap index a68cdab1c911eb..ae6c0db2d55750 100644 --- a/packages/rich-text/src/test/__snapshots__/to-dom.js.snap +++ b/packages/rich-text/src/test/__snapshots__/to-dom.js.snap @@ -36,6 +36,7 @@ exports[`recordToDom should create a value with formatting with attributes 1`] = exports[`recordToDom should create a value with image object 1`] = ` + @@ -45,7 +46,10 @@ exports[`recordToDom should create a value with image object 1`] = ` exports[`recordToDom should create a value with image object and formatting 1`] = ` - + + @@ -57,7 +61,10 @@ exports[`recordToDom should create a value with image object and formatting 1`] exports[`recordToDom should create a value with image object and text after 1`] = ` - + + diff --git a/packages/rich-text/src/test/change-list-type.js b/packages/rich-text/src/test/change-list-type.js index 3817c66ba7977e..bfbf209f029be0 100644 --- a/packages/rich-text/src/test/change-list-type.js +++ b/packages/rich-text/src/test/change-list-type.js @@ -17,7 +17,8 @@ describe( 'changeListType', () => { it( 'should only change list type if list item is indented', () => { const record = { - formats: [ , ], + formats: [], + lineFormats: [ , ], text: '1', start: 1, end: 1, @@ -26,27 +27,26 @@ describe( 'changeListType', () => { expect( result ).toEqual( record ); expect( result ).toBe( record ); - expect( getSparseArrayLength( result.formats ) ).toBe( 0 ); + expect( getSparseArrayLength( result.lineFormats ) ).toBe( 0 ); } ); it( 'should change list type', () => { const record = { - formats: [ , [ ul ] ], + formats: [], + lineFormats: [ , [ ul ] ], text: `1${ LINE_SEPARATOR }`, start: 2, end: 2, }; const expected = { - formats: [ , [ ol ] ], - text: `1${ LINE_SEPARATOR }`, - start: 2, - end: 2, + ...record, + lineFormats: [ , [ ol ] ], }; const result = changeListType( deepFreeze( record ), ol ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.formats ) ).toBe( 1 ); + expect( getSparseArrayLength( result.lineFormats ) ).toBe( 1 ); } ); it( 'should outdent with multiple lines selected', () => { @@ -54,21 +54,20 @@ describe( 'changeListType', () => { const text = `a${ LINE_SEPARATOR }1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }i${ LINE_SEPARATOR }3${ LINE_SEPARATOR }4${ LINE_SEPARATOR }b`; const record = { - formats: [ , [ ul ], , [ ul ], , [ ul, ul ], , [ ul ], , [ ul ], , , , [ ul ], , ], + formats: [], + lineFormats: [ , [ ul ], , [ ul ], , [ ul, ul ], , [ ul ], , [ ul ], , , , [ ul ], , ], text, start: 4, end: 9, }; const expected = { - formats: [ , [ ol ], , [ ol ], , [ ol, ul ], , [ ol ], , [ ol ], , , , [ ul ], , ], - text, - start: 4, - end: 9, + ...record, + lineFormats: [ , [ ol ], , [ ol ], , [ ol, ul ], , [ ol ], , [ ol ], , , , [ ul ], , ], }; const result = changeListType( deepFreeze( record ), ol ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.formats ) ).toBe( 6 ); + expect( getSparseArrayLength( result.lineFormats ) ).toBe( 6 ); } ); } ); diff --git a/packages/rich-text/src/test/concat.js b/packages/rich-text/src/test/concat.js index 9ac2aa2dc75569..5ca3e4b3225137 100644 --- a/packages/rich-text/src/test/concat.js +++ b/packages/rich-text/src/test/concat.js @@ -16,14 +16,20 @@ describe( 'concat', () => { it( 'should merge records', () => { const one = { formats: [ , , [ em ] ], + lineFormats: [ , , , ], + objects: [ , , , ], text: 'one', }; const two = { formats: [ [ em ], , , ], + lineFormats: [ , , , ], + objects: [ , , , ], text: 'two', }; const three = { formats: [ , , [ em ], [ em ], , , ], + lineFormats: [ , , , , , , ], + objects: [ , , , , , , ], text: 'onetwo', }; diff --git a/packages/rich-text/src/test/create.js b/packages/rich-text/src/test/create.js index 5128c55273d78a..795c66e109df2f 100644 --- a/packages/rich-text/src/test/create.js +++ b/packages/rich-text/src/test/create.js @@ -81,6 +81,8 @@ describe( 'create', () => { expect( value ).toEqual( { formats: [ [ em ], [ em ], [ em, strong ], [ em, strong ] ], + lineFormats: [ , , , , ], + objects: [ , , , , ], text: 'test', } ); diff --git a/packages/rich-text/src/test/get-last-child-index.js b/packages/rich-text/src/test/get-last-child-index.js index 55c881d356555c..e3b4a8b2ac6719 100644 --- a/packages/rich-text/src/test/get-last-child-index.js +++ b/packages/rich-text/src/test/get-last-child-index.js @@ -10,40 +10,40 @@ import deepFreeze from 'deep-freeze'; import { getLastChildIndex } from '../get-last-child-index'; import { LINE_SEPARATOR } from '../special-characters'; -describe( 'outdentListItems', () => { +describe( 'getLastChildIndex', () => { const ul = { type: 'ul' }; it( 'should return undefined if there is only one line', () => { expect( getLastChildIndex( deepFreeze( { - formats: [ , ], + lineFormats: [ , ], text: '1', } ), undefined ) ).toBe( undefined ); } ); it( 'should return the last line if no line is indented', () => { expect( getLastChildIndex( deepFreeze( { - formats: [ , ], + lineFormats: [ , ], text: `1${ LINE_SEPARATOR }`, } ), undefined ) ).toBe( 1 ); } ); it( 'should return the last child index', () => { expect( getLastChildIndex( deepFreeze( { - formats: [ , [ ul ], , [ ul ], , ], + lineFormats: [ , [ ul ], , [ ul ], , ], text: `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`, } ), undefined ) ).toBe( 3 ); } ); it( 'should return the last child index by sibling', () => { expect( getLastChildIndex( deepFreeze( { - formats: [ , [ ul ], , [ ul ], , ], + lineFormats: [ , [ ul ], , [ ul ], , ], text: `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`, } ), 1 ) ).toBe( 3 ); } ); it( 'should return the last child index (with further lower indented items)', () => { expect( getLastChildIndex( deepFreeze( { - formats: [ , [ ul ], , , , ], + lineFormats: [ , [ ul ], , , , ], text: `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`, } ), 1 ) ).toBe( 1 ); } ); diff --git a/packages/rich-text/src/test/get-parent-line-index.js b/packages/rich-text/src/test/get-parent-line-index.js index 4e6a75ffd0a6e6..00bf7b70af4c0d 100644 --- a/packages/rich-text/src/test/get-parent-line-index.js +++ b/packages/rich-text/src/test/get-parent-line-index.js @@ -15,28 +15,28 @@ describe( 'getParentLineIndex', () => { it( 'should return undefined if there is only one line', () => { expect( getParentLineIndex( deepFreeze( { - formats: [ , ], + lineFormats: [ , ], text: '1', } ), undefined ) ).toBe( undefined ); } ); it( 'should return undefined if the list is part of the first root list child', () => { expect( getParentLineIndex( deepFreeze( { - formats: [ , ], + lineFormats: [ , ], text: `1${ LINE_SEPARATOR }2`, } ), 2 ) ).toBe( undefined ); } ); it( 'should return the line index of the parent list (1)', () => { expect( getParentLineIndex( deepFreeze( { - formats: [ , , , [ ul ], , ], + lineFormats: [ , , , [ ul ], , ], text: `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`, } ), 3 ) ).toBe( 1 ); } ); it( 'should return the line index of the parent list (2)', () => { expect( getParentLineIndex( deepFreeze( { - formats: [ , [ ul ], , [ ul, ul ], , [ ul ], , ], + lineFormats: [ , [ ul ], , [ ul, ul ], , [ ul ], , ], text: `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3${ LINE_SEPARATOR }4`, } ), 5 ) ).toBe( undefined ); } ); diff --git a/packages/rich-text/src/test/helpers/index.js b/packages/rich-text/src/test/helpers/index.js index 859e7e3acefc2e..e80b053a4f8015 100644 --- a/packages/rich-text/src/test/helpers/index.js +++ b/packages/rich-text/src/test/helpers/index.js @@ -4,7 +4,7 @@ export function getSparseArrayLength( array ) { const em = { type: 'em' }; const strong = { type: 'strong' }; -const img = { type: 'img', attributes: { src: '' }, object: true }; +const img = { type: 'img', attributes: { src: '' } }; const a = { type: 'a', attributes: { href: '#' } }; const ul = { type: 'ul' }; const ol = { type: 'ol' }; @@ -25,6 +25,8 @@ export const spec = [ start: 0, end: 0, formats: [], + lineFormats: [], + objects: [], text: '', }, }, @@ -43,6 +45,8 @@ export const spec = [ start: 0, end: 1, formats: [ , ], + lineFormats: [ , ], + objects: [ , ], text: ' ', }, }, @@ -61,6 +65,8 @@ export const spec = [ start: 5, end: 5, formats: [ , , , , , , , , , , ], + lineFormats: [ , , , , , , , , , , ], + objects: [ , , , , , , , , , , ], text: 'test\u00a0 test', }, }, @@ -79,6 +85,8 @@ export const spec = [ start: 0, end: 0, formats: [], + lineFormats: [], + objects: [], text: '', }, }, @@ -97,6 +105,8 @@ export const spec = [ start: 0, end: 4, formats: [ , , , , ], + lineFormats: [ , , , , ], + objects: [ , , , , ], text: 'test', }, }, @@ -115,6 +125,8 @@ export const spec = [ start: 0, end: 2, formats: [ , , ], + lineFormats: [ , , ], + objects: [ , , ], text: '🍒', }, }, @@ -133,6 +145,8 @@ export const spec = [ start: 0, end: 2, formats: [ [ em ], [ em ] ], + lineFormats: [ , , ], + objects: [ , , ], text: '🍒', }, }, @@ -151,6 +165,8 @@ export const spec = [ start: 0, end: 4, formats: [ [ em ], [ em ], [ em ], [ em ] ], + lineFormats: [ , , , , ], + objects: [ , , , , ], text: 'test', }, }, @@ -169,6 +185,8 @@ export const spec = [ start: 0, end: 4, formats: [ [ em, strong ], [ em, strong ], [ em, strong ], [ em, strong ] ], + lineFormats: [ , , , , ], + objects: [ , , , , ], text: 'test', }, }, @@ -187,6 +205,8 @@ export const spec = [ start: 0, end: 2, formats: [ [ em ], [ em ], [ em ], [ em ] ], + lineFormats: [ , , , , ], + objects: [ , , , , ], text: 'test', }, }, @@ -205,6 +225,8 @@ export const spec = [ start: 0, end: 4, formats: [ [ a ], [ a ], [ a ], [ a ] ], + lineFormats: [ , , , , ], + objects: [ , , , , ], text: 'test', }, }, @@ -217,12 +239,14 @@ export const spec = [ endOffset: 1, endContainer: element, } ), - startPath: [ 1, 0 ], - endPath: [ 1, 0 ], + startPath: [ 0, 0 ], + endPath: [ 0, 0 ], record: { start: 0, end: 0, - formats: [ [ img ] ], + formats: [ , ], + lineFormats: [ , ], + objects: [ img ], text: '\ufffc', }, }, @@ -235,12 +259,14 @@ export const spec = [ endOffset: 1, endContainer: element.querySelector( 'img' ), } ), - startPath: [ 0, 1, 0 ], - endPath: [ 0, 1, 0 ], + startPath: [ 0, 0, 0 ], + endPath: [ 0, 2, 0 ], record: { start: 0, end: 1, - formats: [ [ em, img ] ], + formats: [ [ em ] ], + lineFormats: [ , ], + objects: [ img ], text: '\ufffc', }, }, @@ -258,7 +284,9 @@ export const spec = [ record: { start: 0, end: 5, - formats: [ , , [ em ], [ em ], [ em, img ] ], + formats: [ , , [ em ], [ em ], [ em ] ], + lineFormats: [ , , , , , ], + objects: [ , , , , img ], text: 'test\ufffc', }, }, @@ -271,12 +299,14 @@ export const spec = [ endOffset: 2, endContainer: element, } ), - startPath: [ 0, 1, 0 ], + startPath: [ 0, 0, 0 ], endPath: [ 1, 2 ], record: { start: 0, end: 5, - formats: [ [ em, img ], [ em ], [ em ], , , ], + formats: [ [ em ], [ em ], [ em ], , , ], + lineFormats: [ , , , , , ], + objects: [ img, , , , , ], text: '\ufffctest', }, }, @@ -295,6 +325,8 @@ export const spec = [ start: 0, end: 0, formats: [ , ], + lineFormats: [ , ], + objects: [ , ], text: '\n', }, }, @@ -313,6 +345,8 @@ export const spec = [ start: 2, end: 3, formats: [ , , , , , ], + lineFormats: [ , , , , , ], + objects: [ , , , , , ], text: 'te\nst', }, }, @@ -331,6 +365,8 @@ export const spec = [ start: 0, end: 1, formats: [ [ em ] ], + lineFormats: [ , ], + objects: [ , ], text: '\n', }, }, @@ -347,6 +383,8 @@ export const spec = [ endPath: [ 4, 0 ], record: { formats: [ , , , , ], + lineFormats: [ , , , , ], + objects: [ , , , , ], text: 'a\n\nb', start: 2, end: 3, @@ -365,6 +403,8 @@ export const spec = [ endPath: [ 2, 0 ], record: { formats: [ , , , , ], + lineFormats: [ , , , , ], + objects: [ , , , , ], text: 'a\n\nb', start: 2, end: 2, @@ -386,6 +426,8 @@ export const spec = [ start: 0, end: 0, formats: [], + lineFormats: [], + objects: [], text: '', }, }, @@ -405,6 +447,8 @@ export const spec = [ start: 1, end: 4, formats: [ , , , , , , , ], + lineFormats: [ , , , , , , , ], + objects: [ , , , , , , , ], text: 'one\u2028two', }, }, @@ -424,7 +468,9 @@ export const spec = [ record: { start: 0, end: 9, - formats: [ , , , [ ul ], , [ ul ], , [ ul, ol ], , [ ul, ol ], , , , , , , , ], + formats: [ , , , , , , , , , , , , , , , , , ], + lineFormats: [ , , , [ ul ], , [ ul ], , [ ul, ol ], , [ ul, ol ], , , , , , , , ], + objects: [ , , , , , , , , , , , , , , , , , ], text: 'one\u2028a\u2028b\u20281\u20282\u2028three', }, }, @@ -445,6 +491,8 @@ export const spec = [ start: 0, end: 0, formats: [], + lineFormats: [], + objects: [], text: '', }, }, @@ -464,7 +512,9 @@ export const spec = [ record: { start: 1, end: 1, - formats: [ [ ul ] ], + formats: [ , ], + lineFormats: [ [ ul ] ], + objects: [ , ], text: '\u2028', }, }, @@ -485,6 +535,8 @@ export const spec = [ start: 1, end: 1, formats: [ , , ], + lineFormats: [ , , ], + objects: [ , , ], text: '\u2028\u2028', }, }, @@ -504,6 +556,8 @@ export const spec = [ start: 4, end: 4, formats: [ , , , , ], + lineFormats: [ , , , , ], + objects: [ , , , , ], text: 'one\u2028', }, }, @@ -524,6 +578,8 @@ export const spec = [ start: 3, end: 3, formats: [ , , , ], + lineFormats: [ , , , ], + objects: [ , , , ], text: 'one', }, }, @@ -534,6 +590,8 @@ export const spec = [ endPath: [], record: { formats: [ [ em ], [ em ], [ em ], [ em ], [ em ], [ em ], [ em ] ], + lineFormats: [ , , , , , , , ], + objects: [ , , , , , , , ], text: 'one\u2028two', }, }, @@ -552,6 +610,8 @@ export const spec = [ start: 0, end: 0, formats: [], + lineFormats: [], + objects: [], text: '', }, }, @@ -570,6 +630,8 @@ export const spec = [ start: 0, end: 4, formats: [ [ strong ], [ strong ], [ strong ], [ strong ] ], + lineFormats: [ , , , , ], + objects: [ , , , , ], text: 'test', }, }, @@ -592,6 +654,8 @@ export const specWithRegistration = [ attributes: {}, unregisteredAttributes: {}, } ] ], + lineFormats: [ , ], + objects: [ , ], text: 'a', }, }, @@ -613,6 +677,8 @@ export const specWithRegistration = [ class: 'test', }, } ] ], + lineFormats: [ , ], + objects: [ , ], text: 'a', }, }, @@ -634,6 +700,8 @@ export const specWithRegistration = [ class: 'custom-format', }, } ] ], + lineFormats: [ , ], + objects: [ , ], text: 'a', }, }, @@ -647,6 +715,8 @@ export const specWithRegistration = [ class: 'custom-format', }, } ] ], + lineFormats: [ , ], + objects: [ , ], text: 'a', }, }, diff --git a/packages/rich-text/src/test/indent-list-items.js b/packages/rich-text/src/test/indent-list-items.js index e7f631e5fa8f94..0e812c360d866c 100644 --- a/packages/rich-text/src/test/indent-list-items.js +++ b/packages/rich-text/src/test/indent-list-items.js @@ -18,6 +18,8 @@ describe( 'indentListItems', () => { it( 'should not indent only item', () => { const record = { formats: [ , ], + lineFormats: [ , ], + objects: [ , ], text: '1', start: 1, end: 1, @@ -26,7 +28,7 @@ describe( 'indentListItems', () => { expect( result ).toEqual( record ); expect( result ).toBe( record ); - expect( getSparseArrayLength( result.formats ) ).toBe( 0 ); + expect( getSparseArrayLength( result.lineFormats ) ).toBe( 0 ); } ); it( 'should indent', () => { @@ -34,26 +36,28 @@ describe( 'indentListItems', () => { const text = `1${ LINE_SEPARATOR }`; const record = { formats: [ , , ], + lineFormats: [ , , ], + objects: [ , , ], text, start: 2, end: 2, }; const expected = { - formats: [ , [ ul ] ], - text, - start: 2, - end: 2, + ...record, + lineFormats: [ , [ ul ] ], }; const result = indentListItems( deepFreeze( record ), ul ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.formats ) ).toBe( 1 ); + expect( getSparseArrayLength( result.lineFormats ) ).toBe( 1 ); } ); it( 'should not indent without target list', () => { const record = { - formats: [ , [ ul ] ], + formats: [ , , ], + lineFormats: [ , [ ul ] ], + objects: [ , , ], text: `1${ LINE_SEPARATOR }`, start: 2, end: 2, @@ -62,80 +66,82 @@ describe( 'indentListItems', () => { expect( result ).toEqual( record ); expect( result ).toBe( record ); - expect( getSparseArrayLength( result.formats ) ).toBe( 1 ); + expect( getSparseArrayLength( result.lineFormats ) ).toBe( 1 ); } ); it( 'should indent and merge with previous list', () => { // As we're testing list formats, the text should remain the same. const text = `1${ LINE_SEPARATOR }${ LINE_SEPARATOR }`; const record = { - formats: [ , [ ol ], , ], + formats: [ , , , ], + lineFormats: [ , [ ol ], , ], + objects: [ , , , ], text, start: 3, end: 3, }; const expected = { - formats: [ , [ ol ], [ ol ] ], - text, - start: 3, - end: 3, + ...record, + lineFormats: [ , [ ol ], [ ol ] ], }; const result = indentListItems( deepFreeze( record ), ul ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.formats ) ).toBe( 2 ); + expect( getSparseArrayLength( result.lineFormats ) ).toBe( 2 ); } ); it( 'should indent already indented item', () => { // As we're testing list formats, the text should remain the same. const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`; const record = { - formats: [ , [ ul ], , [ ul ], , ], + formats: [ , , , , , ], + lineFormats: [ , [ ul ], , [ ul ], , ], + objects: [ , , , , , ], text, start: 5, end: 5, }; const expected = { - formats: [ , [ ul ], , [ ul, ul ], , ], - text, - start: 5, - end: 5, + ...record, + lineFormats: [ , [ ul ], , [ ul, ul ], , ], }; const result = indentListItems( deepFreeze( record ), ul ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.formats ) ).toBe( 2 ); + expect( getSparseArrayLength( result.lineFormats ) ).toBe( 2 ); } ); it( 'should indent with multiple lines selected', () => { // As we're testing list formats, the text should remain the same. const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`; const record = { - formats: [ , , , [ ul ], , ], + formats: [ , , , , , ], + lineFormats: [ , , , [ ul ], , ], + objects: [ , , , , , ], text, start: 2, end: 5, }; const expected = { - formats: [ , [ ul ], , [ ul, ul ], , ], - text, - start: 2, - end: 5, + ...record, + lineFormats: [ , [ ul ], , [ ul, ul ], , ], }; const result = indentListItems( deepFreeze( record ), ul ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.formats ) ).toBe( 2 ); + expect( getSparseArrayLength( result.lineFormats ) ).toBe( 2 ); } ); it( 'should indent one level at a time', () => { // As we're testing list formats, the text should remain the same. const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3${ LINE_SEPARATOR }4`; const record = { - formats: [ , [ ul ], , [ ul, ul ], , , , ], + formats: Array( text.length ), + lineFormats: [ , [ ul ], , [ ul, ul ], , , , ], + objects: Array( text.length ), text, start: 6, end: 6, @@ -144,34 +150,28 @@ describe( 'indentListItems', () => { const result1 = indentListItems( deepFreeze( record ), ul ); expect( result1 ).not.toBe( record ); - expect( getSparseArrayLength( result1.formats ) ).toBe( 3 ); + expect( getSparseArrayLength( result1.lineFormats ) ).toBe( 3 ); expect( result1 ).toEqual( { - formats: [ , [ ul ], , [ ul, ul ], , [ ul ], , ], - text, - start: 6, - end: 6, + ...record, + lineFormats: [ , [ ul ], , [ ul, ul ], , [ ul ], , ], } ); const result2 = indentListItems( deepFreeze( result1 ), ul ); expect( result2 ).not.toBe( result1 ); - expect( getSparseArrayLength( result2.formats ) ).toBe( 3 ); + expect( getSparseArrayLength( result2.lineFormats ) ).toBe( 3 ); expect( result2 ).toEqual( { - formats: [ , [ ul ], , [ ul, ul ], , [ ul, ul ], , ], - text, - start: 6, - end: 6, + ...record, + lineFormats: [ , [ ul ], , [ ul, ul ], , [ ul, ul ], , ], } ); const result3 = indentListItems( deepFreeze( result2 ), ul ); expect( result3 ).not.toBe( result2 ); - expect( getSparseArrayLength( result3.formats ) ).toBe( 3 ); + expect( getSparseArrayLength( result3.lineFormats ) ).toBe( 3 ); expect( result3 ).toEqual( { - formats: [ , [ ul ], , [ ul, ul ], , [ ul, ul, ul ], , ], - text, - start: 6, - end: 6, + ...record, + lineFormats: [ , [ ul ], , [ ul, ul ], , [ ul, ul, ul ], , ], } ); } ); } ); diff --git a/packages/rich-text/src/test/insert-line-separator.js b/packages/rich-text/src/test/insert-line-separator.js index 398b0a2b8834f3..6512f8bbb3526f 100644 --- a/packages/rich-text/src/test/insert-line-separator.js +++ b/packages/rich-text/src/test/insert-line-separator.js @@ -17,12 +17,16 @@ describe( 'insertLineSeparator', () => { it( 'should insert line separator at end', () => { const value = { formats: [ , ], + lineFormats: [ , ], + objects: [ , ], text: '1', start: 1, end: 1, }; const expected = { formats: [ , , ], + lineFormats: [ , , ], + objects: [ , , ], text: `1${ LINE_SEPARATOR }`, start: 2, end: 2, @@ -31,18 +35,22 @@ describe( 'insertLineSeparator', () => { expect( result ).not.toBe( value ); expect( result ).toEqual( expected ); - expect( getSparseArrayLength( result.formats ) ).toBe( 0 ); + expect( getSparseArrayLength( result.lineFormats ) ).toBe( 0 ); } ); it( 'should insert line separator at start', () => { const value = { formats: [ , ], + lineFormats: [ , ], + objects: [ , ], text: '1', start: 0, end: 0, }; const expected = { formats: [ , , ], + lineFormats: [ , , ], + objects: [ , , ], text: `${ LINE_SEPARATOR }1`, start: 1, end: 1, @@ -51,18 +59,22 @@ describe( 'insertLineSeparator', () => { expect( result ).not.toBe( value ); expect( result ).toEqual( expected ); - expect( getSparseArrayLength( result.formats ) ).toBe( 0 ); + expect( getSparseArrayLength( result.lineFormats ) ).toBe( 0 ); } ); it( 'should insert line separator with previous line separator formats', () => { const value = { - formats: [ , , , [ ol ], , ], + formats: [ , , , , , ], + lineFormats: [ , , , [ ol ], , ], + objects: [ , , , , , ], text: `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }a`, start: 5, end: 5, }; const expected = { - formats: [ , , , [ ol ], , [ ol ] ], + formats: [ , , , , , , ], + lineFormats: [ , , , [ ol ], , [ ol ] ], + objects: [ , , , , , , ], text: `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }a${ LINE_SEPARATOR }`, start: 6, end: 6, @@ -71,18 +83,22 @@ describe( 'insertLineSeparator', () => { expect( result ).not.toBe( value ); expect( result ).toEqual( expected ); - expect( getSparseArrayLength( result.formats ) ).toBe( 2 ); + expect( getSparseArrayLength( result.lineFormats ) ).toBe( 2 ); } ); it( 'should insert line separator without formats if previous line separator did not have any', () => { const value = { formats: [ , , , , , ], + lineFormats: [ , , , , , ], + objects: [ , , , , , ], text: `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }a`, start: 5, end: 5, }; const expected = { formats: [ , , , , , , ], + lineFormats: [ , , , , , , ], + objects: [ , , , , , , ], text: `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }a${ LINE_SEPARATOR }`, start: 6, end: 6, @@ -91,6 +107,6 @@ describe( 'insertLineSeparator', () => { expect( result ).not.toBe( value ); expect( result ).toEqual( expected ); - expect( getSparseArrayLength( result.formats ) ).toBe( 0 ); + expect( getSparseArrayLength( result.lineFormats ) ).toBe( 0 ); } ); } ); diff --git a/packages/rich-text/src/test/insert-object.js b/packages/rich-text/src/test/insert-object.js index 15680372986a9d..daee49543cbd0f 100644 --- a/packages/rich-text/src/test/insert-object.js +++ b/packages/rich-text/src/test/insert-object.js @@ -17,12 +17,16 @@ describe( 'insert', () => { it( 'should delete and insert', () => { const record = { formats: [ , , , , [ em ], [ em ], [ em ], , , , , , , ], + lineFormats: [ , , , , , , , , , , , , , ], + objects: [ , , , , , , , , , , , , , ], text: 'one two three', start: 6, end: 6, }; const expected = { - formats: [ , , [ { ...obj, object: true } ], [ em ], , , , , , , ], + formats: [ , , , [ em ], , , , , , , ], + lineFormats: [ , , , , , , , , , , ], + objects: [ , , obj, , , , , , , , ], text: `on${ OBJECT_REPLACEMENT_CHARACTER }o three`, start: 3, end: 3, @@ -31,6 +35,7 @@ describe( 'insert', () => { expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.formats ) ).toBe( 2 ); + expect( getSparseArrayLength( result.formats ) ).toBe( 1 ); + expect( getSparseArrayLength( result.objects ) ).toBe( 1 ); } ); } ); diff --git a/packages/rich-text/src/test/insert.js b/packages/rich-text/src/test/insert.js index 64de9f44828a23..f5dabca196f254 100644 --- a/packages/rich-text/src/test/insert.js +++ b/packages/rich-text/src/test/insert.js @@ -17,16 +17,22 @@ describe( 'insert', () => { it( 'should delete and insert', () => { const record = { formats: [ , , , , [ em ], [ em ], [ em ], , , , , , , ], + lineFormats: [], + objects: [], text: 'one two three', start: 6, end: 6, }; const toInsert = { formats: [ [ strong ] ], + lineFormats: [], + objects: [], text: 'a', }; const expected = { formats: [ , , [ strong ], [ em ], , , , , , , ], + lineFormats: [], + objects: [], text: 'onao three', start: 3, end: 3, @@ -41,16 +47,22 @@ describe( 'insert', () => { it( 'should insert line break with selection', () => { const record = { formats: [ , , ], + lineFormats: [], + objects: [], text: 'tt', start: 1, end: 1, }; const toInsert = { formats: [ , ], + lineFormats: [], + objects: [], text: '\n', }; const expected = { formats: [ , , , ], + lineFormats: [], + objects: [], text: 't\nt', start: 2, end: 2, diff --git a/packages/rich-text/src/test/join.js b/packages/rich-text/src/test/join.js index fb2f20b1b2784e..df4b4a73b30f81 100644 --- a/packages/rich-text/src/test/join.js +++ b/packages/rich-text/src/test/join.js @@ -15,8 +15,10 @@ describe( 'join', () => { const separators = [ ' ', { - text: ' ', formats: [ , ], + lineFormats: [ , ], + objects: [ , ], + text: ' ', }, ]; @@ -24,14 +26,20 @@ describe( 'join', () => { it( 'should join records with string separator', () => { const one = { formats: [ , , [ em ] ], + lineFormats: [ , , , ], + objects: [ , , , ], text: 'one', }; const two = { formats: [ [ em ], , , ], + lineFormats: [ , , , ], + objects: [ , , , ], text: 'two', }; const three = { formats: [ , , [ em ], , [ em ], , , ], + lineFormats: [ , , , , , , , ], + objects: [ , , , , , , , ], text: 'one two', }; const result = join( [ deepFreeze( one ), deepFreeze( two ) ], separator ); diff --git a/packages/rich-text/src/test/outdent-list-items.js b/packages/rich-text/src/test/outdent-list-items.js index c2bf8b30e4766b..5258be43a54b8e 100644 --- a/packages/rich-text/src/test/outdent-list-items.js +++ b/packages/rich-text/src/test/outdent-list-items.js @@ -17,6 +17,8 @@ describe( 'outdentListItems', () => { it( 'should not outdent only item', () => { const record = { formats: [ , ], + lineFormats: [ , ], + objects: [ , ], text: '1', start: 1, end: 1, @@ -25,138 +27,138 @@ describe( 'outdentListItems', () => { expect( result ).toEqual( record ); expect( result ).toBe( record ); - expect( getSparseArrayLength( result.formats ) ).toBe( 0 ); + expect( getSparseArrayLength( result.lineFormats ) ).toBe( 0 ); } ); it( 'should indent', () => { // As we're testing list formats, the text should remain the same. const text = `1${ LINE_SEPARATOR }`; const record = { - formats: [ , [ ul ] ], + formats: Array( text.length ), + lineFormats: [ , [ ul ] ], + objects: Array( text.length ), text, start: 2, end: 2, }; const expected = { - formats: [ , , ], - text, - start: 2, - end: 2, + ...record, + lineFormats: [ , , ], }; const result = outdentListItems( deepFreeze( record ) ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.formats ) ).toBe( 0 ); + expect( getSparseArrayLength( result.lineFormats ) ).toBe( 0 ); } ); it( 'should outdent two levels deep', () => { // As we're testing list formats, the text should remain the same. const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`; const record = { - formats: [ , [ ul ], , [ ul, ul ], , ], + formats: Array( text.length ), + lineFormats: [ , [ ul ], , [ ul, ul ], , ], + objects: Array( text.length ), text, start: 5, end: 5, }; const expected = { - formats: [ , [ ul ], , [ ul ], , ], - text, - start: 5, - end: 5, + ...record, + lineFormats: [ , [ ul ], , [ ul ], , ], }; const result = outdentListItems( deepFreeze( record ) ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.formats ) ).toBe( 2 ); + expect( getSparseArrayLength( result.lineFormats ) ).toBe( 2 ); } ); it( 'should outdent with multiple lines selected', () => { // As we're testing list formats, the text should remain the same. const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`; const record = { - formats: [ , [ ul ], , [ ul, ul ], , ], + formats: Array( text.length ), + lineFormats: [ , [ ul ], , [ ul, ul ], , ], + objects: Array( text.length ), text, start: 2, end: 5, }; const expected = { - formats: [ , , , [ ul ], , ], - text, - start: 2, - end: 5, + ...record, + lineFormats: [ , , , [ ul ], , ], }; const result = outdentListItems( deepFreeze( record ) ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.formats ) ).toBe( 1 ); + expect( getSparseArrayLength( result.lineFormats ) ).toBe( 1 ); } ); it( 'should outdent list item with children', () => { // As we're testing list formats, the text should remain the same. const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3${ LINE_SEPARATOR }4`; const record = { - formats: [ , [ ul ], , [ ul, ul ], , [ ul, ul ], , ], + formats: Array( text.length ), + lineFormats: [ , [ ul ], , [ ul, ul ], , [ ul, ul ], , ], + objects: Array( text.length ), text, start: 2, end: 2, }; const expected = { - formats: [ , , , [ ul ], , [ ul ], , ], - text, - start: 2, - end: 2, + ...record, + lineFormats: [ , , , [ ul ], , [ ul ], , ], }; const result = outdentListItems( deepFreeze( record ) ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.formats ) ).toBe( 2 ); + expect( getSparseArrayLength( result.lineFormats ) ).toBe( 2 ); } ); it( 'should outdent list based on parent list', () => { // As we're testing list formats, the text should remain the same. const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3${ LINE_SEPARATOR }4`; const record = { - formats: [ , [ ul ], , [ ul, ul ], , [ ul ], , ], + formats: Array( text.length ), + lineFormats: [ , [ ul ], , [ ul, ul ], , [ ul ], , ], + objects: Array( text.length ), text, start: 6, end: 6, }; const expected = { - formats: [ , [ ul ], , [ ul, ul ], , , , ], - text, - start: 6, - end: 6, + ...record, + lineFormats: [ , [ ul ], , [ ul, ul ], , , , ], }; const result = outdentListItems( deepFreeze( record ) ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.formats ) ).toBe( 2 ); + expect( getSparseArrayLength( result.lineFormats ) ).toBe( 2 ); } ); it( 'should outdent when a selected item is at level 0', () => { // As we're testing list formats, the text should remain the same. const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`; const record = { - formats: [ , [ ul ], , , , ], + formats: Array( text.length ), + lineFormats: [ , [ ul ], , , , ], + objects: Array( text.length ), text, start: 2, end: 5, }; const expected = { - formats: [ , , , , , ], - text, - start: 2, - end: 5, + ...record, + lineFormats: [ , , , , , ], }; const result = outdentListItems( deepFreeze( record ) ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.formats ) ).toBe( 0 ); + expect( getSparseArrayLength( result.lineFormats ) ).toBe( 0 ); } ); } ); diff --git a/packages/rich-text/src/test/replace.js b/packages/rich-text/src/test/replace.js index f3c7d9aa923e9f..2866433982ce87 100644 --- a/packages/rich-text/src/test/replace.js +++ b/packages/rich-text/src/test/replace.js @@ -16,12 +16,16 @@ describe( 'replace', () => { it( 'should replace string to string', () => { const record = { formats: [ , , , , [ em ], [ em ], [ em ], , , , , , , ], + lineFormats: [ , , , , , , , , , , , , , ], + objects: [ , , , , , , , , , , , , , ], text: 'one two three', start: 6, end: 6, }; const expected = { formats: [ , , , , [ em ], , , , , , , ], + lineFormats: [ , , , , , , , , , , , ], + objects: [ , , , , , , , , , , , ], text: 'one 2 three', start: 5, end: 5, @@ -36,16 +40,22 @@ describe( 'replace', () => { it( 'should replace string to record', () => { const record = { formats: [ , , , , [ em ], [ em ], [ em ], , , , , , , ], + lineFormats: [ , , , , , , , , , , , , , ], + objects: [ , , , , , , , , , , , , , ], text: 'one two three', start: 6, end: 6, }; const replacement = { formats: [ , ], + lineFormats: [ , ], + objects: [ , ], text: '2', }; const expected = { formats: [ , , , , , , , , , , , ], + lineFormats: [ , , , , , , , , , , , ], + objects: [ , , , , , , , , , , , ], text: 'one 2 three', start: 5, end: 5, @@ -60,12 +70,16 @@ describe( 'replace', () => { it( 'should replace string to function', () => { const record = { formats: [ , , , , , , , , , , , , ], + lineFormats: [ , , , , , , , , , , , , ], + objects: [ , , , , , , , , , , , , ], text: 'abc12345#$*%', start: 6, end: 6, }; const expected = { formats: [ , , , , , , , , , , , , , , , , , , ], + lineFormats: [ , , , , , , , , , , , , , , , , , , ], + objects: [ , , , , , , , , , , , , , , , , , , ], text: 'abc - 12345 - #$*%', start: 18, end: 18, diff --git a/packages/rich-text/src/test/slice.js b/packages/rich-text/src/test/slice.js index 9d40f7a6de0377..a658dcff56290e 100644 --- a/packages/rich-text/src/test/slice.js +++ b/packages/rich-text/src/test/slice.js @@ -16,10 +16,14 @@ describe( 'slice', () => { it( 'should slice', () => { const record = { formats: [ , , , , [ em ], [ em ], [ em ], , , , , , , ], + lineFormats: [ , , , , , , , , , , , , , ], + objects: [ , , , , , , , , , , , , , ], text: 'one two three', }; const expected = { formats: [ , [ em ], [ em ] ], + lineFormats: [ , , , ], + objects: [ , , , ], text: ' tw', }; const result = slice( deepFreeze( record ), 3, 6 ); @@ -32,12 +36,16 @@ describe( 'slice', () => { it( 'should slice record', () => { const record = { formats: [ , , , , [ em ], [ em ], [ em ], , , , , , , ], + lineFormats: [ , , , , , , , , , , , , , ], + objects: [ , , , , , , , , , , , , , ], text: 'one two three', start: 3, end: 6, }; const expected = { formats: [ , [ em ], [ em ] ], + lineFormats: [ , , , ], + objects: [ , , , ], text: ' tw', }; const result = slice( deepFreeze( record ) ); diff --git a/packages/rich-text/src/test/split.js b/packages/rich-text/src/test/split.js index 1cdfbae9630d23..1d740cab7c11d8 100644 --- a/packages/rich-text/src/test/split.js +++ b/packages/rich-text/src/test/split.js @@ -18,17 +18,23 @@ describe( 'split', () => { start: 5, end: 10, formats: [ , , , , [ em ], [ em ], [ em ], , , , , , , ], + lineFormats: [ , , , , , , , , , , , , , ], + objects: [ , , , , , , , , , , , , , ], text: 'one two three', }; const expected = [ { formats: [ , , , , [ em ], [ em ] ], + lineFormats: [ , , , , , , ], + objects: [ , , , , , , ], text: 'one tw', }, { start: 0, end: 0, formats: [ [ em ], , , , , , , ], + lineFormats: [ , , , , , , , ], + objects: [ , , , , , , , ], text: 'o three', }, ]; @@ -45,6 +51,8 @@ describe( 'split', () => { it( 'should split with selection', () => { const record = { formats: [ , , , , [ em ], [ em ], [ em ], , , , , , , ], + lineFormats: [ , , , , , , , , , , , , , ], + objects: [ , , , , , , , , , , , , , ], text: 'one two three', start: 6, end: 6, @@ -52,10 +60,14 @@ describe( 'split', () => { const expected = [ { formats: [ , , , , [ em ], [ em ] ], + lineFormats: [ , , , , , , ], + objects: [ , , , , , , ], text: 'one tw', }, { formats: [ [ em ], , , , , , , ], + lineFormats: [ , , , , , , , ], + objects: [ , , , , , , , ], text: 'o three', start: 0, end: 0, @@ -74,6 +86,8 @@ describe( 'split', () => { it( 'should split empty', () => { const record = { formats: [], + lineFormats: [], + objects: [], text: '', start: 0, end: 0, @@ -81,10 +95,14 @@ describe( 'split', () => { const expected = [ { formats: [], + lineFormats: [], + objects: [], text: '', }, { formats: [], + lineFormats: [], + objects: [], text: '', start: 0, end: 0, @@ -103,6 +121,8 @@ describe( 'split', () => { it( 'should split multiline', () => { const record = { formats: [ , , , , , , , , , , ], + lineFormats: [ , , , , , , , , , , ], + objects: [ , , , , , , , , , , ], text: 'test\u2028\u2028test', start: 5, end: 5, @@ -110,10 +130,14 @@ describe( 'split', () => { const expected = [ { formats: [ , , , , ], + lineFormats: [ , , , , ], + objects: [ , , , , ], text: 'test', }, { formats: [ , , , , ], + lineFormats: [ , , , , ], + objects: [ , , , , ], text: 'test', start: 0, end: 0, @@ -134,33 +158,45 @@ describe( 'split', () => { start: 6, end: 16, formats: [ , , , , [ em ], [ em ], [ em ], , , , , , , , , , , , , , , , , ], + lineFormats: [ , , , , , , , , , , , , , , , , , , , , , , , ], + objects: [ , , , , , , , , , , , , , , , , , , , , , , , ], text: 'one two three four five', }; const expected = [ { formats: [ , , , ], + lineFormats: [ , , , ], + objects: [ , , , ], text: 'one', }, { start: 2, end: 3, formats: [ [ em ], [ em ], [ em ] ], + lineFormats: [ , , , ], + objects: [ , , , ], text: 'two', }, { start: 0, end: 5, formats: [ , , , , , ], + lineFormats: [ , , , , , ], + objects: [ , , , , , ], text: 'three', }, { start: 0, end: 2, formats: [ , , , , ], + lineFormats: [ , , , , ], + objects: [ , , , , ], text: 'four', }, { formats: [ , , , , ], + lineFormats: [ , , , , ], + objects: [ , , , , ], text: 'five', }, ]; @@ -179,21 +215,29 @@ describe( 'split', () => { start: 5, end: 6, formats: [ , , , , [ em ], [ em ], [ em ], , , , , , , ], + lineFormats: [ , , , , , , , , , , , , , ], + objects: [ , , , , , , , , , , , , , ], text: 'one two three', }; const expected = [ { formats: [ , , , ], + lineFormats: [ , , , ], + objects: [ , , , ], text: 'one', }, { start: 1, end: 2, formats: [ [ em ], [ em ], [ em ] ], + lineFormats: [ , , , ], + objects: [ , , , ], text: 'two', }, { formats: [ , , , , , ], + lineFormats: [ , , , , , ], + objects: [ , , , , , ], text: 'three', }, ]; diff --git a/packages/rich-text/src/to-dom.js b/packages/rich-text/src/to-dom.js index b81c5184684440..9ebe8365a25bab 100644 --- a/packages/rich-text/src/to-dom.js +++ b/packages/rich-text/src/to-dom.js @@ -122,7 +122,6 @@ function prepareFormats( prepareEditableTree = [], value ) { export function toDom( { value, multilineTag, - multilineWrapperTags, prepareEditableTree, isEditableTree = true, } ) { @@ -135,7 +134,6 @@ export function toDom( { formats: prepareFormats( prepareEditableTree, value ), }, multilineTag, - multilineWrapperTags, createEmpty, append, getLastChild, @@ -174,7 +172,6 @@ export function apply( { value, current, multilineTag, - multilineWrapperTags, prepareEditableTree, __unstableDomOnly, } ) { @@ -182,7 +179,6 @@ export function apply( { const { body, selection } = toDom( { value, multilineTag, - multilineWrapperTags, prepareEditableTree, } ); diff --git a/packages/rich-text/src/to-html-string.js b/packages/rich-text/src/to-html-string.js index 0ba36e62510a35..bf6c60fda0442d 100644 --- a/packages/rich-text/src/to-html-string.js +++ b/packages/rich-text/src/to-html-string.js @@ -21,16 +21,13 @@ import { toTree } from './to-tree'; * @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, multilineWrapperTags } ) { +export function toHTMLString( { value, multilineTag } ) { const tree = toTree( { value, multilineTag, - multilineWrapperTags, createEmpty, append, getLastChild, diff --git a/packages/rich-text/src/to-tree.js b/packages/rich-text/src/to-tree.js index c89bdc94a2d061..81ad1ee062d512 100644 --- a/packages/rich-text/src/to-tree.js +++ b/packages/rich-text/src/to-tree.js @@ -91,7 +91,6 @@ const padding = { export function toTree( { value, multilineTag, - multilineWrapperTags = [], createEmpty, append, getLastChild, @@ -104,7 +103,7 @@ export function toTree( { onEndIndex, isEditableTree, } ) { - const { formats, text, start, end } = value; + const { formats, lineFormats, objects, text, start, end } = value; const formatsLength = formats.length + 1; const tree = createEmpty(); const multilineFormat = { type: multilineTag }; @@ -138,12 +137,9 @@ export function toTree( { // 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 ); - } - + characterFormats = lastSeparatorFormats = ( lineFormats[ i ] || [] ).reduce( ( accumulator, format ) => { + accumulator.push( format ); + accumulator.push( multilineFormat ); return accumulator; }, [ multilineFormat ] ); } else { @@ -196,11 +192,10 @@ export function toTree( { return; } - const { type, attributes, unregisteredAttributes, object } = format; + const { type, attributes, unregisteredAttributes } = format; const boundaryClass = ( isEditableTree && - ! object && character !== LINE_SEPARATOR && format === deepestActiveFormat ); @@ -210,7 +205,6 @@ export function toTree( { type, attributes, unregisteredAttributes, - object, boundaryClass, } ) ); @@ -218,7 +212,7 @@ export function toTree( { remove( pointer ); } - pointer = append( format.object ? parent : newNode, '' ); + pointer = append( newNode, '' ); } ); } @@ -240,22 +234,27 @@ export function toTree( { } } - if ( character !== OBJECT_REPLACEMENT_CHARACTER ) { - if ( character === '\n' ) { - pointer = append( getParent( pointer ), { - type: 'br', - attributes: isEditableTree ? { - 'data-rich-text-line-break': 'true', - } : undefined, - object: true, - } ); - // Ensure pointer is text node. - pointer = append( getParent( pointer ), '' ); - } else if ( ! isText( pointer ) ) { - pointer = append( getParent( pointer ), character ); - } else { - appendText( pointer, character ); - } + if ( character === OBJECT_REPLACEMENT_CHARACTER ) { + pointer = append( getParent( pointer ), fromFormat( { + ...objects[ i ], + object: true, + } ) ); + // Ensure pointer is text node. + pointer = append( getParent( pointer ), '' ); + } else if ( character === '\n' ) { + pointer = append( getParent( pointer ), { + type: 'br', + attributes: isEditableTree ? { + 'data-rich-text-line-break': 'true', + } : undefined, + object: true, + } ); + // Ensure pointer is text node. + pointer = append( getParent( pointer ), '' ); + } else if ( ! isText( pointer ) ) { + pointer = append( getParent( pointer ), character ); + } else { + appendText( pointer, character ); } if ( onStartIndex && start === i + 1 ) { diff --git a/packages/rich-text/src/toggle-format.js b/packages/rich-text/src/toggle-format.js index 6e7854dcaa6626..7545f5d30c9d6a 100644 --- a/packages/rich-text/src/toggle-format.js +++ b/packages/rich-text/src/toggle-format.js @@ -14,10 +14,7 @@ import { applyFormat } from './apply-format'; * * @return {Object} A new value with the format applied or removed. */ -export function toggleFormat( - value, - format -) { +export function toggleFormat( value, format ) { if ( getActiveFormat( value, format.type ) ) { return removeFormat( value, format.type ); } From 190970a495d7b44871ed5c379e2f1a3a248047c8 Mon Sep 17 00:00:00 2001 From: iseulde Date: Tue, 19 Feb 2019 16:08:39 +0100 Subject: [PATCH 02/18] Update RichText --- packages/block-editor/src/components/rich-text/index.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/block-editor/src/components/rich-text/index.js b/packages/block-editor/src/components/rich-text/index.js index be8d4c6c1ecc5d..565528c03c2754 100644 --- a/packages/block-editor/src/components/rich-text/index.js +++ b/packages/block-editor/src/components/rich-text/index.js @@ -177,10 +177,10 @@ export class RichText extends Component { * @return {Object} The current record (value and selection). */ getRecord() { - const { formats, text } = this.formatToValue( this.props.value ); + const { formats, lineFormats, objects, text } = this.formatToValue( this.props.value ); const { start, end, selectedFormat } = this.state; - return { formats, text, start, end, selectedFormat }; + return { formats, lineFormats, objects, text, start, end, selectedFormat }; } createRecord() { @@ -394,7 +394,7 @@ export class RichText extends Component { } let { selectedFormat } = this.state; - const { formats, text, start, end } = this.createRecord(); + const { formats, lineFormats, objects, text, start, end } = this.createRecord(); if ( this.formatPlaceholder ) { formats[ this.state.start ] = formats[ this.state.start ] || []; @@ -411,12 +411,13 @@ export class RichText extends Component { } source = source.slice( 0, selectedFormat ); + formats[ this.state.start ] = source; } else { delete formats[ this.state.start ]; } - const change = { formats, text, start, end, selectedFormat }; + const change = { formats, lineFormats, objects, text, start, end, selectedFormat }; this.onChange( change, { withoutHistory: true, From a5fd0ed2fd175e85e31e96f4031951faee93a69f Mon Sep 17 00:00:00 2001 From: iseulde Date: Thu, 21 Feb 2019 15:31:38 +0100 Subject: [PATCH 03/18] Fix image toolbar --- .../src/components/rich-text/format-edit.js | 13 ++++++++++--- packages/format-library/src/image/index.js | 19 +++++++++---------- packages/rich-text/src/get-active-object.js | 14 ++++++++++++++ packages/rich-text/src/index.js | 1 + 4 files changed, 34 insertions(+), 13 deletions(-) create mode 100644 packages/rich-text/src/get-active-object.js diff --git a/packages/block-editor/src/components/rich-text/format-edit.js b/packages/block-editor/src/components/rich-text/format-edit.js index 7505ed1f81a3cc..790ec092d70a99 100644 --- a/packages/block-editor/src/components/rich-text/format-edit.js +++ b/packages/block-editor/src/components/rich-text/format-edit.js @@ -3,7 +3,7 @@ */ import { withSelect } from '@wordpress/data'; import { Fragment } from '@wordpress/element'; -import { getActiveFormat } from '@wordpress/rich-text'; +import { getActiveFormat, getActiveObject } from '@wordpress/rich-text'; const FormatEdit = ( { formatTypes, onChange, value } ) => { return ( @@ -15,13 +15,20 @@ const FormatEdit = ( { formatTypes, onChange, value } ) => { const activeFormat = getActiveFormat( value, name ); const isActive = activeFormat !== undefined; - const activeAttributes = isActive ? activeFormat.attributes || {} : {}; + const activeObject = getActiveObject( value ); + const isObjectActive = activeObject !== undefined; return ( diff --git a/packages/format-library/src/image/index.js b/packages/format-library/src/image/index.js index 2dca1c41506b61..441a4934847079 100644 --- a/packages/format-library/src/image/index.js +++ b/packages/format-library/src/image/index.js @@ -40,7 +40,7 @@ export const image = { } static getDerivedStateFromProps( props, state ) { - const { activeAttributes: { style } } = props; + const { objectAttributes: { style } } = props; if ( style === state.previousStyle ) { return null; @@ -79,8 +79,8 @@ export const image = { } render() { - const { value, onChange, isActive, activeAttributes } = this.props; - const { style } = activeAttributes; + const { value, onChange, isObjectActive, objectAttributes } = this.props; + const { style } = objectAttributes; // Rerender PositionedAtSelection when the selection changes or when // the width changes. const key = value.start + style; @@ -113,7 +113,7 @@ export const image = { return null; } } /> } - { isActive && + { isObjectActive && { - const newFormats = value.formats.slice( 0 ); + const newObjects = value.objects.slice(); - newFormats[ value.start ] = [ { + newObjects[ value.start ] = { type: name, - object: true, attributes: { - ...activeAttributes, + ...objectAttributes, style: `width: ${ this.state.width }px;`, }, - } ]; + }; onChange( { ...value, - formats: newFormats, + objects: newObjects, } ); event.preventDefault(); diff --git a/packages/rich-text/src/get-active-object.js b/packages/rich-text/src/get-active-object.js new file mode 100644 index 00000000000000..ae83cb75255b38 --- /dev/null +++ b/packages/rich-text/src/get-active-object.js @@ -0,0 +1,14 @@ +/** + * Gets the active object, if there is any. + * + * @param {Object} value Value to inspect. + * + * @return {?Object} Active object, or undefined. + */ +export function getActiveObject( { start, end, objects } ) { + if ( start + 1 !== end ) { + return; + } + + return objects[ start ]; +} diff --git a/packages/rich-text/src/index.js b/packages/rich-text/src/index.js index 423046079132bd..9d9f4620212876 100644 --- a/packages/rich-text/src/index.js +++ b/packages/rich-text/src/index.js @@ -8,6 +8,7 @@ export { charAt } from './char-at'; export { concat } from './concat'; export { create } from './create'; export { getActiveFormat } from './get-active-format'; +export { getActiveObject } from './get-active-object'; export { getSelectionEnd } from './get-selection-end'; export { getSelectionStart } from './get-selection-start'; export { getTextContent } from './get-text-content'; From aee24d22af0e98697e3e30f25d40587806ab407b Mon Sep 17 00:00:00 2001 From: iseulde Date: Thu, 21 Feb 2019 17:10:07 +0100 Subject: [PATCH 04/18] Update format placeholder --- .../src/components/rich-text/index.js | 10 +++++-- packages/rich-text/src/apply-format.js | 3 +- packages/rich-text/src/remove-format.js | 28 +++++++++++++------ packages/rich-text/src/test/apply-format.js | 2 +- 4 files changed, 28 insertions(+), 15 deletions(-) diff --git a/packages/block-editor/src/components/rich-text/index.js b/packages/block-editor/src/components/rich-text/index.js index 565528c03c2754..98238b664e8a97 100644 --- a/packages/block-editor/src/components/rich-text/index.js +++ b/packages/block-editor/src/components/rich-text/index.js @@ -397,9 +397,13 @@ export class RichText extends Component { const { formats, lineFormats, objects, text, start, end } = this.createRecord(); if ( this.formatPlaceholder ) { - formats[ this.state.start ] = formats[ this.state.start ] || []; - formats[ this.state.start ].push( this.formatPlaceholder ); - selectedFormat = formats[ this.state.start ].length; + selectedFormat = this.formatPlaceholder.length; + + if ( selectedFormat ) { + formats[ this.state.start ] = this.formatPlaceholder; + } else { + delete formats[ this.state.start ]; + } } else if ( selectedFormat ) { const formatsBefore = formats[ start - 1 ] || []; const formatsAfter = formats[ start ] || []; diff --git a/packages/rich-text/src/apply-format.js b/packages/rich-text/src/apply-format.js index a3d7b3835b952e..c9a59b96e6a656 100644 --- a/packages/rich-text/src/apply-format.js +++ b/packages/rich-text/src/apply-format.js @@ -52,11 +52,10 @@ export function applyFormat( // with the format applied. } else { const previousFormat = newFormats[ startIndex - 1 ] || []; - const hasType = find( previousFormat, { type: format.type } ); return { ...value, - formatPlaceholder: hasType ? undefined : format, + formatPlaceholder: [ ...previousFormat, format ], }; } } else { diff --git a/packages/rich-text/src/remove-format.js b/packages/rich-text/src/remove-format.js index 0e75efee2fd636..405cb6265e1e06 100644 --- a/packages/rich-text/src/remove-format.js +++ b/packages/rich-text/src/remove-format.js @@ -2,7 +2,7 @@ * External dependencies */ -import { find } from 'lodash'; +import { find, reject } from 'lodash'; /** * Internal dependencies @@ -35,16 +35,26 @@ export function removeFormat( if ( startIndex === endIndex ) { const format = find( newFormats[ startIndex ], { type: formatType } ); - while ( find( newFormats[ startIndex ], format ) ) { - filterFormats( newFormats, startIndex, formatType ); - startIndex--; - } - - endIndex++; + if ( format ) { + while ( find( newFormats[ startIndex ], format ) ) { + filterFormats( newFormats, startIndex, formatType ); + startIndex--; + } - while ( find( newFormats[ endIndex ], format ) ) { - filterFormats( newFormats, endIndex, formatType ); endIndex++; + + while ( find( newFormats[ endIndex ], format ) ) { + filterFormats( newFormats, endIndex, formatType ); + endIndex++; + } + } else { + return { + ...value, + formatPlaceholder: reject( + newFormats[ startIndex - 1 ] || [], + { type: formatType } + ), + }; } } else { for ( let i = startIndex; i < endIndex; i++ ) { diff --git a/packages/rich-text/src/test/apply-format.js b/packages/rich-text/src/test/apply-format.js index de4f7b69e5f5ef..b8cff3bc476202 100644 --- a/packages/rich-text/src/test/apply-format.js +++ b/packages/rich-text/src/test/apply-format.js @@ -61,7 +61,7 @@ describe( 'applyFormat', () => { }; const expected = { ...record, - formatPlaceholder: a2, + formatPlaceholder: [ a2 ], }; const result = applyFormat( deepFreeze( record ), a2 ); From f8c46083ba05142372abf08793d31fcc2eaa4a77 Mon Sep 17 00:00:00 2001 From: iseulde Date: Tue, 26 Feb 2019 11:03:31 +0100 Subject: [PATCH 05/18] lineFormat => lines --- .../src/components/rich-text/index.js | 8 +-- packages/rich-text/src/change-list-type.js | 20 +++--- packages/rich-text/src/concat.js | 2 +- packages/rich-text/src/create.js | 10 +-- .../rich-text/src/get-last-child-index.js | 8 +-- .../rich-text/src/get-parent-line-index.js | 6 +- packages/rich-text/src/indent-list-items.js | 28 ++++---- .../rich-text/src/insert-line-separator.js | 8 +-- packages/rich-text/src/insert-object.js | 2 +- packages/rich-text/src/insert.js | 4 +- packages/rich-text/src/join.js | 4 +- packages/rich-text/src/outdent-list-items.js | 18 ++--- packages/rich-text/src/replace.js | 6 +- packages/rich-text/src/slice.js | 4 +- packages/rich-text/src/split.js | 10 +-- .../rich-text/src/test/change-list-type.js | 16 ++--- packages/rich-text/src/test/concat.js | 6 +- packages/rich-text/src/test/create.js | 2 +- .../src/test/get-last-child-index.js | 10 +-- .../src/test/get-parent-line-index.js | 8 +-- packages/rich-text/src/test/helpers/index.js | 70 +++++++++---------- .../rich-text/src/test/indent-list-items.js | 46 ++++++------ .../src/test/insert-line-separator.js | 24 +++---- packages/rich-text/src/test/insert-object.js | 4 +- packages/rich-text/src/test/insert.js | 12 ++-- packages/rich-text/src/test/join.js | 8 +-- .../rich-text/src/test/outdent-list-items.js | 40 +++++------ packages/rich-text/src/test/replace.js | 14 ++-- packages/rich-text/src/test/slice.js | 8 +-- packages/rich-text/src/test/split.js | 44 ++++++------ packages/rich-text/src/to-tree.js | 4 +- 31 files changed, 227 insertions(+), 227 deletions(-) diff --git a/packages/block-editor/src/components/rich-text/index.js b/packages/block-editor/src/components/rich-text/index.js index 98238b664e8a97..4e71c436467fe9 100644 --- a/packages/block-editor/src/components/rich-text/index.js +++ b/packages/block-editor/src/components/rich-text/index.js @@ -177,10 +177,10 @@ export class RichText extends Component { * @return {Object} The current record (value and selection). */ getRecord() { - const { formats, lineFormats, objects, text } = this.formatToValue( this.props.value ); + const { formats, lines, objects, text } = this.formatToValue( this.props.value ); const { start, end, selectedFormat } = this.state; - return { formats, lineFormats, objects, text, start, end, selectedFormat }; + return { formats, lines, objects, text, start, end, selectedFormat }; } createRecord() { @@ -394,7 +394,7 @@ export class RichText extends Component { } let { selectedFormat } = this.state; - const { formats, lineFormats, objects, text, start, end } = this.createRecord(); + const { formats, lines, objects, text, start, end } = this.createRecord(); if ( this.formatPlaceholder ) { selectedFormat = this.formatPlaceholder.length; @@ -421,7 +421,7 @@ export class RichText extends Component { delete formats[ this.state.start ]; } - const change = { formats, lineFormats, objects, text, start, end, selectedFormat }; + const change = { formats, lines, objects, text, start, end, selectedFormat }; this.onChange( change, { withoutHistory: true, diff --git a/packages/rich-text/src/change-list-type.js b/packages/rich-text/src/change-list-type.js index ace21d12c78dda..64202a274dd0d3 100644 --- a/packages/rich-text/src/change-list-type.js +++ b/packages/rich-text/src/change-list-type.js @@ -20,14 +20,14 @@ import { getParentLineIndex } from './get-parent-line-index'; * @return {Object} The changed value. */ export function changeListType( value, newFormat ) { - const { text, lineFormats, start, end } = value; + const { text, lines, start, end } = value; const startingLineIndex = getLineIndex( value, start ); - const startLineFormats = lineFormats[ startingLineIndex ] || []; - const endLineFormats = lineFormats[ getLineIndex( value, end ) ] || []; + const startlines = lines[ startingLineIndex ] || []; + const endlines = lines[ getLineIndex( value, end ) ] || []; const startIndex = getParentLineIndex( value, startingLineIndex ); - const newLineFormats = lineFormats.slice(); - const startCount = startLineFormats.length - 1; - const endCount = endLineFormats.length - 1; + const newLines = lines.slice(); + const startCount = startlines.length - 1; + const endCount = endlines.length - 1; let changed; @@ -36,16 +36,16 @@ export function changeListType( value, newFormat ) { continue; } - if ( ( newLineFormats[ index ] || [] ).length <= startCount ) { + if ( ( newLines[ index ] || [] ).length <= startCount ) { break; } - if ( ! newLineFormats[ index ] ) { + if ( ! newLines[ index ] ) { continue; } changed = true; - newLineFormats[ index ] = newLineFormats[ index ].map( ( format, i ) => { + newLines[ index ] = newLines[ index ].map( ( format, i ) => { return i < startCount || i > endCount ? format : newFormat; } ); } @@ -56,6 +56,6 @@ export function changeListType( value, newFormat ) { return normaliseFormats( { ...value, - lineFormats: newLineFormats, + lines: newLines, } ); } diff --git a/packages/rich-text/src/concat.js b/packages/rich-text/src/concat.js index 04b3533145614a..34cf43a011f8d5 100644 --- a/packages/rich-text/src/concat.js +++ b/packages/rich-text/src/concat.js @@ -16,7 +16,7 @@ import { create } from './create'; */ export function concatPair( a, b ) { a.formats = a.formats.concat( b.formats ); - a.lineFormats = a.lineFormats.concat( b.lineFormats ); + a.lines = a.lines.concat( b.lines ); a.objects = a.objects.concat( b.objects ); a.text += b.text; diff --git a/packages/rich-text/src/create.js b/packages/rich-text/src/create.js index d2d33df48125f7..9ff8bd608d8997 100644 --- a/packages/rich-text/src/create.js +++ b/packages/rich-text/src/create.js @@ -25,7 +25,7 @@ const { TEXT_NODE, ELEMENT_NODE } = window.Node; function createEmptyValue() { return { formats: [], - lineFormats: [], + lines: [], objects: [], text: '', }; @@ -126,7 +126,7 @@ export function create( { if ( typeof text === 'string' && text.length > 0 ) { return { formats: Array( text.length ), - lineFormats: Array( text.length ), + lines: Array( text.length ), objects: Array( text.length ), text, }; @@ -302,7 +302,7 @@ function createFromElement( { // Create a sparse array of the same length as `text`, in which // formats can be added. accumulator.formats.length += text.length; - accumulator.lineFormats.length += text.length; + accumulator.lines.length += text.length; accumulator.objects.length += text.length; accumulator.text += text; continue; @@ -367,7 +367,7 @@ function createFromElement( { if ( format.attributes && value.text.length === 0 ) { concatPair( accumulator, { formats: [ , ], - lineFormats: [ , ], + lines: [ , ], objects: [ format ], text: OBJECT_REPLACEMENT_CHARACTER, } ); @@ -439,7 +439,7 @@ function createFromMultilineElement( { const formats = currentWrapperTags.length > 0 ? [ currentWrapperTags ] : [ , ]; accumulator.formats.length += 1; - accumulator.lineFormats = accumulator.lineFormats.concat( formats ); + accumulator.lines = accumulator.lines.concat( formats ); accumulator.objects.length += 1; accumulator.text += LINE_SEPARATOR; } diff --git a/packages/rich-text/src/get-last-child-index.js b/packages/rich-text/src/get-last-child-index.js index 11699c92f9ca18..5075dafa8dd752 100644 --- a/packages/rich-text/src/get-last-child-index.js +++ b/packages/rich-text/src/get-last-child-index.js @@ -12,8 +12,8 @@ import { LINE_SEPARATOR } from './special-characters'; * * @return {Array} The index of the last child. */ -export function getLastChildIndex( { text, lineFormats }, lineIndex ) { - const currentLineFormats = lineFormats[ lineIndex ] || []; +export function getLastChildIndex( { text, lines }, lineIndex ) { + const currentlines = lines[ lineIndex ] || []; // Use the given line index in case there are no next children. let childIndex = lineIndex; @@ -24,11 +24,11 @@ export function getLastChildIndex( { text, lineFormats }, lineIndex ) { continue; } - const formatsAtIndex = lineFormats[ index ] || []; + const formatsAtIndex = lines[ index ] || []; // If the amout of formats is equal or more, store it, then return the // last one if the amount of formats is less. - if ( formatsAtIndex.length >= currentLineFormats.length ) { + if ( formatsAtIndex.length >= currentlines.length ) { childIndex = index; } else { return childIndex; diff --git a/packages/rich-text/src/get-parent-line-index.js b/packages/rich-text/src/get-parent-line-index.js index 3151bc355cd0ff..c2144a5e5ca132 100644 --- a/packages/rich-text/src/get-parent-line-index.js +++ b/packages/rich-text/src/get-parent-line-index.js @@ -14,8 +14,8 @@ import { LINE_SEPARATOR } from './special-characters'; * * @return {Array} The parent list line index. */ -export function getParentLineIndex( { text, lineFormats }, lineIndex ) { - const startFormats = lineFormats[ lineIndex ] || []; +export function getParentLineIndex( { text, lines }, lineIndex ) { + const startFormats = lines[ lineIndex ] || []; let index = lineIndex; @@ -24,7 +24,7 @@ export function getParentLineIndex( { text, lineFormats }, lineIndex ) { continue; } - const formatsAtIndex = lineFormats[ index ] || []; + const formatsAtIndex = lines[ index ] || []; if ( formatsAtIndex.length === startFormats.length - 1 ) { return index; diff --git a/packages/rich-text/src/indent-list-items.js b/packages/rich-text/src/indent-list-items.js index 84ca90513e157e..efc94fcb1e4526 100644 --- a/packages/rich-text/src/indent-list-items.js +++ b/packages/rich-text/src/indent-list-items.js @@ -14,8 +14,8 @@ import { getLineIndex } from './get-line-index'; * * @return {boolean} The line index. */ -function getTargetLevelLineIndex( { text, lineFormats }, lineIndex ) { - const startFormats = lineFormats[ lineIndex ] || []; +function getTargetLevelLineIndex( { text, lines }, lineIndex ) { + const startFormats = lines[ lineIndex ] || []; let index = lineIndex; @@ -24,7 +24,7 @@ function getTargetLevelLineIndex( { text, lineFormats }, lineIndex ) { continue; } - const formatsAtIndex = lineFormats[ index ] || []; + const formatsAtIndex = lines[ index ] || []; // Return the first line index that is one level higher. If the level is // lower or equal, there is no result. @@ -52,10 +52,10 @@ export function indentListItems( value, rootFormat ) { return value; } - const { text, lineFormats, end } = value; + const { text, lines, end } = value; const previousLineIndex = getLineIndex( value, lineIndex ); - const formatsAtLineIndex = lineFormats[ lineIndex ] || []; - const formatsAtPreviousLineIndex = lineFormats[ previousLineIndex ] || []; + const formatsAtLineIndex = lines[ lineIndex ] || []; + const formatsAtPreviousLineIndex = lines[ previousLineIndex ] || []; // The the indentation of the current line is greater than previous line, // then the line cannot be furter indented. @@ -63,7 +63,7 @@ export function indentListItems( value, rootFormat ) { return value; } - const newFormats = lineFormats.slice(); + const newLines = lines.slice(); const targetLevelLineIndex = getTargetLevelLineIndex( value, lineIndex ); for ( let index = lineIndex; index < end; index++ ) { @@ -74,23 +74,23 @@ export function indentListItems( value, rootFormat ) { // Get the previous list, and if there's a child list, take over the // formats. If not, duplicate the last level and create a new level. if ( targetLevelLineIndex ) { - const targetFormats = lineFormats[ targetLevelLineIndex ] || []; - newFormats[ index ] = targetFormats.concat( - ( newFormats[ index ] || [] ).slice( targetFormats.length - 1 ) + const targetFormats = lines[ targetLevelLineIndex ] || []; + newLines[ index ] = targetFormats.concat( + ( newLines[ index ] || [] ).slice( targetFormats.length - 1 ) ); } else { - const targetFormats = lineFormats[ previousLineIndex ] || []; + const targetFormats = lines[ previousLineIndex ] || []; const lastformat = targetFormats[ targetFormats.length - 1 ] || rootFormat; - newFormats[ index ] = targetFormats.concat( + newLines[ index ] = targetFormats.concat( [ lastformat ], - ( newFormats[ index ] || [] ).slice( targetFormats.length ) + ( newLines[ index ] || [] ).slice( targetFormats.length ) ); } } return normaliseFormats( { ...value, - lineFormats: newFormats, + lines: newLines, } ); } diff --git a/packages/rich-text/src/insert-line-separator.js b/packages/rich-text/src/insert-line-separator.js index ee1fc9554ea969..a43834896d484f 100644 --- a/packages/rich-text/src/insert-line-separator.js +++ b/packages/rich-text/src/insert-line-separator.js @@ -24,16 +24,16 @@ export function insertLineSeparator( ) { const beforeText = getTextContent( value ).slice( 0, startIndex ); const previousLineSeparatorIndex = beforeText.lastIndexOf( LINE_SEPARATOR ); - const previousLineSeparatorFormats = value.lineFormats[ previousLineSeparatorIndex ]; - let lineFormats = [ , ]; + const previousLineSeparatorFormats = value.lines[ previousLineSeparatorIndex ]; + let lines = [ , ]; if ( previousLineSeparatorFormats ) { - lineFormats = [ previousLineSeparatorFormats ]; + lines = [ previousLineSeparatorFormats ]; } const valueToInsert = { formats: [ , ], - lineFormats, + lines, objects: [ , ], text: LINE_SEPARATOR, }; diff --git a/packages/rich-text/src/insert-object.js b/packages/rich-text/src/insert-object.js index a8c22cb93d81ff..fa2d8437162928 100644 --- a/packages/rich-text/src/insert-object.js +++ b/packages/rich-text/src/insert-object.js @@ -26,7 +26,7 @@ export function insertObject( ) { const valueToInsert = { formats: [ , ], - lineFormats: [ , ], + lines: [ , ], objects: [ formatToInsert ], text: OBJECT_REPLACEMENT_CHARACTER, }; diff --git a/packages/rich-text/src/insert.js b/packages/rich-text/src/insert.js index a7cd8554587a49..4c029c04bdaef7 100644 --- a/packages/rich-text/src/insert.js +++ b/packages/rich-text/src/insert.js @@ -24,7 +24,7 @@ export function insert( startIndex = value.start, endIndex = value.end ) { - const { formats, lineFormats, objects, text } = value; + const { formats, lines, objects, text } = value; if ( typeof valueToInsert === 'string' ) { valueToInsert = create( { text: valueToInsert } ); @@ -34,7 +34,7 @@ export function insert( return normaliseFormats( { formats: formats.slice( 0, startIndex ).concat( valueToInsert.formats, formats.slice( endIndex ) ), - lineFormats: lineFormats.slice( 0, startIndex ).concat( valueToInsert.lineFormats, lineFormats.slice( endIndex ) ), + lines: lines.slice( 0, startIndex ).concat( valueToInsert.lines, lines.slice( endIndex ) ), objects: objects.slice( 0, startIndex ).concat( valueToInsert.objects, objects.slice( endIndex ) ), text: text.slice( 0, startIndex ) + valueToInsert.text + text.slice( endIndex ), start: index, diff --git a/packages/rich-text/src/join.js b/packages/rich-text/src/join.js index bdc24b59f3c41f..d7a56c76586f26 100644 --- a/packages/rich-text/src/join.js +++ b/packages/rich-text/src/join.js @@ -20,9 +20,9 @@ export function join( values, separator = '' ) { separator = create( { text: separator } ); } - return normaliseFormats( values.reduce( ( accumlator, { formats, lineFormats, objects, text } ) => ( { + return normaliseFormats( values.reduce( ( accumlator, { formats, lines, objects, text } ) => ( { formats: accumlator.formats.concat( separator.formats, formats ), - lineFormats: accumlator.lineFormats.concat( separator.lineFormats, lineFormats ), + lines: accumlator.lines.concat( separator.lines, lines ), objects: accumlator.objects.concat( separator.objects, objects ), text: accumlator.text + separator.text + text, } ) ) ); diff --git a/packages/rich-text/src/outdent-list-items.js b/packages/rich-text/src/outdent-list-items.js index f78c3cdff38e11..07fbb273644adb 100644 --- a/packages/rich-text/src/outdent-list-items.js +++ b/packages/rich-text/src/outdent-list-items.js @@ -16,16 +16,16 @@ import { getLastChildIndex } from './get-last-child-index'; * @return {Object} The changed value. */ export function outdentListItems( value ) { - const { text, lineFormats, start, end } = value; + const { text, lines, start, end } = value; const startingLineIndex = getLineIndex( value, start ); // Return early if the starting line index cannot be further outdented. - if ( lineFormats[ startingLineIndex ] === undefined ) { + if ( lines[ startingLineIndex ] === undefined ) { return value; } - const newFormats = lineFormats.slice( 0 ); - const parentFormats = lineFormats[ getParentLineIndex( value, startingLineIndex ) ] || []; + const newLines = lines.slice( 0 ); + const parentFormats = lines[ getParentLineIndex( value, startingLineIndex ) ] || []; const endingLineIndex = getLineIndex( value, end ); const lastChildIndex = getLastChildIndex( value, endingLineIndex ); @@ -39,20 +39,20 @@ export function outdentListItems( value ) { } // In the case of level 0, the formats at the index are undefined. - const currentFormats = newFormats[ index ] || []; + const currentFormats = newLines[ index ] || []; // Omit the indentation level where the selection starts. - newFormats[ index ] = parentFormats.concat( + newLines[ index ] = parentFormats.concat( currentFormats.slice( parentFormats.length + 1 ) ); - if ( newFormats[ index ].length === 0 ) { - delete newFormats[ index ]; + if ( newLines[ index ].length === 0 ) { + delete newLines[ index ]; } } return normaliseFormats( { ...value, - lineFormats: newFormats, + lines: newLines, } ); } diff --git a/packages/rich-text/src/replace.js b/packages/rich-text/src/replace.js index 788b476e42f962..eabe4ae1778130 100644 --- a/packages/rich-text/src/replace.js +++ b/packages/rich-text/src/replace.js @@ -20,7 +20,7 @@ import { normaliseFormats } from './normalise-formats'; * * @return {Object} A new value with replacements applied. */ -export function replace( { formats, lineFormats, objects, text, start, end }, pattern, replacement ) { +export function replace( { formats, lines, objects, text, start, end }, pattern, replacement ) { text = text.replace( pattern, ( match, ...rest ) => { const offset = rest[ rest.length - 2 ]; let newText = replacement; @@ -45,7 +45,7 @@ export function replace( { formats, lineFormats, objects, text, start, end }, pa } formats = formats.slice( 0, offset ).concat( newFormats, formats.slice( offset + match.length ) ); - lineFormats = lineFormats.slice( 0, offset ).concat( Array( newText.length ), lineFormats.slice( offset + match.length ) ); + lines = lines.slice( 0, offset ).concat( Array( newText.length ), lines.slice( offset + match.length ) ); objects = objects.slice( 0, offset ).concat( newObjects, objects.slice( offset + match.length ) ); if ( start ) { @@ -55,5 +55,5 @@ export function replace( { formats, lineFormats, objects, text, start, end }, pa return newText; } ); - return normaliseFormats( { formats, lineFormats, objects, text, start, end } ); + return normaliseFormats( { formats, lines, objects, text, start, end } ); } diff --git a/packages/rich-text/src/slice.js b/packages/rich-text/src/slice.js index 25323946a7264d..09b5ce9a1d08de 100644 --- a/packages/rich-text/src/slice.js +++ b/packages/rich-text/src/slice.js @@ -14,7 +14,7 @@ export function slice( startIndex = value.start, endIndex = value.end ) { - const { formats, lineFormats, objects, text } = value; + const { formats, lines, objects, text } = value; if ( startIndex === undefined || endIndex === undefined ) { return { ...value }; @@ -22,7 +22,7 @@ export function slice( return { formats: formats.slice( startIndex, endIndex ), - lineFormats: lineFormats.slice( startIndex, endIndex ), + lines: lines.slice( startIndex, endIndex ), objects: objects.slice( startIndex, endIndex ), text: text.slice( startIndex, endIndex ), }; diff --git a/packages/rich-text/src/split.js b/packages/rich-text/src/split.js index 030cbe5ad74cb0..70db0bad6269a0 100644 --- a/packages/rich-text/src/split.js +++ b/packages/rich-text/src/split.js @@ -15,7 +15,7 @@ import { replace } from './replace'; * * @return {Array} An array of new values. */ -export function split( { formats, lineFormats, objects, text, start, end }, string ) { +export function split( { formats, lines, objects, text, start, end }, string ) { if ( typeof string !== 'string' ) { return splitAtSelection( ...arguments ); } @@ -26,7 +26,7 @@ export function split( { formats, lineFormats, objects, text, start, end }, stri const startIndex = nextStart; const value = { formats: formats.slice( startIndex, startIndex + substring.length ), - lineFormats: lineFormats.slice( startIndex, startIndex + substring.length ), + lines: lines.slice( startIndex, startIndex + substring.length ), objects: objects.slice( startIndex, startIndex + substring.length ), text: substring, }; @@ -52,19 +52,19 @@ export function split( { formats, lineFormats, objects, text, start, end }, stri } function splitAtSelection( - { formats, lineFormats, objects, text, start, end }, + { formats, lines, objects, text, start, end }, startIndex = start, endIndex = end ) { const before = { formats: formats.slice( 0, startIndex ), - lineFormats: lineFormats.slice( 0, startIndex ), + lines: lines.slice( 0, startIndex ), objects: objects.slice( 0, startIndex ), text: text.slice( 0, startIndex ), }; const after = { formats: formats.slice( endIndex ), - lineFormats: lineFormats.slice( endIndex ), + lines: lines.slice( endIndex ), objects: objects.slice( endIndex ), text: text.slice( endIndex ), start: 0, diff --git a/packages/rich-text/src/test/change-list-type.js b/packages/rich-text/src/test/change-list-type.js index bfbf209f029be0..0896d66b62f7d1 100644 --- a/packages/rich-text/src/test/change-list-type.js +++ b/packages/rich-text/src/test/change-list-type.js @@ -18,7 +18,7 @@ describe( 'changeListType', () => { it( 'should only change list type if list item is indented', () => { const record = { formats: [], - lineFormats: [ , ], + lines: [ , ], text: '1', start: 1, end: 1, @@ -27,26 +27,26 @@ describe( 'changeListType', () => { expect( result ).toEqual( record ); expect( result ).toBe( record ); - expect( getSparseArrayLength( result.lineFormats ) ).toBe( 0 ); + expect( getSparseArrayLength( result.lines ) ).toBe( 0 ); } ); it( 'should change list type', () => { const record = { formats: [], - lineFormats: [ , [ ul ] ], + lines: [ , [ ul ] ], text: `1${ LINE_SEPARATOR }`, start: 2, end: 2, }; const expected = { ...record, - lineFormats: [ , [ ol ] ], + lines: [ , [ ol ] ], }; const result = changeListType( deepFreeze( record ), ol ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.lineFormats ) ).toBe( 1 ); + expect( getSparseArrayLength( result.lines ) ).toBe( 1 ); } ); it( 'should outdent with multiple lines selected', () => { @@ -55,19 +55,19 @@ describe( 'changeListType', () => { const record = { formats: [], - lineFormats: [ , [ ul ], , [ ul ], , [ ul, ul ], , [ ul ], , [ ul ], , , , [ ul ], , ], + lines: [ , [ ul ], , [ ul ], , [ ul, ul ], , [ ul ], , [ ul ], , , , [ ul ], , ], text, start: 4, end: 9, }; const expected = { ...record, - lineFormats: [ , [ ol ], , [ ol ], , [ ol, ul ], , [ ol ], , [ ol ], , , , [ ul ], , ], + lines: [ , [ ol ], , [ ol ], , [ ol, ul ], , [ ol ], , [ ol ], , , , [ ul ], , ], }; const result = changeListType( deepFreeze( record ), ol ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.lineFormats ) ).toBe( 6 ); + expect( getSparseArrayLength( result.lines ) ).toBe( 6 ); } ); } ); diff --git a/packages/rich-text/src/test/concat.js b/packages/rich-text/src/test/concat.js index 5ca3e4b3225137..f7f5ea1bf73710 100644 --- a/packages/rich-text/src/test/concat.js +++ b/packages/rich-text/src/test/concat.js @@ -16,19 +16,19 @@ describe( 'concat', () => { it( 'should merge records', () => { const one = { formats: [ , , [ em ] ], - lineFormats: [ , , , ], + lines: [ , , , ], objects: [ , , , ], text: 'one', }; const two = { formats: [ [ em ], , , ], - lineFormats: [ , , , ], + lines: [ , , , ], objects: [ , , , ], text: 'two', }; const three = { formats: [ , , [ em ], [ em ], , , ], - lineFormats: [ , , , , , , ], + lines: [ , , , , , , ], objects: [ , , , , , , ], text: 'onetwo', }; diff --git a/packages/rich-text/src/test/create.js b/packages/rich-text/src/test/create.js index 795c66e109df2f..83b81b121de872 100644 --- a/packages/rich-text/src/test/create.js +++ b/packages/rich-text/src/test/create.js @@ -81,7 +81,7 @@ describe( 'create', () => { expect( value ).toEqual( { formats: [ [ em ], [ em ], [ em, strong ], [ em, strong ] ], - lineFormats: [ , , , , ], + lines: [ , , , , ], objects: [ , , , , ], text: 'test', } ); diff --git a/packages/rich-text/src/test/get-last-child-index.js b/packages/rich-text/src/test/get-last-child-index.js index e3b4a8b2ac6719..43f88044b160d0 100644 --- a/packages/rich-text/src/test/get-last-child-index.js +++ b/packages/rich-text/src/test/get-last-child-index.js @@ -15,35 +15,35 @@ describe( 'getLastChildIndex', () => { it( 'should return undefined if there is only one line', () => { expect( getLastChildIndex( deepFreeze( { - lineFormats: [ , ], + lines: [ , ], text: '1', } ), undefined ) ).toBe( undefined ); } ); it( 'should return the last line if no line is indented', () => { expect( getLastChildIndex( deepFreeze( { - lineFormats: [ , ], + lines: [ , ], text: `1${ LINE_SEPARATOR }`, } ), undefined ) ).toBe( 1 ); } ); it( 'should return the last child index', () => { expect( getLastChildIndex( deepFreeze( { - lineFormats: [ , [ ul ], , [ ul ], , ], + lines: [ , [ ul ], , [ ul ], , ], text: `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`, } ), undefined ) ).toBe( 3 ); } ); it( 'should return the last child index by sibling', () => { expect( getLastChildIndex( deepFreeze( { - lineFormats: [ , [ ul ], , [ ul ], , ], + lines: [ , [ ul ], , [ ul ], , ], text: `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`, } ), 1 ) ).toBe( 3 ); } ); it( 'should return the last child index (with further lower indented items)', () => { expect( getLastChildIndex( deepFreeze( { - lineFormats: [ , [ ul ], , , , ], + lines: [ , [ ul ], , , , ], text: `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`, } ), 1 ) ).toBe( 1 ); } ); diff --git a/packages/rich-text/src/test/get-parent-line-index.js b/packages/rich-text/src/test/get-parent-line-index.js index 00bf7b70af4c0d..cad9580b70d088 100644 --- a/packages/rich-text/src/test/get-parent-line-index.js +++ b/packages/rich-text/src/test/get-parent-line-index.js @@ -15,28 +15,28 @@ describe( 'getParentLineIndex', () => { it( 'should return undefined if there is only one line', () => { expect( getParentLineIndex( deepFreeze( { - lineFormats: [ , ], + lines: [ , ], text: '1', } ), undefined ) ).toBe( undefined ); } ); it( 'should return undefined if the list is part of the first root list child', () => { expect( getParentLineIndex( deepFreeze( { - lineFormats: [ , ], + lines: [ , ], text: `1${ LINE_SEPARATOR }2`, } ), 2 ) ).toBe( undefined ); } ); it( 'should return the line index of the parent list (1)', () => { expect( getParentLineIndex( deepFreeze( { - lineFormats: [ , , , [ ul ], , ], + lines: [ , , , [ ul ], , ], text: `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`, } ), 3 ) ).toBe( 1 ); } ); it( 'should return the line index of the parent list (2)', () => { expect( getParentLineIndex( deepFreeze( { - lineFormats: [ , [ ul ], , [ ul, ul ], , [ ul ], , ], + lines: [ , [ ul ], , [ ul, ul ], , [ ul ], , ], text: `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3${ LINE_SEPARATOR }4`, } ), 5 ) ).toBe( undefined ); } ); diff --git a/packages/rich-text/src/test/helpers/index.js b/packages/rich-text/src/test/helpers/index.js index e80b053a4f8015..0769d14fb6c413 100644 --- a/packages/rich-text/src/test/helpers/index.js +++ b/packages/rich-text/src/test/helpers/index.js @@ -25,7 +25,7 @@ export const spec = [ start: 0, end: 0, formats: [], - lineFormats: [], + lines: [], objects: [], text: '', }, @@ -45,7 +45,7 @@ export const spec = [ start: 0, end: 1, formats: [ , ], - lineFormats: [ , ], + lines: [ , ], objects: [ , ], text: ' ', }, @@ -65,7 +65,7 @@ export const spec = [ start: 5, end: 5, formats: [ , , , , , , , , , , ], - lineFormats: [ , , , , , , , , , , ], + lines: [ , , , , , , , , , , ], objects: [ , , , , , , , , , , ], text: 'test\u00a0 test', }, @@ -85,7 +85,7 @@ export const spec = [ start: 0, end: 0, formats: [], - lineFormats: [], + lines: [], objects: [], text: '', }, @@ -105,7 +105,7 @@ export const spec = [ start: 0, end: 4, formats: [ , , , , ], - lineFormats: [ , , , , ], + lines: [ , , , , ], objects: [ , , , , ], text: 'test', }, @@ -125,7 +125,7 @@ export const spec = [ start: 0, end: 2, formats: [ , , ], - lineFormats: [ , , ], + lines: [ , , ], objects: [ , , ], text: '🍒', }, @@ -145,7 +145,7 @@ export const spec = [ start: 0, end: 2, formats: [ [ em ], [ em ] ], - lineFormats: [ , , ], + lines: [ , , ], objects: [ , , ], text: '🍒', }, @@ -165,7 +165,7 @@ export const spec = [ start: 0, end: 4, formats: [ [ em ], [ em ], [ em ], [ em ] ], - lineFormats: [ , , , , ], + lines: [ , , , , ], objects: [ , , , , ], text: 'test', }, @@ -185,7 +185,7 @@ export const spec = [ start: 0, end: 4, formats: [ [ em, strong ], [ em, strong ], [ em, strong ], [ em, strong ] ], - lineFormats: [ , , , , ], + lines: [ , , , , ], objects: [ , , , , ], text: 'test', }, @@ -205,7 +205,7 @@ export const spec = [ start: 0, end: 2, formats: [ [ em ], [ em ], [ em ], [ em ] ], - lineFormats: [ , , , , ], + lines: [ , , , , ], objects: [ , , , , ], text: 'test', }, @@ -225,7 +225,7 @@ export const spec = [ start: 0, end: 4, formats: [ [ a ], [ a ], [ a ], [ a ] ], - lineFormats: [ , , , , ], + lines: [ , , , , ], objects: [ , , , , ], text: 'test', }, @@ -245,7 +245,7 @@ export const spec = [ start: 0, end: 0, formats: [ , ], - lineFormats: [ , ], + lines: [ , ], objects: [ img ], text: '\ufffc', }, @@ -265,7 +265,7 @@ export const spec = [ start: 0, end: 1, formats: [ [ em ] ], - lineFormats: [ , ], + lines: [ , ], objects: [ img ], text: '\ufffc', }, @@ -285,7 +285,7 @@ export const spec = [ start: 0, end: 5, formats: [ , , [ em ], [ em ], [ em ] ], - lineFormats: [ , , , , , ], + lines: [ , , , , , ], objects: [ , , , , img ], text: 'test\ufffc', }, @@ -305,7 +305,7 @@ export const spec = [ start: 0, end: 5, formats: [ [ em ], [ em ], [ em ], , , ], - lineFormats: [ , , , , , ], + lines: [ , , , , , ], objects: [ img, , , , , ], text: '\ufffctest', }, @@ -325,7 +325,7 @@ export const spec = [ start: 0, end: 0, formats: [ , ], - lineFormats: [ , ], + lines: [ , ], objects: [ , ], text: '\n', }, @@ -345,7 +345,7 @@ export const spec = [ start: 2, end: 3, formats: [ , , , , , ], - lineFormats: [ , , , , , ], + lines: [ , , , , , ], objects: [ , , , , , ], text: 'te\nst', }, @@ -365,7 +365,7 @@ export const spec = [ start: 0, end: 1, formats: [ [ em ] ], - lineFormats: [ , ], + lines: [ , ], objects: [ , ], text: '\n', }, @@ -383,7 +383,7 @@ export const spec = [ endPath: [ 4, 0 ], record: { formats: [ , , , , ], - lineFormats: [ , , , , ], + lines: [ , , , , ], objects: [ , , , , ], text: 'a\n\nb', start: 2, @@ -403,7 +403,7 @@ export const spec = [ endPath: [ 2, 0 ], record: { formats: [ , , , , ], - lineFormats: [ , , , , ], + lines: [ , , , , ], objects: [ , , , , ], text: 'a\n\nb', start: 2, @@ -426,7 +426,7 @@ export const spec = [ start: 0, end: 0, formats: [], - lineFormats: [], + lines: [], objects: [], text: '', }, @@ -447,7 +447,7 @@ export const spec = [ start: 1, end: 4, formats: [ , , , , , , , ], - lineFormats: [ , , , , , , , ], + lines: [ , , , , , , , ], objects: [ , , , , , , , ], text: 'one\u2028two', }, @@ -469,7 +469,7 @@ export const spec = [ start: 0, end: 9, formats: [ , , , , , , , , , , , , , , , , , ], - lineFormats: [ , , , [ ul ], , [ ul ], , [ ul, ol ], , [ ul, ol ], , , , , , , , ], + lines: [ , , , [ ul ], , [ ul ], , [ ul, ol ], , [ ul, ol ], , , , , , , , ], objects: [ , , , , , , , , , , , , , , , , , ], text: 'one\u2028a\u2028b\u20281\u20282\u2028three', }, @@ -491,7 +491,7 @@ export const spec = [ start: 0, end: 0, formats: [], - lineFormats: [], + lines: [], objects: [], text: '', }, @@ -513,7 +513,7 @@ export const spec = [ start: 1, end: 1, formats: [ , ], - lineFormats: [ [ ul ] ], + lines: [ [ ul ] ], objects: [ , ], text: '\u2028', }, @@ -535,7 +535,7 @@ export const spec = [ start: 1, end: 1, formats: [ , , ], - lineFormats: [ , , ], + lines: [ , , ], objects: [ , , ], text: '\u2028\u2028', }, @@ -556,7 +556,7 @@ export const spec = [ start: 4, end: 4, formats: [ , , , , ], - lineFormats: [ , , , , ], + lines: [ , , , , ], objects: [ , , , , ], text: 'one\u2028', }, @@ -578,7 +578,7 @@ export const spec = [ start: 3, end: 3, formats: [ , , , ], - lineFormats: [ , , , ], + lines: [ , , , ], objects: [ , , , ], text: 'one', }, @@ -590,7 +590,7 @@ export const spec = [ endPath: [], record: { formats: [ [ em ], [ em ], [ em ], [ em ], [ em ], [ em ], [ em ] ], - lineFormats: [ , , , , , , , ], + lines: [ , , , , , , , ], objects: [ , , , , , , , ], text: 'one\u2028two', }, @@ -610,7 +610,7 @@ export const spec = [ start: 0, end: 0, formats: [], - lineFormats: [], + lines: [], objects: [], text: '', }, @@ -630,7 +630,7 @@ export const spec = [ start: 0, end: 4, formats: [ [ strong ], [ strong ], [ strong ], [ strong ] ], - lineFormats: [ , , , , ], + lines: [ , , , , ], objects: [ , , , , ], text: 'test', }, @@ -654,7 +654,7 @@ export const specWithRegistration = [ attributes: {}, unregisteredAttributes: {}, } ] ], - lineFormats: [ , ], + lines: [ , ], objects: [ , ], text: 'a', }, @@ -677,7 +677,7 @@ export const specWithRegistration = [ class: 'test', }, } ] ], - lineFormats: [ , ], + lines: [ , ], objects: [ , ], text: 'a', }, @@ -700,7 +700,7 @@ export const specWithRegistration = [ class: 'custom-format', }, } ] ], - lineFormats: [ , ], + lines: [ , ], objects: [ , ], text: 'a', }, @@ -715,7 +715,7 @@ export const specWithRegistration = [ class: 'custom-format', }, } ] ], - lineFormats: [ , ], + lines: [ , ], objects: [ , ], text: 'a', }, diff --git a/packages/rich-text/src/test/indent-list-items.js b/packages/rich-text/src/test/indent-list-items.js index 0e812c360d866c..c59afcad192209 100644 --- a/packages/rich-text/src/test/indent-list-items.js +++ b/packages/rich-text/src/test/indent-list-items.js @@ -18,7 +18,7 @@ describe( 'indentListItems', () => { it( 'should not indent only item', () => { const record = { formats: [ , ], - lineFormats: [ , ], + lines: [ , ], objects: [ , ], text: '1', start: 1, @@ -28,7 +28,7 @@ describe( 'indentListItems', () => { expect( result ).toEqual( record ); expect( result ).toBe( record ); - expect( getSparseArrayLength( result.lineFormats ) ).toBe( 0 ); + expect( getSparseArrayLength( result.lines ) ).toBe( 0 ); } ); it( 'should indent', () => { @@ -36,7 +36,7 @@ describe( 'indentListItems', () => { const text = `1${ LINE_SEPARATOR }`; const record = { formats: [ , , ], - lineFormats: [ , , ], + lines: [ , , ], objects: [ , , ], text, start: 2, @@ -44,19 +44,19 @@ describe( 'indentListItems', () => { }; const expected = { ...record, - lineFormats: [ , [ ul ] ], + lines: [ , [ ul ] ], }; const result = indentListItems( deepFreeze( record ), ul ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.lineFormats ) ).toBe( 1 ); + expect( getSparseArrayLength( result.lines ) ).toBe( 1 ); } ); it( 'should not indent without target list', () => { const record = { formats: [ , , ], - lineFormats: [ , [ ul ] ], + lines: [ , [ ul ] ], objects: [ , , ], text: `1${ LINE_SEPARATOR }`, start: 2, @@ -66,7 +66,7 @@ describe( 'indentListItems', () => { expect( result ).toEqual( record ); expect( result ).toBe( record ); - expect( getSparseArrayLength( result.lineFormats ) ).toBe( 1 ); + expect( getSparseArrayLength( result.lines ) ).toBe( 1 ); } ); it( 'should indent and merge with previous list', () => { @@ -74,7 +74,7 @@ describe( 'indentListItems', () => { const text = `1${ LINE_SEPARATOR }${ LINE_SEPARATOR }`; const record = { formats: [ , , , ], - lineFormats: [ , [ ol ], , ], + lines: [ , [ ol ], , ], objects: [ , , , ], text, start: 3, @@ -82,13 +82,13 @@ describe( 'indentListItems', () => { }; const expected = { ...record, - lineFormats: [ , [ ol ], [ ol ] ], + lines: [ , [ ol ], [ ol ] ], }; const result = indentListItems( deepFreeze( record ), ul ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.lineFormats ) ).toBe( 2 ); + expect( getSparseArrayLength( result.lines ) ).toBe( 2 ); } ); it( 'should indent already indented item', () => { @@ -96,7 +96,7 @@ describe( 'indentListItems', () => { const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`; const record = { formats: [ , , , , , ], - lineFormats: [ , [ ul ], , [ ul ], , ], + lines: [ , [ ul ], , [ ul ], , ], objects: [ , , , , , ], text, start: 5, @@ -104,13 +104,13 @@ describe( 'indentListItems', () => { }; const expected = { ...record, - lineFormats: [ , [ ul ], , [ ul, ul ], , ], + lines: [ , [ ul ], , [ ul, ul ], , ], }; const result = indentListItems( deepFreeze( record ), ul ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.lineFormats ) ).toBe( 2 ); + expect( getSparseArrayLength( result.lines ) ).toBe( 2 ); } ); it( 'should indent with multiple lines selected', () => { @@ -118,7 +118,7 @@ describe( 'indentListItems', () => { const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`; const record = { formats: [ , , , , , ], - lineFormats: [ , , , [ ul ], , ], + lines: [ , , , [ ul ], , ], objects: [ , , , , , ], text, start: 2, @@ -126,13 +126,13 @@ describe( 'indentListItems', () => { }; const expected = { ...record, - lineFormats: [ , [ ul ], , [ ul, ul ], , ], + lines: [ , [ ul ], , [ ul, ul ], , ], }; const result = indentListItems( deepFreeze( record ), ul ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.lineFormats ) ).toBe( 2 ); + expect( getSparseArrayLength( result.lines ) ).toBe( 2 ); } ); it( 'should indent one level at a time', () => { @@ -140,7 +140,7 @@ describe( 'indentListItems', () => { const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3${ LINE_SEPARATOR }4`; const record = { formats: Array( text.length ), - lineFormats: [ , [ ul ], , [ ul, ul ], , , , ], + lines: [ , [ ul ], , [ ul, ul ], , , , ], objects: Array( text.length ), text, start: 6, @@ -150,28 +150,28 @@ describe( 'indentListItems', () => { const result1 = indentListItems( deepFreeze( record ), ul ); expect( result1 ).not.toBe( record ); - expect( getSparseArrayLength( result1.lineFormats ) ).toBe( 3 ); + expect( getSparseArrayLength( result1.lines ) ).toBe( 3 ); expect( result1 ).toEqual( { ...record, - lineFormats: [ , [ ul ], , [ ul, ul ], , [ ul ], , ], + lines: [ , [ ul ], , [ ul, ul ], , [ ul ], , ], } ); const result2 = indentListItems( deepFreeze( result1 ), ul ); expect( result2 ).not.toBe( result1 ); - expect( getSparseArrayLength( result2.lineFormats ) ).toBe( 3 ); + expect( getSparseArrayLength( result2.lines ) ).toBe( 3 ); expect( result2 ).toEqual( { ...record, - lineFormats: [ , [ ul ], , [ ul, ul ], , [ ul, ul ], , ], + lines: [ , [ ul ], , [ ul, ul ], , [ ul, ul ], , ], } ); const result3 = indentListItems( deepFreeze( result2 ), ul ); expect( result3 ).not.toBe( result2 ); - expect( getSparseArrayLength( result3.lineFormats ) ).toBe( 3 ); + expect( getSparseArrayLength( result3.lines ) ).toBe( 3 ); expect( result3 ).toEqual( { ...record, - lineFormats: [ , [ ul ], , [ ul, ul ], , [ ul, ul, ul ], , ], + lines: [ , [ ul ], , [ ul, ul ], , [ ul, ul, ul ], , ], } ); } ); } ); diff --git a/packages/rich-text/src/test/insert-line-separator.js b/packages/rich-text/src/test/insert-line-separator.js index 6512f8bbb3526f..5b79e492eaef15 100644 --- a/packages/rich-text/src/test/insert-line-separator.js +++ b/packages/rich-text/src/test/insert-line-separator.js @@ -17,7 +17,7 @@ describe( 'insertLineSeparator', () => { it( 'should insert line separator at end', () => { const value = { formats: [ , ], - lineFormats: [ , ], + lines: [ , ], objects: [ , ], text: '1', start: 1, @@ -25,7 +25,7 @@ describe( 'insertLineSeparator', () => { }; const expected = { formats: [ , , ], - lineFormats: [ , , ], + lines: [ , , ], objects: [ , , ], text: `1${ LINE_SEPARATOR }`, start: 2, @@ -35,13 +35,13 @@ describe( 'insertLineSeparator', () => { expect( result ).not.toBe( value ); expect( result ).toEqual( expected ); - expect( getSparseArrayLength( result.lineFormats ) ).toBe( 0 ); + expect( getSparseArrayLength( result.lines ) ).toBe( 0 ); } ); it( 'should insert line separator at start', () => { const value = { formats: [ , ], - lineFormats: [ , ], + lines: [ , ], objects: [ , ], text: '1', start: 0, @@ -49,7 +49,7 @@ describe( 'insertLineSeparator', () => { }; const expected = { formats: [ , , ], - lineFormats: [ , , ], + lines: [ , , ], objects: [ , , ], text: `${ LINE_SEPARATOR }1`, start: 1, @@ -59,13 +59,13 @@ describe( 'insertLineSeparator', () => { expect( result ).not.toBe( value ); expect( result ).toEqual( expected ); - expect( getSparseArrayLength( result.lineFormats ) ).toBe( 0 ); + expect( getSparseArrayLength( result.lines ) ).toBe( 0 ); } ); it( 'should insert line separator with previous line separator formats', () => { const value = { formats: [ , , , , , ], - lineFormats: [ , , , [ ol ], , ], + lines: [ , , , [ ol ], , ], objects: [ , , , , , ], text: `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }a`, start: 5, @@ -73,7 +73,7 @@ describe( 'insertLineSeparator', () => { }; const expected = { formats: [ , , , , , , ], - lineFormats: [ , , , [ ol ], , [ ol ] ], + lines: [ , , , [ ol ], , [ ol ] ], objects: [ , , , , , , ], text: `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }a${ LINE_SEPARATOR }`, start: 6, @@ -83,13 +83,13 @@ describe( 'insertLineSeparator', () => { expect( result ).not.toBe( value ); expect( result ).toEqual( expected ); - expect( getSparseArrayLength( result.lineFormats ) ).toBe( 2 ); + expect( getSparseArrayLength( result.lines ) ).toBe( 2 ); } ); it( 'should insert line separator without formats if previous line separator did not have any', () => { const value = { formats: [ , , , , , ], - lineFormats: [ , , , , , ], + lines: [ , , , , , ], objects: [ , , , , , ], text: `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }a`, start: 5, @@ -97,7 +97,7 @@ describe( 'insertLineSeparator', () => { }; const expected = { formats: [ , , , , , , ], - lineFormats: [ , , , , , , ], + lines: [ , , , , , , ], objects: [ , , , , , , ], text: `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }a${ LINE_SEPARATOR }`, start: 6, @@ -107,6 +107,6 @@ describe( 'insertLineSeparator', () => { expect( result ).not.toBe( value ); expect( result ).toEqual( expected ); - expect( getSparseArrayLength( result.lineFormats ) ).toBe( 0 ); + expect( getSparseArrayLength( result.lines ) ).toBe( 0 ); } ); } ); diff --git a/packages/rich-text/src/test/insert-object.js b/packages/rich-text/src/test/insert-object.js index daee49543cbd0f..e835cc9f1a9b73 100644 --- a/packages/rich-text/src/test/insert-object.js +++ b/packages/rich-text/src/test/insert-object.js @@ -17,7 +17,7 @@ describe( 'insert', () => { it( 'should delete and insert', () => { const record = { formats: [ , , , , [ em ], [ em ], [ em ], , , , , , , ], - lineFormats: [ , , , , , , , , , , , , , ], + lines: [ , , , , , , , , , , , , , ], objects: [ , , , , , , , , , , , , , ], text: 'one two three', start: 6, @@ -25,7 +25,7 @@ describe( 'insert', () => { }; const expected = { formats: [ , , , [ em ], , , , , , , ], - lineFormats: [ , , , , , , , , , , ], + lines: [ , , , , , , , , , , ], objects: [ , , obj, , , , , , , , ], text: `on${ OBJECT_REPLACEMENT_CHARACTER }o three`, start: 3, diff --git a/packages/rich-text/src/test/insert.js b/packages/rich-text/src/test/insert.js index f5dabca196f254..b22747210bcbfe 100644 --- a/packages/rich-text/src/test/insert.js +++ b/packages/rich-text/src/test/insert.js @@ -17,7 +17,7 @@ describe( 'insert', () => { it( 'should delete and insert', () => { const record = { formats: [ , , , , [ em ], [ em ], [ em ], , , , , , , ], - lineFormats: [], + lines: [], objects: [], text: 'one two three', start: 6, @@ -25,13 +25,13 @@ describe( 'insert', () => { }; const toInsert = { formats: [ [ strong ] ], - lineFormats: [], + lines: [], objects: [], text: 'a', }; const expected = { formats: [ , , [ strong ], [ em ], , , , , , , ], - lineFormats: [], + lines: [], objects: [], text: 'onao three', start: 3, @@ -47,7 +47,7 @@ describe( 'insert', () => { it( 'should insert line break with selection', () => { const record = { formats: [ , , ], - lineFormats: [], + lines: [], objects: [], text: 'tt', start: 1, @@ -55,13 +55,13 @@ describe( 'insert', () => { }; const toInsert = { formats: [ , ], - lineFormats: [], + lines: [], objects: [], text: '\n', }; const expected = { formats: [ , , , ], - lineFormats: [], + lines: [], objects: [], text: 't\nt', start: 2, diff --git a/packages/rich-text/src/test/join.js b/packages/rich-text/src/test/join.js index df4b4a73b30f81..6f7f681dec1bf8 100644 --- a/packages/rich-text/src/test/join.js +++ b/packages/rich-text/src/test/join.js @@ -16,7 +16,7 @@ describe( 'join', () => { ' ', { formats: [ , ], - lineFormats: [ , ], + lines: [ , ], objects: [ , ], text: ' ', }, @@ -26,19 +26,19 @@ describe( 'join', () => { it( 'should join records with string separator', () => { const one = { formats: [ , , [ em ] ], - lineFormats: [ , , , ], + lines: [ , , , ], objects: [ , , , ], text: 'one', }; const two = { formats: [ [ em ], , , ], - lineFormats: [ , , , ], + lines: [ , , , ], objects: [ , , , ], text: 'two', }; const three = { formats: [ , , [ em ], , [ em ], , , ], - lineFormats: [ , , , , , , , ], + lines: [ , , , , , , , ], objects: [ , , , , , , , ], text: 'one two', }; diff --git a/packages/rich-text/src/test/outdent-list-items.js b/packages/rich-text/src/test/outdent-list-items.js index 5258be43a54b8e..3ef8091e148400 100644 --- a/packages/rich-text/src/test/outdent-list-items.js +++ b/packages/rich-text/src/test/outdent-list-items.js @@ -17,7 +17,7 @@ describe( 'outdentListItems', () => { it( 'should not outdent only item', () => { const record = { formats: [ , ], - lineFormats: [ , ], + lines: [ , ], objects: [ , ], text: '1', start: 1, @@ -27,7 +27,7 @@ describe( 'outdentListItems', () => { expect( result ).toEqual( record ); expect( result ).toBe( record ); - expect( getSparseArrayLength( result.lineFormats ) ).toBe( 0 ); + expect( getSparseArrayLength( result.lines ) ).toBe( 0 ); } ); it( 'should indent', () => { @@ -35,7 +35,7 @@ describe( 'outdentListItems', () => { const text = `1${ LINE_SEPARATOR }`; const record = { formats: Array( text.length ), - lineFormats: [ , [ ul ] ], + lines: [ , [ ul ] ], objects: Array( text.length ), text, start: 2, @@ -43,13 +43,13 @@ describe( 'outdentListItems', () => { }; const expected = { ...record, - lineFormats: [ , , ], + lines: [ , , ], }; const result = outdentListItems( deepFreeze( record ) ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.lineFormats ) ).toBe( 0 ); + expect( getSparseArrayLength( result.lines ) ).toBe( 0 ); } ); it( 'should outdent two levels deep', () => { @@ -57,7 +57,7 @@ describe( 'outdentListItems', () => { const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`; const record = { formats: Array( text.length ), - lineFormats: [ , [ ul ], , [ ul, ul ], , ], + lines: [ , [ ul ], , [ ul, ul ], , ], objects: Array( text.length ), text, start: 5, @@ -65,13 +65,13 @@ describe( 'outdentListItems', () => { }; const expected = { ...record, - lineFormats: [ , [ ul ], , [ ul ], , ], + lines: [ , [ ul ], , [ ul ], , ], }; const result = outdentListItems( deepFreeze( record ) ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.lineFormats ) ).toBe( 2 ); + expect( getSparseArrayLength( result.lines ) ).toBe( 2 ); } ); it( 'should outdent with multiple lines selected', () => { @@ -79,7 +79,7 @@ describe( 'outdentListItems', () => { const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`; const record = { formats: Array( text.length ), - lineFormats: [ , [ ul ], , [ ul, ul ], , ], + lines: [ , [ ul ], , [ ul, ul ], , ], objects: Array( text.length ), text, start: 2, @@ -87,13 +87,13 @@ describe( 'outdentListItems', () => { }; const expected = { ...record, - lineFormats: [ , , , [ ul ], , ], + lines: [ , , , [ ul ], , ], }; const result = outdentListItems( deepFreeze( record ) ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.lineFormats ) ).toBe( 1 ); + expect( getSparseArrayLength( result.lines ) ).toBe( 1 ); } ); it( 'should outdent list item with children', () => { @@ -101,7 +101,7 @@ describe( 'outdentListItems', () => { const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3${ LINE_SEPARATOR }4`; const record = { formats: Array( text.length ), - lineFormats: [ , [ ul ], , [ ul, ul ], , [ ul, ul ], , ], + lines: [ , [ ul ], , [ ul, ul ], , [ ul, ul ], , ], objects: Array( text.length ), text, start: 2, @@ -109,13 +109,13 @@ describe( 'outdentListItems', () => { }; const expected = { ...record, - lineFormats: [ , , , [ ul ], , [ ul ], , ], + lines: [ , , , [ ul ], , [ ul ], , ], }; const result = outdentListItems( deepFreeze( record ) ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.lineFormats ) ).toBe( 2 ); + expect( getSparseArrayLength( result.lines ) ).toBe( 2 ); } ); it( 'should outdent list based on parent list', () => { @@ -123,7 +123,7 @@ describe( 'outdentListItems', () => { const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3${ LINE_SEPARATOR }4`; const record = { formats: Array( text.length ), - lineFormats: [ , [ ul ], , [ ul, ul ], , [ ul ], , ], + lines: [ , [ ul ], , [ ul, ul ], , [ ul ], , ], objects: Array( text.length ), text, start: 6, @@ -131,13 +131,13 @@ describe( 'outdentListItems', () => { }; const expected = { ...record, - lineFormats: [ , [ ul ], , [ ul, ul ], , , , ], + lines: [ , [ ul ], , [ ul, ul ], , , , ], }; const result = outdentListItems( deepFreeze( record ) ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.lineFormats ) ).toBe( 2 ); + expect( getSparseArrayLength( result.lines ) ).toBe( 2 ); } ); it( 'should outdent when a selected item is at level 0', () => { @@ -145,7 +145,7 @@ describe( 'outdentListItems', () => { const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`; const record = { formats: Array( text.length ), - lineFormats: [ , [ ul ], , , , ], + lines: [ , [ ul ], , , , ], objects: Array( text.length ), text, start: 2, @@ -153,12 +153,12 @@ describe( 'outdentListItems', () => { }; const expected = { ...record, - lineFormats: [ , , , , , ], + lines: [ , , , , , ], }; const result = outdentListItems( deepFreeze( record ) ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.lineFormats ) ).toBe( 0 ); + expect( getSparseArrayLength( result.lines ) ).toBe( 0 ); } ); } ); diff --git a/packages/rich-text/src/test/replace.js b/packages/rich-text/src/test/replace.js index 2866433982ce87..456a45faa3b5d8 100644 --- a/packages/rich-text/src/test/replace.js +++ b/packages/rich-text/src/test/replace.js @@ -16,7 +16,7 @@ describe( 'replace', () => { it( 'should replace string to string', () => { const record = { formats: [ , , , , [ em ], [ em ], [ em ], , , , , , , ], - lineFormats: [ , , , , , , , , , , , , , ], + lines: [ , , , , , , , , , , , , , ], objects: [ , , , , , , , , , , , , , ], text: 'one two three', start: 6, @@ -24,7 +24,7 @@ describe( 'replace', () => { }; const expected = { formats: [ , , , , [ em ], , , , , , , ], - lineFormats: [ , , , , , , , , , , , ], + lines: [ , , , , , , , , , , , ], objects: [ , , , , , , , , , , , ], text: 'one 2 three', start: 5, @@ -40,7 +40,7 @@ describe( 'replace', () => { it( 'should replace string to record', () => { const record = { formats: [ , , , , [ em ], [ em ], [ em ], , , , , , , ], - lineFormats: [ , , , , , , , , , , , , , ], + lines: [ , , , , , , , , , , , , , ], objects: [ , , , , , , , , , , , , , ], text: 'one two three', start: 6, @@ -48,13 +48,13 @@ describe( 'replace', () => { }; const replacement = { formats: [ , ], - lineFormats: [ , ], + lines: [ , ], objects: [ , ], text: '2', }; const expected = { formats: [ , , , , , , , , , , , ], - lineFormats: [ , , , , , , , , , , , ], + lines: [ , , , , , , , , , , , ], objects: [ , , , , , , , , , , , ], text: 'one 2 three', start: 5, @@ -70,7 +70,7 @@ describe( 'replace', () => { it( 'should replace string to function', () => { const record = { formats: [ , , , , , , , , , , , , ], - lineFormats: [ , , , , , , , , , , , , ], + lines: [ , , , , , , , , , , , , ], objects: [ , , , , , , , , , , , , ], text: 'abc12345#$*%', start: 6, @@ -78,7 +78,7 @@ describe( 'replace', () => { }; const expected = { formats: [ , , , , , , , , , , , , , , , , , , ], - lineFormats: [ , , , , , , , , , , , , , , , , , , ], + lines: [ , , , , , , , , , , , , , , , , , , ], objects: [ , , , , , , , , , , , , , , , , , , ], text: 'abc - 12345 - #$*%', start: 18, diff --git a/packages/rich-text/src/test/slice.js b/packages/rich-text/src/test/slice.js index a658dcff56290e..cfd53a8bf859b5 100644 --- a/packages/rich-text/src/test/slice.js +++ b/packages/rich-text/src/test/slice.js @@ -16,13 +16,13 @@ describe( 'slice', () => { it( 'should slice', () => { const record = { formats: [ , , , , [ em ], [ em ], [ em ], , , , , , , ], - lineFormats: [ , , , , , , , , , , , , , ], + lines: [ , , , , , , , , , , , , , ], objects: [ , , , , , , , , , , , , , ], text: 'one two three', }; const expected = { formats: [ , [ em ], [ em ] ], - lineFormats: [ , , , ], + lines: [ , , , ], objects: [ , , , ], text: ' tw', }; @@ -36,7 +36,7 @@ describe( 'slice', () => { it( 'should slice record', () => { const record = { formats: [ , , , , [ em ], [ em ], [ em ], , , , , , , ], - lineFormats: [ , , , , , , , , , , , , , ], + lines: [ , , , , , , , , , , , , , ], objects: [ , , , , , , , , , , , , , ], text: 'one two three', start: 3, @@ -44,7 +44,7 @@ describe( 'slice', () => { }; const expected = { formats: [ , [ em ], [ em ] ], - lineFormats: [ , , , ], + lines: [ , , , ], objects: [ , , , ], text: ' tw', }; diff --git a/packages/rich-text/src/test/split.js b/packages/rich-text/src/test/split.js index 1d740cab7c11d8..1c82d3fb1a8081 100644 --- a/packages/rich-text/src/test/split.js +++ b/packages/rich-text/src/test/split.js @@ -18,14 +18,14 @@ describe( 'split', () => { start: 5, end: 10, formats: [ , , , , [ em ], [ em ], [ em ], , , , , , , ], - lineFormats: [ , , , , , , , , , , , , , ], + lines: [ , , , , , , , , , , , , , ], objects: [ , , , , , , , , , , , , , ], text: 'one two three', }; const expected = [ { formats: [ , , , , [ em ], [ em ] ], - lineFormats: [ , , , , , , ], + lines: [ , , , , , , ], objects: [ , , , , , , ], text: 'one tw', }, @@ -33,7 +33,7 @@ describe( 'split', () => { start: 0, end: 0, formats: [ [ em ], , , , , , , ], - lineFormats: [ , , , , , , , ], + lines: [ , , , , , , , ], objects: [ , , , , , , , ], text: 'o three', }, @@ -51,7 +51,7 @@ describe( 'split', () => { it( 'should split with selection', () => { const record = { formats: [ , , , , [ em ], [ em ], [ em ], , , , , , , ], - lineFormats: [ , , , , , , , , , , , , , ], + lines: [ , , , , , , , , , , , , , ], objects: [ , , , , , , , , , , , , , ], text: 'one two three', start: 6, @@ -60,13 +60,13 @@ describe( 'split', () => { const expected = [ { formats: [ , , , , [ em ], [ em ] ], - lineFormats: [ , , , , , , ], + lines: [ , , , , , , ], objects: [ , , , , , , ], text: 'one tw', }, { formats: [ [ em ], , , , , , , ], - lineFormats: [ , , , , , , , ], + lines: [ , , , , , , , ], objects: [ , , , , , , , ], text: 'o three', start: 0, @@ -86,7 +86,7 @@ describe( 'split', () => { it( 'should split empty', () => { const record = { formats: [], - lineFormats: [], + lines: [], objects: [], text: '', start: 0, @@ -95,13 +95,13 @@ describe( 'split', () => { const expected = [ { formats: [], - lineFormats: [], + lines: [], objects: [], text: '', }, { formats: [], - lineFormats: [], + lines: [], objects: [], text: '', start: 0, @@ -121,7 +121,7 @@ describe( 'split', () => { it( 'should split multiline', () => { const record = { formats: [ , , , , , , , , , , ], - lineFormats: [ , , , , , , , , , , ], + lines: [ , , , , , , , , , , ], objects: [ , , , , , , , , , , ], text: 'test\u2028\u2028test', start: 5, @@ -130,13 +130,13 @@ describe( 'split', () => { const expected = [ { formats: [ , , , , ], - lineFormats: [ , , , , ], + lines: [ , , , , ], objects: [ , , , , ], text: 'test', }, { formats: [ , , , , ], - lineFormats: [ , , , , ], + lines: [ , , , , ], objects: [ , , , , ], text: 'test', start: 0, @@ -158,14 +158,14 @@ describe( 'split', () => { start: 6, end: 16, formats: [ , , , , [ em ], [ em ], [ em ], , , , , , , , , , , , , , , , , ], - lineFormats: [ , , , , , , , , , , , , , , , , , , , , , , , ], + lines: [ , , , , , , , , , , , , , , , , , , , , , , , ], objects: [ , , , , , , , , , , , , , , , , , , , , , , , ], text: 'one two three four five', }; const expected = [ { formats: [ , , , ], - lineFormats: [ , , , ], + lines: [ , , , ], objects: [ , , , ], text: 'one', }, @@ -173,7 +173,7 @@ describe( 'split', () => { start: 2, end: 3, formats: [ [ em ], [ em ], [ em ] ], - lineFormats: [ , , , ], + lines: [ , , , ], objects: [ , , , ], text: 'two', }, @@ -181,7 +181,7 @@ describe( 'split', () => { start: 0, end: 5, formats: [ , , , , , ], - lineFormats: [ , , , , , ], + lines: [ , , , , , ], objects: [ , , , , , ], text: 'three', }, @@ -189,13 +189,13 @@ describe( 'split', () => { start: 0, end: 2, formats: [ , , , , ], - lineFormats: [ , , , , ], + lines: [ , , , , ], objects: [ , , , , ], text: 'four', }, { formats: [ , , , , ], - lineFormats: [ , , , , ], + lines: [ , , , , ], objects: [ , , , , ], text: 'five', }, @@ -215,14 +215,14 @@ describe( 'split', () => { start: 5, end: 6, formats: [ , , , , [ em ], [ em ], [ em ], , , , , , , ], - lineFormats: [ , , , , , , , , , , , , , ], + lines: [ , , , , , , , , , , , , , ], objects: [ , , , , , , , , , , , , , ], text: 'one two three', }; const expected = [ { formats: [ , , , ], - lineFormats: [ , , , ], + lines: [ , , , ], objects: [ , , , ], text: 'one', }, @@ -230,13 +230,13 @@ describe( 'split', () => { start: 1, end: 2, formats: [ [ em ], [ em ], [ em ] ], - lineFormats: [ , , , ], + lines: [ , , , ], objects: [ , , , ], text: 'two', }, { formats: [ , , , , , ], - lineFormats: [ , , , , , ], + lines: [ , , , , , ], objects: [ , , , , , ], text: 'three', }, diff --git a/packages/rich-text/src/to-tree.js b/packages/rich-text/src/to-tree.js index 81ad1ee062d512..2f949a5cfc69f0 100644 --- a/packages/rich-text/src/to-tree.js +++ b/packages/rich-text/src/to-tree.js @@ -103,7 +103,7 @@ export function toTree( { onEndIndex, isEditableTree, } ) { - const { formats, lineFormats, objects, text, start, end } = value; + const { formats, lines, objects, text, start, end } = value; const formatsLength = formats.length + 1; const tree = createEmpty(); const multilineFormat = { type: multilineTag }; @@ -137,7 +137,7 @@ export function toTree( { // Set multiline tags in queue for building the tree. if ( multilineTag ) { if ( character === LINE_SEPARATOR ) { - characterFormats = lastSeparatorFormats = ( lineFormats[ i ] || [] ).reduce( ( accumulator, format ) => { + characterFormats = lastSeparatorFormats = ( lines[ i ] || [] ).reduce( ( accumulator, format ) => { accumulator.push( format ); accumulator.push( multilineFormat ); return accumulator; From 848650208fe432042321f1b168c7284700bb1b30 Mon Sep 17 00:00:00 2001 From: iseulde Date: Tue, 26 Feb 2019 11:10:12 +0100 Subject: [PATCH 06/18] concatPair => mergePair --- packages/rich-text/src/concat.js | 4 ++-- packages/rich-text/src/create.js | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/rich-text/src/concat.js b/packages/rich-text/src/concat.js index 34cf43a011f8d5..c620b6fd6b23cb 100644 --- a/packages/rich-text/src/concat.js +++ b/packages/rich-text/src/concat.js @@ -14,7 +14,7 @@ import { create } from './create'; * * @return {Object} `a`, mutated. */ -export function concatPair( a, b ) { +export function mergePair( a, b ) { a.formats = a.formats.concat( b.formats ); a.lines = a.lines.concat( b.lines ); a.objects = a.objects.concat( b.objects ); @@ -32,5 +32,5 @@ export function concatPair( a, b ) { * @return {Object} A new value combining all given records. */ export function concat( ...values ) { - return normaliseFormats( values.reduce( concatPair, create() ) ); + return normaliseFormats( values.reduce( mergePair, create() ) ); } diff --git a/packages/rich-text/src/create.js b/packages/rich-text/src/create.js index 9ff8bd608d8997..9c362170b3c2fc 100644 --- a/packages/rich-text/src/create.js +++ b/packages/rich-text/src/create.js @@ -10,7 +10,7 @@ import { select } from '@wordpress/data'; import { isEmpty } from './is-empty'; import { isFormatEqual } from './is-format-equal'; import { createElement } from './create-element'; -import { concatPair } from './concat'; +import { mergePair } from './concat'; import { LINE_SEPARATOR, OBJECT_REPLACEMENT_CHARACTER, @@ -322,7 +322,7 @@ function createFromElement( { if ( type === 'br' ) { accumulateSelection( accumulator, node, range, createEmptyValue() ); - concatPair( accumulator, create( { text: '\n' } ) ); + mergePair( accumulator, create( { text: '\n' } ) ); continue; } @@ -345,7 +345,7 @@ function createFromElement( { } ); accumulateSelection( accumulator, node, range, value ); - concatPair( accumulator, value ); + mergePair( accumulator, value ); continue; } @@ -365,7 +365,7 @@ function createFromElement( { } if ( format.attributes && value.text.length === 0 ) { - concatPair( accumulator, { + mergePair( accumulator, { formats: [ , ], lines: [ , ], objects: [ format ], @@ -374,7 +374,7 @@ function createFromElement( { continue; } - concatPair( accumulator, { + mergePair( accumulator, { ...value, formats: Array.from( value.formats, ( formats ) => formats ? [ format, ...formats ] : [ format ] @@ -436,16 +436,16 @@ function createFromMultilineElement( { // Multiline value text should be separated by a line separator. if ( index !== 0 || currentWrapperTags.length > 0 ) { - const formats = currentWrapperTags.length > 0 ? [ currentWrapperTags ] : [ , ]; - - accumulator.formats.length += 1; - accumulator.lines = accumulator.lines.concat( formats ); - accumulator.objects.length += 1; - accumulator.text += LINE_SEPARATOR; + mergePair( accumulator, { + formats: [ , ], + lines: currentWrapperTags.length > 0 ? [ currentWrapperTags ] : [ , ], + objects: [ , ], + text: LINE_SEPARATOR, + } ); } accumulateSelection( accumulator, node, range, value ); - concatPair( accumulator, value ); + mergePair( accumulator, value ); } return accumulator; From 80ddb029b9a2ac787cb24210dd7093f5f074817b Mon Sep 17 00:00:00 2001 From: iseulde Date: Tue, 26 Feb 2019 11:15:17 +0100 Subject: [PATCH 07/18] Update selectedFormat checks --- packages/block-editor/src/components/rich-text/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/src/components/rich-text/index.js b/packages/block-editor/src/components/rich-text/index.js index 4e71c436467fe9..ff0016954b54fd 100644 --- a/packages/block-editor/src/components/rich-text/index.js +++ b/packages/block-editor/src/components/rich-text/index.js @@ -399,12 +399,12 @@ export class RichText extends Component { if ( this.formatPlaceholder ) { selectedFormat = this.formatPlaceholder.length; - if ( selectedFormat ) { + if ( selectedFormat > 0 ) { formats[ this.state.start ] = this.formatPlaceholder; } else { delete formats[ this.state.start ]; } - } else if ( selectedFormat ) { + } else if ( selectedFormat > 0 ) { const formatsBefore = formats[ start - 1 ] || []; const formatsAfter = formats[ start ] || []; From 279bf24805f5e1de881eb58c125d69082ff0137f Mon Sep 17 00:00:00 2001 From: iseulde Date: Tue, 26 Feb 2019 11:29:36 +0100 Subject: [PATCH 08/18] Add some extra info to create docs --- packages/rich-text/README.md | 44 ++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/packages/rich-text/README.md b/packages/rich-text/README.md index 9e187b88f8f79f..246b1e1f74667a 100644 --- a/packages/rich-text/README.md +++ b/packages/rich-text/README.md @@ -93,9 +93,23 @@ is no format at the selection. `(Object|undefined)`: Active format object of the specified type, or undefined. +### getActiveObject + +[src/index.js#L11-L11](src/index.js#L11-L11) + +Gets the active object, if there is any. + +**Parameters** + +- **value** `Object`: Value to inspect. + +**Returns** + +`?Object`: Active object, or undefined. + ### getTextContent -[src/index.js#L13-L13](src/index.js#L13-L13) +[src/index.js#L14-L14](src/index.js#L14-L14) Get the textual content of a Rich Text value. This is similar to `Element.textContent`. @@ -110,7 +124,7 @@ Get the textual content of a Rich Text value. This is similar to ### insert -[src/index.js#L21-L21](src/index.js#L21-L21) +[src/index.js#L22-L22](src/index.js#L22-L22) Insert a Rich Text value, an HTML string, or a plain text string, into a Rich Text value at the given `startIndex`. Any content between `startIndex` @@ -130,7 +144,7 @@ none are provided. ### insertObject -[src/index.js#L24-L24](src/index.js#L24-L24) +[src/index.js#L25-L25](src/index.js#L25-L25) Insert a format as an object into a Rich Text value at the given `startIndex`. Any content between `startIndex` and `endIndex` will be @@ -149,7 +163,7 @@ removed. Indices are retrieved from the selection if none are provided. ### isCollapsed -[src/index.js#L14-L14](src/index.js#L14-L14) +[src/index.js#L15-L15](src/index.js#L15-L15) Check if the selection of a Rich Text value is collapsed or not. Collapsed means that no characters are selected, but there is a caret present. If there @@ -166,7 +180,7 @@ is no selection, `undefined` will be returned. This is similar to ### isEmpty -[src/index.js#L15-L15](src/index.js#L15-L15) +[src/index.js#L16-L16](src/index.js#L16-L16) Check if a Rich Text value is Empty, meaning it contains no text or any objects (such as images). @@ -181,7 +195,7 @@ objects (such as images). ### join -[src/index.js#L16-L16](src/index.js#L16-L16) +[src/index.js#L17-L17](src/index.js#L17-L17) Combine an array of Rich Text values into one, optionally separated by `separator`, which can be a Rich Text value, HTML string, or plain text @@ -198,7 +212,7 @@ string. This is similar to `Array.prototype.join`. ### registerFormatType -[src/index.js#L17-L17](src/index.js#L17-L17) +[src/index.js#L18-L18](src/index.js#L18-L18) Registers a new format provided a unique name and an object defining its behavior. @@ -218,7 +232,7 @@ behavior. ### remove -[src/index.js#L19-L19](src/index.js#L19-L19) +[src/index.js#L20-L20](src/index.js#L20-L20) Remove content from a Rich Text value between the given `startIndex` and `endIndex`. Indices are retrieved from the selection if none are provided. @@ -235,7 +249,7 @@ Remove content from a Rich Text value between the given `startIndex` and ### removeFormat -[src/index.js#L18-L18](src/index.js#L18-L18) +[src/index.js#L19-L19](src/index.js#L19-L19) Remove any format object from a Rich Text value by type from the given `startIndex` to the given `endIndex`. Indices are retrieved from the @@ -254,7 +268,7 @@ selection if none are provided. ### replace -[src/index.js#L20-L20](src/index.js#L20-L20) +[src/index.js#L21-L21](src/index.js#L21-L21) Search a Rich Text value and replace the match(es) with `replacement`. This is similar to `String.prototype.replace`. @@ -271,7 +285,7 @@ is similar to `String.prototype.replace`. ### slice -[src/index.js#L25-L25](src/index.js#L25-L25) +[src/index.js#L26-L26](src/index.js#L26-L26) Slice a Rich Text value from `startIndex` to `endIndex`. Indices are retrieved from the selection if none are provided. This is similar to @@ -289,7 +303,7 @@ retrieved from the selection if none are provided. This is similar to ### split -[src/index.js#L26-L26](src/index.js#L26-L26) +[src/index.js#L27-L27](src/index.js#L27-L27) Split a Rich Text value in two at the given `startIndex` and `endIndex`, or split at the given separator. This is similar to `String.prototype.split`. @@ -307,7 +321,7 @@ Indices are retrieved from the selection if none are provided. ### toggleFormat -[src/index.js#L29-L29](src/index.js#L29-L29) +[src/index.js#L30-L30](src/index.js#L30-L30) Toggles a format object to a Rich Text value at the current selection. @@ -322,7 +336,7 @@ Toggles a format object to a Rich Text value at the current selection. ### toHTMLString -[src/index.js#L28-L28](src/index.js#L28-L28) +[src/index.js#L29-L29](src/index.js#L29-L29) Create an HTML string from a Rich Text value. If a `multilineTag` is provided, text separated by a line separator will be wrapped in it. @@ -339,7 +353,7 @@ provided, text separated by a line separator will be wrapped in it. ### unregisterFormatType -[src/index.js#L31-L31](src/index.js#L31-L31) +[src/index.js#L32-L32](src/index.js#L32-L32) Unregisters a format. From 9d5de549abf4e73f46d9ba1fd132fabbfd5c44ba Mon Sep 17 00:00:00 2001 From: iseulde Date: Tue, 26 Feb 2019 17:22:32 +0100 Subject: [PATCH 09/18] Move create docs inline --- packages/rich-text/README.md | 21 +++++++++++++++++++++ packages/rich-text/src/create.js | 21 +++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/packages/rich-text/README.md b/packages/rich-text/README.md index 246b1e1f74667a..62755da3718c74 100644 --- a/packages/rich-text/README.md +++ b/packages/rich-text/README.md @@ -61,6 +61,27 @@ called without any input, an empty value will be created. If `multilineTag` will be separated by two newlines. The optional functions can be used to filter out content. +A value will have the following shape, which you are strongly encouraged not +to modify without the use of helper functions: + +```js +{ + text: string, + formats: Array, + objects: Array, + lines: Array, + ?start: number, + ?end: number, +} +``` + +As you can see, text and formatting are separated. `text` holds the text, +including any replacement characters for objects and lines. `formats`, +`objects` and `lines` are all sparse arrays of the same length as `text`. It +holds information about the formatting at the relevant text indices. Finally +`start` and `end` state which text indices are selected. They are only +provided if a `Range` was given. + **Parameters** - **$1** `[Object]`: Optional named arguments. diff --git a/packages/rich-text/src/create.js b/packages/rich-text/src/create.js index 9c362170b3c2fc..64e6c4477bd56b 100644 --- a/packages/rich-text/src/create.js +++ b/packages/rich-text/src/create.js @@ -102,6 +102,27 @@ function toFormat( { type, attributes } ) { * `multilineTag` will be separated by two newlines. The optional functions can * be used to filter out content. * + * A value will have the following shape, which you are strongly encouraged not + * to modify without the use of helper functions: + * + * ```js + * { + * text: string, + * formats: Array, + * objects: Array, + * lines: Array, + * ?start: number, + * ?end: number, + * } + * ``` + * + * As you can see, text and formatting are separated. `text` holds the text, + * including any replacement characters for objects and lines. `formats`, + * `objects` and `lines` are all sparse arrays of the same length as `text`. It + * holds information about the formatting at the relevant text indices. Finally + * `start` and `end` state which text indices are selected. They are only + * provided if a `Range` was given. + * * @param {Object} [$1] Optional named arguments. * @param {Element} [$1.element] Element to create value from. * @param {string} [$1.text] Text to create value from. From c6a02e1d3f8e7dee3c3e52c019a9509d0b107364 Mon Sep 17 00:00:00 2001 From: iseulde Date: Mon, 4 Mar 2019 16:12:19 +0100 Subject: [PATCH 10/18] Merge lines and objects --- .../src/components/rich-text/index.js | 8 +- packages/rich-text/src/change-list-type.js | 20 ++-- packages/rich-text/src/concat.js | 3 +- packages/rich-text/src/create.js | 18 +-- packages/rich-text/src/get-active-object.js | 12 +- .../rich-text/src/get-last-child-index.js | 8 +- .../rich-text/src/get-parent-line-index.js | 6 +- packages/rich-text/src/indent-list-items.js | 28 ++--- .../rich-text/src/insert-line-separator.js | 9 +- packages/rich-text/src/insert-object.js | 3 +- packages/rich-text/src/insert.js | 5 +- packages/rich-text/src/join.js | 5 +- packages/rich-text/src/outdent-list-items.js | 18 +-- packages/rich-text/src/replace.js | 13 +-- packages/rich-text/src/slice.js | 5 +- packages/rich-text/src/split.js | 13 +-- .../rich-text/src/test/change-list-type.js | 16 +-- packages/rich-text/src/test/concat.js | 9 +- packages/rich-text/src/test/create.js | 3 +- .../src/test/get-last-child-index.js | 10 +- .../src/test/get-parent-line-index.js | 8 +- packages/rich-text/src/test/helpers/index.js | 105 ++++++------------ .../rich-text/src/test/indent-list-items.js | 53 ++++----- .../src/test/insert-line-separator.js | 32 ++---- packages/rich-text/src/test/insert-object.js | 8 +- packages/rich-text/src/test/insert.js | 18 +-- packages/rich-text/src/test/join.js | 12 +- .../rich-text/src/test/outdent-list-items.js | 47 ++++---- packages/rich-text/src/test/replace.js | 21 ++-- packages/rich-text/src/test/slice.js | 12 +- packages/rich-text/src/test/split.js | 66 ++++------- packages/rich-text/src/to-tree.js | 6 +- 32 files changed, 242 insertions(+), 358 deletions(-) diff --git a/packages/block-editor/src/components/rich-text/index.js b/packages/block-editor/src/components/rich-text/index.js index ff0016954b54fd..a8556d2fd1d0de 100644 --- a/packages/block-editor/src/components/rich-text/index.js +++ b/packages/block-editor/src/components/rich-text/index.js @@ -177,10 +177,10 @@ export class RichText extends Component { * @return {Object} The current record (value and selection). */ getRecord() { - const { formats, lines, objects, text } = this.formatToValue( this.props.value ); + const { formats, replacements, text } = this.formatToValue( this.props.value ); const { start, end, selectedFormat } = this.state; - return { formats, lines, objects, text, start, end, selectedFormat }; + return { formats, replacements, text, start, end, selectedFormat }; } createRecord() { @@ -394,7 +394,7 @@ export class RichText extends Component { } let { selectedFormat } = this.state; - const { formats, lines, objects, text, start, end } = this.createRecord(); + const { formats, replacements, text, start, end } = this.createRecord(); if ( this.formatPlaceholder ) { selectedFormat = this.formatPlaceholder.length; @@ -421,7 +421,7 @@ export class RichText extends Component { delete formats[ this.state.start ]; } - const change = { formats, lines, objects, text, start, end, selectedFormat }; + const change = { formats, replacements, text, start, end, selectedFormat }; this.onChange( change, { withoutHistory: true, diff --git a/packages/rich-text/src/change-list-type.js b/packages/rich-text/src/change-list-type.js index 64202a274dd0d3..7b4075276f6872 100644 --- a/packages/rich-text/src/change-list-type.js +++ b/packages/rich-text/src/change-list-type.js @@ -20,14 +20,14 @@ import { getParentLineIndex } from './get-parent-line-index'; * @return {Object} The changed value. */ export function changeListType( value, newFormat ) { - const { text, lines, start, end } = value; + const { text, replacements, start, end } = value; const startingLineIndex = getLineIndex( value, start ); - const startlines = lines[ startingLineIndex ] || []; - const endlines = lines[ getLineIndex( value, end ) ] || []; + const startLineFormats = replacements[ startingLineIndex ] || []; + const endLineFormats = replacements[ getLineIndex( value, end ) ] || []; const startIndex = getParentLineIndex( value, startingLineIndex ); - const newLines = lines.slice(); - const startCount = startlines.length - 1; - const endCount = endlines.length - 1; + const newReplacements = replacements.slice(); + const startCount = startLineFormats.length - 1; + const endCount = endLineFormats.length - 1; let changed; @@ -36,16 +36,16 @@ export function changeListType( value, newFormat ) { continue; } - if ( ( newLines[ index ] || [] ).length <= startCount ) { + if ( ( newReplacements[ index ] || [] ).length <= startCount ) { break; } - if ( ! newLines[ index ] ) { + if ( ! newReplacements[ index ] ) { continue; } changed = true; - newLines[ index ] = newLines[ index ].map( ( format, i ) => { + newReplacements[ index ] = newReplacements[ index ].map( ( format, i ) => { return i < startCount || i > endCount ? format : newFormat; } ); } @@ -56,6 +56,6 @@ export function changeListType( value, newFormat ) { return normaliseFormats( { ...value, - lines: newLines, + replacements: newReplacements, } ); } diff --git a/packages/rich-text/src/concat.js b/packages/rich-text/src/concat.js index c620b6fd6b23cb..07be12140db91b 100644 --- a/packages/rich-text/src/concat.js +++ b/packages/rich-text/src/concat.js @@ -16,8 +16,7 @@ import { create } from './create'; */ export function mergePair( a, b ) { a.formats = a.formats.concat( b.formats ); - a.lines = a.lines.concat( b.lines ); - a.objects = a.objects.concat( b.objects ); + a.replacements = a.replacements.concat( b.replacements ); a.text += b.text; return a; diff --git a/packages/rich-text/src/create.js b/packages/rich-text/src/create.js index 64e6c4477bd56b..eb6b016c836342 100644 --- a/packages/rich-text/src/create.js +++ b/packages/rich-text/src/create.js @@ -25,8 +25,7 @@ const { TEXT_NODE, ELEMENT_NODE } = window.Node; function createEmptyValue() { return { formats: [], - lines: [], - objects: [], + replacements: [], text: '', }; } @@ -109,8 +108,7 @@ function toFormat( { type, attributes } ) { * { * text: string, * formats: Array, - * objects: Array, - * lines: Array, + * replacements: Array, * ?start: number, * ?end: number, * } @@ -147,8 +145,7 @@ export function create( { if ( typeof text === 'string' && text.length > 0 ) { return { formats: Array( text.length ), - lines: Array( text.length ), - objects: Array( text.length ), + replacements: Array( text.length ), text, }; } @@ -323,8 +320,7 @@ function createFromElement( { // Create a sparse array of the same length as `text`, in which // formats can be added. accumulator.formats.length += text.length; - accumulator.lines.length += text.length; - accumulator.objects.length += text.length; + accumulator.replacements.length += text.length; accumulator.text += text; continue; } @@ -388,8 +384,7 @@ function createFromElement( { if ( format.attributes && value.text.length === 0 ) { mergePair( accumulator, { formats: [ , ], - lines: [ , ], - objects: [ format ], + replacements: [ format ], text: OBJECT_REPLACEMENT_CHARACTER, } ); continue; @@ -459,8 +454,7 @@ function createFromMultilineElement( { if ( index !== 0 || currentWrapperTags.length > 0 ) { mergePair( accumulator, { formats: [ , ], - lines: currentWrapperTags.length > 0 ? [ currentWrapperTags ] : [ , ], - objects: [ , ], + replacements: currentWrapperTags.length > 0 ? [ currentWrapperTags ] : [ , ], text: LINE_SEPARATOR, } ); } diff --git a/packages/rich-text/src/get-active-object.js b/packages/rich-text/src/get-active-object.js index ae83cb75255b38..e324521284597b 100644 --- a/packages/rich-text/src/get-active-object.js +++ b/packages/rich-text/src/get-active-object.js @@ -1,3 +1,9 @@ +/** + * Internal dependencies + */ + +import { OBJECT_REPLACEMENT_CHARACTER } from './special-characters'; + /** * Gets the active object, if there is any. * @@ -5,10 +11,10 @@ * * @return {?Object} Active object, or undefined. */ -export function getActiveObject( { start, end, objects } ) { - if ( start + 1 !== end ) { +export function getActiveObject( { start, end, replacements, text } ) { + if ( start + 1 !== end || text[ start ] !== OBJECT_REPLACEMENT_CHARACTER ) { return; } - return objects[ start ]; + return replacements[ start ]; } diff --git a/packages/rich-text/src/get-last-child-index.js b/packages/rich-text/src/get-last-child-index.js index 5075dafa8dd752..0fc4aeb32ff3ee 100644 --- a/packages/rich-text/src/get-last-child-index.js +++ b/packages/rich-text/src/get-last-child-index.js @@ -12,8 +12,8 @@ import { LINE_SEPARATOR } from './special-characters'; * * @return {Array} The index of the last child. */ -export function getLastChildIndex( { text, lines }, lineIndex ) { - const currentlines = lines[ lineIndex ] || []; +export function getLastChildIndex( { text, replacements }, lineIndex ) { + const lineFormats = replacements[ lineIndex ] || []; // Use the given line index in case there are no next children. let childIndex = lineIndex; @@ -24,11 +24,11 @@ export function getLastChildIndex( { text, lines }, lineIndex ) { continue; } - const formatsAtIndex = lines[ index ] || []; + const formatsAtIndex = replacements[ index ] || []; // If the amout of formats is equal or more, store it, then return the // last one if the amount of formats is less. - if ( formatsAtIndex.length >= currentlines.length ) { + if ( formatsAtIndex.length >= lineFormats.length ) { childIndex = index; } else { return childIndex; diff --git a/packages/rich-text/src/get-parent-line-index.js b/packages/rich-text/src/get-parent-line-index.js index c2144a5e5ca132..1b0a0ecb5cf48c 100644 --- a/packages/rich-text/src/get-parent-line-index.js +++ b/packages/rich-text/src/get-parent-line-index.js @@ -14,8 +14,8 @@ import { LINE_SEPARATOR } from './special-characters'; * * @return {Array} The parent list line index. */ -export function getParentLineIndex( { text, lines }, lineIndex ) { - const startFormats = lines[ lineIndex ] || []; +export function getParentLineIndex( { text, replacements }, lineIndex ) { + const startFormats = replacements[ lineIndex ] || []; let index = lineIndex; @@ -24,7 +24,7 @@ export function getParentLineIndex( { text, lines }, lineIndex ) { continue; } - const formatsAtIndex = lines[ index ] || []; + const formatsAtIndex = replacements[ index ] || []; if ( formatsAtIndex.length === startFormats.length - 1 ) { return index; diff --git a/packages/rich-text/src/indent-list-items.js b/packages/rich-text/src/indent-list-items.js index efc94fcb1e4526..09301583f28be6 100644 --- a/packages/rich-text/src/indent-list-items.js +++ b/packages/rich-text/src/indent-list-items.js @@ -14,8 +14,8 @@ import { getLineIndex } from './get-line-index'; * * @return {boolean} The line index. */ -function getTargetLevelLineIndex( { text, lines }, lineIndex ) { - const startFormats = lines[ lineIndex ] || []; +function getTargetLevelLineIndex( { text, replacements }, lineIndex ) { + const startFormats = replacements[ lineIndex ] || []; let index = lineIndex; @@ -24,7 +24,7 @@ function getTargetLevelLineIndex( { text, lines }, lineIndex ) { continue; } - const formatsAtIndex = lines[ index ] || []; + const formatsAtIndex = replacements[ index ] || []; // Return the first line index that is one level higher. If the level is // lower or equal, there is no result. @@ -52,10 +52,10 @@ export function indentListItems( value, rootFormat ) { return value; } - const { text, lines, end } = value; + const { text, replacements, end } = value; const previousLineIndex = getLineIndex( value, lineIndex ); - const formatsAtLineIndex = lines[ lineIndex ] || []; - const formatsAtPreviousLineIndex = lines[ previousLineIndex ] || []; + const formatsAtLineIndex = replacements[ lineIndex ] || []; + const formatsAtPreviousLineIndex = replacements[ previousLineIndex ] || []; // The the indentation of the current line is greater than previous line, // then the line cannot be furter indented. @@ -63,7 +63,7 @@ export function indentListItems( value, rootFormat ) { return value; } - const newLines = lines.slice(); + const newFormats = replacements.slice(); const targetLevelLineIndex = getTargetLevelLineIndex( value, lineIndex ); for ( let index = lineIndex; index < end; index++ ) { @@ -74,23 +74,23 @@ export function indentListItems( value, rootFormat ) { // Get the previous list, and if there's a child list, take over the // formats. If not, duplicate the last level and create a new level. if ( targetLevelLineIndex ) { - const targetFormats = lines[ targetLevelLineIndex ] || []; - newLines[ index ] = targetFormats.concat( - ( newLines[ index ] || [] ).slice( targetFormats.length - 1 ) + const targetFormats = replacements[ targetLevelLineIndex ] || []; + newFormats[ index ] = targetFormats.concat( + ( newFormats[ index ] || [] ).slice( targetFormats.length - 1 ) ); } else { - const targetFormats = lines[ previousLineIndex ] || []; + const targetFormats = replacements[ previousLineIndex ] || []; const lastformat = targetFormats[ targetFormats.length - 1 ] || rootFormat; - newLines[ index ] = targetFormats.concat( + newFormats[ index ] = targetFormats.concat( [ lastformat ], - ( newLines[ index ] || [] ).slice( targetFormats.length ) + ( newFormats[ index ] || [] ).slice( targetFormats.length ) ); } } return normaliseFormats( { ...value, - lines: newLines, + replacements: newFormats, } ); } diff --git a/packages/rich-text/src/insert-line-separator.js b/packages/rich-text/src/insert-line-separator.js index a43834896d484f..77434a25ac012a 100644 --- a/packages/rich-text/src/insert-line-separator.js +++ b/packages/rich-text/src/insert-line-separator.js @@ -24,17 +24,16 @@ export function insertLineSeparator( ) { const beforeText = getTextContent( value ).slice( 0, startIndex ); const previousLineSeparatorIndex = beforeText.lastIndexOf( LINE_SEPARATOR ); - const previousLineSeparatorFormats = value.lines[ previousLineSeparatorIndex ]; - let lines = [ , ]; + const previousLineSeparatorFormats = value.replacements[ previousLineSeparatorIndex ]; + let replacements = [ , ]; if ( previousLineSeparatorFormats ) { - lines = [ previousLineSeparatorFormats ]; + replacements = [ previousLineSeparatorFormats ]; } const valueToInsert = { formats: [ , ], - lines, - objects: [ , ], + replacements, text: LINE_SEPARATOR, }; diff --git a/packages/rich-text/src/insert-object.js b/packages/rich-text/src/insert-object.js index fa2d8437162928..7495d6082cbcb1 100644 --- a/packages/rich-text/src/insert-object.js +++ b/packages/rich-text/src/insert-object.js @@ -26,8 +26,7 @@ export function insertObject( ) { const valueToInsert = { formats: [ , ], - lines: [ , ], - objects: [ formatToInsert ], + replacements: [ formatToInsert ], text: OBJECT_REPLACEMENT_CHARACTER, }; diff --git a/packages/rich-text/src/insert.js b/packages/rich-text/src/insert.js index 4c029c04bdaef7..4d2353eaba4cb9 100644 --- a/packages/rich-text/src/insert.js +++ b/packages/rich-text/src/insert.js @@ -24,7 +24,7 @@ export function insert( startIndex = value.start, endIndex = value.end ) { - const { formats, lines, objects, text } = value; + const { formats, replacements, text } = value; if ( typeof valueToInsert === 'string' ) { valueToInsert = create( { text: valueToInsert } ); @@ -34,8 +34,7 @@ export function insert( return normaliseFormats( { formats: formats.slice( 0, startIndex ).concat( valueToInsert.formats, formats.slice( endIndex ) ), - lines: lines.slice( 0, startIndex ).concat( valueToInsert.lines, lines.slice( endIndex ) ), - objects: objects.slice( 0, startIndex ).concat( valueToInsert.objects, objects.slice( endIndex ) ), + replacements: replacements.slice( 0, startIndex ).concat( valueToInsert.replacements, replacements.slice( endIndex ) ), text: text.slice( 0, startIndex ) + valueToInsert.text + text.slice( endIndex ), start: index, end: index, diff --git a/packages/rich-text/src/join.js b/packages/rich-text/src/join.js index d7a56c76586f26..cabfc827560164 100644 --- a/packages/rich-text/src/join.js +++ b/packages/rich-text/src/join.js @@ -20,10 +20,9 @@ export function join( values, separator = '' ) { separator = create( { text: separator } ); } - return normaliseFormats( values.reduce( ( accumlator, { formats, lines, objects, text } ) => ( { + return normaliseFormats( values.reduce( ( accumlator, { formats, replacements, text } ) => ( { formats: accumlator.formats.concat( separator.formats, formats ), - lines: accumlator.lines.concat( separator.lines, lines ), - objects: accumlator.objects.concat( separator.objects, objects ), + replacements: accumlator.replacements.concat( separator.replacements, replacements ), text: accumlator.text + separator.text + text, } ) ) ); } diff --git a/packages/rich-text/src/outdent-list-items.js b/packages/rich-text/src/outdent-list-items.js index 07fbb273644adb..4a2087ed532712 100644 --- a/packages/rich-text/src/outdent-list-items.js +++ b/packages/rich-text/src/outdent-list-items.js @@ -16,16 +16,16 @@ import { getLastChildIndex } from './get-last-child-index'; * @return {Object} The changed value. */ export function outdentListItems( value ) { - const { text, lines, start, end } = value; + const { text, replacements, start, end } = value; const startingLineIndex = getLineIndex( value, start ); // Return early if the starting line index cannot be further outdented. - if ( lines[ startingLineIndex ] === undefined ) { + if ( replacements[ startingLineIndex ] === undefined ) { return value; } - const newLines = lines.slice( 0 ); - const parentFormats = lines[ getParentLineIndex( value, startingLineIndex ) ] || []; + const newFormats = replacements.slice( 0 ); + const parentFormats = replacements[ getParentLineIndex( value, startingLineIndex ) ] || []; const endingLineIndex = getLineIndex( value, end ); const lastChildIndex = getLastChildIndex( value, endingLineIndex ); @@ -39,20 +39,20 @@ export function outdentListItems( value ) { } // In the case of level 0, the formats at the index are undefined. - const currentFormats = newLines[ index ] || []; + const currentFormats = newFormats[ index ] || []; // Omit the indentation level where the selection starts. - newLines[ index ] = parentFormats.concat( + newFormats[ index ] = parentFormats.concat( currentFormats.slice( parentFormats.length + 1 ) ); - if ( newLines[ index ].length === 0 ) { - delete newLines[ index ]; + if ( newFormats[ index ].length === 0 ) { + delete newFormats[ index ]; } } return normaliseFormats( { ...value, - lines: newLines, + replacements: newFormats, } ); } diff --git a/packages/rich-text/src/replace.js b/packages/rich-text/src/replace.js index eabe4ae1778130..0cb26cb7431bd0 100644 --- a/packages/rich-text/src/replace.js +++ b/packages/rich-text/src/replace.js @@ -20,12 +20,12 @@ import { normaliseFormats } from './normalise-formats'; * * @return {Object} A new value with replacements applied. */ -export function replace( { formats, lines, objects, text, start, end }, pattern, replacement ) { +export function replace( { formats, replacements, text, start, end }, pattern, replacement ) { text = text.replace( pattern, ( match, ...rest ) => { const offset = rest[ rest.length - 2 ]; let newText = replacement; let newFormats; - let newObjects; + let newReplacements; if ( typeof newText === 'function' ) { newText = replacement( match, ...rest ); @@ -33,11 +33,11 @@ export function replace( { formats, lines, objects, text, start, end }, pattern, if ( typeof newText === 'object' ) { newFormats = newText.formats; - newObjects = newText.objects; + newReplacements = newText.replacements; newText = newText.text; } else { newFormats = Array( newText.length ); - newObjects = Array( newText.length ); + newReplacements = Array( newText.length ); if ( formats[ offset ] ) { newFormats = newFormats.fill( formats[ offset ] ); @@ -45,8 +45,7 @@ export function replace( { formats, lines, objects, text, start, end }, pattern, } formats = formats.slice( 0, offset ).concat( newFormats, formats.slice( offset + match.length ) ); - lines = lines.slice( 0, offset ).concat( Array( newText.length ), lines.slice( offset + match.length ) ); - objects = objects.slice( 0, offset ).concat( newObjects, objects.slice( offset + match.length ) ); + replacements = replacements.slice( 0, offset ).concat( newReplacements, replacements.slice( offset + match.length ) ); if ( start ) { start = end = offset + newText.length; @@ -55,5 +54,5 @@ export function replace( { formats, lines, objects, text, start, end }, pattern, return newText; } ); - return normaliseFormats( { formats, lines, objects, text, start, end } ); + return normaliseFormats( { formats, replacements, text, start, end } ); } diff --git a/packages/rich-text/src/slice.js b/packages/rich-text/src/slice.js index 09b5ce9a1d08de..b535a445d45f5c 100644 --- a/packages/rich-text/src/slice.js +++ b/packages/rich-text/src/slice.js @@ -14,7 +14,7 @@ export function slice( startIndex = value.start, endIndex = value.end ) { - const { formats, lines, objects, text } = value; + const { formats, replacements, text } = value; if ( startIndex === undefined || endIndex === undefined ) { return { ...value }; @@ -22,8 +22,7 @@ export function slice( return { formats: formats.slice( startIndex, endIndex ), - lines: lines.slice( startIndex, endIndex ), - objects: objects.slice( startIndex, endIndex ), + replacements: replacements.slice( startIndex, endIndex ), text: text.slice( startIndex, endIndex ), }; } diff --git a/packages/rich-text/src/split.js b/packages/rich-text/src/split.js index 70db0bad6269a0..f79a675b1e1f4f 100644 --- a/packages/rich-text/src/split.js +++ b/packages/rich-text/src/split.js @@ -15,7 +15,7 @@ import { replace } from './replace'; * * @return {Array} An array of new values. */ -export function split( { formats, lines, objects, text, start, end }, string ) { +export function split( { formats, replacements, text, start, end }, string ) { if ( typeof string !== 'string' ) { return splitAtSelection( ...arguments ); } @@ -26,8 +26,7 @@ export function split( { formats, lines, objects, text, start, end }, string ) { const startIndex = nextStart; const value = { formats: formats.slice( startIndex, startIndex + substring.length ), - lines: lines.slice( startIndex, startIndex + substring.length ), - objects: objects.slice( startIndex, startIndex + substring.length ), + replacements: replacements.slice( startIndex, startIndex + substring.length ), text: substring, }; @@ -52,20 +51,18 @@ export function split( { formats, lines, objects, text, start, end }, string ) { } function splitAtSelection( - { formats, lines, objects, text, start, end }, + { formats, replacements, text, start, end }, startIndex = start, endIndex = end ) { const before = { formats: formats.slice( 0, startIndex ), - lines: lines.slice( 0, startIndex ), - objects: objects.slice( 0, startIndex ), + replacements: replacements.slice( 0, startIndex ), text: text.slice( 0, startIndex ), }; const after = { formats: formats.slice( endIndex ), - lines: lines.slice( endIndex ), - objects: objects.slice( endIndex ), + replacements: replacements.slice( endIndex ), text: text.slice( endIndex ), start: 0, end: 0, diff --git a/packages/rich-text/src/test/change-list-type.js b/packages/rich-text/src/test/change-list-type.js index 0896d66b62f7d1..cdc9821bb30d00 100644 --- a/packages/rich-text/src/test/change-list-type.js +++ b/packages/rich-text/src/test/change-list-type.js @@ -18,7 +18,7 @@ describe( 'changeListType', () => { it( 'should only change list type if list item is indented', () => { const record = { formats: [], - lines: [ , ], + replacements: [ , ], text: '1', start: 1, end: 1, @@ -27,26 +27,26 @@ describe( 'changeListType', () => { expect( result ).toEqual( record ); expect( result ).toBe( record ); - expect( getSparseArrayLength( result.lines ) ).toBe( 0 ); + expect( getSparseArrayLength( result.replacements ) ).toBe( 0 ); } ); it( 'should change list type', () => { const record = { formats: [], - lines: [ , [ ul ] ], + replacements: [ , [ ul ] ], text: `1${ LINE_SEPARATOR }`, start: 2, end: 2, }; const expected = { ...record, - lines: [ , [ ol ] ], + replacements: [ , [ ol ] ], }; const result = changeListType( deepFreeze( record ), ol ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.lines ) ).toBe( 1 ); + expect( getSparseArrayLength( result.replacements ) ).toBe( 1 ); } ); it( 'should outdent with multiple lines selected', () => { @@ -55,19 +55,19 @@ describe( 'changeListType', () => { const record = { formats: [], - lines: [ , [ ul ], , [ ul ], , [ ul, ul ], , [ ul ], , [ ul ], , , , [ ul ], , ], + replacements: [ , [ ul ], , [ ul ], , [ ul, ul ], , [ ul ], , [ ul ], , , , [ ul ], , ], text, start: 4, end: 9, }; const expected = { ...record, - lines: [ , [ ol ], , [ ol ], , [ ol, ul ], , [ ol ], , [ ol ], , , , [ ul ], , ], + replacements: [ , [ ol ], , [ ol ], , [ ol, ul ], , [ ol ], , [ ol ], , , , [ ul ], , ], }; const result = changeListType( deepFreeze( record ), ol ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.lines ) ).toBe( 6 ); + expect( getSparseArrayLength( result.replacements ) ).toBe( 6 ); } ); } ); diff --git a/packages/rich-text/src/test/concat.js b/packages/rich-text/src/test/concat.js index f7f5ea1bf73710..ae8253e1a5461e 100644 --- a/packages/rich-text/src/test/concat.js +++ b/packages/rich-text/src/test/concat.js @@ -16,20 +16,17 @@ describe( 'concat', () => { it( 'should merge records', () => { const one = { formats: [ , , [ em ] ], - lines: [ , , , ], - objects: [ , , , ], + replacements: [ , , , ], text: 'one', }; const two = { formats: [ [ em ], , , ], - lines: [ , , , ], - objects: [ , , , ], + replacements: [ , , , ], text: 'two', }; const three = { formats: [ , , [ em ], [ em ], , , ], - lines: [ , , , , , , ], - objects: [ , , , , , , ], + replacements: [ , , , , , , ], text: 'onetwo', }; diff --git a/packages/rich-text/src/test/create.js b/packages/rich-text/src/test/create.js index 83b81b121de872..b585d72ec66142 100644 --- a/packages/rich-text/src/test/create.js +++ b/packages/rich-text/src/test/create.js @@ -81,8 +81,7 @@ describe( 'create', () => { expect( value ).toEqual( { formats: [ [ em ], [ em ], [ em, strong ], [ em, strong ] ], - lines: [ , , , , ], - objects: [ , , , , ], + replacements: [ , , , , ], text: 'test', } ); diff --git a/packages/rich-text/src/test/get-last-child-index.js b/packages/rich-text/src/test/get-last-child-index.js index 43f88044b160d0..f59cec9eeeab1f 100644 --- a/packages/rich-text/src/test/get-last-child-index.js +++ b/packages/rich-text/src/test/get-last-child-index.js @@ -15,35 +15,35 @@ describe( 'getLastChildIndex', () => { it( 'should return undefined if there is only one line', () => { expect( getLastChildIndex( deepFreeze( { - lines: [ , ], + replacements: [ , ], text: '1', } ), undefined ) ).toBe( undefined ); } ); it( 'should return the last line if no line is indented', () => { expect( getLastChildIndex( deepFreeze( { - lines: [ , ], + replacements: [ , ], text: `1${ LINE_SEPARATOR }`, } ), undefined ) ).toBe( 1 ); } ); it( 'should return the last child index', () => { expect( getLastChildIndex( deepFreeze( { - lines: [ , [ ul ], , [ ul ], , ], + replacements: [ , [ ul ], , [ ul ], , ], text: `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`, } ), undefined ) ).toBe( 3 ); } ); it( 'should return the last child index by sibling', () => { expect( getLastChildIndex( deepFreeze( { - lines: [ , [ ul ], , [ ul ], , ], + replacements: [ , [ ul ], , [ ul ], , ], text: `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`, } ), 1 ) ).toBe( 3 ); } ); it( 'should return the last child index (with further lower indented items)', () => { expect( getLastChildIndex( deepFreeze( { - lines: [ , [ ul ], , , , ], + replacements: [ , [ ul ], , , , ], text: `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`, } ), 1 ) ).toBe( 1 ); } ); diff --git a/packages/rich-text/src/test/get-parent-line-index.js b/packages/rich-text/src/test/get-parent-line-index.js index cad9580b70d088..832ee4412dacc7 100644 --- a/packages/rich-text/src/test/get-parent-line-index.js +++ b/packages/rich-text/src/test/get-parent-line-index.js @@ -15,28 +15,28 @@ describe( 'getParentLineIndex', () => { it( 'should return undefined if there is only one line', () => { expect( getParentLineIndex( deepFreeze( { - lines: [ , ], + replacements: [ , ], text: '1', } ), undefined ) ).toBe( undefined ); } ); it( 'should return undefined if the list is part of the first root list child', () => { expect( getParentLineIndex( deepFreeze( { - lines: [ , ], + replacements: [ , ], text: `1${ LINE_SEPARATOR }2`, } ), 2 ) ).toBe( undefined ); } ); it( 'should return the line index of the parent list (1)', () => { expect( getParentLineIndex( deepFreeze( { - lines: [ , , , [ ul ], , ], + replacements: [ , , , [ ul ], , ], text: `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`, } ), 3 ) ).toBe( 1 ); } ); it( 'should return the line index of the parent list (2)', () => { expect( getParentLineIndex( deepFreeze( { - lines: [ , [ ul ], , [ ul, ul ], , [ ul ], , ], + replacements: [ , [ ul ], , [ ul, ul ], , [ ul ], , ], text: `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3${ LINE_SEPARATOR }4`, } ), 5 ) ).toBe( undefined ); } ); diff --git a/packages/rich-text/src/test/helpers/index.js b/packages/rich-text/src/test/helpers/index.js index 0769d14fb6c413..7ac345ffb9b9ff 100644 --- a/packages/rich-text/src/test/helpers/index.js +++ b/packages/rich-text/src/test/helpers/index.js @@ -25,8 +25,7 @@ export const spec = [ start: 0, end: 0, formats: [], - lines: [], - objects: [], + replacements: [], text: '', }, }, @@ -45,8 +44,7 @@ export const spec = [ start: 0, end: 1, formats: [ , ], - lines: [ , ], - objects: [ , ], + replacements: [ , ], text: ' ', }, }, @@ -65,8 +63,7 @@ export const spec = [ start: 5, end: 5, formats: [ , , , , , , , , , , ], - lines: [ , , , , , , , , , , ], - objects: [ , , , , , , , , , , ], + replacements: [ , , , , , , , , , , ], text: 'test\u00a0 test', }, }, @@ -85,8 +82,7 @@ export const spec = [ start: 0, end: 0, formats: [], - lines: [], - objects: [], + replacements: [], text: '', }, }, @@ -105,8 +101,7 @@ export const spec = [ start: 0, end: 4, formats: [ , , , , ], - lines: [ , , , , ], - objects: [ , , , , ], + replacements: [ , , , , ], text: 'test', }, }, @@ -125,8 +120,7 @@ export const spec = [ start: 0, end: 2, formats: [ , , ], - lines: [ , , ], - objects: [ , , ], + replacements: [ , , ], text: '🍒', }, }, @@ -145,8 +139,7 @@ export const spec = [ start: 0, end: 2, formats: [ [ em ], [ em ] ], - lines: [ , , ], - objects: [ , , ], + replacements: [ , , ], text: '🍒', }, }, @@ -165,8 +158,7 @@ export const spec = [ start: 0, end: 4, formats: [ [ em ], [ em ], [ em ], [ em ] ], - lines: [ , , , , ], - objects: [ , , , , ], + replacements: [ , , , , ], text: 'test', }, }, @@ -185,8 +177,7 @@ export const spec = [ start: 0, end: 4, formats: [ [ em, strong ], [ em, strong ], [ em, strong ], [ em, strong ] ], - lines: [ , , , , ], - objects: [ , , , , ], + replacements: [ , , , , ], text: 'test', }, }, @@ -205,8 +196,7 @@ export const spec = [ start: 0, end: 2, formats: [ [ em ], [ em ], [ em ], [ em ] ], - lines: [ , , , , ], - objects: [ , , , , ], + replacements: [ , , , , ], text: 'test', }, }, @@ -225,8 +215,7 @@ export const spec = [ start: 0, end: 4, formats: [ [ a ], [ a ], [ a ], [ a ] ], - lines: [ , , , , ], - objects: [ , , , , ], + replacements: [ , , , , ], text: 'test', }, }, @@ -245,8 +234,7 @@ export const spec = [ start: 0, end: 0, formats: [ , ], - lines: [ , ], - objects: [ img ], + replacements: [ img ], text: '\ufffc', }, }, @@ -265,8 +253,7 @@ export const spec = [ start: 0, end: 1, formats: [ [ em ] ], - lines: [ , ], - objects: [ img ], + replacements: [ img ], text: '\ufffc', }, }, @@ -285,8 +272,7 @@ export const spec = [ start: 0, end: 5, formats: [ , , [ em ], [ em ], [ em ] ], - lines: [ , , , , , ], - objects: [ , , , , img ], + replacements: [ , , , , img ], text: 'test\ufffc', }, }, @@ -305,8 +291,7 @@ export const spec = [ start: 0, end: 5, formats: [ [ em ], [ em ], [ em ], , , ], - lines: [ , , , , , ], - objects: [ img, , , , , ], + replacements: [ img, , , , , ], text: '\ufffctest', }, }, @@ -325,8 +310,7 @@ export const spec = [ start: 0, end: 0, formats: [ , ], - lines: [ , ], - objects: [ , ], + replacements: [ , ], text: '\n', }, }, @@ -345,8 +329,7 @@ export const spec = [ start: 2, end: 3, formats: [ , , , , , ], - lines: [ , , , , , ], - objects: [ , , , , , ], + replacements: [ , , , , , ], text: 'te\nst', }, }, @@ -365,8 +348,7 @@ export const spec = [ start: 0, end: 1, formats: [ [ em ] ], - lines: [ , ], - objects: [ , ], + replacements: [ , ], text: '\n', }, }, @@ -383,8 +365,7 @@ export const spec = [ endPath: [ 4, 0 ], record: { formats: [ , , , , ], - lines: [ , , , , ], - objects: [ , , , , ], + replacements: [ , , , , ], text: 'a\n\nb', start: 2, end: 3, @@ -403,8 +384,7 @@ export const spec = [ endPath: [ 2, 0 ], record: { formats: [ , , , , ], - lines: [ , , , , ], - objects: [ , , , , ], + replacements: [ , , , , ], text: 'a\n\nb', start: 2, end: 2, @@ -426,8 +406,7 @@ export const spec = [ start: 0, end: 0, formats: [], - lines: [], - objects: [], + replacements: [], text: '', }, }, @@ -447,8 +426,7 @@ export const spec = [ start: 1, end: 4, formats: [ , , , , , , , ], - lines: [ , , , , , , , ], - objects: [ , , , , , , , ], + replacements: [ , , , , , , , ], text: 'one\u2028two', }, }, @@ -469,8 +447,7 @@ export const spec = [ start: 0, end: 9, formats: [ , , , , , , , , , , , , , , , , , ], - lines: [ , , , [ ul ], , [ ul ], , [ ul, ol ], , [ ul, ol ], , , , , , , , ], - objects: [ , , , , , , , , , , , , , , , , , ], + replacements: [ , , , [ ul ], , [ ul ], , [ ul, ol ], , [ ul, ol ], , , , , , , , ], text: 'one\u2028a\u2028b\u20281\u20282\u2028three', }, }, @@ -491,8 +468,7 @@ export const spec = [ start: 0, end: 0, formats: [], - lines: [], - objects: [], + replacements: [], text: '', }, }, @@ -513,8 +489,7 @@ export const spec = [ start: 1, end: 1, formats: [ , ], - lines: [ [ ul ] ], - objects: [ , ], + replacements: [ [ ul ] ], text: '\u2028', }, }, @@ -535,8 +510,7 @@ export const spec = [ start: 1, end: 1, formats: [ , , ], - lines: [ , , ], - objects: [ , , ], + replacements: [ , , ], text: '\u2028\u2028', }, }, @@ -556,8 +530,7 @@ export const spec = [ start: 4, end: 4, formats: [ , , , , ], - lines: [ , , , , ], - objects: [ , , , , ], + replacements: [ , , , , ], text: 'one\u2028', }, }, @@ -578,8 +551,7 @@ export const spec = [ start: 3, end: 3, formats: [ , , , ], - lines: [ , , , ], - objects: [ , , , ], + replacements: [ , , , ], text: 'one', }, }, @@ -590,8 +562,7 @@ export const spec = [ endPath: [], record: { formats: [ [ em ], [ em ], [ em ], [ em ], [ em ], [ em ], [ em ] ], - lines: [ , , , , , , , ], - objects: [ , , , , , , , ], + replacements: [ , , , , , , , ], text: 'one\u2028two', }, }, @@ -610,8 +581,7 @@ export const spec = [ start: 0, end: 0, formats: [], - lines: [], - objects: [], + replacements: [], text: '', }, }, @@ -630,8 +600,7 @@ export const spec = [ start: 0, end: 4, formats: [ [ strong ], [ strong ], [ strong ], [ strong ] ], - lines: [ , , , , ], - objects: [ , , , , ], + replacements: [ , , , , ], text: 'test', }, }, @@ -654,8 +623,7 @@ export const specWithRegistration = [ attributes: {}, unregisteredAttributes: {}, } ] ], - lines: [ , ], - objects: [ , ], + replacements: [ , ], text: 'a', }, }, @@ -677,8 +645,7 @@ export const specWithRegistration = [ class: 'test', }, } ] ], - lines: [ , ], - objects: [ , ], + replacements: [ , ], text: 'a', }, }, @@ -700,8 +667,7 @@ export const specWithRegistration = [ class: 'custom-format', }, } ] ], - lines: [ , ], - objects: [ , ], + replacements: [ , ], text: 'a', }, }, @@ -715,8 +681,7 @@ export const specWithRegistration = [ class: 'custom-format', }, } ] ], - lines: [ , ], - objects: [ , ], + replacements: [ , ], text: 'a', }, }, diff --git a/packages/rich-text/src/test/indent-list-items.js b/packages/rich-text/src/test/indent-list-items.js index c59afcad192209..e37b788833e5dc 100644 --- a/packages/rich-text/src/test/indent-list-items.js +++ b/packages/rich-text/src/test/indent-list-items.js @@ -18,8 +18,7 @@ describe( 'indentListItems', () => { it( 'should not indent only item', () => { const record = { formats: [ , ], - lines: [ , ], - objects: [ , ], + replacements: [ , ], text: '1', start: 1, end: 1, @@ -28,7 +27,7 @@ describe( 'indentListItems', () => { expect( result ).toEqual( record ); expect( result ).toBe( record ); - expect( getSparseArrayLength( result.lines ) ).toBe( 0 ); + expect( getSparseArrayLength( result.replacements ) ).toBe( 0 ); } ); it( 'should indent', () => { @@ -36,28 +35,26 @@ describe( 'indentListItems', () => { const text = `1${ LINE_SEPARATOR }`; const record = { formats: [ , , ], - lines: [ , , ], - objects: [ , , ], + replacements: [ , , ], text, start: 2, end: 2, }; const expected = { ...record, - lines: [ , [ ul ] ], + replacements: [ , [ ul ] ], }; const result = indentListItems( deepFreeze( record ), ul ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.lines ) ).toBe( 1 ); + expect( getSparseArrayLength( result.replacements ) ).toBe( 1 ); } ); it( 'should not indent without target list', () => { const record = { formats: [ , , ], - lines: [ , [ ul ] ], - objects: [ , , ], + replacements: [ , [ ul ] ], text: `1${ LINE_SEPARATOR }`, start: 2, end: 2, @@ -66,7 +63,7 @@ describe( 'indentListItems', () => { expect( result ).toEqual( record ); expect( result ).toBe( record ); - expect( getSparseArrayLength( result.lines ) ).toBe( 1 ); + expect( getSparseArrayLength( result.replacements ) ).toBe( 1 ); } ); it( 'should indent and merge with previous list', () => { @@ -74,21 +71,20 @@ describe( 'indentListItems', () => { const text = `1${ LINE_SEPARATOR }${ LINE_SEPARATOR }`; const record = { formats: [ , , , ], - lines: [ , [ ol ], , ], - objects: [ , , , ], + replacements: [ , [ ol ], , ], text, start: 3, end: 3, }; const expected = { ...record, - lines: [ , [ ol ], [ ol ] ], + replacements: [ , [ ol ], [ ol ] ], }; const result = indentListItems( deepFreeze( record ), ul ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.lines ) ).toBe( 2 ); + expect( getSparseArrayLength( result.replacements ) ).toBe( 2 ); } ); it( 'should indent already indented item', () => { @@ -96,21 +92,20 @@ describe( 'indentListItems', () => { const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`; const record = { formats: [ , , , , , ], - lines: [ , [ ul ], , [ ul ], , ], - objects: [ , , , , , ], + replacements: [ , [ ul ], , [ ul ], , ], text, start: 5, end: 5, }; const expected = { ...record, - lines: [ , [ ul ], , [ ul, ul ], , ], + replacements: [ , [ ul ], , [ ul, ul ], , ], }; const result = indentListItems( deepFreeze( record ), ul ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.lines ) ).toBe( 2 ); + expect( getSparseArrayLength( result.replacements ) ).toBe( 2 ); } ); it( 'should indent with multiple lines selected', () => { @@ -118,21 +113,20 @@ describe( 'indentListItems', () => { const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`; const record = { formats: [ , , , , , ], - lines: [ , , , [ ul ], , ], - objects: [ , , , , , ], + replacements: [ , , , [ ul ], , ], text, start: 2, end: 5, }; const expected = { ...record, - lines: [ , [ ul ], , [ ul, ul ], , ], + replacements: [ , [ ul ], , [ ul, ul ], , ], }; const result = indentListItems( deepFreeze( record ), ul ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.lines ) ).toBe( 2 ); + expect( getSparseArrayLength( result.replacements ) ).toBe( 2 ); } ); it( 'should indent one level at a time', () => { @@ -140,8 +134,7 @@ describe( 'indentListItems', () => { const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3${ LINE_SEPARATOR }4`; const record = { formats: Array( text.length ), - lines: [ , [ ul ], , [ ul, ul ], , , , ], - objects: Array( text.length ), + replacements: [ , [ ul ], , [ ul, ul ], , , , ], text, start: 6, end: 6, @@ -150,28 +143,28 @@ describe( 'indentListItems', () => { const result1 = indentListItems( deepFreeze( record ), ul ); expect( result1 ).not.toBe( record ); - expect( getSparseArrayLength( result1.lines ) ).toBe( 3 ); + expect( getSparseArrayLength( result1.replacements ) ).toBe( 3 ); expect( result1 ).toEqual( { ...record, - lines: [ , [ ul ], , [ ul, ul ], , [ ul ], , ], + replacements: [ , [ ul ], , [ ul, ul ], , [ ul ], , ], } ); const result2 = indentListItems( deepFreeze( result1 ), ul ); expect( result2 ).not.toBe( result1 ); - expect( getSparseArrayLength( result2.lines ) ).toBe( 3 ); + expect( getSparseArrayLength( result2.replacements ) ).toBe( 3 ); expect( result2 ).toEqual( { ...record, - lines: [ , [ ul ], , [ ul, ul ], , [ ul, ul ], , ], + replacements: [ , [ ul ], , [ ul, ul ], , [ ul, ul ], , ], } ); const result3 = indentListItems( deepFreeze( result2 ), ul ); expect( result3 ).not.toBe( result2 ); - expect( getSparseArrayLength( result3.lines ) ).toBe( 3 ); + expect( getSparseArrayLength( result3.replacements ) ).toBe( 3 ); expect( result3 ).toEqual( { ...record, - lines: [ , [ ul ], , [ ul, ul ], , [ ul, ul, ul ], , ], + replacements: [ , [ ul ], , [ ul, ul ], , [ ul, ul, ul ], , ], } ); } ); } ); diff --git a/packages/rich-text/src/test/insert-line-separator.js b/packages/rich-text/src/test/insert-line-separator.js index 5b79e492eaef15..497555cc4a01a0 100644 --- a/packages/rich-text/src/test/insert-line-separator.js +++ b/packages/rich-text/src/test/insert-line-separator.js @@ -17,16 +17,14 @@ describe( 'insertLineSeparator', () => { it( 'should insert line separator at end', () => { const value = { formats: [ , ], - lines: [ , ], - objects: [ , ], + replacements: [ , ], text: '1', start: 1, end: 1, }; const expected = { formats: [ , , ], - lines: [ , , ], - objects: [ , , ], + replacements: [ , , ], text: `1${ LINE_SEPARATOR }`, start: 2, end: 2, @@ -35,22 +33,20 @@ describe( 'insertLineSeparator', () => { expect( result ).not.toBe( value ); expect( result ).toEqual( expected ); - expect( getSparseArrayLength( result.lines ) ).toBe( 0 ); + expect( getSparseArrayLength( result.replacements ) ).toBe( 0 ); } ); it( 'should insert line separator at start', () => { const value = { formats: [ , ], - lines: [ , ], - objects: [ , ], + replacements: [ , ], text: '1', start: 0, end: 0, }; const expected = { formats: [ , , ], - lines: [ , , ], - objects: [ , , ], + replacements: [ , , ], text: `${ LINE_SEPARATOR }1`, start: 1, end: 1, @@ -59,22 +55,20 @@ describe( 'insertLineSeparator', () => { expect( result ).not.toBe( value ); expect( result ).toEqual( expected ); - expect( getSparseArrayLength( result.lines ) ).toBe( 0 ); + expect( getSparseArrayLength( result.replacements ) ).toBe( 0 ); } ); it( 'should insert line separator with previous line separator formats', () => { const value = { formats: [ , , , , , ], - lines: [ , , , [ ol ], , ], - objects: [ , , , , , ], + replacements: [ , , , [ ol ], , ], text: `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }a`, start: 5, end: 5, }; const expected = { formats: [ , , , , , , ], - lines: [ , , , [ ol ], , [ ol ] ], - objects: [ , , , , , , ], + replacements: [ , , , [ ol ], , [ ol ] ], text: `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }a${ LINE_SEPARATOR }`, start: 6, end: 6, @@ -83,22 +77,20 @@ describe( 'insertLineSeparator', () => { expect( result ).not.toBe( value ); expect( result ).toEqual( expected ); - expect( getSparseArrayLength( result.lines ) ).toBe( 2 ); + expect( getSparseArrayLength( result.replacements ) ).toBe( 2 ); } ); it( 'should insert line separator without formats if previous line separator did not have any', () => { const value = { formats: [ , , , , , ], - lines: [ , , , , , ], - objects: [ , , , , , ], + replacements: [ , , , , , ], text: `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }a`, start: 5, end: 5, }; const expected = { formats: [ , , , , , , ], - lines: [ , , , , , , ], - objects: [ , , , , , , ], + replacements: [ , , , , , , ], text: `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }a${ LINE_SEPARATOR }`, start: 6, end: 6, @@ -107,6 +99,6 @@ describe( 'insertLineSeparator', () => { expect( result ).not.toBe( value ); expect( result ).toEqual( expected ); - expect( getSparseArrayLength( result.lines ) ).toBe( 0 ); + expect( getSparseArrayLength( result.replacements ) ).toBe( 0 ); } ); } ); diff --git a/packages/rich-text/src/test/insert-object.js b/packages/rich-text/src/test/insert-object.js index e835cc9f1a9b73..7c2ba57806ad03 100644 --- a/packages/rich-text/src/test/insert-object.js +++ b/packages/rich-text/src/test/insert-object.js @@ -17,16 +17,14 @@ describe( 'insert', () => { it( 'should delete and insert', () => { const record = { formats: [ , , , , [ em ], [ em ], [ em ], , , , , , , ], - lines: [ , , , , , , , , , , , , , ], - objects: [ , , , , , , , , , , , , , ], + replacements: [ , , , , , , , , , , , , , ], text: 'one two three', start: 6, end: 6, }; const expected = { formats: [ , , , [ em ], , , , , , , ], - lines: [ , , , , , , , , , , ], - objects: [ , , obj, , , , , , , , ], + replacements: [ , , obj, , , , , , , , ], text: `on${ OBJECT_REPLACEMENT_CHARACTER }o three`, start: 3, end: 3, @@ -36,6 +34,6 @@ describe( 'insert', () => { expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); expect( getSparseArrayLength( result.formats ) ).toBe( 1 ); - expect( getSparseArrayLength( result.objects ) ).toBe( 1 ); + expect( getSparseArrayLength( result.replacements ) ).toBe( 1 ); } ); } ); diff --git a/packages/rich-text/src/test/insert.js b/packages/rich-text/src/test/insert.js index b22747210bcbfe..cae4cc5b85d5f5 100644 --- a/packages/rich-text/src/test/insert.js +++ b/packages/rich-text/src/test/insert.js @@ -17,22 +17,19 @@ describe( 'insert', () => { it( 'should delete and insert', () => { const record = { formats: [ , , , , [ em ], [ em ], [ em ], , , , , , , ], - lines: [], - objects: [], + replacements: [], text: 'one two three', start: 6, end: 6, }; const toInsert = { formats: [ [ strong ] ], - lines: [], - objects: [], + replacements: [], text: 'a', }; const expected = { formats: [ , , [ strong ], [ em ], , , , , , , ], - lines: [], - objects: [], + replacements: [], text: 'onao three', start: 3, end: 3, @@ -47,22 +44,19 @@ describe( 'insert', () => { it( 'should insert line break with selection', () => { const record = { formats: [ , , ], - lines: [], - objects: [], + replacements: [], text: 'tt', start: 1, end: 1, }; const toInsert = { formats: [ , ], - lines: [], - objects: [], + replacements: [], text: '\n', }; const expected = { formats: [ , , , ], - lines: [], - objects: [], + replacements: [], text: 't\nt', start: 2, end: 2, diff --git a/packages/rich-text/src/test/join.js b/packages/rich-text/src/test/join.js index 6f7f681dec1bf8..84801125cc2b0a 100644 --- a/packages/rich-text/src/test/join.js +++ b/packages/rich-text/src/test/join.js @@ -16,8 +16,7 @@ describe( 'join', () => { ' ', { formats: [ , ], - lines: [ , ], - objects: [ , ], + replacements: [ , ], text: ' ', }, ]; @@ -26,20 +25,17 @@ describe( 'join', () => { it( 'should join records with string separator', () => { const one = { formats: [ , , [ em ] ], - lines: [ , , , ], - objects: [ , , , ], + replacements: [ , , , ], text: 'one', }; const two = { formats: [ [ em ], , , ], - lines: [ , , , ], - objects: [ , , , ], + replacements: [ , , , ], text: 'two', }; const three = { formats: [ , , [ em ], , [ em ], , , ], - lines: [ , , , , , , , ], - objects: [ , , , , , , , ], + replacements: [ , , , , , , , ], text: 'one two', }; const result = join( [ deepFreeze( one ), deepFreeze( two ) ], separator ); diff --git a/packages/rich-text/src/test/outdent-list-items.js b/packages/rich-text/src/test/outdent-list-items.js index 3ef8091e148400..ef06ff9fe3f073 100644 --- a/packages/rich-text/src/test/outdent-list-items.js +++ b/packages/rich-text/src/test/outdent-list-items.js @@ -17,8 +17,7 @@ describe( 'outdentListItems', () => { it( 'should not outdent only item', () => { const record = { formats: [ , ], - lines: [ , ], - objects: [ , ], + replacements: [ , ], text: '1', start: 1, end: 1, @@ -27,7 +26,7 @@ describe( 'outdentListItems', () => { expect( result ).toEqual( record ); expect( result ).toBe( record ); - expect( getSparseArrayLength( result.lines ) ).toBe( 0 ); + expect( getSparseArrayLength( result.replacements ) ).toBe( 0 ); } ); it( 'should indent', () => { @@ -35,21 +34,20 @@ describe( 'outdentListItems', () => { const text = `1${ LINE_SEPARATOR }`; const record = { formats: Array( text.length ), - lines: [ , [ ul ] ], - objects: Array( text.length ), + replacements: [ , [ ul ] ], text, start: 2, end: 2, }; const expected = { ...record, - lines: [ , , ], + replacements: [ , , ], }; const result = outdentListItems( deepFreeze( record ) ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.lines ) ).toBe( 0 ); + expect( getSparseArrayLength( result.replacements ) ).toBe( 0 ); } ); it( 'should outdent two levels deep', () => { @@ -57,21 +55,20 @@ describe( 'outdentListItems', () => { const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`; const record = { formats: Array( text.length ), - lines: [ , [ ul ], , [ ul, ul ], , ], - objects: Array( text.length ), + replacements: [ , [ ul ], , [ ul, ul ], , ], text, start: 5, end: 5, }; const expected = { ...record, - lines: [ , [ ul ], , [ ul ], , ], + replacements: [ , [ ul ], , [ ul ], , ], }; const result = outdentListItems( deepFreeze( record ) ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.lines ) ).toBe( 2 ); + expect( getSparseArrayLength( result.replacements ) ).toBe( 2 ); } ); it( 'should outdent with multiple lines selected', () => { @@ -79,21 +76,20 @@ describe( 'outdentListItems', () => { const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`; const record = { formats: Array( text.length ), - lines: [ , [ ul ], , [ ul, ul ], , ], - objects: Array( text.length ), + replacements: [ , [ ul ], , [ ul, ul ], , ], text, start: 2, end: 5, }; const expected = { ...record, - lines: [ , , , [ ul ], , ], + replacements: [ , , , [ ul ], , ], }; const result = outdentListItems( deepFreeze( record ) ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.lines ) ).toBe( 1 ); + expect( getSparseArrayLength( result.replacements ) ).toBe( 1 ); } ); it( 'should outdent list item with children', () => { @@ -101,21 +97,20 @@ describe( 'outdentListItems', () => { const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3${ LINE_SEPARATOR }4`; const record = { formats: Array( text.length ), - lines: [ , [ ul ], , [ ul, ul ], , [ ul, ul ], , ], - objects: Array( text.length ), + replacements: [ , [ ul ], , [ ul, ul ], , [ ul, ul ], , ], text, start: 2, end: 2, }; const expected = { ...record, - lines: [ , , , [ ul ], , [ ul ], , ], + replacements: [ , , , [ ul ], , [ ul ], , ], }; const result = outdentListItems( deepFreeze( record ) ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.lines ) ).toBe( 2 ); + expect( getSparseArrayLength( result.replacements ) ).toBe( 2 ); } ); it( 'should outdent list based on parent list', () => { @@ -123,21 +118,20 @@ describe( 'outdentListItems', () => { const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3${ LINE_SEPARATOR }4`; const record = { formats: Array( text.length ), - lines: [ , [ ul ], , [ ul, ul ], , [ ul ], , ], - objects: Array( text.length ), + replacements: [ , [ ul ], , [ ul, ul ], , [ ul ], , ], text, start: 6, end: 6, }; const expected = { ...record, - lines: [ , [ ul ], , [ ul, ul ], , , , ], + replacements: [ , [ ul ], , [ ul, ul ], , , , ], }; const result = outdentListItems( deepFreeze( record ) ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.lines ) ).toBe( 2 ); + expect( getSparseArrayLength( result.replacements ) ).toBe( 2 ); } ); it( 'should outdent when a selected item is at level 0', () => { @@ -145,20 +139,19 @@ describe( 'outdentListItems', () => { const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`; const record = { formats: Array( text.length ), - lines: [ , [ ul ], , , , ], - objects: Array( text.length ), + replacements: [ , [ ul ], , , , ], text, start: 2, end: 5, }; const expected = { ...record, - lines: [ , , , , , ], + replacements: [ , , , , , ], }; const result = outdentListItems( deepFreeze( record ) ); expect( result ).toEqual( expected ); expect( result ).not.toBe( record ); - expect( getSparseArrayLength( result.lines ) ).toBe( 0 ); + expect( getSparseArrayLength( result.replacements ) ).toBe( 0 ); } ); } ); diff --git a/packages/rich-text/src/test/replace.js b/packages/rich-text/src/test/replace.js index 456a45faa3b5d8..6cfd4dcc9e48b7 100644 --- a/packages/rich-text/src/test/replace.js +++ b/packages/rich-text/src/test/replace.js @@ -16,16 +16,14 @@ describe( 'replace', () => { it( 'should replace string to string', () => { const record = { formats: [ , , , , [ em ], [ em ], [ em ], , , , , , , ], - lines: [ , , , , , , , , , , , , , ], - objects: [ , , , , , , , , , , , , , ], + replacements: [ , , , , , , , , , , , , , ], text: 'one two three', start: 6, end: 6, }; const expected = { formats: [ , , , , [ em ], , , , , , , ], - lines: [ , , , , , , , , , , , ], - objects: [ , , , , , , , , , , , ], + replacements: [ , , , , , , , , , , , ], text: 'one 2 three', start: 5, end: 5, @@ -40,22 +38,19 @@ describe( 'replace', () => { it( 'should replace string to record', () => { const record = { formats: [ , , , , [ em ], [ em ], [ em ], , , , , , , ], - lines: [ , , , , , , , , , , , , , ], - objects: [ , , , , , , , , , , , , , ], + replacements: [ , , , , , , , , , , , , , ], text: 'one two three', start: 6, end: 6, }; const replacement = { formats: [ , ], - lines: [ , ], - objects: [ , ], + replacements: [ , ], text: '2', }; const expected = { formats: [ , , , , , , , , , , , ], - lines: [ , , , , , , , , , , , ], - objects: [ , , , , , , , , , , , ], + replacements: [ , , , , , , , , , , , ], text: 'one 2 three', start: 5, end: 5, @@ -70,16 +65,14 @@ describe( 'replace', () => { it( 'should replace string to function', () => { const record = { formats: [ , , , , , , , , , , , , ], - lines: [ , , , , , , , , , , , , ], - objects: [ , , , , , , , , , , , , ], + replacements: [ , , , , , , , , , , , , ], text: 'abc12345#$*%', start: 6, end: 6, }; const expected = { formats: [ , , , , , , , , , , , , , , , , , , ], - lines: [ , , , , , , , , , , , , , , , , , , ], - objects: [ , , , , , , , , , , , , , , , , , , ], + replacements: [ , , , , , , , , , , , , , , , , , , ], text: 'abc - 12345 - #$*%', start: 18, end: 18, diff --git a/packages/rich-text/src/test/slice.js b/packages/rich-text/src/test/slice.js index cfd53a8bf859b5..b181e5e9be8171 100644 --- a/packages/rich-text/src/test/slice.js +++ b/packages/rich-text/src/test/slice.js @@ -16,14 +16,12 @@ describe( 'slice', () => { it( 'should slice', () => { const record = { formats: [ , , , , [ em ], [ em ], [ em ], , , , , , , ], - lines: [ , , , , , , , , , , , , , ], - objects: [ , , , , , , , , , , , , , ], + replacements: [ , , , , , , , , , , , , , ], text: 'one two three', }; const expected = { formats: [ , [ em ], [ em ] ], - lines: [ , , , ], - objects: [ , , , ], + replacements: [ , , , ], text: ' tw', }; const result = slice( deepFreeze( record ), 3, 6 ); @@ -36,16 +34,14 @@ describe( 'slice', () => { it( 'should slice record', () => { const record = { formats: [ , , , , [ em ], [ em ], [ em ], , , , , , , ], - lines: [ , , , , , , , , , , , , , ], - objects: [ , , , , , , , , , , , , , ], + replacements: [ , , , , , , , , , , , , , ], text: 'one two three', start: 3, end: 6, }; const expected = { formats: [ , [ em ], [ em ] ], - lines: [ , , , ], - objects: [ , , , ], + replacements: [ , , , ], text: ' tw', }; const result = slice( deepFreeze( record ) ); diff --git a/packages/rich-text/src/test/split.js b/packages/rich-text/src/test/split.js index 1c82d3fb1a8081..8eef998e488d6e 100644 --- a/packages/rich-text/src/test/split.js +++ b/packages/rich-text/src/test/split.js @@ -18,23 +18,20 @@ describe( 'split', () => { start: 5, end: 10, formats: [ , , , , [ em ], [ em ], [ em ], , , , , , , ], - lines: [ , , , , , , , , , , , , , ], - objects: [ , , , , , , , , , , , , , ], + replacements: [ , , , , , , , , , , , , , ], text: 'one two three', }; const expected = [ { formats: [ , , , , [ em ], [ em ] ], - lines: [ , , , , , , ], - objects: [ , , , , , , ], + replacements: [ , , , , , , ], text: 'one tw', }, { start: 0, end: 0, formats: [ [ em ], , , , , , , ], - lines: [ , , , , , , , ], - objects: [ , , , , , , , ], + replacements: [ , , , , , , , ], text: 'o three', }, ]; @@ -51,8 +48,7 @@ describe( 'split', () => { it( 'should split with selection', () => { const record = { formats: [ , , , , [ em ], [ em ], [ em ], , , , , , , ], - lines: [ , , , , , , , , , , , , , ], - objects: [ , , , , , , , , , , , , , ], + replacements: [ , , , , , , , , , , , , , ], text: 'one two three', start: 6, end: 6, @@ -60,14 +56,12 @@ describe( 'split', () => { const expected = [ { formats: [ , , , , [ em ], [ em ] ], - lines: [ , , , , , , ], - objects: [ , , , , , , ], + replacements: [ , , , , , , ], text: 'one tw', }, { formats: [ [ em ], , , , , , , ], - lines: [ , , , , , , , ], - objects: [ , , , , , , , ], + replacements: [ , , , , , , , ], text: 'o three', start: 0, end: 0, @@ -86,8 +80,7 @@ describe( 'split', () => { it( 'should split empty', () => { const record = { formats: [], - lines: [], - objects: [], + replacements: [], text: '', start: 0, end: 0, @@ -95,14 +88,12 @@ describe( 'split', () => { const expected = [ { formats: [], - lines: [], - objects: [], + replacements: [], text: '', }, { formats: [], - lines: [], - objects: [], + replacements: [], text: '', start: 0, end: 0, @@ -121,8 +112,7 @@ describe( 'split', () => { it( 'should split multiline', () => { const record = { formats: [ , , , , , , , , , , ], - lines: [ , , , , , , , , , , ], - objects: [ , , , , , , , , , , ], + replacements: [ , , , , , , , , , , ], text: 'test\u2028\u2028test', start: 5, end: 5, @@ -130,14 +120,12 @@ describe( 'split', () => { const expected = [ { formats: [ , , , , ], - lines: [ , , , , ], - objects: [ , , , , ], + replacements: [ , , , , ], text: 'test', }, { formats: [ , , , , ], - lines: [ , , , , ], - objects: [ , , , , ], + replacements: [ , , , , ], text: 'test', start: 0, end: 0, @@ -158,45 +146,39 @@ describe( 'split', () => { start: 6, end: 16, formats: [ , , , , [ em ], [ em ], [ em ], , , , , , , , , , , , , , , , , ], - lines: [ , , , , , , , , , , , , , , , , , , , , , , , ], - objects: [ , , , , , , , , , , , , , , , , , , , , , , , ], + replacements: [ , , , , , , , , , , , , , , , , , , , , , , , ], text: 'one two three four five', }; const expected = [ { formats: [ , , , ], - lines: [ , , , ], - objects: [ , , , ], + replacements: [ , , , ], text: 'one', }, { start: 2, end: 3, formats: [ [ em ], [ em ], [ em ] ], - lines: [ , , , ], - objects: [ , , , ], + replacements: [ , , , ], text: 'two', }, { start: 0, end: 5, formats: [ , , , , , ], - lines: [ , , , , , ], - objects: [ , , , , , ], + replacements: [ , , , , , ], text: 'three', }, { start: 0, end: 2, formats: [ , , , , ], - lines: [ , , , , ], - objects: [ , , , , ], + replacements: [ , , , , ], text: 'four', }, { formats: [ , , , , ], - lines: [ , , , , ], - objects: [ , , , , ], + replacements: [ , , , , ], text: 'five', }, ]; @@ -215,29 +197,25 @@ describe( 'split', () => { start: 5, end: 6, formats: [ , , , , [ em ], [ em ], [ em ], , , , , , , ], - lines: [ , , , , , , , , , , , , , ], - objects: [ , , , , , , , , , , , , , ], + replacements: [ , , , , , , , , , , , , , ], text: 'one two three', }; const expected = [ { formats: [ , , , ], - lines: [ , , , ], - objects: [ , , , ], + replacements: [ , , , ], text: 'one', }, { start: 1, end: 2, formats: [ [ em ], [ em ], [ em ] ], - lines: [ , , , ], - objects: [ , , , ], + replacements: [ , , , ], text: 'two', }, { formats: [ , , , , , ], - lines: [ , , , , , ], - objects: [ , , , , , ], + replacements: [ , , , , , ], text: 'three', }, ]; diff --git a/packages/rich-text/src/to-tree.js b/packages/rich-text/src/to-tree.js index 2f949a5cfc69f0..38299e86e79e14 100644 --- a/packages/rich-text/src/to-tree.js +++ b/packages/rich-text/src/to-tree.js @@ -103,7 +103,7 @@ export function toTree( { onEndIndex, isEditableTree, } ) { - const { formats, lines, objects, text, start, end } = value; + const { formats, replacements, text, start, end } = value; const formatsLength = formats.length + 1; const tree = createEmpty(); const multilineFormat = { type: multilineTag }; @@ -137,7 +137,7 @@ export function toTree( { // Set multiline tags in queue for building the tree. if ( multilineTag ) { if ( character === LINE_SEPARATOR ) { - characterFormats = lastSeparatorFormats = ( lines[ i ] || [] ).reduce( ( accumulator, format ) => { + characterFormats = lastSeparatorFormats = ( replacements[ i ] || [] ).reduce( ( accumulator, format ) => { accumulator.push( format ); accumulator.push( multilineFormat ); return accumulator; @@ -236,7 +236,7 @@ export function toTree( { if ( character === OBJECT_REPLACEMENT_CHARACTER ) { pointer = append( getParent( pointer ), fromFormat( { - ...objects[ i ], + ...replacements[ i ], object: true, } ) ); // Ensure pointer is text node. From 60bb806dbc2e81238b7d38ae1a1c7b9b414273c8 Mon Sep 17 00:00:00 2001 From: iseulde Date: Mon, 4 Mar 2019 17:04:39 +0100 Subject: [PATCH 11/18] Fix typos --- .../src/components/rich-text/format-edit.js | 2 +- packages/format-library/src/image/index.js | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/block-editor/src/components/rich-text/format-edit.js b/packages/block-editor/src/components/rich-text/format-edit.js index 790ec092d70a99..29911206aba839 100644 --- a/packages/block-editor/src/components/rich-text/format-edit.js +++ b/packages/block-editor/src/components/rich-text/format-edit.js @@ -26,7 +26,7 @@ const FormatEdit = ( { formatTypes, onChange, value } ) => { isActive ? activeFormat.attributes || {} : {} } isObjectActive={ isObjectActive } - objectAttributes={ + activeObjectAttributes={ isObjectActive ? activeObject.attributes || {} : {} } value={ value } diff --git a/packages/format-library/src/image/index.js b/packages/format-library/src/image/index.js index 441a4934847079..77248a95ced535 100644 --- a/packages/format-library/src/image/index.js +++ b/packages/format-library/src/image/index.js @@ -40,7 +40,7 @@ export const image = { } static getDerivedStateFromProps( props, state ) { - const { objectAttributes: { style } } = props; + const { activeObjectAttributes: { style } } = props; if ( style === state.previousStyle ) { return null; @@ -79,8 +79,8 @@ export const image = { } render() { - const { value, onChange, isObjectActive, objectAttributes } = this.props; - const { style } = objectAttributes; + const { value, onChange, isObjectActive, activeObjectAttributes } = this.props; + const { style } = activeObjectAttributes; // Rerender PositionedAtSelection when the selection changes or when // the width changes. const key = value.start + style; @@ -125,19 +125,19 @@ export const image = { onKeyPress={ stopKeyPropagation } onKeyDown={ this.onKeyDown } onSubmit={ ( event ) => { - const newObjects = value.objects.slice(); + const newReplacements = value.replacements.slice(); - newObjects[ value.start ] = { + newReplacements[ value.start ] = { type: name, attributes: { - ...objectAttributes, + ...activeObjectAttributes, style: `width: ${ this.state.width }px;`, }, }; onChange( { ...value, - objects: newObjects, + replacements: newReplacements, } ); event.preventDefault(); From c844cb86f11c98ddd859ef2ed619ed5d8f5bd884 Mon Sep 17 00:00:00 2001 From: iseulde Date: Mon, 4 Mar 2019 18:01:54 +0100 Subject: [PATCH 12/18] Add getActiveObject unit tests --- .../rich-text/src/test/get-active-object.js | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 packages/rich-text/src/test/get-active-object.js diff --git a/packages/rich-text/src/test/get-active-object.js b/packages/rich-text/src/test/get-active-object.js new file mode 100644 index 00000000000000..35d0f7637c7bc2 --- /dev/null +++ b/packages/rich-text/src/test/get-active-object.js @@ -0,0 +1,41 @@ +/** + * Internal dependencies + */ + +import { getActiveObject } from '../get-active-object'; +import { OBJECT_REPLACEMENT_CHARACTER } from '../special-characters'; + +describe( 'getActiveObject', () => { + it( 'should return object if selected', () => { + const record = { + replacements: [ { type: 'img' } ], + text: OBJECT_REPLACEMENT_CHARACTER, + start: 0, + end: 1, + }; + + expect( getActiveObject( record ) ).toEqual( { type: 'img' } ); + } ); + + it( 'should return nothing if nothing is selected', () => { + const record = { + replacements: [ { type: 'img' } ], + text: OBJECT_REPLACEMENT_CHARACTER, + start: 0, + end: 0, + }; + + expect( getActiveObject( record ) ).toBe( undefined ); + } ); + + it( 'should return nothing if te selection is not an object', () => { + const record = { + replacements: [ { type: 'em' } ], + text: 'a', + start: 0, + end: 1, + }; + + expect( getActiveObject( record ) ).toBe( undefined ); + } ); +} ); From 1dabca6a13f750b02de5f40a8bf638fc970d8b95 Mon Sep 17 00:00:00 2001 From: iseulde Date: Thu, 7 Mar 2019 15:30:54 +0100 Subject: [PATCH 13/18] Update docs --- packages/rich-text/README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/rich-text/README.md b/packages/rich-text/README.md index 62755da3718c74..90fe67367ddc8c 100644 --- a/packages/rich-text/README.md +++ b/packages/rich-text/README.md @@ -68,8 +68,7 @@ to modify without the use of helper functions: { text: string, formats: Array, - objects: Array, - lines: Array, + replacements: Array, ?start: number, ?end: number, } From 2889c29458489876a941cf4aaae093b10c1990e8 Mon Sep 17 00:00:00 2001 From: iseulde Date: Tue, 12 Mar 2019 15:49:24 +0100 Subject: [PATCH 14/18] Rebase --- packages/format-library/src/image/index.js | 2 +- packages/rich-text/src/create.js | 33 +++++++++----------- packages/rich-text/src/test/helpers/index.js | 2 ++ 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/packages/format-library/src/image/index.js b/packages/format-library/src/image/index.js index 77248a95ced535..ce62a8b6c5a759 100644 --- a/packages/format-library/src/image/index.js +++ b/packages/format-library/src/image/index.js @@ -91,7 +91,7 @@ export const image = { icon={ } title={ __( 'Inline Image' ) } onClick={ this.openModal } - isActive={ isActive } + isActive={ isObjectActive } /> { this.state.modal && + formats ? [ format, ...formats ] : [ format ] + ), } ); - continue; } - - mergePair( accumulator, { - ...value, - formats: Array.from( value.formats, ( formats ) => - formats ? [ format, ...formats ] : [ format ] - ), - } ); } return accumulator; diff --git a/packages/rich-text/src/test/helpers/index.js b/packages/rich-text/src/test/helpers/index.js index 7ac345ffb9b9ff..16b09bb19b8326 100644 --- a/packages/rich-text/src/test/helpers/index.js +++ b/packages/rich-text/src/test/helpers/index.js @@ -698,6 +698,7 @@ export const specWithRegistration = [ html: 'a', value: { formats: [ , ], + replacements: [ , ], text: 'a', }, noToHTMLString: true, @@ -720,6 +721,7 @@ export const specWithRegistration = [ attributes: {}, unregisteredAttributes: {}, } ] ], + replacements: [ , ], text: 'a', }, }, From abde860e99a31e8aaf6707016c927514efd37482 Mon Sep 17 00:00:00 2001 From: iseulde Date: Wed, 13 Mar 2019 10:01:56 +0100 Subject: [PATCH 15/18] Adjust unstableToDom arguments --- packages/block-editor/src/components/rich-text/index.js | 2 -- packages/rich-text/src/test/to-dom.js | 2 -- 2 files changed, 4 deletions(-) diff --git a/packages/block-editor/src/components/rich-text/index.js b/packages/block-editor/src/components/rich-text/index.js index a8556d2fd1d0de..1d714ba9844d39 100644 --- a/packages/block-editor/src/components/rich-text/index.js +++ b/packages/block-editor/src/components/rich-text/index.js @@ -941,7 +941,6 @@ export class RichText extends Component { return unstableToDom( { value, multilineTag: this.multilineTag, - multilineWrapperTags: this.multilineWrapperTags, prepareEditableTree: this.props.prepareEditableTree, } ).body.innerHTML; } @@ -980,7 +979,6 @@ export class RichText extends Component { return children.fromDOM( unstableToDom( { value, multilineTag: this.multilineTag, - multilineWrapperTags: this.multilineWrapperTags, isEditableTree: false, } ).body.childNodes ); } diff --git a/packages/rich-text/src/test/to-dom.js b/packages/rich-text/src/test/to-dom.js index 1df1e8e25b229a..8db8a52e1b4435 100644 --- a/packages/rich-text/src/test/to-dom.js +++ b/packages/rich-text/src/test/to-dom.js @@ -24,7 +24,6 @@ describe( 'recordToDom', () => { spec.forEach( ( { description, multilineTag, - multilineWrapperTags, record, startPath, endPath, @@ -33,7 +32,6 @@ describe( 'recordToDom', () => { const { body, selection } = toDom( { value: record, multilineTag, - multilineWrapperTags, } ); expect( body ).toMatchSnapshot(); expect( selection ).toEqual( { startPath, endPath } ); From 8c9def81668396aaa2d87a89d801ba43ec430d17 Mon Sep 17 00:00:00 2001 From: iseulde Date: Wed, 13 Mar 2019 10:22:14 +0100 Subject: [PATCH 16/18] Remove normaliseFormats from list functions --- packages/rich-text/src/change-list-type.js | 5 ++--- packages/rich-text/src/indent-list-items.js | 5 ++--- packages/rich-text/src/outdent-list-items.js | 5 ++--- packages/rich-text/src/test/change-list-type.js | 3 --- packages/rich-text/src/test/indent-list-items.js | 7 ------- packages/rich-text/src/test/outdent-list-items.js | 7 ------- packages/rich-text/src/to-tree.js | 3 +-- 7 files changed, 7 insertions(+), 28 deletions(-) diff --git a/packages/rich-text/src/change-list-type.js b/packages/rich-text/src/change-list-type.js index 7b4075276f6872..e429b91c6cbca6 100644 --- a/packages/rich-text/src/change-list-type.js +++ b/packages/rich-text/src/change-list-type.js @@ -3,7 +3,6 @@ */ import { LINE_SEPARATOR } from './special-characters'; -import { normaliseFormats } from './normalise-formats'; import { getLineIndex } from './get-line-index'; import { getParentLineIndex } from './get-parent-line-index'; @@ -54,8 +53,8 @@ export function changeListType( value, newFormat ) { return value; } - return normaliseFormats( { + return { ...value, replacements: newReplacements, - } ); + }; } diff --git a/packages/rich-text/src/indent-list-items.js b/packages/rich-text/src/indent-list-items.js index 09301583f28be6..985d1062c76ed1 100644 --- a/packages/rich-text/src/indent-list-items.js +++ b/packages/rich-text/src/indent-list-items.js @@ -3,7 +3,6 @@ */ import { LINE_SEPARATOR } from './special-characters'; -import { normaliseFormats } from './normalise-formats'; import { getLineIndex } from './get-line-index'; /** @@ -89,8 +88,8 @@ export function indentListItems( value, rootFormat ) { } } - return normaliseFormats( { + return { ...value, replacements: newFormats, - } ); + }; } diff --git a/packages/rich-text/src/outdent-list-items.js b/packages/rich-text/src/outdent-list-items.js index 4a2087ed532712..19fac90515dfb2 100644 --- a/packages/rich-text/src/outdent-list-items.js +++ b/packages/rich-text/src/outdent-list-items.js @@ -3,7 +3,6 @@ */ import { LINE_SEPARATOR } from './special-characters'; -import { normaliseFormats } from './normalise-formats'; import { getLineIndex } from './get-line-index'; import { getParentLineIndex } from './get-parent-line-index'; import { getLastChildIndex } from './get-last-child-index'; @@ -51,8 +50,8 @@ export function outdentListItems( value ) { } } - return normaliseFormats( { + return { ...value, replacements: newFormats, - } ); + }; } diff --git a/packages/rich-text/src/test/change-list-type.js b/packages/rich-text/src/test/change-list-type.js index cdc9821bb30d00..6294368c6427d2 100644 --- a/packages/rich-text/src/test/change-list-type.js +++ b/packages/rich-text/src/test/change-list-type.js @@ -17,7 +17,6 @@ describe( 'changeListType', () => { it( 'should only change list type if list item is indented', () => { const record = { - formats: [], replacements: [ , ], text: '1', start: 1, @@ -32,7 +31,6 @@ describe( 'changeListType', () => { it( 'should change list type', () => { const record = { - formats: [], replacements: [ , [ ul ] ], text: `1${ LINE_SEPARATOR }`, start: 2, @@ -54,7 +52,6 @@ describe( 'changeListType', () => { const text = `a${ LINE_SEPARATOR }1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }i${ LINE_SEPARATOR }3${ LINE_SEPARATOR }4${ LINE_SEPARATOR }b`; const record = { - formats: [], replacements: [ , [ ul ], , [ ul ], , [ ul, ul ], , [ ul ], , [ ul ], , , , [ ul ], , ], text, start: 4, diff --git a/packages/rich-text/src/test/indent-list-items.js b/packages/rich-text/src/test/indent-list-items.js index e37b788833e5dc..349174247cc422 100644 --- a/packages/rich-text/src/test/indent-list-items.js +++ b/packages/rich-text/src/test/indent-list-items.js @@ -17,7 +17,6 @@ describe( 'indentListItems', () => { it( 'should not indent only item', () => { const record = { - formats: [ , ], replacements: [ , ], text: '1', start: 1, @@ -34,7 +33,6 @@ describe( 'indentListItems', () => { // As we're testing list formats, the text should remain the same. const text = `1${ LINE_SEPARATOR }`; const record = { - formats: [ , , ], replacements: [ , , ], text, start: 2, @@ -53,7 +51,6 @@ describe( 'indentListItems', () => { it( 'should not indent without target list', () => { const record = { - formats: [ , , ], replacements: [ , [ ul ] ], text: `1${ LINE_SEPARATOR }`, start: 2, @@ -70,7 +67,6 @@ describe( 'indentListItems', () => { // As we're testing list formats, the text should remain the same. const text = `1${ LINE_SEPARATOR }${ LINE_SEPARATOR }`; const record = { - formats: [ , , , ], replacements: [ , [ ol ], , ], text, start: 3, @@ -91,7 +87,6 @@ describe( 'indentListItems', () => { // As we're testing list formats, the text should remain the same. const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`; const record = { - formats: [ , , , , , ], replacements: [ , [ ul ], , [ ul ], , ], text, start: 5, @@ -112,7 +107,6 @@ describe( 'indentListItems', () => { // As we're testing list formats, the text should remain the same. const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`; const record = { - formats: [ , , , , , ], replacements: [ , , , [ ul ], , ], text, start: 2, @@ -133,7 +127,6 @@ describe( 'indentListItems', () => { // As we're testing list formats, the text should remain the same. const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3${ LINE_SEPARATOR }4`; const record = { - formats: Array( text.length ), replacements: [ , [ ul ], , [ ul, ul ], , , , ], text, start: 6, diff --git a/packages/rich-text/src/test/outdent-list-items.js b/packages/rich-text/src/test/outdent-list-items.js index ef06ff9fe3f073..e4325dfb61c904 100644 --- a/packages/rich-text/src/test/outdent-list-items.js +++ b/packages/rich-text/src/test/outdent-list-items.js @@ -16,7 +16,6 @@ describe( 'outdentListItems', () => { it( 'should not outdent only item', () => { const record = { - formats: [ , ], replacements: [ , ], text: '1', start: 1, @@ -33,7 +32,6 @@ describe( 'outdentListItems', () => { // As we're testing list formats, the text should remain the same. const text = `1${ LINE_SEPARATOR }`; const record = { - formats: Array( text.length ), replacements: [ , [ ul ] ], text, start: 2, @@ -54,7 +52,6 @@ describe( 'outdentListItems', () => { // As we're testing list formats, the text should remain the same. const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`; const record = { - formats: Array( text.length ), replacements: [ , [ ul ], , [ ul, ul ], , ], text, start: 5, @@ -75,7 +72,6 @@ describe( 'outdentListItems', () => { // As we're testing list formats, the text should remain the same. const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`; const record = { - formats: Array( text.length ), replacements: [ , [ ul ], , [ ul, ul ], , ], text, start: 2, @@ -96,7 +92,6 @@ describe( 'outdentListItems', () => { // As we're testing list formats, the text should remain the same. const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3${ LINE_SEPARATOR }4`; const record = { - formats: Array( text.length ), replacements: [ , [ ul ], , [ ul, ul ], , [ ul, ul ], , ], text, start: 2, @@ -117,7 +112,6 @@ describe( 'outdentListItems', () => { // As we're testing list formats, the text should remain the same. const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3${ LINE_SEPARATOR }4`; const record = { - formats: Array( text.length ), replacements: [ , [ ul ], , [ ul, ul ], , [ ul ], , ], text, start: 6, @@ -138,7 +132,6 @@ describe( 'outdentListItems', () => { // As we're testing list formats, the text should remain the same. const text = `1${ LINE_SEPARATOR }2${ LINE_SEPARATOR }3`; const record = { - formats: Array( text.length ), replacements: [ , [ ul ], , , , ], text, start: 2, diff --git a/packages/rich-text/src/to-tree.js b/packages/rich-text/src/to-tree.js index 38299e86e79e14..ef15fe7524b6ea 100644 --- a/packages/rich-text/src/to-tree.js +++ b/packages/rich-text/src/to-tree.js @@ -138,8 +138,7 @@ export function toTree( { if ( multilineTag ) { if ( character === LINE_SEPARATOR ) { characterFormats = lastSeparatorFormats = ( replacements[ i ] || [] ).reduce( ( accumulator, format ) => { - accumulator.push( format ); - accumulator.push( multilineFormat ); + accumulator.push( format, multilineFormat ); return accumulator; }, [ multilineFormat ] ); } else { From 62fa458ce672c5cd7da9c172751d948b65a6c7a3 Mon Sep 17 00:00:00 2001 From: iseulde Date: Wed, 13 Mar 2019 11:06:21 +0100 Subject: [PATCH 17/18] Update native files --- packages/rich-text/src/apply-format.native.js | 14 ++++---- .../rich-text/src/normalise-formats.native.js | 36 ------------------- .../rich-text/src/remove-format.native.js | 9 ++--- 3 files changed, 12 insertions(+), 47 deletions(-) delete mode 100644 packages/rich-text/src/normalise-formats.native.js diff --git a/packages/rich-text/src/apply-format.native.js b/packages/rich-text/src/apply-format.native.js index 9c5a4749ae928b..ef641cbaa224d9 100644 --- a/packages/rich-text/src/apply-format.native.js +++ b/packages/rich-text/src/apply-format.native.js @@ -23,11 +23,13 @@ import { normaliseFormats } from './normalise-formats'; * @return {Object} A new value with the format applied. */ export function applyFormat( - { formats: currentFormats, formatPlaceholder, text, start, end }, + value, formats, - startIndex = start, - endIndex = end + startIndex = value.start, + endIndex = value.end ) { + const { formats: currentFormats, formatPlaceholder, start } = value; + if ( ! Array.isArray( formats ) ) { formats = [ formats ]; } @@ -40,10 +42,8 @@ export function applyFormat( // Follow the same logic as in getActiveFormat: placeholderFormats has priority over previousFormats const activeFormats = ( placeholderFormats ? placeholderFormats : previousFormats ) || []; return { + ...value, formats: currentFormats, - text, - start, - end, formatPlaceholder: { index: start, formats: mergeFormats( activeFormats, formats ), @@ -57,7 +57,7 @@ export function applyFormat( applyFormats( newFormats, index, formats ); } - return normaliseFormats( { formats: newFormats, text, start, end } ); + return normaliseFormats( { ...value, formats: newFormats } ); } function mergeFormats( formats1, formats2 ) { diff --git a/packages/rich-text/src/normalise-formats.native.js b/packages/rich-text/src/normalise-formats.native.js deleted file mode 100644 index 2a75e343a2c125..00000000000000 --- a/packages/rich-text/src/normalise-formats.native.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Internal dependencies - */ - -import { isFormatEqual } from './is-format-equal'; - -/** - * Normalises formats: ensures subsequent equal formats have the same reference. - * - * @param {Object} value Value to normalise formats of. - * - * @return {Object} New value with normalised formats. - */ -export function normaliseFormats( { formats, formatPlaceholder, text, start, end } ) { - const newFormats = formats.slice( 0 ); - - newFormats.forEach( ( formatsAtIndex, index ) => { - const lastFormatsAtIndex = newFormats[ index - 1 ]; - - if ( lastFormatsAtIndex ) { - const newFormatsAtIndex = formatsAtIndex.slice( 0 ); - - newFormatsAtIndex.forEach( ( format, formatIndex ) => { - const lastFormat = lastFormatsAtIndex[ formatIndex ]; - - if ( isFormatEqual( format, lastFormat ) ) { - newFormatsAtIndex[ formatIndex ] = lastFormat; - } - } ); - - newFormats[ index ] = newFormatsAtIndex; - } - } ); - - return { formats: newFormats, formatPlaceholder, text, start, end }; -} diff --git a/packages/rich-text/src/remove-format.native.js b/packages/rich-text/src/remove-format.native.js index b6213f813bb636..5c20260728b719 100644 --- a/packages/rich-text/src/remove-format.native.js +++ b/packages/rich-text/src/remove-format.native.js @@ -23,11 +23,12 @@ import { normaliseFormats } from './normalise-formats'; * @return {Object} A new value with the format applied. */ export function removeFormat( - { formats, formatPlaceholder, text, start, end }, + value, formatType, - startIndex = start, - endIndex = end + startIndex = value.start, + endIndex = value.end ) { + const { formats, formatPlaceholder, start, end } = value; const newFormats = formats.slice( 0 ); let newFormatPlaceholder = null; @@ -55,7 +56,7 @@ export function removeFormat( } } - return normaliseFormats( { formats: newFormats, formatPlaceholder: newFormatPlaceholder, text, start, end } ); + return normaliseFormats( { ...value, formats: newFormats, formatPlaceholder: newFormatPlaceholder } ); } function filterFormats( formats, index, formatType ) { From 0c97f0dccc248dc5a17e4aa2a7d68f27d92b4cba Mon Sep 17 00:00:00 2001 From: iseulde Date: Wed, 13 Mar 2019 12:04:38 +0100 Subject: [PATCH 18/18] Update native file --- .../src/components/rich-text/index.native.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/packages/block-editor/src/components/rich-text/index.native.js b/packages/block-editor/src/components/rich-text/index.native.js index 55bf4580e5e70d..db750a18d41f26 100644 --- a/packages/block-editor/src/components/rich-text/index.native.js +++ b/packages/block-editor/src/components/rich-text/index.native.js @@ -98,9 +98,9 @@ export class RichText extends Component { const { formatPlaceholder, start, end } = this.state; // Since we get the text selection from Aztec we need to be in sync with the HTML `value` // Removing leading white spaces using `trim()` should make sure this is the case. - const { formats, text } = this.formatToValue( this.props.value === undefined ? undefined : this.props.value.trimLeft() ); + const { formats, replacements, text } = this.formatToValue( this.props.value === undefined ? undefined : this.props.value.trimLeft() ); - return { formats, formatPlaceholder, text, start, end }; + return { formats, replacements, formatPlaceholder, text, start, end }; } /* @@ -156,13 +156,12 @@ export class RichText extends Component { onSplit( before, after, ...blocks ); } - valueToFormat( { formats, text } ) { - const value = toHTMLString( { - value: { formats, text }, - multilineTag: this.multilineTag, - } ); + valueToFormat( value ) { // remove the outer root tags - return this.removeRootTagsProduceByAztec( value ); + return this.removeRootTagsProduceByAztec( toHTMLString( { + value, + multilineTag: this.multilineTag, + } ) ); } getActiveFormatNames( record ) {