From 1c50b9607d6ea6916e6ae32d9d51fba096421b08 Mon Sep 17 00:00:00 2001 From: geireann Date: Wed, 6 Oct 2021 18:09:54 -0400 Subject: presBox type fix --- src/client/views/nodes/trails/PresBox.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/nodes') diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index 8e61a224c..8a3df09e3 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -1143,10 +1143,10 @@ export class PresBox extends ViewBoxBaseComponent @computed get transitionDropdown() { const activeItem: Doc = this.activeItem; const targetDoc: Doc = this.targetDoc; - const type = targetDoc.type; const isPresCollection: boolean = (targetDoc === this.layoutDoc.presCollection); const isPinWithView: boolean = BoolCast(activeItem.presPinView); if (activeItem && targetDoc) { + const type = targetDoc.type; const transitionSpeed = activeItem.presTransition ? NumCast(activeItem.presTransition) / 1000 : 0.5; let duration = activeItem.presDuration ? NumCast(activeItem.presDuration) / 1000 : 2; if (activeItem.type === DocumentType.AUDIO) duration = NumCast(activeItem.duration); -- cgit v1.2.3-70-g09d2 From a46d659229120cdb139f716b1a48ec6b887807bb Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 6 Oct 2021 19:40:40 -0400 Subject: fixed lightbox view to shrinkwrap collections when opened, but not force fit contents to allow users to navigate. fixed comparison box to show context of maker'/annotation documents. fixed ink pointer events to honor pointerEvents prop (eg when embedded in a comparisonBox that turns them off). --- src/client/views/InkingStroke.tsx | 2 +- src/client/views/LightboxView.tsx | 4 ++-- .../collectionFreeForm/CollectionFreeFormView.tsx | 2 +- .../collections/collectionSchema/CollectionSchemaCells.tsx | 1 - src/client/views/nodes/ComparisonBox.tsx | 12 +++++++++--- 5 files changed, 13 insertions(+), 8 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index d05a4a6e4..752db1413 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -209,7 +209,7 @@ export class InkingStroke extends ViewBoxBaseComponent { LightboxView.SetLightboxDoc(undefined); } }} > - +
{ DataDoc={undefined} LayoutTemplate={LightboxView.LightboxDocTemplate} addDocument={undefined} - fitContentsToDoc={this.fitToBox} + // fitContentsToDoc={this.fitToBox} // bcz: why do we want this? when we initially open a colletion, we shrinkwrap it which allows for user navigation. if we later encounter a collection, it's not clear to me that we want to make it either shrinkwrap or fitContents... isDocumentActive={returnFalse} isContentActive={returnTrue} addDocTab={this.addDocTab} diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index b2db1168d..7dcd63b80 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1036,7 +1036,7 @@ export class CollectionFreeFormView extends CollectionSubView; diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx index ed196349e..0274cc49c 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaCells.tsx @@ -103,7 +103,6 @@ export class CollectionSchemaCell extends React.Component { this.props.changeFocusedCellByIndex(this.props.row, this.props.col); this.props.setPreviewDoc(this.props.rowProps.original); - console.log("click cell"); let url: string; if (url = StrCast(this.props.rowProps.row.href)) { try { diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx index f23c68409..b1aada158 100644 --- a/src/client/views/nodes/ComparisonBox.tsx +++ b/src/client/views/nodes/ComparisonBox.tsx @@ -89,14 +89,20 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent { var whichDoc = Cast(this.dataDoc[which], Doc, null); - if (whichDoc?.type === DocumentType.MARKER) whichDoc = Cast(whichDoc.annotationOn, Doc, null); + //if (whichDoc?.type === DocumentType.MARKER) + const targetDoc = Cast(whichDoc.annotationOn, Doc, null) ?? whichDoc; return whichDoc ? <> - { + whichDoc !== targetDoc && r?.focus(targetDoc); + }} + {...OmitKeys(this.props, ["NativeWidth", "NativeHeight"]).omit} isContentActive={returnFalse} isDocumentActive={returnFalse} styleProvider={this.docStyleProvider} - Document={whichDoc} + Document={targetDoc} DataDoc={undefined} + hideLinkButton={true} pointerEvents={"none"} /> {clearButton(which)} : // placeholder image if doc is missing -- cgit v1.2.3-70-g09d2 From 8691e25e2f65e5041e147d37374c77947298a4b5 Mon Sep 17 00:00:00 2001 From: geireann Date: Wed, 6 Oct 2021 20:02:24 -0400 Subject: added zoom --- src/client/util/DocumentManager.ts | 5 +++-- src/client/views/nodes/trails/PresBox.tsx | 37 ++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 3 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index b66befb08..66b6a1e44 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -161,7 +161,8 @@ export class DocumentManager { originatingDoc: Opt = undefined, // doc that initiated the display of the target odoc finished?: () => void, originalTarget?: Doc, - noSelect?: boolean + noSelect?: boolean, + presZoom?: number ): Promise => { originalTarget = originalTarget ?? targetDoc; const getFirstDocView = LightboxView.LightboxDoc ? DocumentManager.Instance.getLightboxDocumentView : DocumentManager.Instance.getFirstDocumentView; @@ -194,7 +195,7 @@ export class DocumentManager { if (focusView) { !noSelect && Doc.linkFollowHighlight(focusView.rootDoc); //TODO:glr make this a setting in PresBox focusView.focus(targetDoc, { - originalTarget, willZoom, afterFocus: (didFocus: boolean) => + originalTarget, willZoom, scale: presZoom, afterFocus: (didFocus: boolean) => new Promise(res => { focusAndFinish(didFocus); res(); diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx index 8a3df09e3..2a153f256 100644 --- a/src/client/views/nodes/trails/PresBox.tsx +++ b/src/client/views/nodes/trails/PresBox.tsx @@ -404,7 +404,7 @@ export class PresBox extends ViewBoxBaseComponent } else if ((curDoc.presMovement === PresMovement.Zoom || curDoc.presMovement === PresMovement.Jump) && targetDoc) { LightboxView.SetLightboxDoc(undefined); //awaiting jump so that new scale can be found, since jumping is async - await DocumentManager.Instance.jumpToDocument(targetDoc, true, openInTab, srcContext, undefined, undefined, undefined, includesDoc || tab ? undefined : resetSelection, undefined, true); // documents open in new tab instead of on right + await DocumentManager.Instance.jumpToDocument(targetDoc, true, openInTab, srcContext, undefined, undefined, undefined, includesDoc || tab ? undefined : resetSelection, undefined, true, NumCast(curDoc.presZoom)); // documents open in new tab instead of on right } // After navigating to the document, if it is added as a presPinView then it will // adjust the pan and scale to that of the pinView when it was added. @@ -1026,6 +1026,15 @@ export class PresBox extends ViewBoxBaseComponent Array.from(this._selectedArray.keys()).forEach((doc) => doc.presTransition = timeInMS); } + // Converts seconds to ms and updates presTransition + setZoom = (number: String, change?: number) => { + let scale = Number(number) / 100; + if (change) scale += change; + if (scale < 0.01) scale = 0.01; + if (scale > 1.5) scale = 1.5; + Array.from(this._selectedArray.keys()).forEach((doc) => doc.presZoom = scale); + } + // Converts seconds to ms and updates presDuration setDurationTime = (number: String, change?: number) => { let timeInMS = Number(number) * 1000; @@ -1148,6 +1157,7 @@ export class PresBox extends ViewBoxBaseComponent if (activeItem && targetDoc) { const type = targetDoc.type; const transitionSpeed = activeItem.presTransition ? NumCast(activeItem.presTransition) / 1000 : 0.5; + const zoom = activeItem.presZoom ? NumCast(activeItem.presZoom) * 100 : 75; let duration = activeItem.presDuration ? NumCast(activeItem.presDuration) / 1000 : 2; if (activeItem.type === DocumentType.AUDIO) duration = NumCast(activeItem.duration); const effect = targetDoc.presEffect ? targetDoc.presEffect : 'None'; @@ -1172,6 +1182,31 @@ export class PresBox extends ViewBoxBaseComponent
} +
+
Zoom (% screen filled)
+
+ this.setZoom(e.target.value))} />% +
+
+
this.setZoom(String(zoom), 0.1))}> + +
+
this.setZoom(String(zoom), -0.1))}> + +
+
+
+ this._batch = UndoManager.StartBatch("presZoom")} + onPointerUp={() => this._batch?.end()} + onChange={(e: React.ChangeEvent) => { + e.stopPropagation(); + this.setZoom(e.target.value); + }} />
Movement Speed
-- cgit v1.2.3-70-g09d2 From ed68bbec549dedeb89bcb584151b097863b52d0d Mon Sep 17 00:00:00 2001 From: bobzel Date: Thu, 14 Oct 2021 12:16:17 -0400 Subject: fixed comparison box error. --- src/client/views/nodes/ComparisonBox.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/views/nodes') diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx index b1aada158..0f962f95c 100644 --- a/src/client/views/nodes/ComparisonBox.tsx +++ b/src/client/views/nodes/ComparisonBox.tsx @@ -90,7 +90,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent { var whichDoc = Cast(this.dataDoc[which], Doc, null); //if (whichDoc?.type === DocumentType.MARKER) - const targetDoc = Cast(whichDoc.annotationOn, Doc, null) ?? whichDoc; + const targetDoc = Cast(whichDoc?.annotationOn, Doc, null) ?? whichDoc; return whichDoc ? <> { -- cgit v1.2.3-70-g09d2 From bdf0befa2b5eff79c2729254c2d053afe18b1646 Mon Sep 17 00:00:00 2001 From: bobzel Date: Sat, 16 Oct 2021 01:58:15 -0400 Subject: fixed warnings/errors & redirection to /home --- src/client/views/collections/TreeView.tsx | 12 ++++++------ .../collections/collectionSchema/CollectionSchemaHeaders.tsx | 4 ++-- src/client/views/linking/LinkEditor.tsx | 4 ++-- src/client/views/nodes/ComparisonBox.tsx | 2 +- src/server/server_Initialization.ts | 2 ++ 5 files changed, 13 insertions(+), 11 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/views/collections/TreeView.tsx b/src/client/views/collections/TreeView.tsx index a3da0e0e4..7f2128230 100644 --- a/src/client/views/collections/TreeView.tsx +++ b/src/client/views/collections/TreeView.tsx @@ -820,7 +820,7 @@ export class TreeView extends React.Component { childDocs: Doc[], treeView: CollectionTreeView, parentTreeView: CollectionTreeView | TreeView | undefined, - conainerCollection: Doc, + containerCollection: Doc, dataDoc: Doc | undefined, parentCollectionDoc: Doc | undefined, containerPrevSibling: Doc | undefined, @@ -846,16 +846,16 @@ export class TreeView extends React.Component { unobserveHeight: (ref: any) => void, contextMenuItems: ({ script: ScriptField, filter: ScriptField, label: string, icon: string }[]) ) { - const viewSpecScript = Cast(conainerCollection.viewSpecScript, ScriptField); + const viewSpecScript = Cast(containerCollection.viewSpecScript, ScriptField); if (viewSpecScript) { childDocs = childDocs.filter(d => viewSpecScript.script.run({ doc: d }, console.log).result); } - const docs = TreeView.sortDocs(childDocs, StrCast(conainerCollection.treeViewSortCriterion)); + const docs = TreeView.sortDocs(childDocs, StrCast(containerCollection.treeViewSortCriterion)); const rowWidth = () => panelWidth() - treeBulletWidth(); const treeViewRefs = new Map(); return docs.filter(child => child instanceof Doc).map((child, i) => { - const pair = Doc.GetLayoutDataDocPair(conainerCollection, dataDoc, child); + const pair = Doc.GetLayoutDataDocPair(containerCollection, dataDoc, child); if (!pair.layout || pair.data instanceof Promise) { return (null); } @@ -883,7 +883,7 @@ export class TreeView extends React.Component { return treeViewRefs.set(child, r ? r : undefined)} document={pair.layout} dataDoc={pair.data} - containerCollection={conainerCollection} + containerCollection={containerCollection} prevSibling={docs[i]} treeView={treeView} indentDocument={indent} @@ -891,7 +891,7 @@ export class TreeView extends React.Component { onCheckedClick={onCheckedClick} onChildClick={onChildClick} renderDepth={renderDepth} - removeDoc={StrCast(conainerCollection.freezeChildren).includes("remove") ? undefined : remove} + removeDoc={StrCast(containerCollection.freezeChildren).includes("remove") ? undefined : remove} addDocument={addDocument} styleProvider={styleProvider} panelWidth={rowWidth} diff --git a/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx b/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx index 074074bc5..1306b79cb 100644 --- a/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx +++ b/src/client/views/collections/collectionSchema/CollectionSchemaHeaders.tsx @@ -395,8 +395,8 @@ export class KeysDropdown extends React.Component { this.closeResultsVisibility = "none"; } for (let i = 0; i < (filters?.length ?? 0) - 1; i++) { - if (filters![i] === this.props.col.heading && keyOptions.includes(filters![i].split(":")[1]) === false) { - keyOptions.push(filters![i + 1]); + if (filters[i] === this.props.col.heading && keyOptions.includes(filters[i].split(":")[1]) === false) { + keyOptions.push(filters[i + 1]); } } const options = keyOptions.map(key => { diff --git a/src/client/views/linking/LinkEditor.tsx b/src/client/views/linking/LinkEditor.tsx index 5b5c3cd01..db331bb75 100644 --- a/src/client/views/linking/LinkEditor.tsx +++ b/src/client/views/linking/LinkEditor.tsx @@ -54,9 +54,9 @@ export class LinkEditor extends React.Component { linkRelationshipList.push(value); linkRelationshipSizes.push(1); const randColor = "rgb(" + Math.floor(Math.random() * 255) + "," + Math.floor(Math.random() * 255) + "," + Math.floor(Math.random() * 255) + ")"; - linkColorList.push(randColor) + linkColorList.push(randColor); // if the relationship is already in the list AND the new rel is different from the prev rel, update the rel sizes - } else if (linkRelationshipList && value != prevRelationship) { + } else if (linkRelationshipList && value !== prevRelationship) { const index = linkRelationshipList.indexOf(value); //increment size of new relationship size if (index !== -1 && index < linkRelationshipSizes.length) { diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx index 0f962f95c..750213e67 100644 --- a/src/client/views/nodes/ComparisonBox.tsx +++ b/src/client/views/nodes/ComparisonBox.tsx @@ -88,7 +88,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent; }; const displayDoc = (which: string) => { - var whichDoc = Cast(this.dataDoc[which], Doc, null); + const whichDoc = Cast(this.dataDoc[which], Doc, null); //if (whichDoc?.type === DocumentType.MARKER) const targetDoc = Cast(whichDoc?.annotationOn, Doc, null) ?? whichDoc; return whichDoc ? <> diff --git a/src/server/server_Initialization.ts b/src/server/server_Initialization.ts index 0f4a067fc..00a801e03 100644 --- a/src/server/server_Initialization.ts +++ b/src/server/server_Initialization.ts @@ -37,6 +37,8 @@ export let resolvedServerUrl: string; export default async function InitializeServer(routeSetter: RouteSetter) { const app = buildWithMiddleware(express()); + // Root route of express app + app.get("/", (req, res) => res.redirect("/home")); app.use(express.static(publicDirectory, { setHeaders: res => res.setHeader("Access-Control-Allow-Origin", "*") -- cgit v1.2.3-70-g09d2 From 3e0a9ff2c708891a15a681e5af549caf0b18ff60 Mon Sep 17 00:00:00 2001 From: bobzel Date: Tue, 26 Oct 2021 12:06:36 -0400 Subject: when document is in lightbox view and a link is followed to its sidebar, we no longer reopen the document in its context. fixed selecting annotations on web/pdf. don't change document height when shown in a linkPreview. webBox fixes for pages with scripts. fixed range bounds when clicking on web text several fixes to web pages on server and client. client webbox allows clicks on divs with onclick instead of doing selection also hacky fix so that google search url doesn't keep expanding by removing 'q=' regions also added prevent/allow script menu item server grabs all html and hides id="google.." which are ads. also rewrites hrefs starting with http to route through corsProxy also removes target=_blank tags to prevent pages from opening outside of dash. also cleaned up routes and comments also when not logged in, references to anything in dash domain route to /home --- package-lock.json | 5 + package.json | 1 + src/Utils.ts | 2 +- src/client/util/LinkManager.ts | 6 +- src/client/views/DocumentDecorations.tsx | 4 +- src/client/views/InkControlPtHandles.tsx | 16 +-- src/client/views/InkStrokeProperties.ts | 72 +++++++------ src/client/views/InkTangentHandles.tsx | 6 +- src/client/views/InkingStroke.tsx | 9 +- src/client/views/collections/CollectionSubView.tsx | 5 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 4 +- src/client/views/nodes/DocumentView.tsx | 6 +- src/client/views/nodes/WebBox.tsx | 77 +++++++++++--- src/server/server_Initialization.ts | 115 ++++++++++++--------- 14 files changed, 206 insertions(+), 122 deletions(-) (limited to 'src/client/views/nodes') diff --git a/package-lock.json b/package-lock.json index c1dd8506f..3aff3a549 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9264,6 +9264,11 @@ "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", "optional": true }, + "memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI=" + }, "meow": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", diff --git a/package.json b/package.json index 5d10c0d54..99c818062 100644 --- a/package.json +++ b/package.json @@ -194,6 +194,7 @@ "libxmljs": "^0.19.7", "lodash": "^4.17.15", "material-ui": "^0.20.2", + "memorystream": "^0.3.1", "mobile-detect": "^1.4.4", "mobx": "^5.15.7", "mobx-react": "^5.4.4", diff --git a/src/Utils.ts b/src/Utils.ts index 53182cc9c..bfb29fe8d 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -599,7 +599,7 @@ export function getWordAtPoint(elem: any, x: number, y: number): string | undefi range.selectNodeContents(elem); var currentPos = 0; const endPos = range.endOffset; - while (currentPos + 1 < endPos) { + while (currentPos + 1 <= endPos) { range.setStart(elem, currentPos); range.setEnd(elem, currentPos + 1); const rangeRect = range.getBoundingClientRect(); diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts index 90a8f2737..62b13e2c6 100644 --- a/src/client/util/LinkManager.ts +++ b/src/client/util/LinkManager.ts @@ -234,8 +234,10 @@ export class LinkManager { setTimeout(LightboxView.Next); finished?.(); } else { - const containerDoc = Cast(target.annotationOn, Doc, null) || target; - const targetContext = Cast(containerDoc?.context, Doc, null); + const containerAnnoDoc = Cast(target.annotationOn, Doc, null); + const containerDoc = containerAnnoDoc || target; + const containerDocContext = Cast(containerDoc?.context, Doc, null); + const targetContext = LightboxView.LightboxDoc ? containerAnnoDoc || containerDocContext : containerDocContext; const targetNavContext = !Doc.AreProtosEqual(targetContext, currentContext) ? targetContext : undefined; DocumentManager.Instance.jumpToDocument(target, zoom, (doc, finished) => createViewFunc(doc, StrCast(linkDoc.followLinkLocation, "lightbox"), finished), targetNavContext, linkDoc, undefined, sourceDoc, finished); } diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 17a81149c..5b44a0552 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -195,11 +195,13 @@ export class DocumentDecorations extends React.Component<{ PanelWidth: number, P @action onRotateDown = (e: React.PointerEvent): void => { this._rotateUndo = UndoManager.StartBatch("rotatedown"); + const pt = { x: (this.Bounds.x + this.Bounds.r) / 2, y: (this.Bounds.y + this.Bounds.b) / 2 }; setupMoveUpEvents(this, e, (e: PointerEvent, down: number[], delta: number[]) => { const movement = { X: delta[0], Y: e.clientY - down[1] }; const angle = Math.max(1, Math.abs(movement.Y / 10)); - InkStrokeProperties.Instance?.rotateInk(2 * movement.X / angle * (Math.PI / 180)); + const selectedInk = SelectionManager.Views().filter(i => Document(i.rootDoc).type === DocumentType.INK); + InkStrokeProperties.Instance?.rotateInk(selectedInk, 2 * movement.X / angle * (Math.PI / 180), pt); return false; }, () => { diff --git a/src/client/views/InkControlPtHandles.tsx b/src/client/views/InkControlPtHandles.tsx index 0644488b3..73de4a3e0 100644 --- a/src/client/views/InkControlPtHandles.tsx +++ b/src/client/views/InkControlPtHandles.tsx @@ -3,18 +3,20 @@ import { action, observable } from "mobx"; import { observer } from "mobx-react"; import { Doc } from "../../fields/Doc"; import { ControlPoint, InkData, PointData } from "../../fields/InkField"; +import { List } from "../../fields/List"; import { listSpec } from "../../fields/Schema"; import { Cast } from "../../fields/Types"; import { setupMoveUpEvents } from "../../Utils"; import { Transform } from "../util/Transform"; import { UndoManager } from "../util/UndoManager"; import { Colors } from "./global/globalEnums"; -import { InkStrokeProperties } from "./InkStrokeProperties"; -import { List } from "../../fields/List"; import { InkingStroke } from "./InkingStroke"; +import { InkStrokeProperties } from "./InkStrokeProperties"; +import { DocumentView } from "./nodes/DocumentView"; export interface InkControlProps { inkDoc: Doc; + inkView: DocumentView; inkCtrlPoints: InkData; screenCtrlPoints: InkData; screenSpaceLineWidth: number; @@ -51,12 +53,12 @@ export class InkControlPtHandles extends React.Component { setupMoveUpEvents(this, e, action((e: PointerEvent, down: number[], delta: number[]) => { if (!this.controlUndo) this.controlUndo = UndoManager.StartBatch("drag ink ctrl pt"); - InkStrokeProperties.Instance?.moveControlPtHandle(delta[0] * screenScale, delta[1] * screenScale, controlIndex); + InkStrokeProperties.Instance?.moveControlPtHandle(this.props.inkView, delta[0] * screenScale, delta[1] * screenScale, controlIndex); return false; }), action(() => { if (this.controlUndo) { - InkStrokeProperties.Instance?.snapControl(this.props.inkDoc, controlIndex); + InkStrokeProperties.Instance?.snapControl(this.props.inkView, controlIndex); } this.controlUndo?.end(); this.controlUndo = undefined; @@ -71,11 +73,11 @@ export class InkControlPtHandles extends React.Component { } else { if (brokenIndices?.includes(equivIndex)) { if (!this.controlUndo) this.controlUndo = UndoManager.StartBatch("make smooth"); - InkStrokeProperties.Instance?.snapHandleTangent(equivIndex, handleIndexA, handleIndexB); + InkStrokeProperties.Instance?.snapHandleTangent(this.props.inkView, equivIndex, handleIndexA, handleIndexB); } if (equivIndex !== controlIndex && brokenIndices?.includes(controlIndex)) { if (!this.controlUndo) this.controlUndo = UndoManager.StartBatch("make smooth"); - InkStrokeProperties.Instance?.snapHandleTangent(controlIndex, handleIndexA, handleIndexB); + InkStrokeProperties.Instance?.snapHandleTangent(this.props.inkView, controlIndex, handleIndexA, handleIndexB); } } this.controlUndo?.end(); @@ -98,7 +100,7 @@ export class InkControlPtHandles extends React.Component { @action onDelete = (e: KeyboardEvent) => { if (["-", "Backspace", "Delete"].includes(e.key)) { - InkStrokeProperties.Instance?.deletePoints(); + InkStrokeProperties.Instance?.deletePoints(this.props.inkView); e.stopPropagation(); } } diff --git a/src/client/views/InkStrokeProperties.ts b/src/client/views/InkStrokeProperties.ts index ee30caa3d..33e25bbbb 100644 --- a/src/client/views/InkStrokeProperties.ts +++ b/src/client/views/InkStrokeProperties.ts @@ -1,16 +1,15 @@ import { Bezier } from "bezier-js"; -import { action, computed, observable, reaction } from "mobx"; -import { Doc } from "../../fields/Doc"; -import { Document } from "../../fields/documentSchemas"; +import { action, observable, reaction } from "mobx"; +import { Doc, Opt } from "../../fields/Doc"; import { InkData, InkField, InkTool, PointData } from "../../fields/InkField"; import { List } from "../../fields/List"; import { listSpec } from "../../fields/Schema"; import { Cast, NumCast } from "../../fields/Types"; import { DocumentType } from "../documents/DocumentTypes"; import { CurrentUserUtils } from "../util/CurrentUserUtils"; -import { SelectionManager } from "../util/SelectionManager"; import { undoBatch } from "../util/UndoManager"; import { InkingStroke } from "./InkingStroke"; +import { DocumentView } from "./nodes/DocumentView"; export class InkStrokeProperties { static Instance: InkStrokeProperties | undefined; @@ -25,21 +24,16 @@ export class InkStrokeProperties { reaction(() => CurrentUserUtils.SelectedTool, tool => (tool !== InkTool.None) && (this._controlButton = false)); } - @computed get selectedInk() { - const inks = SelectionManager.Views().filter(i => Document(i.rootDoc).type === DocumentType.INK); - return inks.length ? inks : undefined; - } - /** * Helper function that enables other functions to be applied to a particular ink instance. * @param func The inputted function. * @param requireCurrPoint Indicates whether the current selected point is needed. */ - applyFunction = (func: (doc: Doc, ink: InkData, ptsXscale: number, ptsYscale: number) => { X: number, Y: number }[] | undefined, requireCurrPoint: boolean = false) => { + applyFunction = (strokes: Opt, func: (view: DocumentView, ink: InkData, ptsXscale: number, ptsYscale: number, inkStrokeWidth: number) => { X: number, Y: number }[] | undefined, requireCurrPoint: boolean = false) => { var appliedFunc = false; - this.selectedInk?.forEach(action(inkView => { - if (this.selectedInk?.length === 1 && (!requireCurrPoint || this._currentPoint !== -1)) { - const doc = Document(inkView.rootDoc); + (strokes instanceof DocumentView ? [strokes] : strokes)?.forEach(action(inkView => { + if (!requireCurrPoint || this._currentPoint !== -1) { + const doc = inkView.rootDoc; if (doc.type === DocumentType.INK && doc.width && doc.height) { const ink = Cast(doc.data, InkField)?.inkData; if (ink) { @@ -47,7 +41,7 @@ export class InkStrokeProperties { const oldYrange = (ys => ({ coord: NumCast(doc.y), min: Math.min(...ys), max: Math.max(...ys) }))(ink.map(p => p.Y)); const ptsXscale = ((NumCast(doc._width) - NumCast(doc.strokeWidth)) / ((oldXrange.max - oldXrange.min) || 1)) || 1; const ptsYscale = ((NumCast(doc._height) - NumCast(doc.strokeWidth)) / ((oldYrange.max - oldYrange.min) || 1)) || 1; - const newPoints = func(doc, ink, ptsXscale, ptsYscale); + const newPoints = func(inkView, ink, ptsXscale, ptsYscale, NumCast(doc.strokeWidth)); if (newPoints) { const newXrange = (xs => ({ min: Math.min(...xs), max: Math.max(...xs) }))(newPoints.map(p => p.X)); const newYrange = (ys => ({ min: Math.min(...ys), max: Math.max(...ys) }))(newPoints.map(p => p.Y)); @@ -73,8 +67,9 @@ export class InkStrokeProperties { */ @undoBatch @action - addPoints = (t: number, i: number, controls: { X: number, Y: number }[]) => { - this.applyFunction((doc: Doc, ink: InkData) => { + addPoints = (inkView: DocumentView, t: number, i: number, controls: { X: number, Y: number }[]) => { + this.applyFunction(inkView, (view: DocumentView, ink: InkData) => { + const doc = view.rootDoc; const array = [controls[i], controls[i + 1], controls[i + 2], controls[i + 3]]; const newsegs = new Bezier(array.map(p => ({ x: p.X, y: p.Y }))).split(t); const splicepts = [...newsegs.left.points, ...newsegs.right.points]; @@ -143,9 +138,10 @@ export class InkStrokeProperties { */ @undoBatch @action - deletePoints = () => this.applyFunction((doc: Doc, ink: InkData) => { + deletePoints = (inkView: DocumentView) => this.applyFunction(inkView, (view: DocumentView, ink: InkData) => { + const doc = view.rootDoc; const newPoints: { X: number, Y: number }[] = []; - const toRemove = Math.floor(((this._currentPoint + 2) / 4)); + const toRemove = Math.floor((this._currentPoint + 2) / 4); const last = this._currentPoint === ink.length - 1; for (let i = 0; i < ink.length; i++) { if (Math.floor((i + 2) / 4) !== toRemove && (toRemove !== 0 || i > 3)) { @@ -164,17 +160,22 @@ export class InkStrokeProperties { */ @undoBatch @action - rotateInk = (angle: number) => { - this.applyFunction((doc: Doc, ink: InkData, xScale: number, yScale: number) => { - const oldXrange = (xs => ({ coord: NumCast(doc.x), min: Math.min(...xs), max: Math.max(...xs) }))(ink.map(p => p.X)); - const oldYrange = (ys => ({ coord: NumCast(doc.y), min: Math.min(...ys), max: Math.max(...ys) }))(ink.map(p => p.Y)); - const centerPoint = { X: (oldXrange.min + oldXrange.max) / 2, Y: (oldYrange.min + oldYrange.max) / 2 }; + rotateInk = (inkStrokes: DocumentView[], angle: number, scrpt: { x: number, y: number }) => { + this.applyFunction(inkStrokes, (view: DocumentView, ink: InkData, xScale: number, yScale: number, inkStrokeWidth: number) => { + const oldXrangeMin = Math.min(...ink.map(p => p.X)); + const oldYrangeMin = Math.min(...ink.map(p => p.Y)); + const docViewCenterPt = view.screenToLocalTransform().transformPoint(scrpt.x, scrpt.y); + const inkCenterPt = { + X: (docViewCenterPt[0] - inkStrokeWidth / 2) / xScale + oldXrangeMin, + Y: (docViewCenterPt[1] - inkStrokeWidth / 2) / yScale + oldYrangeMin + }; const newPoints = ink.map(i => { - const pt = { X: i.X - centerPoint.X, Y: i.Y - centerPoint.Y }; + const pt = { X: i.X - inkCenterPt.X, Y: i.Y - inkCenterPt.Y }; const newX = Math.cos(angle) * pt.X - Math.sin(angle) * pt.Y * yScale / xScale; const newY = Math.sin(angle) * pt.X * xScale / yScale + Math.cos(angle) * pt.Y; - return { X: newX + centerPoint.X, Y: newY + centerPoint.Y }; + return { X: newX + inkCenterPt.X, Y: newY + inkCenterPt.Y }; }); + const doc = view.rootDoc; doc.rotation = NumCast(doc.rotation) + angle; return newPoints; }); @@ -185,8 +186,8 @@ export class InkStrokeProperties { */ @undoBatch @action - moveControlPtHandle = (deltaX: number, deltaY: number, controlIndex: number) => - this.applyFunction((doc: Doc, ink: InkData, xScale: number, yScale: number) => { + moveControlPtHandle = (inkView: DocumentView, deltaX: number, deltaY: number, controlIndex: number) => + this.applyFunction(inkView, (view: DocumentView, ink: InkData, xScale: number, yScale: number) => { const order = controlIndex % 4; const closed = InkingStroke.IsClosed(ink); @@ -235,7 +236,8 @@ export class InkStrokeProperties { /** * Handles the movement/scaling of a control point. */ - snapControl = (inkDoc: Doc, controlIndex: number) => { + snapControl = (inkView: DocumentView, controlIndex: number) => { + const inkDoc = inkView.rootDoc; const ink = Cast(inkDoc.data, InkField)?.inkData; if (ink) { const closed = InkingStroke.IsClosed(ink); @@ -257,8 +259,8 @@ export class InkStrokeProperties { const near = Math.sqrt((nearestPt.X - refPt.X) * (nearestPt.X - refPt.X) * ptsXscale * ptsXscale + (nearestPt.Y - refPt.Y) * (nearestPt.Y - refPt.Y) * ptsYscale * ptsYscale); - if (near / (this.selectedInk?.lastElement().props.ScreenToLocalTransform().Scale || 1) < 10) { - return this.moveControlPtHandle((nearestPt.X - ink[controlIndex].X) * ptsXscale, (nearestPt.Y - ink[controlIndex].Y) * ptsYscale, controlIndex); + if (near / (inkView.props.ScreenToLocalTransform().Scale || 1) < 10) { + return this.moveControlPtHandle(inkView, (nearestPt.X - ink[controlIndex].X) * ptsXscale, (nearestPt.Y - ink[controlIndex].Y) * ptsYscale, controlIndex); } } return false; @@ -269,8 +271,9 @@ export class InkStrokeProperties { * @param handleIndexA The handle point that retains its current position. * @param handleIndexB The handle point that is rotated to be 180 degrees from its opposite. */ - snapHandleTangent = (controlIndex: number, handleIndexA: number, handleIndexB: number) => { - this.applyFunction((doc: Doc, ink: InkData) => { + snapHandleTangent = (inkView: DocumentView, controlIndex: number, handleIndexA: number, handleIndexB: number) => { + this.applyFunction(inkView, (view: DocumentView, ink: InkData) => { + const doc = view.rootDoc; const brokenIndices = Cast(doc.brokenInkIndices, listSpec("number"), []); const ind = brokenIndices.findIndex(value => value === controlIndex); if (ind !== -1) { @@ -330,8 +333,9 @@ export class InkStrokeProperties { */ @undoBatch @action - moveTangentHandle = (deltaX: number, deltaY: number, handleIndex: number, oppositeHandleIndex: number, controlIndex: number) => - this.applyFunction((doc: Doc, ink: InkData, xScale: number, yScale: number) => { + moveTangentHandle = (inkView: DocumentView, deltaX: number, deltaY: number, handleIndex: number, oppositeHandleIndex: number, controlIndex: number) => + this.applyFunction(inkView, (view: DocumentView, ink: InkData, xScale: number, yScale: number) => { + const doc = view.rootDoc; const closed = InkingStroke.IsClosed(ink); const oldHandlePoint = ink[handleIndex]; const oppositeHandlePoint = ink[oppositeHandleIndex]; diff --git a/src/client/views/InkTangentHandles.tsx b/src/client/views/InkTangentHandles.tsx index df5bebf31..f88a20448 100644 --- a/src/client/views/InkTangentHandles.tsx +++ b/src/client/views/InkTangentHandles.tsx @@ -10,11 +10,13 @@ import { emptyFunction, setupMoveUpEvents } from "../../Utils"; import { Transform } from "../util/Transform"; import { UndoManager } from "../util/UndoManager"; import { Colors } from "./global/globalEnums"; -import { InkStrokeProperties } from "./InkStrokeProperties"; import { InkingStroke } from "./InkingStroke"; +import { InkStrokeProperties } from "./InkStrokeProperties"; +import { DocumentView } from "./nodes/DocumentView"; export interface InkHandlesProps { inkDoc: Doc; + inkView: DocumentView; screenCtrlPoints: InkData; screenSpaceLineWidth: number; ScreenToLocalTransform: () => Transform; @@ -37,7 +39,7 @@ export class InkTangentHandles extends React.Component { setupMoveUpEvents(this, e, (e: PointerEvent, down: number[], delta: number[]) => { if (!controlUndo) controlUndo = UndoManager.StartBatch("DocDecs move tangent"); if (e.altKey) this.onBreakTangent(controlIndex); - InkStrokeProperties.Instance?.moveTangentHandle(-delta[0] * screenScale, -delta[1] * screenScale, handleIndex, oppositeHandleIndex, controlIndex); + InkStrokeProperties.Instance?.moveTangentHandle(this.props.inkView, -delta[0] * screenScale, -delta[1] * screenScale, handleIndex, oppositeHandleIndex, controlIndex); return false; }, () => { controlUndo?.end(); diff --git a/src/client/views/InkingStroke.tsx b/src/client/views/InkingStroke.tsx index 752db1413..d312331d0 100644 --- a/src/client/views/InkingStroke.tsx +++ b/src/client/views/InkingStroke.tsx @@ -1,17 +1,17 @@ import React = require("react"); -import { Bezier } from "bezier-js"; import { action, IReactionDisposer, observable, reaction } from "mobx"; import { observer } from "mobx-react"; import { Doc } from "../../fields/Doc"; import { documentSchema } from "../../fields/documentSchemas"; import { InkData, InkField, InkTool } from "../../fields/InkField"; import { makeInterface } from "../../fields/Schema"; -import { Cast, NumCast, StrCast, BoolCast } from "../../fields/Types"; +import { BoolCast, Cast, NumCast, StrCast } from "../../fields/Types"; import { TraceMobx } from "../../fields/util"; import { emptyFunction, returnFalse, setupMoveUpEvents } from "../../Utils"; import { CognitiveServices } from "../cognitive_services/CognitiveServices"; import { CurrentUserUtils } from "../util/CurrentUserUtils"; import { InteractionUtils } from "../util/InteractionUtils"; +import { SnappingManager } from "../util/SnappingManager"; import { ContextMenu } from "./ContextMenu"; import { ViewBoxBaseComponent } from "./DocComponent"; import { Colors } from "./global/globalEnums"; @@ -20,7 +20,6 @@ import "./InkStroke.scss"; import { InkStrokeProperties } from "./InkStrokeProperties"; import { InkTangentHandles } from "./InkTangentHandles"; import { FieldView, FieldViewProps } from "./nodes/FieldView"; -import { SnappingManager } from "../util/SnappingManager"; import Color = require("color"); type InkDocument = makeInterface<[typeof documentSchema]>; @@ -83,7 +82,7 @@ export class InkingStroke extends ViewBoxBaseComponent (schemaCtor: (doc: Doc) => T, moreProps?: // } } if (uriList) { - console.log("Web URI = ", uriList); // const existingWebDoc = await Hypothesis.findWebDoc(uriList); // if (existingWebDoc) { // const alias = Doc.MakeAlias(existingWebDoc); @@ -390,7 +389,6 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: // addDocument(alias); // } else { - console.log("Adding ..."); const newDoc = Docs.Create.WebDocument(uriList.split("#annotations:")[0], {// clean hypothes.is URLs that reference a specific annotation (eg. https://en.wikipedia.org/wiki/Cartoon#annotations:t7qAeNbCEeqfG5972KR2Ig) ...options, title: uriList.split("#annotations:")[0], @@ -399,8 +397,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T, moreProps?: _nativeWidth: 850, useCors: true }); - console.log(" ... " + newDoc.title); - console.log(" ... " + addDocument(newDoc) + " " + newDoc.title); + addDocument(newDoc); } return; } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index 7dcd63b80..febccbfcc 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -75,7 +75,7 @@ export type collectionFreeformViewProps = { scaleField?: string; noOverlay?: boolean; // used to suppress docs in the overlay (z) layer (ie, for minimap since overlay doesn't scale) engineProps?: any; - dontRenderDocuments?: boolean; // used for annotation overlays which need to distribute documents into different freeformviews with different mixBlendModes depending on whether they are trnasparent or not. + dontRenderDocuments?: boolean; // used for annotation overlays which need to distribute documents into different freeformviews with different mixBlendModes depending on whether they are transparent or not. // However, this screws up interactions since only the top layer gets events. so we render the freeformview a 3rd time with all documents in order to get interaction events (eg., marquee) but we don't actually want to display the documents. }; @@ -1472,7 +1472,7 @@ export class CollectionFreeFormView extends CollectionSubView -
+
{this.layoutDoc._backgroundGridShow ? this.backgroundGrid : (null)} this.props.ScreenToLocalTransform().translate(0, -this.headerMargin); contentScaling = () => this.ContentScale; onClickFunc = () => this.onClickHandler; - setHeight = (height: number) => this.layoutDoc._height = height; + setHeight = (height: number) => { + if (this.props.renderDepth !== -1) { + this.layoutDoc._height = height; + } + } setContentView = action((view: { getAnchor?: () => Doc, forward?: () => boolean, back?: () => boolean }) => this._componentView = view); isContentActive = (outsideReaction?: boolean) => { return CurrentUserUtils.SelectedTool !== InkTool.None || diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx index 37d716993..9956cc36b 100644 --- a/src/client/views/nodes/WebBox.tsx +++ b/src/client/views/nodes/WebBox.tsx @@ -58,8 +58,10 @@ export class WebBox extends ViewBoxAnnotatableComponent(); private _searchRef = React.createRef(); private _searchString = ""; + @observable private _webUrl = ""; // url of the src parameter of the embedded iframe but not necessarily the rendered page - eg, when following a link, the rendered page changes but we don't wan the src parameter to also change as that would cause an unnecessary re-render. + @observable private _hackHide = false; // apparently changing the value of the 'sandbox' prop doesn't necessarily apply it to the active iframe. so thisforces the ifrmae to be rebuilt when allowScripts is toggled @observable private _searching: boolean = false; - @observable _showSidebar = false; + @observable private _showSidebar = false; @observable private _scrollTimer: any; @observable private _overlayAnnoInfo: Opt; @observable private _marqueeing: number[] | undefined; @@ -79,6 +81,7 @@ export class WebBox extends ViewBoxAnnotatableComponent this._webUrl = this._url); // setting the weburl will change the src parameter of the embedded iframe and force a navigation to it. } @action @@ -239,7 +242,7 @@ export class WebBox extends ViewBoxAnnotatableComponent this._marqueeing = undefined), 100); // bcz: hack .. anchor menu is setup within MarqueeAnnotator so we need to at least create the marqueeAnnotator even though we aren't using it. } else { this._iframeClick = this._iframe ?? undefined; @@ -269,9 +272,24 @@ export class WebBox extends ViewBoxAnnotatableComponent { const iframe = this._iframe; - this._iframe?.contentDocument?.addEventListener("pointerup", this.iframeUp); + let requrlraw = decodeURIComponent(iframe?.contentWindow?.location.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); + const newsearch = matches?.lastElement()!; + if (matches) { + requrlraw = requrlraw.substring(0, requrlraw.indexOf(newsearch)); + for (let i = 1; i < Array.from(matches)?.length; i++) { + requrlraw = requrlraw.replace(matches[i], ""); + } + } + requrlraw = requrlraw.replace(/q=[^&]*/, newsearch.substring(1)).replace("search&", "search?").replace("?gbv=1", ""); + } + this.submitURL(requrlraw, undefined, true); + } if (iframe?.contentDocument) { - iframe?.contentDocument.addEventListener("pointerdown", this.iframeDown); + 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)), 5000); const initialScroll = this._initialScroll; @@ -281,13 +299,15 @@ export class WebBox extends ViewBoxAnnotatableComponent { + iframe.contentDocument.addEventListener("click", undoBatch(action((e: MouseEvent) => { let href = ""; - for (let ele = e.target; ele; ele = ele.parentElement) { + 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; } - if (href && this.webField?.origin) { - this.submitURL(href.replace(Utils.prepend(""), this.webField?.origin)); + const origin = this.webField?.origin; + if (href && origin) { + e.stopPropagation(); + setTimeout(() => this.submitURL(href.replace(Utils.prepend(""), origin))); if (this._outerRef.current) { this._outerRef.current.scrollTop = NumCast(this.layoutDoc._scrollTop); this._outerRef.current.scrollLeft = 0; @@ -338,8 +358,15 @@ export class WebBox extends ViewBoxAnnotatableComponent([...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; @@ -350,10 +377,16 @@ export class WebBox extends ViewBoxAnnotatableComponent([this._url]); else this.dataDoc[this.fieldKey + "-future"] = new List([...future, this._url]); this.dataDoc[this.fieldKey] = new WebField(new URL(history.pop()!)); - console.log(this._urlHash); + if (this._webUrl === this._url) { + this._webUrl = curUrl; + setTimeout(action(() => this._webUrl = this._url)); + } else { + this._webUrl = this._url; + } return true; } return false; @@ -362,9 +395,8 @@ export class WebBox extends ViewBoxAnnotatableComponent { return Math.abs(s.split('').reduce((a: any, b: any) => { a = ((a << 5) - a) + b.charCodeAt(0); return a & a; }, 0)); } - @action - submitURL = (newUrl?: string, preview?: boolean) => { + submitURL = (newUrl?: string, preview?: boolean, dontUpdateIframe?: boolean) => { if (!newUrl) return; if (!newUrl.startsWith("http")) newUrl = "http://" + newUrl; try { @@ -376,7 +408,10 @@ export class WebBox extends ViewBoxAnnotatableComponent this.layoutDoc.useCors = !this.layoutDoc.useCors, icon: "snowflake" }); + funcs.push({ + description: (this.layoutDoc.allowScripts ? "Prevent" : "Allow") + " Scripts", event: () => { + this.layoutDoc.allowScripts = !this.layoutDoc.allowScripts; + if (this._iframe) { + runInAction(() => this._hackHide = true); + setTimeout(action(() => this._hackHide = false)); + } + }, icon: "snowflake" + }); funcs.push({ description: (!this.layoutDoc.forceReflow ? "Force" : "Prevent") + " Reflow", event: () => { const nw = !this.layoutDoc.forceReflow ? undefined : Doc.NativeWidth(this.layoutDoc) - this.sidebarWidth() / (this.props.scaling?.() || 1); @@ -468,18 +512,19 @@ export class WebBox extends ViewBoxAnnotatableComponent; } else if (field instanceof WebField) { - const url = this.layoutDoc.useCors ? Utils.CorsProxy(this._url) : this._url; + const url = this.layoutDoc.useCors ? Utils.CorsProxy(this._webUrl) : this._webUrl; view =