@@ -1172,92 +1172,42 @@ exports.composeAttributes = (att1, att2, resultIsMutation, pool) => {
11721172 */
11731173const slicerZipperFunc = ( attOp , csOp , pool ) => {
11741174 const opOut = exports . newOp ( ) ;
1175- if ( attOp . opcode === '-' ) {
1175+ if ( ! attOp . opcode ) {
1176+ copyOp ( csOp , opOut ) ;
1177+ csOp . opcode = '' ;
1178+ } else if ( ! csOp . opcode ) {
1179+ copyOp ( attOp , opOut ) ;
1180+ attOp . opcode = '' ;
1181+ } else if ( attOp . opcode === '-' ) {
11761182 copyOp ( attOp , opOut ) ;
11771183 attOp . opcode = '' ;
1178- } else if ( ! attOp . opcode ) {
1184+ } else if ( csOp . opcode === '+' ) {
11791185 copyOp ( csOp , opOut ) ;
11801186 csOp . opcode = '' ;
11811187 } else {
1182- switch ( csOp . opcode ) {
1183- case '-' :
1184- {
1185- if ( csOp . chars <= attOp . chars ) {
1186- // delete or delete part
1187- if ( attOp . opcode === '=' ) {
1188- opOut . opcode = '-' ;
1189- opOut . chars = csOp . chars ;
1190- opOut . lines = csOp . lines ;
1191- // csOp is a remove op and remove ops normally never have any attributes, so this should
1192- // normally be the empty string. However, padDiff.js adds attributes to remove ops and
1193- // needs them preserved so they are copied here.
1194- opOut . attribs = csOp . attribs ;
1195- }
1196- attOp . chars -= csOp . chars ;
1197- attOp . lines -= csOp . lines ;
1198- csOp . opcode = '' ;
1199- if ( ! attOp . chars ) {
1200- attOp . opcode = '' ;
1201- }
1202- } else {
1203- // delete and keep going
1204- if ( attOp . opcode === '=' ) {
1205- opOut . opcode = '-' ;
1206- opOut . chars = attOp . chars ;
1207- opOut . lines = attOp . lines ;
1208- // csOp is a remove op and remove ops normally never have any attributes, so this should
1209- // normally be the empty string. However, padDiff.js adds attributes to remove ops and
1210- // needs them preserved so they are copied here.
1211- opOut . attribs = csOp . attribs ;
1212- }
1213- csOp . chars -= attOp . chars ;
1214- csOp . lines -= attOp . lines ;
1215- attOp . opcode = '' ;
1216- }
1217- break ;
1218- }
1219- case '+' :
1220- {
1221- // insert
1222- copyOp ( csOp , opOut ) ;
1223- csOp . opcode = '' ;
1224- break ;
1225- }
1226- case '=' :
1227- {
1228- if ( csOp . chars <= attOp . chars ) {
1229- // keep or keep part
1230- opOut . opcode = attOp . opcode ;
1231- opOut . chars = csOp . chars ;
1232- opOut . lines = csOp . lines ;
1233- opOut . attribs = exports . composeAttributes (
1234- attOp . attribs , csOp . attribs , attOp . opcode === '=' , pool ) ;
1235- csOp . opcode = '' ;
1236- attOp . chars -= csOp . chars ;
1237- attOp . lines -= csOp . lines ;
1238- if ( ! attOp . chars ) {
1239- attOp . opcode = '' ;
1240- }
1241- } else {
1242- // keep and keep going
1243- opOut . opcode = attOp . opcode ;
1244- opOut . chars = attOp . chars ;
1245- opOut . lines = attOp . lines ;
1246- opOut . attribs = exports . composeAttributes (
1247- attOp . attribs , csOp . attribs , attOp . opcode === '=' , pool ) ;
1248- attOp . opcode = '' ;
1249- csOp . chars -= attOp . chars ;
1250- csOp . lines -= attOp . lines ;
1251- }
1252- break ;
1253- }
1254- case '' :
1255- {
1256- copyOp ( attOp , opOut ) ;
1257- attOp . opcode = '' ;
1258- break ;
1259- }
1260- }
1188+ opOut . opcode = {
1189+ '+' : {
1190+ '-' : '' , // The '-' cancels out (some of) the '+', leaving any remainder for the next call.
1191+ '=' : '+' ,
1192+ } ,
1193+ '=' : {
1194+ '-' : '-' ,
1195+ '=' : '=' ,
1196+ } ,
1197+ } [ attOp . opcode ] [ csOp . opcode ] ;
1198+ const [ fullyConsumedOp , partiallyConsumedOp ] = [ attOp , csOp ] . sort ( ( a , b ) => a . chars - b . chars ) ;
1199+ opOut . chars = fullyConsumedOp . chars ;
1200+ opOut . lines = fullyConsumedOp . lines ;
1201+ opOut . attribs = csOp . opcode === '-'
1202+ // csOp is a remove op and remove ops normally never have any attributes, so this should
1203+ // normally be the empty string. However, padDiff.js adds attributes to remove ops and needs
1204+ // them preserved so they are copied here.
1205+ ? csOp . attribs
1206+ : exports . composeAttributes ( attOp . attribs , csOp . attribs , attOp . opcode === '=' , pool ) ;
1207+ partiallyConsumedOp . chars -= fullyConsumedOp . chars ;
1208+ partiallyConsumedOp . lines -= fullyConsumedOp . lines ;
1209+ if ( ! partiallyConsumedOp . chars ) partiallyConsumedOp . opcode = '' ;
1210+ fullyConsumedOp . opcode = '' ;
12611211 }
12621212 return opOut ;
12631213} ;
0 commit comments