compose: Use class to find markdown_preview related elements.

We convert the following elements to use a class instead of
id for accessing them across the codebase:

* markdown_preview
* undo_markdown_preview
* markdown_preview_spinner
* message_edit_content
* preview_content

Converted them together since changes to one impacted the other in
some modules like click_handlers.

Also, added a function in rows to get `message_row`.
This commit is contained in:
Aman Agrawal
2021-04-20 17:50:01 +00:00
committed by Tim Abbott
parent 8ebced2791
commit 84a7f08acc
17 changed files with 120 additions and 114 deletions

View File

@@ -872,9 +872,9 @@ test_ui("enter_with_preview_open", (override) => {
compose_state.set_message_type("stream");
$("#compose-textarea").val("message me");
$("#compose-textarea").hide();
$("#undo_markdown_preview").show();
$("#preview_message_area").show();
$("#markdown_preview").hide();
$("#compose .undo_markdown_preview").show();
$("#compose .preview_message_area").show();
$("#compose .markdown_preview").hide();
page_params.enter_sends = true;
let send_message_called = false;
override(compose, "send_message", () => {
@@ -882,9 +882,9 @@ test_ui("enter_with_preview_open", (override) => {
});
compose.enter_with_preview_open();
assert($("#compose-textarea").visible());
assert(!$("#undo_markdown_preview").visible());
assert(!$("#preview_message_area").visible());
assert($("#markdown_preview").visible());
assert(!$("#compose .undo_markdown_preview").visible());
assert(!$("#compose .preview_message_area").visible());
assert($("#compose .markdown_preview").visible());
assert(send_message_called);
page_params.enter_sends = false;
@@ -894,7 +894,7 @@ test_ui("enter_with_preview_open", (override) => {
// Test sending a message without content.
$("#compose-textarea").val("");
$("#preview_message_area").show();
$("#compose .preview_message_area").show();
$("#enter_sends").prop("checked", true);
page_params.enter_sends = true;
@@ -929,9 +929,9 @@ test_ui("finish", (override) => {
(function test_when_compose_validation_succeed() {
$("#compose-textarea").hide();
$("#undo_markdown_preview").show();
$("#preview_message_area").show();
$("#markdown_preview").hide();
$("#compose .undo_markdown_preview").show();
$("#compose .preview_message_area").show();
$("#compose .markdown_preview").hide();
$("#compose-textarea").val("foobarfoobar");
compose_state.set_message_type("private");
override(compose_state, "private_message_recipient", () => "bob@example.com");
@@ -946,9 +946,9 @@ test_ui("finish", (override) => {
});
assert(compose.finish());
assert($("#compose-textarea").visible());
assert(!$("#undo_markdown_preview").visible());
assert(!$("#preview_message_area").visible());
assert($("#markdown_preview").visible());
assert(!$("#compose .undo_markdown_preview").visible());
assert(!$("#compose .preview_message_area").visible());
assert($("#compose .markdown_preview").visible());
assert(send_message_called);
assert(compose_finished_event_checked);
})();
@@ -1530,16 +1530,16 @@ test_ui("on_events", (override) => {
// Tests setup
function setup_visibilities() {
$("#compose-textarea").show();
$("#markdown_preview").show();
$("#undo_markdown_preview").hide();
$("#preview_message_area").hide();
$("#compose .markdown_preview").show();
$("#compose .undo_markdown_preview").hide();
$("#compose .preview_message_area").hide();
}
function assert_visibilities() {
assert(!$("#compose-textarea").visible());
assert(!$("#markdown_preview").visible());
assert($("#undo_markdown_preview").visible());
assert($("#preview_message_area").visible());
assert(!$("#compose .markdown_preview").visible());
assert($("#compose .undo_markdown_preview").visible());
assert($("#compose .preview_message_area").visible());
}
function setup_mock_markdown_contains_backend_only_syntax(msg_content, return_val) {
@@ -1561,13 +1561,13 @@ test_ui("on_events", (override) => {
rendered: "Server: foobarfoobar",
};
success_callback(resp);
assert.equal($("#preview_content").html(), "Server: foobarfoobar");
assert.equal($("#compose .preview_content").html(), "Server: foobarfoobar");
}
function test_post_error(error_callback) {
error_callback();
assert.equal(
$("#preview_content").html(),
$("#compose .preview_content").html(),
"translated HTML: Failed to generate preview",
);
}
@@ -1582,7 +1582,7 @@ test_ui("on_events", (override) => {
function test(func, param) {
let destroy_indicator_called = false;
loading.destroy_indicator = (spinner) => {
assert.equal(spinner, $("#markdown_preview_spinner"));
assert.equal(spinner, $("#compose .markdown_preview_spinner"));
destroy_indicator_called = true;
};
setup_mock_markdown_contains_backend_only_syntax(msg, true);
@@ -1597,7 +1597,7 @@ test_ui("on_events", (override) => {
};
}
const handler = $("#compose").get_on_handler("click", "#markdown_preview");
const handler = $("#compose").get_on_handler("click", ".markdown_preview");
// Tests start here
$("#compose-textarea").val("");
@@ -1609,7 +1609,7 @@ test_ui("on_events", (override) => {
handler(event);
assert.equal($("#preview_content").html(), "translated HTML: Nothing to preview");
assert.equal($("#compose .preview_content").html(), "translated HTML: Nothing to preview");
assert_visibilities();
let make_indicator_called = false;
@@ -1618,7 +1618,7 @@ test_ui("on_events", (override) => {
setup_mock_markdown_contains_backend_only_syntax("```foobarfoobar```", true);
setup_mock_markdown_is_status_message("```foobarfoobar```", false);
loading.make_indicator = (spinner) => {
assert.equal(spinner.selector, "#markdown_preview_spinner");
assert.equal(spinner.selector, "#compose .markdown_preview_spinner");
make_indicator_called = true;
};
mock_channel_post("```foobarfoobar```");
@@ -1644,16 +1644,16 @@ test_ui("on_events", (override) => {
assert(apply_markdown_called);
assert_visibilities();
assert.equal($("#preview_content").html(), "Server: foobarfoobar");
assert.equal($("#compose .preview_content").html(), "Server: foobarfoobar");
})();
(function test_undo_markdown_preview_clicked() {
const handler = $("#compose").get_on_handler("click", "#undo_markdown_preview");
const handler = $("#compose").get_on_handler("click", ".undo_markdown_preview");
$("#compose-textarea").hide();
$("#undo_markdown_preview").show();
$("#preview_message_area").show();
$("#markdown_preview").hide();
$("#compose .undo_markdown_preview").show();
$("#compose .preview_message_area").show();
$("#compose .markdown_preview").hide();
const event = {
preventDefault: noop,
@@ -1662,9 +1662,9 @@ test_ui("on_events", (override) => {
handler(event);
assert($("#compose-textarea").visible());
assert(!$("#undo_markdown_preview").visible());
assert(!$("#preview_message_area").visible());
assert($("#markdown_preview").visible());
assert(!$("#compose .undo_markdown_preview").visible());
assert(!$("#compose .preview_message_area").visible());
assert($("#compose .markdown_preview").visible());
})();
});

View File

@@ -79,15 +79,15 @@ test("get_item", () => {
assert.equal(upload.get_item("drag_drop_container", {mode: "compose"}), $("#compose"));
assert.equal(
upload.get_item("markdown_preview_hide_button", {mode: "compose"}),
$("#undo_markdown_preview"),
$("#compose .undo_markdown_preview"),
);
assert.equal(
upload.get_item("textarea", {mode: "edit", row: 1}),
$(`#message_edit_content_${CSS.escape(1)}`),
$(`#edit_form_${CSS.escape(1)} .message_edit_content`),
);
$(`#message_edit_content_${CSS.escape(2)}`).closest = () => {
$(`#edit_form_${CSS.escape(2)} .message_edit_content`).closest = () => {
$(".message_edit_form").set_find_results(".message_edit_save", $(".message_edit_save"));
return $(".message_edit_form");
};
@@ -128,7 +128,7 @@ test("get_item", () => {
);
assert.equal(
upload.get_item("markdown_preview_hide_button", {mode: "edit", row: 65}),
$(`#undo_markdown_preview_${CSS.escape(65)}`),
$(`#edit_form_${CSS.escape(65)} .undo_markdown_preview`),
);
assert.throws(
@@ -268,12 +268,12 @@ test("upload_files", (override) => {
compose_ui_autosize_textarea_called = true;
});
let markdown_preview_hide_button_clicked = false;
$("#undo_markdown_preview").on("click", () => {
$("#compose .undo_markdown_preview").on("click", () => {
markdown_preview_hide_button_clicked = true;
});
$("#compose-send-button").prop("disabled", false);
$("#compose-send-status").removeClass("alert-info").hide();
$("#undo_markdown_preview").show();
$("#compose .undo_markdown_preview").show();
upload.upload_files(uppy, config, files);
assert($("#compose-send-button").prop("disabled"));
assert($("#compose-send-status").hasClass("alert-info"));

View File

@@ -157,8 +157,8 @@ async function test_send_multirecipient_pm_from_cordelia_pm_narrow(page: Page):
await common.pm_recipient.expect(page, recipient_internal_emails);
}
const markdown_preview_button = "#markdown_preview";
const markdown_preview_hide_button = "#undo_markdown_preview";
const markdown_preview_button = "#compose .markdown_preview";
const markdown_preview_hide_button = "#compose .undo_markdown_preview";
async function test_markdown_preview_buttons_visibility(page: Page): Promise<void> {
await page.waitForSelector(markdown_preview_button, {visible: true});
@@ -176,19 +176,19 @@ async function test_markdown_preview_buttons_visibility(page: Page): Promise<voi
}
async function test_markdown_preview_without_any_content(page: Page): Promise<void> {
await page.click("#markdown_preview");
await page.waitForSelector("#undo_markdown_preview", {visible: true});
const markdown_preview_element = await page.$("#preview_content");
await page.click("#compose .markdown_preview");
await page.waitForSelector("#compose .undo_markdown_preview", {visible: true});
const markdown_preview_element = await page.$("#compose .preview_content");
assert.equal(
await page.evaluate((element: Element) => element.textContent, markdown_preview_element),
"Nothing to preview",
);
await page.click("#undo_markdown_preview");
await page.click("#compose .undo_markdown_preview");
}
async function test_markdown_rendering(page: Page): Promise<void> {
await page.waitForSelector("#markdown_preview", {visible: true});
let markdown_preview_element = await page.$("#preview_content");
await page.waitForSelector("#compose .markdown_preview", {visible: true});
let markdown_preview_element = await page.$("#compose .preview_content");
assert.equal(
await page.evaluate((element: Element) => element.textContent, markdown_preview_element),
"",
@@ -196,12 +196,12 @@ async function test_markdown_rendering(page: Page): Promise<void> {
await common.fill_form(page, 'form[action^="/json/messages"]', {
content: "**Markdown preview** >> Test for Markdown preview",
});
await page.click("#markdown_preview");
await page.waitForSelector("#preview_content", {visible: true});
await page.click("#compose .markdown_preview");
await page.waitForSelector("#compose .preview_content", {visible: true});
const expected_markdown_html =
"<p><strong>Markdown preview</strong> &gt;&gt; Test for Markdown preview</p>";
await page.waitForFunction(() => $("#preview_content").html() !== "");
markdown_preview_element = await page.$("#preview_content");
await page.waitForFunction(() => $("#compose .preview_content").html() !== "");
markdown_preview_element = await page.$("#compose .preview_content");
assert.equal(
await page.evaluate((element: Element) => element.innerHTML, markdown_preview_element),
expected_markdown_html,

View File

@@ -63,7 +63,7 @@ async function open_compose_markdown_preview(page: Page): Promise<void> {
await page.waitForSelector(new_topic_button, {visible: true});
await page.click(new_topic_button);
const markdown_preview_button = "#markdown_preview"; // eye icon.
const markdown_preview_button = "#compose .markdown_preview"; // eye icon.
await page.waitForSelector(markdown_preview_button, {visible: true});
await page.click(markdown_preview_button);
}

View File

@@ -339,40 +339,31 @@ export function initialize() {
$(`#edit_form_${CSS.escape(row_id)} .file_input`).trigger("click");
});
$("body").on("click", ".message_edit_form [id^='markdown_preview_']", function (e) {
$("body").on("click", ".message_edit_form .markdown_preview", (e) => {
e.preventDefault();
const row_id = rows.id($(this).closest(".message_row"));
function $_(selector) {
return $(`${selector}_${CSS.escape(row_id)}`);
}
const content = $_("#message_edit_content").val();
$_("#message_edit_content").hide();
$_("#markdown_preview").hide();
$_("#undo_markdown_preview").show();
$_("#preview_message_area").show();
const row = rows.get_closest_row(e.target);
const $msg_edit_content = row.find(".message_edit_content");
const content = $msg_edit_content.val();
$msg_edit_content.hide();
row.find(".markdown_preview").hide();
row.find(".undo_markdown_preview").show();
row.find(".preview_message_area").show();
compose.render_and_show_preview(
$_("#markdown_preview_spinner"),
$_("#preview_content"),
row.find(".markdown_preview_spinner"),
row.find(".preview_content"),
content,
);
});
$("body").on("click", ".message_edit_form [id^='undo_markdown_preview_']", function (e) {
$("body").on("click", ".message_edit_form .undo_markdown_preview", (e) => {
e.preventDefault();
const row_id = rows.id($(this).closest(".message_row"));
function $_(selector) {
return $(`${selector}_${CSS.escape(row_id)}`);
}
$_("#message_edit_content").show();
$_("#undo_markdown_preview").hide();
$_("#preview_message_area").hide();
$_("#preview_content").empty();
$_("#markdown_preview").show();
const row = rows.get_closest_row(e.target);
row.find(".message_edit_content").show();
row.find(".undo_markdown_preview").hide();
row.find(".preview_message_area").hide();
row.find(".preview_content").empty();
row.find(".markdown_preview").show();
});
// TOPIC MUTING

View File

@@ -163,10 +163,10 @@ export function reset_user_acknowledged_announce_flag() {
export function clear_preview_area() {
$("#compose-textarea").show();
$("#undo_markdown_preview").hide();
$("#preview_message_area").hide();
$("#preview_content").empty();
$("#markdown_preview").show();
$("#compose .undo_markdown_preview").hide();
$("#compose .preview_message_area").hide();
$("#compose .preview_content").empty();
$("#compose .markdown_preview").show();
}
function update_stream_button(btn_text, title) {
@@ -1317,18 +1317,22 @@ export function initialize() {
}
});
$("#compose").on("click", "#markdown_preview", (e) => {
$("#compose").on("click", ".markdown_preview", (e) => {
e.preventDefault();
const content = $("#compose-textarea").val();
$("#compose-textarea").hide();
$("#markdown_preview").hide();
$("#undo_markdown_preview").show();
$("#preview_message_area").show();
$("#compose .markdown_preview").hide();
$("#compose .undo_markdown_preview").show();
$("#compose .preview_message_area").show();
render_and_show_preview($("#markdown_preview_spinner"), $("#preview_content"), content);
render_and_show_preview(
$("#compose .markdown_preview_spinner"),
$("#compose .preview_content"),
content,
);
});
$("#compose").on("click", "#undo_markdown_preview", (e) => {
$("#compose").on("click", ".undo_markdown_preview", (e) => {
e.preventDefault();
clear_preview_area();
});

View File

@@ -686,7 +686,9 @@ export function register_click_handlers() {
// The following check will return false if emoji was not selected in
// message edit form.
if (edit_message_id !== null) {
const edit_message_textarea = $(`#message_edit_content_${CSS.escape(edit_message_id)}`);
const edit_message_textarea = $(
`#edit_form_${CSS.escape(edit_message_id)} .message_edit_content`,
);
// Assign null to edit_message_id so that the selection of emoji in new
// message composition form works correctly.
edit_message_id = null;

View File

@@ -25,7 +25,7 @@ export function is_popped_from_edit_messsage() {
}
export function focus_current_edit_message() {
$(`#message_edit_content_${CSS.escape(edit_message_id)}`).trigger("focus");
$(`#edit_form_${CSS.escape(edit_message_id)} .message_edit_content`).trigger("focus");
}
// Approximate width and height of
@@ -66,7 +66,9 @@ function renderGIPHYGrid(targetEl) {
onGifClick: (props) => {
let textarea = $("#compose-textarea");
if (edit_message_id !== undefined) {
textarea = $(`#message_edit_content_${CSS.escape(edit_message_id)}`);
textarea = $(
`#edit_form_${CSS.escape(edit_message_id)} .message_edit_content`,
);
}
compose_ui.insert_syntax_and_focus(

View File

@@ -216,8 +216,8 @@ export function parse_image_data(image) {
const is_vimeo_video = Boolean($image.closest(".vimeo-video").length);
const is_embed_video = Boolean($image.closest(".embed-video").length);
// check if image is descendent of #preview_content
const is_compose_preview_image = $image.closest("#preview_content").length === 1;
// check if image is descendent of #compose .preview_content
const is_compose_preview_image = $image.closest("#compose .preview_content").length === 1;
const $parent = $image.parent();
let $type;
@@ -277,7 +277,7 @@ export function next() {
// this is a block of events that are required for the lightbox to work.
export function initialize() {
$("#main_div, #preview_content").on("click", ".message_inline_image a", function (e) {
$("#main_div, #compose .preview_content").on("click", ".message_inline_image a", function (e) {
// prevent the link from opening in a new page.
e.preventDefault();
// prevent the message compose dialog from happening.

View File

@@ -300,7 +300,8 @@ function timer_text(seconds_left) {
function create_copy_to_clipboard_handler(source, message_id) {
new ClipboardJS(source, {
target: () => document.querySelector(`#message_edit_content_${CSS.escape(message_id)}`),
target: () =>
document.querySelector(`#edit_form_${CSS.escape(message_id)} .message_edit_content`),
});
}
@@ -403,7 +404,7 @@ function edit_message(row, raw_content) {
create_copy_to_clipboard_handler(copy_message[0], message.id);
} else if (editability === editability_types.FULL) {
copy_message.remove();
const edit_id = `#message_edit_content_${CSS.escape(rows.id(row))}`;
const edit_id = `#edit_form_${CSS.escape(rows.id(row))} .message_edit_content`;
const listeners = resize.watch_manual_resize(edit_id);
if (listeners) {
currently_editing_messages.get(rows.id(row)).listeners = listeners;
@@ -590,7 +591,9 @@ export function end_message_row_edit(row) {
// Clean up resize event listeners
const listeners = currently_editing_messages.get(message.id).listeners;
const edit_box = document.querySelector(`#message_edit_content_${CSS.escape(message.id)}`);
const edit_box = document.querySelector(
`#edit_form_${CSS.escape(message.id)} .message_edit_content`,
);
if (listeners !== undefined) {
// Event listeners to clean up are only set in some edit types
edit_box.removeEventListener("mousedown", listeners[0]);
@@ -872,7 +875,7 @@ export function edit_last_sent_message() {
// Finally do the real work!
compose_actions.cancel();
start(msg_row, () => {
$("#message_edit_content").trigger("focus");
$(".message_edit_content").trigger("focus");
});
}

View File

@@ -934,7 +934,7 @@ export function register_click_handlers() {
}
});
$("#main_div, #preview_content").on("click", ".code_external_link", function (e) {
$("#main_div, #compose .preview_content").on("click", ".code_external_link", function (e) {
const view_in_playground_button = $(this);
const codehilite_div = $(this).closest(".codehilite");
e.stopPropagation();

View File

@@ -142,6 +142,10 @@ export function get_closest_group(element) {
return $(element).closest("div.recipient_row");
}
export function get_closest_row(element) {
return $(element).closest("div.message_row");
}
export function first_message_in_group(message_group) {
return $("div.message_row", message_group).first();
}

View File

@@ -56,7 +56,7 @@ export function get_item(key, config) {
case "drag_drop_container":
return $("#compose");
case "markdown_preview_hide_button":
return $("#undo_markdown_preview");
return $("#compose .undo_markdown_preview");
default:
throw new Error(`Invalid key name for mode "${config.mode}"`);
}
@@ -66,9 +66,9 @@ export function get_item(key, config) {
}
switch (key) {
case "textarea":
return $(`#message_edit_content_${CSS.escape(config.row)}`);
return $(`#edit_form_${CSS.escape(config.row)} .message_edit_content`);
case "send_button":
return $(`#message_edit_content_${CSS.escape(config.row)}`)
return $(`#edit_form_${CSS.escape(config.row)} .message_edit_content`)
.closest(".message_edit_form")
.find(".message_edit_save");
case "send_status_identifier":
@@ -88,7 +88,7 @@ export function get_item(key, config) {
case "drag_drop_container":
return $(".message_edit_form");
case "markdown_preview_hide_button":
return $(`#undo_markdown_preview_${CSS.escape(config.row)}`);
return $(`#edit_form_${CSS.escape(config.row)} .undo_markdown_preview`);
default:
throw new Error(`Invalid key name for mode "${config.mode}"`);
}

View File

@@ -462,13 +462,13 @@ a.compose_control_button {
min-height: 42px;
}
a#undo_markdown_preview {
a.undo_markdown_preview {
text-decoration: none;
position: relative;
font-size: 15px;
}
#markdown_preview_spinner {
.markdown_preview_spinner {
margin: auto;
}

View File

@@ -86,8 +86,8 @@
<div class="messagebox">
<textarea class="new_message_textarea" name="content" id='compose-textarea' placeholder="{{t 'Compose your message here' }}" tabindex="0" maxlength="10000" aria-label="{{t 'Compose your message here...' }}"></textarea>
<div class="scrolling_list preview_message_area" data-simplebar id="preview_message_area" style="display:none;">
<div id="markdown_preview_spinner"></div>
<div id="preview_content" class="preview_content rendered_markdown"></div>
<div class="markdown_preview_spinner"></div>
<div class="preview_content rendered_markdown"></div>
</div>
<div class="drag"></div>
<div id="below-compose-content">

View File

@@ -2,8 +2,8 @@
{{#if file_upload_enabled }}
<a role="button" class="compose_control_button compose_upload_file fa fa-paperclip notdisplayed" aria-label="{{t 'Upload files' }}" tabindex=0 title="{{t 'Upload files' }}"></a>
{{/if}}
<a role="button" id="markdown_preview" class="compose_control_button fa fa-eye" aria-label="{{t 'Preview' }}" tabindex=0 title="{{t 'Preview' }}"></a>
<a role="button" id="undo_markdown_preview" class="compose_control_button fa fa-edit" aria-label="{{t 'Write' }}" tabindex=0 style="display:none;" title="{{t 'Write' }}"></a>
<a role="button" class="markdown_preview compose_control_button fa fa-eye" aria-label="{{t 'Preview' }}" tabindex=0 title="{{t 'Preview' }}"></a>
<a role="button" class="undo_markdown_preview compose_control_button fa fa-edit" aria-label="{{t 'Write' }}" tabindex=0 style="display:none;" title="{{t 'Write' }}"></a>
<a role="button" class="compose_control_button fa fa-video-camera video_link" aria-label="{{t 'Add video call' }}" tabindex=0 title="{{t 'Add video call' }}"></a>
<a role="button" class="compose_control_button fa fa-smile-o" aria-label="{{t 'Add emoji' }}" id="emoji_map" tabindex=0 title="{{t 'Add emoji' }}"></a>
{{#if giphy_api_available }}

View File

@@ -43,10 +43,10 @@
<div class="control-group no-margin">
<div class="controls edit-controls">
{{> copy_message_button message_id=this.message_id}}
<textarea class="message_edit_content" maxlength="10000" id="message_edit_content_{{message_id}}">{{content}}</textarea>
<textarea class="message_edit_content" maxlength="10000">{{content}}</textarea>
<div class="scrolling_list preview_message_area" id="preview_message_area_{{message_id}}" style="display:none;">
<div id="markdown_preview_spinner_{{message_id}}"></div>
<div id="preview_content_{{message_id}}" class="preview_content rendered_markdown"></div>
<div class="markdown_preview_spinner"></div>
<div class="preview_content rendered_markdown"></div>
</div>
</div>
</div>
@@ -62,8 +62,8 @@
{{#if file_upload_enabled}}
<a role="button" tabindex=0 class="compose_control_button attach_files fa fa-paperclip notdisplayed" aria-label="{{t "Attach files" }}" title="{{t "Attach files" }}"></a>
{{/if}}
<a role="button" tabindex=0 id="markdown_preview_{{message_id}}" class="compose_control_button fa fa-eye" aria-label="{{t 'Preview' }}" title="{{t 'Preview' }}"></a>
<a role="button" tabindex=0 id="undo_markdown_preview_{{message_id}}" class="compose_control_button fa fa-edit" aria-label="{{t 'Write' }}" style="display:none;" title="{{t 'Write' }}"></a>
<a role="button" tabindex=0 class="markdown_preview compose_control_button fa fa-eye" aria-label="{{t 'Preview' }}" title="{{t 'Preview' }}"></a>
<a role="button" tabindex=0 class="undo_markdown_preview compose_control_button fa fa-edit" aria-label="{{t 'Write' }}" style="display:none;" title="{{t 'Write' }}"></a>
{{#if show_video_chat_button}}
<a role="button" tabindex=0 class="compose_control_button fa fa-video-camera video_link" aria-label="{{t "Add video call" }}" data-message-id="{{message_id}}" title="{{t "Add video call" }}"></a>
{{/if}}