aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoranika-ahluwalia <anika.ahluwalia@gmail.com>2020-07-26 11:25:38 -0500
committeranika-ahluwalia <anika.ahluwalia@gmail.com>2020-07-26 11:25:38 -0500
commit55d08b339ad83166410ce4f7b6a2d39991907b1f (patch)
treed58f0348453612671f4a4c925b8cb4b542f3a54c /src
parent8f250a359e957b01e281cfad1bd92043a2f1b165 (diff)
parent72778bb3de8cb53c7303f6575f839314c6c331b3 (diff)
Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web into menu_restructure
Diffstat (limited to 'src')
-rw-r--r--src/client/util/CurrentUserUtils.ts12
-rw-r--r--src/client/util/DragManager.ts7
-rw-r--r--src/client/util/DropConverter.ts2
-rw-r--r--src/client/views/ContextMenuItem.tsx4
-rw-r--r--src/client/views/DocumentDecorations.tsx14
-rw-r--r--src/client/views/MainView.tsx4
-rw-r--r--src/client/views/collections/CollectionMenu.tsx23
-rw-r--r--src/client/views/collections/CollectionView.tsx14
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx4
-rw-r--r--src/client/views/nodes/DocumentView.tsx21
-rw-r--r--src/client/views/nodes/FontIconBox.tsx2
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx4
-rw-r--r--src/fields/Doc.ts2
-rw-r--r--src/fields/Schema.ts2
-rw-r--r--src/fields/util.ts9
15 files changed, 73 insertions, 51 deletions
diff --git a/src/client/util/CurrentUserUtils.ts b/src/client/util/CurrentUserUtils.ts
index cc9f6aad7..e5582aa0a 100644
--- a/src/client/util/CurrentUserUtils.ts
+++ b/src/client/util/CurrentUserUtils.ts
@@ -356,6 +356,14 @@ export class CurrentUserUtils {
iconRtfView.isTemplateDoc = makeTemplate(iconRtfView, true, "icon_" + DocumentType.RTF);
doc["template-icon-view-rtf"] = new PrefetchProxy(iconRtfView);
}
+ if (doc["template-icon-view-button"] === undefined) {
+ const iconBtnView = Docs.Create.FontIconDocument({
+ title: "icon_" + DocumentType.BUTTON, _nativeHeight: 30, _nativeWidth: 30,
+ _width: 30, _height: 30, isTemplateDoc: true, onDoubleClick: ScriptField.MakeScript("deiconifyView(self)")
+ });
+ iconBtnView.isTemplateDoc = makeTemplate(iconBtnView, true, "icon_" + DocumentType.BUTTON);
+ doc["template-icon-view-button"] = new PrefetchProxy(iconBtnView);
+ }
if (doc["template-icon-view-img"] === undefined) {
const iconImageView = Docs.Create.ImageDocument("http://www.cs.brown.edu/~bcz/face.gif", {
title: "data", _width: 50, isTemplateDoc: true, onDoubleClick: ScriptField.MakeScript("deiconifyView(self)")
@@ -369,11 +377,11 @@ export class CurrentUserUtils {
doc["template-icon-view-col"] = new PrefetchProxy(iconColView);
}
if (doc["template-icons"] === undefined) {
- doc["template-icons"] = new PrefetchProxy(Docs.Create.TreeDocument([doc["template-icon-view"] as Doc, doc["template-icon-view-img"] as Doc,
+ doc["template-icons"] = new PrefetchProxy(Docs.Create.TreeDocument([doc["template-icon-view"] as Doc, doc["template-icon-view-img"] as Doc, doc["template-icon-view-button"] as Doc,
doc["template-icon-view-col"] as Doc, doc["template-icon-view-rtf"] as Doc, doc["template-icon-view-pdf"] as Doc], { title: "icon templates", _height: 75 }));
} else {
const templateIconsDoc = Cast(doc["template-icons"], Doc, null);
- const requiredTypes = [doc["template-icon-view"] as Doc, doc["template-icon-view-img"] as Doc,
+ const requiredTypes = [doc["template-icon-view"] as Doc, doc["template-icon-view-img"] as Doc, doc["template-icon-view-button"] as Doc,
doc["template-icon-view-col"] as Doc, doc["template-icon-view-rtf"] as Doc];
DocListCastAsync(templateIconsDoc.data).then(async curIcons => {
await Promise.all(curIcons!);
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 837f0b1db..4b1860b5c 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -224,11 +224,10 @@ export namespace DragManager {
}
// drag a button template and drop a new button
- export function StartButtonDrag(eles: HTMLElement[], script: string, title: string, vars: { [name: string]: Field }, params: string[], initialize: (button: Doc) => void, downX: number, downY: number, options?: DragOptions) {
+ export function
+ StartButtonDrag(eles: HTMLElement[], script: string, title: string, vars: { [name: string]: Field }, params: string[], initialize: (button: Doc) => void, downX: number, downY: number, options?: DragOptions) {
const finishDrag = (e: DragCompleteEvent) => {
- const bd = params.length > Object.keys(vars).length ?
- Docs.Create.ButtonDocument({ toolTip: title, z: 1, _width: 150, _height: 50, title, onClick: ScriptField.MakeScript(script) }) :
- Docs.Create.FontIconDocument({ toolTip: title, z: 1, _nativeWidth: 30, _nativeHeight: 30, _width: 30, _height: 30, title, onClick: ScriptField.MakeScript(script) });
+ const bd = Docs.Create.ButtonDocument({ toolTip: title, z: 1, _width: 150, _height: 50, title, onClick: ScriptField.MakeScript(script) });
params.map(p => Object.keys(vars).indexOf(p) !== -1 && (Doc.GetProto(bd)[p] = new PrefetchProxy(vars[p] as Doc))); // copy all "captured" arguments into document parameterfields
initialize?.(bd);
Doc.GetProto(bd)["onClick-paramFieldKeys"] = new List<string>(params);
diff --git a/src/client/util/DropConverter.ts b/src/client/util/DropConverter.ts
index f9837298d..d0acf14c3 100644
--- a/src/client/util/DropConverter.ts
+++ b/src/client/util/DropConverter.ts
@@ -57,7 +57,7 @@ export function convertDropDataToButtons(data: DragManager.DocumentDragData) {
data?.draggedDocuments.map((doc, i) => {
let dbox = doc;
// bcz: isButtonBar is intended to allow a collection of linear buttons to be dropped and nested into another collection of buttons... it's not being used yet, and isn't very elegant
- if (doc.type === DocumentType.FONTICON) {
+ if (doc.type === DocumentType.FONTICON || StrCast(Doc.Layout(doc).layout).includes("FontIconBox")) {
dbox = Doc.MakeAlias(doc);
} else if (!doc.onDragStart && !doc.isButtonBar) {
const layoutDoc = doc.layout instanceof Doc && doc.layout.isTemplateForField ? doc.layout : doc;
diff --git a/src/client/views/ContextMenuItem.tsx b/src/client/views/ContextMenuItem.tsx
index 86d1f22e1..81432968d 100644
--- a/src/client/views/ContextMenuItem.tsx
+++ b/src/client/views/ContextMenuItem.tsx
@@ -20,6 +20,7 @@ export interface SubmenuProps {
description: string;
subitems: ContextMenuProps[];
noexpand?: boolean;
+ addDivider?: boolean;
icon: IconProp; //maybe should be optional (icon?)
closeMenu?: () => void;
}
@@ -103,7 +104,8 @@ export class ContextMenuItem extends React.Component<ContextMenuProps & { select
</div>;
}
return (
- <div className={"contextMenu-item" + (this.props.selected ? " contextMenu-itemSelected" : "")} style={{ alignItems: where }}
+ <div className={"contextMenu-item" + (this.props.selected ? " contextMenu-itemSelected" : "")}
+ style={{ alignItems: where, borderTop: this.props.addDivider ? "solid 1px" : undefined }}
onMouseLeave={this.onPointerLeave} onMouseEnter={this.onPointerEnter}>
{this.props.icon ? (
<span className="icon-background" onMouseEnter={this.onPointerLeave} style={{ alignItems: "center" }}>
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index d92b1366b..87222e942 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -439,8 +439,10 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
if (nwidth / nheight !== width / height) {
height = nheight / nwidth * width;
}
- if (Math.abs(dW) > Math.abs(dH)) dH = dW * nheight / nwidth;
- else dW = dH * nwidth / nheight;
+ if (!e.ctrlKey) {
+ if (Math.abs(dW) > Math.abs(dH)) dH = dW * nheight / nwidth;
+ else dW = dH * nwidth / nheight;
+ }
}
const actualdW = Math.max(width + (dW * scale), 20);
const actualdH = Math.max(height + (dH * scale), 20);
@@ -464,20 +466,20 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
}
else if (nwidth > 0 && nheight > 0) {
if (Math.abs(dW) > Math.abs(dH)) {
- if (!fixedAspect) {
+ if (!fixedAspect || e.ctrlKey) {
doc._nativeWidth = actualdW / (doc._width || 1) * (doc._nativeWidth || 0);
}
doc._width = actualdW;
if (fixedAspect && !doc._fitWidth) doc._height = nheight / nwidth * doc._width;
- else doc._height = actualdH;
+ else if (!fixedAspect || !e.ctrlKey) doc._height = actualdH;
}
else {
- if (!fixedAspect) {
+ if (!fixedAspect || e.ctrlKey) {
doc._nativeHeight = actualdH / (doc._height || 1) * (doc._nativeHeight || 0);
}
doc._height = actualdH;
if (fixedAspect && !doc._fitWidth) doc._width = nwidth / nheight * doc._height;
- else doc._width = actualdW;
+ else if (!fixedAspect || !e.ctrlKey) doc._width = actualdW;
}
} else {
dW && (doc._width = actualdW);
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 7bb2524a7..5eb9f3c38 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -8,7 +8,7 @@ import {
faLongArrowAltRight, faMicrophone, faMousePointer, faMusic, faObjectGroup, faPause, faPen, faPenNib, faPhone, faPlay, faPortrait, faRedoAlt, faStamp, faStickyNote, faTimesCircle,
faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faArrowsAlt, faQuoteLeft, faSortAmountDown, faAlignLeft, faAlignCenter, faAlignRight,
faHeading, faRulerCombined, faFillDrip, faLink, faUnlink, faBold, faItalic, faChevronLeft, faUnderline, faStrikethrough, faSuperscript, faSubscript, faIndent, faEyeDropper,
- faPaintRoller, faBars, faBrush, faShapes, faEllipsisH, faHandPaper, faMap, faDesktop, faTrashRestore, faUsers, faWrench, faCog, faBellSlash, faExpandAlt
+ faPaintRoller, faBars, faBrush, faShapes, faEllipsisH, faHandPaper, faMap, faDesktop, faTrashRestore, faUsers, faWrench, faCog, faBellSlash, faExpandAlt, faUser
} from '@fortawesome/free-solid-svg-icons';
import { ANTIMODEMENU_HEIGHT } from './globalCssVariables.scss';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
@@ -175,7 +175,7 @@ export class MainView extends React.Component {
faLongArrowAltRight, faMicrophone, faMousePointer, faMusic, faObjectGroup, faPause, faPen, faPenNib, faPhone, faPlay, faPortrait, faRedoAlt, faStamp, faStickyNote, faTrashAlt, faAngleRight, faBell,
faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faArrowsAlt, faQuoteLeft, faSortAmountDown, faAlignLeft, faAlignCenter, faAlignRight,
faHeading, faRulerCombined, faFillDrip, faLink, faUnlink, faBold, faItalic, faChevronLeft, faUnderline, faStrikethrough, faSuperscript, faSubscript, faIndent, faEyeDropper,
- faPaintRoller, faBars, faBrush, faShapes, faEllipsisH, faHandPaper, faDesktop, faTrashRestore, faUsers, faWrench, faCog, faMap, faBellSlash, faExpandAlt);
+ faPaintRoller, faBars, faBrush, faShapes, faEllipsisH, faHandPaper, faDesktop, faTrashRestore, faUsers, faWrench, faCog, faMap, faBellSlash, faExpandAlt, faUser);
this.initEventListeners();
this.initAuthenticationRouters();
}
diff --git a/src/client/views/collections/CollectionMenu.tsx b/src/client/views/collections/CollectionMenu.tsx
index 992c1f600..24be69050 100644
--- a/src/client/views/collections/CollectionMenu.tsx
+++ b/src/client/views/collections/CollectionMenu.tsx
@@ -2,7 +2,7 @@ import React = require("react");
import { FontAwesomeIcon, FontAwesomeIconProps } from "@fortawesome/react-fontawesome";
import { action, computed, observable, reaction, runInAction, Lambda } from "mobx";
import { observer } from "mobx-react";
-import { Doc, DocListCast, Opt } from "../../../fields/Doc";
+import { Doc, DocListCast, Opt, Field } from "../../../fields/Doc";
import { BoolCast, Cast, StrCast, NumCast } from "../../../fields/Types";
import AntimodeMenu from "../AntimodeMenu";
import "./CollectionMenu.scss";
@@ -24,6 +24,7 @@ import { Document } from "../../../fields/documentSchemas";
import { SelectionManager } from "../../util/SelectionManager";
import { DocumentView } from "../nodes/DocumentView";
import { ColorState } from "react-color";
+import { ObjectField } from "../../../fields/ObjectField";
@observer
export default class CollectionMenu extends AntimodeMenu {
@@ -72,42 +73,48 @@ export class CollectionViewBaseChrome extends React.Component<CollectionMenuProp
get target() { return this.props.CollectionView.props.Document; }
_templateCommand = {
params: ["target", "source"], title: "item view",
- script: "this.target.childLayoutTemplate = getDocTemplate(this.source?.[0])",
+ script: "self.target.childLayoutTemplate = getDocTemplate(self.source?.[0])",
immediate: undoBatch((source: Doc[]) => source.length && (this.target.childLayoutTemplate = Doc.getDocTemplate(source?.[0]))),
initialize: emptyFunction,
};
_narrativeCommand = {
params: ["target", "source"], title: "child click view",
- script: "this.target.childClickedOpenTemplateView = getDocTemplate(this.source?.[0])",
+ script: "self.target.childClickedOpenTemplateView = getDocTemplate(self.source?.[0])",
immediate: undoBatch((source: Doc[]) => source.length && (this.target.childClickedOpenTemplateView = Doc.getDocTemplate(source?.[0]))),
initialize: emptyFunction,
};
_contentCommand = {
params: ["target", "source"], title: "clear content",
- script: "getProto(this.target).data = copyField(this.source);",
+ script: "getProto(self.target).data = copyField(self.source);",
immediate: undoBatch((source: Doc[]) => Doc.GetProto(this.target).data = new List<Doc>(source)), // Doc.aliasDocs(source),
initialize: emptyFunction,
};
_viewCommand = {
params: ["target"], title: "bookmark view",
- script: "this.target._panX = this['target-panX']; this.target._panY = this['target-panY']; this.target._viewScale = this['target-viewScale'];",
+ script: "self.target._panX = self['target-panX']; self.target._panY = self['target-panY']; self.target._viewScale = self['target-viewScale'];",
immediate: undoBatch((source: Doc[]) => { this.target._panX = 0; this.target._panY = 0; this.target._viewScale = 1; }),
initialize: (button: Doc) => { button['target-panX'] = this.target._panX; button['target-panY'] = this.target._panY; button['target-viewScale'] = this.target._viewScale; },
};
_clusterCommand = {
params: ["target"], title: "fit content",
- script: "this.target._fitToBox = !this.target._fitToBox;",
+ script: "self.target._fitToBox = !self.target._fitToBox;",
immediate: undoBatch((source: Doc[]) => this.target._fitToBox = !this.target._fitToBox),
initialize: emptyFunction
};
_fitContentCommand = {
params: ["target"], title: "toggle clusters",
- script: "this.target.useClusters = !this.target.useClusters;",
+ script: "self.target.useClusters = !self.target.useClusters;",
immediate: undoBatch((source: Doc[]) => this.target.useClusters = !this.target.useClusters),
initialize: emptyFunction
};
+ _saveFilterCommand = {
+ params: ["target"], title: "save filter",
+ script: "self.target._docFilters = copyField(self['target-docFilters']);",
+ immediate: undoBatch((source: Doc[]) => this.target._docFilters = undefined),
+ initialize: (button: Doc) => { button['target-docFilters'] = this.target._docFilters instanceof ObjectField ? ObjectField.MakeCopy(this.target._docFilters as any as ObjectField) : ""; },
+ };
- _freeform_commands = [this._viewCommand, this._fitContentCommand, this._clusterCommand, this._contentCommand, this._templateCommand, this._narrativeCommand];
+ _freeform_commands = [this._viewCommand, this._saveFilterCommand, this._fitContentCommand, this._clusterCommand, this._contentCommand, this._templateCommand, this._narrativeCommand];
_stacking_commands = [this._contentCommand, this._templateCommand];
_masonry_commands = [this._contentCommand, this._templateCommand];
_schema_commands = [this._templateCommand, this._narrativeCommand];
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 2d360d13c..2a700be9c 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -48,8 +48,7 @@ import { CollectionTimeView } from './CollectionTimeView';
import { CollectionTreeView } from "./CollectionTreeView";
import './CollectionView.scss';
import CollectionMenu from './CollectionMenu';
-//import SharingPermissions from '../../util/SharingManager';
-import { DocumentView } from '../nodes/DocumentView';
+import { ContextMenuProps } from '../ContextMenuItem';
const higflyout = require("@hig/flyout");
export const { anchorPoints } = higflyout;
export const Flyout = higflyout.default;
@@ -272,9 +271,8 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
setupViewTypes(category: string, func: (viewType: CollectionViewType) => Doc, addExtras: boolean) {
- const existingVm = ContextMenu.Instance.findByDescription(category);
- const subItems = existingVm && "subitems" in existingVm ? existingVm.subitems : [];
+ const subItems: ContextMenuProps[] = [];
subItems.push({ description: "Freeform", event: () => func(CollectionViewType.Freeform), icon: "signature" });
if (addExtras && CollectionView._safeMode) {
ContextMenu.Instance.addItem({ description: "Test Freeform", event: () => func(CollectionViewType.Invalid), icon: "project-diagram" });
@@ -296,13 +294,17 @@ export class CollectionView extends Touchable<FieldViewProps & CollectionViewCus
subItems.push({ description: "Custom", icon: "fingerprint", event: AddCustomFreeFormLayout(this.props.Document, this.props.fieldKey) });
}
addExtras && subItems.push({ description: "lightbox", event: action(() => this._isLightboxOpen = true), icon: "eye" });
- !existingVm && ContextMenu.Instance.addItem({ description: category, noexpand: true, subitems: subItems, icon: "eye" });
+
+ const existingVm = ContextMenu.Instance.findByDescription(category);
+ const catItems = existingVm && "subitems" in existingVm ? existingVm.subitems : [];
+ catItems.push({ description: "Add a Perspective...", addDivider: true, noexpand: true, subitems: subItems, icon: "eye" });
+ !existingVm && ContextMenu.Instance.addItem({ description: category, subitems: catItems, icon: "eye" });
}
onContextMenu = (e: React.MouseEvent): void => {
const cm = ContextMenu.Instance;
if (cm && !e.isPropagationStopped() && this.props.Document[Id] !== CurrentUserUtils.MainDocId) { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7
- this.setupViewTypes("Add a Perspective...", vtype => {
+ this.setupViewTypes("UI Controls...", vtype => {
const newRendition = Doc.MakeAlias(this.props.Document);
newRendition._viewType = vtype;
this.props.addDocTab(newRendition, "onRight");
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 079add4b0..daa6e7440 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -1247,11 +1247,11 @@ export class CollectionFreeFormView extends CollectionSubView<PanZoomDocument, P
appearanceItems.push({ description: "Arrange contents in grid", event: this.layoutDocsInGrid, icon: "table" });
!appearance && ContextMenu.Instance.addItem({ description: "Appearance...", subitems: appearanceItems, icon: "eye" });
- const viewctrls = ContextMenu.Instance.findByDescription("View Controls...");
+ const viewctrls = ContextMenu.Instance.findByDescription("UI Controls...");
const viewCtrlItems = viewctrls && "subitems" in viewctrls ? viewctrls.subitems : [];
viewCtrlItems.push({ description: (Doc.UserDoc().showSnapLines ? "Hide" : "Show") + " Snap Lines", event: () => Doc.UserDoc().showSnapLines = !Doc.UserDoc().showSnapLines, icon: "compress-arrows-alt" });
viewCtrlItems.push({ description: (this.Document.useClusters ? "Hide" : "Show") + " Clusters", event: () => this.updateClusters(!this.Document.useClusters), icon: "braille" });
- !viewctrls && ContextMenu.Instance.addItem({ description: "View Controls...", subitems: viewCtrlItems, icon: "eye" });
+ !viewctrls && ContextMenu.Instance.addItem({ description: "UI Controls...", subitems: viewCtrlItems, icon: "eye" });
const options = ContextMenu.Instance.findByDescription("Options...");
const optionItems = options && "subitems" in options ? options.subitems : [];
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index bb1c43e6b..0cfb12f95 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -295,7 +295,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
let stopPropagate = true;
let preventDefault = true;
!this.props.Document.isBackground && this.props.bringToFront(this.props.Document);
- if (this._doubleTap && this.props.renderDepth && !this.onClickHandler?.script) { // disable double-click to show full screen for things that have an on click behavior since clicking them twice can be misinterpreted as a double click
+ if (this._doubleTap && this.props.renderDepth) {// && !this.onClickHandler?.script) { // disable double-click to show full screen for things that have an on click behavior since clicking them twice can be misinterpreted as a double click
if (!(e.nativeEvent as any).formattedHandled) {
if (this.onDoubleClickHandler?.script && !StrCast(Doc.LayoutField(this.layoutDoc))?.includes("ScriptingBox")) { // bcz: hack? don't execute script if you're clicking on a scripting box itself
const func = () => this.onDoubleClickHandler.script.run({
@@ -764,10 +764,11 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
cm.addItem({ description: item.label, event: () => item.script.script.run({ this: this.layoutDoc, self: this.rootDoc }), icon: "sticky-note" }));
const templateDoc = Cast(this.props.Document[StrCast(this.props.Document.layoutKey)], Doc, null);
- const appearance = cm.findByDescription("Appearance...");
+ const appearance = cm.findByDescription("UI Controls...");
const appearanceItems: ContextMenuProps[] = appearance && "subitems" in appearance ? appearance.subitems : [];
templateDoc && appearanceItems.push({ description: "Open Template ", event: () => this.props.addDocTab(templateDoc, "onRight"), icon: "eye" });
- !appearance && cm.addItem({ description: "Appearance...", subitems: appearanceItems, icon: "compass" });
+ //DocListCast(this.Document.links).length && appearanceItems.splice(0, 0, { description: `${this.layoutDoc.hideLinkButton ? "Show" : "Hide"} Link Button`, event: action(() => this.layoutDoc.hideLinkButton = !this.layoutDoc.hideLinkButton), icon: "eye" });
+ !appearance && cm.addItem({ description: "UI Controls...", subitems: appearanceItems, icon: "compass" });
const options = cm.findByDescription("Options...");
const optionItems: ContextMenuProps[] = options && "subitems" in options ? options.subitems : [];
@@ -784,7 +785,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
onClicks.push({ description: this.Document.isLinkButton ? "Remove Follow Behavior" : "Follow Link on Right", event: this.toggleFollowOnRight, icon: "concierge-bell" });
onClicks.push({ description: this.Document.isLinkButton || this.onClickHandler ? "Remove Click Behavior" : "Follow Link", event: this.toggleLinkButtonBehavior, icon: "concierge-bell" });
onClicks.push({ description: "Edit onClick Script", event: () => UndoManager.RunInBatch(() => DocUtils.makeCustomViewClicked(this.props.Document, undefined, "onClick"), "edit onClick"), icon: "edit" });
- !existingOnClick && cm.addItem({ description: "OnClick...", noexpand: true, subitems: onClicks, icon: "hand-point-right" });
+ !existingOnClick && cm.addItem({ description: "OnClick...", noexpand: true, addDivider: true, subitems: onClicks, icon: "hand-point-right" });
const funcs: ContextMenuProps[] = [];
if (this.layoutDoc.onDragStart) {
@@ -829,12 +830,11 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
const help = cm.findByDescription("Help...");
const helpItems: ContextMenuProps[] = help && "subitems" in help ? help.subitems : [];
- //!Doc.UserDoc().novice && helpItems.push({ description: "Text Shortcuts Ctrl+/", event: () => this.props.addDocTab(Docs.Create.PdfDocument(Utils.prepend("/assets/cheat-sheet.pdf"), { _width: 300, _height: 300 }), "onRight"), icon: "keyboard" });
!Doc.UserDoc().novice && helpItems.push({ description: "Show Fields ", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { _width: 300, _height: 300 }), "onRight"), icon: "layer-group" });
- //cm.addItem({ description: "Help...", noexpand: true, subitems: helpItems, icon: "question" });
-
- // to be removed for baseline
- cm.addItem({ description: "Print Document in Console", event: () => console.log(this.props.Document), icon: "hand-point-right" });
+ helpItems.push({ description: "Text Shortcuts Ctrl+/", event: () => this.props.addDocTab(Docs.Create.PdfDocument(Utils.prepend("/assets/cheat-sheet.pdf"), { _width: 300, _height: 300 }), "onRight"), icon: "keyboard" });
+ helpItems.push({ description: "Show Fields ", event: () => this.props.addDocTab(Docs.Create.KVPDocument(this.props.Document, { _width: 300, _height: 300 }), "onRight"), icon: "layer-group" });
+ helpItems.push({ description: "Print Document in Console", event: () => console.log(this.props.Document), icon: "hand-point-right" });
+ cm.addItem({ description: "Help...", noexpand: true, subitems: helpItems, icon: "question" });
// const existingAcls = cm.findByDescription("Privacy...");
// const aclItems: ContextMenuProps[] = existingAcls && "subitems" in existingAcls ? existingAcls.subitems : [];
@@ -1081,7 +1081,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
layoutKey={this.finalLayoutKey} />
{this.layoutDoc.hideAllLinks ? (null) : this.allAnchors}
{/* {this.allAnchors} */}
- {this.props.forcedBackgroundColor?.(this.Document) === "transparent" || this.layoutDoc.hideLinkButton || this.props.dontRegisterView ? (null) : <DocumentLinksButton View={this} Offset={[-15, 0]} />}
+ {this.props.forcedBackgroundColor?.(this.Document) === "transparent" || this.layoutDoc.isLinkButton || this.layoutDoc.hideLinkButton || this.props.dontRegisterView ? (null) :
+ <DocumentLinksButton View={this} Offset={[-15, 0]} />}
</div>
);
}
diff --git a/src/client/views/nodes/FontIconBox.tsx b/src/client/views/nodes/FontIconBox.tsx
index ab34e13b0..2611d2ca7 100644
--- a/src/client/views/nodes/FontIconBox.tsx
+++ b/src/client/views/nodes/FontIconBox.tsx
@@ -67,7 +67,7 @@ export class FontIconBox extends DocComponent<FieldViewProps, FontIconDocument>(
background: StrCast(refLayout._backgroundColor, StrCast(refLayout.backgroundColor)),
boxShadow: this.layoutDoc.ischecked ? `4px 4px 12px black` : undefined
}}>
- <FontAwesomeIcon className="fontIconBox-icon" icon={this.dataDoc.icon as any} color={StrCast(this.layoutDoc.color, this._foregroundColor)} size="sm" />
+ <FontAwesomeIcon className="fontIconBox-icon" icon={StrCast(this.dataDoc.icon, "user") as any} color={StrCast(this.layoutDoc.color, this._foregroundColor)} size="sm" />
{!this.rootDoc.title ? (null) : <div className="fontIconBox-label" style={{ width: this.rootDoc.label ? "max-content" : undefined }}> {StrCast(this.rootDoc.label, StrCast(this.rootDoc.title).substring(0, 6))} </div>}
</button>;
return !this.layoutDoc.toolTip ? button :
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index 966aaa895..6b6fc5da2 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -1401,12 +1401,12 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp
onDoubleClick={this.onDoubleClick}
>
<div className={`formattedTextBox-outer`} ref={this._scrollRef}
- style={{ width: `calc(100% - ${this.sidebarWidthPercent})`, pointerEvents: !this.props.isSelected() ? "none" : undefined }}
+ style={{ width: `calc(100% - ${this.sidebarWidthPercent})`, pointerEvents: !this.props.active() ? "none" : undefined }}
onScroll={this.onscrolled} onDrop={this.ondrop} >
<div className={`formattedTextBox-inner${rounded}${selclass}`} ref={this.createDropTarget}
style={{
padding: this.layoutDoc._textBoxPadding ? StrCast(this.layoutDoc._textBoxPadding) : `${Math.max(0, NumCast(this.layoutDoc._yMargin, this.props.yMargin || 0) + selPad)}px ${NumCast(this.layoutDoc._xMargin, this.props.xMargin || 0) + selPad}px`,
- pointerEvents: !this.props.isSelected() ? ((this.layoutDoc.isLinkButton || this.props.onClick) ? "none" : undefined) : undefined
+ pointerEvents: !this.props.active() ? ((this.layoutDoc.isLinkButton || this.props.onClick) ? "none" : undefined) : undefined
}}
/>
</div>
diff --git a/src/fields/Doc.ts b/src/fields/Doc.ts
index 3ea53a9e0..87acb2ea7 100644
--- a/src/fields/Doc.ts
+++ b/src/fields/Doc.ts
@@ -1235,7 +1235,7 @@ Scripting.addGlobal(function getProto(doc: any) { return Doc.GetProto(doc); });
Scripting.addGlobal(function getDocTemplate(doc?: any) { return Doc.getDocTemplate(doc); });
Scripting.addGlobal(function getAlias(doc: any) { return Doc.MakeAlias(doc); });
Scripting.addGlobal(function getCopy(doc: any, copyProto: any) { return doc.isTemplateDoc ? Doc.ApplyTemplate(doc) : Doc.MakeCopy(doc, copyProto); });
-Scripting.addGlobal(function copyField(field: any) { return ObjectField.MakeCopy(field); });
+Scripting.addGlobal(function copyField(field: any) { return field instanceof ObjectField ? ObjectField.MakeCopy(field) : field; });
Scripting.addGlobal(function aliasDocs(field: any) { return Doc.aliasDocs(field); });
Scripting.addGlobal(function docList(field: any) { return DocListCast(field); });
Scripting.addGlobal(function setInPlace(doc: any, field: any, value: any) { return Doc.SetInPlace(doc, field, value, false); });
diff --git a/src/fields/Schema.ts b/src/fields/Schema.ts
index c6a8d6ae9..23ac50f74 100644
--- a/src/fields/Schema.ts
+++ b/src/fields/Schema.ts
@@ -52,7 +52,7 @@ export function makeInterface<T extends Interface[]>(...schemas: T): InterfaceFu
return field;
},
set(target: any, prop, value, receiver) {
- receiver.doc[prop] = value;
+ receiver.doc && (receiver.doc[prop] = value); // receiver.doc may be undefined as the result of a change in ACLs
return true;
}
});
diff --git a/src/fields/util.ts b/src/fields/util.ts
index e0b1843a1..a62795e64 100644
--- a/src/fields/util.ts
+++ b/src/fields/util.ts
@@ -1,5 +1,5 @@
import { UndoManager } from "../client/util/UndoManager";
-import { Doc, FieldResult, UpdatingFromServer, LayoutSym, AclPrivate, AclEdit, AclReadonly, AclAddonly, AclSym, CachedUpdates, DataSym, DocListCast, AclAdmin, FieldsSym } from "./Doc";
+import { Doc, FieldResult, UpdatingFromServer, LayoutSym, AclPrivate, AclEdit, AclReadonly, AclAddonly, AclSym, CachedUpdates, DataSym, DocListCast, AclAdmin, FieldsSym, HeightSym, WidthSym } from "./Doc";
import { SerializationHelper } from "../client/util/SerializationHelper";
import { ProxyField, PrefetchProxy } from "./Proxy";
import { RefField } from "./RefField";
@@ -9,6 +9,7 @@ import { Parent, OnUpdate, Update, Id, SelfProxy, Self, HandleUpdate } from "./F
import { DocServer } from "../client/DocServer";
import { ComputedField } from "./ScriptField";
import { ScriptCast, StrCast } from "./Types";
+import { returnZero } from "../Utils";
function _readOnlySetter(): never {
@@ -77,10 +78,10 @@ const _setterImpl = action(function (target: any, prop: string | symbol | number
if (writeToDoc) {
if (value === undefined) {
- delete target.__fieldKeys[prop];
+ target.__fieldKeys && (delete target.__fieldKeys[prop]);
delete target.__fields[prop];
} else {
- target.__fieldKeys[prop] = true;
+ target.__fieldKeys && (target.__fieldKeys[prop] = true);
target.__fields[prop] = value;
}
//if (typeof value === "object" && !(value instanceof ObjectField)) debugger;
@@ -246,7 +247,7 @@ export function getter(target: any, in_prop: string | symbol | number, receiver:
if (in_prop === FieldsSym || in_prop === Id || in_prop === HandleUpdate || in_prop === CachedUpdates) return target.__fields[prop] || target[prop];
if (in_prop === AclSym) return _overrideAcl ? undefined : target[AclSym];
- if (GetEffectiveAcl(target) === AclPrivate && !_overrideAcl) return undefined;
+ if (GetEffectiveAcl(target) === AclPrivate && !_overrideAcl) return prop === HeightSym || prop === WidthSym ? returnZero : undefined;
if (prop === LayoutSym) {
return target.__LAYOUT__;
}