aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/DocumentView.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes/DocumentView.tsx')
-rw-r--r--src/client/views/nodes/DocumentView.tsx203
1 files changed, 96 insertions, 107 deletions
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 1e7f1015a..f8ce50c98 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -7,10 +7,10 @@ import { IReactionDisposer, action, computed, makeObservable, observable, reacti
import { observer } from 'mobx-react';
import * as React from 'react';
import { Bounce, Fade, Flip, JackInTheBox, Roll, Rotate, Zoom } from 'react-awesome-reveal';
-import { ClientUtils, DivWidth, isTargetChildOf as isParentOf, lightOrDark, returnEmptyString, returnFalse, returnTrue, returnVal, simulateMouseClick } from '../../../ClientUtils';
+import { ClientUtils, DivWidth, isTargetChildOf as isParentOf, lightOrDark, returnFalse, returnVal, simulateMouseClick } from '../../../ClientUtils';
import { Utils, emptyFunction, emptyPath } from '../../../Utils';
import { Doc, DocListCast, Field, FieldType, Opt, StrListCast } from '../../../fields/Doc';
-import { AclPrivate, Animation, AudioPlay, DocData, DocViews } from '../../../fields/DocSymbols';
+import { AclAdmin, AclEdit, AclPrivate, Animation, AudioPlay, DocData, DocViews } from '../../../fields/DocSymbols';
import { Id } from '../../../fields/FieldSymbols';
import { InkTool } from '../../../fields/InkField';
import { List } from '../../../fields/List';
@@ -20,20 +20,17 @@ import { ScriptField } from '../../../fields/ScriptField';
import { BoolCast, Cast, DocCast, NumCast, ScriptCast, StrCast } from '../../../fields/Types';
import { AudioField } from '../../../fields/URLField';
import { GetEffectiveAcl, TraceMobx } from '../../../fields/util';
+import { AudioAnnoState } from '../../../server/SharedMediaTypes';
import { DocServer } from '../../DocServer';
-import { Networking } from '../../Network';
import { DocUtils, FollowLinkScript } from '../../documents/DocUtils';
import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes';
import { Docs } from '../../documents/Documents';
-import { DictationManager } from '../../util/DictationManager';
-import { DocumentManager } from '../../util/DocumentManager';
import { DragManager } from '../../util/DragManager';
import { dropActionType } from '../../util/DropActionTypes';
import { MakeTemplate, makeUserTemplateButton } from '../../util/DropConverter';
-import { LinkManager, UPDATE_SERVER_CACHE } from '../../util/LinkManager';
+import { UPDATE_SERVER_CACHE } from '../../util/LinkManager';
import { ScriptingGlobals } from '../../util/ScriptingGlobals';
import { SearchUtil } from '../../util/SearchUtil';
-import { SelectionManager } from '../../util/SelectionManager';
import { SharingManager } from '../../util/SharingManager';
import { SnappingManager } from '../../util/SnappingManager';
import { UndoManager, undoBatch, undoable } from '../../util/UndoManager';
@@ -42,16 +39,15 @@ import { ContextMenuProps } from '../ContextMenuItem';
import { DocComponent, ViewBoxInterface } from '../DocComponent';
import { EditableView } from '../EditableView';
import { FieldsDropdown } from '../FieldsDropdown';
-import { GestureOverlay } from '../GestureOverlay';
import { LightboxView } from '../LightboxView';
-import { AudioAnnoState, StyleProp } from '../StyleProvider';
+import { PinProps } from '../PinFuncs';
+import { StyleProp } from '../StyleProp';
import { DocumentContentsView, ObserverJsxParser } from './DocumentContentsView';
import { DocumentLinksButton } from './DocumentLinksButton';
import './DocumentView.scss';
import { FieldViewProps, FieldViewSharedProps } from './FieldView';
import { FocusViewOptions } from './FocusViewOptions';
import { KeyValueBox } from './KeyValueBox';
-import { LinkAnchorBox } from './LinkAnchorBox';
import { OpenWhere } from './OpenWhere';
import { FormattedTextBox } from './formattedText/FormattedTextBox';
import { PresEffect, PresEffectDirection } from './trails';
@@ -90,6 +86,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
// this makes mobx trace() statements more descriptive
public get displayName() { return 'DocumentViewInternal(' + this.Document.title + ')'; } // prettier-ignore
public static SelectAfterContextMenu = true; // whether a document should be selected after it's contextmenu is triggered.
+
/**
* This function is filled in by MainView to allow non-viewBox views to add Docs as tabs without
* needing to know about/reference MainView
@@ -183,11 +180,10 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
// anchors that are not rendered as DocumentViews (marked as 'layout_unrendered' with their 'annotationOn' set to this document). e.g.,
// - PDF text regions are rendered as an Annotations without generating a DocumentView, '
// - RTF selections are rendered via Prosemirror and have a mark which contains the Document ID for the annotation link
- // - and links to PDF/Web docs at a certain scroll location never create an explicit view.
- // For each of these, we create LinkAnchorBox's on the border of the DocumentView.
+ // - and links to PDF/Web docs at a certain scroll location never create an explicit anchor view.
@computed get directLinks() {
TraceMobx();
- return LinkManager.Instance.getAllRelatedLinks(this.Document).filter(
+ return Doc.Links(this.Document).filter(
link =>
(link.link_matchEmbeddings ? link.link_anchor_1 === this.Document : Doc.AreProtosEqual(link.link_anchor_1 as Doc, this.Document)) ||
(link.link_matchEmbeddings ? link.link_anchor_2 === this.Document : Doc.AreProtosEqual(link.link_anchor_2 as Doc, this.Document)) ||
@@ -197,11 +193,11 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
}
@computed get _allLinks(): Doc[] {
TraceMobx();
- return LinkManager.Instance.getAllRelatedLinks(this.Document).filter(link => !link.link_matchEmbeddings || link.link_anchor_1 === this.Document || link.link_anchor_2 === this.Document);
+ return Doc.Links(this.Document).filter(link => !link.link_matchEmbeddings || link.link_anchor_1 === this.Document || link.link_anchor_2 === this.Document);
}
@computed get filteredLinks() {
- return DocUtils.FilterDocs(this.directLinks, this._props.childFilters?.() ?? [], []).filter(d => d.link_displayLine || Doc.UserDoc().showLinkLines);
+ return DocUtils.FilterDocs(this.directLinks, this._props.childFilters?.() ?? [], []);
}
componentWillUnmount() {
@@ -259,7 +255,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
startDragging(x: number, y: number, dropAction: dropActionType, hideSource = false) {
const docView = this._docView;
if (this._mainCont.current && docView) {
- const views = SelectionManager.Views.filter(dv => dv.ContentDiv);
+ const views = DocumentView.Selected().filter(dv => dv.ContentDiv);
const selected = views.length > 1 && views.some(dv => dv.Document === this.Document) ? views : [docView];
const dragData = new DragManager.DocumentDragData(selected.map(dv => dv.Document));
const screenXf = docView.screenToViewTransform();
@@ -289,8 +285,8 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
};
onBrowseClick = (e: React.MouseEvent) => {
const browseTransitionTime = 500;
- SelectionManager.DeselectAll();
- DocumentManager.Instance.showDocument(this.Document, { zoomScale: 0.8, willZoomCentered: true }, (focused: boolean) => {
+ DocumentView.DeselectAll();
+ DocumentView.showDocument(this.Document, { zoomScale: 0.8, willZoomCentered: true }, (focused: boolean) => {
const options: FocusViewOptions = { pointFocus: { X: e.clientX, Y: e.clientY }, zoomTime: browseTransitionTime };
if (!focused && this._docView) {
this._docView
@@ -327,7 +323,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
UndoManager.RunInBatch(() => this.onDoubleClickHandler.script.run(scriptProps, console.log).result?.select && this._props.select(false), 'on double click: ' + this.Document.title);
} else if (!Doc.IsSystem(this.Document) && defaultDblclick !== 'ignore') {
UndoManager.RunInBatch(() => LightboxView.Instance.AddDocTab(this.Document, OpenWhere.lightbox), 'double tap');
- SelectionManager.DeselectAll();
+ DocumentView.DeselectAll();
Doc.UnBrushDoc(this.Document);
} else {
this._singleClickFunc?.();
@@ -377,7 +373,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
if (this._props.isGroupActive?.() === 'child' && !this._props.isDocumentActive?.()) return;
// eslint-disable-next-line no-use-before-define
this._longPressSelector = setTimeout(() => DocumentView.LongPress && this._props.select(false), 1000);
- if (!GestureOverlay.DownDocView) GestureOverlay.DownDocView = this._docView;
+ if (!DocumentView.DownDocView) DocumentView.DownDocView = this._docView;
this._downX = e.clientX;
this._downY = e.clientY;
@@ -463,7 +459,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
}, 'set toggle detail');
drop = undoable((e: Event, de: DragManager.DropEvent) => {
- if (this._props.dontRegisterView || this._props.LayoutTemplateString?.includes(LinkAnchorBox.name)) return false;
+ if (this._props.dontRegisterView) return false;
if (this.Document === Doc.ActiveDashboard) {
e.stopPropagation();
e.preventDefault();
@@ -484,7 +480,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
if (linkDoc) {
de.complete.linkDocument = linkDoc;
linkDoc.layout_isSvg = true;
- DocumentManager.LinkCommonAncestor(linkDoc)?.ComponentView?.addDocument?.(linkDoc);
+ DocumentView.linkCommonAncestor(linkDoc)?.ComponentView?.addDocument?.(linkDoc);
}
}
e.stopPropagation();
@@ -516,7 +512,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
if (e && this.layoutDoc.layout_hideContextMenu && Doc.noviceMode) {
e.preventDefault();
e.stopPropagation();
- // !this._props.isSelected(true) && SelectionManager.SelectView(this.DocumentView(), false);
+ // !this._props.isSelected(true) && DocumentView.SelectView(this.DocumentView(), false);
}
// the touch onContextMenu is button 0, the pointer onContextMenu is button 2
if (e) {
@@ -576,8 +572,8 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
if (this._props.bringToFront) {
const zorders = cm.findByDescription('ZOrder...');
const zorderItems: ContextMenuProps[] = zorders && 'subitems' in zorders ? zorders.subitems : [];
- zorderItems.push({ description: 'Bring to Front', event: () => SelectionManager.Views.forEach(dv => dv._props.bringToFront?.(dv.Document, false)), icon: 'arrow-up' });
- zorderItems.push({ description: 'Send to Back', event: () => SelectionManager.Views.forEach(dv => dv._props.bringToFront?.(dv.Document, true)), icon: 'arrow-down' });
+ zorderItems.push({ description: 'Bring to Front', event: () => DocumentView.Selected().forEach(dv => dv._props.bringToFront?.(dv.Document, false)), icon: 'arrow-up' });
+ zorderItems.push({ description: 'Send to Back', event: () => DocumentView.Selected().forEach(dv => dv._props.bringToFront?.(dv.Document, true)), icon: 'arrow-down' });
zorderItems.push({
description: !this.layoutDoc._keepZDragged ? 'Keep ZIndex when dragged' : 'Allow ZIndex to change when dragged',
event: undoBatch(
@@ -601,7 +597,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
onClicks.push({ description: this.onClickHandler ? 'Remove Click Behavior' : 'Follow Link', event: () => this.toggleFollowLink(false, false), icon: 'link' });
!Doc.noviceMode && onClicks.push({ description: 'Edit onClick Script', event: () => UndoManager.RunInBatch(() => DocUtils.makeCustomViewClicked(this.Document, undefined, 'onClick'), 'edit onClick'), icon: 'terminal' });
!existingOnClick && cm.addItem({ description: 'OnClick...', noexpand: true, subitems: onClicks, icon: 'mouse-pointer' });
- } else if (LinkManager.Links(this.Document).length) {
+ } else if (Doc.Links(this.Document).length) {
onClicks.push({ description: 'Restore On Click default', event: () => this.noOnClick(), icon: 'link' });
onClicks.push({ description: 'Follow Link on Click', event: () => this.followLinkOnClick(), icon: 'link' });
!existingOnClick && cm.addItem({ description: 'OnClick...', subitems: onClicks, icon: 'mouse-pointer' });
@@ -718,7 +714,7 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
case StyleProp.PointerEvents: return 'none';
case StyleProp.Highlighting: return undefined;
case StyleProp.Opacity: {
- const filtered = DocUtils.FilterDocs(this.directLinks, this._props.childFilters?.() ?? [], []).filter(d => d.link_displayLine || Doc.UserDoc().showLinkLines);
+ const filtered = DocUtils.FilterDocs(this.directLinks, this._props.childFilters?.() ?? [], []);
return filtered.some(link => link._link_displayArrow) ? 0 : undefined;
}
default:
@@ -726,34 +722,6 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
return this._props.styleProvider?.(doc, props, property);
};
- // eslint-disable-next-line no-return-assign
- removeLinkByHiding = (link: Doc) => () => link.link_displayLine = false; // prettier-ignore
- @computed get allLinkEndpoints() {
- // the small blue dots that mark the endpoints of links
- if (this._componentView instanceof KeyValueBox || this._props.hideLinkAnchors || this.layoutDoc.layout_hideLinkAnchors || this._props.dontRegisterView || this.layoutDoc.layout_unrendered) return null;
- return this.filteredLinks.map(link => (
- <div className="documentView-anchorCont" key={link[Id]}>
- <DocumentView
- {...this._props}
- isContentActive={returnFalse}
- Document={link}
- containerViewPath={this._props.docViewPath}
- PanelWidth={this.anchorPanelWidth}
- PanelHeight={this.anchorPanelHeight}
- dontRegisterView={false}
- layout_showTitle={returnEmptyString}
- hideCaptions
- hideLinkAnchors
- layout_fitWidth={returnTrue}
- removeDocument={this.removeLinkByHiding(link)}
- styleProvider={this.anchorStyleProvider}
- LayoutTemplate={undefined}
- LayoutTemplateString={LinkAnchorBox.LayoutString(`link_anchor_${LinkManager.anchorIndex(link, this.Document)}`)}
- />
- </div>
- ));
- }
-
@computed get viewBoxContents() {
TraceMobx();
const isInk = this.layoutDoc._layout_isSvg && !this._props.LayoutTemplateString;
@@ -780,7 +748,6 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
setTitleFocus={this.setTitleFocus}
hideClickBehaviors={BoolCast(this.Document.hideClickBehaviors)}
/>
- {this.layoutDoc.layout_hideAllLinks ? null : this.allLinkEndpoints}
</div>
);
}
@@ -1008,50 +975,45 @@ export class DocumentViewInternal extends DocComponent<FieldViewProps & Document
default: return renderDoc;
}
}
- public static recordAudioAnnotation(dataDoc: Doc, field: string, onRecording?: (stop: () => void) => void, onEnd?: () => void) {
- let gumStream: any;
- let recorder: any;
- navigator.mediaDevices.getUserMedia({ audio: true }).then(stream => {
- let audioTextAnnos = Cast(dataDoc[field + '_audioAnnotations_text'], listSpec('string'), null);
- if (audioTextAnnos) audioTextAnnos.push('');
- else audioTextAnnos = dataDoc[field + '_audioAnnotations_text'] = new List<string>(['']);
- DictationManager.Controls.listen({
- interimHandler: value => { audioTextAnnos[audioTextAnnos.length - 1] = value; }, // prettier-ignore
- continuous: { indefinite: false },
- }).then(results => {
- if (results && [DictationManager.Controls.Infringed].includes(results)) {
- DictationManager.Controls.stop();
- }
- onEnd?.();
- });
-
- gumStream = stream;
- recorder = new MediaRecorder(stream);
- recorder.ondataavailable = async (e: any) => {
- const [{ result }] = await Networking.UploadFilesToServer({ file: e.data });
- if (!(result instanceof Error)) {
- const audioField = new AudioField(result.accessPaths.agnostic.client);
- const audioAnnos = Cast(dataDoc[field + '_audioAnnotations'], listSpec(AudioField), null);
- if (audioAnnos) audioAnnos.push(audioField);
- else dataDoc[field + '_audioAnnotations'] = new List([audioField]);
- }
- };
- recorder.start();
- const stopFunc = () => {
- recorder.stop();
- DictationManager.Controls.stop(/* false */);
- dataDoc.audioAnnoState = AudioAnnoState.stopped;
- gumStream.getAudioTracks()[0].stop();
- };
- if (onRecording) onRecording(stopFunc);
- else setTimeout(stopFunc, 5000);
- });
- }
}
@observer
export class DocumentView extends DocComponent<DocumentViewProps>() {
public static ROOT_DIV = 'documentView-effectsWrapper';
+ // LinkFollower
+ public static FollowLink: (linkDoc: Opt<Doc>, sourceDoc: Doc, altKey: boolean) => boolean;
+ // selection funcs
+ public static DeselectAll: (except?: Doc) => void | undefined;
+ public static DeselectView: (dv: DocumentView | undefined) => void | undefined;
+ public static SelectView: (dv: DocumentView | undefined, extendSelection: boolean) => void | undefined;
+ public static Selected: () => DocumentView[];
+ public static SelectedDocs: () => Doc[];
+ public static SelectSchemaDoc: (doc: Doc, deselectAllFirst?: boolean) => void;
+ public static SelectedSchemaDoc: () => Opt<Doc>;
+ // view mgr funcs
+ public static activateTabView: (tabDoc: Doc) => boolean;
+ public static allViews: () => DocumentView[];
+ public static addView: (dv: DocumentView) => void | undefined;
+ public static removeView: (dv: DocumentView) => void | undefined;
+ public static addViewRenderedCb: (doc: Opt<Doc>, func: (dv: DocumentView) => any) => boolean;
+ public static getFirstDocumentView: (toFind: Doc) => DocumentView | undefined;
+ public static getDocumentView: (target: Doc | undefined, preferredCollection?: DocumentView) => Opt<DocumentView>;
+ public static getContextPath: (doc: Opt<Doc>, includeExistingViews?: boolean) => Doc[];
+ public static getLightboxDocumentView: (toFind: Doc) => Opt<DocumentView>;
+ public static showDocumentView: (targetDocView: DocumentView, options: FocusViewOptions) => Promise<void>;
+ public static showDocument: (
+ targetDoc: Doc, // document to display
+ optionsIn: FocusViewOptions, // options for how to navigate to target
+ finished?: (changed: boolean) => void // func called after focusing on target with flag indicating whether anything needed to be done.
+ ) => Promise<void>;
+ public static linkCommonAncestor: (link: Doc) => DocumentView | undefined;
+ // pin func
+ public static PinDoc: (docIn: Doc | Doc[], pinProps: PinProps) => void;
+ // gesture
+ public static DownDocView: DocumentView | undefined; // the first DocView that receives a pointerdown event. used by GestureOverlay to determine the doc a gesture should apply to.
+ // media playing
+ @observable public static CurrentlyPlaying: DocumentView[] = [];
+
public get displayName() { return 'DocumentView(' + (this.Document?.title??"") + ')'; } // prettier-ignore
public ContentRef = React.createRef<HTMLDivElement>();
private _htmlOverlayEffect: Opt<Doc>;
@@ -1138,14 +1100,14 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
componentDidMount() {
runInAction(() => this.Document[DocViews].add(this));
this._disposers.onViewMounted = reaction(() => ScriptCast(this.Document.onViewMounted)?.script?.run({ this: this.Document }).result, emptyFunction);
- !BoolCast(this.Document.dontRegisterView, this._props.dontRegisterView) && DocumentManager.Instance.AddView(this);
+ !BoolCast(this.Document.dontRegisterView, this._props.dontRegisterView) && DocumentView.addView(this);
}
componentWillUnmount() {
this._viewTimer && clearTimeout(this._viewTimer);
runInAction(() => this.Document[DocViews].delete(this));
Object.values(this._disposers).forEach(disposer => disposer?.());
- !BoolCast(this.Document.dontRegisterView, this._props.dontRegisterView) && DocumentManager.Instance.RemoveView(this);
+ !BoolCast(this.Document.dontRegisterView, this._props.dontRegisterView) && DocumentView.removeView(this);
}
public set IsSelected(val) { runInAction(() => { this._selected = val; }); } // prettier-ignore
@@ -1176,10 +1138,6 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
const xf = this.screenToContentsTransform().scale(this.nativeScaling).inverse();
const [[left, top], [right, bottom]] = [xf.transformPoint(0, 0), xf.transformPoint(this.panelWidth, this.panelHeight)];
- if (this._props.LayoutTemplateString?.includes(LinkAnchorBox.name)) {
- const docuBox = this.ContentDiv.getElementsByClassName('linkAnchorBox-cont');
- if (docuBox.length) return { ...docuBox[0].getBoundingClientRect(), transition: undefined };
- }
// transition is returned so that the bounds will 'update' at the end of an animated transition. This is needed by xAnchor in LinkBox
const transition = this.docViewPath().find((parent: DocumentView) => parent.DataTransition?.() || parent.ComponentView?.viewTransition?.());
return { left, top, right, bottom, transition: transition?.DataTransition?.() || transition?.ComponentView?.viewTransition?.() };
@@ -1289,7 +1247,7 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
if (checkResult) {
return Doc.UserDoc().defaultTextLayout;
}
- const view = SelectionManager.Views[0]?._props.renderDepth > 0 ? SelectionManager.Views[0] : undefined;
+ const view = DocumentView.Selected()[0]?._props.renderDepth > 0 ? DocumentView.Selected()[0] : undefined;
undoable(() => {
let tempDoc: Opt<Doc>;
if (view) {
@@ -1359,11 +1317,11 @@ export class DocumentView extends DocComponent<DocumentViewProps>() {
screenToLocalScale = () => this._props.ScreenToLocalTransform().Scale;
isSelected = () => this.IsSelected;
select = (extendSelection: boolean, focusSelection?: boolean) => {
- if (this.IsSelected && SelectionManager.Views.length > 1) SelectionManager.DeselectView(this);
+ if (this.IsSelected && DocumentView.Selected().length > 1) DocumentView.DeselectView(this);
else {
- SelectionManager.SelectView(this, extendSelection);
+ DocumentView.SelectView(this, extendSelection);
if (focusSelection) {
- DocumentManager.Instance.showDocument(this.Document, {
+ DocumentView.showDocument(this.Document, {
willZoomCentered: true,
zoomScale: 0.9,
zoomTime: 500,
@@ -1506,6 +1464,37 @@ export function returnEmptyDocViewList() {
return emptyPath;
}
+// eslint-disable-next-line default-param-last
+export function DocFocusOrOpen(docIn: Doc, optionsIn: FocusViewOptions = { willZoomCentered: true, zoomScale: 0, openLocation: OpenWhere.toggleRight }, containingDoc?: Doc) {
+ let doc = docIn;
+ const options = optionsIn;
+ const func = () => {
+ const cv = DocumentView.getDocumentView(containingDoc);
+ const dv = DocumentView.getDocumentView(doc, cv);
+ if (dv && (!containingDoc || dv.containerViewPath?.().lastElement()?.Document === containingDoc)) {
+ DocumentView.showDocumentView(dv, options).then(() => dv && Doc.linkFollowHighlight(dv.Document));
+ } else {
+ const container = DocCast(containingDoc ?? doc.embedContainer ?? Doc.BestEmbedding(doc));
+ const showDoc = !Doc.IsSystem(container) && !cv ? container : doc;
+ options.toggleTarget = undefined;
+ DocumentView.showDocument(showDoc, options, () => DocumentView.showDocument(doc, { ...options, openLocation: undefined })).then(() => {
+ const cvFound = DocumentView.getDocumentView(containingDoc);
+ const dvFound = DocumentView.getDocumentView(doc, cvFound);
+ dvFound && Doc.linkFollowHighlight(dvFound.Document);
+ });
+ }
+ };
+ if (Doc.IsDataProto(doc) && Doc.GetEmbeddings(doc).some(embed => embed.hidden && [AclAdmin, AclEdit].includes(GetEffectiveAcl(embed)))) {
+ doc = Doc.GetEmbeddings(doc).find(embed => embed.hidden && [AclAdmin, AclEdit].includes(GetEffectiveAcl(embed)))!;
+ }
+ if (doc.hidden) {
+ doc.hidden = false;
+ options.toggleTarget = false;
+ setTimeout(func);
+ } else func();
+}
+ScriptingGlobals.add(DocFocusOrOpen);
+
// eslint-disable-next-line prefer-arrow-callback
ScriptingGlobals.add(function deiconifyView(documentView: DocumentView) {
documentView.iconify();
@@ -1527,9 +1516,9 @@ ScriptingGlobals.add(function updateLinkCollection(linkCollection: Doc, linkSour
const collectedLinks = DocListCast(linkCollection[DocData].data);
let wid = NumCast(linkSource._width);
let embedding: Doc | undefined;
- const links = LinkManager.Links(linkSource);
+ const links = Doc.Links(linkSource);
links.forEach(link => {
- const other = LinkManager.getOppositeAnchor(link, linkSource);
+ const other = Doc.getOppositeAnchor(link, linkSource);
const otherdoc = DocCast(other?.annotationOn ?? other);
if (otherdoc && !collectedLinks?.some(d => Doc.AreProtosEqual(d, otherdoc))) {
embedding = Doc.MakeEmbedding(otherdoc);