jenkins-bot has submitted this change and it was merged.

Change subject: Fix TextState#getChangeTransaction bug
......................................................................


Fix TextState#getChangeTransaction bug

Also document the algorithm more clearly

Bug: T141573
Change-Id: I3cfca36c289a6936810665233547d37ef504905f
---
M src/ce/ve.ce.TextState.js
M tests/ce/ve.ce.TextState.test.js
2 files changed, 52 insertions(+), 11 deletions(-)

Approvals:
  Esanders: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/src/ce/ve.ce.TextState.js b/src/ce/ve.ce.TextState.js
index 1663f74..5aa464b 100644
--- a/src/ce/ve.ce.TextState.js
+++ b/src/ce/ve.ce.TextState.js
@@ -213,7 +213,11 @@
        // During typical typing, there is a single changed chunk with matching 
start/end chars.
        textStart = 0;
        textEnd = 0;
-       if ( change.start < Math.min( oldChunks.length, newChunks.length ) ) {
+       if ( change.start + change.end < Math.min( oldChunks.length, 
newChunks.length ) ) {
+               // Both oldChunks and newChunks include a changed chunk. 
Therefore the first changed
+               // chunk of oldChunks and newChunks is respectively oldChunks[ 
change.start ] and
+               // newChunks[ change.start ] . If they have matching 
annotations, then matching
+               // characters at their start are also part of the unchanged 
start region.
                if ( oldChunks[ change.start ].hasEqualElements( newChunks[ 
change.start ] ) ) {
                        oldChunk = oldChunks[ change.start ];
                        newChunk = newChunks[ change.start ];
@@ -226,19 +230,22 @@
                        textStart = i;
                }
 
-               if (
-                       change.end < Math.min( oldChunks.length, 
newChunks.length ) &&
-                       oldChunks[ oldChunks.length - 1 - change.end 
].hasEqualElements(
+               // Likewise, the last changed chunk of oldChunks and newChunks 
is respectively
+               // oldChunks[ oldChunks.length - 1 - change.end ] and
+               // newChunks[ newChunks.length - 1 - change.end ] , and if they 
have matching
+               // annotations, then matching characters at their end 
potentially form part of
+               // the unchanged end region.
+               if ( oldChunks[ oldChunks.length - 1 - change.end 
].hasEqualElements(
                                newChunks[ newChunks.length - 1 - change.end ]
-                       )
-               ) {
+               ) ) {
                        oldChunk = oldChunks[ oldChunks.length - 1 - change.end 
];
                        newChunk = newChunks[ newChunks.length - 1 - change.end 
];
-                       // For oldChunks/newChunks/both, it's possible that 
only one chunk
-                       // changed, in which case textStart has already eaten 
into that chunk;
-                       // so take care not to overlap it. (For example, for 
'ana'->'anna',
-                       // textStart will be 2 so we want to limit textEnd to 
1, else the 'n'
-                       // of 'ana' will be counted twice).
+                       // However, if only one chunk has changed in 
oldChunks/newChunks, then
+                       // oldChunk/newChunk is also the *first* changed chunk, 
in which case
+                       // textStart has already eaten into that chunk; so take 
care not to
+                       // overlap it. (For example, for 'ana'->'anna', 
textStart will be 2 so
+                       // we want to limit textEnd to 1, else the 'n' of 'ana' 
will be counted
+                       // twice).
                        iLen = Math.min(
                                oldChunk.text.length -
                                ( change.start + change.end === 
oldChunks.length - 1 ? textStart : 0 ),
diff --git a/tests/ce/ve.ce.TextState.test.js b/tests/ce/ve.ce.TextState.test.js
index 593c987..57e3342 100644
--- a/tests/ce/ve.ce.TextState.test.js
+++ b/tests/ce/ve.ce.TextState.test.js
@@ -317,6 +317,40 @@
                                },
                                { type: 'retain', length: 3 }
                        ]
+               },
+               {
+                       msg: 'Insert new chunk whose annotations match end 
chunk\'s',
+                       oldRawHtml: '<u>x</u>yz',
+                       oldInnerHtml: '<u class="ve-ce-textStyleAnnotation 
ve-ce-underlineAnnotation">x</u>yz',
+                       newInnerHtml: '<u class="ve-ce-textStyleAnnotation 
ve-ce-underlineAnnotation">x</u>y<u class="ve-ce-textStyleAnnotation 
ve-ce-underlineAnnotation">w</u>yz',
+                       operations: [
+                               { type: 'retain', length: 2 },
+                               {
+                                       type: 'replace',
+                                       remove: [],
+                                       insert: [ 'y', [ 'w', [ 0 ] ] ],
+                                       insertedDataOffset: 0,
+                                       insertedDataLength: 2
+                               },
+                               { type: 'retain', length: 5 }
+                       ]
+               },
+               {
+                       msg: 'Ambiguous insert with start and end both 
identical to original',
+                       oldRawHtml: 'ab',
+                       oldInnerHtml: 'ab',
+                       newInnerHtml: 'ab<u class="ve-ce-textStyleAnnotation 
ve-ce-underlineAnnotation">x</u>ab',
+                       operations: [
+                               { type: 'retain', length: 3 },
+                               {
+                                       type: 'replace',
+                                       remove: [],
+                                       insert: [ [ 'x', [ 0 ] ], 'a', 'b' ],
+                                       insertedDataOffset: 0,
+                                       insertedDataLength: 3
+                               },
+                               { type: 'retain', length: 3 }
+                       ]
                }
        ];
 

-- 
To view, visit https://gerrit.wikimedia.org/r/304135
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I3cfca36c289a6936810665233547d37ef504905f
Gerrit-PatchSet: 2
Gerrit-Project: VisualEditor/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Divec <da...@troi.org>
Gerrit-Reviewer: Esanders <esand...@wikimedia.org>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to