diff options
Diffstat (limited to 'src/client/views/nodes/formattedText/FormattedTextBox.tsx')
-rw-r--r-- | src/client/views/nodes/formattedText/FormattedTextBox.tsx | 364 |
1 files changed, 165 insertions, 199 deletions
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index 31c0545d4..ad2fab8b0 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -1,9 +1,8 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Tooltip } from '@material-ui/core'; -import { setCORS } from 'google-translate-api-browser'; +import { Tooltip } from '@mui/material'; import { isEqual } from 'lodash'; -import { action, computed, IReactionDisposer, observable, ObservableSet, reaction, runInAction } from 'mobx'; +import { action, computed, IReactionDisposer, makeObservable, observable, ObservableSet, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import { baseKeymap, selectAll } from 'prosemirror-commands'; import { history } from 'prosemirror-history'; @@ -56,7 +55,7 @@ import { StyleProp } from '../../StyleProvider'; import { media_state } from '../AudioBox'; import { DocFocusOptions, DocumentView, DocumentViewInternal, OpenWhere } from '../DocumentView'; import { FieldView, FieldViewProps } from '../FieldView'; -import { LinkDocPreview } from '../LinkDocPreview'; +import { LinkInfo } from '../LinkDocPreview'; import { PinProps, PresBox } from '../trails'; import { DashDocCommentView } from './DashDocCommentView'; import { DashDocView } from './DashDocView'; @@ -71,10 +70,8 @@ import { RichTextMenu, RichTextMenuPlugin } from './RichTextMenu'; import { RichTextRules } from './RichTextRules'; import { schema } from './schema_rts'; import { SummaryView } from './SummaryView'; -import applyDevTools = require('prosemirror-dev-tools'); -import React = require('react'); -// setting up cors-anywhere server address -const translate = setCORS('http://cors-anywhere.herokuapp.com/'); +// import * as applyDevTools from 'prosemirror-dev-tools'; +import * as React from 'react'; export const GoogleRef = 'googleDocId'; type PullHandler = (exportState: Opt<GoogleApiClientUtils.Docs.ImportResult>, dataDoc: Doc) => void; @@ -132,7 +129,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps } @computed get noSidebar() { - return this.props.docViewPath().lastElement()?.props.hideDecorationTitle || this.props.noSidebar || this.Document._layout_noSidebar; + return this._props.docViewPath().lastElement()?._props.hideDecorationTitle || this._props.noSidebar || this.Document._layout_noSidebar; } @computed get layout_sidebarWidthPercent() { return this._showSidebar ? '20%' : StrCast(this.layoutDoc._layout_sidebarWidthPercent, '0%'); @@ -141,19 +138,19 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps return StrCast(this.layoutDoc.sidebar_color, StrCast(this.layoutDoc[this.fieldKey + '_backgroundColor'], '#e4e4e4')); } @computed get layout_autoHeight() { - return (this.props.forceAutoHeight || this.layoutDoc._layout_autoHeight) && !this.props.ignoreAutoHeight; + return (this._props.forceAutoHeight || this.layoutDoc._layout_autoHeight) && !this._props.ignoreAutoHeight; } @computed get textHeight() { - return NumCast(this.rootDoc[this.fieldKey + '_height']); + return NumCast(this.dataDoc[this.fieldKey + '_height']); } @computed get scrollHeight() { - return NumCast(this.rootDoc[this.fieldKey + '_scrollHeight']); + return NumCast(this.dataDoc[this.fieldKey + '_scrollHeight']); } @computed get sidebarHeight() { - return !this.sidebarWidth() ? 0 : NumCast(this.rootDoc[this.SidebarKey + '_height']); + return !this.sidebarWidth() ? 0 : NumCast(this.dataDoc[this.SidebarKey + '_height']); } @computed get titleHeight() { - return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.HeaderMargin) || 0; + return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.HeaderMargin) || 0; } @computed get layout_autoHeightMargins() { return this.titleHeight + NumCast(this.layoutDoc._layout_autoHeightMargins); @@ -165,8 +162,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps !this.dataDoc[`${this.fieldKey}_recordingSource`] && (this.dataDoc.mediaState = value ? media_state.Recording : undefined); } @computed get config() { - this._keymap = buildKeymap(schema, this.props); - this._rules = new RichTextRules(this.rootDoc, this); + this._keymap = buildKeymap(schema, this._props); + this._rules = new RichTextRules(this.Document, this); return { schema, plugins: [ @@ -190,7 +187,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps private gptRes: string = ''; public static PasteOnLoad: ClipboardEvent | undefined; - public static SelectOnLoad = ''; + private static SelectOnLoad: Doc | undefined; + public static SetSelectOnLoad(doc: Doc) { + FormattedTextBox.SelectOnLoad = doc; + } public static DontSelectInitialText = false; // whether initial text should be selected or not public static SelectOnLoadChar = ''; public static IsFragment(html: string) { @@ -210,6 +210,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps constructor(props: any) { super(props); + makeObservable(this); FormattedTextBox.Instance = this; this._recordingStart = Date.now(); } @@ -310,15 +311,15 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps e.preventDefault(); e.stopPropagation(); const targetCreator = (annotationOn?: Doc) => { - const target = DocUtils.GetNewTextDoc('Note linked to ' + this.rootDoc.title, 0, 0, 100, 100, undefined, annotationOn); - FormattedTextBox.SelectOnLoad = target[Id]; + const target = DocUtils.GetNewTextDoc('Note linked to ' + this.Document.title, 0, 0, 100, 100, undefined, annotationOn); + FormattedTextBox.SetSelectOnLoad(target); return target; }; - DragManager.StartAnchorAnnoDrag([ele], new DragManager.AnchorAnnoDragData(this.props.docViewPath().lastElement(), () => this.getAnchor(true), targetCreator), e.pageX, e.pageY); + DragManager.StartAnchorAnnoDrag([ele], new DragManager.AnchorAnnoDragData(this._props.docViewPath().lastElement(), () => this.getAnchor(true), targetCreator), e.pageX, e.pageY); }); const coordsB = this._editorView!.coordsAtPos(this._editorView!.state.selection.to); - this.props.rootSelected() && AnchorMenu.Instance.jumpTo(coordsB.left, coordsB.bottom); + this._props.rootSelected?.() && AnchorMenu.Instance.jumpTo(coordsB.left, coordsB.bottom); let ele: Opt<HTMLDivElement> = undefined; try { const contents = window.getSelection()?.getRangeAt(0).cloneContents(); @@ -339,7 +340,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps const newText = state.doc.textBetween(0, state.doc.content.size, ' \n'); const newJson = JSON.stringify(state.toJSON()); const prevData = Cast(this.layoutDoc[this.fieldKey], RichTextField, null); // the actual text in the text box - const templateData = this.rootDoc !== this.layoutDoc ? prevData : undefined; // the default text stored in a layout template + const templateData = this.Document !== this.layoutDoc ? prevData : undefined; // the default text stored in a layout template const protoData = Cast(Cast(dataDoc.proto, Doc, null)?.[this.fieldKey], RichTextField, null); // the default text inherited from a prototype const effectiveAcl = GetEffectiveAcl(dataDoc); @@ -361,11 +362,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps textChange && (dataDoc[this.fieldKey + '_modificationDate'] = new DateField(new Date(Date.now()))); if ((!prevData && !protoData) || newText || (!newText && !templateData)) { // if no template, or there's text that didn't come from the layout template, write it to the document. (if this is driven by a template, then this overwrites the template text which is intended) - if ((this._finishingLink || this.props.isContentActive()) && removeSelection(newJson) !== removeSelection(prevData?.Data)) { + if ((this._finishingLink || this._props.isContentActive()) && removeSelection(newJson) !== removeSelection(prevData?.Data)) { const numstring = NumCast(dataDoc[this.fieldKey], null); dataDoc[this.fieldKey] = numstring !== undefined ? Number(newText) : new RichTextField(newJson, newText); dataDoc[this.fieldKey + '_noTemplate'] = true; // mark the data field as being split from the template if it has been edited - textChange && ScriptCast(this.layoutDoc.onTextChanged, null)?.script.run({ this: this.layoutDoc, self: this.rootDoc, text: newText }); + textChange && ScriptCast(this.layoutDoc.onTextChanged, null)?.script.run({ this: this.Document, text: newText }); unchanged = false; } } else { @@ -373,7 +374,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps dataDoc[this.fieldKey] = undefined; this._editorView.updateState(EditorState.fromJSON(this.config, JSON.parse((protoData || prevData).Data))); dataDoc[this.fieldKey + '_noTemplate'] = undefined; // mark the data field as not being split from any template it might have - ScriptCast(this.layoutDoc.onTextChanged, null)?.script.run({ this: this.layoutDoc, self: this.rootDoc, text: newText }); + ScriptCast(this.layoutDoc.onTextChanged, null)?.script.run({ this: this.layoutDoc, text: newText }); unchanged = false; } this._applyingChange = ''; @@ -390,7 +391,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps this._editorView.updateState(EditorState.fromJSON(this.config, json)); } } - if (window.getSelection()?.isCollapsed && this.props.rootSelected()) { + if (window.getSelection()?.isCollapsed && this._props.rootSelected?.()) { AnchorMenu.Instance.fadeOut(true); } } @@ -438,7 +439,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps autoLink = () => { const newAutoLinks = new Set<Doc>(); - const oldAutoLinks = LinkManager.Links(this.props.Document).filter(link => link.link_relationship === LinkManager.AutoKeywords); + const oldAutoLinks = LinkManager.Links(this._props.Document).filter(link => link.link_relationship === LinkManager.AutoKeywords); if (this._editorView?.state.doc.textContent) { const isNodeSel = this._editorView.state.selection instanceof NodeSelection; const f = this._editorView.state.selection.from; @@ -450,17 +451,17 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps tr = tr.setSelection(isNodeSel && false ? new NodeSelection(tr.doc.resolve(f)) : new TextSelection(tr.doc.resolve(f), tr.doc.resolve(t))); this._editorView?.dispatch(tr); } - oldAutoLinks.filter(oldLink => !newAutoLinks.has(oldLink) && oldLink.link_anchor_2 !== this.rootDoc).forEach(LinkManager.Instance.deleteLink); + oldAutoLinks.filter(oldLink => !newAutoLinks.has(oldLink) && oldLink.link_anchor_2 !== this.Document).forEach(LinkManager.Instance.deleteLink); }; updateTitle = () => { const title = StrCast(this.dataDoc.title, Cast(this.dataDoc.title, RichTextField, null)?.Text); if ( - !this.props.dontRegisterView && // (this.props.Document.isTemplateForField === "text" || !this.props.Document.isTemplateForField) && // only update the title if the data document's data field is changing + !this._props.dontRegisterView && // (this._props.Document.isTemplateForField === "text" || !this._props.Document.isTemplateForField) && // only update the title if the data document's data field is changing (title.startsWith('-') || title.startsWith('@')) && this._editorView && !this.dataDoc.title_custom && - (Doc.LayoutFieldKey(this.rootDoc) === this.fieldKey || this.fieldKey === 'text') + (Doc.LayoutFieldKey(this.Document) === this.fieldKey || this.fieldKey === 'text') ) { let node = this._editorView.state.doc; while (node.firstChild && node.firstChild.type.name !== 'text') node = node.firstChild; @@ -471,7 +472,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps if (!(cfield instanceof ComputedField)) { this.dataDoc.title = (prefix + str.substring(0, Math.min(40, str.length)) + (str.length > 40 ? '...' : '')).trim(); if (str.startsWith('@') && str.length > 1) { - Doc.AddToMyPublished(this.rootDoc); + Doc.AddToMyPublished(this.Document); } } } @@ -480,7 +481,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps // creates links between terms in a document and published documents (myPublishedDocs) that have titles starting with an '@' hyperlinkTerm = (tr: any, target: Doc, newAutoLinks: Set<Doc>) => { const editorView = this._editorView; - if (editorView && (editorView as any).docView && !Doc.AreProtosEqual(target, this.rootDoc)) { + if (editorView && (editorView as any).docView && !Doc.AreProtosEqual(target, this.Document)) { const autoLinkTerm = StrCast(target.title).replace(/^@/, ''); var alink: Doc | undefined; this.findInNode(editorView, editorView.state.doc, autoLinkTerm).forEach(sel => { @@ -491,15 +492,15 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps if (node.firstChild === null && !node.marks.find((m: Mark) => m.type.name === schema.marks.noAutoLinkAnchor.name) && node.marks.find((m: Mark) => m.type.name === schema.marks.splitter.name)) { alink = alink ?? - (LinkManager.Links(this.rootDoc).find( + (LinkManager.Links(this.Document).find( link => - Doc.AreProtosEqual(Cast(link.link_anchor_1, Doc, null), this.rootDoc) && // + Doc.AreProtosEqual(Cast(link.link_anchor_1, Doc, null), this.Document) && // Doc.AreProtosEqual(Cast(link.link_anchor_2, Doc, null), target) ) || - DocUtils.MakeLink(this.rootDoc, target, { link_relationship: LinkManager.AutoKeywords })!); + DocUtils.MakeLink(this.Document, target, { link_relationship: LinkManager.AutoKeywords })!); newAutoLinks.add(alink); // DocCast(alink.link_anchor_1).followLinkLocation = 'add:right'; - const allAnchors = [{ href: Doc.localServerPath(target), title: 'a link', anchorId: this.props.Document[Id] }]; + const allAnchors = [{ href: Doc.localServerPath(target), title: 'a link', anchorId: this._props.Document[Id] }]; allAnchors.push(...(node.marks.find((m: Mark) => m.type.name === schema.marks.autoLinkAnchor.name)?.attrs.allAnchors ?? [])); const link = editorView.state.schema.marks.autoLinkAnchor.create({ allAnchors, title: 'auto term' }); tr = tr.addMark(pos, pos + node.nodeSize, link); @@ -568,7 +569,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps }; @undoBatch - @action drop = (e: Event, de: DragManager.DropEvent) => { if (de.complete.annoDragData) { de.complete.annoDragData.dropDocCreator = () => this.getAnchor(true); @@ -584,7 +584,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps // replace text contents when dragging with Alt if (de.altKey) { const fieldKey = Doc.LayoutFieldKey(draggedDoc); - if (draggedDoc[fieldKey] instanceof RichTextField && !Doc.AreProtosEqual(draggedDoc, this.props.Document)) { + if (draggedDoc[fieldKey] instanceof RichTextField && !Doc.AreProtosEqual(draggedDoc, this._props.Document)) { Doc.GetProto(this.dataDoc)[this.fieldKey] = Field.Copy(draggedDoc[fieldKey]); } @@ -602,7 +602,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps } if (added) { draggedDoc._freeform_fitContentsToBox = true; - Doc.SetContainer(draggedDoc, this.rootDoc); + Doc.SetContainer(draggedDoc, this.Document); const view = this._editorView!; try { const pos = view.posAtCoords({ left: de.x, top: de.y })?.pos; @@ -742,9 +742,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps ); }; sidebarMove = (e: PointerEvent, down: number[], delta: number[]) => { - const localDelta = this.props + const localDelta = this._props .ScreenToLocalTransform() - .scale(this.props.NativeDimScaling?.() || 1) + .scale(this._props.NativeDimScaling?.() || 1) .transformDirection(delta[0], delta[1]); const sidebarWidth = (NumCast(this.layoutDoc._width) * Number(this.layout_sidebarWidthPercent.replace('%', ''))) / 100; const width = NumCast(this.layoutDoc._width) + localDelta[0]; @@ -758,15 +758,15 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps deleteAnnotation = (anchor: Doc) => { const batch = UndoManager.StartBatch('delete link'); LinkManager.Instance.deleteLink(LinkManager.Links(anchor)[0]); - // const docAnnotations = DocListCast(this.props.dataDoc[this.fieldKey]); - // this.props.dataDoc[this.fieldKey] = new List<Doc>(docAnnotations.filter(a => a !== this.annoTextRegion)); + // const docAnnotations = DocListCast(this._props.dataDoc[this.fieldKey]); + // this._props.dataDoc[this.fieldKey] = new List<Doc>(docAnnotations.filter(a => a !== this.annoTextRegion)); // AnchorMenu.Instance.fadeOut(true); - this.props.select(false); + this._props.select(false); setTimeout(batch.end); // wait for reaction to remove link from document }; @undoBatch - pinToPres = (anchor: Doc) => this.props.pinToPres(anchor, {}); + pinToPres = (anchor: Doc) => this._props.pinToPres(anchor, {}); @undoBatch makeTargetToggle = (anchor: Doc) => (anchor.followLinkToggle = !anchor.followLinkToggle); @@ -776,7 +776,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps const trail = DocCast(anchor.presentationTrail); if (trail) { Doc.ActivePresentation = trail; - this.props.addDocTab(trail, OpenWhere.replaceRight); + this._props.addDocTab(trail, OpenWhere.replaceRight); } }; @@ -794,7 +794,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps ?.trim() .split(' ') .filter(h => h); - const anchorDoc = Array.from(hrefs).lastElement().replace(Doc.localServerPath(), '').split('?')[0]; + const anchorDoc = Array.from(hrefs ?? []) + .lastElement() + .replace(Doc.localServerPath(), '') + .split('?')[0]; const deleteMarkups = undoBatch(() => { const sel = editor.state.selection; editor.dispatch(editor.state.tr.removeMark(sel.from, sel.to, editor.state.schema.marks.linkAnchor)); @@ -823,7 +826,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps changeItems.push({ description: 'plain', event: undoBatch(() => { - Doc.setNativeView(this.rootDoc); + Doc.setNativeView(this.Document); this.layoutDoc.layout_autoHeightMargins = undefined; }), icon: 'eye', @@ -832,8 +835,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps description: 'metadata', event: undoBatch(() => { this.dataDoc.layout_meta = Cast(Doc.UserDoc().emptyHeader, Doc, null)?.layout; - this.rootDoc.layout_fieldKey = 'layout_meta'; - setTimeout(() => (this.rootDoc._headerHeight = this.rootDoc._layout_autoHeightMargins = 50), 50); + this.Document.layout_fieldKey = 'layout_meta'; + setTimeout(() => (this.layoutDoc._headerHeight = this.layoutDoc._layout_autoHeightMargins = 50), 50); }), icon: 'eye', }); @@ -844,8 +847,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps description: StrCast(note.title), event: undoBatch(() => { this.layoutDoc.layout_autoHeightMargins = undefined; - Doc.setNativeView(this.rootDoc); - DocUtils.makeCustomViewClicked(this.rootDoc, Docs.Create.TreeDocument, StrCast(note.title), note); + Doc.setNativeView(this.Document); + DocUtils.makeCustomViewClicked(this.Document, Docs.Create.TreeDocument, StrCast(note.title), note); }), icon: icon, }); @@ -884,40 +887,23 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps !Doc.noviceMode && appearanceItems.push({ description: 'Broadcast Message', - event: () => DocServer.GetRefField('rtfProto').then(proto => proto instanceof Doc && (proto.BROADCAST_MESSAGE = Cast(this.rootDoc[this.fieldKey], RichTextField)?.Text)), + event: () => DocServer.GetRefField('rtfProto').then(proto => proto instanceof Doc && (proto.BROADCAST_MESSAGE = Cast(this.dataDoc[this.fieldKey], RichTextField)?.Text)), icon: 'expand-arrows-alt', }); appearanceItems.push({ description: 'Change Style...', noexpand: true, subitems: changeItems, icon: 'external-link-alt' }); - // this.rootDoc.isTemplateDoc && appearanceItems.push({ description: "Make Default Layout", event: async () => Doc.UserDoc().defaultTextLayout = new PrefetchProxy(this.rootDoc), icon: "eye" }); !Doc.noviceMode && appearanceItems.push({ description: 'Make Default Layout', event: () => { if (!this.layoutDoc.isTemplateDoc) { - const title = StrCast(this.rootDoc.title); - this.rootDoc.title = 'text'; - MakeTemplate(this.rootDoc, true, title); - } else if (!this.rootDoc.isTemplateDoc) { - const title = StrCast(this.rootDoc.title); - this.rootDoc.title = 'text'; - this.rootDoc.layout = this.layoutDoc.layout as string; - this.rootDoc.title = this.layoutDoc.isTemplateForField as string; - this.rootDoc.isTemplateDoc = false; - this.rootDoc.isTemplateForField = ''; - this.rootDoc.layout_fieldKey = 'layout'; - MakeTemplate(this.rootDoc, true, title); - setTimeout(() => { - this.rootDoc._layout_autoHeight = this.layoutDoc._layout_autoHeight; // layout_autoHeight, width and height - this.rootDoc._width = this.layoutDoc._width || 300; // are stored on the template, since we're getting rid of the old template - this.rootDoc._height = this.layoutDoc._height || 200; // we need to copy them over to the root. This should probably apply to all '_' fields - this.rootDoc._backgroundColor = Cast(this.layoutDoc._backgroundColor, 'string', null); - this.rootDoc.backgroundColor = Cast(this.layoutDoc.backgroundColor, 'string', null); - }, 10); + const title = StrCast(this.Document.title); + this.Document.title = 'text'; + MakeTemplate(this.Document, true, title); } - Doc.UserDoc().defaultTextLayout = new PrefetchProxy(this.rootDoc); - Doc.AddDocToList(Cast(Doc.UserDoc().template_notes, Doc, null), 'data', this.rootDoc); + Doc.UserDoc().defaultTextLayout = new PrefetchProxy(this.Document); + Doc.AddDocToList(Cast(Doc.UserDoc().template_notes, Doc, null), 'data', this.Document); }, icon: 'eye', }); @@ -927,7 +913,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps const optionItems = options && 'subitems' in options ? options.subitems : []; optionItems.push({ description: `Generate Dall-E Image`, event: () => this.generateImage(), icon: 'star' }); optionItems.push({ description: `Ask GPT-3`, event: () => this.askGPT(), icon: 'lightbulb' }); - this.props.renderDepth && + this._props.renderDepth && optionItems.push({ description: !this.Document._createDocOnCR ? 'Create New Doc on Carriage Return' : 'Allow Carriage Returns', event: () => (this.layoutDoc._createDocOnCR = !this.layoutDoc._createDocOnCR), @@ -971,8 +957,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps generateImage = async () => { GPTPopup.Instance?.setTextAnchor(this.getAnchor(false)); - GPTPopup.Instance?.setImgTargetDoc(this.rootDoc); - GPTPopup.Instance.addToCollection = this.props.addDocument; + GPTPopup.Instance?.setImgTargetDoc(this.Document); + GPTPopup.Instance.addToCollection = this._props.addDocument; GPTPopup.Instance.setImgDesc((this.dataDoc.text as RichTextField)?.Text); GPTPopup.Instance.generateImage(); }; @@ -1071,13 +1057,13 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps anchor.presentation_zoomText = true; return anchor; } - return anchorDoc ?? this.rootDoc; + return anchorDoc ?? this.Document; } - return anchorDoc ?? this.rootDoc; + return anchorDoc ?? this.Document; } getView = async (doc: Doc) => { - if (DocListCast(this.rootDoc[this.SidebarKey]).find(anno => Doc.AreProtosEqual(doc.layout_unrendered ? DocCast(doc.annotationOn) : doc, anno))) { + if (DocListCast(this.dataDoc[this.SidebarKey]).find(anno => Doc.AreProtosEqual(doc.layout_unrendered ? DocCast(doc.annotationOn) : doc, anno))) { !this.SidebarShown && this.toggleSidebar(false); setTimeout(() => this._sidebarRef?.current?.makeDocUnfiltered(doc)); } @@ -1141,7 +1127,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps setTimeout(() => clearStyleSheetRules(FormattedTextBox._highlightStyleSheet), Math.max(this._focusSpeed || 0, 3000)); return focusSpeed; } else { - return this.props.focus(this.rootDoc, options); + return this._props.focus(this.Document, options); } } }; @@ -1150,15 +1136,15 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps // Since we also monitor all component height changes, this will update the document's height. resetNativeHeight = (scrollHeight: number) => { const nh = this.layoutDoc.isTemplateForField ? 0 : NumCast(this.layoutDoc._nativeHeight); - this.rootDoc[this.fieldKey + '_height'] = scrollHeight; + this.dataDoc[this.fieldKey + '_height'] = scrollHeight; if (nh) this.layoutDoc._nativeHeight = scrollHeight; }; @computed get contentScaling() { - return Doc.NativeAspect(this.rootDoc, this.dataDoc, false) ? this.props.NativeDimScaling?.() || 1 : 1; + return Doc.NativeAspect(this.Document, this.dataDoc, false) ? this._props.NativeDimScaling?.() || 1 : 1; } componentDidMount() { - !this.props.dontSelectOnLoad && this.props.setContentView?.(this); // this tells the DocumentView that this AudioBox is the "content" of the document. this allows the DocumentView to indirectly call getAnchor() on the AudioBox when making a link. + !this._props.dontSelectOnLoad && this._props.setContentView?.(this); // this tells the DocumentView that this AudioBox is the "content" of the document. this allows the DocumentView to indirectly call getAnchor() on the AudioBox when making a link. this._cachedLinks = LinkManager.Links(this.Document); this._disposers.breakupDictation = reaction(() => Doc.RecordingEvent, this.breakupDictation); this._disposers.layout_autoHeight = reaction( @@ -1171,7 +1157,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps { fireImmediately: true } ); this._disposers.width = reaction( - () => this.props.PanelWidth(), + () => this._props.PanelWidth(), width => this.tryUpdateScrollHeight() ); this._disposers.scrollHeight = reaction( @@ -1185,13 +1171,13 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps ({ sidebarHeight, textHeight, layout_autoHeight, marginsHeight }) => { const newHeight = this.contentScaling * (marginsHeight + Math.max(sidebarHeight, textHeight)); if ( - (!Array.from(FormattedTextBox._globalHighlights).includes('Bold Text') || this.props.isSelected()) && // + (!Array.from(FormattedTextBox._globalHighlights).includes('Bold Text') || this._props.isSelected()) && // layout_autoHeight && newHeight && - newHeight !== this.rootDoc.height && - !this.props.dontRegisterView + newHeight !== this.layoutDoc.height && + !this._props.dontRegisterView ) { - this.props.setHeight?.(newHeight); + this._props.setHeight?.(newHeight); } }, { fireImmediately: !Array.from(FormattedTextBox._globalHighlights).includes('Bold Text') } @@ -1233,7 +1219,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps } ); this._disposers.pullDoc = reaction( - () => this.props.Document[Pulls], + () => this._props.Document[Pulls], () => { if (!DocumentButtonBar.hasPulledHack) { DocumentButtonBar.hasPulledHack = true; @@ -1242,7 +1228,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps } ); this._disposers.pushDoc = reaction( - () => this.props.Document[Pushes], + () => this._props.Document[Pushes], () => { if (!DocumentButtonBar.hasPushedHack) { DocumentButtonBar.hasPushedHack = true; @@ -1252,13 +1238,13 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps ); this._disposers.search = reaction( - () => Doc.IsSearchMatch(this.rootDoc), + () => Doc.IsSearchMatch(this.Document), search => (search ? this.highlightSearchTerms([Doc.SearchQuery()], search.searchMatch < 0) : this.unhighlightSearchTerms()), - { fireImmediately: Doc.IsSearchMatchUnmemoized(this.rootDoc) ? true : false } + { fireImmediately: Doc.IsSearchMatchUnmemoized(this.Document) ? true : false } ); this._disposers.selected = reaction( - () => this.props.rootSelected(), + () => this._props.rootSelected?.(), action(selected => { //selected && setTimeout(() => this.prepareForTyping()); if (FormattedTextBox._globalHighlights.has('Bold Text')) { @@ -1268,14 +1254,14 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps RichTextMenu.Instance?.updateMenu(undefined, undefined, undefined, undefined); } if (this._editorView && selected) { - RichTextMenu.Instance?.updateMenu(this._editorView, undefined, this.props, this.layoutDoc); + RichTextMenu.Instance?.updateMenu(this._editorView, undefined, this._props, this.layoutDoc); setTimeout(this.autoLink, 20); } }), { fireImmediately: true } ); - if (!this.props.dontRegisterView) { + if (!this._props.dontRegisterView) { this._disposers.record = reaction( () => this._recordingDictation, () => { @@ -1290,7 +1276,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps this._disposers.scroll = reaction( () => NumCast(this.layoutDoc._layout_scrollTop), pos => { - if (!this._ignoreScroll && this._scrollRef.current && !this.props.dontSelectOnLoad) { + if (!this._ignoreScroll && this._scrollRef.current && !this._props.dontSelectOnLoad) { const viewTrans = quickScroll ?? StrCast(this.Document._viewTransition); const durationMiliStr = viewTrans.match(/([0-9]*)ms/); const durationSecStr = viewTrans.match(/([0-9.]*)s/); @@ -1322,7 +1308,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps if (this._editorView && reference) { const content = await RichTextUtils.GoogleDocs.Export(this._editorView.state); const response = await GoogleApiClientUtils.Docs.write({ reference, content, mode }); - response && (this.dataDoc[GoogleRef] = response.documentId); + response?.documentId && (this.dataDoc[GoogleRef] = response.documentId); const pushSuccess = response !== undefined && !('errors' in response); dataDoc.googleDocUnchanged = pushSuccess; DocumentButtonBar.Instance.startPushOutcome(pushSuccess); @@ -1420,7 +1406,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps const dashField = view.state.schema.nodes.paragraph.create({}, [ view.state.schema.nodes.dashField.create({ fieldKey: 'text', docId: pdfAnchor[Id], hideKey: true, editable: false }, undefined, [ view.state.schema.marks.linkAnchor.create({ - allAnchors: [{ href: `/doc/${this.rootDoc[Id]}`, title: this.rootDoc.title, anchorId: `${this.rootDoc[Id]}` }], + allAnchors: [{ href: `/doc/${this.Document[Id]}`, title: this.Document.title, anchorId: `${this.Document[Id]}` }], title: `from: ${DocCast(pdfAnchor.embedContainer).title}`, noPreview: true, docref: false, @@ -1430,7 +1416,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps ]), ]); - const link = DocUtils.MakeLink(pdfAnchor, this.rootDoc, { link_relationship: 'PDF pasted' }); + const link = DocUtils.MakeLink(pdfAnchor, this.Document, { link_relationship: 'PDF pasted' }); if (link) { view.dispatch(view.state.tr.replaceSelectionWith(dashField, false).scrollIntoView().setMeta('paste', true).setMeta('uiEvent', 'paste')); } @@ -1453,8 +1439,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps const self = this; return new Plugin({ view(newView) { - runInAction(() => self.props.rootSelected() && RichTextMenu.Instance && (RichTextMenu.Instance.view = newView)); - return new RichTextMenuPlugin({ editorProps: this.props }); + runInAction(() => self._props.rootSelected?.() && RichTextMenu.Instance && (RichTextMenu.Instance.view = newView)); + return new RichTextMenuPlugin({ editorProps: this._props }); }, }); } @@ -1476,7 +1462,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps const botOff = docPos.bottom > viewRect.bottom ? docPos.bottom - viewRect.bottom : undefined; if (((topOff && Math.abs(Math.trunc(topOff)) > 0) || (botOff && Math.abs(Math.trunc(botOff)) > 0)) && scrollRef) { const shift = Math.min(topOff ?? Number.MAX_VALUE, botOff ?? Number.MAX_VALUE); - const scrollPos = scrollRef.scrollTop + shift * self.props.ScreenToLocalTransform().Scale; + const scrollPos = scrollRef.scrollTop + shift * self._props.ScreenToLocalTransform().Scale; if (this._focusSpeed !== undefined) { scrollPos && (this._scrollStopper = smoothScroll(this._focusSpeed, scrollRef, scrollPos, 'ease', this._scrollStopper)); } else { @@ -1528,11 +1514,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps (this._editorView as any).TextView = this; } - const selectOnLoad = this.rootDoc[Id] === FormattedTextBox.SelectOnLoad && (!LightboxView.LightboxDoc || LightboxView.IsLightboxDocView(this.props.docViewPath())); - if (this._editorView && selectOnLoad && !this.props.dontRegisterView && !this.props.dontSelectOnLoad && this.isActiveTab(this.ProseRef)) { + const selectOnLoad = Doc.AreProtosEqual(this._props.TemplateDataDocument ?? this.Document, FormattedTextBox.SelectOnLoad) && (!LightboxView.LightboxDoc || LightboxView.IsLightboxDocView(this._props.docViewPath())); + if (this._editorView && selectOnLoad && !this._props.dontRegisterView && !this._props.dontSelectOnLoad && this.isActiveTab(this.ProseRef)) { const selLoadChar = FormattedTextBox.SelectOnLoadChar; - FormattedTextBox.SelectOnLoad = ''; - this.props.select(false); + FormattedTextBox.SelectOnLoad = undefined; + this._props.select(false); if (selLoadChar) { const $from = this._editorView.state.selection.anchor ? this._editorView.state.doc.resolve(this._editorView.state.selection.anchor - 1) : undefined; const mark = schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(Date.now() / 1000) }); @@ -1548,7 +1534,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps } } selectOnLoad && this._editorView!.focus(); - if (this.props.isContentActive()) this.prepareForTyping(); + if (this._props.isContentActive()) this.prepareForTyping(); if (this._editorView) { const tr = this._editorView.state.tr; const { from, to } = tr.selection; @@ -1571,15 +1557,14 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps ...(Doc.UserDoc().fontColor !== 'transparent' && Doc.UserDoc().fontColor ? [schema.mark(schema.marks.pFontColor, { color: StrCast(Doc.UserDoc().fontColor) })] : []), ...(Doc.UserDoc().fontStyle === 'italics' ? [schema.mark(schema.marks.em)] : []), ...(Doc.UserDoc().textDecoration === 'underline' ? [schema.mark(schema.marks.underline)] : []), - ...(Doc.UserDoc().fontFamily ? [schema.mark(schema.marks.pFontFamily, { family: this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.FontFamily) })] : []), - ...(Doc.UserDoc().fontSize ? [schema.mark(schema.marks.pFontSize, { fontSize: this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.FontSize) })] : []), + ...(Doc.UserDoc().fontFamily ? [schema.mark(schema.marks.pFontFamily, { family: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FontFamily) })] : []), + ...(Doc.UserDoc().fontSize ? [schema.mark(schema.marks.pFontSize, { fontSize: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FontSize) })] : []), ...(Doc.UserDoc().fontWeight === 'bold' ? [schema.mark(schema.marks.strong)] : []), ...[schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(Date.now() / 1000) })], ]; this._editorView?.dispatch(this._editorView?.state.tr.setStoredMarks(docDefaultMarks)); }; - @action componentWillUnmount() { if (this._recordingDictation) { this._recordingDictation = !this._recordingDictation; @@ -1612,7 +1597,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps const func = () => { const docView = DocumentManager.Instance.getDocumentView(audiodoc); if (!docView) { - this.props.addDocTab(audiodoc, OpenWhere.addBottom); + this._props.addDocTab(audiodoc, OpenWhere.addBottom); setTimeout(func); } else docView.ComponentView?.playFrom?.(timecode, Cast(anchor.timecodeToHide, 'number', null)); // bcz: would be nice to find the next audio tag in the doc and play until that }; @@ -1628,7 +1613,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps this._downTime = Date.now(); this._hadDownFocus = this.ProseRef?.children[0].className.includes('focused') ?? false; FormattedTextBoxComment.textBox = this; - if (e.button === 0 && (this.props.rootSelected() || this.props.rootSelected()) && !e.altKey && !e.ctrlKey && !e.metaKey) { + if (e.button === 0 && this._props.rootSelected?.() && !e.altKey && !e.ctrlKey && !e.metaKey) { if (e.clientX < this.ProseRef!.getBoundingClientRect().right) { // stop propagation if not in sidebar, otherwise nested boxes will lose focus to outer boxes. e.stopPropagation(); // if the text box's content is active, then it consumes all down events @@ -1650,7 +1635,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps } if (!state || !editor || !this.ProseRef?.children[0].className.includes('-focused')) return; if (!state.selection.empty && !(state.selection instanceof NodeSelection)) this.setupAnchorMenu(); - else if (this.props.isContentActive(true)) { + else if (this._props.isContentActive(true)) { const pcords = editor.posAtCoords({ left: e.clientX, top: e.clientY }); let xpos = pcords?.pos || 0; while (xpos > 0 && !state.doc.resolve(xpos).node()?.isTextblock) { @@ -1665,7 +1650,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps @action onDoubleClick = (e: React.MouseEvent): void => { FormattedTextBoxComment.textBox = this; - if (e.button === 0 && this.props.rootSelected() && !e.altKey && !e.ctrlKey && !e.metaKey) { + if (e.button === 0 && this._props.rootSelected?.() && !e.altKey && !e.ctrlKey && !e.metaKey) { if (e.clientX < this.ProseRef!.getBoundingClientRect().right) { // stop propagation if not in sidebar e.stopPropagation(); // if the text box is selected, then it consumes all click events @@ -1676,7 +1661,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps } FormattedTextBoxComment.Hide(); - if (e.buttons === 1 && this.props.rootSelected() && !e.altKey) { + if (e.buttons === 1 && this._props.rootSelected?.() && !e.altKey) { e.stopPropagation(); } }; @@ -1687,14 +1672,13 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps }; @action onFocused = (e: React.FocusEvent): void => { - console.log('FOCUSED = ' + this.layoutDoc.title + ' ' + this.props.rootSelected()); //applyDevTools.applyDevTools(this._editorView); - this.ProseRef?.children[0] === e.nativeEvent.target && this._editorView && RichTextMenu.Instance?.updateMenu(this._editorView, undefined, this.props, this.layoutDoc); + this.ProseRef?.children[0] === e.nativeEvent.target && this._editorView && RichTextMenu.Instance?.updateMenu(this._editorView, undefined, this._props, this.layoutDoc); e.stopPropagation(); }; onClick = (e: React.MouseEvent): void => { - if (!this.props.isContentActive()) return; + if (!this._props.isContentActive()) return; if ((e.nativeEvent as any).handledByInnerReactInstance) { e.stopPropagation(); return; @@ -1723,7 +1707,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps this._editorView!.dispatch(this._editorView!.state.tr.setSelection(NodeSelection.create(this._editorView!.state.doc, pcords.pos))); } } - if (this.props.rootSelected()) { + if (this._props.rootSelected?.()) { // if text box is selected, then it consumes all click events (e.nativeEvent as any).handledByInnerReactInstance = true; this.hitBulletTargets(e.clientX, e.clientY, !this._editorView?.state.selection.empty || this._forceUncollapse, false, this._forceDownNode, e.shiftKey); @@ -1737,7 +1721,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps clearStyleSheetRules(FormattedTextBox._bulletStyleSheet); const clickPos = this._editorView!.posAtCoords({ left: x, top: y }); let olistPos = clickPos?.pos; - if (clickPos && olistPos && this.props.rootSelected()) { + if (clickPos && olistPos && this._props.rootSelected?.()) { const clickNode = this._editorView?.state.doc.nodeAt(olistPos); const nodeBef = this._editorView?.state.doc.nodeAt(Math.max(0, olistPos - 1)); olistPos = nodeBef?.type === this._editorView?.state.schema.nodes.ordered_list ? olistPos - 1 : olistPos; @@ -1765,7 +1749,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps } } startUndoTypingBatch() { - !this._undoTyping && (this._undoTyping = UndoManager.StartBatch('text edits on ' + this.rootDoc.title)); + !this._undoTyping && (this._undoTyping = UndoManager.StartBatch('text edits on ' + this.Document.title)); } public endUndoTypingBatch() { this._undoTyping?.end(); @@ -1774,7 +1758,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps @action onBlur = (e: any) => { - console.log('BLUREd = ' + this.layoutDoc.title + ' ' + this.props.rootSelected()); if (this.ProseRef?.children[0] !== e.nativeEvent.target) return; if (!(this.EditorView?.state.selection instanceof NodeSelection) || this.EditorView.state.selection.node.type !== this.EditorView.state.schema.nodes.footnote) { const stordMarks = this._editorView?.state.storedMarks?.slice(); @@ -1787,7 +1770,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps tr && this._editorView.dispatch(tr); } } - if (RichTextMenu.Instance?.view === this._editorView && !this.props.rootSelected()) { + if (RichTextMenu.Instance?.view === this._editorView && !this._props.rootSelected?.()) { RichTextMenu.Instance?.updateMenu(undefined, undefined, undefined, undefined); } FormattedTextBox._hadSelection = window.getSelection()?.toString() !== ''; @@ -1798,29 +1781,12 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps const state = this._editorView!.state; const curText = state.doc.textBetween(0, state.doc.content.size, ' \n'); - if (this.layoutDoc[this.SidebarKey + '_type_collection'] === 'translation' && !this.fieldKey.includes('translation') && curText.endsWith(' ') && curText !== this._lastText) { - try { - translate(curText, { from: 'en', to: 'es' }).then((result1: any) => { - setTimeout( - () => - translate(result1.text, { from: 'es', to: 'en' }).then((result: any) => { - const tb = this._sidebarTagRef.current as FormattedTextBox; - tb._editorView?.dispatch(tb._editorView!.state.tr.insertText(result1.text + '\r\n\r\n' + result.text)); - }), - 1000 - ); - }); - } catch (e: any) { - console.log(e.message); - } - this._lastText = curText; - } - if (StrCast(this.rootDoc.title).startsWith('@') && !this.dataDoc.title_custom) { + if (StrCast(this.Document.title).startsWith('@') && !this.dataDoc.title_custom) { UndoManager.RunInBatch(() => { this.dataDoc.title_custom = true; this.dataDoc.layout_showTitle = 'title'; const tr = this._editorView!.state.tr; - this._editorView?.dispatch(tr.setSelection(new TextSelection(tr.doc.resolve(0), tr.doc.resolve(StrCast(this.rootDoc.title).length + 2))).deleteSelection()); + this._editorView?.dispatch(tr.setSelection(new TextSelection(tr.doc.resolve(0), tr.doc.resolve(StrCast(this.Document.title).length + 2))).deleteSelection()); }, 'titler'); } }; @@ -1829,7 +1795,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps if ((e.altKey || e.ctrlKey) && e.key === 't') { e.preventDefault(); e.stopPropagation(); - this.props.setTitleFocus?.(); + this._props.setTitleFocus?.(); return; } const state = this._editorView!.state; @@ -1846,7 +1812,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps let stopPropagation = true; for (var i = state.selection.from; i <= state.selection.to; i++) { const node = state.doc.resolve(i); - if (state.doc.content.size - 1 > i && node?.marks?.().some(mark => mark.type === schema.marks.user_mark && mark.attrs.userid !== Doc.CurrentUserEmail) && [AclAugment, AclSelfEdit].includes(GetEffectiveAcl(this.rootDoc))) { + if (state.doc.content.size - 1 > i && node?.marks?.().some(mark => mark.type === schema.marks.user_mark && mark.attrs.userid !== Doc.CurrentUserEmail) && [AclAugment, AclSelfEdit].includes(GetEffectiveAcl(this.Document))) { e.preventDefault(); } } @@ -1869,7 +1835,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps if (this._lastTimedMark?.attrs.userid === Doc.CurrentUserEmail) break; case ' ': if (e.code !== 'Space') { - [AclEdit, AclAugment, AclAdmin].includes(GetEffectiveAcl(this.rootDoc)) && + [AclEdit, AclAugment, AclAdmin].includes(GetEffectiveAcl(this.Document)) && this._editorView!.dispatch(this._editorView!.state.tr.removeStoredMark(schema.marks.user_mark).addStoredMark(schema.marks.user_mark.create({ userid: Doc.CurrentUserEmail, modified: Math.floor(Date.now() / 1000) }))); } break; @@ -1882,8 +1848,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps e.stopPropagation(); // drag n drop of text within text note will generate a new note if not caughst, as will dragging in from outside of Dash. }; onScroll = (e: React.UIEvent) => { - if (!LinkDocPreview.LinkInfo && this._scrollRef.current) { - if (!this.props.dontSelectOnLoad) { + if (!LinkInfo.Instance?.LinkInfo && this._scrollRef.current) { + if (!this._props.dontSelectOnLoad) { this._ignoreScroll = true; this.layoutDoc._layout_scrollTop = this._scrollRef.current.scrollTop; this._ignoreScroll = false; @@ -1893,9 +1859,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps } }; tryUpdateScrollHeight = () => { - const margins = 2 * NumCast(this.layoutDoc._yMargin, this.props.yPadding || 0); + const margins = 2 * NumCast(this.layoutDoc._yMargin, this._props.yPadding || 0); const children = this.ProseRef?.children.length ? Array.from(this.ProseRef.children[0].children) : undefined; - if (children && !SnappingManager.GetIsDragging()) { + if (children && !SnappingManager.IsDragging) { const toNum = (val: string) => Number(val.replace('px', '').replace('auto', '0')); const toHgt = (node: Element) => { const { height, marginTop, marginBottom } = getComputedStyle(node); @@ -1903,11 +1869,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps }; const proseHeight = !this.ProseRef ? 0 : children.reduce((p, child) => p + toHgt(child), margins); const scrollHeight = this.ProseRef && Math.min(NumCast(this.layoutDoc.layout_maxAutoHeight, proseHeight), proseHeight); - if (this.props.setHeight && scrollHeight && !this.props.dontRegisterView) { + if (this._props.setHeight && scrollHeight && !this._props.dontRegisterView) { // if top === 0, then the text box is growing upward (as the overlay caption) which doesn't contribute to the height computation - const setScrollHeight = () => (this.rootDoc[this.fieldKey + '_scrollHeight'] = scrollHeight); + const setScrollHeight = () => (this.dataDoc[this.fieldKey + '_scrollHeight'] = scrollHeight); - if (this.rootDoc === this.layoutDoc || this.layoutDoc.resolvedDataDoc) { + if (this.Document === this.layoutDoc || this.layoutDoc.resolvedDataDoc) { setScrollHeight(); } else { setTimeout(setScrollHeight, 10); // if we have a template that hasn't been resolved yet, we can't set the height or we'd be setting it on the unresolved template. So set a timeout and hope its arrived... @@ -1915,21 +1881,21 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps } } }; - fitContentsToBox = () => BoolCast(this.props.Document._freeform_fitContentsToBox); - sidebarContentScaling = () => (this.props.NativeDimScaling?.() || 1) * NumCast(this.layoutDoc._freeform_scale, 1); + fitContentsToBox = () => BoolCast(this._props.Document._freeform_fitContentsToBox); + sidebarContentScaling = () => (this._props.NativeDimScaling?.() || 1) * NumCast(this.layoutDoc._freeform_scale, 1); sidebarAddDocument = (doc: Doc | Doc[], sidebarKey: string = this.SidebarKey) => { if (!this.layoutDoc._layout_showSidebar) this.toggleSidebar(); return this.addDocument(doc, sidebarKey); }; sidebarMoveDocument = (doc: Doc | Doc[], targetCollection: Doc | undefined, addDocument: (doc: Doc | Doc[]) => boolean) => this.moveDocument(doc, targetCollection, addDocument, this.SidebarKey); sidebarRemDocument = (doc: Doc | Doc[]) => this.removeDocument(doc, this.SidebarKey); - setSidebarHeight = (height: number) => (this.rootDoc[this.SidebarKey + '_height'] = height); - sidebarWidth = () => (Number(this.layout_sidebarWidthPercent.substring(0, this.layout_sidebarWidthPercent.length - 1)) / 100) * this.props.PanelWidth(); + setSidebarHeight = (height: number) => (this.dataDoc[this.SidebarKey + '_height'] = height); + sidebarWidth = () => (Number(this.layout_sidebarWidthPercent.substring(0, this.layout_sidebarWidthPercent.length - 1)) / 100) * this._props.PanelWidth(); sidebarScreenToLocal = () => - this.props + this._props .ScreenToLocalTransform() - .translate(-(this.props.PanelWidth() - this.sidebarWidth()) / (this.props.NativeDimScaling?.() || 1), 0) - .scale(1 / NumCast(this.layoutDoc._freeform_scale, 1) / (this.props.NativeDimScaling?.() || 1)); + .translate(-(this._props.PanelWidth() - this.sidebarWidth()) / (this._props.NativeDimScaling?.() || 1), 0) + .scale(1 / NumCast(this.layoutDoc._freeform_scale, 1) / (this._props.NativeDimScaling?.() || 1)); @computed get audioHandle() { return !this._recordingDictation ? null : ( @@ -1952,9 +1918,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps TraceMobx(); const annotated = DocListCast(this.dataDoc[this.SidebarKey]).filter(d => d?.author).length; const color = !annotated ? Colors.WHITE : Colors.BLACK; - const backgroundColor = !annotated ? (this.sidebarWidth() ? Colors.MEDIUM_BLUE : Colors.BLACK) : this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.WidgetColor + (annotated ? ':annotated' : '')); + const backgroundColor = !annotated ? (this.sidebarWidth() ? Colors.MEDIUM_BLUE : Colors.BLACK) : this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.WidgetColor + (annotated ? ':annotated' : '')); - return !annotated && (!this.props.isContentActive() || SnappingManager.GetIsDragging() || Doc.ActiveTool !== InkTool.None) ? null : ( + return !annotated && (!this._props.isContentActive() || SnappingManager.IsDragging || Doc.ActiveTool !== InkTool.None) ? null : ( <div className="formattedTextBox-sidebar-handle" onPointerDown={this.sidebarDown} @@ -1969,12 +1935,12 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps } @computed get sidebarCollection() { const renderComponent = (tag: string) => { - const ComponentTag = tag === CollectionViewType.Freeform ? CollectionFreeFormView : tag === CollectionViewType.Tree ? CollectionTreeView : tag === 'translation' ? FormattedTextBox : CollectionStackingView; + const ComponentTag: any = tag === CollectionViewType.Freeform ? CollectionFreeFormView : tag === CollectionViewType.Tree ? CollectionTreeView : tag === 'translation' ? FormattedTextBox : CollectionStackingView; return ComponentTag === CollectionStackingView ? ( <SidebarAnnos ref={this._sidebarRef} - {...this.props} - rootDoc={this.rootDoc} + {...this._props} + Document={this.Document} layoutDoc={this.layoutDoc} dataDoc={this.dataDoc} usePanelWidth={true} @@ -1990,14 +1956,14 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps setHeight={this.setSidebarHeight} /> ) : ( - <div onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => SelectionManager.SelectView(this.props.DocumentView?.()!, false), true)}> + <div onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => SelectionManager.SelectView(this._props.DocumentView?.()!, false), true)}> <ComponentTag - {...this.props} + {...this._props} ref={this._sidebarTagRef as any} setContentView={emptyFunction} NativeWidth={returnZero} NativeHeight={returnZero} - PanelHeight={this.props.PanelHeight} + PanelHeight={this._props.PanelHeight} PanelWidth={this.sidebarWidth} xPadding={0} yPadding={0} @@ -2011,7 +1977,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps moveDocument={this.sidebarMoveDocument} addDocument={this.sidebarAddDocument} ScreenToLocalTransform={this.sidebarScreenToLocal} - renderDepth={this.props.renderDepth + 1} + renderDepth={this._props.renderDepth + 1} setHeight={this.setSidebarHeight} fitContentsToBox={this.fitContentsToBox} noSidebar={true} @@ -2029,12 +1995,12 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps } cycleAlternateText = () => { if (this.layoutDoc._layout_enableAltContentUI) { - const usePath = this.rootDoc[`_${this.props.fieldKey}_usePath`]; - this.rootDoc[`_${this.props.fieldKey}_usePath`] = usePath === undefined ? 'alternate' : usePath === 'alternate' ? 'alternate:hover' : undefined; + const usePath = this.layoutDoc[`_${this._props.fieldKey}_usePath`]; + this.layoutDoc[`_${this._props.fieldKey}_usePath`] = usePath === undefined ? 'alternate' : usePath === 'alternate' ? 'alternate:hover' : undefined; } }; @computed get overlayAlternateIcon() { - const usePath = this.rootDoc[`_${this.props.fieldKey}_usePath`]; + const usePath = this.layoutDoc[`_${this._props.fieldKey}_usePath`]; return ( <Tooltip title={ @@ -2056,7 +2022,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps className="formattedTextBox-alternateButton" onPointerDown={e => setupMoveUpEvents(e.target, e, returnFalse, emptyFunction, e => this.cycleAlternateText())} style={{ - display: this.props.isContentActive() && !SnappingManager.GetIsDragging() ? 'flex' : 'none', + display: this._props.isContentActive() && !SnappingManager.IsDragging ? 'flex' : 'none', background: usePath === undefined ? 'white' : usePath === 'alternate' ? 'black' : 'gray', color: usePath === undefined ? 'black' : 'white', }}> @@ -2065,14 +2031,14 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps </Tooltip> ); } - @computed get fieldKey() { - const usePath = StrCast(this.rootDoc[`${this.props.fieldKey}_usePath`]); - return this.props.fieldKey + (usePath && (!usePath.includes(':hover') || this._isHovering || this.props.isContentActive()) ? `_${usePath.replace(':hover', '')}` : ''); + get fieldKey() { + const usePath = StrCast(this.layoutDoc[`${this._props.fieldKey}_usePath`]); + return this._props.fieldKey + (usePath && (!usePath.includes(':hover') || this._isHovering || this._props.isContentActive()) ? `_${usePath.replace(':hover', '')}` : ''); } @observable _isHovering = false; onPassiveWheel = (e: WheelEvent) => { if (e.clientX > this.ProseRef!.getBoundingClientRect().right) { - if (this.rootDoc[this.SidebarKey + '_type_collection'] === CollectionViewType.Freeform) { + if (this.dataDoc[this.SidebarKey + '_type_collection'] === CollectionViewType.Freeform) { // if the scrolled freeform is a child of the sidebar component, we need to let the event go through // so react can let the freeform view handle it. We prevent default to stop any containing views from scrolling e.preventDefault(); @@ -2081,14 +2047,14 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps } // if scrollTop is 0, then don't let wheel trigger scroll on any container (which it would since onScroll won't be triggered on this) - if (this.props.isContentActive()) { - const scale = this.props.NativeDimScaling?.() || 1; - const styleFromLayoutString = Doc.styleFromLayoutString(this.Document, this.props, scale); // this converts any expressions in the format string to style props. e.g., <FormattedTextBox height='{this._headerHeight}px' > + if (this._props.isContentActive()) { + const scale = this._props.NativeDimScaling?.() || 1; + const styleFromLayoutString = Doc.styleFromLayoutString(this.Document, this._props, scale); // this converts any expressions in the format string to style props. e.g., <FormattedTextBox height='{this._headerHeight}px' > const height = Number(styleFromLayoutString.height?.replace('px', '')); // prevent default if selected || child is active but this doc isn't scrollable if ( - (this._scrollRef.current?.scrollHeight ?? 0) <= Math.ceil((height ? height : this.props.PanelHeight()) / scale) && // - (this.props.rootSelected() || this.isAnyChildContentActive()) + (this._scrollRef.current?.scrollHeight ?? 0) <= Math.ceil((height ? height : this._props.PanelHeight()) / scale) && // + (this._props.rootSelected?.() || this.isAnyChildContentActive()) ) { e.preventDefault(); } @@ -2097,25 +2063,25 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps }; _oldWheel: any; @computed get fontColor() { - return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Color); + return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Color); } @computed get fontSize() { - return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.FontSize); + return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FontSize); } @computed get fontFamily() { - return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.FontFamily); + return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FontFamily); } @computed get fontWeight() { - return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.FontWeight); + return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.FontWeight); } render() { TraceMobx(); - const scale = (this.props.NativeDimScaling?.() || 1) * NumCast(this.layoutDoc._freeform_scale, 1); + const scale = (this._props.NativeDimScaling?.() || 1) * NumCast(this.layoutDoc._freeform_scale, 1); const rounded = StrCast(this.layoutDoc.layout_borderRounding) === '100%' ? '-rounded' : ''; - setTimeout(() => !this.props.isContentActive() && FormattedTextBoxComment.textBox === this && FormattedTextBoxComment.Hide); - const paddingX = NumCast(this.layoutDoc._xMargin, this.props.xPadding || 0); - const paddingY = NumCast(this.layoutDoc._yMargin, this.props.yPadding || 0); - const styleFromLayoutString = Doc.styleFromLayoutString(this.Document, this.props, scale); // this converts any expressions in the format string to style props. e.g., <FormattedTextBox height='{this._headerHeight}px' > + setTimeout(() => !this._props.isContentActive() && FormattedTextBoxComment.textBox === this && FormattedTextBoxComment.Hide); + const paddingX = NumCast(this.layoutDoc._xMargin, this._props.xPadding || 0); + const paddingY = NumCast(this.layoutDoc._yMargin, this._props.yPadding || 0); + const styleFromLayoutString = Doc.styleFromLayoutString(this.Document, this._props, scale); // this converts any expressions in the format string to style props. e.g., <FormattedTextBox height='{this._headerHeight}px' > return styleFromLayoutString?.height === '0px' ? null : ( <div className="formattedTextBox" @@ -2127,7 +2093,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps r?.addEventListener('wheel', this.onPassiveWheel, { passive: false }); }} style={{ - ...(this.props.dontScale + ...(this._props.dontScale ? {} : { transform: `scale(${scale})`, @@ -2146,9 +2112,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps className="formattedTextBox-cont" ref={this._ref} style={{ - cursor: this.props.isContentActive() ? 'text' : undefined, - height: this.props.height ? 'max-content' : undefined, - pointerEvents: Doc.ActiveTool === InkTool.None && !this.props.onBrowseClick?.() ? undefined : 'none', + cursor: this._props.isContentActive() ? 'text' : undefined, + height: this._props.height ? 'max-content' : undefined, + pointerEvents: Doc.ActiveTool === InkTool.None && !this._props.onBrowseClick?.() ? undefined : 'none', }} onContextMenu={this.specificContextMenu} onKeyDown={this.onKeyDown} @@ -2163,7 +2129,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps className="formattedTextBox-outer" ref={this._scrollRef} style={{ - width: this.props.dontSelectOnLoad || this.noSidebar ? '100%' : `calc(100% - ${this.layout_sidebarWidthPercent})`, + width: this._props.dontSelectOnLoad || this.noSidebar ? '100%' : `calc(100% - ${this.layout_sidebarWidthPercent})`, overflow: this.layoutDoc._createDocOnCR ? 'hidden' : this.layoutDoc._layout_autoHeight ? 'visible' : undefined, }} onScroll={this.onScroll} @@ -2180,8 +2146,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps }} /> </div> - {this.noSidebar || this.props.dontSelectOnLoad || !this.SidebarShown || this.layout_sidebarWidthPercent === '0%' ? null : this.sidebarCollection} - {this.noSidebar || this.Document._layout_noSidebar || this.props.dontSelectOnLoad || this.Document._createDocOnCR || this.layoutDoc._chromeHidden ? null : this.sidebarHandle} + {this.noSidebar || this._props.dontSelectOnLoad || !this.SidebarShown || this.layout_sidebarWidthPercent === '0%' ? null : this.sidebarCollection} + {this.noSidebar || this.Document._layout_noSidebar || this._props.dontSelectOnLoad || this.Document._createDocOnCR || this.layoutDoc._chromeHidden ? null : this.sidebarHandle} {this.audioHandle} {this.layoutDoc._layout_enableAltContentUI && !this.layoutDoc._chromeHidden ? this.overlayAlternateIcon : null} </div> |