@@ -550,22 +550,37 @@ exports.textLinesMutator = (lines) => {
550550 // is not actually a newline, but for the purposes of N and L values,
551551 // the caller should pretend it is, and for things to work right in that case, the input
552552 // to insert() should be a single line with no newlines.
553+
554+ // The splice holds information which lines are to be deleted or changed.
555+ // curSplice[0] is an index into the lines array
556+ // curSplice[1] is the number of lines that will be removed from lines
557+ // the other elements represent mutated (changed by ops) lines or new lines (added by ops)
553558 const curSplice = [ 0 , 0 ] ;
554559 let inSplice = false ;
555- // position in document after curSplice is applied:
560+
561+ // position in lines after curSplice is applied:
556562 let curLine = 0 ;
557563 let curCol = 0 ;
558564 // invariant: if (inSplice) then (curLine is in curSplice[0] + curSplice.length - {2,3}) &&
559565 // curLine >= curSplice[0]
560566 // invariant: if (inSplice && (curLine >= curSplice[0] + curSplice.length - 2)) then
561567 // curCol == 0
562568
569+ /**
570+ * Adds and/or removes entries at a specific offset in lines array
571+ * It is called when leaving the splice
572+ * @param {Array } s curSplice
573+ */
563574 const lines_applySplice = ( s ) => {
564575 lines . splice . apply ( lines , s ) ;
565576 } ;
566577
567578 const lines_toSource = ( ) => lines . toSource ( ) ;
568579
580+ /**
581+ * Get a line from lines at given index
582+ * @param {Number } idx an index
583+ */
569584 const lines_get = ( idx ) => {
570585 if ( lines . get ) {
571586 return lines . get ( idx ) ;
@@ -575,6 +590,11 @@ exports.textLinesMutator = (lines) => {
575590 } ;
576591 // can be unimplemented if removeLines's return value not needed
577592
593+ /**
594+ * Return a slice from lines array
595+ * @param {Number } start the start index
596+ * @param {Number } end the end index
597+ */
578598 const lines_slice = ( start , end ) => {
579599 if ( lines . slice ) {
580600 return lines . slice ( start , end ) ;
@@ -583,6 +603,9 @@ exports.textLinesMutator = (lines) => {
583603 }
584604 } ;
585605
606+ /**
607+ * Return the length of lines array
608+ */
586609 const lines_length = ( ) => {
587610 if ( ( typeof lines . length ) === 'number' ) {
588611 return lines . length ;
@@ -591,42 +614,71 @@ exports.textLinesMutator = (lines) => {
591614 }
592615 } ;
593616
617+ /**
618+ * Starts a new splice.
619+ */
594620 const enterSplice = ( ) => {
595621 curSplice [ 0 ] = curLine ;
596622 curSplice [ 1 ] = 0 ;
623+ // TODO(doc) when is this the case?
624+ // check all enterSplice calls and changes to curCol
597625 if ( curCol > 0 ) {
598626 putCurLineInSplice ( ) ;
599627 }
600628 inSplice = true ;
601629 } ;
602630
631+ /**
632+ * Changes the lines array according to the values in curSplice
633+ * and resets curSplice.
634+ * This is called via close or TODO(doc)
635+ */
603636 const leaveSplice = ( ) => {
604637 lines_applySplice ( curSplice ) ;
605638 curSplice . length = 2 ;
606639 curSplice [ 0 ] = curSplice [ 1 ] = 0 ;
607640 inSplice = false ;
608641 } ;
609642
643+ /**
644+ * Indicates if curLine is already in the splice. This is necessary because the last element in
645+ * curSplice is curLine when this line is currently worked on (e.g. when skipping are inserting)
646+ *
647+ * TODO(doc) why aren't removals considered?
648+ * @returns {Boolean } true if curLine is in splice
649+ */
610650 const isCurLineInSplice = ( ) => ( curLine - curSplice [ 0 ] < ( curSplice . length - 2 ) ) ;
611651
612652 const debugPrint = ( typ ) => { /* eslint-disable-line no-unused-vars */
613653 print ( `${ typ } : ${ curSplice . toSource ( ) } / ${ curLine } ,${ curCol } / ${ lines_toSource ( ) } ` ) ;
614654 } ;
615655
656+ /**
657+ * Incorporates current line into the splice
658+ * and marks its old position to be deleted.
659+ *
660+ * @returns {Number } the index of the added line in curSplice
661+ */
616662 const putCurLineInSplice = ( ) => {
617663 if ( ! isCurLineInSplice ( ) ) {
618664 curSplice . push ( lines_get ( curSplice [ 0 ] + curSplice [ 1 ] ) ) ;
619665 curSplice [ 1 ] ++ ;
620666 }
621- return 2 + curLine - curSplice [ 0 ] ;
667+ return 2 + curLine - curSplice [ 0 ] ; // TODO should be the same as curSplice.length - 1
622668 } ;
623669
670+ /**
671+ * It will skip some newlines by putting them into the splice.
672+ *
673+ * @param {Boolean } includeInSplice indicates if attributes are present
674+ */
624675 const skipLines = ( L , includeInSplice ) => {
625676 if ( L ) {
626677 if ( includeInSplice ) {
627678 if ( ! inSplice ) {
628679 enterSplice ( ) ;
629680 }
681+ // TODO(doc) should this count the number of characters that are skipped to check?
630682 for ( let i = 0 ; i < L ; i ++ ) {
631683 curCol = 0 ;
632684 putCurLineInSplice ( ) ;
@@ -635,6 +687,7 @@ exports.textLinesMutator = (lines) => {
635687 } else {
636688 if ( inSplice ) {
637689 if ( L > 1 ) {
690+ // TODO(doc) figure out why single lines are incorporated into splice instead of ignored
638691 leaveSplice ( ) ;
639692 } else {
640693 putCurLineInSplice ( ) ;
@@ -647,6 +700,13 @@ exports.textLinesMutator = (lines) => {
647700 }
648701 } ;
649702
703+ /**
704+ * Skip some characters. Can contain newlines.
705+ *
706+ * @param {Number } N number of characters to skip
707+ * @param {Number } L number of newlines to skip
708+ * @param {Boolean } includeInSplice indicates if attributes are present
709+ */
650710 const skip = ( N , L , includeInSplice ) => {
651711 if ( N ) {
652712 if ( L ) {
@@ -656,20 +716,33 @@ exports.textLinesMutator = (lines) => {
656716 enterSplice ( ) ;
657717 }
658718 if ( inSplice ) {
719+ // although the line is put into splice curLine is not increased, because
720+ // only some chars are skipped, not the whole line
659721 putCurLineInSplice ( ) ;
660722 }
661723 curCol += N ;
662724 }
663725 }
664726 } ;
665727
728+ /**
729+ * Remove whole lines from lines array
730+ *
731+ * @param {Number } L number of lines to be removed
732+ */
666733 const removeLines = ( L ) => {
667734 let removed = '' ;
668735 if ( L ) {
669736 if ( ! inSplice ) {
670737 enterSplice ( ) ;
671738 }
672739
740+ /**
741+ * Gets a string of joined lines after the end of the splice
742+ *
743+ * @param k {Number} number of lines
744+ * @returns {String } joined lines
745+ */
673746 const nextKLinesText = ( k ) => {
674747 const m = curSplice [ 0 ] + curSplice [ 1 ] ;
675748 return lines_slice ( m , m + k ) . join ( '' ) ;
@@ -697,6 +770,12 @@ exports.textLinesMutator = (lines) => {
697770 return removed ;
698771 } ;
699772
773+ /**
774+ * Remove text from lines array
775+ *
776+ * @param N {Number} characters to delete
777+ * @param L {Number} lines to delete
778+ */
700779 const remove = ( N , L ) => {
701780 let removed = '' ;
702781 if ( N ) {
@@ -706,6 +785,8 @@ exports.textLinesMutator = (lines) => {
706785 if ( ! inSplice ) {
707786 enterSplice ( ) ;
708787 }
788+ // although the line is put into splice, curLine is not increased, because
789+ // only some chars are removed not the whole line
709790 const sline = putCurLineInSplice ( ) ;
710791 removed = curSplice [ sline ] . substring ( curCol , curCol + N ) ;
711792 curSplice [ sline ] = curSplice [ sline ] . substring ( 0 , curCol ) +
@@ -715,6 +796,12 @@ exports.textLinesMutator = (lines) => {
715796 return removed ;
716797 } ;
717798
799+ /**
800+ * Inserts text into lines array.
801+ *
802+ * @param text {String} the text to insert
803+ * @param L {Number} number of newlines in text
804+ */
718805 const insert = ( text , L ) => {
719806 if ( text ) {
720807 if ( ! inSplice ) {
@@ -726,18 +813,25 @@ exports.textLinesMutator = (lines) => {
726813 const sline = curSplice . length - 1 ;
727814 const theLine = curSplice [ sline ] ;
728815 const lineCol = curCol ;
816+ // insert the first new line
729817 curSplice [ sline ] = theLine . substring ( 0 , lineCol ) + newLines [ 0 ] ;
730818 curLine ++ ;
731819 newLines . splice ( 0 , 1 ) ;
820+ // insert the remaining new lines
732821 Array . prototype . push . apply ( curSplice , newLines ) ;
733822 curLine += newLines . length ;
823+ // insert the remaining chars from the "old" line (e.g. the line we were in
824+ // when we started to insert new lines)
734825 curSplice . push ( theLine . substring ( lineCol ) ) ;
735- curCol = 0 ;
826+ curCol = 0 ; // TODO(doc) why is this not set to the length of last line?
736827 } else {
737828 Array . prototype . push . apply ( curSplice , newLines ) ;
738829 curLine += newLines . length ;
739830 }
740831 } else {
832+ // there are no additional lines
833+ // although the line is put into splice, curLine is not increased, because
834+ // there may be more chars in the line (newline is not reached)
741835 const sline = putCurLineInSplice ( ) ;
742836 if ( ! curSplice [ sline ] ) {
743837 console . error ( 'curSplice[sline] not populated, actual curSplice contents is ' , curSplice , '. Possibly related to https://github.com/ether/etherpad-lite/issues/2802' ) ;
@@ -749,6 +843,12 @@ exports.textLinesMutator = (lines) => {
749843 }
750844 } ;
751845
846+ /**
847+ * Checks if curLine (the line we are in when curSplice is applied) is the last line
848+ * in lines.
849+ *
850+ * @return {Boolean } indicates if there are lines left
851+ */
752852 const hasMore = ( ) => {
753853 let docLines = lines_length ( ) ;
754854 if ( inSplice ) {
@@ -757,6 +857,9 @@ exports.textLinesMutator = (lines) => {
757857 return curLine < docLines ;
758858 } ;
759859
860+ /**
861+ * Closes the splice
862+ */
760863 const close = ( ) => {
761864 if ( inSplice ) {
762865 leaveSplice ( ) ;
0 commit comments