aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFawn <fangrui_tong@brown.edu>2019-07-27 17:19:00 -0400
committerFawn <fangrui_tong@brown.edu>2019-07-27 17:19:00 -0400
commitf02e8416239b612f40dd2c65d6ca9173e81fb1a9 (patch)
tree6541914e8d71f7dd57e66ed7fbc7679820d7594b
parent905d77804bf9a810822e5e43f0cd06019aef7620 (diff)
parent606e87ccd9c06c83114d5962382cd76def86f103 (diff)
Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web into schema_view_improvements_2
-rw-r--r--src/client/cognitive_services/CognitiveServices.ts5
-rw-r--r--src/client/util/DocumentManager.ts16
-rw-r--r--src/client/util/DragManager.ts5
-rw-r--r--src/client/views/ContextMenu.scss57
-rw-r--r--src/client/views/ContextMenu.tsx8
-rw-r--r--src/client/views/ContextMenuItem.tsx6
-rw-r--r--src/client/views/DocumentDecorations.tsx18
-rw-r--r--src/client/views/EditableView.tsx3
-rw-r--r--src/client/views/GlobalKeyHandler.ts1
-rw-r--r--src/client/views/InkingControl.tsx2
-rw-r--r--src/client/views/MainView.tsx5
-rw-r--r--src/client/views/MetadataEntryMenu.tsx1
-rw-r--r--src/client/views/ScriptingRepl.tsx19
-rw-r--r--src/client/views/collections/CollectionBaseView.scss2
-rw-r--r--src/client/views/collections/CollectionBaseView.tsx8
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx39
-rw-r--r--src/client/views/collections/CollectionSchemaView.tsx9
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx43
-rw-r--r--src/client/views/collections/CollectionStackingViewFieldColumn.tsx29
-rw-r--r--src/client/views/collections/CollectionSubView.tsx2
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx16
-rw-r--r--src/client/views/collections/CollectionView.tsx5
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx8
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx71
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx2
-rw-r--r--src/client/views/nodes/ButtonBox.scss2
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx16
-rw-r--r--src/client/views/nodes/DocumentView.scss1
-rw-r--r--src/client/views/nodes/DocumentView.tsx113
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx14
-rw-r--r--src/client/views/nodes/IconBox.tsx12
-rw-r--r--src/client/views/nodes/ImageBox.tsx57
-rw-r--r--src/client/views/nodes/KeyValueBox.tsx3
-rw-r--r--src/client/views/nodes/LinkMenuItem.tsx2
-rw-r--r--src/client/views/nodes/VideoBox.tsx6
-rw-r--r--src/client/views/pdf/Page.tsx22
-rw-r--r--src/client/views/presentationview/PresentationElement.tsx24
-rw-r--r--src/client/views/presentationview/PresentationView.tsx2
-rw-r--r--src/client/views/search/SearchItem.tsx7
-rw-r--r--src/new_fields/Doc.ts32
-rw-r--r--src/new_fields/ScriptField.ts1
-rw-r--r--src/new_fields/Types.ts2
-rw-r--r--src/scraping/buxton/scraper.py3
-rw-r--r--src/scraping/buxton/source/Bill_Notes_Bill_Notes_CyKey.docxbin1675500 -> 1561425 bytes
-rw-r--r--src/scraping/buxton/source/Bill_Notes_Braun_T3.docxbin1671968 -> 1510917 bytes
-rw-r--r--src/scraping/buxton/source/Bill_Notes_CasioC801.docxbin574664 -> 413861 bytes
-rw-r--r--src/scraping/buxton/source/Bill_Notes_Casio_Mini.docxbin581069 -> 467304 bytes
-rw-r--r--src/scraping/buxton/source/Bill_Notes_FingerWorks_Prototype.docxbin585090 -> 423384 bytes
-rw-r--r--src/scraping/buxton/source/Bill_Notes_Fingerworks_TouchStream.docxbin1722555 -> 1558473 bytes
-rw-r--r--src/scraping/buxton/source/Bill_Notes_FrogPad.docxbin840173 -> 679241 bytes
-rw-r--r--src/scraping/buxton/source/Bill_Notes_Gavilan_SC.docxbin1695290 -> 1531689 bytes
-rw-r--r--src/scraping/buxton/source/Bill_Notes_Grandjean_Stenotype.docxbin2094142 -> 1933004 bytes
-rw-r--r--src/scraping/buxton/source/Bill_Notes_Matias.docxbin590407 -> 476141 bytes
-rw-r--r--src/scraping/buxton/source/Bill_Notes_MousePen.docxbin505322 -> 344083 bytes
-rw-r--r--src/scraping/buxton/source/Bill_Notes_NewO.docxbin2264571 -> 2150143 bytes
-rw-r--r--src/scraping/buxton/source/Bill_Notes_OLPC.docxbin6883659 -> 6721592 bytes
-rw-r--r--src/scraping/buxton/source/Bill_Notes_PARCkbd.docxbin631959 -> 517484 bytes
-rw-r--r--src/scraping/buxton/source/Bill_Notes_Philco_Mystery_Control.docxbin1994439 -> 1880816 bytes
-rw-r--r--src/scraping/buxton/source/Bill_Notes_TASA_Kbd.docxbin461199 -> 347612 bytes
-rw-r--r--src/scraping/buxton/source/Bill_Notes_The_Tap.docxbin711321 -> 597382 bytes
60 files changed, 424 insertions, 275 deletions
diff --git a/src/client/cognitive_services/CognitiveServices.ts b/src/client/cognitive_services/CognitiveServices.ts
index d69378d0e..bbc438a9b 100644
--- a/src/client/cognitive_services/CognitiveServices.ts
+++ b/src/client/cognitive_services/CognitiveServices.ts
@@ -9,6 +9,7 @@ import { Utils } from "../../Utils";
import { CompileScript } from "../util/Scripting";
import { ComputedField } from "../../new_fields/ScriptField";
import { InkData } from "../../new_fields/InkField";
+import { undoBatch, UndoManager } from "../util/UndoManager";
type APIManager<D> = { converter: BodyConverter<D>, requester: RequestExecutor, analyzer: AnalysisApplier };
type RequestExecutor = (apiKey: string, body: string, service: Service) => Promise<string>;
@@ -103,6 +104,7 @@ export namespace CognitiveServices {
},
analyzer: async (target: Doc, keys: string[], service: Service, converter: Converter) => {
+ let batch = UndoManager.StartBatch("Image Analysis");
let imageData = Cast(target.data, ImageField);
let storageKey = keys[0];
if (!imageData || await Cast(target[storageKey], Doc)) {
@@ -120,6 +122,7 @@ export namespace CognitiveServices {
}
}
target[storageKey] = toStore;
+ batch.end();
}
};
@@ -205,6 +208,7 @@ export namespace CognitiveServices {
},
analyzer: async (target: Doc, keys: string[], inkData: InkData) => {
+ let batch = UndoManager.StartBatch("Ink Analysis");
let results = await executeQuery<InkData, any>(Service.Handwriting, Manager, inkData);
if (results) {
results.recognitionUnits && (results = results.recognitionUnits);
@@ -213,6 +217,7 @@ export namespace CognitiveServices {
let individualWords = recognizedText.filter((text: string) => text && text.split(" ").length === 1);
target[keys[1]] = individualWords.join(" ");
}
+ batch.end();
}
};
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index 262194a40..32f728c71 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -1,16 +1,14 @@
-import { computed, observable, action } from 'mobx';
-import { DocumentView } from '../views/nodes/DocumentView';
-import { Doc, DocListCast, Opt } from '../../new_fields/Doc';
-import { FieldValue, Cast, NumCast, BoolCast, StrCast } from '../../new_fields/Types';
-import { listSpec } from '../../new_fields/Schema';
-import { undoBatch, UndoManager } from './UndoManager';
+import { action, computed, observable } from 'mobx';
+import { Doc } from '../../new_fields/Doc';
+import { Id } from '../../new_fields/FieldSymbols';
+import { BoolCast, Cast, NumCast } from '../../new_fields/Types';
import { CollectionDockingView } from '../views/collections/CollectionDockingView';
-import { CollectionView } from '../views/collections/CollectionView';
import { CollectionPDFView } from '../views/collections/CollectionPDFView';
import { CollectionVideoView } from '../views/collections/CollectionVideoView';
-import { Id } from '../../new_fields/FieldSymbols';
+import { CollectionView } from '../views/collections/CollectionView';
+import { DocumentView } from '../views/nodes/DocumentView';
import { LinkManager } from './LinkManager';
-import { CurrentUserUtils } from '../../server/authentication/models/current_user_utils';
+import { undoBatch, UndoManager } from './UndoManager';
export class DocumentManager {
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 47d3c313d..5a4fa3688 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -9,6 +9,7 @@ import { DocumentManager } from "./DocumentManager";
import { LinkManager } from "./LinkManager";
import { SelectionManager } from "./SelectionManager";
import { SchemaHeaderField } from "../../new_fields/SchemaHeaderField";
+import { DocumentDecorations } from "../views/DocumentDecorations";
export type dropActionType = "alias" | "copy" | undefined;
export function SetupDrag(
@@ -426,7 +427,6 @@ export namespace DragManager {
};
let hideDragElements = () => {
- SelectionManager.SetIsDragging(false);
dragElements.map(dragElement => dragElement.parentNode === dragDiv && dragDiv.removeChild(dragElement));
eles.map(ele => (ele.hidden = false));
};
@@ -436,15 +436,18 @@ export namespace DragManager {
if (options) {
options.handlers.dragComplete({});
}
+ DocumentDecorations.Instance.endLinkDragBatch();
};
AbortDrag = () => {
hideDragElements();
+ SelectionManager.SetIsDragging(false);
endDrag();
};
const upHandler = (e: PointerEvent) => {
hideDragElements();
dispatchDrag(eles, e, dragData, options, finishDrag);
+ SelectionManager.SetIsDragging(false);
endDrag();
};
document.addEventListener("pointermove", moveHandler, true);
diff --git a/src/client/views/ContextMenu.scss b/src/client/views/ContextMenu.scss
index 254163b53..e2c0de8af 100644
--- a/src/client/views/ContextMenu.scss
+++ b/src/client/views/ContextMenu.scss
@@ -6,6 +6,10 @@
z-index: $contextMenu-zindex;
box-shadow: $intermediate-color 0.2vw 0.2vw 0.4vw;
flex-direction: column;
+ background: whitesmoke;
+ padding-bottom: 10px;
+ border-radius: 15px;
+ border: solid #BBBBBBBB 1px;
}
// .contextMenu-item:first-child {
@@ -28,12 +32,17 @@
z-index: 1000;
box-shadow: #AAAAAA .2vw .2vw .4vw;
flex-direction: column;
+ border: 1px solid #BBBBBBBB;
+ border-radius: 15px;
+ padding-top: 10px;
+ padding-bottom: 10px;
+ background: whitesmoke;
}
.contextMenu-item {
// width: 11vw; //10vw
height: 30px; //2vh
- background: #DDDDDD;
+ background: whitesmoke;
display: flex; //comment out to allow search icon to be inline with search text
justify-content: left;
align-items: center;
@@ -44,23 +53,33 @@
-ms-user-select: none;
user-select: none;
transition: all .1s;
+ border-style: none;
+ // padding: 10px 0px 10px 0px;
+ white-space: nowrap;
+ font-size: 13px;
+ color: grey;
+ letter-spacing: 2px;
+ text-transform: uppercase;
+ padding-right: 30px;
+}
+
+.contextMenu-item:hover {
border-width: .11px;
border-style: none;
border-color: $intermediate-color; // rgb(187, 186, 186);
border-bottom-style: solid;
- // padding: 10px 0px 10px 0px;
- white-space: nowrap;
- font-size: 20px;
+ border-top-style: solid;
}
.contextMenu-itemSelected {
- background: rgb(136, 136, 136)
+ background: lightgoldenrodyellow;
+ border-style: none;
}
.contextMenu-group {
// width: 11vw; //10vw
height: 30px; //2vh
- background: rgb(200, 200, 200);
+ background: lightgray;
display: flex; //comment out to allow search icon to be inline with search text
justify-content: left;
align-items: center;
@@ -74,27 +93,41 @@
border-width: .11px;
border-style: none;
border-color: $intermediate-color; // rgb(187, 186, 186);
- border-bottom-style: solid;
// padding: 10px 0px 10px 0px;
white-space: nowrap;
- font-size: 20px;
+ font-size: 13px;
+ text-transform: uppercase;
+ letter-spacing: 2px;
+ padding-left: 5px;
}
.contextMenu-item:hover {
- transition: all 0.1s;
+ transition: all 0.1s ease;
background: $lighter-alt-accent;
}
.contextMenu-description {
- font-size: 20px;
+ margin-left: 5px;
text-align: left;
display: inline; //need this?
}
+.search-icon {
+ margin: 10px;
+}
+
+.search {
+ margin-left: 10px;
+ padding-left: 10px;
+ border: solid black 1px;
+ border-radius: 5px;
+}
+
.icon-background {
pointer-events: none;
- background-color: #DDDDDD;
+ background-color: transparent;
width: 35px;
text-align: center;
- font-size: 22px;
+ font-size: 20px;
+ margin-left: 5px;
} \ No newline at end of file
diff --git a/src/client/views/ContextMenu.tsx b/src/client/views/ContextMenu.tsx
index c163c56a0..a608e448a 100644
--- a/src/client/views/ContextMenu.tsx
+++ b/src/client/views/ContextMenu.tsx
@@ -38,6 +38,10 @@ export class ContextMenu extends React.Component {
this._items = [];
}
+ findByDescription = (target: string) => {
+ return this._items.find(menuItem => menuItem.description === target);
+ }
+
@action
addItem(item: ContextMenuProps) {
if (this._items.indexOf(item) === -1) {
@@ -165,11 +169,11 @@ export class ContextMenu extends React.Component {
const contents = (
<>
- <span>
+ <span className={"search-icon"}>
<span className="icon-background">
<FontAwesomeIcon icon="search" size="lg" />
</span>
- <input className="contextMenu-item contextMenu-description" type="text" placeholder="Search . . ." value={this._searchString} onKeyDown={this.onKeyDown} onChange={this.onChange} autoFocus />
+ <input className="contextMenu-item contextMenu-description search" type="text" placeholder="Search . . ." value={this._searchString} onKeyDown={this.onKeyDown} onChange={this.onChange} autoFocus />
</span>
{this.menuItems}
</>
diff --git a/src/client/views/ContextMenuItem.tsx b/src/client/views/ContextMenuItem.tsx
index 9bbb97d7e..badb9cf19 100644
--- a/src/client/views/ContextMenuItem.tsx
+++ b/src/client/views/ContextMenuItem.tsx
@@ -10,14 +10,14 @@ library.add(faAngleRight);
export interface OriginalMenuProps {
description: string;
event: () => void;
- icon?: IconProp; //maybe should be optional (icon?)
+ icon: IconProp; //maybe should be optional (icon?)
closeMenu?: () => void;
}
export interface SubmenuProps {
description: string;
subitems: ContextMenuProps[];
- icon?: IconProp; //maybe should be optional (icon?)
+ icon: IconProp; //maybe should be optional (icon?)
closeMenu?: () => void;
}
@@ -94,7 +94,7 @@ export class ContextMenuItem extends React.Component<ContextMenuProps & { select
) : null}
<div className="contextMenu-description">
{this.props.description}
- <FontAwesomeIcon icon={faAngleRight} size="lg" style={{ position: "absolute", right: "5px" }} />
+ <FontAwesomeIcon icon={faAngleRight} size="lg" style={{ position: "absolute", right: "10px"}} />
</div>
{submenu}
</div>
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx
index 6fecbd3a7..ee16938ff 100644
--- a/src/client/views/DocumentDecorations.tsx
+++ b/src/client/views/DocumentDecorations.tsx
@@ -54,6 +54,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
private _downY = 0;
private _iconDoc?: Doc = undefined;
private _resizeUndo?: UndoManager.Batch;
+ private _linkDrag?: UndoManager.Batch;
@observable private _minimizedX = 0;
@observable private _minimizedY = 0;
@observable private _title: string = "";
@@ -96,6 +97,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
}
else {
if (SelectionManager.SelectedDocuments().length > 0) {
+ SelectionManager.SelectedDocuments()[0].props.Document.customTitle = true;
let field = SelectionManager.SelectedDocuments()[0].props.Document[this._fieldKey];
if (typeof field === "number") {
SelectionManager.SelectedDocuments().forEach(d => {
@@ -346,7 +348,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
onRadiusMove = (e: PointerEvent): void => {
let dist = Math.sqrt((e.clientX - this._radiusDown[0]) * (e.clientX - this._radiusDown[0]) + (e.clientY - this._radiusDown[1]) * (e.clientY - this._radiusDown[1]));
- SelectionManager.SelectedDocuments().map(dv => dv.props.Document.borderRounding = Doc.GetProto(dv.props.Document).borderRounding = `${Math.min(100, dist)}%`);
+ SelectionManager.SelectedDocuments().map(dv => dv.props.Document.layout instanceof Doc ? dv.props.Document.layout : dv.props.Document.isTemplate ? dv.props.Document : Doc.GetProto(dv.props.Document)).
+ map(d => d.borderRounding = `${Math.min(100, dist)}%`);
e.stopPropagation();
e.preventDefault();
}
@@ -375,7 +378,16 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
}
}
+ endLinkDragBatch = () => {
+ if (!this._linkDrag) {
+ return;
+ }
+ this._linkDrag.end();
+ this._linkDrag = undefined;
+ }
+
onLinkerButtonDown = (e: React.PointerEvent): void => {
+ this._linkDrag = UndoManager.StartBatch("Drag Link");
e.stopPropagation();
document.removeEventListener("pointermove", this.onLinkerButtonMoved);
document.addEventListener("pointermove", this.onLinkerButtonMoved);
@@ -532,7 +544,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
proto.nativeHeight = nheight = doc.height || 0;
proto.ignoreAspect = true;
}
- if (nwidth > 0 && nheight > 0) {
+ if (nwidth > 0 && nheight > 0 && !BoolCast(proto.ignoreAspect)) {
if (Math.abs(dW) > Math.abs(dH)) {
if (!fixedAspect) {
Doc.SetInPlace(element.props.Document, "nativeWidth", actualdW / (doc.width || 1) * (doc.nativeWidth || 0), true);
@@ -552,7 +564,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }>
} else {
dW && (doc.width = actualdW);
dH && (doc.height = actualdH);
- Doc.SetInPlace(element.props.Document, "autoHeight", undefined, true);
+ dH && Doc.SetInPlace(element.props.Document, "autoHeight", undefined, true);
}
}
});
diff --git a/src/client/views/EditableView.tsx b/src/client/views/EditableView.tsx
index 31e4557be..373b63282 100644
--- a/src/client/views/EditableView.tsx
+++ b/src/client/views/EditableView.tsx
@@ -69,8 +69,10 @@ export class EditableView extends React.Component<EditableProps> {
@action
onKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === "Tab") {
+ e.stopPropagation();
this.props.OnTab && this.props.OnTab();
} else if (e.key === "Enter") {
+ e.stopPropagation();
if (!e.ctrlKey) {
if (this.props.SetValue(e.currentTarget.value, e.shiftKey)) {
this._editing = false;
@@ -82,6 +84,7 @@ export class EditableView extends React.Component<EditableProps> {
this.props.isEditingCallback && this.props.isEditingCallback(false);
}
} else if (e.key === "Escape") {
+ e.stopPropagation();
this._editing = false;
this.props.isEditingCallback && this.props.isEditingCallback(false);
}
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index 7477c5b4f..5050f34ab 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -67,6 +67,7 @@ export default class KeyManager {
}
}
MainView.Instance.toggleColorPicker(true);
+ SelectionManager.DeselectAll();
break;
case "delete":
case "backspace":
diff --git a/src/client/views/InkingControl.tsx b/src/client/views/InkingControl.tsx
index da388e532..58c83915b 100644
--- a/src/client/views/InkingControl.tsx
+++ b/src/client/views/InkingControl.tsx
@@ -47,7 +47,7 @@ export class InkingControl extends React.Component {
if (MainOverlayTextBox.Instance.SetColor(color.hex)) return;
let selected = SelectionManager.SelectedDocuments();
let oldColors = selected.map(view => {
- let targetDoc = view.props.Document.isTemplate ? view.props.Document : Doc.GetProto(view.props.Document);
+ let targetDoc = view.props.Document.layout instanceof Doc ? view.props.Document.layout : view.props.Document.isTemplate ? view.props.Document : Doc.GetProto(view.props.Document);
let oldColor = StrCast(targetDoc.backgroundColor);
targetDoc.backgroundColor = this._selectedColor;
return {
diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx
index 282db244e..f5a6715e5 100644
--- a/src/client/views/MainView.tsx
+++ b/src/client/views/MainView.tsx
@@ -7,7 +7,6 @@ import "normalize.css";
import * as React from 'react';
import { SketchPicker } from 'react-color';
import Measure from 'react-measure';
-import * as request from 'request';
import { Doc, DocListCast, Opt, HeightSym } from '../../new_fields/Doc';
import { Id } from '../../new_fields/FieldSymbols';
import { InkTool } from '../../new_fields/InkField';
@@ -393,7 +392,7 @@ export class MainView extends React.Component {
];
if (!ClientUtils.RELEASE) btns.unshift([React.createRef<HTMLDivElement>(), "cat", "Add Cat Image", addImageNode]);
- return < div id="add-nodes-menu" style={{ left: this.flyoutWidth + 5 }} >
+ return < div id="add-nodes-menu" style={{ left: this.flyoutWidth + 20, bottom: 20 }} >
<input type="checkbox" id="add-menu-toggle" ref={this.addMenuToggle} />
<label htmlFor="add-menu-toggle" style={{ marginTop: 2 }} title="Add Node"><p>+</p></label>
@@ -410,7 +409,7 @@ export class MainView extends React.Component {
</button>
</div></li>)}
<li key="undoTest"><button className="add-button round-button" title="Click if undo isn't working" onClick={() => UndoManager.TraceOpenBatches()}><FontAwesomeIcon icon="exclamation" size="sm" /></button></li>
- <li key="color"><button className="add-button round-button" title="Select Color" onClick={() => this.toggleColorPicker()}><div className="toolbar-color-button" style={{ backgroundColor: InkingControl.Instance.selectedColor }} >
+ <li key="color"><button className="add-button round-button" title="Select Color" style={{ zIndex: 1000 }} onClick={() => this.toggleColorPicker()}><div className="toolbar-color-button" style={{ backgroundColor: InkingControl.Instance.selectedColor }} >
<div className="toolbar-color-picker" onClick={this.onColorClick} style={this._colorPickerDisplay ? { color: "black", display: "block" } : { color: "black", display: "none" }}>
<SketchPicker color={InkingControl.Instance.selectedColor} onChange={InkingControl.Instance.switchColor} />
</div>
diff --git a/src/client/views/MetadataEntryMenu.tsx b/src/client/views/MetadataEntryMenu.tsx
index 7fce3dd0c..652e0e91a 100644
--- a/src/client/views/MetadataEntryMenu.tsx
+++ b/src/client/views/MetadataEntryMenu.tsx
@@ -77,6 +77,7 @@ export class MetadataEntryMenu extends React.Component<MetadataEntryProps>{
@action
onValueKeyDown = async (e: React.KeyboardEvent) => {
if (e.key === "Enter") {
+ e.stopPropagation();
const script = KeyValueBox.CompileKVPScript(this._currentValue);
if (!script) return;
let doc = this.props.docs;
diff --git a/src/client/views/ScriptingRepl.tsx b/src/client/views/ScriptingRepl.tsx
index 9e538cf1b..0cff145b6 100644
--- a/src/client/views/ScriptingRepl.tsx
+++ b/src/client/views/ScriptingRepl.tsx
@@ -95,6 +95,7 @@ export class ScriptingValueDisplay extends React.Component<{ scrollToBottom: ()
@observer
export class ScriptingRepl extends React.Component {
@observable private commands: { command: string, result: any }[] = [];
+ private commandsHistory: string[] = [];
@observable private commandString: string = "";
private commandBuffer: string = "";
@@ -113,12 +114,21 @@ export class ScriptingRepl extends React.Component {
Scripting.getGlobals().forEach(global => knownVars[global] = 1);
return root => {
function visit(node: ts.Node) {
+ let skip = false;
+ if (ts.isIdentifier(node)) {
+ if (ts.isParameter(node.parent)) {
+ skip = true;
+ knownVars[node.text] = 1;
+ }
+ }
node = ts.visitEachChild(node, visit, context);
if (ts.isIdentifier(node)) {
const isntPropAccess = !ts.isPropertyAccessExpression(node.parent) || node.parent.expression === node;
const isntPropAssign = !ts.isPropertyAssignment(node.parent) || node.parent.name !== node;
- if (isntPropAccess && isntPropAssign && !(node.text in knownVars) && !(node.text in globalThis)) {
+ if (ts.isParameter(node.parent)) {
+ // delete knownVars[node.text];
+ } else if (isntPropAccess && isntPropAssign && !(node.text in knownVars) && !(node.text in globalThis)) {
const match = node.text.match(/\$([0-9]+)/);
if (match) {
const m = parseInt(match[1]);
@@ -147,13 +157,16 @@ export class ScriptingRepl extends React.Component {
const globals = Scripting.makeMutableGlobalsCopy(docGlobals);
const script = CompileScript(this.commandString, { typecheck: false, addReturn: true, editable: true, params: { args: "any" }, transformer: this.getTransformer(), globals });
if (!script.compiled) {
+ this.commands.push({ command: this.commandString, result: script.errors });
return;
}
const result = script.run({ args: this.args });
if (!result.success) {
+ this.commands.push({ command: this.commandString, result: result.error.toString() });
return;
}
this.commands.push({ command: this.commandString, result: result.result });
+ this.commandsHistory.push(this.commandString);
this.maybeScrollToBottom();
@@ -168,7 +181,7 @@ export class ScriptingRepl extends React.Component {
if (this.historyIndex === 0) {
this.commandBuffer = this.commandString;
}
- this.commandString = this.commands[this.commands.length - 1 - this.historyIndex].command;
+ this.commandString = this.commandsHistory[this.commands.length - 1 - this.historyIndex];
}
break;
}
@@ -179,7 +192,7 @@ export class ScriptingRepl extends React.Component {
this.commandString = this.commandBuffer;
this.commandBuffer = "";
} else {
- this.commandString = this.commands[this.commands.length - 1 - this.historyIndex].command;
+ this.commandString = this.commandsHistory[this.commands.length - 1 - this.historyIndex];
}
}
break;
diff --git a/src/client/views/collections/CollectionBaseView.scss b/src/client/views/collections/CollectionBaseView.scss
index 34bcb705e..583e6f6ca 100644
--- a/src/client/views/collections/CollectionBaseView.scss
+++ b/src/client/views/collections/CollectionBaseView.scss
@@ -6,7 +6,7 @@
border-radius: 0 0 $border-radius $border-radius;
box-sizing: border-box;
border-radius: inherit;
- pointer-events: all;
width:100%;
height:100%;
+ overflow: auto;
} \ No newline at end of file
diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx
index 4cdbd8554..c595a4c56 100644
--- a/src/client/views/collections/CollectionBaseView.tsx
+++ b/src/client/views/collections/CollectionBaseView.tsx
@@ -124,9 +124,8 @@ export class CollectionBaseView extends React.Component<CollectionViewProps> {
@action.bound
moveDocument(doc: Doc, targetCollection: Doc, addDocument: (doc: Doc) => boolean): boolean {
let self = this;
- let targetDataDoc = this.props.fieldExt || this.props.Document.isTemplate ? this.extensionDoc : this.props.Document;
+ let targetDataDoc = this.props.Document;
if (Doc.AreProtosEqual(targetDataDoc, targetCollection)) {
- //if (Doc.AreProtosEqual(this.extensionDoc, targetCollection)) {
return true;
}
if (this.removeDocument(doc)) {
@@ -146,7 +145,10 @@ export class CollectionBaseView extends React.Component<CollectionViewProps> {
const viewtype = this.collectionViewType;
return (
<div id="collectionBaseView"
- style={{ overflow: "auto", boxShadow: `#9c9396 ${StrCast(this.props.Document.boxShadow, "0.2vw 0.2vw 0.8vw")}` }}
+ style={{
+ pointerEvents: this.props.Document.isBackground ? "none" : "all",
+ boxShadow: `#9c9396 ${StrCast(this.props.Document.boxShadow, "0.2vw 0.2vw 0.8vw")}`
+ }}
className={this.props.className || "collectionView-cont"}
onContextMenu={this.props.onContextMenu} ref={this.props.contentRef}>
{viewtype !== undefined ? this.props.children(viewtype, props) : (null)}
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index ba7903419..0865058be 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -539,17 +539,17 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
}
}
+ panelWidth = () => Math.min(this._panelWidth, Math.max(NumCast(this._document!.width), this.nativeWidth()));
+ panelHeight = () => Math.min(this._panelHeight, Math.max(NumCast(this._document!.height), NumCast(this._document!.nativeHeight, this._panelHeight)));
+
+ nativeWidth = () => !BoolCast(this._document!.ignoreAspect) ? NumCast(this._document!.nativeWidth, this._panelWidth) : 0;
+ nativeHeight = () => !BoolCast(this._document!.ignoreAspect) ? NumCast(this._document!.nativeHeight, this._panelHeight) : 0;
- nativeWidth = () => NumCast(this._document!.nativeWidth, this._panelWidth);
- nativeHeight = () => {
- let nh = NumCast(this._document!.nativeHeight, this._panelHeight);
- let res = BoolCast(this._document!.ignoreAspect) ? this._panelHeight : nh;
- return res;
- }
contentScaling = () => {
const nativeH = this.nativeHeight();
const nativeW = this.nativeWidth();
- let wscale = this._panelWidth / nativeW;
+ if (!nativeW || !nativeH) return 1;
+ let wscale = this.panelWidth() / nativeW;
return wscale * nativeH > this._panelHeight ? this._panelHeight / nativeH : wscale;
}
@@ -561,18 +561,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
}
return Transform.Identity();
}
- get scaleToFitMultiplier() {
- let docWidth = NumCast(this._document!.width);
- let docHeight = NumCast(this._document!.height);
- if (NumCast(this._document!.nativeWidth) || !docWidth || !this._panelWidth || !this._panelHeight) return 1;
- if (StrCast(this._document!.layout).indexOf("Collection") === -1 ||
- !BoolCast(this._document!.fitToContents, false) ||
- NumCast(this._document!.viewType) !== CollectionViewType.Freeform) return 1;
- let scaling = Math.max(1, this._panelWidth / docWidth * docHeight > this._panelHeight ?
- this._panelHeight / docHeight : this._panelWidth / docWidth);
- return scaling;
- }
- get previewPanelCenteringOffset() { return (this._panelWidth - this.nativeWidth() * this.contentScaling()) / 2; }
+ get previewPanelCenteringOffset() { return this.nativeWidth && !BoolCast(this._document!.ignoreAspect) ? (this._panelWidth - this.nativeWidth() * this.contentScaling()) / 2 : 0; }
addDocTab = (doc: Doc, dataDoc: Doc | undefined, location: string) => {
if (doc.dockingConfig) {
@@ -588,6 +577,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
return (null);
}
let resolvedDataDoc = this._document.layout instanceof Doc ? this._document : this._dataDoc;
+ console.log("pw = " + this.panelWidth() + "," + this.panelHeight() + " " + this.contentScaling());
return <DocumentView key={this._document[Id]}
Document={this._document}
DataDoc={resolvedDataDoc}
@@ -595,8 +585,8 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
addDocument={undefined}
removeDocument={undefined}
ContentScaling={this.contentScaling}
- PanelWidth={this.nativeWidth}
- PanelHeight={this.nativeHeight}
+ PanelWidth={this.panelWidth}
+ PanelHeight={this.panelHeight}
ScreenToLocalTransform={this.ScreenToLocalTransform}
renderDepth={0}
selectOnLoad={false}
@@ -610,18 +600,15 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
}
@computed get content() {
- if (!this._document) {
- return (null);
- }
return (
<div className="collectionDockingView-content" ref={this._mainCont}
- style={{ transform: `translate(${this.previewPanelCenteringOffset}px, 0px) scale(${this.scaleToFitMultiplier})` }}>
+ style={{ transform: `translate(${this.previewPanelCenteringOffset}px, 0px)` }}>
{this.docView}
</div >);
}
render() {
- if (!this._isActive) return null;
+ if (!this._isActive || !this._document) return null;
let theContent = this.content;
return !this._document ? (null) :
<Measure offset onResize={action((r: any) => { this._panelWidth = r.offset.width; this._panelHeight = r.offset.height; })}>
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 176872503..d504f9799 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -1,6 +1,6 @@
import React = require("react");
import { library } from '@fortawesome/fontawesome-svg-core';
-import { faCog, faPlus, faSortUp, faSortDown } from '@fortawesome/free-solid-svg-icons';
+import { faCog, faPlus, faTable, faSortUp, faSortDown } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, observable, trace, untracked } from "mobx";
import { observer } from "mobx-react";
@@ -11,8 +11,8 @@ import { Doc, DocListCast, DocListCastAsync, Field, FieldResult, Opt } from "../
import { Id } from "../../../new_fields/FieldSymbols";
import { List } from "../../../new_fields/List";
import { listSpec } from "../../../new_fields/Schema";
-import { Cast, FieldValue, NumCast, StrCast, BoolCast } from "../../../new_fields/Types";
import { Docs, DocumentOptions } from "../../documents/Documents";
+import { Cast, FieldValue, NumCast, StrCast } from "../../../new_fields/Types";
import { Gateway } from "../../northstar/manager/Gateway";
import { SetupDrag, DragManager } from "../../util/DragManager";
import { CompileScript, ts, Transformer } from "../../util/Scripting";
@@ -42,6 +42,7 @@ import { SchemaHeaderField, RandomPastel } from "../../../new_fields/SchemaHeade
library.add(faCog, faPlus, faSortUp, faSortDown);
+library.add(faTable);
// bcz: need to add drag and drop of rows and columns. This seems like it might work for rows: https://codesandbox.io/s/l94mn1q657
export enum ColumnType {
@@ -746,7 +747,7 @@ export class SchemaTable extends React.Component<SchemaTableProps> {
onContextMenu = (e: React.MouseEvent): void => {
if (!e.isPropagationStopped() && this.props.Document[Id] !== "mainDoc") { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7
- ContextMenu.Instance.addItem({ description: "Make DB", event: this.makeDB });
+ ContextMenu.Instance.addItem({ description: "Make DB", event: this.makeDB, icon: "table" });
}
}
@@ -878,7 +879,7 @@ export class CollectionSchemaPreview extends React.Component<CollectionSchemaPre
height: "100%"
}}>
<DocumentView
- DataDoc={this.props.Document.layout instanceof Doc ? this.props.Document : this.props.DataDocument}
+ DataDoc={this.props.DataDocument}
Document={this.props.Document}
fitToBox={this.props.fitToBox}
renderDepth={this.props.renderDepth + 1}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index e897c5676..b96b1f8c8 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -38,6 +38,13 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
@computed get singleColumn() { return BoolCast(this.props.Document.singleColumn, true); }
@computed get columnWidth() { return this.singleColumn ? (this.props.PanelWidth() / (this.props as any).ContentScaling() - 2 * this.xMargin) : Math.min(this.props.PanelWidth() - 2 * this.xMargin, NumCast(this.props.Document.columnWidth, 250)); }
@computed get filteredChildren() { return this.childDocs.filter(d => !d.isMinimized); }
+
+ get layoutDoc() {
+ // if this document's layout field contains a document (ie, a rendering template), then we will use that
+ // to determine the render JSX string, otherwise the layout field should directly contain a JSX layout string.
+ return this.props.Document.layout instanceof Doc ? this.props.Document.layout : this.props.Document;
+ }
+
get Sections() {
let sectionFilter = StrCast(this.props.Document.sectionFilter);
let sectionHeaders = this.sectionHeaders;
@@ -69,13 +76,20 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
}
return fields;
}
+
componentDidMount() {
// is there any reason this needs to exist? -syip
- // this._heightDisposer = reaction(() => [this.yMargin, this.gridGap, this.columnWidth, this.childDocs.map(d => [d.height, d.width, d.zoomBasis, d.nativeHeight, d.nativeWidth, d.isMinimized])],
- // () => this.singleColumn &&
- // (this.props.Document.height = this.Sections.size * 50 + this.filteredChildren.reduce((height, d, i) =>
- // height + this.getDocHeight(d) + (i === this.filteredChildren.length - 1 ? this.yMargin : this.gridGap), this.yMargin))
- // , { fireImmediately: true });
+ this._heightDisposer = reaction(() => [this.yMargin, this.props.Document[WidthSym](), this.gridGap, this.columnWidth, this.childDocs.map(d => [d.height, d.width, d.zoomBasis, d.nativeHeight, d.nativeWidth, d.isMinimized])],
+ () => {
+ if (this.singleColumn && BoolCast(this.props.Document.autoHeight)) {
+ let hgt = this.Sections.size * 50 + this.filteredChildren.reduce((height, d, i) => {
+ let pair = Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, this.props.fieldKey, d);
+ return height + this.getDocHeight(pair.layout) + (i === this.filteredChildren.length - 1 ? this.yMargin : this.gridGap);
+ }, this.yMargin);
+ (this.props.DataDoc && this.props.DataDoc.layout === this.layoutDoc ? this.props.DataDoc : this.layoutDoc)
+ .height = hgt * (this.props as any).ContentScaling();
+ }
+ }, { fireImmediately: true });
// reset section headers when a new filter is inputted
this._sectionFilterDisposer = reaction(
@@ -103,16 +117,12 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
return doc.type === DocumentType.IMG || doc.type === DocumentType.VID ? { title: "title", caption: "caption" } : {};
}
- getDisplayDoc(layoutDoc: Doc, d: Doc, dxf: () => Transform) {
- let resolvedDataDoc = !this.props.Document.isTemplate && this.props.DataDoc !== this.props.Document ? this.props.DataDoc : undefined;
- let headings = Array.from(this.Sections.keys());
- // let uniqueHeadings = headings.map((i, idx) => headings.indexOf(i) === idx);
- let width = () => (d.nativeWidth ? Math.min(layoutDoc[WidthSym](), this.columnWidth) : this.columnWidth) / (headings.length + 1);
+ getDisplayDoc(layoutDoc: Doc, dataDoc: Doc | undefined, dxf: () => Transform, width: () => number) {
let height = () => this.getDocHeight(layoutDoc);
let finalDxf = () => dxf().scale(this.columnWidth / layoutDoc[WidthSym]());
return <CollectionSchemaPreview
Document={layoutDoc}
- DataDocument={resolvedDataDoc}
+ DataDocument={dataDoc}
showOverlays={this.overlays}
renderDepth={this.props.renderDepth}
fitToBox={true}
@@ -133,9 +143,12 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
getDocHeight(d: Doc) {
let nw = NumCast(d.nativeWidth);
let nh = NumCast(d.nativeHeight);
- let aspect = nw && nh ? nh / nw : 1;
- let wid = Math.min(d[WidthSym](), this.columnWidth);
- return (nw && nh) ? wid * aspect : d[HeightSym]();
+ if (!BoolCast(d.ignoreAspect) && nw && nh) {
+ let aspect = nw && nh ? nh / nw : 1;
+ let wid = Math.min(d[WidthSym](), this.columnWidth);
+ return wid * aspect;
+ }
+ return d[HeightSym]();
}
columnDividerDown = (e: React.PointerEvent) => {
@@ -151,7 +164,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
let dragPos = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY)[0];
let delta = dragPos - this._columnStart;
this._columnStart = dragPos;
- this.props.Document.columnWidth = this.columnWidth + delta;
+ this.layoutDoc.columnWidth = this.columnWidth + delta;
}
@action
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index ea2a302ff..1a5d203f9 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -5,7 +5,7 @@ import { Doc, WidthSym } from "../../../new_fields/Doc";
import { CollectionStackingView } from "./CollectionStackingView";
import { Id } from "../../../new_fields/FieldSymbols";
import { Utils } from "../../../Utils";
-import { NumCast, StrCast } from "../../../new_fields/Types";
+import { NumCast, StrCast, BoolCast } from "../../../new_fields/Types";
import { EditableView } from "../EditableView";
import { action, observable, computed } from "mobx";
import { undoBatch } from "../../util/UndoManager";
@@ -68,15 +68,16 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
}
children(docs: Doc[]) {
- let style = this.props.parent;
+ let parent = this.props.parent;
this.props.parent._docXfs.length = 0;
return docs.map((d, i) => {
- let layoutDoc = Doc.expandTemplateLayout(d, this.props.parent.props.DataDoc);
+ let layoutDoc = Doc.expandTemplateLayout(d, parent.props.DataDoc);
let headings = this.props.headings();
let uniqueHeadings = headings.map((i, idx) => headings.indexOf(i) === idx);
- let width = () => (d.nativeWidth ? Math.min(layoutDoc[WidthSym](), style.columnWidth) : style.columnWidth) / (uniqueHeadings.length + 1);
- let height = () => this.props.parent.getDocHeight(layoutDoc);
- if (style.singleColumn) {
+ let pair = Doc.GetLayoutDataDocPair(parent.props.Document, parent.props.DataDoc, parent.props.fieldKey, d)
+ let width = () => (d.nativeWidth && !BoolCast(d.ignoreAspect) ? Math.min(pair.layout[WidthSym](), parent.columnWidth) : parent.columnWidth) / (uniqueHeadings.length + 1);
+ let height = () => parent.getDocHeight(pair.layout);
+ if (parent.singleColumn) {
let dxf;
let dref = React.createRef<HTMLDivElement>();
if (uniqueHeadings.length > 0) {
@@ -89,16 +90,18 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
this.props.parent._docXfs.push({ dxf: dxf, width: width, height: height });
}
let rowHgtPcnt = height();
- return <div className="collectionStackingView-columnDoc" key={d[Id]} ref={dref} style={{ width: width(), marginTop: i === 0 ? 0 : style.gridGap, height: `${rowHgtPcnt}` }} >
- {this.props.parent.getDisplayDoc(layoutDoc, d, dxf)}
+ return <div className="collectionStackingView-columnDoc" key={d[Id]} ref={dref} style={{ width: width(), marginTop: i === 0 ? 0 : parent.gridGap, height: `${rowHgtPcnt}` }} >
+ {this.props.parent.getDisplayDoc(layoutDoc, d, dxf, width)}
</div>;
} else {
let dref = React.createRef<HTMLDivElement>();
let dxf = () => this.getDocTransform(layoutDoc, dref.current!);
- let rowSpan = Math.ceil((height() + style.gridGap) / style.gridGap);
this.props.parent._docXfs.push({ dxf: dxf, width: width, height: height });
- return <div className="collectionStackingView-masonryDoc" key={d[Id]} ref={dref} style={{ gridRowEnd: `span ${rowSpan}` }} >
- {this.props.parent.getDisplayDoc(layoutDoc, d, dxf)}
+ let rowHgtPcnt = height();
+ let rowSpan = Math.ceil((height() + parent.gridGap) / parent.gridGap);
+ let divStyle = parent.singleColumn ? { width: width(), marginTop: i === 0 ? 0 : parent.gridGap, height: `${rowHgtPcnt}` } : { gridRowEnd: `span ${rowSpan}` };
+ return <div className="collectionStackingView-masonryDoc" key={d[Id]} ref={dref} style={divStyle} >
+ {this.props.parent.getDisplayDoc(layoutDoc, d, dxf, width)}
</div>;
}
});
@@ -119,7 +122,9 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
getDocTransform(doc: Doc, dref: HTMLDivElement) {
let { scale, translateX, translateY } = Utils.GetScreenTransform(dref);
- return this.offsetTransform(doc, translateX, translateY);
+ let outerXf = Utils.GetScreenTransform(this.props.parent._masonryGridRef!);
+ let offset = this.props.parent.props.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY);
+ return this.props.parent.props.ScreenToLocalTransform().translate(offset[0], offset[1]).scale(NumCast(doc.width, 1) / this.props.parent.columnWidth);
}
getValue = (value: string): any => {
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 98447e824..a15ed8f94 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -118,7 +118,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
} else if (de.data.moveDocument) {
let movedDocs = de.data.options === this.props.Document[Id] ? de.data.draggedDocuments : de.data.droppedDocuments;
added = movedDocs.reduce((added: boolean, d) =>
- de.data.moveDocument(d, /*this.props.DataDoc ? this.props.DataDoc :*/ this.props.Document, this.props.addDocument) || added, false);
+ de.data.moveDocument(d, this.props.Document, this.props.addDocument) || added, false);
} else {
added = de.data.droppedDocuments.reduce((added: boolean, d) => this.props.addDocument(d) || added, false);
}
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index eeb33b40d..4d31c3ae7 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -1,5 +1,5 @@
import { library } from '@fortawesome/fontawesome-svg-core';
-import { faAngleRight, faCamera, faExpand, faTrash, faBell, faCaretDown, faCaretRight, faArrowsAltH, faCaretSquareDown, faCaretSquareRight, faTrashAlt } from '@fortawesome/free-solid-svg-icons';
+import { faAngleRight, faCamera, faExpand, faTrash, faBell, faCaretDown, faCaretRight, faArrowsAltH, faCaretSquareDown, faCaretSquareRight, faTrashAlt, faPlus, faMinus } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, observable, trace, untracked } from "mobx";
import { observer } from "mobx-react";
@@ -61,7 +61,7 @@ library.add(faCaretRight);
library.add(faCaretSquareDown);
library.add(faCaretSquareRight);
library.add(faArrowsAltH);
-
+library.add(faPlus, faMinus);
@observer
/**
* Component that takes in a document prop and a boolean whether it's collapsed or not.
@@ -201,7 +201,11 @@ class TreeView extends React.Component<TreeViewProps> {
let headerElements = (
<span className="collectionTreeView-keyHeader" key={this.treeViewExpandedView}
- onPointerDown={action(() => this.props.document.treeViewExpandedView = this.treeViewExpandedView === "data" ? "fields" : this.treeViewExpandedView === "fields" && this.props.document.layout ? "layout" : "data")}>
+ onPointerDown={action(() => {
+ this.props.document.treeViewExpandedView = this.treeViewExpandedView === "data" ? "fields" :
+ this.treeViewExpandedView === "fields" && this.props.document.layout ? "layout" : "data";
+ this._collapsed = false;
+ })}>
{this.treeViewExpandedView}
</span>);
let dataDocs = CollectionDockingView.Instance ? Cast(CollectionDockingView.Instance.props.Document[this.fieldKey], listSpec(Doc), []) : [];
@@ -356,7 +360,7 @@ class TreeView extends React.Component<TreeViewProps> {
let remDoc = (doc: Doc) => this.remove(doc, key);
let addDoc = (doc: Doc, addBefore?: Doc, before?: boolean) => Doc.AddDocToList(this.dataDoc, key, doc, addBefore, before);
contentElement = key === "links" ? this.renderLinks() :
- TreeView.GetChildElements(docList instanceof Doc ? [docList as Doc] : DocListCast(docList), this.props.treeViewId, realDoc, undefined, key, addDoc, remDoc, this.move,
+ TreeView.GetChildElements(docList instanceof Doc ? [docList] : DocListCast(docList), this.props.treeViewId, realDoc, undefined, key, addDoc, remDoc, this.move,
this.props.dropAction, this.props.addDocTab, this.props.ScreenToLocalTransform, this.props.outerXf, this.props.active, this.props.panelWidth, this.props.renderDepth);
} else {
contentElement = <EditableView
@@ -518,8 +522,8 @@ export class CollectionTreeView extends CollectionSubView(Document) {
onContextMenu = (e: React.MouseEvent): void => {
// need to test if propagation has stopped because GoldenLayout forces a parallel react hierarchy to be created for its top-level layout
if (!e.isPropagationStopped() && this.props.Document.workspaceLibrary) { // excludeFromLibrary means this is the user document
- ContextMenu.Instance.addItem({ description: "Create Workspace", event: undoBatch(() => MainView.Instance.createNewWorkspace()) });
- ContextMenu.Instance.addItem({ description: "Delete Workspace", event: undoBatch(() => this.remove(this.props.Document)) });
+ ContextMenu.Instance.addItem({ description: "Create Workspace", event: undoBatch(() => MainView.Instance.createNewWorkspace()), icon: "plus" });
+ ContextMenu.Instance.addItem({ description: "Delete Workspace", event: undoBatch(() => this.remove(this.props.Document)), icon: "minus" });
e.stopPropagation();
e.preventDefault();
ContextMenu.Instance.displayMenu(e.pageX - 15, e.pageY - 15);
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index d90eba401..81c84852a 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -19,6 +19,7 @@ import { StrCast, PromiseValue } from '../../../new_fields/Types';
import { DocumentType } from '../../documents/Documents';
import { CollectionStackingViewChrome, CollectionViewBaseChrome } from './CollectionViewChromes';
import { observable, action, runInAction } from 'mobx';
+import { faEye } from '@fortawesome/free-regular-svg-icons';
export const COLLECTION_BORDER_WIDTH = 2;
library.add(faTh);
@@ -30,7 +31,7 @@ library.add(faThList);
library.add(faFingerprint);
library.add(faColumns);
library.add(faEllipsisV);
-library.add(faImage);
+library.add(faImage, faEye);
@observer
export class CollectionView extends React.Component<FieldViewProps> {
@@ -100,7 +101,7 @@ export class CollectionView extends React.Component<FieldViewProps> {
break;
}
}
- ContextMenu.Instance.addItem({ description: "View Modes...", subitems: subItems });
+ ContextMenu.Instance.addItem({ description: "View Modes...", subitems: subItems, icon: "eye" });
ContextMenu.Instance.addItem({ description: "Apply Template", event: undoBatch(() => this.props.addDocTab && this.props.addDocTab(Doc.ApplyTemplate(this.props.Document)!, undefined, "onRight")), icon: "project-diagram" });
}
}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
index b546d1b78..6af87b138 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLinkView.tsx
@@ -21,10 +21,10 @@ export class CollectionFreeFormLinkView extends React.Component<CollectionFreeFo
if (e.button === 0 && !InkingControl.Instance.selectedTool) {
let a = this.props.A;
let b = this.props.B;
- let x1 = NumCast(a.x) + (BoolCast(a.isMinimized, false) ? 5 : a[WidthSym]() / 2);
- let y1 = NumCast(a.y) + (BoolCast(a.isMinimized, false) ? 5 : a[HeightSym]() / 2);
- let x2 = NumCast(b.x) + (BoolCast(b.isMinimized, false) ? 5 : b[WidthSym]() / 2);
- let y2 = NumCast(b.y) + (BoolCast(b.isMinimized, false) ? 5 : b[HeightSym]() / 2);
+ let x1 = NumCast(a.x) + (BoolCast(a.isMinimized) ? 5 : a[WidthSym]() / 2);
+ let y1 = NumCast(a.y) + (BoolCast(a.isMinimized) ? 5 : a[HeightSym]() / 2);
+ let x2 = NumCast(b.x) + (BoolCast(b.isMinimized) ? 5 : b[WidthSym]() / 2);
+ let y2 = NumCast(b.y) + (BoolCast(b.isMinimized) ? 5 : b[HeightSym]() / 2);
// this.props.LinkDocs.map(l => {
// let width = l[WidthSym]();
// l.x = (x1 + x2) / 2 - width / 2;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 74535222f..d70022280 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -13,7 +13,7 @@ import { SelectionManager } from "../../../util/SelectionManager";
import { Transform } from "../../../util/Transform";
import { undoBatch, UndoManager } from "../../../util/UndoManager";
import { COLLECTION_BORDER_WIDTH } from "../../../views/globalCssVariables.scss";
-import { ContextMenu } from "../../ContextMenu";
+import { SubmenuProps, ContextMenuProps } from "../../ContextMenuItem";
import { InkingCanvas } from "../../InkingCanvas";
import { CollectionFreeFormDocumentView } from "../../nodes/CollectionFreeFormDocumentView";
import { DocumentContentsView } from "../../nodes/DocumentContentsView";
@@ -34,9 +34,12 @@ import { CompileScript } from "../../../util/Scripting";
import { CognitiveServices } from "../../../cognitive_services/CognitiveServices";
import { library } from "@fortawesome/fontawesome-svg-core";
import { faEye } from "@fortawesome/free-regular-svg-icons";
-import { faTable, faPaintBrush, faAsterisk } from "@fortawesome/free-solid-svg-icons";
+import { faTable, faPaintBrush, faAsterisk, faExpandArrowsAlt, faCompressArrowsAlt, faCompass } from "@fortawesome/free-solid-svg-icons";
+import { undo } from "prosemirror-history";
+import { number } from "prop-types";
+import { ContextMenu } from "../../ContextMenu";
-library.add(faEye, faTable, faPaintBrush);
+library.add(faEye, faTable, faPaintBrush, faExpandArrowsAlt, faCompressArrowsAlt, faCompass);
export const panZoomSchema = createSchema({
panX: "number",
@@ -58,24 +61,29 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
private get _pheight() { return this.props.PanelHeight(); }
private inkKey = "ink";
+ get parentScaling() {
+ return (this.props as any).ContentScaling && this.fitToBox && !this.isAnnotationOverlay ? (this.props as any).ContentScaling() : 1;
+ }
+
@computed get contentBounds() {
- let bounds = this.props.fitToBox && !NumCast(this.nativeWidth) ? Doc.ComputeContentBounds(DocListCast(this.props.Document.data)) : undefined;
+ let bounds = this.fitToBox && !this.isAnnotationOverlay ? Doc.ComputeContentBounds(DocListCast(this.props.Document.data)) : undefined;
return {
panX: bounds ? (bounds.x + bounds.r) / 2 : this.Document.panX || 0,
panY: bounds ? (bounds.y + bounds.b) / 2 : this.Document.panY || 0,
- scale: bounds ? Math.min(this.props.PanelHeight() / (bounds.b - bounds.y), this.props.PanelWidth() / (bounds.r - bounds.x)) : this.Document.scale || 1
+ scale: (bounds ? Math.min(this.props.PanelHeight() / (bounds.b - bounds.y), this.props.PanelWidth() / (bounds.r - bounds.x)) : this.Document.scale || 1) / this.parentScaling
};
}
- @computed get nativeWidth() { return this.Document.nativeWidth || 0; }
- @computed get nativeHeight() { return this.Document.nativeHeight || 0; }
+ @computed get fitToBox() { return this.props.fitToBox || this.props.Document.fitToBox; }
+ @computed get nativeWidth() { return this.fitToBox ? 0 : this.Document.nativeWidth || 0; }
+ @computed get nativeHeight() { return this.fitToBox ? 0 : this.Document.nativeHeight || 0; }
public get isAnnotationOverlay() { return this.props.fieldExt ? true : false; } // fieldExt will be "" or "annotation". should maybe generalize this, or make it more specific (ie, 'annotation' instead of 'fieldExt')
private get borderWidth() { return this.isAnnotationOverlay ? 0 : COLLECTION_BORDER_WIDTH; }
private panX = () => this.contentBounds.panX;
private panY = () => this.contentBounds.panY;
private zoomScaling = () => this.contentBounds.scale;
- private centeringShiftX = () => !this.nativeWidth ? this._pwidth / 2 : 0; // shift so pan position is at center of window for non-overlay collections
- private centeringShiftY = () => !this.nativeHeight ? this._pheight / 2 : 0;// shift so pan position is at center of window for non-overlay collections
+ private centeringShiftX = () => !this.nativeWidth && !this.isAnnotationOverlay ? this._pwidth / 2 / this.parentScaling : 0; // shift so pan position is at center of window for non-overlay collections
+ private centeringShiftY = () => !this.nativeHeight && !this.isAnnotationOverlay ? this._pheight / 2 / this.parentScaling : 0;// shift so pan position is at center of window for non-overlay collections
private getTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.borderWidth + 1, -this.borderWidth + 1).translate(-this.centeringShiftX(), -this.centeringShiftY()).transform(this.getLocalTransform());
private getContainerTransform = (): Transform => this.props.ScreenToLocalTransform().translate(-this.borderWidth, -this.borderWidth);
private getLocalTransform = (): Transform => Transform.Identity().scale(1 / this.zoomScaling()).translate(this.panX(), this.panY());
@@ -109,11 +117,11 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
@undoBatch
@action
drop = (e: Event, de: DragManager.DropEvent) => {
+ let xf = this.getTransform();
if (super.drop(e, de)) {
if (de.data instanceof DragManager.DocumentDragData) {
if (de.data.droppedDocuments.length) {
- let dragDoc = de.data.droppedDocuments[0];
- let [xp, yp] = this.getTransform().transformPoint(de.x, de.y);
+ let [xp, yp] = xf.transformPoint(de.x, de.y);
let x = xp - de.data.xOffset;
let y = yp - de.data.yOffset;
let dropX = NumCast(de.data.droppedDocuments[0].x);
@@ -296,7 +304,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
doc.zIndex = docs.length + 1;
}
- focusDocument = (doc: Doc, willZoom: boolean) => {
+ focusDocument = (doc: Doc, willZoom: boolean, scale?: number) => {
const panX = this.Document.panX;
const panY = this.Document.panY;
const id = this.Document[Id];
@@ -328,20 +336,20 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
this.props.Document.panTransformType = "Ease";
this.props.focus(this.props.Document);
if (willZoom) {
- this.setScaleToZoom(doc);
+ this.setScaleToZoom(doc, scale);
}
}
- setScaleToZoom = (doc: Doc) => {
+ setScaleToZoom = (doc: Doc, scale: number = 0.5) => {
let p = this.props;
let PanelHeight = p.PanelHeight();
let panelWidth = p.PanelWidth();
let docHeight = NumCast(doc.height);
let docWidth = NumCast(doc.width);
- let targetHeight = 0.5 * PanelHeight;
- let targetWidth = 0.5 * panelWidth;
+ let targetHeight = scale * PanelHeight;
+ let targetWidth = scale * panelWidth;
let maxScaleX: number = targetWidth / docWidth;
let maxScaleY: number = targetHeight / docHeight;
@@ -363,24 +371,18 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
getChildDocumentViewProps(childDocLayout: Doc): DocumentViewProps {
let self = this;
- let resolvedDataDoc = !this.props.Document.isTemplate && this.props.DataDoc !== this.props.Document ? this.props.DataDoc : undefined;
- let layoutDoc = childDocLayout;
- if (resolvedDataDoc && Doc.WillExpandTemplateLayout(childDocLayout, resolvedDataDoc)) {
- Doc.UpdateDocumentExtensionForField(resolvedDataDoc, this.props.fieldKey);
- let fieldExtensionDoc = Doc.resolvedFieldDataDoc(resolvedDataDoc, StrCast(childDocLayout.templateField, StrCast(childDocLayout.title)), "dummy");
- layoutDoc = Doc.expandTemplateLayout(childDocLayout, fieldExtensionDoc !== resolvedDataDoc ? fieldExtensionDoc : undefined);
- } else layoutDoc = Doc.expandTemplateLayout(childDocLayout, resolvedDataDoc);
+ let pair = Doc.GetLayoutDataDocPair(this.props.Document, this.props.DataDoc, this.props.fieldKey, childDocLayout);
return {
- DataDoc: resolvedDataDoc !== layoutDoc && resolvedDataDoc ? resolvedDataDoc : undefined,
- Document: layoutDoc,
+ DataDoc: pair.data,
+ Document: pair.layout,
addDocument: this.props.addDocument,
removeDocument: this.props.removeDocument,
moveDocument: this.props.moveDocument,
ScreenToLocalTransform: this.getTransform,
renderDepth: this.props.renderDepth + 1,
- selectOnLoad: layoutDoc[Id] === this._selectOnLoaded,
- PanelWidth: layoutDoc[WidthSym],
- PanelHeight: layoutDoc[HeightSym],
+ selectOnLoad: pair.layout[Id] === this._selectOnLoaded,
+ PanelWidth: pair.layout[WidthSym],
+ PanelHeight: pair.layout[HeightSym],
ContentScaling: returnOne,
ContainingCollectionView: this.props.CollectionView,
focus: this.focusDocument,
@@ -400,7 +402,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
removeDocument: this.props.removeDocument,
moveDocument: this.props.moveDocument,
ScreenToLocalTransform: this.getTransform,
- renderDepth: this.props.renderDepth + 1,
+ renderDepth: this.props.renderDepth,
selectOnLoad: layoutDoc[Id] === this._selectOnLoaded,
PanelWidth: layoutDoc[WidthSym],
PanelHeight: layoutDoc[HeightSym],
@@ -470,7 +472,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
if (!(doc instanceof Doc)) return prev;
var page = NumCast(doc.page, -1);
if ((Math.abs(Math.round(page) - Math.round(curPage)) < 3) || page === -1) {
- let minim = BoolCast(doc.isMinimized, false);
+ let minim = BoolCast(doc.isMinimized);
if (minim === undefined || !minim) {
const pos = script ? this.getCalculatedPositions(script, { doc, index: prev.length, collection: this.Document, docs, state }) : {};
state = pos.state === undefined ? state : pos.state;
@@ -491,7 +493,13 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
}
onContextMenu = () => {
- ContextMenu.Instance.addItem({
+ let layoutItems: ContextMenuProps[] = [];
+ layoutItems.push({
+ description: `${this.fitToBox ? "Unset" : "Set"} Fit To Container`,
+ event: undoBatch(async () => this.props.Document.fitToBox = !this.fitToBox),
+ icon: !this.fitToBox ? "expand-arrows-alt" : "compress-arrows-alt"
+ });
+ layoutItems.push({
description: "Arrange contents in grid",
icon: "table",
event: async () => {
@@ -518,6 +526,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
}, "arrange contents");
}
});
+ ContextMenu.Instance.addItem({ description: "Layout...", subitems: layoutItems, icon: "compass" });
ContextMenu.Instance.addItem({
description: "Analyze Strokes", event: async () => {
let data = Cast(this.fieldExtensionDoc[this.inkKey], InkField);
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 2e54a9736..1c767e012 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -366,7 +366,7 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
marqueeSelect() {
let selRect = this.Bounds;
let selection: Doc[] = [];
- this.props.activeDocuments().map(doc => {
+ this.props.activeDocuments().filter(doc => !doc.isBackground).map(doc => {
var z = NumCast(doc.zoomBasis, 1);
var x = NumCast(doc.x);
var y = NumCast(doc.y);
diff --git a/src/client/views/nodes/ButtonBox.scss b/src/client/views/nodes/ButtonBox.scss
index 97cc91128..92beafa15 100644
--- a/src/client/views/nodes/ButtonBox.scss
+++ b/src/client/views/nodes/ButtonBox.scss
@@ -2,9 +2,11 @@
width: 100%;
height: 100%;
pointer-events: all;
+ border-radius: inherit;
}
.buttonBox-mainButton {
width: 100%;
height: 100%;
+ border-radius: inherit;
} \ No newline at end of file
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 389b9f68b..7ffd760e0 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -35,21 +35,9 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
@computed get zoom(): number { return 1 / FieldValue(this.Document.zoomBasis, 1); }
@computed get nativeWidth(): number { return FieldValue(this.Document.nativeWidth, 0); }
@computed get nativeHeight(): number { return FieldValue(this.Document.nativeHeight, 0); }
-
- set width(w: number) {
- this.Document.width = w;
- if (this.nativeWidth && this.nativeHeight) {
- this.Document.height = this.nativeHeight / this.nativeWidth * w;
- }
- }
- set height(h: number) {
- this.Document.height = h;
- if (this.nativeWidth && this.nativeHeight) {
- this.Document.width = this.nativeWidth / this.nativeHeight * h;
- }
- }
@computed get scaleToOverridingWidth() { return this.width / NumCast(this.props.Document.width, this.width); }
- contentScaling = () => this.nativeWidth > 0 ? this.width / this.nativeWidth : 1;
+
+ contentScaling = () => this.nativeWidth > 0 && !BoolCast(this.props.Document.ignoreAspect) ? this.width / this.nativeWidth : 1;
panelWidth = () => this.props.PanelWidth();
panelHeight = () => this.props.PanelHeight();
getTransform = (): Transform => this.props.ScreenToLocalTransform()
diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss
index 3a4b46b7e..7c72fb6e6 100644
--- a/src/client/views/nodes/DocumentView.scss
+++ b/src/client/views/nodes/DocumentView.scss
@@ -4,7 +4,6 @@
position: inherit;
top: 0;
left:0;
- pointer-events: all;
// background: $light-color; //overflow: hidden;
transform-origin: left top;
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 16cfeba3f..99f073459 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -39,6 +39,8 @@ import { OverlayView } from '../OverlayView';
import { ScriptingRepl } from '../ScriptingRepl';
import { ClientUtils } from '../../util/ClientUtils';
import { EditableView } from '../EditableView';
+import { faHandPointer, faHandPointRight } from '@fortawesome/free-regular-svg-icons';
+import { DocumentDecorations } from '../DocumentDecorations';
const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this?
library.add(fa.faTrash);
@@ -60,8 +62,7 @@ library.add(fa.faCrosshairs);
library.add(fa.faDesktop);
library.add(fa.faUnlock);
library.add(fa.faLock);
-library.add(fa.faLaptopCode);
-
+library.add(fa.faLaptopCode, fa.faMale, fa.faCopy, fa.faHandPointRight, fa.faCompass, fa.faSnowflake);
// const linkSchema = createSchema({
// title: "string",
@@ -88,7 +89,7 @@ export interface DocumentViewProps {
ContentScaling: () => number;
PanelWidth: () => number;
PanelHeight: () => number;
- focus: (doc: Doc, willZoom: boolean) => void;
+ focus: (doc: Doc, willZoom: boolean, scale?: number) => void;
selectOnLoad: boolean;
parentActive: () => boolean;
whenActiveChanged: (isActive: boolean) => void;
@@ -275,7 +276,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
let iconAnimating = Cast(maximizedDoc.isIconAnimating, List);
if (!iconAnimating || (Date.now() - iconAnimating[2] > 1000)) {
if (isMinimized === undefined) {
- isMinimized = BoolCast(maximizedDoc.isMinimized, false);
+ isMinimized = BoolCast(maximizedDoc.isMinimized);
}
maximizedDoc.willMaximize = isMinimized;
maximizedDoc.isMinimized = false;
@@ -298,6 +299,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
let fullScreenAlias = Doc.MakeAlias(this.props.Document);
fullScreenAlias.templates = new List<string>();
Doc.UseDetailLayout(fullScreenAlias);
+ fullScreenAlias.showCaption = true;
this.props.addDocTab(fullScreenAlias, this.dataDoc, "inTab");
SelectionManager.DeselectAll();
this.props.Document.libraryBrush = false;
@@ -307,7 +309,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
Math.abs(e.clientY - this._downY) < Utils.DRAG_THRESHOLD)) {
SelectionManager.SelectDoc(this, e.ctrlKey);
let isExpander = (e.target as any).id === "isExpander";
- if (BoolCast(this.props.Document.isButton, false) || isExpander) {
+ if (BoolCast(this.props.Document.isButton) || isExpander) {
SelectionManager.DeselectAll();
let subBulletDocs = await DocListCastAsync(this.props.Document.subBulletDocs);
let maximizedDocs = await DocListCastAsync(this.props.Document.maximizedDocs);
@@ -325,7 +327,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
maxLocation = this.props.Document.maximizeLocation = (ctrlKey ? maxLocation : (maxLocation === "inPlace" || !maxLocation ? "inTab" : "inPlace"));
if (!maxLocation || maxLocation === "inPlace") {
let hadView = expandedDocs.length === 1 && DocumentManager.Instance.getDocumentView(expandedDocs[0], this.props.ContainingCollectionView);
- let wasMinimized = !hadView && expandedDocs.reduce((min, d) => !min && !BoolCast(d.IsMinimized, false), false);
+ let wasMinimized = !hadView && expandedDocs.reduce((min, d) => !min && !BoolCast(d.IsMinimized), false);
expandedDocs.forEach(maxDoc => Doc.GetProto(maxDoc).isMinimized = false);
let hasView = expandedDocs.length === 1 && DocumentManager.Instance.getDocumentView(expandedDocs[0], this.props.ContainingCollectionView);
if (!hasView) {
@@ -358,7 +360,12 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
if (!linkedFwdDocs.some(l => l instanceof Promise)) {
let maxLocation = StrCast(linkedFwdDocs[0].maximizeLocation, "inTab");
let targetContext = !Doc.AreProtosEqual(linkedFwdContextDocs[altKey ? 1 : 0], this.props.ContainingCollectionView && this.props.ContainingCollectionView.props.Document) ? linkedFwdContextDocs[altKey ? 1 : 0] : undefined;
- DocumentManager.Instance.jumpToDocument(linkedFwdDocs[altKey ? 1 : 0], ctrlKey, false, document => this.props.addDocTab(document, undefined, maxLocation), linkedFwdPage[altKey ? 1 : 0], targetContext);
+ DocumentManager.Instance.jumpToDocument(linkedFwdDocs[altKey ? 1 : 0], ctrlKey, false, document => {
+ this.props.focus(this.props.Document, true, 1);
+ setTimeout(() =>
+ this.props.addDocTab(document, undefined, maxLocation), 1000);
+ }
+ , linkedFwdPage[altKey ? 1 : 0], targetContext);
}
}
}
@@ -408,7 +415,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
@undoBatch
makeBtnClicked = (): void => {
let doc = Doc.GetProto(this.props.Document);
- doc.isButton = !BoolCast(doc.isButton, false);
+ doc.isButton = !BoolCast(doc.isButton);
if (doc.isButton) {
if (!doc.nativeWidth) {
doc.nativeWidth = this.props.Document[WidthSym]();
@@ -506,12 +513,17 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
@action
freezeNativeDimensions = (): void => {
let proto = this.props.Document.isTemplate ? this.props.Document : Doc.GetProto(this.props.Document);
- if (proto.ignoreAspect === undefined && !proto.nativeWidth) {
+ this.props.Document.autoHeight = proto.autoHeight = false;
+ proto.ignoreAspect = !BoolCast(proto.ignoreAspect);
+ if (!BoolCast(proto.ignoreAspect) && !proto.nativeWidth) {
proto.nativeWidth = this.props.PanelWidth();
proto.nativeHeight = this.props.PanelHeight();
- proto.ignoreAspect = true;
}
- proto.ignoreAspect = !BoolCast(proto.ignoreAspect, false);
+ }
+ @undoBatch
+ @action
+ makeBackground = (): void => {
+ this.props.Document.isBackground = true;
}
@undoBatch
@@ -540,21 +552,27 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
subitems.push({ description: "Open Right Alias", event: () => this.props.addDocTab && this.props.addDocTab(Doc.MakeAlias(this.props.Document), this.dataDoc, "onRight"), icon: "caret-square-right" });
subitems.push({ description: "Open Fields", event: this.fieldsClicked, icon: "layer-group" });
cm.addItem({ description: "Open...", subitems: subitems, icon: "external-link-alt" });
- cm.addItem({ description: BoolCast(this.props.Document.ignoreAspect, false) || !this.props.Document.nativeWidth || !this.props.Document.nativeHeight ? "Freeze" : "Unfreeze", event: this.freezeNativeDimensions, icon: "edit" });
- cm.addItem({ description: "Pin to Pres", event: () => PresentationView.Instance.PinDoc(this.props.Document), icon: "map-pin" });
- cm.addItem({ description: BoolCast(this.props.Document.lockedPosition) ? "Unlock Pos" : "Lock Pos", event: this.toggleLockPosition, icon: BoolCast(this.props.Document.lockedPosition) ? "unlock" : "lock" });
- cm.addItem({ description: this.props.Document.isButton ? "Remove Button" : "Make Button", event: this.makeBtnClicked, icon: "concierge-bell" });
- cm.addItem({
+ cm.addItem({ description: BoolCast(this.props.Document.ignoreAspect, false) || !this.props.Document.nativeWidth || !this.props.Document.nativeHeight ? "Freeze" : "Unfreeze", event: this.freezeNativeDimensions, icon: "snowflake" });
+ cm.addItem({ description: "Pin to Presentation", event: () => PresentationView.Instance.PinDoc(this.props.Document), icon: "map-pin" });
+ cm.addItem({ description: BoolCast(this.props.Document.lockedPosition) ? "Unlock Position" : "Lock Position", event: this.toggleLockPosition, icon: BoolCast(this.props.Document.lockedPosition) ? "unlock" : "lock" });
+ let makes: ContextMenuProps[] = [];
+ makes.push({ description: "Make Background", event: this.makeBackground, icon: BoolCast(this.props.Document.lockedPosition) ? "unlock" : "lock" });
+ makes.push({ description: this.props.Document.isButton ? "Remove Button" : "Make Button", event: this.makeBtnClicked, icon: "concierge-bell" });
+ makes.push({
description: "Make Portal", event: () => {
let portal = Docs.Create.FreeformDocument([], { width: this.props.Document[WidthSym]() + 10, height: this.props.Document[HeightSym](), title: this.props.Document.title + ".portal" });
- Doc.GetProto(this.props.Document).subBulletDocs = new List<Doc>([portal]);
+ //Doc.GetProto(this.props.Document).subBulletDocs = new List<Doc>([portal]);
//summary.proto!.maximizeLocation = "inTab"; // or "inPlace", or "onRight"
- Doc.GetProto(this.props.Document).templates = new List<string>([Templates.Bullet.Layout]);
- let coll = Docs.Create.StackingDocument([this.props.Document, portal], { x: NumCast(this.props.Document.x), y: NumCast(this.props.Document.y), width: this.props.Document[WidthSym]() + 10, height: this.props.Document[HeightSym](), title: this.props.Document.title + ".cont" });
- this.props.addDocument && this.props.addDocument(coll);
- this.props.removeDocument && this.props.removeDocument(this.props.Document);
+ //Doc.GetProto(this.props.Document).templates = new List<string>([Templates.Bullet.Layout]);
+ //let coll = Docs.Create.StackingDocument([this.props.Document, portal], { x: NumCast(this.props.Document.x), y: NumCast(this.props.Document.y), width: this.props.Document[WidthSym]() + 10, height: this.props.Document[HeightSym](), title: this.props.Document.title + ".cont" });
+ //this.props.addDocument && this.props.addDocument(coll);
+ //this.props.removeDocument && this.props.removeDocument(this.props.Document);
+ DocUtils.MakeLink(this.props.Document, portal, undefined, this.props.Document.title + ".portal");
+ this.makeBtnClicked();
+
}, icon: "window-restore"
});
+ cm.addItem({ description: "Make...", subitems: makes, icon: "hand-point-right" });
// cm.addItem({
// description: "Find aliases", event: async () => {
// const aliases = await SearchUtil.GetAliasesOfDocument(this.props.Document);
@@ -565,11 +583,16 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
cm.addItem({ description: "Toggle detail", event: () => Doc.ToggleDetailLayout(this.props.Document), icon: "image" });
}
cm.addItem({ description: "Add Repl", icon: "laptop-code", event: () => OverlayView.Instance.addWindow(<ScriptingRepl />, { x: 300, y: 100, width: 200, height: 200, title: "Scripting REPL" }) });
- cm.addItem({ description: "Center View", event: () => this.props.focus(this.props.Document, false), icon: "crosshairs" });
- cm.addItem({ description: "Zoom to Document", event: () => this.props.focus(this.props.Document, true), icon: "search" });
+ let existing = ContextMenu.Instance.findByDescription("Layout...");
+ let layoutItems: ContextMenuProps[] = existing && "subitems" in existing ? existing.subitems : [];
+ layoutItems.push({ description: "Center View", event: () => this.props.focus(this.props.Document, false), icon: "crosshairs" });
+ layoutItems.push({ description: "Zoom to Document", event: () => this.props.focus(this.props.Document, true), icon: "search" });
+ !existing && cm.addItem({ description: "Layout...", subitems: layoutItems, icon: "compass" });
if (!ClientUtils.RELEASE) {
- cm.addItem({ description: "Copy URL", event: () => Utils.CopyText(Utils.prepend("/doc/" + this.props.Document[Id])), icon: "link" });
- cm.addItem({ description: "Copy ID", event: () => Utils.CopyText(this.props.Document[Id]), icon: "fingerprint" });
+ let copies: ContextMenuProps[] = [];
+ copies.push({ description: "Copy URL", event: () => Utils.CopyText(Utils.prepend("/doc/" + this.props.Document[Id])), icon: "link" });
+ copies.push({ description: "Copy ID", event: () => Utils.CopyText(this.props.Document[Id]), icon: "fingerprint" });
+ cm.addItem({ description: "Copy...", subitems: copies, icon: "copy" });
}
cm.addItem({ description: "Delete", event: this.deleteClicked, icon: "trash" });
type User = { email: string, userDocumentId: string };
@@ -593,7 +616,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
notifDoc.data = new List([sharedDoc]);
}
}
- }
+ }, icon: "male"
}));
} catch {
@@ -628,36 +651,46 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
DataDoc={this.dataDoc} />);
}
+ get layoutDoc() {
+ // if this document's layout field contains a document (ie, a rendering template), then we will use that
+ // to determine the render JSX string, otherwise the layout field should directly contain a JSX layout string.
+ return this.props.Document.layout instanceof Doc ? this.props.Document.layout : this.props.Document;
+ }
render() {
if (this.Document.hidden) {
return null;
}
let self = this;
- let backgroundColor = this.props.Document.layout instanceof Doc ? StrCast(this.props.Document.layout.backgroundColor) : this.Document.backgroundColor;
- let foregroundColor = StrCast(this.props.Document.layout instanceof Doc ? this.props.Document.layout.color : this.props.Document.color);
- var nativeWidth = this.nativeWidth > 0 ? `${this.nativeWidth}px` : "100%";
+ let backgroundColor = StrCast(this.layoutDoc.backgroundColor);
+ let foregroundColor = StrCast(this.layoutDoc.color);
+ var nativeWidth = this.nativeWidth > 0 && !BoolCast(this.props.Document.ignoreAspect) ? `${this.nativeWidth}px` : "100%";
var nativeHeight = BoolCast(this.props.Document.ignoreAspect) ? this.props.PanelHeight() / this.props.ContentScaling() : this.nativeHeight > 0 ? `${this.nativeHeight}px` : "100%";
- let showOverlays = this.props.showOverlays ? this.props.showOverlays(this.props.Document) : undefined;
- let showTitle = showOverlays && showOverlays.title !== "undefined" ? showOverlays.title : StrCast(this.props.Document.showTitle);
- let showCaption = showOverlays && showOverlays.caption !== "undefined" ? showOverlays.caption : StrCast(this.props.Document.showCaption);
- let templates = Cast(this.props.Document.templates, listSpec("string"));
+ let showOverlays = this.props.showOverlays ? this.props.showOverlays(this.layoutDoc) : undefined;
+ let showTitle = showOverlays && showOverlays.title !== "undefined" ? showOverlays.title : StrCast(this.layoutDoc.showTitle);
+ let showCaption = showOverlays && showOverlays.caption !== "undefined" ? showOverlays.caption : StrCast(this.layoutDoc.showCaption);
+ let templates = Cast(this.layoutDoc.templates, listSpec("string"));
if (!showOverlays && templates instanceof List) {
templates.map(str => {
if (str.indexOf("{props.Document.title}") !== -1) showTitle = "title";
if (str.indexOf("fieldKey={\"caption\"}") !== -1) showCaption = "caption";
});
}
- let showTextTitle = showTitle && StrCast(this.props.Document.layout).startsWith("<FormattedTextBox") || (this.props.Document.layout instanceof Doc && StrCast(this.props.Document.layout.layout).startsWith("<FormattedTextBox")) ? showTitle : undefined;
+ let showTextTitle = showTitle && StrCast(this.layoutDoc.layout).startsWith("<FormattedTextBox") ? showTitle : undefined;
return (
<div className={`documentView-node${this.topMost ? "-topmost" : ""}`}
ref={this._mainCont}
style={{
+ pointerEvents: this.layoutDoc.isBackground ? "none" : "all",
color: foregroundColor,
outlineColor: "maroon",
outlineStyle: "dashed",
- outlineWidth: BoolCast(this.props.Document.libraryBrush) && !StrCast(this.props.Document.borderRounding) ?
+ outlineWidth: BoolCast(this.layoutDoc.libraryBrush) && !StrCast(Doc.GetProto(this.props.Document).borderRounding) ?
`${this.props.ScreenToLocalTransform().Scale}px` : "0px",
- border: BoolCast(this.props.Document.libraryBrush) && StrCast(this.props.Document.borderRounding) ?
+ marginLeft: BoolCast(this.layoutDoc.libraryBrush) && StrCast(Doc.GetProto(this.props.Document).borderRounding) ?
+ `${-1 * this.props.ScreenToLocalTransform().Scale}px` : undefined,
+ marginTop: BoolCast(this.layoutDoc.libraryBrush) && StrCast(Doc.GetProto(this.props.Document).borderRounding) ?
+ `${-1 * this.props.ScreenToLocalTransform().Scale}px` : undefined,
+ border: BoolCast(this.layoutDoc.libraryBrush) && StrCast(Doc.GetProto(this.props.Document).borderRounding) ?
`dashed maroon ${this.props.ScreenToLocalTransform().Scale}px` : undefined,
borderRadius: "inherit",
background: backgroundColor,
@@ -678,17 +711,17 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
{!showTitle ? (null) :
<div style={{
position: showTextTitle ? "relative" : "absolute", top: 0, padding: "4px", textAlign: "center", textOverflow: "ellipsis", whiteSpace: "pre",
- pointerEvents: "all",
+ pointerEvents: SelectionManager.GetIsDragging() ? "none" : "all",
overflow: "hidden", width: `${100 * this.props.ContentScaling()}%`, height: 25, background: "rgba(0, 0, 0, .4)", color: "white",
transformOrigin: "top left", transform: `scale(${1 / this.props.ContentScaling()})`
}}>
<EditableView
- contents={this.props.Document[showTitle]}
+ contents={(this.dataDoc || this.layoutDoc)[showTitle]}
display={"block"}
height={72}
fontSize={12}
- GetValue={() => StrCast(this.props.Document[showTitle!])}
- SetValue={(value: string) => (Doc.GetProto(this.props.Document)[showTitle!] = value) ? true : true}
+ GetValue={() => StrCast(this.layoutDoc[showTitle!])}
+ SetValue={(value: string) => (Doc.GetProto(this.layoutDoc)[showTitle!] = value) ? true : true}
/>
</div>
}
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 0a79677e2..5ac4af0bb 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -1,5 +1,5 @@
import { library } from '@fortawesome/fontawesome-svg-core';
-import { faEdit, faSmile } from '@fortawesome/free-solid-svg-icons';
+import { faEdit, faSmile, faTextHeight } from '@fortawesome/free-solid-svg-icons';
import { action, IReactionDisposer, observable, reaction, runInAction, computed, trace } from "mobx";
import { observer } from "mobx-react";
import { baseKeymap } from "prosemirror-commands";
@@ -38,7 +38,7 @@ import { thisExpression } from 'babel-types';
import { Utils } from '../../../Utils';
library.add(faEdit);
-library.add(faSmile);
+library.add(faSmile, faTextHeight);
// FormattedTextBox: Displays an editable plain text node that maps to a specified Key of a Document
//
@@ -139,7 +139,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
this.dataDoc[this.props.fieldKey] = new RichTextField(JSON.stringify(state.toJSON()));
this._applyingChange = false;
let title = StrCast(this.dataDoc.title);
- if (title && title.startsWith("-") && this._editorView) {
+ if (title && title.startsWith("-") && this._editorView && !this.Document.customTitle) {
let str = this._editorView.state.doc.textContent;
let titlestr = str.substr(0, Math.min(40, str.length));
this.dataDoc.title = "-" + titlestr + (str.length > 40 ? "..." : "");
@@ -422,7 +422,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
// stop propagation doesn't seem to stop propagation of native keyboard events.
// so we set a flag on the native event that marks that the event's been handled.
(e.nativeEvent as any).DASHFormattedTextBoxHandled = true;
- if (StrCast(this.dataDoc.title).startsWith("-") && this._editorView) {
+ if (StrCast(this.dataDoc.title).startsWith("-") && this._editorView && !this.Document.customTitle) {
let str = this._editorView.state.doc.textContent;
let titlestr = str.substr(0, Math.min(40, str.length));
this.dataDoc.title = "-" + titlestr + (str.length > 40 ? "..." : "");
@@ -459,10 +459,10 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
specificContextMenu = (e: React.MouseEvent): void => {
let subitems: ContextMenuProps[] = [];
subitems.push({
- description: BoolCast(this.props.Document.autoHeight, false) ? "Manual Height" : "Auto Height",
- event: action(() => Doc.GetProto(this.props.Document).autoHeight = !BoolCast(this.props.Document.autoHeight, false)), icon: "expand-arrows-alt"
+ description: BoolCast(this.props.Document.autoHeight) ? "Manual Height" : "Auto Height",
+ event: action(() => Doc.GetProto(this.props.Document).autoHeight = !BoolCast(this.props.Document.autoHeight)), icon: "expand-arrows-alt"
});
- ContextMenu.Instance.addItem({ description: "Text Funcs...", subitems: subitems });
+ ContextMenu.Instance.addItem({ description: "Text Funcs...", subitems: subitems, icon: "text-height" });
}
render() {
let self = this;
diff --git a/src/client/views/nodes/IconBox.tsx b/src/client/views/nodes/IconBox.tsx
index d6ab2a34a..7e78ec684 100644
--- a/src/client/views/nodes/IconBox.tsx
+++ b/src/client/views/nodes/IconBox.tsx
@@ -1,6 +1,6 @@
import React = require("react");
import { library } from '@fortawesome/fontawesome-svg-core';
-import { faCaretUp, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote } from '@fortawesome/free-solid-svg-icons';
+import { faCaretUp, faFilePdf, faFilm, faImage, faObjectGroup, faStickyNote, faTag, faTextHeight } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { computed, observable, runInAction } from "mobx";
import { observer } from "mobx-react";
@@ -18,7 +18,7 @@ library.add(faCaretUp);
library.add(faObjectGroup);
library.add(faStickyNote);
library.add(faFilePdf);
-library.add(faFilm);
+library.add(faFilm, faTag, faTextHeight);
@observer
export class IconBox extends React.Component<FieldViewProps> {
@@ -47,13 +47,15 @@ export class IconBox extends React.Component<FieldViewProps> {
specificContextMenu = (): void => {
ContextMenu.Instance.addItem({
description: BoolCast(this.props.Document.hideLabel) ? "Show label with icon" : "Remove label from icon",
- event: this.setLabelField
+ event: this.setLabelField,
+ icon: "tag"
});
let maxDocs = DocListCast(this.props.Document.maximizedDocs);
if (maxDocs.length === 1 && !BoolCast(this.props.Document.hideLabel)) {
ContextMenu.Instance.addItem({
description: BoolCast(this.props.Document.useOwnTitle) ? "Use target title for label" : "Use own title label",
- event: this.setUseOwnTitleField
+ event: this.setUseOwnTitleField,
+ icon: "text-height"
});
}
}
@@ -64,7 +66,7 @@ export class IconBox extends React.Component<FieldViewProps> {
let hideLabel = BoolCast(this.props.Document.hideLabel);
let maxDocs = DocListCast(this.props.Document.maximizedDocs);
let firstDoc = maxDocs.length ? maxDocs[0] : undefined;
- let label = hideLabel ? "" : (firstDoc && labelField && !BoolCast(this.props.Document.useOwnTitle, false) ? firstDoc[labelField] : this.props.Document.title);
+ let label = hideLabel ? "" : (firstDoc && labelField && !BoolCast(this.props.Document.useOwnTitle) ? firstDoc[labelField] : this.props.Document.title);
return (
<div className="iconBox-container" onContextMenu={this.specificContextMenu}>
{this.minimizedIcon}
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 6541007d0..29a76b0c8 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -21,7 +21,7 @@ import { FieldView, FieldViewProps } from './FieldView';
import "./ImageBox.scss";
import React = require("react");
import { RouteStore } from '../../../server/RouteStore';
-import { Docs } from '../../documents/Documents';
+import { Docs, DocumentType } from '../../documents/Documents';
import { DocServer } from '../../DocServer';
import { Font } from '@react-pdf/renderer';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
@@ -30,7 +30,7 @@ import FaceRectangles from './FaceRectangles';
import { faEye } from '@fortawesome/free-regular-svg-icons';
var requestImageSize = require('../../util/request-image-size');
var path = require('path');
-const { Howl, Howler } = require('howler');
+const { Howl } = require('howler');
library.add(faImage, faEye, faPaintBrush);
@@ -85,10 +85,20 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
@computed get extensionDoc() { return Doc.resolvedFieldDataDoc(this.dataDoc, this.props.fieldKey, "Alternates"); }
@undoBatch
+ @action
drop = (e: Event, de: DragManager.DropEvent) => {
if (de.data instanceof DragManager.DocumentDragData) {
de.data.droppedDocuments.forEach(action((drop: Doc) => {
- if (de.mods === "AltKey" && /*this.dataDoc !== this.props.Document &&*/ drop.data instanceof ImageField) {
+ if (de.mods === "CtrlKey") {
+ let temp = Doc.MakeDelegate(drop);
+ this.props.Document.nativeWidth = Doc.GetProto(this.props.Document).nativeWidth = undefined;
+ this.props.Document.nativeHeight = Doc.GetProto(this.props.Document).nativeHeight = undefined;
+ this.props.Document.width = drop.width;
+ this.props.Document.height = drop.height;
+ Doc.GetProto(this.props.Document).type = DocumentType.TEMPLATE;
+ this.props.Document.layout = temp;
+ e.stopPropagation();
+ } else if (de.mods === "AltKey" && /*this.dataDoc !== this.props.Document &&*/ drop.data instanceof ImageField) {
Doc.GetProto(this.dataDoc)[this.props.fieldKey] = new ImageField(drop.data.url);
e.stopPropagation();
} else if (de.mods === "CtrlKey") {
@@ -104,8 +114,6 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
e.stopPropagation();
}
}
- } else if (!this.props.isSelected()) {
- e.stopPropagation();
}
}));
// de.data.removeDocument() bcz: need to implement
@@ -194,6 +202,20 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
});
}
+ @undoBatch
+ rotate = action(() => {
+ let proto = Doc.GetProto(this.props.Document);
+ let nw = this.props.Document.nativeWidth;
+ let nh = this.props.Document.nativeHeight;
+ let w = this.props.Document.width;
+ let h = this.props.Document.height;
+ proto.rotation = (NumCast(this.props.Document.rotation) + 90) % 360;
+ proto.nativeWidth = nh;
+ proto.nativeHeight = nw;
+ this.props.Document.width = h;
+ this.props.Document.height = w;
+ });
+
specificContextMenu = (e: React.MouseEvent): void => {
let field = Cast(this.Document[this.props.fieldKey], ImageField);
if (field) {
@@ -201,20 +223,7 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
let funcs: ContextMenuProps[] = [];
funcs.push({ description: "Copy path", event: () => Utils.CopyText(url), icon: "expand-arrows-alt" });
funcs.push({ description: "Record 1sec audio", event: this.recordAudioAnnotation, icon: "expand-arrows-alt" });
- funcs.push({
- description: "Rotate", event: action(() => {
- let proto = Doc.GetProto(this.props.Document);
- let nw = this.props.Document.nativeWidth;
- let nh = this.props.Document.nativeHeight;
- let w = this.props.Document.width;
- let h = this.props.Document.height;
- proto.rotation = (NumCast(this.props.Document.rotation) + 90) % 360;
- proto.nativeWidth = nh;
- proto.nativeHeight = nw;
- this.props.Document.width = h;
- this.props.Document.height = w;
- }), icon: "expand-arrows-alt"
- });
+ funcs.push({ description: "Rotate", event: this.rotate, icon: "expand-arrows-alt" });
let modes: ContextMenuProps[] = [];
let dataDoc = Doc.GetProto(this.props.Document);
@@ -244,11 +253,15 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
choosePath(url: URL) {
const lower = url.href.toLowerCase();
- if (url.protocol === "data" || url.href.indexOf(window.location.origin) === -1 || !(lower.endsWith(".png") || lower.endsWith(".jpg") || lower.endsWith(".jpeg"))) {
+ if (url.protocol === "data") {
return url.href;
+ } else if (url.href.indexOf(window.location.origin) === -1) {
+ return Utils.CorsProxy(url.href);
+ } else if (!(lower.endsWith(".png") || lower.endsWith(".jpg") || lower.endsWith(".jpeg"))) {
+ return url.href;//Why is this here
}
let ext = path.extname(url.href);
- const suffix = this.props.renderDepth <= 1 ? "_o" : this._curSuffix;
+ const suffix = this.props.renderDepth < 1 ? "_o" : this._curSuffix;
return url.href.replace(ext, suffix + ext);
}
@@ -352,7 +365,7 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
if (field instanceof ImageField) paths = [this.choosePath(field.url)];
paths.push(...altpaths);
// }
- let interactive = InkingControl.Instance.selectedTool ? "" : "-interactive";
+ let interactive = InkingControl.Instance.selectedTool || this.props.Document.isBackground ? "" : "-interactive";
let rotation = NumCast(this.dataDoc.rotation, 0);
let aspect = (rotation % 180) ? this.dataDoc[HeightSym]() / this.dataDoc[WidthSym]() : 1;
let shift = (rotation % 180) ? (nativeHeight - nativeWidth / aspect) / 2 : 0;
diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx
index 9fc0f2080..77824b4ff 100644
--- a/src/client/views/nodes/KeyValueBox.tsx
+++ b/src/client/views/nodes/KeyValueBox.tsx
@@ -46,6 +46,7 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
@action
onEnterKey = (e: React.KeyboardEvent): void => {
if (e.key === 'Enter') {
+ e.stopPropagation();
if (this._keyInput && this._valueInput && this.fieldDocToLayout) {
if (KeyValueBox.SetField(this.fieldDocToLayout, this._keyInput, this._valueInput)) {
this._keyInput = "";
@@ -153,7 +154,7 @@ export class KeyValueBox extends React.Component<FieldViewProps> {
<input style={{ width: "100%" }} type="text" value={this._keyInput} placeholder="Key" onChange={this.keyChanged} />
</td>
<td className="keyValueBox-td-value" style={{ width: `${this.splitPercentage}%` }}>
- <input style={{ width: "100%" }} type="text" value={this._valueInput} placeholder="Value" onChange={this.valueChanged} onKeyPress={this.onEnterKey} />
+ <input style={{ width: "100%" }} type="text" value={this._valueInput} placeholder="Value" onChange={this.valueChanged} onKeyDown={this.onEnterKey} />
</td>
</tr>
)
diff --git a/src/client/views/nodes/LinkMenuItem.tsx b/src/client/views/nodes/LinkMenuItem.tsx
index a0c37a719..d4c92c9f2 100644
--- a/src/client/views/nodes/LinkMenuItem.tsx
+++ b/src/client/views/nodes/LinkMenuItem.tsx
@@ -7,7 +7,7 @@ import { undoBatch } from "../../util/UndoManager";
import './LinkMenu.scss';
import React = require("react");
import { Doc } from '../../../new_fields/Doc';
-import { StrCast, Cast, BoolCast, FieldValue, NumCast } from '../../../new_fields/Types';
+import { StrCast, Cast, FieldValue, NumCast } from '../../../new_fields/Types';
import { observable, action } from 'mobx';
import { LinkManager } from '../../util/LinkManager';
import { DragLinkAsDocument } from '../../util/DragManager';
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 30ad75000..34cb47b20 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -19,10 +19,14 @@ import { positionSchema } from "./DocumentView";
import { FieldView, FieldViewProps } from './FieldView';
import { pageSchema } from "./ImageBox";
import "./VideoBox.scss";
+import { library } from "@fortawesome/fontawesome-svg-core";
+import { faVideo } from "@fortawesome/free-solid-svg-icons";
type VideoDocument = makeInterface<[typeof positionSchema, typeof pageSchema]>;
const VideoDocument = makeInterface(positionSchema, pageSchema);
+library.add(faVideo);
+
@observer
export class VideoBox extends DocComponent<FieldViewProps, VideoDocument>(VideoDocument) {
private _reactionDisposer?: IReactionDisposer;
@@ -179,7 +183,7 @@ export class VideoBox extends DocComponent<FieldViewProps, VideoDocument>(VideoD
},
icon: "expand-arrows-alt"
});
- ContextMenu.Instance.addItem({ description: "Video Funcs...", subitems: subitems });
+ ContextMenu.Instance.addItem({ description: "Video Funcs...", subitems: subitems, icon: "video" });
}
}
diff --git a/src/client/views/pdf/Page.tsx b/src/client/views/pdf/Page.tsx
index c9d442fe5..a6864e0f3 100644
--- a/src/client/views/pdf/Page.tsx
+++ b/src/client/views/pdf/Page.tsx
@@ -1,22 +1,18 @@
+import { action, IReactionDisposer, observable } from "mobx";
import { observer } from "mobx-react";
-import React = require("react");
-import { observable, action, runInAction, IReactionDisposer, reaction } from "mobx";
import * as Pdfjs from "pdfjs-dist";
-import { Opt, Doc, FieldResult, Field, DocListCast, WidthSym, HeightSym, DocListCastAsync } from "../../../new_fields/Doc";
-import "./PDFViewer.scss";
import "pdfjs-dist/web/pdf_viewer.css";
-import { PDFBox } from "../nodes/PDFBox";
-import { DragManager } from "../../util/DragManager";
-import { Docs, DocUtils } from "../../documents/Documents";
+import { Doc, DocListCastAsync, Opt, WidthSym } from "../../../new_fields/Doc";
import { List } from "../../../new_fields/List";
-import { emptyFunction } from "../../../Utils";
-import { Cast, NumCast, StrCast, BoolCast } from "../../../new_fields/Types";
import { listSpec } from "../../../new_fields/Schema";
-import { menuBar } from "prosemirror-menu";
-import { AnnotationTypes, PDFViewer, scale } from "./PDFViewer";
+import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
+import { Docs, DocUtils } from "../../documents/Documents";
+import { DragManager } from "../../util/DragManager";
+import { PDFBox } from "../nodes/PDFBox";
import PDFMenu from "./PDFMenu";
-import { UndoManager } from "../../util/UndoManager";
-import { copy } from "typescript-collections/dist/lib/arrays";
+import { scale } from "./PDFViewer";
+import "./PDFViewer.scss";
+import React = require("react");
interface IPageProps {
diff --git a/src/client/views/presentationview/PresentationElement.tsx b/src/client/views/presentationview/PresentationElement.tsx
index 329630875..36f1178f1 100644
--- a/src/client/views/presentationview/PresentationElement.tsx
+++ b/src/client/views/presentationview/PresentationElement.tsx
@@ -1,21 +1,19 @@
-import { observer } from "mobx-react";
-import React = require("react");
-import { Doc, DocListCast, DocListCastAsync } from "../../../new_fields/Doc";
-import { NumCast, BoolCast, StrCast, Cast } from "../../../new_fields/Types";
-import { Id } from "../../../new_fields/FieldSymbols";
-import { observable, action, computed, runInAction } from "mobx";
-import "./PresentationView.scss";
-import { Utils } from "../../../Utils";
import { library } from '@fortawesome/fontawesome-svg-core';
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { faFile as fileSolid, faFileDownload, faLocationArrow, faArrowUp, faSearch } from '@fortawesome/free-solid-svg-icons';
import { faFile as fileRegular } from '@fortawesome/free-regular-svg-icons';
+import { faArrowUp, faFile as fileSolid, faFileDownload, faLocationArrow, faSearch } from '@fortawesome/free-solid-svg-icons';
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { action, computed, observable, runInAction } from "mobx";
+import { observer } from "mobx-react";
+import { Doc } from "../../../new_fields/Doc";
+import { Id } from "../../../new_fields/FieldSymbols";
import { List } from "../../../new_fields/List";
import { listSpec } from "../../../new_fields/Schema";
-import { DragManager, SetupDrag, dropActionType } from "../../util/DragManager";
+import { BoolCast, Cast, NumCast, StrCast } from "../../../new_fields/Types";
+import { Utils } from "../../../Utils";
+import { DragManager, dropActionType, SetupDrag } from "../../util/DragManager";
import { SelectionManager } from "../../util/SelectionManager";
-import { indexOf } from "typescript-collections/dist/lib/arrays";
-import { map } from "bluebird";
+import "./PresentationView.scss";
+import React = require("react");
library.add(faArrowUp);
library.add(fileSolid);
diff --git a/src/client/views/presentationview/PresentationView.tsx b/src/client/views/presentationview/PresentationView.tsx
index f2fef7f16..e25725275 100644
--- a/src/client/views/presentationview/PresentationView.tsx
+++ b/src/client/views/presentationview/PresentationView.tsx
@@ -171,7 +171,7 @@ export class PresentationView extends React.Component<PresViewProps> {
//storing the presentation status,ie. whether it was stopped or playing
- let presStatusBackUp = BoolCast(this.curPresentation.presStatus, null);
+ let presStatusBackUp = BoolCast(this.curPresentation.presStatus);
runInAction(() => this.presStatus = presStatusBackUp);
}
diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx
index 5c2ced2eb..562594210 100644
--- a/src/client/views/search/SearchItem.tsx
+++ b/src/client/views/search/SearchItem.tsx
@@ -1,6 +1,6 @@
import React = require("react");
import { library } from '@fortawesome/fontawesome-svg-core';
-import { faCaretUp, faChartBar, faFilePdf, faFilm, faGlobeAsia, faImage, faLink, faMusic, faObjectGroup, faStickyNote } from '@fortawesome/free-solid-svg-icons';
+import { faCaretUp, faChartBar, faFilePdf, faFilm, faGlobeAsia, faImage, faLink, faMusic, faObjectGroup, faStickyNote, faFingerprint } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { action, computed, observable, runInAction } from "mobx";
import { observer } from "mobx-react";
@@ -38,7 +38,7 @@ library.add(faFilm);
library.add(faMusic);
library.add(faLink);
library.add(faChartBar);
-library.add(faGlobeAsia);
+library.add(faGlobeAsia, faFingerprint);
@observer
export class SelectorContextMenu extends React.Component<SearchItemProps> {
@@ -223,7 +223,8 @@ export class SearchItem extends React.Component<SearchItemProps> {
ContextMenu.Instance.addItem({
description: "Copy ID", event: () => {
Utils.CopyText(this.props.doc[Id]);
- }
+ },
+ icon: "fingerprint"
});
ContextMenu.Instance.displayMenu(e.clientX, e.clientY);
}
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index bb6130992..da4f459e2 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -396,11 +396,22 @@ export namespace Doc {
}
if (expandedTemplateLayout === undefined) {
setTimeout(() =>
- dataDoc[expandedLayoutFieldKey] = Doc.MakeDelegate(templateLayoutDoc, undefined, "["+templateLayoutDoc.title + "]"), 0);
+ dataDoc[expandedLayoutFieldKey] = Doc.MakeDelegate(templateLayoutDoc, undefined, "[" + templateLayoutDoc.title + "]"), 0);
}
return templateLayoutDoc; // use the templateLayout when it's not a template or the expandedTemplate is pending.
}
+ export function GetLayoutDataDocPair(doc: Doc, dataDoc: Doc | undefined, fieldKey: string, childDocLayout: Doc) {
+ let layoutDoc = childDocLayout;
+ let resolvedDataDoc = !doc.isTemplate && dataDoc !== doc ? dataDoc : undefined;
+ if (resolvedDataDoc && Doc.WillExpandTemplateLayout(childDocLayout, resolvedDataDoc)) {
+ Doc.UpdateDocumentExtensionForField(resolvedDataDoc, fieldKey);
+ let fieldExtensionDoc = Doc.resolvedFieldDataDoc(resolvedDataDoc, StrCast(childDocLayout.templateField, StrCast(childDocLayout.title)), "dummy");
+ layoutDoc = Doc.expandTemplateLayout(childDocLayout, fieldExtensionDoc !== resolvedDataDoc ? fieldExtensionDoc : undefined);
+ } else layoutDoc = Doc.expandTemplateLayout(childDocLayout, resolvedDataDoc);
+ return { layout: layoutDoc, data: resolvedDataDoc };
+ }
+
export function MakeCopy(doc: Doc, copyProto: boolean = false): Doc {
const copy = new Doc;
Object.keys(doc).forEach(key => {
@@ -451,7 +462,7 @@ export namespace Doc {
return otherdoc;
}
- export function MakeTemplate(fieldTemplate: Doc, metaKey: string, proto: Doc) {
+ export function MakeTemplate(fieldTemplate: Doc, metaKey: string, templateDataDoc: Doc) {
// move data doc fields to layout doc as needed (nativeWidth/nativeHeight, data, ??)
let backgroundLayout = StrCast(fieldTemplate.backgroundLayout);
let fieldLayoutDoc = fieldTemplate;
@@ -462,21 +473,24 @@ export namespace Doc {
if (backgroundLayout) {
backgroundLayout = backgroundLayout.replace(/fieldKey={"[^"]*"}/, `fieldKey={"${metaKey}"}`);
}
- let nw = Cast(fieldTemplate.nativeWidth, "number");
- let nh = Cast(fieldTemplate.nativeHeight, "number");
let layoutDelegate = fieldTemplate.layout instanceof Doc ? fieldLayoutDoc : fieldTemplate;
layoutDelegate.layout = layout;
- fieldTemplate.title = metaKey;
fieldTemplate.templateField = metaKey;
+ fieldTemplate.title = metaKey;
+ fieldTemplate.isTemplate = true;
fieldTemplate.layout = layoutDelegate !== fieldTemplate ? layoutDelegate : layout;
fieldTemplate.backgroundLayout = backgroundLayout;
- fieldTemplate.nativeWidth = nw;
- fieldTemplate.nativeHeight = nh;
- fieldTemplate.isTemplate = true;
+ /* move certain layout properties from the original data doc to the template layout to avoid
+ inheriting them from the template's data doc which may also define these fields for its own use.
+ */
+ fieldTemplate.ignoreAspect = BoolCast(fieldTemplate.ignoreAspect);
+ fieldTemplate.singleColumn = BoolCast(fieldTemplate.singleColumn);
+ fieldTemplate.nativeWidth = Cast(fieldTemplate.nativeWidth, "number");
+ fieldTemplate.nativeHeight = Cast(fieldTemplate.nativeHeight, "number");
fieldTemplate.showTitle = "title";
- setTimeout(() => fieldTemplate.proto = proto);
+ setTimeout(() => fieldTemplate.proto = templateDataDoc);
}
export async function ToggleDetailLayout(d: Doc) {
diff --git a/src/new_fields/ScriptField.ts b/src/new_fields/ScriptField.ts
index 00b4dec2c..6d52525b8 100644
--- a/src/new_fields/ScriptField.ts
+++ b/src/new_fields/ScriptField.ts
@@ -26,6 +26,7 @@ const optionsSchema = createSimpleSchema({
requiredType: true,
addReturn: true,
typecheck: true,
+ editable: true,
readonly: true,
params: optional(map(primitive()))
});
diff --git a/src/new_fields/Types.ts b/src/new_fields/Types.ts
index f8a4a30b4..565ae2ee3 100644
--- a/src/new_fields/Types.ts
+++ b/src/new_fields/Types.ts
@@ -78,7 +78,7 @@ export function StrCast(field: FieldResult, defaultVal: string | null = "") {
return Cast(field, "string", defaultVal);
}
-export function BoolCast(field: FieldResult, defaultVal: boolean | null = null) {
+export function BoolCast(field: FieldResult, defaultVal: boolean | null = false) {
return Cast(field, "boolean", defaultVal);
}
export function DateCast(field: FieldResult) {
diff --git a/src/scraping/buxton/scraper.py b/src/scraping/buxton/scraper.py
index 48b8fe3fa..182b22a1a 100644
--- a/src/scraping/buxton/scraper.py
+++ b/src/scraping/buxton/scraper.py
@@ -1,4 +1,5 @@
import os
+from shutil import copyfile
import docx2txt
from docx import Document
from docx.opc.constants import RELATIONSHIP_TYPE as RT
@@ -233,6 +234,8 @@ def parse_document(file_name: str):
for image in os.listdir(dir_path):
count += 1
view_guids.append(write_image(pure_name, image))
+ copyfile(dir_path + "/" + image, dir_path +
+ "/" + image.replace(".", "_o.", 1))
os.rename(dir_path + "/" + image, dir_path +
"/" + image.replace(".", "_m.", 1))
print(f"extracted {count} images...")
diff --git a/src/scraping/buxton/source/Bill_Notes_Bill_Notes_CyKey.docx b/src/scraping/buxton/source/Bill_Notes_Bill_Notes_CyKey.docx
index 06094b4d3..649d636e3 100644
--- a/src/scraping/buxton/source/Bill_Notes_Bill_Notes_CyKey.docx
+++ b/src/scraping/buxton/source/Bill_Notes_Bill_Notes_CyKey.docx
Binary files differ
diff --git a/src/scraping/buxton/source/Bill_Notes_Braun_T3.docx b/src/scraping/buxton/source/Bill_Notes_Braun_T3.docx
index 356697092..b00080e08 100644
--- a/src/scraping/buxton/source/Bill_Notes_Braun_T3.docx
+++ b/src/scraping/buxton/source/Bill_Notes_Braun_T3.docx
Binary files differ
diff --git a/src/scraping/buxton/source/Bill_Notes_CasioC801.docx b/src/scraping/buxton/source/Bill_Notes_CasioC801.docx
index cd89fb97b..510a006e0 100644
--- a/src/scraping/buxton/source/Bill_Notes_CasioC801.docx
+++ b/src/scraping/buxton/source/Bill_Notes_CasioC801.docx
Binary files differ
diff --git a/src/scraping/buxton/source/Bill_Notes_Casio_Mini.docx b/src/scraping/buxton/source/Bill_Notes_Casio_Mini.docx
index a503cddfc..cea9e7b69 100644
--- a/src/scraping/buxton/source/Bill_Notes_Casio_Mini.docx
+++ b/src/scraping/buxton/source/Bill_Notes_Casio_Mini.docx
Binary files differ
diff --git a/src/scraping/buxton/source/Bill_Notes_FingerWorks_Prototype.docx b/src/scraping/buxton/source/Bill_Notes_FingerWorks_Prototype.docx
index 4d13a8cf5..f53402a06 100644
--- a/src/scraping/buxton/source/Bill_Notes_FingerWorks_Prototype.docx
+++ b/src/scraping/buxton/source/Bill_Notes_FingerWorks_Prototype.docx
Binary files differ
diff --git a/src/scraping/buxton/source/Bill_Notes_Fingerworks_TouchStream.docx b/src/scraping/buxton/source/Bill_Notes_Fingerworks_TouchStream.docx
index 578a1be08..0eec89949 100644
--- a/src/scraping/buxton/source/Bill_Notes_Fingerworks_TouchStream.docx
+++ b/src/scraping/buxton/source/Bill_Notes_Fingerworks_TouchStream.docx
Binary files differ
diff --git a/src/scraping/buxton/source/Bill_Notes_FrogPad.docx b/src/scraping/buxton/source/Bill_Notes_FrogPad.docx
index d01e1bf5c..ba80c1959 100644
--- a/src/scraping/buxton/source/Bill_Notes_FrogPad.docx
+++ b/src/scraping/buxton/source/Bill_Notes_FrogPad.docx
Binary files differ
diff --git a/src/scraping/buxton/source/Bill_Notes_Gavilan_SC.docx b/src/scraping/buxton/source/Bill_Notes_Gavilan_SC.docx
index 7bd28b376..8558a4e13 100644
--- a/src/scraping/buxton/source/Bill_Notes_Gavilan_SC.docx
+++ b/src/scraping/buxton/source/Bill_Notes_Gavilan_SC.docx
Binary files differ
diff --git a/src/scraping/buxton/source/Bill_Notes_Grandjean_Stenotype.docx b/src/scraping/buxton/source/Bill_Notes_Grandjean_Stenotype.docx
index 0615c4953..09e17f971 100644
--- a/src/scraping/buxton/source/Bill_Notes_Grandjean_Stenotype.docx
+++ b/src/scraping/buxton/source/Bill_Notes_Grandjean_Stenotype.docx
Binary files differ
diff --git a/src/scraping/buxton/source/Bill_Notes_Matias.docx b/src/scraping/buxton/source/Bill_Notes_Matias.docx
index 547603256..d2d014bbe 100644
--- a/src/scraping/buxton/source/Bill_Notes_Matias.docx
+++ b/src/scraping/buxton/source/Bill_Notes_Matias.docx
Binary files differ
diff --git a/src/scraping/buxton/source/Bill_Notes_MousePen.docx b/src/scraping/buxton/source/Bill_Notes_MousePen.docx
index 4e1056636..cd0b3eab3 100644
--- a/src/scraping/buxton/source/Bill_Notes_MousePen.docx
+++ b/src/scraping/buxton/source/Bill_Notes_MousePen.docx
Binary files differ
diff --git a/src/scraping/buxton/source/Bill_Notes_NewO.docx b/src/scraping/buxton/source/Bill_Notes_NewO.docx
index a514926d2..2f4a04e81 100644
--- a/src/scraping/buxton/source/Bill_Notes_NewO.docx
+++ b/src/scraping/buxton/source/Bill_Notes_NewO.docx
Binary files differ
diff --git a/src/scraping/buxton/source/Bill_Notes_OLPC.docx b/src/scraping/buxton/source/Bill_Notes_OLPC.docx
index bfca0a9bb..7a636e2d6 100644
--- a/src/scraping/buxton/source/Bill_Notes_OLPC.docx
+++ b/src/scraping/buxton/source/Bill_Notes_OLPC.docx
Binary files differ
diff --git a/src/scraping/buxton/source/Bill_Notes_PARCkbd.docx b/src/scraping/buxton/source/Bill_Notes_PARCkbd.docx
index c0cf6ba9a..3038de363 100644
--- a/src/scraping/buxton/source/Bill_Notes_PARCkbd.docx
+++ b/src/scraping/buxton/source/Bill_Notes_PARCkbd.docx
Binary files differ
diff --git a/src/scraping/buxton/source/Bill_Notes_Philco_Mystery_Control.docx b/src/scraping/buxton/source/Bill_Notes_Philco_Mystery_Control.docx
index ad06903f3..af72fa662 100644
--- a/src/scraping/buxton/source/Bill_Notes_Philco_Mystery_Control.docx
+++ b/src/scraping/buxton/source/Bill_Notes_Philco_Mystery_Control.docx
Binary files differ
diff --git a/src/scraping/buxton/source/Bill_Notes_TASA_Kbd.docx b/src/scraping/buxton/source/Bill_Notes_TASA_Kbd.docx
index e4c659de9..5c2eb8d7f 100644
--- a/src/scraping/buxton/source/Bill_Notes_TASA_Kbd.docx
+++ b/src/scraping/buxton/source/Bill_Notes_TASA_Kbd.docx
Binary files differ
diff --git a/src/scraping/buxton/source/Bill_Notes_The_Tap.docx b/src/scraping/buxton/source/Bill_Notes_The_Tap.docx
index 8ceebc71e..c9ee2eaea 100644
--- a/src/scraping/buxton/source/Bill_Notes_The_Tap.docx
+++ b/src/scraping/buxton/source/Bill_Notes_The_Tap.docx
Binary files differ