aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/WebBox.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/WebBox.tsx')
-rw-r--r--src/client/views/nodes/WebBox.tsx235
1 files changed, 156 insertions, 79 deletions
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 033b01d24..8835ea5e7 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -1,22 +1,26 @@
+/* eslint-disable jsx-a11y/control-has-associated-label */
+/* eslint-disable jsx-a11y/no-static-element-interactions */
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { htmlToText } from 'html-to-text';
import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import * as WebRequest from 'web-request';
-import { Doc, DocListCast, Field, Opt } from '../../../fields/Doc';
+import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, ClientUtils, DivHeight, getWordAtPoint, lightOrDark, returnFalse, returnOne, returnZero, setupMoveUpEvents, smoothScroll } from '../../../ClientUtils';
+import { Doc, DocListCast, Field, FieldType, Opt } from '../../../fields/Doc';
import { Id } from '../../../fields/FieldSymbols';
import { HtmlField } from '../../../fields/HtmlField';
import { InkTool } from '../../../fields/InkField';
import { List } from '../../../fields/List';
import { RefField } from '../../../fields/RefField';
import { listSpec } from '../../../fields/Schema';
-import { Cast, NumCast, StrCast, WebCast } from '../../../fields/Types';
+import { Cast, NumCast, StrCast, toList, WebCast } from '../../../fields/Types';
import { ImageField, WebField } from '../../../fields/URLField';
import { TraceMobx } from '../../../fields/util';
-import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, DivHeight, emptyFunction, getWordAtPoint, lightOrDark, returnFalse, returnOne, returnZero, setupMoveUpEvents, smoothScroll, stringHash, Utils } from '../../../Utils';
-import { Docs, DocUtils } from '../../documents/Documents';
-import { DocumentManager } from '../../util/DocumentManager';
+import { emptyFunction, stringHash } from '../../../Utils';
+import { Docs } from '../../documents/Documents';
+import { DocumentType } from '../../documents/DocumentTypes';
+import { DocUtils } from '../../documents/DocUtils';
import { ScriptingGlobals } from '../../util/ScriptingGlobals';
import { SnappingManager } from '../../util/SnappingManager';
import { undoBatch, UndoManager } from '../../util/UndoManager';
@@ -24,24 +28,27 @@ import { MarqueeOptionsMenu } from '../collections/collectionFreeForm';
import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView';
import { ContextMenu } from '../ContextMenu';
import { ContextMenuProps } from '../ContextMenuItem';
-import { ViewBoxAnnotatableComponent, ViewBoxInterface } from '../DocComponent';
+import { ViewBoxAnnotatableComponent } from '../DocComponent';
import { Colors } from '../global/globalEnums';
-import { LightboxView } from '../LightboxView';
import { MarqueeAnnotator } from '../MarqueeAnnotator';
import { AnchorMenu } from '../pdf/AnchorMenu';
import { Annotation } from '../pdf/Annotation';
import { GPTPopup } from '../pdf/GPTPopup/GPTPopup';
+import { PinDocView, PinProps } from '../PinFuncs';
import { SidebarAnnos } from '../SidebarAnnos';
-import { StyleProp } from '../StyleProvider';
-import { DocumentView, OpenWhere } from './DocumentView';
-import { FieldView, FieldViewProps, FocusViewOptions } from './FieldView';
+import { StyleProp } from '../StyleProp';
+import { ViewBoxInterface } from '../ViewBoxInterface';
+import { DocumentView } from './DocumentView';
+import { FieldView, FieldViewProps } from './FieldView';
+import { FocusViewOptions } from './FocusViewOptions';
import { LinkInfo } from './LinkDocPreview';
-import { PinProps, PresBox } from './trails';
+import { OpenWhere } from './OpenWhere';
import './WebBox.scss';
+
const { CreateImage } = require('./WebBoxRenderer');
-const _global = (window /* browser */ || global) /* node */ as any;
+
@observer
-export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implements ViewBoxInterface {
+export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
public static LayoutString(fieldKey: string) {
return FieldView.LayoutString(WebBox, fieldKey);
}
@@ -105,7 +112,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
}
@action
- search = (searchString: string, bwd?: boolean, clear: boolean = false) => {
+ override search = (searchString: string, bwd?: boolean, clear: boolean = false) => {
if (!this._searching && !clear) {
this._searching = true;
setTimeout(() => {
@@ -141,19 +148,19 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
const scrollTop = NumCast(this.layoutDoc._layout_scrollTop);
const nativeWidth = NumCast(this.layoutDoc.nativeWidth);
const nativeHeight = (nativeWidth * this._props.PanelHeight()) / this._props.PanelWidth();
- var htmlString = this._iframe.contentDocument && new XMLSerializer().serializeToString(this._iframe.contentDocument);
+ let htmlString = this._iframe.contentDocument && new XMLSerializer().serializeToString(this._iframe.contentDocument);
if (!htmlString) {
- htmlString = await (await fetch(Utils.CorsProxy(this.webField!.href))).text();
+ htmlString = await (await fetch(ClientUtils.CorsProxy(this.webField!.href))).text();
}
this.layoutDoc.thumb = undefined;
this.Document.thumbLockout = true; // lock to prevent multiple thumb updates.
CreateImage(this._webUrl.endsWith('/') ? this._webUrl.substring(0, this._webUrl.length - 1) : this._webUrl, this._iframe.contentDocument?.styleSheets ?? [], htmlString, nativeWidth, nativeHeight, scrollTop)
- .then((data_url: any) => {
- if (data_url.includes('<!DOCTYPE')) {
+ .then((dataUrl: any) => {
+ if (dataUrl.includes('<!DOCTYPE')) {
console.log('BAD DATA IN THUMB CREATION');
return;
}
- Utils.convertDataUri(data_url, this.layoutDoc[Id] + '-icon' + new Date().getTime(), true, this.layoutDoc[Id] + '-icon').then(returnedfilename =>
+ ClientUtils.convertDataUri(dataUrl, this.layoutDoc[Id] + '-icon' + new Date().getTime(), true, this.layoutDoc[Id] + '-icon').then(returnedfilename =>
setTimeout(
action(() => {
this.Document.thumbLockout = false;
@@ -166,7 +173,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
)
);
})
- .catch(function (error: any) {
+ .catch((error: any) => {
console.error('oops, something went wrong!', error);
});
};
@@ -187,7 +194,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
});
this._disposers.urlchange = reaction(
() => WebCast(this.dataDoc.data),
- url => this.submitURL(false, false)
+ () => this.submitURL(false, false)
);
this._disposers.titling = reaction(
() => StrCast(this.Document.title),
@@ -199,8 +206,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
this._disposers.layout_autoHeight = reaction(
() => this.layoutDoc._layout_autoHeight,
- layout_autoHeight => {
- if (layout_autoHeight) {
+ layoutAutoHeight => {
+ if (layoutAutoHeight) {
this.layoutDoc._nativeHeight = NumCast(this.Document[this._props.fieldKey + '_nativeHeight']);
this._props.setHeight?.(NumCast(this.Document[this._props.fieldKey + '_nativeHeight']) * (this._props.NativeDimScaling?.() || 1));
}
@@ -219,8 +226,10 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
}
} // else it's an HTMLfield
} else if (this.webField && !this.dataDoc.text) {
- WebRequest.get(Utils.CorsProxy(this.webField.href)) //
- .then(result => result && (this.dataDoc.text = htmlToText(result.content)));
+ WebRequest.get(ClientUtils.CorsProxy(this.webField.href)) //
+ .then(result => {
+ result && (this.dataDoc.text = htmlToText(result.content));
+ });
}
this._disposers.scrollReaction = reaction(
@@ -254,7 +263,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
const clientRects = selRange.getClientRects();
for (let i = 0; i < clientRects.length; i++) {
const rect = clientRects.item(i);
- const mainrect = this._url ? { translateX: 0, translateY: 0, scale: 1 } : Utils.GetScreenTransform(this._mainCont.current);
+ const mainrect = this._url ? { translateX: 0, translateY: 0, scale: 1 } : ClientUtils.GetScreenTransform(this._mainCont.current);
if (rect && rect.width !== this._mainCont.current.clientWidth) {
const annoBox = document.createElement('div');
annoBox.className = 'marqueeAnnotator-annotationBox';
@@ -283,27 +292,39 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
focus = (anchor: Doc, options: FocusViewOptions) => {
if (anchor !== this.Document && this._outerRef.current) {
const windowHeight = this._props.PanelHeight() / (this._props.NativeDimScaling?.() || 1);
- const scrollTo = Utils.scrollIntoView(NumCast(anchor.y), NumCast(anchor._height), NumCast(this.layoutDoc._layout_scrollTop), windowHeight, windowHeight * 0.1, Math.max(NumCast(anchor.y) + NumCast(anchor._height), this._scrollHeight));
+ const scrollTo = ClientUtils.scrollIntoView(
+ NumCast(anchor.y),
+ NumCast(anchor._height),
+ NumCast(this.layoutDoc._layout_scrollTop),
+ windowHeight,
+ windowHeight * 0.1,
+ Math.max(NumCast(anchor.y) + NumCast(anchor._height), this._scrollHeight)
+ );
if (scrollTo !== undefined) {
if (this._initialScroll === undefined) {
const focusTime = options.zoomTime ?? 500;
this.goTo(scrollTo, focusTime, options.easeFunc);
return focusTime;
- } else {
- this._initialScroll = scrollTo;
}
+ this._initialScroll = scrollTo;
}
}
+ return undefined;
};
@action
- getView = (doc: Doc, options: FocusViewOptions) => {
- if (Doc.AreProtosEqual(doc, this.Document)) return new Promise<Opt<DocumentView>>(res => res(this.DocumentView?.()));
+ getView = (doc: Doc /* , options: FocusViewOptions */) => {
+ if (Doc.AreProtosEqual(doc, this.Document))
+ return new Promise<Opt<DocumentView>>(res => {
+ res(this.DocumentView?.());
+ });
if (this.Document.layout_fieldKey === 'layout_icon') this.DocumentView?.().iconify();
const webUrl = WebCast(doc.config_data)?.url;
if (this._url && webUrl && webUrl.href !== this._url) this.setData(webUrl.href);
if (this._sidebarRef?.current?.makeDocUnfiltered(doc) && !this.SidebarShown) this.toggleSidebar(false);
- return new Promise<Opt<DocumentView>>(res => DocumentManager.Instance.AddViewRenderedCb(doc, dv => res(dv)));
+ return new Promise<Opt<DocumentView>>(res => {
+ DocumentView.addViewRenderedCb(doc, dv => res(dv));
+ });
};
sidebarAddDocTab = (doc: Doc, where: OpenWhere) => {
@@ -314,14 +335,16 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
return this._props.addDocTab(doc, where);
};
getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => {
- let ele: Opt<HTMLDivElement> = undefined;
+ let ele: Opt<HTMLDivElement>;
try {
const contents = this._iframe?.contentWindow?.getSelection()?.getRangeAt(0).cloneContents();
if (contents) {
ele = document.createElement('div');
ele.append(contents);
}
- } catch (e) {}
+ } catch (e) {
+ /* empty */
+ }
const visibleAnchor = this._getAnchor(this._savedAnnotations, true);
const anchor =
visibleAnchor ??
@@ -330,7 +353,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
y: NumCast(this.layoutDoc._layout_scrollTop),
annotationOn: this.Document,
});
- PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), scrollable: pinProps?.pinData ? true : false, pannable: true } }, this.Document);
+ PinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), scrollable: !!pinProps?.pinData, pannable: true } }, this.Document);
anchor.text = ele?.textContent ?? '';
anchor.text_html = ele?.innerHTML ?? this._selectionText;
addAsAnnotation && this.addDocumentWrapper(anchor);
@@ -356,7 +379,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
this._textAnnotationCreator = undefined;
this.DocumentView?.()?.cleanupPointerEvents(); // pointerup events aren't generated on containing document view, so we have to invoke it here.
if (this._iframe?.contentWindow && this._iframe.contentDocument && !this._iframe.contentWindow.getSelection()?.isCollapsed) {
- const mainContBounds = Utils.GetScreenTransform(this._mainCont.current!);
+ const mainContBounds = ClientUtils.GetScreenTransform(this._mainCont.current!);
const scale = (this._props.NativeDimScaling?.() || 1) * mainContBounds.scale;
const sel = this._iframe.contentWindow.getSelection();
if (sel) {
@@ -387,7 +410,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
e?.stopPropagation();
setTimeout(() => {
// if menu comes up right away, the down event can still be active causing a menu item to be selected
- this.specificContextMenu(undefined as any);
+ this.specificContextMenu();
this.DocumentView?.().onContextMenu(undefined, theclick[0], theclick[1]);
});
}
@@ -462,6 +485,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
const sheets = document.head.appendChild(style);
return (sheets as any).sheet;
}
+ return undefined;
}
addWebStyleSheetRule(sheet: any, selector: any, css: any, selectorPrefix = '.') {
const propText =
@@ -476,7 +500,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
_iframetimeout: any = undefined;
@observable _warning = 0;
@action
- iframeLoaded = (e: any) => {
+ iframeLoaded = () => {
const iframe = this._iframe;
if (this._initialScroll !== undefined) {
this.setScrollPos(this._initialScroll);
@@ -491,7 +515,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
runInAction(() => this._warning++);
href = undefined;
}
- let requrlraw = decodeURIComponent(href?.replace(Utils.prepend('') + '/corsProxy/', '') ?? this._url.toString());
+ let requrlraw = decodeURIComponent(href?.replace(ClientUtils.prepend('') + '/corsProxy/', '') ?? this._url.toString());
if (requrlraw !== this._url.toString()) {
if (requrlraw.match(/q=.*&/)?.length && this._url.toString().match(/q=.*&/)?.length) {
const matches = requrlraw.match(/[^a-zA-z]q=[^&]*/g);
@@ -544,16 +568,16 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
'click',
undoBatch(
action((e: MouseEvent) => {
- let href = '';
+ let eleHref = '';
for (let ele = e.target as any; ele; ele = ele.parentElement) {
- href = (typeof ele.href === 'string' ? ele.href : ele.href?.baseVal) || ele.parentElement?.href || href;
+ eleHref = (typeof ele.href === 'string' ? ele.href : ele.href?.baseVal) || ele.parentElement?.href || eleHref;
}
const origin = this.webField?.origin;
- if (href && origin) {
+ if (eleHref && origin) {
const batch = UndoManager.StartBatch('webclick');
e.stopPropagation();
setTimeout(() => {
- this.setData(href.replace(Utils.prepend(''), origin));
+ this.setData(eleHref.replace(ClientUtils.prepend(''), origin));
batch.end();
});
if (this._outerRef.current) {
@@ -599,7 +623,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
clearStyleSheetRules(WebBox.webStyleSheet);
this._scrollTimer = undefined;
const newScrollTop = scrollTop > iframeHeight ? iframeHeight : scrollTop;
- if (!LinkInfo.Instance?.LinkInfo && this._outerRef.current && newScrollTop !== this.layoutDoc.thumbScrollTop && (!LightboxView.LightboxDoc || LightboxView.Contains(this.DocumentView?.()))) {
+ if (!LinkInfo.Instance?.LinkInfo && this._outerRef.current && newScrollTop !== this.layoutDoc.thumbScrollTop && (!DocumentView.LightboxDoc() || DocumentView.LightboxContains(this.DocumentView?.()))) {
this.layoutDoc.thumb = undefined;
this.layoutDoc.thumbScrollTop = undefined;
this.layoutDoc.thumbNativeWidth = undefined;
@@ -632,12 +656,17 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
this._scrollHeight = 0;
if (this._webUrl === this._url) {
this._webUrl = curUrl;
- setTimeout(action(() => (this._webUrl = this._url)));
+ setTimeout(
+ action(() => {
+ this._webUrl = this._url;
+ })
+ );
} else {
this._webUrl = this._url;
}
return true;
}
+ return undefined;
});
return false;
};
@@ -655,12 +684,17 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
this._scrollHeight = 0;
if (this._webUrl === this._url) {
this._webUrl = curUrl;
- setTimeout(action(() => (this._webUrl = this._url)));
+ setTimeout(
+ action(() => {
+ this._webUrl = this._url;
+ })
+ );
} else {
this._webUrl = this._url;
}
return true;
}
+ return undefined;
});
return false;
};
@@ -692,13 +726,13 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
const html = dataTransfer.getData('text/html');
const uri = dataTransfer.getData('text/uri-list');
const url = uri || html || this._url || '';
- const newurl = url.startsWith(window.location.origin) ? url.replace(window.location.origin, this._url?.match(/http[s]?:\/\/[^\/]*/)?.[0] || '') : url;
+ const newurl = url.startsWith(window.location.origin) ? url.replace(window.location.origin, this._url?.match(/http[s]?:\/\/[^/]*/)?.[0] || '') : url;
this.setData(newurl);
e.stopPropagation();
};
@action
- setData = (data: Field | Promise<RefField | undefined>) => {
+ setData = (data: FieldType | Promise<RefField | undefined>) => {
if (!(typeof data === 'string') && !(data instanceof WebField)) return false;
if (Field.toString(data) === this._url) return false;
this._scrollHeight = 0;
@@ -715,19 +749,31 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
e.stopPropagation();
};
- specificContextMenu = (e: React.MouseEvent | PointerEvent): void => {
+ specificContextMenu = (): void => {
const cm = ContextMenu.Instance;
const funcs: ContextMenuProps[] = [];
if (!cm.findByDescription('Options...')) {
!Doc.noviceMode &&
- funcs.push({ description: (this.layoutDoc[this.fieldKey + '_useCors'] ? "Don't Use" : 'Use') + ' Cors', event: () => (this.layoutDoc[this.fieldKey + '_useCors'] = !this.layoutDoc[this.fieldKey + '_useCors']), icon: 'snowflake' });
+ funcs.push({
+ description: (this.layoutDoc[this.fieldKey + '_useCors'] ? "Don't Use" : 'Use') + ' Cors',
+ event: () => {
+ this.layoutDoc[this.fieldKey + '_useCors'] = !this.layoutDoc[this.fieldKey + '_useCors'];
+ },
+ icon: 'snowflake',
+ });
funcs.push({
description: (this.dataDoc[this.fieldKey + '_allowScripts'] ? 'Prevent' : 'Allow') + ' Scripts',
event: () => {
this.dataDoc[this.fieldKey + '_allowScripts'] = !this.dataDoc[this.fieldKey + '_allowScripts'];
if (this._iframe) {
- runInAction(() => (this._hackHide = true));
- setTimeout(action(() => (this._hackHide = false)));
+ runInAction(() => {
+ this._hackHide = true;
+ });
+ setTimeout(
+ action(() => {
+ this._hackHide = false;
+ })
+ );
}
},
icon: 'snowflake',
@@ -765,7 +811,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
setupMoveUpEvents(
this,
e,
- action(e => {
+ action(() => {
MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
return true;
}),
@@ -789,7 +835,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
@observable lighttext = false;
@computed get urlContent() {
- if (this.ScreenToLocalBoxXf().Scale > 25) return <div></div>;
+ if (this.ScreenToLocalBoxXf().Scale > 25) return <div />;
setTimeout(
action(() => {
if (this._initialScroll === undefined && !this._webPageHasBeenRendered) {
@@ -811,19 +857,23 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
})}
contentEditable
onPointerDown={this.webClipDown}
+ // eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{ __html: field.html }}
/>
);
}
if (field instanceof WebField) {
- const url = this.layoutDoc[this.fieldKey + '_useCors'] ? Utils.CorsProxy(this._webUrl) : this._webUrl;
+ const url = this.layoutDoc[this.fieldKey + '_useCors'] ? ClientUtils.CorsProxy(this._webUrl) : this._webUrl;
const scripts = this.dataDoc[this.fieldKey + '_allowScripts'] || this._webUrl.includes('wikipedia.org') || this._webUrl.includes('google.com') || this._webUrl.startsWith('https://bing');
- //if (!scripts) console.log('No scripts for: ' + url);
+ // if (!scripts) console.log('No scripts for: ' + url);
return (
<iframe
+ title="web iframe"
key={this._warning}
className="webBox-iframe"
- ref={action((r: HTMLIFrameElement | null) => (this._iframe = r))}
+ ref={action((r: HTMLIFrameElement | null) => {
+ this._iframe = r;
+ })}
style={{ pointerEvents: SnappingManager.IsResizing ? 'none' : undefined }}
src={url}
onLoad={this.iframeLoaded}
@@ -834,12 +884,24 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
/>
);
}
- return <iframe className="webBox-iframe" ref={action((r: HTMLIFrameElement | null) => (this._iframe = r))} src={'https://crossorigin.me/https://cs.brown.edu'} />;
+ return (
+ <iframe
+ title="web frame"
+ className="webBox-iframe"
+ ref={action((r: HTMLIFrameElement | null) => {
+ this._iframe = r;
+ })}
+ src="https://crossorigin.me/https://cs.brown.edu"
+ />
+ );
}
- addDocumentWrapper = (doc: Doc | Doc[], annotationKey?: string) => {
- this._url && (doc instanceof Doc ? [doc] : doc).forEach(doc => (doc.config_data = new WebField(this._url)));
- return this.addDocument(doc, annotationKey);
+ addDocumentWrapper = (docs: Doc | Doc[], annotationKey?: string) => {
+ this._url &&
+ toList(docs).forEach(doc => {
+ doc.config_data = new WebField(this._url);
+ });
+ return this.addDocument(docs, annotationKey);
};
sidebarAddDocument = (doc: Doc | Doc[], sidebarKey?: string) => {
@@ -853,7 +915,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
setupMoveUpEvents(
this,
e,
- action((e, down, delta) => {
+ action((moveEv, down, delta) => {
this._draggingSidebar = true;
const localDelta = this._props
.ScreenToLocalTransform()
@@ -871,7 +933,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
}
return false;
}),
- action((e, movement, isClick) => {
+ action((upEv, movement, isClick) => {
this._draggingSidebar = false;
!isClick && batch.end();
}),
@@ -892,14 +954,14 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
backgroundColor: this.SidebarShown ? Colors.MEDIUM_BLUE : Colors.BLACK,
}}
onPointerDown={e => this.sidebarBtnDown(e, true)}>
- <FontAwesomeIcon style={{ color: Colors.WHITE }} icon={'comment-alt'} size="sm" />
+ <FontAwesomeIcon style={{ color: Colors.WHITE }} icon="comment-alt" size="sm" />
</div>
);
}
@observable _previewNativeWidth: Opt<number> = undefined;
@observable _previewWidth: Opt<number> = undefined;
toggleSidebar = action((preview: boolean = false) => {
- var nativeWidth = NumCast(this.layoutDoc[this.fieldKey + '_nativeWidth']);
+ let nativeWidth = NumCast(this.layoutDoc[this.fieldKey + '_nativeWidth']);
if (!nativeWidth) {
const defaultNativeWidth = NumCast(this.Document.nativeWidth, this.dataDoc[this.fieldKey] instanceof WebField ? 850 : NumCast(this.Document._width));
Doc.SetNativeWidth(this.dataDoc, Doc.NativeWidth(this.dataDoc) || defaultNativeWidth);
@@ -938,7 +1000,9 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
};
_innerCollectionView: CollectionFreeFormView | undefined;
zoomScaling = () => this._innerCollectionView?.zoomScaling() ?? 1;
- setInnerContent = (component: ViewBoxInterface) => (this._innerCollectionView = component as CollectionFreeFormView);
+ setInnerContent = (component: ViewBoxInterface<any>) => {
+ this._innerCollectionView = component as CollectionFreeFormView;
+ };
@computed get content() {
const interactive = this._props.isContentActive() && this._props.pointerEvents?.() !== 'none' && Doc.ActiveTool === InkTool.None;
@@ -969,24 +1033,25 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
{this.inlineTextAnnotations
.sort((a, b) => NumCast(a.y) - NumCast(b.y))
.map(anno => (
- <Annotation {...this._props} fieldKey={this.annotationKey} pointerEvents={this.pointerEvents} dataDoc={this.dataDoc} anno={anno} key={`${anno[Id]}-annotation`} />
+ // eslint-disable-next-line react/jsx-props-no-spreading
+ <Annotation {...this._props} fieldKey={this.annotationKey} pointerEvents={this.pointerEvents} containerDataDoc={this.dataDoc} annoDoc={anno} key={`${anno[Id]}-annotation`} />
))}
</div>
);
}
@computed get SidebarShown() {
- return this._showSidebar || this.layoutDoc._layout_showSidebar ? true : false;
+ return !!(this._showSidebar || this.layoutDoc._layout_showSidebar);
}
renderAnnotations = (childFilters: () => string[]) => (
<CollectionFreeFormView
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
setContentViewBox={this.setInnerContent}
NativeWidth={returnZero}
NativeHeight={returnZero}
- originTopLeft={false}
- isAnnotationOverlayScrollable={true}
+ isAnnotationOverlayScrollable
renderDepth={this._props.renderDepth + 1}
- isAnnotationOverlay={true}
+ isAnnotationOverlay
fieldKey={this.annotationKey}
setPreviewCursor={this.setPreviewCursor}
PanelWidth={this.panelWidth}
@@ -1029,7 +1094,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
}}
// when active, block wheel events from propagating since they're handled by the iframe
onWheel={this.onZoomWheel}
- onScroll={e => this.setDashScrollTop(this._outerRef.current?.scrollTop || 0)}
+ onScroll={() => this.setDashScrollTop(this._outerRef.current?.scrollTop || 0)}
onPointerDown={this.onMarqueeDown}>
<div className="webBox-innerContent" style={{ height: (this._webPageHasBeenRendered && this._scrollHeight > this._props.PanelHeight() && this._scrollHeight) || '100%', pointerEvents }}>
{this.content}
@@ -1045,7 +1110,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
return (
<div className="webBox-ui" onPointerDown={e => e.stopPropagation()} style={{ display: this._props.isContentActive() ? 'flex' : 'none' }}>
<div className="webBox-overlayCont" onPointerDown={e => e.stopPropagation()} style={{ left: `${this._searching ? 0 : 100}%` }}>
- <button className="webBox-overlayButton" title={'search'} />
+ <button type="button" className="webBox-overlayButton" title="search" />
<input
className="webBox-searchBar"
placeholder="Search"
@@ -1056,13 +1121,14 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
e.stopPropagation();
}}
/>
- <button className="webBox-search" title="Search" onClick={e => this.search(this._searchString, e.shiftKey)}>
+ <button type="button" className="webBox-search" title="Search" onClick={e => this.search(this._searchString, e.shiftKey)}>
<FontAwesomeIcon icon="search" size="sm" />
</button>
</div>
<button
+ type="button"
className="webBox-overlayButton"
- title={'search'}
+ title="search"
onClick={action(() => {
this._searching = !this._searching;
this.search('', false, true);
@@ -1075,14 +1141,18 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
</div>
);
}
- searchStringChanged = (e: React.ChangeEvent<HTMLInputElement>) => (this._searchString = e.currentTarget.value);
- setPreviewCursor = (func?: (x: number, y: number, drag: boolean, hide: boolean, doc: Opt<Doc>) => void) => (this._setPreviewCursor = func);
+ searchStringChanged = (e: React.ChangeEvent<HTMLInputElement>) => {
+ this._searchString = e.currentTarget.value;
+ };
+ setPreviewCursor = (func?: (x: number, y: number, drag: boolean, hide: boolean, doc: Opt<Doc>) => void) => {
+ this._setPreviewCursor = func;
+ };
panelWidth = () => this._props.PanelWidth() / (this._props.NativeDimScaling?.() || 1) - this.sidebarWidth() + WebBox.sidebarResizerWidth;
panelHeight = () => this._props.PanelHeight() / (this._props.NativeDimScaling?.() || 1);
scrollXf = () => this.ScreenToLocalBoxXf().translate(0, NumCast(this.layoutDoc._layout_scrollTop));
anchorMenuClick = () => this._sidebarRef.current?.anchorMenuClick;
- transparentFilter = () => [...this._props.childFilters(), Utils.TransparentBackgroundFilter];
- opaqueFilter = () => [...this._props.childFilters(), Utils.noDragDocsFilter, ...(SnappingManager.CanEmbed ? [] : [Utils.OpaqueBackgroundFilter])];
+ transparentFilter = () => [...this._props.childFilters(), ClientUtils.TransparentBackgroundFilter];
+ opaqueFilter = () => [...this._props.childFilters(), ClientUtils.noDragDocsFilter, ...(SnappingManager.CanEmbed ? [] : [ClientUtils.OpaqueBackgroundFilter])];
childStyleProvider = (doc: Doc | undefined, props: Opt<FieldViewProps>, property: string): any => {
if (doc instanceof Doc && property === StyleProp.PointerEvents) {
if (this.inlineTextAnnotations.includes(doc)) return 'none';
@@ -1149,6 +1219,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
<div style={{ position: 'absolute', height: '100%', right: 0, top: 0, width: `calc(100 * ${this.sidebarWidth() / this._props.PanelWidth()}%` }}>
<SidebarAnnos
ref={this._sidebarRef}
+ // eslint-disable-next-line react/jsx-props-no-spreading
{...this._props}
whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
fieldKey={this.fieldKey + '_' + this._urlHash}
@@ -1169,6 +1240,12 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem
);
}
}
+// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function urlHash(url: string) {
return stringHash(url);
});
+
+Docs.Prototypes.TemplateMap.set(DocumentType.WEB, {
+ layout: { view: WebBox, dataField: 'data' },
+ options: { acl: '', _height: 300, _layout_fitWidth: true, _layout_nativeDimEditable: true, _layout_reflowVertical: true, waitForDoubleClickToClick: 'always', systemIcon: 'BsGlobe' },
+});