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