🐛 table cell 三击/ctrl+k

This commit is contained in:
Vanessa 2022-09-19 16:47:38 +08:00
parent 1fedca6929
commit c0c795c214
8 changed files with 51 additions and 57 deletions

View file

@ -1,5 +1,6 @@
import {ToolbarItem} from "./ToolbarItem";
import {hintRef} from "../hint/extend";
import {fixTableRange} from "../util/selection";
export class BlockRef extends ToolbarItem {
public element: HTMLElement;
@ -8,6 +9,7 @@ export class BlockRef extends ToolbarItem {
super(protyle, menuItem);
// 不能用 getEventName否则会导致光标位置变动到点击的文档中
this.element.addEventListener("click", (event: MouseEvent & { changedTouches: MouseEvent[] }) => {
fixTableRange(protyle.toolbar.range);
hintRef(protyle.toolbar.range.toString(), protyle, true);
protyle.toolbar.element.classList.add("fn__none");
event.stopPropagation();

View file

@ -4,6 +4,7 @@ import {updateTransaction} from "../wysiwyg/transaction";
import {hasClosestBlock} from "../util/hasClosest";
import {hasNextSibling, hasPreviousSibling} from "../wysiwyg/getBlock";
import {mathRender} from "../markdown/mathRender";
import {fixTableRange} from "../util/selection";
export class InlineMath extends ToolbarItem {
public element: HTMLElement;
@ -19,10 +20,11 @@ export class InlineMath extends ToolbarItem {
if (!nodeElement) {
return;
}
if (!["DIV", "TD", "TH"].includes(range.startContainer.parentElement.tagName) && range.startOffset === 0 && !hasPreviousSibling(range.startContainer)) {
fixTableRange(range);
if (!["DIV", "TD", "TH", "TR"].includes(range.startContainer.parentElement.tagName) && range.startOffset === 0 && !hasPreviousSibling(range.startContainer)) {
range.setStartBefore(range.startContainer.parentElement);
}
if (!["DIV", "TD", "TH"].includes(range.endContainer.parentElement.tagName) && range.endOffset === range.endContainer.textContent.length && !hasNextSibling(range.endContainer)) {
if (!["DIV", "TD", "TH", "TR"].includes(range.endContainer.parentElement.tagName) && range.endOffset === range.endContainer.textContent.length && !hasNextSibling(range.endContainer)) {
range.setEndAfter(range.endContainer.parentElement);
}
const wbrElement = document.createElement("wbr");

View file

@ -3,6 +3,7 @@ import * as dayjs from "dayjs";
import {updateTransaction} from "../wysiwyg/transaction";
import {hasClosestBlock, hasClosestByAttribute} from "../util/hasClosest";
import {hasNextSibling, hasPreviousSibling} from "../wysiwyg/getBlock";
import {fixTableRange} from "../util/selection";
export class InlineMemo extends ToolbarItem {
public element: HTMLElement;
@ -28,10 +29,12 @@ export class InlineMemo extends ToolbarItem {
return;
}
if (!["DIV", "TD", "TH"].includes(range.startContainer.parentElement.tagName) && range.startOffset === 0 && !hasPreviousSibling(range.startContainer)) {
fixTableRange(range);
if (!["DIV", "TD", "TH", "TR"].includes(range.startContainer.parentElement.tagName) && range.startOffset === 0 && !hasPreviousSibling(range.startContainer)) {
range.setStartBefore(range.startContainer.parentElement);
}
if (!["DIV", "TD", "TH"].includes(range.endContainer.parentElement.tagName) && range.endOffset === range.endContainer.textContent.length && !hasNextSibling(range.endContainer)) {
if (!["DIV", "TD", "TH", "TR"].includes(range.endContainer.parentElement.tagName) && range.endOffset === range.endContainer.textContent.length && !hasNextSibling(range.endContainer)) {
range.setEndAfter(range.endContainer.parentElement);
}
const wbrElement = document.createElement("wbr");

View file

@ -5,7 +5,7 @@ import * as dayjs from "dayjs";
import {updateTransaction} from "../wysiwyg/transaction";
import {hasClosestBlock, hasClosestByAttribute} from "../util/hasClosest";
import {hasNextSibling, hasPreviousSibling} from "../wysiwyg/getBlock";
import {focusByRange, focusByWbr} from "../util/selection";
import {fixTableRange, focusByRange, focusByWbr} from "../util/selection";
export class Link extends ToolbarItem {
public element: HTMLElement;
@ -28,10 +28,12 @@ export class Link extends ToolbarItem {
return;
}
if (!["DIV", "TD", "TH"].includes(range.startContainer.parentElement.tagName) && range.startOffset === 0 && !hasPreviousSibling(range.startContainer)) {
fixTableRange(range);
if (!["DIV", "TD", "TH", "TR"].includes(range.startContainer.parentElement.tagName) && range.startOffset === 0 && !hasPreviousSibling(range.startContainer)) {
range.setStartBefore(range.startContainer.parentElement);
}
if (!["DIV", "TD", "TH"].includes(range.endContainer.parentElement.tagName) && range.endOffset === range.endContainer.textContent.length && !hasNextSibling(range.endContainer)) {
if (!["DIV", "TD", "TH", "TR"].includes(range.endContainer.parentElement.tagName) && range.endOffset === range.endContainer.textContent.length && !hasNextSibling(range.endContainer)) {
range.setEndAfter(range.endContainer.parentElement);
}
const wbrElement = document.createElement("wbr");
@ -40,6 +42,7 @@ export class Link extends ToolbarItem {
const newElement = document.createElement("span");
newElement.setAttribute("data-type", "a");
newElement.setAttribute("data-href", "");
const rangeString = range.toString();
newElement.textContent = rangeString;
range.extractContents();

View file

@ -2,6 +2,7 @@ import {Divider} from "./Divider";
import {Font, hasSameTextStyle, setFontStyle} from "./Font";
import {ToolbarItem} from "./ToolbarItem";
import {
fixTableRange,
focusByRange,
focusByWbr,
focusSideBlock,
@ -244,34 +245,7 @@ export class Toolbar {
}
const rangeTypes = this.getCurrentType(this.range);
const selectText = this.range.toString();
// table 选中处理
const tableElement = hasClosestByAttribute(this.range.startContainer, "data-type", "NodeTable");
if (selectText !== "" && tableElement && this.range.commonAncestorContainer.nodeType !== 3) {
const parentTag = (this.range.commonAncestorContainer as Element).tagName;
if (parentTag !== "TH" && parentTag !== "TD") {
const startCellElement = hasClosestByMatchTag(this.range.startContainer, "TD") || hasClosestByMatchTag(this.range.startContainer, "TH");
const endCellElement = hasClosestByMatchTag(this.range.endContainer, "TD") || hasClosestByMatchTag(this.range.endContainer, "TH");
if (!startCellElement && !endCellElement) {
const cellElement = tableElement.querySelector("th") || tableElement.querySelector("td");
this.range.setStartBefore(cellElement.firstChild);
this.range.setEndAfter(cellElement.lastChild);
} else if (startCellElement &&
// 不能包含自身元素,否则对 cell 中的部分文字两次高亮后就会选中整个 cell。 https://github.com/siyuan-note/siyuan/issues/3649 第二点
!startCellElement.contains(this.range.endContainer)) {
const cloneRange = this.range.cloneRange();
this.range.setEndAfter(startCellElement.lastChild);
if (this.range.toString() === "" && endCellElement) {
this.range.setEnd(cloneRange.endContainer, cloneRange.endOffset);
this.range.setStartBefore(endCellElement.lastChild);
}
if (this.range.toString() === "") {
return;
}
}
}
}
fixTableRange(this.range);
let previousElement: HTMLElement;
let nextElement: HTMLElement;
let previousIndex: number;

View file

@ -3,7 +3,7 @@ import * as dayjs from "dayjs";
import {removeEmbed} from "../wysiwyg/removeEmbed";
import {transaction, updateTransaction} from "../wysiwyg/transaction";
import {getContenteditableElement} from "../wysiwyg/getBlock";
import {focusBlock, getEditorRange, focusByWbr} from "./selection";
import {focusBlock, getEditorRange, focusByWbr, fixTableRange} from "./selection";
import {mathRender} from "../markdown/mathRender";
import {Constants} from "../../constants";
@ -12,24 +12,8 @@ export const insertHTML = (html: string, protyle: IProtyle, isBlock = false, spl
return;
}
const range = getEditorRange(protyle.wysiwyg.element);
// table 选中处理 https://ld246.com/article/1624269001599
const tableElement = hasClosestByAttribute(range.startContainer, "data-type", "NodeTable");
if (range.toString() !== "" && tableElement && range.commonAncestorContainer.nodeType !== 3) {
const parentTag = (range.commonAncestorContainer as Element).tagName;
if (parentTag !== "TH" && parentTag !== "TD") {
let cellElement = hasClosestByMatchTag(range.startContainer, "TD") || hasClosestByMatchTag(range.startContainer, "TH");
if (!cellElement) {
cellElement = tableElement.querySelector("th") || tableElement.querySelector("td");
range.setStartBefore(cellElement.firstChild);
}
if (cellElement.lastChild) {
range.setEndAfter(cellElement.lastChild);
} else {
range.collapse(true);
}
}
}
if (tableElement && !isBlock) {
fixTableRange(range);
if (hasClosestByAttribute(range.startContainer, "data-type", "NodeTable") && !isBlock) {
html = protyle.lute.BlockDOM2InlineBlockDOM(html);
}
let blockElement = hasClosestBlock(range.startContainer) as Element;

View file

@ -5,7 +5,7 @@ import {
hasPreviousSibling,
isNotEditBlock
} from "../wysiwyg/getBlock";
import {hasClosestByMatchTag} from "./hasClosest";
import {hasClosestByAttribute, hasClosestByMatchTag} from "./hasClosest";
import {countBlockWord, countSelectWord} from "../../layout/status";
const selectIsEditor = (editor: Element, range?: Range) => {
@ -21,6 +21,32 @@ const selectIsEditor = (editor: Element, range?: Range) => {
return editor.isEqualNode(container) || editor.contains(container);
};
// table 选中处理
export const fixTableRange = (range:Range) => {
const tableElement = hasClosestByAttribute(range.startContainer, "data-type", "NodeTable");
if (range.toString() !== "" && tableElement && range.commonAncestorContainer.nodeType !== 3) {
const parentTag = (range.commonAncestorContainer as Element).tagName;
if (parentTag !== "TH" && parentTag !== "TD") {
const startCellElement = hasClosestByMatchTag(range.startContainer, "TD") || hasClosestByMatchTag(range.startContainer, "TH");
const endCellElement = hasClosestByMatchTag(range.endContainer, "TD") || hasClosestByMatchTag(range.endContainer, "TH");
if (!startCellElement && !endCellElement) {
const cellElement = tableElement.querySelector("th") || tableElement.querySelector("td");
range.setStart(cellElement.firstChild, 0);
range.setEnd(cellElement.lastChild, cellElement.lastChild.textContent.length);
} else if (startCellElement &&
// 不能包含自身元素,否则对 cell 中的部分文字两次高亮后就会选中整个 cell。 https://github.com/siyuan-note/siyuan/issues/3649 第二点
!startCellElement.contains(range.endContainer)) {
const cloneRange = range.cloneRange();
range.setEnd(startCellElement.lastChild, startCellElement.lastChild.textContent.length);
if (range.toString() === "" && endCellElement) {
range.setStart(endCellElement.firstChild, 0);
range.setEnd(cloneRange.endContainer, cloneRange.endOffset);
}
}
}
}
}
export const selectAll = (protyle: IProtyle, nodeElement: Element, range: Range) => {
const editElement = getContenteditableElement(nodeElement);
if (editElement) {

View file

@ -225,7 +225,7 @@ export class WYSIWYG {
if (range.startContainer.parentElement.parentElement.getAttribute("data-type") === "NodeHeading") {
// 复制标题 https://github.com/siyuan-note/insider/issues/297
tempElement.append(range.startContainer.parentElement.parentElement.cloneNode(true));
} else if (!["DIV", "TD", "TH"].includes(range.startContainer.parentElement.tagName)) {
} else if (!["DIV", "TD", "TH", "TR"].includes(range.startContainer.parentElement.tagName)) {
// 复制行内元素 https://github.com/siyuan-note/insider/issues/191
tempElement.append(range.startContainer.parentElement.cloneNode(true));
} else {
@ -986,7 +986,7 @@ export class WYSIWYG {
transaction(protyle, doOperations, undoOperations);
} else if (range.toString() !== "" && startContainer.isSameNode(range.endContainer) && range.startContainer.nodeType === 3
&& range.endOffset === range.endContainer.textContent.length && range.startOffset === 0 &&
!["DIV", "TD", "TH"].includes(range.startContainer.parentElement.tagName)) {
!["DIV", "TD", "TH", "TR"].includes(range.startContainer.parentElement.tagName)) {
// 选中整个内联元素
tempElement.append(range.startContainer.parentElement);
} else if (selectImgElement) {