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/AudioBox.tsx37
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx19
-rw-r--r--src/client/views/nodes/ColorBox.tsx4
-rw-r--r--src/client/views/nodes/ComparisonBox.tsx28
-rw-r--r--src/client/views/nodes/DataVizBox/DataVizBox.tsx18
-rw-r--r--src/client/views/nodes/DataVizBox/components/LineChart.tsx14
-rw-r--r--src/client/views/nodes/DataVizBox/components/TableBox.tsx12
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx12
-rw-r--r--src/client/views/nodes/DocumentIcon.tsx56
-rw-r--r--src/client/views/nodes/DocumentLinksButton.tsx6
-rw-r--r--src/client/views/nodes/DocumentView.tsx148
-rw-r--r--src/client/views/nodes/EquationBox.tsx2
-rw-r--r--src/client/views/nodes/FieldView.tsx50
-rw-r--r--src/client/views/nodes/FunctionPlotBox.tsx2
-rw-r--r--src/client/views/nodes/ImageBox.tsx90
-rw-r--r--src/client/views/nodes/KeyValueBox.tsx38
-rw-r--r--src/client/views/nodes/KeyValuePair.scss68
-rw-r--r--src/client/views/nodes/KeyValuePair.tsx14
-rw-r--r--src/client/views/nodes/LabelBox.tsx8
-rw-r--r--src/client/views/nodes/LinkAnchorBox.tsx16
-rw-r--r--src/client/views/nodes/LinkBox.tsx4
-rw-r--r--src/client/views/nodes/LinkDescriptionPopup.tsx2
-rw-r--r--src/client/views/nodes/LinkDocPreview.tsx20
-rw-r--r--src/client/views/nodes/MapBox/MapBox.tsx42
-rw-r--r--src/client/views/nodes/MapBox/MapBox2.tsx68
-rw-r--r--src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx6
-rw-r--r--src/client/views/nodes/PDFBox.tsx72
-rw-r--r--src/client/views/nodes/RecordingBox/RecordingBox.tsx2
-rw-r--r--src/client/views/nodes/ScreenshotBox.tsx12
-rw-r--r--src/client/views/nodes/ScriptingBox.tsx10
-rw-r--r--src/client/views/nodes/VideoBox.tsx102
-rw-r--r--src/client/views/nodes/WebBox.tsx454
-rw-r--r--src/client/views/nodes/button/FontIconBox.tsx254
-rw-r--r--src/client/views/nodes/formattedText/DashDocView.tsx45
-rw-r--r--src/client/views/nodes/formattedText/DashFieldView.tsx163
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.scss2
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx244
-rw-r--r--src/client/views/nodes/formattedText/RichTextMenu.tsx14
-rw-r--r--src/client/views/nodes/formattedText/RichTextRules.ts28
-rw-r--r--src/client/views/nodes/formattedText/marks_rts.ts2
-rw-r--r--src/client/views/nodes/formattedText/nodes_rts.ts2
-rw-r--r--src/client/views/nodes/trails/PresBox.tsx117
-rw-r--r--src/client/views/nodes/trails/PresElementBox.tsx8
43 files changed, 1113 insertions, 1202 deletions
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 68fb19208..8e83cf121 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -76,7 +76,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
return DateCast(this.dataDoc[this.fieldKey + '-recordingStart'])?.date.getTime();
}
@computed get rawDuration() {
- return NumCast(this.dataDoc[`${this.fieldKey}-duration`]);
+ return NumCast(this.dataDoc[`${this.fieldKey}_duration`]);
} // bcz: shouldn't be needed since it's computed from audio element
// mehek: not 100% sure but i think due to the order in which things are loaded this is necessary ^^
// if you get rid of it and set the value to 0 the timeline and waveform will set their bounds incorrectly
@@ -123,12 +123,12 @@ export class AudioBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
}
getLinkData(l: Doc) {
- let la1 = l.anchor1 as Doc;
- let la2 = l.anchor2 as Doc;
+ let la1 = l.link_anchor_1 as Doc;
+ let la2 = l.link_anchor_2 as Doc;
const linkTime = this.timeline?.anchorStart(la2) || this.timeline?.anchorStart(la1) || 0;
if (Doc.AreProtosEqual(la1, this.dataDoc)) {
- la1 = l.anchor2 as Doc;
- la2 = l.anchor1 as Doc;
+ la1 = l.link_anchor_2 as Doc;
+ la2 = l.link_anchor_1 as Doc;
}
return { la1, la2, linkTime };
}
@@ -139,7 +139,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
this.rootDoc,
this.dataDoc,
this.annotationKey,
- this._ele?.currentTime || Cast(this.props.Document._currentTimecode, 'number', null) || (this.mediaState === media_state.Recording ? (Date.now() - (this.recordingStart || 0)) / 1000 : undefined),
+ this._ele?.currentTime || Cast(this.props.Document._layout_currentTimecode, 'number', null) || (this.mediaState === media_state.Recording ? (Date.now() - (this.recordingStart || 0)) / 1000 : undefined),
undefined,
undefined,
addAsAnnotation
@@ -155,12 +155,12 @@ export class AudioBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
this.links
.map(l => this.getLinkData(l))
.forEach(({ la1, la2, linkTime }) => {
- if (linkTime > NumCast(this.layoutDoc._currentTimecode) && linkTime < this._ele!.currentTime) {
+ if (linkTime > NumCast(this.layoutDoc._layout_currentTimecode) && linkTime < this._ele!.currentTime) {
Doc.linkFollowHighlight(la1);
}
});
- this.layoutDoc._currentTimecode = this._ele.currentTime;
- this.timeline?.scrollToTime(NumCast(this.layoutDoc._currentTimecode));
+ this.layoutDoc._layout_currentTimecode = this._ele.currentTime;
+ this.timeline?.scrollToTime(NumCast(this.layoutDoc._layout_currentTimecode));
}
};
@@ -221,7 +221,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
if (this.mediaState === media_state.Recording) {
setTimeout(this.updateRecordTime, 30);
if (!this._paused) {
- this.layoutDoc._currentTimecode = (new Date().getTime() - this._recordStart - this._pausedTime) / 1000;
+ this.layoutDoc._layout_currentTimecode = (new Date().getTime() - this._recordStart - this._pausedTime) / 1000;
}
}
};
@@ -253,7 +253,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
this._recorder = undefined;
const now = new Date().getTime();
this._paused && (this._pausedTime += now - this._pauseStart);
- this.dataDoc[this.fieldKey + '-duration'] = (now - this._recordStart - this._pausedTime) / 1000;
+ this.dataDoc[this.fieldKey + '_duration'] = (now - this._recordStart - this._pausedTime) / 1000;
this.mediaState = media_state.Paused;
this._stream?.getAudioTracks()[0].stop();
const ind = DocUtils.ActiveRecordings.indexOf(this);
@@ -422,11 +422,11 @@ export class AudioBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
if (!this.layoutDoc.dontAutoPlayFollowedLinks) {
this.playFrom(this.timeline?.anchorStart(link) || 0, this.timeline?.anchorEnd(link));
} else {
- this._ele!.currentTime = this.layoutDoc._currentTimecode = this.timeline?.anchorStart(link) || 0;
+ this._ele!.currentTime = this.layoutDoc._layout_currentTimecode = this.timeline?.anchorStart(link) || 0;
}
} else {
this.links
- .filter(l => l.anchor1 === link || l.anchor2 === link)
+ .filter(l => l.link_anchor_1 === link || l.link_anchor_2 === link)
.forEach(l => {
const { la1, la2 } = this.getLinkData(l);
const startTime = this.timeline?.anchorStart(la1) || this.timeline?.anchorStart(la2);
@@ -435,7 +435,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
if (!this.layoutDoc.dontAutoPlayFollowedLinks) {
this.playFrom(startTime, endTime);
} else {
- this._ele!.currentTime = this.layoutDoc._currentTimecode = startTime;
+ this._ele!.currentTime = this.layoutDoc._layout_currentTimecode = startTime;
}
}
});
@@ -447,7 +447,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
timelineScreenToLocal = () => this.props.ScreenToLocalTransform().translate(0, -AudioBox.topControlsHeight);
- setPlayheadTime = (time: number) => (this._ele!.currentTime = this.layoutDoc._currentTimecode = time);
+ setPlayheadTime = (time: number) => (this._ele!.currentTime = this.layoutDoc._layout_currentTimecode = time);
playing = () => this.mediaState === media_state.Playing;
@@ -547,7 +547,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
<div className="record-button" onPointerDown={this._paused ? this.recordPlay : this.recordPause}>
<FontAwesomeIcon size="2x" icon={this._paused ? 'play' : 'pause'} />
</div>
- <div className="record-timecode">{formatTime(Math.round(NumCast(this.layoutDoc._currentTimecode)))}</div>
+ <div className="record-timecode">{formatTime(Math.round(NumCast(this.layoutDoc._layout_currentTimecode)))}</div>
</div>
) : (
<div className="audiobox-start-record" onPointerDown={this.Record}>
@@ -623,7 +623,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
{this.audio}
<div className="audiobox-timecodes">
- <div className="timecode-current">{this.timeline && formatTime(Math.round(NumCast(this.layoutDoc._currentTimecode) - NumCast(this.timeline.clipStart)))}</div>
+ <div className="timecode-current">{this.timeline && formatTime(Math.round(NumCast(this.layoutDoc._layout_currentTimecode) - NumCast(this.timeline.clipStart)))}</div>
{this.miniPlayer ? (
<div>/</div>
) : (
@@ -656,6 +656,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
ref={action((r: any) => (this._stackedTimeline = r))}
{...this.props}
CollectionFreeFormDocumentView={undefined}
+ dataFieldKey={this.fieldKey}
fieldKey={this.annotationKey}
dictationKey={this.fieldKey + '-dictation'}
mediaPath={this.path}
@@ -689,7 +690,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
<audio
ref={this.setRef}
className={`audiobox-control${this.props.isContentActive() ? '-interactive' : ''}`}
- onLoadedData={action(e => this._ele?.duration && this._ele?.duration !== Infinity && (this.dataDoc[this.fieldKey + '-duration'] = this._ele.duration))}>
+ onLoadedData={action(e => this._ele?.duration && this._ele?.duration !== Infinity && (this.dataDoc[this.fieldKey + '_duration'] = this._ele.duration))}>
<source src={this.path} type="audio/mpeg" />
Not supported.
</audio>
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index a8c8a0d2e..6710cee63 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -12,12 +12,11 @@ import { SelectionManager } from '../../util/SelectionManager';
import { Transform } from '../../util/Transform';
import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView';
import { DocComponent } from '../DocComponent';
+import { InkingStroke } from '../InkingStroke';
import { StyleProp } from '../StyleProvider';
import './CollectionFreeFormDocumentView.scss';
import { DocumentView, DocumentViewProps, OpenWhere } from './DocumentView';
import React = require('react');
-import { DocumentType } from '../../documents/DocumentTypes';
-import { InkingStroke } from '../InkingStroke';
export interface CollectionFreeFormDocumentViewProps extends DocumentViewProps {
dataProvider?: (doc: Doc, replica: string) => { x: number; y: number; zIndex?: number; rotation?: number; color?: string; backgroundColor?: string; opacity?: number; highlight?: boolean; z: number; transition?: string } | undefined;
@@ -37,13 +36,13 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
{ key: 'x' },
{ key: 'y' },
{ key: '_rotation', val: 0 },
- { key: '_scrollTop' },
+ { key: '_layout_scrollTop' },
{ key: 'opacity', val: 1 },
{ key: '_currentFrame' },
- { key: 'viewScale', val: 1 },
- { key: 'viewScale', val: 1 },
- { key: 'panX' },
- { key: 'panY' },
+ { key: 'freeform_scale', val: 1 },
+ { key: 'freeform_scale', val: 1 },
+ { key: 'freeform_panX' },
+ { key: 'freeform_panY' },
]; // fields that are configured to be animatable using animation frames
public static animStringFields = ['backgroundColor', 'color', 'fillColor']; // fields that are configured to be animatable using animation frames
public static animDataFields = (doc: Doc) => (Doc.LayoutFieldKey(doc) ? [Doc.LayoutFieldKey(doc)] : []); // fields that are configured to be animatable using animation frames
@@ -155,8 +154,8 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
CollectionFreeFormDocumentView.animStringFields.forEach(val => (doc[val] = ComputedField.MakeInterpolatedString(val, 'activeFrame', doc, currTimecode)));
CollectionFreeFormDocumentView.animDataFields(doc).forEach(val => (doc[val] = ComputedField.MakeInterpolatedDataField(val, 'activeFrame', doc, currTimecode)));
const targetDoc = doc; // data fields, like rtf 'text' exist on the data doc, so
- //doc !== targetDoc && (targetDoc.context = doc.context); // the computed fields don't see the layout doc -- need to copy the context to the data doc (HACK!!!) and set the activeFrame on the data doc (HACK!!!)
- targetDoc.activeFrame = ComputedField.MakeFunction('self.context?._currentFrame||0');
+ //doc !== targetDoc && (targetDoc.embedContainer = doc.embedContainer); // the computed fields don't see the layout doc -- need to copy the embedContainer to the data doc (HACK!!!) and set the activeFrame on the data doc (HACK!!!)
+ targetDoc.activeFrame = ComputedField.MakeFunction('self.embedContainer?._currentFrame||0');
targetDoc.dataTransition = 'inherit';
});
}
@@ -203,7 +202,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
PanelWidth: this.panelWidth,
PanelHeight: this.panelHeight,
};
- const isInk = StrCast(this.layoutDoc.layout).includes(InkingStroke.name) && !this.props.LayoutTemplateString && !this.layoutDoc._isInkMask;
+ const isInk = StrCast(this.layoutDoc.layout).includes(InkingStroke.name) && !this.props.LayoutTemplateString && !this.layoutDoc._stroke_isInkMask;
return (
<div
className="collectionFreeFormDocumentView-container"
diff --git a/src/client/views/nodes/ColorBox.tsx b/src/client/views/nodes/ColorBox.tsx
index 70ba7e182..330cc3971 100644
--- a/src/client/views/nodes/ColorBox.tsx
+++ b/src/client/views/nodes/ColorBox.tsx
@@ -48,7 +48,7 @@ export class ColorBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
render() {
- const scaling = Math.min(this.layoutDoc.fitWidth ? 10000 : this.props.PanelHeight() / this.rootDoc[HeightSym](), this.props.PanelWidth() / this.rootDoc[WidthSym]());
+ const scaling = Math.min(this.layoutDoc.layout_fitWidth ? 10000 : this.props.PanelHeight() / this.rootDoc[HeightSym](), this.props.PanelWidth() / this.rootDoc[WidthSym]());
return (
<div
className={`colorBox-container${this.props.isContentActive() ? '-interactive' : ''}`}
@@ -72,7 +72,7 @@ export class ColorBox extends ViewBoxBaseComponent<FieldViewProps>() {
SetActiveInkWidth(e.target.value);
SelectionManager.Views()
.filter(i => StrCast(i.rootDoc.type) === DocumentType.INK)
- .map(i => (i.rootDoc.strokeWidth = Number(e.target.value)));
+ .map(i => (i.rootDoc.stroke_width = Number(e.target.value)));
}}
/>
</div>
diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx
index ace388c57..3be2d9a77 100644
--- a/src/client/views/nodes/ComparisonBox.tsx
+++ b/src/client/views/nodes/ComparisonBox.tsx
@@ -1,5 +1,5 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { action, observable } from 'mobx';
+import { action, computed, observable } from 'mobx';
import { observer } from 'mobx-react';
import { Doc, Opt } from '../../../fields/Doc';
import { Cast, NumCast, StrCast } from '../../../fields/Types';
@@ -26,6 +26,13 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
@observable _animating = '';
+ @computed get clipWidth() {
+ return NumCast(this.layoutDoc[this.clipWidthKey], 50);
+ }
+ get clipWidthKey() {
+ return '_' + this.props.fieldKey + '_clipWidth';
+ }
+
componentDidMount() {
this.props.setContentView?.(this);
}
@@ -59,7 +66,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
action(() => {
// on click, animate slider movement to the targetWidth
this._animating = 'all 200ms';
- this.layoutDoc._clipWidth = (targetWidth * 100) / this.props.PanelWidth();
+ this.layoutDoc[this.clipWidthKey] = (targetWidth * 100) / this.props.PanelWidth();
setTimeout(
action(() => (this._animating = '')),
200
@@ -71,9 +78,9 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
@action
private onPointerMove = ({ movementX }: PointerEvent) => {
- const width = movementX * this.props.ScreenToLocalTransform().Scale + (NumCast(this.layoutDoc._clipWidth) / 100) * this.props.PanelWidth();
+ const width = movementX * this.props.ScreenToLocalTransform().Scale + (this.clipWidth / 100) * this.props.PanelWidth();
if (width && width > 5 && width < this.props.PanelWidth()) {
- this.layoutDoc._clipWidth = (width * 100) / this.props.PanelWidth();
+ this.layoutDoc[this.clipWidthKey] = (width * 100) / this.props.PanelWidth();
}
return false;
};
@@ -101,7 +108,6 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
};
render() {
- const clipWidth = NumCast(this.layoutDoc._clipWidth) + '%';
const clearButton = (which: string) => {
return (
<div
@@ -143,7 +149,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
};
const displayBox = (which: string, index: number, cover: number) => {
return (
- <div className={`${which}Box-cont`} key={which} style={{ width: this.props.PanelWidth() }} onPointerDown={e => this.registerSliding(e, cover)} ref={ele => this.createDropTarget(ele, which, index)}>
+ <div className={`${index === 0 ? 'before' : 'after'}Box-cont`} key={which} style={{ width: this.props.PanelWidth() }} onPointerDown={e => this.registerSliding(e, cover)} ref={ele => this.createDropTarget(ele, which, index)}>
{displayDoc(which)}
</div>
);
@@ -151,16 +157,16 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
return (
<div className={`comparisonBox${this.props.isContentActive() || SnappingManager.GetIsDragging() ? '-interactive' : ''}` /* change className to easily disable/enable pointer events in CSS */}>
- {displayBox(this.fieldKey === 'data' ? 'compareBox-after' : `${this.fieldKey}2`, 1, this.props.PanelWidth() - 3)}
- <div className="clip-div" style={{ width: clipWidth, transition: this._animating, background: StrCast(this.layoutDoc._backgroundColor, 'gray') }}>
- {displayBox(this.fieldKey === 'data' ? 'compareBox-before' : `${this.fieldKey}1`, 0, 0)}
+ {displayBox(`${this.fieldKey}_2`, 1, this.props.PanelWidth() - 3)}
+ <div className="clip-div" style={{ width: this.clipWidth + '%', transition: this._animating, background: StrCast(this.layoutDoc._backgroundColor, 'gray') }}>
+ {displayBox(`${this.fieldKey}_1`, 0, 0)}
</div>
<div
className="slide-bar"
style={{
- left: `calc(${clipWidth} - 0.5px)`,
- cursor: NumCast(this.layoutDoc._clipWidth) < 5 ? 'e-resize' : NumCast(this.layoutDoc._clipWidth) / 100 > (this.props.PanelWidth() - 5) / this.props.PanelWidth() ? 'w-resize' : undefined,
+ left: `calc(${this.clipWidth + '%'} - 0.5px)`,
+ cursor: this.clipWidth < 5 ? 'e-resize' : this.clipWidth / 100 > (this.props.PanelWidth() - 5) / this.props.PanelWidth() ? 'w-resize' : undefined,
}}
onPointerDown={e => this.registerSliding(e, this.props.PanelWidth() / 2)} /* if clicked, return slide-bar to center */
>
diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
index eb25d3264..5876efb01 100644
--- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx
+++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
@@ -3,7 +3,7 @@ import { observer } from 'mobx-react';
import * as React from 'react';
import { Doc, StrListCast } from '../../../../fields/Doc';
import { List } from '../../../../fields/List';
-import { Cast, NumCast, StrCast } from '../../../../fields/Types';
+import { Cast, CsvCast, NumCast, StrCast } from '../../../../fields/Types';
import { CsvField } from '../../../../fields/URLField';
import { Docs } from '../../../documents/Documents';
import { ViewBoxAnnotatableComponent } from '../../DocComponent';
@@ -29,7 +29,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
// @observable private pairs: { [key: string]: FieldResult }[] = [];
static pairSet = new ObservableMap<string, { [key: string]: string }[]>();
@computed.struct get pairs() {
- return DataVizBox.pairSet.get(StrCast(this.rootDoc.fileUpload));
+ return DataVizBox.pairSet.get(CsvCast(this.rootDoc[this.fieldKey]).url.href);
}
private _chartRenderer: LineChart | undefined;
// // another way would be store a schema that defines the type of data we are expecting from an imported doc
@@ -61,7 +61,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
@action
restoreView = (data: Doc) => {
const changedView = this.dataVizView !== data.presDataVizView && (this.layoutDoc._dataVizView = data.presDataVizView);
- const changedAxes = this.axes.join('') !== StrListCast(data.presDataVizAxes).join('') && (this.layoutDoc._dataVizAxes = new List<string>(StrListCast(data.presDataVizAxes)));
+ const changedAxes = this.axes.join('') !== StrListCast(data.presDataVizAxes).join('') && (this.layoutDoc._data_vizAxes = new List<string>(StrListCast(data.presDataVizAxes)));
const func = () => this._chartRenderer?.restoreView(data);
if (changedView || changedAxes) {
setTimeout(func, 100);
@@ -88,14 +88,14 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
};
@computed.struct get axes() {
- return StrListCast(this.layoutDoc.dataVizAxes);
+ return StrListCast(this.layoutDoc.data_vizAxes);
}
- selectAxes = (axes: string[]) => (this.layoutDoc.dataVizAxes = new List<string>(axes));
+ selectAxes = (axes: string[]) => (this.layoutDoc.data_vizAxes = new List<string>(axes));
@computed get selectView() {
const width = this.props.PanelWidth() * 0.9;
const height = (this.props.PanelHeight() - 32) /* height of 'change view' button */ * 0.9;
- const margin = { top: 10, right: 25, bottom: 50, left:25};
+ const margin = { top: 10, right: 25, bottom: 50, left: 25 };
if (!this.pairs) return 'no data';
// prettier-ignore
switch (this.dataVizView) {
@@ -113,10 +113,10 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
}
fetchData() {
- if (DataVizBox.pairSet.has(StrCast(this.rootDoc.fileUpload))) return;
- DataVizBox.pairSet.set(StrCast(this.rootDoc.fileUpload), []);
+ if (DataVizBox.pairSet.has(CsvCast(this.rootDoc[this.fieldKey]).url.href)) return;
+ DataVizBox.pairSet.set(CsvCast(this.rootDoc[this.fieldKey]).url.href, []);
fetch('/csvData?uri=' + this.dataUrl?.url.href) //
- .then(res => res.json().then(action(res => !res.errno && DataVizBox.pairSet.set(StrCast(this.rootDoc.fileUpload), res))));
+ .then(res => res.json().then(action(res => !res.errno && DataVizBox.pairSet.set(CsvCast(this.rootDoc[this.fieldKey]).url.href, res))));
}
// handle changing the view using a button
diff --git a/src/client/views/nodes/DataVizBox/components/LineChart.tsx b/src/client/views/nodes/DataVizBox/components/LineChart.tsx
index 777bf2f66..11f62a61f 100644
--- a/src/client/views/nodes/DataVizBox/components/LineChart.tsx
+++ b/src/client/views/nodes/DataVizBox/components/LineChart.tsx
@@ -56,8 +56,8 @@ export class LineChart extends React.Component<LineChartProps> {
}
@computed get incomingLinks() {
return LinkManager.Instance.getAllRelatedLinks(this.props.rootDoc) // out of all links
- .filter(link => link.anchor1 !== this.props.rootDoc) // get links where this chart doc is the target of the link
- .map(link => DocCast(link.anchor1)); // then return the source of the link
+ .filter(link => link.link_anchor_1 !== this.props.rootDoc) // get links where this chart doc is the target of the link
+ .map(link => DocCast(link.link_anchor_1)); // then return the source of the link
}
@computed get incomingSelected() {
return this.incomingLinks // all links that are pointing to this node
@@ -87,7 +87,7 @@ export class LineChart extends React.Component<LineChartProps> {
{ fireImmediately: true }
);
this._disposers.annos = reaction(
- () => DocListCast(this.props.dataDoc[this.props.fieldKey + '-annotations']),
+ () => DocListCast(this.props.dataDoc[this.props.fieldKey + '_annotations']),
annotations => {
// modify how d3 renders so that anything in this annotations list would be potentially highlighted in some way
// could be blue colored to make it look like anchor
@@ -123,7 +123,7 @@ export class LineChart extends React.Component<LineChartProps> {
element.classList.remove('selected');
}
};
- // gets called whenever the "data-annotations" fields gets updated
+ // gets called whenever the "data_annotations" fields gets updated
drawAnnotations = (dataX: number, dataY: number, selected?: boolean) => {
// TODO: nda - can optimize this by having some sort of mapping of the x and y values to the individual circle elements
// loop through all html elements with class .circle-d1 and find the one that has "data-x" and "data-y" attributes that match the dataX and dataY
@@ -228,15 +228,15 @@ export class LineChart extends React.Component<LineChartProps> {
// creating the x and y scales
const xScale = scaleCreatorNumerical(xMin, xMax, 0, width);
- const yScale = scaleCreatorNumerical(0, yMax,height, 0);
+ const yScale = scaleCreatorNumerical(0, yMax, height, 0);
// adding svg
const margin = this.props.margin;
const svg = (this._lineChartSvg = d3
.select(this._lineChartRef.current)
.append('svg')
- .attr('width', `${width +margin.left + margin.right}`)
- .attr('height', `${height + margin.top + margin.bottom }`)
+ .attr('width', `${width + margin.left + margin.right}`)
+ .attr('height', `${height + margin.top + margin.bottom}`)
.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`));
diff --git a/src/client/views/nodes/DataVizBox/components/TableBox.tsx b/src/client/views/nodes/DataVizBox/components/TableBox.tsx
index 0d69ac890..3816bddfa 100644
--- a/src/client/views/nodes/DataVizBox/components/TableBox.tsx
+++ b/src/client/views/nodes/DataVizBox/components/TableBox.tsx
@@ -47,17 +47,17 @@ export class TableBox extends React.Component<TableBoxProps> {
e => {
const sourceAnchorCreator = () => this.props.docView?.()!.rootDoc!;
const targetCreator = (annotationOn: Doc | undefined) => {
- const alias = Doc.MakeAlias(this.props.docView?.()!.rootDoc!);
- alias._dataVizView = DataVizView.LINECHART;
- alias._dataVizAxes = new List<string>([col, col]);
- alias.annotationOn = annotationOn; //this.props.docView?.()!.rootDoc!;
- return alias;
+ const embedding = Doc.MakeEmbedding(this.props.docView?.()!.rootDoc!);
+ embedding._dataVizView = DataVizView.LINECHART;
+ embedding._data_vizAxes = new List<string>([col, col]);
+ embedding.annotationOn = annotationOn; //this.props.docView?.()!.rootDoc!;
+ return embedding;
};
if (this.props.docView?.() && !Utils.isClick(e.clientX, e.clientY, downX, downY, Date.now())) {
DragManager.StartAnchorAnnoDrag([header.current!], new DragManager.AnchorAnnoDragData(this.props.docView()!, sourceAnchorCreator, targetCreator), downX, downY, {
dragComplete: e => {
if (!e.aborted && e.annoDragData && e.annoDragData.linkSourceDoc && e.annoDragData.dropDocument && e.linkDocument) {
- e.linkDocument.linkDisplay = true;
+ e.linkDocument.layout_linkDisplay = true;
// e.annoDragData.linkSourceDoc.followLinkToggle = e.annoDragData.dropDocument.annotationOn === this.props.rootDoc;
// e.annoDragData.linkSourceDoc.followLinkZoom = false;
}
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 76a5ce7b3..348ef910a 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -120,15 +120,15 @@ export class DocumentContentsView extends React.Component<
select: (ctrl: boolean) => void;
NativeDimScaling?: () => number;
setHeight?: (height: number) => void;
- layoutKey: string;
+ layout_fieldKey: string;
}
> {
@computed get layout(): string {
TraceMobx();
if (this.props.LayoutTemplateString) return this.props.LayoutTemplateString;
if (!this.layoutDoc) return '<p>awaiting layout</p>';
- if (this.props.layoutKey === 'layout_keyValue') return StrCast(this.props.Document.layout_keyValue, KeyValueBox.LayoutString());
- const layout = Cast(this.layoutDoc[this.layoutDoc === this.props.Document && this.props.layoutKey ? this.props.layoutKey : StrCast(this.layoutDoc.layoutKey, 'layout')], 'string');
+ if (this.props.layout_fieldKey === 'layout_keyValue') return StrCast(this.props.Document.layout_keyValue, KeyValueBox.LayoutString());
+ const layout = Cast(this.layoutDoc[this.layoutDoc === this.props.Document && this.props.layout_fieldKey ? this.props.layout_fieldKey : StrCast(this.layoutDoc.layout_fieldKey, 'layout')], 'string');
if (layout === undefined) return this.props.Document.data ? "<FieldView {...props} fieldKey='data' />" : KeyValueBox.LayoutString();
if (typeof layout === 'string') return layout;
return '<p>Loading layout</p>';
@@ -140,12 +140,12 @@ export class DocumentContentsView extends React.Component<
}
get layoutDoc() {
// bcz: replaced this with below : is it correct? change was made to accommodate passing fieldKey's from a layout script
- // const template: Doc = this.props.LayoutTemplate?.() || Doc.Layout(this.props.Document, this.props.layoutKey ? Cast(this.props.Document[this.props.layoutKey], Doc, null) : undefined);
+ // const template: Doc = this.props.LayoutTemplate?.() || Doc.Layout(this.props.Document, this.props.layout_fieldKey ? Cast(this.props.Document[this.props.layout_fieldKey], Doc, null) : undefined);
const template: Doc =
this.props.LayoutTemplate?.() ||
(this.props.LayoutTemplateString && this.props.Document) ||
- (this.props.layoutKey && StrCast(this.props.Document[this.props.layoutKey]) && this.props.Document) ||
- Doc.Layout(this.props.Document, this.props.layoutKey ? Cast(this.props.Document[this.props.layoutKey], Doc, null) : undefined);
+ (this.props.layout_fieldKey && StrCast(this.props.Document[this.props.layout_fieldKey]) && this.props.Document) ||
+ Doc.Layout(this.props.Document, this.props.layout_fieldKey ? Cast(this.props.Document[this.props.layout_fieldKey], Doc, null) : undefined);
return Doc.expandTemplateLayout(template, this.props.Document);
}
diff --git a/src/client/views/nodes/DocumentIcon.tsx b/src/client/views/nodes/DocumentIcon.tsx
index 56de2d1fc..6e2ed72b8 100644
--- a/src/client/views/nodes/DocumentIcon.tsx
+++ b/src/client/views/nodes/DocumentIcon.tsx
@@ -1,23 +1,39 @@
-
-import { observer } from "mobx-react";
-import * as React from "react";
-import { DocumentView } from "./DocumentView";
-import { DocumentManager } from "../../util/DocumentManager";
-import { Transformer, ts } from "../../util/Scripting";
-import { Field } from "../../../fields/Doc";
+import { observer } from 'mobx-react';
+import * as React from 'react';
+import { DocumentView } from './DocumentView';
+import { DocumentManager } from '../../util/DocumentManager';
+import { Transformer, ts } from '../../util/Scripting';
+import { Field } from '../../../fields/Doc';
+import { Tooltip } from '@material-ui/core';
+import { action, observable } from 'mobx';
+import { Id } from '../../../fields/FieldSymbols';
+import { factory } from 'typescript';
+import { LightboxView } from '../LightboxView';
@observer
-export class DocumentIcon extends React.Component<{ view: DocumentView, index: number }> {
+export class DocumentIcon extends React.Component<{ view: DocumentView; index: number }> {
+ @observable _hovered = false;
+ static get DocViews() {
+ return LightboxView.LightboxDoc ? DocumentManager.Instance.DocumentViews.filter(v => LightboxView.IsLightboxDocView(v.props.docViewPath())) : DocumentManager.Instance.DocumentViews;
+ }
render() {
const view = this.props.view;
const { left, top, right, bottom } = view.getBounds() || { left: 0, top: 0, right: 0, bottom: 0 };
return (
- <div className="documentIcon-outerDiv" style={{
- position: "absolute",
- transform: `translate(${(left + right) / 2}px, ${top}px)`,
- }}>
- <p>d{this.props.index}</p>
+ <div
+ className="documentIcon-outerDiv"
+ onPointerEnter={action(e => (this._hovered = true))}
+ onPointerLeave={action(e => (this._hovered = false))}
+ style={{
+ pointerEvents: 'all',
+ opacity: this._hovered ? 0.3 : 1,
+ position: 'absolute',
+ transform: `translate(${(left + right) / 2}px, ${top}px)`,
+ }}>
+ <Tooltip title={<>{this.props.view.rootDoc.title}</>}>
+ <p>d{this.props.index}</p>
+ </Tooltip>
</div>
);
}
@@ -41,7 +57,9 @@ export class DocumentIconContainer extends React.Component {
const match = node.text.match(/d([0-9]+)/);
if (match) {
const m = parseInt(match[1]);
+ const doc = DocumentIcon.DocViews[m].rootDoc;
usedDocuments.add(m);
+ return factory.createIdentifier(`idToDoc("${doc[Id]}")`);
}
}
}
@@ -52,14 +70,14 @@ export class DocumentIconContainer extends React.Component {
};
},
getVars() {
- const docs = Array.from(DocumentManager.Instance.DocumentViews);
+ const docs = DocumentIcon.DocViews;
const capturedVariables: { [name: string]: Field } = {};
- usedDocuments.forEach(index => capturedVariables[`d${index}`] = docs[index].props.Document);
- return { capturedVariables };
- }
+ usedDocuments.forEach(index => (capturedVariables[`d${index}`] = docs.length > index ? docs[index].props.Document : `d${index}`));
+ return capturedVariables;
+ },
};
}
render() {
- return Array.from(DocumentManager.Instance.DocumentViews).map((dv, i) => <DocumentIcon key={i} index={i} view={dv} />);
+ return DocumentIcon.DocViews.map((dv, i) => <DocumentIcon key={i} index={i} view={dv} />);
}
-} \ No newline at end of file
+}
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx
index 47705d53d..d5ca30957 100644
--- a/src/client/views/nodes/DocumentLinksButton.tsx
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -52,7 +52,7 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
dragComplete: dropEv => {
if (this.props.View && dropEv.linkDocument) {
// dropEv.linkDocument equivalent to !dropEve.aborted since linkDocument is only assigned on a completed drop
- !dropEv.linkDocument.linkRelationship && (Doc.GetProto(dropEv.linkDocument).linkRelationship = 'hyperlink');
+ !dropEv.linkDocument.link_relationship && (Doc.GetProto(dropEv.linkDocument).link_relationship = 'hyperlink');
}
linkDrag?.end();
},
@@ -142,7 +142,7 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
} else if (startLink !== endLink) {
endLink = endLinkView?.docView?._componentView?.getAnchor?.(true, pinProps) || endLink;
startLink = DocumentLinksButton.StartLinkView?.docView?._componentView?.getAnchor?.(true) || startLink;
- const linkDoc = DocUtils.MakeLink(startLink, endLink, { linkRelationship: DocumentLinksButton.AnnotationId ? 'hypothes.is annotation' : undefined });
+ const linkDoc = DocUtils.MakeLink(startLink, endLink, { link_relationship: DocumentLinksButton.AnnotationId ? 'hypothes.is annotation' : undefined });
LinkManager.currentLink = linkDoc;
@@ -197,7 +197,7 @@ export class DocumentLinksButton extends React.Component<DocumentLinksButtonProp
const results = [] as Doc[];
const filters = this.props.View.props.docFilters();
Array.from(new Set<Doc>(this.props.View.allLinks)).forEach(link => {
- if (DocUtils.FilterDocs([link], filters, []).length || DocUtils.FilterDocs([link.anchor2 as Doc], filters, []).length || DocUtils.FilterDocs([link.anchor1 as Doc], filters, []).length) {
+ if (DocUtils.FilterDocs([link], filters, []).length || DocUtils.FilterDocs([link.link_anchor_2 as Doc], filters, []).length || DocUtils.FilterDocs([link.link_anchor_1 as Doc], filters, []).length) {
results.push(link);
}
});
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index f1f5f7e10..d8494e58e 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -48,6 +48,7 @@ import { PresEffect, PresEffectDirection } from './trails';
import { PinProps, PresBox } from './trails/PresBox';
import React = require('react');
import { InkingStroke } from '../InkingStroke';
+import { RefField } from '../../../fields/RefField';
const { Howl } = require('howler');
interface Window {
@@ -127,9 +128,10 @@ export interface DocComponentView {
IsPlaying?: () => boolean; // is a media document playing
TogglePause?: (keep?: boolean) => void; // toggle media document playing state
setFocus?: () => void; // sets input focus to the componentView
+ setData?: (data: Field | Promise<RefField | undefined>) => boolean;
componentUI?: (boundsLeft: number, boundsTop: number) => JSX.Element | null;
incrementalRendering?: () => void;
- fitWidth?: () => boolean; // whether the component always fits width (eg, KeyValueBox)
+ layout_fitWidth?: () => boolean; // whether the component always fits width (eg, KeyValueBox)
overridePointerEvents?: () => 'all' | 'none' | undefined; // if the conmponent overrides the pointer events for the document
fieldKey?: string;
annotationKey?: string;
@@ -148,7 +150,7 @@ export interface DocumentViewSharedProps {
Document: Doc;
DataDoc?: Doc;
contentBounds?: () => undefined | { x: number; y: number; r: number; b: number };
- fitContentsToBox?: () => boolean; // used by freeformview to fit its contents to its panel. corresponds to _fitContentsToBox property on a Document
+ fitContentsToBox?: () => boolean; // used by freeformview to fit its contents to its panel. corresponds to _freeform_fitContentsToBox property on a Document
suppressSetHeight?: boolean;
thumbShown?: () => boolean;
setContentView?: (view: DocComponentView) => any;
@@ -162,11 +164,11 @@ export interface DocumentViewSharedProps {
styleProvider: Opt<StyleProviderFunc>;
setTitleFocus?: () => void;
focus: DocFocusFunc;
- fitWidth?: (doc: Doc) => boolean | undefined;
+ layout_fitWidth?: (doc: Doc) => boolean | undefined;
docFilters: () => string[];
docRangeFilters: () => string[];
searchFilterDocs: () => Doc[];
- showTitle?: () => string;
+ layout_showTitle?: () => string;
whenChildContentsActiveChanged: (isActive: boolean) => void;
rootSelected: (outsideReaction?: boolean) => boolean; // whether the root of a template has been selected
addDocTab: (doc: Doc, where: OpenWhere) => boolean;
@@ -273,8 +275,8 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
public get LayoutFieldKey() {
return Doc.LayoutFieldKey(this.layoutDoc);
}
- @computed get ShowTitle() {
- return this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.ShowTitle) as Opt<string>;
+ @computed get layout_showTitle() {
+ return this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.layout_showTitle) as Opt<string>;
}
@computed get NativeDimScaling() {
return this.props.NativeDimScaling?.() || 1;
@@ -303,8 +305,8 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
@computed get headerMargin() {
return this.props?.styleProvider?.(this.layoutDoc, this.props, StyleProp.HeaderMargin) || 0;
}
- @computed get showCaption() {
- return this.props?.styleProvider?.(this.layoutDoc, this.props, StyleProp.ShowCaption) || 0;
+ @computed get layout_showCaption() {
+ return this.props?.styleProvider?.(this.layoutDoc, this.props, StyleProp.showCaption) || 0;
}
@computed get titleHeight() {
return this.props?.styleProvider?.(this.layoutDoc, this.props, StyleProp.TitleHeight) || 0;
@@ -313,7 +315,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
return this.props.styleProvider?.(this.Document, this.props, StyleProp.PointerEvents + (this.props.isSelected() ? ':selected' : ''));
}
@computed get finalLayoutKey() {
- return StrCast(this.Document.layoutKey, 'layout');
+ return StrCast(this.Document.layout_fieldKey, 'layout');
}
@computed get nativeWidth() {
return this.props.NativeWidth();
@@ -408,7 +410,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
// switches text input focus to the title bar of the document (and displays the title bar if it hadn't been)
setTitleFocus = () => {
- if (!StrCast(this.layoutDoc._showTitle)) this.layoutDoc._showTitle = 'title';
+ if (!StrCast(this.layoutDoc._layout_showTitle)) this.layoutDoc._layout_showTitle = 'title';
setTimeout(() => this._titleRef.current?.setIsFocused(true)); // use timeout in case title wasn't shown to allow re-render so that titleref will be defined
};
@@ -434,7 +436,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
}, console.log );
UndoManager.RunInBatch(() => (func().result?.select === true ? this.props.select(false) : ''), 'on double click');
} else if (!Doc.IsSystem(this.rootDoc) && (defaultDblclick === undefined || defaultDblclick === 'default')) {
- UndoManager.RunInBatch(() => this.props.addDocTab(this.rootDoc, OpenWhere.lightbox), 'double tap');
+ UndoManager.RunInBatch(() => LightboxView.AddDocTab(this.rootDoc, OpenWhere.lightbox), 'double tap');
SelectionManager.DeselectAll();
Doc.UnBrushDoc(this.props.Document);
} else {
@@ -537,7 +539,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
if (!Utils.isClick(e.clientX, e.clientY, this._downX, this._downY, Date.now())) {
this.cleanupPointerEvents();
- this.startDragging(this._downX, this._downY, ((e.ctrlKey || e.altKey) && 'alias') || ((this.Document.dropAction || this.props.dropAction || undefined) as dropActionType));
+ this.startDragging(this._downX, this._downY, ((e.ctrlKey || e.altKey) && 'embed') || ((this.Document.dropAction || this.props.dropAction || undefined) as dropActionType));
}
};
@@ -587,7 +589,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
@undoBatch deleteClicked = () => this.props.removeDocument?.(this.props.Document);
@undoBatch setToggleDetail = () =>
(this.Document.onClick = ScriptField.MakeScript(
- `toggleDetail(documentView, "${StrCast(this.Document.layoutKey)
+ `toggleDetail(documentView, "${StrCast(this.Document.layout_fieldKey)
.replace('layout_', '')
.replace(/^layout$/, 'detail')}")`,
{ documentView: 'any' }
@@ -609,7 +611,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
if (de.complete.annoDragData && !de.complete.annoDragData.dropDocument) {
de.complete.annoDragData.dropDocument = de.complete.annoDragData.dropDocCreator(undefined);
}
- if (de.complete.annoDragData || this.rootDoc !== linkdrag.linkSourceDoc.context) {
+ if (de.complete.annoDragData || this.rootDoc !== linkdrag.linkSourceDoc.embedContainer) {
const dropDoc = de.complete.annoDragData?.dropDocument ?? this._componentView?.getAnchor?.(true) ?? this.rootDoc;
de.complete.linkDocument = DocUtils.MakeLink(linkdrag.linkSourceDoc, dropDoc, {}, undefined, [de.x, de.y - 50]);
}
@@ -620,12 +622,12 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
@undoBatch
@action
makeIntoPortal = () => {
- const portalLink = this.allLinks.find(d => d.anchor1 === this.props.Document && d.linkRelationship === 'portal to:portal from');
+ const portalLink = this.allLinks.find(d => d.link_anchor_1 === this.props.Document && d.link_relationship === 'portal to:portal from');
if (!portalLink) {
DocUtils.MakeLink(
this.props.Document,
- Docs.Create.FreeformDocument([], { _width: NumCast(this.layoutDoc._width) + 10, _height: NumCast(this.layoutDoc._height), _isLightbox: true, _fitWidth: true, title: StrCast(this.props.Document.title) + ' [Portal]' }),
- { linkRelationship: 'portal to:portal from' }
+ Docs.Create.FreeformDocument([], { _width: NumCast(this.layoutDoc._width) + 10, _height: NumCast(this.layoutDoc._height), _isLightbox: true, _layout_fitWidth: true, title: StrCast(this.props.Document.title) + ' [Portal]' }),
+ { link_relationship: 'portal to:portal from' }
);
}
this.Document.followLinkLocation = OpenWhere.lightbox;
@@ -697,7 +699,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
.forEach(item => item.label && cm.addItem({ description: item.label, event: () => item.script.script.run({ this: this.layoutDoc, scriptContext: this.props.scriptContext, self: this.rootDoc }), icon: item.icon as IconProp }));
if (!this.props.Document.isFolder) {
- const templateDoc = Cast(this.props.Document[StrCast(this.props.Document.layoutKey)], Doc, null);
+ const templateDoc = Cast(this.props.Document[StrCast(this.props.Document.layout_fieldKey)], Doc, null);
const appearance = cm.findByDescription('UI Controls...');
const appearanceItems: ContextMenuProps[] = appearance && 'subitems' in appearance ? appearance.subitems : [];
!Doc.noviceMode && templateDoc && appearanceItems.push({ description: 'Open Template ', event: () => this.props.addDocTab(templateDoc, OpenWhere.addRight), icon: 'eye' });
@@ -740,7 +742,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
const funcs: ContextMenuProps[] = [];
if (!Doc.noviceMode && this.layoutDoc.onDragStart) {
- funcs.push({ description: 'Drag an Alias', icon: 'edit', event: () => this.Document.dragFactory && (this.layoutDoc.onDragStart = ScriptField.MakeFunction('getAlias(this.dragFactory)')) });
+ funcs.push({ description: 'Drag an Embedding', icon: 'edit', event: () => this.Document.dragFactory && (this.layoutDoc.onDragStart = ScriptField.MakeFunction('getEmbedding(this.dragFactory)')) });
funcs.push({ description: 'Drag a Copy', icon: 'edit', event: () => this.Document.dragFactory && (this.layoutDoc.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)')) });
funcs.push({ description: 'Drag Document', icon: 'edit', event: () => (this.layoutDoc.onDragStart = undefined) });
cm.addItem({ description: 'OnDrag...', noexpand: true, subitems: funcs, icon: 'asterisk' });
@@ -908,7 +910,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
onClick={this.onClickFunc}
focus={this.props.focus}
setTitleFocus={this.setTitleFocus}
- layoutKey={this.finalLayoutKey}
+ layout_fieldKey={this.finalLayoutKey}
/>
{this.layoutDoc.hideAllLinks ? null : this.allLinkEndpoints}
</div>
@@ -920,7 +922,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
anchorStyleProvider = (doc: Opt<Doc>, props: Opt<DocumentViewProps>, property: string): any => {
// prettier-ignore
switch (property.split(':')[0]) {
- case StyleProp.ShowTitle: return '';
+ case StyleProp.layout_showTitle: return '';
case StyleProp.PointerEvents: return 'none';
case StyleProp.Highlighting: return undefined;
}
@@ -936,22 +938,22 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
TraceMobx();
return LinkManager.Instance.getAllRelatedLinks(this.rootDoc).filter(
link =>
- Doc.AreProtosEqual(link.anchor1 as Doc, this.rootDoc) ||
- Doc.AreProtosEqual(link.anchor2 as Doc, this.rootDoc) ||
- ((link.anchor1 as Doc)?.unrendered && Doc.AreProtosEqual((link.anchor1 as Doc)?.annotationOn as Doc, this.rootDoc)) ||
- ((link.anchor2 as Doc)?.unrendered && Doc.AreProtosEqual((link.anchor2 as Doc)?.annotationOn as Doc, this.rootDoc))
+ Doc.AreProtosEqual(link.link_anchor_1 as Doc, this.rootDoc) ||
+ Doc.AreProtosEqual(link.link_anchor_2 as Doc, this.rootDoc) ||
+ ((link.link_anchor_1 as Doc)?.unrendered && Doc.AreProtosEqual((link.link_anchor_1 as Doc)?.annotationOn as Doc, this.rootDoc)) ||
+ ((link.link_anchor_2 as Doc)?.unrendered && Doc.AreProtosEqual((link.link_anchor_2 as Doc)?.annotationOn as Doc, this.rootDoc))
);
}
@computed get allLinks() {
TraceMobx();
return LinkManager.Instance.getAllRelatedLinks(this.rootDoc);
}
- hideLink = computedFn((link: Doc) => () => (link.linkDisplay = false));
+ hideLink = computedFn((link: Doc) => () => (link.layout_linkDisplay = false));
@computed get allLinkEndpoints() {
// the small blue dots that mark the endpoints of links
TraceMobx();
- if (this.props.hideLinkAnchors || this.layoutDoc.hideLinkAnchors || this.props.dontRegisterView || this.layoutDoc.unrendered) return null;
- const filtered = DocUtils.FilterDocs(this.directLinks, this.props.docFilters?.() ?? [], []).filter(d => d.linkDisplay);
+ if (this.props.hideLinkAnchors || this.layoutDoc.layout_hideLinkAnchors || this.props.dontRegisterView || this.layoutDoc.unrendered) return null;
+ const filtered = DocUtils.FilterDocs(this.directLinks, this.props.docFilters?.() ?? [], []).filter(d => d.layout_linkDisplay);
return filtered.map(link => (
<div className="documentView-anchorCont" key={link[Id]}>
<DocumentView
@@ -962,14 +964,14 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
PanelWidth={this.anchorPanelWidth}
PanelHeight={this.anchorPanelHeight}
dontRegisterView={false}
- showTitle={returnEmptyString}
+ layout_showTitle={returnEmptyString}
hideCaptions={true}
hideLinkAnchors={true}
- fitWidth={returnTrue}
+ layout_fitWidth={returnTrue}
removeDocument={this.hideLink(link)}
styleProvider={this.anchorStyleProvider}
LayoutTemplate={undefined}
- LayoutTemplateString={LinkAnchorBox.LayoutString(`anchor${Doc.LinkEndpoint(link, this.rootDoc)}`)}
+ LayoutTemplateString={LinkAnchorBox.LayoutString(`link_anchor_${Doc.LinkEndpoint(link, this.rootDoc)}`)}
/>
</div>
));
@@ -1044,9 +1046,9 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
@computed get innards() {
TraceMobx();
const ffscale = () => this.props.DocumentView().props.CollectionFreeFormDocumentView?.().props.ScreenToLocalTransform().Scale || 1;
- const showTitle = this.ShowTitle?.split(':')[0];
- const showTitleHover = this.ShowTitle?.includes(':hover');
- const captionView = !this.showCaption ? null : (
+ const layout_showTitle = this.layout_showTitle?.split(':')[0];
+ const layout_showTitleHover = this.layout_showTitle?.includes(':hover');
+ const captionView = !this.layout_showCaption ? null : (
<div
className="documentView-captionWrapper"
style={{
@@ -1058,7 +1060,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
{...this.props}
yPadding={10}
xPadding={10}
- fieldKey={this.showCaption}
+ fieldKey={this.layout_showCaption}
fontSize={12 * Math.max(1, (2 * ffscale()) / 3)}
styleProvider={this.captionStyleProvider}
dontRegisterView={true}
@@ -1069,26 +1071,27 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
/>
</div>
);
- const targetDoc = showTitle?.startsWith('_') ? this.layoutDoc : this.rootDoc;
+ const targetDoc = layout_showTitle?.startsWith('_') ? this.layoutDoc : this.rootDoc;
const background = StrCast(
SharingManager.Instance.users.find(users => users.user.email === this.dataDoc.author)?.sharingDoc.userColor,
- Doc.UserDoc().showTitle && [DocumentType.RTF, DocumentType.COL].includes(this.rootDoc.type as any) ? StrCast(Doc.SharingDoc().userColor) : 'rgba(0,0,0,0.4)'
+ Doc.UserDoc().layout_showTitle && [DocumentType.RTF, DocumentType.COL].includes(this.rootDoc.type as any) ? StrCast(Doc.SharingDoc().userColor) : 'rgba(0,0,0,0.4)'
);
- const titleView = !showTitle ? null : (
+ const layout_sidebarWidthPercent = +StrCast(this.layoutDoc.layout_sidebarWidthPercent).replace('%', '');
+ const titleView = !layout_showTitle ? null : (
<div
- className={`documentView-titleWrapper${showTitleHover ? '-hover' : ''}`}
+ className={`documentView-titleWrapper${layout_showTitleHover ? '-hover' : ''}`}
key="title"
style={{
position: this.headerMargin ? 'relative' : 'absolute',
height: this.titleHeight,
- width: !this.headerMargin ? `calc(100% - 18px)` : '100%', // leave room for annotation button
+ width: !this.headerMargin ? `calc(${layout_sidebarWidthPercent || 100}% - 18px)` : (layout_sidebarWidthPercent || 100) + '%', // leave room for annotation button
color: lightOrDark(background),
background,
pointerEvents: (!this.disableClickScriptFunc && this.onClickHandler) || this.Document.ignoreClick ? 'none' : this.isContentActive() || this.props.isDocumentActive?.() ? 'all' : undefined,
}}>
<EditableView
ref={this._titleRef}
- contents={showTitle
+ contents={layout_showTitle
.split(';')
.map(field => field.trim())
.map(field => targetDoc[field]?.toString())
@@ -1097,27 +1100,27 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
fontSize={10}
GetValue={() => {
this.props.select(false);
- return showTitle.split(';').length === 1 ? showTitle + '=' + Field.toString(targetDoc[showTitle.split(';')[0]] as any as Field) : '#' + showTitle;
+ return layout_showTitle.split(';').length === 1 ? layout_showTitle + '=' + Field.toString(targetDoc[layout_showTitle.split(';')[0]] as any as Field) : '#' + layout_showTitle;
}}
SetValue={undoBatch((input: string) => {
if (input?.startsWith('#')) {
- if (this.props.showTitle) {
- this.rootDoc._showTitle = input?.substring(1) ? input.substring(1) : undefined;
+ if (this.props.layout_showTitle) {
+ this.rootDoc._layout_showTitle = input?.substring(1) ? input.substring(1) : undefined;
} else {
- Doc.UserDoc().showTitle = input?.substring(1) ? input.substring(1) : 'creationDate';
+ Doc.UserDoc().layout_showTitle = input?.substring(1) ? input.substring(1) : 'creationDate';
}
} else {
- var value = input.replace(new RegExp(showTitle + '='), '') as string | number;
- if (showTitle !== 'title' && Number(value).toString() === value) value = Number(value);
- if (showTitle.includes('Date') || showTitle === 'author') return true;
- Doc.SetInPlace(targetDoc, showTitle, value, true);
+ var value = input.replace(new RegExp(layout_showTitle + '='), '') as string | number;
+ if (layout_showTitle !== 'title' && Number(value).toString() === value) value = Number(value);
+ if (layout_showTitle.includes('Date') || layout_showTitle === 'author') return true;
+ Doc.SetInPlace(targetDoc, layout_showTitle, value, true);
}
return true;
})}
/>
</div>
);
- return this.props.hideTitle || (!showTitle && !this.showCaption) ? (
+ return this.props.hideTitle || (!layout_showTitle && !this.layout_showCaption) ? (
this.contents
) : (
<div className="documentView-styleWrapper">
@@ -1316,11 +1319,11 @@ export class DocumentView extends React.Component<DocumentViewProps> {
get LayoutFieldKey() {
return this.docView?.LayoutFieldKey || 'layout';
}
- @computed get fitWidth() {
- return this.docView?._componentView?.fitWidth?.() ?? this.props.fitWidth?.(this.rootDoc) ?? this.layoutDoc?.fitWidth;
+ @computed get layout_fitWidth() {
+ return this.docView?._componentView?.layout_fitWidth?.() ?? this.props.layout_fitWidth?.(this.rootDoc) ?? this.layoutDoc?.layout_fitWidth;
}
@computed get anchorViewDoc() {
- return this.props.LayoutTemplateString?.includes('anchor2') ? DocCast(this.rootDoc['anchor2']) : this.props.LayoutTemplateString?.includes('anchor1') ? DocCast(this.rootDoc['anchor1']) : undefined;
+ return this.props.LayoutTemplateString?.includes('link_anchor_2') ? DocCast(this.rootDoc['link_anchor_2']) : this.props.LayoutTemplateString?.includes('link_anchor_1') ? DocCast(this.rootDoc['link_anchor_1']) : undefined;
}
@computed get hideLinkButton() {
return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.HideLinkButton + (this.isSelected() ? ':selected' : ''));
@@ -1336,13 +1339,13 @@ export class DocumentView extends React.Component<DocumentViewProps> {
return Doc.Layout(this.Document, this.props.LayoutTemplate?.());
}
@computed get nativeWidth() {
- return this.docView?._componentView?.reverseNativeScaling?.() ? 0 : returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.layoutDoc, this.props.DataDoc, !this.fitWidth));
+ return this.docView?._componentView?.reverseNativeScaling?.() ? 0 : returnVal(this.props.NativeWidth?.(), Doc.NativeWidth(this.layoutDoc, this.props.DataDoc, !this.layout_fitWidth));
}
@computed get nativeHeight() {
- return this.docView?._componentView?.reverseNativeScaling?.() ? 0 : returnVal(this.props.NativeHeight?.(), Doc.NativeHeight(this.layoutDoc, this.props.DataDoc, !this.fitWidth));
+ return this.docView?._componentView?.reverseNativeScaling?.() ? 0 : returnVal(this.props.NativeHeight?.(), Doc.NativeHeight(this.layoutDoc, this.props.DataDoc, !this.layout_fitWidth));
}
@computed get shouldNotScale() {
- return (this.fitWidth && !this.nativeWidth) || [CollectionViewType.Docking].includes(this.Document._viewType as any);
+ return (this.layout_fitWidth && !this.nativeWidth) || [CollectionViewType.Docking].includes(this.Document._viewType as any);
}
@computed get effectiveNativeWidth() {
return this.shouldNotScale ? 0 : this.nativeWidth || NumCast(this.layoutDoc.width);
@@ -1353,8 +1356,8 @@ export class DocumentView extends React.Component<DocumentViewProps> {
@computed get nativeScaling() {
if (this.shouldNotScale) return 1;
const minTextScale = this.Document.type === DocumentType.RTF ? 0.1 : 0;
- if (this.fitWidth || this.props.PanelHeight() / (this.effectiveNativeHeight || 1) > this.props.PanelWidth() / (this.effectiveNativeWidth || 1)) {
- return Math.max(minTextScale, this.props.PanelWidth() / (this.effectiveNativeWidth || 1)); // width-limited or fitWidth
+ if (this.layout_fitWidth || this.props.PanelHeight() / (this.effectiveNativeHeight || 1) > this.props.PanelWidth() / (this.effectiveNativeWidth || 1)) {
+ return Math.max(minTextScale, this.props.PanelWidth() / (this.effectiveNativeWidth || 1)); // width-limited or layout_fitWidth
}
return Math.max(minTextScale, this.props.PanelHeight() / (this.effectiveNativeHeight || 1)); // height-limited or unscaled
}
@@ -1362,7 +1365,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
return this.effectiveNativeWidth ? this.effectiveNativeWidth * this.nativeScaling : this.props.PanelWidth();
}
@computed get panelHeight() {
- if (this.effectiveNativeHeight && (!this.fitWidth || !this.layoutDoc.nativeHeightUnfrozen)) {
+ if (this.effectiveNativeHeight && (!this.layout_fitWidth || !this.layoutDoc.nativeHeightUnfrozen)) {
return Math.min(this.props.PanelHeight(), this.effectiveNativeHeight * this.nativeScaling);
}
return this.props.PanelHeight();
@@ -1371,7 +1374,10 @@ export class DocumentView extends React.Component<DocumentViewProps> {
return this.effectiveNativeWidth ? Math.max(0, (this.props.PanelWidth() - this.effectiveNativeWidth * this.nativeScaling) / 2) : 0;
}
@computed get Yshift() {
- return this.effectiveNativeWidth && this.effectiveNativeHeight && Math.abs(this.Xshift) < 0.001 && (!this.layoutDoc.nativeHeightUnfrozen || (!this.fitWidth && this.effectiveNativeHeight * this.nativeScaling <= this.props.PanelHeight()))
+ return this.effectiveNativeWidth &&
+ this.effectiveNativeHeight &&
+ Math.abs(this.Xshift) < 0.001 &&
+ (!this.layoutDoc.nativeHeightUnfrozen || (!this.layout_fitWidth && this.effectiveNativeHeight * this.nativeScaling <= this.props.PanelHeight()))
? Math.max(0, (this.props.PanelHeight() - this.effectiveNativeHeight * this.nativeScaling) / 2)
: 0;
}
@@ -1407,10 +1413,10 @@ export class DocumentView extends React.Component<DocumentViewProps> {
finished?.();
this.docView && (this.docView._animateScaleTime = animTime);
});
- const layoutKey = Cast(this.Document.layoutKey, 'string', null);
- if (layoutKey !== 'layout_icon') {
+ const layout_fieldKey = Cast(this.Document.layout_fieldKey, 'string', null);
+ if (layout_fieldKey !== 'layout_icon') {
this.switchViews(true, 'icon', finalFinished);
- if (layoutKey && layoutKey !== 'layout' && layoutKey !== 'layout_icon') this.Document.deiconifyLayout = layoutKey.replace('layout_', '');
+ if (layout_fieldKey && layout_fieldKey !== 'layout' && layout_fieldKey !== 'layout_icon') this.Document.deiconifyLayout = layout_fieldKey.replace('layout_', '');
} else {
const deiconifyLayout = Cast(this.Document.deiconifyLayout, 'string', null);
this.switchViews(deiconifyLayout ? true : false, deiconifyLayout, finalFinished);
@@ -1430,7 +1436,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
setTimeout(
action(() => {
if (useExistingLayout && custom && this.rootDoc['layout_' + view]) {
- this.rootDoc.layoutKey = 'layout_' + view;
+ this.rootDoc.layout_fieldKey = 'layout_' + view;
} else {
this.setCustomView(custom, view);
}
@@ -1517,7 +1523,7 @@ export class DocumentView extends React.Component<DocumentViewProps> {
width: xshift ?? `${(100 * (this.props.PanelWidth() - this.Xshift * 2)) / this.props.PanelWidth()}%`,
height: this.props.forceAutoHeight
? undefined
- : yshift ?? (this.fitWidth ? `${this.panelHeight}px` : `${(((100 * this.effectiveNativeHeight) / this.effectiveNativeWidth) * this.props.PanelWidth()) / this.props.PanelHeight()}%`),
+ : yshift ?? (this.layout_fitWidth ? `${this.panelHeight}px` : `${(((100 * this.effectiveNativeHeight) / this.effectiveNativeWidth) * this.props.PanelWidth()) / this.props.PanelHeight()}%`),
}}>
<DocumentViewInternal
{...this.props}
@@ -1555,7 +1561,7 @@ ScriptingGlobals.add(function deiconifyViewToLightbox(documentView: DocumentView
});
ScriptingGlobals.add(function toggleDetail(dv: DocumentView, detailLayoutKeySuffix: string) {
- if (dv.Document.layoutKey === 'layout_' + detailLayoutKeySuffix) dv.switchViews(false, 'layout');
+ if (dv.Document.layout_fieldKey === 'layout_' + detailLayoutKeySuffix) dv.switchViews(false, 'layout');
else dv.switchViews(true, detailLayoutKeySuffix, undefined, true);
});
@@ -1568,12 +1574,12 @@ ScriptingGlobals.add(function updateLinkCollection(linkCollection: Doc) {
const other = LinkManager.getOppositeAnchor(link, linkSource);
const otherdoc = !other ? undefined : other.annotationOn ? Cast(other.annotationOn, Doc, null) : other;
if (otherdoc && !collectedLinks?.some(d => Doc.AreProtosEqual(d, otherdoc))) {
- const alias = Doc.MakeAlias(otherdoc);
- alias.x = wid;
- alias.y = 0;
- alias._lockedPosition = false;
+ const embedding = Doc.MakeEmbedding(otherdoc);
+ embedding.x = wid;
+ embedding.y = 0;
+ embedding._lockedPosition = false;
wid += otherdoc[WidthSym]();
- Doc.AddDocToList(Doc.GetProto(linkCollection), 'data', alias);
+ Doc.AddDocToList(Doc.GetProto(linkCollection), 'data', embedding);
}
});
return links;
diff --git a/src/client/views/nodes/EquationBox.tsx b/src/client/views/nodes/EquationBox.tsx
index 163c5a9ed..f17ab06e7 100644
--- a/src/client/views/nodes/EquationBox.tsx
+++ b/src/client/views/nodes/EquationBox.tsx
@@ -90,7 +90,7 @@ export class EquationBox extends ViewBoxBaseComponent<FieldViewProps>() {
};
render() {
TraceMobx();
- const scale = (this.props.NativeDimScaling?.() || 1) * NumCast(this.layoutDoc._viewScale, 1);
+ const scale = (this.props.NativeDimScaling?.() || 1) * NumCast(this.layoutDoc._freeform_scale, 1);
return (
<div
ref={r => this.updateSize()}
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 86779e0dd..85dd779fc 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -50,50 +50,18 @@ export class FieldView extends React.Component<FieldViewProps> {
@computed
get field(): FieldResult {
- const { Document, fieldKey } = this.props;
+ const { Document, fieldKey: fieldKey } = this.props;
return Document[fieldKey];
}
render() {
const field = this.field;
- if (field === undefined) {
- return <p>{'<null>'}</p>;
- }
- // if (typeof field === "string") {
- // return <p>{field}</p>;
- // }
- // else if (field instanceof RichTextField) {
- // return <FormattedTextBox {...this.props} />;
- // }
- // else if (field instanceof ImageField) {
- // return <ImageBox {...this.props} />;
- // }
- // else if (field instaceof PresBox) {
- // return <PresBox {...this.props} />;
- // }
- // else if (field instanceof VideoField) {
- // return <VideoBox {...this.props} />;
- // }
- // else if (field instanceof AudioField) {
- // return <AudioBox {...this.props} />;
- //}
- else if (field instanceof DateField) {
- return <p>{field.date.toLocaleString()}</p>;
- } else if (field instanceof Doc) {
- return (
- <p>
- <b>{field.title?.toString()}</b>
- </p>
- );
- } else if (field instanceof List) {
- return <div> {field.length ? field.map(f => Field.toString(f)).join(', ') : ''} </div>;
- }
- // bcz: this belongs here, but it doesn't render well so taking it out for now
- else if (field instanceof WebField) {
- return <p>{Field.toString(field.url.href)}</p>;
- } else if (!(field instanceof Promise)) {
- return <p>{Field.toString(field)}</p>;
- } else {
- return <p> {'Waiting for server...'} </p>;
- }
+ // prettier-ignore
+ if (field instanceof Doc) return <p> <b>{field.title?.toString()}</b></p>;
+ if (field === undefined) return <p>{'<null>'}</p>;
+ if (field instanceof DateField) return <p>{field.date.toLocaleString()}</p>;
+ if (field instanceof List) return <div> {field.map(f => Field.toString(f)).join(', ')} </div>;
+ if (field instanceof WebField) return <p>{Field.toString(field.url.href)}</p>;
+ if (!(field instanceof Promise)) return <p>{Field.toString(field)}</p>;
+ return <p> {'Waiting for server...'} </p>;
}
}
diff --git a/src/client/views/nodes/FunctionPlotBox.tsx b/src/client/views/nodes/FunctionPlotBox.tsx
index b43e359ff..db72209ab 100644
--- a/src/client/views/nodes/FunctionPlotBox.tsx
+++ b/src/client/views/nodes/FunctionPlotBox.tsx
@@ -90,7 +90,7 @@ export class FunctionPlotBox extends ViewBoxAnnotatableComponent<FieldViewProps>
if (ele) {
this._dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this), this.layoutDoc);
}
- // if (this.autoHeight) this.tryUpdateScrollHeight();
+ // if (this.layout_autoHeight) this.tryUpdateScrollHeight();
};
@computed get theGraph() {
return <div id={`${this._plotId}`} ref={r => r && this.createGraph(r)} style={{ position: 'absolute', width: '100%', height: '100%' }} onPointerDown={e => e.stopPropagation()} />;
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index c9be10d3a..7d1d50cc7 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -79,9 +79,9 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
this._getAnchor?.(this._savedAnnotations, false) ?? // use marquee anchor, otherwise, save zoom/pan as anchor
Docs.Create.ImageanchorDocument({
title: 'ImgAnchor:' + this.rootDoc.title,
- presPanX: NumCast(this.layoutDoc._panX),
- presPanY: NumCast(this.layoutDoc._panY),
- presViewScale: Cast(this.layoutDoc._viewScale, 'number', null),
+ presPanX: NumCast(this.layoutDoc._freeform_panX),
+ presPanY: NumCast(this.layoutDoc._freeform_panY),
+ presViewScale: Cast(this.layoutDoc._freeform_scale, 'number', null),
presTransition: 1000,
unrendered: true,
annotationOn: this.rootDoc,
@@ -99,7 +99,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
this._disposers.sizer = reaction(
() => ({
forceFull: this.props.renderDepth < 1 || this.layoutDoc._showFullRes,
- scrSize: (this.props.ScreenToLocalTransform().inverse().transformDirection(this.nativeSize.nativeWidth, this.nativeSize.nativeHeight)[0] / this.nativeSize.nativeWidth) * NumCast(this.rootDoc._viewScale, 1),
+ scrSize: (this.props.ScreenToLocalTransform().inverse().transformDirection(this.nativeSize.nativeWidth, this.nativeSize.nativeHeight)[0] / this.nativeSize.nativeWidth) * NumCast(this.rootDoc._freeform_scale, 1),
selected: this.props.isSelected(),
}),
({ forceFull, scrSize, selected }) => (this._curSuffix = selected ? '_o' : this.fieldKey === 'icon' ? '_m' : forceFull ? '_o' : scrSize < 0.25 ? '_s' : scrSize < 0.5 ? '_m' : scrSize < 0.8 ? '_l' : '_o'),
@@ -116,7 +116,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
{ fireImmediately: true }
);
this._disposers.scroll = reaction(
- () => this.layoutDoc._scrollTop,
+ () => this.layoutDoc.layout_scrollTop,
s_top => {
this._forcedScroll = true;
!this._ignoreScroll && this._mainCont.current && (this._mainCont.current.scrollTop = NumCast(s_top));
@@ -144,7 +144,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
de.complete.docDragData.droppedDocuments.forEach(
action((drop: Doc) => {
Doc.AddDocToList(this.dataDoc, this.fieldKey + '-alternates', drop);
- this.rootDoc[this.fieldKey + '-usePath'] = 'alternate:hover';
+ this.rootDoc[this.fieldKey + '_usePath'] = 'alternate:hover';
e.stopPropagation();
})
);
@@ -167,28 +167,28 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
@undoBatch
setNativeSize = action(() => {
- const scaling = (this.props.DocumentView?.().props.ScreenToLocalTransform().Scale || 1) / NumCast(this.rootDoc._viewScale, 1);
+ const scaling = (this.props.DocumentView?.().props.ScreenToLocalTransform().Scale || 1) / NumCast(this.rootDoc._freeform_scale, 1);
const nscale = NumCast(this.props.PanelWidth()) / scaling;
- const nh = nscale / NumCast(this.dataDoc[this.fieldKey + '-nativeHeight']);
- const nw = nscale / NumCast(this.dataDoc[this.fieldKey + '-nativeWidth']);
- this.dataDoc[this.fieldKey + '-nativeHeight'] = NumCast(this.dataDoc[this.fieldKey + '-nativeHeight']) * nh;
- this.dataDoc[this.fieldKey + '-nativeWidth'] = NumCast(this.dataDoc[this.fieldKey + '-nativeWidth']) * nh;
- this.rootDoc._panX = nh * NumCast(this.rootDoc._panX);
- this.rootDoc._panY = nh * NumCast(this.rootDoc._panY);
- this.dataDoc._panXMax = this.dataDoc._panXMax ? nh * NumCast(this.dataDoc._panXMax) : undefined;
- this.dataDoc._panXMin = this.dataDoc._panXMin ? nh * NumCast(this.dataDoc._panXMin) : undefined;
- this.dataDoc._panYMax = this.dataDoc._panYMax ? nw * NumCast(this.dataDoc._panYMax) : undefined;
- this.dataDoc._panYMin = this.dataDoc._panYMin ? nw * NumCast(this.dataDoc._panYMin) : undefined;
+ const nh = nscale / NumCast(this.dataDoc[this.fieldKey + '_nativeHeight']);
+ const nw = nscale / NumCast(this.dataDoc[this.fieldKey + '_nativeWidth']);
+ this.dataDoc[this.fieldKey + '_nativeHeight'] = NumCast(this.dataDoc[this.fieldKey + '_nativeHeight']) * nh;
+ this.dataDoc[this.fieldKey + '_nativeWidth'] = NumCast(this.dataDoc[this.fieldKey + '_nativeWidth']) * nh;
+ this.rootDoc._freeform_panX = nh * NumCast(this.rootDoc._freeform_panX);
+ this.rootDoc._freeform_panY = nh * NumCast(this.rootDoc._freeform_panY);
+ this.dataDoc._freeform_panXMax = this.dataDoc._freeform_panXMax ? nh * NumCast(this.dataDoc._freeform_panXMax) : undefined;
+ this.dataDoc._freeform_panXMin = this.dataDoc._freeform_panXMin ? nh * NumCast(this.dataDoc._freeform_panXMin) : undefined;
+ this.dataDoc._freeform_panYMax = this.dataDoc._freeform_panYMax ? nw * NumCast(this.dataDoc._freeform_panYMax) : undefined;
+ this.dataDoc._freeform_panYMin = this.dataDoc._freeform_panYMin ? nw * NumCast(this.dataDoc._freeform_panYMin) : undefined;
});
@undoBatch
rotate = action(() => {
- const nw = NumCast(this.dataDoc[this.fieldKey + '-nativeWidth']);
- const nh = NumCast(this.dataDoc[this.fieldKey + '-nativeHeight']);
+ const nw = NumCast(this.dataDoc[this.fieldKey + '_nativeWidth']);
+ const nh = NumCast(this.dataDoc[this.fieldKey + '_nativeHeight']);
const w = this.layoutDoc._width;
const h = this.layoutDoc._height;
this.dataDoc[this.fieldKey + '-rotation'] = (NumCast(this.dataDoc[this.fieldKey + '-rotation']) + 90) % 360;
- this.dataDoc[this.fieldKey + '-nativeWidth'] = nh;
- this.dataDoc[this.fieldKey + '-nativeHeight'] = nw;
+ this.dataDoc[this.fieldKey + '_nativeWidth'] = nh;
+ this.dataDoc[this.fieldKey + '_nativeHeight'] = nw;
this.layoutDoc._width = h;
this.layoutDoc._height = w;
});
@@ -204,7 +204,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
const anchy = NumCast(cropping.y);
const anchw = NumCast(cropping._width);
const anchh = NumCast(cropping._height);
- const viewScale = NumCast(this.rootDoc[this.fieldKey + '-nativeWidth']) / anchw;
+ const viewScale = NumCast(this.rootDoc[this.fieldKey + '_nativeWidth']) / anchw;
cropping.title = 'crop: ' + this.rootDoc.title;
cropping.x = NumCast(this.rootDoc.x) + NumCast(this.rootDoc._width);
cropping.y = NumCast(this.rootDoc.y);
@@ -213,24 +213,24 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
cropping.onClick = undefined;
const croppingProto = Doc.GetProto(cropping);
croppingProto.annotationOn = undefined;
- croppingProto.isPrototype = true;
+ croppingProto.isDataDoc = true;
croppingProto.backgroundColor = undefined;
croppingProto.proto = Cast(this.rootDoc.proto, Doc, null)?.proto; // set proto of cropping's data doc to be IMAGE_PROTO
croppingProto.type = DocumentType.IMG;
croppingProto.layout = ImageBox.LayoutString('data');
croppingProto.data = ObjectField.MakeCopy(this.rootDoc[this.fieldKey] as ObjectField);
- croppingProto['data-nativeWidth'] = anchw;
- croppingProto['data-nativeHeight'] = anchh;
- croppingProto.viewScale = viewScale;
- croppingProto.viewScaleMin = viewScale;
- croppingProto.panX = anchx / viewScale;
- croppingProto.panY = anchy / viewScale;
- croppingProto.panXMin = anchx / viewScale;
- croppingProto.panXMax = anchw / viewScale;
- croppingProto.panYMin = anchy / viewScale;
- croppingProto.panYMax = anchh / viewScale;
+ croppingProto['data_nativeWidth'] = anchw;
+ croppingProto['data_nativeHeight'] = anchh;
+ croppingProto.freeform_scale = viewScale;
+ croppingProto.freeform_scaleMin = viewScale;
+ croppingProto.freeform_panX = anchx / viewScale;
+ croppingProto.freeform_panY = anchy / viewScale;
+ croppingProto.freeform_panXMin = anchx / viewScale;
+ croppingProto.freeform_panXMax = anchw / viewScale;
+ croppingProto.freeform_panYMin = anchy / viewScale;
+ croppingProto.freeform_panYMax = anchh / viewScale;
if (addCrop) {
- DocUtils.MakeLink(region, cropping, { linkRelationship: 'cropped image' });
+ DocUtils.MakeLink(region, cropping, { link_relationship: 'cropped image' });
cropping.x = NumCast(this.rootDoc.x) + this.rootDoc[WidthSym]();
cropping.y = NumCast(this.rootDoc.y);
this.props.addDocTab(cropping, OpenWhere.inParent);
@@ -312,7 +312,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
return !tags ? null : <img id={'google-tags'} src={'/assets/google_tags.png'} />;
};
- getScrollHeight = () => (this.props.fitWidth?.(this.rootDoc) !== false && NumCast(this.rootDoc._viewScale, 1) === NumCast(this.rootDoc._viewScaleMin, 1) ? this.nativeSize.nativeHeight : undefined);
+ getScrollHeight = () => (this.props.layout_fitWidth?.(this.rootDoc) !== false && NumCast(this.rootDoc._freeform_scale, 1) === NumCast(this.rootDoc._freeform_scaleMin, 1) ? this.nativeSize.nativeHeight : undefined);
@computed
private get considerDownloadIcon() {
@@ -358,13 +358,13 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
@computed get nativeSize() {
TraceMobx();
- const nativeWidth = NumCast(this.dataDoc[this.fieldKey + '-nativeWidth'], NumCast(this.layoutDoc[this.fieldKey + '-nativeWidth'], 500));
- const nativeHeight = NumCast(this.dataDoc[this.fieldKey + '-nativeHeight'], NumCast(this.layoutDoc[this.fieldKey + '-nativeHeight'], 500));
+ const nativeWidth = NumCast(this.dataDoc[this.fieldKey + '_nativeWidth'], NumCast(this.layoutDoc[this.fieldKey + '_nativeWidth'], 500));
+ const nativeHeight = NumCast(this.dataDoc[this.fieldKey + '_nativeHeight'], NumCast(this.layoutDoc[this.fieldKey + '_nativeHeight'], 500));
const nativeOrientation = NumCast(this.dataDoc[this.fieldKey + '-nativeOrientation'], 1);
return { nativeWidth, nativeHeight, nativeOrientation };
}
@computed get overlayImageIcon() {
- const usePath = this.rootDoc[`_${this.fieldKey}-usePath`];
+ const usePath = this.rootDoc[`_${this.fieldKey}_usePath`];
return (
<Tooltip
title={
@@ -385,7 +385,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
<div
className="imageBox-alternateDropTarget"
ref={this._overlayIconRef}
- onPointerDown={e => setupMoveUpEvents(e.target, e, returnFalse, emptyFunction, e => (this.rootDoc[`_${this.fieldKey}-usePath`] = usePath === undefined ? 'alternate' : usePath === 'alternate' ? 'alternate:hover' : undefined))}
+ onPointerDown={e => setupMoveUpEvents(e.target, e, returnFalse, emptyFunction, e => (this.rootDoc[`_${this.fieldKey}_usePath`] = usePath === undefined ? 'alternate' : usePath === 'alternate' ? 'alternate:hover' : undefined))}
style={{
display: (SnappingManager.GetIsDragging() && DragManager.DocDragData?.canEmbed) || DocListCast(this.dataDoc[this.fieldKey + '-alternates']).length ? 'block' : 'none',
width: 'min(10%, 25px)',
@@ -431,7 +431,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
transformOrigin = 'right top';
transform = `translate(-100%, 0%) rotate(${rotation}deg) scale(${aspect})`;
}
- const usePath = this.rootDoc[`_${this.fieldKey}-usePath`];
+ const usePath = this.rootDoc[`_${this.fieldKey}_usePath`];
return (
<div className="imageBox-cont" onPointerEnter={action(() => (this._isHovering = true))} onPointerLeave={action(() => (this._isHovering = false))} key={this.layoutDoc[Id]} ref={this.createDropTarget} onPointerDown={this.marqueeDown}>
@@ -459,9 +459,9 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
TraceMobx();
return <div className="imageBox-annotationLayer" style={{ height: this.props.PanelHeight() }} ref={this._annotationLayer} />;
}
- screenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._scrollTop) * this.props.ScreenToLocalTransform().Scale);
+ screenToLocalTransform = () => this.props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._layout_scrollTop) * this.props.ScreenToLocalTransform().Scale);
marqueeDown = (e: React.PointerEvent) => {
- if (!e.altKey && e.button === 0 && NumCast(this.rootDoc._viewScale, 1) <= NumCast(this.rootDoc.viewScaleMin, 1) && this.props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(Doc.ActiveTool)) {
+ if (!e.altKey && e.button === 0 && NumCast(this.rootDoc._freeform_scale, 1) <= NumCast(this.rootDoc.freeform_scaleMin, 1) && this.props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(Doc.ActiveTool)) {
setupMoveUpEvents(
this,
e,
@@ -497,9 +497,9 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
ref={this._mainCont}
onScroll={action(e => {
if (!this._forcedScroll) {
- if (this.layoutDoc._scrollTop || this._mainCont.current?.scrollTop) {
+ if (this.layoutDoc._layout_scrollTop || this._mainCont.current?.scrollTop) {
this._ignoreScroll = true;
- this.layoutDoc._scrollTop = this._mainCont.current?.scrollTop;
+ this.layoutDoc._layout_scrollTop = this._mainCont.current?.scrollTop;
this._ignoreScroll = false;
}
}
@@ -510,7 +510,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
height: this.props.PanelWidth() ? undefined : `100%`,
pointerEvents: this.layoutDoc._lockedPosition ? 'none' : undefined,
borderRadius,
- overflow: this.layoutDoc.fitWidth || this.props.fitWidth?.(this.rootDoc) ? 'auto' : undefined,
+ overflow: this.layoutDoc.layout_fitWidth || this.props.layout_fitWidth?.(this.rootDoc) ? 'auto' : undefined,
}}>
<CollectionFreeFormView
ref={this._ffref}
diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx
index e317de11e..88a82e8e6 100644
--- a/src/client/views/nodes/KeyValueBox.tsx
+++ b/src/client/views/nodes/KeyValueBox.tsx
@@ -20,6 +20,10 @@ import { ImageBox } from './ImageBox';
import './KeyValueBox.scss';
import { KeyValuePair } from './KeyValuePair';
import React = require('react');
+import { DocumentManager } from '../../util/DocumentManager';
+import { ScriptingGlobals } from '../../util/ScriptingGlobals';
+import { ScriptingRepl } from '../ScriptingRepl';
+import { DocumentIconContainer } from './DocumentIcon';
export type KVPScript = {
script: CompiledScript;
@@ -42,15 +46,13 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
}
reverseNativeScaling = returnTrue;
able = returnAlways;
- fitWidth = returnTrue;
+ layout_fitWidth = returnTrue;
overridePointerEvents = returnAll;
onClickScriptDisable = returnAlways;
@observable private rows: KeyValuePair[] = [];
+ @observable _splitPercentage = 50;
- @computed get splitPercentage() {
- return NumCast(this.props.Document.schemaSplitPercentage, 50);
- }
get fieldDocToLayout() {
return this.props.fieldKey ? DocCast(this.props.Document[this.props.fieldKey], DocCast(this.props.Document)) : this.props.Document;
}
@@ -75,7 +77,7 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
value = dubEq ? value.substring(2) : value;
const options: ScriptOptions = { addReturn: true, typecheck: false, params: { this: Doc.name, self: Doc.name, _last_: 'any', _readOnly_: 'boolean' }, editable: true };
if (dubEq) options.typecheck = false;
- const script = CompileScript(value, options);
+ const script = CompileScript(value, { ...options, transformer: DocumentIconContainer.getTransformer() });
return !script.compiled ? undefined : { script, type: dubEq, onDelegate: eq };
}
@@ -143,7 +145,9 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
const rows: JSX.Element[] = [];
let i = 0;
const self = this;
- for (const key of Object.keys(ids).slice().sort()) {
+ const keys = Object.keys(ids).slice();
+ //for (const key of [...keys.filter(id => id !== 'layout' && !id.includes('_')).sort(), ...keys.filter(id => id === 'layout' || id.includes('_')).sort()]) {
+ for (const key of keys.sort()) {
rows.push(
<KeyValuePair
doc={realDoc}
@@ -158,7 +162,7 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
if (el) self.rows.push(el);
};
})()}
- keyWidth={100 - this.splitPercentage}
+ keyWidth={100 - this._splitPercentage}
rowStyle={'keyValueBox-' + (i++ % 2 ? 'oddRow' : 'evenRow')}
key={key}
keyName={key}
@@ -176,7 +180,7 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
this._keyInput.current!.select();
e.stopPropagation();
}}
- style={{ width: `${100 - this.splitPercentage}%` }}>
+ style={{ width: `${100 - this._splitPercentage}%` }}>
<input style={{ width: '100%' }} ref={this._keyInput} type="text" placeholder="Key" />
</td>
<td
@@ -185,7 +189,7 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
this._valInput.current!.select();
e.stopPropagation();
}}
- style={{ width: `${this.splitPercentage}%` }}>
+ style={{ width: `${this._splitPercentage}%` }}>
<input style={{ width: '100%' }} ref={this._valInput} type="text" placeholder="Value" onKeyDown={this.onEnterKey} />
</td>
</tr>
@@ -195,7 +199,7 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
@action
onDividerMove = (e: PointerEvent): void => {
const nativeWidth = this._mainCont.current!.getBoundingClientRect();
- this.props.Document.schemaSplitPercentage = Math.max(0, 100 - Math.round(((e.clientX - nativeWidth.left) / nativeWidth.width) * 100));
+ this._splitPercentage = Math.max(0, 100 - Math.round(((e.clientX - nativeWidth.left) / nativeWidth.width) * 100));
};
@action
onDividerUp = (e: PointerEvent): void => {
@@ -212,7 +216,7 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
getFieldView = async () => {
const rows = this.rows.filter(row => row.isChecked);
if (rows.length > 1) {
- const parent = Docs.Create.StackingDocument([], { _autoHeight: true, _width: 300, title: `field views for ${DocCast(this.props.Document.data).title}`, _chromeHidden: true });
+ const parent = Docs.Create.StackingDocument([], { _layout_autoHeight: true, _width: 300, title: `field views for ${DocCast(this.props.Document.data).title}`, _chromeHidden: true });
for (const row of rows) {
const field = this.createFieldView(DocCast(this.props.Document.data), row);
field && Doc.AddDocToList(parent, 'data', field);
@@ -225,9 +229,9 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
createFieldView = (templateDoc: Doc, row: KeyValuePair) => {
const metaKey = row.props.keyName;
- const fieldTemplate = Doc.IsDelegateField(templateDoc, metaKey) ? Doc.MakeDelegate(templateDoc) : Doc.MakeAlias(templateDoc);
+ const fieldTemplate = Doc.IsDelegateField(templateDoc, metaKey) ? Doc.MakeDelegate(templateDoc) : Doc.MakeEmbedding(templateDoc);
fieldTemplate.title = metaKey;
- fieldTemplate.fitWidth = true;
+ fieldTemplate.layout_fitWidth = true;
fieldTemplate._xMargin = 10;
fieldTemplate._yMargin = 10;
fieldTemplate._width = 100;
@@ -280,8 +284,8 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
render() {
const dividerDragger =
- this.splitPercentage === 0 ? null : (
- <div className="keyValueBox-dividerDragger" style={{ transform: `translate(calc(${100 - this.splitPercentage}% - 5px), 0px)` }}>
+ this._splitPercentage === 0 ? null : (
+ <div className="keyValueBox-dividerDragger" style={{ transform: `translate(calc(${100 - this._splitPercentage}% - 5px), 0px)` }}>
<div className="keyValueBox-dividerDraggerThumb" onPointerDown={this.onDividerDown} />
</div>
);
@@ -291,10 +295,10 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
<table className="keyValueBox-table">
<tbody className="keyValueBox-tbody">
<tr className="keyValueBox-header">
- <th className="keyValueBox-key" style={{ width: `${100 - this.splitPercentage}%` }} ref={this._keyHeader} onPointerDown={SetupDrag(this._keyHeader, this.getFieldView)}>
+ <th className="keyValueBox-key" style={{ width: `${100 - this._splitPercentage}%` }} ref={this._keyHeader} onPointerDown={SetupDrag(this._keyHeader, this.getFieldView)}>
Key
</th>
- <th className="keyValueBox-fields" style={{ width: `${this.splitPercentage}%` }}>
+ <th className="keyValueBox-fields" style={{ width: `${this._splitPercentage}%` }}>
Fields
</th>
</tr>
diff --git a/src/client/views/nodes/KeyValuePair.scss b/src/client/views/nodes/KeyValuePair.scss
index 5b660e582..2b4867321 100644
--- a/src/client/views/nodes/KeyValuePair.scss
+++ b/src/client/views/nodes/KeyValuePair.scss
@@ -1,60 +1,56 @@
-@import "../global/globalCssVariables";
-
+@import '../global/globalCssVariables';
.keyValuePair-td-key {
- display:inline-block;
+ display: inline-block;
- .keyValuePair-td-key-container{
- width:100%;
- height:100%;
- display: flex;
- flex-direction: row;
- flex-wrap: nowrap;
- justify-content: space-between;
- align-items: center;
- .keyValuePair-td-key-delete{
+ .keyValuePair-td-key-container {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ flex-wrap: nowrap;
+ justify-content: space-between;
+ .keyValuePair-td-key-delete {
position: relative;
background-color: transparent;
- color:red;
+ color: red;
}
.keyValuePair-td-key-check {
position: relative;
margin: 0;
}
+ .keyValuePair-keyFieldMod,
.keyValuePair-keyField {
- width:100%;
+ width: 100%;
margin-left: 20px;
- margin-top: -1px;
font-family: monospace;
- // text-align: center;
- align-self: center;
position: relative;
overflow: auto;
+ display: inline;
+ }
+ .keyValuePair-keyFieldMod {
+ margin-left: 35px;
}
}
}
.keyValuePair-td-value {
- display:inline-block;
+ display: inline-block;
overflow: scroll;
font-family: monospace;
height: 30px;
- .keyValuePair-td-value-container {
- display: flex;
- align-items: center;
- align-content: center;
- flex-direction: row;
- justify-content: space-between;
- flex-wrap: nowrap;
- width: 100%;
- height: 100%;
+ .keyValuePair-td-value-container {
+ display: inline;
+ justify-content: space-between;
+ width: 100%;
+ height: 100%;
- img {
- max-height: 36px;
- width: auto;
- }
- .videoBox-cont{
- width: auto;
- max-height: 36px;
- }
+ img {
+ max-height: 36px;
+ width: auto;
+ }
+ .videoBox-cont {
+ width: auto;
+ max-height: 36px;
+ }
}
-} \ No newline at end of file
+}
diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx
index 7ea6d42ff..509bb667e 100644
--- a/src/client/views/nodes/KeyValuePair.tsx
+++ b/src/client/views/nodes/KeyValuePair.tsx
@@ -66,7 +66,7 @@ export class KeyValuePair extends React.Component<KeyValuePairProps> {
isSelected: returnFalse,
setHeight: returnFalse,
select: emptyFunction,
- dropAction: 'alias',
+ dropAction: 'embed',
bringToFront: emptyFunction,
renderDepth: 1,
isContentActive: returnFalse,
@@ -108,8 +108,8 @@ export class KeyValuePair extends React.Component<KeyValuePairProps> {
})}>
X
</button>
- <input className={'keyValuePair-td-key-check'} type="checkbox" style={hover} onChange={this.handleCheck} ref={this.checkbox} />
- <div className="keyValuePair-keyField" style={{ color: keyStyle }}>
+ <input className="keyValuePair-td-key-check" type="checkbox" style={hover} onChange={this.handleCheck} ref={this.checkbox} />
+ <div className={`keyValuePair-keyField${props.fieldKey.includes('_') ? 'Mod' : ''}`} style={{ color: keyStyle }}>
{'('.repeat(parenCount)}
{props.fieldKey}
{')'.repeat(parenCount)}
@@ -118,13 +118,7 @@ export class KeyValuePair extends React.Component<KeyValuePairProps> {
</td>
<td className="keyValuePair-td-value" style={{ width: `${100 - this.props.keyWidth}%` }} onContextMenu={this.onContextMenu}>
<div className="keyValuePair-td-value-container">
- <EditableView
- contents={contents}
- maxHeight={36}
- height={'auto'}
- GetValue={() => Field.toKeyValueString(props.Document, props.fieldKey)}
- SetValue={(value: string) => KeyValueBox.SetField(props.Document, props.fieldKey, value)}
- />
+ <EditableView contents={contents} GetValue={() => Field.toKeyValueString(props.Document, props.fieldKey)} SetValue={(value: string) => KeyValueBox.SetField(props.Document, props.fieldKey, value)} />
</div>
</td>
</tr>
diff --git a/src/client/views/nodes/LabelBox.tsx b/src/client/views/nodes/LabelBox.tsx
index 916458dfd..32026ea9c 100644
--- a/src/client/views/nodes/LabelBox.tsx
+++ b/src/client/views/nodes/LabelBox.tsx
@@ -37,7 +37,7 @@ export class LabelBox extends ViewBoxBaseComponent<FieldViewProps & LabelBoxProp
}
getTitle() {
- return this.rootDoc['title-custom'] ? StrCast(this.rootDoc.title) : this.props.label ? this.props.label : typeof this.rootDoc[this.fieldKey] === 'string' ? StrCast(this.rootDoc[this.fieldKey]) : StrCast(this.rootDoc.title);
+ return this.rootDoc.title_custom ? StrCast(this.rootDoc.title) : this.props.label ? this.props.label : typeof this.rootDoc[this.fieldKey] === 'string' ? StrCast(this.rootDoc[this.fieldKey]) : StrCast(this.rootDoc.title);
}
protected createDropTarget = (ele: HTMLDivElement) => {
@@ -82,7 +82,7 @@ export class LabelBox extends ViewBoxBaseComponent<FieldViewProps & LabelBoxProp
return this._mouseOver ? StrCast(this.layoutDoc._hoverBackgroundColor) : this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
}
- fitTextToBox = (r: any): any => {
+ fitTextToBox = (r: any) => {
const singleLine = BoolCast(this.rootDoc._singleLine, true);
const params = {
rotateText: null,
@@ -141,9 +141,9 @@ export class LabelBox extends ViewBoxBaseComponent<FieldViewProps & LabelBoxProp
paddingBottom: NumCast(this.rootDoc._yPadding),
width: this.props.PanelWidth(),
height: this.props.PanelHeight(),
- whiteSpace: boxParams.singleLine ? 'pre' : 'pre-wrap',
+ whiteSpace: typeof boxParams !== 'number' && boxParams.singleLine ? 'pre' : 'pre-wrap',
}}>
- <span style={{ width: boxParams.singleLine ? '' : '100%' }} ref={action((r: any) => this.fitTextToBox(r))}>
+ <span style={{ width: typeof boxParams !== 'number' && boxParams.singleLine ? '' : '100%' }} ref={action((r: any) => this.fitTextToBox(r))}>
{label.startsWith('#') ? null : label.replace(/([^a-zA-Z])/g, '$1\u200b')}
</span>
</div>
diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx
index 31f1775e5..f38ef634c 100644
--- a/src/client/views/nodes/LinkAnchorBox.tsx
+++ b/src/client/views/nodes/LinkAnchorBox.tsx
@@ -46,14 +46,14 @@ export class LinkAnchorBox extends ViewBoxBaseComponent<FieldViewProps>() {
const separation = Math.sqrt((pt[0] - e.clientX) * (pt[0] - e.clientX) + (pt[1] - e.clientY) * (pt[1] - e.clientY));
if (separation > 100) {
const dragData = new DragManager.DocumentDragData([this.rootDoc]);
- dragData.dropAction = 'alias';
- dragData.removeDropProperties = ['anchor1_x', 'anchor1_y', 'anchor2_x', 'anchor2_y', 'onClick'];
+ dragData.dropAction = 'embed';
+ dragData.removeDropProperties = ['link_anchor_1_x', 'link_anchor_1_y', 'link_anchor_2_x', 'link_anchor_2_y', 'onClick'];
DragManager.StartDocumentDrag([this._ref.current!], dragData, pt[0], pt[1]);
return true;
} else {
this.rootDoc[this.fieldKey + '_x'] = ((pt[0] - bounds.left) / bounds.width) * 100;
this.rootDoc[this.fieldKey + '_y'] = ((pt[1] - bounds.top) / bounds.height) * 100;
- this.rootDoc.linkAutoMove = false;
+ this.rootDoc.layout_autoMoveAnchors = false;
}
}
return false;
@@ -67,10 +67,14 @@ export class LinkAnchorBox extends ViewBoxBaseComponent<FieldViewProps>() {
const x = NumCast(this.rootDoc[this.fieldKey + '_x'], 100);
const y = NumCast(this.rootDoc[this.fieldKey + '_y'], 100);
const background = this.props.styleProvider?.(this.dataDoc, this.props, StyleProp.BackgroundColor + ':anchor');
- const anchor = this.fieldKey === 'anchor1' ? 'anchor2' : 'anchor1';
- const anchorScale = !this.dataDoc[this.fieldKey + '-useLinkSmallAnchor'] && (x === 0 || x === 100 || y === 0 || y === 100) ? 1 : 0.25;
+ const anchor = this.fieldKey === 'link_anchor_1' ? 'link_anchor_2' : 'link_anchor_1';
+ const anchorScale = !this.dataDoc[this.fieldKey + '_useLinkSmallAnchor'] && (x === 0 || x === 100 || y === 0 || y === 100) ? 1 : 0.25;
const targetTitle = StrCast((this.dataDoc[anchor] as Doc)?.title);
- const selView = SelectionManager.Views().lastElement()?.props.LayoutTemplateString?.includes('anchor1') ? 'anchor1' : SelectionManager.Views().lastElement()?.props.LayoutTemplateString?.includes('anchor2') ? 'anchor2' : '';
+ const selView = SelectionManager.Views().lastElement()?.props.LayoutTemplateString?.includes('link_anchor_1')
+ ? 'link_anchor_1'
+ : SelectionManager.Views().lastElement()?.props.LayoutTemplateString?.includes('link_anchor_2')
+ ? 'link_anchor_2'
+ : '';
return (
<div
ref={this._ref}
diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx
index 46ccdecae..710d41471 100644
--- a/src/client/views/nodes/LinkBox.tsx
+++ b/src/client/views/nodes/LinkBox.tsx
@@ -9,7 +9,7 @@ import './LinkBox.scss';
@observer
export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
- public static LayoutString(fieldKey: string) {
+ public static LayoutString(fieldKey: string = 'link') {
return FieldView.LayoutString(LinkBox, fieldKey);
}
@@ -23,7 +23,7 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
<div className={`linkBox-container${this.props.isContentActive() ? '-interactive' : ''}`} style={{ background: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.BackgroundColor) }}>
<ComparisonBox
{...this.props}
- fieldKey="anchor"
+ fieldKey="link_anchor"
setHeight={emptyFunction}
dontRegisterView={true}
renderDepth={this.props.renderDepth + 1}
diff --git a/src/client/views/nodes/LinkDescriptionPopup.tsx b/src/client/views/nodes/LinkDescriptionPopup.tsx
index 91bd505c5..c45045a8a 100644
--- a/src/client/views/nodes/LinkDescriptionPopup.tsx
+++ b/src/client/views/nodes/LinkDescriptionPopup.tsx
@@ -24,7 +24,7 @@ export class LinkDescriptionPopup extends React.Component<{}> {
onDismiss = (add: boolean) => {
LinkDescriptionPopup.descriptionPopup = false;
if (add) {
- LinkManager.currentLink && (Doc.GetProto(LinkManager.currentLink).description = this.description);
+ LinkManager.currentLink && (Doc.GetProto(LinkManager.currentLink).link_description = this.description);
}
};
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index c58b5dd8c..c6172ee01 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -58,13 +58,13 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
var linkTarget = this.props.linkDoc;
this._linkSrc = this.props.linkSrc;
this._linkDoc = this.props.linkDoc;
- const anchor1 = this._linkDoc?.anchor1 as Doc;
- const anchor2 = this._linkDoc?.anchor2 as Doc;
- if (anchor1 && anchor2) {
- linkTarget = Doc.AreProtosEqual(anchor1, this._linkSrc) || Doc.AreProtosEqual(anchor1?.annotationOn as Doc, this._linkSrc) ? anchor2 : anchor1;
+ const link_anchor_1 = this._linkDoc?.link_anchor_1 as Doc;
+ const link_anchor_2 = this._linkDoc?.link_anchor_2 as Doc;
+ if (link_anchor_1 && link_anchor_2) {
+ linkTarget = Doc.AreProtosEqual(link_anchor_1, this._linkSrc) || Doc.AreProtosEqual(link_anchor_1?.annotationOn as Doc, this._linkSrc) ? link_anchor_2 : link_anchor_1;
}
if (linkTarget?.annotationOn && linkTarget?.type !== DocumentType.RTF) {
- // want to show annotation context document if annotation is not text
+ // want to show annotation embedContainer document if annotation is not text
linkTarget && DocCastAsync(linkTarget.annotationOn).then(action(anno => (this._markerTargetDoc = this._targetDoc = anno)));
} else {
this._markerTargetDoc = this._targetDoc = linkTarget;
@@ -111,7 +111,7 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
action(anchor => {
if (anchor instanceof Doc && LinkManager.Links(anchor).length) {
this._linkDoc = this._linkDoc ?? LinkManager.Links(anchor)[0];
- const automaticLink = this._linkDoc.linkRelationship === LinkManager.AutoKeywords;
+ const automaticLink = this._linkDoc.link_relationship === LinkManager.AutoKeywords;
if (automaticLink) {
// automatic links specify the target in the link info, not the source
const linkTarget = anchor;
@@ -175,7 +175,7 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
} else if (this.props.hrefs?.length) {
const webDoc =
Array.from(SearchBox.staticSearchCollection(Doc.MyFilesystem, this.props.hrefs[0]).keys()).lastElement() ??
- Docs.Create.WebDocument(this.props.hrefs[0], { title: this.props.hrefs[0], _nativeWidth: 850, _width: 200, _height: 400, useCors: true });
+ Docs.Create.WebDocument(this.props.hrefs[0], { title: this.props.hrefs[0], _nativeWidth: 850, _width: 200, _height: 400, data_useCors: true });
this.props.docProps?.addDocTab(webDoc, OpenWhere.lightbox);
}
};
@@ -208,7 +208,7 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
</div>
<div className="linkDocPreview-title" style={{ pointerEvents: 'all' }}>
{StrCast(this._markerTargetDoc.title).length > 16 ? StrCast(this._markerTargetDoc.title).substr(0, 16) + '...' : StrCast(this._markerTargetDoc.title)}
- <p className="linkDocPreview-description"> {StrCast(this._linkDoc.description)}</p>
+ <p className="linkDocPreview-description"> {StrCast(this._linkDoc.link_description)}</p>
</div>
<div className="linkDocPreview-buttonBar" style={{ float: 'right' }}>
<Tooltip title={<div className="dash-tooltip">Next Link</div>} placement="top">
@@ -263,7 +263,7 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
isDocumentActive={returnFalse}
isContentActive={returnFalse}
addDocument={returnFalse}
- showTitle={returnEmptyString}
+ layout_showTitle={returnEmptyString}
removeDocument={returnFalse}
addDocTab={returnFalse}
pinToPres={returnFalse}
@@ -278,7 +278,7 @@ export class LinkDocPreview extends React.Component<LinkDocPreviewProps> {
pointerEvents={returnNone}
focus={emptyFunction}
whenChildContentsActiveChanged={returnFalse}
- ignoreAutoHeight={true} // need to ignore autoHeight otherwise autoHeight text boxes will expand beyond the preview panel size.
+ ignoreAutoHeight={true} // need to ignore layout_autoHeight otherwise layout_autoHeight text boxes will expand beyond the preview panel size.
bringToFront={returnFalse}
NativeWidth={Doc.NativeWidth(this._targetDoc) ? () => Doc.NativeWidth(this._targetDoc) : undefined}
NativeHeight={Doc.NativeHeight(this._targetDoc) ? () => Doc.NativeHeight(this._targetDoc) : undefined}
diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx
index 06021921c..d87974bd4 100644
--- a/src/client/views/nodes/MapBox/MapBox.tsx
+++ b/src/client/views/nodes/MapBox/MapBox.tsx
@@ -90,7 +90,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
return FieldView.LayoutString(MapBox, fieldKey);
}
public get SidebarKey() {
- return this.fieldKey + '-sidebar';
+ return this.fieldKey + '_sidebar';
}
private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean, hide: boolean) => void);
@computed get inlineTextAnnotations() {
@@ -117,7 +117,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
@observable _showSidebar = false;
@computed get SidebarShown() {
- return this._showSidebar || this.layoutDoc._showSidebar ? true : false;
+ return this._showSidebar || this.layoutDoc._layout_showSidebar ? true : false;
}
static _canAnnotate = true;
@@ -274,7 +274,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
setTimeout(() => {
if (this._loadPending && this._map.getBounds()) {
this._loadPending = false;
- this.layoutDoc.fitContentsToBox && this.fitBounds(this._map);
+ this.layoutDoc.freeform_fitContentsToBox && this.fitBounds(this._map);
}
}, 250);
// listener to addmarker event
@@ -289,7 +289,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
centered = () => {
if (this._loadPending && this._map.getBounds()) {
this._loadPending = false;
- this.layoutDoc.fitContentsToBox && this.fitBounds(this._map);
+ this.layoutDoc.freeform_fitContentsToBox && this.fitBounds(this._map);
}
this.dataDoc.mapLat = this._map.getCenter()?.lat();
this.dataDoc.mapLng = this._map.getCenter()?.lng();
@@ -299,7 +299,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
zoomChanged = () => {
if (this._loadPending && this._map.getBounds()) {
this._loadPending = false;
- this.layoutDoc.fitContentsToBox && this.fitBounds(this._map);
+ this.layoutDoc.freeform_fitContentsToBox && this.fitBounds(this._map);
}
this.dataDoc.mapZoom = this._map.getZoom();
};
@@ -358,7 +358,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
*/
sidebarAddDocument = (doc: Doc | Doc[], sidebarKey?: string) => {
console.log('print all sidebar Docs');
- if (!this.layoutDoc._showSidebar) this.toggleSidebar();
+ if (!this.layoutDoc._layout_showSidebar) this.toggleSidebar();
const docs = doc instanceof Doc ? [doc] : doc;
docs.forEach(doc => {
if (doc.lat !== undefined && doc.lng !== undefined) {
@@ -382,7 +382,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
* @returns
*/
sidebarRemoveDocument = (doc: Doc | Doc[], sidebarKey?: string) => {
- if (this.layoutDoc._showSidebar) this.toggleSidebar();
+ if (this.layoutDoc._layout_showSidebar) this.toggleSidebar();
const docs = doc instanceof Doc ? [doc] : doc;
return this.removeDocument(doc, sidebarKey);
};
@@ -406,11 +406,11 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
if (this.sidebarWidth() + localDelta[0] > 0) {
this._showSidebar = true;
this.layoutDoc._width = fullWidth + localDelta[0];
- this.layoutDoc._sidebarWidthPercent = ((100 * (this.sidebarWidth() + localDelta[0])) / (fullWidth + localDelta[0])).toString() + '%';
+ this.layoutDoc._layout_sidebarWidthPercent = ((100 * (this.sidebarWidth() + localDelta[0])) / (fullWidth + localDelta[0])).toString() + '%';
} else {
this._showSidebar = false;
this.layoutDoc._width = mapWidth;
- this.layoutDoc._sidebarWidthPercent = '0%';
+ this.layoutDoc._layout_sidebarWidthPercent = '0%';
}
return false;
}),
@@ -419,12 +419,12 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
);
};
- sidebarWidth = () => (Number(this.sidebarWidthPercent.substring(0, this.sidebarWidthPercent.length - 1)) / 100) * this.props.PanelWidth();
- @computed get sidebarWidthPercent() {
- return StrCast(this.layoutDoc._sidebarWidthPercent, '0%');
+ sidebarWidth = () => (Number(this.layout_sidebarWidthPercent.substring(0, this.layout_sidebarWidthPercent.length - 1)) / 100) * this.props.PanelWidth();
+ @computed get layout_sidebarWidthPercent() {
+ return StrCast(this.layoutDoc._layout_sidebarWidthPercent, '0%');
}
@computed get sidebarColor() {
- return StrCast(this.layoutDoc.sidebarColor, StrCast(this.layoutDoc[this.props.fieldKey + '-backgroundColor'], '#e4e4e4'));
+ return StrCast(this.layoutDoc.sidebarColor, StrCast(this.layoutDoc[this.props.fieldKey + '_backgroundColor'], '#e4e4e4'));
}
/**
@@ -438,7 +438,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
title="Toggle Sidebar"
style={{
display: !this.props.isContentActive() ? 'none' : undefined,
- top: StrCast(this.rootDoc._showTitle) === 'title' ? 20 : 5,
+ top: StrCast(this.rootDoc._layout_showTitle) === 'title' ? 20 : 5,
backgroundColor: this.SidebarShown ? Colors.MEDIUM_BLUE : Colors.BLACK,
}}
onPointerDown={this.sidebarBtnDown}>
@@ -452,8 +452,8 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
toggleSidebar = () => {
//1.2 * w * ? = .2 * w .2/1.2
const prevWidth = this.sidebarWidth();
- this.layoutDoc._showSidebar = (this.layoutDoc._sidebarWidthPercent = StrCast(this.layoutDoc._sidebarWidthPercent, '0%') === '0%' ? `${(100 * 0.2) / 1.2}%` : '0%') !== '0%';
- this.layoutDoc._width = this.layoutDoc._showSidebar ? NumCast(this.layoutDoc._width) * 1.2 : Math.max(20, NumCast(this.layoutDoc._width) - prevWidth);
+ this.layoutDoc._layout_showSidebar = (this.layoutDoc._layout_sidebarWidthPercent = StrCast(this.layoutDoc._layout_sidebarWidthPercent, '0%') === '0%' ? `${(100 * 0.2) / 1.2}%` : '0%') !== '0%';
+ this.layoutDoc._width = this.layoutDoc._layout_showSidebar ? NumCast(this.layoutDoc._width) * 1.2 : Math.max(20, NumCast(this.layoutDoc._width) - prevWidth);
};
sidebarDown = (e: React.PointerEvent) => {
@@ -461,8 +461,8 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
};
sidebarMove = (e: PointerEvent, down: number[], delta: number[]) => {
const bounds = this._ref.current!.getBoundingClientRect();
- this.layoutDoc._sidebarWidthPercent = '' + 100 * Math.max(0, 1 - (e.clientX - bounds.left) / bounds.width) + '%';
- this.layoutDoc._showSidebar = this.layoutDoc._sidebarWidthPercent !== '0%';
+ this.layoutDoc._layout_sidebarWidthPercent = '' + 100 * Math.max(0, 1 - (e.clientX - bounds.left) / bounds.width) + '%';
+ this.layoutDoc._layout_showSidebar = this.layoutDoc._layout_sidebarWidthPercent !== '0%';
e.preventDefault();
return false;
};
@@ -532,7 +532,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
panelWidth = () => this.props.PanelWidth() / (this.props.NativeDimScaling?.() || 1) - this.sidebarWidth();
panelHeight = () => this.props.PanelHeight() / (this.props.NativeDimScaling?.() || 1);
- scrollXf = () => this.props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._scrollTop));
+ scrollXf = () => this.props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._layout_scrollTop));
transparentFilter = () => [...this.props.docFilters(), Utils.IsTransparentFilter()];
opaqueFilter = () => [...this.props.docFilters(), Utils.IsOpaqueFilter()];
infoWidth = () => this.props.PanelWidth() / 5;
@@ -791,7 +791,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
// zoom: 15,
// });
}}
- style={{ width: `calc(100% - ${this.sidebarWidthPercent})`, pointerEvents: this.pointerEvents() }}>
+ style={{ width: `calc(100% - ${this.layout_sidebarWidthPercent})`, pointerEvents: this.pointerEvents() }}>
<div style={{ mixBlendMode: 'multiply' }}>{renderAnnotations(this.transparentFilter)}</div>
{renderAnnotations(this.opaqueFilter)}
{SnappingManager.GetIsDragging() ? null : renderAnnotations()}
@@ -853,7 +853,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
)}
</div>
{/* </LoadScript > */}
- <div className="mapBox-sidebar" style={{ width: `${this.sidebarWidthPercent}`, backgroundColor: `${this.sidebarColor}` }}>
+ <div className="mapBox-sidebar" style={{ width: `${this.layout_sidebarWidthPercent}`, backgroundColor: `${this.sidebarColor}` }}>
<SidebarAnnos
ref={this._sidebarRef}
{...this.props}
diff --git a/src/client/views/nodes/MapBox/MapBox2.tsx b/src/client/views/nodes/MapBox/MapBox2.tsx
index e3eeaba26..9354f9639 100644
--- a/src/client/views/nodes/MapBox/MapBox2.tsx
+++ b/src/client/views/nodes/MapBox/MapBox2.tsx
@@ -21,16 +21,16 @@ import { Annotation } from '../../pdf/Annotation';
import { SidebarAnnos } from '../../SidebarAnnos';
import { FieldView, FieldViewProps } from '../FieldView';
import { PinProps } from '../trails';
-import './MapBox.scss';
+import './MapBox2.scss';
import { MapBoxInfoWindow } from './MapBoxInfoWindow';
/**
- * MapBox architecture:
- * Main component: MapBox.tsx
+ * MapBox2 architecture:
+ * Main component: MapBox2.tsx
* Supporting Components: SidebarAnnos, CollectionStackingView
*
- * MapBox is a node that extends the ViewBoxAnnotatableComponent. Similar to PDFBox and WebBox, it supports interaction between sidebar content and document content.
- * The main body of MapBox uses Google Maps API to allow location retrieval, adding map markers, pan and zoom, and open street view.
+ * MapBox2 is a node that extends the ViewBoxAnnotatableComponent. Similar to PDFBox and WebBox, it supports interaction between sidebar content and document content.
+ * The main body of MapBox2 uses Google Maps API to allow location retrieval, adding map markers, pan and zoom, and open street view.
* Dash Document architecture is integrated with Maps API: When drag and dropping documents with ExifData (gps Latitude and Longitude information) available,
* sidebarAddDocument function checks if the document contains lat & lng information, if it does, then the document is added to both the sidebar and the infowindow (a pop up corresponding to a map marker--pin on map).
* The lat and lng field of the document is filled when importing (spec see ConvertDMSToDD method and processFileUpload method in Documents.ts).
@@ -85,17 +85,17 @@ const options = {
} as google.maps.places.AutocompleteOptions;
@observer
-export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps & FieldViewProps & Partial<GoogleMapProps>>() {
+export class MapBox2 extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps & FieldViewProps & Partial<GoogleMapProps>>() {
private _dropDisposer?: DragManager.DragDropDisposer;
private _disposers: { [name: string]: IReactionDisposer } = {};
private _annotationLayer: React.RefObject<HTMLDivElement> = React.createRef();
@observable private _overlayAnnoInfo: Opt<Doc>;
showInfo = action((anno: Opt<Doc>) => (this._overlayAnnoInfo = anno));
public static LayoutString(fieldKey: string) {
- return FieldView.LayoutString(MapBox, fieldKey);
+ return FieldView.LayoutString(MapBox2, fieldKey);
}
public get SidebarKey() {
- return this.fieldKey + '-sidebar';
+ return this.fieldKey + '_sidebar';
}
private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean, hide: boolean) => void);
@computed get inlineTextAnnotations() {
@@ -123,7 +123,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
@observable _showSidebar = false;
@computed get SidebarShown() {
- return this._showSidebar || this.layoutDoc._showSidebar ? true : false;
+ return this._showSidebar || this.layoutDoc._layout_showSidebar ? true : false;
}
static _canAnnotate = true;
@@ -154,7 +154,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
*/
private CenterControl = () => {
const controlDiv = document.createElement('div');
- controlDiv.className = 'mapBox-addMarker';
+ controlDiv.className = 'MapBox2-addMarker';
// Set CSS for the control border.
const controlUI = document.createElement('div');
controlUI.style.backgroundColor = '#fff';
@@ -264,7 +264,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
setTimeout(() => {
if (this._loadPending && this._map.getBounds()) {
this._loadPending = false;
- this.layoutDoc.fitContentsToBox && this.fitBounds(this._map);
+ this.layoutDoc.freeform_fitContentsToBox && this.fitBounds(this._map);
}
}, 250);
// listener to addmarker event
@@ -279,7 +279,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
centered = () => {
if (this._loadPending && this._map.getBounds()) {
this._loadPending = false;
- this.layoutDoc.fitContentsToBox && this.fitBounds(this._map);
+ this.layoutDoc.freeform_fitContentsToBox && this.fitBounds(this._map);
}
this.dataDoc.mapLat = this._map.getCenter()?.lat();
this.dataDoc.mapLng = this._map.getCenter()?.lng();
@@ -289,7 +289,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
zoomChanged = () => {
if (this._loadPending && this._map.getBounds()) {
this._loadPending = false;
- this.layoutDoc.fitContentsToBox && this.fitBounds(this._map);
+ this.layoutDoc.freeform_fitContentsToBox && this.fitBounds(this._map);
}
this.dataDoc.mapZoom = this._map.getZoom();
};
@@ -324,7 +324,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
*/
sidebarAddDocument = (doc: Doc | Doc[], sidebarKey?: string) => {
console.log('print all sidebar Docs');
- if (!this.layoutDoc._showSidebar) this.toggleSidebar();
+ if (!this.layoutDoc._layout_showSidebar) this.toggleSidebar();
const docs = doc instanceof Doc ? [doc] : doc;
docs.forEach(doc => {
if (doc.lat !== undefined && doc.lng !== undefined) {
@@ -348,7 +348,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
* @returns
*/
sidebarRemoveDocument = (doc: Doc | Doc[], sidebarKey?: string) => {
- if (this.layoutDoc._showSidebar) this.toggleSidebar();
+ if (this.layoutDoc._layout_showSidebar) this.toggleSidebar();
const docs = doc instanceof Doc ? [doc] : doc;
return this.removeDocument(doc, sidebarKey);
};
@@ -372,11 +372,11 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
if (this.sidebarWidth() + localDelta[0] > 0) {
this._showSidebar = true;
this.layoutDoc._width = fullWidth + localDelta[0];
- this.layoutDoc._sidebarWidthPercent = ((100 * (this.sidebarWidth() + localDelta[0])) / (fullWidth + localDelta[0])).toString() + '%';
+ this.layoutDoc._layout_sidebarWidthPercent = ((100 * (this.sidebarWidth() + localDelta[0])) / (fullWidth + localDelta[0])).toString() + '%';
} else {
this._showSidebar = false;
this.layoutDoc._width = mapWidth;
- this.layoutDoc._sidebarWidthPercent = '0%';
+ this.layoutDoc._layout_sidebarWidthPercent = '0%';
}
return false;
}),
@@ -385,12 +385,12 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
);
};
- sidebarWidth = () => (Number(this.sidebarWidthPercent.substring(0, this.sidebarWidthPercent.length - 1)) / 100) * this.props.PanelWidth();
- @computed get sidebarWidthPercent() {
- return StrCast(this.layoutDoc._sidebarWidthPercent, '0%');
+ sidebarWidth = () => (Number(this.layout_sidebarWidthPercent.substring(0, this.layout_sidebarWidthPercent.length - 1)) / 100) * this.props.PanelWidth();
+ @computed get layout_sidebarWidthPercent() {
+ return StrCast(this.layoutDoc._layout_sidebarWidthPercent, '0%');
}
@computed get sidebarColor() {
- return StrCast(this.layoutDoc.sidebarColor, StrCast(this.layoutDoc[this.props.fieldKey + '-backgroundColor'], '#e4e4e4'));
+ return StrCast(this.layoutDoc.sidebarColor, StrCast(this.layoutDoc[this.props.fieldKey + '_backgroundColor'], '#e4e4e4'));
}
/**
@@ -445,12 +445,12 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
@computed get sidebarHandle() {
return (
<div
- className="mapBox-overlayButton-sidebar"
+ className="MapBox2-overlayButton-sidebar"
key="sidebar"
title="Toggle Sidebar"
style={{
display: !this.props.isContentActive() ? 'none' : undefined,
- top: StrCast(this.rootDoc._showTitle) === 'title' ? 20 : 5,
+ top: StrCast(this.rootDoc._layout_showTitle) === 'title' ? 20 : 5,
backgroundColor: this.SidebarShown ? Colors.MEDIUM_BLUE : Colors.BLACK,
}}
onPointerDown={this.sidebarBtnDown}>
@@ -464,8 +464,8 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
toggleSidebar = () => {
//1.2 * w * ? = .2 * w .2/1.2
const prevWidth = this.sidebarWidth();
- this.layoutDoc._showSidebar = (this.layoutDoc._sidebarWidthPercent = StrCast(this.layoutDoc._sidebarWidthPercent, '0%') === '0%' ? `${(100 * 0.2) / 1.2}%` : '0%') !== '0%';
- this.layoutDoc._width = this.layoutDoc._showSidebar ? NumCast(this.layoutDoc._width) * 1.2 : Math.max(20, NumCast(this.layoutDoc._width) - prevWidth);
+ this.layoutDoc._layout_showSidebar = (this.layoutDoc._layout_sidebarWidthPercent = StrCast(this.layoutDoc._layout_sidebarWidthPercent, '0%') === '0%' ? `${(100 * 0.2) / 1.2}%` : '0%') !== '0%';
+ this.layoutDoc._width = this.layoutDoc._layout_showSidebar ? NumCast(this.layoutDoc._width) * 1.2 : Math.max(20, NumCast(this.layoutDoc._width) - prevWidth);
};
sidebarDown = (e: React.PointerEvent) => {
@@ -473,8 +473,8 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
};
sidebarMove = (e: PointerEvent, down: number[], delta: number[]) => {
const bounds = this._ref.current!.getBoundingClientRect();
- this.layoutDoc._sidebarWidthPercent = '' + 100 * Math.max(0, 1 - (e.clientX - bounds.left) / bounds.width) + '%';
- this.layoutDoc._showSidebar = this.layoutDoc._sidebarWidthPercent !== '0%';
+ this.layoutDoc._layout_sidebarWidthPercent = '' + 100 * Math.max(0, 1 - (e.clientX - bounds.left) / bounds.width) + '%';
+ this.layoutDoc._layout_showSidebar = this.layoutDoc._layout_sidebarWidthPercent !== '0%';
e.preventDefault();
return false;
};
@@ -513,7 +513,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
};
@computed get annotationLayer() {
return (
- <div className="mapBox-annotationLayer" style={{ height: Doc.NativeHeight(this.Document) || undefined }} ref={this._annotationLayer}>
+ <div className="MapBox2-annotationLayer" style={{ height: Doc.NativeHeight(this.Document) || undefined }} ref={this._annotationLayer}>
{this.inlineTextAnnotations
.sort((a, b) => NumCast(a.y) - NumCast(b.y))
.map(anno => (
@@ -545,7 +545,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
panelWidth = () => this.props.PanelWidth() / (this.props.NativeDimScaling?.() || 1) - this.sidebarWidth();
panelHeight = () => this.props.PanelHeight() / (this.props.NativeDimScaling?.() || 1);
- scrollXf = () => this.props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._scrollTop));
+ scrollXf = () => this.props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._layout_scrollTop));
transparentFilter = () => [...this.props.docFilters(), Utils.IsTransparentFilter()];
opaqueFilter = () => [...this.props.docFilters(), Utils.IsOpaqueFilter()];
infoWidth = () => this.props.PanelWidth() / 5;
@@ -559,14 +559,14 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
render() {
const renderAnnotations = (docFilters?: () => string[]) => null;
return (
- <div className="mapBox" ref={this._ref}>
+ <div className="MapBox2" ref={this._ref}>
<div
- className="mapBox-wrapper"
+ className="MapBox2-wrapper"
onWheel={e => e.stopPropagation()}
onPointerDown={async e => {
e.button === 0 && !e.ctrlKey && e.stopPropagation();
}}
- style={{ width: `calc(100% - ${this.sidebarWidthPercent})`, pointerEvents: this.pointerEvents() }}>
+ style={{ width: `calc(100% - ${this.layout_sidebarWidthPercent})`, pointerEvents: this.pointerEvents() }}>
<div style={{ mixBlendMode: 'multiply' }}>{renderAnnotations(this.transparentFilter)}</div>
{renderAnnotations(this.opaqueFilter)}
{SnappingManager.GetIsDragging() ? null : renderAnnotations()}
@@ -575,7 +575,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
<div>
<GoogleMap mapContainerStyle={mapContainerStyle} onZoomChanged={this.zoomChanged} onCenterChanged={this.centered} onLoad={this.loadHandler} options={mapOptions}>
<Autocomplete onLoad={this.setSearchBox} onPlaceChanged={this.handlePlaceChanged}>
- <input className="mapBox-input" ref={this.inputRef} type="text" onKeyDown={e => e.stopPropagation()} placeholder="Enter location" />
+ <input className="MapBox2-input" ref={this.inputRef} type="text" onKeyDown={e => e.stopPropagation()} placeholder="Enter location" />
</Autocomplete>
{this.renderMarkers()}
@@ -616,7 +616,7 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
)}
</div>
{/* </LoadScript > */}
- <div className="mapBox-sidebar" style={{ width: `${this.sidebarWidthPercent}`, backgroundColor: `${this.sidebarColor}` }}>
+ <div className="MapBox2-sidebar" style={{ width: `${this.layout_sidebarWidthPercent}`, backgroundColor: `${this.sidebarColor}` }}>
<SidebarAnnos
ref={this._sidebarRef}
{...this.props}
diff --git a/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx b/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx
index 0c1a62ddb..04cb12ade 100644
--- a/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx
+++ b/src/client/views/nodes/MapBox/MapBoxInfoWindow.tsx
@@ -32,7 +32,7 @@ export class MapBoxInfoWindow extends React.Component<MapBoxInfoWindowProps & Vi
addNoteClick = (e: React.PointerEvent) => {
setupMoveUpEvents(this, e, returnFalse, emptyFunction, e => {
- const newBox = Docs.Create.TextDocument('Note', { _autoHeight: true });
+ const newBox = Docs.Create.TextDocument('Note', { _layout_autoHeight: true });
FormattedTextBox.SelectOnLoad = newBox[Id]; // track the new text box so we can give it a prop that tells it to focus itself when it's displayed
Doc.AddDocToList(this.props.place, 'data', newBox);
this._stack?.scrollToBottom();
@@ -42,7 +42,7 @@ export class MapBoxInfoWindow extends React.Component<MapBoxInfoWindowProps & Vi
};
_stack: CollectionStackingView | CollectionNoteTakingView | null | undefined;
- childFitWidth = (doc: Doc) => doc.type === DocumentType.RTF;
+ childLayoutFitWidth = (doc: Doc) => doc.type === DocumentType.RTF;
addDoc = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((p, d) => p && Doc.AddDocToList(this.props.place, 'data', d), true as boolean);
removeDoc = (doc: Doc | Doc[]) => (doc instanceof Doc ? [doc] : doc).reduce((p, d) => p && Doc.RemoveDocFromList(this.props.place, 'data', d), true as boolean);
render() {
@@ -71,7 +71,7 @@ export class MapBoxInfoWindow extends React.Component<MapBoxInfoWindowProps & Vi
rootSelected={returnFalse}
childHideResizeHandles={returnTrue}
childHideDecorationTitle={returnTrue}
- childFitWidth={this.childFitWidth}
+ childLayoutFitWidth={this.childLayoutFitWidth}
// childDocumentsActive={returnFalse}
removeDocument={this.removeDoc}
addDocument={this.addDoc}
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 6aa04e356..edeaba322 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -63,7 +63,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
super(props);
const nw = Doc.NativeWidth(this.Document, this.dataDoc) || 927;
const nh = Doc.NativeHeight(this.Document, this.dataDoc) || 1200;
- !this.Document._fitWidth && (this.Document._height = this.Document[WidthSym]() * (nh / nw));
+ !this.Document._layout_fitWidth && (this.Document._height = this.Document[WidthSym]() * (nh / nw));
if (this.pdfUrl) {
if (PDFBox.pdfcache.get(this.pdfUrl.url.href)) runInAction(() => (this._pdf = PDFBox.pdfcache.get(this.pdfUrl!.url.href)));
else if (PDFBox.pdfpromise.get(this.pdfUrl.url.href)) PDFBox.pdfpromise.get(this.pdfUrl.url.href)?.then(action((pdf: any) => (this._pdf = pdf)));
@@ -122,15 +122,15 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
cropping.onClick = undefined;
const croppingProto = Doc.GetProto(cropping);
croppingProto.annotationOn = undefined;
- croppingProto.isPrototype = true;
+ croppingProto.isDataDoc = true;
croppingProto.proto = Cast(this.rootDoc.proto, Doc, null)?.proto; // set proto of cropping's data doc to be IMAGE_PROTO
croppingProto.type = DocumentType.IMG;
croppingProto.layout = ImageBox.LayoutString('data');
croppingProto.data = new ImageField(Utils.CorsProxy('http://www.cs.brown.edu/~bcz/noImage.png'));
- croppingProto['data-nativeWidth'] = anchw;
- croppingProto['data-nativeHeight'] = anchh;
+ croppingProto['data_nativeWidth'] = anchw;
+ croppingProto['data_nativeHeight'] = anchh;
if (addCrop) {
- DocUtils.MakeLink(region, cropping, { linkRelationship: 'cropped image' });
+ DocUtils.MakeLink(region, cropping, { link_relationship: 'cropped image' });
}
this.props.bringToFront(cropping);
@@ -140,8 +140,8 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
htmlString,
anchw,
anchh,
- (NumCast(region.y) * this.props.PanelWidth()) / NumCast(this.rootDoc[this.fieldKey + '-nativeWidth']),
- (NumCast(region.x) * this.props.PanelWidth()) / NumCast(this.rootDoc[this.fieldKey + '-nativeWidth']),
+ (NumCast(region.y) * this.props.PanelWidth()) / NumCast(this.rootDoc[this.fieldKey + '_nativeWidth']),
+ (NumCast(region.x) * this.props.PanelWidth()) / NumCast(this.rootDoc[this.fieldKey + '_nativeWidth']),
4
)
.then((data_url: any) => {
@@ -173,15 +173,15 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
this.layoutDoc[HeightSym](),
this.props.PanelWidth(),
this.props.PanelHeight(),
- NumCast(this.layoutDoc._scrollTop),
- NumCast(this.rootDoc[this.fieldKey + '-nativeHeight'], 1),
+ NumCast(this.layoutDoc._layout_scrollTop),
+ NumCast(this.rootDoc[this.fieldKey + '_nativeHeight'], 1),
true,
this.layoutDoc[Id] + '-icon',
(iconFile: string, nativeWidth: number, nativeHeight: number) => {
setTimeout(() => {
this.dataDoc.icon = new ImageField(iconFile);
- this.dataDoc['icon-nativeWidth'] = nativeWidth;
- this.dataDoc['icon-nativeHeight'] = nativeHeight;
+ this.dataDoc['icon_nativeWidth'] = nativeWidth;
+ this.dataDoc['icon_nativeHeight'] = nativeHeight;
}, 500);
}
);
@@ -201,13 +201,13 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
{ fireImmediately: true }
);
this._disposers.scroll = reaction(
- () => this.rootDoc.scrollTop,
+ () => this.rootDoc.layout_scrollTop,
() => {
- if (!(ComputedField.WithoutComputed(() => FieldValue(this.props.Document[this.SidebarKey + '-panY'])) instanceof ComputedField)) {
- this.props.Document[this.SidebarKey + '-panY'] = ComputedField.MakeFunction('this.scrollTop');
+ if (!(ComputedField.WithoutComputed(() => FieldValue(this.props.Document[this.SidebarKey + '_panY'])) instanceof ComputedField)) {
+ this.props.Document[this.SidebarKey + '_panY'] = ComputedField.MakeFunction('this.layout_scrollTop');
}
- this.props.Document[this.SidebarKey + '-viewScale'] = 1;
- this.props.Document[this.SidebarKey + '-panX'] = 0;
+ this.props.Document[this.SidebarKey + '_freeform_scale'] = 1;
+ this.props.Document[this.SidebarKey + '_freeform_panX'] = 0;
}
);
}
@@ -215,7 +215,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
brushView = (view: { width: number; height: number; panX: number; panY: number }) => this._pdfViewer?.brushView(view);
sidebarAddDocTab = (doc: Doc, where: OpenWhere) => {
- if (DocListCast(this.props.Document[this.props.fieldKey + '-sidebar']).includes(doc) && !this.SidebarShown) {
+ if (DocListCast(this.props.Document[this.props.fieldKey + '_sidebar']).includes(doc) && !this.SidebarShown) {
this.toggleSidebar(false);
return true;
}
@@ -239,7 +239,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
}
const docAnchor = () => {
const anchor = Docs.Create.TextanchorDocument({
- title: StrCast(this.rootDoc.title + '@' + NumCast(this.layoutDoc._scrollTop)?.toFixed(0)),
+ title: StrCast(this.rootDoc.title + '@' + NumCast(this.layoutDoc._layout_scrollTop)?.toFixed(0)),
unrendered: true,
annotationOn: this.rootDoc,
});
@@ -258,11 +258,11 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
@action
loaded = (nw: number, nh: number, np: number) => {
- this.dataDoc[this.props.fieldKey + '-numPages'] = np;
+ this.dataDoc[this.props.fieldKey + '_numPages'] = np;
Doc.SetNativeWidth(this.dataDoc, Math.max(Doc.NativeWidth(this.dataDoc), (nw * 96) / 72));
Doc.SetNativeHeight(this.dataDoc, (nh * 96) / 72);
this.layoutDoc._height = this.layoutDoc[WidthSym]() / (Doc.NativeAspect(this.dataDoc) || 1);
- !this.Document._fitWidth && (this.Document._height = this.Document[WidthSym]() * (nh / nw));
+ !this.Document._layout_fitWidth && (this.Document._height = this.Document[WidthSym]() * (nh / nw));
};
public search = action((searchString: string, bwd?: boolean, clear: boolean = false) => {
@@ -279,14 +279,14 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
public prevAnnotation = () => this._pdfViewer?.prevAnnotation();
public nextAnnotation = () => this._pdfViewer?.nextAnnotation();
public backPage = () => {
- this.Document._curPage = Math.max(1, (NumCast(this.Document._curPage) || 1) - 1);
+ this.Document._layout_curPage = Math.max(1, (NumCast(this.Document._layout_curPage) || 1) - 1);
return true;
};
public forwardPage = () => {
- this.Document._curPage = Math.min(NumCast(this.dataDoc[this.props.fieldKey + '-numPages']), (NumCast(this.Document._curPage) || 1) + 1);
+ this.Document._layout_curPage = Math.min(NumCast(this.dataDoc[this.props.fieldKey + '_numPages']), (NumCast(this.Document._layout_curPage) || 1) + 1);
return true;
};
- public gotoPage = (p: number) => (this.Document._curPage = p);
+ public gotoPage = (p: number) => (this.Document._layout_curPage = p);
@undoBatch
onKeyDown = action((e: KeyboardEvent) => {
@@ -316,9 +316,9 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
searchStringChanged = (e: React.ChangeEvent<HTMLInputElement>) => (this._searchString = e.currentTarget.value);
// adding external documents; to sidebar key
- // if (doc.Geolocation) this.addDocument(doc, this.fieldkey+"-annotation")
+ // if (doc.Geolocation) this.addDocument(doc, this.fieldkey+"_annotation")
sidebarAddDocument = (doc: Doc | Doc[], sidebarKey: string = this.SidebarKey) => {
- if (!this.layoutDoc._showSidebar) this.toggleSidebar();
+ if (!this.layoutDoc._show_sidebar) this.toggleSidebar();
return this.addDocument(doc, sidebarKey);
};
sidebarBtnDown = (e: React.PointerEvent, onButton: boolean) => {
@@ -332,13 +332,13 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
.ScreenToLocalTransform()
.scale(this.props.NativeDimScaling?.() || 1)
.transformDirection(delta[0], delta[1]);
- const nativeWidth = NumCast(this.layoutDoc[this.fieldKey + '-nativeWidth']);
+ const nativeWidth = NumCast(this.layoutDoc[this.fieldKey + '_nativeWidth']);
const curNativeWidth = NumCast(this.layoutDoc.nativeWidth, nativeWidth);
const ratio = (curNativeWidth + ((onButton ? 1 : -1) * localDelta[0]) / (this.props.NativeDimScaling?.() || 1)) / nativeWidth;
if (ratio >= 1) {
this.layoutDoc.nativeWidth = nativeWidth * ratio;
onButton && (this.layoutDoc._width = this.layoutDoc[WidthSym]() + localDelta[0]);
- this.layoutDoc._showSidebar = nativeWidth !== this.layoutDoc._nativeWidth;
+ this.layoutDoc._show_sidebar = nativeWidth !== this.layoutDoc._nativeWidth;
}
return false;
},
@@ -352,7 +352,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
@observable _previewNativeWidth: Opt<number> = undefined;
@observable _previewWidth: Opt<number> = undefined;
toggleSidebar = action((preview: boolean = false) => {
- const nativeWidth = NumCast(this.layoutDoc[this.fieldKey + '-nativeWidth']);
+ const nativeWidth = NumCast(this.layoutDoc[this.fieldKey + '_nativeWidth']);
const sideratio = ((!this.layoutDoc.nativeWidth || this.layoutDoc.nativeWidth === nativeWidth ? PDFBox.openSidebarWidth : 0) + nativeWidth) / nativeWidth;
const pdfratio = ((!this.layoutDoc.nativeWidth || this.layoutDoc.nativeWidth === nativeWidth ? PDFBox.openSidebarWidth + PDFBox.sidebarResizerWidth : 0) + nativeWidth) / nativeWidth;
const curNativeWidth = NumCast(this.layoutDoc.nativeWidth, nativeWidth);
@@ -363,7 +363,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
} else {
this.layoutDoc.nativeWidth = nativeWidth * pdfratio;
this.layoutDoc._width = (this.layoutDoc[WidthSym]() * nativeWidth * pdfratio) / curNativeWidth;
- this.layoutDoc._showSidebar = nativeWidth !== this.layoutDoc._nativeWidth;
+ this.layoutDoc._show_sidebar = nativeWidth !== this.layoutDoc._nativeWidth;
}
});
settingsPanel() {
@@ -378,7 +378,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
</>
);
const searchTitle = `${!this._searching ? 'Open' : 'Close'} Search Bar`;
- const curPage = NumCast(this.Document._curPage) || 1;
+ const curPage = NumCast(this.Document._layout_curPage) || 1;
return !this.props.isContentActive() || this._pdfViewer?.isAnnotating ? null : (
<div
className="pdfBox-ui"
@@ -424,7 +424,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
<input
value={curPage}
style={{ width: `${curPage > 99 ? 4 : 3}ch`, pointerEvents: 'all' }}
- onChange={e => (this.Document._curPage = Number(e.currentTarget.value))}
+ onChange={e => (this.Document._layout_curPage = Number(e.currentTarget.value))}
onKeyDown={e => e.stopPropagation()}
onClick={action(() => (this._pageControls = !this._pageControls))}
/>
@@ -470,7 +470,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
anchorMenuClick = () => this._sidebarRef.current?.anchorMenuClick;
@observable _showSidebar = false;
@computed get SidebarShown() {
- return this._showSidebar || this.layoutDoc._showSidebar ? true : false;
+ return this._showSidebar || this.layoutDoc._show_sidebar ? true : false;
}
@computed get sidebarHandle() {
return (
@@ -480,7 +480,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
title="Toggle Sidebar"
style={{
display: !this.props.isContentActive() ? 'none' : undefined,
- top: StrCast(this.rootDoc._showTitle) === 'title' ? 20 : 5,
+ top: StrCast(this.rootDoc._layout_showTitle) === 'title' ? 20 : 5,
backgroundColor: this.SidebarShown ? Colors.MEDIUM_BLUE : Colors.BLACK,
}}
onPointerDown={e => this.sidebarBtnDown(e, true)}>
@@ -490,10 +490,10 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
}
public get SidebarKey() {
- return this.fieldKey + '-sidebar';
+ return this.fieldKey + '_sidebar';
}
@computed get pdfScale() {
- const pdfNativeWidth = NumCast(this.layoutDoc[this.fieldKey + '-nativeWidth']);
+ const pdfNativeWidth = NumCast(this.layoutDoc[this.fieldKey + '_nativeWidth']);
const nativeWidth = NumCast(this.layoutDoc.nativeWidth, pdfNativeWidth);
const pdfRatio = pdfNativeWidth / nativeWidth;
return (pdfRatio * this.props.PanelWidth()) / pdfNativeWidth;
@@ -572,7 +572,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
onContextMenu={this.specificContextMenu}
style={{
display: this.props.thumbShown?.() ? 'none' : undefined,
- height: this.props.Document._scrollTop && !this.Document._fitWidth && window.screen.width > 600 ? (NumCast(this.Document._height) * this.props.PanelWidth()) / NumCast(this.Document._width) : undefined,
+ height: this.props.Document._layout_scrollTop && !this.Document._layout_fitWidth && window.screen.width > 600 ? (NumCast(this.Document._height) * this.props.PanelWidth()) / NumCast(this.Document._width) : undefined,
}}>
<div className="pdfBox-background" onPointerDown={e => this.sidebarBtnDown(e, false)} />
<div
diff --git a/src/client/views/nodes/RecordingBox/RecordingBox.tsx b/src/client/views/nodes/RecordingBox/RecordingBox.tsx
index f406ffbea..80b12b96e 100644
--- a/src/client/views/nodes/RecordingBox/RecordingBox.tsx
+++ b/src/client/views/nodes/RecordingBox/RecordingBox.tsx
@@ -41,7 +41,7 @@ export class RecordingBox extends ViewBoxBaseComponent() {
setResult = (info: Upload.AccessPathInfo, presentation?: Presentation) => {
this.result = info;
this.dataDoc.type = DocumentType.VID;
- this.dataDoc[this.fieldKey + '-duration'] = this.videoDuration;
+ this.dataDoc[this.fieldKey + '_duration'] = this.videoDuration;
this.dataDoc.layout = VideoBox.LayoutString(this.fieldKey);
this.dataDoc[this.props.fieldKey] = new VideoField(this.result.accessPaths.client);
diff --git a/src/client/views/nodes/ScreenshotBox.tsx b/src/client/views/nodes/ScreenshotBox.tsx
index aa2b22e28..7bf765042 100644
--- a/src/client/views/nodes/ScreenshotBox.tsx
+++ b/src/client/views/nodes/ScreenshotBox.tsx
@@ -129,7 +129,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
}
}
getAnchor = (addAsAnnotation: boolean) => {
- const startTime = Cast(this.layoutDoc._currentTimecode, 'number', null) || (this._videoRec ? (Date.now() - (this.recordingStart || 0)) / 1000 : undefined);
+ const startTime = Cast(this.layoutDoc._layout_currentTimecode, 'number', null) || (this._videoRec ? (Date.now() - (this.recordingStart || 0)) / 1000 : undefined);
return CollectionStackedTimeline.createAnchor(this.rootDoc, this.dataDoc, this.annotationKey, startTime, startTime === undefined ? undefined : startTime + 3, undefined, addAsAnnotation) || this.rootDoc;
};
@@ -236,13 +236,13 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
console.log('screenshotbox: upload');
const file = new File(vid_chunks, `${this.rootDoc[Id]}.mkv`, { type: vid_chunks[0].type, lastModified: Date.now() });
const [{ result }] = await Networking.UploadFilesToServer(file);
- this.dataDoc[this.fieldKey + '-duration'] = (new Date().getTime() - this.recordingStart!) / 1000;
+ this.dataDoc[this.fieldKey + '_duration'] = (new Date().getTime() - this.recordingStart!) / 1000;
if (!(result instanceof Error)) {
// convert this screenshotBox into normal videoBox
this.dataDoc.type = DocumentType.VID;
this.layoutDoc.layout = VideoBox.LayoutString(this.fieldKey);
this.dataDoc.nativeWidth = this.dataDoc.nativeHeight = undefined;
- this.layoutDoc._fitWidth = undefined;
+ this.layoutDoc._layout_fitWidth = undefined;
this.dataDoc[this.props.fieldKey] = new VideoField(result.accessPaths.agnostic.client);
} else alert('video conversion failed');
};
@@ -270,14 +270,14 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
setupDictation = () => {
if (this.dataDoc[this.fieldKey + '-dictation']) return;
const dictationText = DocUtils.GetNewTextDoc('dictation', NumCast(this.rootDoc.x), NumCast(this.rootDoc.y) + NumCast(this.layoutDoc._height) + 10, NumCast(this.layoutDoc._width), 2 * NumCast(this.layoutDoc._height));
- dictationText._autoHeight = false;
+ dictationText._layout_autoHeight = false;
const dictationTextProto = Doc.GetProto(dictationText);
dictationTextProto.recordingSource = this.dataDoc;
dictationTextProto.recordingStart = ComputedField.MakeFunction(`self.recordingSource["${this.props.fieldKey}-recordingStart"]`);
dictationTextProto.mediaState = ComputedField.MakeFunction('self.recordingSource.mediaState');
this.dataDoc[this.fieldKey + '-dictation'] = dictationText;
};
- videoPanelHeight = () => (NumCast(this.dataDoc[this.fieldKey + '-nativeHeight'], this.layoutDoc[HeightSym]()) / NumCast(this.dataDoc[this.fieldKey + '-nativeWidth'], this.layoutDoc[WidthSym]())) * this.props.PanelWidth();
+ videoPanelHeight = () => (NumCast(this.dataDoc[this.fieldKey + '_nativeHeight'], this.layoutDoc[HeightSym]()) / NumCast(this.dataDoc[this.fieldKey + '_nativeWidth'], this.layoutDoc[WidthSym]())) * this.props.PanelWidth();
formattedPanelHeight = () => Math.max(0, this.props.PanelHeight() - this.videoPanelHeight());
render() {
TraceMobx();
@@ -311,7 +311,7 @@ export class ScreenshotBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
</>
</CollectionFreeFormView>
</div>
- <div style={{ position: 'relative', height: this.formattedPanelHeight() }}>
+ <div style={{ background: 'white', position: 'relative', height: this.formattedPanelHeight() }}>
{!(this.dataDoc[this.fieldKey + '-dictation'] instanceof Doc) ? null : (
<FormattedTextBox
{...this.props}
diff --git a/src/client/views/nodes/ScriptingBox.tsx b/src/client/views/nodes/ScriptingBox.tsx
index f09962b22..37fda14fc 100644
--- a/src/client/views/nodes/ScriptingBox.tsx
+++ b/src/client/views/nodes/ScriptingBox.tsx
@@ -167,7 +167,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatable
// only included in buttons, transforms scripting UI to a button
@action
onFinish = () => {
- this.rootDoc.layoutKey = 'layout';
+ this.rootDoc.layout_fieldKey = 'layout';
};
// displays error message
@@ -702,7 +702,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatable
// toolbar (with compile and apply buttons) for scripting UI
renderScriptingTools() {
- const buttonStyle = 'scriptingBox-button' + (StrCast(this.rootDoc.layoutKey).startsWith('layout_on') ? '-finish' : '');
+ const buttonStyle = 'scriptingBox-button' + (StrCast(this.rootDoc.layout_fieldKey).startsWith('layout_on') ? '-finish' : '');
return (
<div className="scriptingBox-toolbar">
<button
@@ -730,7 +730,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatable
Save
</button>
- {!StrCast(this.rootDoc.layoutKey).startsWith('layout_on') ? null : ( // onClick, onChecked, etc need a Finish button to return to their default layout
+ {!StrCast(this.rootDoc.layout_fieldKey).startsWith('layout_on') ? null : ( // onClick, onChecked, etc need a Finish button to return to their default layout
<button
className={buttonStyle}
onPointerDown={e => {
@@ -776,7 +776,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatable
// toolbar (with edit and run buttons and error message) for params UI
renderTools(toolSet: string, func: () => void) {
- const buttonStyle = 'scriptingBox-button' + (StrCast(this.rootDoc.layoutKey).startsWith('layout_on') ? '-finish' : '');
+ const buttonStyle = 'scriptingBox-button' + (StrCast(this.rootDoc.layout_fieldKey).startsWith('layout_on') ? '-finish' : '');
return (
<div className="scriptingBox-toolbar">
<button
@@ -795,7 +795,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatable
}}>
{toolSet}
</button>
- {!StrCast(this.rootDoc.layoutKey).startsWith('layout_on') ? null : (
+ {!StrCast(this.rootDoc.layout_fieldKey).startsWith('layout_on') ? null : (
<button
className={buttonStyle}
onPointerDown={e => {
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 7a7d4fe37..e00cb8618 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -3,7 +3,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction, untracked } from 'mobx';
import { observer } from 'mobx-react';
import { basename } from 'path';
-import { Doc, HeightSym, WidthSym } from '../../../fields/Doc';
+import { Doc, HeightSym, StrListCast, WidthSym } from '../../../fields/Doc';
import { InkTool } from '../../../fields/InkField';
import { List } from '../../../fields/List';
import { ObjectField } from '../../../fields/ObjectField';
@@ -91,9 +91,9 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
return LinkManager.Links(this.dataDoc);
}
@computed get heightPercent() {
- return NumCast(this.layoutDoc._timelineHeightPercent, 100);
+ return NumCast(this.layoutDoc._layout_timelineHeightPercent, 100);
} // current percent of video relative to VideoBox height
- // @computed get rawDuration() { return NumCast(this.dataDoc[this.fieldKey + "-duration"]); }
+ // @computed get rawDuration() { return NumCast(this.dataDoc[this.fieldKey + "_duration"]); }
@observable rawDuration: number = 0;
@computed get youtubeVideoId() {
@@ -325,14 +325,14 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
y: NumCast(this.layoutDoc.y, 1),
_width: 150,
_height: 50,
- title: (this.layoutDoc._currentTimecode || 0).toString(),
+ title: (this.layoutDoc._layout_currentTimecode || 0).toString(),
onClick: FollowLinkScript(),
});
this.props.addDocument?.(b);
- DocUtils.MakeLink(b, this.rootDoc, { linkRelationship: 'video snapshot' });
+ DocUtils.MakeLink(b, this.rootDoc, { link_relationship: 'video snapshot' });
Networking.PostToServer('/youtubeScreenshot', {
id: this.youtubeVideoId,
- timecode: this.layoutDoc._currentTimecode,
+ timecode: this.layoutDoc._layout_currentTimecode,
}).then(response => {
const resolved = response?.accessPaths?.agnostic?.client;
if (resolved) {
@@ -345,7 +345,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
const dataUrl = canvas.toDataURL('image/png'); // can also use 'image/png'
// if you want to preview the captured image,
const retitled = StrCast(this.rootDoc.title).replace(/[ -\.:]/g, '');
- const encodedFilename = encodeURIComponent('snapshot' + retitled + '_' + (this.layoutDoc._currentTimecode || 0).toString().replace(/\./, '_'));
+ const encodedFilename = encodeURIComponent('snapshot' + retitled + '_' + (this.layoutDoc._layout_currentTimecode || 0).toString().replace(/\./, '_'));
const filename = basename(encodedFilename);
Utils.convertDataUri(dataUrl, filename).then((returnedFilename: string) => returnedFilename && (cb ?? this.createSnapshotLink)(returnedFilename, downX, downY));
}
@@ -354,8 +354,8 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
updateIcon = () => {
const makeIcon = (returnedfilename: string) => {
this.dataDoc.icon = new ImageField(returnedfilename);
- this.dataDoc['icon-nativeWidth'] = this.layoutDoc[WidthSym]();
- this.dataDoc['icon-nativeHeight'] = this.layoutDoc[HeightSym]();
+ this.dataDoc.icon_nativeWidth = this.layoutDoc[WidthSym]();
+ this.dataDoc.icon_nativeHeight = this.layoutDoc[HeightSym]();
};
this.Snapshot(undefined, undefined, makeIcon);
};
@@ -373,18 +373,18 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
onClick: FollowLinkScript(),
_width: 150,
_height: (height / width) * 150,
- title: '--snapshot' + NumCast(this.layoutDoc._currentTimecode) + ' image-',
+ title: '--snapshot' + NumCast(this.layoutDoc._layout_currentTimecode) + ' image-',
});
Doc.SetNativeWidth(Doc.GetProto(imageSnapshot), Doc.NativeWidth(this.layoutDoc));
Doc.SetNativeHeight(Doc.GetProto(imageSnapshot), Doc.NativeHeight(this.layoutDoc));
this.props.addDocument?.(imageSnapshot);
- const link = DocUtils.MakeLink(imageSnapshot, this.getAnchor(true), { linkRelationship: 'video snapshot' });
- link && (Doc.GetProto(link.anchor2 as Doc).timecodeToHide = NumCast((link.anchor2 as Doc).timecodeToShow) + 3);
+ const link = DocUtils.MakeLink(imageSnapshot, this.getAnchor(true), { link_relationship: 'video snapshot' });
+ link && (Doc.GetProto(link.link_anchor_2 as Doc).timecodeToHide = NumCast((link.link_anchor_2 as Doc).timecodeToShow) + 3);
setTimeout(() => downX !== undefined && downY !== undefined && DocumentManager.Instance.getFirstDocumentView(imageSnapshot)?.startDragging(downX, downY, 'move', true));
};
getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => {
- const timecode = Cast(this.layoutDoc._currentTimecode, 'number', null);
+ const timecode = Cast(this.layoutDoc._layout_currentTimecode, 'number', null);
const marquee = AnchorMenu.Instance.GetAnchor?.(undefined, addAsAnnotation);
if (!addAsAnnotation && marquee) marquee.backgroundColor = 'transparent';
const anchor = CollectionStackedTimeline.createAnchor(this.rootDoc, this.dataDoc, this.annotationKey, timecode ? timecode : undefined, undefined, marquee, addAsAnnotation) || this.rootDoc;
@@ -402,16 +402,16 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
}
if (Number.isFinite(this.player!.duration)) {
this.rawDuration = this.player!.duration;
- this.dataDoc[this.fieldKey + '-duration'] = this.rawDuration;
- } else this.rawDuration = NumCast(this.dataDoc[this.fieldKey + '-duration']);
+ this.dataDoc[this.fieldKey + '_duration'] = this.rawDuration;
+ } else this.rawDuration = NumCast(this.dataDoc[this.fieldKey + '_duration']);
});
// updates video time
@action
updateTimecode = () => {
- this.player && (this.layoutDoc._currentTimecode = this.player.currentTime);
+ this.player && (this.layoutDoc._layout_currentTimecode = this.player.currentTime);
try {
- this._youtubePlayer && (this.layoutDoc._currentTimecode = this._youtubePlayer.getCurrentTime?.());
+ this._youtubePlayer && (this.layoutDoc._layout_currentTimecode = this._youtubePlayer.getCurrentTime?.());
} catch (e) {
console.log('Video Timecode Exception:', e);
}
@@ -423,8 +423,8 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
// extracts video thumbnails and saves them as field of doc
getVideoThumbnails = () => {
- if (this.dataDoc.thumbnails !== undefined) return;
- this.dataDoc.thumbnails = new List<string>();
+ if (this.dataDoc[this.fieldKey + '_thumbnails'] !== undefined) return;
+ this.dataDoc[this.fieldKey + '_thumbnails'] = new List<string>();
const thumbnailPromises: Promise<any>[] = [];
const video = document.createElement('video');
@@ -442,7 +442,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
if (newTime < video.duration) {
video.currentTime = newTime;
} else {
- Promise.all(thumbnailPromises).then(thumbnails => (this.dataDoc.thumbnails = new List<string>(thumbnails)));
+ Promise.all(thumbnailPromises).then(thumbnails => (this.dataDoc[this.fieldKey + '_thumbnails'] = new List<string>(thumbnails)));
}
};
@@ -460,12 +460,12 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
// vref.onfullscreenchange = action((e) => this._fullScreen = vref.webkitDisplayingFullscreen);
this._disposers.reactionDisposer?.();
this._disposers.reactionDisposer = reaction(
- () => NumCast(this.layoutDoc._currentTimecode),
+ () => NumCast(this.layoutDoc._layout_currentTimecode),
time => !this._playing && (vref.currentTime = time),
{ fireImmediately: true }
);
- (!this.dataDoc.thumbnails || this.dataDoc.thumbnails.length != VideoBox.numThumbnails) && this.getVideoThumbnails();
+ (!this.dataDoc[this.fieldKey + '_thumbnails'] || this.dataDoc[this.fieldKey + '_thumbnails'].length != VideoBox.numThumbnails) && this.getVideoThumbnails();
}
};
@@ -531,7 +531,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
this.dataDoc.layout = RecordingBox.LayoutString(this.fieldKey);
// delete assoicated video data
this.dataDoc[this.props.fieldKey] = '';
- this.dataDoc[this.fieldKey + '-duration'] = '';
+ this.dataDoc[this.fieldKey + '_duration'] = '';
// delete assoicated presentation data
this.dataDoc[this.fieldKey + '-presentation'] = '';
},
@@ -573,7 +573,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
key="video"
autoPlay={this._screenCapture}
ref={this.setVideoRef}
- style={this._fullScreen ? this.fullScreenSize() : this.isCropped ? { width: 'max-content', height: 'max-content', transform: `scale(${1 / NumCast(this.rootDoc._viewScale)})`, transformOrigin: 'top left' } : {}}
+ style={this._fullScreen ? this.fullScreenSize() : this.isCropped ? { width: 'max-content', height: 'max-content', transform: `scale(${1 / NumCast(this.rootDoc._freeform_scale)})`, transformOrigin: 'top left' } : {}}
onCanPlay={this.videoLoad}
controls={VideoBox._nativeControls}
onPlay={() => this.Play()}
@@ -620,8 +620,8 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
this._disposers.reactionDisposer?.();
this._disposers.youtubeReactionDisposer?.();
this._disposers.reactionDisposer = reaction(
- () => this.layoutDoc._currentTimecode,
- () => !this._playing && this.Seek(NumCast(this.layoutDoc._currentTimecode))
+ () => this.layoutDoc._layout_currentTimecode,
+ () => !this._playing && this.Seek(NumCast(this.layoutDoc._layout_currentTimecode))
);
this._disposers.youtubeReactionDisposer = reaction(
() => Doc.ActiveTool === InkTool.None && this.props.isSelected(true) && !SnappingManager.GetIsDragging() && !DocumentDecorations.Instance.Interacting,
@@ -677,15 +677,15 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
this._clicking = false;
if (this.props.isContentActive()) {
// const local = this.props.ScreenToLocalTransform().scale(this.props.scaling?.() || 1).transformPoint(e.clientX, e.clientY);
- // this.layoutDoc._timelineHeightPercent = Math.max(0, Math.min(100, local[1] / this.props.PanelHeight() * 100));
+ // this.layoutDoc._layout_timelineHeightPercent = Math.max(0, Math.min(100, local[1] / this.props.PanelHeight() * 100));
- this.layoutDoc._timelineHeightPercent = 80;
+ this.layoutDoc._layout_timelineHeightPercent = 80;
}
return false;
}),
emptyFunction,
() => {
- this.layoutDoc._timelineHeightPercent = this.heightPercent !== 100 ? 100 : VideoBox.heightPercent;
+ this.layoutDoc._layout_timelineHeightPercent = this.heightPercent !== 100 ? 100 : VideoBox.heightPercent;
setTimeout(
action(() => (this._clicking = false)),
500
@@ -721,7 +721,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
this._youtubeIframeId = VideoBox._youtubeIframeCounter++;
this._youtubeContentCreated = this._forceCreateYouTubeIFrame ? true : true;
const classname = 'videoBox-content-YouTube' + (this._fullScreen ? '-fullScreen' : '');
- const start = untracked(() => Math.round(NumCast(this.layoutDoc._currentTimecode)));
+ const start = untracked(() => Math.round(NumCast(this.layoutDoc._layout_currentTimecode)));
return (
<iframe
key={this._youtubeIframeId}
@@ -740,7 +740,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
@action.bound
addDocWithTimecode(doc: Doc | Doc[]): boolean {
const docs = doc instanceof Doc ? [doc] : doc;
- const curTime = NumCast(this.layoutDoc._currentTimecode);
+ const curTime = NumCast(this.layoutDoc._layout_currentTimecode);
docs.forEach(doc => (doc._timecodeToHide = (doc._timecodeToShow = curTime) + 1));
return this.addDocument(doc);
}
@@ -859,7 +859,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
// starts marquee selection
marqueeDown = (e: React.PointerEvent) => {
- if (!e.altKey && e.button === 0 && NumCast(this.layoutDoc._viewScale, 1) === 1 && this.props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen].includes(Doc.ActiveTool)) {
+ if (!e.altKey && e.button === 0 && NumCast(this.layoutDoc._freeform_scale, 1) === 1 && this.props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen].includes(Doc.ActiveTool)) {
setupMoveUpEvents(
this,
e,
@@ -890,7 +890,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
.scale(this.scaling())
.translate(0, (-this.heightPercent / 100) * this.props.PanelHeight());
- setPlayheadTime = (time: number) => (this.player!.currentTime = this.layoutDoc._currentTimecode = time);
+ setPlayheadTime = (time: number) => (this.player!.currentTime = this.layoutDoc._layout_currentTimecode = time);
timelineHeight = () => (this.props.PanelHeight() * (100 - this.heightPercent)) / 100;
@@ -899,7 +899,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
scaling = () => this.props.NativeDimScaling?.() || 1;
panelWidth = () => (this.props.PanelWidth() * this.heightPercent) / 100;
- panelHeight = () => (this.layoutDoc._fitWidth ? this.panelWidth() / (Doc.NativeAspect(this.rootDoc) || 1) : (this.props.PanelHeight() * this.heightPercent) / 100);
+ panelHeight = () => (this.layoutDoc._layout_fitWidth ? this.panelWidth() / (Doc.NativeAspect(this.rootDoc) || 1) : (this.props.PanelHeight() * this.heightPercent) / 100);
screenToLocalTransform = () => {
const offset = (this.props.PanelWidth() - this.panelWidth()) / 2 / this.scaling();
@@ -956,9 +956,11 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
<CollectionStackedTimeline
ref={action((r: any) => (this._stackedTimeline = r))}
{...this.props}
+ dataFieldKey={this.fieldKey}
fieldKey={this.annotationKey}
dictationKey={this.fieldKey + '-dictation'}
mediaPath={this.audiopath}
+ thumbnails={() => StrListCast(this.dataDoc[this.fieldKey + '_thumbnails'])}
renderDepth={this.props.renderDepth + 1}
startTag={'_timecodeToShow' /* videoStart */}
endTag={'_timecodeToHide' /* videoEnd */}
@@ -1003,7 +1005,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
const anchy = NumCast(cropping.y);
const anchw = NumCast(cropping._width);
const anchh = NumCast(cropping._height);
- const viewScale = NumCast(this.rootDoc[this.fieldKey + '-nativeWidth']) / anchw;
+ const viewScale = NumCast(this.rootDoc[this.fieldKey + '_nativeWidth']) / anchw;
cropping.title = 'crop: ' + this.rootDoc.title;
cropping.x = NumCast(this.rootDoc.x) + NumCast(this.rootDoc._width);
cropping.y = NumCast(this.rootDoc.y);
@@ -1014,25 +1016,25 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
cropping.onClick = undefined;
const croppingProto = Doc.GetProto(cropping);
croppingProto.annotationOn = undefined;
- croppingProto.isPrototype = true;
+ croppingProto.isDataDoc = true;
croppingProto.proto = Cast(this.rootDoc.proto, Doc, null)?.proto; // set proto of cropping's data doc to be IMAGE_PROTO
croppingProto.type = DocumentType.VID;
croppingProto.layout = VideoBox.LayoutString('data');
croppingProto.data = ObjectField.MakeCopy(this.rootDoc[this.fieldKey] as ObjectField);
- croppingProto['data-nativeWidth'] = anchw;
- croppingProto['data-nativeHeight'] = anchh;
+ croppingProto['data_nativeWidth'] = anchw;
+ croppingProto['data_nativeHeight'] = anchh;
croppingProto.videoCrop = true;
- croppingProto.currentTimecode = this.layoutDoc._currentTimecode;
- croppingProto.viewScale = viewScale;
- croppingProto.viewScaleMin = viewScale;
- croppingProto.panX = anchx / viewScale;
- croppingProto.panY = anchy / viewScale;
- croppingProto.panXMin = anchx / viewScale;
- croppingProto.panXMax = anchw / viewScale;
- croppingProto.panYMin = anchy / viewScale;
- croppingProto.panYMax = anchh / viewScale;
+ croppingProto.layout_currentTimecode = this.layoutDoc._layout_currentTimecode;
+ croppingProto.freeform_scale = viewScale;
+ croppingProto.freeform_scaleMin = viewScale;
+ croppingProto.freeform_ = anchx / viewScale;
+ croppingProto.freeform_panY = anchy / viewScale;
+ croppingProto.freeform_panXMin = anchx / viewScale;
+ croppingProto.freeform_panXMax = anchw / viewScale;
+ croppingProto.freeform_panYMin = anchy / viewScale;
+ croppingProto.freeform_panYMax = anchh / viewScale;
if (addCrop) {
- DocUtils.MakeLink(region, cropping, { linkRelationship: 'cropped image' });
+ DocUtils.MakeLink(region, cropping, { link_relationship: 'cropped image' });
}
this.props.bringToFront(cropping);
return cropping;
@@ -1050,7 +1052,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
style={{
pointerEvents: this.layoutDoc._lockedPosition ? 'none' : undefined,
borderRadius,
- overflow: this.props.docViewPath?.().slice(-1)[0].fitWidth ? 'auto' : undefined,
+ overflow: this.props.docViewPath?.().slice(-1)[0].layout_fitWidth ? 'auto' : undefined,
}}
onWheel={e => {
e.stopPropagation();
@@ -1116,7 +1118,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
@computed get UIButtons() {
const bounds = this.props.docViewPath().lastElement().getBounds();
const width = (bounds?.right || 0) - (bounds?.left || 0);
- const curTime = NumCast(this.layoutDoc._currentTimecode) - (this.timeline?.clipStart || 0);
+ const curTime = NumCast(this.layoutDoc._layout_currentTimecode) - (this.timeline?.clipStart || 0);
return (
<>
<div className="videobox-button" title={this._playing ? 'play' : 'pause'} onPointerDown={this.onPlayDown}>
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index e05b48c0b..3da5d8f17 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -2,16 +2,16 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, IReactionDisposer, observable, ObservableMap, reaction, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as WebRequest from 'web-request';
-import { Doc, DocListCast, HeightSym, Opt, WidthSym } from '../../../fields/Doc';
+import { Doc, DocListCast, Field, HeightSym, Opt, WidthSym } from '../../../fields/Doc';
import { Id } from '../../../fields/FieldSymbols';
import { HtmlField } from '../../../fields/HtmlField';
import { InkTool } from '../../../fields/InkField';
import { List } from '../../../fields/List';
import { listSpec } from '../../../fields/Schema';
-import { Cast, ImageCast, NumCast, StrCast } from '../../../fields/Types';
+import { Cast, ImageCast, NumCast, StrCast, WebCast } from '../../../fields/Types';
import { ImageField, WebField } from '../../../fields/URLField';
import { TraceMobx } from '../../../fields/util';
-import { emptyFunction, getWordAtPoint, returnFalse, returnOne, returnZero, setupMoveUpEvents, smoothScroll, StopEvent, Utils } from '../../../Utils';
+import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, getWordAtPoint, removeStyleSheetRule, returnFalse, returnOne, returnTrue, returnZero, setupMoveUpEvents, smoothScroll, StopEvent, Utils } from '../../../Utils';
import { Docs, DocUtils } from '../../documents/Documents';
import { DocumentManager } from '../../util/DocumentManager';
import { DragManager } from '../../util/DragManager';
@@ -31,12 +31,13 @@ import { Annotation } from '../pdf/Annotation';
import { GPTPopup } from '../pdf/GPTPopup/GPTPopup';
import { SidebarAnnos } from '../SidebarAnnos';
import { StyleProp } from '../StyleProvider';
-import { DocFocusOptions, DocumentView, DocumentViewProps, OpenWhere } from './DocumentView';
+import { DocComponentView, DocFocusOptions, DocumentView, DocumentViewProps, OpenWhere } from './DocumentView';
import { FieldView, FieldViewProps } from './FieldView';
import { LinkDocPreview } from './LinkDocPreview';
import { PinProps, PresBox } from './trails';
import './WebBox.scss';
import React = require('react');
+import { RefField } from '../../../fields/RefField';
const { CreateImage } = require('./WebBoxRenderer');
const _global = (window /* browser */ || global) /* node */ as any;
const htmlToText = require('html-to-text');
@@ -47,6 +48,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
}
public static openSidebarWidth = 250;
public static sidebarResizerWidth = 5;
+ static webStyleSheet = addStyleSheet();
private _setPreviewCursor: undefined | ((x: number, y: number, drag: boolean, hide: boolean) => void);
private _setBrushViewer: undefined | ((view: { width: number; height: number; panX: number; panY: number }) => void);
private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
@@ -54,19 +56,19 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
private _disposers: { [name: string]: IReactionDisposer } = {};
private _annotationLayer: React.RefObject<HTMLDivElement> = React.createRef();
private _keyInput = React.createRef<HTMLInputElement>();
- private _initialScroll: Opt<number> = NumCast(this.layoutDoc.thumbScrollTop, NumCast(this.layoutDoc.scrollTop));
+ private _initialScroll: Opt<number> = NumCast(this.layoutDoc.thumbScrollTop, NumCast(this.layoutDoc.layout_scrollTop));
private _sidebarRef = React.createRef<SidebarAnnos>();
private _searchRef = React.createRef<HTMLInputElement>();
private _searchString = '';
+ private _scrollTimer: any;
private get _getAnchor() {
return AnchorMenu.Instance?.GetAnchor;
}
- @observable private _webUrl = ''; // url of the src parameter of the embedded iframe but not necessarily the rendered page - eg, when following a link, the rendered page changes but we don't wan the src parameter to also change as that would cause an unnecessary re-render.
+ @observable private _webUrl = ''; // url of the src parameter of the embedded iframe but not necessarily the rendered page - eg, when following a link, the rendered page changes but we don't want the src parameter to also change as that would cause an unnecessary re-render.
@observable private _hackHide = false; // apparently changing the value of the 'sandbox' prop doesn't necessarily apply it to the active iframe. so thisforces the ifrmae to be rebuilt when allowScripts is toggled
@observable private _searching: boolean = false;
@observable private _showSidebar = false;
- @observable private _scrollTimer: any;
@observable private _webPageHasBeenRendered = false;
@observable private _overlayAnnoInfo: Opt<Doc>;
@observable private _marqueeing: number[] | undefined;
@@ -99,7 +101,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
ImageCast(
this.layoutDoc['thumb-frozen'],
ImageCast(
- this.layoutDoc.thumbScrollTop === this.layoutDoc._scrollTop && this.layoutDoc.thumbNativeWidth === NumCast(this.layoutDoc.nativeWidth) && this.layoutDoc.thumbNativeHeight === NumCast(this.layoutDoc.nativeHeight)
+ this.layoutDoc.thumbScrollTop === this.layoutDoc._layout_scrollTop && this.layoutDoc.thumbNativeWidth === NumCast(this.layoutDoc.nativeWidth) && this.layoutDoc.thumbNativeHeight === NumCast(this.layoutDoc.nativeHeight)
? this.layoutDoc.thumb
: undefined
)
@@ -141,87 +143,65 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
};
updateThumb = async () => {
- const imageBitmap = ImageCast(this.layoutDoc['thumb-frozen'])?.url.href;
- const scrollTop = NumCast(this.layoutDoc._scrollTop);
+ if (!this._iframe) return;
+ const scrollTop = NumCast(this.layoutDoc._layout_scrollTop);
const nativeWidth = NumCast(this.layoutDoc.nativeWidth);
const nativeHeight = (nativeWidth * this.props.PanelHeight()) / this.props.PanelWidth();
- if (
- !this.props.isSelected(true) &&
- !Doc.IsBrushedDegree(this.rootDoc) &&
- !this.isAnyChildContentActive() &&
- !this.rootDoc.thumbLockout &&
- !this.props.dontRegisterView &&
- this._iframe &&
- !imageBitmap &&
- (scrollTop !== this.layoutDoc.thumbScrollTop || nativeWidth !== this.layoutDoc.thumbNativeWidth || nativeHeight !== this.layoutDoc.thumbNativeHeight)
- ) {
- var htmlString = this._iframe.contentDocument && new XMLSerializer().serializeToString(this._iframe.contentDocument);
- if (!htmlString) {
- htmlString = await (await fetch(Utils.CorsProxy(this.webField!.href))).text();
- }
- this.layoutDoc.thumb = undefined;
- this.rootDoc.thumbLockout = true; // lock to prevent multiple thumb updates.
- CreateImage(this._webUrl.endsWith('/') ? this._webUrl.substring(0, this._webUrl.length - 1) : this._webUrl, this._iframe.contentDocument?.styleSheets ?? [], htmlString, nativeWidth, nativeHeight, scrollTop)
- .then((data_url: any) => {
- if (data_url.includes('<!DOCTYPE')) {
- console.log('BAD DATA IN THUMB CREATION');
- return;
- }
- Utils.convertDataUri(data_url, this.layoutDoc[Id] + '-icon' + new Date().getTime(), true, this.layoutDoc[Id] + '-icon').then(returnedfilename =>
- setTimeout(
- action(() => {
- this.rootDoc.thumbLockout = false;
- this.layoutDoc.thumb = new ImageField(returnedfilename);
- this.layoutDoc.thumbScrollTop = scrollTop;
- this.layoutDoc.thumbNativeWidth = nativeWidth;
- this.layoutDoc.thumbNativeHeight = nativeHeight;
- }),
- 500
- )
- );
- })
- .catch(function (error: any) {
- console.error('oops, something went wrong!', error);
- });
+ var htmlString = this._iframe.contentDocument && new XMLSerializer().serializeToString(this._iframe.contentDocument);
+ if (!htmlString) {
+ htmlString = await (await fetch(Utils.CorsProxy(this.webField!.href))).text();
}
+ this.layoutDoc.thumb = undefined;
+ this.rootDoc.thumbLockout = true; // lock to prevent multiple thumb updates.
+ CreateImage(this._webUrl.endsWith('/') ? this._webUrl.substring(0, this._webUrl.length - 1) : this._webUrl, this._iframe.contentDocument?.styleSheets ?? [], htmlString, nativeWidth, nativeHeight, scrollTop)
+ .then((data_url: any) => {
+ if (data_url.includes('<!DOCTYPE')) {
+ console.log('BAD DATA IN THUMB CREATION');
+ return;
+ }
+ Utils.convertDataUri(data_url, this.layoutDoc[Id] + '-icon' + new Date().getTime(), true, this.layoutDoc[Id] + '-icon').then(returnedfilename =>
+ setTimeout(
+ action(() => {
+ this.rootDoc.thumbLockout = false;
+ this.layoutDoc.thumb = new ImageField(returnedfilename);
+ this.layoutDoc.thumbScrollTop = scrollTop;
+ this.layoutDoc.thumbNativeWidth = nativeWidth;
+ this.layoutDoc.thumbNativeHeight = nativeHeight;
+ }),
+ 500
+ )
+ );
+ })
+ .catch(function (error: any) {
+ console.error('oops, something went wrong!', error);
+ });
};
- _thumbTimer: any;
+
async componentDidMount() {
this.props.setContentView?.(this); // this tells the DocumentView that this WebBox is the "content" of the document. this allows the DocumentView to call WebBox relevant methods to configure the UI (eg, show back/forward buttons)
runInAction(() => {
- this._annotationKeySuffix = () => this._urlHash + '-annotations';
+ this._annotationKeySuffix = () => this._urlHash + '_annotations';
const reqdFuncs: { [key: string]: string } = {};
- // bcz: need to make sure that doc.data-annotations points to the currently active web page's annotations (this could/should be when the doc is created)
- reqdFuncs[this.fieldKey + '-annotations'] = `copyField(this["${this.fieldKey}-"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"-annotations"])`;
- reqdFuncs[this.fieldKey + '-annotations-setter'] = `this["${this.fieldKey}-"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"-annotations"] = value`;
- reqdFuncs[this.fieldKey + '-sidebar'] = `copyField(this["${this.fieldKey}-"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"-sidebar"])`;
- DocUtils.AssignScripts(this.rootDoc, {}, reqdFuncs);
+ // bcz: need to make sure that doc.data_annotations points to the currently active web page's annotations (this could/should be when the doc is created)
+ reqdFuncs[this.fieldKey + '_annotations'] = `copyField(this["${this.fieldKey}_"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"_annotations"])`;
+ reqdFuncs[this.fieldKey + '_annotations-setter'] = `this["${this.fieldKey}_"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"_annotations"] = value`;
+ reqdFuncs[this.fieldKey + '_sidebar'] = `copyField(this["${this.fieldKey}_"+urlHash(this["${this.fieldKey}"]?.url?.toString())+"_sidebar"])`;
+ DocUtils.AssignScripts(this.dataDoc, {}, reqdFuncs);
});
- reaction(
- () => this.props.isSelected(true) || this.isAnyChildContentActive() || Doc.isBrushedHighlightedDegree(this.props.Document),
- async selected => {
- if (selected) {
- this._thumbTimer && clearTimeout(this._thumbTimer);
- this._webPageHasBeenRendered = true;
- } else if (
- (!this.props.isContentActive(true) || SnappingManager.GetIsDragging()) && // update thumnail when unselected AND (no child annotation is active OR we've started dragging the document in which case no additional deselect will occur so this is the only chance to update the thumbnail)
- LightboxView.LightboxDoc !== this.rootDoc
- ) {
- // don't create a thumbnail if entering Lightbox from maximize either, since thumb will be empty.
- this._thumbTimer && clearTimeout(this._thumbTimer);
- this._thumbTimer = setTimeout(this.updateThumb, 2000);
- }
- },
- { fireImmediately: this.props.isSelected(true) || this.isAnyChildContentActive() || (Doc.isBrushedHighlightedDegreeUnmemoized(this.props.Document) ? true : false) }
+ this._disposers.urlchange = reaction(
+ () => WebCast(this.rootDoc.data),
+ url => {
+ this.submitURL(url.url.href, false, false);
+ }
);
- this._disposers.autoHeight = reaction(
- () => this.layoutDoc._autoHeight,
- autoHeight => {
- if (autoHeight) {
- this.layoutDoc._nativeHeight = NumCast(this.props.Document[this.props.fieldKey + '-nativeHeight']);
- this.props.setHeight?.(NumCast(this.props.Document[this.props.fieldKey + '-nativeHeight']) * (this.props.NativeDimScaling?.() || 1));
+ this._disposers.layout_autoHeight = reaction(
+ () => this.layoutDoc._layout_autoHeight,
+ layout_autoHeight => {
+ if (layout_autoHeight) {
+ this.layoutDoc._nativeHeight = NumCast(this.props.Document[this.props.fieldKey + '_nativeHeight']);
+ this.props.setHeight?.(NumCast(this.props.Document[this.props.fieldKey + '_nativeHeight']) * (this.props.NativeDimScaling?.() || 1));
}
}
);
@@ -245,7 +225,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
}
this._disposers.scrollReaction = reaction(
- () => NumCast(this.layoutDoc._scrollTop),
+ () => NumCast(this.layoutDoc._layout_scrollTop),
scrollTop => {
const viewTrans = StrCast(this.Document._viewTransition);
const durationMiliStr = viewTrans.match(/([0-9]*)ms/);
@@ -296,14 +276,12 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
return this._savedAnnotations;
};
- menuControls = () => this.urlEditor; // controls to be added to the top bar when a document of this type is selected
-
setBrushViewer = (func?: (view: { width: number; height: number; panX: number; panY: number }) => void) => (this._setBrushViewer = func);
brushView = (view: { width: number; height: number; panX: number; panY: number }) => this._setBrushViewer?.(view);
focus = (anchor: Doc, options: DocFocusOptions) => {
if (anchor !== this.rootDoc && this._outerRef.current) {
const windowHeight = this.props.PanelHeight() / (this.props.NativeDimScaling?.() || 1);
- const scrollTo = Utils.scrollIntoView(NumCast(anchor.y), anchor[HeightSym](), NumCast(this.layoutDoc._scrollTop), windowHeight, windowHeight * 0.1, Math.max(NumCast(anchor.y) + anchor[HeightSym](), this._scrollHeight));
+ const scrollTo = Utils.scrollIntoView(NumCast(anchor.y), anchor[HeightSym](), NumCast(this.layoutDoc._layout_scrollTop), windowHeight, windowHeight * 0.1, Math.max(NumCast(anchor.y) + anchor[HeightSym](), this._scrollHeight));
if (scrollTo !== undefined) {
if (this._initialScroll === undefined) {
const focusTime = options.zoomTime ?? 500;
@@ -316,15 +294,16 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
}
};
- getView = async (doc: Doc) => {
- if (this.rootDoc.layoutKey === 'layout_icon') this.props.DocumentView?.().iconify();
- if (this._url && StrCast(doc.webUrl) !== this._url) this.submitURL(StrCast(doc.webUrl));
+ @action
+ getView = (doc: Doc) => {
+ if (this.rootDoc.layout_fieldKey === 'layout_icon') this.props.DocumentView?.().iconify();
+ if (this._url && WebCast(doc.presData).url.href !== this._url) this.setData(WebCast(doc.presData).url.href);
if (this._sidebarRef?.current?.makeDocUnfiltered(doc) && !this.SidebarShown) this.toggleSidebar(false);
return new Promise<Opt<DocumentView>>(res => DocumentManager.Instance.AddViewRenderedCb(doc, dv => res(dv)));
};
sidebarAddDocTab = (doc: Doc, where: OpenWhere) => {
- if (DocListCast(this.props.Document[this.props.fieldKey + '-sidebar']).includes(doc) && !this.SidebarShown) {
+ if (DocListCast(this.props.Document[this.props.fieldKey + '_sidebar']).includes(doc) && !this.SidebarShown) {
this.toggleSidebar(false);
return true;
}
@@ -341,13 +320,13 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
} catch (e) {}
const anchor =
this._getAnchor(this._savedAnnotations, false) ??
- Docs.Create.WebanchorDocument(this._url, {
- title: StrCast(this.rootDoc.title + ' ' + this.layoutDoc._scrollTop),
- y: NumCast(this.layoutDoc._scrollTop),
+ Docs.Create.WebanchorDocument({
+ title: StrCast(this.rootDoc.title + ' ' + this.layoutDoc._layout_scrollTop),
+ y: NumCast(this.layoutDoc._layout_scrollTop),
unrendered: true,
annotationOn: this.rootDoc,
});
- PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), scrollable: true, pannable: true } }, this.rootDoc);
+ PresBox.pinDocView(anchor, { pinDocLayout: pinProps?.pinDocLayout, pinData: { ...(pinProps?.pinData ?? {}), scrollable: pinProps?.pinData ? true : false, pannable: true } }, this.rootDoc);
anchor.text = ele?.textContent ?? '';
anchor.textHtml = ele?.innerHTML;
//addAsAnnotation &&
@@ -370,9 +349,9 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
this._selectionText = sel.toString();
AnchorMenu.Instance.setSelectedText(sel.toString());
this._textAnnotationCreator = () => this.createTextAnnotation(sel, !sel.isCollapsed ? sel.getRangeAt(0) : undefined);
- AnchorMenu.Instance.jumpTo(e.clientX * scale + mainContBounds.translateX, e.clientY * scale + mainContBounds.translateY - NumCast(this.layoutDoc._scrollTop) * scale);
+ AnchorMenu.Instance.jumpTo(e.clientX * scale + mainContBounds.translateX, e.clientY * scale + mainContBounds.translateY - NumCast(this.layoutDoc._layout_scrollTop) * scale);
// Changing which document to add the annotation to (the currently selected WebBox)
- GPTPopup.Instance.setSidebarId(`${this.props.fieldKey}-${this._urlHash}-sidebar`);
+ GPTPopup.Instance.setSidebarId(`${this.props.fieldKey}_${this._urlHash}_sidebar`);
GPTPopup.Instance.addDoc = this.sidebarAddDocument;
}
}
@@ -385,7 +364,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
const word = getWordAtPoint(e.target, e.clientX, e.clientY);
this._setPreviewCursor?.(e.clientX, e.clientY, false, true);
MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
- e.button !== 2 && (this._marqueeing = [e.clientX * scale + mainContBounds.translateX, e.clientY * scale + mainContBounds.translateY - NumCast(this.layoutDoc._scrollTop) * scale]);
+ e.button !== 2 && (this._marqueeing = [e.clientX * scale + mainContBounds.translateX, e.clientY * scale + mainContBounds.translateY - NumCast(this.layoutDoc._layout_scrollTop) * scale]);
if (word || ((e.target as any) || '').className.includes('rangeslider') || (e.target as any)?.onclick || (e.target as any)?.parentNode?.onclick) {
setTimeout(
action(() => (this._marqueeing = undefined)),
@@ -413,7 +392,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
iframeClick = () => this._iframeClick;
iframeScaling = () => 1 / this.props.ScreenToLocalTransform().Scale;
- addStyleSheet(document: any, styleType: string = 'text/css') {
+ addWebStyleSheet(document: any, styleType: string = 'text/css') {
if (document) {
const style = document.createElement('style');
style.type = styleType;
@@ -421,7 +400,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
return (sheets as any).sheet;
}
}
- addStyleSheetRule(sheet: any, selector: any, css: any, selectorPrefix = '.') {
+ addWebStyleSheetRule(sheet: any, selector: any, css: any, selectorPrefix = '.') {
const propText =
typeof css === 'string'
? css
@@ -438,8 +417,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
if (this._initialScroll !== undefined) {
this.setScrollPos(this._initialScroll);
}
-
- this.addStyleSheetRule(this.addStyleSheet(this._iframe?.contentDocument), '::selection', { color: 'white', background: 'orange' }, '');
+ this._scrollHeight = this._iframe?.contentDocument?.body?.scrollHeight ?? 0;
+ this.addWebStyleSheetRule(this.addWebStyleSheet(this._iframe?.contentDocument), '::selection', { color: 'white', background: 'orange' }, '');
let href: Opt<string>;
try {
@@ -463,12 +442,19 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
.replace('search&', 'search?')
.replace('?gbv=1', '');
}
- this.submitURL(requrlraw, undefined, true);
+ this.setData(requrlraw);
}
const iframeContent = iframe?.contentDocument;
if (iframeContent) {
iframeContent.addEventListener('pointerup', this.iframeUp);
iframeContent.addEventListener('pointerdown', this.iframeDown);
+ // iframeContent.addEventListener(
+ // 'wheel',
+ // e => {
+ // e.ctrlKey && e.preventDefault();
+ // },
+ // { passive: false }
+ // );
const initHeights = () => {
this._scrollHeight = Math.max(this._scrollHeight, (iframeContent.body.children[0] as any)?.scrollHeight || 0);
if (this._scrollHeight) {
@@ -482,11 +468,11 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
action(() => initHeights),
5000
);
- iframe.setAttribute('enable-annotation', 'true');
iframeContent.addEventListener(
'click',
undoBatch(
action((e: MouseEvent) => {
+ const batch = UndoManager.StartBatch('webclick');
let href = '';
for (let ele = e.target as any; ele; ele = ele.parentElement) {
href = (typeof ele.href === 'string' ? ele.href : ele.href?.baseVal) || ele.parentElement?.href || href;
@@ -494,48 +480,61 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
const origin = this.webField?.origin;
if (href && origin) {
e.stopPropagation();
- setTimeout(() => this.submitURL(href.replace(Utils.prepend(''), origin)));
+ setTimeout(() => {
+ this.setData(href.replace(Utils.prepend(''), origin));
+ batch.end();
+ });
if (this._outerRef.current) {
- this._outerRef.current.scrollTop = NumCast(this.layoutDoc._scrollTop);
+ this._outerRef.current.scrollTop = NumCast(this.layoutDoc._layout_scrollTop);
this._outerRef.current.scrollLeft = 0;
}
}
})
)
);
- iframe.contentDocument.addEventListener('wheel', this.iframeWheel, false);
- //iframe.contentDocument.addEventListener('scroll', () => !this.active() && this._iframe && (this._iframe.scrollTop = NumCast(this.layoutDoc._scrollTop), false));
+ iframe.contentDocument.addEventListener('wheel', this.iframeWheel, { passive: false });
}
};
@action
- iframeWheel = (e: any) => {
+ iframeWheel = (e: WheelEvent) => {
if (!this._scrollTimer) {
- this._scrollTimer = setTimeout(
- action(() => (this._scrollTimer = undefined)),
- 250
- ); // this turns events off on the iframe which allows scrolling to change direction smoothly
+ addStyleSheetRule(WebBox.webStyleSheet, 'webBox-iframe', { 'pointer-events': 'none' });
+ this._scrollTimer = setTimeout(() => {
+ this._scrollTimer = undefined;
+ clearStyleSheetRules(WebBox.webStyleSheet);
+ }, 250); // this turns events off on the iframe which allows scrolling to change direction smoothly
+ }
+ if (e.ctrlKey) {
+ if (this._innerCollectionView) {
+ this._innerCollectionView.zoom(e.screenX, e.screenY, e.deltaY);
+ const offset = e.clientY - NumCast(this.layoutDoc._layout_scrollTop);
+ this.layoutDoc.panY = offset - offset / NumCast(this.layoutDoc._freeform_scale) + NumCast(this.layoutDoc._layout_scrollTop) - NumCast(this.layoutDoc._layout_scrollTop) / NumCast(this.layoutDoc._freeform_scale);
+ }
+ e.preventDefault();
}
};
@action
setDashScrollTop = (scrollTop: number, timeout: number = 250) => {
const iframeHeight = Math.max(scrollTop, this._scrollHeight - this.panelHeight());
- this._scrollTimer && clearTimeout(this._scrollTimer);
- this._scrollTimer = setTimeout(
- action(() => {
- this._scrollTimer = undefined;
- const newScrollTop = scrollTop > iframeHeight ? iframeHeight : scrollTop;
- if (!LinkDocPreview.LinkInfo && this._outerRef.current && newScrollTop !== this.layoutDoc.thumbScrollTop && (!LightboxView.LightboxDoc || LightboxView.IsLightboxDocView(this.props.docViewPath()))) {
- this.layoutDoc.thumb = undefined;
- this.layoutDoc.thumbScrollTop = undefined;
- this.layoutDoc.thumbNativeWidth = undefined;
- this.layoutDoc.thumbNativeHeight = undefined;
- this.layoutDoc.scrollTop = this._outerRef.current.scrollTop = newScrollTop;
- } else if (this._outerRef.current) this._outerRef.current.scrollTop = newScrollTop;
- }),
- timeout
- );
+ if (this._scrollTimer) {
+ clearTimeout(this._scrollTimer);
+ clearStyleSheetRules(WebBox.webStyleSheet);
+ }
+ addStyleSheetRule(WebBox.webStyleSheet, 'webBox-iframe', { 'pointer-events': 'none' });
+ this._scrollTimer = setTimeout(() => {
+ clearStyleSheetRules(WebBox.webStyleSheet);
+ this._scrollTimer = undefined;
+ const newScrollTop = scrollTop > iframeHeight ? iframeHeight : scrollTop;
+ if (!LinkDocPreview.LinkInfo && this._outerRef.current && newScrollTop !== this.layoutDoc.thumbScrollTop && (!LightboxView.LightboxDoc || LightboxView.IsLightboxDocView(this.props.docViewPath()))) {
+ this.layoutDoc.thumb = undefined;
+ this.layoutDoc.thumbScrollTop = undefined;
+ this.layoutDoc.thumbNativeWidth = undefined;
+ this.layoutDoc.thumbNativeHeight = undefined;
+ this.layoutDoc.layout_scrollTop = this._outerRef.current.scrollTop = newScrollTop;
+ } else if (this._outerRef.current) this._outerRef.current.scrollTop = newScrollTop;
+ }, timeout);
};
goTo = (scrollTop: number, duration: number, easeFunc: 'linear' | 'ease' | undefined) => {
@@ -551,14 +550,15 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
};
forward = (checkAvailable?: boolean) => {
- const future = Cast(this.rootDoc[this.fieldKey + '-future'], listSpec('string'), []);
- const history = Cast(this.rootDoc[this.fieldKey + '-history'], listSpec('string'), []);
+ const future = Cast(this.rootDoc[this.fieldKey + '_future'], listSpec('string'), []);
+ const history = Cast(this.rootDoc[this.fieldKey + '_history'], listSpec('string'), []);
if (checkAvailable) return future.length;
runInAction(() => {
if (future.length) {
const curUrl = this._url;
- this.rootDoc[this.fieldKey + '-history'] = new List<string>([...history, this._url]);
- this.rootDoc[this.fieldKey] = new WebField(new URL(future.pop()!));
+ this.dataDoc[this.fieldKey + '_history'] = new List<string>([...history, this._url]);
+ this.dataDoc[this.fieldKey] = new WebField(new URL(future.pop()!));
+ this._scrollHeight = 0;
if (this._webUrl === this._url) {
this._webUrl = curUrl;
setTimeout(action(() => (this._webUrl = this._url)));
@@ -572,15 +572,16 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
};
back = (checkAvailable?: boolean) => {
- const future = Cast(this.rootDoc[this.fieldKey + '-future'], listSpec('string'));
- const history = Cast(this.rootDoc[this.fieldKey + '-history'], listSpec('string'), []);
+ const future = Cast(this.rootDoc[this.fieldKey + '_future'], listSpec('string'));
+ const history = Cast(this.rootDoc[this.fieldKey + '_history'], listSpec('string'), []);
if (checkAvailable) return history.length;
runInAction(() => {
if (history.length) {
const curUrl = this._url;
- if (future === undefined) this.rootDoc[this.fieldKey + '-future'] = new List<string>([this._url]);
- else this.rootDoc[this.fieldKey + '-future'] = new List<string>([...future, this._url]);
- this.layoutDoc[this.fieldKey] = new WebField(new URL(history.pop()!));
+ if (future === undefined) this.dataDoc[this.fieldKey + '_future'] = new List<string>([this._url]);
+ else this.dataDoc[this.fieldKey + '_future'] = new List<string>([...future, this._url]);
+ this.dataDoc[this.fieldKey] = new WebField(new URL(history.pop()!));
+ this._scrollHeight = 0;
if (this._webUrl === this._url) {
this._webUrl = curUrl;
setTimeout(action(() => (this._webUrl = this._url)));
@@ -607,23 +608,18 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
if (!newUrl) return;
if (!newUrl.startsWith('http')) newUrl = 'http://' + newUrl;
try {
- const future = Cast(this.rootDoc[this.fieldKey + '-future'], listSpec('string'));
- const history = Cast(this.rootDoc[this.fieldKey + '-history'], listSpec('string'));
- const url = this.webField?.toString();
- if (url && !preview) {
- this.rootDoc[this.fieldKey + '-history'] = new List<string>([...(history || []), url]);
- this.layoutDoc._scrollTop = 0;
+ if (!preview) {
if (this._webPageHasBeenRendered) {
this.layoutDoc.thumb = undefined;
this.layoutDoc.thumbScrollTop = undefined;
this.layoutDoc.thumbNativeWidth = undefined;
this.layoutDoc.thumbNativeHeight = undefined;
}
- future && (future.length = 0);
}
if (!preview) {
- this.layoutDoc[this.fieldKey] = new WebField(new URL(newUrl));
- !dontUpdateIframe && (this._webUrl = this._url);
+ if (!dontUpdateIframe) {
+ this._webUrl = this._url;
+ }
}
} catch (e) {
console.log('WebBox URL error:' + this._url);
@@ -637,53 +633,34 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
const uri = dataTransfer.getData('text/uri-list');
const url = uri || html || this._url || '';
const newurl = url.startsWith(window.location.origin) ? url.replace(window.location.origin, this._url?.match(/http[s]?:\/\/[^\/]*/)?.[0] || '') : url;
- this.submitURL(newurl);
+ this.setData(newurl);
e.stopPropagation();
};
+
+ @action
+ setData = (data: Field | Promise<RefField | undefined>) => {
+ if (!(typeof data === 'string') && !(data instanceof WebField)) return false;
+ if (Field.toString(data) === this._url) return false;
+ this._scrollHeight = 0;
+ const oldUrl = this._url;
+ const history = Cast(this.rootDoc[this.fieldKey + '_history'], listSpec('string'), []);
+ const weburl = new WebField(Field.toString(data));
+ this.dataDoc[this.fieldKey + '_future'] = new List<string>([]);
+ this.dataDoc[this.fieldKey + '_history'] = new List<string>([...(history || []), oldUrl]);
+ this.dataDoc[this.fieldKey] = weburl;
+ return true;
+ };
onWebUrlValueKeyDown = (e: React.KeyboardEvent) => {
- e.key === 'Enter' && this.submitURL(this._keyInput.current!.value);
+ if (e.key === 'Enter') this.setData(this._keyInput.current!.value);
e.stopPropagation();
};
- @computed get urlEditor() {
- return (
- <div className="collectionMenu-webUrlButtons" onDrop={this.onWebUrlDrop} onDragOver={e => e.preventDefault()}>
- <input
- className="collectionMenu-urlInput"
- key={this._url}
- placeholder="ENTER URL"
- defaultValue={this._url}
- onDrop={this.onWebUrlDrop}
- onDragOver={e => e.preventDefault()}
- onKeyDown={this.onWebUrlValueKeyDown}
- onClick={e => {
- this._keyInput.current!.select();
- e.stopPropagation();
- }}
- ref={this._keyInput}
- />
- <div style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between', maxWidth: '250px' }}>
- <button className="submitUrl" onClick={() => this.submitURL(this._keyInput.current!.value)} onDragOver={e => e.stopPropagation()} onDrop={this.onWebUrlDrop}>
- GO
- </button>
- <button className="submitUrl" onClick={() => this.back}>
- {' '}
- <FontAwesomeIcon icon="caret-left" size="lg" />{' '}
- </button>
- <button className="submitUrl" onClick={() => this.forward}>
- {' '}
- <FontAwesomeIcon icon="caret-right" size="lg" />{' '}
- </button>
- </div>
- </div>
- );
- }
-
specificContextMenu = (e: React.MouseEvent | PointerEvent): void => {
const cm = ContextMenu.Instance;
const funcs: ContextMenuProps[] = [];
if (!cm.findByDescription('Options...')) {
- !Doc.noviceMode && funcs.push({ description: (this.layoutDoc.useCors ? "Don't Use" : 'Use') + ' Cors', event: () => (this.layoutDoc.useCors = !this.layoutDoc.useCors), icon: 'snowflake' });
+ !Doc.noviceMode &&
+ funcs.push({ description: (this.layoutDoc[this.fieldKey + '_useCors'] ? "Don't Use" : 'Use') + ' Cors', event: () => (this.layoutDoc[this.fieldKey + '_useCors'] = !this.layoutDoc[this.fieldKey + '_useCors']), icon: 'snowflake' });
funcs.push({
description: (this.layoutDoc.allowScripts ? 'Prevent' : 'Allow') + ' Scripts',
event: () => {
@@ -696,16 +673,17 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
icon: 'snowflake',
});
funcs.push({
- description: (!this.layoutDoc.forceReflow ? 'Force' : 'Prevent') + ' Reflow',
+ description: (!this.layoutDoc.layout_forceReflow ? 'Force' : 'Prevent') + ' Reflow',
event: () => {
- const nw = !this.layoutDoc.forceReflow ? undefined : Doc.NativeWidth(this.layoutDoc) - this.sidebarWidth() / (this.props.NativeDimScaling?.() || 1);
- this.layoutDoc.forceReflow = !nw;
+ const nw = !this.layoutDoc.layout_forceReflow ? undefined : Doc.NativeWidth(this.layoutDoc) - this.sidebarWidth() / (this.props.NativeDimScaling?.() || 1);
+ this.layoutDoc.layout_forceReflow = !nw;
if (nw) {
- Doc.SetInPlace(this.layoutDoc, this.fieldKey + '-nativeWidth', nw, true);
+ Doc.SetInPlace(this.layoutDoc, this.fieldKey + '_nativeWidth', nw, true);
}
},
icon: 'snowflake',
});
+ funcs.push({ description: 'Create Thumbnail', event: () => this.updateThumb(), icon: 'portrait' });
cm.addItem({ description: 'Options...', subitems: funcs, icon: 'asterisk' });
}
};
@@ -746,19 +724,23 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
};
@computed get urlContent() {
- if (this._hackHide || (this.webThumb && !this._webPageHasBeenRendered && LightboxView.LightboxDoc !== this.rootDoc)) return null;
- this.props.thumbShown?.();
+ setTimeout(
+ action(() => {
+ if (this._initialScroll === undefined && !this._webPageHasBeenRendered) {
+ this.setScrollPos(NumCast(this.layoutDoc.thumbScrollTop, NumCast(this.layoutDoc.layout_scrollTop)));
+ }
+ this._webPageHasBeenRendered = true;
+ })
+ );
const field = this.rootDoc[this.props.fieldKey];
- let view;
if (field instanceof HtmlField) {
- view = <span className="webBox-htmlSpan" contentEditable onPointerDown={e => e.stopPropagation()} dangerouslySetInnerHTML={{ __html: field.html }} />;
- } else if (field instanceof WebField) {
- const url = this.layoutDoc.useCors ? Utils.CorsProxy(this._webUrl) : this._webUrl;
- view = (
+ return <span className="webBox-htmlSpan" contentEditable onPointerDown={e => e.stopPropagation()} dangerouslySetInnerHTML={{ __html: field.html }} />;
+ }
+ if (field instanceof WebField) {
+ const url = this.layoutDoc[this.fieldKey + '_useCors'] ? Utils.CorsProxy(this._webUrl) : this._webUrl;
+ return (
<iframe
className="webBox-iframe"
- enable-annotation={'true'}
- style={{ pointerEvents: this._scrollTimer ? 'none' : undefined }}
ref={action((r: HTMLIFrameElement | null) => (this._iframe = r))}
src={url}
onLoad={this.iframeLoaded}
@@ -767,37 +749,17 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
sandbox={`${this.layoutDoc.allowScripts ? 'allow-scripts' : ''} allow-forms allow-modals allow-orientation-lock allow-pointer-lock allow-popups allow-popups-to-escape-sandbox allow-presentation allow-same-origin`}
/>
);
- } else {
- view = (
- <iframe
- className="webBox-iframe"
- enable-annotation={'true'}
- style={{ pointerEvents: this._scrollTimer ? 'none' : undefined }} // if we allow pointer events when scrolling is on, then reversing direction does not work smoothly
- ref={action((r: HTMLIFrameElement | null) => (this._iframe = r))}
- src={'https://crossorigin.me/https://cs.brown.edu'}
- />
- );
}
- setTimeout(
- action(() => {
- this._scrollHeight = Math.max(this._scrollHeight, this._iframe && this._iframe.contentDocument && this._iframe.contentDocument.body ? this._iframe.contentDocument.body.scrollHeight : 0);
- if (this._initialScroll === undefined && !this._webPageHasBeenRendered) {
- this.setScrollPos(NumCast(this.layoutDoc.thumbScrollTop, NumCast(this.layoutDoc.scrollTop)));
- }
- this._webPageHasBeenRendered = true;
- })
- );
- return view;
+ return <iframe className="webBox-iframe" ref={action((r: HTMLIFrameElement | null) => (this._iframe = r))} src={'https://crossorigin.me/https://cs.brown.edu'} />;
}
addDocumentWrapper = (doc: Doc | Doc[], annotationKey?: string) => {
- console.log(annotationKey);
- (doc instanceof Doc ? [doc] : doc).forEach(doc => (doc.webUrl = this._url));
+ (doc instanceof Doc ? [doc] : doc).forEach(doc => (doc.presData = new WebField(this._url)));
return this.addDocument(doc, annotationKey);
};
sidebarAddDocument = (doc: Doc | Doc[], sidebarKey?: string) => {
- if (!this.layoutDoc._showSidebar) this.toggleSidebar();
+ if (!this.layoutDoc._layout_showSidebar) this.toggleSidebar();
return this.addDocumentWrapper(doc, sidebarKey);
};
@observable _draggingSidebar = false;
@@ -813,15 +775,15 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
.ScreenToLocalTransform()
.scale(this.props.NativeDimScaling?.() || 1)
.transformDirection(delta[0], delta[1]);
- const nativeWidth = NumCast(this.layoutDoc[this.fieldKey + '-nativeWidth']);
- const nativeHeight = NumCast(this.layoutDoc[this.fieldKey + '-nativeHeight']);
+ const nativeWidth = NumCast(this.layoutDoc[this.fieldKey + '_nativeWidth']);
+ const nativeHeight = NumCast(this.layoutDoc[this.fieldKey + '_nativeHeight']);
const curNativeWidth = NumCast(this.layoutDoc.nativeWidth, nativeWidth);
const ratio = (curNativeWidth + ((onButton ? 1 : -1) * localDelta[0]) / (this.props.NativeDimScaling?.() || 1)) / nativeWidth;
if (ratio >= 1) {
this.layoutDoc.nativeWidth = nativeWidth * ratio;
this.layoutDoc.nativeHeight = nativeHeight * (1 + ratio);
onButton && (this.layoutDoc._width = this.layoutDoc[WidthSym]() + localDelta[0]);
- this.layoutDoc._showSidebar = nativeWidth !== this.layoutDoc._nativeWidth;
+ this.layoutDoc._layout_showSidebar = nativeWidth !== this.layoutDoc._nativeWidth;
}
return false;
}),
@@ -843,7 +805,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
title="Toggle Sidebar"
style={{
display: !this.props.isContentActive() ? 'none' : undefined,
- top: StrCast(this.rootDoc._showTitle) === 'title' ? 20 : 5,
+ top: StrCast(this.layoutDoc._layout_showTitle) === 'title' ? 20 : 5,
backgroundColor: this.SidebarShown ? Colors.MEDIUM_BLUE : Colors.BLACK,
}}
onPointerDown={e => this.sidebarBtnDown(e, true)}>
@@ -854,12 +816,12 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
@observable _previewNativeWidth: Opt<number> = undefined;
@observable _previewWidth: Opt<number> = undefined;
toggleSidebar = action((preview: boolean = false) => {
- var nativeWidth = NumCast(this.layoutDoc[this.fieldKey + '-nativeWidth']);
+ var nativeWidth = NumCast(this.layoutDoc[this.fieldKey + '_nativeWidth']);
if (!nativeWidth) {
const defaultNativeWidth = this.rootDoc[this.fieldKey] instanceof WebField ? 850 : this.Document[WidthSym]();
Doc.SetNativeWidth(this.dataDoc, Doc.NativeWidth(this.dataDoc) || defaultNativeWidth);
Doc.SetNativeHeight(this.dataDoc, Doc.NativeHeight(this.dataDoc) || (this.Document[HeightSym]() / this.Document[WidthSym]()) * defaultNativeWidth);
- nativeWidth = NumCast(this.layoutDoc[this.fieldKey + '-nativeWidth']);
+ nativeWidth = NumCast(this.layoutDoc[this.fieldKey + '_nativeWidth']);
}
const sideratio = ((!this.layoutDoc.nativeWidth || this.layoutDoc.nativeWidth === nativeWidth ? WebBox.openSidebarWidth : 0) + nativeWidth) / nativeWidth;
const pdfratio = ((!this.layoutDoc.nativeWidth || this.layoutDoc.nativeWidth === nativeWidth ? WebBox.openSidebarWidth + WebBox.sidebarResizerWidth : 0) + nativeWidth) / nativeWidth;
@@ -869,26 +831,42 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
this._previewWidth = (this.layoutDoc[WidthSym]() * nativeWidth * sideratio) / curNativeWidth;
this._showSidebar = true;
} else {
- this.layoutDoc._showSidebar = !this.layoutDoc._showSidebar;
+ this.layoutDoc._layout_showSidebar = !this.layoutDoc._layout_showSidebar;
this.layoutDoc._width = (this.layoutDoc[WidthSym]() * nativeWidth * pdfratio) / curNativeWidth;
- if (!this.layoutDoc._showSidebar && !(this.dataDoc[this.fieldKey] instanceof WebField)) {
- this.layoutDoc.nativeWidth = this.dataDoc[this.fieldKey + '-nativeWidth'] = undefined;
+ if (!this.layoutDoc._layout_showSidebar && !(this.dataDoc[this.fieldKey] instanceof WebField)) {
+ this.layoutDoc.nativeWidth = this.dataDoc[this.fieldKey + '_nativeWidth'] = undefined;
} else {
this.layoutDoc.nativeWidth = nativeWidth * pdfratio;
}
}
});
+ @action
+ onZoomWheel = (e: React.WheelEvent) => {
+ if (this.props.isContentActive(true)) {
+ e.stopPropagation();
+ }
+ };
sidebarWidth = () => {
if (!this.SidebarShown) return 0;
if (this._previewWidth) return WebBox.sidebarResizerWidth + WebBox.openSidebarWidth; // return default sidebar if previewing (as in viewing a link target)
const nativeDiff = NumCast(this.layoutDoc.nativeWidth) - Doc.NativeWidth(this.dataDoc);
return WebBox.sidebarResizerWidth + nativeDiff * (this.props.NativeDimScaling?.() || 1);
};
+ _innerCollectionView: CollectionFreeFormView | undefined;
+ zoomScaling = () => this._innerCollectionView?.zoomScaling() ?? 1;
+ setInnerContent = (component: DocComponentView) => (this._innerCollectionView = component as CollectionFreeFormView);
+
@computed get content() {
const interactive = this.props.isContentActive() && this.props.pointerEvents?.() !== 'none' && Doc.ActiveTool === InkTool.None;
return (
- <div className={'webBox-cont' + (interactive ? '-interactive' : '')} onKeyDown={e => e.stopPropagation()} style={{ width: !this.layoutDoc.forceReflow ? NumCast(this.layoutDoc[this.fieldKey + '-nativeWidth']) || `100%` : '100%' }}>
- {this.urlContent}
+ <div
+ className={'webBox-cont' + (interactive ? '-interactive' : '')}
+ onKeyDown={e => e.stopPropagation()}
+ style={{
+ width: !this.layoutDoc.layout_forceReflow ? NumCast(this.layoutDoc[this.fieldKey + '_nativeWidth']) || `100%` : '100%',
+ transform: `scale(${this.zoomScaling()}) translate(${-NumCast(this.layoutDoc.freeform_panX)}px, ${-NumCast(this.layoutDoc.freeform_panY)}px)`,
+ }}>
+ {this._hackHide || (this.webThumb && !this._webPageHasBeenRendered && LightboxView.LightboxDoc !== this.rootDoc) ? null : this.urlContent}
</div>
);
}
@@ -896,7 +874,13 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
@computed get annotationLayer() {
TraceMobx();
return (
- <div className="webBox-annotationLayer" style={{ height: Doc.NativeHeight(this.Document) || undefined }} ref={this._annotationLayer}>
+ <div
+ className="webBox-annotationLayer"
+ style={{
+ transform: `scale(${this.zoomScaling()}) translate(${-NumCast(this.layoutDoc.freeform_panX)}px, ${-NumCast(this.layoutDoc.freeform_panY)}px)`,
+ height: Doc.NativeHeight(this.Document) || undefined,
+ }}
+ ref={this._annotationLayer}>
{this.inlineTextAnnotations
.sort((a, b) => NumCast(a.y) - NumCast(b.y))
.map(anno => (
@@ -906,7 +890,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
);
}
@computed get SidebarShown() {
- return this._showSidebar || this.layoutDoc._showSidebar ? true : false;
+ return this._showSidebar || this.layoutDoc._layout_showSidebar ? true : false;
}
@computed get webpage() {
@@ -916,9 +900,11 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
const renderAnnotations = (docFilters: () => string[]) => (
<CollectionFreeFormView
{...this.props}
- setContentView={emptyFunction}
+ setContentView={this.setInnerContent}
NativeWidth={returnZero}
NativeHeight={returnZero}
+ originTopLeft={false}
+ isAnnotationOverlayScrollable={true}
renderDepth={this.props.renderDepth + 1}
isAnnotationOverlay={true}
fieldKey={this.annotationKey}
@@ -929,7 +915,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
ScreenToLocalTransform={this.scrollXf}
NativeDimScaling={returnOne}
focus={this.focus}
- dropAction={'alias'}
+ dropAction="embed"
docFilters={docFilters}
select={emptyFunction}
isAnyChildContentActive={returnFalse}
@@ -945,16 +931,17 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
);
return (
<div
- className={'webBox-outerContent'}
+ className="webBox-outerContent"
ref={this._outerRef}
style={{
height: `${100 / scale}%`,
pointerEvents,
}}
- onWheel={StopEvent} // block wheel events from propagating since they're handled by the iframe
+ // when active, block wheel events from propagating since they're handled by the iframe
+ onWheel={this.onZoomWheel}
onScroll={e => this.setDashScrollTop(this._outerRef.current?.scrollTop || 0)}
onPointerDown={this.onMarqueeDown}>
- <div className={'webBox-innerContent'} style={{ height: this._webPageHasBeenRendered && this._scrollHeight ? this.scrollHeight : '100%', pointerEvents }}>
+ <div className="webBox-innerContent" style={{ height: (this._webPageHasBeenRendered && this._scrollHeight) || '100%', pointerEvents }}>
{this.content}
{<div style={{ display: DragManager.docsBeingDragged.length ? 'none' : undefined, mixBlendMode: 'multiply' }}>{renderAnnotations(this.transparentFilter)}</div>}
{renderAnnotations(this.opaqueFilter)}
@@ -1003,7 +990,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
setPreviewCursor = (func?: (x: number, y: number, drag: boolean, hide: boolean) => void) => (this._setPreviewCursor = func);
panelWidth = () => this.props.PanelWidth() / (this.props.NativeDimScaling?.() || 1) - this.sidebarWidth() + WebBox.sidebarResizerWidth;
panelHeight = () => this.props.PanelHeight() / (this.props.NativeDimScaling?.() || 1);
- scrollXf = () => this.props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._scrollTop));
+ scrollXf = () => this.props.ScreenToLocalTransform().translate(0, NumCast(this.layoutDoc._layout_scrollTop));
anchorMenuClick = () => this._sidebarRef.current?.anchorMenuClick;
transparentFilter = () => [...this.props.docFilters(), Utils.IsTransparentFilter()];
opaqueFilter = () => [...this.props.docFilters(), Utils.noDragsDocFilter, ...(DragManager.docsBeingDragged.length ? [] : [Utils.IsOpaqueFilter()])];
@@ -1016,7 +1003,6 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
pointerEvents = () => (!this._draggingSidebar && this.props.isContentActive() && this.props.pointerEvents?.() !== 'none' && !MarqueeOptionsMenu.Instance?.isShown() ? 'all' : SnappingManager.GetIsDragging() ? undefined : 'none');
annotationPointerEvents = () => (this._isAnnotating || SnappingManager.GetIsDragging() || Doc.ActiveTool !== InkTool.None ? 'all' : 'none');
render() {
- setTimeout(() => DocListCast(this.rootDoc[this.annotationKey]).forEach(doc => (doc.webUrl = this._url)));
const previewScale = this._previewNativeWidth ? 1 - this.sidebarWidth() / this._previewNativeWidth : 1;
const pointerEvents = this.layoutDoc._lockedPosition ? 'none' : (this.props.pointerEvents?.() as any);
const scale = previewScale * (this.props.NativeDimScaling?.() || 1);
@@ -1070,7 +1056,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
ref={this._sidebarRef}
{...this.props}
whenChildContentsActiveChanged={this.whenChildContentsActiveChanged}
- fieldKey={this.fieldKey + '-' + this._urlHash}
+ fieldKey={this.fieldKey + '_' + this._urlHash}
rootDoc={this.rootDoc}
layoutDoc={this.layoutDoc}
dataDoc={this.dataDoc}
diff --git a/src/client/views/nodes/button/FontIconBox.tsx b/src/client/views/nodes/button/FontIconBox.tsx
index 26515da30..5e615f2c1 100644
--- a/src/client/views/nodes/button/FontIconBox.tsx
+++ b/src/client/views/nodes/button/FontIconBox.tsx
@@ -44,16 +44,12 @@ export enum ButtonType {
ToggleButton = 'tglBtn',
ColorButton = 'colorBtn',
ToolButton = 'toolBtn',
- NumberButton = 'numBtn',
+ NumberSliderButton = 'numSliderBtn',
+ NumberDropdownButton = 'numDropdownBtn',
+ NumberInlineButton = 'numInlineBtn',
EditableText = 'editableText',
}
-export enum NumButtonType {
- Slider = 'slider',
- DropdownOptions = 'list',
- Inline = 'inline',
-}
-
export interface ButtonProps extends FieldViewProps {
type?: ButtonType;
}
@@ -132,8 +128,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
/**
* Number button
*/
- @computed get numberButton() {
- const numBtnType: string = StrCast(this.rootDoc.numBtnType);
+ @computed get numberSliderButton() {
const numScript = ScriptCast(this.rootDoc.script);
const setValue = (value: number) => UndoManager.RunInBatch(() => numScript?.script.run({ self: this.rootDoc, value, _readOnly_: false }), 'set num value');
@@ -142,102 +137,116 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
const label = !FontIconBox.GetShowLabels() ? null : <div className="fontIconBox-label">{this.label}</div>;
- if (numBtnType === NumButtonType.Slider) {
- const dropdown = (
- <div className="menuButton-dropdownBox" onPointerDown={e => e.stopPropagation()}>
- <input
- type="range"
- step="1"
- min={NumCast(this.rootDoc.numBtnMin, 0)}
- max={NumCast(this.rootDoc.numBtnMax, 100)}
- value={checkResult}
- className="menu-slider"
- onPointerDown={() => (this._batch = UndoManager.StartBatch('presDuration'))}
- onPointerUp={() => this._batch?.end()}
- onChange={e => {
- e.stopPropagation();
- setValue(Number(e.target.value));
- }}
- />
+ const dropdown = (
+ <div className="menuButton-dropdownBox" onPointerDown={e => e.stopPropagation()}>
+ <input
+ type="range"
+ step="1"
+ min={NumCast(this.rootDoc.numBtnMin, 0)}
+ max={NumCast(this.rootDoc.numBtnMax, 100)}
+ value={checkResult}
+ className="menu-slider"
+ onPointerDown={() => (this._batch = UndoManager.StartBatch('presDuration'))}
+ onPointerUp={() => this._batch?.end()}
+ onChange={e => {
+ e.stopPropagation();
+ setValue(Number(e.target.value));
+ }}
+ />
+ </div>
+ );
+ return (
+ <div
+ className="menuButton numBtn slider"
+ onPointerDown={e => e.stopPropagation()}
+ onClick={action(() => {
+ this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen;
+ this.noTooltip = this.rootDoc.dropDownOpen;
+ Doc.UnBrushAllDocs();
+ })}>
+ {checkResult}
+ {label}
+ {this.rootDoc.dropDownOpen ? dropdown : null}
+ </div>
+ );
+ }
+ /**
+ * Number button
+ */
+ @computed get numberDropdownButton() {
+ const numScript = ScriptCast(this.rootDoc.script);
+ const setValue = (value: number) => UndoManager.RunInBatch(() => numScript?.script.run({ self: this.rootDoc, value, _readOnly_: false }), 'set num value');
+
+ // Script for checking the outcome of the toggle
+ const checkResult = Number(numScript?.script.run({ self: this.rootDoc, value: 0, _readOnly_: true }).result ?? 0).toPrecision(NumCast(this.dataDoc.numPrecision, 3));
+
+ const label = !FontIconBox.GetShowLabels() ? null : <div className="fontIconBox-label">{this.label}</div>;
+
+ const items: number[] = [];
+ for (let i = 0; i < 100; i++) {
+ if (i % 2 === 0) {
+ items.push(i);
+ }
+ }
+ const list = items.map(value => {
+ return (
+ <div
+ className="list-item"
+ key={`${value}`}
+ style={{
+ backgroundColor: value.toString() === checkResult ? Colors.LIGHT_BLUE : undefined,
+ }}
+ onClick={() => setValue(value)}>
+ {value}
</div>
);
- return (
+ });
+ return (
+ <div className="menuButton numBtn list">
+ <div className="button" onClick={action(e => setValue(Number(checkResult) - 1))}>
+ <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={'minus'} />
+ </div>
<div
- className={`menuButton ${this.type} ${numBtnType}`}
- onPointerDown={e => e.stopPropagation()}
+ className={`button ${'number'}`}
+ onPointerDown={e => {
+ e.stopPropagation();
+ e.preventDefault();
+ }}
onClick={action(() => {
this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen;
this.noTooltip = this.rootDoc.dropDownOpen;
Doc.UnBrushAllDocs();
})}>
- {checkResult}
- {label}
- {this.rootDoc.dropDownOpen ? dropdown : null}
+ <input style={{ width: 30 }} className="button-input" type="number" value={checkResult} onChange={undoBatch(action(e => setValue(Number(e.target.value))))} />
+ </div>
+ <div className={`button`} onClick={action(e => setValue(Number(checkResult) + 1))}>
+ <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={'plus'} />
</div>
- );
- } else if (numBtnType === NumButtonType.DropdownOptions) {
- const items: number[] = [];
- for (let i = 0; i < 100; i++) {
- if (i % 2 === 0) {
- items.push(i);
- }
- }
- const list = items.map(value => {
- return (
- <div
- className="list-item"
- key={`${value}`}
- style={{
- backgroundColor: value.toString() === checkResult ? Colors.LIGHT_BLUE : undefined,
- }}
- onClick={() => setValue(value)}>
- {value}
- </div>
- );
- });
- return (
- <div className={`menuButton ${this.type} ${numBtnType}`}>
- <div className={`button`} onClick={action(e => setValue(Number(checkResult) - 1))}>
- <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={'minus'} />
- </div>
- <div
- className={`button ${'number'}`}
- onPointerDown={e => {
- e.stopPropagation();
- e.preventDefault();
- }}
- onClick={action(() => {
- this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen;
- this.noTooltip = this.rootDoc.dropDownOpen;
- Doc.UnBrushAllDocs();
- })}>
- <input style={{ width: 30 }} className="button-input" type="number" value={checkResult} onChange={undoBatch(action(e => setValue(Number(e.target.value))))} />
- </div>
- <div className={`button`} onClick={action(e => setValue(Number(checkResult) + 1))}>
- <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={'plus'} />
- </div>
- {this.rootDoc.dropDownOpen ? (
- <div>
- <div className="menuButton-dropdownList" style={{ left: '25%' }}>
- {list}
- </div>
- <div
- className="dropbox-background"
- onClick={action(e => {
- e.stopPropagation();
- this.rootDoc.dropDownOpen = false;
- this.noTooltip = false;
- Doc.UnBrushAllDocs();
- })}
- />
+ {this.rootDoc.dropDownOpen ? (
+ <div>
+ <div className="menuButton-dropdownList" style={{ left: '25%' }}>
+ {list}
</div>
- ) : null}
- </div>
- );
- } else {
- return <div />;
- }
+ <div
+ className="dropbox-background"
+ onClick={action(e => {
+ e.stopPropagation();
+ this.rootDoc.dropDownOpen = false;
+ this.noTooltip = false;
+ Doc.UnBrushAllDocs();
+ })}
+ />
+ </div>
+ ) : null}
+ </div>
+ );
+ }
+ /**
+ * Number button
+ */
+ @computed get numberInlineButton() {
+ return <div />;
}
/**
@@ -505,7 +514,7 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
<div className="menuButton editableText">
<FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={'lock'} />
<div style={{ width: 'calc(100% - .875em)', paddingLeft: '4px' }}>
- <EditableView GetValue={() => script?.script.run({ value: '', _readOnly_: true }).result} SetValue={setValue} contents={checkResult} />
+ <EditableView GetValue={() => script?.script.run({ value: '', _readOnly_: true }).result} SetValue={setValue} oneLine={true} contents={checkResult} />
</div>
</div>
);
@@ -528,7 +537,9 @@ export class FontIconBox extends DocComponent<ButtonProps>() {
case ButtonType.EditableText: return this.editableText;
case ButtonType.DropdownList: button = this.dropdownListButton; break;
case ButtonType.ColorButton: button = this.colorButton; break;
- case ButtonType.NumberButton: button = this.numberButton; break;
+ case ButtonType.NumberDropdownButton: button = this.numberDropdownButton; break;
+ case ButtonType.NumberInlineButton: button = this.numberInlineButton; break;
+ case ButtonType.NumberSliderButton: button = this.numberSliderButton; break;
case ButtonType.DropdownButton: button = this.dropdownButton; break;
case ButtonType.ToggleButton: button = this.toggleButton; break;
case ButtonType.TextButton:
@@ -613,7 +624,7 @@ ScriptingGlobals.add(function setHeaderColor(color?: string, checkResult?: boole
}
Doc.SharingDoc().userColor = undefined;
Doc.GetProto(Doc.SharingDoc()).userColor = color;
- Doc.UserDoc().showTitle = color === 'transparent' ? undefined : StrCast(Doc.UserDoc().showTitle, 'creationDate');
+ Doc.UserDoc().layout_showTitle = color === 'transparent' ? undefined : StrCast(Doc.UserDoc().layout_showTitle, 'creationDate');
});
// toggle: Set overlay status of selected document
@@ -626,29 +637,29 @@ ScriptingGlobals.add(function toggleOverlay(checkResult?: boolean) {
selected ? selected.props.CollectionFreeFormDocumentView?.().float() : console.log('[FontIconBox.tsx] toggleOverlay failed');
});
-ScriptingGlobals.add(function showFreeform(attr: 'grid' | 'snapline' | 'clusters' | 'arrange' | 'viewAll', checkResult?: boolean) {
+ScriptingGlobals.add(function showFreeform(attr: 'grid' | 'snaplines' | 'clusters' | 'arrange' | 'viewAll', checkResult?: boolean) {
const selected = SelectionManager.Docs().lastElement();
// prettier-ignore
- const map: Map<'grid' | 'snapline' | 'clusters' | 'arrange'| 'viewAll', { undo: boolean, checkResult: (doc:Doc) => any; setDoc: (doc:Doc) => void;}> = new Map([
+ const map: Map<'grid' | 'snaplines' | 'clusters' | 'arrange'| 'viewAll', { undo: boolean, checkResult: (doc:Doc) => any; setDoc: (doc:Doc) => void;}> = new Map([
['grid', {
undo: false,
- checkResult: (doc:Doc) => doc._backgroundGridShow,
- setDoc: (doc:Doc) => doc._backgroundGridShow = !doc._backgroundGridShow,
+ checkResult: (doc:Doc) => doc._freeform_backgroundGrid,
+ setDoc: (doc:Doc) => doc._freeform_backgroundGrid = !doc._freeform_backgroundGrid,
}],
- ['snapline', {
+ ['snaplines', {
undo: false,
- checkResult: (doc:Doc) => doc.showSnapLines,
- setDoc: (doc:Doc) => doc._showSnapLines = !doc._showSnapLines,
+ checkResult: (doc:Doc) => doc._freeform_snapLines,
+ setDoc: (doc:Doc) => doc._freeform_snapLines = !doc._freeform_snapLines,
}],
['viewAll', {
undo: false,
- checkResult: (doc:Doc) => doc._fitContentsToBox,
- setDoc: (doc:Doc) => doc._fitContentsToBox = !doc._fitContentsToBox,
+ checkResult: (doc:Doc) => doc._freeform_fitContentsToBox,
+ setDoc: (doc:Doc) => doc._freeform_fitContentsToBox = !doc._freeform_fitContentsToBox,
}],
['clusters', {
undo: false,
- checkResult: (doc:Doc) => doc._useClusters,
- setDoc: (doc:Doc) => doc._useClusters = !doc._useClusters,
+ checkResult: (doc:Doc) => doc._freeform_useClusters,
+ setDoc: (doc:Doc) => doc._freeform_useClusters = !doc._freeform_useClusters,
}],
['arrange', {
undo: true,
@@ -850,8 +861,8 @@ ScriptingGlobals.add(function setInkProperty(option: 'inkMask' | 'fillColor' | '
// prettier-ignore
const map: Map<'inkMask' | 'fillColor' | 'strokeWidth' | 'strokeColor', { checkResult: () => any; setInk: (doc: Doc) => void; setMode: () => void }> = new Map([
['inkMask', {
- checkResult: () => ((selected?.type === DocumentType.INK ? BoolCast(selected.isInkMask) : ActiveIsInkMask()) ? Colors.MEDIUM_BLUE : 'transparent'),
- setInk: (doc: Doc) => (doc.isInkMask = !doc.isInkMask),
+ checkResult: () => ((selected?.type === DocumentType.INK ? BoolCast(selected.stroke_isInkMask) : ActiveIsInkMask()) ? Colors.MEDIUM_BLUE : 'transparent'),
+ setInk: (doc: Doc) => (doc.stroke_isInkMask = !doc.stroke_isInkMask),
setMode: () => selected?.type !== DocumentType.INK && SetActiveIsInkMask(!ActiveIsInkMask()),
}],
['fillColor', {
@@ -860,8 +871,8 @@ ScriptingGlobals.add(function setInkProperty(option: 'inkMask' | 'fillColor' | '
setMode: () => SetActiveFillColor(StrCast(value)),
}],
[ 'strokeWidth', {
- checkResult: () => (selected?.type === DocumentType.INK ? NumCast(selected.strokeWidth) : ActiveInkWidth()),
- setInk: (doc: Doc) => (doc.strokeWidth = NumCast(value)),
+ checkResult: () => (selected?.type === DocumentType.INK ? NumCast(selected.stroke_width) : ActiveInkWidth()),
+ setInk: (doc: Doc) => (doc.stroke_width = NumCast(value)),
setMode: () => SetActiveInkWidth(value.toString()),
}],
['strokeColor', {
@@ -889,7 +900,7 @@ ScriptingGlobals.add(function webSetURL(url: string, checkResult?: boolean) {
if (checkResult) {
return StrCast(selected.rootDoc.data, Cast(selected.rootDoc.data, WebField, null)?.url?.href);
}
- (selected.ComponentView as WebBox).submitURL(url);
+ selected.ComponentView?.setData?.(url);
//selected.rootDoc.data = new WebField(url);
}
});
@@ -914,17 +925,26 @@ ScriptingGlobals.add(function webBack(checkResult?: boolean) {
ScriptingGlobals.add(function toggleSchemaPreview(checkResult?: boolean) {
const selected = SelectionManager.Docs().lastElement();
if (checkResult && selected) {
- const result: boolean = NumCast(selected.schemaPreviewWidth) > 0;
+ const result: boolean = NumCast(selected.schema_previewWidth) > 0;
if (result) return Colors.MEDIUM_BLUE;
else return 'transparent';
} else if (selected) {
- if (NumCast(selected.schemaPreviewWidth) > 0) {
- selected.schemaPreviewWidth = 0;
+ if (NumCast(selected.schema_previewWidth) > 0) {
+ selected.schema_previewWidth = 0;
} else {
- selected.schemaPreviewWidth = 200;
+ selected.schema_previewWidth = 200;
}
}
});
+ScriptingGlobals.add(function toggleSingleLineSchema(checkResult?: boolean) {
+ const selected = SelectionManager.Docs().lastElement();
+ if (checkResult && selected) {
+ return NumCast(selected._schema_singleLine) > 0 ? Colors.MEDIUM_BLUE : 'transparent';
+ }
+ if (selected) {
+ selected._schema_singleLine = !selected._schema_singleLine;
+ }
+});
/** STACK
* groupBy
diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx
index c05a30d1a..c929b7ff3 100644
--- a/src/client/views/nodes/formattedText/DashDocView.tsx
+++ b/src/client/views/nodes/formattedText/DashDocView.tsx
@@ -41,18 +41,33 @@ export class DashDocView {
this.root = ReactDOM.createRoot(this.dom);
this.root.render(
- <DashDocViewInternal docId={node.attrs.docId} alias={node.attrs.alias} width={node.attrs.width} height={node.attrs.height} hidden={node.attrs.hidden} fieldKey={node.attrs.fieldKey} tbox={tbox} view={view} node={node} getPos={getPos} />
+ <DashDocViewInternal
+ docId={node.attrs.docId}
+ embedding={node.attrs.embedding}
+ width={node.attrs.width}
+ height={node.attrs.height}
+ hidden={node.attrs.hidden}
+ fieldKey={node.attrs.fieldKey}
+ tbox={tbox}
+ view={view}
+ node={node}
+ getPos={getPos}
+ />
);
}
destroy() {
- setTimeout(this.root.unmount);
+ setTimeout(() => {
+ try {
+ this.root.unmount();
+ } catch {}
+ });
}
selectNode() {}
}
interface IDashDocViewInternal {
docId: string;
- alias: string;
+ embedding: string;
tbox: FormattedTextBox;
width: string;
height: string;
@@ -69,25 +84,18 @@ export class DashDocViewInternal extends React.Component<IDashDocViewInternal> {
_textBox: FormattedTextBox;
@observable _dashDoc: Doc | undefined;
@observable _finalLayout: any;
- @observable _resolvedDataDoc: any;
@observable _width: number = 0;
@observable _height: number = 0;
updateDoc = action((dashDoc: Doc) => {
this._dashDoc = dashDoc;
- this._finalLayout = this.props.docId ? dashDoc : Doc.expandTemplateLayout(Doc.Layout(dashDoc), dashDoc);
+ this._finalLayout = dashDoc;
- if (this._finalLayout) {
- if (!Doc.AreProtosEqual(this._finalLayout, dashDoc)) {
- this._finalLayout.rootDocument = dashDoc.aliasOf;
- }
- this._resolvedDataDoc = Cast(this._finalLayout.resolvedDataDoc, Doc, null);
- }
if (this.props.width !== (this._dashDoc?._width ?? '') + 'px' || this.props.height !== (this._dashDoc?._height ?? '') + 'px') {
try {
this._width = NumCast(this._dashDoc?._width);
this._height = NumCast(this._dashDoc?._height);
- // bcz: an exception will be thrown if two aliases are open at the same time when a doc view comment is made
+ // bcz: an exception will be thrown if two embeddings are open at the same time when a doc view comment is made
this.props.view.dispatch(
this.props.view.state.tr.setNodeMarkup(this.props.getPos(), null, {
...this.props.node.attrs,
@@ -105,15 +113,15 @@ export class DashDocViewInternal extends React.Component<IDashDocViewInternal> {
super(props);
this._textBox = this.props.tbox;
- DocServer.GetRefField(this.props.docId + this.props.alias).then(async dashDoc => {
+ DocServer.GetRefField(this.props.docId + this.props.embedding).then(async dashDoc => {
if (!(dashDoc instanceof Doc)) {
- this.props.alias &&
+ this.props.embedding &&
DocServer.GetRefField(this.props.docId).then(async dashDocBase => {
if (dashDocBase instanceof Doc) {
- const aliasedDoc = Doc.MakeAlias(dashDocBase, this.props.docId + this.props.alias);
- aliasedDoc.layoutKey = 'layout';
- this.props.fieldKey && DocUtils.makeCustomViewClicked(aliasedDoc, Docs.Create.StackingDocument, this.props.fieldKey, undefined);
- this.updateDoc(aliasedDoc);
+ const embedding = Doc.MakeEmbedding(dashDocBase, this.props.docId + this.props.embedding);
+ embedding.layout_fieldKey = 'layout';
+ this.props.fieldKey && DocUtils.makeCustomViewClicked(embedding, Docs.Create.StackingDocument, this.props.fieldKey, undefined);
+ this.updateDoc(embedding);
}
});
} else {
@@ -191,7 +199,6 @@ export class DashDocViewInternal extends React.Component<IDashDocViewInternal> {
onWheel={e => e.preventDefault()}>
<DocumentView
Document={this._finalLayout}
- DataDoc={this._resolvedDataDoc}
addDocument={returnFalse}
rootSelected={returnFalse} //{this._textBox.props.isSelected}
removeDocument={this.removeDoc}
diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx
index bf6fa2ec6..6c61f6709 100644
--- a/src/client/views/nodes/formattedText/DashFieldView.tsx
+++ b/src/client/views/nodes/formattedText/DashFieldView.tsx
@@ -2,18 +2,17 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@material-ui/core';
import { action, computed, IReactionDisposer, observable } from 'mobx';
import { observer } from 'mobx-react';
-import { NodeSelection } from 'prosemirror-state';
import * as ReactDOM from 'react-dom/client';
-import { DataSym, Doc, DocListCast, Field } from '../../../../fields/Doc';
+import { DataSym, Doc, Field } from '../../../../fields/Doc';
import { List } from '../../../../fields/List';
import { listSpec } from '../../../../fields/Schema';
import { SchemaHeaderField } from '../../../../fields/SchemaHeaderField';
-import { ComputedField } from '../../../../fields/ScriptField';
import { Cast, StrCast } from '../../../../fields/Types';
-import { emptyFunction, returnFalse, setupMoveUpEvents } from '../../../../Utils';
+import { emptyFunction, returnFalse, returnZero, setupMoveUpEvents } from '../../../../Utils';
import { DocServer } from '../../../DocServer';
import { CollectionViewType } from '../../../documents/DocumentTypes';
import { AntimodeMenu, AntimodeMenuProps } from '../../AntimodeMenu';
+import { SchemaTableCell } from '../../collections/collectionSchema/SchemaTableCell';
import { OpenWhere } from '../DocumentView';
import './DashFieldView.scss';
import { FormattedTextBox } from './FormattedTextBox';
@@ -70,10 +69,10 @@ export class DashFieldView {
} catch {}
});
}
- deselectNode() {
+ @action deselectNode() {
this.dom.classList.remove('ProseMirror-selectednode');
}
- selectNode() {
+ @action selectNode() {
this.dom.classList.add('ProseMirror-selectednode');
}
}
@@ -98,6 +97,7 @@ export class DashFieldViewInternal extends React.Component<IDashFieldViewInterna
_fieldKey: string;
_fieldStringRef = React.createRef<HTMLSpanElement>();
@observable _dashDoc: Doc | undefined;
+ @observable _expanded = false;
constructor(props: IDashFieldViewInternal) {
super(props);
@@ -114,139 +114,46 @@ export class DashFieldViewInternal extends React.Component<IDashFieldViewInterna
this._reactionDisposer?.();
}
- public static multiValueDelimeter = ';';
- public static fieldContent(textBoxDoc: Doc, dashDoc: Doc, fieldKey: string) {
- const dashVal = dashDoc[fieldKey] ?? dashDoc[DataSym][fieldKey] ?? '';
- const fval = dashVal instanceof List ? dashVal.join(DashFieldViewInternal.multiValueDelimeter) : StrCast(dashVal).startsWith(':=') || dashVal === '' ? Doc.Layout(textBoxDoc)[fieldKey] : dashVal;
- return { boolVal: Cast(fval, 'boolean', null), strVal: Field.toString(fval as Field) || '' };
- }
-
// set the display of the field's value (checkbox for booleans, span of text for strings)
@computed get fieldValueContent() {
- if (this._dashDoc) {
- const { boolVal, strVal } = DashFieldViewInternal.fieldContent(this._textBoxDoc, this._dashDoc, this._fieldKey);
- // field value is a boolean, so use a checkbox or similar widget to display it
- if (boolVal === true || boolVal === false) {
- return (
- <input
- className="dashFieldView-fieldCheck"
- type="checkbox"
- checked={boolVal}
- onChange={e => {
- if (this._fieldKey.startsWith('_')) Doc.Layout(this._textBoxDoc)[this._fieldKey] = e.target.checked;
- Doc.SetInPlace(this._dashDoc!, this._fieldKey, e.target.checked, true);
- }}
- />
- );
- } // field value is a string, so display it as an editable span
- else {
- // bcz: this is unfortunate, but since this React component is nested within a non-React text box (prosemirror), we can't
- // use React events. Essentially, React events occur after native events have been processed, so corresponding React events
- // will never fire because Prosemirror has handled the native events. So we add listeners for native events here.
- return (
- <span
- className="dashFieldView-fieldSpan"
- contentEditable={!this.props.unclickable()}
- style={{ display: strVal.length < 2 ? 'inline-block' : undefined }}
- suppressContentEditableWarning={true}
- defaultValue={strVal}
- ref={r => {
- r?.addEventListener('keydown', e => this.fieldSpanKeyDown(e, r));
- r?.addEventListener('blur', e => r && this.updateText(r.textContent!, false));
- r?.addEventListener(
- 'pointerdown',
- action(e => {
- // let target = e.target as any; // hrefs are stored on the dataset of the <a> node that wraps the hyerlink <span>
- // while (target && !target.dataset?.targethrefs) target = target.parentElement;
- this.props.tbox.EditorView!.dispatch(this.props.tbox.EditorView!.state.tr.setSelection(new NodeSelection(this.props.tbox.EditorView!.state.doc.resolve(this.props.getPos()))));
- // FormattedTextBoxComment.update(this.props.tbox, this.props.tbox.EditorView!, undefined, target?.dataset?.targethrefs, target?.dataset.linkdoc);
- // e.stopPropagation();
- })
- );
- }}>
- {strVal}
- </span>
- );
- }
- }
+ return !this._dashDoc ? null : (
+ <div onClick={action(e => (this._expanded = !this.props.editable ? !this._expanded : true))} style={{ fontSize: 'smaller', width: this.props.hideKey ? this.props.tbox.props.PanelWidth() - 20 : undefined }}>
+ <SchemaTableCell
+ Document={this._dashDoc}
+ col={0}
+ deselectCell={emptyFunction}
+ selectCell={emptyFunction}
+ maxWidth={this.props.hideKey ? undefined : () => 100}
+ columnWidth={this.props.hideKey ? () => this.props.tbox.props.PanelWidth() - 20 : returnZero}
+ selectedCell={() => [this._dashDoc!, 0]}
+ fieldKey={this._fieldKey}
+ rowHeight={returnZero}
+ isRowActive={() => this._expanded && this.props.editable}
+ padding={0}
+ getFinfo={emptyFunction}
+ setColumnValues={returnFalse}
+ allowCRs={true}
+ oneLine={!this._expanded}
+ finishEdit={action(() => (this._expanded = false))}
+ />
+ </div>
+ );
}
- // we need to handle all key events on the input span or else they will propagate to prosemirror.
- @action
- fieldSpanKeyDown = (e: KeyboardEvent, span: HTMLSpanElement) => {
- if (e.key === 'c' && (e.ctrlKey || e.metaKey)) {
- navigator.clipboard.writeText(window.getSelection()?.toString() || '');
- return;
- }
- if (e.key === 'Enter') {
- // handle the enter key by "submitting" the current text to Dash's database.
- this.updateText(span.textContent!, true);
- e.preventDefault(); // prevent default to avoid a newline from being generated and wiping out this field view
- }
- if (e.key === 'a' && (e.ctrlKey || e.metaKey)) {
- // handle ctrl-A to select all the text within the span
- if (window.getSelection) {
- const range = document.createRange();
- range.selectNodeContents(span);
- window.getSelection()!.removeAllRanges();
- window.getSelection()!.addRange(range);
- }
- e.preventDefault(); //prevent default so that all the text in the prosemirror text box isn't selected
- }
- if (!this.props.editable) {
- e.preventDefault();
- }
- e.stopPropagation(); // we need to handle all events or else they will propagate to prosemirror.
- };
-
- @action
- updateText = (nodeText: string, forceMatch: boolean) => {
- if (nodeText) {
- const newText = nodeText.startsWith(':=') || nodeText.startsWith('=:=') ? ':=-computed-' : nodeText;
- // look for a document whose id === the fieldKey being displayed. If there's a match, then that document
- // holds the different enumerated values for the field in the titles of its collected documents.
- // if there's a partial match from the start of the input text, complete the text --- TODO: make this an auto suggest box and select from a drop down.
- DocServer.GetRefField(this._fieldKey).then(options => {
- let modText = '';
- options instanceof Doc && DocListCast(options.data).forEach(opt => (forceMatch ? StrCast(opt.title).startsWith(newText) : StrCast(opt.title) === newText) && (modText = StrCast(opt.title)));
- if (modText) {
- // elementfieldSpan.innerHTML = this._dashDoc![this._fieldKey as string] = modText;
- Doc.SetInPlace(this._dashDoc!, this._fieldKey, modText, true);
- } // if the text starts with a ':=' then treat it as an expression by making a computed field from its value storing it in the key
- else if (nodeText.startsWith(':=')) {
- this._dashDoc![DataSym][this._fieldKey] = ComputedField.MakeFunction(nodeText.substring(2));
- } else if (nodeText.startsWith('=:=')) {
- Doc.Layout(this._textBoxDoc)[this._fieldKey] = ComputedField.MakeFunction(nodeText.substring(3));
- } else {
- if (Number(newText).toString() === newText) {
- if (this._fieldKey.startsWith('_')) Doc.Layout(this._textBoxDoc)[this._fieldKey] = Number(newText);
- Doc.SetInPlace(this._dashDoc!, this._fieldKey, Number(newText), true);
- } else {
- const splits = newText.split(DashFieldViewInternal.multiValueDelimeter);
- if (!this._textBoxDoc[this._fieldKey]) {
- const strVal = splits.length > 1 ? new List<string>(splits) : newText;
- if (this._fieldKey.startsWith('_')) Doc.Layout(this._textBoxDoc)[this._fieldKey] = strVal;
- Doc.SetInPlace(this._dashDoc!, this._fieldKey, strVal, true);
- }
- }
- }
- });
- }
- };
-
createPivotForField = (e: React.MouseEvent) => {
let container = this.props.tbox.props.DocumentView?.().props.docViewPath().lastElement();
if (container) {
- const alias = Doc.MakeAlias(container.props.Document);
- alias._viewType = CollectionViewType.Time;
- let list = Cast(alias._columnHeaders, listSpec(SchemaHeaderField));
+ const embedding = Doc.MakeEmbedding(container.rootDoc);
+ embedding._viewType = CollectionViewType.Time;
+ const colHdrKey = '_' + container.LayoutFieldKey + '_columnHeaders';
+ let list = Cast(embedding[colHdrKey], listSpec(SchemaHeaderField));
if (!list) {
- alias._columnHeaders = list = new List<SchemaHeaderField>();
+ embedding[colHdrKey] = 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'));
- alias._pivotField = this._fieldKey.startsWith('#') ? 'tags' : this._fieldKey;
- this.props.tbox.props.addDocTab(alias, OpenWhere.addRight);
+ embedding._pivotField = this._fieldKey.startsWith('#') ? 'tags' : this._fieldKey;
+ this.props.tbox.props.addDocTab(embedding, OpenWhere.addRight);
}
};
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.scss b/src/client/views/nodes/formattedText/FormattedTextBox.scss
index b5a3c5d84..109b62e6f 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.scss
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.scss
@@ -41,7 +41,7 @@ audiotag:hover {
flex-direction: row;
transition: opacity 1s;
width: 100%;
- position: absolute;
+ position: relative;
top: 0;
left: 0;
}
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index b5aa34a29..023814a9d 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -74,8 +74,11 @@ const translateGoogleApi = require('translate-google-api');
export const GoogleRef = 'googleDocId';
type PullHandler = (exportState: Opt<GoogleApiClientUtils.Docs.ImportResult>, dataDoc: Doc) => void;
+export interface FormattedTextBoxProps {
+ allowScroll?: boolean;
+}
@observer
-export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
+export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps & FormattedTextBoxProps>() {
public static LayoutString(fieldStr: string) {
return FieldView.LayoutString(FormattedTextBox, fieldStr);
}
@@ -115,38 +118,38 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
return this._editorView;
}
public get SidebarKey() {
- return this.fieldKey + '-sidebar';
+ return this.fieldKey + '_sidebar';
}
@computed get allSidebarDocs() {
return DocListCast(this.dataDoc[this.SidebarKey]);
}
@computed get noSidebar() {
- return this.props.docViewPath().lastElement()?.props.hideDecorationTitle || this.props.noSidebar || this.Document._noSidebar;
+ return this.props.docViewPath().lastElement()?.props.hideDecorationTitle || this.props.noSidebar || this.Document._layout_noSidebar;
}
- @computed get sidebarWidthPercent() {
- return this._showSidebar ? '20%' : StrCast(this.layoutDoc._sidebarWidthPercent, '0%');
+ @computed get layout_sidebarWidthPercent() {
+ return this._showSidebar ? '20%' : StrCast(this.layoutDoc._layout_sidebarWidthPercent, '0%');
}
@computed get sidebarColor() {
- return StrCast(this.layoutDoc.sidebarColor, StrCast(this.layoutDoc[this.fieldKey + '-backgroundColor'], '#e4e4e4'));
+ return StrCast(this.layoutDoc.sidebarColor, StrCast(this.layoutDoc[this.fieldKey + '_backgroundColor'], '#e4e4e4'));
}
- @computed get autoHeight() {
- return (this.props.forceAutoHeight || this.layoutDoc._autoHeight) && !this.props.ignoreAutoHeight;
+ @computed get layout_autoHeight() {
+ return (this.props.forceAutoHeight || this.layoutDoc._layout_autoHeight) && !this.props.ignoreAutoHeight;
}
@computed get textHeight() {
- return NumCast(this.rootDoc[this.fieldKey + '-height']);
+ return NumCast(this.rootDoc[this.fieldKey + '_height']);
}
@computed get scrollHeight() {
- return NumCast(this.rootDoc[this.fieldKey + '-scrollHeight']);
+ return NumCast(this.rootDoc[this.fieldKey + '_scrollHeight']);
}
@computed get sidebarHeight() {
- return !this.sidebarWidth() ? 0 : NumCast(this.rootDoc[this.SidebarKey + '-height']);
+ return !this.sidebarWidth() ? 0 : NumCast(this.rootDoc[this.SidebarKey + '_height']);
}
@computed get titleHeight() {
return this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.HeaderMargin) || 0;
}
- @computed get autoHeightMargins() {
- return this.titleHeight + NumCast(this.layoutDoc._autoHeightMargins);
+ @computed get layout_autoHeightMargins() {
+ return this.titleHeight + NumCast(this.layoutDoc._layout_autoHeightMargins);
}
@computed get _recording() {
return this.dataDoc?.mediaState === 'recording';
@@ -210,8 +213,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
public RemoveLinkFromDoc(linkDoc?: Doc) {
this.unhighlightSearchTerms();
const state = this._editorView?.state;
- const a1 = linkDoc?.anchor1 as Doc;
- const a2 = linkDoc?.anchor2 as Doc;
+ const a1 = linkDoc?.link_anchor_1 as Doc;
+ const a2 = linkDoc?.link_anchor_2 as Doc;
if (state && a1 && a2 && this._editorView) {
this.removeDocument(a1);
this.removeDocument(a2);
@@ -252,18 +255,18 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
AnchorMenu.Instance.Status = 'marquee';
AnchorMenu.Instance.OnClick = (e: PointerEvent) => {
- !this.layoutDoc.showSidebar && this.toggleSidebar();
+ !this.layoutDoc.layout_showSidebar && this.toggleSidebar();
setTimeout(() => this._sidebarRef.current?.anchorMenuClick(this.makeLinkAnchor(undefined, OpenWhere.addRight, undefined, 'Anchored Selection', true))); // give time for sidebarRef to be created
};
AnchorMenu.Instance.OnAudio = (e: PointerEvent) => {
- !this.layoutDoc.showSidebar && this.toggleSidebar();
+ !this.layoutDoc.layout_showSidebar && this.toggleSidebar();
const anchor = this.makeLinkAnchor(undefined, OpenWhere.addRight, undefined, 'Anchored Selection', true, true);
setTimeout(() => {
const target = this._sidebarRef.current?.anchorMenuClick(anchor);
if (target) {
anchor.followLinkAudio = true;
DocumentViewInternal.recordAudioAnnotation(Doc.GetProto(target), Doc.LayoutFieldKey(target));
- target.title = ComputedField.MakeFunction(`self["text-audioAnnotations-text"].lastElement()`);
+ target.title = ComputedField.MakeFunction(`self["text_audioAnnotations_text"].lastElement()`);
}
});
};
@@ -320,7 +323,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
if (this._applyingChange !== this.fieldKey && removeSelection(json) !== removeSelection(curProto?.Data)) {
this._applyingChange = this.fieldKey;
const textChange = curText !== Cast(dataDoc[this.fieldKey], RichTextField)?.Text;
- textChange && (dataDoc[this.fieldKey + '-lastModified'] = new DateField(new Date(Date.now())));
+ textChange && (dataDoc[this.fieldKey + '_modificationDate'] = new DateField(new Date(Date.now())));
if ((!curTemp && !curProto) || curText || json.includes('dash')) {
// 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 (removeSelection(json) !== removeSelection(curLayout?.Data)) {
@@ -330,7 +333,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
} else {
dataDoc[this.fieldKey] = new RichTextField(json, curText);
}
- dataDoc[this.fieldKey + '-noTemplate'] = true; //(curTemp?.Text || "") !== curText; // mark the data field as being split from the template if it has been edited
+ dataDoc[this.fieldKey + '_noTemplate'] = true; //(curTemp?.Text || "") !== curText; // 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: curText });
unchanged = false;
}
@@ -338,7 +341,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
// if we've deleted all the text in a note driven by a template, then restore the template data
dataDoc[this.fieldKey] = undefined;
this._editorView.updateState(EditorState.fromJSON(this.config, JSON.parse((curProto || curTemp).Data)));
- dataDoc[this.fieldKey + '-noTemplate'] = undefined; // mark the data field as not being split from any template it might have
+ 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: curText });
unchanged = false;
}
@@ -368,7 +371,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
let linkAnchor;
let link;
LinkManager.Links(this.dataDoc).forEach((l, i) => {
- const anchor = (l.anchor1 as Doc).annotationOn ? (l.anchor1 as Doc) : (l.anchor2 as Doc).annotationOn ? (l.anchor2 as Doc) : undefined;
+ const anchor = (l.link_anchor_1 as Doc).annotationOn ? (l.link_anchor_1 as Doc) : (l.link_anchor_2 as Doc).annotationOn ? (l.link_anchor_2 as Doc) : undefined;
if (anchor && (anchor.annotationOn as Doc).mediaState === 'recording') {
linkTime = NumCast(anchor._timecodeToShow /* audioStart */);
linkAnchor = anchor;
@@ -404,7 +407,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
autoLink = () => {
const newAutoLinks = new Set<Doc>();
- const oldAutoLinks = LinkManager.Links(this.props.Document).filter(link => link.linkRelationship === 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;
@@ -416,7 +419,7 @@ 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.anchor2 !== this.rootDoc).forEach(LinkManager.Instance.deleteLink);
+ oldAutoLinks.filter(oldLink => !newAutoLinks.has(oldLink) && oldLink.link_anchor_2 !== this.rootDoc).forEach(LinkManager.Instance.deleteLink);
};
updateTitle = () => {
@@ -425,7 +428,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
!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'] &&
+ !this.dataDoc.title_custom &&
(Doc.LayoutFieldKey(this.rootDoc) === this.fieldKey || this.fieldKey === 'text')
) {
let node = this._editorView.state.doc;
@@ -457,8 +460,8 @@ 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.Document).find(link => Doc.AreProtosEqual(Cast(link.anchor1, Doc, null), this.rootDoc) && Doc.AreProtosEqual(Cast(link.anchor2, Doc, null), target)) ||
- DocUtils.MakeLink(this.props.Document, target, { linkRelationship: LinkManager.AutoKeywords })!);
+ (LinkManager.Links(this.Document).find(link => Doc.AreProtosEqual(Cast(link.link_anchor_1, Doc, null), this.rootDoc) && Doc.AreProtosEqual(Cast(link.link_anchor_2, Doc, null), target)) ||
+ DocUtils.MakeLink(this.props.Document, target, { link_relationship: LinkManager.AutoKeywords })!);
newAutoLinks.add(alink);
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 ?? []));
@@ -525,7 +528,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
this.setupEditor(this.config, this.fieldKey);
this._dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this), this.layoutDoc);
}
- // if (this.autoHeight) this.tryUpdateScrollHeight();
+ // if (this.layout_autoHeight) this.tryUpdateScrollHeight();
};
@undoBatch
@@ -551,11 +554,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
docId: target[Id],
float: 'unset',
});
- if (!['alias', 'copy'].includes((dragData.dropAction ?? '') as any)) {
+ if (!['embed', 'copy'].includes((dragData.dropAction ?? '') as any)) {
dragData.removeDocument?.(dragData.draggedDocuments[0]);
}
- target._fitContentsToBox = true;
- target.context = this.rootDoc;
+ target._freeform_fitContentsToBox = true;
+ target.embedContainer = this.rootDoc;
const view = this._editorView!;
view.dispatch(view.state.tr.insert(view.posAtCoords({ left: de.x, top: de.y })!.pos, node));
e.stopPropagation();
@@ -612,7 +615,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
if (Array.from(highlights).join('') === FormattedTextBox._globalHighlightsCache) return;
setTimeout(() => (FormattedTextBox._globalHighlightsCache = Array.from(highlights).join('')));
clearStyleSheetRules(FormattedTextBox._userStyleSheet);
- if (highlights.includes('Audio Tags')) {
+ if (!highlights.includes('Audio Tags')) {
addStyleSheetRule(FormattedTextBox._userStyleSheet, 'audiotag', { display: 'none' }, '');
}
if (highlights.includes('Text from Others')) {
@@ -652,14 +655,14 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
@observable _showSidebar = false;
@computed get SidebarShown() {
- return this._showSidebar || this.layoutDoc._showSidebar ? true : false;
+ return this._showSidebar || this.layoutDoc._layout_showSidebar ? true : false;
}
@action
toggleSidebar = (preview: boolean = false) => {
const prevWidth = 1 - this.sidebarWidth() / Number(getComputedStyle(this._ref.current!).width.replace('px', ''));
if (preview) this._showSidebar = true;
- else this.layoutDoc._showSidebar = (this.layoutDoc._sidebarWidthPercent = StrCast(this.layoutDoc._sidebarWidthPercent, '0%') === '0%' ? '50%' : '0%') !== '0%';
+ else this.layoutDoc._layout_showSidebar = (this.layoutDoc._layout_sidebarWidthPercent = StrCast(this.layoutDoc._layout_sidebarWidthPercent, '0%') === '0%' ? '50%' : '0%') !== '0%';
this.layoutDoc._width = !preview && this.SidebarShown ? NumCast(this.layoutDoc._width) * 2 : Math.max(20, NumCast(this.layoutDoc._width) * prevWidth);
};
@@ -682,11 +685,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
.ScreenToLocalTransform()
.scale(this.props.NativeDimScaling?.() || 1)
.transformDirection(delta[0], delta[1]);
- const sidebarWidth = (NumCast(this.layoutDoc._width) * Number(this.sidebarWidthPercent.replace('%', ''))) / 100;
+ const sidebarWidth = (NumCast(this.layoutDoc._width) * Number(this.layout_sidebarWidthPercent.replace('%', ''))) / 100;
const width = this.layoutDoc[WidthSym]() + localDelta[0];
- this.layoutDoc._sidebarWidthPercent = Math.max(0, (sidebarWidth + localDelta[0]) / width) * 100 + '%';
+ this.layoutDoc._layout_sidebarWidthPercent = Math.max(0, (sidebarWidth + localDelta[0]) / width) * 100 + '%';
this.layoutDoc.width = width;
- this.layoutDoc._showSidebar = this.layoutDoc._sidebarWidthPercent !== '0%';
+ this.layoutDoc._layout_showSidebar = this.layoutDoc._layout_sidebarWidthPercent !== '0%';
e.preventDefault();
return false;
};
@@ -754,7 +757,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
description: 'plain',
event: undoBatch(() => {
Doc.setNativeView(this.rootDoc);
- this.layoutDoc.autoHeightMargins = undefined;
+ this.layoutDoc.layout_autoHeightMargins = undefined;
}),
icon: 'eye',
});
@@ -762,18 +765,18 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
description: 'metadata',
event: undoBatch(() => {
this.dataDoc.layout_meta = Cast(Doc.UserDoc().emptyHeader, Doc, null)?.layout;
- this.rootDoc.layoutKey = 'layout_meta';
- setTimeout(() => (this.rootDoc._headerHeight = this.rootDoc._autoHeightMargins = 50), 50);
+ this.rootDoc.layout_fieldKey = 'layout_meta';
+ setTimeout(() => (this.rootDoc._headerHeight = this.rootDoc._layout_autoHeightMargins = 50), 50);
}),
icon: 'eye',
});
- const noteTypesDoc = Cast(Doc.UserDoc()['template-notes'], Doc, null);
+ const noteTypesDoc = Cast(Doc.UserDoc().template_notes, Doc, null);
DocListCast(noteTypesDoc?.data).forEach(note => {
const icon: IconProp = StrCast(note.icon) as IconProp;
changeItems.push({
description: StrCast(note.title),
event: undoBatch(() => {
- this.layoutDoc.autoHeightMargins = undefined;
+ this.layoutDoc.layout_autoHeightMargins = undefined;
Doc.setNativeView(this.rootDoc);
DocUtils.makeCustomViewClicked(this.rootDoc, Docs.Create.TreeDocument, StrCast(note.title), note);
}),
@@ -799,11 +802,15 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
);
const uicontrols: ContextMenuProps[] = [];
- uicontrols.push({ description: !this.Document._noSidebar ? 'Hide Sidebar Handle' : 'Show Sidebar Handle', event: () => (this.layoutDoc._noSidebar = !this.layoutDoc._noSidebar), icon: !this.Document._noSidebar ? 'eye-slash' : 'eye' });
uicontrols.push({
- description: (this.Document._showAltContentUI ? 'Hide' : 'Show') + ' Alt Content UI',
- event: () => (this.layoutDoc._showAltContentUI = !this.layoutDoc._showAltContentUI),
- icon: !this.Document._showAltContentUI ? 'eye-slash' : 'eye',
+ description: !this.Document._layout_noSidebar ? 'Hide Sidebar Handle' : 'Show Sidebar Handle',
+ event: () => (this.layoutDoc._layout_noSidebar = !this.layoutDoc._layout_noSidebar),
+ icon: !this.Document._layout_noSidebar ? 'eye-slash' : 'eye',
+ });
+ uicontrols.push({
+ description: (this.Document._layout_altContentUI ? 'Hide' : 'Show') + ' Alt Content UI',
+ event: () => (this.layoutDoc._layout_altContentUI = !this.layoutDoc._layout_altContentUI),
+ icon: !this.Document._layout_altContentUI ? 'eye-slash' : 'eye',
});
uicontrols.push({ description: 'Show Highlights...', noexpand: true, subitems: highlighting, icon: 'hand-point-right' });
!Doc.noviceMode &&
@@ -834,10 +841,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
this.rootDoc.title = this.layoutDoc.isTemplateForField as string;
this.rootDoc.isTemplateDoc = false;
this.rootDoc.isTemplateForField = '';
- this.rootDoc.layoutKey = 'layout';
+ this.rootDoc.layout_fieldKey = 'layout';
MakeTemplate(this.rootDoc, true, title);
setTimeout(() => {
- this.rootDoc._autoHeight = this.layoutDoc._autoHeight; // autoHeight, width and height
+ 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);
@@ -845,7 +852,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
}, 10);
}
Doc.UserDoc().defaultTextLayout = new PrefetchProxy(this.rootDoc);
- Doc.AddDocToList(Cast(Doc.UserDoc()['template-notes'], Doc, null), 'data', this.rootDoc);
+ Doc.AddDocToList(Cast(Doc.UserDoc().template_notes, Doc, null), 'data', this.rootDoc);
},
icon: 'eye',
});
@@ -856,11 +863,16 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
optionItems.push({ description: `Generate Dall-E Image`, event: () => this.generateImage(), icon: 'star' });
optionItems.push({ description: `Ask GPT-3`, event: () => this.askGPT(), icon: 'lightbulb' });
optionItems.push({
- description: !this.Document._singleLine ? 'Create New Doc on Carriage Return' : 'Allow Carriage Returns',
- event: () => (this.layoutDoc._singleLine = !this.layoutDoc._singleLine),
- icon: !this.Document._singleLine ? 'grip-lines' : 'bars',
+ description: !this.Document._createDocOnCR ? 'Create New Doc on Carriage Return' : 'Allow Carriage Returns',
+ event: () => (this.layoutDoc._createDocOnCR = !this.layoutDoc._createDocOnCR),
+ icon: !this.Document._createDocOnCR ? 'grip-lines' : 'bars',
});
- !Doc.noviceMode && optionItems.push({ description: `${this.Document._autoHeight ? 'Lock' : 'Auto'} Height`, event: () => (this.layoutDoc._autoHeight = !this.layoutDoc._autoHeight), icon: this.Document._autoHeight ? 'lock' : 'unlock' });
+ !Doc.noviceMode &&
+ optionItems.push({
+ description: `${this.Document._layout_autoHeight ? 'Lock' : 'Auto'} Height`,
+ event: () => (this.layoutDoc._layout_autoHeight = !this.layoutDoc._layout_autoHeight),
+ icon: this.Document._layout_autoHeight ? 'lock' : 'unlock',
+ });
optionItems.push({ description: `show markdown options`, event: RTFMarkup.Instance.open, icon: 'text' });
!options && cm.addItem({ description: 'Options...', subitems: optionItems, icon: 'eye' });
this._downX = this._downY = Number.NaN;
@@ -900,8 +912,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
y: NumCast(this.rootDoc.y),
_height: 200,
_width: 200,
- 'data-nativeWidth': result.nativeWidth,
- 'data-nativeHeight': result.nativeHeight,
+ data_nativeWidth: result.nativeWidth,
+ data_nativeHeight: result.nativeHeight,
});
if (DocListCast(Doc.MyOverlayDocs?.data).includes(this.rootDoc)) {
newDoc.overlayX = this.rootDoc.x;
@@ -911,7 +923,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
this.props.addDocument?.(newDoc);
}
// Create link between prompt and image
- DocUtils.MakeLink(this.rootDoc, newDoc, { linkRelationship: 'Image Prompt' });
+ DocUtils.MakeLink(this.rootDoc, newDoc, { link_relationship: 'Image Prompt' });
}
} catch (err) {
console.log(err);
@@ -954,8 +966,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
const link = DocUtils.MakeLinkToActiveAudio(textanchorFunc, false).lastElement();
if (link) {
Doc.GetProto(link).isDictation = true;
- const audioanchor = Cast(link.anchor2, Doc, null);
- const textanchor = Cast(link.anchor1, Doc, null);
+ const audioanchor = Cast(link.link_anchor_2, Doc, null);
+ const textanchor = Cast(link.link_anchor_1, Doc, null);
if (audioanchor) {
audioanchor.backgroundColor = 'tan';
const audiotag = this._editorView.state.schema.nodes.audiotag.create({
@@ -1079,11 +1091,11 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
}
};
- // if the scroll height has changed and we're in autoHeight mode, then we need to update the textHeight component of the doc.
+ // if the scroll height has changed and we're in layout_autoHeight mode, then we need to update the textHeight component of the doc.
// 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.rootDoc[this.fieldKey + '_height'] = scrollHeight;
if (nh) this.layoutDoc._nativeHeight = scrollHeight;
};
@@ -1094,9 +1106,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
!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(() => DocumentManager.Instance.RecordingEvent, this.breakupDictation);
- this._disposers.autoHeight = reaction(
- () => this.autoHeight,
- autoHeight => autoHeight && this.tryUpdateScrollHeight()
+ this._disposers.layout_autoHeight = reaction(
+ () => this.layout_autoHeight,
+ layout_autoHeight => layout_autoHeight && this.tryUpdateScrollHeight()
);
this._disposers.highlights = reaction(
() => Array.from(FormattedTextBox._globalHighlights).slice(),
@@ -1108,16 +1120,16 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
width => this.tryUpdateScrollHeight()
);
this._disposers.scrollHeight = reaction(
- () => ({ scrollHeight: this.scrollHeight, autoHeight: this.autoHeight, width: NumCast(this.layoutDoc._width) }),
- ({ width, scrollHeight, autoHeight }) => width && autoHeight && this.resetNativeHeight(scrollHeight),
+ () => ({ scrollHeight: this.scrollHeight, layout_autoHeight: this.layout_autoHeight, width: NumCast(this.layoutDoc._width) }),
+ ({ width, scrollHeight, layout_autoHeight }) => width && layout_autoHeight && this.resetNativeHeight(scrollHeight),
{ fireImmediately: true }
);
this._disposers.componentHeights = reaction(
- // set the document height when one of the component heights changes and autoHeight is on
- () => ({ sidebarHeight: this.sidebarHeight, textHeight: this.textHeight, autoHeight: this.autoHeight, marginsHeight: this.autoHeightMargins }),
- ({ sidebarHeight, textHeight, autoHeight, marginsHeight }) => {
+ // set the document height when one of the component heights changes and layout_autoHeight is on
+ () => ({ sidebarHeight: this.sidebarHeight, textHeight: this.textHeight, layout_autoHeight: this.layout_autoHeight, marginsHeight: this.layout_autoHeightMargins }),
+ ({ sidebarHeight, textHeight, layout_autoHeight, marginsHeight }) => {
const newHeight = this.contentScaling * (marginsHeight + Math.max(sidebarHeight, textHeight));
- if (autoHeight && newHeight && newHeight !== this.rootDoc.height && !this.props.dontRegisterView) {
+ if (layout_autoHeight && newHeight && newHeight !== this.rootDoc.height && !this.props.dontRegisterView) {
this.props.setHeight?.(newHeight);
}
},
@@ -1142,7 +1154,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
this._disposers.editorState = reaction(
() => {
const dataDoc = Doc.IsDelegateField(DocCast(this.layoutDoc?.proto), this.fieldKey) ? DocCast(this.layoutDoc?.proto) : this?.dataDoc;
- const whichDoc = !this.dataDoc || !this.layoutDoc ? undefined : dataDoc?.[this.fieldKey + '-noTemplate'] || !this.layoutDoc[this.fieldKey] ? dataDoc : this.layoutDoc;
+ const whichDoc = !this.dataDoc || !this.layoutDoc ? undefined : dataDoc?.[this.fieldKey + '_noTemplate'] || !this.layoutDoc[this.fieldKey] ? dataDoc : this.layoutDoc;
return !whichDoc ? undefined : { data: Cast(whichDoc[this.fieldKey], RichTextField, null), str: Field.toString(whichDoc[this.fieldKey]) };
},
incomingValue => {
@@ -1220,7 +1232,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
}
var quickScroll: string | undefined = '';
this._disposers.scroll = reaction(
- () => NumCast(this.layoutDoc._scrollTop),
+ () => NumCast(this.layoutDoc._layout_scrollTop),
pos => {
if (!this._ignoreScroll && this._scrollRef.current && !this.props.dontSelectOnLoad) {
const viewTrans = quickScroll ?? StrCast(this.Document._viewTransition);
@@ -1297,7 +1309,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
}
}, 0);
dataDoc.title = exportState.title;
- this.dataDoc['title-custom'] = true;
+ this.dataDoc.title_custom = true;
dataDoc.googleDocUnchanged = true;
} else {
delete dataDoc[GoogleRef];
@@ -1354,7 +1366,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
view.state.schema.marks.linkAnchor.create({
allAnchors: [{ href: `/doc/${this.rootDoc[Id]}`, title: this.rootDoc.title, anchorId: `${this.rootDoc[Id]}` }],
location: 'add:right',
- title: `from: ${DocCast(pdfAnchor.context).title}`,
+ title: `from: ${DocCast(pdfAnchor.embedContainer).title}`,
noPreview: true,
docref: false,
}),
@@ -1363,7 +1375,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
]),
]);
- const link = DocUtils.MakeLink(pdfAnchor, this.rootDoc, { linkRelationship: 'PDF pasted' });
+ const link = DocUtils.MakeLink(pdfAnchor, this.rootDoc, { link_relationship: 'PDF pasted' });
if (link) {
view.dispatch(view.state.tr.replaceSelectionWith(dashField, false).scrollIntoView().setMeta('paste', true).setMeta('uiEvent', 'paste'));
}
@@ -1451,7 +1463,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
if (startupText) {
dispatch(state.tr.insertText(startupText));
}
- const textAlign = StrCast(this.dataDoc['text-align'], StrCast(Doc.UserDoc().textAlign, 'left'));
+ const textAlign = StrCast(this.dataDoc.text_align, StrCast(Doc.UserDoc().textAlign, 'left'));
if (textAlign !== 'left') {
selectAll(this._editorView.state, tr => {
this._editorView!.dispatch(tr.replaceSelectionWith(state.schema.nodes.paragraph.create({ align: textAlign })));
@@ -1524,7 +1536,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
} else (e.nativeEvent as any).handledByInnerReactInstance = true;
if (this.Document.forceActive) e.stopPropagation();
- this.tryUpdateScrollHeight(); // if a doc a fitWidth doc is being viewed in different context (eg freeform & lightbox), then it will have conflicting heights. so when the doc is clicked on, we want to make sure it has the appropriate height for the selected view.
+ this.tryUpdateScrollHeight(); // if a doc a fitWidth doc is being viewed in different embedContainer (eg freeform & lightbox), then it will have conflicting heights. so when the doc is clicked on, we want to make sure it has the appropriate height for the selected view.
if ((e.target as any).tagName === 'AUDIOTAG') {
e.preventDefault();
e.stopPropagation();
@@ -1575,7 +1587,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
if (!state.selection.empty && !(state.selection instanceof NodeSelection)) this.setupAnchorMenu();
else if (this.props.isContentActive(true)) {
const pcords = editor.posAtCoords({ left: e.clientX, top: e.clientY });
- !this.props.isSelected(true) && editor.dispatch(state.tr.setSelection(new TextSelection(state.doc.resolve(pcords?.pos || 0))));
+ // !this.props.isSelected(true) &&
+ editor.dispatch(state.tr.setSelection(new TextSelection(state.doc.resolve(pcords?.pos || 0))));
let target = e.target as any; // hrefs are stored on the dataset of the <a> node that wraps the hyerlink <span>
while (target && !target.dataset?.targethrefs) target = target.parentElement;
FormattedTextBoxComment.update(this, editor, undefined, target?.dataset?.targethrefs, target?.dataset.linkdoc, target?.dataset.nopreview === 'true');
@@ -1726,7 +1739,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
setTimeout(
() =>
translateGoogleApi(result1[0], { from: 'es', to: 'en' }).then((result: any) => {
- this.dataDoc[this.fieldKey + '-translation'] = result1 + '\r\n\r\n' + result[0];
+ this.dataDoc[this.fieldKey + '_translation'] = result1 + '\r\n\r\n' + result[0];
}),
1000
);
@@ -1736,10 +1749,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
}
this._lastText = curText;
}
- if (StrCast(this.rootDoc.title).startsWith('@') && !this.dataDoc['title-custom']) {
+ if (StrCast(this.rootDoc.title).startsWith('@') && !this.dataDoc.title_custom) {
UndoManager.RunInBatch(() => {
- this.dataDoc['title-custom'] = true;
- this.dataDoc.showTitle = 'title';
+ 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());
}, 'titler');
@@ -1799,7 +1812,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
if (!LinkDocPreview.LinkInfo && this._scrollRef.current) {
if (!this.props.dontSelectOnLoad) {
this._ignoreScroll = true;
- this.layoutDoc._scrollTop = this._scrollRef.current.scrollTop;
+ this.layoutDoc._layout_scrollTop = this._scrollRef.current.scrollTop;
this._ignoreScroll = false;
e.stopPropagation();
e.preventDefault();
@@ -1810,13 +1823,16 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
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) {
- const proseHeight = !this.ProseRef
- ? 0
- : children.reduce((p, child) => p + Number(getComputedStyle(child).height.replace('px', '')) + Number(getComputedStyle(child).marginTop.replace('px', '')) + Number(getComputedStyle(child).marginBottom.replace('px', '')), margins);
+ const toNum = (val: string) => Number(val.replace('px', '').replace('auto', '0'));
+ const toHgt = (node: Element) => {
+ const { height, marginTop, marginBottom } = getComputedStyle(node);
+ return toNum(height) + Math.max(0, toNum(marginTop)) + Math.max(0, toNum(marginBottom));
+ };
+ const proseHeight = !this.ProseRef ? 0 : children.reduce((p, child) => p + toHgt(child), margins);
const scrollHeight = this.ProseRef && Math.min(NumCast(this.layoutDoc.docMaxAutoHeight, proseHeight), proseHeight);
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.rootDoc[this.fieldKey + '_scrollHeight'] = scrollHeight);
if (this.rootDoc === this.layoutDoc || this.layoutDoc.resolvedDataDoc) {
setScrollHeight();
} else {
@@ -1825,21 +1841,21 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
}
}
};
- fitContentsToBox = () => BoolCast(this.props.Document._fitContentsToBox);
- sidebarContentScaling = () => (this.props.NativeDimScaling?.() || 1) * NumCast(this.layoutDoc._viewScale, 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._showSidebar) this.toggleSidebar();
+ 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.sidebarWidthPercent.substring(0, this.sidebarWidthPercent.length - 1)) / 100) * this.props.PanelWidth();
+ 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();
sidebarScreenToLocal = () =>
this.props
.ScreenToLocalTransform()
.translate(-(this.props.PanelWidth() - this.sidebarWidth()) / (this.props.NativeDimScaling?.() || 1), 0)
- .scale(1 / NumCast(this.layoutDoc._viewScale, 1) / (this.props.NativeDimScaling?.() || 1));
+ .scale(1 / NumCast(this.layoutDoc._freeform_scale, 1) / (this.props.NativeDimScaling?.() || 1));
@computed get audioHandle() {
return !this._recording ? null : (
@@ -1873,7 +1889,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
color,
opacity: annotated ? 1 : undefined,
}}>
- <FontAwesomeIcon icon={'comment-alt'} />
+ <FontAwesomeIcon icon="comment-alt" />
</div>
);
}
@@ -1925,25 +1941,25 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
fitContentsToBox={this.fitContentsToBox}
noSidebar={true}
treeViewHideTitle={true}
- fieldKey={this.layoutDoc.sidebarViewType === 'translation' ? `${this.fieldKey}-translation` : `${this.fieldKey}-sidebar`}
+ fieldKey={this.layoutDoc.sidebarViewType === 'translation' ? `${this.fieldKey}_translation` : `${this.fieldKey}_sidebar`}
/>
</div>
);
};
return (
- <div className={'formattedTextBox-sidebar' + (Doc.ActiveTool !== InkTool.None ? '-inking' : '')} style={{ width: `${this.sidebarWidthPercent}`, backgroundColor: `${this.sidebarColor}` }}>
+ <div className={'formattedTextBox-sidebar' + (Doc.ActiveTool !== InkTool.None ? '-inking' : '')} style={{ width: `${this.layout_sidebarWidthPercent}`, backgroundColor: `${this.sidebarColor}` }}>
{renderComponent(StrCast(this.layoutDoc.sidebarViewType))}
</div>
);
}
cycleAlternateText = () => {
- if (this.layoutDoc._showAltContentUI) {
- const usePath = this.rootDoc[`${this.props.fieldKey}-usePath`];
- this.rootDoc[`_${this.props.fieldKey}-usePath`] = usePath === undefined ? 'alternate' : usePath === 'alternate' ? 'alternate:hover' : undefined;
+ if (this.layoutDoc._layout_altContentUI) {
+ const usePath = this.rootDoc[`${this.props.fieldKey}_usePath`];
+ this.rootDoc[`_${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.rootDoc[`${this.props.fieldKey}_usePath`];
return (
<Tooltip
title={
@@ -1975,23 +1991,23 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
);
}
@computed get fieldKey() {
- const usePath = StrCast(this.rootDoc[`${this.props.fieldKey}-usePath`]);
- return this.props.fieldKey + (usePath && (!usePath.includes(':hover') || this._isHovering) ? `-${usePath.replace(':hover', '')}` : '');
+ const usePath = StrCast(this.rootDoc[`${this.props.fieldKey}_usePath`]);
+ return this.props.fieldKey + (usePath && (!usePath.includes(':hover') || this._isHovering) ? `_${usePath.replace(':hover', '')}` : '');
}
@observable _isHovering = false;
render() {
TraceMobx();
const active = this.props.isContentActive() || this.props.isSelected();
const selected = active;
- const scale = (this.props.NativeDimScaling?.() || 1) * NumCast(this.layoutDoc._viewScale, 1);
+ const scale = (this.props.NativeDimScaling?.() || 1) * NumCast(this.layoutDoc._freeform_scale, 1);
const rounded = StrCast(this.layoutDoc.borderRounding) === '100%' ? '-rounded' : '';
const interactive = (Doc.ActiveTool === InkTool.None || SnappingManager.GetIsDragging()) && (this.layoutDoc.z || !this.layoutDoc._lockedPosition);
if (!selected && FormattedTextBoxComment.textBox === this) setTimeout(FormattedTextBoxComment.Hide);
const minimal = this.props.ignoreAutoHeight;
const paddingX = NumCast(this.layoutDoc._xMargin, this.props.xPadding || 0);
const paddingY = NumCast(this.layoutDoc._yMargin, this.props.yPadding || 0);
- const selPad = (selected && !this.layoutDoc._singleLine) || minimal ? Math.min(paddingY, Math.min(paddingX, 10)) : 0;
- const selPaddingClass = selected && !this.layoutDoc._singleLine && paddingY >= 10 ? '-selected' : '';
+ const selPad = (selected && !this.layoutDoc._createDocOnCR) || minimal ? Math.min(paddingY, Math.min(paddingX, 10)) : 0;
+ const selPaddingClass = selected && !this.layoutDoc._createDocOnCR && paddingY >= 10 ? '-selected' : '';
const styleFromLayoutString = Doc.styleFromLayoutString(this.rootDoc, this.layoutDoc, 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
@@ -2002,8 +2018,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
r?.addEventListener(
'wheel', // 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)
(e: WheelEvent) => {
- if (this.props.isContentActive()) {
- if (!NumCast(this.layoutDoc._scrollTop) && e.deltaY <= 0) e.preventDefault();
+ if (this.props.isContentActive() && !this.props.allowScroll) {
+ if (!NumCast(this.layoutDoc._layout_scrollTop) && e.deltaY <= 0) e.preventDefault();
e.stopPropagation();
}
},
@@ -2021,7 +2037,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
}),
display: !SnappingManager.GetIsDragging() && this.props.thumbShown?.() ? 'none' : undefined,
transition: 'inherit',
- // overflowY: this.layoutDoc._autoHeight ? "hidden" : undefined,
+ // overflowY: this.layoutDoc._layout_autoHeight ? "hidden" : undefined,
color: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.Color),
fontSize: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.FontSize),
fontFamily: this.props.styleProvider?.(this.layoutDoc, this.props, StyleProp.FontFamily),
@@ -2032,8 +2048,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
className="formattedTextBox-cont"
ref={this._ref}
style={{
- overflow: this.autoHeight && this.props.CollectionFreeFormDocumentView?.() ? 'hidden' : undefined, //x this breaks viewing an autoHeight doc in its own tab, or in the lightbox
- height: this.props.height || (this.autoHeight && this.props.renderDepth && !this.props.suppressSetHeight ? 'max-content' : undefined),
+ overflow: this.layout_autoHeight && this.props.CollectionFreeFormDocumentView?.() ? 'hidden' : undefined, //x this breaks viewing an layout_autoHeight doc in its own tab, or in the lightbox
+ height: this.props.height || (this.layout_autoHeight && this.props.renderDepth && !this.props.suppressSetHeight ? 'max-content' : undefined),
pointerEvents: interactive ? undefined : 'none',
}}
onContextMenu={this.specificContextMenu}
@@ -2049,9 +2065,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
className={`formattedTextBox-outer${selected ? '-selected' : ''}`}
ref={this._scrollRef}
style={{
- width: this.props.dontSelectOnLoad ? '100%' : `calc(100% - ${this.sidebarWidthPercent})`,
+ width: this.props.dontSelectOnLoad ? '100%' : `calc(100% - ${this.layout_sidebarWidthPercent})`,
pointerEvents: !active && !SnappingManager.GetIsDragging() ? 'none' : undefined,
- overflow: this.layoutDoc._singleLine ? 'hidden' : this.layoutDoc._autoHeight ? 'visible' : undefined,
+ overflow: this.layoutDoc._createDocOnCR ? 'hidden' : this.layoutDoc._layout_autoHeight ? 'visible' : undefined,
}}
onScroll={this.onScroll}
onDrop={this.ondrop}>
@@ -2068,10 +2084,10 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
}}
/>
</div>
- {this.noSidebar || this.props.dontSelectOnLoad || !this.SidebarShown || this.sidebarWidthPercent === '0%' ? null : this.sidebarCollection}
- {this.noSidebar || this.Document._noSidebar || this.props.dontSelectOnLoad || this.Document._singleLine ? 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 ? null : this.sidebarHandle}
{this.audioHandle}
- {this.layoutDoc._showAltContentUI ? this.overlayAlternateIcon : null}
+ {this.layoutDoc._layout_altContentUI ? this.overlayAlternateIcon : null}
</div>
</div>
);
diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx
index f0caa1f4f..5e0041b84 100644
--- a/src/client/views/nodes/formattedText/RichTextMenu.tsx
+++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx
@@ -623,15 +623,15 @@ export class RichTextMenu extends AntimodeMenu<AntimodeMenuProps> {
if (linkclicked) {
const linkDoc = await DocServer.GetRefField(linkclicked);
if (linkDoc instanceof Doc) {
- const anchor1 = await Cast(linkDoc.anchor1, Doc);
- const anchor2 = await Cast(linkDoc.anchor2, Doc);
+ const link_anchor_1 = await Cast(linkDoc.link_anchor_1, Doc);
+ const link_anchor_2 = await Cast(linkDoc.link_anchor_2, Doc);
const currentDoc = SelectionManager.Docs().lastElement();
- if (currentDoc && anchor1 && anchor2) {
- if (Doc.AreProtosEqual(currentDoc, anchor1)) {
- return StrCast(anchor2.title);
+ if (currentDoc && link_anchor_1 && link_anchor_2) {
+ if (Doc.AreProtosEqual(currentDoc, link_anchor_1)) {
+ return StrCast(link_anchor_2.title);
}
- if (Doc.AreProtosEqual(currentDoc, anchor2)) {
- return StrCast(anchor1.title);
+ if (Doc.AreProtosEqual(currentDoc, link_anchor_2)) {
+ return StrCast(link_anchor_1.title);
}
}
}
diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts
index cad56b14b..104aed058 100644
--- a/src/client/views/nodes/formattedText/RichTextRules.ts
+++ b/src/client/views/nodes/formattedText/RichTextRules.ts
@@ -81,9 +81,9 @@ export class RichTextRules {
textDoc.inlineTextCount = numInlines + 1;
const inlineFieldKey = 'inline' + numInlines; // which field on the text document this annotation will write to
const inlineLayoutKey = 'layout_' + inlineFieldKey; // the field holding the layout string that will render the inline annotation
- const textDocInline = Docs.Create.TextDocument('', { _layoutKey: inlineLayoutKey, _width: 75, _height: 35, annotationOn: textDoc, _fitWidth: true, _autoHeight: true, _fontSize: '9px', title: 'inline comment' });
+ const textDocInline = Docs.Create.TextDocument('', { _layout_fieldKey: inlineLayoutKey, _width: 75, _height: 35, annotationOn: textDoc, _layout_fitWidth: true, _layout_autoHeight: true, _fontSize: '9px', title: 'inline comment' });
textDocInline.title = inlineFieldKey; // give the annotation its own title
- textDocInline['title-custom'] = true; // And make sure that it's 'custom' so that editing text doesn't change the title of the containing doc
+ textDocInline.title_custom = true; // And make sure that it's 'custom' so that editing text doesn't change the title of the containing doc
textDocInline.isTemplateForField = inlineFieldKey; // this is needed in case the containing text doc is converted to a template at some point
textDocInline.proto = textDoc; // make the annotation inherit from the outer text doc so that it can resolve any nested field references, e.g., [[field]]
textDocInline._textContext = ComputedField.MakeFunction(`copyField(self.${inlineFieldKey})`);
@@ -249,7 +249,7 @@ export class RichTextRules {
this.TextBox.EditorView?.dispatch(rstate.tr.setSelection(new TextSelection(rstate.doc.resolve(start), rstate.doc.resolve(end - 3))));
}
- DocUtils.MakeLink(this.TextBox.getAnchor(true), target, { linkRelationship: 'portal to:portal from' });
+ DocUtils.MakeLink(this.TextBox.getAnchor(true), target, { link_relationship: 'portal to:portal from' });
const fstate = this.TextBox.EditorView?.state;
if (fstate && selection) {
@@ -299,28 +299,6 @@ export class RichTextRules {
return tr.setSelection(new NodeSelection(tr.doc.resolve(tr.selection.$from.pos - 1)));
}),
- // create an inline view of a document {{ <layoutKey> : <Doc> }}
- // {{:Doc}} => show default view of document
- // {{<layout>}} => show layout for this doc
- // {{<layout> : Doc}} => show layout for another doc
- new InputRule(new RegExp(/\{\{([a-zA-Z_ \-0-9]*)(\([a-zA-Z0-9…._/\-]*\))?(:[a-zA-Z_@\.\? \-0-9]+)?\}\}$/), (state, match, start, end) => {
- const fieldKey = match[1] || '';
- const fieldParam = match[2]?.replace('…', '...') || '';
- const rawdocid = match[3]?.substring(1);
- const docId = rawdocid ? (!rawdocid.includes('@') ? normalizeEmail(Doc.CurrentUserEmail) + '@' + rawdocid : rawdocid) : undefined;
- if (!fieldKey && !docId) return state.tr;
- docId &&
- DocServer.GetRefField(docId).then(docx => {
- if (!(docx instanceof Doc && docx)) {
- Docs.Create.FreeformDocument([], { title: rawdocid, _width: 500, _height: 500 }, docId);
- }
- });
- const node = (state.doc.resolve(start) as any).nodeAfter;
- const dashDoc = schema.nodes.dashDoc.create({ width: 75, height: 75, title: 'dashDoc', docId, fieldKey: fieldKey + fieldParam, float: 'unset', alias: Utils.GenerateGuid() });
- const sm = state.storedMarks || undefined;
- return node ? state.tr.replaceRangeWith(start, end, dashDoc).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : state.tr;
- }),
-
// create an inline view of a tag stored under the '#' field
new InputRule(new RegExp(/#([a-zA-Z_\-]+[a-zA-Z_\-0-9]*)\s$/), (state, match, start, end) => {
const tag = match[1];
diff --git a/src/client/views/nodes/formattedText/marks_rts.ts b/src/client/views/nodes/formattedText/marks_rts.ts
index 5b47e8a70..7e17008bb 100644
--- a/src/client/views/nodes/formattedText/marks_rts.ts
+++ b/src/client/views/nodes/formattedText/marks_rts.ts
@@ -46,7 +46,7 @@ export const marks: { [index: string]: MarkSpec } = {
toDOM(node: any) {
const targethrefs = node.attrs.allAnchors.reduce((p: string, item: { href: string; title: string; anchorId: string }) => (p ? p + ' ' + item.href : item.href), '');
const anchorids = node.attrs.allAnchors.reduce((p: string, item: { href: string; title: string; anchorId: string }) => (p ? p + ' ' + item.anchorId : item.anchorId), '');
- return ['a', { class: anchorids, 'data-targethrefs': targethrefs, 'data-linkdoc': node.attrs.linkDoc, title: node.attrs.title, location: node.attrs.location, style: `background: lightBlue` }, 0];
+ return ['a', { class: anchorids, 'data-targethrefs': targethrefs, 'data-noPreview': 'true', 'data-linkdoc': node.attrs.linkDoc, title: node.attrs.title, location: node.attrs.location, style: `background: lightBlue` }, 0];
},
},
noAutoLinkAnchor: {
diff --git a/src/client/views/nodes/formattedText/nodes_rts.ts b/src/client/views/nodes/formattedText/nodes_rts.ts
index 6c9d5d31a..f27fb18e2 100644
--- a/src/client/views/nodes/formattedText/nodes_rts.ts
+++ b/src/client/views/nodes/formattedText/nodes_rts.ts
@@ -247,7 +247,7 @@ export const nodes: { [index: string]: NodeSpec } = {
hidden: { default: false }, // whether dashComment node has toggle the dashDoc's display off
fieldKey: { default: '' },
docId: { default: '' },
- alias: { default: '' },
+ embedding: { default: '' },
},
group: 'inline',
draggable: false,
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index bd2be8f11..858d83b7a 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -5,7 +5,7 @@ import { action, computed, IReactionDisposer, observable, ObservableSet, reactio
import { observer } from 'mobx-react';
import { AnimationSym, Doc, DocListCast, Field, FieldResult, Opt, StrListCast } from '../../../../fields/Doc';
import { Copy, Id } from '../../../../fields/FieldSymbols';
-import { InkField, InkTool } from '../../../../fields/InkField';
+import { InkField } from '../../../../fields/InkField';
import { List } from '../../../../fields/List';
import { ObjectField } from '../../../../fields/ObjectField';
import { listSpec } from '../../../../fields/Schema';
@@ -273,7 +273,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
progressivizedItems = (doc: Doc) => {
const targetList = PresBox.targetRenderedDoc(doc);
if (doc.presIndexed !== undefined && targetList) {
- const listItems = (Cast(targetList[Doc.LayoutFieldKey(targetList)], listSpec(Doc), null)?.filter(d => d instanceof Doc) as Doc[]) ?? DocListCast(targetList[Doc.LayoutFieldKey(targetList) + '-annotations']);
+ const listItems = (Cast(targetList[Doc.LayoutFieldKey(targetList)], listSpec(Doc), null)?.filter(d => d instanceof Doc) as Doc[]) ?? DocListCast(targetList[Doc.LayoutFieldKey(targetList) + '_annotations']);
return listItems.filter(doc => !doc.unrendered);
}
};
@@ -419,7 +419,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const activeFrame = activeItem.presActiveFrame ?? activeItem.presCurrentFrame;
if (activeFrame !== undefined) {
const transTime = NumCast(activeItem.presTransition, 500);
- const acontext = activeItem.presActiveFrame !== undefined ? DocCast(DocCast(activeItem.presentationTargetDoc).context) : DocCast(activeItem.presentationTargetDoc);
+ const acontext = activeItem.presActiveFrame !== undefined ? DocCast(DocCast(activeItem.presentationTargetDoc).embedContainer) : DocCast(activeItem.presentationTargetDoc);
const context = DocCast(acontext)?.annotationOn ? DocCast(DocCast(acontext).annotationOn) : acontext;
if (context) {
const ffview = DocumentManager.Instance.getFirstDocumentView(context)?.props.CollectionFreeFormDocumentView?.().props.CollectionFreeFormView;
@@ -429,6 +429,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
}
}
+ if ((pinDataTypes?.dataview && activeItem.presData !== undefined) || (!pinDataTypes && activeItem.presData !== undefined)) {
+ bestTarget._dataTransition = `all ${transTime}ms`;
+ const fkey = Doc.LayoutFieldKey(bestTarget);
+ const setData = bestTargetView?.ComponentView?.setData;
+ if (setData) setData(activeItem.presData);
+ else Doc.GetProto(bestTarget)[fkey] = activeItem.presData instanceof ObjectField ? activeItem.presData[Copy]() : activeItem.presData;
+ bestTarget[fkey + '_usePath'] = activeItem.presUsePath;
+ setTimeout(() => (bestTarget._dataTransition = undefined), transTime + 10);
+ }
if (pinDataTypes?.datarange || (!pinDataTypes && activeItem.presXRange !== undefined)) {
if (bestTarget.xRange !== activeItem.presXRange) {
bestTarget.xRange = (activeItem.presXRange as ObjectField)?.[Copy]();
@@ -440,14 +449,15 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
}
if (pinDataTypes?.clippable || (!pinDataTypes && activeItem.presClipWidth !== undefined)) {
- if (bestTarget._clipWidth !== activeItem.presClipWidth) {
- bestTarget._clipWidth = activeItem.presClipWidth;
+ const fkey = '_' + Doc.LayoutFieldKey(bestTarget);
+ if (bestTarget[fkey + '_clipWidth'] !== activeItem.presClipWidth) {
+ bestTarget[fkey + '_clipWidth'] = activeItem.presClipWidth;
changed = true;
}
}
if (pinDataTypes?.temporal || (!pinDataTypes && activeItem.presStartTime !== undefined)) {
- if (bestTarget._currentTimecode !== activeItem.presStartTime) {
- bestTarget._currentTimecode = activeItem.presStartTime;
+ if (bestTarget._layout_currentTimecode !== activeItem.presStartTime) {
+ bestTarget._layout_currentTimecode = activeItem.presStartTime;
changed = true;
}
}
@@ -495,8 +505,8 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
if (pinDataTypes?.scrollable || (!pinDataTypes && activeItem.presViewScroll !== undefined)) {
- if (bestTarget._scrollTop !== activeItem.presViewScroll) {
- bestTarget._scrollTop = activeItem.presViewScroll;
+ if (bestTarget._layout_scrollTop !== activeItem.presViewScroll) {
+ bestTarget._layout_scrollTop = activeItem.presViewScroll;
changed = true;
const contentBounds = Cast(activeItem.presPinViewBounds, listSpec('number'));
if (contentBounds) {
@@ -507,26 +517,19 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
if (pinDataTypes?.dataannos || (!pinDataTypes && activeItem.presAnnotations !== undefined)) {
const fkey = Doc.LayoutFieldKey(bestTarget);
- const oldItems = DocListCast(bestTarget[fkey + '-annotations']).filter(doc => doc.unrendered);
+ const oldItems = DocListCast(bestTarget[fkey + '_annotations']).filter(doc => doc.unrendered);
const newItems = DocListCast(activeItem.presAnnotations).map(doc => {
doc.hidden = false;
return doc;
});
- const hiddenItems = DocListCast(bestTarget[fkey + '-annotations'])
+ const hiddenItems = DocListCast(bestTarget[fkey + '_annotations'])
.filter(doc => !doc.unrendered && !newItems.includes(doc))
.map(doc => {
doc.hidden = true;
return doc;
});
const newList = new List<Doc>([...oldItems, ...hiddenItems, ...newItems]);
- Doc.GetProto(bestTarget)[fkey + '-annotations'] = newList;
- }
- if ((pinDataTypes?.dataview && activeItem.presData !== undefined) || (!pinDataTypes && activeItem.presData !== undefined)) {
- bestTarget._dataTransition = `all ${transTime}ms`;
- const fkey = Doc.LayoutFieldKey(bestTarget);
- Doc.GetProto(bestTarget)[fkey] = activeItem.presData instanceof ObjectField ? activeItem.presData[Copy]() : activeItem.presData;
- bestTarget[fkey + '-usePath'] = activeItem.presUsePath;
- setTimeout(() => (bestTarget._dataTransition = undefined), transTime + 10);
+ Doc.GetProto(bestTarget)[fkey + '_annotations'] = newList;
}
if (pinDataTypes?.poslayoutview || (!pinDataTypes && activeItem.presPinLayoutData !== undefined)) {
changed = true;
@@ -558,20 +561,20 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const contentBounds = Cast(activeItem.presPinViewBounds, listSpec('number'));
if (contentBounds) {
const viewport = { panX: (contentBounds[0] + contentBounds[2]) / 2, panY: (contentBounds[1] + contentBounds[3]) / 2, width: contentBounds[2] - contentBounds[0], height: contentBounds[3] - contentBounds[1] };
- bestTarget._panX = viewport.panX;
- bestTarget._panY = viewport.panY;
+ bestTarget._freeform_panX = viewport.panX;
+ bestTarget._freeform_panY = viewport.panY;
const dv = DocumentManager.Instance.getDocumentView(bestTarget);
if (dv) {
changed = true;
const computedScale = NumCast(activeItem.presZoom, 1) * Math.min(dv.props.PanelWidth() / viewport.width, dv.props.PanelHeight() / viewport.height);
- activeItem.presMovement === PresMovement.Zoom && (bestTarget._viewScale = computedScale);
+ activeItem.presMovement === PresMovement.Zoom && (bestTarget._freeform_scale = computedScale);
dv.ComponentView?.brushView?.(viewport);
}
} else {
- if (bestTarget._panX !== activeItem.presPanX || bestTarget._panY !== activeItem.presPanY || bestTarget._viewScale !== activeItem.presViewScale) {
- bestTarget._panX = activeItem.presPanX ?? bestTarget._panX;
- bestTarget._panY = activeItem.presPanY ?? bestTarget._panY;
- bestTarget._viewScale = activeItem.presViewScale ?? bestTarget._viewScale;
+ if (bestTarget._freeform_panX !== activeItem.presPanX || bestTarget._freeform_panY !== activeItem.presPanY || bestTarget._freeform_scale !== activeItem.presViewScale) {
+ bestTarget._freeform_panX = activeItem.presPanX ?? bestTarget._freeform_panX;
+ bestTarget._freeform_panY = activeItem.presPanY ?? bestTarget._freeform_panY;
+ bestTarget._freeform_scale = activeItem.presViewScale ?? bestTarget._freeform_scale;
changed = true;
}
}
@@ -608,12 +611,12 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
pinProps?.activeFrame !== undefined;
const fkey = Doc.LayoutFieldKey(targetDoc);
if (pinProps.pinData.dataview) {
- pinDoc.presUsePath = targetDoc[fkey + '-usePath'];
+ pinDoc.presUsePath = targetDoc[fkey + '_usePath'];
pinDoc.presData = targetDoc[fkey] instanceof ObjectField ? (targetDoc[fkey] as ObjectField)[Copy]() : targetDoc.data;
}
if (pinProps.pinData.dataannos) {
const fkey = Doc.LayoutFieldKey(targetDoc);
- pinDoc.presAnnotations = new List<Doc>(DocListCast(Doc.GetProto(targetDoc)[fkey + '-annotations']).filter(doc => !doc.unrendered));
+ pinDoc.presAnnotations = new List<Doc>(DocListCast(Doc.GetProto(targetDoc)[fkey + '_annotations']).filter(doc => !doc.unrendered));
}
if (pinProps.pinData.inkable) {
pinDoc.presFillColor = targetDoc.fillColor;
@@ -621,8 +624,11 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
pinDoc.presWidth = targetDoc._width;
pinDoc.presHeight = targetDoc._height;
}
- if (pinProps.pinData.scrollable) pinDoc.presViewScroll = targetDoc._scrollTop;
- if (pinProps.pinData.clippable) pinDoc.presClipWidth = targetDoc._clipWidth;
+ if (pinProps.pinData.scrollable) pinDoc.presViewScroll = targetDoc._layout_scrollTop;
+ if (pinProps.pinData.clippable) {
+ const fkey = Doc.LayoutFieldKey(targetDoc);
+ pinDoc.presClipWidth = targetDoc[fkey + '_clipWidth'];
+ }
if (pinProps.pinData.datarange) {
pinDoc.presXRange = undefined; //targetDoc?.xrange;
pinDoc.presYRange = undefined; //targetDoc?.yrange;
@@ -647,13 +653,13 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
if (pinProps.pinData.filters) pinDoc.presDocFilters = ObjectField.MakeCopy(targetDoc.docFilters as ObjectField);
if (pinProps.pinData.pivot) pinDoc.presPivotField = targetDoc._pivotField;
if (pinProps.pinData.pannable) {
- pinDoc.presPanX = NumCast(targetDoc._panX);
- pinDoc.presPanY = NumCast(targetDoc._panY);
- pinDoc.presViewScale = NumCast(targetDoc._viewScale, 1);
+ pinDoc.presPanX = NumCast(targetDoc._freeform_panX);
+ pinDoc.presPanY = NumCast(targetDoc._freeform_panY);
+ pinDoc.presViewScale = NumCast(targetDoc._freeform_scale, 1);
}
if (pinProps.pinData.temporal) {
- pinDoc.presStartTime = targetDoc._currentTimecode;
- const duration = NumCast(pinDoc[`${Doc.LayoutFieldKey(pinDoc)}-duration`], NumCast(targetDoc.presStartTime) + 0.1);
+ pinDoc.presStartTime = targetDoc._layout_currentTimecode;
+ const duration = NumCast(pinDoc[`${Doc.LayoutFieldKey(pinDoc)}_duration`], NumCast(targetDoc.presStartTime) + 0.1);
pinDoc.presEndTime = NumCast(targetDoc.clipEnd, duration);
}
}
@@ -661,7 +667,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
// If pinWithView option set then update scale and x / y props of slide
const bounds = pinProps.pinViewport;
pinDoc.presPinView = true;
- pinDoc.presViewScale = NumCast(targetDoc._viewScale, 1);
+ pinDoc.presViewScale = NumCast(targetDoc._freeform_scale, 1);
pinDoc.presPanX = bounds.left + bounds.width / 2;
pinDoc.presPanY = bounds.top + bounds.height / 2;
pinDoc.presPinViewBounds = new List<number>([bounds.left, bounds.top, bounds.left + bounds.width, bounds.top + bounds.height]);
@@ -791,7 +797,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const savedStates = docs.map(doc => {
switch (doc.type) {
case DocumentType.COL:
- if (doc._viewType === CollectionViewType.Freeform) return { type: CollectionViewType.Freeform, doc, x: NumCast(doc.panX), y: NumCast(doc.panY), s: NumCast(doc.viewScale) };
+ if (doc._viewType === CollectionViewType.Freeform) return { type: CollectionViewType.Freeform, doc, x: NumCast(doc.freeform_panX), y: NumCast(doc.freeform_panY), s: NumCast(doc.freeform_scale) };
break;
case DocumentType.INK:
if (doc.data instanceof InkField) {
@@ -811,7 +817,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const { x, y, s, doc } = savedState!;
doc._panX = x;
doc._panY = y;
- doc._viewScale = s;
+ doc._freeform_scale = s;
}
break;
case DocumentType.INK:
@@ -1006,17 +1012,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
return false;
}
} else {
- if (!doc.aliasOf) {
- const original = Doc.MakeAlias(doc);
- TabDocView.PinDoc(original, {});
- setTimeout(() => this.removeDocument(doc), 0);
- return false;
- } else {
- if (!doc.presentationTargetDoc) doc.title = doc.title + ' - Slide';
- doc.aliasOf instanceof Doc && (doc.presentationTargetDoc = doc.aliasOf);
- doc.presMovement = PresMovement.Zoom;
- if (this._expandBoolean) doc.presExpandInlineButton = true;
- }
+ if (!doc.presentationTargetDoc) doc.title = doc.title + ' - Slide';
+ doc.presentationTargetDoc = doc.createdFrom; // dropped document will be a new embedding of an embedded document somewhere else.
+ doc.presMovement = PresMovement.Zoom;
+ if (this._expandBoolean) doc.presExpandInlineButton = true;
}
});
return true;
@@ -1084,7 +1083,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
this.rootDoc._itemIndex = index;
}
} else this.gotoDocument(this.childDocs.indexOf(doc), this.activeItem);
- this.updateCurrentPresentation(DocCast(doc.context));
+ this.updateCurrentPresentation(DocCast(doc.embedContainer));
};
//Command click
@@ -1238,7 +1237,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
.filter(doc => Cast(doc.presentationTargetDoc, Doc, null))
.forEach((doc, index) => {
const tagDoc = Cast(doc.presentationTargetDoc, Doc, null);
- const srcContext = Cast(tagDoc.context, Doc, null);
+ const srcContext = Cast(tagDoc.embedContainer, Doc, null);
const width = NumCast(tagDoc._width) / 10;
const height = Math.max(NumCast(tagDoc._height) / 10, 15);
const edge = Math.max(width, height);
@@ -1298,7 +1297,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
/**
* Method called for viewing paths which adds a single line with
* points at the center of each document added.
- * Design choice: When this is called it sets _fitContentsToBox as true so the
+ * Design choice: When this is called it sets _freeform_fitContentsToBox as true so the
* user can have an overview of all of the documents in the collection.
* (Design needed for when documents in presentation trail are in another
* collection)
@@ -1551,7 +1550,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
// a progressivized slide doesn't have sub-slides, but rather iterates over the data list of the target being progressivized.
// to avoid creating a new slide to correspond to each of the target's data list, we create a computedField to refernce the target's data list.
let dataField = Doc.LayoutFieldKey(tagDoc);
- if (Cast(tagDoc[dataField], listSpec(Doc), null)?.filter(d => d instanceof Doc) === undefined) dataField = dataField + '-annotations';
+ if (Cast(tagDoc[dataField], listSpec(Doc), null)?.filter(d => d instanceof Doc) === undefined) dataField = dataField + '_annotations';
if (DocCast(activeItem.presentationTargetDoc).annotationOn) activeItem.data = ComputedField.MakeFunction(`self.presentationTargetDoc.annotationOn["${dataField}"]`);
else activeItem.data = ComputedField.MakeFunction(`self.presentationTargetDoc["${dataField}"]`);
@@ -1741,7 +1740,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
const activeItem = this.activeItem;
if (activeItem && this.targetDoc) {
const clipStart = NumCast(activeItem.clipStart);
- const clipEnd = NumCast(activeItem.clipEnd, NumCast(activeItem[Doc.LayoutFieldKey(activeItem) + '-duration']));
+ const clipEnd = NumCast(activeItem.clipEnd, NumCast(activeItem[Doc.LayoutFieldKey(activeItem) + '_duration']));
return (
<div className={'presBox-ribbon'} onClick={e => e.stopPropagation()} onPointerUp={e => e.stopPropagation()} onPointerDown={e => e.stopPropagation()}>
<div>
@@ -2075,10 +2074,10 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
// prettier-ignore
switch (layout) {
case 'blank': return Docs.Create.FreeformDocument([], { title: input ? input : 'Blank slide', _width: 400, _height: 225, x, y });
- case 'title': return Docs.Create.FreeformDocument([title(), subtitle()], { title: input ? input : 'Title slide', _width: 400, _height: 225, _fitContentsToBox: true, x, y });
- case 'header': return Docs.Create.FreeformDocument([header()], { title: input ? input : 'Section header', _width: 400, _height: 225, _fitContentsToBox: true, x, y });
- case 'content': return Docs.Create.FreeformDocument([contentTitle(), content()], { title: input ? input : 'Title and content', _width: 400, _height: 225, _fitContentsToBox: true, x, y });
- case 'twoColumns': return Docs.Create.FreeformDocument([contentTitle(), content1(), content2()], { title: input ? input : 'Title and two columns', _width: 400, _height: 225, _fitContentsToBox: true, x, y })
+ case 'title': return Docs.Create.FreeformDocument([title(), subtitle()], { title: input ? input : 'Title slide', _width: 400, _height: 225, _layoutFitContentsToBox: true, x, y });
+ case 'header': return Docs.Create.FreeformDocument([header()], { title: input ? input : 'Section header', _width: 400, _height: 225, _layoutFitContentsToBox: true, x, y });
+ case 'content': return Docs.Create.FreeformDocument([contentTitle(), content()], { title: input ? input : 'Title and content', _width: 400, _height: 225, _layoutFitContentsToBox: true, x, y });
+ case 'twoColumns': return Docs.Create.FreeformDocument([contentTitle(), content1(), content2()], { title: input ? input : 'Title and two columns', _width: 400, _height: 225, _layoutFitContentsToBox: true, x, y })
}
};
@@ -2456,7 +2455,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
childIgnoreNativeSize={true}
moveDocument={returnFalse}
ignoreUnrendered={true}
- //childFitWidth={returnTrue}
+ //childLayoutFitWidth={returnTrue}
childOpacity={returnOne}
//childLayoutString={PresElementBox.LayoutString('data')}
childClickScript={PresBox.navigateToDocScript}
diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx
index 62e5314c3..e48d2d674 100644
--- a/src/client/views/nodes/trails/PresElementBox.tsx
+++ b/src/client/views/nodes/trails/PresElementBox.tsx
@@ -61,7 +61,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
componentDidMount() {
- this.layoutDoc.hideLinkButton = true;
+ this.layoutDoc.layout_hideLinkButton = true;
this._heightDisposer = reaction(
() => ({ expand: this.rootDoc.presExpandInlineButton, height: this.collapsedHeight }),
({ expand, height }) => (this.layoutDoc._height = height + (expand ? this.expandViewHeight : 0)),
@@ -319,7 +319,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
// a previously recorded video will have timecode defined
static videoIsRecorded = (activeItem: Opt<Doc>) => {
const casted = Cast(activeItem?.recording, Doc, null);
- return casted && 'currentTimecode' in casted;
+ return casted && 'layout_currentTimecode' in casted;
};
removeAllRecordingInOverlay = () => {
@@ -380,10 +380,10 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
_width: 384,
_height: 216,
hideDocumentButtonBar: true,
- hideDecorationTitle: true,
+ layout_hideDecorationTitle: true,
hideOpenButton: true,
// hideDeleteButton: true,
- cloneFieldFilter: new List<string>(['system']),
+ cloneFieldFilter: new List<string>(['isSystem']),
});
// attach the recording to the slide, and attach the slide to the recording