aboutsummaryrefslogtreecommitdiff
path: root/src/client/documents/Documents.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/documents/Documents.ts')
-rw-r--r--src/client/documents/Documents.ts131
1 files changed, 99 insertions, 32 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 4086ede20..029653204 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -2,7 +2,7 @@ import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { action, reaction, runInAction } from 'mobx';
import { basename } from 'path';
import { DateField } from '../../fields/DateField';
-import { Doc, DocListCast, Field, LinkedTo, Opt, updateCachedAcls } from '../../fields/Doc';
+import { Doc, DocListCast, Field, LinkedTo, Opt, StrListCast, updateCachedAcls } from '../../fields/Doc';
import { Initializing } from '../../fields/DocSymbols';
import { Id } from '../../fields/FieldSymbols';
import { HtmlField } from '../../fields/HtmlField';
@@ -186,8 +186,6 @@ export class DocumentOptions {
linearBtnWidth?: NUMt = new NumInfo('unexpanded width of a linear menu button (button "width" changes when it expands)', false);
_nativeWidth?: NUMt = new NumInfo('native width of document contents (e.g., the pixel width of an image)', false);
_nativeHeight?: NUMt = new NumInfo('native height of document contents (e.g., the pixel height of an image)', false);
- _nativeDimModifiable?: BOOLt = new BoolInfo('native dimensions can be modified using document decoration reizers', false);
- _nativeHeightUnfrozen?: BOOLt = new BoolInfo('native height can be changed independent of width by dragging decoration resizers');
'acl-Guest'?: STRt = new StrInfo("permissions granted to users logged in as 'guest' (either view, or private)"); // public permissions
'_acl-Guest'?: string; // public permissions
@@ -229,12 +227,16 @@ export class DocumentOptions {
layout_hideLinkButton?: BOOLt = new BoolInfo('whether the blue link counter button should be hidden');
layout_hideDecorationTitle?: BOOLt = new BoolInfo('whether to suppress the document decortations title when selected');
layout_borderRounding?: string;
+ _layout_nativeDimEditable?: BOOLt = new BoolInfo('native dimensions can be modified using document decoration reizers', false);
+ _layout_reflowVertical?: BOOLt = new BoolInfo('native height can be changed independent of width by dragging decoration resizers');
+ _layout_reflowHorizontal?: BOOLt = new BoolInfo('whether a doc with a native size can be horizonally resized, causing some form of reflow');
layout_boxShadow?: string; // box-shadow css string OR "standard" to use dash standard box shadow
layout_maxAutoHeight?: NUMt = new NumInfo('maximum height for newly created (eg, from pasting) text documents', false);
_layout_autoHeight?: BOOLt = new BoolInfo('whether document automatically resizes vertically to display contents');
_layout_curPage?: NUMt = new NumInfo('current page of a PDF or other? paginated document', false);
_layout_currentTimecode?: NUMt = new NumInfo('the current timecode of a time-based document (e.g., current time of a video) value is in seconds', false);
_layout_hideContextMenu?: BOOLt = new BoolInfo('whether the context menu can be shown');
+ _layout_centered?: BOOLt = new BoolInfo('whether text should be vertically centered in Doc');
_layout_fitWidth?: BOOLt = new BoolInfo('whether document should scale its contents to fit its rendered width or not (e.g., for PDFviews)');
_layout_fitContentsToBox?: BOOLt = new BoolInfo('whether a freeformview should zoom/scale to create a shrinkwrapped view of its content');
_layout_fieldKey?: STRt = new StrInfo('the field key containing the current layout definition', false);
@@ -472,9 +474,9 @@ export namespace Docs {
_height: 35,
_xMargin: 10,
_yMargin: 10,
- nativeDimModifiable: true,
- nativeHeightUnfrozen: true,
- layout_forceReflow: true,
+ layout_nativeDimEditable: true,
+ layout_reflowVertical: true,
+ layout_reflowHorizontal: true,
defaultDoubleClick: 'ignore',
systemIcon: 'BsFileEarmarkTextFill',
},
@@ -505,14 +507,24 @@ export namespace Docs {
DocumentType.WEB,
{
layout: { view: WebBox, dataField: defaultDataKey },
- options: { _height: 300, _layout_fitWidth: true, nativeDimModifiable: true, nativeHeightUnfrozen: true, waitForDoubleClickToClick: 'always', systemIcon: 'BsGlobe' },
+ options: { _height: 300, _layout_fitWidth: true, layout_nativeDimEditable: true, layout_reflowVertical: true, waitForDoubleClickToClick: 'always', systemIcon: 'BsGlobe' },
},
],
[
DocumentType.COL,
{
layout: { view: CollectionView, dataField: defaultDataKey },
- options: { _layout_fitWidth: true, freeform: '', _freeform_panX: 0, _freeform_panY: 0, _freeform_scale: 1, systemIcon: 'BsFillCollectionFill' },
+ options: {
+ _layout_fitWidth: true,
+ freeform: '',
+ _freeform_panX: 0,
+ _freeform_panY: 0,
+ _freeform_scale: 1,
+ layout_nativeDimEditable: true,
+ layout_reflowHorizontal: true,
+ layout_reflowVertical: true,
+ systemIcon: 'BsFillCollectionFill',
+ },
},
],
[
@@ -533,7 +545,7 @@ export namespace Docs {
DocumentType.AUDIO,
{
layout: { view: AudioBox, dataField: defaultDataKey },
- options: { _height: 100, layout_fitWidth: true, layout_forceReflow: true, nativeDimModifiable: true, systemIcon: 'BsFillVolumeUpFill' },
+ options: { _height: 100, layout_fitWidth: true, layout_reflowHorizontal: true, layout_reflowVertical: true, layout_nativeDimEditable: true, systemIcon: 'BsFillVolumeUpFill' },
},
],
[
@@ -547,14 +559,14 @@ export namespace Docs {
DocumentType.PDF,
{
layout: { view: PDFBox, dataField: defaultDataKey },
- options: { _layout_curPage: 1, _layout_fitWidth: true, nativeDimModifiable: true, nativeHeightUnfrozen: true, systemIcon: 'BsFileEarmarkPdfFill' },
+ options: { _layout_curPage: 1, _layout_fitWidth: true, layout_nativeDimEditable: true, layout_reflowVertical: true, systemIcon: 'BsFileEarmarkPdfFill' },
},
],
[
DocumentType.MAP,
{
layout: { view: MapBox, dataField: defaultDataKey },
- options: { map: '', _height: 600, _width: 800, nativeDimModifiable: true, systemIcon: 'BsFillPinMapFill' },
+ options: { map: '', _height: 600, _width: 800, layout_reflowHorizontal: true, layout_reflowVertical: true, layout_nativeDimEditable: true, systemIcon: 'BsFillPinMapFill' },
},
],
[
@@ -613,14 +625,25 @@ export namespace Docs {
DocumentType.EQUATION,
{
layout: { view: EquationBox, dataField: 'text' },
- options: { nativeDimModifiable: true, fontSize: '14px', layout_hideResizeHandles: true, layout_hideDecorationTitle: true, systemIcon: 'BsCalculatorFill' }, ///systemIcon: 'BsSuperscript' + BsSubscript
+ options: {
+ fontSize: '14px',
+ layout_reflowHorizontal: true,
+ layout_reflowVertical: true,
+ layout_nativeDimEditable: true,
+ layout_hideDecorationTitle: true,
+ systemIcon: 'BsCalculatorFill',
+ }, ///systemIcon: 'BsSuperscript' + BsSubscript
},
],
[
DocumentType.FUNCPLOT,
{
layout: { view: FunctionPlotBox, dataField: defaultDataKey },
- options: { nativeDimModifiable: true },
+ options: {
+ layout_reflowHorizontal: true,
+ layout_reflowVertical: true,
+ layout_nativeDimEditable: true,
+ },
},
],
[
@@ -672,12 +695,12 @@ export namespace Docs {
layout: { view: InkingStroke, dataField: 'stroke' },
options: {
systemIcon: 'BsFillPencilFill', //
- nativeDimModifiable: true,
- nativeHeightUnfrozen: true,
+ layout_nativeDimEditable: true,
+ layout_reflowVertical: true,
+ layout_reflowHorizontal: true,
layout_hideDecorationTitle: true, // don't show title when selected
fitWidth: false,
layout_isSvg: true,
- layout_forceReflow: true,
},
},
],
@@ -685,7 +708,7 @@ export namespace Docs {
DocumentType.SCREENSHOT,
{
layout: { view: ScreenshotBox, dataField: defaultDataKey },
- options: { nativeDimModifiable: true, nativeHeightUnfrozen: true, systemIcon: 'BsCameraFill' },
+ options: { layout_nativeDimEditable: true, systemIcon: 'BsCameraFill' },
},
],
[
@@ -693,7 +716,7 @@ export namespace Docs {
{
data: '',
layout: { view: ComparisonBox, dataField: defaultDataKey },
- options: { backgroundColor: 'gray', dropAction: 'move', waitForDoubleClickToClick: 'always', systemIcon: 'BsLayoutSplit' },
+ options: { backgroundColor: 'gray', dropAction: 'move', waitForDoubleClickToClick: 'always', layout_reflowHorizontal: true, layout_reflowVertical: true, layout_nativeDimEditable: true, systemIcon: 'BsLayoutSplit' },
},
],
[
@@ -714,14 +737,14 @@ export namespace Docs {
DocumentType.DATAVIZ,
{
layout: { view: DataVizBox, dataField: defaultDataKey },
- options: { dataViz_title: '', dataViz_line: '', dataViz_pie: '', dataViz_histogram: '', dataViz: 'table', _layout_fitWidth: true, nativeDimModifiable: true },
+ options: { dataViz_title: '', dataViz_line: '', dataViz_pie: '', dataViz_histogram: '', dataViz: 'table', _layout_fitWidth: true, layout_reflowHorizontal: true, layout_reflowVertical: true, layout_nativeDimEditable: true },
},
],
[
DocumentType.LOADING,
{
layout: { view: LoadingBox, dataField: '' },
- options: { _layout_fitWidth: true, _fitHeight: true, nativeDimModifiable: true },
+ options: { _layout_fitWidth: true, _fitHeight: true, layout_nativeDimEditable: true },
},
],
[
@@ -731,11 +754,9 @@ export namespace Docs {
layout: { view: PhysicsSimulationBox, dataField: defaultDataKey, _width: 1000, _height: 800 },
options: {
_height: 100,
- layout_forceReflow: true,
- nativeHeightUnfrozen: true,
mass1: '',
mass2: '',
- nativeDimModifiable: true,
+ layout_nativeDimEditable: true,
position: '',
acceleration: '',
pendulum: '',
@@ -948,7 +969,7 @@ export namespace Docs {
export function ImageDocument(url: string | ImageField, options: DocumentOptions = {}, overwriteDoc?: Doc) {
const imgField = url instanceof ImageField ? url : new ImageField(url);
- return InstanceFromProto(Prototypes.get(DocumentType.IMG), imgField, { _nativeDimModifiable: false, _nativeHeightUnfrozen: false, title: basename(imgField.url.href), ...options }, undefined, undefined, undefined, overwriteDoc);
+ return InstanceFromProto(Prototypes.get(DocumentType.IMG), imgField, { title: basename(imgField.url.href), ...options }, undefined, undefined, undefined, overwriteDoc);
}
export function PresDocument(options: DocumentOptions = {}) {
@@ -1042,7 +1063,18 @@ export namespace Docs {
return linkDoc;
}
- export function InkDocument(color: string, strokeWidth: number, stroke_bezier: string, fillColor: string, arrowStart: string, arrowEnd: string, dash: string, points: PointData[], isInkMask: boolean, options: DocumentOptions = {}) {
+ export function InkDocument(
+ points: PointData[],
+ options: DocumentOptions = {},
+ strokeWidth = ActiveInkWidth(),
+ color = ActiveInkColor(),
+ stroke_bezier = ActiveInkBezierApprox(),
+ fillColor = ActiveFillColor(),
+ arrowStart = ActiveArrowStart(),
+ arrowEnd = ActiveArrowEnd(),
+ dash = ActiveDash(),
+ isInkMask = ActiveIsInkMask()
+ ) {
const ink = InstanceFromProto(Prototypes.get(DocumentType.INK), '', { title: 'ink', ...options });
const I = Doc.GetProto(ink);
// I.layout_hideOpenButton = true; // don't show open full screen button when selected
@@ -1253,6 +1285,40 @@ export namespace Docs {
}
export namespace DocUtils {
+ function matchFieldValue(doc: Doc, key: string, value: any): boolean {
+ const hasFunctionFilter = Utils.HasFunctionFilter(value);
+ if (hasFunctionFilter) {
+ return hasFunctionFilter(StrCast(doc[key]));
+ }
+ if (key === LinkedTo) {
+ // links are not a field value, so handled here. value is an expression of form ([field=]idToDoc("..."))
+ const allLinks = LinkManager.Instance.getAllRelatedLinks(doc);
+ const matchLink = (value: string, anchor: Doc) => {
+ const linkedToExp = value?.split('=');
+ if (linkedToExp.length === 1) return Field.toScriptString(anchor) === value;
+ return Field.toScriptString(DocCast(anchor[linkedToExp[0]])) === linkedToExp[1];
+ };
+ // prettier-ignore
+ return (value === Doc.FilterNone && !allLinks.length) ||
+ (value === Doc.FilterAny && !!allLinks.length) ||
+ (allLinks.some(link => matchLink(value,DocCast(link.link_anchor_1)) ||
+ matchLink(value,DocCast(link.link_anchor_2)) ));
+ }
+ if (typeof value === 'string') {
+ value = value.replace(`,${Utils.noRecursionHack}`, '');
+ }
+ const fieldVal = doc[key];
+ // prettier-ignore
+ if ((value === Doc.FilterAny && fieldVal !== undefined) ||
+ (value === Doc.FilterNone && fieldVal === undefined)) {
+ return true;
+ }
+ const vals = StrListCast(fieldVal); // list typing is very imperfect. casting to a string list doesn't mean that the entries will actually be strings
+ if (vals.length) {
+ return vals.some(v => typeof v === 'string' && v.includes(value)); // bcz: arghh: Todo: comparison should be parameterized as exact, or substring
+ }
+ return Field.toString(fieldVal as Field).includes(value); // bcz: arghh: Todo: comparison should be parameterized as exact, or substring
+ }
/**
* @param docs
* @param childFilters
@@ -1284,7 +1350,7 @@ export namespace DocUtils {
if (d.cookies && (!filterFacets.cookies || !Object.keys(filterFacets.cookies).some(key => d.cookies === key))) {
return false;
}
- for (const facetKey of Object.keys(filterFacets).filter(fkey => fkey !== 'cookies' && fkey !== Utils.noDragsDocFilter.split(Doc.FilterSep)[0])) {
+ for (const facetKey of Object.keys(filterFacets).filter(fkey => fkey !== 'cookies' && fkey !== Utils.noDragDocsFilter.split(Doc.FilterSep)[0])) {
const facet = filterFacets[facetKey];
// facets that match some value in the field of the document (e.g. some text field)
@@ -1303,8 +1369,8 @@ export namespace DocUtils {
const xs = Object.keys(facet).filter(value => facet[value] === 'x');
if (!unsets.length && !exists.length && !xs.length && !checks.length && !matches.length) return true;
- const failsNotEqualFacets = !xs.length ? false : xs.some(value => Doc.matchFieldValue(d, facetKey, value));
- const satisfiesCheckFacets = !checks.length ? true : checks.some(value => Doc.matchFieldValue(d, facetKey, value));
+ const failsNotEqualFacets = !xs.length ? false : xs.some(value => matchFieldValue(d, facetKey, value));
+ const satisfiesCheckFacets = !checks.length ? true : checks.some(value => matchFieldValue(d, facetKey, value));
const satisfiesExistsFacets = !exists.length ? true : exists.some(value => (facetKey !== LinkedTo ? d[facetKey] !== undefined : LinkManager.Instance.getAllRelatedLinks(d).length));
const satisfiesUnsetsFacets = !unsets.length ? true : unsets.some(value => d[facetKey] === undefined);
const satisfiesMatchFacets = !matches.length
@@ -1492,7 +1558,7 @@ export namespace DocUtils {
created = Docs.Create.AudioDocument(field.url.href, resolved);
created.layout = AudioBox.LayoutString(fieldKey);
} else if (field instanceof InkField) {
- created = Docs.Create.InkDocument(ActiveInkColor(), ActiveInkWidth(), ActiveInkBezierApprox(), ActiveFillColor(), ActiveArrowStart(), ActiveArrowEnd(), ActiveDash(), field.inkData, ActiveIsInkMask(), resolved);
+ created = Docs.Create.InkDocument(field.inkData, resolved);
created.layout = InkingStroke.LayoutString(fieldKey);
} else if (field instanceof List && field[0] instanceof Doc) {
created = Docs.Create.StackingDocument(DocListCast(field), resolved);
@@ -1802,7 +1868,7 @@ export namespace DocUtils {
proto.data_duration = result.duration;
}
if (overwriteDoc) {
- Doc.removeCurrentlyLoading(overwriteDoc);
+ LoadingBox.removeCurrentlyLoading(overwriteDoc);
}
generatedDocuments.push(doc);
}
@@ -1819,6 +1885,7 @@ export namespace DocUtils {
_height: 35,
x: x,
y: y,
+ _layout_centered: BoolCast(Doc.UserDoc().layout_centered),
_layout_fitWidth: true,
_layout_autoHeight: true,
_layout_enableAltContentUI: BoolCast(Doc.UserDoc().defaultToFlashcards),
@@ -1844,7 +1911,7 @@ export namespace DocUtils {
if (overwriteDoc) {
overwriteDoc.isLoading = false;
overwriteDoc.loadingError = (result as any).message;
- Doc.removeCurrentlyLoading(overwriteDoc);
+ LoadingBox.removeCurrentlyLoading(overwriteDoc);
}
} else name && processFileupload(generatedDocuments, name, type, result, options, overwriteDoc);
});
@@ -1885,7 +1952,7 @@ export namespace DocUtils {
if ((result as any).message) {
if (overwriteDoc) {
overwriteDoc.loadingError = (result as any).message;
- Doc.removeCurrentlyLoading(overwriteDoc);
+ LoadingBox.removeCurrentlyLoading(overwriteDoc);
}
} else name && type && processFileupload(generatedDocuments, name, type, result, options, overwriteDoc);
});