Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add strikethrough formatting #1809

Merged
merged 2 commits into from
Sep 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/1809.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add strikethrough formatting support
10 changes: 10 additions & 0 deletions spec/unit/formatting.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ describe("Formatting", function() {
formatting.htmlToIrc("The quick brown <code>fox</code> jumps over the lazy <code>dog</code>.")
).toBe("The quick brown \u0011fox\u000f jumps over the lazy \u0011dog\u000f.");
});
it("should format <del> inputs", function() {
expect(
formatting.htmlToIrc("The quick brown <del>fox</del> jumps over the lazy <del>dog</del>.")
).toBe("The quick brown \u001efox\u000f jumps over the lazy \u001edog\u000f.");
});
it("should have regular characters for inputs containing non-safe html chars", function() {
expect(
formatting.htmlToIrc("%100 of \"homes\" should have <u>dogs</u>. Facts © Half-Shot")
Expand Down Expand Up @@ -55,6 +60,11 @@ describe("Formatting", function() {
formatting.ircToHtml("The quick brown \u0002fox\u000f jumps over the lazy \u0002dog\u000f.")
).toBe("The quick brown <b>fox</b> jumps over the lazy <b>dog</b>.");
});
it("should <del> for strikethrough inputs", function() {
expect(
formatting.ircToHtml("The quick brown \u001efox\u000f jumps over the lazy \u001edog\u000f.")
).toBe("The quick brown <del>fox</del> jumps over the lazy <del>dog</del>.");
});
it("should <code> for monospace inputs", function() {
expect(
formatting.ircToHtml("The quick brown \u0011fox\u000f jumps over the lazy \u0011dog\u000f.")
Expand Down
17 changes: 11 additions & 6 deletions src/irc/formatting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@ const STYLE_COLOR = '\u0003';
const STYLE_BOLD = '\u0002';
const STYLE_MONOSPACE = '\u0011';
const STYLE_ITALICS = '\u001d';
const STYLE_STRIKE = '\u001e';
const STYLE_UNDERLINE = '\u001f';
const STYLE_CODES = [STYLE_BOLD, STYLE_MONOSPACE, STYLE_ITALICS, STYLE_UNDERLINE];
const STYLE_CODES = [STYLE_BOLD, STYLE_MONOSPACE, STYLE_ITALICS, STYLE_STRIKE, STYLE_UNDERLINE];
const RESET_CODE = '\u000f';
const REVERSE_CODE = '\u0016';

Expand Down Expand Up @@ -166,7 +167,7 @@ export function htmlToIrc(html?: string): string|null {
// things like case-sensitivity and spacing). Use he to decode any html entities
// because we don't want those.
let cleanHtml = he.decode(sanitizeHtml(html, {
allowedTags: ["b", "code", "i", "u", "strong", "font", "em"],
allowedTags: ["b", "code", "del", "i", "u", "strong", "font", "em"],
allowedAttributes: {
font: ["color"]
}
Expand All @@ -181,7 +182,7 @@ export function htmlToIrc(html?: string): string|null {
const replacements: [RegExp, string][] = [
[/<b>/g, STYLE_BOLD], [/<u>/g, STYLE_UNDERLINE], [/<i>/g, STYLE_ITALICS],
[/<strong>/g, STYLE_BOLD], [/<em>/g, STYLE_ITALICS],
[/<code>/g, STYLE_MONOSPACE],
[/<del>/g, STYLE_STRIKE], [/<code>/g, STYLE_MONOSPACE],
];
Object.keys(htmlNamesToColorCodes).forEach(function(htmlColor) {
replacements.push([
Expand All @@ -199,6 +200,7 @@ export function htmlToIrc(html?: string): string|null {
const openStyleCodes = [];
const closeTagsToStyle: {[tag: string]: string} = {
"</b>": STYLE_BOLD,
"</del>": STYLE_STRIKE,
"</code>": STYLE_MONOSPACE,
"</u>": STYLE_UNDERLINE,
"</i>": STYLE_ITALICS,
Expand Down Expand Up @@ -260,13 +262,13 @@ export function ircToHtml(text: string): string {
// Replace all mIRC formatting characters.
// The color character can have arguments.
// The regex matches:
// - Any single 'simple' formatting character: \x02, \x11, \x1d, \x1f, \x0f and
// \x16 for bold, italics, underline, reset and reverse respectively.
// - Any single 'simple' formatting character: \x02, \x11, \x1d, \x1e, \x1f, \x0f and
// \x16 for bold, italics, underline, strikethrough, reset and reverse respectively.
// - The colour formatting character (\x03) followed by 0 to 2 digits for
// the foreground colour and (optionally) a comma and 1-2 digits for the
// background colour.
// eslint-disable-next-line no-control-regex
const colorRegex = /[\x02\x11\x1d\x1f\x0f\x16]|\x03(\d{0,2})(?:,(\d{1,2}))?/g;
const colorRegex = /[\x02\x11\x1d\x1e\x1f\x0f\x16]|\x03(\d{0,2})(?:,(\d{1,2}))?/g;

// Maintain a small state machine of which tags are open so we can close the right
// ones on RESET codes and toggle appropriately if they do the same code again.
Expand All @@ -284,6 +286,9 @@ export function ircToHtml(text: string): string {
case STYLE_MONOSPACE:
return htmlTag(state, 'code');

case STYLE_STRIKE:
return htmlTag(state, 'del');

case STYLE_ITALICS:
return htmlTag(state, 'i');

Expand Down
Loading