aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes')
-rw-r--r--src/client/views/nodes/DocumentView.tsx18
-rw-r--r--src/client/views/nodes/PDFBox.tsx3
-rw-r--r--src/client/views/nodes/WebBox.tsx50
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx10
4 files changed, 48 insertions, 33 deletions
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 47668d0f3..a5698e138 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -1,6 +1,6 @@
import { action, computed, observable, runInAction } from "mobx";
import { observer } from "mobx-react";
-import { AclAdmin, AclEdit, AclPrivate, DataSym, Doc, DocListCast, Field, Opt, StrListCast } from "../../../fields/Doc";
+import { AclAdmin, AclEdit, AclPrivate, DataSym, Doc, DocListCast, Field, Opt, StrListCast, HeightSym } from "../../../fields/Doc";
import { Document } from '../../../fields/documentSchemas';
import { Id } from '../../../fields/FieldSymbols';
import { InkTool } from '../../../fields/InkField';
@@ -44,11 +44,11 @@ import { LinkDocPreview } from "./LinkDocPreview";
import { FormattedTextBoxComment } from "./formattedText/FormattedTextBoxComment";
export type DocAfterFocusFunc = (notFocused: boolean) => boolean;
-export type DocFocusFunc = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc, dontCenter?: boolean, focused?: boolean) => void;
+export type DocFocusFunc = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc) => void;
export type StyleProviderFunc = (doc: Opt<Doc>, props: Opt<DocumentViewProps | FieldViewProps>, property: string) => any;
export interface DocComponentView {
getAnchor: () => Doc;
- scrollFocus?: (doc: Doc, smooth: boolean) => void;
+ scrollFocus?: (doc: Doc, smooth: boolean, afterFocus?: DocAfterFocusFunc) => void;
back?: () => boolean;
forward?: () => boolean;
url?: () => string;
@@ -376,9 +376,11 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
}
}
- focus = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc, dontCenter?: boolean, focused?: boolean) => {
- this._componentView?.scrollFocus?.(doc, !LinkDocPreview.LinkInfo); // bcz: smooth parameter should really be passed into focus() instead of inferred here
- return this.props.focus(doc, willZoom, scale, afterFocus, dontCenter, focused);
+ focus = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc) => {
+ if (this._componentView?.scrollFocus) {
+ return this._componentView?.scrollFocus?.(doc, !LinkDocPreview.LinkInfo, afterFocus); // bcz: smooth parameter should really be passed into focus() instead of inferred here
+ }
+ return this.props.focus(doc, willZoom, scale, afterFocus);
}
onClick = action((e: React.MouseEvent | React.PointerEvent) => {
if (!e.nativeEvent.cancelBubble && !this.Document.ignoreClick && this.props.renderDepth >= 0 &&
@@ -917,8 +919,8 @@ export class DocumentView extends React.Component<DocumentViewProps> {
toggleNativeDimensions = () => this.docView && Doc.toggleNativeDimensions(this.layoutDoc, this.docView.ContentScale, this.props.PanelWidth(), this.props.PanelHeight());
contentsActive = () => this.docView?.contentsActive();
- focus = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc, dontCenter?: boolean, focused?: boolean) => {
- return this.docView?.focus(doc, willZoom, scale, afterFocus, dontCenter, focused);
+ focus = (doc: Doc, willZoom?: boolean, scale?: number, afterFocus?: DocAfterFocusFunc, focused?: boolean) => {
+ return this.docView?.focus(doc, willZoom, scale, afterFocus, focused);
}
getBounds = () => {
if (!this.docView || !this.docView.ContentDiv || this.docView.props.renderDepth === 0 || this.docView.props.treeViewDoc || Doc.AreProtosEqual(this.props.Document, Doc.UserDoc())) {
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 496caedaa..4b926bb6f 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -22,6 +22,7 @@ import { FieldView, FieldViewProps } from './FieldView';
import { pageSchema } from "./ImageBox";
import "./PDFBox.scss";
import React = require("react");
+import { DocAfterFocusFunc } from './DocumentView';
type PdfDocument = makeInterface<[typeof documentSchema, typeof panZoomSchema, typeof pageSchema]>;
const PdfDocument = makeInterface(documentSchema, panZoomSchema, pageSchema);
@@ -79,7 +80,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
}
}
- scrollFocus = (doc: Doc, smooth: boolean) => doc !== this.rootDoc && this._pdfViewer?.scrollFocus(doc, smooth);
+ scrollFocus = (doc: Doc, smooth: boolean, afterFocus?: DocAfterFocusFunc) => { this._pdfViewer?.scrollFocus(doc, smooth, afterFocus); }
getAnchor = () => this.rootDoc;
componentWillUnmount() { this._selectReactionDisposer?.(); }
componentDidMount() {
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index ee152ddb3..d3d58b2f8 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -29,6 +29,7 @@ import { Annotation } from "../pdf/Annotation";
import { FieldView, FieldViewProps } from './FieldView';
import "./WebBox.scss";
import React = require("react");
+import { DocFocusFunc, DocAfterFocusFunc, DocumentView } from "./DocumentView";
const htmlToText = require("html-to-text");
type WebDocument = makeInterface<[typeof documentSchema]>;
@@ -110,22 +111,21 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
}
getAnchor = () => this.rootDoc;
- scrollFocus = (doc: Doc, smooth: boolean) => {
+ scrollFocus = (doc: Doc, smooth: boolean, afterFocus?: DocAfterFocusFunc) => {
if (doc !== this.rootDoc && this.webpage && this._outerRef.current) {
- this._initialScroll !== undefined && (this._initialScroll = NumCast(doc.y));
- this._ignoreScroll = true;
- if (smooth) {
- smoothScroll(500, this.webpage as any as HTMLElement, NumCast(doc.y));
- smoothScroll(500, this._outerRef.current, NumCast(doc.y));
- } else {
- this.webpage.scrollTop = NumCast(doc.y);
- this._outerRef.current.scrollTop = NumCast(doc.y);
+ const scrollTo = Utils.scrollIntoView(NumCast(doc.y), doc[HeightSym](), NumCast(this.layoutDoc._scrollTop), this.props.PanelHeight() / (this.props.scaling?.() || 1));
+ if (scrollTo !== undefined) {
+ this._initialScroll !== undefined && (this._initialScroll = scrollTo);
+ this._ignoreScroll = true;
+ this.goTo(scrollTo, smooth ? 500 : 0);
+ this.layoutDoc._scrollTop = scrollTo;
+ this._ignoreScroll = false;
+ return afterFocus?.(true);
}
- smooth && (this.layoutDoc._scrollTop = NumCast(doc.y));
- this._ignoreScroll = false;
} else {
this._initialScroll = NumCast(doc.y);
}
+ afterFocus?.(false);
}
async componentDidMount() {
@@ -164,29 +164,35 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
}
}
- var quickScroll: string | undefined = "";
+ var quickScroll = true;
this._disposers.scrollReaction = reaction(() => NumCast(this.layoutDoc._scrollTop),
(scrollTop) => {
- if (quickScroll !== undefined) {
+ if (quickScroll) {
this._initialScroll = scrollTop;
}
- else if (!this._ignoreScroll && this._outerRef.current && this.webpage) {
+ else if (!this._ignoreScroll) {
const viewTrans = StrCast(this.Document._viewTransition);
const durationMiliStr = viewTrans.match(/([0-9]*)ms/);
const durationSecStr = viewTrans.match(/([0-9.]*)s/);
const duration = durationMiliStr ? Number(durationMiliStr[1]) : durationSecStr ? Number(durationSecStr[1]) * 1000 : 0;
- if (duration) {
- smoothScroll(duration, this.webpage as any as HTMLElement, scrollTop);
- smoothScroll(duration, this._outerRef.current, scrollTop);
- } else {
- this.webpage.scrollTop = scrollTop;
- this._outerRef.current.scrollTop = scrollTop;
- }
+ this.goTo(scrollTop, duration);
}
},
{ fireImmediately: true }
);
- quickScroll = undefined;
+ quickScroll = false;
+ }
+
+ goTo = (scrollTop: number, duration: number) => {
+ if (this._outerRef.current && this.webpage) {
+ if (duration) {
+ smoothScroll(duration, this.webpage as any as HTMLElement, scrollTop);
+ smoothScroll(duration, this._outerRef.current, scrollTop);
+ } else {
+ this.webpage.scrollTop = scrollTop;
+ this._outerRef.current.scrollTop = scrollTop;
+ }
+ }
}
componentWillUnmount() {
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index c15c30803..183719e31 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -67,6 +67,7 @@ import { AnchorMenu } from '../../pdf/AnchorMenu';
import { CurrentUserUtils } from '../../../util/CurrentUserUtils';
import { DocumentManager } from '../../../util/DocumentManager';
import { LightboxView } from '../../LightboxView';
+import { DocAfterFocusFunc } from '../DocumentView';
const translateGoogleApi = require("translate-google-api");
export interface FormattedTextBoxProps {
@@ -867,7 +868,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
return this.active();//this.props.isSelected() || this._isChildActive || this.props.renderDepth === 0;
}
- scrollFocus = (doc: Doc, smooth: boolean) => {
+ scrollFocus = (doc: Doc, smooth: boolean, afterFocus?: DocAfterFocusFunc) => {
const anchorId = doc[Id];
const findAnchorFrag = (frag: Fragment, editor: EditorView) => {
const nodes: Node[] = [];
@@ -905,8 +906,13 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
editor.dispatch(editor.state.tr.setSelection(new TextSelection(selection.$from, selection.$from)).scrollIntoView());
const escAnchorId = anchorId[0] > '0' && anchorId[0] <= '9' ? `\\3${anchorId[0]} ${anchorId.substr(1)}` : anchorId;
addStyleSheetRule(FormattedTextBox._highlightStyleSheet, `${escAnchorId}`, { background: "yellow" });
- setTimeout(() => clearStyleSheetRules(FormattedTextBox._highlightStyleSheet), 1500);
+ setTimeout(() => {
+ clearStyleSheetRules(FormattedTextBox._highlightStyleSheet);
+ afterFocus?.(true);
+ }, 1500);
}
+ } else {
+ afterFocus?.(false);
}
}