(frame: Frame)
| 175 | } |
| 176 | |
| 177 | private renderFullFrame(frame: Frame): Diff { |
| 178 | const { screen } = frame |
| 179 | const lines: string[] = [] |
| 180 | let currentStyles: AnsiCode[] = [] |
| 181 | let currentHyperlink: Hyperlink = undefined |
| 182 | for (let y = 0; y < screen.height; y++) { |
| 183 | let line = '' |
| 184 | for (let x = 0; x < screen.width; x++) { |
| 185 | const cell = cellAt(screen, x, y) |
| 186 | if (cell && cell.width !== CellWidth.SpacerTail) { |
| 187 | // Handle hyperlink transitions |
| 188 | if (cell.hyperlink !== currentHyperlink) { |
| 189 | if (currentHyperlink !== undefined) { |
| 190 | line += LINK_END |
| 191 | } |
| 192 | if (cell.hyperlink !== undefined) { |
| 193 | line += oscLink(cell.hyperlink) |
| 194 | } |
| 195 | currentHyperlink = cell.hyperlink |
| 196 | } |
| 197 | const cellStyles = this.options.stylePool.get(cell.styleId) |
| 198 | const styleDiff = diffAnsiCodes(currentStyles, cellStyles) |
| 199 | if (styleDiff.length > 0) { |
| 200 | line += ansiCodesToString(styleDiff) |
| 201 | currentStyles = cellStyles |
| 202 | } |
| 203 | line += cell.char |
| 204 | } |
| 205 | } |
| 206 | // Close any open hyperlink before resetting styles |
| 207 | if (currentHyperlink !== undefined) { |
| 208 | line += LINK_END |
| 209 | currentHyperlink = undefined |
| 210 | } |
| 211 | // Reset styles at end of line so trimEnd doesn't leave dangling codes |
| 212 | const resetCodes = diffAnsiCodes(currentStyles, []) |
| 213 | if (resetCodes.length > 0) { |
| 214 | line += ansiCodesToString(resetCodes) |
| 215 | currentStyles = [] |
| 216 | } |
| 217 | lines.push(line.trimEnd()) |
| 218 | } |
| 219 | |
| 220 | if (lines.length === 0) { |
| 221 | return [] |
| 222 | } |
| 223 | return [{ type: 'stdout', content: lines.join('\n') }] |
| 224 | } |
| 225 | |
| 226 | private getRenderOpsForDone(prev: Frame): Diff { |
| 227 | this.state.previousOutput = '' |
no test coverage detected