mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-04 14:03:30 +00:00 
			
		
		
		
	compose: Format button for spoilers.
Note that toggling off spoiler formatting works if either all the content inside, or the header (if it exists) or both are selected. Co-authored-by: N-Shar-ma <bablinaneh@gmail.com>
This commit is contained in:
		
				
					committed by
					
						
						Tim Abbott
					
				
			
			
				
	
			
			
			
						parent
						
							df143137ef
						
					
				
				
					commit
					2db8563a7e
				
			@@ -580,6 +580,151 @@ export function format_text($textarea, type, inserted_content) {
 | 
				
			|||||||
        wrapSelection(field, syntax_start, syntax_end);
 | 
					        wrapSelection(field, syntax_start, syntax_end);
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const format_spoiler = () => {
 | 
				
			||||||
 | 
					        let spoiler_syntax_start = "```spoiler \n";
 | 
				
			||||||
 | 
					        const spoiler_syntax_start_without_break = "```spoiler ";
 | 
				
			||||||
 | 
					        let spoiler_syntax_end = "\n```";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // For when the entire spoiler block (with no header) is selected.
 | 
				
			||||||
 | 
					        if (is_inner_text_formatted(spoiler_syntax_start, spoiler_syntax_end)) {
 | 
				
			||||||
 | 
					            text =
 | 
				
			||||||
 | 
					                text.slice(0, range.start) +
 | 
				
			||||||
 | 
					                text.slice(
 | 
				
			||||||
 | 
					                    range.start + spoiler_syntax_start.length,
 | 
				
			||||||
 | 
					                    range.end - spoiler_syntax_end.length,
 | 
				
			||||||
 | 
					                ) +
 | 
				
			||||||
 | 
					                text.slice(range.end);
 | 
				
			||||||
 | 
					            if (text.startsWith("\n")) {
 | 
				
			||||||
 | 
					                text = text.slice(1);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            set(field, text);
 | 
				
			||||||
 | 
					            field.setSelectionRange(
 | 
				
			||||||
 | 
					                range.start,
 | 
				
			||||||
 | 
					                range.end - spoiler_syntax_start.length - spoiler_syntax_end.length,
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // For when the entire spoiler block (with a header) is selected.
 | 
				
			||||||
 | 
					        if (is_inner_text_formatted(spoiler_syntax_start_without_break, spoiler_syntax_end)) {
 | 
				
			||||||
 | 
					            text =
 | 
				
			||||||
 | 
					                text.slice(0, range.start) +
 | 
				
			||||||
 | 
					                text.slice(
 | 
				
			||||||
 | 
					                    range.start + spoiler_syntax_start_without_break.length,
 | 
				
			||||||
 | 
					                    range.end - spoiler_syntax_end.length,
 | 
				
			||||||
 | 
					                ) +
 | 
				
			||||||
 | 
					                text.slice(range.end);
 | 
				
			||||||
 | 
					            if (text.startsWith("\n")) {
 | 
				
			||||||
 | 
					                text = text.slice(1);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            set(field, text);
 | 
				
			||||||
 | 
					            field.setSelectionRange(
 | 
				
			||||||
 | 
					                range.start,
 | 
				
			||||||
 | 
					                range.end - spoiler_syntax_start_without_break.length - spoiler_syntax_end.length,
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // For when the text (including the header) inside a spoiler block is selected.
 | 
				
			||||||
 | 
					        if (is_selection_formatted(spoiler_syntax_start_without_break, spoiler_syntax_end)) {
 | 
				
			||||||
 | 
					            text =
 | 
				
			||||||
 | 
					                text.slice(0, range.start - spoiler_syntax_start_without_break.length) +
 | 
				
			||||||
 | 
					                selected_text +
 | 
				
			||||||
 | 
					                text.slice(range.end + spoiler_syntax_end.length);
 | 
				
			||||||
 | 
					            set(field, text);
 | 
				
			||||||
 | 
					            field.setSelectionRange(
 | 
				
			||||||
 | 
					                range.start - spoiler_syntax_start_without_break.length,
 | 
				
			||||||
 | 
					                range.end - spoiler_syntax_start_without_break.length,
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // For when only the text inside a spoiler block (without a header) is selected.
 | 
				
			||||||
 | 
					        if (is_selection_formatted(spoiler_syntax_start, spoiler_syntax_end)) {
 | 
				
			||||||
 | 
					            text =
 | 
				
			||||||
 | 
					                text.slice(0, range.start - spoiler_syntax_start.length) +
 | 
				
			||||||
 | 
					                selected_text +
 | 
				
			||||||
 | 
					                text.slice(range.end + spoiler_syntax_end.length);
 | 
				
			||||||
 | 
					            set(field, text);
 | 
				
			||||||
 | 
					            field.setSelectionRange(
 | 
				
			||||||
 | 
					                range.start - spoiler_syntax_start.length,
 | 
				
			||||||
 | 
					                range.end - spoiler_syntax_start.length,
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const is_inner_content_selected = () =>
 | 
				
			||||||
 | 
					            range.start >= spoiler_syntax_start.length &&
 | 
				
			||||||
 | 
					            text.length - range.end >= spoiler_syntax_end.length &&
 | 
				
			||||||
 | 
					            text.slice(range.end, range.end + spoiler_syntax_end.length) === spoiler_syntax_end &&
 | 
				
			||||||
 | 
					            text[range.start - 1] === "\n" &&
 | 
				
			||||||
 | 
					            text.lastIndexOf(spoiler_syntax_start_without_break, range.start - 1) ===
 | 
				
			||||||
 | 
					                text.lastIndexOf("\n", range.start - 2) + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // For when only the text inside a spoiler block (with a header) is selected.
 | 
				
			||||||
 | 
					        if (is_inner_content_selected()) {
 | 
				
			||||||
 | 
					            const new_selection_start = text.lastIndexOf(
 | 
				
			||||||
 | 
					                spoiler_syntax_start_without_break,
 | 
				
			||||||
 | 
					                range.start,
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            text =
 | 
				
			||||||
 | 
					                text.slice(0, new_selection_start) +
 | 
				
			||||||
 | 
					                text.slice(
 | 
				
			||||||
 | 
					                    new_selection_start + spoiler_syntax_start_without_break.length,
 | 
				
			||||||
 | 
					                    range.start,
 | 
				
			||||||
 | 
					                ) +
 | 
				
			||||||
 | 
					                selected_text +
 | 
				
			||||||
 | 
					                text.slice(range.end + spoiler_syntax_end.length);
 | 
				
			||||||
 | 
					            set(field, text);
 | 
				
			||||||
 | 
					            field.setSelectionRange(
 | 
				
			||||||
 | 
					                new_selection_start,
 | 
				
			||||||
 | 
					                range.end - spoiler_syntax_start_without_break.length,
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const is_header_selected = () =>
 | 
				
			||||||
 | 
					            range.start >= spoiler_syntax_start_without_break.length &&
 | 
				
			||||||
 | 
					            text.slice(range.start - spoiler_syntax_start_without_break.length, range.start) ===
 | 
				
			||||||
 | 
					                spoiler_syntax_start_without_break &&
 | 
				
			||||||
 | 
					            text.length - range.end >= spoiler_syntax_end.length &&
 | 
				
			||||||
 | 
					            text[range.end] === "\n";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // For when only the header of a spoiler block  is selected.
 | 
				
			||||||
 | 
					        if (is_header_selected()) {
 | 
				
			||||||
 | 
					            const header = range.text;
 | 
				
			||||||
 | 
					            const new_range_end = text.indexOf(spoiler_syntax_end, range.start);
 | 
				
			||||||
 | 
					            const new_range_start = header ? range.start : range.start + 1;
 | 
				
			||||||
 | 
					            text =
 | 
				
			||||||
 | 
					                text.slice(0, range.start - spoiler_syntax_start_without_break.length) +
 | 
				
			||||||
 | 
					                text.slice(new_range_start, new_range_end) +
 | 
				
			||||||
 | 
					                text.slice(new_range_end + spoiler_syntax_end.length);
 | 
				
			||||||
 | 
					            set(field, text);
 | 
				
			||||||
 | 
					            field.setSelectionRange(
 | 
				
			||||||
 | 
					                new_range_start - spoiler_syntax_start_without_break.length - (header ? 0 : 1),
 | 
				
			||||||
 | 
					                new_range_end - spoiler_syntax_start_without_break.length - (header ? 0 : 1),
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (range.start > 0 && text[range.start - 1] !== "\n") {
 | 
				
			||||||
 | 
					            spoiler_syntax_start = "\n" + spoiler_syntax_start;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (range.end < text.length && text[range.end] !== "\n") {
 | 
				
			||||||
 | 
					            spoiler_syntax_end = spoiler_syntax_end + "\n";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const spoiler_syntax_start_with_header = spoiler_syntax_start_without_break + "Header\n";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Otherwise, we don't have spoiler syntax, so we add it.
 | 
				
			||||||
 | 
					        wrapSelection(field, spoiler_syntax_start_with_header, spoiler_syntax_end);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        field.setSelectionRange(
 | 
				
			||||||
 | 
					            range.start + spoiler_syntax_start.length - 1,
 | 
				
			||||||
 | 
					            range.start + spoiler_syntax_start_with_header.length - 1,
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch (type) {
 | 
					    switch (type) {
 | 
				
			||||||
        case "bold":
 | 
					        case "bold":
 | 
				
			||||||
            // Ctrl + B: Toggle bold syntax on selection.
 | 
					            // Ctrl + B: Toggle bold syntax on selection.
 | 
				
			||||||
@@ -739,6 +884,9 @@ export function format_text($textarea, type, inserted_content) {
 | 
				
			|||||||
            format(quote_syntax_start, quote_syntax_end);
 | 
					            format(quote_syntax_start, quote_syntax_end);
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        case "spoiler":
 | 
				
			||||||
 | 
					            format_spoiler();
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
        case "latex": {
 | 
					        case "latex": {
 | 
				
			||||||
            const inline_latex_syntax = "$$";
 | 
					            const inline_latex_syntax = "$$";
 | 
				
			||||||
            let block_latex_syntax_start = "```math\n";
 | 
					            let block_latex_syntax_start = "```math\n";
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,6 +8,7 @@
 | 
				
			|||||||
    <a role="button" data-format-type="bulleted" class="compose_control_button fa fa-list-ul formatting_button" aria-label="{{t 'Bulleted list' }}" {{#unless preview_mode_on}} tabindex=0 {{/unless}} data-tippy-content="{{t 'Bulleted list' }}"></a>
 | 
					    <a role="button" data-format-type="bulleted" class="compose_control_button fa fa-list-ul formatting_button" aria-label="{{t 'Bulleted list' }}" {{#unless preview_mode_on}} tabindex=0 {{/unless}} data-tippy-content="{{t 'Bulleted list' }}"></a>
 | 
				
			||||||
    <div class="divider">|</div>
 | 
					    <div class="divider">|</div>
 | 
				
			||||||
    <a role="button" data-format-type="quote" class="compose_control_button fa fa-quote-left formatting_button" aria-label="{{t 'Quote' }}" {{#unless preview_mode_on}} tabindex=0 {{/unless}} data-tippy-content="{{t 'Quote' }}"></a>
 | 
					    <a role="button" data-format-type="quote" class="compose_control_button fa fa-quote-left formatting_button" aria-label="{{t 'Quote' }}" {{#unless preview_mode_on}} tabindex=0 {{/unless}} data-tippy-content="{{t 'Quote' }}"></a>
 | 
				
			||||||
 | 
					    <a role="button" data-format-type="spoiler" class="compose_control_button fa fa-minus formatting_button" aria-label="{{t 'Spoiler' }}" {{#unless preview_mode_on}} tabindex=0 {{/unless}} data-tippy-content="{{t 'Spoiler' }}"></a>
 | 
				
			||||||
    <a role="button" data-format-type="code" class="compose_control_button fa fa-code formatting_button" aria-label="{{t 'Code' }}" {{#unless preview_mode_on}} tabindex=0 {{/unless}} data-tippy-content="{{t 'Code' }}"></a>
 | 
					    <a role="button" data-format-type="code" class="compose_control_button fa fa-code formatting_button" aria-label="{{t 'Code' }}" {{#unless preview_mode_on}} tabindex=0 {{/unless}} data-tippy-content="{{t 'Code' }}"></a>
 | 
				
			||||||
    <a role="button" data-format-type="latex" class="compose_control_button fa fa-superscript formatting_button" aria-label="{{t 'LaTeX' }}" {{#unless preview_mode_on}} tabindex=0 {{/unless}} data-tippy-content="{{t 'LaTeX' }}"></a>
 | 
					    <a role="button" data-format-type="latex" class="compose_control_button fa fa-superscript formatting_button" aria-label="{{t 'LaTeX' }}" {{#unless preview_mode_on}} tabindex=0 {{/unless}} data-tippy-content="{{t 'LaTeX' }}"></a>
 | 
				
			||||||
    <div class="divider">|</div>
 | 
					    <div class="divider">|</div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1167,6 +1167,137 @@ run_test("format_text - quote", ({override}) => {
 | 
				
			|||||||
    assert.equal(wrap_selection_called, false);
 | 
					    assert.equal(wrap_selection_called, false);
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					run_test("format_text - spoiler", ({override}) => {
 | 
				
			||||||
 | 
					    override(text_field_edit, "set", (_field, text) => {
 | 
				
			||||||
 | 
					        set_text = text;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    override(text_field_edit, "wrapSelection", (_field, syntax_start, syntax_end) => {
 | 
				
			||||||
 | 
					        wrap_selection_called = true;
 | 
				
			||||||
 | 
					        wrap_syntax_start = syntax_start;
 | 
				
			||||||
 | 
					        wrap_syntax_end = syntax_end;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const spoiler_syntax_start_with_header = "```spoiler Header\n";
 | 
				
			||||||
 | 
					    const spoiler_syntax_end = "\n```";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Spoiler selected text
 | 
				
			||||||
 | 
					    reset_state();
 | 
				
			||||||
 | 
					    init_textarea("abc", {
 | 
				
			||||||
 | 
					        start: 0,
 | 
				
			||||||
 | 
					        end: 3,
 | 
				
			||||||
 | 
					        text: "abc",
 | 
				
			||||||
 | 
					        length: 3,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    compose_ui.format_text($textarea, "spoiler");
 | 
				
			||||||
 | 
					    assert.equal(set_text, "");
 | 
				
			||||||
 | 
					    assert.equal(wrap_selection_called, true);
 | 
				
			||||||
 | 
					    assert.equal(wrap_syntax_start, spoiler_syntax_start_with_header);
 | 
				
			||||||
 | 
					    assert.equal(wrap_syntax_end, spoiler_syntax_end);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Undo spoiler, header selected
 | 
				
			||||||
 | 
					    reset_state();
 | 
				
			||||||
 | 
					    init_textarea("```spoiler Header\nabc\n```", {
 | 
				
			||||||
 | 
					        start: 11,
 | 
				
			||||||
 | 
					        end: 17,
 | 
				
			||||||
 | 
					        text: "Header",
 | 
				
			||||||
 | 
					        length: 6,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    compose_ui.format_text($textarea, "spoiler");
 | 
				
			||||||
 | 
					    assert.equal(set_text, "Header\nabc");
 | 
				
			||||||
 | 
					    assert.equal(wrap_selection_called, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    reset_state();
 | 
				
			||||||
 | 
					    init_textarea("abc\n```spoiler \ndef\n```\nghi", {
 | 
				
			||||||
 | 
					        start: 15,
 | 
				
			||||||
 | 
					        end: 15,
 | 
				
			||||||
 | 
					        text: "",
 | 
				
			||||||
 | 
					        length: 0,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    compose_ui.format_text($textarea, "spoiler");
 | 
				
			||||||
 | 
					    assert.equal(set_text, "abc\ndef\nghi");
 | 
				
			||||||
 | 
					    assert.equal(wrap_selection_called, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Undo spoiler selected text, only content selected
 | 
				
			||||||
 | 
					    reset_state();
 | 
				
			||||||
 | 
					    init_textarea("```spoiler \nabc\n```", {
 | 
				
			||||||
 | 
					        start: 12,
 | 
				
			||||||
 | 
					        end: 15,
 | 
				
			||||||
 | 
					        text: "abc",
 | 
				
			||||||
 | 
					        length: 3,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    compose_ui.format_text($textarea, "spoiler");
 | 
				
			||||||
 | 
					    assert.equal(set_text, "abc");
 | 
				
			||||||
 | 
					    assert.equal(wrap_selection_called, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    reset_state();
 | 
				
			||||||
 | 
					    init_textarea("```spoiler abc\ndef\n```", {
 | 
				
			||||||
 | 
					        start: 15,
 | 
				
			||||||
 | 
					        end: 18,
 | 
				
			||||||
 | 
					        text: "def",
 | 
				
			||||||
 | 
					        length: 3,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    compose_ui.format_text($textarea, "spoiler");
 | 
				
			||||||
 | 
					    assert.equal(set_text, "abc\ndef");
 | 
				
			||||||
 | 
					    assert.equal(wrap_selection_called, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    reset_state();
 | 
				
			||||||
 | 
					    init_textarea("abc\n```spoiler d\nef\n```\nghi", {
 | 
				
			||||||
 | 
					        start: 17,
 | 
				
			||||||
 | 
					        end: 19,
 | 
				
			||||||
 | 
					        text: "ef",
 | 
				
			||||||
 | 
					        length: 2,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    compose_ui.format_text($textarea, "spoiler");
 | 
				
			||||||
 | 
					    assert.equal(set_text, "abc\nd\nef\nghi");
 | 
				
			||||||
 | 
					    assert.equal(wrap_selection_called, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Undo spoiler selected text, content and title selected
 | 
				
			||||||
 | 
					    reset_state();
 | 
				
			||||||
 | 
					    init_textarea("```spoiler abc\ndef\n```", {
 | 
				
			||||||
 | 
					        start: 11,
 | 
				
			||||||
 | 
					        end: 18,
 | 
				
			||||||
 | 
					        text: "abc\ndef",
 | 
				
			||||||
 | 
					        length: 7,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    compose_ui.format_text($textarea, "spoiler");
 | 
				
			||||||
 | 
					    assert.equal(set_text, "abc\ndef");
 | 
				
			||||||
 | 
					    assert.equal(wrap_selection_called, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    reset_state();
 | 
				
			||||||
 | 
					    init_textarea("abc\n```spoiler d\nef\n```\nghi", {
 | 
				
			||||||
 | 
					        start: 15,
 | 
				
			||||||
 | 
					        end: 19,
 | 
				
			||||||
 | 
					        text: "d\nef",
 | 
				
			||||||
 | 
					        length: 4,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    compose_ui.format_text($textarea, "spoiler");
 | 
				
			||||||
 | 
					    assert.equal(set_text, "abc\nd\nef\nghi");
 | 
				
			||||||
 | 
					    assert.equal(wrap_selection_called, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Undo spoiler selected text, syntax selected
 | 
				
			||||||
 | 
					    reset_state();
 | 
				
			||||||
 | 
					    init_textarea("```spoiler abc\ndef\n```", {
 | 
				
			||||||
 | 
					        start: 0,
 | 
				
			||||||
 | 
					        end: 22,
 | 
				
			||||||
 | 
					        text: "```spoiler abc\ndef\n```",
 | 
				
			||||||
 | 
					        length: 22,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    compose_ui.format_text($textarea, "spoiler");
 | 
				
			||||||
 | 
					    assert.equal(set_text, "abc\ndef");
 | 
				
			||||||
 | 
					    assert.equal(wrap_selection_called, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    reset_state();
 | 
				
			||||||
 | 
					    init_textarea("abc\n```spoiler d\nef\n```\nghi", {
 | 
				
			||||||
 | 
					        start: 4,
 | 
				
			||||||
 | 
					        end: 23,
 | 
				
			||||||
 | 
					        text: "```spoiler d\nef\n```",
 | 
				
			||||||
 | 
					        length: 19,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    compose_ui.format_text($textarea, "spoiler");
 | 
				
			||||||
 | 
					    assert.equal(set_text, "abc\nd\nef\nghi");
 | 
				
			||||||
 | 
					    assert.equal(wrap_selection_called, false);
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
run_test("markdown_shortcuts", ({override_rewire}) => {
 | 
					run_test("markdown_shortcuts", ({override_rewire}) => {
 | 
				
			||||||
    let format_text_type;
 | 
					    let format_text_type;
 | 
				
			||||||
    override_rewire(compose_ui, "format_text", (_$textarea, type) => {
 | 
					    override_rewire(compose_ui, "format_text", (_$textarea, type) => {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user