From f6db7693e18e06c467a7136c591bd12a2cc96c7f Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 14 Jul 2020 14:20:53 -0400 Subject: fixed issues with creating & using scripting boxes by making scriptFields be a function, not value, prop --- src/client/util/CurrentUserUtils.ts | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 7a06e1bc1..ad8336e8a 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -413,7 +413,7 @@ export class CurrentUserUtils { { title: "Drag a presentation view", label: "Prezi", icon: "tv", click: 'openOnRight(Doc.UserDoc().activePresentation = getCopy(this.dragFactory, true))', drag: `Doc.UserDoc().activePresentation = getCopy(this.dragFactory,true)`, dragFactory: doc.emptyPresentation as Doc }, { title: "Drag a search box", label: "Query", icon: "search", ignoreClick: true, drag: 'Docs.Create.QueryDocument({ _width: 200, title: "an image of a cat" })' }, { title: "Drag a scripting box", label: "Script", icon: "terminal", click: 'openOnRight(getCopy(this.dragFactory, true))', drag: 'getCopy(this.dragFactory, true)', dragFactory: doc.emptyScript as Doc }, - // { title: "Drag an import folder", label: "Load", icon: "cloud-upload-alt", ignoreClick: true, drag: 'Docs.Create.DirectoryImportDocument({ title: "Directory Import", _width: 400, _height: 400 })' }, + { title: "Drag an import folder", label: "Load", icon: "cloud-upload-alt", ignoreClick: true, drag: 'Docs.Create.DirectoryImportDocument({ title: "Directory Import", _width: 400, _height: 400 })' }, { title: "Drag a mobile view", label: "Phone", icon: "mobile", click: 'openOnRight(Doc.UserDoc().activeMobileMenu)', drag: 'this.dragFactory', dragFactory: doc.activeMobileMenu as Doc }, // { title: "Drag an instance of the device collection", label: "Buxton", icon: "globe-asia", ignoreClick: true, drag: 'Docs.Create.Buxton()' }, // { title: "use pen", icon: "pen-nib", click: 'activatePen(this.activeInkPen = sameDocs(this.activeInkPen, this) ? undefined : this)', backgroundColor: "blue", ischecked: `sameDocs(this.activeInkPen, this)`, activeInkPen: doc }, @@ -775,17 +775,17 @@ export class CurrentUserUtils { static setupClickEditorTemplates(doc: Doc) { if (doc["clickFuncs-child"] === undefined) { + // to use this function, select it from the context menu of a collection. then edit the onChildClick script. Add two Doc variables: 'target' and 'thisContainer', then assign 'target' to some target collection. After that, clicking on any document in the initial collection will open it in the target const openInTarget = Docs.Create.ScriptingDocument(ScriptField.MakeScript( - "docCast(thisContainer.target).then((target) => {" + - " target && docCast(this.source).then((source) => { " + - " target.proto.data = new List([source || this]); " + - " }); " + - "})", - { target: Doc.name }), { title: "Click to open in target", _width: 300, _height: 200, targetScriptKey: "onChildClick" }); + "docCast(thisContainer.target).then((target) => target && (target.proto.data = new List([self]))) ", + { thisContainer: Doc.name }), { + title: "Click to open in target", _width: 300, _height: 200, + targetScriptKey: "onChildClick", + }); const openDetail = Docs.Create.ScriptingDocument(ScriptField.MakeScript( "openOnRight(self.doubleClickView)", - { target: Doc.name }), { title: "Double click to open doubleClickView", _width: 300, _height: 200, targetScriptKey: "onChildDoubleClick" }); + {}), { title: "Double click to open doubleClickView", _width: 300, _height: 200, targetScriptKey: "onChildDoubleClick" }); doc["clickFuncs-child"] = Docs.Create.TreeDocument([openInTarget, openDetail], { title: "on Child Click function templates" }); } @@ -797,14 +797,22 @@ export class CurrentUserUtils { title: "onClick", "onClick-rawScript": "console.log('click')", isTemplateDoc: true, isTemplateForField: "onClick", _width: 300, _height: 200 }, "onClick"); + const onChildClick = Docs.Create.ScriptingDocument(undefined, { + title: "onChildClick", "onChildClick-rawScript": "console.log('child click')", + isTemplateDoc: true, isTemplateForField: "onChildClick", _width: 300, _height: 200 + }, "onChildClick"); const onDoubleClick = Docs.Create.ScriptingDocument(undefined, { title: "onDoubleClick", "onDoubleClick-rawScript": "console.log('double click')", isTemplateDoc: true, isTemplateForField: "onDoubleClick", _width: 300, _height: 200 }, "onDoubleClick"); + const onChildDoubleClick = Docs.Create.ScriptingDocument(undefined, { + title: "onChildDoubleClick", "onChildDoubleClick-rawScript": "console.log('child double click')", + isTemplateDoc: true, isTemplateForField: "onChildDoubleClick", _width: 300, _height: 200 + }, "onChildDoubleClick"); const onCheckedClick = Docs.Create.ScriptingDocument(undefined, { title: "onCheckedClick", "onCheckedClick-rawScript": "console.log(heading + checked + containingTreeView)", "onCheckedClick-params": new List(["heading", "checked", "containingTreeView"]), isTemplateDoc: true, isTemplateForField: "onCheckedClick", _width: 300, _height: 200 }, "onCheckedClick"); - doc.clickFuncs = Docs.Create.TreeDocument([onClick, onDoubleClick, onCheckedClick], { title: "onClick funcs" }); + doc.clickFuncs = Docs.Create.TreeDocument([onClick, onChildClick, onDoubleClick, onCheckedClick], { title: "onClick funcs" }); } PromiseValue(Cast(doc.clickFuncs, Doc)).then(func => func && PromiseValue(func.data).then(DocListCast)); -- cgit v1.2.3-70-g09d2 From d97a4f470456a89597017d643bf5139a2f8ef3e0 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 14 Jul 2020 15:00:54 -0400 Subject: possible fix for dragging icons problem caused by setisdragging invalidating the dragged element --- src/client/util/DragManager.ts | 2 +- src/client/views/collections/CollectionTreeView.tsx | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 5f34509a1..40467abaf 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -330,7 +330,6 @@ export namespace DragManager { DragManager.Root().appendChild(dragDiv); } dragLabel.style.display = ""; - SnappingManager.SetIsDragging(true); const scaleXs: number[] = []; const scaleYs: number[] = []; const xs: number[] = []; @@ -394,6 +393,7 @@ export namespace DragManager { set[i].hasAttribute("style") && ((set[i] as any).style.pointerEvents = "none"); } + SnappingManager.SetIsDragging(true); dragDiv.appendChild(dragElement); return dragElement; }); diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 8438248ad..eb355fa2b 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -405,6 +405,7 @@ class TreeView extends React.Component { contextMenuItems = () => [{ script: ScriptField.MakeFunction(`DocFocus(self)`)!, label: "Focus" }]; truncateTitleWidth = () => NumCast(this.props.treeViewDoc.treeViewTruncateTitleWidth, 0); showTitleEdit = () => ["*", this._uniqueId].includes(Doc.GetT(this.doc, "editTitle", "string", true) || ""); + onChildClick = () => this.props.onChildClick?.() ?? (this._editTitleScript?.() || ScriptCast(this.doc.editTitleScript)); /** * Renders the EditableView title element for placement into the tree. */ @@ -438,7 +439,7 @@ class TreeView extends React.Component { addDocTab={this.props.addDocTab} rootSelected={returnTrue} pinToPres={emptyFunction} - onClick={this.props.onChildClick || this._editTitleScript} + onClick={this.onChildClick} dropAction={this.props.dropAction} moveDocument={this.move} removeDocument={this.removeDoc} -- cgit v1.2.3-70-g09d2 From a88c5f551347c934686327bdfa4070084ccfc1ef Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 14 Jul 2020 15:35:16 -0400 Subject: proper fix for onClickHandlers so they don't invalidate things when they haven't changed. --- src/client/util/DragManager.ts | 2 +- src/client/views/nodes/DocumentView.tsx | 46 +++++++++++++++++---------------- 2 files changed, 25 insertions(+), 23 deletions(-) (limited to 'src/client/util') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 40467abaf..5f34509a1 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -330,6 +330,7 @@ export namespace DragManager { DragManager.Root().appendChild(dragDiv); } dragLabel.style.display = ""; + SnappingManager.SetIsDragging(true); const scaleXs: number[] = []; const scaleYs: number[] = []; const xs: number[] = []; @@ -393,7 +394,6 @@ export namespace DragManager { set[i].hasAttribute("style") && ((set[i] as any).style.pointerEvents = "none"); } - SnappingManager.SetIsDragging(true); dragDiv.appendChild(dragElement); return dragElement; }); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index b118ec243..7d9c4da87 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -127,12 +127,14 @@ export class DocumentView extends DocComponent(Docu @computed get freezeDimensions() { return this.props.FreezeDimensions; } @computed get nativeWidth() { return NumCast(this.layoutDoc._nativeWidth, this.props.NativeWidth() || (this.freezeDimensions ? this.layoutDoc[WidthSym]() : 0)); } @computed get nativeHeight() { return NumCast(this.layoutDoc._nativeHeight, this.props.NativeHeight() || (this.freezeDimensions ? this.layoutDoc[HeightSym]() : 0)); } - @computed get onClickHandler() { return this.props.onClick?.() ? this.props.onClick : (() => Cast(this.Document.onClick, ScriptField, Cast(this.layoutDoc.onClick, ScriptField, null))); } - @computed get onDoubleClickHandler() { return this.props.onDoubleClick?.() ? this.props.onDoubleClick : () => (Cast(this.layoutDoc.onDoubleClick, ScriptField, null) || this.Document.onDoubleClick); } - @computed get onPointerDownHandler() { return this.props.onPointerDown?.() ? this.props.onPointerDown : () => ScriptCast(this.Document.onPointerDown) } - @computed get onPointerUpHandler() { return this.props.onPointerUp ?? (() => ScriptCast(this.Document.onPointerUp)); } + @computed get onClickHandler() { return this.props.onClick?.() ?? Cast(this.Document.onClick, ScriptField, Cast(this.layoutDoc.onClick, ScriptField, null)); } + @computed get onDoubleClickHandler() { return this.props.onDoubleClick?.() || (Cast(this.layoutDoc.onDoubleClick, ScriptField, null) || this.Document.onDoubleClick); } + @computed get onPointerDownHandler() { return this.props.onPointerDown?.() || ScriptCast(this.Document.onPointerDown) } + @computed get onPointerUpHandler() { return this.props.onPointerUp?.() || ScriptCast(this.Document.onPointerUp); } NativeWidth = () => this.nativeWidth; NativeHeight = () => this.nativeHeight; + onClickFunc = () => this.onClickHandler; + onDoubleClickFunc = () => this.onDoubleClickHandler; private _firstX: number = -1; private _firstY: number = -1; @@ -293,10 +295,10 @@ export class DocumentView extends DocComponent(Docu let stopPropagate = true; let preventDefault = true; !this.props.Document.isBackground && this.props.bringToFront(this.props.Document); - if (this._doubleTap && this.props.renderDepth && !this.onClickHandler()?.script) { // disable double-click to show full screen for things that have an on click behavior since clicking them twice can be misinterpreted as a double click + if (this._doubleTap && this.props.renderDepth && !this.onClickHandler?.script) { // disable double-click to show full screen for things that have an on click behavior since clicking them twice can be misinterpreted as a double click if (!(e.nativeEvent as any).formattedHandled) { - if (this.onDoubleClickHandler()?.script && !StrCast(Doc.LayoutField(this.layoutDoc))?.includes("ScriptingBox")) { // bcz: hack? don't execute script if you're clicking on a scripting box itself - const func = () => this.onDoubleClickHandler()?.script.run({ + if (this.onDoubleClickHandler?.script && !StrCast(Doc.LayoutField(this.layoutDoc))?.includes("ScriptingBox")) { // bcz: hack? don't execute script if you're clicking on a scripting box itself + const func = () => this.onDoubleClickHandler?.script.run({ this: this.layoutDoc, self: this.rootDoc, thisContainer: this.props.ContainingCollectionDoc, shiftKey: e.shiftKey @@ -316,9 +318,9 @@ export class DocumentView extends DocComponent(Docu Doc.UnBrushDoc(this.props.Document); } } - } else if (this.onClickHandler()?.script && !StrCast(Doc.LayoutField(this.layoutDoc))?.includes("ScriptingBox")) { // bcz: hack? don't execute script if you're clicking on a scripting box itself + } else if (this.onClickHandler?.script && !StrCast(Doc.LayoutField(this.layoutDoc))?.includes("ScriptingBox")) { // bcz: hack? don't execute script if you're clicking on a scripting box itself //SelectionManager.DeselectAll(); - const func = () => this.onClickHandler()?.script.run({ + const func = () => this.onClickHandler?.script.run({ this: this.layoutDoc, self: this.rootDoc, thisContainer: this.props.ContainingCollectionDoc, shiftKey: e.shiftKey @@ -379,7 +381,7 @@ export class DocumentView extends DocComponent(Docu this._downX = touch.clientX; this._downY = touch.clientY; if (!e.nativeEvent.cancelBubble) { - if ((this.active || this.layoutDoc.onDragStart || this.onClickHandler()) && !e.ctrlKey && !this.layoutDoc.lockedPosition && !this.layoutDoc.inOverlay) e.stopPropagation(); + if ((this.active || this.layoutDoc.onDragStart || this.onClickHandler) && !e.ctrlKey && !this.layoutDoc.lockedPosition && !this.layoutDoc.inOverlay) e.stopPropagation(); this.removeMoveListeners(); this.addMoveListeners(); this.removeEndListeners(); @@ -394,11 +396,11 @@ export class DocumentView extends DocComponent(Docu if (e.cancelBubble && this.active) { this.removeMoveListeners(); } - else if (!e.cancelBubble && (SelectionManager.IsSelected(this, true) || this.props.parentActive(true) || this.layoutDoc.onDragStart || this.onClickHandler()) && !this.layoutDoc.lockedPosition && !this.layoutDoc.inOverlay) { + else if (!e.cancelBubble && (SelectionManager.IsSelected(this, true) || this.props.parentActive(true) || this.layoutDoc.onDragStart || this.onClickHandler) && !this.layoutDoc.lockedPosition && !this.layoutDoc.inOverlay) { const touch = me.touchEvent.changedTouches.item(0); if (touch && (Math.abs(this._downX - touch.clientX) > 3 || Math.abs(this._downY - touch.clientY) > 3)) { - if (!e.altKey && (!this.topMost || this.layoutDoc.onDragStart || this.onClickHandler())) { + if (!e.altKey && (!this.topMost || this.layoutDoc.onDragStart || this.onClickHandler)) { this.cleanUpInteractions(); this.startDragging(this._downX, this._downY, this.Document.dropAction ? this.Document.dropAction as any : e.ctrlKey || e.altKey ? "alias" : undefined); } @@ -511,7 +513,7 @@ export class DocumentView extends DocComponent(Docu } this._downX = e.clientX; this._downY = e.clientY; - if ((!e.nativeEvent.cancelBubble || this.onClickHandler() || this.layoutDoc.onDragStart) && + if ((!e.nativeEvent.cancelBubble || this.onClickHandler || this.layoutDoc.onDragStart) && // if this is part of a template, let the event go up to the tempalte root unless right/ctrl clicking !((this.props.Document.rootDocument) && !(e.ctrlKey || e.button > 0))) { if ((this.active || this.layoutDoc.onDragStart) && @@ -539,7 +541,7 @@ export class DocumentView extends DocComponent(Docu } else if (!e.cancelBubble && (SelectionManager.IsSelected(this, true) || this.props.parentActive(true) || this.layoutDoc.onDragStart) && !this.layoutDoc.lockedPosition && !this.layoutDoc.inOverlay) { if (Math.abs(this._downX - e.clientX) > 3 || Math.abs(this._downY - e.clientY) > 3) { - if (!e.altKey && (!this.topMost || this.layoutDoc.onDragStart || this.onClickHandler()) && (e.buttons === 1 || InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE))) { + if (!e.altKey && (!this.topMost || this.layoutDoc.onDragStart || this.onClickHandler) && (e.buttons === 1 || InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE))) { document.removeEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); this.startDragging(this._downX, this._downY, ((e.ctrlKey || e.altKey) && "alias") || (this.props.dropAction || this.Document.dropAction || undefined) as dropActionType); @@ -553,8 +555,8 @@ export class DocumentView extends DocComponent(Docu onPointerUp = (e: PointerEvent): void => { this.cleanUpInteractions(); - if (this.onPointerUpHandler()?.script && !InteractionUtils.IsType(e, InteractionUtils.PENTYPE)) { - this.onPointerUpHandler()?.script.run({ self: this.rootDoc, this: this.layoutDoc }, console.log); + if (this.onPointerUpHandler?.script && !InteractionUtils.IsType(e, InteractionUtils.PENTYPE)) { + this.onPointerUpHandler?.script.run({ self: this.rootDoc, this: this.layoutDoc }, console.log); document.removeEventListener("pointerup", this.onPointerUp); return; } @@ -587,7 +589,7 @@ export class DocumentView extends DocComponent(Docu @undoBatch toggleLinkButtonBehavior = (): void => { - if (this.Document.isLinkButton || this.onClickHandler() || this.Document.ignoreClick) { + if (this.Document.isLinkButton || this.onClickHandler || this.Document.ignoreClick) { this.Document.isLinkButton = false; const first = DocListCast(this.Document.links).find(d => d instanceof Doc); first && (first.hidden = false); @@ -782,7 +784,7 @@ export class DocumentView extends DocComponent(Docu onClicks.push({ description: this.Document.ignoreClick ? "Select" : "Do Nothing", event: () => this.Document.ignoreClick = !this.Document.ignoreClick, icon: this.Document.ignoreClick ? "unlock" : "lock" }); onClicks.push({ description: this.Document.isLinkButton ? "Remove Follow Behavior" : "Follow Link in Place", event: this.toggleFollowInPlace, icon: "concierge-bell" }); onClicks.push({ description: this.Document.isLinkButton ? "Remove Follow Behavior" : "Follow Link on Right", event: this.toggleFollowOnRight, icon: "concierge-bell" }); - onClicks.push({ description: this.Document.isLinkButton || this.onClickHandler() ? "Remove Click Behavior" : "Follow Link", event: this.toggleLinkButtonBehavior, icon: "concierge-bell" }); + onClicks.push({ description: this.Document.isLinkButton || this.onClickHandler ? "Remove Click Behavior" : "Follow Link", event: this.toggleLinkButtonBehavior, icon: "concierge-bell" }); onClicks.push({ description: "Edit onClick Script", event: () => UndoManager.RunInBatch(() => DocUtils.makeCustomViewClicked(this.props.Document, undefined, "onClick"), "edit onClick"), icon: "edit" }); !existingOnClick && cm.addItem({ description: "OnClick...", noexpand: true, subitems: onClicks, icon: "hand-point-right" }); @@ -1070,7 +1072,7 @@ export class DocumentView extends DocComponent(Docu ChromeHeight={this.chromeHeight} isSelected={this.isSelected} select={this.select} - onClick={this.onClickHandler} + onClick={this.onClickFunc} layoutKey={this.finalLayoutKey} /> {this.layoutDoc.hideAllLinks ? (null) : this.allAnchors} {/* {this.allAnchors} */} @@ -1141,13 +1143,13 @@ export class DocumentView extends DocComponent(Docu ChromeHeight={this.chromeHeight} isSelected={this.isSelected} select={this.select} - onClick={this.onClickHandler} + onClick={this.onClickFunc} layoutKey={this.finalLayoutKey} /> ); const titleView = (!showTitle ? (null) :
(Docu fontFamily: StrCast(this.Document._fontFamily, "inherit"), fontSize: Cast(this.Document._fontSize, "string", null) }}> - {this.onClickHandler() && this.props.ContainingCollectionView?.props.Document._viewType === CollectionViewType.Time ? <> + {this.onClickHandler && this.props.ContainingCollectionView?.props.Document._viewType === CollectionViewType.Time ? <> {this.innards}
: -- cgit v1.2.3-70-g09d2 From 9fae8d59b6dfaa0641941cd59aaa21ed271d6586 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 14 Jul 2020 15:36:06 -0400 Subject: from last --- src/client/util/CurrentUserUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/util') diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index ad8336e8a..e0cb90b46 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -413,7 +413,7 @@ export class CurrentUserUtils { { title: "Drag a presentation view", label: "Prezi", icon: "tv", click: 'openOnRight(Doc.UserDoc().activePresentation = getCopy(this.dragFactory, true))', drag: `Doc.UserDoc().activePresentation = getCopy(this.dragFactory,true)`, dragFactory: doc.emptyPresentation as Doc }, { title: "Drag a search box", label: "Query", icon: "search", ignoreClick: true, drag: 'Docs.Create.QueryDocument({ _width: 200, title: "an image of a cat" })' }, { title: "Drag a scripting box", label: "Script", icon: "terminal", click: 'openOnRight(getCopy(this.dragFactory, true))', drag: 'getCopy(this.dragFactory, true)', dragFactory: doc.emptyScript as Doc }, - { title: "Drag an import folder", label: "Load", icon: "cloud-upload-alt", ignoreClick: true, drag: 'Docs.Create.DirectoryImportDocument({ title: "Directory Import", _width: 400, _height: 400 })' }, + // { title: "Drag an import folder", label: "Load", icon: "cloud-upload-alt", ignoreClick: true, drag: 'Docs.Create.DirectoryImportDocument({ title: "Directory Import", _width: 400, _height: 400 })' }, { title: "Drag a mobile view", label: "Phone", icon: "mobile", click: 'openOnRight(Doc.UserDoc().activeMobileMenu)', drag: 'this.dragFactory', dragFactory: doc.activeMobileMenu as Doc }, // { title: "Drag an instance of the device collection", label: "Buxton", icon: "globe-asia", ignoreClick: true, drag: 'Docs.Create.Buxton()' }, // { title: "use pen", icon: "pen-nib", click: 'activatePen(this.activeInkPen = sameDocs(this.activeInkPen, this) ? undefined : this)', backgroundColor: "blue", ischecked: `sameDocs(this.activeInkPen, this)`, activeInkPen: doc }, -- cgit v1.2.3-70-g09d2 From 866561aa20aff0f570d31edf64eae36cd2d35279 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 14 Jul 2020 17:27:19 -0400 Subject: fixed onClickHandler stuff to use functions properly. fixed several linking to annotations/pushpins problems. --- src/client/documents/Documents.ts | 8 +- src/client/util/DocumentManager.ts | 4 +- src/client/util/LinkManager.ts | 11 ++- src/client/util/SettingsManager.tsx | 4 +- src/client/views/DocumentButtonBar.tsx | 2 +- src/client/views/MetadataEntryMenu.tsx | 96 ++++++---------------- src/client/views/collections/CollectionView.tsx | 7 +- .../collectionFreeForm/CollectionFreeFormView.tsx | 10 +-- .../collectionFreeForm/FormatShapePane.tsx | 2 +- .../collectionFreeForm/InkOptionsMenu.tsx | 2 +- .../collectionGrid/CollectionGridView.tsx | 2 +- .../CollectionMulticolumnView.tsx | 5 +- .../CollectionMultirowView.tsx | 4 +- src/client/views/linking/LinkMenuGroup.tsx | 4 +- src/client/views/linking/LinkMenuItem.tsx | 5 +- src/client/views/nodes/DocumentLinksButton.tsx | 3 - src/client/views/nodes/DocumentView.tsx | 17 ++-- src/client/views/nodes/FieldView.tsx | 2 +- .../views/nodes/formattedText/RichTextMenu.tsx | 2 +- src/fields/documentSchemas.ts | 3 + 20 files changed, 78 insertions(+), 115 deletions(-) (limited to 'src/client/util') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 90cef31d9..1fd533b62 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -102,6 +102,8 @@ export interface DocumentOptions { childLayoutTemplate?: Doc; // template for collection to use to render its children (see PresBox or Buxton layout in tree view) childLayoutString?: string; // template string for collection to use to render its children hideFilterView?: boolean; // whether to hide the filter popout on collections + hideLinkButton?: boolean; // whether the blue link counter button should be hidden + hideAllLinks?: boolean; // whether all individual blue anchor dots should be hidden _columnsHideIfEmpty?: boolean; // whether stacking view column headings should be hidden isTemplateForField?: string; // the field key for which the containing document is a rendering template isTemplateDoc?: boolean; @@ -137,7 +139,7 @@ export interface DocumentOptions { lookupField?: ScriptField; // script that returns the value of a field. This script is passed the rootDoc, layoutDoc, field, and container of the document. see PresBox. "onDoubleClick-rawScript"?: string; // onDoubleClick script in raw text form "onChildDoubleClick-rawScript"?: string; // onChildDoubleClick script in raw text form - "onChildClick-rawScript"?: string // on ChildClick script in raw text form + "onChildClick-rawScript"?: string; // on ChildClick script in raw text form "onClick-rawScript"?: string; // onClick script in raw text form "onCheckedClick-rawScript"?: string; // onChecked script in raw text form "onCheckedClick-params"?: List; // parameter list for onChecked treeview functions @@ -779,7 +781,7 @@ export namespace Docs { export function FontIconDocument(options?: DocumentOptions) { - return InstanceFromProto(Prototypes.get(DocumentType.FONTICON), undefined, { ...(options || {}) }); + return InstanceFromProto(Prototypes.get(DocumentType.FONTICON), undefined, { hideLinkButton: true, ...(options || {}) }); } export function PresElementBoxDocument(options?: DocumentOptions) { @@ -912,6 +914,8 @@ export namespace DocUtils { if (target.doc === Doc.UserDoc()) return undefined; const linkDoc = Docs.Create.LinkDocument(source, target, { linkRelationship, layoutKey: "layout_linkView", description }, id); + linkDoc.linkDisplay = true; + linkDoc.hideAnhors = true; linkDoc.layout_linkView = Cast(Cast(Doc.UserDoc()["template-button-link"], Doc, null).dragFactory, Doc, null); Doc.GetProto(linkDoc).title = ComputedField.MakeFunction('self.anchor1?.title +" (" + (self.linkRelationship||"to") +") " + self.anchor2?.title'); diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts index 1fa5faeb3..b66e7fdc4 100644 --- a/src/client/util/DocumentManager.ts +++ b/src/client/util/DocumentManager.ts @@ -146,7 +146,7 @@ export class DocumentManager { }; const docView = getFirstDocView(targetDoc, originatingDoc); let annotatedDoc = await Cast(targetDoc.annotationOn, Doc); - if (annotatedDoc && !linkDoc?.isPushpin) { + if (annotatedDoc && !targetDoc?.isPushpin) { const first = getFirstDocView(annotatedDoc); if (first) { annotatedDoc = first.props.Document; @@ -156,7 +156,7 @@ export class DocumentManager { } } if (docView) { // we have a docView already and aren't forced to create a new one ... just focus on the document. TODO move into view if necessary otherwise just highlight? - if (linkDoc?.isPushpin) docView.props.Document.hidden = !docView.props.Document.hidden; + if (originatingDoc?.isPushpin) docView.props.Document.hidden = !docView.props.Document.hidden; else { docView.props.Document.hidden && (docView.props.Document.hidden = undefined); docView.props.focus(docView.props.Document, willZoom, undefined, focusAndFinish); diff --git a/src/client/util/LinkManager.ts b/src/client/util/LinkManager.ts index 50f3fc1d6..974744344 100644 --- a/src/client/util/LinkManager.ts +++ b/src/client/util/LinkManager.ts @@ -63,12 +63,17 @@ export class LinkManager { } // finds all links that contain the given anchor - public getAllRelatedLinks(anchor: Doc): Doc[] { + public getAllDirectLinks(anchor: Doc): Doc[] { const related = LinkManager.Instance.getAllLinks().filter(link => { const protomatch1 = Doc.AreProtosEqual(anchor, Cast(link.anchor1, Doc, null)); const protomatch2 = Doc.AreProtosEqual(anchor, Cast(link.anchor2, Doc, null)); return protomatch1 || protomatch2 || Doc.AreProtosEqual(link, anchor); }); + return related; + } + // finds all links that contain the given anchor + public getAllRelatedLinks(anchor: Doc): Doc[] { + const related = LinkManager.Instance.getAllDirectLinks(anchor); DocListCast(anchor[Doc.LayoutFieldKey(anchor) + "-annotations"]).map(anno => { related.push(...LinkManager.Instance.getAllRelatedLinks(anno)); }); @@ -208,4 +213,6 @@ export class LinkManager { } Scripting.addGlobal(function links(doc: any) { return new List(LinkManager.Instance.getAllRelatedLinks(doc)); }, - "creates a link to inputted document", "(doc: any)"); \ No newline at end of file + "returns all the links to the document or its annotations", "(doc: any)"); +Scripting.addGlobal(function directLinks(doc: any) { return new List(LinkManager.Instance.getAllDirectLinks(doc)); }, + "returns all the links directly to the document", "(doc: any)"); \ No newline at end of file diff --git a/src/client/util/SettingsManager.tsx b/src/client/util/SettingsManager.tsx index f7ca3942b..981ee698d 100644 --- a/src/client/util/SettingsManager.tsx +++ b/src/client/util/SettingsManager.tsx @@ -87,11 +87,11 @@ export default class SettingsManager extends React.Component<{}> { } @action googleAuthorize = (event: any) => { - GoogleAuthenticationManager.Instance.fetchOrGenerateAccessToken(true) + GoogleAuthenticationManager.Instance.fetchOrGenerateAccessToken(true); } @action hypothesisAuthorize = (event: any) => { - HypothesisAuthenticationManager.Instance.fetchAccessToken(true) + HypothesisAuthenticationManager.Instance.fetchAccessToken(true); } private get settingsInterface() { diff --git a/src/client/views/DocumentButtonBar.tsx b/src/client/views/DocumentButtonBar.tsx index c188618f4..927c192cd 100644 --- a/src/client/views/DocumentButtonBar.tsx +++ b/src/client/views/DocumentButtonBar.tsx @@ -208,7 +208,7 @@ export class DocumentButtonBar extends React.Component<{ views: () => (DocumentV const view0 = this.view0; return !view0 ? (null) :
this.props.views().filter(dv => dv).map(dv => dv!.props.Document)} suggestWithFunction /> /* tfs: @bcz This might need to be the data document? */}> + content={ dv).map(dv => dv!.props.Document)} suggestWithFunction /> /* tfs: @bcz This might need to be the data document? */}>
e.stopPropagation()} > {}
diff --git a/src/client/views/MetadataEntryMenu.tsx b/src/client/views/MetadataEntryMenu.tsx index b0752ffb2..ca8a6e1d7 100644 --- a/src/client/views/MetadataEntryMenu.tsx +++ b/src/client/views/MetadataEntryMenu.tsx @@ -3,14 +3,14 @@ import "./MetadataEntryMenu.scss"; import { observer } from 'mobx-react'; import { observable, action, runInAction, trace, computed, IReactionDisposer, reaction } from 'mobx'; import { KeyValueBox } from './nodes/KeyValueBox'; -import { Doc, Field, DocListCastAsync } from '../../fields/Doc'; +import { Doc, Field, DocListCastAsync, DocListCast } from '../../fields/Doc'; import * as Autosuggest from 'react-autosuggest'; -import { undoBatch } from '../util/UndoManager'; +import { undoBatch, UndoManager } from '../util/UndoManager'; import { emptyFunction, emptyPath } from '../../Utils'; export type DocLike = Doc | Doc[] | Promise | Promise; export interface MetadataEntryProps { - docs: DocLike | (() => DocLike); + docs: Doc[]; onError?: () => boolean; suggestWithFunction?: boolean; } @@ -39,26 +39,13 @@ export class MetadataEntryMenu extends React.Component{ let onProto: boolean = false; let value: string | undefined = undefined; let docs = this.props.docs; - if (typeof docs === "function") { - if (this.props.suggestWithFunction) { - docs = docs(); - } else { - return; - } - } - docs = await docs; - if (docs instanceof Doc) { - await docs[this._currentKey]; - value = Field.toKeyValueString(docs, this._currentKey); - } else { - for (const doc of docs) { - const v = await doc[this._currentKey]; - onProto = onProto || !Object.keys(doc).includes(this._currentKey); - if (field === null) { - field = v; - } else if (v !== field) { - value = "multiple values"; - } + for (const doc of docs) { + const v = await doc[this._currentKey]; + onProto = onProto || !Object.keys(doc).includes(this._currentKey); + if (field === null) { + field = v; + } else if (v !== field) { + value = "multiple values"; } } if (value === undefined) { @@ -86,27 +73,16 @@ export class MetadataEntryMenu extends React.Component{ const script = KeyValueBox.CompileKVPScript(this._currentValue); if (!script) return; - let doc = this.props.docs; - if (typeof doc === "function") { - doc = doc(); - } - doc = await doc; - - let success: boolean; - if (doc instanceof Doc) { - success = KeyValueBox.ApplyKVPScript(doc, this._currentKey, script); - } else { - let childSuccess = true; - if (this._addChildren) { - for (const document of doc) { - const collectionChildren = await DocListCastAsync(document.data); - if (collectionChildren) { - childSuccess = collectionChildren.every(c => KeyValueBox.ApplyKVPScript(c, this._currentKey, script)); - } + let childSuccess = true; + if (this._addChildren) { + for (const document of this.props.docs) { + const collectionChildren = DocListCast(document.data); + if (collectionChildren) { + childSuccess = collectionChildren.every(c => KeyValueBox.ApplyKVPScript(c, this._currentKey, script)); } } - success = doc.every(d => KeyValueBox.ApplyKVPScript(d, this._currentKey, script)) && childSuccess; } + const success = this.props.docs.every(d => KeyValueBox.ApplyKVPScript(d, this._currentKey, script)) && childSuccess; if (!success) { if (this.props.onError) { if (this.props.onError()) { @@ -132,24 +108,12 @@ export class MetadataEntryMenu extends React.Component{ } } - getKeySuggestions = async (value: string): Promise => { + getKeySuggestions = (value: string) => { value = value.toLowerCase(); let docs = this.props.docs; - if (typeof docs === "function") { - if (this.props.suggestWithFunction) { - docs = docs(); - } else { - return []; - } - } - docs = await docs; - if (docs instanceof Doc) { - return Object.keys(docs).filter(key => key.toLowerCase().startsWith(value)); - } else { - const keys = new Set(); - docs.forEach(doc => Doc.allKeys(doc).forEach(key => keys.add(key))); - return Array.from(keys).filter(key => key.toLowerCase().startsWith(value)); - } + const keys = new Set(); + docs.forEach(doc => Doc.allKeys(doc).forEach(key => keys.add(key))); + return Array.from(keys).filter(key => key.toLowerCase().startsWith(value)); } getSuggestionValue = (suggestion: string) => suggestion; @@ -157,9 +121,8 @@ export class MetadataEntryMenu extends React.Component{ return (null); } componentDidMount() { - this._suggestionDispser = reaction(() => this._currentKey, - () => this.getKeySuggestions(this._currentKey).then(action((s: string[]) => this._allSuggestions = s)), + () => this._allSuggestions = this.getKeySuggestions(this._currentKey), { fireImmediately: true }); } componentWillUnmount() { @@ -171,19 +134,8 @@ export class MetadataEntryMenu extends React.Component{ } private get considerChildOptions() { - let docSource = this.props.docs; - if (typeof docSource === "function") { - docSource = docSource(); - } - docSource = docSource as Doc[] | Doc; - if (docSource instanceof Doc) { - if (docSource._viewType === undefined) { - return (null); - } - } else if (Array.isArray(docSource)) { - if (!docSource.every(doc => doc._viewType !== undefined)) { - return null; - } + if (!this.props.docs.every(doc => doc._viewType !== undefined)) { + return null; } return (
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 5165a8f11..6ab4645ea 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -140,17 +140,18 @@ export class CollectionView extends Touchable { const context = Cast(doc.context, Doc, null); - if (context && (context.type === DocumentType.VID || context.type === DocumentType.WEB || context.type === DocumentType.PDF || context.type === DocumentType.IMG) && - !DocListCast(doc.links).some(d => d.isPushpin)) { + if (context && (context.type === DocumentType.VID || context.type === DocumentType.WEB || context.type === DocumentType.PDF || context.type === DocumentType.IMG)) { const pushpin = Docs.Create.FontIconDocument({ icon: "map-pin", x: Cast(doc.x, "number", null), y: Cast(doc.y, "number", null), _backgroundColor: "#0000003d", color: "#ACCEF7", _width: 15, _height: 15, _xPadding: 0, isLinkButton: true, displayTimecode: Cast(doc.displayTimecode, "number", null) }); + pushpin.isPushpin = true; + Doc.GetProto(pushpin).annotationOn = doc.annotationOn; + Doc.SetInPlace(doc, "annotationOn", undefined, true); Doc.AddDocToList(context, Doc.LayoutFieldKey(context) + "-annotations", pushpin); const pushpinLink = DocUtils.MakeLink({ doc: pushpin }, { doc: doc }, "pushpin", ""); const first = DocListCast(pushpin.links).find(d => d instanceof Doc); first && (first.hidden = true); - pushpinLink && (Doc.GetProto(pushpinLink).isPushpin = true); doc.displayTimecode = undefined; } doc.context = this.props.Document; diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index f33b5371f..994f4ce6e 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -939,9 +939,9 @@ export class CollectionFreeFormView extends CollectionSubView (this.props.childClickScript || ScriptCast(this.Document.onChildClick)); } - @computed get onChildDoubleClickHandler() { return () => (this.props.childDoubleClickScript || ScriptCast(this.Document.onChildDoubleClick)); } @computed get backgroundActive() { return this.layoutDoc.isBackground && (this.props.ContainingCollectionView?.active() || this.props.active()); } + onChildClickHandler = () => this.props.childClickScript || ScriptCast(this.Document.onChildClick); + onChildDoubleClickHandler = () => this.props.childDoubleClickScript || ScriptCast(this.Document.onChildDoubleClick); backgroundHalo = () => BoolCast(this.Document.useClusters); parentActive = (outsideReaction: boolean) => this.props.active(outsideReaction) || this.backgroundActive ? true : false; getChildDocumentViewProps(childLayout: Doc, childData?: Doc): DocumentViewProps { @@ -1186,8 +1186,8 @@ export class CollectionFreeFormView extends CollectionSubView - (p === undefined || (p && p === i.rootDoc[key])) && i.rootDoc[key] !== "0" ? Field.toString(i.rootDoc[key] as Field) : "", undefined as Opt) + (p === undefined || (p && p === i.rootDoc[key])) && i.rootDoc[key] !== "0" ? Field.toString(i.rootDoc[key] as Field) : "", undefined as Opt); } @computed get selectedInk() { diff --git a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx index 15707ad9e..5d115df69 100644 --- a/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx +++ b/src/client/views/collections/collectionFreeForm/InkOptionsMenu.tsx @@ -128,7 +128,7 @@ export default class InkOptionsMenu extends AntimodeMenu { // doc.strokeBezier === 300 ? doc.strokeBezier = 0 : doc.strokeBezier = 300; break; case "dash": - doc.strokeDash = Number(value); + doc.strokeDash = value; default: break; } diff --git a/src/client/views/collections/collectionGrid/CollectionGridView.tsx b/src/client/views/collections/collectionGrid/CollectionGridView.tsx index b2e506dfa..73d0ae374 100644 --- a/src/client/views/collections/collectionGrid/CollectionGridView.tsx +++ b/src/client/views/collections/collectionGrid/CollectionGridView.tsx @@ -31,7 +31,7 @@ export class CollectionGridView extends CollectionSubView(GridSchema) { @observable private _rowHeight: Opt; // temporary store of row height to make change undoable @observable private _scroll: number = 0; // required to make sure the decorations box container updates on scroll - @computed get onChildClickHandler() { return () => ScriptCast(this.Document.onChildClick); } + onChildClickHandler = () => ScriptCast(this.Document.onChildClick); @computed get numCols() { return NumCast(this.props.Document.gridNumCols, 10); } @computed get rowHeight() { return this._rowHeight === undefined ? NumCast(this.props.Document.gridRowHeight, 100) : this._rowHeight; } diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx index 402e7563d..21d283547 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMulticolumnView.tsx @@ -202,9 +202,8 @@ export class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocu } - @computed get onChildClickHandler() { return () => ScriptCast(this.Document.onChildClick); } - @computed get onChildDoubleClickHandler() { return () => ScriptCast(this.Document.onChildDoubleClick); } - + onChildClickHandler = () => ScriptCast(this.Document.onChildClick); + onChildDoubleClickHandler = () => ScriptCast(this.Document.onChildDoubleClick); addDocTab = (doc: Doc, where: string) => { if (where === "inPlace" && this.layoutDoc.isInPlaceContainer) { diff --git a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx index e4ef9b436..d02088a6c 100644 --- a/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx +++ b/src/client/views/collections/collectionMulticolumn/CollectionMultirowView.tsx @@ -202,8 +202,8 @@ export class CollectionMultirowView extends CollectionSubView(MultirowDocument) } - @computed get onChildClickHandler() { return () => ScriptCast(this.Document.onChildClick); } - @computed get onChildDoubleClickHandler() { return () => ScriptCast(this.Document.onChildDoubleClick); } + onChildClickHandler = () => ScriptCast(this.Document.onChildClick); + onChildDoubleClickHandler = () => ScriptCast(this.Document.onChildDoubleClick); addDocTab = (doc: Doc, where: string) => { if (where === "inPlace" && this.layoutDoc.isInPlaceContainer) { diff --git a/src/client/views/linking/LinkMenuGroup.tsx b/src/client/views/linking/LinkMenuGroup.tsx index 2f6b75437..2ae87ac13 100644 --- a/src/client/views/linking/LinkMenuGroup.tsx +++ b/src/client/views/linking/LinkMenuGroup.tsx @@ -11,6 +11,7 @@ import { DocumentView } from "../nodes/DocumentView"; import './LinkMenu.scss'; import { LinkMenuItem, StartLinkTargetsDrag } from "./LinkMenuItem"; import React = require("react"); +import { Cast } from "../../../fields/Types"; interface LinkMenuGroupProps { sourceDoc: Doc; @@ -66,7 +67,8 @@ export class LinkMenuGroup extends React.Component { render() { const groupItems = this.props.group.map(linkDoc => { - const destination = LinkManager.Instance.getOppositeAnchor(linkDoc, this.props.sourceDoc); + const destination = LinkManager.Instance.getOppositeAnchor(linkDoc, this.props.sourceDoc) || + LinkManager.Instance.getOppositeAnchor(linkDoc, Cast(linkDoc.anchor2, Doc, null).annotationOn === this.props.sourceDoc ? Cast(linkDoc.anchor2, Doc, null) : Cast(linkDoc.anchor1, Doc, null)); if (destination && this.props.sourceDoc) { return { const eyeIcon = this.props.linkDoc.hidden ? "eye-slash" : "eye"; - let destinationIcon: string = "";; + let destinationIcon: FontAwesomeIconProps["icon"] = "question"; switch (this.props.destinationDoc.type) { case DocumentType.IMG: destinationIcon = "image"; break; case DocumentType.COMPARISON: destinationIcon = "columns"; break; @@ -205,7 +205,6 @@ export class LinkMenuItem extends React.Component { case DocumentType.SCRIPTING: destinationIcon = "terminal"; break; case DocumentType.IMPORT: destinationIcon = "cloud-upload-alt"; break; case DocumentType.DOCHOLDER: destinationIcon = "expand"; break; - default: "question"; } const title = StrCast(this.props.destinationDoc.title).length > 18 ? diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx index 83710cfbf..823e25471 100644 --- a/src/client/views/nodes/DocumentLinksButton.tsx +++ b/src/client/views/nodes/DocumentLinksButton.tsx @@ -101,8 +101,6 @@ export class DocumentLinksButton extends React.Component { if (linkDoc) { @@ -137,7 +135,6 @@ export class DocumentLinksButton extends React.Component { if (linkDoc) { diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 7d9c4da87..a6771443a 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -128,9 +128,9 @@ export class DocumentView extends DocComponent(Docu @computed get nativeWidth() { return NumCast(this.layoutDoc._nativeWidth, this.props.NativeWidth() || (this.freezeDimensions ? this.layoutDoc[WidthSym]() : 0)); } @computed get nativeHeight() { return NumCast(this.layoutDoc._nativeHeight, this.props.NativeHeight() || (this.freezeDimensions ? this.layoutDoc[HeightSym]() : 0)); } @computed get onClickHandler() { return this.props.onClick?.() ?? Cast(this.Document.onClick, ScriptField, Cast(this.layoutDoc.onClick, ScriptField, null)); } - @computed get onDoubleClickHandler() { return this.props.onDoubleClick?.() || (Cast(this.layoutDoc.onDoubleClick, ScriptField, null) || this.Document.onDoubleClick); } - @computed get onPointerDownHandler() { return this.props.onPointerDown?.() || ScriptCast(this.Document.onPointerDown) } - @computed get onPointerUpHandler() { return this.props.onPointerUp?.() || ScriptCast(this.Document.onPointerUp); } + @computed get onDoubleClickHandler() { return this.props.onDoubleClick?.() ?? (Cast(this.layoutDoc.onDoubleClick, ScriptField, null) ?? this.Document.onDoubleClick); } + @computed get onPointerDownHandler() { return this.props.onPointerDown?.() ?? ScriptCast(this.Document.onPointerDown); } + @computed get onPointerUpHandler() { return this.props.onPointerUp?.() ?? ScriptCast(this.Document.onPointerUp); } NativeWidth = () => this.nativeWidth; NativeHeight = () => this.nativeHeight; onClickFunc = () => this.onClickHandler; @@ -298,7 +298,7 @@ export class DocumentView extends DocComponent(Docu if (this._doubleTap && this.props.renderDepth && !this.onClickHandler?.script) { // disable double-click to show full screen for things that have an on click behavior since clicking them twice can be misinterpreted as a double click if (!(e.nativeEvent as any).formattedHandled) { if (this.onDoubleClickHandler?.script && !StrCast(Doc.LayoutField(this.layoutDoc))?.includes("ScriptingBox")) { // bcz: hack? don't execute script if you're clicking on a scripting box itself - const func = () => this.onDoubleClickHandler?.script.run({ + const func = () => this.onDoubleClickHandler.script.run({ this: this.layoutDoc, self: this.rootDoc, thisContainer: this.props.ContainingCollectionDoc, shiftKey: e.shiftKey @@ -320,7 +320,7 @@ export class DocumentView extends DocComponent(Docu } } else if (this.onClickHandler?.script && !StrCast(Doc.LayoutField(this.layoutDoc))?.includes("ScriptingBox")) { // bcz: hack? don't execute script if you're clicking on a scripting box itself //SelectionManager.DeselectAll(); - const func = () => this.onClickHandler?.script.run({ + const func = () => this.onClickHandler.script.run({ this: this.layoutDoc, self: this.rootDoc, thisContainer: this.props.ContainingCollectionDoc, shiftKey: e.shiftKey @@ -556,7 +556,7 @@ export class DocumentView extends DocComponent(Docu this.cleanUpInteractions(); if (this.onPointerUpHandler?.script && !InteractionUtils.IsType(e, InteractionUtils.PENTYPE)) { - this.onPointerUpHandler?.script.run({ self: this.rootDoc, this: this.layoutDoc }, console.log); + this.onPointerUpHandler.script.run({ self: this.rootDoc, this: this.layoutDoc }, console.log); document.removeEventListener("pointerup", this.onPointerUp); return; } @@ -644,7 +644,6 @@ export class DocumentView extends DocComponent(Docu const makeLink = action((linkDoc: Doc) => { LinkManager.currentLink = linkDoc; linkDoc.hidden = true; - linkDoc.linkDisplay = true; LinkCreatedBox.popupX = de.x; LinkCreatedBox.popupY = de.y - 33; @@ -1076,7 +1075,7 @@ export class DocumentView extends DocComponent(Docu layoutKey={this.finalLayoutKey} /> {this.layoutDoc.hideAllLinks ? (null) : this.allAnchors} {/* {this.allAnchors} */} - {this.props.forcedBackgroundColor?.(this.Document) === "transparent" || this.props.dontRegisterView ? (null) : } + {this.props.forcedBackgroundColor?.(this.Document) === "transparent" || this.layoutDoc.hideLinkButton || this.props.dontRegisterView ? (null) : }
); } @@ -1105,7 +1104,7 @@ export class DocumentView extends DocComponent(Docu return (this.props.treeViewDoc && this.props.LayoutTemplateString) || // render nothing for: tree view anchor dots this.layoutDoc.presBox || // presentationbox nodes this.props.dontRegisterView ? (null) : // view that are not registered - DocUtils.FilterDocs(DocListCast(this.Document.links), this.props.docFilters(), []).filter(d => !d.hidden && this.isNonTemporalLink).map((d, i) => + DocUtils.FilterDocs(LinkManager.Instance.getAllDirectLinks(this.Document), this.props.docFilters(), []).filter(d => !d.hidden && this.isNonTemporalLink).map((d, i) => ScriptField; dropAction: dropActionType; backgroundHalo?: () => boolean; docFilters: () => string[]; diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx index 8da1f99b5..c8798d757 100644 --- a/src/client/views/nodes/formattedText/RichTextMenu.tsx +++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx @@ -431,7 +431,7 @@ export default class RichTextMenu extends AntimodeMenu { const nextIsOL = this.view.state.selection.$from.nodeAfter?.type === schema.nodes.ordered_list; let inList: any = undefined; let fromList = -1; - let path: any = Array.from((this.view.state.selection.$from as any).path); + const path: any = Array.from((this.view.state.selection.$from as any).path); for (let i = 0; i < path.length; i++) { if (path[i]?.type === schema.nodes.ordered_list) { inList = path[i]; diff --git a/src/fields/documentSchemas.ts b/src/fields/documentSchemas.ts index 9dda644f3..ddffb56c3 100644 --- a/src/fields/documentSchemas.ts +++ b/src/fields/documentSchemas.ts @@ -65,6 +65,7 @@ export const documentSchema = createSchema({ color: "string", // foreground color of document fitToBox: "boolean", // whether freeform view contents should be zoomed/panned to fill the area of the document view fontSize: "string", + hidden: "boolean", // whether a document should not be displayed isInkMask: "boolean", // is the document a mask (ie, sits on top of other documents, has an unbounded width/height that is dark, and content uses 'hard-light' mix-blend-mode to let other documents pop through) layout: "string", // this is the native layout string for the document. templates can be added using other fields and setting layoutKey below layoutKey: "string", // holds the field key for the field that actually holds the current lyoat @@ -87,6 +88,8 @@ export const documentSchema = createSchema({ onPointerUp: ScriptField, // script to run when document is clicked (can be overriden by an onClick prop) onDragStart: ScriptField, // script to run when document is dragged (without being selected). the script should return the Doc to be dropped. followLinkLocation: "string",// flag for where to place content when following a click interaction (e.g., onRight, inPlace, inTab, ) + hideLinkButton: "boolean", // whether the blue link counter button should be hidden + hideAllLinks: "boolean", // whether all individual blue anchor dots should be hidden isInPlaceContainer: "boolean",// whether the marked object will display addDocTab() calls that target "inPlace" destinations isLinkButton: "boolean", // whether document functions as a link follow button to follow the first link on the document when clicked isBackground: "boolean", // whether document is a background element and ignores input events (can only select with marquee) -- cgit v1.2.3-70-g09d2