aboutsummaryrefslogtreecommitdiff
path: root/src/client/util/TooltipTextMenu.tsx
diff options
context:
space:
mode:
authorTyler Schicke <tyler_schicke@brown.edu>2019-05-07 16:29:02 -0400
committerTyler Schicke <tyler_schicke@brown.edu>2019-05-07 16:29:02 -0400
commit14c776b6d30e0bc0d5b3712f28e4b9f1170eae3b (patch)
tree5255d8cce8a72a5b09cc1ad58661e2176295467a /src/client/util/TooltipTextMenu.tsx
parente19fdbba4cf672aee5bfb59b91b6162431d146d3 (diff)
parent26141a697ae52a7edf3cc6845ce2153111f8860e (diff)
Merge branch 'master' of github-tsch-brown:browngraphicslab/Dash-Web into new_search
Diffstat (limited to 'src/client/util/TooltipTextMenu.tsx')
-rw-r--r--src/client/util/TooltipTextMenu.tsx148
1 files changed, 112 insertions, 36 deletions
diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx
index a92cbd263..68a73375e 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;