diff options
Diffstat (limited to 'src/client/views/nodes')
| -rw-r--r-- | src/client/views/nodes/LinkAnchorBox.tsx | 2 | ||||
| -rw-r--r-- | src/client/views/nodes/PresBox.tsx | 26 | ||||
| -rw-r--r-- | src/client/views/nodes/ScriptingBox.scss | 25 | ||||
| -rw-r--r-- | src/client/views/nodes/ScriptingBox.tsx | 258 | ||||
| -rw-r--r-- | src/client/views/nodes/VideoBox.tsx | 16 | ||||
| -rw-r--r-- | src/client/views/nodes/WebBox.tsx | 62 |
6 files changed, 314 insertions, 75 deletions
diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx index 098aa58e9..83245a89c 100644 --- a/src/client/views/nodes/LinkAnchorBox.tsx +++ b/src/client/views/nodes/LinkAnchorBox.tsx @@ -72,7 +72,7 @@ export class LinkAnchorBox extends ViewBoxBaseComponent<FieldViewProps, LinkAnch anchorContainerDoc && this.props.bringToFront(anchorContainerDoc, false); if (anchorContainerDoc && !this.layoutDoc.onClick && !this._isOpen) { this._timeout = setTimeout(action(() => { - DocumentManager.Instance.FollowLink(this.rootDoc, anchorContainerDoc, document => this.props.addDocTab(document, StrCast(this.layoutDoc.linkOpenLocation, "inTab")), false); + DocumentManager.Instance.FollowLink(this.rootDoc, anchorContainerDoc, document => this.props.addDocTab(document, StrCast(this.layoutDoc.linkOpenLocation, e.altKey ? "inTab" : "onRight")), false); this._editing = false; }), 300 - (Date.now() - this._lastTap)); } diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx index 6edcae417..09c03fb30 100644 --- a/src/client/views/nodes/PresBox.tsx +++ b/src/client/views/nodes/PresBox.tsx @@ -15,7 +15,7 @@ import { InkingControl } from "../InkingControl"; import { FieldView, FieldViewProps } from './FieldView'; import "./PresBox.scss"; import { ViewBoxBaseComponent } from "../DocComponent"; -import { makeInterface } from "../../../fields/Schema"; +import { makeInterface, listSpec } from "../../../fields/Schema"; import { List } from "../../../fields/List"; import { Docs } from "../../documents/Documents"; import { PrefetchProxy } from "../../../fields/Proxy"; @@ -59,7 +59,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> @action next = () => { this.updateCurrentPresentation(); - if (this.childDocs[this.itemIndex + 1] !== undefined) { + const presTargetDoc = Cast(this.childDocs[this.itemIndex].presentationTargetDoc, Doc, null); + const lastFrame = Cast(presTargetDoc.lastTimecode, "number", null); + const curFrame = NumCast(presTargetDoc.currentTimecode); + if (lastFrame !== undefined && curFrame < lastFrame) { + presTargetDoc.currentTimecode = curFrame + 1; + } + else if (this.childDocs[this.itemIndex + 1] !== undefined) { let nextSelected = this.itemIndex + 1; this.gotoDocument(nextSelected, this.itemIndex); @@ -188,11 +194,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> //The function that is called when a document is clicked or reached through next or back. //it'll also execute the necessary actions if presentation is playing. - public gotoDocument = (index: number, fromDoc: number) => { + public gotoDocument = action((index: number, fromDoc: number) => { this.updateCurrentPresentation(); Doc.UnBrushAllDocs(); if (index >= 0 && index < this.childDocs.length) { this.rootDoc._itemIndex = index; + const presTargetDoc = Cast(this.childDocs[this.itemIndex].presentationTargetDoc, Doc, null); + if (presTargetDoc.lastTimecode !== undefined) { + presTargetDoc.currentTimecode = 0; + } if (!this.layoutDoc.presStatus) { this.layoutDoc.presStatus = true; @@ -203,7 +213,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> this.hideIfNotPresented(index); this.showAfterPresented(index); } - } + }) //The function that starts or resets presentaton functionally, depending on status flag. startOrResetPres = () => { @@ -286,7 +296,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema> (this.layoutDoc.forceActive || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0) ? true : false) render() { - this.rootDoc.presOrderedDocs = new List<Doc>(this.childDocs.map((child, i) => child)); + // console.log("render = " + this.layoutDoc.title + " " + this.layoutDoc.presStatus); + // const presOrderedDocs = DocListCast(this.rootDoc.presOrderedDocs); + // if (presOrderedDocs.length != this.childDocs.length || presOrderedDocs.some((pd, i) => pd !== this.childDocs[i])) { + // this.rootDoc.presOrderedDocs = new List<Doc>(this.childDocs.slice()); + // } + this.childDocs.slice(); // needed to insure that the childDocs are loaded for looking up fields const mode = StrCast(this.rootDoc._viewType) as CollectionViewType; return <div className="presBox-cont" style={{ minWidth: this.layoutDoc.inOverlay ? 240 : undefined }} > <div className="presBox-buttons" style={{ display: this.rootDoc._chromeStatus === "disabled" ? "none" : undefined }}> @@ -334,5 +349,6 @@ Scripting.addGlobal(function lookupPresBoxField(container: Doc, field: string, d if (field === 'presCollapsedHeight') return container._viewType === CollectionViewType.Stacking ? 50 : 46; if (field === 'presStatus') return container.presStatus; if (field === '_itemIndex') return container._itemIndex; + if (field === 'presBox') return container; return undefined; }); diff --git a/src/client/views/nodes/ScriptingBox.scss b/src/client/views/nodes/ScriptingBox.scss index 4746d62d4..273e8e7bf 100644 --- a/src/client/views/nodes/ScriptingBox.scss +++ b/src/client/views/nodes/ScriptingBox.scss @@ -22,7 +22,7 @@ display: flex; flex-direction: row; justify-content: center; - overflow-y: hidden; + overflow-y: scroll; .scriptingBox-textArea { flex: 70; @@ -31,7 +31,7 @@ box-sizing: border-box; resize: none; padding: 7px; - overflow-y: hidden; + overflow-y: scroll; } .scriptingBox-plist { @@ -43,10 +43,31 @@ padding: 2px; overflow-y: scroll; } + + .scriptingBox-paramNames { + flex: 40; + width: 40%; + box-sizing: border-box; + resize: none; + padding: 7px; + overflow-y: scroll; + } + + .scriptingBox-paramInputs { + flex: 60; + width: 60%; + box-sizing: border-box; + resize: none; + padding: 2px; + overflow-y: scroll; + } } .scriptingBox-errorMessage { overflow: auto; + background: "red"; + background-color: "red"; + height: 40px; } .scripting-params { diff --git a/src/client/views/nodes/ScriptingBox.tsx b/src/client/views/nodes/ScriptingBox.tsx index eaf8f0e5b..f088fc5d2 100644 --- a/src/client/views/nodes/ScriptingBox.tsx +++ b/src/client/views/nodes/ScriptingBox.tsx @@ -1,4 +1,4 @@ -import { action, observable, computed } from "mobx"; +import { action, observable, computed, _allowStateChangesInsideComputed } from "mobx"; import { observer } from "mobx-react"; import * as React from "react"; import { documentSchema } from "../../../fields/documentSchemas"; @@ -33,7 +33,11 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps, Sc _overlayDisposer?: () => void; @observable private _errorMessage: string = ""; - @observable private _dropped: boolean = false; + @observable private _applied: boolean = false; + @observable private _paramsNames: any; + @observable private _paramsTypes: any; + @observable private _paramsValues: any; + @computed get rawScript() { return StrCast(this.dataDoc[this.props.fieldKey + "-rawScript"], StrCast(this.layoutDoc[this.props.fieldKey + "-rawScript"])); } @computed get compileParams() { return Cast(this.dataDoc[this.props.fieldKey + "-params"], listSpec("string"), Cast(this.layoutDoc[this.props.fieldKey + "-params"], listSpec("string"), [])); } @@ -134,6 +138,52 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps, Sc //this.onCompile()?.script.run({}, err => this._errorMessage = err.map((e: any) => e.messageText).join("\n")); } + @action + onApply = () => { + const params = this.compileParams.reduce((o: ScriptParam, p: string) => { + const param = p.split(":"); + + o[param[0].trim()] = param[1].trim(); + return o; + }, + {} as ScriptParam); + + console.log(this.compileParams); + + const result = CompileScript(this.rawScript, { + editable: true, + transformer: DocumentIconContainer.getTransformer(), + params, + typecheck: true + }); + this._errorMessage = ""; + if (result.compiled) { + this._errorMessage = ""; + this.props.Document.data = new ScriptField(result); + + this._applied = true; + } + else { + this.onError(result.errors); + } + this.props.Document.documentText = this.rawScript; + + this._paramsNames = []; + this._paramsTypes = []; + + this.compileParams.forEach(element => { + const param = element.split(":"); + this._paramsNames.push(param[0].trim()); + this._paramsTypes.push(param[1].trim()); + } + ); + } + + @action + onEdit = () => { + this._applied = false; + } + onFocus = () => { this._overlayDisposer?.(); this._overlayDisposer = OverlayView.Instance.addElement(<DocumentIconContainer />, { x: 0, y: 0 }); @@ -141,13 +191,12 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps, Sc @action onDrop = (e: Event, de: DragManager.DropEvent, index: any) => { - this._dropped = true; console.log("drop"); const firstParam = this.compileParams[index].split(":"); const droppedDocs = de.complete.docDragData?.droppedDocuments; if (droppedDocs?.length) { const dropped = droppedDocs[0]; - this.compileParams[index] = firstParam[0] + ":" + Doc.name; + this._paramsValues[index] = dropped; // you can't just bind a variable to a specific Doc. The Doc would have to be added to 'capturedVariables' field of the compile options, but I think it makes more sense to just be declaring this variable to be a Doc } } @@ -170,14 +219,24 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps, Sc if (value !== "" && value !== " ") { const parameter = value.split(":"); if (parameter[1] !== undefined) { - this._errorMessage = ""; - this._paramNum++; - const par = this.compileParams; - this.compileParams = new List<string>(value.split(";").filter(s => s !== " ")); - this.compileParams.push.apply(this.compileParams, par); - return true; + if (parameter[1].trim() === "Doc" || parameter[1].trim() === "string") { + //if (!!!this._paramsNames.includes(parameter[0].trim())) { + this._errorMessage = ""; + this._paramNum++; + const par = this.compileParams; + this.compileParams = new List<string>(value.split(";").filter(s => s !== " ")); + this.compileParams.push.apply(this.compileParams, par); + return true; + // } else { + // this._errorMessage = "this name has already been used"; + // return false; + // } + } else { + this._errorMessage = "this type is not supported"; + return false; + } } else { - //this._errorMessage = "must set type of parameter"; + this._errorMessage = "must set type of parameter"; return false; } } @@ -187,15 +246,15 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps, Sc const listParams = this.compileParams.map((parameter, i) => <div className="scriptingBox-pborder" - onFocus={this.onFocus} - onBlur={e => this._overlayDisposer?.()} + background-color="white" + onKeyPress={e => { if (e.key === "Enter") { this._overlayDisposer?.(); } } } - style={{ background: this._dropped ? "yellow" : "" }}> + > <EditableView contents={parameter} display={"block"} @@ -218,40 +277,155 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps, Sc </div> ); + // const settingParams = this._paramsNames.map((parameter: string, i: number) => + // <div className="scriptingBox-pborder" + // background-color="white" + + // onKeyPress={e => { + // if (e.key === "Enter") { + // this._overlayDisposer?.(); + // } + // } + // } + // > + + // {this._paramsTypes[i] === "Doc" ? <div> + // <div className="scriptingBox-wrapper"> + + // <div className="scriptingBox-paramNames"> + // {parameter + ":" + this._paramsValues[i] + " = "} + // </div> + + // <div className="scriptingBox-paramInputs" + // onFocus={this.onFocus}> + // <EditableView + // contents={this._paramsValues[i]} + // display={"block"} + // maxHeight={72} + // height={35} + // fontSize={12} + // GetValue={() => this._paramsValues[i]} + // onDrop={(e: Event, de: DragManager.DropEvent) => this.onDrop(e, de, i)} + // SetValue={value => { + // this._paramsValues[i] = value; + // return true; + // }} + // /> + // </div> + // </div> + // </div> : null} + + // {this._paramsTypes[i] === "string" ? <div> + // <div className="scriptingBox-wrapper"> + + // <div className="scriptingBox-paramNames"> + // {parameter + ":" + this._paramsValues[i] + " = "} + // </div> + + // <div className="scriptingBox-paramInputs" + // onFocus={this.onFocus}> + // <EditableView + // contents={this._paramsValues[i]} + // display={"block"} + // maxHeight={72} + // height={35} + // fontSize={12} + // GetValue={() => this._paramsValues[i]} + // SetValue={value => { + // this._paramsValues[i] = value; + // return true; + // }} + // /> + // </div> + // </div> + // </div> : null} + + + + // </div> + // ); + + const scriptingInputs = <div className="scriptingBox-inputDiv" style={{ height: "100%" }} + onPointerDown={e => this.props.isSelected(true) && e.stopPropagation()} > + <div className="scriptingBox-wrapper"> + + <textarea + placeholder="write your script here" + onChange={e => this.rawScript = e.target.value} + value={this.rawScript} + onFocus={this.onFocus} + onBlur={e => this._overlayDisposer?.()} + style={{ width: this.compileParams.length > 0 ? "70%" : "100%", resize: "none", height: "100%" }} + /> + + + {this.compileParams.length > 0 ? <div className="scriptingBox-plist" style={{ width: "30%" }}> + {listParams} + </div> : null} + </div> + <div className="scriptingBox-params">{params}</div> + + {this._errorMessage ? <div className="scriptingBox-errorMessage"> + {this._errorMessage} + </div> : null} + </div>; + + + const scriptingTools = <div className="scriptingBox-toolbar"> + <button className="scriptingBox-button" style={{ width: this.rootDoc.layoutKey === "layout_onClick" ? "33%" : "50%" }} + onPointerDown={e => { this.onCompile(); e.stopPropagation(); }}>Compile</button> + <button className="scriptingBox-button" style={{ width: this.rootDoc.layoutKey === "layout_onClick" ? "33%" : "50%" }} + onPointerDown={e => { this.onApply(); e.stopPropagation(); }}>Apply</button> + {this.rootDoc.layoutKey === "layout_onClick" ? <button className="scriptingBox-button" + style={{ width: this.rootDoc.layoutKey === "layout_onClick" ? "33%" : "50%" }} + onPointerDown={e => { this.onFinish(); e.stopPropagation(); }}>Finish</button> : null} + </div>; + + + const paramsInputs = <div className="scriptingBox-inputDiv" style={{ height: "100%" }} + onPointerDown={e => this.props.isSelected(true) && e.stopPropagation()} > + + {this.compileParams.length > 0 ? <div className="scriptingBox-plist"> + {this.compileParams} + </div> : null} + + </div>; + + const paramsTools = <div className="scriptingBox-toolbar"> + <button className="scriptingBox-button" style={{ width: this.rootDoc.layoutKey === "layout_onClick" ? "33%" : "50%" }} + onPointerDown={e => { this.onEdit(); e.stopPropagation(); }}>Edit</button> + <button className="scriptingBox-button" style={{ width: this.rootDoc.layoutKey === "layout_onClick" ? "33%" : "50%" }} + onPointerDown={e => { this.onRun(); e.stopPropagation(); }}>Run</button> + {this.rootDoc.layoutKey === "layout_onClick" ? <button className="scriptingBox-button" + style={{ width: this.rootDoc.layoutKey === "layout_onClick" ? "33%" : "50%" }} + onPointerDown={e => { this.onFinish(); e.stopPropagation(); }}>Finish</button> : null} + </div>; + + + return ( <div className="scriptingBox-outerDiv" onWheel={e => this.props.isSelected(true) && e.stopPropagation()}> - <div className="scriptingBox-inputDiv" - onPointerDown={e => this.props.isSelected(true) && e.stopPropagation()} > - <div className="scriptingBox-wrapper"> - - <textarea className="scriptingBox-textarea" - placeholder="write your script here" - onChange={e => this.rawScript = e.target.value} - value={this.rawScript} - onFocus={this.onFocus} - onBlur={e => this._overlayDisposer?.()} - style={{ width: this.compileParams.length > 0 ? "70%" : "100%" }} /> - - {this.compileParams.length > 0 ? <div className="scriptingBox-plist" style={{ width: "30%" }}> - {listParams} - </div> : null} - </div> - <div className="scriptingBox-params" >{params}</div> - <div className="scriptingBox-errorMessage" style={{ background: this._errorMessage ? "red" : "" }}>{this._errorMessage}</div> - </div> + {!!!this._applied ? <div style={{ height: "100%" }}> + {scriptingInputs} + </div> : null} + + {this._applied ? <div style={{ height: "100%" }}> + {paramsInputs} + </div> : null} + {this.rootDoc.layout === "layout" ? <div></div> : (null)} - <div className="scriptingBox-toolbar"> - <button className="scriptingBox-button" style={{ width: this.rootDoc.layoutKey === "layout_onClick" ? "33%" : "50%" }} - onPointerDown={e => { this.onCompile(); e.stopPropagation(); }}>Compile</button> - <button className="scriptingBox-button" style={{ width: this.rootDoc.layoutKey === "layout_onClick" ? "33%" : "50%" }} - onPointerDown={e => { this.onRun(); e.stopPropagation(); }}>Run</button> - {this.rootDoc.layoutKey === "layout_onClick" ? <button className="scriptingBox-button" - style={{ width: this.rootDoc.layoutKey === "layout_onClick" ? "33%" : "50%" }} - onPointerDown={e => { this.onFinish(); e.stopPropagation(); }}>Finish</button> : null} - </div> + + {!!!this._applied ? <div> + {scriptingTools} + </div> : null} + + {this._applied ? <div> + {paramsTools} + </div> : null} + </div> ); } diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index ccf1f5588..bcbd65258 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -104,18 +104,20 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD canvas.height = 640 * (this.layoutDoc._nativeHeight || 0) / (this.layoutDoc._nativeWidth || 1); const ctx = canvas.getContext('2d');//draw image to canvas. scale to target dimensions if (ctx) { - ctx.rect(0, 0, canvas.width, canvas.height); - ctx.fillStyle = "blue"; - ctx.fill(); + // ctx.rect(0, 0, canvas.width, canvas.height); + // ctx.fillStyle = "blue"; + // ctx.fill(); this._videoRef && ctx.drawImage(this._videoRef, 0, 0, canvas.width, canvas.height); } if (!this._videoRef) { // can't find a way to take snapshots of videos - const b = Docs.Create.ButtonDocument({ + const b = Docs.Create.LabelDocument({ x: (this.layoutDoc.x || 0) + width, y: (this.layoutDoc.y || 1), - _width: 150, _height: 50, title: (this.layoutDoc.currentTimecode || 0).toString() + _width: 150, _height: 50, title: (this.layoutDoc.currentTimecode || 0).toString(), }); - b.onClick = ScriptField.MakeScript(`this.currentTimecode = ${(this.layoutDoc.currentTimecode || 0)}`); + b.isLinkButton = true; + this.props.addDocument?.(b); + DocUtils.MakeLink({ doc: b }, { doc: this.rootDoc }, "video snapshot"); } else { //convert to desired file format const dataUrl = canvas.toDataURL('image/png'); // can also use 'image/png' @@ -132,7 +134,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD Doc.GetProto(imageSummary)["data-nativeWidth"] = this.layoutDoc._nativeWidth; Doc.GetProto(imageSummary)["data-nativeHeight"] = this.layoutDoc._nativeHeight; imageSummary.isLinkButton = true; - this.props.addDocument && this.props.addDocument(imageSummary); + this.props.addDocument?.(imageSummary); DocUtils.MakeLink({ doc: imageSummary }, { doc: this.rootDoc }, "video snapshot"); } }); diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 82f05012a..8844702d7 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -22,6 +22,9 @@ import React = require("react"); import * as WebRequest from 'web-request'; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { CollectionFreeFormView } from "../collections/collectionFreeForm/CollectionFreeFormView"; +import { ContextMenu } from "../ContextMenu"; +import { ContextMenuProps } from "../ContextMenuItem"; +import { undoBatch } from "../../util/UndoManager"; const htmlToText = require("html-to-text"); library.add(faStickyNote); @@ -33,7 +36,7 @@ const WebDocument = makeInterface(documentSchema); export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocument>(WebDocument) { public static LayoutString(fieldKey: string) { return FieldView.LayoutString(WebBox, fieldKey); } - get _collapsed() { return StrCast(this.layoutDoc._chromeStatus) === "disabled"; } + get _collapsed() { return StrCast(this.layoutDoc._chromeStatus) !== "enabled"; } set _collapsed(value) { this.layoutDoc._chromeStatus = !value ? "enabled" : "disabled"; } @observable private _url: string = "hello"; @observable private _pressX: number = 0; @@ -48,11 +51,13 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean) => void); iframeLoaded = action((e: any) => { - if (this._iframeRef.current?.contentDocument) { - this._iframeRef.current.contentDocument.addEventListener('pointerdown', this.iframedown, false); - this._iframeRef.current.contentDocument.addEventListener('scroll', this.iframeScrolled, false); - this.layoutDoc.scrollHeight = this._iframeRef.current.contentDocument.children?.[0].scrollHeight || 1000; - this._iframeRef.current.contentDocument.children[0].scrollTop = NumCast(this.layoutDoc.scrollTop); + const iframe = this._iframeRef.current; + if (iframe && iframe.contentDocument) { + iframe.setAttribute("enable-annotation", "true"); + iframe.contentDocument.addEventListener('pointerdown', this.iframedown, false); + iframe.contentDocument.addEventListener('scroll', this.iframeScrolled, false); + this.layoutDoc.scrollHeight = iframe.contentDocument.children?.[0].scrollHeight || 1000; + iframe.contentDocument.children[0].scrollTop = NumCast(this.layoutDoc.scrollTop); } this._reactionDisposer?.(); this._reactionDisposer = reaction(() => this.layoutDoc.scrollY, @@ -77,8 +82,6 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum this.setURL(); - this._iframeRef.current!.setAttribute("enable-annotation", "true"); - document.addEventListener("pointerup", this.onLongPressUp); document.addEventListener("pointermove", this.onLongPressMove); const field = Cast(this.rootDoc[this.props.fieldKey], WebField); @@ -86,11 +89,13 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum const youtubeaspect = 400 / 315; const nativeWidth = NumCast(this.layoutDoc._nativeWidth); const nativeHeight = NumCast(this.layoutDoc._nativeHeight); - if (!nativeWidth || !nativeHeight || Math.abs(nativeWidth / nativeHeight - youtubeaspect) > 0.05) { - if (!nativeWidth) this.layoutDoc._nativeWidth = 600; - this.layoutDoc._nativeHeight = NumCast(this.layoutDoc._nativeWidth) / youtubeaspect; - this.layoutDoc._height = NumCast(this.layoutDoc._width) / youtubeaspect; - } + if (field) { + if (!nativeWidth || !nativeHeight || Math.abs(nativeWidth / nativeHeight - youtubeaspect) > 0.05) { + if (!nativeWidth) this.layoutDoc._nativeWidth = 600; + this.layoutDoc._nativeHeight = NumCast(this.layoutDoc._nativeWidth) / youtubeaspect; + this.layoutDoc._height = NumCast(this.layoutDoc._width) / youtubeaspect; + } + } // else it's an HTMLfield } else if (field?.url) { const result = await WebRequest.get(Utils.CorsProxy(field.url.href)); this.dataDoc.text = htmlToText.fromString(result.content); @@ -101,8 +106,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum this._reactionDisposer?.(); document.removeEventListener("pointerup", this.onLongPressUp); document.removeEventListener("pointermove", this.onLongPressMove); - this._iframeRef.current!.contentDocument?.removeEventListener('pointerdown', this.iframedown); - this._iframeRef.current!.contentDocument?.removeEventListener('scroll', this.iframeScrolled); + this._iframeRef.current?.contentDocument?.removeEventListener('pointerdown', this.iframedown); + this._iframeRef.current?.contentDocument?.removeEventListener('scroll', this.iframeScrolled); } @action @@ -112,6 +117,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum @action submitURL = () => { + if (!this._url.startsWith("http")) this._url = "http://" + this._url; this.dataDoc[this.props.fieldKey] = new WebField(new URL(this._url)); } @@ -308,6 +314,20 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum } } + + @undoBatch + @action + toggleNativeDimensions = () => { + Doc.toggleNativeDimensions(this.layoutDoc, this.props.ContentScaling(), this.props.NativeWidth(), this.props.NativeHeight()); + } + specificContextMenu = (e: React.MouseEvent): void => { + const cm = ContextMenu.Instance; + const funcs: ContextMenuProps[] = []; + funcs.push({ description: (!this.layoutDoc._nativeWidth || !this.layoutDoc._nativeHeight ? "Freeze" : "Unfreeze") + " Aspect", event: this.toggleNativeDimensions, icon: "snowflake" }); + cm.addItem({ description: "Options...", subitems: funcs, icon: "asterisk" }); + + } + //const href = "https://brown365-my.sharepoint.com/personal/bcz_ad_brown_edu/_layouts/15/Doc.aspx?sourcedoc={31aa3178-4c21-4474-b367-877d0a7135e4}&action=embedview&wdStartOn=1"; @computed @@ -356,14 +376,20 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum width: Number.isFinite(this.props.ContentScaling()) ? `${100 / this.props.ContentScaling()}%` : "100%", height: Number.isFinite(this.props.ContentScaling()) ? `${100 / this.props.ContentScaling()}%` : "100%", pointerEvents: this.layoutDoc.isBackground ? "none" : undefined - }} > + }} + onContextMenu={this.specificContextMenu}> + <base target="_blank" /> {this.content} <div className={"webBox-outerContent"} ref={this._outerRef} style={{ pointerEvents: this.layoutDoc.isAnnotating && !this.layoutDoc.isBackground ? "all" : "none" }} onWheel={e => e.stopPropagation()} onScroll={e => { - if (this._iframeRef.current!.contentDocument!.children[0].scrollTop !== this._outerRef.current!.scrollTop) { - this._iframeRef.current!.contentDocument!.children[0].scrollTop = this._outerRef.current!.scrollTop; + const iframe = this._iframeRef?.current?.contentDocument; + const outerFrame = this._outerRef.current; + if (iframe && outerFrame) { + if (iframe.children[0].scrollTop !== outerFrame.scrollTop) { + iframe.children[0].scrollTop = outerFrame.scrollTop; + } } //this._outerRef.current!.scrollTop !== this._scrollTop && (this._outerRef.current!.scrollTop = this._scrollTop) }}> |
