mirror of https://github.com/zulip/zulip.git
compose: Refactor and generalise functions for formatting.
The logic for formatting code is generalised to make it reusable for multiple styles of formatting (added in the next commits). Co-authored-by: N-Shar-ma <bablinaneh@gmail.com>
This commit is contained in:
parent
e24689a1ce
commit
5817da709c
|
@ -377,19 +377,18 @@ export function format_text($textarea, type, inserted_content) {
|
|||
range = $textarea.range();
|
||||
const selected_text = range.text;
|
||||
|
||||
const is_selection_formatted = (syntax) =>
|
||||
// First check if there are enough characters before/after selection.
|
||||
range.start >= syntax.length &&
|
||||
text.length - range.end >= syntax.length &&
|
||||
// And then if the characters have syntax around them.
|
||||
text.slice(range.start - syntax.length, range.start) === syntax &&
|
||||
text.slice(range.end, range.end + syntax.length) === syntax;
|
||||
// Check if the selection is already surrounded by syntax
|
||||
const is_selection_formatted = (syntax_start, syntax_end = syntax_start) =>
|
||||
range.start >= syntax_start.length &&
|
||||
text.length - range.end >= syntax_end.length &&
|
||||
text.slice(range.start - syntax_start.length, range.start) === syntax_start &&
|
||||
text.slice(range.end, range.end + syntax_end.length) === syntax_end;
|
||||
|
||||
const is_inner_text_formatted = (syntax) =>
|
||||
// Check if selected text itself has bold_syntax inside it.
|
||||
range.length > 4 &&
|
||||
selected_text.slice(0, syntax.length) === syntax &&
|
||||
selected_text.slice(-syntax.length) === syntax;
|
||||
// Check if selected text itself has syntax inside it.
|
||||
const is_inner_text_formatted = (syntax_start, syntax_end = syntax_start) =>
|
||||
range.length >= syntax_start.length + syntax_end.length &&
|
||||
selected_text.slice(0, syntax_start.length) === syntax_start &&
|
||||
selected_text.slice(-syntax_end.length) === syntax_end;
|
||||
|
||||
const section_off_selected_lines = () => {
|
||||
// Divide all lines of text (separated by `\n`) into those entirely or
|
||||
|
@ -505,31 +504,46 @@ export function format_text($textarea, type, inserted_content) {
|
|||
}
|
||||
};
|
||||
|
||||
const format = (syntax) => {
|
||||
// If the selection is already surrounded by syntax,
|
||||
// remove it rather than adding another copy.
|
||||
if (is_selection_formatted(syntax)) {
|
||||
// Remove the syntax from text.
|
||||
const format = (syntax_start, syntax_end = syntax_start) => {
|
||||
let linebreak_start = "";
|
||||
let linebreak_end = "";
|
||||
if (syntax_start[0] === "\n") {
|
||||
linebreak_start = "\n";
|
||||
}
|
||||
if (syntax_end.at(-1) === "\n") {
|
||||
linebreak_end = "\n";
|
||||
}
|
||||
if (is_selection_formatted(syntax_start, syntax_end)) {
|
||||
text =
|
||||
text.slice(0, range.start - syntax.length) +
|
||||
text.slice(0, range.start - syntax_start.length) +
|
||||
linebreak_start +
|
||||
text.slice(range.start, range.end) +
|
||||
text.slice(range.end + syntax.length);
|
||||
linebreak_end +
|
||||
text.slice(range.end + syntax_end.length);
|
||||
set(field, text);
|
||||
field.setSelectionRange(range.start - syntax.length, range.end - syntax.length);
|
||||
field.setSelectionRange(
|
||||
range.start - syntax_start.length,
|
||||
range.end - syntax_start.length,
|
||||
);
|
||||
return;
|
||||
} else if (is_inner_text_formatted(syntax)) {
|
||||
} else if (is_inner_text_formatted(syntax_start, syntax_end)) {
|
||||
// Remove syntax inside the selection, if present.
|
||||
text =
|
||||
text.slice(0, range.start) +
|
||||
text.slice(range.start + syntax.length, range.end - syntax.length) +
|
||||
linebreak_start +
|
||||
text.slice(range.start + syntax_start.length, range.end - syntax_end.length) +
|
||||
linebreak_end +
|
||||
text.slice(range.end);
|
||||
set(field, text);
|
||||
field.setSelectionRange(range.start, range.end - syntax.length * 2);
|
||||
field.setSelectionRange(
|
||||
range.start,
|
||||
range.end - syntax_start.length - syntax_end.length,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, we don't have syntax, so we add it.
|
||||
wrapSelection(field, syntax);
|
||||
|
||||
// Otherwise, we don't have syntax within or around, so we add it.
|
||||
wrapSelection(field, syntax_start, syntax_end);
|
||||
};
|
||||
|
||||
switch (type) {
|
||||
|
@ -555,7 +569,7 @@ export function format_text($textarea, type, inserted_content) {
|
|||
if (is_selection_formatted(bold_syntax)) {
|
||||
// If text has bold_syntax around it.
|
||||
if (
|
||||
range.start >= 3 &&
|
||||
range.start > bold_syntax.length &&
|
||||
text.length - range.end >= bold_and_italic_syntax.length
|
||||
) {
|
||||
// If text is both bold and italic.
|
||||
|
|
|
@ -485,42 +485,45 @@ run_test("test_compose_height_changes", ({override, override_rewire}) => {
|
|||
assert.ok(!compose_box_top_set);
|
||||
});
|
||||
|
||||
run_test("format_text", ({override}) => {
|
||||
let set_text = "";
|
||||
let wrap_selection_called = false;
|
||||
let wrap_syntax = "";
|
||||
let set_text = "";
|
||||
let wrap_selection_called = false;
|
||||
let wrap_syntax_start = "";
|
||||
let wrap_syntax_end = "";
|
||||
|
||||
function reset_state() {
|
||||
set_text = "";
|
||||
wrap_selection_called = false;
|
||||
wrap_syntax_start = "";
|
||||
wrap_syntax_end = "";
|
||||
}
|
||||
|
||||
const $textarea = $("#compose-textarea");
|
||||
$textarea.get = () => ({
|
||||
setSelectionRange(start, end) {
|
||||
$textarea.range = () => ({
|
||||
start,
|
||||
end,
|
||||
text: $textarea.val().slice(start, end),
|
||||
length: end - start,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
function init_textarea(val, range) {
|
||||
$textarea.val = () => val;
|
||||
$textarea.range = () => range;
|
||||
}
|
||||
|
||||
run_test("format_text - bold and italic", ({override}) => {
|
||||
override(text_field_edit, "set", (_field, text) => {
|
||||
set_text = text;
|
||||
});
|
||||
override(text_field_edit, "wrapSelection", (_field, syntax) => {
|
||||
override(text_field_edit, "wrapSelection", (_field, syntax_start, syntax_end) => {
|
||||
wrap_selection_called = true;
|
||||
wrap_syntax = syntax;
|
||||
wrap_syntax_start = syntax_start;
|
||||
wrap_syntax_end = syntax_end || syntax_start;
|
||||
});
|
||||
|
||||
function reset_state() {
|
||||
set_text = "";
|
||||
wrap_selection_called = false;
|
||||
wrap_syntax = "";
|
||||
}
|
||||
|
||||
const $textarea = $("#compose-textarea");
|
||||
$textarea.get = () => ({
|
||||
setSelectionRange(start, end) {
|
||||
$textarea.range = () => ({
|
||||
start,
|
||||
end,
|
||||
text: $textarea.val().slice(start, end),
|
||||
length: end - start,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
function init_textarea(val, range) {
|
||||
$textarea.val = () => val;
|
||||
$textarea.range = () => range;
|
||||
}
|
||||
|
||||
const italic_syntax = "*";
|
||||
const bold_syntax = "**";
|
||||
|
||||
|
@ -535,7 +538,8 @@ run_test("format_text", ({override}) => {
|
|||
compose_ui.format_text($textarea, "bold");
|
||||
assert.equal(set_text, "");
|
||||
assert.equal(wrap_selection_called, true);
|
||||
assert.equal(wrap_syntax, bold_syntax);
|
||||
assert.equal(wrap_syntax_start, bold_syntax);
|
||||
assert.equal(wrap_syntax_end, bold_syntax);
|
||||
|
||||
// Undo bold selected text, syntax not selected
|
||||
reset_state();
|
||||
|
@ -572,7 +576,8 @@ run_test("format_text", ({override}) => {
|
|||
compose_ui.format_text($textarea, "italic");
|
||||
assert.equal(set_text, "");
|
||||
assert.equal(wrap_selection_called, true);
|
||||
assert.equal(wrap_syntax, italic_syntax);
|
||||
assert.equal(wrap_syntax_start, italic_syntax);
|
||||
assert.equal(wrap_syntax_end, italic_syntax);
|
||||
|
||||
// Undo italic selected text, syntax not selected
|
||||
reset_state();
|
||||
|
|
Loading…
Reference in New Issue