mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-05-10 00:21:42 +08:00
This commit is contained in:
parent
e8f1808cb0
commit
452b79c601
@ -5,14 +5,55 @@
|
||||
|
||||
.protyle-scroll {
|
||||
position: absolute;
|
||||
right: -80px;
|
||||
right: 0;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
width: 24px;
|
||||
svg {
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
&__down,
|
||||
&__up {
|
||||
transition: var(--b3-transition);
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
color: var(--b3-border-color);
|
||||
|
||||
&:hover {
|
||||
color: var(--b3-theme-on-surface);
|
||||
}
|
||||
}
|
||||
|
||||
&__up {
|
||||
top: calc(50% - 114px);
|
||||
}
|
||||
|
||||
&__down {
|
||||
bottom: calc(50% - 135px);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.protyle-scroll__down,
|
||||
.protyle-scroll__up {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&__bar {
|
||||
position: absolute;
|
||||
right: -89px;
|
||||
top: 50%;
|
||||
transform: rotate(90deg);
|
||||
z-index: 1;
|
||||
|
||||
.b3-slider {
|
||||
width: 200px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.protyle-attr {
|
||||
display: flex;
|
||||
@ -110,6 +151,7 @@
|
||||
flex-shrink: 0;
|
||||
box-sizing: border-box;
|
||||
min-height: 30px;
|
||||
z-index: 1;
|
||||
|
||||
&__space {
|
||||
flex: 1;
|
||||
|
@ -59,6 +59,7 @@ export const openMobileFileById = (id: string, action = [Constants.CB_GET_HL]) =
|
||||
blockId: id,
|
||||
action,
|
||||
render: {
|
||||
scroll: true,
|
||||
background: true,
|
||||
gutter: true,
|
||||
},
|
||||
|
@ -72,7 +72,7 @@ export class Protyle {
|
||||
this.protyle.undo = new Undo();
|
||||
this.protyle.wysiwyg = new WYSIWYG(this.protyle);
|
||||
this.protyle.toolbar = new Toolbar(this.protyle);
|
||||
this.protyle.scroll = new Scroll(this.protyle);
|
||||
this.protyle.scroll = new Scroll(this.protyle); // 不能使用 render.scroll 来判读是否初始化,除非重构后面用到的相关变量
|
||||
if (this.protyle.options.render.gutter) {
|
||||
this.protyle.gutter = new Gutter(this.protyle);
|
||||
}
|
||||
|
@ -1,25 +1,37 @@
|
||||
import {Constants} from "../../constants";
|
||||
import {onGet} from "../util/onGet";
|
||||
import {fetchPost} from "../../util/fetch";
|
||||
import {updateHotkeyTip} from "../util/compatibility";
|
||||
import {hasClosestByClassName} from "../util/hasClosest";
|
||||
import {goEnd, goHome} from "../wysiwyg/commonHotkey";
|
||||
|
||||
export class Scroll {
|
||||
public element: HTMLElement;
|
||||
private parentElement: HTMLElement;
|
||||
private inputElement: HTMLInputElement;
|
||||
public lastScrollTop: number;
|
||||
public keepLazyLoad: boolean;
|
||||
|
||||
constructor(protyle: IProtyle) {
|
||||
const divElement = document.createElement("div");
|
||||
divElement.innerHTML = "<input class='b3-slider' type='range' max='1' min='1' step='1' value='1' />";
|
||||
divElement.className = "fn__none protyle-scroll b3-tooltips b3-tooltips__s";
|
||||
divElement.setAttribute("aria-label", "Blocks 1/1");
|
||||
this.element = divElement;
|
||||
this.parentElement = document.createElement("div");
|
||||
this.parentElement.classList.add("protyle-scroll");
|
||||
this.parentElement.innerHTML = `<div class="b3-tooltips b3-tooltips__nw protyle-scroll__up" aria-label="${updateHotkeyTip("⌘Home")}">
|
||||
<svg><use xlink:href="#iconUp"></use></svg>
|
||||
</div>
|
||||
<div class="fn__none protyle-scroll__bar b3-tooltips b3-tooltips__s" aria-label="Blocks 1/1">
|
||||
<input class="b3-slider" type="range" max="1" min="1" step="1" value="1" />
|
||||
</div>
|
||||
<div class="b3-tooltips b3-tooltips__sw protyle-scroll__down" aria-label="${updateHotkeyTip("⌘End")}">
|
||||
<svg><use xlink:href="#iconDown"></use></svg>
|
||||
</div>`
|
||||
|
||||
this.element = this.parentElement.querySelector(".protyle-scroll__bar");
|
||||
this.keepLazyLoad = false;
|
||||
if (!protyle.options.render.scroll) {
|
||||
this.element.classList.add("fn__none");
|
||||
this.parentElement.classList.add("fn__none");
|
||||
}
|
||||
this.lastScrollTop = 0;
|
||||
this.inputElement = divElement.firstElementChild as HTMLInputElement;
|
||||
this.inputElement = this.element.firstElementChild as HTMLInputElement;
|
||||
this.inputElement.addEventListener("input", () => {
|
||||
this.element.setAttribute("aria-label", `Blocks ${this.inputElement.value}/${protyle.block.blockCount}`);
|
||||
});
|
||||
@ -31,13 +43,20 @@ export class Scroll {
|
||||
this.setIndex(protyle);
|
||||
});
|
||||
/// #endif
|
||||
this.inputElement.addEventListener("click", () => {
|
||||
this.parentElement.addEventListener("click", (event) => {
|
||||
const target = event.target as HTMLElement
|
||||
if (hasClosestByClassName(target, "protyle-scroll__up")) {
|
||||
goHome(protyle)
|
||||
} else if (hasClosestByClassName(target, "protyle-scroll__down")) {
|
||||
goEnd(protyle)
|
||||
} else if (target.classList.contains("b3-slider")) {
|
||||
this.setIndex(protyle);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private setIndex(protyle: IProtyle) {
|
||||
if (protyle.wysiwyg.element.getAttribute("data-top") || !protyle.model) {
|
||||
if (protyle.wysiwyg.element.getAttribute("data-top")) {
|
||||
return;
|
||||
}
|
||||
protyle.wysiwyg.element.setAttribute("data-top", protyle.wysiwyg.element.scrollTop.toString());
|
||||
|
@ -28,8 +28,8 @@ export const initUI = (protyle: IProtyle) => {
|
||||
if (protyle.upload) {
|
||||
protyle.element.appendChild(protyle.upload.element);
|
||||
}
|
||||
if (protyle.scroll) {
|
||||
protyle.element.appendChild(protyle.scroll.element);
|
||||
if (protyle.options.render) {
|
||||
protyle.element.appendChild(protyle.scroll.element.parentElement);
|
||||
}
|
||||
if (protyle.gutter) {
|
||||
protyle.element.appendChild(protyle.gutter.element);
|
||||
|
@ -19,6 +19,8 @@ import {hideElements} from "../ui/hideElements";
|
||||
import {countBlockWord} from "../../layout/status";
|
||||
import {scrollCenter} from "../../util/highlightById";
|
||||
import {transaction} from "./transaction";
|
||||
import {onGet} from "../util/onGet";
|
||||
import {Constants} from "../../constants";
|
||||
|
||||
export const commonHotkey = (protyle: IProtyle, event: KeyboardEvent) => {
|
||||
const target = event.target as HTMLElement;
|
||||
@ -215,3 +217,38 @@ export const duplicateBlock = (nodeElements: Element[], protyle: IProtyle) => {
|
||||
focusBlock(focusElement);
|
||||
scrollCenter(protyle);
|
||||
};
|
||||
|
||||
export const goHome = (protyle:IProtyle) => {
|
||||
if (protyle.wysiwyg.element.firstElementChild.getAttribute("data-node-index") === "0" ||
|
||||
protyle.wysiwyg.element.firstElementChild.getAttribute("data-eof") === "true" ||
|
||||
protyle.options.backlinkData) {
|
||||
focusBlock(protyle.wysiwyg.element.firstElementChild);
|
||||
protyle.contentElement.scrollTop = 0;
|
||||
protyle.scroll.lastScrollTop = 1;
|
||||
} else {
|
||||
fetchPost("/api/filetree/getDoc", {
|
||||
id: protyle.block.rootID,
|
||||
mode: 0,
|
||||
size: window.siyuan.config.editor.dynamicLoadBlocks,
|
||||
}, getResponse => {
|
||||
onGet(getResponse, protyle, [Constants.CB_GET_FOCUS]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const goEnd = (protyle:IProtyle) => {
|
||||
if (!protyle.scroll.element.classList.contains("fn__none") &&
|
||||
protyle.wysiwyg.element.lastElementChild.getAttribute("data-eof") !== "true") {
|
||||
fetchPost("/api/filetree/getDoc", {
|
||||
id: protyle.block.rootID,
|
||||
mode: 4,
|
||||
size: window.siyuan.config.editor.dynamicLoadBlocks,
|
||||
}, getResponse => {
|
||||
onGet(getResponse, protyle, [Constants.CB_GET_FOCUS]);
|
||||
});
|
||||
} else {
|
||||
protyle.contentElement.scrollTop = protyle.contentElement.scrollHeight;
|
||||
protyle.scroll.lastScrollTop = protyle.contentElement.scrollTop;
|
||||
focusBlock(protyle.wysiwyg.element.lastElementChild, undefined, false);
|
||||
}
|
||||
}
|
||||
|
@ -42,14 +42,13 @@ import {isLocalPath} from "../../util/pathName";
|
||||
/// #if !MOBILE
|
||||
import {openBy, openFileById} from "../../editor/util";
|
||||
/// #endif
|
||||
import {commonHotkey, downSelect, duplicateBlock, getStartEndElement, upSelect} from "./commonHotkey";
|
||||
import {commonHotkey, downSelect, duplicateBlock, getStartEndElement, goEnd, goHome, upSelect} from "./commonHotkey";
|
||||
import {linkMenu, refMenu, setFold, zoomOut} from "../../menus/protyle";
|
||||
import {removeEmbed} from "./removeEmbed";
|
||||
import {openAttr} from "../../menus/commonMenuItem";
|
||||
import {Constants} from "../../constants";
|
||||
import {bindMenuKeydown} from "../../menus/Menu";
|
||||
import {fetchPost} from "../../util/fetch";
|
||||
import {onGet} from "../util/onGet";
|
||||
import {scrollCenter} from "../../util/highlightById";
|
||||
import {BlockPanel} from "../../block/Panel";
|
||||
import * as dayjs from "dayjs";
|
||||
@ -452,41 +451,14 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
|
||||
}
|
||||
// ctrl+home 光标移动到顶
|
||||
if (!event.altKey && !event.shiftKey && isCtrl(event) && event.key === "Home") {
|
||||
if (protyle.wysiwyg.element.firstElementChild.getAttribute("data-node-index") === "0" ||
|
||||
protyle.wysiwyg.element.firstElementChild.getAttribute("data-eof") === "true" ||
|
||||
protyle.options.backlinkData) {
|
||||
focusBlock(protyle.wysiwyg.element.firstElementChild);
|
||||
protyle.contentElement.scrollTop = 0;
|
||||
protyle.scroll.lastScrollTop = 1;
|
||||
} else {
|
||||
fetchPost("/api/filetree/getDoc", {
|
||||
id: protyle.block.rootID,
|
||||
mode: 0,
|
||||
size: window.siyuan.config.editor.dynamicLoadBlocks,
|
||||
}, getResponse => {
|
||||
onGet(getResponse, protyle, [Constants.CB_GET_FOCUS]);
|
||||
});
|
||||
}
|
||||
goHome(protyle);
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
// ctrl+end 光标移动到尾
|
||||
if (!event.altKey && !event.shiftKey && isCtrl(event) && event.key === "End") {
|
||||
if (!protyle.scroll.element.classList.contains("fn__none") &&
|
||||
protyle.wysiwyg.element.lastElementChild.getAttribute("data-eof") !== "true") {
|
||||
fetchPost("/api/filetree/getDoc", {
|
||||
id: protyle.block.rootID,
|
||||
mode: 4,
|
||||
size: window.siyuan.config.editor.dynamicLoadBlocks,
|
||||
}, getResponse => {
|
||||
onGet(getResponse, protyle, [Constants.CB_GET_FOCUS]);
|
||||
});
|
||||
} else {
|
||||
protyle.contentElement.scrollTop = protyle.contentElement.scrollHeight;
|
||||
protyle.scroll.lastScrollTop = protyle.contentElement.scrollTop;
|
||||
focusBlock(protyle.wysiwyg.element.lastElementChild, undefined, false);
|
||||
}
|
||||
goEnd(protyle);
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
return;
|
||||
|
@ -311,7 +311,6 @@ export const openHistory = () => {
|
||||
background: false,
|
||||
title: false,
|
||||
gutter: false,
|
||||
scroll: false,
|
||||
breadcrumb: false,
|
||||
breadcrumbDocName: false,
|
||||
breadcrumbContext: false,
|
||||
|
Loading…
Reference in New Issue
Block a user