aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/WebBox.tsx
diff options
context:
space:
mode:
authorEric <ericmabr@gmail.com>2023-03-15 17:29:33 -0400
committerEric <ericmabr@gmail.com>2023-03-15 17:29:33 -0400
commit06980bb5fa9f72ad20896be132bcc29e9ae4617e (patch)
treee98357191b26b14bd17b3f8d4656b6789022e1cd /src/client/views/nodes/WebBox.tsx
parentc50fc16a161379b20eed04794d1433499b1483c7 (diff)
parent20c0190e820f2bd343693368b7ef55a91f19c880 (diff)
Merge branch 'master' into UI_Update_Eric_Ma
Diffstat (limited to 'src/client/views/nodes/WebBox.tsx')
-rw-r--r--src/client/views/nodes/WebBox.tsx107
1 files changed, 63 insertions, 44 deletions
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 5bbe521a7..f7425b26a 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -1,5 +1,5 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction, trace } from 'mobx';
+import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as WebRequest from 'web-request';
import { Doc, DocListCast, HeightSym, Opt, WidthSym } from '../../../fields/Doc';
@@ -11,8 +11,10 @@ import { listSpec } from '../../../fields/Schema';
import { Cast, ImageCast, NumCast, StrCast } from '../../../fields/Types';
import { ImageField, WebField } from '../../../fields/URLField';
import { TraceMobx } from '../../../fields/util';
-import { emptyFunction, getWordAtPoint, OmitKeys, returnEmptyString, returnFalse, returnOne, setupMoveUpEvents, smoothScroll, StopEvent, Utils } from '../../../Utils';
+import { emptyFunction, getWordAtPoint, OmitKeys, returnFalse, returnOne, setupMoveUpEvents, smoothScroll, StopEvent, Utils } from '../../../Utils';
import { Docs, DocUtils } from '../../documents/Documents';
+import { DocumentManager } from '../../util/DocumentManager';
+import { DragManager } from '../../util/DragManager';
import { ScriptingGlobals } from '../../util/ScriptingGlobals';
import { SnappingManager } from '../../util/SnappingManager';
import { undoBatch, UndoManager } from '../../util/UndoManager';
@@ -21,7 +23,6 @@ import { CollectionFreeFormView } from '../collections/collectionFreeForm/Collec
import { ContextMenu } from '../ContextMenu';
import { ContextMenuProps } from '../ContextMenuItem';
import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../DocComponent';
-import { DocumentDecorations } from '../DocumentDecorations';
import { Colors } from '../global/globalEnums';
import { LightboxView } from '../LightboxView';
import { MarqueeAnnotator } from '../MarqueeAnnotator';
@@ -29,13 +30,12 @@ import { AnchorMenu } from '../pdf/AnchorMenu';
import { Annotation } from '../pdf/Annotation';
import { SidebarAnnos } from '../SidebarAnnos';
import { StyleProp } from '../StyleProvider';
-import { DocFocusOptions, DocumentView, DocumentViewInternal, DocumentViewProps } from './DocumentView';
+import { DocFocusOptions, DocumentView, DocumentViewProps, OpenWhere } from './DocumentView';
import { FieldView, FieldViewProps } from './FieldView';
import { LinkDocPreview } from './LinkDocPreview';
-import { VideoBox } from './VideoBox';
+import { PinProps, PresBox } from './trails';
import './WebBox.scss';
import React = require('react');
-import { DragManager } from '../../util/DragManager';
const { CreateImage } = require('./WebBoxRenderer');
const _global = (window /* browser */ || global) /* node */ as any;
const htmlToText = require('html-to-text');
@@ -90,7 +90,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
return this.allAnnotations.filter(a => a.textInlineAnnotations);
}
@computed get webField() {
- return Cast(this.dataDoc[this.props.fieldKey], WebField)?.url;
+ return Cast(this.rootDoc[this.props.fieldKey], WebField)?.url;
}
@computed get webThumb() {
return (
@@ -145,6 +145,9 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
const nativeWidth = NumCast(this.layoutDoc.nativeWidth);
const nativeHeight = (nativeWidth * this.props.PanelHeight()) / this.props.PanelWidth();
if (
+ !this.props.isSelected(true) &&
+ !Doc.IsBrushedDegree(this.rootDoc) &&
+ !this.isAnyChildContentActive() &&
!this.rootDoc.thumbLockout &&
!this.props.dontRegisterView &&
this._iframe &&
@@ -163,7 +166,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
console.log('BAD DATA IN THUMB CREATION');
return;
}
- VideoBox.convertDataUri(data_url, this.layoutDoc[Id] + '-icon' + new Date().getTime(), true, this.layoutDoc[Id] + '-icon').then(returnedfilename =>
+ Utils.convertDataUri(data_url, this.layoutDoc[Id] + '-icon' + new Date().getTime(), true, this.layoutDoc[Id] + '-icon').then(returnedfilename =>
setTimeout(
action(() => {
this.rootDoc.thumbLockout = false;
@@ -181,6 +184,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
});
}
};
+ _thumbTimer: any;
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)
@@ -188,14 +192,16 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
this._annotationKeySuffix = () => this._urlHash + '-annotations';
const reqdFuncs: { [key: string]: string } = {};
// bcz: need to make sure that doc.data-annotations points to the currently active web page's annotations (this could/should be when the doc is created)
- reqdFuncs[this.fieldKey + '-annotations'] = `copyField(this["${this.fieldKey}-"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"-annotations"`;
- reqdFuncs[this.fieldKey + '-sidebar'] = `copyField(this["${this.fieldKey}-"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"-sidebar"`;
- DocUtils.AssignScripts(this.dataDoc, {}, reqdFuncs);
+ reqdFuncs[this.fieldKey + '-annotations'] = `copyField(this["${this.fieldKey}-"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"-annotations"])`;
+ reqdFuncs[this.fieldKey + '-annotations-setter'] = `this["${this.fieldKey}-"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"-annotations"] = value`;
+ reqdFuncs[this.fieldKey + '-sidebar'] = `copyField(this["${this.fieldKey}-"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"-sidebar"])`;
+ DocUtils.AssignScripts(this.rootDoc, {}, reqdFuncs);
});
reaction(
() => this.props.isSelected(true) || this.isAnyChildContentActive() || Doc.isBrushedHighlightedDegree(this.props.Document),
async selected => {
if (selected) {
+ this._thumbTimer && clearTimeout(this._thumbTimer);
this._webPageHasBeenRendered = true;
} else if (
(!this.props.isContentActive(true) || SnappingManager.GetIsDragging()) && // update thumnail when unselected AND (no child annotation is active OR we've started dragging the document in which case no additional deselect will occur so this is the only chance to update the thumbnail)
@@ -203,7 +209,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
LightboxView.LightboxDoc !== this.rootDoc
) {
// don't create a thumbnail if entering Lightbox from maximize either, since thumb will be empty.
- this.updateThumb();
+ this._thumbTimer && clearTimeout(this._thumbTimer);
+ this._thumbTimer = setTimeout(this.updateThumb, 2000);
}
},
{ fireImmediately: this.props.isSelected(true) || this.isAnyChildContentActive() || (Doc.isBrushedHighlightedDegreeUnmemoized(this.props.Document) ? true : false) }
@@ -293,27 +300,35 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
setBrushViewer = (func?: (view: { width: number; height: number; panX: number; panY: number }) => void) => (this._setBrushViewer = func);
brushView = (view: { width: number; height: number; panX: number; panY: number }) => this._setBrushViewer?.(view);
- scrollFocus = (doc: Doc, options: DocFocusOptions) => {
- if (this._url && StrCast(doc.webUrl) !== this._url) this.submitURL(StrCast(doc.webUrl), options.instant);
- if (DocListCast(this.props.Document[this.fieldKey + '-sidebar']).includes(doc) && !this.SidebarShown) {
- this.toggleSidebar(options.instant);
- }
- if (this._sidebarRef?.current?.makeDocUnfiltered(doc)) return 1;
- if (doc !== this.rootDoc && this._outerRef.current) {
+ focus = (anchor: Doc, options: DocFocusOptions) => {
+ if (anchor !== this.rootDoc && this._outerRef.current) {
const windowHeight = this.props.PanelHeight() / (this.props.NativeDimScaling?.() || 1);
- const scrollTo = Utils.scrollIntoView(NumCast(doc.y), doc[HeightSym](), NumCast(this.layoutDoc._scrollTop), windowHeight, windowHeight * 0.1, Math.max(NumCast(doc.y) + doc[HeightSym](), this._scrollHeight));
- if (scrollTo !== undefined && this._initialScroll === undefined) {
- const focusSpeed = options.instant ? 0 : options.zoomTime ?? 500;
- this.goTo(scrollTo, focusSpeed, options.easeFunc);
- return focusSpeed;
- } else if (!this._webPageHasBeenRendered || !this._scrollHeight || this._initialScroll !== undefined) {
- this._initialScroll = scrollTo;
+ const scrollTo = Utils.scrollIntoView(NumCast(anchor.y), anchor[HeightSym](), NumCast(this.layoutDoc._scrollTop), windowHeight, windowHeight * 0.1, Math.max(NumCast(anchor.y) + anchor[HeightSym](), this._scrollHeight));
+ if (scrollTo !== undefined) {
+ if (this._initialScroll === undefined) {
+ this.goTo(scrollTo, options.zoomTime ?? 500, options.easeFunc);
+ } else {
+ this._initialScroll = scrollTo;
+ }
}
}
- return undefined;
};
- getAnchor = (addAsAnnotation: boolean) => {
+ getView = async (doc: Doc) => {
+ if (this.rootDoc.layoutKey === 'layout_icon') this.props.DocumentView?.().iconify();
+ if (this._url && StrCast(doc.webUrl) !== this._url) this.submitURL(StrCast(doc.webUrl));
+ if (this._sidebarRef?.current?.makeDocUnfiltered(doc) && !this.SidebarShown) this.toggleSidebar(false);
+ return new Promise<Opt<DocumentView>>(res => DocumentManager.Instance.AddViewRenderedCb(doc, dv => res(dv)));
+ };
+
+ sidebarAddDocTab = (doc: Doc, where: OpenWhere) => {
+ if (DocListCast(this.props.Document[this.props.fieldKey + '-sidebar']).includes(doc) && !this.SidebarShown) {
+ this.toggleSidebar(false);
+ return true;
+ }
+ return this.props.addDocTab(doc, where);
+ };
+ getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => {
let ele: Opt<HTMLDivElement> = undefined;
try {
const contents = this._iframe?.contentWindow?.getSelection()?.getRangeAt(0).cloneContents();
@@ -330,9 +345,11 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
unrendered: true,
annotationOn: this.rootDoc,
});
+ PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), scrollable: true, pannable: true } }, this.rootDoc);
anchor.text = ele?.textContent ?? '';
anchor.textHtml = ele?.innerHTML;
- addAsAnnotation && this.addDocumentWrapper(anchor);
+ //addAsAnnotation &&
+ this.addDocumentWrapper(anchor);
return anchor;
};
@@ -527,14 +544,14 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
};
forward = (checkAvailable?: boolean) => {
- const future = Cast(this.dataDoc[this.fieldKey + '-future'], listSpec('string'), []);
- const history = Cast(this.dataDoc[this.fieldKey + '-history'], listSpec('string'), []);
+ const future = Cast(this.rootDoc[this.fieldKey + '-future'], listSpec('string'), []);
+ const history = Cast(this.rootDoc[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()!));
+ this.rootDoc[this.fieldKey + '-history'] = new List<string>([...history, this._url]);
+ this.rootDoc[this.fieldKey] = new WebField(new URL(future.pop()!));
if (this._webUrl === this._url) {
this._webUrl = curUrl;
setTimeout(action(() => (this._webUrl = this._url)));
@@ -548,15 +565,15 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
};
back = (checkAvailable?: boolean) => {
- const future = Cast(this.dataDoc[this.fieldKey + '-future'], listSpec('string'));
- const history = Cast(this.dataDoc[this.fieldKey + '-history'], listSpec('string'), []);
+ const future = Cast(this.rootDoc[this.fieldKey + '-future'], listSpec('string'));
+ const history = Cast(this.rootDoc[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 (future === undefined) this.rootDoc[this.fieldKey + '-future'] = new List<string>([this._url]);
+ else this.rootDoc[this.fieldKey + '-future'] = new List<string>([...future, this._url]);
+ this.layoutDoc[this.fieldKey] = new WebField(new URL(history.pop()!));
if (this._webUrl === this._url) {
this._webUrl = curUrl;
setTimeout(action(() => (this._webUrl = this._url)));
@@ -583,11 +600,11 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
if (!newUrl) return;
if (!newUrl.startsWith('http')) newUrl = 'http://' + newUrl;
try {
- const future = Cast(this.dataDoc[this.fieldKey + '-future'], listSpec('string'));
- const history = Cast(this.dataDoc[this.fieldKey + '-history'], listSpec('string'));
+ const future = Cast(this.rootDoc[this.fieldKey + '-future'], listSpec('string'));
+ const history = Cast(this.rootDoc[this.fieldKey + '-history'], listSpec('string'));
const url = this.webField?.toString();
if (url && !preview) {
- this.dataDoc[this.fieldKey + '-history'] = new List<string>([...(history || []), url]);
+ this.rootDoc[this.fieldKey + '-history'] = new List<string>([...(history || []), url]);
this.layoutDoc._scrollTop = 0;
if (this._webPageHasBeenRendered) {
this.layoutDoc.thumb = undefined;
@@ -598,7 +615,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
future && (future.length = 0);
}
if (!preview) {
- this.dataDoc[this.fieldKey] = new WebField(new URL(newUrl));
+ this.layoutDoc[this.fieldKey] = new WebField(new URL(newUrl));
!dontUpdateIframe && (this._webUrl = this._url);
}
} catch (e) {
@@ -724,7 +741,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
@computed get urlContent() {
if (this._hackHide || (this.webThumb && !this._webPageHasBeenRendered && LightboxView.LightboxDoc !== this.rootDoc)) return null;
this.props.thumbShown?.();
- const field = this.dataDoc[this.props.fieldKey];
+ const field = this.rootDoc[this.props.fieldKey];
let view;
if (field instanceof HtmlField) {
view = <span className="webBox-htmlSpan" contentEditable onPointerDown={e => e.stopPropagation()} dangerouslySetInnerHTML={{ __html: field.html }} />;
@@ -831,7 +848,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
toggleSidebar = action((preview: boolean = false) => {
var nativeWidth = NumCast(this.layoutDoc[this.fieldKey + '-nativeWidth']);
if (!nativeWidth) {
- const defaultNativeWidth = this.dataDoc[this.fieldKey] instanceof WebField ? 850 : this.Document[WidthSym]();
+ const defaultNativeWidth = this.rootDoc[this.fieldKey] instanceof WebField ? 850 : this.Document[WidthSym]();
Doc.SetNativeWidth(this.dataDoc, Doc.NativeWidth(this.dataDoc) || defaultNativeWidth);
Doc.SetNativeHeight(this.dataDoc, Doc.NativeHeight(this.dataDoc) || (this.Document[HeightSym]() / this.Document[WidthSym]()) * defaultNativeWidth);
nativeWidth = NumCast(this.layoutDoc[this.fieldKey + '-nativeWidth']);
@@ -901,6 +918,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
PanelHeight={this.panelHeight}
ScreenToLocalTransform={this.scrollXf}
NativeDimScaling={returnOne}
+ focus={this.focus}
dropAction={'alias'}
docFilters={docFilters}
select={emptyFunction}
@@ -987,6 +1005,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
pointerEvents = () => (!this._draggingSidebar && this.props.isContentActive() && this.props.pointerEvents?.() !== 'none' && !MarqueeOptionsMenu.Instance?.isShown() ? 'all' : SnappingManager.GetIsDragging() ? undefined : 'none');
annotationPointerEvents = () => (this._isAnnotating || SnappingManager.GetIsDragging() || Doc.ActiveTool !== InkTool.None ? 'all' : 'none');
render() {
+ setTimeout(() => DocListCast(this.rootDoc[this.annotationKey]).forEach(doc => (doc.webUrl = this._url)));
const previewScale = this._previewNativeWidth ? 1 - this.sidebarWidth() / this._previewNativeWidth : 1;
const pointerEvents = this.layoutDoc._lockedPosition ? 'none' : (this.props.pointerEvents?.() as any);
const scale = previewScale * (this.props.NativeDimScaling?.() || 1);