@@ -10,15 +10,22 @@ import { isFormatEqual } from './is-format-equal';
1010 * Efficiently updates all the formats from `start` (including) until `end`
1111 * (excluding) with the active formats. Mutates `value`.
1212 *
13- * @param {Object } $1 Named paramentes.
14- * @param {RichTextValue } $1.value Value te update.
15- * @param {number } $1.start Index to update from.
16- * @param {number } $1.end Index to update until.
17- * @param {Array } $1.formats Replacement formats.
13+ * @param {Object } $1 Named parameters.
14+ * @param {RichTextValue } $1.value Value to update.
15+ * @param {number } $1.start Index to update from.
16+ * @param {number } $1.end Index to update until.
17+ * @param {Array } $1.formats Replacement formats.
18+ * @param {Array } $1.preserveEditorOnlyFormatsFrom Formats that were active at the caret before typing.
1819 *
1920 * @return {RichTextValue } Mutated value.
2021 */
21- export function updateFormats ( { value, start, end, formats } ) {
22+ export function updateFormats ( {
23+ value,
24+ start,
25+ end,
26+ formats,
27+ preserveEditorOnlyFormatsFrom = [ ] ,
28+ } ) {
2229 // Start and end may be switched in case of delete.
2330 const min = Math . min ( start , end ) ;
2431 const max = Math . max ( start , end ) ;
@@ -48,24 +55,32 @@ export function updateFormats( { value, start, end, formats } ) {
4855 return format ;
4956 } ) ;
5057
51- // Preserve editor-only formats (like annotations) from surrounding positions
52- // when typing, so annotations grow to include newly typed text.
53- const annotationFormatsBefore = formatsBefore . filter (
54- ( format ) => format . type === 'core/annotation'
55- ) ;
56- const annotationFormatsAfter = formatsAfter . filter (
58+ const wasInsideAnnotation = preserveEditorOnlyFormatsFrom . some (
5759 ( format ) => format . type === 'core/annotation'
5860 ) ;
59- // Merge annotation formats from both positions, preferring formatsAfter.
60- const annotationFormats = [
61- ...annotationFormatsAfter ,
62- ...annotationFormatsBefore . filter (
63- ( format ) =>
64- ! annotationFormatsAfter . find ( ( f ) =>
65- isFormatEqual ( f , format )
66- )
67- ) ,
68- ] ;
61+
62+ // Preserve editor-only formats (like annotations) from surrounding positions
63+ // when typing, so annotations grow to include newly typed text. Only do this
64+ // when the caret was inside an annotation before typing.
65+ let annotationFormats = [ ] ;
66+ if ( wasInsideAnnotation ) {
67+ const annotationFormatsBefore = formatsBefore . filter (
68+ ( format ) => format . type === 'core/annotation'
69+ ) ;
70+ const annotationFormatsAfter = formatsAfter . filter (
71+ ( format ) => format . type === 'core/annotation'
72+ ) ;
73+ // Merge annotation formats from both positions, preferring formatsAfter.
74+ annotationFormats = [
75+ ...annotationFormatsAfter ,
76+ ...annotationFormatsBefore . filter (
77+ ( format ) =>
78+ ! annotationFormatsAfter . find ( ( f ) =>
79+ isFormatEqual ( f , format )
80+ )
81+ ) ,
82+ ] ;
83+ }
6984
7085 while ( -- end >= start ) {
7186 if ( value . activeFormats . length > 0 || annotationFormats . length > 0 ) {
0 commit comments