diff options
-rw-r--r-- | src/client/util/CurrentUserUtils.ts | 43 | ||||
-rw-r--r-- | src/client/util/DropConverter.ts | 2 | ||||
-rw-r--r-- | src/client/views/Main.scss | 4 | ||||
-rw-r--r-- | src/client/views/collections/CollectionMenu.tsx | 2 | ||||
-rw-r--r-- | src/client/views/collections/CollectionStackingView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/collections/CollectionTreeView.tsx | 2 | ||||
-rw-r--r-- | src/client/views/globalCssVariables.scss | 4 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 1 | ||||
-rw-r--r-- | src/client/views/nodes/formattedText/DashFieldView.tsx | 22 | ||||
-rw-r--r-- | src/client/views/nodes/formattedText/FormattedTextBox.scss | 5 | ||||
-rw-r--r-- | src/client/views/nodes/formattedText/FormattedTextBox.tsx | 25 | ||||
-rw-r--r-- | src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts | 14 | ||||
-rw-r--r-- | src/client/views/nodes/formattedText/RichTextRules.ts | 2 | ||||
-rw-r--r-- | src/fields/Doc.ts | 10 |
14 files changed, 81 insertions, 57 deletions
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts index 365a0a409..3dc16b864 100644 --- a/src/client/util/CurrentUserUtils.ts +++ b/src/client/util/CurrentUserUtils.ts @@ -47,7 +47,7 @@ export class CurrentUserUtils { @observable public static propertiesWidth: number = 0; - // sets up the default User Templates - slideView, queryView, descriptionView + // sets up the default User Templates - slideView, headerView static setupUserTemplateButtons(doc: Doc) { // Prototype for mobile button (not sure if 'Advanced Item Prototypes' is ideal location) if (doc["template-mobile-button"] === undefined) { @@ -85,29 +85,12 @@ export class CurrentUserUtils { }); } - if (doc["template-button-description"] === undefined) { - const descriptionTemplate = Doc.MakeDelegate(Docs.Create.TextDocument(" ", { title: "header", _height: 100, system: true }, "header")); // text needs to be a space to allow templateText to be created - descriptionTemplate.system = true; - descriptionTemplate[DataSym].layout = - "<div>" + - " <FormattedTextBox {...props} height='{this._headerHeight||75}px' background='{this._headerColor||`orange`}' fieldKey={'header'}/>" + - " <FormattedTextBox {...props} position='absolute' top='{(this._headerHeight||75)*scale}px' height='calc({100/scale}% - {this._headerHeight||75}px)' fieldKey={'text'}/>" + - "</div>"; - (descriptionTemplate.proto as Doc).isTemplateDoc = makeTemplate(descriptionTemplate.proto as Doc, true, "descriptionView"); - - doc["template-button-description"] = CurrentUserUtils.ficon({ - onDragStart: ScriptField.MakeFunction('copyDragFactory(this.dragFactory)'), - dragFactory: new PrefetchProxy(descriptionTemplate) as any as Doc, - removeDropProperties: new List<string>(["dropAction"]), title: "description view", icon: "window-maximize", system: true - }); - } - if (doc["template-button-link"] === undefined) { // set _backgroundColor to transparent to prevent link dot from obscuring document it's attached to. - const linkTemplate = Doc.MakeDelegate(Docs.Create.TextDocument(" ", { title: "header", _height: 100, system: true }, "header")); // text needs to be a space to allow templateText to be created + const linkTemplate = Doc.MakeDelegate(Docs.Create.TextDocument(" ", { title: "header", _autoHeight: true, system: true }, "header")); // text needs to be a space to allow templateText to be created linkTemplate.system = true; Doc.GetProto(linkTemplate).layout = "<div>" + - " <FormattedTextBox {...props} height='{this._headerHeight||75}px' background='{this._headerColor||`lightGray`}' fieldKey={'header'}/>" + + " <FormattedTextBox {...props} dontSelectOnLoad={'true'} height='{this._headerHeight||75}px' ignoreAutoHeight={'true'} background='{this._headerColor||`lightGray`}' fieldKey={'header'}/>" + " <FormattedTextBox {...props} position='absolute' top='{(this._headerHeight||75)*scale}px' height='calc({100/scale}% - {this._headerHeight||75}px)' fieldKey={'text'}/>" + "</div>"; (linkTemplate.proto as Doc).isTemplateDoc = makeTemplate(linkTemplate.proto as Doc, true, "linkView"); @@ -190,9 +173,9 @@ export class CurrentUserUtils { onChildDoubleClick: openInTarget, backgroundColor: "#9b9b9b3F", system: true }); - const details = TextDocument("", { title: "details", _height: 350, _autoHeight: true, system: true }); - const short = TextDocument("", { title: "shortDescription", treeViewOpen: true, treeViewExpandedView: "layout", _height: 100, _autoHeight: true, system: true }); - const long = TextDocument("", { title: "longDescription", treeViewOpen: false, treeViewExpandedView: "layout", _height: 350, _autoHeight: true, system: true }); + const details = TextDocument("", { title: "details", _height: 200, _autoHeight: true, system: true }); + const short = TextDocument("", { title: "shortDescription", treeViewOpen: true, treeViewExpandedView: "layout", _height: 75, _autoHeight: true, system: true }); + const long = TextDocument("", { title: "longDescription", treeViewOpen: false, treeViewExpandedView: "layout", _height: 150, _autoHeight: true, system: true }); const buxtonFieldKeys = ["year", "originalPrice", "degreesOfFreedom", "company", "attribute", "primaryKey", "secondaryKey", "dimensions"]; const detailedTemplate = { @@ -253,7 +236,6 @@ export class CurrentUserUtils { const requiredTypes = [ doc["template-button-slides"] as Doc, - doc["template-button-description"] as Doc, doc["template-mobile-button"] as Doc, doc["template-button-detail"] as Doc, doc["template-button-simple"] as Doc, @@ -426,6 +408,17 @@ export class CurrentUserUtils { FormattedTextBox.SelectOnLoad = textDoc[Id]; doc.emptySlide = textDoc; } + if (doc.emptyHeader === undefined) { + const headerTemplate = Docs.Create.TextDocument(" ", { title: "header", _autoHeight: true, system: true, cloneFieldFilter: new List<string>(["system"]) }, "header"); // text needs to be a space to allow templateText to be created + headerTemplate[DataSym].layout = + "<div>" + + " <FormattedTextBox {...props} dontSelectOnLoad={'true'} ignoreAutoHeight={'true'} height='{this._headerHeight||75}px' background='{this._headerColor||`orange`}' fieldKey={'header'}/>" + + " <FormattedTextBox {...props} position='absolute' top='{(this._headerHeight||75)*scale}px' height='calc({100/scale}% - {this._headerHeight||75}px)' fieldKey={'text'}/>" + + "</div>"; + (headerTemplate.proto as Doc).isTemplateDoc = makeTemplate(headerTemplate.proto as Doc, true, "headerView"); + doc.emptyHeader = headerTemplate; + ((doc.emptyHeader as Doc).proto as Doc)["dragFactory-count"] = 0; + } if (doc.emptyComparison === undefined) { doc.emptyComparison = Docs.Create.ComparisonDocument({ title: "compare", _width: 300, _height: 300, system: true, cloneFieldFilter: new List<string>(["system"]) }); } @@ -468,10 +461,10 @@ export class CurrentUserUtils { { toolTip: "Tap to create an audio recorder in a new pane, drag for an audio recorder", title: "Audio", icon: "microphone", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyAudio as Doc, noviceMode: true }, { toolTip: "Tap to create a button in a new pane, drag for a button", title: "Button", icon: "bolt", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyButton as Doc, noviceMode: true }, { toolTip: "Tap to create a presentation in a new pane, drag for a presentation", title: "Trails", icon: "pres-trail", click: 'openOnRight(Doc.UserDoc().activePresentation = copyDragFactory(this.dragFactory))', drag: `Doc.UserDoc().activePresentation = copyDragFactory(this.dragFactory)`, dragFactory: doc.emptyPresentation as Doc, noviceMode: true }, - { toolTip: "Tap to create a search box in a new pane, drag for a search box", title: "Query", icon: "search", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptySearch as Doc }, { toolTip: "Tap to create a scripting box in a new pane, drag for a scripting box", title: "Script", icon: "terminal", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyScript as Doc }, { toolTip: "Tap to create a mobile view in a new pane, drag for a mobile view", title: "Phone", icon: "mobile", click: 'openOnRight(Doc.UserDoc().activeMobileMenu)', drag: 'this.dragFactory', dragFactory: doc.activeMobileMenu as Doc }, { toolTip: "Tap to create a document previewer in a new pane, drag for a document previewer", title: "Prev", icon: "expand", click: 'openOnRight(copyDragFactory(this.dragFactory))', drag: 'copyDragFactory(this.dragFactory)', dragFactory: doc.emptyDocHolder as Doc }, + { toolTip: "Tap to create a custom header note document, drag for a custom header note", title: "Custom", icon: "window-maximize", click: 'openOnRight(delegateDragFactory(this.dragFactory))', drag: 'delegateDragFactory(this.dragFactory)', dragFactory: doc.emptyHeader as Doc, noviceMode: true }, { toolTip: "Toggle a Calculator REPL", title: "repl", icon: "calculator", click: 'addOverlayWindow("ScriptingRepl", { x: 300, y: 100, width: 200, height: 200, title: "Scripting REPL" })' }, ]; diff --git a/src/client/util/DropConverter.ts b/src/client/util/DropConverter.ts index f1848f7e5..49643b5bb 100644 --- a/src/client/util/DropConverter.ts +++ b/src/client/util/DropConverter.ts @@ -60,7 +60,7 @@ export function convertDropDataToButtons(data: DragManager.DocumentDragData) { if (doc.type === DocumentType.FONTICON || StrCast(Doc.Layout(doc).layout).includes("FontIconBox")) { //dbox = Doc.MakeAlias(doc); // don't need to do anything if dropping an icon doc onto an icon bar since there should be no layout data for an icon } else if (!doc.onDragStart && !doc.isButtonBar) { - const layoutDoc = doc.layout instanceof Doc && doc.layout.isTemplateForField ? doc.layout : doc; + const layoutDoc = doc;// doc.layout instanceof Doc && doc.layout.isTemplateForField ? doc.layout : doc; if (layoutDoc.type !== DocumentType.FONTICON) { !layoutDoc.isTemplateDoc && makeTemplate(layoutDoc); } diff --git a/src/client/views/Main.scss b/src/client/views/Main.scss index 97ed0a901..b1ad4868c 100644 --- a/src/client/views/Main.scss +++ b/src/client/views/Main.scss @@ -1,6 +1,10 @@ @import "globalCssVariables"; @import "nodeModuleOverrides"; +:root { + --flyoutHandleWidth: 28px; + --menuPanelWidth: 60px; +} html, body { width: 100%; diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx index a58edc604..3cc041e0b 100644 --- a/src/client/views/collections/CollectionMenu.tsx +++ b/src/client/views/collections/CollectionMenu.tsx @@ -533,7 +533,7 @@ export class CollectionFreeFormViewChrome extends React.Component<CollectionMenu if (this.selectedDoc) { const layoutField = Doc.LayoutField(this.selectedDoc); const layoutStr = this.selectedDocumentView?.props.LayoutTemplateString || StrCast(layoutField); - return layoutStr.includes("FormattedText") || StrCast((layoutField as Doc)?.layout).includes("FormattedText"); + return (document.activeElement as any)?.className.includes("ProseMirror") || layoutStr.includes("FormattedText") || StrCast((layoutField as Doc)?.layout).includes("FormattedText"); } else return false; } diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index cbc62be91..9c9dad2c9 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -187,7 +187,7 @@ export class CollectionStackingView extends CollectionSubView(StackingDocument) const opacity = () => this.Document._currentFrame === undefined ? this.props.childOpacity?.() : CollectionFreeFormDocumentView.getValues(doc, NumCast(this.Document._currentFrame))?.opacity; return <ContentFittingDocumentView Document={doc} - DataDoc={dataDoc || (doc[DataSym] !== doc && doc[DataSym])} + DataDoc={dataDoc || (!Doc.AreProtosEqual(doc[DataSym], doc) && doc[DataSym])} backgroundColor={this.props.backgroundColor} LayoutTemplate={this.props.ChildLayoutTemplate} LayoutTemplateString={this.props.ChildLayoutString} diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx index 276e0b873..47d4aad94 100644 --- a/src/client/views/collections/CollectionTreeView.tsx +++ b/src/client/views/collections/CollectionTreeView.tsx @@ -177,7 +177,7 @@ class TreeView extends React.Component<TreeViewProps> { } public static makeTextBullet() { - const bullet = Docs.Create.TextDocument("-text-", { title: "-title-", _viewType: CollectionViewType.Tree, hideLinkButton: true, treeViewOutlineMode: true, x: 0, y: 0, _xMargin: 0, _yMargin: 0, _autoHeight: true, _singleLine: true, _backgroundColor: "transparent", _width: 500, _height: 10, templates: new List<string>([Templates.Title.Layout]) }); + const bullet = Docs.Create.TextDocument("-text-", { title: "-title-", _viewType: CollectionViewType.Tree, hideLinkButton: true, _showSidebar: true, treeViewOutlineMode: true, x: 0, y: 0, _xMargin: 0, _yMargin: 0, _autoHeight: true, _singleLine: true, _backgroundColor: "transparent", _width: 1000, _height: 10, templates: new List<string>([Templates.Title.Layout]) }); Doc.GetProto(bullet).layout = CollectionView.LayoutString("data"); Doc.GetProto(bullet).title = ComputedField.MakeFunction('self.text?.Text'); Doc.GetProto(bullet).data = new List<Doc>([]); diff --git a/src/client/views/globalCssVariables.scss b/src/client/views/globalCssVariables.scss index d0c90edcb..1539d1399 100644 --- a/src/client/views/globalCssVariables.scss +++ b/src/client/views/globalCssVariables.scss @@ -38,10 +38,6 @@ $MINIMIZED_ICON_SIZE:25; $MAX_ROW_HEIGHT: 44px; $DFLT_IMAGE_NATIVE_DIM: 900px; $MENU_PANEL_WIDTH: 60px; -:root { - --flyoutHandleWidth: 28px; - --menuPanelWidth: 60px; -} :export { contextMenuZindex: $contextMenu-zindex; diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index b372f3691..ad99001dd 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -987,6 +987,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu yMargin={10} xMargin={10} hideOnLeave={true} + dontRegisterView={true} LayoutTemplateString={`<FormattedTextBox {...props} fieldKey={'${showCaption}'}/>`} ContentScaling={returnOne} ChromeHeight={this.chromeHeight} diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx index f14a57e31..0332bb4fd 100644 --- a/src/client/views/nodes/formattedText/DashFieldView.tsx +++ b/src/client/views/nodes/formattedText/DashFieldView.tsx @@ -1,5 +1,5 @@ import { IReactionDisposer, observable, runInAction, computed, action } from "mobx"; -import { Doc, DocListCast, Field } from "../../../../fields/Doc"; +import { Doc, DocListCast, Field, LayoutSym } from "../../../../fields/Doc"; import { List } from "../../../../fields/List"; import { listSpec } from "../../../../fields/Schema"; import { SchemaHeaderField } from "../../../../fields/SchemaHeaderField"; @@ -70,7 +70,7 @@ export class DashFieldViewInternal extends React.Component<IDashFieldViewInterna DocServer.GetRefField(this.props.docid). then(action(async dashDoc => dashDoc instanceof Doc && (this._dashDoc = dashDoc))); } else { - this._dashDoc = this.props.tbox.props.DataDoc || this.props.tbox.dataDoc; + this._dashDoc = this.props.tbox.rootDoc; } } componentWillUnmount() { @@ -92,7 +92,10 @@ export class DashFieldViewInternal extends React.Component<IDashFieldViewInterna return <input className="dashFieldView-fieldCheck" type="checkbox" checked={boolVal} - onChange={e => this._dashDoc![this._fieldKey] = e.target.checked} + onChange={e => { + if (this._fieldKey.startsWith("_")) Doc.Layout(this._textBoxDoc)[this._fieldKey] = e.target.checked; + this._dashDoc![this._fieldKey] = e.target.checked; + }} />; } else // field value is a string, so display it as an editable span @@ -159,9 +162,16 @@ export class DashFieldViewInternal extends React.Component<IDashFieldViewInterna } else if (nodeText.startsWith("=:=")) { Doc.Layout(this._textBoxDoc)[this._fieldKey] = ComputedField.MakeFunction(nodeText.substring(3)); } else { - const splits = newText.split(this.multiValueDelimeter); - if (this._fieldKey !== "PARAMS" || !this._textBoxDoc[this._fieldKey] || this._dashDoc?.PARAMS) { - this._dashDoc![this._fieldKey] = splits.length > 1 ? new List<string>(splits) : newText; + if (Number(newText).toString() === newText) { + if (this._fieldKey.startsWith("_")) Doc.Layout(this._textBoxDoc)[this._fieldKey] = Number(newText); + this._dashDoc![this._fieldKey] = Number(newText); + } else { + const splits = newText.split(this.multiValueDelimeter); + if (this._fieldKey !== "PARAMS" || !this._textBoxDoc[this._fieldKey] || this._dashDoc?.PARAMS) { + const strVal = splits.length > 1 ? new List<string>(splits) : newText; + if (this._fieldKey.startsWith("_")) Doc.Layout(this._textBoxDoc)[this._fieldKey] = strVal; + this._dashDoc![this._fieldKey] = strVal; + } } } }); diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.scss b/src/client/views/nodes/formattedText/FormattedTextBox.scss index 847b1bb30..43e64d2d2 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.scss +++ b/src/client/views/nodes/formattedText/FormattedTextBox.scss @@ -43,7 +43,7 @@ overflow: auto; display: inline-block; width: 100%; - height: 100%; + height: unset; } .formattedTextBox-sidebar-handle { @@ -51,7 +51,8 @@ top: 0; //top: calc(50% - 17.5px); // use this to center vertically -- make sure it looks okay for slide views width: 10px; - height: 35px; + height: 100%; + max-height: 35px; background: lightgray; border-radius: 20px; cursor:grabbing; diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index a79e70017..4cc0309eb 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -64,6 +64,7 @@ export interface FormattedTextBoxProps { hideOnLeave?: boolean; // used by DocumentView for setting caption's hide on leave (bcz: would prefer to have caption-hideOnLeave field set or something similar) xMargin?: number; // used to override document's settings for xMargin --- see CollectionCarouselView yMargin?: number; + dontSelectOnLoad?: boolean; // suppress selecting the text box when loaded } export const GoogleRef = "googleDocId"; @@ -79,6 +80,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp public static Instance: FormattedTextBox; public ProseRef?: HTMLDivElement; public get EditorView() { return this._editorView; } + private _boxRef: React.RefObject<HTMLDivElement> = React.createRef(); private _ref: React.RefObject<HTMLDivElement> = React.createRef(); private _scrollRef: React.RefObject<HTMLDivElement> = React.createRef(); private _editorView: Opt<EditorView>; @@ -346,7 +348,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } updateTitle = () => { - if ((this.props.Document.isTemplateForField === "text" || !this.props.Document.isTemplateForField) && // only update the title if the data document's data field is changing + 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 StrCast(this.dataDoc.title).startsWith("-") && this._editorView && !this.dataDoc["title-custom"] && Doc.LayoutFieldKey(this.rootDoc) === this.fieldKey) { let node = this._editorView.state.doc; @@ -556,7 +558,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } sidebarMove = (e: PointerEvent, down: number[], delta: number[]) => { const bounds = this.CurrentDiv.getBoundingClientRect(); - this.layoutDoc._sidebarWidthPercent = "" + 100 * (1 - (e.clientX - bounds.left) / bounds.width) + "%"; + this.layoutDoc._sidebarWidthPercent = "" + 100 * Math.max(0, (1 - (e.clientX - bounds.left) / bounds.width)) + "%"; return false; } @undoBatch @@ -1144,7 +1146,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } const selectOnLoad = this.rootDoc[Id] === FormattedTextBox.SelectOnLoad; - if (selectOnLoad && !this.props.dontRegisterView) { + if (selectOnLoad && !this.props.dontRegisterView && !this.props.dontSelectOnLoad) { FormattedTextBox.SelectOnLoad = ""; this.props.select(false); if (FormattedTextBox.SelectOnLoadChar) { @@ -1314,7 +1316,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } if (!node && this.ProseRef) { const lastNode = this.ProseRef.children[this.ProseRef.children.length - 1].children[this.ProseRef.children[this.ProseRef.children.length - 1].children.length - 1]; // get the last prosemirror div - if (e.clientY > lastNode?.getBoundingClientRect().bottom) { // if we clicked below the last prosemirror div, then set the selection to be the end of the document + const boundsRect = lastNode?.getBoundingClientRect(); + if (e.clientX > boundsRect.left && e.clientX < boundsRect.right && + e.clientY > boundsRect.bottom) { // if we clicked below the last prosemirror div, then set the selection to be the end of the document + this._editorView?.focus(); this._editorView!.dispatch(this._editorView!.state.tr.setSelection(TextSelection.create(this._editorView!.state.doc, this._editorView!.state.doc.content.size))); } } else if ([this._editorView!.state.schema.nodes.ordered_list, this._editorView!.state.schema.nodes.listItem].includes(node?.type) && @@ -1473,7 +1478,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } @action tryUpdateHeight(limitHeight?: number) { - let scrollHeight = this._ref.current?.scrollHeight; + let scrollHeight = this.ProseRef?.scrollHeight || 0; if (this.props.renderDepth && this.layoutDoc._autoHeight && !this.props.ignoreAutoHeight && scrollHeight) { // if top === 0, then the text box is growing upward (as the overlay caption) which doesn't contribute to the height computation scrollHeight = scrollHeight * NumCast(this.layoutDoc._viewScale, 1); if (limitHeight && scrollHeight > limitHeight) { @@ -1493,14 +1498,16 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp }, 10); } else { try { - this.layoutDoc._height = newHeight; + const boxHeight = Number(getComputedStyle(this._boxRef.current!).height.replace("px", "")); + const outer = this.rootDoc[HeightSym]() - boxHeight - (this.props.ChromeHeight ? this.props.ChromeHeight() : 0); + this.rootDoc._height = newHeight + outer; this.layoutDoc._nativeHeight = nh ? scrollHeight : undefined; } catch (e) { console.log("Error in tryUpdateHeight"); } } } } - @computed get sidebarWidthPercent() { return StrCast(this.layoutDoc._sidebarWidthPercent, "20%"); } + @computed get sidebarWidthPercent() { return StrCast(this.layoutDoc._sidebarWidthPercent, "0%"); } sidebarWidth = () => Number(this.sidebarWidthPercent.substring(0, this.sidebarWidthPercent.length - 1)) / 100 * this.props.PanelWidth(); sidebarScreenToLocal = () => this.props.ScreenToLocalTransform().translate(-(this.props.PanelWidth() - this.sidebarWidth()) / this.props.ContentScaling(), 0); @computed get sidebarColor() { return StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "transparent")); } @@ -1516,7 +1523,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const selPad = this.props.isSelected() && !this.layoutDoc._singleLine ? -10 : 0; const selclass = this.props.isSelected() && !this.layoutDoc._singleLine ? "-selected" : ""; return ( - <div className={"formattedTextBox-cont"} + <div className={"formattedTextBox-cont"} ref={this._boxRef} style={{ transform: `scale(${scale})`, transformOrigin: "top left", @@ -1594,7 +1601,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp ContainingCollectionDoc={this.props.ContainingCollectionDoc} /> } </div> - {this.props.isSelected() ? <div className="formattedTextBox-sidebar-handle" style={{ left: `calc(100% - ${this.sidebarWidthPercent} - 5px)` }} onPointerDown={this.sidebarDown} /> : (null)} + {this.props.isSelected() ? <div className="formattedTextBox-sidebar-handle" style={{ left: `max(0px, calc(100% - ${this.sidebarWidthPercent} - 5px))` }} onPointerDown={this.sidebarDown} /> : (null)} </>} {!this.layoutDoc._showAudio ? (null) : <div className="formattedTextBox-dictation" onClick={action(e => this._recording = !this._recording)} > diff --git a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts index 9895940d1..f1a0188c5 100644 --- a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts +++ b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts @@ -49,7 +49,7 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey /// bcz; Argh!! replace with an onEnter func that conditionally handles Enter const addTextBox = (below: boolean, force?: boolean) => { - if (props.LayoutTemplateString) return true; + if (props.Document.treeViewOutlineMode) return true; // bcz: Arghh .. need to determine if this is an treeViewOutlineBox in which case Enter's are ignored.. const layoutDoc = props.Document; const originalDoc = layoutDoc.rootDocument || layoutDoc; if (force || props.Document._singleLine) { @@ -217,11 +217,13 @@ export function buildKeymap<S extends Schema<any>>(schema: S, props: any, mapKey const fromattrs = state.selection.$from.node().attrs; if (!splitBlockKeepMarks(state, (tx3: Transaction) => { const tonode = tx3.selection.$to.node(); - const tx4 = tx3.setNodeMarkup(tx3.selection.to - 1, tonode.type, fromattrs, tonode.marks); - splitMetadata(marks, tx4); - if (!liftListItem(schema.nodes.list_item)(tx4, dispatch as ((tx: Transaction<Schema<any, any>>) => void))) { - dispatch(tx4); - } + if (tx3.doc.nodeAt(tx3.selection.to - 1)) { + const tx4 = tx3.setNodeMarkup(tx3.selection.to - 1, tonode.type, fromattrs, tonode.marks); + splitMetadata(marks, tx4); + if (!liftListItem(schema.nodes.list_item)(tx4, dispatch as ((tx: Transaction<Schema<any, any>>) => void))) { + dispatch(tx4); + } + } else dispatch(tx3.insertText("\r")); })) { return false; } diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts index 02f9c6268..06c73265a 100644 --- a/src/client/views/nodes/formattedText/RichTextRules.ts +++ b/src/client/views/nodes/formattedText/RichTextRules.ts @@ -324,7 +324,7 @@ export class RichTextRules { this.Document[DataSym]["#" + tag] = "#" + tag; const tags = StrCast(this.Document.tags, ":"); if (!tags.includes(`#${tag}:`)) { - this.Document[DataSym].tags = `"${tags + "#" + tag + ':'}"`; + this.Document[DataSym].tags = `${tags + "#" + tag + ':'}`; } const fieldView = state.schema.nodes.dashField.create({ fieldKey: "#" + tag }); return state.tr.deleteRange(start, end).insert(start, fieldView); diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts index be62249c6..9553c4c7b 100644 --- a/src/fields/Doc.ts +++ b/src/fields/Doc.ts @@ -782,6 +782,7 @@ export namespace Doc { if (doc) { const delegate = new Doc(id, true); delegate.proto = doc; + delegate.isPrototype = true; delegate.author = Doc.CurrentUserEmail; title && (delegate.title = title); return delegate; @@ -1134,6 +1135,14 @@ export namespace Doc { } return ndoc; } + export function delegateDragFactory(dragFactory: Doc) { + const ndoc = Doc.MakeDelegate(dragFactory); + if (ndoc && dragFactory["dragFactory-count"] !== undefined) { + dragFactory["dragFactory-count"] = NumCast(dragFactory["dragFactory-count"]) + 1; + Doc.GetProto(ndoc).title = ndoc.title + " " + NumCast(dragFactory["dragFactory-count"]).toString(); + } + return ndoc; + } export namespace Get { @@ -1284,6 +1293,7 @@ Scripting.addGlobal(function getDocTemplate(doc?: any) { return Doc.getDocTempla 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) { return Doc.copyDragFactory(dragFactory); }); +Scripting.addGlobal(function delegateDragFactory(dragFactory: Doc) { return Doc.delegateDragFactory(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); }); |