mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-16 14:40:12 +01:00
Fix SQL search results centering (#16290)
* 🎨 Refactor `highlightById` and `scrollCenter` functions to support position options * 🎨 Fix SQL search results centering fix https://github.com/siyuan-note/siyuan/issues/16279
This commit is contained in:
parent
c0e947d2ac
commit
8d6c422af0
12 changed files with 50 additions and 25 deletions
|
|
@ -385,17 +385,17 @@ const switchEditor = (editor: Editor, options: IOpenFileOptions, allModels: IMod
|
|||
preventScroll(editor.editor.protyle);
|
||||
editor.editor.protyle.observerLoad?.disconnect();
|
||||
if (options.action?.includes(Constants.CB_GET_HL)) {
|
||||
highlightById(editor.editor.protyle, options.id, true);
|
||||
highlightById(editor.editor.protyle, options.id, "top");
|
||||
} else if (options.action?.includes(Constants.CB_GET_FOCUS)) {
|
||||
if (nodeElement) {
|
||||
const newRange = focusBlock(nodeElement, undefined, options.action?.includes(Constants.CB_GET_OUTLINE) ? false : true);
|
||||
const newRange = focusBlock(nodeElement, undefined, !options.action?.includes(Constants.CB_GET_OUTLINE));
|
||||
if (newRange) {
|
||||
editor.editor.protyle.toolbar.range = newRange;
|
||||
}
|
||||
scrollCenter(editor.editor.protyle, nodeElement, true);
|
||||
scrollCenter(editor.editor.protyle, nodeElement, {position: "top"});
|
||||
editor.editor.protyle.observerLoad = new ResizeObserver(() => {
|
||||
if (document.contains(nodeElement)) {
|
||||
scrollCenter(editor.editor.protyle, nodeElement, true);
|
||||
scrollCenter(editor.editor.protyle, nodeElement, {position: "top"});
|
||||
}
|
||||
});
|
||||
setTimeout(() => {
|
||||
|
|
|
|||
|
|
@ -548,7 +548,7 @@ export class Wnd {
|
|||
range.collapse();
|
||||
currentTab.model.editor.protyle.toolbar.range = range;
|
||||
}
|
||||
scrollCenter(currentTab.model.editor.protyle, nodeElement, true);
|
||||
scrollCenter(currentTab.model.editor.protyle, nodeElement, {position: "top"});
|
||||
} else {
|
||||
openFileById({
|
||||
app: this.app,
|
||||
|
|
|
|||
|
|
@ -1022,7 +1022,7 @@ export const zoomOut = (options: {
|
|||
}
|
||||
focusBlock(showElement);
|
||||
const resizeObserver = new ResizeObserver(() => {
|
||||
scrollCenter(options.protyle, focusElement, true);
|
||||
scrollCenter(options.protyle, focusElement, {position: "top"});
|
||||
});
|
||||
resizeObserver.observe(options.protyle.wysiwyg.element);
|
||||
setTimeout(() => {
|
||||
|
|
|
|||
|
|
@ -41,9 +41,9 @@ export const openMobileFileById = (app: App, id: string, action: TProtyleAction[
|
|||
});
|
||||
if (blockElement) {
|
||||
pushBack();
|
||||
scrollCenter(window.siyuan.mobile.editor.protyle, blockElement, true);
|
||||
scrollCenter(window.siyuan.mobile.editor.protyle, blockElement, {position: "top"});
|
||||
if (action.includes(Constants.CB_GET_HL)) {
|
||||
highlightById(window.siyuan.mobile.editor.protyle, id, true);
|
||||
highlightById(window.siyuan.mobile.editor.protyle, id, "top");
|
||||
}
|
||||
closePanel();
|
||||
// 更新文档浏览时间
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ const genUploadedLabel = (responseText: string, protyle: IProtyle) => {
|
|||
insertHTML(successFileText, protyle, insertBlock);
|
||||
// 粘贴图片后定位不准确 https://github.com/siyuan-note/siyuan/issues/13336
|
||||
setTimeout(() => {
|
||||
scrollCenter(protyle, undefined, false, "smooth");
|
||||
scrollCenter(protyle, undefined, {behavior: "smooth"});
|
||||
}, hasImage ? 0 : Constants.TIMEOUT_LOAD);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -333,7 +333,7 @@ export const insertHTML = (html: string, protyle: IProtyle, isBlock = false,
|
|||
blockElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
|
||||
updateTransaction(protyle, id, blockElement.outerHTML, oldHTML);
|
||||
setTimeout(() => {
|
||||
scrollCenter(protyle, blockElement, false, "smooth");
|
||||
scrollCenter(protyle, blockElement, {behavior: "smooth"});
|
||||
}, Constants.TIMEOUT_LOAD);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -493,7 +493,7 @@ const focusElementById = (protyle: IProtyle, action: string[], scrollAttr?: IScr
|
|||
const contentRect = protyle.contentElement.getBoundingClientRect();
|
||||
const focusRect = focusElement.getBoundingClientRect();
|
||||
if (!hasScrollTop && (contentRect.top > focusRect.top || contentRect.bottom < focusRect.bottom)) {
|
||||
scrollCenter(protyle, focusElement, true);
|
||||
scrollCenter(protyle, focusElement, {position: "top"});
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
|
|
@ -507,7 +507,7 @@ const focusElementById = (protyle: IProtyle, action: string[], scrollAttr?: IScr
|
|||
const contentRect = protyle.contentElement.getBoundingClientRect();
|
||||
const focusRect = focusElement.getBoundingClientRect();
|
||||
if (!hasScrollTop && (contentRect.top > focusRect.top || contentRect.bottom < focusRect.bottom)) {
|
||||
scrollCenter(protyle, focusElement, true);
|
||||
scrollCenter(protyle, focusElement, {position: "top"});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -539,7 +539,7 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven
|
|||
processRender(protyle.wysiwyg.element);
|
||||
highlightRender(protyle.wysiwyg.element);
|
||||
avRender(protyle.wysiwyg.element, protyle);
|
||||
scrollCenter(protyle, undefined, false, "smooth");
|
||||
scrollCenter(protyle, undefined, {behavior: "smooth"});
|
||||
});
|
||||
return;
|
||||
} else if (files && files.length > 0) {
|
||||
|
|
@ -592,7 +592,7 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven
|
|||
if (nodeElement.classList.contains("av") && selectCellElement) {
|
||||
cellScrollIntoView(nodeElement, selectCellElement);
|
||||
} else {
|
||||
scrollCenter(protyle, undefined, false, "smooth");
|
||||
scrollCenter(protyle, undefined, {behavior: "smooth"});
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1417,7 +1417,7 @@ const processFold = (operation: IOperation, protyle: IProtyle) => {
|
|||
if (operation.context?.focusId) {
|
||||
const focusElement = protyle.wysiwyg.element.querySelector(`[data-node-id="${operation.context.focusId}"]`);
|
||||
focusBlock(focusElement);
|
||||
scrollCenter(protyle, focusElement, false);
|
||||
scrollCenter(protyle, focusElement);
|
||||
} else {
|
||||
protyle.contentElement.scrollTop = scrollTop;
|
||||
protyle.scroll.lastScrollTop = scrollTop;
|
||||
|
|
|
|||
|
|
@ -1049,7 +1049,7 @@ const renderNextSearchMark = (options: {
|
|||
});
|
||||
if (currentRange) {
|
||||
if (!currentRange.toString()) {
|
||||
highlightById(options.edit.protyle, options.id);
|
||||
highlightById(options.edit.protyle, options.id, "center");
|
||||
} else {
|
||||
scrollToCurrent(options.edit.protyle.contentElement, currentRange, contentRect);
|
||||
}
|
||||
|
|
@ -1131,12 +1131,12 @@ export const getArticle = (options: {
|
|||
const currentRange = options.edit.protyle.highlight.ranges[options.edit.protyle.highlight.rangeIndex];
|
||||
if (options.edit.protyle.highlight.ranges.length > 0 && currentRange) {
|
||||
if (!currentRange.toString()) {
|
||||
highlightById(options.edit.protyle, options.id);
|
||||
highlightById(options.edit.protyle, options.id, "center");
|
||||
} else {
|
||||
scrollToCurrent(options.edit.protyle.contentElement, currentRange, contentRect);
|
||||
}
|
||||
} else {
|
||||
highlightById(options.edit.protyle, options.id);
|
||||
highlightById(options.edit.protyle, options.id, "center");
|
||||
}
|
||||
};
|
||||
if (observer) {
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ const focusStack = async (app: App, stack: IBackStack) => {
|
|||
}
|
||||
});
|
||||
focusByOffset(getContenteditableElement(blockElement), stack.position.start, stack.position.end);
|
||||
scrollCenter(stack.protyle, blockElement, true);
|
||||
scrollCenter(stack.protyle, blockElement, {position: "top"});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
@ -207,7 +207,7 @@ const focusStack = async (app: App, stack: IBackStack) => {
|
|||
}
|
||||
});
|
||||
focusByOffset(getContenteditableElement(blockElement), stack.position.start, stack.position.end);
|
||||
scrollCenter(stack.protyle, blockElement, true);
|
||||
scrollCenter(stack.protyle, blockElement, {position: "top"});
|
||||
}
|
||||
});
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ export const bgFade = (element: Element) => {
|
|||
}, 1024);
|
||||
};
|
||||
|
||||
export const highlightById = (protyle: IProtyle, id: string, top = false) => {
|
||||
export const highlightById = (protyle: IProtyle, id: string, position: "auto" | "center" | "top" = "auto") => {
|
||||
let nodeElement: HTMLElement;
|
||||
const protyleElement = protyle.wysiwyg.element;
|
||||
if (!protyle.preview.element.classList.contains("fn__none")) {
|
||||
|
|
@ -28,7 +28,7 @@ export const highlightById = (protyle: IProtyle, id: string, top = false) => {
|
|||
}
|
||||
});
|
||||
if (nodeElement) {
|
||||
scrollCenter(protyle, nodeElement, top);
|
||||
scrollCenter(protyle, nodeElement, {position});
|
||||
bgFade(nodeElement);
|
||||
return nodeElement;// 仅配合前进后退使用
|
||||
}
|
||||
|
|
@ -38,8 +38,16 @@ export const highlightById = (protyle: IProtyle, id: string, top = false) => {
|
|||
}
|
||||
};
|
||||
|
||||
export const scrollCenter = (protyle: IProtyle, nodeElement?: Element, top = false, behavior: ScrollBehavior = "auto") => {
|
||||
if (!protyle.disabled && !top && getSelection().rangeCount > 0) {
|
||||
export const scrollCenter = (
|
||||
protyle: IProtyle,
|
||||
nodeElement?: Element,
|
||||
options?: {
|
||||
position?: "top" | "center" | "auto";
|
||||
behavior?: ScrollBehavior;
|
||||
}
|
||||
) => {
|
||||
const {position = "auto", behavior = "auto"} = options || {};
|
||||
if (!protyle.disabled && position === "auto" && getSelection().rangeCount > 0) {
|
||||
const range = getSelection().getRangeAt(0);
|
||||
const blockElement = hasClosestBlock(range.startContainer);
|
||||
if (blockElement) {
|
||||
|
|
@ -108,16 +116,33 @@ export const scrollCenter = (protyle: IProtyle, nodeElement?: Element, top = fal
|
|||
contentTop += topElement.clientHeight;
|
||||
topElement = topElement.nextElementSibling;
|
||||
}
|
||||
if (top) {
|
||||
if (position === "center") {
|
||||
const elementRect = nodeElement.getBoundingClientRect();
|
||||
const contentRect = protyle.contentElement.getBoundingClientRect();
|
||||
// 如果块的高度超过容器视口,让块的上边界贴着容器上边界;否则让整个块居中
|
||||
if (elementRect.height > contentRect.height) {
|
||||
protyle.contentElement.scroll({top: protyle.contentElement.scrollTop + elementRect.top - contentRect.top, behavior});
|
||||
} else {
|
||||
const elementCenter = elementRect.top + elementRect.height / 2;
|
||||
const contentCenter = contentRect.top + contentRect.height / 2;
|
||||
protyle.contentElement.scroll({top: protyle.contentElement.scrollTop + elementCenter - contentCenter, behavior});
|
||||
}
|
||||
return;
|
||||
} else if (position === "top") {
|
||||
protyle.contentElement.scroll({top: offsetTop - contentTop, behavior});
|
||||
return;
|
||||
}
|
||||
if (protyle.contentElement.scrollTop > offsetTop - 32) {
|
||||
protyle.contentElement.scroll({top: offsetTop - contentTop, behavior});
|
||||
return;
|
||||
} else if (protyle.contentElement.scrollTop + protyle.contentElement.clientHeight < offsetTop + nodeElement.clientHeight - contentTop) {
|
||||
protyle.contentElement.scroll({
|
||||
top: offsetTop + nodeElement.clientHeight - contentTop - protyle.contentElement.clientHeight,
|
||||
behavior
|
||||
});
|
||||
return;
|
||||
}
|
||||
const elementRect = nodeElement.getBoundingClientRect();
|
||||
const contentRect = protyle.contentElement.getBoundingClientRect();
|
||||
protyle.contentElement.scroll({top: protyle.contentElement.scrollTop + elementRect.top - contentRect.top - contentRect.height / 2, behavior});
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue