aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/documents/Documents.ts16
-rw-r--r--src/client/util/CurrentUserUtils.ts19
-rw-r--r--src/client/views/DocComponent.tsx6
-rw-r--r--src/client/views/MainView.tsx2
-rw-r--r--src/client/views/animationtimeline/Keyframe.tsx2
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx316
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx18
-rw-r--r--src/client/views/collections/CollectionView.tsx4
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx16
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx8
-rw-r--r--src/client/views/collections/collectionFreeForm/PropertiesView.tsx2
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx6
-rw-r--r--src/client/views/nodes/DocumentView.tsx18
-rw-r--r--src/client/views/nodes/ImageBox.tsx4
-rw-r--r--src/client/views/nodes/LinkAnchorBox.tsx2
-rw-r--r--src/client/views/nodes/PresBox.tsx12
-rw-r--r--src/client/views/nodes/VideoBox.tsx3
-rw-r--r--src/client/views/nodes/WebBox.tsx8
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx16
-rw-r--r--src/client/views/presentationview/PresElementBox.tsx2
-rw-r--r--src/client/views/search/SearchBox.tsx2
-rw-r--r--src/fields/Doc.ts22
-rw-r--r--src/fields/documentSchemas.ts2
23 files changed, 231 insertions, 275 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index b8cac2beb..18ff993fe 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -33,7 +33,6 @@ import { ColorBox } from "../views/nodes/ColorBox";
import { ComparisonBox } from "../views/nodes/ComparisonBox";
import { DocHolderBox } from "../views/nodes/DocHolderBox";
import { FontIconBox } from "../views/nodes/FontIconBox";
-import { MenuIconBox } from "../views/nodes/MenuIconBox";
import { FormattedTextBox } from "../views/nodes/formattedText/FormattedTextBox";
import { ImageBox } from "../views/nodes/ImageBox";
import { KeyValueBox } from "../views/nodes/KeyValueBox";
@@ -129,7 +128,7 @@ export interface DocumentOptions {
isAnnotating?: boolean; // whether we web document is annotation mode where links can't be clicked to allow annotations to be created
opacity?: number;
defaultBackgroundColor?: string;
- isBackground?: boolean;
+ _isBackground?: boolean;
isLinkButton?: boolean;
_columnWidth?: number;
_fontSize?: string;
@@ -186,6 +185,7 @@ export interface DocumentOptions {
strokeWidth?: number;
cloneFieldFilter?: List<string>; // fields not to copy when the document is cloned
_stayInCollection?: boolean;// whether the document should remain in its collection when someone tries to drag and drop it elsewhere
+ freezeChildren?: string; // whether children are now allowed to be added and or removed from a collection
treeViewPreventOpen?: boolean; // ignores the treeViewOpen Doc flag which allows a treeViewItem's expand/collapse state to be independent of other views of the same document in the tree view
treeViewHideTitle?: boolean; // whether to hide the top document of a tree view
treeViewHideHeaderFields?: boolean; // whether to hide the drop down options for tree view items.
@@ -535,7 +535,7 @@ export namespace Docs {
Scripting.addGlobal(Buxton);
- const delegateKeys = ["x", "y", "system", "layoutKey", "dropAction", "lockedPosiiton", "childDropAction", "isLinkButton", "isBackground", "removeDropProperties", "treeViewOpen"];
+ const delegateKeys = ["x", "y", "system", "layoutKey", "dropAction", "lockedPosiiton", "childDropAction", "isLinkButton", "removeDropProperties", "treeViewOpen"];
/**
* This function receives the relevant document prototype and uses
@@ -684,7 +684,7 @@ export namespace Docs {
const doc = InstanceFromProto(Prototypes.get(DocumentType.LINK), undefined, {
dontRegisterChildViews: true,
isLinkButton: true, treeViewHideTitle: true, backgroundColor: "lightBlue", // lightBlue is default color for linking dot and link documents text comment area
- treeViewExpandedView: "fields", removeDropProperties: new List(["isBackground", "isLinkButton"]), ...options
+ treeViewExpandedView: "fields", removeDropProperties: new List(["_isBackground", "isLinkButton"]), ...options
}, id);
const linkDocProto = Doc.GetProto(doc);
linkDocProto.treeViewOpen = true;// setting this in the instance creator would set it on the view document.
@@ -694,7 +694,7 @@ export namespace Docs {
linkDocProto.anchor2_timecode = target.doc._currentTimecode || target.doc.displayTimecode;
if (linkDocProto.linkBoxExcludedKeys === undefined) {
- Cast(linkDocProto.proto, Doc, null).linkBoxExcludedKeys = new List(["treeViewExpandedView", "aliases", "treeViewHideTitle", "removeDropProperties", "linkBoxExcludedKeys", "treeViewOpen", "aliasNumber", "isPrototype", "lastOpened", "creationDate", "author"]);
+ Cast(linkDocProto.proto, Doc, null).linkBoxExcludedKeys = new List(["treeViewExpandedView", "aliases", "treeViewHideTitle", "removeDropProperties", "linkBoxExcludedKeys", "treeViewOpen", "aliasNumber", "isPrototype", "creationDate", "author"]);
Cast(linkDocProto.proto, Doc, null).layoutKey = undefined;
}
@@ -825,9 +825,9 @@ export namespace Docs {
}
export function DockDocument(documents: Array<Doc>, config: string, options: DocumentOptions, id?: string) {
- const inst = InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { treeViewLockExpandedView: true, treeViewDefaultExpandedView: "data", ...options, _viewType: CollectionViewType.Docking, dockingConfig: config }, id);
- const tabs = TreeDocument(documents, { title: "On-Screen Tabs", treeViewLockExpandedView: true, treeViewDefaultExpandedView: "data", system: true });
- const all = TreeDocument([], { title: "Off-Screen Tabs", treeViewLockExpandedView: true, treeViewDefaultExpandedView: "data", system: true });
+ const inst = InstanceFromProto(Prototypes.get(DocumentType.COL), new List(documents), { freezeChildren: "remove|add", treeViewLockExpandedView: true, treeViewDefaultExpandedView: "data", ...options, _viewType: CollectionViewType.Docking, dockingConfig: config }, id);
+ const tabs = TreeDocument(documents, { title: "On-Screen Tabs", freezeChildren: "remove|add", treeViewLockExpandedView: true, treeViewDefaultExpandedView: "data", system: true });
+ const all = TreeDocument([], { title: "Off-Screen Tabs", freezeChildren: "add", treeViewLockExpandedView: true, treeViewDefaultExpandedView: "data", system: true });
Doc.GetProto(inst).data = new List<Doc>([tabs, all]);
return inst;
}
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index 2c9c870aa..c60403701 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -26,6 +26,8 @@ import { LinkManager } from "./LinkManager";
import { Id } from "../../fields/FieldSymbols";
import { HistoryUtil } from "./History";
import { CollectionDockingView } from "../views/collections/CollectionDockingView";
+import { SelectionManager } from "./SelectionManager";
+import { DocumentManager } from "./DocumentManager";
export class CurrentUserUtils {
private static curr_id: string;
@@ -1018,12 +1020,9 @@ export class CurrentUserUtils {
}
public static snapshotDashboard = (userDoc: Doc) => {
- const activeDashboard = Cast(userDoc.activeDashboard, Doc, null);
- CollectionDockingView.Copy(activeDashboard).then(copy => {
- Doc.AddDocToList(Cast(userDoc.myDashboards, Doc, null), "data", copy);
- // bcz: strangely, we need a timeout to prevent exceptions/issues initializing GoldenLayout (the rendering engine for Main Container)
- setTimeout(() => CurrentUserUtils.openDashboard(userDoc, copy), 0);
- });
+ const copy = CollectionDockingView.Copy(Cast(userDoc.activeDashboard, Doc, null));
+ Doc.AddDocToList(Cast(userDoc.myDashboards, Doc, null), "data", copy);
+ CurrentUserUtils.openDashboard(userDoc, copy);
}
public static createNewDashboard = async (userDoc: Doc, id?: string) => {
@@ -1059,6 +1058,14 @@ export class CurrentUserUtils {
}
}
+Scripting.addGlobal(function openDragFactory(dragFactory: Doc) {
+ const copy = Doc.copyDragFactory(dragFactory);
+ if (copy) {
+ CollectionDockingView.AddRightSplit(copy);
+ const view = DocumentManager.Instance.getFirstDocumentView(copy);
+ view && SelectionManager.SelectDoc(view, false);
+ }
+});
Scripting.addGlobal(function snapshotDashboard() { CurrentUserUtils.snapshotDashboard(Doc.UserDoc()); },
"creates a snapshot copy of a dashboard");
Scripting.addGlobal(function createNewDashboard() { return CurrentUserUtils.createNewDashboard(Doc.UserDoc()); },
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index 1cea94064..e9469d7bb 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -58,7 +58,7 @@ export function ViewBoxBaseComponent<P extends ViewBoxBaseProps, T>(schemaCtor:
lookupField = (field: string) => ScriptCast(this.layoutDoc.lookupField)?.script.run({ self: this.layoutDoc, data: this.rootDoc, field: field, container: this.props.ContainingCollectionDoc }).result;
- active = (outsideReaction?: boolean) => !this.props.Document.isBackground && (this.props.rootSelected(outsideReaction) || this.props.isSelected(outsideReaction) || this.props.renderDepth === 0 || this.layoutDoc.forceActive);// && !Doc.SelectedTool(); // bcz: inking state shouldn't affect static tools
+ active = (outsideReaction?: boolean) => !this.props.Document._isBackground && (this.props.rootSelected(outsideReaction) || this.props.isSelected(outsideReaction) || this.props.renderDepth === 0 || this.layoutDoc.forceActive);// && !Doc.SelectedTool(); // bcz: inking state shouldn't affect static tools
protected _multiTouchDisposer?: InteractionUtils.MultiTouchEventDisposer;
}
return Component;
@@ -187,9 +187,9 @@ export function ViewBoxAnnotatableComponent<P extends ViewBoxAnnotatableProps, T
}
whenActiveChanged = action((isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive));
- active = (outsideReaction?: boolean) => ((Doc.GetSelectedTool() === InkTool.None && !this.props.Document.isBackground) &&
+ active = (outsideReaction?: boolean) => ((Doc.GetSelectedTool() === InkTool.None && !this.props.Document._) &&
(this.props.rootSelected(outsideReaction) || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0 || BoolCast((this.layoutDoc as any).forceActive)) ? true : false)
- annotationsActive = (outsideReaction?: boolean) => (Doc.GetSelectedTool() !== InkTool.None || (this.props.Document.isBackground && this.props.active()) ||
+ annotationsActive = (outsideReaction?: boolean) => (Doc.GetSelectedTool() !== InkTool.None || (this.props.Document._isBackground && this.props.active()) ||
(this.props.Document.forceActive || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0) ? true : false)
}
return Component;
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 9371728ce..3afda13c2 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -386,7 +386,7 @@ export class MainView extends React.Component {
addDocTabFunc = (doc: Doc, where: string, libraryPath?: Doc[]): boolean => {
return where === "close" ? CollectionDockingView.CloseRightSplit(doc) :
doc.dockingConfig ? CurrentUserUtils.openDashboard(Doc.UserDoc(), doc) :
- CollectionDockingView.AddRightSplit(doc, libraryPath);
+ CollectionDockingView.AddRightSplit(doc);
}
sidebarScreenToLocal = () => new Transform(0, (CollectionMenu.Instance.Pinned ? -35 : 0) - Number(SEARCH_PANEL_HEIGHT.replace("px", "")), 1);
mainContainerXf = () => this.sidebarScreenToLocal().translate(-58, 0);
diff --git a/src/client/views/animationtimeline/Keyframe.tsx b/src/client/views/animationtimeline/Keyframe.tsx
index 1b81c544a..4fb362ab1 100644
--- a/src/client/views/animationtimeline/Keyframe.tsx
+++ b/src/client/views/animationtimeline/Keyframe.tsx
@@ -331,7 +331,7 @@ export class Keyframe extends React.Component<IProps> {
}),
TimelineMenu.Instance.addItem("button", "Show Data", action(() => {
const kvp = Docs.Create.KVPDocument(kf, { _width: 300, _height: 300 });
- CollectionDockingView.AddRightSplit(kvp, emptyPath);
+ CollectionDockingView.AddRightSplit(kvp);
})),
TimelineMenu.Instance.addItem("button", "Delete", action(() => {
(this.regiondata.keyframes as List<Doc>).splice(this.keyframes.indexOf(kf), 1);
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 3d8ac2a23..86d27acd5 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -24,7 +24,7 @@ import { Scripting } from '../../util/Scripting';
import { SelectionManager } from '../../util/SelectionManager';
import { SnappingManager } from '../../util/SnappingManager';
import { Transform } from '../../util/Transform';
-import { undoBatch } from "../../util/UndoManager";
+import { undoBatch, UndoManager } from "../../util/UndoManager";
import { DocumentView } from "../nodes/DocumentView";
import { PresBox } from '../nodes/PresBox';
import "./CollectionDockingView.scss";
@@ -59,7 +59,7 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
@observable private _goldenLayout: any = null;
private _containerRef = React.createRef<HTMLDivElement>();
- private _flush: boolean = false;
+ private _flush: UndoManager.Batch | undefined;
private _ignoreStateChange = "";
private _isPointerDown = false;
private _maximizedSrc: Opt<DocumentView>;
@@ -73,6 +73,8 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
DragManager.StartWindowDrag = this.StartOtherDrag;
}
public StartOtherDrag = (e: any, dragDocs: Doc[]) => {
+ console.log("START drag batch");
+ !this._flush && (this._flush = UndoManager.StartBatch("golden layout drag"));
const config = dragDocs.length === 1 ? CollectionDockingView.makeDocumentConfig(dragDocs[0]) :
{
type: 'row',
@@ -104,6 +106,7 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
SelectionManager.DeselectAll();
}
+ @undoBatch
public CloseFullScreen = () => {
const target = this._goldenLayout._maximisedItem;
if (target !== null && this._maximizedSrc) {
@@ -121,25 +124,24 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
@undoBatch
@action
public static CloseRightSplit(document: Opt<Doc>): boolean {
- const instance = CollectionDockingView.Instance;
const tryClose = (childItem: any) => {
if (childItem.config?.component === "DocumentFrameRenderer") {
const docView = DocumentManager.Instance.getDocumentViewById(childItem.config.props.documentId);
if (docView && ((!document && docView.Document.isDisplayPanel) || (document && Doc.AreProtosEqual(docView.props.Document, document)))) {
childItem.remove();
- instance.layoutChanged(document);
return true;
}
}
return false;
};
- const retVal = !instance?._goldenLayout.root.contentItems[0].isRow ? false :
- Array.from(instance._goldenLayout.root.contentItems[0].contentItems).some((child: any) => Array.from(child.contentItems).some(tryClose));
+ const retVal = !CollectionDockingView.Instance?._goldenLayout.root.contentItems[0].isRow ? false :
+ Array.from(CollectionDockingView.Instance._goldenLayout.root.contentItems[0].contentItems).some((child: any) => Array.from(child.contentItems).some(tryClose));
- retVal && instance.stateChanged();
+ retVal && CollectionDockingView.Instance.layoutChanged(document);
return retVal;
}
+ @undoBatch
@action
layoutChanged(removed?: Doc) {
this._goldenLayout.root.callDownwards('setSize', [this._goldenLayout.width, this._goldenLayout.height]);
@@ -147,20 +149,17 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
this._ignoreStateChange = JSON.stringify(this._goldenLayout.toConfig());
this.stateChanged();
}
- @undoBatch
- @action
+
public static ReplaceRightSplit(document: Doc, libraryPath?: Doc[], addToSplit?: boolean): boolean {
if (!CollectionDockingView.Instance) return false;
const instance = CollectionDockingView.Instance;
- let retVal = false;
- if (instance._goldenLayout.root.contentItems[0].isRow) {
- retVal = Array.from(instance._goldenLayout.root.contentItems[0].contentItems).some((child: any) => {
+ const retVal = !instance._goldenLayout.root.contentItems[0].isRow ? false :
+ Array.from(instance._goldenLayout.root.contentItems[0].contentItems).some((child: any) => {
if (child.contentItems.length === 1 && child.contentItems[0].config.component === "DocumentFrameRenderer" &&
DocumentManager.Instance.getDocumentViewById(child.contentItems[0].config.props.documentId)?.Document.isDisplayPanel) {
const newItemStackConfig = CollectionDockingView.makeDocumentConfig(document, undefined, libraryPath);
child.addChild(newItemStackConfig, undefined);
!addToSplit && child.contentItems[0].remove();
- instance.layoutChanged(document);
return true;
}
return Array.from(child.contentItems).filter((tab: any) => tab.config.component === "DocumentFrameRenderer").some((tab: any, j: number) => {
@@ -168,16 +167,12 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
const newItemStackConfig = CollectionDockingView.makeDocumentConfig(document, undefined, libraryPath);
child.addChild(newItemStackConfig, undefined);
!addToSplit && child.contentItems[j].remove();
- instance.layoutChanged(document);
return true;
}
return false;
});
});
- }
- if (retVal) {
- instance.stateChanged();
- }
+ retVal && instance.layoutChanged(document);
return retVal;
}
@@ -186,34 +181,51 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
//
@undoBatch
@action
- public static AddRightSplit(document: Doc, libraryPath?: Doc[]) {
+ public static AddRightSplit(document: Doc, dontSelect: boolean = false, isDisplayPanel: Opt<boolean> = undefined) {
if (!CollectionDockingView.Instance) return false;
- if (document._viewType === CollectionViewType.Docking) return CurrentUserUtils.openDashboard(Doc.UserDoc(), document);
- const instance = CollectionDockingView.Instance;
- const newItemStackConfig = {
- type: 'stack',
- content: [CollectionDockingView.makeDocumentConfig(document, undefined, libraryPath)]
- };
- const newContentItem = instance._goldenLayout.root.layoutManager.createContentItem(newItemStackConfig, instance._goldenLayout);
-
- if (instance._goldenLayout.root.contentItems.length === 0) {
- instance._goldenLayout.root.addChild(newContentItem);
- } else if (instance._goldenLayout.root.contentItems[0].isRow) {
- instance._goldenLayout.root.contentItems[0].addChild(newContentItem);
+ const ind = CollectionDockingView.Instance._tabMap.findIndex((val) => val.doc === document);
+ if (ind !== -1) {
+ const tab = CollectionDockingView.Instance._tabMap[ind].tab;
+ const activeContentItem = tab.header.parent.getActiveContentItem();
+ if (tab.contentItem !== activeContentItem) {
+ tab.header.parent.setActiveContentItem(tab.contentItem);
+ }
+ tab.setActive(true);
} else {
- const collayout = instance._goldenLayout.root.contentItems[0];
- const newRow = collayout.layoutManager.createContentItem({ type: "row" }, instance._goldenLayout);
- collayout.parent.replaceChild(collayout, newRow);
+ document.isDisplayPanel = isDisplayPanel;
- newRow.addChild(newContentItem, undefined, true);
- newRow.addChild(collayout, 0, true);
+ if (document._viewType === CollectionViewType.Docking) return CurrentUserUtils.openDashboard(Doc.UserDoc(), document);
+ const instance = CollectionDockingView.Instance;
+ const newItemStackConfig = {
+ type: 'stack',
+ content: [CollectionDockingView.makeDocumentConfig(document, undefined, [])]
+ };
+
+ const newContentItem = instance._goldenLayout.root.layoutManager.createContentItem(newItemStackConfig, instance._goldenLayout);
- collayout.config.width = 50;
- newContentItem.config.width = 50;
+ if (instance._goldenLayout.root.contentItems.length === 0) {
+ instance._goldenLayout.root.addChild(newContentItem);
+ } else if (instance._goldenLayout.root.contentItems[0].isRow) {
+ instance._goldenLayout.root.contentItems[0].addChild(newContentItem);
+ } else {
+ const collayout = instance._goldenLayout.root.contentItems[0];
+ const newRow = collayout.layoutManager.createContentItem({ type: "row" }, instance._goldenLayout);
+ collayout.parent.replaceChild(collayout, newRow);
+
+ newRow.addChild(newContentItem, undefined, true);
+ newRow.addChild(collayout, 0, true);
+
+ collayout.config.width = 50;
+ newContentItem.config.width = 50;
+ }
+ newContentItem.callDownwards('_$init');
+ instance.layoutChanged();
+ }
+ if (!dontSelect) {
+ const view = DocumentManager.Instance.getFirstDocumentView(document);
+ view && SelectionManager.SelectDoc(view, false);
}
- newContentItem.callDownwards('_$init');
- instance.layoutChanged();
return true;
}
@@ -221,7 +233,6 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
//
// Creates a split on any side of the docking view based on the passed input pullSide and then adds the Document to the requested side
//
- @undoBatch
@action
public static AddSplit(document: Doc, pullSide: string, libraryPath?: Doc[]) {
if (!CollectionDockingView.Instance) return false;
@@ -289,19 +300,13 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
//
// Creates a vertical split on the right side of the docking view, and then adds the Document to that split
//
- @undoBatch
- @action
public static UseRightSplit(document: Doc, libraryPath?: Doc[], shiftKey?: boolean) {
- document.isDisplayPanel = true;
if (shiftKey || !CollectionDockingView.ReplaceRightSplit(document, libraryPath, shiftKey)) {
- CollectionDockingView.AddRightSplit(document, libraryPath);
+ CollectionDockingView.AddRightSplit(document, false, true);
}
}
- @undoBatch
- @action
public AddTab = (stack: any, document: Doc, libraryPath?: Doc[]) => {
- Doc.GetProto(document).lastOpened = new DateField;
const docContentConfig = CollectionDockingView.makeDocumentConfig(document, undefined, libraryPath);
if (stack === undefined) {
let stack: any = this._goldenLayout.root;
@@ -324,10 +329,7 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
return true;
}
- @undoBatch
- @action
public ReplaceTab = (stack: any, document: Doc, libraryPath?: Doc[]) => {
- Doc.GetProto(document).lastOpened = new DateField;
const docContentConfig = CollectionDockingView.makeDocumentConfig(document, undefined, libraryPath);
if (stack === undefined) {
let stack: any = this._goldenLayout.root;
@@ -350,9 +352,15 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
return true;
}
- setupGoldenLayout() {
+ _tabMap: { tab: any, doc: Doc }[] = [];
+
+ async setupGoldenLayout() {
const config = StrCast(this.props.Document.dockingConfig);
if (config) {
+ const matches = config.match(/\"documentId\":\"[a-z0-9-]+\"/g);
+ const docids = matches?.map(m => m.replace("\"documentId\":\"", "").replace("\"", "")) ?? [];
+ await Promise.all(docids.map(id => DocServer.GetRefField(id)));
+
if (!this._goldenLayout) {
runInAction(() => this._goldenLayout = new GoldenLayout(JSON.parse(config)));
}
@@ -361,7 +369,6 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
return;
}
try {
- this._goldenLayout.unbind('itemDropped', this.itemDropped);
this._goldenLayout.unbind('tabCreated', this.tabCreated);
this._goldenLayout.unbind('tabDestroyed', this.tabDestroyed);
this._goldenLayout.unbind('stackCreated', this.stackCreated);
@@ -369,12 +376,12 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
this._goldenLayout.destroy();
runInAction(() => this._goldenLayout = new GoldenLayout(JSON.parse(config)));
}
- this._goldenLayout.on('itemDropped', this.itemDropped);
this._goldenLayout.on('tabCreated', this.tabCreated);
this._goldenLayout.on('tabDestroyed', this.tabDestroyed);
this._goldenLayout.on('stackCreated', this.stackCreated);
this._goldenLayout.registerComponent('DocumentFrameRenderer', DockedFrameRenderer);
this._goldenLayout.container = this._containerRef.current;
+ //this._goldenLayout.on("stateChanged", () => console.log("STATE CHANGED"));
if (this._goldenLayout.config.maximisedItemId === '__glMaximised') {
try {
this._goldenLayout.config.root.getItemsById(this._goldenLayout.config.maximisedItemId)[0].toggleMaximise();
@@ -388,46 +395,39 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
reactionDisposer?: Lambda;
componentDidMount: () => void = () => {
if (this._containerRef.current) {
- const observer = new _global.ResizeObserver(action((entries: any) => {
- for (const entry of entries) {
- this.onResize(null as any);
- }
- }));
+ const observer = new _global.ResizeObserver(this.onResize);
observer.observe(this._containerRef.current);
this.reactionDisposer = reaction(
- () => this.props.Document.dockingConfig,
- () => {
- if (!this._goldenLayout || this._ignoreStateChange !== JSON.stringify(this._goldenLayout.toConfig())) {
- // Because this is in a set timeout, if this component unmounts right after mounting,
- // we will leak a GoldenLayout, because we try to destroy it before we ever create it
- setTimeout(() => this.setupGoldenLayout(), 1);
+ () => StrCast(this.props.Document.dockingConfig),
+ config => {
+ if (!this._goldenLayout || this._ignoreStateChange !== config) {
+ this.setupGoldenLayout();
DocListCast((Doc.UserDoc().myDashboards as Doc).data).map(d => d.dashboardBrush = false);
this.props.Document.dashboardBrush = true;
}
this._ignoreStateChange = "";
- }, { fireImmediately: true });
-
+ });
+ setTimeout(() => this.setupGoldenLayout(), 0);
window.addEventListener('resize', this.onResize); // bcz: would rather add this event to the parent node, but resize events only come from Window
}
}
componentWillUnmount: () => void = () => {
try {
this.props.Document.dashboardBrush = false;
- this._goldenLayout.unbind('itemDropped', this.itemDropped);
this._goldenLayout.unbind('tabCreated', this.tabCreated);
this._goldenLayout.unbind('stackCreated', this.stackCreated);
this._goldenLayout.unbind('tabDestroyed', this.tabDestroyed);
} catch (e) {
}
- this._goldenLayout && this._goldenLayout.destroy();
+ this._goldenLayout?.destroy();
runInAction(() => {
CollectionDockingView.Instances.splice(CollectionDockingView.Instances.indexOf(this), 1);
this._goldenLayout = null;
});
window.removeEventListener('resize', this.onResize);
- this.reactionDisposer && this.reactionDisposer();
+ this.reactionDisposer?.();
}
@action
onResize = (event: any) => {
@@ -437,26 +437,26 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
}
@action
- onPointerUp = (e: React.PointerEvent): void => {
+ onPointerUp = (e: MouseEvent): void => {
+ window.removeEventListener("pointerup", this.onPointerUp);
+ this._isPointerDown = false;
if (this._flush) {
- this._flush = false;
setTimeout(() => {
CollectionDockingView.Instance._ignoreStateChange = JSON.stringify(CollectionDockingView.Instance._goldenLayout.toConfig());
this.stateChanged();
+ console.log("END BATCH Up");
+ this._flush!.end();
+ this._flush = undefined;
}, 10);
}
}
@action
onPointerDown = (e: React.PointerEvent): void => {
- this._isPointerDown = true;
- const onPointerUp = action(() => {
- window.removeEventListener("pointerup", onPointerUp);
- this._isPointerDown = false;
- });
- window.addEventListener("pointerup", onPointerUp);
- const className = (e.target as any).className;
- if (className === "lm_drag_handle" || className === "lm_close" || className === "lm_maximise" || className === "lm_minimise" || className === "lm_close_tab") {
- this._flush = true;
+ window.addEventListener("mouseup", this.onPointerUp);
+
+ if (!(e.target as HTMLElement).closest("*.lm_content") && ((e.target as HTMLElement).closest("*.lm_tab") || (e.target as HTMLElement).closest("*.lm_stack"))) {
+ console.log("START BATCH dwn");
+ this._flush = UndoManager.StartBatch("golden layout edit");
}
if (e.nativeEvent.cancelBubble || InteractionUtils.IsType(e, InteractionUtils.TOUCHTYPE) || InteractionUtils.IsType(e, InteractionUtils.PENTYPE) || (Doc.GetSelectedTool() === InkTool.Highlighter || Doc.GetSelectedTool() === InkTool.Pen)) {
return;
@@ -464,29 +464,11 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
e.stopPropagation();
}
}
-
- updateDataField = async (json: string) => {
- const matches = json.match(/\"documentId\":\"[a-z0-9-]+\"/g);
- const docids = matches?.map(m => m.replace("\"documentId\":\"", "").replace("\"", ""));
-
- const docs = !docids ? [] : (await Promise.all(docids.map(id => DocServer.GetRefField(id)))).filter(f => f).map(f => f as Doc);
- const sublists = DocListCast(this.props.Document[this.props.fieldKey]);
- const tabs = Cast(sublists[0], Doc, null);
- const other = Cast(sublists[1], Doc, null);
- const tabdocs = DocListCast(tabs.data);
- const otherdocs = DocListCast(other.data);
- Doc.GetProto(tabs).data = new List<Doc>(docs);
- const otherSet = new Set<Doc>();
- otherdocs.filter(doc => !docs.includes(doc)).forEach(doc => otherSet.add(doc));
- tabdocs.filter(doc => !docs.includes(doc)).forEach(doc => otherSet.add(doc));
- Doc.GetProto(other).data = new List<Doc>(Array.from(otherSet.values()));
- }
-
- public static async Copy(doc: Doc) {
+ public static Copy(doc: Doc) {
let json = StrCast(doc.dockingConfig);
const matches = json.match(/\"documentId\":\"[a-z0-9-]+\"/g);
const docids = matches?.map(m => m.replace("\"documentId\":\"", "").replace("\"", "")) || [];
- const docs = (await Promise.all(docids.map(id => DocServer.GetRefField(id)))).filter(f => f).map(f => f as Doc);
+ const docs = docids.map(id => DocServer.GetCachedRefField(id)).filter(f => f).map(f => f as Doc);
const newtabs = docs.map(doc => {
const copy = Doc.MakeAlias(doc);
json = json.replace(doc[Id], copy[Id]);
@@ -503,34 +485,36 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
return copy;
}
- @undoBatch
+ @action
stateChanged = () => {
const json = JSON.stringify(this._goldenLayout.toConfig());
- this.props.Document.dockingConfig = json;
- this.updateDataField(json);
- }
-
- itemDropped = () => {
- CollectionDockingView.Instance._ignoreStateChange = JSON.stringify(CollectionDockingView.Instance._goldenLayout.toConfig());
- this.stateChanged();
- }
+ const matches = json.match(/\"documentId\":\"[a-z0-9-]+\"/g);
+ const docids = matches?.map(m => m.replace("\"documentId\":\"", "").replace("\"", ""));
+ const docs = !docids ? [] : docids.map(id => DocServer.GetCachedRefField(id)).filter(f => f).map(f => f as Doc);
- htmlToElement(html: string) {
- const template = document.createElement('template');
- html = html.trim(); // Never return a text node of whitespace as the result
- template.innerHTML = html;
- return template.content.firstChild;
+ this.props.Document.dockingConfig = json;
+ const sublists = DocListCast(this.props.Document[this.props.fieldKey]);
+ const tabs = Cast(sublists[0], Doc, null);
+ const other = Cast(sublists[1], Doc, null);
+ const tabdocs = DocListCast(tabs.data);
+ const otherdocs = DocListCast(other.data);
+ Doc.GetProto(tabs).data = new List<Doc>(docs);
+ const otherSet = new Set<Doc>();
+ otherdocs.filter(doc => !docs.includes(doc)).forEach(doc => otherSet.add(doc));
+ tabdocs.filter(doc => !docs.includes(doc)).forEach(doc => otherSet.add(doc));
+ Doc.GetProto(other).data = new List<Doc>(Array.from(otherSet.values()));
}
- tabCreated = async (tab: any) => {
+ tabCreated = (tab: any) => {
tab.titleElement[0].Tab = tab;
if (tab.hasOwnProperty("contentItem") && tab.contentItem.config.type !== "stack") {
if (tab.contentItem.config.fixed) {
tab.contentItem.parent.config.fixed = true;
}
- const doc = await DocServer.GetRefField(tab.contentItem.config.props.documentId) as Doc;
+ const doc = DocServer.GetCachedRefField(tab.contentItem.config.props.documentId) as Doc;
if (doc instanceof Doc) {
+ this._tabMap.push({ tab: tab, doc: doc });
tab.titleElement[0].onclick = (e: any) => {
if (Date.now() - tab.titleElement[0].lastClick < 1000) tab.titleElement[0].select();
tab.titleElement[0].lastClick = Date.now();
@@ -550,8 +534,10 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
gearSpan.style.paddingRight = "12px";
const stack = tab.contentItem.parent;
tab.element[0].onpointerdown = (e: any) => {
- const view = DocumentManager.Instance.getDocumentView(doc);
- view && SelectionManager.SelectDoc(view, false);
+ if (e.target.className !== "lm_close_tab") {
+ const view = DocumentManager.Instance.getDocumentView(doc);
+ view && SelectionManager.SelectDoc(view, false);
+ }
};
// shifts the focus to this tab when another tab is dragged over it
tab.element[0].onmouseenter = (e: any) => {
@@ -594,27 +580,23 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
tab.reactComponents = [gearSpan];
tab.element.append(gearSpan);
tab.reactionDisposer = reaction(() => ({ title: doc.title, degree: Doc.IsBrushedDegree(doc) }), ({ title, degree }) => {
- tab.titleElement[0].textContent = title, { fireImmediately: true };
+ tab.titleElement[0].value = title;
tab.titleElement[0].style.padding = degree ? 0 : 2;
tab.titleElement[0].style.border = `${["gray", "gray", "gray"][degree]} ${["none", "dashed", "solid"][degree]} 2px`;
- });
+ }, { fireImmediately: true });
//TODO why can't this just be doc instead of the id?
tab.titleElement[0].DashDocId = tab.contentItem.config.props.documentId;
}
}
tab.closeElement.off('click') //unbind the current click handler
- .click(async function () {
+ .click(function () {
tab.selectionDisposer?.();
tab.reactionDisposer?.();
tab.buttonDisposer?.();
- const doc = await DocServer.GetRefField(tab.contentItem.config.props.documentId);
+ const doc = DocServer.GetCachedRefField(tab.contentItem.config.props.documentId);
if (doc instanceof Doc) {
- const theDoc = doc;
-
- const recent = await Cast(Doc.UserDoc().myRecentlyClosedDocs, Doc);
- if (recent) {
- Doc.AddDocToList(recent, "data", doc, undefined, true, true);
- }
+ const recent = Cast(Doc.UserDoc().myRecentlyClosedDocs, Doc, null);
+ recent && Doc.AddDocToList(recent, "data", doc, undefined, true, true);
SelectionManager.DeselectAll();
}
CollectionDockingView.Instance._ignoreStateChange = JSON.stringify(CollectionDockingView.Instance._goldenLayout.toConfig());
@@ -624,6 +606,8 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
}
tabDestroyed = (tab: any) => {
+ const ind = this._tabMap.findIndex((val) => val.tab === tab);
+ ind !== -1 && this._tabMap.splice(ind, 1);
if (tab.reactComponents) {
for (const ele of tab.reactComponents) {
ReactDOM.unmountComponentAtNode(ele);
@@ -631,15 +615,8 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
}
}
- stackActiveChanged = () => {
- try {
- CollectionDockingView.Instance._ignoreStateChange = JSON.stringify(CollectionDockingView.Instance._goldenLayout.toConfig());
- this.stateChanged();
- } catch (e) { } // catch exception thrown when config has not been initialzed yet
- }
stackCreated = (stack: any) => {
- stack.layoutManager.on("activeContentItemChanged", this.stackActiveChanged);
//stack.header.controlsContainer.find('.lm_popout').hide();
stack.header.element.on('mousedown', (e: any) => {
if (e.target === stack.header.element[0] && e.button === 2) {
@@ -651,58 +628,28 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
}
});
- // starter code for bezel to add new pane
- // stack.element.on("touchstart", (e: TouchEvent) => {
- // if (e.targetTouches.length === 2) {
- // let pt1 = e.targetTouches.item(0);
- // let pt2 = e.targetTouches.item(1);
- // let threshold = 40 * window.devicePixelRatio;
- // if (pt1 && pt2 && InteractionUtils.TwoPointEuclidist(pt1, pt2) < threshold) {
- // let edgeThreshold = 30 * window.devicePixelRatio;
- // let center = InteractionUtils.CenterPoint([pt1, pt2]);
- // let stackRect: DOMRect = stack.element.getBoundingClientRect();
- // let nearLeft = center.X - stackRect.x < edgeThreshold;
- // let nearTop = center.Y - stackRect.y < edgeThreshold;
- // let nearRight = stackRect.right - center.X < edgeThreshold;
- // let nearBottom = stackRect.bottom - center.Y < edgeThreshold;
- // let ns = [nearLeft, nearTop, nearRight, nearBottom].filter(n => n);
- // if (ns.length === 1) {
-
- // }
- // }
- // }
- // });
stack.header.controlsContainer.find('.lm_close') //get the close icon
.off('click') //unbind the current click handler
- .click(action(async () => {
+ .click(action(() => {
//if (confirm('really close this?')) {
-
stack.remove();
- stack.contentItems.forEach(async (contentItem: any) => {
- const doc = await DocServer.GetRefField(contentItem.config.props.documentId);
+ stack.contentItems.forEach((contentItem: any) => {
+ const doc = Cast(DocServer.GetCachedRefField(contentItem.config.props.documentId), Doc, null);
if (doc instanceof Doc) {
- let recent: Doc | undefined;
- if (recent = await Cast(Doc.UserDoc().myRecentlyClosedDocs, Doc)) {
- Doc.AddDocToList(recent, "data", doc, undefined, true, true);
- }
- const theDoc = doc;
+ const recent = Cast(Doc.UserDoc().myRecentlyClosedDocs, Doc, null);
+ recent && Doc.AddDocToList(recent, "data", doc, undefined, true, true);
}
});
- //}
}));
stack.header.controlsContainer.find('.lm_popout') //get the close icon
.off('click') //unbind the current click handler
.click(action(() => {
// stack.config.fixed = !stack.config.fixed; // force the stack to have a fixed size
-
const emptyPane = Cast(Doc.UserDoc().emptyPane, Doc, null);
emptyPane["dragFactory-count"] = NumCast(emptyPane["dragFactory-count"]) + 1;
this.AddTab(stack, Docs.Create.FreeformDocument([], {
_width: this.props.PanelWidth(), _height: this.props.PanelHeight(), title: `Untitled Tab ${NumCast(emptyPane["dragFactory-count"])}`
}));
-
- // const url = Utils.prepend("/doc/" + stack.contentItems[0].tab.contentItem.config.props.documentId);
- // let win = window.open(url, stack.contentItems[0].tab.title, "width=300,height=400");
}));
}
@@ -710,10 +657,8 @@ export class CollectionDockingView extends CollectionSubView(doc => doc) {
if (this.props.renderDepth > 0) {
return <div style={{ width: "100%", height: "100%" }}>Nested dashboards can't be rendered</div>;
}
- return <div className="collectiondockingview-container" id="menuContainer"
- onPointerDown={this.onPointerDown} onPointerUp={this.onPointerUp} ref={this._containerRef} />;
+ return <div className="collectiondockingview-container" onPointerDown={this.onPointerDown} ref={this._containerRef} />;
}
-
}
interface DockedFrameProps {
@@ -725,7 +670,6 @@ interface DockedFrameProps {
@observer
export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
_mainCont: HTMLDivElement | null = null;
- @observable private _libraryPath: Doc[] = [];
@observable private _panelWidth = 0;
@observable private _panelHeight = 0;
@observable private _document: Opt<Doc>;
@@ -741,17 +685,8 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
}
constructor(props: any) {
super(props);
- DocServer.GetRefField(this.props.documentId).then(action((f: Opt<Field>) => this._document = f as Doc));
- this.props.libraryPath && this.setupLibraryPath();
- }
-
- async setupLibraryPath() {
- Promise.all(this.props.libraryPath.map(async docid => {
- const d = await DocServer.GetRefField(docid);
- return d instanceof Doc ? d : undefined;
- })).then(action((list: (Doc | undefined)[]) => this._libraryPath = list.filter(d => d).map(d => d as Doc)));
+ this._document = Cast(DocServer.GetCachedRefField(this.props.documentId), Doc, null);
}
-
/**
* Adds a document to the presentation view
**/
@@ -792,7 +727,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
componentDidMount() {
const color = () => StrCast(this._document?._backgroundColor, this._document && CollectionDockingView.Instance?.props.backgroundColor?.(this._document, 0) || "white");
- const selected = () => SelectionManager.SelectedDocuments().some(v => Doc.AreProtosEqual(v.props.Document, this._document));
+ const selected = () => SelectionManager.SelectedDocuments().some(v => v.props.Document === this._document);
const updateTabColor = () => this._tab && (this._tab.style.backgroundColor = selected() ? color() : "");
const observer = new _global.ResizeObserver(action((entries: any) => {
for (const entry of entries) {
@@ -820,6 +755,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
const dv = this._document && DocumentManager.Instance.getFirstDocumentView(this._document);
dv && SelectionManager.SelectDoc(dv, false);
});
+ (CollectionDockingView.Instance as any)._goldenLayout.isInitialised && CollectionDockingView.Instance.stateChanged();
!this._isActive && this._document && Doc.UnBrushDoc(this._document); // bcz: bad -- trying to simulate a pointer leave event when a new tab is opened up on top of an existing one.
}
}
@@ -873,7 +809,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
if (doc._viewType === CollectionViewType.Docking) {
return CurrentUserUtils.openDashboard(Doc.UserDoc(), doc);
} else if (location === "onRight") {
- return CollectionDockingView.AddRightSplit(doc, libraryPath);
+ return CollectionDockingView.AddRightSplit(doc);
} else if (location === "close") {
return CollectionDockingView.CloseRightSplit(doc);
} else if (location === "replace") {
@@ -968,7 +904,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
const resolvedDataDoc = !Doc.AreProtosEqual(this._document[DataSym], this._document) ? this._document[DataSym] : undefined;
return <>
<DocumentView key={document[Id]}
- LibraryPath={this._libraryPath}
+ LibraryPath={emptyPath}
Document={document}
DataDoc={resolvedDataDoc}
bringToFront={emptyFunction}
@@ -1008,6 +944,6 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
</div >);
}
}
-Scripting.addGlobal(function openOnRight(doc: any) { CollectionDockingView.AddRightSplit(doc); },
- "opens up the inputted document on the right side of the screen", "(doc: any)");
+Scripting.addGlobal(function openOnRight(doc: any, dontSelect: boolean = false) { CollectionDockingView.AddRightSplit(doc, dontSelect); },
+ "opens up the inputted document on the right side of the screen", "(doc: any, dontSelect: boolean)");
Scripting.addGlobal(function useRightSplit(doc: any, shiftKey?: boolean) { CollectionDockingView.UseRightSplit(doc, undefined, shiftKey); });
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 66bdcf130..cdfa67769 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -39,7 +39,7 @@ export interface TreeViewProps {
containingCollection: Doc;
prevSibling?: Doc;
renderDepth: number;
- deleteDoc: (doc: Doc | Doc[]) => boolean;
+ removeDoc: ((doc: Doc | Doc[]) => boolean) | undefined;
moveDocument: DragManager.MoveFunction;
dropAction: dropActionType;
addDocTab: (doc: Doc, where: string, libraryPath?: Doc[]) => boolean;
@@ -119,14 +119,14 @@ class TreeView extends React.Component<TreeViewProps> {
@undoBatch openRight = () => this.props.addDocTab(this.doc, "onRight");
@undoBatch move = (doc: Doc | Doc[], target: Doc | undefined, addDoc: (doc: Doc | Doc[]) => boolean) => {
- return this.doc !== target && this.props.deleteDoc(doc) && addDoc(doc);
+ return this.doc !== target && this.props.removeDoc?.(doc) === true && addDoc(doc);
}
@undoBatch @action remove = (doc: Doc | Doc[], key: string) => {
return (doc instanceof Doc ? [doc] : doc).reduce((flg, doc) => flg && Doc.RemoveDocFromList(this.dataDoc, key, doc), true);
}
@undoBatch @action removeDoc = (doc: Doc | Doc[]) => {
return (doc instanceof Doc ? [doc] : doc).reduce((flg, doc) =>
- flg && Doc.RemoveDocFromList(this.props.containingCollection, Doc.LayoutFieldKey(this.props.containingCollection), doc), true);
+ flg && Doc.RemoveDocFromList(this.doc, Doc.LayoutFieldKey(this.doc), doc), true);
}
constructor(props: any) {
@@ -280,8 +280,8 @@ class TreeView extends React.Component<TreeViewProps> {
const remDoc = (doc: Doc | Doc[]) => this.remove(doc, key);
const addDoc = (doc: Doc | Doc[], addBefore?: Doc, before?: boolean) => (doc instanceof Doc ? [doc] : doc).reduce(
(flg, doc) => flg && Doc.AddDocToList(this.dataDoc, key, doc, addBefore, before, false, true), true);
- contentElement = TreeView.GetChildElements(contents instanceof Doc ? [contents] :
- DocListCast(contents), this.props.treeView, doc, undefined, key, this.props.containingCollection, this.props.prevSibling, addDoc, remDoc, this.move,
+ contentElement = TreeView.GetChildElements(contents instanceof Doc ? [contents] : DocListCast(contents),
+ this.props.treeView, doc, undefined, key, this.props.containingCollection, this.props.prevSibling, addDoc, remDoc, this.move,
this.props.dropAction, this.props.addDocTab, this.props.pinToPres, this.props.backgroundColor, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active,
this.props.panelWidth, this.props.ChromeHeight, this.props.renderDepth, this.props.treeViewHideHeaderFields, this.props.treeViewPreventOpen,
[...this.props.renderedIds, doc[Id]], this.props.onCheckedClick, this.props.onChildClick, this.props.ignoreFields, false, this.props.whenActiveChanged);
@@ -458,7 +458,7 @@ class TreeView extends React.Component<TreeViewProps> {
onDoubleClick={this.onChildDoubleClick}
dropAction={this.props.dropAction}
moveDocument={this.move}
- removeDocument={this.removeDoc}
+ removeDocument={this.props.removeDoc}
ScreenToLocalTransform={this.getTransform}
ContentScaling={returnOne}
PanelWidth={this.truncateTitleWidth}
@@ -612,7 +612,7 @@ class TreeView extends React.Component<TreeViewProps> {
}
const indent = i === 0 ? undefined : () => {
- if (StrCast(docs[i - 1].layout).indexOf('fieldKey') !== -1) {
+ if (remove && StrCast(docs[i - 1].layout).indexOf('fieldKey') !== -1) {
const fieldKeysub = StrCast(docs[i - 1].layout).split('fieldKey')[1];
const fieldKey = fieldKeysub.split("\'")[1];
if (fieldKey && Cast(docs[i - 1][fieldKey], listSpec(Doc)) !== undefined) {
@@ -623,7 +623,7 @@ class TreeView extends React.Component<TreeViewProps> {
}
};
const outdent = !parentCollectionDoc ? undefined : () => {
- if (StrCast(parentCollectionDoc.layout).indexOf('fieldKey') !== -1) {
+ if (remove && StrCast(parentCollectionDoc.layout).indexOf('fieldKey') !== -1) {
const fieldKeysub = StrCast(parentCollectionDoc.layout).split('fieldKey')[1];
const fieldKey = fieldKeysub.split("\'")[1];
Doc.AddDocToList(parentCollectionDoc, fieldKey, child, parentPrevSibling, false);
@@ -651,7 +651,7 @@ class TreeView extends React.Component<TreeViewProps> {
onCheckedClick={onCheckedClick}
onChildClick={onChildClick}
renderDepth={renderDepth}
- deleteDoc={remove}
+ removeDoc={StrCast(containingCollection.freezeChildren).includes("remove") ? undefined : remove}
addDocument={addDocument}
backgroundColor={backgroundColor}
panelWidth={rowWidth}
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index f028b797c..1da0e601a 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -582,10 +582,10 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
ChildLayoutTemplate: this.childLayoutTemplate,
ChildLayoutString: this.childLayoutString,
};
- const boxShadow = Doc.UserDoc().renderStyle === "comic" || this.props.Document.isBackground || this.collectionViewType === CollectionViewType.Linear ? undefined :
+ const boxShadow = Doc.UserDoc().renderStyle === "comic" || this.props.Document._isBackground || this.collectionViewType === CollectionViewType.Linear ? undefined :
`${Cast(Doc.UserDoc().activeDashboard, Doc, null)?.darkScheme ? "rgb(30, 32, 31) " : "#9c9396 "} ${StrCast(this.props.Document.boxShadow, "0.2vw 0.2vw 0.8vw")}`;
return (<div className={"collectionView"} onContextMenu={this.onContextMenu}
- style={{ pointerEvents: this.props.Document.isBackground ? "none" : undefined, boxShadow }}>
+ style={{ pointerEvents: this.props.Document._isBackground ? "none" : undefined, boxShadow }}>
{this.showIsTagged()}
<div className="collectionView-facetCont" style={{ display: this.props.PanelPosition === "absolute" ? "flex" : "", justifyContent: this.props.PanelPosition === "absolute" ? "center" : "", width: `calc(100% - ${this.facetWidth()}px)` }}>
{this.collectionViewType !== undefined ? this.SubView(this.collectionViewType, props) : (null)}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 7ba8694ed..b55dc467a 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -217,7 +217,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
const nd = [NumCast(layoutDoc._nativeWidth), NumCast(layoutDoc._nativeHeight)];
layoutDoc._width = NumCast(layoutDoc._width, 300);
layoutDoc._height = NumCast(layoutDoc._height, nd[0] && nd[1] ? nd[1] / nd[0] * NumCast(layoutDoc._width) : 300);
- d.isBackground === undefined && (d.zIndex = zsorted.length + 1 + i); // bringToFront
+ d._isBackground === undefined && (d.zIndex = zsorted.length + 1 + i); // bringToFront
}
(docDragData.droppedDocuments.length === 1 || de.shiftKey) && this.updateClusterDocs(docDragData.droppedDocuments);
@@ -256,7 +256,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
@action
onInternalDrop = (e: Event, de: DragManager.DropEvent) => {
- // if (this.props.Document.isBackground) return false;
+ // if (this.props.Document._isBackground) return false;
const [xp, yp] = this.getTransform().transformPoint(de.x, de.y);
if (this.isAnnotationOverlay !== true && de.complete.linkDragData) {
return this.internalLinkDrop(e, de, de.complete.linkDragData, xp, yp);
@@ -384,8 +384,8 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
clusterColor = colors[cluster % colors.length];
const set = this._clusterSets[cluster]?.filter(s => s.backgroundColor);
// override the cluster color with an explicitly set color on a non-background document. then override that with an explicitly set color on a background document
- set && set.filter(s => !s.isBackground).map(s => clusterColor = StrCast(s.backgroundColor));
- set && set.filter(s => s.isBackground).map(s => clusterColor = StrCast(s.backgroundColor));
+ set && set.filter(s => !s._isBackground).map(s => clusterColor = StrCast(s.backgroundColor));
+ set && set.filter(s => s._isBackground).map(s => clusterColor = StrCast(s.backgroundColor));
}
}
return clusterColor;
@@ -839,7 +839,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
}
bringToFront = action((doc: Doc, sendToBack?: boolean) => {
- if (sendToBack || doc.isBackground) {
+ if (sendToBack || doc._isBackground) {
doc.zIndex = 0;
} else if (doc.isInkMask) {
doc.zIndex = 5000;
@@ -935,7 +935,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
}
@computed get libraryPath() { return this.props.LibraryPath ? [...this.props.LibraryPath, this.props.Document] : []; }
- @computed get backgroundActive() { return this.layoutDoc.isBackground && (this.props.ContainingCollectionView?.active() || this.props.active()); }
+ @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);
@@ -1328,7 +1328,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
};
const snappableDocs: Doc[] = []; // the set of documents in the visible viewport that we will try to snap to;
const otherBounds = { left: this.panX(), top: this.panY(), width: Math.abs(size[0]), height: Math.abs(size[1]) };
- this.getActiveDocuments().filter(doc => !doc.isBackground && doc.z === undefined).map(doc => isDocInView(doc, selRect)); // first see if there are any foreground docs to snap to
+ this.getActiveDocuments().filter(doc => !doc._isBackground && doc.z === undefined).map(doc => isDocInView(doc, selRect)); // first see if there are any foreground docs to snap to
!snappableDocs.length && this.getActiveDocuments().filter(doc => doc.z === undefined).map(doc => isDocInView(doc, selRect)); // if not, see if there are background docs to snap to
!snappableDocs.length && this.getActiveDocuments().filter(doc => doc.z !== undefined).map(doc => isDocInView(doc, otherBounds)); // if not, then why not snap to floating docs
@@ -1422,7 +1422,7 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
const wscale = nw ? this.props.PanelWidth() / nw : 1;
return wscale < hscale ? wscale : hscale;
}
- @computed get backgroundEvents() { return this.layoutDoc.isBackground && SnappingManager.GetIsDragging(); }
+ @computed get backgroundEvents() { return this.layoutDoc._isBackground && SnappingManager.GetIsDragging(); }
render() {
TraceMobx();
const clientRect = this._mainCont?.getBoundingClientRect();
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 864c45ca2..759d142ea 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -355,7 +355,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
this.hideMarquee();
}
- getCollection = action((selected: Doc[], creator: Opt<(documents: Array<Doc>, options: DocumentOptions, id?: string) => Doc>, isBackground?: boolean) => {
+ getCollection = action((selected: Doc[], creator: Opt<(documents: Array<Doc>, options: DocumentOptions, id?: string) => Doc>, _isBackground?: boolean) => {
const newCollection = creator ? creator(selected, { title: "nested stack", }) : ((doc: Doc) => {
Doc.GetProto(doc).data = new List<Doc>(selected);
Doc.GetProto(doc).title = "nested freeform";
@@ -363,8 +363,8 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
return doc;
})(Doc.MakeCopy(Doc.UserDoc().emptyCollection as Doc, true));
newCollection.system = undefined;
- newCollection.isBackground = isBackground;
- newCollection.backgroundColor = this.props.isAnnotationOverlay ? "#00000015" : isBackground ? "cyan" : undefined;
+ newCollection._isBackground = _isBackground;
+ newCollection.backgroundColor = this.props.isAnnotationOverlay ? "#00000015" : _isBackground ? "cyan" : undefined;
newCollection._width = this.Bounds.width;
newCollection._height = this.Bounds.height;
newCollection.x = this.Bounds.left;
@@ -682,7 +682,7 @@ export class MarqueeView extends React.Component<SubCollectionViewProps & Marque
marqueeSelect(selectBackgrounds: boolean = true) {
const selRect = this.Bounds;
const selection: Doc[] = [];
- this.props.activeDocuments().filter(doc => !doc.isBackground && !doc.z).map(doc => {
+ this.props.activeDocuments().filter(doc => !doc._isBackground && !doc.z).map(doc => {
const layoutDoc = Doc.Layout(doc);
const x = NumCast(doc.x);
const y = NumCast(doc.y);
diff --git a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
index f9ffb4260..c316e1aad 100644
--- a/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
+++ b/src/client/views/collections/collectionFreeForm/PropertiesView.tsx
@@ -148,7 +148,7 @@ export class PropertiesView extends React.Component<PropertiesViewProps> {
&nbsp;
</div>);
} else {
- let contentElement = <EditableView key="editableView"
+ const contentElement = <EditableView key="editableView"
contents={contents !== undefined ? Field.toString(contents as Field) : "null"}
height={13}
fontSize={10}
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 48f10ba26..16b2f7c2a 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -252,8 +252,8 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
boxShadow:
this.Opacity === 0 ? undefined : // if it's not visible, then no shadow
this.layoutDoc.z ? `#9c9396 ${StrCast(this.layoutDoc.boxShadow, "10px 10px 0.9vw")}` : // if it's a floating doc, give it a big shadow
- this.props.backgroundHalo?.() && this.props.Document.type !== DocumentType.INK ? (`${this.props.backgroundColor?.(this.props.Document, this.props.renderDepth)} ${StrCast(this.layoutDoc.boxShadow, `0vw 0vw ${(this.layoutDoc.isBackground ? 100 : 50) / this.props.ContentScaling()}px`)}`) : // if it's just in a cluster, make the shadown roughly match the cluster border extent
- this.layoutDoc.isBackground ? undefined : // if it's a background & has a cluster color, make the shadow spread really big
+ this.props.backgroundHalo?.() && this.props.Document.type !== DocumentType.INK ? (`${this.props.backgroundColor?.(this.props.Document, this.props.renderDepth)} ${StrCast(this.layoutDoc.boxShadow, `0vw 0vw ${(this.layoutDoc._isBackground ? 100 : 50) / this.props.ContentScaling()}px`)}`) : // if it's just in a cluster, make the shadown roughly match the cluster border extent
+ this.layoutDoc._isBackground ? undefined : // if it's a background & has a cluster color, make the shadow spread really big
StrCast(this.layoutDoc.boxShadow, ""),
borderRadius: StrCast(Doc.Layout(this.layoutDoc).borderRounding),
outline: this.Highlight ? "orange solid 2px" : "",
@@ -264,7 +264,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
zIndex: this.ZInd,
mixBlendMode: StrCast(this.layoutDoc.mixBlendMode) as any,
display: this.ZInd === -99 ? "none" : undefined,
- pointerEvents: this.props.Document.isBackground || this.Opacity === 0 || this.props.Document.type === DocumentType.INK || this.props.Document.isInkMask ? "none" : this.props.pointerEvents ? "all" : undefined
+ pointerEvents: this.props.Document._isBackground || this.Opacity === 0 || this.props.Document.type === DocumentType.INK || this.props.Document.isInkMask ? "none" : this.props.pointerEvents ? "all" : undefined
}} >
{Doc.UserDoc().renderStyle !== "comic" ? (null) :
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 30416b280..eb6988362 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -292,7 +292,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
(Math.abs(e.clientX - this._downX) < Utils.DRAG_THRESHOLD && Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD)) {
let stopPropagate = true;
let preventDefault = true;
- !this.props.Document.isBackground && this.props.bringToFront(this.props.Document);
+ !this.props.Document._isBackground && this.props.bringToFront(this.props.Document);
if (this._doubleTap && this.props.renderDepth && (this.props.Document.type !== DocumentType.FONTICON || this.onDoubleClickHandler)) {// && !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._timeout) {
clearTimeout(this._timeout);
@@ -694,9 +694,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
@undoBatch
@action
toggleBackground = () => {
- this.Document.isBackground = (this.Document.isBackground ? undefined : true);
- this.Document._overflow = this.Document.isBackground ? "visible" : undefined;
- if (this.Document.isBackground) {
+ this.Document._isBackground = (this.Document._isBackground ? undefined : true);
+ this.Document._overflow = this.Document._isBackground ? "visible" : undefined;
+ if (this.Document._isBackground) {
this.props.bringToFront(this.props.Document, true);
this.props.Document[DataSym][Doc.LayoutFieldKey(this.Document) + "-nativeWidth"] = this.Document[WidthSym]();
this.props.Document[DataSym][Doc.LayoutFieldKey(this.Document) + "-nativeHeight"] = this.Document[HeightSym]();
@@ -795,7 +795,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
}
const collectionAcl = GetEffectiveAcl(this.props.ContainingCollectionDoc?.[DataSym]);
- if (collectionAcl === AclAdmin || collectionAcl === AclEdit) moreItems.push({ description: "Close", event: this.deleteClicked, icon: "times" });
+ if ((collectionAcl === AclAdmin || collectionAcl === AclEdit) && this.props.removeDocument) {
+ moreItems.push({ description: "Close", event: this.deleteClicked, icon: "times" });
+ }
!more && cm.addItem({ description: "More...", subitems: moreItems, icon: "hand-point-right" });
cm.moveAfter(cm.findByDescription("More...")!, cm.findByDescription("OnClick...")!);
@@ -991,7 +993,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
}
@computed get ignorePointerEvents() {
return this.props.pointerEvents === false ||
- (this.Document.isBackground && !this.isSelected() && !SnappingManager.GetIsDragging()) ||
+ (this.Document._isBackground && !this.isSelected() && !SnappingManager.GetIsDragging()) ||
(this.Document.type === DocumentType.INK && Doc.GetSelectedTool() !== InkTool.None);
}
@undoBatch
@@ -1013,11 +1015,11 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
});
renderLock() {
- return (this.Document.isBackground !== undefined || this.isSelected(false)) &&
+ return (this.Document._isBackground !== undefined || this.isSelected(false)) &&
((this.Document.type === DocumentType.COL && this.Document._viewType !== CollectionViewType.Pile) || this.Document.type === DocumentType.IMG) &&
this.props.renderDepth > 0 && !this.props.treeViewDoc ?
<div className="documentView-lock" onClick={this.toggleBackground}>
- <FontAwesomeIcon icon={this.Document.isBackground ? "unlock" : "lock"} style={{ color: this.Document.isBackground ? "red" : undefined }} size="lg" />
+ <FontAwesomeIcon icon={this.Document._isBackground ? "unlock" : "lock"} style={{ color: this.Document._isBackground ? "red" : undefined }} size="lg" />
</div>
: (null);
}
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 855160524..6cce5fb87 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -145,7 +145,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD
if (field) {
const funcs: ContextMenuProps[] = [];
funcs.push({ description: "Rotate Clockwise 90", event: this.rotate, icon: "expand-arrows-alt" });
- funcs.push({ description: "Make Background", event: () => { this.layoutDoc.isBackground = true; this.props.bringToFront?.(this.rootDoc); }, icon: "expand-arrows-alt" });
+ funcs.push({ description: "Make Background", event: () => { this.layoutDoc._isBackground = true; this.props.bringToFront?.(this.rootDoc); }, icon: "expand-arrows-alt" });
if (!Doc.UserDoc().noviceMode) {
funcs.push({ description: "Export to Google Photos", event: () => GooglePhotos.Transactions.UploadImages([this.props.Document]), icon: "caret-square-right" });
funcs.push({ description: "Copy path", event: () => Utils.CopyText(field.url.href), icon: "expand-arrows-alt" });
@@ -452,7 +452,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<FieldViewProps, ImageD
transform: this.props.PanelWidth() ? undefined : `scale(${this.props.ContentScaling()})`,
width: this.props.PanelWidth() ? undefined : `${100 / this.props.ContentScaling()}%`,
height: this.props.PanelWidth() ? undefined : `${100 / this.props.ContentScaling()}%`,
- pointerEvents: this.layoutDoc.isBackground ? "none" : undefined,
+ pointerEvents: this.layoutDoc._isBackground ? "none" : undefined,
borderRadius: `${Number(StrCast(this.layoutDoc.borderRounding).replace("px", "")) / this.props.ContentScaling()}px`
}} >
<CollectionFreeFormView {...this.props}
diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx
index 50b2af0d7..1ef25c80d 100644
--- a/src/client/views/nodes/LinkAnchorBox.tsx
+++ b/src/client/views/nodes/LinkAnchorBox.tsx
@@ -92,7 +92,7 @@ export class LinkAnchorBox extends ViewBoxBaseComponent<FieldViewProps, LinkAnch
openLinkTargetOnRight = (e: React.MouseEvent) => {
const alias = Doc.MakeAlias(Cast(this.layoutDoc[this.fieldKey], Doc, null));
alias.isLinkButton = undefined;
- alias.isBackground = undefined;
+ alias._isBackground = undefined;
alias.layoutKey = "layout";
this.props.addDocTab(alias, "onRight");
}
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index 02c62be95..f60c521ad 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -262,10 +262,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
// if targetDoc is not displayed but one of its aliases is, then we need to modify that alias, not the original target
const bestTarget = DocumentManager.Instance.getFirstDocumentView(targetDoc)?.props.Document;
bestTarget && runInAction(() => {
- bestTarget!._viewTransition = "all 1s";
- bestTarget!._panX = activeItem.presPinViewX;
- bestTarget!._panY = activeItem.presPinViewY;
- bestTarget!._viewScale = activeItem.presPinViewScale;
+ bestTarget._viewTransition = "all 1s";
+ bestTarget._panX = activeItem.presPinViewX;
+ bestTarget._panY = activeItem.presPinViewY;
+ bestTarget._viewScale = activeItem.presPinViewScale;
});
//setTimeout(() => targetDoc._viewTransition = undefined, 1010);
}
@@ -548,7 +548,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
removeDocument = (doc: Doc) => { Doc.RemoveDocFromList(this.dataDoc, this.fieldKey, doc); };
getTransform = () => this.props.ScreenToLocalTransform().translate(-5, -65);// listBox padding-left and pres-box-cont minHeight
panelHeight = () => this.props.PanelHeight() - 40;
- active = (outsideReaction?: boolean) => ((Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc.isBackground) &&
+ active = (outsideReaction?: boolean) => ((Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc._isBackground) &&
(this.layoutDoc.forceActive || this.props.isSelected(outsideReaction) || this._isChildActive || this.props.renderDepth === 0) ? true : false)
/**
@@ -674,7 +674,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
}
handled = true;
}
- })
+ });
/**
*
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 88c3e6730..85d010aaa 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -185,8 +185,9 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD
this._videoRef = vref;
if (vref) {
this._videoRef!.ontimeupdate = this.updateTimecode;
+ // @ts-ignore
vref.onfullscreenchange = action((e) => this._fullScreen = vref.webkitDisplayingFullscreen);
- this._reactionDisposer && this._reactionDisposer();
+ this._reactionDisposer?.();
this._reactionDisposer = reaction(() => (this.layoutDoc._currentTimecode || 0),
time => !this._playing && (vref.currentTime = time), { fireImmediately: true });
}
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index f0e3a2b54..7758b1815 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -476,7 +476,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
{view}
</div>;
{!frozen ? (null) :
- <div className="webBox-overlay" style={{ pointerEvents: this.layoutDoc.isBackground ? undefined : "all" }}
+ <div className="webBox-overlay" style={{ pointerEvents: this.layoutDoc._isBackground ? undefined : "all" }}
onWheel={this.onPreWheel} onPointerDown={this.onPrePointer} onPointerMove={this.onPrePointer} onPointerUp={this.onPrePointer}>
<div className="touch-iframe-overlay" onPointerDown={this.onLongPressDown} >
<div className="indicator" ref={this._iframeIndicatorRef}></div>
@@ -682,7 +682,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
transform: `scale(${this.props.ContentScaling()})`,
width: Number.isFinite(this.props.ContentScaling()) ? `${100 / this.props.ContentScaling()}% ` : "100%",
height: Number.isFinite(this.props.ContentScaling()) ? `${100 / this.props.ContentScaling()}% ` : "100%",
- pointerEvents: this.layoutDoc.isBackground ? "none" : undefined
+ pointerEvents: this.layoutDoc._isBackground ? "none" : undefined
}}
onContextMenu={this.specificContextMenu}>
<base target="_blank" />
@@ -690,7 +690,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
<div className={"webBox-outerContent"} ref={this._outerRef}
style={{
width: Number.isFinite(this.props.ContentScaling()) ? `${Math.max(100, 100 / this.props.ContentScaling())}% ` : "100%",
- pointerEvents: this.layoutDoc.isAnnotating && !this.layoutDoc.isBackground ? "all" : "none"
+ pointerEvents: this.layoutDoc.isAnnotating && !this.layoutDoc._isBackground ? "all" : "none"
}}
onWheel={e => e.stopPropagation()}
onPointerDown={this.onMarqueeDown}
@@ -709,7 +709,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<FieldViewProps, WebDocum
}}>
<div className={"webBox-innerContent"} style={{
height: NumCast(this.layoutDoc.scrollHeight),
- pointerEvents: this.layoutDoc.isBackground ? "none" : undefined
+ pointerEvents: this.layoutDoc._isBackground ? "none" : undefined
}}>
<CollectionFreeFormView {...this.props}
PanelHeight={this.props.PanelHeight}
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 063cdb0cc..356e36b76 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -94,7 +94,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
private _linkTime: number | null = null;
private _pause: boolean = false;
- @computed get _recording() { return this.dataDoc.audioState === "recording"; }
+ @computed get _recording() { return this.dataDoc?.audioState === "recording"; }
set _recording(value) {
this.dataDoc.audioState = value ? "recording" : undefined;
}
@@ -818,6 +818,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
);
this._disposers.editorState = reaction(
() => {
+ if (!this.dataDoc || !this.layoutDoc) return undefined;
if (this.dataDoc?.[this.props.fieldKey + "-noTemplate"] || !this.layoutDoc[this.props.fieldKey + "-textTemplate"]) {
return Cast(this.dataDoc[this.props.fieldKey], RichTextField, null)?.Data;
}
@@ -853,13 +854,16 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
}
);
this._disposers.autoHeight = reaction(
- () => [this.layoutDoc[WidthSym](), this.layoutDoc._autoHeight],
- () => setTimeout(() => this.tryUpdateHeight(), 0)
+ () => ({
+ width: NumCast(this.layoutDoc._width),
+ autoHeight: this.layoutDoc?._autoHeight
+ }),
+ ({ width, autoHeight }) => width !== undefined && setTimeout(() => this.tryUpdateHeight(), 0)
);
this._disposers.height = reaction(
- () => this.layoutDoc[HeightSym](),
+ () => NumCast(this.layoutDoc._height),
action(height => {
- if (height <= 20 && height < NumCast(this.layoutDoc._delayAutoHeight, 20)) {
+ if (height !== undefined && height <= 20 && height < NumCast(this.layoutDoc._delayAutoHeight, 20)) {
this.layoutDoc._delayAutoHeight = height;
}
})
@@ -1490,7 +1494,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
TraceMobx();
const scale = this.props.hideOnLeave ? 1 : this.props.ContentScaling() * NumCast(this.layoutDoc._viewScale, 1);
const rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : "";
- const interactive = Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc.isBackground;
+ const interactive = Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc._isBackground;
this.props.isSelected() && setTimeout(() => this._editorView && RichTextMenu.Instance?.updateMenu(this._editorView, undefined, this.props), 0); // need to make sure that we update a text box that is selected after updating the one that was deselected
if (!this.props.isSelected() && FormattedTextBoxComment.textBox === this) {
setTimeout(() => FormattedTextBoxComment.Hide(), 0);
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index 7ff21975b..c33637d0f 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -214,7 +214,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps, PresDoc
PresBox.Instance._selectedArray.splice(PresBox.Instance._selectedArray.indexOf(this.rootDoc), 1);
}
e.stopPropagation();
- })
+ });
render() {
const className = "presElementBox-item" + (PresBox.Instance._selectedArray.includes(this.rootDoc) ? " presElementBox-active" : "");
diff --git a/src/client/views/search/SearchBox.tsx b/src/client/views/search/SearchBox.tsx
index 7e233ecbb..a24761195 100644
--- a/src/client/views/search/SearchBox.tsx
+++ b/src/client/views/search/SearchBox.tsx
@@ -507,7 +507,7 @@ export class SearchBox extends ViewBoxBaseComponent<FieldViewProps, SearchBoxDoc
</div>
<div className="searchBox-lozenge-dashboard" >
<select className="searchBox-dashSelect" onChange={e => CurrentUserUtils.openDashboard(Doc.UserDoc(), myDashboards[Number(e.target.value)])}
- value={myDashboards.indexOf(Cast(Doc.UserDoc().activeDashboard, Doc, null)!)}>
+ value={myDashboards.indexOf(Cast(Doc.UserDoc().activeDashboard, Doc, null))}>
{myDashboards.map((dash, i) => <option key={dash[Id]} value={i}> {StrCast(dash.title)} </option>)}
</select>
<div className="searchBox-dashboards" onClick={undoBatch(() => CurrentUserUtils.createNewDashboard(Doc.UserDoc()))}>
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index e569dabc1..cb4ca9a25 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -939,16 +939,19 @@ export namespace Doc {
}
export function IsBrushed(doc: Doc) {
+ return false;
return computedFn(function IsBrushed(doc: Doc) {
return brushManager.BrushedDoc.has(doc) || brushManager.BrushedDoc.has(Doc.GetProto(doc));
})(doc);
}
// don't bother memoizing (caching) the result if called from a non-reactive context. (plus this avoids a warning message)
export function IsBrushedDegreeUnmemoized(doc: Doc) {
+ return 0;
if (!doc || GetEffectiveAcl(doc) === AclPrivate || GetEffectiveAcl(Doc.GetProto(doc)) === AclPrivate) return 0;
return brushManager.BrushedDoc.has(doc) ? 2 : brushManager.BrushedDoc.has(Doc.GetProto(doc)) ? 1 : 0;
}
export function IsBrushedDegree(doc: Doc) {
+ return 0;
return computedFn(function IsBrushDegree(doc: Doc) {
return Doc.IsBrushedDegreeUnmemoized(doc);
})(doc);
@@ -977,6 +980,7 @@ export namespace Doc {
let _lastDate = 0;
export function linkFollowHighlight(destDoc: Doc, dataAndDisplayDocs = true) {
+ return;
linkFollowUnhighlight();
Doc.HighlightDoc(destDoc, dataAndDisplayDocs);
document.removeEventListener("pointerdown", linkFollowUnhighlight);
@@ -1128,6 +1132,15 @@ export namespace Doc {
return false;
}
+ export function copyDragFactory(dragFactory: Doc) {
+ const ndoc = dragFactory.isTemplateDoc ? Doc.ApplyTemplate(dragFactory) : Doc.MakeCopy(dragFactory, true);
+ if (ndoc && dragFactory["dragFactory-count"] !== undefined) {
+ dragFactory["dragFactory-count"] = NumCast(dragFactory["dragFactory-count"]) + 1;
+ Doc.SetInPlace(ndoc, "title", ndoc.title + " " + NumCast(dragFactory["dragFactory-count"]).toString(), true);
+ }
+ return ndoc;
+ }
+
export namespace Get {
@@ -1276,14 +1289,7 @@ Scripting.addGlobal(function getProto(doc: any) { return Doc.GetProto(doc); });
Scripting.addGlobal(function getDocTemplate(doc?: any) { return Doc.getDocTemplate(doc); });
Scripting.addGlobal(function getAlias(doc: any) { return Doc.MakeAlias(doc); });
Scripting.addGlobal(function getCopy(doc: any, copyProto: any) { return doc.isTemplateDoc ? Doc.ApplyTemplate(doc) : Doc.MakeCopy(doc, copyProto); });
-Scripting.addGlobal(function copyDragFactory(dragFactory: Doc) {
- const ndoc = dragFactory.isTemplateDoc ? Doc.ApplyTemplate(dragFactory) : Doc.MakeCopy(dragFactory, true);
- if (ndoc && dragFactory["dragFactory-count"] !== undefined) {
- dragFactory["dragFactory-count"] = NumCast(dragFactory["dragFactory-count"]) + 1;
- Doc.SetInPlace(ndoc, "title", ndoc.title + " " + NumCast(dragFactory["dragFactory-count"]).toString(), true);
- }
- return ndoc;
-});
+Scripting.addGlobal(function copyDragFactory(dragFactory: Doc) { return Doc.copyDragFactory(dragFactory); });
Scripting.addGlobal(function copyField(field: any) { return field instanceof ObjectField ? ObjectField.MakeCopy(field) : field; });
Scripting.addGlobal(function docList(field: any) { return DocListCast(field); });
Scripting.addGlobal(function setInPlace(doc: any, field: any, value: any) { return Doc.SetInPlace(doc, field, value, false); });
diff --git a/src/fields/documentSchemas.ts b/src/fields/documentSchemas.ts
index a83fec4ab..76b26a9aa 100644
--- a/src/fields/documentSchemas.ts
+++ b/src/fields/documentSchemas.ts
@@ -101,7 +101,7 @@ export const documentSchema = createSchema({
linkDisplay: "boolean", // whether a link connection should be shown between link anchor endpoints.
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)
+ _isBackground: "boolean", // whether document is a background element and ignores input events (can only select with marquee)
lockedPosition: "boolean", // whether the document can be moved (dragged)
_lockedTransform: "boolean",// whether a freeformview can pan/zoom