aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes')
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx34
-rw-r--r--src/client/views/nodes/ColorBox.tsx2
-rw-r--r--src/client/views/nodes/DocumentLinksButton.tsx8
-rw-r--r--src/client/views/nodes/DocumentView.scss11
-rw-r--r--src/client/views/nodes/DocumentView.tsx65
-rw-r--r--src/client/views/nodes/KeyValueBox.tsx4
-rw-r--r--src/client/views/nodes/LinkAnchorBox.tsx10
-rw-r--r--src/client/views/nodes/LinkDocPreview.tsx6
-rw-r--r--src/client/views/nodes/PDFBox.scss9
-rw-r--r--src/client/views/nodes/PDFBox.tsx37
-rw-r--r--src/client/views/nodes/PresBox.tsx4
-rw-r--r--src/client/views/nodes/formattedText/DashFieldView.tsx4
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.scss62
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx65
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx7
-rw-r--r--src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts30
-rw-r--r--src/client/views/nodes/formattedText/RichTextRules.ts4
-rw-r--r--src/client/views/nodes/formattedText/marks_rts.ts2
-rw-r--r--src/client/views/nodes/formattedText/nodes_rts.ts2
19 files changed, 217 insertions, 149 deletions
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 404d69730..a3020f912 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -22,7 +22,7 @@ export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
zIndex?: number;
highlight?: boolean;
jitterRotation: number;
- transition?: string;
+ dataTransition?: string;
fitToBox?: boolean;
replica: string;
}
@@ -60,10 +60,10 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
const someView = Cast(this.props.Document.someView, Doc);
const minimap = Cast(this.props.Document.minimap, Doc);
if (someView instanceof Doc && minimap instanceof Doc) {
- const x = (NumCast(someView._panX) - NumCast(someView._width) / 2 / NumCast(someView.scale) - (NumCast(minimap.fitX) - NumCast(minimap.fitW) / 2)) / NumCast(minimap.fitW) * NumCast(minimap._width) - NumCast(minimap._width) / 2;
- const y = (NumCast(someView._panY) - NumCast(someView._height) / 2 / NumCast(someView.scale) - (NumCast(minimap.fitY) - NumCast(minimap.fitH) / 2)) / NumCast(minimap.fitH) * NumCast(minimap._height) - NumCast(minimap._height) / 2;
- const w = NumCast(someView._width) / NumCast(someView.scale) / NumCast(minimap.fitW) * NumCast(minimap.width);
- const h = NumCast(someView._height) / NumCast(someView.scale) / NumCast(minimap.fitH) * NumCast(minimap.height);
+ const x = (NumCast(someView._panX) - NumCast(someView._width) / 2 / NumCast(someView._viewScale) - (NumCast(minimap.fitX) - NumCast(minimap.fitW) / 2)) / NumCast(minimap.fitW) * NumCast(minimap._width) - NumCast(minimap._width) / 2;
+ const y = (NumCast(someView._panY) - NumCast(someView._height) / 2 / NumCast(someView._viewScale) - (NumCast(minimap.fitY) - NumCast(minimap.fitH) / 2)) / NumCast(minimap.fitH) * NumCast(minimap._height) - NumCast(minimap._height) / 2;
+ const w = NumCast(someView._width) / NumCast(someView._viewScale) / NumCast(minimap.fitW) * NumCast(minimap.width);
+ const h = NumCast(someView._height) / NumCast(someView._viewScale) / NumCast(minimap.fitH) * NumCast(minimap.height);
return { x: x, y: y, width: w, height: h };
}
}
@@ -81,9 +81,15 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
public static setValues(time: number, d: Doc, x?: number, y?: number, opacity?: number) {
const timecode = Math.round(time);
- Cast(d["x-indexed"], listSpec("number"), [])[timecode] = x as any as number;
- Cast(d["y-indexed"], listSpec("number"), [])[timecode] = y as any as number;
- Cast(d["opacity-indexed"], listSpec("number"), null)[timecode] = opacity as any as number;
+ const xindexed = Cast(d["x-indexed"], listSpec("number"), []).slice();
+ const yindexed = Cast(d["y-indexed"], listSpec("number"), []).slice();
+ const oindexed = Cast(d["opacity-indexed"], listSpec("number"), []).slice();
+ xindexed[timecode] = x as any as number;
+ yindexed[timecode] = y as any as number;
+ oindexed[timecode] = opacity as any as number;
+ d["x-indexed"] = new List<number>(xindexed);
+ d["y-indexed"] = new List<number>(yindexed);
+ d["opacity-indexed"] = new List<number>(oindexed);
}
public static updateKeyframe(docs: Doc[], time: number) {
const timecode = Math.round(time);
@@ -94,14 +100,14 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
xindexed?.length <= timecode + 1 && xindexed.push(undefined as any as number);
yindexed?.length <= timecode + 1 && yindexed.push(undefined as any as number);
opacityindexed?.length <= timecode + 1 && opacityindexed.push(undefined as any as number);
- doc.transition = "all 1s";
+ doc.dataTransition = "all 1s";
});
- setTimeout(() => docs.forEach(doc => doc.transition = "inherit"), 1010);
+ setTimeout(() => docs.forEach(doc => doc.dataTransition = "inherit"), 1010);
}
public static gotoKeyframe(docs: Doc[]) {
- docs.forEach(doc => doc.transition = "all 1s");
- setTimeout(() => docs.forEach(doc => doc.transition = "inherit"), 1010);
+ docs.forEach(doc => doc.dataTransition = "all 1s");
+ setTimeout(() => docs.forEach(doc => doc.dataTransition = "inherit"), 1010);
}
public static setupKeyframes(docs: Doc[], timecode: number, progressivize: boolean = false) {
@@ -119,7 +125,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
doc.x = ComputedField.MakeInterpolated("x", "activeFrame");
doc.y = ComputedField.MakeInterpolated("y", "activeFrame");
doc.opacity = ComputedField.MakeInterpolated("opacity", "activeFrame");
- doc.transition = "inherit";
+ doc.dataTransition = "inherit";
});
}
@@ -150,7 +156,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
borderRadius: StrCast(Doc.Layout(this.layoutDoc).borderRounding),
outline: this.Highlight ? "orange solid 2px" : "",
transform: this.transform,
- transition: this.props.transition ? this.props.transition : this.dataProvider ? this.dataProvider.transition : StrCast(this.layoutDoc.transition),
+ transition: this.props.dataTransition ? this.props.dataTransition : this.dataProvider ? this.dataProvider.transition : StrCast(this.layoutDoc.dataTransition),
width: this.props.Document.isInkMask ? 5000 : this.width,
height: this.props.Document.isInkMask ? 5000 : this.height,
zIndex: this.ZInd,
diff --git a/src/client/views/nodes/ColorBox.tsx b/src/client/views/nodes/ColorBox.tsx
index a49b4eee7..b3a9b6fee 100644
--- a/src/client/views/nodes/ColorBox.tsx
+++ b/src/client/views/nodes/ColorBox.tsx
@@ -39,7 +39,7 @@ export class ColorBox extends ViewBoxBaseComponent<FieldViewProps, ColorDocument
if (view.props.LayoutTemplate?.() || view.props.LayoutTemplateString) { // this situation typically occurs when you have a link dot
targetDoc.backgroundColor = Doc.UserDoc().backgroundColor; // bcz: don't know how to change the color of an inline template...
}
- else if (StrCast(Doc.Layout(view.props.Document).layout).includes("FormattedTextBox") && FormattedTextBox.HadSelection) {
+ else if (StrCast(Doc.Layout(view.props.Document).layout).includes("FormattedTextBox") && window.getSelection()?.toString() !== "") {
Doc.Layout(view.props.Document)[Doc.LayoutFieldKey(view.props.Document) + "-color"] = Doc.UserDoc().backgroundColor;
} else {
Doc.Layout(view.props.Document)._backgroundColor = Doc.UserDoc().backgroundColor; // '_backgroundColor' is template specific. 'backgroundColor' would apply to all templates, but has no UI at the moment
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx
index f35b48ce4..3940b7a98 100644
--- a/src/client/views/nodes/DocumentLinksButton.tsx
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -82,16 +82,16 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
get linkButton() {
const links = DocListCast(this.props.View.props.Document.links);
return (!links.length || links[0].hidden) && !this.props.AlwaysOn ? (null) :
- <div title="Drag(create link) Tap(view links)" ref={this._linkButton} style={{ position: "absolute", left: this.props.Offset?.[0] }}>
+ <div title="Drag(create link) Tap(view links)" ref={this._linkButton} style={{ minWidth: 20, minHeight: 20, position: "absolute", left: this.props.Offset?.[0] }}>
<div className={"documentLinksButton"} style={{ backgroundColor: DocumentLinksButton.StartLink ? "transparent" : "" }}
onPointerDown={this.onLinkButtonDown}
onPointerLeave={action(() => LinkDocPreview.LinkInfo = undefined)}
- onPointerEnter={action(e => LinkDocPreview.LinkInfo = {
+ onPointerEnter={action(e => links.length && (LinkDocPreview.LinkInfo = {
addDocTab: this.props.View.props.addDocTab,
linkSrc: this.props.View.props.Document,
linkDoc: links[0],
Location: [e.clientX, e.clientY + 20]
- })} >
+ }))} >
{links.length ? links.length : <FontAwesomeIcon className="documentdecorations-icon" icon="link" size="sm" />}
</div>
{DocumentLinksButton.StartLink && DocumentLinksButton.StartLink !== this.props.View ? <div className={"documentLinksButton-endLink"} onPointerDown={this.completeLink} /> : (null)}
@@ -101,4 +101,4 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
render() {
return this.linkButton;
}
-} \ No newline at end of file
+}
diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss
index b7726f7ba..b978f6245 100644
--- a/src/client/views/nodes/DocumentView.scss
+++ b/src/client/views/nodes/DocumentView.scss
@@ -42,6 +42,17 @@
width:10px !important;
}
}
+ .documentView-treeView {
+ max-height: 1.5em;
+ text-overflow: ellipsis;
+ display: inline-block;
+ white-space: pre;
+ width: 100%;
+ overflow: hidden;
+ > .documentView-node {
+ position: absolute;
+ }
+ }
.documentView-lock {
width: 20;
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index afd28534e..9a3516ea1 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -41,7 +41,6 @@ import "./DocumentView.scss";
import { LinkAnchorBox } from './LinkAnchorBox';
import { RadialMenu } from './RadialMenu';
import React = require("react");
-import { MobileInterface } from '../../../mobile/MobileInterface';
import { DocumentLinksButton } from './DocumentLinksButton';
library.add(fa.faEdit, fa.faTrash, fa.faShare, fa.faDownload, fa.faExpandArrowsAlt, fa.faCompressArrowsAlt, fa.faLayerGroup, fa.faExternalLinkAlt, fa.faAlignCenter, fa.faCaretSquareRight,
@@ -70,7 +69,7 @@ export interface DocumentViewProps {
onDoubleClick?: ScriptField;
onPointerDown?: ScriptField;
onPointerUp?: ScriptField;
- treeViewId?: string;
+ treeViewDoc?: Doc;
dropAction?: dropActionType;
dragDivName?: string;
nudge?: (x: number, y: number) => void;
@@ -124,7 +123,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
@computed get freezeDimensions() { return this.props.FreezeDimensions; }
@computed get nativeWidth() { return NumCast(this.layoutDoc._nativeWidth, this.props.NativeWidth() || (this.freezeDimensions ? this.layoutDoc[WidthSym]() : 0)); }
@computed get nativeHeight() { return NumCast(this.layoutDoc._nativeHeight, this.props.NativeHeight() || (this.freezeDimensions ? this.layoutDoc[HeightSym]() : 0)); }
- @computed get onClickHandler() { return this.props.onClick || Cast(this.layoutDoc.onClick, ScriptField, null); }
+ @computed get onClickHandler() { return this.props.onClick || Cast(this.Document.onClick, ScriptField, Cast(this.layoutDoc.onClick, ScriptField, null)); }
@computed get onDoubleClickHandler() { return this.props.onDoubleClick || Cast(this.layoutDoc.onDoubleClick, ScriptField, null) || this.Document.onDoubleClick; }
@computed get onPointerDownHandler() { return this.props.onPointerDown ? this.props.onPointerDown : this.Document.onPointerDown; }
@computed get onPointerUpHandler() { return this.props.onPointerUp ? this.props.onPointerUp : this.Document.onPointerUp; }
@@ -239,7 +238,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
dragData.removeDocument = this.props.removeDocument;
dragData.moveDocument = this.props.moveDocument;// this.layoutDoc.onDragStart ? undefined : this.props.moveDocument;
dragData.dragDivName = this.props.dragDivName;
- dragData.treeViewId = this.props.treeViewId;
+ dragData.treeViewDoc = this.props.treeViewDoc;
DragManager.StartDocumentDrag([this._mainCont.current], dragData, x, y, { hideSource: !dropAction && !this.layoutDoc.onDragStart });
}
}
@@ -376,7 +375,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
this._downX = touch.clientX;
this._downY = touch.clientY;
if (!e.nativeEvent.cancelBubble) {
- if ((this.active || this.layoutDoc.onDragStart || this.layoutDoc.onClick) && !e.ctrlKey && !this.layoutDoc.lockedPosition && !this.layoutDoc.inOverlay) e.stopPropagation();
+ if ((this.active || this.layoutDoc.onDragStart || this.onClickHandler) && !e.ctrlKey && !this.layoutDoc.lockedPosition && !this.layoutDoc.inOverlay) e.stopPropagation();
this.removeMoveListeners();
this.addMoveListeners();
this.removeEndListeners();
@@ -391,11 +390,11 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
if (e.cancelBubble && this.active) {
this.removeMoveListeners();
}
- else if (!e.cancelBubble && (SelectionManager.IsSelected(this, true) || this.props.parentActive(true) || this.layoutDoc.onDragStart || this.layoutDoc.onClick) && !this.layoutDoc.lockedPosition && !this.layoutDoc.inOverlay) {
+ else if (!e.cancelBubble && (SelectionManager.IsSelected(this, true) || this.props.parentActive(true) || this.layoutDoc.onDragStart || this.onClickHandler) && !this.layoutDoc.lockedPosition && !this.layoutDoc.inOverlay) {
const touch = me.touchEvent.changedTouches.item(0);
if (touch && (Math.abs(this._downX - touch.clientX) > 3 || Math.abs(this._downY - touch.clientY) > 3)) {
- if (!e.altKey && (!this.topMost || this.layoutDoc.onDragStart || this.layoutDoc.onClick)) {
+ if (!e.altKey && (!this.topMost || this.layoutDoc.onDragStart || this.onClickHandler)) {
this.cleanUpInteractions();
this.startDragging(this._downX, this._downY, this.Document.dropAction ? this.Document.dropAction as any : e.ctrlKey || e.altKey ? "alias" : undefined);
}
@@ -584,12 +583,12 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
@undoBatch
toggleLinkButtonBehavior = (): void => {
- if (this.Document.isLinkButton || this.layoutDoc.onClick || this.Document.ignoreClick) {
+ if (this.Document.isLinkButton || this.onClickHandler || this.Document.ignoreClick) {
this.Document.isLinkButton = false;
const first = DocListCast(this.Document.links).find(d => d instanceof Doc);
first && (first.hidden = false);
this.Document.ignoreClick = false;
- this.layoutDoc.onClick = undefined;
+ this.Document.onClick = this.layoutDoc.onClick = undefined;
} else {
this.Document.isLinkButton = true;
const first = DocListCast(this.Document.links).find(d => d instanceof Doc);
@@ -744,7 +743,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
this.props.contextMenuItems?.().forEach(item =>
cm?.addItem({ description: item.label, event: () => item.script.script.run({ this: this.layoutDoc, self: this.rootDoc }), icon: "sticky-note" }));
- let options = cm?.findByDescription("Options...");
+ const options = cm.findByDescription("Options...");
const optionItems: ContextMenuProps[] = options && "subitems" in options ? options.subitems : [];
const templateDoc = Cast(this.props.Document[StrCast(this.props.Document.layoutKey)], Doc, null);
templateDoc && optionItems.push({ description: "Open Template ", event: () => this.props.addDocTab(templateDoc, "onRight"), icon: "eye" });
@@ -754,11 +753,11 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
const existingOnClick = cm?.findByDescription("OnClick...");
const onClicks: ContextMenuProps[] = existingOnClick && "subitems" in existingOnClick ? existingOnClick.subitems : [];
onClicks.push({ description: "Enter Portal", event: this.makeIntoPortal, icon: "window-restore" });
- onClicks.push({ description: "Toggle Detail", event: () => this.layoutDoc.onClick = ScriptField.MakeScript(`toggleDetail(self, "${this.Document.layoutKey}")`), icon: "window-restore" });
+ onClicks.push({ description: "Toggle Detail", event: () => this.Document.onClick = ScriptField.MakeScript(`toggleDetail(self, "${this.Document.layoutKey}")`), icon: "window-restore" });
onClicks.push({ description: this.Document.ignoreClick ? "Select" : "Do Nothing", event: () => this.Document.ignoreClick = !this.Document.ignoreClick, icon: this.Document.ignoreClick ? "unlock" : "lock" });
onClicks.push({ description: this.Document.isLinkButton ? "Remove Follow Behavior" : "Follow Link in Place", event: this.toggleFollowInPlace, icon: "concierge-bell" });
onClicks.push({ description: this.Document.isLinkButton ? "Remove Follow Behavior" : "Follow Link on Right", event: this.toggleFollowOnRight, icon: "concierge-bell" });
- onClicks.push({ description: this.Document.isLinkButton || this.layoutDoc.onClick ? "Remove Click Behavior" : "Follow Link", event: this.toggleLinkButtonBehavior, icon: "concierge-bell" });
+ onClicks.push({ description: this.Document.isLinkButton || this.onClickHandler ? "Remove Click Behavior" : "Follow Link", event: this.toggleLinkButtonBehavior, icon: "concierge-bell" });
onClicks.push({ description: "Edit onClick Script", event: () => UndoManager.RunInBatch(() => DocUtils.makeCustomViewClicked(this.props.Document, undefined, "onClick"), "edit onClick"), icon: "edit" });
!existingOnClick && cm?.addItem({ description: "OnClick...", subitems: onClicks, icon: "hand-point-right" });
@@ -1073,30 +1072,34 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
anchorPanelHeight = () => this.props.PanelHeight() || 1;
@computed get anchors() {
TraceMobx();
- return this.props.forcedBackgroundColor?.(this.Document) === "transparent" || this.layoutDoc.presBox || this.props.dontRegisterView ? (null) : DocListCast(this.Document.links).filter(d => !d.hidden && this.isNonTemporalLink).map((d, i) =>
- <DocumentView {...this.props} key={i + 1}
- Document={d}
- ContainingCollectionView={this.props.ContainingCollectionView}
- ContainingCollectionDoc={this.props.Document} // bcz: hack this.props.Document is not a collection Need a better prop for passing the containing document to the LinkAnchorBox
- PanelWidth={this.anchorPanelWidth}
- PanelHeight={this.anchorPanelHeight}
- ContentScaling={returnOne}
- dontRegisterView={false}
- forcedBackgroundColor={returnTransparent}
- removeDocument={this.hideLinkAnchor}
- pointerEvents={false}
- LayoutTemplate={undefined}
- LayoutTemplateString={LinkAnchorBox.LayoutString(`anchor${Doc.LinkEndpoint(d, this.props.Document)}`)}
- />);
+ return (this.props.treeViewDoc && this.props.LayoutTemplateString) || // render nothing for: tree view anchor dots
+ this.layoutDoc.presBox || // presentationbox nodes
+ this.props.dontRegisterView ? (null) : // view that are not registered
+ DocListCast(this.Document.links).filter(d => !d.hidden && this.isNonTemporalLink).map((d, i) =>
+ <DocumentView {...this.props} key={i + 1}
+ Document={d}
+ ContainingCollectionView={this.props.ContainingCollectionView}
+ ContainingCollectionDoc={this.props.Document} // bcz: hack this.props.Document is not a collection Need a better prop for passing the containing document to the LinkAnchorBox
+ PanelWidth={this.anchorPanelWidth}
+ PanelHeight={this.anchorPanelHeight}
+ ContentScaling={returnOne}
+ dontRegisterView={false}
+ forcedBackgroundColor={returnTransparent}
+ removeDocument={this.hideLinkAnchor}
+ pointerEvents={false}
+ LayoutTemplate={undefined}
+ LayoutTemplateString={LinkAnchorBox.LayoutString(`anchor${Doc.LinkEndpoint(d, this.props.Document)}`)}
+ />);
}
@computed get innards() {
TraceMobx();
- if (!this.props.PanelWidth()) { // this happens when the document is a tree view label
- return <div className="documentView-linkAnchorBoxAnchor" >
+ if (this.props.treeViewDoc && !this.props.LayoutTemplateString) { // this happens when the document is a tree view label (but not an anchor dot)
+ return <div className="documentView-treeView" style={{ maxWidth: this.props.PanelWidth() || undefined }}>
{StrCast(this.props.Document.title)}
{this.anchors}
</div>;
}
+
const showTitle = StrCast(this.layoutDoc._showTitle);
const showTitleHover = StrCast(this.layoutDoc._showTitleHover);
const showCaption = StrCast(this.layoutDoc._showCaption);
@@ -1158,7 +1161,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
renderLock() {
return (this.Document.isBackground !== undefined || this.isSelected(false)) &&
((this.Document.type === DocumentType.COL && this.Document._viewType !== CollectionViewType.Pile) || this.Document.type === DocumentType.IMG) &&
- this.props.renderDepth > 0 && this.props.PanelWidth() > 0 ?
+ this.props.renderDepth > 0 && !this.props.treeViewDoc ?
<div className="documentView-lock" onClick={() => this.toggleBackground(true)}>
<FontAwesomeIcon icon={this.Document.isBackground ? "unlock" : "lock"} style={{ color: this.Document.isBackground ? "red" : undefined }} size="lg" />
</div>
@@ -1200,7 +1203,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
style={{
transformOrigin: this._animateScalingTo ? "center center" : undefined,
transform: this._animateScalingTo ? `scale(${this._animateScalingTo})` : undefined,
- transition: !this._animateScalingTo ? StrCast(this.Document.transition) : this._animateScalingTo < 1 ? "transform 0.5s ease-in" : "transform 0.5s ease-out",
+ transition: !this._animateScalingTo ? StrCast(this.Document.dataTransition) : this._animateScalingTo < 1 ? "transform 0.5s ease-in" : "transform 0.5s ease-out",
pointerEvents: this.ignorePointerEvents ? "none" : undefined,
color: StrCast(this.layoutDoc.color, "inherit"),
outline: highlighting && !borderRounding ? `${highlightColors[fullDegree]} ${highlightStyles[fullDegree]} ${localScale}px` : "solid 0px",
diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx
index d375466c9..b732f5f83 100644
--- a/src/client/views/nodes/KeyValueBox.tsx
+++ b/src/client/views/nodes/KeyValueBox.tsx
@@ -169,8 +169,8 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
getTemplate = async () => {
const parent = Docs.Create.StackingDocument([], { _width: 800, _height: 800, title: "Template" });
- parent.singleColumn = false;
- parent.columnWidth = 100;
+ parent._columnsStack = false;
+ parent._columnWidth = 100;
for (const row of this.rows.filter(row => row.isChecked)) {
await this.createTemplateField(parent, row);
row.uncheck();
diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx
index 2bcc6168b..d4ab70200 100644
--- a/src/client/views/nodes/LinkAnchorBox.tsx
+++ b/src/client/views/nodes/LinkAnchorBox.tsx
@@ -115,8 +115,9 @@ export class LinkAnchorBox extends ViewBoxBaseComponent<FieldViewProps, LinkAnch
render() {
TraceMobx();
- const x = this.props.PanelWidth() > 1 ? NumCast(this.rootDoc[this.fieldKey + "_x"], 100) : 0;
- const y = this.props.PanelWidth() > 1 ? NumCast(this.rootDoc[this.fieldKey + "_y"], 100) : 0;
+ const small = this.props.PanelWidth() <= 1; // this happens when rendered in a treeView
+ const x = NumCast(this.rootDoc[this.fieldKey + "_x"], 100);
+ const y = NumCast(this.rootDoc[this.fieldKey + "_y"], 100);
const c = StrCast(this.layoutDoc._backgroundColor, StrCast(this.layoutDoc.backgroundColor, StrCast(this.dataDoc.backgroundColor, "lightBlue"))); // note this is not where the typical lightBlue default color comes from. See Documents.Create.LinkDocument()
const anchor = this.fieldKey === "anchor1" ? "anchor2" : "anchor1";
const anchorScale = (x === 0 || x === 100 || y === 0 || y === 100) ? 1 : .25;
@@ -131,7 +132,6 @@ export class LinkAnchorBox extends ViewBoxBaseComponent<FieldViewProps, LinkAnch
</div>}
</div>
);
- const small = this.props.PanelWidth() <= 1;
return <div className={`linkAnchorBox-cont${small ? "-small" : ""} ${this.rootDoc[Id]}`}
onPointerLeave={action(() => LinkDocPreview.LinkInfo = undefined)}
onPointerEnter={action(e => LinkDocPreview.LinkInfo = {
@@ -143,8 +143,8 @@ export class LinkAnchorBox extends ViewBoxBaseComponent<FieldViewProps, LinkAnch
onPointerDown={this.onPointerDown} onClick={this.onClick} title={targetTitle} onContextMenu={this.specificContextMenu}
ref={this._ref} style={{
background: c,
- left: !small ? `calc(${x}% - 7.5px)` : undefined,
- top: !small ? `calc(${y}% - 7.5px)` : undefined,
+ left: `calc(${x}% - ${small ? 2.5 : 7.5}px)`,
+ top: `calc(${y}% - ${small ? 2.5 : 7.5}px)`,
transform: `scale(${anchorScale / this.props.ContentScaling()})`
}} >
{!this._editing && !this._forceOpen ? (null) :
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index 126dc240a..e8a08abb5 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -25,8 +25,8 @@ export class LinkDocPreview extends React.Component<Props> {
@observable _targetDoc: Opt<Doc>;
@observable _toolTipText = "";
- componentDidUpdate() { this.updatePreview() }
- componentDidMount() { this.updatePreview() }
+ componentDidUpdate() { this.updatePreview(); }
+ componentDidMount() { this.updatePreview(); }
async updatePreview() {
const linkDoc = this.props.linkDoc;
const linkSrc = this.props.linkSrc;
@@ -104,4 +104,4 @@ export class LinkDocPreview extends React.Component<Props> {
{this.targetDocView}
</div>;
}
-} \ No newline at end of file
+}
diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss
index fbbd49a2f..f2ab37984 100644
--- a/src/client/views/nodes/PDFBox.scss
+++ b/src/client/views/nodes/PDFBox.scss
@@ -1,7 +1,7 @@
.pdfBox,
.pdfBox-interactive {
display: inline-block;
- position: absolute;
+ position: relative;
height: 100%;
width: 100%;
overflow: hidden;
@@ -202,7 +202,7 @@
}
.pdfBox {
- .pdfViewer-text {
+ .pdfViewerDash-text {
.textLayer {
span {
user-select: none;
@@ -213,8 +213,7 @@
.pdfBox-interactive {
pointer-events: all;
-
- .pdfViewer-text {
+ .pdfViewerDash-text {
.textLayer {
span {
user-select: text;
@@ -293,4 +292,4 @@
width: 50px;
font-size: 30px;
}
-} \ No newline at end of file
+}
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index c1a0be9ea..54f44a0f9 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -55,25 +55,28 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps, PdfDocum
const backup = "oldPath";
const { Document } = this.props;
- const { url: { href } } = Cast(this.dataDoc[this.props.fieldKey], PdfField)!;
- const pathCorrectionTest = /upload\_[a-z0-9]{32}.(.*)/g;
- const matches = pathCorrectionTest.exec(href);
- console.log("\nHere's the { url } being fed into the outer regex:");
- console.log(href);
- console.log("And here's the 'properPath' build from the captured filename:\n");
- if (matches !== null && href.startsWith(window.location.origin)) {
- const properPath = Utils.prepend(`/files/pdfs/${matches[0]}`);
- console.log(properPath);
- if (!properPath.includes(href)) {
- console.log(`The two (url and proper path) were not equal`);
- const proto = Doc.GetProto(Document);
- proto[this.props.fieldKey] = new PdfField(properPath);
- proto[backup] = href;
+ const pdf = Cast(this.dataDoc[this.props.fieldKey], PdfField);
+ const href = pdf?.url?.href;
+ if (href) {
+ const pathCorrectionTest = /upload\_[a-z0-9]{32}.(.*)/g;
+ const matches = pathCorrectionTest.exec(href);
+ console.log("\nHere's the { url } being fed into the outer regex:");
+ console.log(href);
+ console.log("And here's the 'properPath' build from the captured filename:\n");
+ if (matches !== null && href.startsWith(window.location.origin)) {
+ const properPath = Utils.prepend(`/files/pdfs/${matches[0]}`);
+ console.log(properPath);
+ if (!properPath.includes(href)) {
+ console.log(`The two (url and proper path) were not equal`);
+ const proto = Doc.GetProto(Document);
+ proto[this.props.fieldKey] = new PdfField(properPath);
+ proto[backup] = href;
+ } else {
+ console.log(`The two (url and proper path) were equal`);
+ }
} else {
- console.log(`The two (url and proper path) were equal`);
+ console.log("Outer matches was null!");
}
- } else {
- console.log("Outer matches was null!");
}
}
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index dbc879920..8818d375e 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -62,8 +62,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps, PresBoxSchema>
const lastFrame = Cast(presTargetDoc.lastFrame, "number", null);
const curFrame = NumCast(presTargetDoc.currentFrame);
if (lastFrame !== undefined && curFrame < lastFrame) {
- presTargetDoc.transition = "all 1s";
- setTimeout(() => presTargetDoc.transition = undefined, 1010);
+ presTargetDoc._viewTransition = "all 1s";
+ setTimeout(() => presTargetDoc._viewTransition = undefined, 1010);
presTargetDoc.currentFrame = curFrame + 1;
}
else if (this.childDocs[this.itemIndex + 1] !== undefined) {
diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx
index 8c16f4a1a..8718bf329 100644
--- a/src/client/views/nodes/formattedText/DashFieldView.tsx
+++ b/src/client/views/nodes/formattedText/DashFieldView.tsx
@@ -184,9 +184,9 @@ export class DashFieldViewInternal extends React.Component<IDashFieldViewInterna
if (container) {
const alias = Doc.MakeAlias(container.props.Document);
alias.viewType = CollectionViewType.Time;
- let list = Cast(alias.schemaColumns, listSpec(SchemaHeaderField));
+ let list = Cast(alias._columnHeaders, listSpec(SchemaHeaderField));
if (!list) {
- alias.schemaColumns = list = new List<SchemaHeaderField>();
+ alias._columnHeaders = list = new List<SchemaHeaderField>();
}
list.map(c => c.heading).indexOf(this._fieldKey) === -1 && list.push(new SchemaHeaderField(this._fieldKey, "#f1efeb"));
list.map(c => c.heading).indexOf("text") === -1 && list.push(new SchemaHeaderField("text", "#f1efeb"));
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.scss b/src/client/views/nodes/formattedText/FormattedTextBox.scss
index 6ac6c57f4..0a094ba6a 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.scss
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.scss
@@ -306,37 +306,37 @@ footnote::after {
margin-left: 1em;
font-family: inherit;
}
- .bullet { p {display: inline; font-family: inherit} margin-left: 0; }
- .bullet1 { p {display: inline; font-family: inherit} }
- .bullet2,.bullet3,.bullet4,.bullet5,.bullet6 { p {display: inline; font-family: inherit} font-size: smaller; }
-
- .decimal1-ol { counter-reset: deci1; p {display: inline; font-family: inherit} margin-left: 0; }
- .decimal2-ol { counter-reset: deci2; p {display: inline; font-family: inherit} font-size: smaller; padding-left: 1em;}
- .decimal3-ol { counter-reset: deci3; p {display: inline; font-family: inherit} font-size: smaller; padding-left: 2em;}
- .decimal4-ol { counter-reset: deci4; p {display: inline; font-family: inherit} font-size: smaller; padding-left: 3em;}
- .decimal5-ol { counter-reset: deci5; p {display: inline; font-family: inherit} font-size: smaller; }
- .decimal6-ol { counter-reset: deci6; p {display: inline; font-family: inherit} font-size: smaller; }
- .decimal7-ol { counter-reset: deci7; p {display: inline; font-family: inherit} font-size: smaller; }
-
- .multi1-ol { counter-reset: multi1; p {display: inline; font-family: inherit} margin-left: 0; padding-left: 1.2em }
- .multi2-ol { counter-reset: multi2; p {display: inline; font-family: inherit} font-size: smaller; padding-left: 1.4em;}
- .multi3-ol { counter-reset: multi3; p {display: inline; font-family: inherit} font-size: smaller; padding-left: 2em;}
- .multi4-ol { counter-reset: multi4; p {display: inline; font-family: inherit} font-size: smaller; padding-left: 3.4em;}
-
- .bullet:before, .bullet1:before, .bullet2:before, .bullet3:before, .bullet4:before, .bullet5:before { transition: 0.5s; display: inline-block; margin-left: -1em; width: 1em; content:" " }
-
- .decimal1:before { transition: 0.5s;counter-increment: deci1; display: inline-block; margin-left: -1em; width: 1em; content: counter(deci1) ". "; }
- .decimal2:before { transition: 0.5s;counter-increment: deci2; display: inline-block; margin-left: -2.1em; width: 2.1em; content: counter(deci1) "."counter(deci2) ". "; }
- .decimal3:before { transition: 0.5s;counter-increment: deci3; display: inline-block; margin-left: -2.85em;width: 2.85em; content: counter(deci1) "."counter(deci2) "."counter(deci3) ". "; }
- .decimal4:before { transition: 0.5s;counter-increment: deci4; display: inline-block; margin-left: -3.85em;width: 3.85em; content: counter(deci1) "."counter(deci2) "."counter(deci3) "."counter(deci4) ". "; }
- .decimal5:before { transition: 0.5s;counter-increment: deci5; display: inline-block; margin-left: -2em; width: 5em; content: counter(deci1) "."counter(deci2) "."counter(deci3) "."counter(deci4) "."counter(deci5) ". "; }
- .decimal6:before { transition: 0.5s;counter-increment: deci6; display: inline-block; margin-left: -2em; width: 6em; content: counter(deci1) "."counter(deci2) "."counter(deci3) "."counter(deci4) "."counter(deci5) "."counter(deci6) ". "; }
- .decimal7:before { transition: 0.5s;counter-increment: deci7; display: inline-block; margin-left: -2em; width: 7em; content: counter(deci1) "."counter(deci2) "."counter(deci3) "."counter(deci4) "."counter(deci5) "."counter(deci6) "."counter(deci7) ". "; }
-
- .multi1:before { transition: 0.5s;counter-increment: multi1; display: inline-block; margin-left: -1em; width: 1.2em; content: counter(multi1, upper-alpha) ". "; }
- .multi2:before { transition: 0.5s;counter-increment: multi2; display: inline-block; margin-left: -2em; width: 2em; content: counter(multi1, upper-alpha) "."counter(multi2, decimal) ". "; }
- .multi3:before { transition: 0.5s;counter-increment: multi3; display: inline-block; margin-left: -2.85em; width:2.85em; content: counter(multi1, upper-alpha) "."counter(multi2, decimal) "."counter(multi3, lower-alpha) ". "; }
- .multi4:before { transition: 0.5s;counter-increment: multi4; display: inline-block; margin-left: -4.2em; width: 4.2em; content: counter(multi1, upper-alpha) "."counter(multi2, decimal) "."counter(multi3, lower-alpha) "."counter(multi4, lower-roman) ". "; }
+ .bullet { p {display: inline-block; font-family: inherit} margin-left: 0; }
+ .bullet1 { p {display: inline-block; font-family: inherit} }
+ .bullet2,.bullet3,.bullet4,.bullet5,.bullet6 { p {display: inline-block; font-family: inherit} font-size: smaller; }
+
+ .decimal1-ol { counter-reset: deci1; p {display: inline-block; font-family: inherit} margin-left: 0; }
+ .decimal2-ol { counter-reset: deci2; p {display: inline-block; font-family: inherit} font-size: smaller; padding-left: 1em;}
+ .decimal3-ol { counter-reset: deci3; p {display: inline-block; font-family: inherit} font-size: smaller; padding-left: 2em;}
+ .decimal4-ol { counter-reset: deci4; p {display: inline-block; font-family: inherit} font-size: smaller; padding-left: 3em;}
+ .decimal5-ol { counter-reset: deci5; p {display: inline-block; font-family: inherit} font-size: smaller; }
+ .decimal6-ol { counter-reset: deci6; p {display: inline-block; font-family: inherit} font-size: smaller; }
+ .decimal7-ol { counter-reset: deci7; p {display: inline-block; font-family: inherit} font-size: smaller; }
+
+ .multi1-ol { counter-reset: multi1; p {display: inline-block; font-family: inherit} margin-left: 0; padding-left: 1.2em }
+ .multi2-ol { counter-reset: multi2; p {display: inline-block; font-family: inherit} font-size: smaller; padding-left: 1.4em;}
+ .multi3-ol { counter-reset: multi3; p {display: inline-block; font-family: inherit} font-size: smaller; padding-left: 2em;}
+ .multi4-ol { counter-reset: multi4; p {display: inline-block; font-family: inherit} font-size: smaller; padding-left: 3.4em;}
+
+ .bullet:before, .bullet1:before, .bullet2:before, .bullet3:before, .bullet4:before, .bullet5:before { transition: 0.5s; display: inline-block; vertical-align: top; margin-left: -1em; width: 1em; content:" " }
+
+ .decimal1:before { transition: 0.5s;counter-increment: deci1; display: inline-block; vertical-align: top; margin-left: -1em; width: 1em; content: counter(deci1) ". "; }
+ .decimal2:before { transition: 0.5s;counter-increment: deci2; display: inline-block; vertical-align: top; margin-left: -2.1em; width: 2.1em; content: counter(deci1) "."counter(deci2) ". "; }
+ .decimal3:before { transition: 0.5s;counter-increment: deci3; display: inline-block; vertical-align: top; margin-left: -2.85em;width: 2.85em; content: counter(deci1) "."counter(deci2) "."counter(deci3) ". "; }
+ .decimal4:before { transition: 0.5s;counter-increment: deci4; display: inline-block; vertical-align: top; margin-left: -3.85em;width: 3.85em; content: counter(deci1) "."counter(deci2) "."counter(deci3) "."counter(deci4) ". "; }
+ .decimal5:before { transition: 0.5s;counter-increment: deci5; display: inline-block; vertical-align: top; margin-left: -2em; width: 5em; content: counter(deci1) "."counter(deci2) "."counter(deci3) "."counter(deci4) "."counter(deci5) ". "; }
+ .decimal6:before { transition: 0.5s;counter-increment: deci6; display: inline-block; vertical-align: top; margin-left: -2em; width: 6em; content: counter(deci1) "."counter(deci2) "."counter(deci3) "."counter(deci4) "."counter(deci5) "."counter(deci6) ". "; }
+ .decimal7:before { transition: 0.5s;counter-increment: deci7; display: inline-block; vertical-align: top; margin-left: -2em; width: 7em; content: counter(deci1) "."counter(deci2) "."counter(deci3) "."counter(deci4) "."counter(deci5) "."counter(deci6) "."counter(deci7) ". "; }
+
+ .multi1:before { transition: 0.5s;counter-increment: multi1; display: inline-block; vertical-align: top; margin-left: -1em; width: 1.2em; content: counter(multi1, upper-alpha) ". "; }
+ .multi2:before { transition: 0.5s;counter-increment: multi2; display: inline-block; vertical-align: top; margin-left: -2em; width: 2em; content: counter(multi1, upper-alpha) "."counter(multi2, decimal) ". "; }
+ .multi3:before { transition: 0.5s;counter-increment: multi3; display: inline-block; vertical-align: top; margin-left: -2.85em; width:2.85em; content: counter(multi1, upper-alpha) "."counter(multi2, decimal) "."counter(multi3, lower-alpha) ". "; }
+ .multi4:before { transition: 0.5s;counter-increment: multi4; display: inline-block; vertical-align: top; margin-left: -4.2em; width: 4.2em; content: counter(multi1, upper-alpha) "."counter(multi2, decimal) "."counter(multi3, lower-alpha) "."counter(multi4, lower-roman) ". "; }
}
.formattedTextBox-inner-rounded-selected,
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index b5591ca02..ae1db76de 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -4,7 +4,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { isEqual } from "lodash";
import { action, computed, IReactionDisposer, Lambda, observable, reaction, runInAction } from "mobx";
import { observer } from "mobx-react";
-import { baseKeymap } from "prosemirror-commands";
+import { baseKeymap, selectAll } from "prosemirror-commands";
import { history } from "prosemirror-history";
import { inputRules } from 'prosemirror-inputrules';
import { keymap } from "prosemirror-keymap";
@@ -102,6 +102,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
public static FocusedBox: FormattedTextBox | undefined;
public static SelectOnLoad = "";
+ public static PasteOnLoad: ClipboardEvent | undefined;
public static SelectOnLoadChar = "";
public static IsFragment(html: string) {
return html.indexOf("data-pm-slice") !== -1;
@@ -276,6 +277,12 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
const end = this._editorView.state.doc.nodeSize - 2;
this._editorView.dispatch(this._editorView.state.tr.removeMark(0, end, mark).removeMark(0, end, activeMark));
}
+ if (FormattedTextBox.PasteOnLoad) {
+ const pdfDocId = FormattedTextBox.PasteOnLoad.clipboardData?.getData("dash/pdfOrigin");
+ const pdfRegionId = FormattedTextBox.PasteOnLoad.clipboardData?.getData("dash/pdfRegion");
+ FormattedTextBox.PasteOnLoad = undefined;
+ setTimeout(() => pdfDocId && pdfRegionId && this.addPdfReference(pdfDocId, pdfRegionId, undefined), 10);
+ }
}
adoptAnnotation = (start: number, end: number, mark: Mark) => {
const view = this._editorView!;
@@ -731,7 +738,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
}
const marks = [...node.marks];
const linkIndex = marks.findIndex(mark => mark.type === editor.state.schema.marks.link);
- return linkIndex !== -1 && marks[linkIndex].attrs.allRefs.find((item: { href: string }) => scrollToLinkID === item.href.replace(/.*\/doc\//, "")) ? node : undefined;
+ return linkIndex !== -1 && marks[linkIndex].attrs.allHrefs.find((item: { href: string }) => scrollToLinkID === item.href.replace(/.*\/doc\//, "")) ? node : undefined;
};
let start = 0;
@@ -862,8 +869,13 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
handlePaste = (view: EditorView, event: Event, slice: Slice): boolean => {
const cbe = event as ClipboardEvent;
- const pdfDocId = cbe.clipboardData && cbe.clipboardData.getData("dash/pdfOrigin");
- const pdfRegionId = cbe.clipboardData && cbe.clipboardData.getData("dash/pdfRegion");
+ const pdfDocId = cbe.clipboardData?.getData("dash/pdfOrigin");
+ const pdfRegionId = cbe.clipboardData?.getData("dash/pdfRegion");
+ return pdfDocId && pdfRegionId && this.addPdfReference(pdfDocId, pdfRegionId, slice) ? true : false;
+ }
+
+ addPdfReference = (pdfDocId: string, pdfRegionId: string, slice?: Slice) => {
+ const view = this._editorView!;
if (pdfDocId && pdfRegionId) {
DocServer.GetRefField(pdfDocId).then(pdfDoc => {
DocServer.GetRefField(pdfRegionId).then(pdfRegion => {
@@ -871,17 +883,22 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
setTimeout(async () => {
const targetField = Doc.LayoutFieldKey(pdfDoc);
const targetAnnotations = await DocListCastAsync(pdfDoc[DataSym][targetField + "-annotations"]);// bcz: better to have the PDF's view handle updating its own annotations
- targetAnnotations?.push(pdfRegion);
+ if (targetAnnotations) targetAnnotations.push(pdfRegion);
+ else Doc.AddDocToList(pdfDoc[DataSym], targetField + "-annotations", pdfRegion);
});
const link = DocUtils.MakeLink({ doc: this.rootDoc }, { doc: pdfRegion }, "PDF pasted");
if (link) {
- cbe.clipboardData!.setData("dash/linkDoc", link[Id]);
const linkId = link[Id];
- const frag = addMarkToFrag(slice.content, (node: Node) => addLinkMark(node, StrCast(pdfDoc.title), linkId));
- slice = new Slice(frag, slice.openStart, slice.openEnd);
- const tr = view.state.tr.replaceSelection(slice);
- view.dispatch(tr.scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste"));
+ const quote = view.state.schema.nodes.blockquote.create();
+ quote.content = addMarkToFrag(slice?.content || view.state.doc.content, (node: Node) => addLinkMark(node, StrCast(pdfDoc.title), linkId));
+ const newSlice = new Slice(Fragment.from(quote), slice?.openStart || 0, slice?.openEnd || 0);
+ if (slice) {
+ view.dispatch(view.state.tr.replaceSelection(newSlice).scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste"));
+ } else {
+ selectAll(view.state, (tx: Transaction) => view.dispatch(tx.replaceSelection(newSlice).scrollIntoView()));
+
+ }
}
}
});
@@ -903,7 +920,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
}
const marks = [...node.marks];
const linkIndex = marks.findIndex(mark => mark.type.name === "link");
- const link = view.state.schema.mark(view.state.schema.marks.link, { href: Utils.prepend(`/doc/${linkId}`), location: "onRight", title: title, docref: true });
+ const allHrefs = [{ href: Utils.prepend(`/doc/${linkId}`), title, linkId }];
+ const link = view.state.schema.mark(view.state.schema.marks.link, { allHrefs, location: "onRight", title, docref: true });
marks.splice(linkIndex === -1 ? 0 : linkIndex, 1, link);
return node.mark(marks);
}
@@ -938,7 +956,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
clipboardTextSerializer: this.clipboardTextSerializer,
handlePaste: this.handlePaste,
});
- //applyDevTools.applyDevTools(this._editorView);
+ !Doc.UserDoc().noviceMode && applyDevTools.applyDevTools(this._editorView);
const startupText = !rtfField && this._editorView && Field.toString(this.dataDoc[fieldKey] as Field);
if (startupText) {
const { state: { tr }, dispatch } = this._editorView;
@@ -1018,9 +1036,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
const editor = this._editorView!;
FormattedTextBoxComment.textBox = this;
const pcords = editor.posAtCoords({ left: e.clientX, top: e.clientY });
- const node = pcords && editor.state.doc.nodeAt(pcords.pos); // get what prosemirror thinks the clicked node is (if it's null, then we didn't click on any text)
- !this.props.isSelected(true) && editor.dispatch(editor.state.tr.setSelection(node && pcords ?
- new NodeSelection(editor.state.doc.resolve(pcords.pos)) : new TextSelection(editor.state.doc.resolve(pcords?.pos || 0))));
+ !this.props.isSelected(true) && editor.dispatch(editor.state.tr.setSelection(new TextSelection(editor.state.doc.resolve(pcords?.pos || 0))));
FormattedTextBoxComment.update(editor, undefined, (e.target as any)?.className === "prosemirror-dropdownlink" ? (e.target as any).href : "");
}
(e.nativeEvent as any).formattedHandled = true;
@@ -1198,6 +1214,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
}
}
+ ondrop = (eve: React.DragEvent) => {
+ eve.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.
+ }
onscrolled = (ev: React.UIEvent) => {
this.layoutDoc._scrollTop = this._scrollRef.current!.scrollTop;
}
@@ -1205,13 +1224,13 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
tryUpdateHeight(limitHeight?: number) {
let scrollHeight = this._ref.current?.scrollHeight;
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.scale, 1);
+ scrollHeight = scrollHeight * NumCast(this.layoutDoc._viewScale, 1);
if (limitHeight && scrollHeight > limitHeight) {
scrollHeight = limitHeight;
this.layoutDoc.limitHeight = undefined;
this.layoutDoc._autoHeight = false;
}
- const nh = this.layoutDoc.isTemplateForField ? 0 : NumCast(this.dataDoc._nativeHeight, 0);
+ const nh = this.layoutDoc.isTemplateForField ? 0 : NumCast(this.layoutDoc._nativeHeight, 0);
const dh = NumCast(this.rootDoc._height, 0);
const newHeight = Math.max(10, (nh ? dh / nh * scrollHeight : scrollHeight) + (this.props.ChromeHeight ? this.props.ChromeHeight() : 0));
if (this.rootDoc !== this.layoutDoc.doc && !this.layoutDoc.resolvedDataDoc) {
@@ -1219,11 +1238,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
console.log("Delayed height adjustment...");
setTimeout(() => {
this.rootDoc._height = newHeight;
- this.dataDoc._nativeHeight = nh ? scrollHeight : undefined;
+ this.layoutDoc._nativeHeight = nh ? scrollHeight : undefined;
}, 10);
} else {
- this.rootDoc._height = newHeight;
- this.dataDoc._nativeHeight = nh ? scrollHeight : undefined;
+ this.layoutDoc._height = newHeight;
+ this.layoutDoc._nativeHeight = nh ? scrollHeight : undefined;
}
}
}
@@ -1234,7 +1253,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
@computed get sidebarColor() { return StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], StrCast(this.layoutDoc[this.props.fieldKey + "-backgroundColor"], "transparent")); }
render() {
TraceMobx();
- const scale = this.props.ContentScaling() * NumCast(this.layoutDoc.scale, 1);
+ const scale = this.props.ContentScaling() * NumCast(this.layoutDoc._viewScale, 1);
const rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : "";
const interactive = Doc.GetSelectedTool() === InkTool.None && !this.layoutDoc.isBackground;
if (this.props.isSelected()) {
@@ -1286,7 +1305,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
}
})}
>
- <div className={`formattedTextBox-outer`} style={{ width: `calc(100% - ${this.sidebarWidthPercent})`, pointerEvents: !this.props.isSelected() ? "none" : undefined }} onScroll={this.onscrolled} ref={this._scrollRef}>
+ <div className={`formattedTextBox-outer`} ref={this._scrollRef}
+ style={{ width: `calc(100% - ${this.sidebarWidthPercent})`, pointerEvents: !this.props.isSelected() ? "none" : undefined }}
+ onScroll={this.onscrolled} onDrop={this.ondrop} >
<div className={`formattedTextBox-inner${rounded}${selclass}`} ref={this.createDropTarget}
style={{
padding: `${Math.max(0, NumCast(this.layoutDoc._yMargin, this.props.yMargin || 0) + selPad)}px ${NumCast(this.layoutDoc._xMargin, this.props.xMargin || 0) + selPad}px`,
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index 0d8e22251..90f2c0aa6 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -177,11 +177,12 @@ export class FormattedTextBoxComment {
// this checks if the selection is a hyperlink. If so, it displays the target doc's text for internal links, and the url of the target for external links.
if (set === "none" && state.selection.$from) {
nbef = findStartOfMark(state.selection.$from, view, findLinkMark);
- const naft = findEndOfMark(state.selection.$from, view, findLinkMark);
+ const naft = findEndOfMark(state.selection.$from, view, findLinkMark) || nbef;
let child: any = null;
state.doc.nodesBetween(state.selection.from, state.selection.to, (node: any, pos: number, parent: any) => !child && node.marks.length && (child = node));
- const mark = child && findLinkMark(child.marks);
- const href = mark?.attrs.allHrefs.find((item: { href: string }) => item.href)?.href || forceUrl;
+ child = child || (nbef && state.selection.$from.nodeBefore);
+ const mark = child ? findLinkMark(child.marks) : undefined;
+ const href = (!mark?.attrs.docref || naft === nbef) && mark?.attrs.allHrefs.find((item: { href: string }) => item.href)?.href || forceUrl;
if (forceUrl || (href && child && nbef && naft && mark?.attrs.showPreview)) {
FormattedTextBoxComment.tooltipText.textContent = "external => " + href;
(FormattedTextBoxComment.tooltipText as any).href = href;
diff --git a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
index 9c91d8007..1bbcb9fa8 100644
--- a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
+++ b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts
@@ -1,4 +1,4 @@
-import { chainCommands, exitCode, joinDown, joinUp, lift, selectParentNode, setBlockType, splitBlockKeepMarks, toggleMark, wrapIn, newlineInCode } from "prosemirror-commands";
+import { chainCommands, exitCode, joinDown, joinUp, lift, deleteSelection, joinBackward, selectNodeBackward, setBlockType, splitBlockKeepMarks, toggleMark, wrapIn, newlineInCode } from "prosemirror-commands";
import { liftTarget } from "prosemirror-transform";
import { redo, undo } from "prosemirror-history";
import { undoInputRule } from "prosemirror-inputrules";
@@ -12,6 +12,7 @@ import { Doc, DataSym } from "../../../../fields/Doc";
import { FormattedTextBox } from "./FormattedTextBox";
import { Id } from "../../../../fields/FieldSymbols";
import { Docs } from "../../../documents/Documents";
+import { update } from "lodash";
const mac = typeof navigator !== "undefined" ? /Mac/.test(navigator.platform) : false;
@@ -43,7 +44,6 @@ export default function buildKeymap<S extends Schema<any>>(schema: S, props: any
//History commands
bind("Mod-z", undo);
- bind("Backspace", undoInputRule);
bind("Shift-Mod-z", redo);
!mac && bind("Mod-y", redo);
@@ -175,6 +175,25 @@ export default function buildKeymap<S extends Schema<any>>(schema: S, props: any
}
});
+ // backspace = chainCommands(deleteSelection, joinBackward, selectNodeBackward);
+ bind("Backspace", (state: EditorState<S>, dispatch: (tx: Transaction<Schema<any, any>>) => void) => {
+ if (!deleteSelection(state, (tx: Transaction<Schema<any, any>>) => {
+ dispatch(updateBullets(tx, schema));
+ })) {
+ if (!joinBackward(state, (tx: Transaction<Schema<any, any>>) => {
+ dispatch(updateBullets(tx, schema));
+ })) {
+ if (!selectNodeBackward(state, (tx: Transaction<Schema<any, any>>) => {
+ dispatch(updateBullets(tx, schema));
+ })) {
+ return false;
+ }
+ }
+ }
+ return true;
+ });
+
+ //newlineInCode, createParagraphNear, liftEmptyBlock, splitBlock
//command to break line
bind("Enter", (state: EditorState<S>, dispatch: (tx: Transaction<Schema<any, any>>) => void) => {
if (addTextOnRight(false)) return true;
@@ -190,7 +209,12 @@ export default function buildKeymap<S extends Schema<any>>(schema: S, props: any
const marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks());
const cr = state.selection.$from.node().textContent.endsWith("\n");
if (cr || !newlineInCode(state, dispatch)) {
- if (!splitListItem(schema.nodes.list_item)(state, dispatch)) {
+ if (!splitListItem(schema.nodes.list_item)(state, (tx2: Transaction) => {
+ const tx3 = updateBullets(tx2, schema);
+ marks && tx3.ensureMarks([...marks]);
+ marks && tx3.setStoredMarks([...marks]);
+ dispatch(tx3);
+ })) {
if (!splitBlockKeepMarks(state, (tx3: Transaction) => {
splitMetadata(marks, tx3);
if (!liftListItem(schema.nodes.list_item)(tx3, dispatch as ((tx: Transaction<Schema<any, any>>) => void))) {
diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts
index ba3230801..6a85e3b7c 100644
--- a/src/client/views/nodes/formattedText/RichTextRules.ts
+++ b/src/client/views/nodes/formattedText/RichTextRules.ts
@@ -275,7 +275,7 @@ export class RichTextRules {
if (!fieldKey) {
if (docid) {
DocServer.GetRefField(docid).then(docx => {
- const target = ((docx instanceof Doc) && docx) || Docs.Create.FreeformDocument([], { title: docid, _width: 500, _height: 500, _LODdisable: true, }, docid);
+ const target = ((docx instanceof Doc) && docx) || Docs.Create.FreeformDocument([], { title: docid, _width: 500, _height: 500, }, docid);
DocUtils.Publish(target, docid, returnFalse, returnFalse);
DocUtils.MakeLink({ doc: this.Document }, { doc: target }, "portal to");
});
@@ -305,7 +305,7 @@ export class RichTextRules {
if (!fieldKey && !docid) return state.tr;
docid && DocServer.GetRefField(docid).then(docx => {
if (!(docx instanceof Doc && docx)) {
- const docx = Docs.Create.FreeformDocument([], { title: docid, _width: 500, _height: 500, _LODdisable: true }, docid);
+ const docx = Docs.Create.FreeformDocument([], { title: docid, _width: 500, _height: 500 }, docid);
DocUtils.Publish(docx, docid, returnFalse, returnFalse);
}
});
diff --git a/src/client/views/nodes/formattedText/marks_rts.ts b/src/client/views/nodes/formattedText/marks_rts.ts
index 1de211f28..b09ac0678 100644
--- a/src/client/views/nodes/formattedText/marks_rts.ts
+++ b/src/client/views/nodes/formattedText/marks_rts.ts
@@ -38,7 +38,7 @@ export const marks: { [index: string]: MarkSpec } = {
const targetids = node.attrs.allHrefs.reduce((p: string, item: { href: string, title: string, targetId: string, linkId: string }) => p + " " + item.targetId, "");
const linkids = node.attrs.allHrefs.reduce((p: string, item: { href: string, title: string, targetId: string, linkId: string }) => p + " " + item.linkId, "");
return node.attrs.docref && node.attrs.title ?
- ["div", ["span", `"`], ["span", 0], ["span", `"`], ["br"], ["a", { ...node.attrs, class: "prosemirror-attribution", title: `${node.attrs.title}` }, node.attrs.title], ["br"]] :
+ ["div", ["span", `"`], ["span", 0], ["span", `"`], ["br"], ["a", { ...node.attrs, href: node.attrs.allHrefs[0].href, class: "prosemirror-attribution" }, node.attrs.title], ["br"]] :
node.attrs.allHrefs.length === 1 ?
["a", { ...node.attrs, class: linkids, targetids, title: `${node.attrs.title}`, href: node.attrs.allHrefs[0].href }, 0] :
["div", { class: "prosemirror-anchor" },
diff --git a/src/client/views/nodes/formattedText/nodes_rts.ts b/src/client/views/nodes/formattedText/nodes_rts.ts
index 0a867912f..afb1f57b7 100644
--- a/src/client/views/nodes/formattedText/nodes_rts.ts
+++ b/src/client/views/nodes/formattedText/nodes_rts.ts
@@ -302,7 +302,7 @@ export const nodes: { [index: string]: NodeSpec } = {
mapStyle: { default: "decimal" }, // "decimal", "multi", "bullet"
visibility: { default: true }
},
- content: 'paragraph block*',
+ content: 'paragraph+ | (paragraph ordered_list)',
parseDOM: [{
tag: "li", getAttrs(dom: any) {
return { mapStyle: dom.getAttribute("data-mapStyle"), bulletStyle: dom.getAttribute("data-bulletStyle") };