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.tsx74
1 files changed, 62 insertions, 12 deletions
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index 2c5deba88..db493934a 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -47,6 +47,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
public static openSidebarWidth = 250;
public static sidebarResizerWidth = 5;
private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean, hide: boolean) => void);
+ private _setBrushViewer: undefined | ((view: { width: number; height: number; panX: number; panY: number }) => void);
private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
private _outerRef: React.RefObject<HTMLDivElement> = React.createRef();
private _disposers: { [name: string]: IReactionDisposer } = {};
@@ -155,6 +156,10 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
this.rootDoc.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')) {
+ 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 =>
setTimeout(
action(() => {
@@ -242,6 +247,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
);
}
@action componentWillUnmount() {
+ this._iframetimeout && clearTimeout(this._iframetimeout);
+ this._iframetimeout = undefined;
Object.values(this._disposers).forEach(disposer => disposer?.());
// this._iframe?.removeEventListener('wheel', this.iframeWheel, true);
// this._iframe?.contentDocument?.removeEventListener("pointerup", this.iframeUp);
@@ -275,6 +282,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
menuControls = () => this.urlEditor; // controls to be added to the top bar when a document of this type is selected
+ 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, smooth: boolean) => {
if (StrCast(doc.webUrl) !== this._url) this.submitURL(StrCast(doc.webUrl), !smooth);
if (DocListCast(this.props.Document[this.fieldKey + '-sidebar']).includes(doc) && !this.SidebarShown) {
@@ -332,7 +341,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
const word = getWordAtPoint(e.target, e.clientX, e.clientY);
this._setPreviewCursor?.(e.clientX, e.clientY, false, true);
MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
- this._marqueeing = [e.clientX * scale + mainContBounds.translateX, e.clientY * scale + mainContBounds.translateY - NumCast(this.layoutDoc._scrollTop) * scale];
+ e.button !== 2 && (this._marqueeing = [e.clientX * scale + mainContBounds.translateX, e.clientY * scale + mainContBounds.translateY - NumCast(this.layoutDoc._scrollTop) * scale]);
if (word || ((e.target as any) || '').className.includes('rangeslider') || (e.target as any)?.onclick || (e.target as any)?.parentNode?.onclick) {
setTimeout(
action(() => (this._marqueeing = undefined)),
@@ -349,7 +358,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
// bcz: hack - iframe grabs all events which messes up how we handle contextMenus. So this super naively simulates the event stack to get the specific menu items and the doc view menu items.
if (e.button === 2 || (e.button === 0 && e.altKey)) {
e.preventDefault();
- e.stopPropagation();
+ //e.stopPropagation();
ContextMenu.Instance.closeMenu();
ContextMenu.Instance.setIgnoreEvents(true);
}
@@ -363,13 +372,41 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
iframeClick = () => this._iframeClick;
iframeScaling = () => 1 / this.props.ScreenToLocalTransform().Scale;
+ addStyleSheet(document: any, styleType: string = 'text/css') {
+ if (document) {
+ const style = document.createElement('style');
+ style.type = styleType;
+ const sheets = document.head.appendChild(style);
+ return (sheets as any).sheet;
+ }
+ }
+ addStyleSheetRule(sheet: any, selector: any, css: any, selectorPrefix = '.') {
+ const propText =
+ typeof css === 'string'
+ ? css
+ : Object.keys(css)
+ .map(p => p + ':' + (p === 'content' ? "'" + css[p] + "'" : css[p]))
+ .join(';');
+ return sheet?.insertRule(selectorPrefix + selector + '{' + propText + '}', sheet.cssRules.length);
+ }
+
+ _iframetimeout: any = undefined;
@action
iframeLoaded = (e: any) => {
const iframe = this._iframe;
if (this._initialScroll !== undefined) {
this.setScrollPos(this._initialScroll);
}
- let requrlraw = decodeURIComponent(iframe?.contentWindow?.location.href.replace(Utils.prepend('') + '/corsProxy/', '') ?? this._url.toString());
+
+ this.addStyleSheetRule(this.addStyleSheet(this._iframe?.contentDocument), '::selection', { color: 'white', background: 'orange' }, '');
+
+ let href: Opt<string>;
+ try {
+ href = iframe?.contentWindow?.location.href;
+ } catch (e) {
+ href = undefined;
+ }
+ let requrlraw = decodeURIComponent(href?.replace(Utils.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);
@@ -387,16 +424,25 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
}
this.submitURL(requrlraw, undefined, true);
}
- if (iframe?.contentDocument) {
- iframe.contentDocument.addEventListener('pointerup', this.iframeUp);
- 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))),
+ const iframeContent = iframe?.contentDocument;
+ if (iframeContent) {
+ iframeContent.addEventListener('pointerup', this.iframeUp);
+ iframeContent.addEventListener('pointerdown', this.iframeDown);
+ const initHeights = () => {
+ this._scrollHeight = Math.max(this._scrollHeight, (iframeContent.body.children[0] as any)?.scrollHeight || 0);
+ if (this._scrollHeight) {
+ this.rootDoc.nativeHeight = Math.min(NumCast(this.rootDoc.nativeHeight), this._scrollHeight);
+ this.layoutDoc.height = Math.min(this.layoutDoc[HeightSym](), (this.layoutDoc[WidthSym]() * NumCast(this.rootDoc.nativeHeight)) / NumCast(this.rootDoc.nativeWidth));
+ }
+ };
+ initHeights();
+ this._iframetimeout && clearTimeout(this._iframetimeout);
+ this._iframetimeout = setTimeout(
+ action(() => initHeights),
5000
);
iframe.setAttribute('enable-annotation', 'true');
- iframe.contentDocument.addEventListener(
+ iframeContent.addEventListener(
'click',
undoBatch(
action((e: MouseEvent) => {
@@ -831,6 +877,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
fieldKey={this.annotationKey}
CollectionView={undefined}
setPreviewCursor={this.setPreviewCursor}
+ setBrushViewer={this.setBrushViewer}
PanelWidth={this.panelWidth}
PanelHeight={this.panelHeight}
ScreenToLocalTransform={this.scrollXf}
@@ -859,7 +906,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
onWheel={StopEvent} // block wheel events from propagating since they're handled by the iframe
onScroll={e => this.setDashScrollTop(this._outerRef.current?.scrollTop || 0)}
onPointerDown={this.onMarqueeDown}>
- <div className={'webBox-innerContent'} style={{ height: this._webPageHasBeenRendered ? NumCast(this.scrollHeight, 50) : '100%', pointerEvents }}>
+ <div className={'webBox-innerContent'} style={{ height: this._webPageHasBeenRendered && this._scrollHeight ? this.scrollHeight : '100%', pointerEvents }}>
{this.content}
{<div style={{ display: DragManager.docsBeingDragged.length ? 'none' : undefined, mixBlendMode: 'multiply' }}>{renderAnnotations(this.transparentFilter)}</div>}
{renderAnnotations(this.opaqueFilter)}
@@ -925,7 +972,10 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
const pointerEvents = this.layoutDoc._lockedPosition ? 'none' : (this.props.pointerEvents?.() as any);
const scale = previewScale * (this.props.NativeDimScaling?.() || 1);
return (
- <div className="webBox" ref={this._mainCont} style={{ pointerEvents: this.pointerEvents(), display: !SnappingManager.GetIsDragging() && this.props.thumbShown?.() ? 'none' : undefined }}>
+ <div
+ className="webBox"
+ ref={this._mainCont}
+ style={{ pointerEvents: this.pointerEvents(), position: SnappingManager.GetIsDragging() ? 'absolute' : undefined, display: !SnappingManager.GetIsDragging() && this.props.thumbShown?.() ? 'none' : undefined }}>
<div className="webBox-background" style={{ backgroundColor: this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor) }} />
<div
className="webBox-container"