aboutsummaryrefslogtreecommitdiff
path: root/src/client/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/util')
-rw-r--r--src/client/util/DocumentManager.ts14
-rw-r--r--src/client/util/DragManager.ts43
-rw-r--r--src/client/util/SelectionManager.ts13
-rw-r--r--src/client/util/TooltipTextMenu.scss4
-rw-r--r--src/client/util/TooltipTextMenu.tsx148
5 files changed, 159 insertions, 63 deletions
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index 3b5a5b470..56669fb79 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -38,11 +38,17 @@ export class DocumentManager {
toReturn = view;
return;
}
- let docSrc = doc.GetT(KeyStore.Prototype, Document);
- if (docSrc && docSrc !== FieldWaiting && Object.is(docSrc, toFind)) {
- toReturn = view;
- }
});
+ if (!toReturn) {
+ DocumentManager.Instance.DocumentViews.map(view => {
+ let doc = view.props.Document;
+
+ let docSrc = doc.GetT(KeyStore.Prototype, Document);
+ if (docSrc && docSrc !== FieldWaiting && Object.is(docSrc, toFind)) {
+ toReturn = view;
+ }
+ });
+ }
return toReturn;
}
diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 4bd654e15..136852e12 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -41,11 +41,11 @@ export function SetupDrag(_reference: React.RefObject<HTMLDivElement>, docFunc:
}
export async function DragLinksAsDocuments(dragEle: HTMLElement, x: number, y: number, sourceDoc: Document) {
- let srcTarg = sourceDoc.GetT(KeyStore.Prototype, Document);
- let draggedDocs = (srcTarg && srcTarg !== FieldWaiting) ?
+ let srcTarg = sourceDoc.GetPrototype();
+ let draggedDocs = srcTarg ?
srcTarg.GetList(KeyStore.LinkedToDocs, [] as Document[]).map(linkDoc =>
(linkDoc.GetT(KeyStore.LinkedToDocs, Document)) as Document) : [];
- let draggedFromDocs = (srcTarg && srcTarg !== FieldWaiting) ?
+ let draggedFromDocs = srcTarg ?
srcTarg.GetList(KeyStore.LinkedFromDocs, [] as Document[]).map(linkDoc =>
(linkDoc.GetT(KeyStore.LinkedFromDocs, Document)) as Document) : [];
draggedDocs.push(...draggedFromDocs);
@@ -158,11 +158,13 @@ export namespace DragManager {
}
export class LinkDragData {
- constructor(linkSourceDoc: Document) {
+ constructor(linkSourceDoc: Document, blacklist: Document[] = []) {
this.linkSourceDocument = linkSourceDoc;
+ this.blacklist = blacklist;
}
droppedDocuments: Document[] = [];
linkSourceDocument: Document;
+ blacklist: Document[];
[id: string]: any;
}
@@ -170,10 +172,13 @@ export namespace DragManager {
StartDrag([ele], dragData, downX, downY, options);
}
+ export let AbortDrag: () => void = emptyFunction;
+
function StartDrag(eles: HTMLElement[], dragData: { [id: string]: any }, downX: number, downY: number, options?: DragOptions, finishDrag?: (dropData: { [id: string]: any }) => void) {
if (!dragDiv) {
dragDiv = document.createElement("div");
dragDiv.className = "dragManager-dragDiv";
+ dragDiv.style.pointerEvents = "none";
DragManager.Root().appendChild(dragDiv);
}
MainOverlayTextBox.Instance.SetTextDoc();
@@ -250,7 +255,7 @@ export namespace DragManager {
dragData.aliasOnDrop = e.ctrlKey || e.altKey;
}
if (e.shiftKey) {
- abortDrag();
+ AbortDrag();
CollectionDockingView.Instance.StartOtherDrag(docs, {
pageX: e.pageX,
pageY: e.pageY,
@@ -269,21 +274,32 @@ export namespace DragManager {
);
};
- const abortDrag = () => {
+ let hideDragElements = () => {
+ dragElements.map(dragElement => dragElement.parentNode == dragDiv && dragDiv.removeChild(dragElement));
+ eles.map(ele => (ele.hidden = false));
+ };
+ let endDrag = () => {
document.removeEventListener("pointermove", moveHandler, true);
document.removeEventListener("pointerup", upHandler);
- dragElements.map(dragElement => dragDiv.removeChild(dragElement));
- eles.map(ele => (ele.hidden = false));
+ if (options) {
+ options.handlers.dragComplete({});
+ }
+ }
+
+ AbortDrag = () => {
+ hideDragElements();
+ endDrag();
};
const upHandler = (e: PointerEvent) => {
- abortDrag();
- FinishDrag(eles, e, dragData, options, finishDrag);
+ hideDragElements();
+ dispatchDrag(eles, e, dragData, options, finishDrag);
+ endDrag();
};
document.addEventListener("pointermove", moveHandler, true);
document.addEventListener("pointerup", upHandler);
}
- function FinishDrag(dragEles: HTMLElement[], e: PointerEvent, dragData: { [index: string]: any }, options?: DragOptions, finishDrag?: (dragData: { [index: string]: any }) => void) {
+ function dispatchDrag(dragEles: HTMLElement[], e: PointerEvent, dragData: { [index: string]: any }, options?: DragOptions, finishDrag?: (dragData: { [index: string]: any }) => void) {
let removed = dragEles.map(dragEle => {
let parent = dragEle.parentElement;
if (parent) parent.removeChild(dragEle);
@@ -308,11 +324,6 @@ export namespace DragManager {
}
})
);
-
- if (options) {
- options.handlers.dragComplete({});
- }
}
- DocumentDecorations.Instance.Hidden = false;
}
}
diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts
index 320553952..da66bf3fc 100644
--- a/src/client/util/SelectionManager.ts
+++ b/src/client/util/SelectionManager.ts
@@ -1,8 +1,7 @@
-import { observable, action } from "mobx";
-import { DocumentView } from "../views/nodes/DocumentView";
+import { action, observable } from "mobx";
import { Document } from "../../fields/Document";
-import { Main } from "../views/Main";
import { MainOverlayTextBox } from "../views/MainOverlayTextBox";
+import { DocumentView } from "../views/nodes/DocumentView";
export namespace SelectionManager {
class Manager {
@@ -18,13 +17,13 @@ export namespace SelectionManager {
if (manager.SelectedDocuments.indexOf(doc) === -1) {
manager.SelectedDocuments.push(doc);
- doc.props.onActiveChanged(true);
+ doc.props.whenActiveChanged(true);
}
}
@action
DeselectAll(): void {
- manager.SelectedDocuments.map(dv => dv.props.onActiveChanged(false));
+ manager.SelectedDocuments.map(dv => dv.props.whenActiveChanged(false));
manager.SelectedDocuments = [];
MainOverlayTextBox.Instance.SetTextDoc();
}
@@ -36,7 +35,7 @@ export namespace SelectionManager {
}
@action
ReselectAll2(sdocs: DocumentView[]) {
- sdocs.map(s => SelectionManager.SelectDoc(s, false));
+ sdocs.map(s => SelectionManager.SelectDoc(s, true));
}
}
@@ -64,7 +63,7 @@ export namespace SelectionManager {
export function ReselectAll() {
let sdocs = manager.ReselectAll();
- manager.ReselectAll2(sdocs);
+ setTimeout(() => manager.ReselectAll2(sdocs), 0);
}
export function SelectedDocuments(): Array<DocumentView> {
return manager.SelectedDocuments;
diff --git a/src/client/util/TooltipTextMenu.scss b/src/client/util/TooltipTextMenu.scss
index 5c2d66480..70d9ad772 100644
--- a/src/client/util/TooltipTextMenu.scss
+++ b/src/client/util/TooltipTextMenu.scss
@@ -35,6 +35,10 @@
cursor: pointer;
position: relative;
padding-right: 15px;
+ margin: 3px;
+ background: #333333;
+ border-radius: 3px;
+ text-align: center;
}
.ProseMirror-menu-dropdown-wrap {
diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx
index a92cbd263..14af4bdfd 100644
--- a/src/client/util/TooltipTextMenu.tsx
+++ b/src/client/util/TooltipTextMenu.tsx
@@ -11,7 +11,8 @@ import React = require("react");
import "./TooltipTextMenu.scss";
const { toggleMark, setBlockType, wrapIn } = require("prosemirror-commands");
import { library } from '@fortawesome/fontawesome-svg-core';
-import { wrapInList, bulletList, liftListItem, listItem } from 'prosemirror-schema-list';
+import { wrapInList, bulletList, liftListItem, listItem, } from 'prosemirror-schema-list';
+import { liftTarget } from 'prosemirror-transform';
import {
faListUl,
} from '@fortawesome/free-solid-svg-icons';
@@ -24,16 +25,22 @@ const SVG = "http://www.w3.org/2000/svg";
//appears above a selection of text in a RichTextBox to give user options such as Bold, Italics, etc.
export class TooltipTextMenu {
- private tooltip: HTMLElement;
+ public tooltip: HTMLElement;
private num_icons = 0;
private view: EditorView;
private fontStyles: MarkType[];
private fontSizes: MarkType[];
+ private listTypes: NodeType[];
private editorProps: FieldViewProps;
private state: EditorState;
private fontSizeToNum: Map<MarkType, number>;
private fontStylesToName: Map<MarkType, string>;
+ private listTypeToIcon: Map<NodeType, string>;
private fontSizeIndicator: HTMLSpanElement = document.createElement("span");
+ //dropdown doms
+ private fontSizeDom: Node;
+ private fontStyleDom: Node;
+ private listTypeBtnDom: Node;
constructor(view: EditorView, editorProps: FieldViewProps) {
this.view = view;
@@ -55,8 +62,9 @@ export class TooltipTextMenu {
{ command: toggleMark(schema.marks.strikethrough), dom: this.icon("S", "strikethrough") },
{ command: toggleMark(schema.marks.superscript), dom: this.icon("s", "superscript") },
{ command: toggleMark(schema.marks.subscript), dom: this.icon("s", "subscript") },
- { command: wrapInList(schema.nodes.bullet_list), dom: this.icon(":", "bullets") },
- { command: lift, dom: this.icon("<", "lift") },
+ // { command: wrapInList(schema.nodes.bullet_list), dom: this.icon(":", "bullets") },
+ // { command: wrapInList(schema.nodes.ordered_list), dom: this.icon("1)", "bullets") },
+ // { command: lift, dom: this.icon("<", "lift") },
];
//add menu items
items.forEach(({ dom, command }) => {
@@ -76,7 +84,7 @@ export class TooltipTextMenu {
this.fontStylesToName.set(schema.marks.timesNewRoman, "Times New Roman");
this.fontStylesToName.set(schema.marks.arial, "Arial");
this.fontStylesToName.set(schema.marks.georgia, "Georgia");
- this.fontStylesToName.set(schema.marks.comicSans, "Comic Sans");
+ this.fontStylesToName.set(schema.marks.comicSans, "Comic Sans MS");
this.fontStylesToName.set(schema.marks.tahoma, "Tahoma");
this.fontStylesToName.set(schema.marks.impact, "Impact");
this.fontStylesToName.set(schema.marks.crimson, "Crimson Text");
@@ -93,38 +101,75 @@ export class TooltipTextMenu {
this.fontSizeToNum.set(schema.marks.p72, 72);
this.fontSizes = Array.from(this.fontSizeToNum.keys());
- this.addFontDropdowns();
+ //list types
+ this.listTypeToIcon = new Map();
+ this.listTypeToIcon.set(schema.nodes.bullet_list, ":");
+ this.listTypeToIcon.set(schema.nodes.ordered_list, "1)");
+ this.listTypes = Array.from(this.listTypeToIcon.keys());
this.update(view, undefined);
}
- //adds font size and font style dropdowns
- addFontDropdowns() {
+ //label of dropdown will change to given label
+ updateFontSizeDropdown(label: string) {
//filtering function - might be unecessary
let cut = (arr: MenuItem[]) => arr.filter(x => x);
+
+ //font SIZES
+ let fontSizeBtns: MenuItem[] = [];
+ this.fontSizeToNum.forEach((number, mark) => {
+ fontSizeBtns.push(this.dropdownMarkBtn(String(number), "width: 50px;", mark, this.view, this.changeToMarkInGroup, this.fontSizes));
+ });
+
+ if (this.fontSizeDom) { this.tooltip.removeChild(this.fontSizeDom); }
+ this.fontSizeDom = (new Dropdown(cut(fontSizeBtns), {
+ label: label,
+ css: "color:white; min-width: 60px; padding-left: 5px; margin-right: 0;"
+ }) as MenuItem).render(this.view).dom;
+ this.tooltip.appendChild(this.fontSizeDom);
+ }
+
+ //label of dropdown will change to given label
+ updateFontStyleDropdown(label: string) {
+ //filtering function - might be unecessary
+ let cut = (arr: MenuItem[]) => arr.filter(x => x);
+
//font STYLES
let fontBtns: MenuItem[] = [];
this.fontStylesToName.forEach((name, mark) => {
- fontBtns.push(this.dropdownBtn(name, "font-family: " + name + ", sans-serif; width: 120px;", mark, this.view, this.changeToMarkInGroup, this.fontStyles));
+ fontBtns.push(this.dropdownMarkBtn(name, "font-family: " + name + ", sans-serif; width: 125px;", mark, this.view, this.changeToMarkInGroup, this.fontStyles));
});
- //font size indicator
- this.fontSizeIndicator = this.icon("12", "font-size-indicator");
+ if (this.fontStyleDom) { this.tooltip.removeChild(this.fontStyleDom); }
+ this.fontStyleDom = (new Dropdown(cut(fontBtns), {
+ label: label,
+ css: "color:white; width: 125px; margin-left: -3px; padding-left: 2px;"
+ }) as MenuItem).render(this.view).dom;
- //font SIZES
- let fontSizeBtns: MenuItem[] = [];
- this.fontSizeToNum.forEach((number, mark) => {
- fontSizeBtns.push(this.dropdownBtn(String(number), "width: 50px;", mark, this.view, this.changeToMarkInGroup, this.fontSizes));
+ this.tooltip.appendChild(this.fontStyleDom);
+ }
+
+ //will display a remove-list-type button if selection is in list, otherwise will show list type dropdown
+ updateListItemDropdown(label: string, listTypeBtn: Node) {
+ //remove old btn
+ if (listTypeBtn) { this.tooltip.removeChild(listTypeBtn); }
+
+ //Make a dropdown of all list types
+ let toAdd: MenuItem[] = [];
+ this.listTypeToIcon.forEach((icon, type) => {
+ toAdd.push(this.dropdownNodeBtn(icon, "width: 40px;", type, this.view, this.listTypes, this.changeToNodeType));
});
+ //option to remove the list formatting
+ toAdd.push(this.dropdownNodeBtn("X", "width: 40px;", undefined, this.view, this.listTypes, this.changeToNodeType));
+
+ listTypeBtn = (new Dropdown(toAdd, {
+ label: label,
+ css: "color:white; width: 40px;"
+ }) as MenuItem).render(this.view).dom;
- //dropdown to hold font btns
- let dd_fontStyle = new Dropdown(cut(fontBtns), { label: "Font Style", css: "color:white;" }) as MenuItem;
- let dd_fontSize = new Dropdown(cut(fontSizeBtns), { label: "Font Size", css: "color:white; margin-left: -6px;" }) as MenuItem;
- this.tooltip.appendChild(dd_fontStyle.render(this.view).dom);
- this.tooltip.appendChild(this.fontSizeIndicator);
- this.tooltip.appendChild(dd_fontSize.render(this.view).dom);
- dd_fontStyle.render(this.view).dom.nodeValue = "TEST";
- console.log(dd_fontStyle.render(this.view).dom.nodeValue);
+ //add this new button and return it
+ this.tooltip.appendChild(listTypeBtn);
+ return listTypeBtn;
}
//for a specific grouping of marks (passed in), remove all and apply the passed-in one to the selected text
@@ -158,9 +203,18 @@ export class TooltipTextMenu {
return toggleMark(markType)(view.state, view.dispatch, view);
}
- //makes a button for the drop down
+ //remove all node typeand apply the passed-in one to the selected text
+ changeToNodeType(nodeType: NodeType | undefined, view: EditorView, allNodes: NodeType[]) {
+ //remove old
+ liftListItem(schema.nodes.list_item)(view.state, view.dispatch);
+ if (nodeType) { //add new
+ wrapInList(nodeType)(view.state, view.dispatch);
+ }
+ }
+
+ //makes a button for the drop down FOR MARKS
//css is the style you want applied to the button
- dropdownBtn(label: string, css: string, markType: MarkType, view: EditorView, changeToMarkInGroup: (markType: MarkType<any>, view: EditorView, groupMarks: MarkType[]) => any, groupMarks: MarkType[]) {
+ dropdownMarkBtn(label: string, css: string, markType: MarkType, view: EditorView, changeToMarkInGroup: (markType: MarkType<any>, view: EditorView, groupMarks: MarkType[]) => any, groupMarks: MarkType[]) {
return new MenuItem({
title: "",
label: label,
@@ -173,6 +227,23 @@ export class TooltipTextMenu {
}
});
}
+
+ //makes a button for the drop down FOR NODE TYPES
+ //css is the style you want applied to the button
+ dropdownNodeBtn(label: string, css: string, nodeType: NodeType | undefined, view: EditorView, groupNodes: NodeType[], changeToNodeInGroup: (nodeType: NodeType<any> | undefined, view: EditorView, groupNodes: NodeType[]) => any) {
+ return new MenuItem({
+ title: "",
+ label: label,
+ execEvent: "",
+ class: "menuicon",
+ css: css,
+ enable(state) { return true; },
+ run() {
+ changeToNodeInGroup(nodeType, view, groupNodes);
+ }
+ });
+ }
+
// Helper function to create menu icons
icon(text: string, name: string) {
let span = document.createElement("span");
@@ -246,34 +317,39 @@ export class TooltipTextMenu {
let width = Math.abs(start.left - end.left) / 2 * this.editorProps.ScreenToLocalTransform().Scale;
let mid = Math.min(start.left, end.left) + width;
- this.tooltip.style.width = 220 + "px";
+ this.tooltip.style.width = 225 + "px";
this.tooltip.style.bottom = (box.bottom - start.top) * this.editorProps.ScreenToLocalTransform().Scale + "px";
+ //UPDATE LIST ITEM DROPDOWN
+ this.listTypeBtnDom = this.updateListItemDropdown(":", this.listTypeBtnDom);
+
+ //UPDATE FONT STYLE DROPDOWN
let activeStyles = this.activeMarksOnSelection(this.fontStyles);
if (activeStyles.length === 1) {
// if we want to update something somewhere with active font name
let fontName = this.fontStylesToName.get(activeStyles[0]);
+ if (fontName) { this.updateFontStyleDropdown(fontName); }
} else if (activeStyles.length === 0) {
//crimson on default
+ this.updateFontStyleDropdown("Crimson Text");
+ } else {
+ this.updateFontStyleDropdown("Various");
}
- //update font size indicator
+ //UPDATE FONT SIZE DROPDOWN
let activeSizes = this.activeMarksOnSelection(this.fontSizes);
if (activeSizes.length === 1) { //if there's only one active font size
let size = this.fontSizeToNum.get(activeSizes[0]);
- if (size) {
- this.fontSizeIndicator.innerHTML = String(size);
- }
- //should be 14 on default
+ if (size) { this.updateFontSizeDropdown(String(size) + " pt"); }
} else if (activeSizes.length === 0) {
- this.fontSizeIndicator.innerHTML = "14";
- //multiple font sizes selected
- } else {
- this.fontSizeIndicator.innerHTML = "";
+ //should be 14 on default
+ this.updateFontSizeDropdown("14 pt");
+ } else { //multiple font sizes selected
+ this.updateFontSizeDropdown("Various");
}
}
- //finds all active marks on selection
+ //finds all active marks on selection in given group
activeMarksOnSelection(markGroup: MarkType[]) {
//current selection
let { empty, $cursor, ranges } = this.view.state.selection as TextSelection;