Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: support tab in text Wyswig (#3411)
* fix: support tab in text Wyswig * Refactor tab handling Tab now indent the whole line, instead of inserting at the cursor position. Shift+Tab now deindent the whole line. * Add multi-line tabulation support * rename * simplify algo for selected lines start indices & naming tweaks * add cmd-bracket shortcuts as alias to indent/outdent * support outdenting partial tabs Co-authored-by: dwelle <luzar.david@gmail.com>
- Loading branch information
1 parent
d5a270f
commit e0a449a
Showing
2 changed files
with
280 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
import ReactDOM from "react-dom"; | ||
import ExcalidrawApp from "../excalidraw-app"; | ||
import { render } from "../tests/test-utils"; | ||
import { Pointer, UI } from "../tests/helpers/ui"; | ||
import { KEYS } from "../keys"; | ||
|
||
// Unmount ReactDOM from root | ||
ReactDOM.unmountComponentAtNode(document.getElementById("root")!); | ||
|
||
const tab = " "; | ||
|
||
describe("textWysiwyg", () => { | ||
let textarea: HTMLTextAreaElement; | ||
beforeEach(async () => { | ||
await render(<ExcalidrawApp />); | ||
|
||
const element = UI.createElement("text"); | ||
|
||
new Pointer("mouse").clickOn(element); | ||
textarea = document.querySelector( | ||
".excalidraw-textEditorContainer > textarea", | ||
)!; | ||
}); | ||
|
||
it("should add a tab at the start of the first line", () => { | ||
const event = new KeyboardEvent("keydown", { key: KEYS.TAB }); | ||
textarea.value = "Line#1\nLine#2"; | ||
// cursor: "|Line#1\nLine#2" | ||
textarea.selectionStart = 0; | ||
textarea.selectionEnd = 0; | ||
textarea.dispatchEvent(event); | ||
|
||
expect(textarea.value).toEqual(`${tab}Line#1\nLine#2`); | ||
// cursor: " |Line#1\nLine#2" | ||
expect(textarea.selectionStart).toEqual(4); | ||
expect(textarea.selectionEnd).toEqual(4); | ||
}); | ||
|
||
it("should add a tab at the start of the second line", () => { | ||
const event = new KeyboardEvent("keydown", { key: KEYS.TAB }); | ||
textarea.value = "Line#1\nLine#2"; | ||
// cursor: "Line#1\nLin|e#2" | ||
textarea.selectionStart = 10; | ||
textarea.selectionEnd = 10; | ||
|
||
textarea.dispatchEvent(event); | ||
|
||
expect(textarea.value).toEqual(`Line#1\n${tab}Line#2`); | ||
|
||
// cursor: "Line#1\n Lin|e#2" | ||
expect(textarea.selectionStart).toEqual(14); | ||
expect(textarea.selectionEnd).toEqual(14); | ||
}); | ||
|
||
it("should add a tab at the start of the first and second line", () => { | ||
const event = new KeyboardEvent("keydown", { key: KEYS.TAB }); | ||
textarea.value = "Line#1\nLine#2\nLine#3"; | ||
// cursor: "Li|ne#1\nLi|ne#2\nLine#3" | ||
textarea.selectionStart = 2; | ||
textarea.selectionEnd = 9; | ||
|
||
textarea.dispatchEvent(event); | ||
|
||
expect(textarea.value).toEqual(`${tab}Line#1\n${tab}Line#2\nLine#3`); | ||
|
||
// cursor: " Li|ne#1\n Li|ne#2\nLine#3" | ||
expect(textarea.selectionStart).toEqual(6); | ||
expect(textarea.selectionEnd).toEqual(17); | ||
}); | ||
|
||
it("should remove a tab at the start of the first line", () => { | ||
const event = new KeyboardEvent("keydown", { | ||
key: KEYS.TAB, | ||
shiftKey: true, | ||
}); | ||
textarea.value = `${tab}Line#1\nLine#2`; | ||
// cursor: "| Line#1\nLine#2" | ||
textarea.selectionStart = 0; | ||
textarea.selectionEnd = 0; | ||
|
||
textarea.dispatchEvent(event); | ||
|
||
expect(textarea.value).toEqual(`Line#1\nLine#2`); | ||
|
||
// cursor: "|Line#1\nLine#2" | ||
expect(textarea.selectionStart).toEqual(0); | ||
expect(textarea.selectionEnd).toEqual(0); | ||
}); | ||
|
||
it("should remove a tab at the start of the second line", () => { | ||
const event = new KeyboardEvent("keydown", { | ||
key: KEYS.TAB, | ||
shiftKey: true, | ||
}); | ||
// cursor: "Line#1\n Lin|e#2" | ||
textarea.value = `Line#1\n${tab}Line#2`; | ||
textarea.selectionStart = 15; | ||
textarea.selectionEnd = 15; | ||
|
||
textarea.dispatchEvent(event); | ||
|
||
expect(textarea.value).toEqual(`Line#1\nLine#2`); | ||
// cursor: "Line#1\nLin|e#2" | ||
expect(textarea.selectionStart).toEqual(11); | ||
expect(textarea.selectionEnd).toEqual(11); | ||
}); | ||
|
||
it("should remove a tab at the start of the first and second line", () => { | ||
const event = new KeyboardEvent("keydown", { | ||
key: KEYS.TAB, | ||
shiftKey: true, | ||
}); | ||
// cursor: " Li|ne#1\n Li|ne#2\nLine#3" | ||
textarea.value = `${tab}Line#1\n${tab}Line#2\nLine#3`; | ||
textarea.selectionStart = 6; | ||
textarea.selectionEnd = 17; | ||
|
||
textarea.dispatchEvent(event); | ||
|
||
expect(textarea.value).toEqual(`Line#1\nLine#2\nLine#3`); | ||
// cursor: "Li|ne#1\nLi|ne#2\nLine#3" | ||
expect(textarea.selectionStart).toEqual(2); | ||
expect(textarea.selectionEnd).toEqual(9); | ||
}); | ||
|
||
it("should remove a tab at the start of the second line and cursor stay on this line", () => { | ||
const event = new KeyboardEvent("keydown", { | ||
key: KEYS.TAB, | ||
shiftKey: true, | ||
}); | ||
// cursor: "Line#1\n | Line#2" | ||
textarea.value = `Line#1\n${tab}Line#2`; | ||
textarea.selectionStart = 9; | ||
textarea.selectionEnd = 9; | ||
textarea.dispatchEvent(event); | ||
|
||
// cursor: "Line#1\n|Line#2" | ||
expect(textarea.selectionStart).toEqual(7); | ||
// expect(textarea.selectionEnd).toEqual(7); | ||
}); | ||
|
||
it("should remove partial tabs", () => { | ||
const event = new KeyboardEvent("keydown", { | ||
key: KEYS.TAB, | ||
shiftKey: true, | ||
}); | ||
// cursor: "Line#1\n Line#|2" | ||
textarea.value = `Line#1\n Line#2`; | ||
textarea.selectionStart = 15; | ||
textarea.selectionEnd = 15; | ||
textarea.dispatchEvent(event); | ||
|
||
expect(textarea.value).toEqual(`Line#1\nLine#2`); | ||
}); | ||
|
||
it("should remove nothing", () => { | ||
const event = new KeyboardEvent("keydown", { | ||
key: KEYS.TAB, | ||
shiftKey: true, | ||
}); | ||
// cursor: "Line#1\n Li|ne#2" | ||
textarea.value = `Line#1\nLine#2`; | ||
textarea.selectionStart = 9; | ||
textarea.selectionEnd = 9; | ||
textarea.dispatchEvent(event); | ||
|
||
expect(textarea.value).toEqual(`Line#1\nLine#2`); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
e0a449a
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs: