forked from Vanessa219/vditor
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
931d8c8
commit a8347b9
Showing
9 changed files
with
281 additions
and
232 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
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
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
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
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
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
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,255 @@ | ||
import {isCtrl} from "./compatibility"; | ||
import {scrollCenter} from "./editorCommenEvent"; | ||
import {hasClosestByMatchTag} from "./hasClosest"; | ||
import {matchHotKey} from "./hotKey"; | ||
import {setRangeByWbr} from "./selection"; | ||
|
||
// 光标设置到前一个表格中 | ||
const goPreviousCell = (cellElement: HTMLElement, range: Range, isSelected = true) => { | ||
let previousElement = cellElement.previousElementSibling; | ||
if (!previousElement) { | ||
if (cellElement.parentElement.previousElementSibling) { | ||
previousElement = cellElement.parentElement.previousElementSibling.lastElementChild; | ||
} else if (cellElement.parentElement.parentElement.tagName === "TBODY" && | ||
cellElement.parentElement.parentElement.previousElementSibling) { | ||
previousElement = cellElement.parentElement | ||
.parentElement.previousElementSibling.lastElementChild.lastElementChild; | ||
} else { | ||
previousElement = null; | ||
} | ||
} | ||
if (previousElement) { | ||
range.selectNodeContents(previousElement); | ||
if (!isSelected) { | ||
range.collapse(false); | ||
} | ||
} | ||
}; | ||
|
||
export const setTableAlign = (tableElement: HTMLTableElement, type: string) => { | ||
const cell = getSelection().getRangeAt(0).startContainer.parentElement; | ||
|
||
const columnCnt = tableElement.rows[0].cells.length; | ||
const rowCnt = tableElement.rows.length; | ||
let currentColumn = 0; | ||
|
||
for (let i = 0; i < rowCnt; i++) { | ||
for (let j = 0; j < columnCnt; j++) { | ||
if (tableElement.rows[i].cells[j].isEqualNode(cell)) { | ||
currentColumn = j; | ||
break; | ||
} | ||
} | ||
} | ||
for (let k = 0; k < rowCnt; k++) { | ||
tableElement.rows[k].cells[currentColumn].setAttribute("align", type); | ||
} | ||
}; | ||
|
||
export const tableHotkey = (vditor: IVditor, event: KeyboardEvent, range: Range, | ||
afterRenderEvent: (vditor: IVditor) => void) => { | ||
const startContainer = range.startContainer; | ||
const cellElement = hasClosestByMatchTag(startContainer, "TD") || | ||
hasClosestByMatchTag(startContainer, "TH"); | ||
if (cellElement) { | ||
// 换行或软换行:在 cell 中添加 br | ||
if (!isCtrl(event) && !event.altKey && event.key === "Enter") { | ||
if (!cellElement.lastElementChild || | ||
(cellElement.lastElementChild && (!cellElement.lastElementChild.isEqualNode(cellElement.lastChild) || | ||
cellElement.lastElementChild.tagName !== "BR"))) { | ||
cellElement.insertAdjacentHTML("beforeend", "<br>"); | ||
} | ||
const brElement = document.createElement("br"); | ||
range.insertNode(brElement); | ||
range.setStartAfter(brElement); | ||
afterRenderEvent(vditor); | ||
scrollCenter(vditor[vditor.currentMode].element); | ||
event.preventDefault(); | ||
return true; | ||
} | ||
|
||
// Backspace:光标移动到前一个 cell | ||
if (!isCtrl(event) && !event.shiftKey && !event.altKey && event.key === "Backspace" | ||
&& range.startOffset === 0 && range.toString() === "") { | ||
goPreviousCell(cellElement, range, false); | ||
event.preventDefault(); | ||
return true; | ||
} | ||
|
||
// tab:光标移向下一个 cell | ||
if (event.key === "Tab") { | ||
if (event.shiftKey) { | ||
// shift + tab 光标移动到前一个 cell | ||
goPreviousCell(cellElement, range); | ||
event.preventDefault(); | ||
return true; | ||
} | ||
|
||
let nextElement = cellElement.nextElementSibling; | ||
if (!nextElement) { | ||
if (cellElement.parentElement.nextElementSibling) { | ||
nextElement = cellElement.parentElement.nextElementSibling.firstElementChild; | ||
} else if (cellElement.parentElement.parentElement.tagName === "THEAD" && | ||
cellElement.parentElement.parentElement.nextElementSibling) { | ||
nextElement = | ||
cellElement.parentElement.parentElement.nextElementSibling.firstElementChild.firstElementChild; | ||
} else { | ||
nextElement = null; | ||
} | ||
} | ||
if (nextElement) { | ||
range.selectNodeContents(nextElement); | ||
} | ||
event.preventDefault(); | ||
return true; | ||
} | ||
|
||
// 删除当前行 | ||
if (cellElement.tagName === "TD" && matchHotKey("⌘--", event)) { | ||
const tbodyElement = cellElement.parentElement.parentElement; | ||
if (cellElement.parentElement.previousElementSibling) { | ||
range.selectNodeContents(cellElement.parentElement.previousElementSibling.lastElementChild); | ||
} else { | ||
range.selectNodeContents(tbodyElement.previousElementSibling.lastElementChild.lastElementChild); | ||
} | ||
|
||
if (tbodyElement.childElementCount === 1) { | ||
tbodyElement.remove(); | ||
} else { | ||
cellElement.parentElement.remove(); | ||
} | ||
|
||
range.collapse(false); | ||
event.preventDefault(); | ||
afterRenderEvent(vditor); | ||
return true; | ||
} | ||
|
||
// 下方新添加一行 https://github.com/Vanessa219/vditor/issues/46 | ||
if (matchHotKey("⌘-=", event)) { | ||
let rowHTML = ""; | ||
for (let m = 0; m < cellElement.parentElement.childElementCount; m++) { | ||
rowHTML += `<td>${m === 0 ? " <wbr>" : " "}</td>`; | ||
} | ||
if (cellElement.tagName === "TH") { | ||
cellElement.parentElement.parentElement.insertAdjacentHTML("afterend", | ||
`<tbody><tr>${rowHTML}</tr></tbody>`); | ||
} else { | ||
cellElement.parentElement.insertAdjacentHTML("afterend", `<tr>${rowHTML}</tr>`); | ||
} | ||
|
||
setRangeByWbr(vditor[vditor.currentMode].element, range); | ||
afterRenderEvent(vditor); | ||
scrollCenter(vditor[vditor.currentMode].element); | ||
event.preventDefault(); | ||
return true; | ||
} | ||
|
||
// 后方新添加一列 | ||
const tableElement = cellElement.parentElement.parentElement.parentElement as HTMLTableElement; | ||
if (matchHotKey("⌘-⇧-=", event)) { | ||
let index = 0; | ||
let previousElement = cellElement.previousElementSibling; | ||
while (previousElement) { | ||
index++; | ||
previousElement = previousElement.previousElementSibling; | ||
} | ||
for (let i = 0; i < tableElement.rows.length; i++) { | ||
if (i === 0) { | ||
tableElement.rows[i].cells[index].insertAdjacentHTML("afterend", "<th> </th>"); | ||
} else { | ||
tableElement.rows[i].cells[index].insertAdjacentHTML("afterend", "<td> </td>"); | ||
} | ||
} | ||
|
||
afterRenderEvent(vditor); | ||
event.preventDefault(); | ||
return true; | ||
} | ||
|
||
// 删除当前列 | ||
if (matchHotKey("⌘-⇧--", event)) { | ||
let index = 0; | ||
let previousElement = cellElement.previousElementSibling; | ||
while (previousElement) { | ||
index++; | ||
previousElement = previousElement.previousElementSibling; | ||
} | ||
if (cellElement.previousElementSibling || cellElement.nextElementSibling) { | ||
range.selectNodeContents(cellElement.previousElementSibling || cellElement.nextElementSibling); | ||
range.collapse(true); | ||
} | ||
for (let i = 0; i < tableElement.rows.length; i++) { | ||
if (tableElement.rows.length === 1) { | ||
tableElement.remove(); | ||
} else { | ||
tableElement.rows[i].cells[index].remove(); | ||
} | ||
} | ||
afterRenderEvent(vditor); | ||
event.preventDefault(); | ||
return true; | ||
} | ||
|
||
// 剧左 | ||
if (matchHotKey("⌘-⇧-L", event)) { | ||
if (vditor.currentMode === "ir") { | ||
setTableAlign(tableElement, "left"); | ||
afterRenderEvent(vditor); | ||
event.preventDefault(); | ||
return true; | ||
} else { | ||
const itemElement: HTMLElement = vditor.wysiwyg.popover.querySelector('[data-type="left"]'); | ||
if (itemElement) { | ||
itemElement.click(); | ||
event.preventDefault(); | ||
return true; | ||
} | ||
} | ||
} | ||
|
||
// 剧中 | ||
if (matchHotKey("⌘-⇧-C", event)) { | ||
if (vditor.currentMode === "ir") { | ||
setTableAlign(tableElement, "center"); | ||
afterRenderEvent(vditor); | ||
event.preventDefault(); | ||
return true; | ||
} else { | ||
const itemElement: HTMLElement = vditor.wysiwyg.popover.querySelector('[data-type="center"]'); | ||
if (itemElement) { | ||
itemElement.click(); | ||
event.preventDefault(); | ||
return true; | ||
} | ||
} | ||
} | ||
// 剧右 | ||
if (matchHotKey("⌘-⇧-R", event)) { | ||
if (vditor.currentMode === "ir") { | ||
setTableAlign(tableElement, "right"); | ||
afterRenderEvent(vditor); | ||
event.preventDefault(); | ||
return true; | ||
} else { | ||
const itemElement: HTMLElement = vditor.wysiwyg.popover.querySelector('[data-type="right"]'); | ||
if (itemElement) { | ||
itemElement.click(); | ||
event.preventDefault(); | ||
return true; | ||
} | ||
} | ||
} | ||
|
||
// focus row input | ||
if (vditor.currentMode === "wysiwyg" && | ||
!isCtrl(event) && event.key === "Enter" && !event.shiftKey && event.altKey) { | ||
const inputElement = (vditor.wysiwyg.popover.querySelector(".vditor-input") as HTMLInputElement); | ||
inputElement.focus(); | ||
inputElement.select(); | ||
event.preventDefault(); | ||
return true; | ||
} | ||
} | ||
return false; | ||
}; |
Oops, something went wrong.