siyuan/app/src/protyle/toolbar/Link.ts

84 lines
3.2 KiB
TypeScript
Raw Normal View History

import {ToolbarItem} from "./ToolbarItem";
import {linkMenu} from "../../menus/protyle";
import {hasClosestBlock, hasClosestByAttribute} from "../util/hasClosest";
2022-09-27 00:13:11 +08:00
import {focusByRange, focusByWbr} from "../util/selection";
import {readText} from "../util/compatibility";
import {Constants} from "../../constants";
export class Link extends ToolbarItem {
public element: HTMLElement;
2023-06-01 20:50:49 +08:00
constructor(protyle: IProtyle, menuItem: IMenuItem) {
super(protyle, menuItem);
// 不能用 getEventName否则会导致光标位置变动到点击的文档中
this.element.addEventListener("click", async (event: MouseEvent & { changedTouches: MouseEvent[] }) => {
protyle.toolbar.element.classList.add("fn__none");
event.stopPropagation();
const range = protyle.toolbar.range;
const nodeElement = hasClosestBlock(range.startContainer);
if (!nodeElement) {
return;
}
const aElement = hasClosestByAttribute(range.startContainer, "data-type", "a");
if (aElement) {
2023-06-01 20:50:49 +08:00
linkMenu(protyle, aElement);
return;
}
const rangeString = range.toString().trim().replace(Constants.ZWSP, "");
let dataHref = "";
let dataText = "";
try {
const clipText = await readText();
// 选中链接时需忽略剪切板内容 https://ld246.com/article/1643035329737
if (protyle.lute.IsValidLinkDest(rangeString)) {
dataHref = rangeString;
} else if (protyle.lute.IsValidLinkDest(clipText)) {
dataHref = clipText;
} else {
// 360
2022-10-19 21:47:47 +08:00
const lastSpace = clipText.lastIndexOf(" ");
if (lastSpace > -1) {
if (protyle.lute.IsValidLinkDest(clipText.substring(lastSpace))) {
dataHref = clipText.substring(lastSpace);
dataText = clipText.substring(0, lastSpace);
}
}
}
} catch (e) {
console.log(e);
}
protyle.toolbar.setInlineMark(protyle, "a", "range", {
type: "a",
color: dataHref + (dataText ? Constants.ZWSP + dataText : "")
});
});
}
}
export const removeLink = (linkElement: HTMLElement, range?: Range) => {
const types = linkElement.getAttribute("data-type").split(" ");
if (types.length === 1) {
const linkParentElement = linkElement.parentElement;
linkElement.outerHTML = linkElement.innerHTML.replace(Constants.ZWSP, "") + "<wbr>";
if (range) {
focusByWbr(linkParentElement, range);
}
} else {
types.find((itemType, index) => {
if ("a" === itemType) {
types.splice(index, 1);
return true;
}
});
linkElement.setAttribute("data-type", types.join(" "));
linkElement.removeAttribute("data-href");
if (range) {
range.selectNodeContents(linkElement);
range.collapse(false);
focusByRange(range);
}
}
};