@@ -522,6 +522,9 @@ exports.mergingOpAssembler = () => {
522522 // ops immediately after it.
523523 let bufOpAdditionalCharsAfterNewline = 0 ;
524524
525+ /**
526+ * @param {boolean } [isEndDocument]
527+ */
525528 const flush = ( isEndDocument ) => {
526529 if ( ! bufOp . opcode ) return ;
527530 if ( isEndDocument && bufOp . opcode === '=' && ! bufOp . attribs ) {
@@ -800,7 +803,7 @@ class TextLinesMutator {
800803
801804 /**
802805 * Indicates if curLine is already in the splice. This is necessary because the last element in
803- * curSplice is curLine when this line is currently worked on (e.g. when skipping are inserting).
806+ * curSplice is curLine when this line is currently worked on (e.g. when skipping or inserting).
804807 *
805808 * TODO(doc) why aren't removals considered?
806809 *
@@ -828,7 +831,7 @@ class TextLinesMutator {
828831 * It will skip some newlines by putting them into the splice.
829832 *
830833 * @param {number } L -
831- * @param {boolean } includeInSplice - indicates if attributes are present
834+ * @param {boolean } includeInSplice - Indicates that attributes are present.
832835 */
833836 skipLines ( L , includeInSplice ) {
834837 if ( ! L ) return ;
@@ -957,7 +960,7 @@ class TextLinesMutator {
957960 /** @type {string } */
958961 const theLine = this . _curSplice [ sline ] ;
959962 const lineCol = this . _curCol ;
960- // insert the first new line
963+ // Insert the chars up to `curCol` and the first new line.
961964 this . _curSplice [ sline ] = theLine . substring ( 0 , lineCol ) + newLines [ 0 ] ;
962965 this . _curLine ++ ;
963966 newLines . splice ( 0 , 1 ) ;
@@ -973,9 +976,8 @@ class TextLinesMutator {
973976 this . _curLine += newLines . length ;
974977 }
975978 } else {
976- // there are no additional lines
977- // although the line is put into splice, curLine is not increased, because
978- // there may be more chars in the line (newline is not reached)
979+ // There are no additional lines. Although the line is put into splice, curLine is not
980+ // increased because there may be more chars in the line (newline is not reached).
979981 const sline = this . _putCurLineInSplice ( ) ;
980982 if ( ! this . _curSplice [ sline ] ) {
981983 const err = new Error (
@@ -1276,6 +1278,13 @@ exports.applyToAttribution = (cs, astr, pool) => {
12761278 return applyZip ( astr , unpacked . ops , ( op1 , op2 ) => slicerZipperFunc ( op1 , op2 , pool ) ) ;
12771279} ;
12781280
1281+ /**
1282+ * Applies a changeset to an array of attribute lines.
1283+ *
1284+ * @param {string } cs - The encoded changeset.
1285+ * @param {Array<string> } lines - Attribute lines. Modified in place.
1286+ * @param {AttributePool } pool - Attribute pool.
1287+ */
12791288exports . mutateAttributionLines = ( cs , lines , pool ) => {
12801289 const unpacked = exports . unpack ( cs ) ;
12811290 const csOps = exports . deserializeOps ( unpacked . ops ) ;
@@ -1285,26 +1294,47 @@ exports.mutateAttributionLines = (cs, lines, pool) => {
12851294 // treat the attribution lines as text lines, mutating a line at a time
12861295 const mut = new TextLinesMutator ( lines ) ;
12871296
1288- /** @type {?Generator<Op> } */
1297+ /**
1298+ * The Ops in the current line from `lines`.
1299+ *
1300+ * @type {?Generator<Op> }
1301+ */
12891302 let lineOps = null ;
12901303 let lineOpsNext = null ;
12911304
12921305 const lineOpsHasNext = ( ) => lineOpsNext && ! lineOpsNext . done ;
1306+ /**
1307+ * Returns false if we are on the last attribute line in `lines` and there is no additional op in
1308+ * that line.
1309+ *
1310+ * @returns {boolean } True if there are more ops to go through.
1311+ */
12931312 const isNextMutOp = ( ) => lineOpsHasNext ( ) || mut . hasMore ( ) ;
12941313
1314+ /**
1315+ * @returns {Op } The next Op from `lineIter`. If there are no more Ops, `lineIter` is reset to
1316+ * iterate over the next line, which is consumed from `mut`. If there are no more lines,
1317+ * returns a null Op.
1318+ */
12951319 const nextMutOp = ( ) => {
12961320 if ( ! lineOpsHasNext ( ) && mut . hasMore ( ) ) {
1321+ // There are more attribute lines in `lines` to do AND either we just started so `lineIter` is
1322+ // still null or there are no more ops in current `lineIter`.
12971323 const line = mut . removeLines ( 1 ) ;
12981324 lineOps = exports . deserializeOps ( line ) ;
12991325 lineOpsNext = lineOps . next ( ) ;
13001326 }
1301- if ( ! lineOpsHasNext ( ) ) return new Op ( ) ;
1327+ if ( ! lineOpsHasNext ( ) ) return new Op ( ) ; // No more ops and no more lines.
13021328 const op = lineOpsNext . value ;
13031329 lineOpsNext = lineOps . next ( ) ;
13041330 return op ;
13051331 } ;
13061332 let lineAssem = null ;
13071333
1334+ /**
1335+ * Appends an op to `lineAssem`. In case `lineAssem` includes one single newline, adds it to the
1336+ * `lines` mutator.
1337+ */
13081338 const outputMutOp = ( op ) => {
13091339 if ( ! lineAssem ) {
13101340 lineAssem = exports . mergingOpAssembler ( ) ;
@@ -1321,25 +1351,29 @@ exports.mutateAttributionLines = (cs, lines, pool) => {
13211351 let attOp = new Op ( ) ;
13221352 while ( csOp . opcode || ! csOpsNext . done || attOp . opcode || isNextMutOp ( ) ) {
13231353 if ( ! csOp . opcode && ! csOpsNext . done ) {
1354+ // coOp done, but more ops in cs.
13241355 csOp = csOpsNext . value ;
13251356 csOpsNext = csOps . next ( ) ;
13261357 }
13271358 if ( ! csOp . opcode && ! attOp . opcode && ! lineAssem && ! lineOpsHasNext ( ) ) {
13281359 break ; // done
13291360 } else if ( csOp . opcode === '=' && csOp . lines > 0 && ! csOp . attribs && ! attOp . opcode &&
13301361 ! lineAssem && ! lineOpsHasNext ( ) ) {
1331- // skip multiple lines; this is what makes small changes not order of the document size
1362+ // Skip multiple lines without attributes; this is what makes small changes not order of the
1363+ // document size.
13321364 mut . skipLines ( csOp . lines ) ;
13331365 csOp . opcode = '' ;
13341366 } else if ( csOp . opcode === '+' ) {
13351367 const opOut = copyOp ( csOp ) ;
13361368 if ( csOp . lines > 1 ) {
1369+ // Copy the first line from `csOp` to `opOut`.
13371370 const firstLineLen = csBank . indexOf ( '\n' , csBankIndex ) + 1 - csBankIndex ;
13381371 csOp . chars -= firstLineLen ;
13391372 csOp . lines -- ;
13401373 opOut . lines = 1 ;
13411374 opOut . chars = firstLineLen ;
13421375 } else {
1376+ // Either one or no newlines in '+' `csOp`, copy to `opOut` and reset `csOp`.
13431377 csOp . opcode = '' ;
13441378 }
13451379 outputMutOp ( opOut ) ;
@@ -1763,7 +1797,7 @@ exports.copyAText = (atext1, atext2) => {
17631797} ;
17641798
17651799/**
1766- * Convert AText to a series of operations.
1800+ * Convert AText to a series of operations. Strips final newline.
17671801 *
17681802 * @param {AText } atext - The AText to convert.
17691803 * @yields {Op}
0 commit comments