@@ -525,6 +525,9 @@ exports.mergingOpAssembler = () => {
525525 // ops immediately after it.
526526 let bufOpAdditionalCharsAfterNewline = 0 ;
527527
528+ /**
529+ * @param {boolean } [isEndDocument]
530+ */
528531 const flush = ( isEndDocument ) => {
529532 if ( ! bufOp . opcode ) return ;
530533 if ( isEndDocument && bufOp . opcode === '=' && ! bufOp . attribs ) {
@@ -803,7 +806,7 @@ class TextLinesMutator {
803806
804807 /**
805808 * Indicates if curLine is already in the splice. This is necessary because the last element in
806- * curSplice is curLine when this line is currently worked on (e.g. when skipping are inserting).
809+ * curSplice is curLine when this line is currently worked on (e.g. when skipping or inserting).
807810 *
808811 * TODO(doc) why aren't removals considered?
809812 *
@@ -831,7 +834,7 @@ class TextLinesMutator {
831834 * It will skip some newlines by putting them into the splice.
832835 *
833836 * @param {number } L -
834- * @param {boolean } includeInSplice - indicates if attributes are present
837+ * @param {boolean } includeInSplice - Indicates that attributes are present.
835838 */
836839 skipLines ( L , includeInSplice ) {
837840 if ( ! L ) return ;
@@ -960,7 +963,7 @@ class TextLinesMutator {
960963 /** @type {string } */
961964 const theLine = this . _curSplice [ sline ] ;
962965 const lineCol = this . _curCol ;
963- // insert the first new line
966+ // Insert the chars up to `curCol` and the first new line.
964967 this . _curSplice [ sline ] = theLine . substring ( 0 , lineCol ) + newLines [ 0 ] ;
965968 this . _curLine ++ ;
966969 newLines . splice ( 0 , 1 ) ;
@@ -976,9 +979,8 @@ class TextLinesMutator {
976979 this . _curLine += newLines . length ;
977980 }
978981 } else {
979- // there are no additional lines
980- // although the line is put into splice, curLine is not increased, because
981- // there may be more chars in the line (newline is not reached)
982+ // There are no additional lines. Although the line is put into splice, curLine is not
983+ // increased because there may be more chars in the line (newline is not reached).
982984 const sline = this . _putCurLineInSplice ( ) ;
983985 if ( ! this . _curSplice [ sline ] ) {
984986 const err = new Error (
@@ -1277,6 +1279,13 @@ exports.applyToAttribution = (cs, astr, pool) => {
12771279 return applyZip ( astr , unpacked . ops , ( op1 , op2 ) => slicerZipperFunc ( op1 , op2 , pool ) ) ;
12781280} ;
12791281
1282+ /**
1283+ * Applies a changeset to an array of attribute lines.
1284+ *
1285+ * @param {string } cs - The encoded changeset.
1286+ * @param {Array<string> } lines - Attribute lines. Modified in place.
1287+ * @param {AttributePool } pool - Attribute pool.
1288+ */
12801289exports . mutateAttributionLines = ( cs , lines , pool ) => {
12811290 const unpacked = exports . unpack ( cs ) ;
12821291 const csOps = exports . deserializeOps ( unpacked . ops ) ;
@@ -1286,26 +1295,47 @@ exports.mutateAttributionLines = (cs, lines, pool) => {
12861295 // treat the attribution lines as text lines, mutating a line at a time
12871296 const mut = new TextLinesMutator ( lines ) ;
12881297
1289- /** @type {?Generator<Op> } */
1298+ /**
1299+ * The Ops in the current line from `lines`.
1300+ *
1301+ * @type {?Generator<Op> }
1302+ */
12901303 let lineOps = null ;
12911304 let lineOpsNext = null ;
12921305
12931306 const lineOpsHasNext = ( ) => lineOpsNext && ! lineOpsNext . done ;
1307+ /**
1308+ * Returns false if we are on the last attribute line in `lines` and there is no additional op in
1309+ * that line.
1310+ *
1311+ * @returns {boolean } True if there are more ops to go through.
1312+ */
12941313 const isNextMutOp = ( ) => lineOpsHasNext ( ) || mut . hasMore ( ) ;
12951314
1315+ /**
1316+ * @returns {Op } The next Op from `lineIter`. If there are no more Ops, `lineIter` is reset to
1317+ * iterate over the next line, which is consumed from `mut`. If there are no more lines,
1318+ * returns a null Op.
1319+ */
12961320 const nextMutOp = ( ) => {
12971321 if ( ! lineOpsHasNext ( ) && mut . hasMore ( ) ) {
1322+ // There are more attribute lines in `lines` to do AND either we just started so `lineIter` is
1323+ // still null or there are no more ops in current `lineIter`.
12981324 const line = mut . removeLines ( 1 ) ;
12991325 lineOps = exports . deserializeOps ( line ) ;
13001326 lineOpsNext = lineOps . next ( ) ;
13011327 }
1302- if ( ! lineOpsHasNext ( ) ) return new Op ( ) ;
1328+ if ( ! lineOpsHasNext ( ) ) return new Op ( ) ; // No more ops and no more lines.
13031329 const op = lineOpsNext . value ;
13041330 lineOpsNext = lineOps . next ( ) ;
13051331 return op ;
13061332 } ;
13071333 let lineAssem = null ;
13081334
1335+ /**
1336+ * Appends an op to `lineAssem`. In case `lineAssem` includes one single newline, adds it to the
1337+ * `lines` mutator.
1338+ */
13091339 const outputMutOp = ( op ) => {
13101340 if ( ! lineAssem ) {
13111341 lineAssem = exports . mergingOpAssembler ( ) ;
@@ -1322,25 +1352,29 @@ exports.mutateAttributionLines = (cs, lines, pool) => {
13221352 let attOp = new Op ( ) ;
13231353 while ( csOp . opcode || ! csOpsNext . done || attOp . opcode || isNextMutOp ( ) ) {
13241354 if ( ! csOp . opcode && ! csOpsNext . done ) {
1355+ // coOp done, but more ops in cs.
13251356 csOp = csOpsNext . value ;
13261357 csOpsNext = csOps . next ( ) ;
13271358 }
13281359 if ( ! csOp . opcode && ! attOp . opcode && ! lineAssem && ! lineOpsHasNext ( ) ) {
13291360 break ; // done
13301361 } else if ( csOp . opcode === '=' && csOp . lines > 0 && ! csOp . attribs && ! attOp . opcode &&
13311362 ! lineAssem && ! lineOpsHasNext ( ) ) {
1332- // skip multiple lines; this is what makes small changes not order of the document size
1363+ // Skip multiple lines without attributes; this is what makes small changes not order of the
1364+ // document size.
13331365 mut . skipLines ( csOp . lines ) ;
13341366 csOp . opcode = '' ;
13351367 } else if ( csOp . opcode === '+' ) {
13361368 const opOut = copyOp ( csOp ) ;
13371369 if ( csOp . lines > 1 ) {
1370+ // Copy the first line from `csOp` to `opOut`.
13381371 const firstLineLen = csBank . indexOf ( '\n' , csBankIndex ) + 1 - csBankIndex ;
13391372 csOp . chars -= firstLineLen ;
13401373 csOp . lines -- ;
13411374 opOut . lines = 1 ;
13421375 opOut . chars = firstLineLen ;
13431376 } else {
1377+ // Either one or no newlines in '+' `csOp`, copy to `opOut` and reset `csOp`.
13441378 csOp . opcode = '' ;
13451379 }
13461380 outputMutOp ( opOut ) ;
@@ -1758,7 +1792,7 @@ exports.copyAText = (atext1, atext2) => {
17581792} ;
17591793
17601794/**
1761- * Convert AText to a series of operations.
1795+ * Convert AText to a series of operations. Strips final newline.
17621796 *
17631797 * @param {AText } atext - The AText to convert.
17641798 * @yields {Op}
0 commit comments