( base: string, diff: IDiffArrayEntry[] | null, level: number, stringifyPatch?: boolean, )
| 133 | * Patch a string according to a line based diff |
| 134 | */ |
| 135 | export function patchString( |
| 136 | base: string, |
| 137 | diff: IDiffArrayEntry[] | null, |
| 138 | level: number, |
| 139 | stringifyPatch?: boolean, |
| 140 | ): StringifiedPatchResult { |
| 141 | let additions: DiffRangeRaw[] = []; |
| 142 | let deletions: DiffRangeRaw[] = []; |
| 143 | let baseIndex = 0; |
| 144 | |
| 145 | // Short-circuit if diff is empty |
| 146 | if (diff === null) { |
| 147 | return { |
| 148 | remote: stringifyPatch ? stringify(base, level) : base, |
| 149 | additions: additions, |
| 150 | deletions: deletions, |
| 151 | }; |
| 152 | } |
| 153 | // Diffs are line-based, so flatten to character based: |
| 154 | diff = flattenStringDiff(base, diff); |
| 155 | |
| 156 | // Index into obj, the next item to take unless diff says otherwise |
| 157 | let take = 0; |
| 158 | let skip = 0; |
| 159 | let remote = ''; |
| 160 | for (let e of diff) { |
| 161 | let index = e.key; |
| 162 | |
| 163 | // Take values from obj not mentioned in diff, up to not including index |
| 164 | let unchanged = base.slice(take, index); |
| 165 | remote += unchanged; |
| 166 | baseIndex += unchanged.length; |
| 167 | |
| 168 | if (e.op === 'addrange') { |
| 169 | let added = e.valuelist; |
| 170 | additions.push(new DiffRangeRaw(remote.length, added.length, e.source)); |
| 171 | remote += added; |
| 172 | skip = 0; |
| 173 | } else if (e.op === 'removerange') { |
| 174 | // Delete a number of values by skipping |
| 175 | skip = e.length; |
| 176 | deletions.push(new DiffRangeRaw(baseIndex, skip, e.source)); |
| 177 | baseIndex += skip; |
| 178 | } |
| 179 | take = Math.max(take, index + skip); |
| 180 | } |
| 181 | remote += base.slice(take, base.length); |
| 182 | if (stringifyPatch) { |
| 183 | // The remote string should be stringified |
| 184 | remote = stringify(remote, level); |
| 185 | // Shift all indices by indentation + one to account for opening quote |
| 186 | _offsetRanges(level * JSON_INDENT.length + 1, additions, deletions); |
| 187 | // Offset ranges by JSON escaping |
| 188 | _adjustRangesByJSONEscapes(remote, additions); |
| 189 | _adjustRangesByJSONEscapes(stringify(base, level), deletions); |
| 190 | } |
| 191 | return { remote: remote, additions: additions, deletions: deletions }; |
| 192 | } |
no test coverage detected