diff options
author | mehekj <mehek.jethani@gmail.com> | 2022-03-20 10:29:42 -0400 |
---|---|---|
committer | mehekj <mehek.jethani@gmail.com> | 2022-03-20 10:29:42 -0400 |
commit | 0a5e02a87fdabff5ff8399829ff857cae90fc1e2 (patch) | |
tree | b7c05080dac66366768f23e59a43f62533a22415 /src/client/views/nodes/WebBox.tsx | |
parent | 1f7cf7babc76ecff5aef5fe663c48e067e85dd26 (diff) |
Revert "Merge remote-tracking branch 'origin/speedups2' into temporalmedia-mehek"
This reverts commit 1f7cf7babc76ecff5aef5fe663c48e067e85dd26, reversing
changes made to 1e3ad4de06f83eab54628de660529fefb9a0dc63.
Diffstat (limited to 'src/client/views/nodes/WebBox.tsx')
-rw-r--r-- | src/client/views/nodes/WebBox.tsx | 176 |
1 files changed, 63 insertions, 113 deletions
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 7ff47107e..9956cc36b 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -3,20 +3,21 @@ import { action, computed, IReactionDisposer, observable, ObservableMap, reactio import { observer } from "mobx-react"; import * as WebRequest from 'web-request'; import { Doc, DocListCast, HeightSym, Opt, WidthSym } from "../../../fields/Doc"; +import { documentSchema } from "../../../fields/documentSchemas"; import { Id } from "../../../fields/FieldSymbols"; import { HtmlField } from "../../../fields/HtmlField"; import { InkTool } from "../../../fields/InkField"; import { List } from "../../../fields/List"; -import { listSpec } from "../../../fields/Schema"; +import { listSpec, makeInterface } from "../../../fields/Schema"; import { ComputedField } from "../../../fields/ScriptField"; -import { Cast, ImageCast, NumCast, StrCast } from "../../../fields/Types"; -import { ImageField, WebField } from "../../../fields/URLField"; +import { Cast, NumCast, StrCast } from "../../../fields/Types"; +import { WebField } from "../../../fields/URLField"; import { TraceMobx } from "../../../fields/util"; import { emptyFunction, getWordAtPoint, OmitKeys, returnFalse, returnOne, setupMoveUpEvents, smoothScroll, Utils } from "../../../Utils"; import { Docs } from "../../documents/Documents"; import { CurrentUserUtils } from "../../util/CurrentUserUtils"; import { KeyCodes } from "../../util/KeyCodes"; -import { ScriptingGlobals } from "../../util/ScriptingGlobals"; +import { Scripting } from "../../util/Scripting"; import { SnappingManager } from "../../util/SnappingManager"; import { undoBatch } from "../../util/UndoManager"; import { MarqueeOptionsMenu } from "../collections/collectionFreeForm"; @@ -35,18 +36,18 @@ import { StyleProp } from "../StyleProvider"; import { DocumentViewProps } from "./DocumentView"; import { FieldView, FieldViewProps } from './FieldView'; import { LinkDocPreview } from "./LinkDocPreview"; -import { VideoBox } from "./VideoBox"; import "./WebBox.scss"; import React = require("react"); -const { CreateImage } = require("./WebBoxRenderer"); const _global = (window /* browser */ || global /* node */) as any; const htmlToText = require("html-to-text"); +type WebDocument = makeInterface<[typeof documentSchema]>; +const WebDocument = makeInterface(documentSchema); + @observer -export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps & FieldViewProps>() { +export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps & FieldViewProps, WebDocument>(WebDocument) { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(WebBox, fieldKey); } public static openSidebarWidth = 250; - public static sidebarResizerWidth = 5; private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean, hide: boolean) => void); private _mainCont: React.RefObject<HTMLDivElement> = React.createRef(); private _outerRef: React.RefObject<HTMLDivElement> = React.createRef(); @@ -62,7 +63,6 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps @observable private _searching: boolean = false; @observable private _showSidebar = false; @observable private _scrollTimer: any; - @observable private _webPageHasBeenRendered = false; @observable private _overlayAnnoInfo: Opt<Doc>; @observable private _marqueeing: number[] | undefined; @observable private _isAnnotating = false; @@ -76,7 +76,6 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps @computed get allAnnotations() { return DocListCast(this.dataDoc[this.annotationKey]); } @computed get inlineTextAnnotations() { return this.allAnnotations.filter(a => a.textInlineAnnotations); } @computed get webField() { return Cast(this.dataDoc[this.props.fieldKey], WebField)?.url; } - @computed get webThumb() { return ImageCast(this.layoutDoc["thumb-frozen"], ImageCast(this.layoutDoc.thumb))?.url; } constructor(props: any) { super(props); @@ -104,7 +103,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps return true; } async componentDidMount() { - this.props.setContentView?.(this); // this tells the DocumentView that this WebBox is the "content" of the document. this allows the DocumentView to call WebBox relevant methods to configure the UI (eg, show back/forward buttons) + this.props.setContentView?.(this); // this tells the DocumentView that this AudioBox is the "content" of the document. this allows the DocumentView to indirectly call getAnchor() on the AudioBox when making a link. runInAction(() => { this._annotationKeySuffix = () => this._urlHash + "-annotations"; @@ -112,48 +111,6 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps this.dataDoc[this.fieldKey + "-annotations"] = ComputedField.MakeFunction(`copyField(this["${this.fieldKey}-"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"-annotations"`); this.dataDoc[this.fieldKey + "-sidebar"] = ComputedField.MakeFunction(`copyField(this["${this.fieldKey}-"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"-sidebar"`); }); - reaction(() => this.props.isSelected(), - async (selected) => { - if (selected) { - this._webPageHasBeenRendered = true; - setTimeout(action(() => { - this._scrollHeight = Math.max(this.scrollHeight, this._iframe?.contentDocument?.body.scrollHeight || 0); - if (this._initialScroll !== undefined && this._outerRef.current) { - setTimeout(() => { - this._outerRef.current!.scrollTop = this._initialScroll!; - this._initialScroll = undefined; - }); - } - })); - } else if (!this.props.isContentActive() && - !this.props.docViewPath().lastElement()?.docView?._pendingDoubleClick && /// don't create a thumbnail when double-clicking to enter lightbox because thumbnail will be empty - LightboxView.LightboxDoc !== this.rootDoc) { // don't create a thumbnail if entering Lightbox from maximize either, since thumb will be empty. - const imageBitmap = ImageCast(this.layoutDoc["thumb-frozen"])?.url.href; - if (this._iframe && !imageBitmap) { - var htmlString = this._iframe.contentDocument && new XMLSerializer().serializeToString(this._iframe.contentDocument); - if (!htmlString) { - htmlString = await (await fetch(Utils.CorsProxy(this.webField!.href))).text(); - } - this.layoutDoc.thumb = undefined; - const nativeWidth = NumCast(this.layoutDoc.nativeWidth); - CreateImage( - this._webUrl.endsWith("/") ? this._webUrl.substring(0, this._webUrl.length - 1) : this._webUrl, - this._iframe.contentDocument?.styleSheets ?? [], - htmlString, - nativeWidth, - nativeWidth * this.props.PanelHeight() / this.props.PanelWidth(), - NumCast(this.layoutDoc._scrollTop) - ).then - ((dataUrl: any) => { - VideoBox.convertDataUri(dataUrl, this.layoutDoc[Id] + "-thumb" + (new Date()).getTime(), true).then( - returnedfilename => setTimeout(action(() => this.layoutDoc.thumb = new ImageField(returnedfilename)), 500)); - }) - .catch(function (error: any) { - console.error('oops, something went wrong!', error); - }); - } - } - }); this._disposers.autoHeight = reaction(() => this.layoutDoc._autoHeight, autoHeight => { @@ -335,6 +292,12 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps iframe.contentDocument.addEventListener("pointerdown", this.iframeDown); this._scrollHeight = Math.max(this.scrollHeight, iframe?.contentDocument.body.scrollHeight); setTimeout(action(() => this._scrollHeight = Math.max(this.scrollHeight, iframe?.contentDocument?.body.scrollHeight || 0)), 5000); + const initialScroll = this._initialScroll; + if (initialScroll !== undefined && this._outerRef.current) { + // bcz: not sure why this happens, but if the webpage isn't ready yet, it's scroll height seems to be limited. So we need to wait tp set scroll location to what we want. + setTimeout(() => this._outerRef.current!.scrollTop = initialScroll); + this._initialScroll = undefined; + } iframe.setAttribute("enable-annotation", "true"); iframe.contentDocument.addEventListener("click", undoBatch(action((e: MouseEvent) => { let href = ""; @@ -390,46 +353,42 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps } } - forward = (checkAvailable?: boolean) => { + @action + forward = () => { const future = Cast(this.dataDoc[this.fieldKey + "-future"], listSpec("string"), []); const history = Cast(this.dataDoc[this.fieldKey + "-history"], listSpec("string"), []); - if (checkAvailable) return future.length; - runInAction(() => { - if (future.length) { - const curUrl = this._url; - this.dataDoc[this.fieldKey + "-history"] = new List<string>([...history, this._url]); - this.dataDoc[this.fieldKey] = new WebField(new URL(future.pop()!)); - if (this._webUrl === this._url) { - this._webUrl = curUrl; - setTimeout(action(() => this._webUrl = this._url)); - } else { - this._webUrl = this._url; - } - return true; + if (future.length) { + const curUrl = this._url; + this.dataDoc[this.fieldKey + "-history"] = new List<string>([...history, this._url]); + this.dataDoc[this.fieldKey] = new WebField(new URL(future.pop()!)); + if (this._webUrl === this._url) { + this._webUrl = curUrl; + setTimeout(action(() => this._webUrl = this._url)); + } else { + this._webUrl = this._url; } - }); + return true; + } return false; } - back = (checkAvailable?: boolean) => { + @action + back = () => { const future = Cast(this.dataDoc[this.fieldKey + "-future"], listSpec("string")); const history = Cast(this.dataDoc[this.fieldKey + "-history"], listSpec("string"), []); - if (checkAvailable) return history.length; - runInAction(() => { - if (history.length) { - const curUrl = this._url; - if (future === undefined) this.dataDoc[this.fieldKey + "-future"] = new List<string>([this._url]); - else this.dataDoc[this.fieldKey + "-future"] = new List<string>([...future, this._url]); - this.dataDoc[this.fieldKey] = new WebField(new URL(history.pop()!)); - if (this._webUrl === this._url) { - this._webUrl = curUrl; - setTimeout(action(() => this._webUrl = this._url)); - } else { - this._webUrl = this._url; - } - return true; + if (history.length) { + const curUrl = this._url; + if (future === undefined) this.dataDoc[this.fieldKey + "-future"] = new List<string>([this._url]); + else this.dataDoc[this.fieldKey + "-future"] = new List<string>([...future, this._url]); + this.dataDoc[this.fieldKey] = new WebField(new URL(history.pop()!)); + if (this._webUrl === this._url) { + this._webUrl = curUrl; + setTimeout(action(() => this._webUrl = this._url)); + } else { + this._webUrl = this._url; } - }); + return true; + } return false; } @@ -493,8 +452,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps <button className="submitUrl" onClick={() => this.submitURL(this._keyInput.current!.value)} onDragOver={e => e.stopPropagation()} onDrop={this.onWebUrlDrop}> GO </button> - <button className="submitUrl" onClick={() => this.back}> <FontAwesomeIcon icon="caret-left" size="lg" /> </button> - <button className="submitUrl" onClick={() => this.forward}> <FontAwesomeIcon icon="caret-right" size="lg" /> </button> + <button className="submitUrl" onClick={this.back}> <FontAwesomeIcon icon="caret-left" size="lg" /> </button> + <button className="submitUrl" onClick={this.forward}> <FontAwesomeIcon icon="caret-right" size="lg" /> </button> </div> </div> ); @@ -553,7 +512,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps } @computed get urlContent() { - if (this._hackHide || (this.webThumb && (!this._webPageHasBeenRendered && LightboxView.LightboxDoc !== this.rootDoc))) return (null); + if (this._hackHide) return (null); const field = this.dataDoc[this.props.fieldKey]; let view; if (field instanceof HtmlField) { @@ -571,7 +530,6 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps style={{ pointerEvents: this._scrollTimer ? "none" : undefined }} // if we allow pointer events when scrolling is on, then reversing direction does not work smoothly ref={action((r: HTMLIFrameElement | null) => this._iframe = r)} src={"https://crossorigin.me/https://cs.brown.edu"} />; } - setTimeout(action(() => this._webPageHasBeenRendered = true)); return view; } @@ -584,37 +542,34 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps if (!this.layoutDoc._showSidebar) this.toggleSidebar(); return this.addDocumentWrapper(doc, sidebarKey); } - @observable _draggingSidebar = false; - sidebarBtnDown = (e: React.PointerEvent, onButton: boolean) => { // onButton determines whether the width of the pdf box changes, or just the ratio of the sidebar to the pdf - setupMoveUpEvents(this, e, action((e, down, delta) => { - this._draggingSidebar = true; + sidebarBtnDown = (e: React.PointerEvent) => { + setupMoveUpEvents(this, e, (e, down, delta) => { const localDelta = this.props.ScreenToLocalTransform().scale(this.props.scaling?.() || 1).transformDirection(delta[0], delta[1]); const nativeWidth = NumCast(this.layoutDoc[this.fieldKey + "-nativeWidth"]); const curNativeWidth = NumCast(this.layoutDoc.nativeWidth, nativeWidth); - const ratio = (curNativeWidth + (onButton ? 1 : -1) * localDelta[0] / (this.props.scaling?.() || 1)) / nativeWidth; + const ratio = (curNativeWidth + localDelta[0] / (this.props.scaling?.() || 1)) / nativeWidth; if (ratio >= 1) { this.layoutDoc.nativeWidth = nativeWidth * ratio; - onButton && (this.layoutDoc._width = this.layoutDoc[WidthSym]() + localDelta[0]); + this.layoutDoc._width = this.layoutDoc[WidthSym]() + localDelta[0]; this.layoutDoc._showSidebar = nativeWidth !== this.layoutDoc._nativeWidth; } return false; - }), action(() => this._draggingSidebar = false), () => this.toggleSidebar()); + }, emptyFunction, () => this.toggleSidebar()); } @observable _previewNativeWidth: Opt<number> = undefined; @observable _previewWidth: Opt<number> = undefined; toggleSidebar = action((preview: boolean = false) => { const nativeWidth = NumCast(this.layoutDoc[this.fieldKey + "-nativeWidth"]); - const sideratio = ((!this.layoutDoc.nativeWidth || this.layoutDoc.nativeWidth === nativeWidth ? WebBox.openSidebarWidth : 0) + nativeWidth) / nativeWidth; - const pdfratio = ((!this.layoutDoc.nativeWidth || this.layoutDoc.nativeWidth === nativeWidth ? WebBox.openSidebarWidth + WebBox.sidebarResizerWidth : 0) + nativeWidth) / nativeWidth; + const ratio = ((!this.layoutDoc.nativeWidth || this.layoutDoc.nativeWidth === nativeWidth ? WebBox.openSidebarWidth : 0) + nativeWidth) / nativeWidth; const curNativeWidth = NumCast(this.layoutDoc.nativeWidth, nativeWidth); if (preview) { - this._previewNativeWidth = nativeWidth * sideratio; - this._previewWidth = this.layoutDoc[WidthSym]() * nativeWidth * sideratio / curNativeWidth; + this._previewNativeWidth = nativeWidth * ratio; + this._previewWidth = this.layoutDoc[WidthSym]() * nativeWidth * ratio / curNativeWidth; this._showSidebar = true; } else { - this.layoutDoc.nativeWidth = nativeWidth * pdfratio; - this.layoutDoc._width = this.layoutDoc[WidthSym]() * nativeWidth * pdfratio / curNativeWidth; + this.layoutDoc.nativeWidth = nativeWidth * ratio; + this.layoutDoc._width = this.layoutDoc[WidthSym]() * nativeWidth * ratio / curNativeWidth; this.layoutDoc._showSidebar = nativeWidth !== this.layoutDoc._nativeWidth; } }); @@ -678,7 +633,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps } return this.props.styleProvider?.(doc, props, property); } - pointerEvents = () => !this._draggingSidebar && this.props.isContentActive() && this.props.pointerEvents !== "none" && !MarqueeOptionsMenu.Instance.isShown() ? "all" : SnappingManager.GetIsDragging() ? undefined : "none"; + pointerEvents = () => this.props.isContentActive() && this.props.pointerEvents !== "none" && !MarqueeOptionsMenu.Instance.isShown() ? "all" : SnappingManager.GetIsDragging() ? undefined : "none"; render() { const pointerEvents = this.props.layerProvider?.(this.layoutDoc) === false ? "none" : this.props.pointerEvents ? this.props.pointerEvents as any : undefined; const previewScale = this._previewNativeWidth ? 1 - this.sidebarWidth() / this._previewNativeWidth : 1; @@ -709,17 +664,13 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps pointerEvents={this._isAnnotating || SnappingManager.GetIsDragging() ? "all" : "none"} />; return ( <div className="webBox" ref={this._mainCont} - style={{ pointerEvents: this.pointerEvents(), display: this.props.thumbShown?.() ? "none" : undefined }} > - <div className="webBox-background" onPointerDown={e => this.sidebarBtnDown(e, false)} /> - <div className="webBox-container" style={{ - position: "absolute", - width: `calc(${100 / scale}% - ${(this.sidebarWidth() + WebBox.sidebarResizerWidth) / scale * (this._previewWidth ? scale : 1)}px)`, - transform: `scale(${scale})`, - pointerEvents - }} onContextMenu={this.specificContextMenu}> + style={{ pointerEvents: this.pointerEvents() }} > + <div className={`webBox-container`} style={{ pointerEvents }} onContextMenu={this.specificContextMenu}> <div className={"webBox-outerContent"} ref={this._outerRef} style={{ + width: `calc(${100 / scale}% - ${this.sidebarWidth() / scale * (this._previewWidth ? scale : 1)}px)`, height: `${100 / scale}%`, + transform: `scale(${scale})`, pointerEvents }} onWheel={e => { e.stopPropagation(); e.preventDefault(); }} // block wheel events from propagating since they're handled by the iframe @@ -752,7 +703,6 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps </div > <SidebarAnnos ref={this._sidebarRef} {...this.props} - whenChildContentsActiveChanged={this.whenChildContentsActiveChanged} fieldKey={this.fieldKey + "-" + this._urlHash} rootDoc={this.rootDoc} layoutDoc={this.layoutDoc} @@ -770,11 +720,11 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps top: StrCast(this.rootDoc._showTitle) === "title" ? 20 : 5, backgroundColor: this.SidebarShown ? Colors.MEDIUM_BLUE : Colors.BLACK }} - onPointerDown={e => this.sidebarBtnDown(e, true)} > + onPointerDown={this.sidebarBtnDown} > <FontAwesomeIcon style={{ color: Colors.WHITE }} icon={"comment-alt"} size="sm" /> </div> {!this.props.isContentActive() ? (null) : this.searchUI} </div>); } } -ScriptingGlobals.add(function urlHash(url: string) { return WebBox.urlHash(url); });
\ No newline at end of file +Scripting.addGlobal(function urlHash(url: string) { return WebBox.urlHash(url); });
\ No newline at end of file |