diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/util/ProsemirrorKeymap.ts | 8 | ||||
-rw-r--r-- | src/client/util/TooltipLinkingMenu.tsx | 86 | ||||
-rw-r--r-- | src/client/util/TooltipTextMenu.scss | 4 | ||||
-rw-r--r-- | src/client/views/nodes/FormattedTextBox.tsx | 19 |
4 files changed, 110 insertions, 7 deletions
diff --git a/src/client/util/ProsemirrorKeymap.ts b/src/client/util/ProsemirrorKeymap.ts index 7718b3c06..00d086b97 100644 --- a/src/client/util/ProsemirrorKeymap.ts +++ b/src/client/util/ProsemirrorKeymap.ts @@ -50,10 +50,10 @@ export default function buildKeymap<S extends Schema<any>>(schema: S, mapKeys?: } if (type = schema.nodes.bullet_list) { - bind("Shift-Ctrl-8", wrapInList(type)); + bind("Ctrl-b", wrapInList(type)); } if (type = schema.nodes.ordered_list) { - bind("Shift-Ctrl-9", wrapInList(type)); + bind("Ctrl-n", wrapInList(type)); } if (type = schema.nodes.blockquote) { bind("Ctrl->", wrapIn(type)); @@ -74,8 +74,8 @@ export default function buildKeymap<S extends Schema<any>>(schema: S, mapKeys?: } if (type = schema.nodes.list_item) { bind("Enter", splitListItem(type)); - bind("Mod-[", liftListItem(type)); - bind("Mod-]", sinkListItem(type)); + bind("Shift-Tab", liftListItem(type)); + bind("Tab", sinkListItem(type)); } if (type = schema.nodes.paragraph) { bind("Shift-Ctrl-0", setBlockType(type)); diff --git a/src/client/util/TooltipLinkingMenu.tsx b/src/client/util/TooltipLinkingMenu.tsx new file mode 100644 index 000000000..55e0eb909 --- /dev/null +++ b/src/client/util/TooltipLinkingMenu.tsx @@ -0,0 +1,86 @@ +import { action, IReactionDisposer, reaction } from "mobx"; +import { Dropdown, DropdownSubmenu, MenuItem, MenuItemSpec, renderGrouped, icons, } from "prosemirror-menu"; //no import css +import { baseKeymap, lift } from "prosemirror-commands"; +import { history, redo, undo } from "prosemirror-history"; +import { keymap } from "prosemirror-keymap"; +import { EditorState, Transaction, NodeSelection, TextSelection } from "prosemirror-state"; +import { EditorView } from "prosemirror-view"; +import { schema } from "./RichTextSchema"; +import { Schema, NodeType, MarkType } from "prosemirror-model"; +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 { + faListUl, +} from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { FieldViewProps } from "../views/nodes/FieldView"; +import { throwStatement } from "babel-types"; + +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 TooltipLinkingMenu { + + private tooltip: HTMLElement; + private view: EditorView; + private editorProps: FieldViewProps; + + constructor(view: EditorView, editorProps: FieldViewProps) { + this.view = view; + this.editorProps = editorProps; + this.tooltip = document.createElement("div"); + this.tooltip.className = "tooltipMenu linking"; + + //add the div which is the tooltip + view.dom.parentNode!.parentNode!.appendChild(this.tooltip); + + let target = "https://www.google.com"; + + let link = document.createElement("a"); + link.href = target; + link.textContent = target; + link.target = "_blank"; + link.style.color = "white"; + this.tooltip.appendChild(link); + + this.update(view, undefined); + } + + //updates the tooltip menu when the selection changes + update(view: EditorView, lastState: EditorState | undefined) { + let state = view.state; + // Don't do anything if the document/selection didn't change + if (lastState && lastState.doc.eq(state.doc) && + lastState.selection.eq(state.selection)) return; + + // Hide the tooltip if the selection is empty + if (state.selection.empty) { + this.tooltip.style.display = "none"; + return; + } + + console.log("STORED:"); + console.log(state.doc.content.firstChild!.content); + + // Otherwise, reposition it and update its content + this.tooltip.style.display = ""; + let { from, to } = state.selection; + let start = view.coordsAtPos(from), end = view.coordsAtPos(to); + // The box in which the tooltip is positioned, to use as base + let box = this.tooltip.offsetParent!.getBoundingClientRect(); + // Find a center-ish x position from the selection endpoints (when + // crossing lines, end may be more to the left) + let left = Math.max((start.left + end.left) / 2, start.left + 3); + this.tooltip.style.left = (left - box.left) * this.editorProps.ScreenToLocalTransform().Scale + "px"; + 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 = "auto"; + this.tooltip.style.bottom = (box.bottom - start.top) * this.editorProps.ScreenToLocalTransform().Scale + "px"; + } + + destroy() { this.tooltip.remove(); } +} diff --git a/src/client/util/TooltipTextMenu.scss b/src/client/util/TooltipTextMenu.scss index 7e6659a52..5c2d66480 100644 --- a/src/client/util/TooltipTextMenu.scss +++ b/src/client/util/TooltipTextMenu.scss @@ -67,6 +67,10 @@ min-width: 6em; } + .linking { + text-align: center; + } + .ProseMirror-menu-dropdown-item { cursor: pointer; padding: 2px 8px 2px 4px; diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 631139d32..7c4463b92 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -19,6 +19,7 @@ import { undoItem } from "prosemirror-menu"; import buildKeymap from "../../util/ProsemirrorKeymap"; import { TextField } from "../../../fields/TextField"; import { KeyStore } from "../../../fields/KeyStore"; +import { TooltipLinkingMenu } from "../../util/TooltipLinkingMenu"; const { buildMenuItems } = require("prosemirror-example-setup"); const { menuBar } = require("prosemirror-menu"); @@ -86,7 +87,8 @@ export class FormattedTextBox extends React.Component<(FieldViewProps & Formatte history(), keymap(buildKeymap(schema)), keymap(baseKeymap), - this.tooltipMenuPlugin(), + this.tooltipTextMenuPlugin(), + // this.tooltipLinkingMenuPlugin(), new Plugin({ props: { attributes: { class: "ProseMirror-example-setup-style" } @@ -94,7 +96,7 @@ export class FormattedTextBox extends React.Component<(FieldViewProps & Formatte }) ] : [ history(), - keymap({ "Mod-z": undo, "Mod-y": redo }), + keymap(buildKeymap(schema)), keymap(baseKeymap), ] }; @@ -230,7 +232,7 @@ export class FormattedTextBox extends React.Component<(FieldViewProps & Formatte e.stopPropagation(); } - tooltipMenuPlugin() { + tooltipTextMenuPlugin() { let myprops = this.props; return new Plugin({ view(_editorView) { @@ -238,8 +240,19 @@ export class FormattedTextBox extends React.Component<(FieldViewProps & Formatte } }); } + + tooltipLinkingMenuPlugin() { + let myprops = this.props; + return new Plugin({ + view(_editorView) { + return new TooltipLinkingMenu(_editorView, myprops); + } + }); + } + onKeyPress(e: React.KeyboardEvent) { e.stopPropagation(); + if (e.keyCode === 9) e.preventDefault(); // 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; |