mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-23 18:10:12 +01:00
This reverts commit 5862811d96.
This commit is contained in:
parent
5862811d96
commit
8eb5e53f81
6 changed files with 36 additions and 306 deletions
|
|
@ -140,12 +140,10 @@
|
||||||
&--header,
|
&--header,
|
||||||
&--footer {
|
&--footer {
|
||||||
background-color: var(--av-background);
|
background-color: var(--av-background);
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&--footer {
|
&--footer {
|
||||||
display: inline-flex;
|
display: flex;
|
||||||
border-top: 1px solid var(--b3-theme-surface-lighter);
|
border-top: 1px solid var(--b3-theme-surface-lighter);
|
||||||
color: var(--b3-theme-on-surface);
|
color: var(--b3-theme-on-surface);
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import {unicode2Emoji} from "../../../emoji";
|
||||||
import {focusBlock} from "../../util/selection";
|
import {focusBlock} from "../../util/selection";
|
||||||
import {isMac} from "../../util/compatibility";
|
import {isMac} from "../../util/compatibility";
|
||||||
import {hasClosestByClassName} from "../../util/hasClosest";
|
import {hasClosestByClassName} from "../../util/hasClosest";
|
||||||
import {avScroll} from "./scroll";
|
|
||||||
|
|
||||||
export const avRender = (element: Element, protyle: IProtyle, cb?: () => void) => {
|
export const avRender = (element: Element, protyle: IProtyle, cb?: () => void) => {
|
||||||
let avElements: Element[] = [];
|
let avElements: Element[] = [];
|
||||||
|
|
@ -42,6 +41,8 @@ export const avRender = (element: Element, protyle: IProtyle, cb?: () => void) =
|
||||||
e.firstElementChild.innerHTML = html;
|
e.firstElementChild.innerHTML = html;
|
||||||
}
|
}
|
||||||
const left = e.querySelector(".av__scroll")?.scrollLeft || 0;
|
const left = e.querySelector(".av__scroll")?.scrollLeft || 0;
|
||||||
|
const headerTransform = (e.querySelector(".av__row--header") as HTMLElement)?.style.transform;
|
||||||
|
const footerTransform = (e.querySelector(".av__row--footer") as HTMLElement)?.style.transform;
|
||||||
let selectCellId = "";
|
let selectCellId = "";
|
||||||
const selectCellElement = e.querySelector(".av__cell--select") as HTMLElement;
|
const selectCellElement = e.querySelector(".av__cell--select") as HTMLElement;
|
||||||
if (selectCellElement) {
|
if (selectCellElement) {
|
||||||
|
|
@ -221,7 +222,7 @@ ${cell.color ? `color:${cell.color};` : ""}">${text}</div>`;
|
||||||
<div class="av__counter fn__none"></div>
|
<div class="av__counter fn__none"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="av__scroll">
|
<div class="av__scroll">
|
||||||
<div class="av__body">
|
<div style="float: left;">
|
||||||
${tableHTML}
|
${tableHTML}
|
||||||
<div class="av__row--add">
|
<div class="av__row--add">
|
||||||
<div class="av__colsticky">
|
<div class="av__colsticky">
|
||||||
|
|
@ -239,7 +240,12 @@ ${cell.color ? `color:${cell.color};` : ""}">${text}</div>`;
|
||||||
if (left) {
|
if (left) {
|
||||||
e.querySelector(".av__scroll").scrollLeft = left;
|
e.querySelector(".av__scroll").scrollLeft = left;
|
||||||
}
|
}
|
||||||
avScroll(protyle.contentElement, e);
|
if (headerTransform) {
|
||||||
|
(e.querySelector(".av__row--header") as HTMLElement).style.transform = headerTransform;
|
||||||
|
}
|
||||||
|
if (footerTransform) {
|
||||||
|
(e.querySelector(".av__row--footer") as HTMLElement).style.transform = footerTransform;
|
||||||
|
}
|
||||||
if (selectCellId) {
|
if (selectCellId) {
|
||||||
const newCellElement = e.querySelector(`.av__row[data-id="${selectCellId.split(Constants.ZWSP)[0]}"] .av__cell[data-col-id="${selectCellId.split(Constants.ZWSP)[1]}"]`);
|
const newCellElement = e.querySelector(`.av__row[data-id="${selectCellId.split(Constants.ZWSP)[0]}"] .av__cell[data-col-id="${selectCellId.split(Constants.ZWSP)[1]}"]`);
|
||||||
if (newCellElement) {
|
if (newCellElement) {
|
||||||
|
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
import {stickyScrollY} from "../../scroll/stickyScroll";
|
|
||||||
|
|
||||||
export const avScroll = (
|
|
||||||
contentElement: HTMLElement,
|
|
||||||
nodeElement: HTMLElement,
|
|
||||||
) => {
|
|
||||||
const bodyElement = nodeElement.querySelector(".av__body") as HTMLElement;
|
|
||||||
|
|
||||||
if (bodyElement) {
|
|
||||||
const headerElement = bodyElement.querySelector(".av__row--header") as HTMLElement;
|
|
||||||
const footerElement = bodyElement.querySelector(".av__row--footer") as HTMLElement;
|
|
||||||
|
|
||||||
stickyScrollY(
|
|
||||||
contentElement,
|
|
||||||
bodyElement,
|
|
||||||
headerElement ? [{element: headerElement}] : [],
|
|
||||||
footerElement ? [{element: footerElement}] : [],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -4,7 +4,6 @@ import {fetchPost} from "../../util/fetch";
|
||||||
import {onGet} from "../util/onGet";
|
import {onGet} from "../util/onGet";
|
||||||
import {isMobile} from "../../util/functions";
|
import {isMobile} from "../../util/functions";
|
||||||
import {hasClosestBlock, hasClosestByClassName} from "../util/hasClosest";
|
import {hasClosestBlock, hasClosestByClassName} from "../util/hasClosest";
|
||||||
import {avScroll} from "../render/av/scroll";
|
|
||||||
|
|
||||||
let getIndexTimeout: number;
|
let getIndexTimeout: number;
|
||||||
export const scrollEvent = (protyle: IProtyle, element: HTMLElement) => {
|
export const scrollEvent = (protyle: IProtyle, element: HTMLElement) => {
|
||||||
|
|
@ -22,7 +21,32 @@ export const scrollEvent = (protyle: IProtyle, element: HTMLElement) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
protyle.wysiwyg.element.querySelectorAll(".av").forEach((item: HTMLElement) => {
|
protyle.wysiwyg.element.querySelectorAll(".av").forEach((item: HTMLElement) => {
|
||||||
avScroll(element, item);
|
if (item.dataset.render !== "true") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const scrollRect = item.querySelector(".av__scroll").getBoundingClientRect();
|
||||||
|
const headerElement = item.querySelector(".av__row--header") as HTMLElement;
|
||||||
|
if (headerElement) {
|
||||||
|
const distance = Math.floor(elementRect.top - scrollRect.top);
|
||||||
|
if (distance > 0 && distance < scrollRect.height) {
|
||||||
|
headerElement.style.transform = `translateY(${distance}px)`;
|
||||||
|
} else {
|
||||||
|
headerElement.style.transform = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const footerElement = item.querySelector(".av__row--footer") as HTMLElement;
|
||||||
|
if (footerElement) {
|
||||||
|
if (footerElement.querySelector(".av__calc--ashow")) {
|
||||||
|
const distance = Math.floor(elementRect.bottom - footerElement.parentElement.getBoundingClientRect().bottom);
|
||||||
|
if (distance < 0 && -distance < scrollRect.height) {
|
||||||
|
footerElement.style.transform = `translateY(${distance}px)`;
|
||||||
|
} else {
|
||||||
|
footerElement.style.transform = "";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
footerElement.style.transform = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!protyle.element.classList.contains("block__edit") && !isMobile()) {
|
if (!protyle.element.classList.contains("block__edit") && !isMobile()) {
|
||||||
|
|
|
||||||
|
|
@ -1,276 +0,0 @@
|
||||||
export interface IStickyPositionY {
|
|
||||||
top: number;
|
|
||||||
bottom: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IStickyElementY {
|
|
||||||
element: HTMLElement;
|
|
||||||
offset?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IStickyContextY extends IStickyElementY {
|
|
||||||
rect: DOMRect;
|
|
||||||
base: number;
|
|
||||||
origin: IStickyPositionY;
|
|
||||||
current: IStickyPositionY;
|
|
||||||
target: IStickyPositionY;
|
|
||||||
style: IStickyPositionY;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const stickyScrollY = (
|
|
||||||
view: HTMLElement, // 视口元素
|
|
||||||
container: HTMLElement, // 容器元素
|
|
||||||
topElements: IStickyElementY[] = [], // 顶部粘性元素
|
|
||||||
bottomElements: IStickyElementY[] = [], // 底部粘性元素
|
|
||||||
) => {
|
|
||||||
if (topElements.length === 0 && bottomElements.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const viewRect = view.getBoundingClientRect();
|
|
||||||
const containerRect = container.getBoundingClientRect();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ┏---------------┓
|
|
||||||
* | view |
|
|
||||||
* ┗---------------┛ → viewRect.bottom
|
|
||||||
* ┌-----------┐ --→ containerRect.top
|
|
||||||
* | container |
|
|
||||||
* └-----------┘
|
|
||||||
* ====== OR ======
|
|
||||||
* ┌-----------┐
|
|
||||||
* | container |
|
|
||||||
* └-----------┘ --→ containerRect.bottom
|
|
||||||
* ┏---------------┓ → viewRect.top
|
|
||||||
* | view |
|
|
||||||
* ┗---------------┛
|
|
||||||
*/
|
|
||||||
if (viewRect.bottom <= containerRect.top || containerRect.bottom <= viewRect.top) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const topContext: IStickyContextY[] = topElements.map(item => {
|
|
||||||
const rect = item.element.getBoundingClientRect();
|
|
||||||
const base = Number.parseFloat(item.element.style.top) || 0;
|
|
||||||
item.offset ??= 0;
|
|
||||||
|
|
||||||
return {
|
|
||||||
...item,
|
|
||||||
rect,
|
|
||||||
base,
|
|
||||||
origin: {
|
|
||||||
top: rect.top - base,
|
|
||||||
bottom: rect.bottom - base,
|
|
||||||
},
|
|
||||||
current: {
|
|
||||||
top: rect.top,
|
|
||||||
bottom: rect.bottom,
|
|
||||||
},
|
|
||||||
target: {
|
|
||||||
top: null,
|
|
||||||
bottom: null,
|
|
||||||
},
|
|
||||||
style: {
|
|
||||||
top: null,
|
|
||||||
bottom: null,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
const bottomContext: IStickyContextY[] = bottomElements.map(item => {
|
|
||||||
const rect = item.element.getBoundingClientRect();
|
|
||||||
const base = Number.parseFloat(item.element.style.bottom) || 0;
|
|
||||||
item.offset ??= 0;
|
|
||||||
|
|
||||||
return {
|
|
||||||
...item,
|
|
||||||
rect,
|
|
||||||
base,
|
|
||||||
origin: {
|
|
||||||
top: rect.top + base,
|
|
||||||
bottom: rect.bottom + base,
|
|
||||||
},
|
|
||||||
current: {
|
|
||||||
top: rect.top,
|
|
||||||
bottom: rect.bottom,
|
|
||||||
},
|
|
||||||
target: {
|
|
||||||
top: null,
|
|
||||||
bottom: null,
|
|
||||||
},
|
|
||||||
style: {
|
|
||||||
top: null,
|
|
||||||
bottom: null,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
let handleTop = false;
|
|
||||||
let handleBottom = false;
|
|
||||||
|
|
||||||
switch (true) {
|
|
||||||
/**
|
|
||||||
* ┏---------------┓ → viewRect.top
|
|
||||||
* | |
|
|
||||||
* | view |
|
|
||||||
* | ┌-----------┐ | → containerRect.top
|
|
||||||
* ┗-╊-----------╊-┛ → viewRect.bottom
|
|
||||||
* | container |
|
|
||||||
* └-----------┘ --→ containerRect.bottom
|
|
||||||
*/
|
|
||||||
case viewRect.top <= containerRect.top
|
|
||||||
&& containerRect.top <= viewRect.bottom
|
|
||||||
&& viewRect.top <= viewRect.bottom:
|
|
||||||
handleBottom = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ┏---------------┓ → viewRect.top
|
|
||||||
* | view |
|
|
||||||
* | ┌-----------┐ | → containerRect.top
|
|
||||||
* | | container | |
|
|
||||||
* | └-----------┘ | → containerRect.bottom
|
|
||||||
* ┗---------------┛ → viewRect.bottom
|
|
||||||
*/
|
|
||||||
case viewRect.top <= containerRect.top
|
|
||||||
&& containerRect.bottom <= viewRect.bottom:
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ┌-----------┐ --→ containerRect.top
|
|
||||||
* ┏-╊-----------╊-┓ → viewRect.top
|
|
||||||
* | | | |}→ view
|
|
||||||
* ┗-╊-----------╊-┛ → viewRect.bottom
|
|
||||||
* | container |
|
|
||||||
* └-----------┘ --→ containerRect.bottom
|
|
||||||
*/
|
|
||||||
case containerRect.top <= viewRect.top
|
|
||||||
&& viewRect.bottom <= containerRect.bottom:
|
|
||||||
handleTop = true;
|
|
||||||
handleBottom = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ┌-----------┐ --→ containerRect.top
|
|
||||||
* | container |
|
|
||||||
* ┏-╊-----------╊-┓ → viewRect.top
|
|
||||||
* | └-----------┘ | → containerRect.bottom
|
|
||||||
* | view |
|
|
||||||
* ┗-|-----------|-┛ → viewRect.bottom
|
|
||||||
*/
|
|
||||||
case containerRect.top <= viewRect.top
|
|
||||||
&& viewRect.top <= containerRect.bottom
|
|
||||||
&& containerRect.bottom <= viewRect.bottom:
|
|
||||||
handleTop = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (handleTop) {
|
|
||||||
if (topContext.length > 0) {
|
|
||||||
topContext.reduceRight((next, current) => {
|
|
||||||
switch (true) {
|
|
||||||
/**
|
|
||||||
* ┌-----------┐ --→ containerRect.top
|
|
||||||
* ┏-╊-----------╊-┓ → viewRect.top
|
|
||||||
* | | ┌┄┄┄┄┄┄┄┐ | | → current.target.top - current.offset
|
|
||||||
* | | ├╌╌╌╌╌╌╌┤ | | → current.origin.top
|
|
||||||
* | | └╌╌╌╌╌╌╌┘ | | → current.origin.bottom
|
|
||||||
* | | ┌╌╌╌╌╌╌╌┐ | | → next.origin.top
|
|
||||||
* | | └╌╌╌╌╌╌╌┘ | | → next.origin.bottom
|
|
||||||
* ┗-╊-----------╊-┛ → viewRect.bottom
|
|
||||||
* └-----------┘ --→ containerRect.bottom
|
|
||||||
*/
|
|
||||||
case viewRect.top <= (current.origin.top - current.offset):
|
|
||||||
current.target.top = current.origin.top;
|
|
||||||
current.target.bottom = current.origin.bottom;
|
|
||||||
current.style.top = null;
|
|
||||||
break;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ┌-----------┐ --→ containerRect.top
|
|
||||||
* | ┌╌╌╌╌╌╌╌┐ | --→ current.origin.top
|
|
||||||
* | └╌╌╌╌╌╌╌┘ | --→ current.origin.bottom
|
|
||||||
* ┏-╊-----------╊-┓ → viewRect.top
|
|
||||||
* | | ┌-------┐ | | → current.target.top
|
|
||||||
* | | └-------┘ | | → current.target.bottom
|
|
||||||
* ┗-╊-----------╊-┛ → viewRect.bottom
|
|
||||||
* | container |
|
|
||||||
* └-----------┘ --→ containerRect.bottom
|
|
||||||
*/
|
|
||||||
default:
|
|
||||||
current.target.top = viewRect.top + current.offset;
|
|
||||||
current.target.bottom = current.target.top + current.rect.height;
|
|
||||||
const nextTop = next
|
|
||||||
? Math.min(next.target.top, next.origin.top, containerRect.bottom)
|
|
||||||
: containerRect.bottom;
|
|
||||||
if (nextTop < current.target.bottom) {
|
|
||||||
const diff = nextTop - current.target.bottom;
|
|
||||||
current.target.top += diff;
|
|
||||||
current.target.bottom += diff;
|
|
||||||
}
|
|
||||||
current.style.top = current.base + (current.target.top - current.current.top);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return current;
|
|
||||||
}, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (handleBottom) {
|
|
||||||
if (bottomContext.length > 0) {
|
|
||||||
bottomContext.reduce((last, current) => {
|
|
||||||
switch (true) {
|
|
||||||
/**
|
|
||||||
* ┌-----------┐ --→ containerRect.top
|
|
||||||
* ┏-╊-----------╊-┓ → viewRect.top
|
|
||||||
* | | ┌╌╌╌╌╌╌╌┐ | | → last.origin.top
|
|
||||||
* | | └╌╌╌╌╌╌╌┘ | | → last.origin.bottom
|
|
||||||
* | | ┌╌╌╌╌╌╌╌┐ | | → current.origin.top
|
|
||||||
* | | ├╌╌╌╌╌╌╌┤ | | → current.origin.bottom
|
|
||||||
* | | └┄┄┄┄┄┄┄┘ | | → current.target.bottom + current.offset
|
|
||||||
* ┗-╊-----------╊-┛ → viewRect.bottom
|
|
||||||
* └-----------┘ --→ containerRect.bottom
|
|
||||||
*/
|
|
||||||
case (current.origin.bottom + current.offset) <= viewRect.bottom:
|
|
||||||
current.target.top = current.origin.top;
|
|
||||||
current.target.bottom = current.origin.bottom;
|
|
||||||
current.style.bottom = null;
|
|
||||||
break;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* ┌-----------┐ --→ containerRect.top
|
|
||||||
* ┏-╊-----------╊-┓ → viewRect.top
|
|
||||||
* | | ┌-------┐ | | → current.target.top
|
|
||||||
* | | └-------┘ | | → current.target.bottom
|
|
||||||
* ┗-╊-----------╊-┛ → viewRect.bottom
|
|
||||||
* | ┌╌╌╌╌╌╌╌┐ | --→ current.origin.top
|
|
||||||
* | └╌╌╌╌╌╌╌┘ | --→ current.origin.bottom
|
|
||||||
* | container |
|
|
||||||
* └-----------┘ --→ containerRect.bottom
|
|
||||||
*/
|
|
||||||
default:
|
|
||||||
current.target.bottom = viewRect.bottom - current.offset;
|
|
||||||
current.target.top = current.target.bottom - current.rect.height;
|
|
||||||
const lastBottom = last
|
|
||||||
? Math.max(last.target.bottom, last.origin.bottom, containerRect.top)
|
|
||||||
: containerRect.top;
|
|
||||||
if (current.target.top < lastBottom) {
|
|
||||||
const diff = lastBottom - current.target.top;
|
|
||||||
current.target.top += diff;
|
|
||||||
current.target.bottom += diff;
|
|
||||||
}
|
|
||||||
current.style.bottom = current.base - (current.target.bottom - current.current.bottom);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return current;
|
|
||||||
}, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[...topContext, ...bottomContext].forEach(item => {
|
|
||||||
item.element.style.top = item.style.top ? `${item.style.top}px` : null;
|
|
||||||
item.element.style.bottom = item.style.bottom ? `${item.style.bottom}px` : null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
@ -77,7 +77,6 @@ import {activeBlur, hideKeyboardToolbar} from "../../mobile/util/keyboardToolbar
|
||||||
import {commonClick} from "./commonClick";
|
import {commonClick} from "./commonClick";
|
||||||
import {avClick, avContextmenu, updateAVName} from "../render/av/action";
|
import {avClick, avContextmenu, updateAVName} from "../render/av/action";
|
||||||
import {updateHeader} from "../render/av/row";
|
import {updateHeader} from "../render/av/row";
|
||||||
import {avScroll} from "../render/av/scroll";
|
|
||||||
|
|
||||||
export class WYSIWYG {
|
export class WYSIWYG {
|
||||||
public lastHTMLs: { [key: string]: string } = {};
|
public lastHTMLs: { [key: string]: string } = {};
|
||||||
|
|
@ -390,7 +389,6 @@ export class WYSIWYG {
|
||||||
scrollElement.querySelectorAll(".av__row, .av__row--footer").forEach(item => {
|
scrollElement.querySelectorAll(".av__row, .av__row--footer").forEach(item => {
|
||||||
(item.querySelector(`[data-col-id="${dragColId}"]`) as HTMLElement).style.width = newWidth;
|
(item.querySelector(`[data-col-id="${dragColId}"]`) as HTMLElement).style.width = newWidth;
|
||||||
});
|
});
|
||||||
avScroll(protyle.contentElement, nodeElement);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue