Vanessa 2023-12-20 22:23:30 +08:00
parent aa2f05dcb5
commit 520c2aec7d
6 changed files with 63 additions and 85 deletions

View file

@ -68,22 +68,6 @@
font-size: 87.5%;
}
&__gutters {
@extend .protyle-gutters;
top: 0;
left: -44px;
opacity: 0;
display: flex;
&--min .av__gutter {
padding: 4px 0;
}
svg {
height: 25px;
}
}
&__mask {
position: fixed;
top: 0;
@ -114,14 +98,8 @@
box-shadow: 0 -3px 0 var(--b3-theme-primary-lighter), inset 0 2px 0 var(--b3-theme-primary-lighter) !important;
}
&:hover {
[data-type="block-more"] {
display: block;
}
.av__gutters {
opacity: 1;
}
&:hover [data-type="block-more"] {
display: block;
}
&--select {

View file

@ -89,11 +89,15 @@ export const windowMouseMove = (event: MouseEvent & { target: HTMLElement }, mou
if (!targetBlockElement) {
return;
}
let rowElement: Element;
if (targetBlockElement.classList.contains("av")) {
rowElement = hasClosestByClassName(mouseElement, "av__row") as HTMLElement;
}
const allModels = getAllModels();
let findNode = false;
allModels.editor.find(item => {
if (item.editor.protyle.wysiwyg.element.isSameNode(eventPath0)) {
item.editor.protyle.gutter.render(item.editor.protyle, targetBlockElement, item.editor.protyle.wysiwyg.element);
item.editor.protyle.gutter.render(item.editor.protyle, targetBlockElement, item.editor.protyle.wysiwyg.element, rowElement);
findNode = true;
return true;
}
@ -102,7 +106,7 @@ export const windowMouseMove = (event: MouseEvent & { target: HTMLElement }, mou
window.siyuan.blockPanels.find(item => {
item.editors.find(eItem => {
if (eItem.protyle.wysiwyg.element.contains(eventPath0)) {
eItem.protyle.gutter.render(eItem.protyle, targetBlockElement, eItem.protyle.wysiwyg.element);
eItem.protyle.gutter.render(eItem.protyle, targetBlockElement, eItem.protyle.wysiwyg.element, rowElement);
findNode = true;
return true;
}
@ -116,7 +120,7 @@ export const windowMouseMove = (event: MouseEvent & { target: HTMLElement }, mou
allModels.backlink.find(item => {
item.editors.find(eItem => {
if (eItem.protyle.wysiwyg.element.isSameNode(eventPath0)) {
eItem.protyle.gutter.render(eItem.protyle, targetBlockElement, eItem.protyle.wysiwyg.element);
eItem.protyle.gutter.render(eItem.protyle, targetBlockElement, eItem.protyle.wysiwyg.element, rowElement);
findNode = true;
return true;
}

View file

@ -44,6 +44,8 @@ import {appearanceMenu} from "../toolbar/Font";
import {setPosition} from "../../util/setPosition";
import {avRender} from "../render/av/render";
import {emitOpenMenu} from "../../plugin/EventBus";
import {insertAttrViewBlockAnimation} from "../render/av/row";
import {avContextmenu} from "../render/av/action";
export class Gutter {
public element: HTMLElement;
@ -183,6 +185,43 @@ export class Gutter {
window.siyuan.menus.menu.remove();
return;
}
if (buttonElement.dataset.type === "NodeAttributeViewRowMenu" || buttonElement.dataset.type === "NodeAttributeViewRow") {
const rowElement = protyle.wysiwyg.element.querySelector(`.av__row[data-id="${buttonElement.dataset.nodeId}"]`) as HTMLElement;
if (!rowElement) {
return;
}
const blockElement = hasClosestBlock(rowElement)
if (!blockElement) {
return;
}
blockElement.querySelector(".av__cell--select")?.classList.remove("av__cell--select");
if (buttonElement.dataset.type === "NodeAttributeViewRow") {
const avID = blockElement.getAttribute("data-av-id");
const srcIDs = [Lute.NewNodeID()];
const previousID = event.altKey ? (rowElement.previousElementSibling.getAttribute("data-id") || "") : buttonElement.dataset.nodeId;
transaction(protyle, [{
action: "insertAttrViewBlock",
avID,
previousID,
srcIDs,
isDetached: true,
}], [{
action: "removeAttrViewBlock",
srcIDs,
avID,
}]);
insertAttrViewBlockAnimation(blockElement, srcIDs, previousID, avID);
} else {
const gutterRect = buttonElement.getBoundingClientRect();
avContextmenu(protyle, rowElement, {
x: gutterRect.left,
y: gutterRect.bottom,
w: gutterRect.width,
h: gutterRect.height
});
}
return;
}
if (isOnlyMeta(event)) {
zoomOut({protyle, id});
} else if (event.altKey) {
@ -1805,7 +1844,7 @@ export class Gutter {
};
}
public render(protyle: IProtyle, element: Element, wysiwyg: HTMLElement) {
public render(protyle: IProtyle, element: Element, wysiwyg: HTMLElement, target?: Element) {
// https://github.com/siyuan-note/siyuan/issues/4659
const titleElement = wysiwyg.parentElement.querySelector(".protyle-title__input");
if (titleElement && titleElement.getAttribute("data-render") !== "true") {
@ -1830,6 +1869,15 @@ export class Gutter {
if (isShow) {
type = nodeElement.getAttribute("data-type");
}
if (type === "NodeAttributeView" && target) {
const rowElement = hasClosestByClassName(target, "av__row");
if (rowElement && !rowElement.classList.contains("av__row--header")) {
element = rowElement;
html = `<button data-type="NodeAttributeViewRow" data-node-id="${rowElement.dataset.id}" class="ariaLabel" data-position="right" aria-label="${isMac() ? window.siyuan.languages.addBelowAbove : window.siyuan.languages.addBelowAbove.replace("⌥", "Alt+")}"><svg><use xlink:href="#iconAdd"></use></svg></button>
<button data-type="NodeAttributeViewRowMenu" data-node-id="${rowElement.dataset.id}" class="ariaLabel" data-position="right" aria-label="${window.siyuan.languages.rowTip}"><svg><use xlink:href="#iconDrag"></use></svg><span ${protyle.disabled ? "" : 'draggable="true"'}></span></button>`
break;
}
}
if (index === 0) {
// 不单独显示要不然在块的间隔中gutter 会跳来跳去的
if (["NodeBlockquote", "NodeList", "NodeSuperBlock"].includes(type)) {
@ -1924,8 +1972,9 @@ data-type="fold"><svg style="width:10px${fold && fold === "1" ? "" : ";transform
} else if (rect.height < Math.floor(window.siyuan.config.editor.fontSize * 1.625) + 8 ||
(rect.height > Math.floor(window.siyuan.config.editor.fontSize * 1.625) + 8 && rect.height < Math.floor(window.siyuan.config.editor.fontSize * 1.625) * 2 + 8)) {
marginHeight = (rect.height - this.element.clientHeight) / 2;
} else if ((nodeElement.getAttribute("data-type") === "NodeAttributeView" ||
element.getAttribute("data-type") === "NodeAttributeView") && contentTop < rect.top) {
} else if (!element.classList.contains("av__row") &&
(nodeElement.getAttribute("data-type") === "NodeAttributeView" || element.getAttribute("data-type") === "NodeAttributeView") &&
contentTop < rect.top) {
marginHeight = 8;
}
this.element.style.top = `${Math.max(rect.top, contentTop) + marginHeight}px`;

View file

@ -159,39 +159,6 @@ export const avClick = (protyle: IProtyle, event: MouseEvent & { target: HTMLEle
event.preventDefault();
event.stopPropagation();
return true;
} else if (target.classList.contains("av__gutter")) {
const rowElement = hasClosestByClassName(target, "av__row");
if (!rowElement) {
return;
}
if (target.dataset.action === "add") {
const avID = blockElement.getAttribute("data-av-id");
const srcIDs = [Lute.NewNodeID()];
const previousID = event.altKey ? (rowElement.previousElementSibling.getAttribute("data-id") || "") : rowElement.getAttribute("data-id");
transaction(protyle, [{
action: "insertAttrViewBlock",
avID,
previousID,
srcIDs,
isDetached: true,
}], [{
action: "removeAttrViewBlock",
srcIDs,
avID,
}]);
insertAttrViewBlockAnimation(blockElement, srcIDs, previousID, avID);
} else {
const gutterRect = target.getBoundingClientRect();
avContextmenu(protyle, rowElement, {
x: gutterRect.left,
y: gutterRect.bottom,
w: gutterRect.width,
h: gutterRect.height
});
}
event.preventDefault();
event.stopPropagation();
return true;
} else if (target.classList.contains("av__firstcol")) {
window.siyuan.menus.menu.remove();
selectRow(target, "toggle");

View file

@ -120,11 +120,7 @@ style="width: ${column.width || "200px"}">${getCalcValue(column) || '<svg><use x
</div>`;
// body
data.rows.forEach((row: IAVRow) => {
tableHTML += `<div class="av__row" data-id="${row.id}">
<div class="av__gutters">
<button class="av__gutter ariaLabel" data-action="add" data-position="right" aria-label="${isMac() ? window.siyuan.languages.addBelowAbove : window.siyuan.languages.addBelowAbove.replace("", "Alt+")}"><svg><use xlink:href="#iconAdd"></use></svg></button>
<button class="av__gutter ariaLabel" draggable="true" data-position="right" aria-label="${window.siyuan.languages.rowTip}"><svg><use xlink:href="#iconDrag"></use></svg></button>
</div>`;
tableHTML += `<div class="av__row" data-id="${row.id}">`;
if (pinIndex > -1) {
tableHTML += '<div class="av__colsticky"><div class="av__firstcol"><svg><use xlink:href="#iconUncheck"></use></svg></div>';
} else {

View file

@ -379,7 +379,6 @@ export class WYSIWYG {
}
const target = event.target as HTMLElement;
if (hasClosestByClassName(target, "protyle-action") ||
hasClosestByClassName(target, "av__gutters") ||
hasClosestByClassName(target, "av__cellheader")) {
return;
}
@ -1511,22 +1510,7 @@ export class WYSIWYG {
if (embedElement) {
protyle.gutter.render(protyle, embedElement, this.element);
} else {
// database 行块标
const rowElement = hasClosestByClassName(event.target, "av__row");
if (rowElement && rowElement.dataset.id) {
const guttersElement = rowElement.querySelector(".av__gutters");
if (guttersElement) {
guttersElement.classList.remove("av__gutters--min");
let guttersLeft = rowElement.parentElement.parentElement.getBoundingClientRect().left - guttersElement.clientWidth;
const contentLeft = protyle.contentElement.getBoundingClientRect().left;
if (guttersLeft < contentLeft) {
guttersLeft = contentLeft;
guttersElement.classList.add("av__gutters--min");
}
guttersElement.setAttribute("style", `left:${guttersLeft}px;top:${rowElement.getBoundingClientRect().top}px`);
}
}
protyle.gutter.render(protyle, nodeElement, this.element);
protyle.gutter.render(protyle, nodeElement, this.element, event.target);
}
}
});