diff --git a/components/buffer-header.js b/components/buffer-header.js index 61774ff..7635c48 100644 --- a/components/buffer-header.js +++ b/components/buffer-header.js @@ -1,5 +1,6 @@ import { html, Component } from "/lib/index.js"; import linkify from "/lib/linkify.js"; +import { strip as stripANSI } from "/lib/ansi.js"; import { BufferType } from "/state.js"; const Status = { @@ -29,10 +30,12 @@ export default function BufferHeader(props) { var serverInfo = props.buffer.serverInfo; description = `Connected to ${serverInfo.name}`; } else if (props.buffer.topic) { - description = linkify(props.buffer.topic); + description = linkify(stripANSI(props.buffer.topic)); } else if (props.buffer.who) { var who = props.buffer.who; + var realname = stripANSI(who.realname || ""); + var status = Status.HERE; if (who.away) { status = Status.GONE; @@ -41,7 +44,7 @@ export default function BufferHeader(props) { status = Status.OFFLINE; } - description = html`<${NickStatus} status=${status}/> ${who.realname} (${who.username}@${who.hostname})`; + description = html`<${NickStatus} status=${status}/> ${realname} (${who.username}@${who.hostname})`; } else if (props.buffer.offline) { // User is offline, but we don't have WHO information description = html`<${NickStatus} status=${Status.OFFLINE}/> ${props.buffer.name}`; diff --git a/components/buffer.js b/components/buffer.js index 5bfb564..6226212 100644 --- a/components/buffer.js +++ b/components/buffer.js @@ -1,6 +1,7 @@ import { html, Component } from "/lib/index.js"; import linkify from "/lib/linkify.js"; import * as irc from "/lib/irc.js"; +import { strip as stripANSI } from "/lib/ansi.js"; import { BufferType, getNickURL, getMessageURL } from "/state.js"; function djb2(s) { @@ -64,10 +65,10 @@ class LogLine extends Component { var action = text.slice(actionPrefix.length, -1); lineClass = "me-tell"; - content = html`* ${createNick(msg.prefix.name)} ${linkify(action)}`; + content = html`* ${createNick(msg.prefix.name)} ${linkify(stripANSI(action))}`; } else { lineClass = "talk"; - content = html`${"<"}${createNick(msg.prefix.name)}${">"} ${linkify(text)}`; + content = html`${"<"}${createNick(msg.prefix.name)}${">"} ${linkify(stripANSI(text))}`; } break; case "JOIN": @@ -94,7 +95,7 @@ class LogLine extends Component { case "TOPIC": var topic = msg.params[1]; content = html` - ${createNick(msg.prefix.name)} changed the topic to: ${linkify(topic)} + ${createNick(msg.prefix.name)} changed the topic to: ${linkify(stripANSI(topic))} `; break; default: diff --git a/lib/ansi.js b/lib/ansi.js new file mode 100644 index 0000000..44bf512 --- /dev/null +++ b/lib/ansi.js @@ -0,0 +1,53 @@ +// See https://modern.ircdocs.horse/formatting.html + +const BOLD = "\x02"; +const ITALIC = "\x1D"; +const UNDERLINE = "\x1F"; +const STRIKETHROUGH = "\x1E"; +const MONOSPACE = "\x11"; +const COLOR = "\x03"; +const COLOR_HEX = "\x04"; +const REVERSE_COLOR = "\x16"; +const RESET = "\x0F"; + +function isDigit(ch) { + return ch >= "0" && ch <= "9"; +} + +export function strip(text) { + var out = ""; + for (var i = 0; i < text.length; i++) { + var ch = text[i]; + switch (ch) { + case BOLD: + case ITALIC: + case UNDERLINE: + case STRIKETHROUGH: + case MONOSPACE: + case REVERSE_COLOR: + case RESET: + break; // skip + case COLOR: + if (!isDigit(text[i + 1])) { + break; + } + i++; + if (isDigit(text[i + 1])) { + i++; + } + if (text[i + 1] == "," && isDigit(text[i + 2])) { + i += 2; + if (isDigit(text[i + 1])) { + i++; + } + } + break; + case COLOR_HEX: + i += 6; + break; + default: + out += ch; + } + } + return out; +}