From 80d4bf70cb8e29f15d8e51b1e0bd378a26d68fcf Mon Sep 17 00:00:00 2001 From: vellichora Date: Tue, 7 Jan 2020 03:07:18 -0500 Subject: converted tool tip text menu to react component with basic marks and dropdown --- src/client/views/DocumentDecorations.tsx | 6 ++++++ src/client/views/MainView.tsx | 2 ++ src/client/views/nodes/FormattedTextBox.tsx | 9 +++++++-- src/client/views/pdf/PDFMenu.tsx | 2 +- 4 files changed, 16 insertions(+), 3 deletions(-) (limited to 'src/client/views') diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 4bc24fa93..76b6a8834 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -26,6 +26,8 @@ import { IconBox } from "./nodes/IconBox"; import React = require("react"); import { DocumentType } from '../documents/DocumentTypes'; import { ScriptField } from '../../new_fields/ScriptField'; +import { render } from 'react-dom'; +import RichTextMenu from '../util/RichTextMenu'; const higflyout = require("@hig/flyout"); export const { anchorPoints } = higflyout; export const Flyout = higflyout.default; @@ -572,6 +574,8 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> if (bounds.y > bounds.b) { bounds.y = bounds.b - (this._resizeBorderWidth + this._linkBoxHeight + this._titleHeight); } + // RichTextMenu.Instance.jumpTo(this._lastX, this._lastY - 50); + RichTextMenu.Instance.jumpTo(500, 300); return (
}}> {minimizeIcon} + {/* */} + {this._edtingTitle ? this.titleBlur(true)} onChange={this.titleChanged} onKeyPress={this.titleEntered} /> :
{`${this.selectionTitle}`}
} diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index db2a3c298..9a0b7b7a2 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -40,6 +40,7 @@ import InkSelectDecorations from './InkSelectDecorations'; import { Scripting } from '../util/Scripting'; import { AudioBox } from './nodes/AudioBox'; import { TraceMobx } from '../../new_fields/util'; +import RichTextMenu from '../util/RichTextMenu'; @observer export class MainView extends React.Component { @@ -516,6 +517,7 @@ export class MainView extends React.Component { +
); } diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index a08c14436..7e81876a2 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -47,6 +47,7 @@ import { AudioBox } from './AudioBox'; import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView'; import { InkTool } from '../../../new_fields/InkField'; import { TraceMobx } from '../../../new_fields/util'; +import RichTextMenu from '../../util/RichTextMenu'; library.add(faEdit); library.add(faSmile, faTextHeight, faUpload); @@ -1032,7 +1033,9 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & const self = FormattedTextBox; return new Plugin({ view(newView) { - return self.ToolTipTextMenu = FormattedTextBox.getToolTip(newView); + // return self.ToolTipTextMenu = FormattedTextBox.getToolTip(newView); + RichTextMenu.Instance.changeView(newView); + return RichTextMenu.Instance; } }); } @@ -1121,7 +1124,9 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & const rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : ""; const interactive = InkingControl.Instance.selectedTool || this.layoutDoc.isBackground; if (this.props.isSelected()) { - FormattedTextBox.ToolTipTextMenu!.updateFromDash(this._editorView!, undefined, this.props); + // TODO: ftong --> update from dash in richtextmenu + RichTextMenu.Instance.updateFromDash(this._editorView!, undefined, this.props); + // FormattedTextBox.ToolTipTextMenu!.updateFromDash(this._editorView!, undefined, this.props); } else if (FormattedTextBoxComment.textBox === this) { FormattedTextBoxComment.Hide(); } diff --git a/src/client/views/pdf/PDFMenu.tsx b/src/client/views/pdf/PDFMenu.tsx index 503696ae9..05c70b74a 100644 --- a/src/client/views/pdf/PDFMenu.tsx +++ b/src/client/views/pdf/PDFMenu.tsx @@ -98,7 +98,7 @@ export default class PDFMenu extends AntimodeMenu { } render() { - const buttons = this.Status === "pdf" ? + const buttons = this.Status === "pdf" ? [ , -- cgit v1.2.3-70-g09d2 From 4791f95d6be68e590d0a80689d89be4c05e9ffc3 Mon Sep 17 00:00:00 2001 From: vellichora Date: Tue, 7 Jan 2020 06:43:26 -0500 Subject: starting integrating brush tool into richtextmenu --- src/client/util/RichTextMenu.scss | 10 +++ src/client/util/RichTextMenu.tsx | 137 +++++++++++++++++++++++++++++++++++-- src/client/views/AntimodeMenu.scss | 2 +- src/client/views/AntimodeMenu.tsx | 12 ++-- 4 files changed, 150 insertions(+), 11 deletions(-) create mode 100644 src/client/util/RichTextMenu.scss (limited to 'src/client/views') diff --git a/src/client/util/RichTextMenu.scss b/src/client/util/RichTextMenu.scss new file mode 100644 index 000000000..f14703006 --- /dev/null +++ b/src/client/util/RichTextMenu.scss @@ -0,0 +1,10 @@ +.button-dropdown-wrapper { + position: relative; + + .dropdown { + position: absolute; + top: 30px; + left: 0; + background-color: black; + } +} \ No newline at end of file diff --git a/src/client/util/RichTextMenu.tsx b/src/client/util/RichTextMenu.tsx index 6b6a2620e..fa65adca5 100644 --- a/src/client/util/RichTextMenu.tsx +++ b/src/client/util/RichTextMenu.tsx @@ -5,10 +5,10 @@ import { observer } from "mobx-react"; import { Mark, MarkType, Node as ProsNode, NodeType, ResolvedPos, Schema } from "prosemirror-model"; import { schema } from "./RichTextSchema"; import { EditorView } from "prosemirror-view"; -import { EditorState, NodeSelection } from "prosemirror-state"; +import { EditorState, NodeSelection, TextSelection } from "prosemirror-state"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { IconProp, library } from '@fortawesome/fontawesome-svg-core'; -import { faBold, faItalic, faUnderline, faStrikethrough, faSubscript, faSuperscript, faIndent } from "@fortawesome/free-solid-svg-icons"; +import { faBold, faItalic, faUnderline, faStrikethrough, faSubscript, faSuperscript, faIndent, faEyeDropper, faCaretDown } from "@fortawesome/free-solid-svg-icons"; import { MenuItem, Dropdown } from "prosemirror-menu"; import { updateBullets } from "./ProsemirrorExampleTransfer"; import { FieldViewProps } from "../views/nodes/FieldView"; @@ -16,9 +16,10 @@ import { NumCast } from "../../new_fields/Types"; import { FormattedTextBoxProps } from "../views/nodes/FormattedTextBox"; import { unimplementedFunction } from "../../Utils"; import { wrapInList } from "prosemirror-schema-list"; +import "./RichTextMenu.scss"; const { toggleMark, setBlockType } = require("prosemirror-commands"); -library.add(faBold, faItalic, faUnderline, faStrikethrough, faSuperscript, faSubscript, faIndent); +library.add(faBold, faItalic, faUnderline, faStrikethrough, faSuperscript, faSubscript, faIndent, faEyeDropper, faCaretDown); @observer export default class RichTextMenu extends AntimodeMenu { @@ -31,6 +32,9 @@ export default class RichTextMenu extends AntimodeMenu { @observable private activeFontFamily: string = ""; @observable private activeListType: string = ""; + @observable private brushIsEmpty: boolean = true; + @observable private brushMarks: Set = new Set(); + constructor(props: Readonly<{}>) { super(props); RichTextMenu.Instance = this; @@ -121,6 +125,13 @@ export default class RichTextMenu extends AntimodeMenu { return styles; } + getMarksInSelection(state: EditorState) { + const found = new Set(); + const { from, to } = state.selection as TextSelection; + state.doc.nodesBetween(from, to, (node) => node.marks?.forEach(m => found.add(m))); + return found; + } + destroy() { console.log("destroy"); } @@ -142,7 +153,7 @@ export default class RichTextMenu extends AntimodeMenu { } return ( - ); @@ -259,6 +270,123 @@ export default class RichTextMenu extends AntimodeMenu { return true; } + createBrushButton() { + const self = this; + function onClick(e: React.PointerEvent) { + console.log("clicked button"); + // dom.addEventListener("pointerdown", e => { + e.preventDefault(); + self.view && self.view.focus(); + // if (dom.contains(e.target as Node)) { + e.stopPropagation(); + // command(this.view.state, this.view.dispatch, this.view); + // } + // }); + + self.view && self.brush_function(self.view.state, self.view.dispatch); + + // // update dropdown with marks + // const newBrushDropdowndom = self.createBrushDropdown().render(self.view).dom; + // self._brushDropdownDom && self.tooltip.replaceChild(newBrushDropdowndom, self._brushDropdownDom); + // self._brushDropdownDom = newBrushDropdowndom; + } + + let label = "Stored marks: "; + if (this.brushMarks && this.brushMarks.size > 0) { + this.brushMarks.forEach((mark: Mark) => { + const markType = mark.type; + label += markType.name; + label += ", "; + }); + label = label.substring(0, label.length - 2); + } else { + label = "No marks are currently stored"; + } + + return ( +
+ + +
+

{label}

+ + {/* */} +
+
+ ); + } + + @action + clearBrush() { + this.brushIsEmpty = true; + this.brushMarks = new Set(); + } + + @action + brush_function(state: EditorState, dispatch: any) { + if (!this.view) return; + + if (this.brushIsEmpty) { + const selected_marks = this.getMarksInSelection(this.view.state); + // if (this._brushdom) { + if (selected_marks.size >= 0) { + this.brushMarks = selected_marks; + // const newbrush = this.createBrush(true).render(this.view).dom; + // this.tooltip.replaceChild(newbrush, this._brushdom); + // this._brushdom = newbrush; + this.brushIsEmpty = !this.brushIsEmpty; + // TooltipTextMenuManager.Instance._brushIsEmpty = !TooltipTextMenuManager.Instance._brushIsEmpty; + } + // } + } + else { + const { from, to, $from } = this.view.state.selection; + // if (this._brushdom) { + if (!this.view.state.selection.empty && $from && $from.nodeAfter) { + if (this.brushMarks && to - from > 0) { + this.view.dispatch(this.view.state.tr.removeMark(from, to)); + Array.from(this.brushMarks).filter(m => m.type !== schema.marks.user_mark).forEach((mark: Mark) => { + this.setMark(mark, this.view!.state, this.view!.dispatch); + }); + } + } + else { + // const newbrush = this.createBrush(false).render(this.view).dom; + // this.tooltip.replaceChild(newbrush, this._brushdom); + // this._brushdom = newbrush; + this.brushIsEmpty = !this.brushIsEmpty; + // TooltipTextMenuManager.Instance._brushIsEmpty = !TooltipTextMenuManager.Instance._brushIsEmpty; + } + // } + } + console.log("brush marks are ", this.brushMarks); + } + + // createColorButton() { + // const self = this; + // function onClick(e: React.PointerEvent) { + // console.log("clicked button"); + // // dom.addEventListener("pointerdown", e => { + // e.preventDefault(); + // self.view && self.view.focus(); + // // if (dom.contains(e.target as Node)) { + // e.stopPropagation(); + // // command(this.view.state, this.view.dispatch, this.view); + // // } + // // }); + // self.view && command && command(self.view!.state, self.view!.dispatch, self.view); + // self.view && onclick && onclick(self.view!.state, self.view!.dispatch, self.view); + // } + + // return ( + // + // ); + // } + reference_node(pos: ResolvedPos): ProsNode | null { if (!this.view) return null; @@ -354,6 +482,7 @@ export default class RichTextMenu extends AntimodeMenu { this.createButton("strikethrough", "Strikethrough", toggleMark(schema.marks.strikethrough)), this.createButton("superscript", "Superscript", toggleMark(schema.marks.superscript)), this.createButton("subscript", "Subscript", toggleMark(schema.marks.subscript)), + this.createBrushButton(), this.createButton("indent", "Summarize", undefined, this.insertSummarizer), this.createMarksDropdown(this.activeFontSize, fontSizeOptions), this.createMarksDropdown(this.activeFontFamily, fontFamilyOptions), diff --git a/src/client/views/AntimodeMenu.scss b/src/client/views/AntimodeMenu.scss index f3da5f284..a45f3346a 100644 --- a/src/client/views/AntimodeMenu.scss +++ b/src/client/views/AntimodeMenu.scss @@ -5,7 +5,7 @@ background: #323232; box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.25); border-radius: 0px 6px 6px 6px; - overflow: hidden; + // overflow: hidden; display: flex; .antimodeMenu-button { diff --git a/src/client/views/AntimodeMenu.tsx b/src/client/views/AntimodeMenu.tsx index 408df8bc2..2e9d29ef9 100644 --- a/src/client/views/AntimodeMenu.tsx +++ b/src/client/views/AntimodeMenu.tsx @@ -62,12 +62,12 @@ export default abstract class AntimodeMenu extends React.Component { @action protected pointerLeave = (e: React.PointerEvent) => { - if (!this.Pinned) { - this._transition = "opacity 0.5s"; - this._transitionDelay = "1s"; - this._opacity = 0.2; - setTimeout(() => this.fadeOut(false), 3000); - } + // if (!this.Pinned) { + // this._transition = "opacity 0.5s"; + // this._transitionDelay = "1s"; + // this._opacity = 0.2; + // setTimeout(() => this.fadeOut(false), 3000); + // } } @action -- cgit v1.2.3-70-g09d2 From 80c417f24bcc1109e12645cfc522a820cf22e099 Mon Sep 17 00:00:00 2001 From: vellichora Date: Tue, 7 Jan 2020 10:51:40 -0500 Subject: pull from master --- package-lock.json | 77 ++++++++++++++++---------------- src/client/util/RichTextMenu.tsx | 20 +-------- src/client/util/SelectionManager.ts | 1 + src/client/views/DocumentDecorations.tsx | 10 ++++- 4 files changed, 50 insertions(+), 58 deletions(-) (limited to 'src/client/views') diff --git a/package-lock.json b/package-lock.json index 0fbc4dcf5..2c70ba94d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2423,7 +2423,7 @@ "resolved": "https://registry.npmjs.org/boolify-string/-/boolify-string-2.0.2.tgz", "integrity": "sha1-n4m9l9YKFEijlAF8SjuaPSQNRY4=", "requires": { - "type-detect": "1.0.0" + "type-detect": "^1.0.0" }, "dependencies": { "type-detect": { @@ -2561,7 +2561,7 @@ }, "browserify-aes": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "requires": { "buffer-xor": "^1.0.3", @@ -2595,7 +2595,7 @@ }, "browserify-rsa": { "version": "4.0.1", - "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "requires": { "bn.js": "^4.1.0", @@ -2632,7 +2632,7 @@ }, "buffer": { "version": "4.9.1", - "resolved": "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", "dev": true, "requires": { @@ -2779,7 +2779,7 @@ }, "camelcase-keys": { "version": "2.1.0", - "resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", "requires": { "camelcase": "^2.0.0", @@ -3482,8 +3482,8 @@ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", "requires": { - "object-assign": "4.1.1", - "vary": "1.1.2" + "object-assign": "^4", + "vary": "^1" } }, "cosmiconfig": { @@ -3563,7 +3563,7 @@ }, "create-hash": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "requires": { "cipher-base": "^1.0.1", @@ -3575,7 +3575,7 @@ }, "create-hmac": { "version": "1.1.7", - "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "requires": { "cipher-base": "^1.0.3", @@ -4118,7 +4118,7 @@ }, "diffie-hellman": { "version": "5.0.3", - "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "requires": { "bn.js": "^4.1.0", @@ -4318,9 +4318,10 @@ }, "emit-logger": { "version": "github:chocolateboy/emit-logger#b9d25a2d939e42f29c940861e9648bd0fb810070", + "from": "github:chocolateboy/emit-logger#better-emitter-name", "requires": { - "chalk": "1.1.3", - "moment": "2.24.0" + "chalk": "^1.1.1", + "moment": "^2.10.6" } }, "emoji-regex": { @@ -7069,18 +7070,18 @@ "resolved": "https://registry.npmjs.org/ipc-event-emitter/-/ipc-event-emitter-2.0.2.tgz", "integrity": "sha512-hJsN8zCg8MZwl5nbTutqINDO4pJPbKwmCfrTJaRLNE+5H15mJx7Mxo3pXIAi8zlh+N5xpf+PdMOQ0pbtZQvRKA==", "requires": { - "babel-runtime": "6.26.0", - "bluebird": "3.5.5", - "boolify-string": "2.0.2", - "emit-logger": "github:chocolateboy/emit-logger#b9d25a2d939e42f29c940861e9648bd0fb810070", - "lodash": "4.17.15", - "semver": "5.7.0", - "source-map-support": "0.5.12" + "babel-runtime": "^6.22.0", + "bluebird": "^3.4.7", + "boolify-string": "^2.0.2", + "emit-logger": "github:chocolateboy/emit-logger#better-emitter-name", + "lodash": "^4.17.4", + "semver": "^5.0.3", + "source-map-support": "^0.5.9" } }, "is-accessor-descriptor": { "version": "0.1.6", - "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "requires": { "kind-of": "^3.0.2" @@ -7129,7 +7130,7 @@ }, "is-data-descriptor": { "version": "0.1.4", - "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "requires": { "kind-of": "^3.0.2" @@ -7914,7 +7915,7 @@ }, "load-json-file": { "version": "1.1.0", - "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "requires": { "graceful-fs": "^4.1.2", @@ -8228,7 +8229,7 @@ }, "media-typer": { "version": "0.3.0", - "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, "mem": { @@ -8260,7 +8261,7 @@ }, "meow": { "version": "3.7.0", - "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", "requires": { "camelcase-keys": "^2.0.0", @@ -8453,7 +8454,7 @@ }, "mkdirp": { "version": "0.5.1", - "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "requires": { "minimist": "0.0.8" @@ -8799,7 +8800,7 @@ }, "next-tick": { "version": "1.0.0", - "resolved": "http://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" }, "nice-try": { @@ -8963,7 +8964,7 @@ }, "semver": { "version": "5.3.0", - "resolved": "http://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" }, "tar": { @@ -12572,7 +12573,7 @@ }, "os-homedir": { "version": "1.0.2", - "resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" }, "os-locale": { @@ -12585,7 +12586,7 @@ }, "os-tmpdir": { "version": "1.0.2", - "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" }, "osenv": { @@ -12825,7 +12826,7 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-is-inside": { @@ -14145,7 +14146,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "requires": { "core-util-is": "~1.0.0", @@ -14490,7 +14491,7 @@ }, "safe-regex": { "version": "1.1.0", - "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "requires": { "ret": "~0.1.10" @@ -14755,7 +14756,7 @@ }, "sha.js": { "version": "2.4.11", - "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "requires": { "inherits": "^2.0.1", @@ -15498,7 +15499,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "requires": { "safe-buffer": "~5.1.0" @@ -15528,7 +15529,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" @@ -15544,7 +15545,7 @@ }, "strip-eof": { "version": "1.0.0", - "resolved": "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" }, "strip-indent": { @@ -16297,7 +16298,7 @@ }, "tty-browserify": { "version": "0.0.0", - "resolved": "http://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", "dev": true }, @@ -17739,7 +17740,7 @@ }, "wrap-ansi": { "version": "2.1.0", - "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "requires": { "string-width": "^1.0.1", diff --git a/src/client/util/RichTextMenu.tsx b/src/client/util/RichTextMenu.tsx index 371ba97a9..111822307 100644 --- a/src/client/util/RichTextMenu.tsx +++ b/src/client/util/RichTextMenu.tsx @@ -53,6 +53,7 @@ export default class RichTextMenu extends AntimodeMenu { constructor(props: Readonly<{}>) { super(props); RichTextMenu.Instance = this; + this.Pinned = true; } @action @@ -79,16 +80,6 @@ export default class RichTextMenu extends AntimodeMenu { // this.reset_mark_doms(); - // // update link dropdown - // const linkDropdown = await this.createLinkDropdown(); - // const newLinkDropdowndom = linkDropdown.render(this.view).dom; - // this._linkDropdownDom && this.tooltip.replaceChild(newLinkDropdowndom, this._linkDropdownDom); - // this._linkDropdownDom = newLinkDropdowndom; - - // const targetTitle = await this.getTextLinkTargetTitle(); - // // console.log(targetTitle); - // this.setCurrentLink(targetTitle); - // update active font family and size const active = this.getActiveFontStylesOnSelection(); const activeFamilies = active && active.get("families"); @@ -97,6 +88,7 @@ export default class RichTextMenu extends AntimodeMenu { this.activeFontFamily = !activeFamilies || activeFamilies.length === 0 ? "default" : activeFamilies.length === 1 ? String(activeFamilies[0]) : "various"; this.activeFontSize = !activeSizes || activeSizes.length === 0 ? "default" : activeSizes.length === 1 ? String(activeSizes[0]) + "pt" : "various"; + // update link in current selection const targetTitle = await this.getTextLinkTargetTitle(); this.setCurrentLink(targetTitle); @@ -574,29 +566,21 @@ export default class RichTextMenu extends AntimodeMenu { const node = this.view.state.selection.$from.nodeAfter; const link = node && node.marks.find(m => m.type === this.view!.state.schema.marks.link); const href = link!.attrs.href; - console.log("delete link", node, link, href); if (href) { - console.log("has href"); if (href.indexOf(Utils.prepend("/doc/")) === 0) { const linkclicked = href.replace(Utils.prepend("/doc/"), "").split("?")[0]; if (linkclicked) { - console.log("linkclicked"); DocServer.GetRefField(linkclicked).then(async linkDoc => { if (linkDoc instanceof Doc) { - console.log("is doc"); LinkManager.Instance.deleteLink(linkDoc); - console.log("remove the link! ", this.view!.state.selection.from, this.view!.state.selection.to, this.view!.state.schema.marks.link); this.view!.dispatch(this.view!.state.tr.removeMark(this.view!.state.selection.from, this.view!.state.selection.to, this.view!.state.schema.marks.link)); } }); } } else { - console.log("remove the link! ", this.view!.state.selection.from, this.view!.state.selection.to, this.view!.state.schema.marks.link); if (node) { let extension = this.linkExtend(this.view!.state.selection.$anchor, href); - console.log("remove the link", extension.from, extension.to); this.view!.dispatch(this.view!.state.tr.removeMark(extension.from, extension.to, this.view!.state.schema.marks.link)); - } } } diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index 4612f10f4..0c733ac47 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -14,6 +14,7 @@ export namespace SelectionManager { @action SelectDoc(docView: DocumentView, ctrlPressed: boolean): void { + console.log("select doc!!!"); // if doc is not in SelectedDocuments, add it if (!manager.SelectedDocuments.get(docView)) { if (!ctrlPressed) { diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 76b6a8834..093761f1f 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -77,6 +77,11 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> DocumentDecorations.Instance = this; this._keyinput = React.createRef(); reaction(() => SelectionManager.SelectedDocuments().slice(), docs => this.titleBlur(false)); + console.log("constructing document decorations!!!"); + } + + componentDidMount() { + console.log("mounting deocument deoctirioeon!!!!"); } @action titleChanged = (event: any) => this._accumulatedTitle = event.target.value; @@ -574,8 +579,9 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> if (bounds.y > bounds.b) { bounds.y = bounds.b - (this._resizeBorderWidth + this._linkBoxHeight + this._titleHeight); } - // RichTextMenu.Instance.jumpTo(this._lastX, this._lastY - 50); - RichTextMenu.Instance.jumpTo(500, 300); + // // RichTextMenu.Instance.jumpTo(this._lastX, this._lastY - 50); + // console.log("jump to "); + // RichTextMenu.Instance.jumpTo(500, 300); return (
Date: Tue, 7 Jan 2020 14:20:36 -0500 Subject: richtextmenu appears whenever formattedtextbox is focused --- src/client/util/RichTextMenu.scss | 64 +++++++++++++++++++++++++++++ src/client/util/RichTextMenu.tsx | 58 +++++++++++++++++--------- src/client/util/SelectionManager.ts | 3 +- src/client/util/TooltipTextMenu.tsx | 2 + src/client/views/DocumentDecorations.tsx | 8 ---- src/client/views/nodes/FormattedTextBox.tsx | 7 ++++ 6 files changed, 113 insertions(+), 29 deletions(-) (limited to 'src/client/views') diff --git a/src/client/util/RichTextMenu.scss b/src/client/util/RichTextMenu.scss index f7414cc7f..85d2765e3 100644 --- a/src/client/util/RichTextMenu.scss +++ b/src/client/util/RichTextMenu.scss @@ -20,9 +20,73 @@ box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.25); min-width: 150px; padding: 5px; + + button { + background-color: #323232; + border: 1px solid black; + border-radius: 1px; + padding: 6px; + margin: 5px 0; + + &:hover { + background-color: black; + } + } } input { color: black; } +} + +.link-menu { + .divider { + background-color: white; + height: 1px; + width: 100%; + } +} + +.color-preview-button { + .color-preview { + width: 100%; + height: 3px; + margin-top: 3px; + } +} + +.color-wrapper { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + + button.color-button { + width: 20px; + height: 20px; + border-radius: 15px !important; + margin: 3px; + border: 2px solid transparent !important; + padding: 3px; + + &.active { + border: 2px solid white !important; + } + } +} + +select { + background-color: #323232; + color: white; + border: 1px solid black; + border-top: none; + border-bottom: none; + + &:focus, + &:hover { + background-color: black; + } + + &::-ms-expand { + color: white; + } } \ No newline at end of file diff --git a/src/client/util/RichTextMenu.tsx b/src/client/util/RichTextMenu.tsx index 111822307..8c373b818 100644 --- a/src/client/util/RichTextMenu.tsx +++ b/src/client/util/RichTextMenu.tsx @@ -29,6 +29,7 @@ library.add(faBold, faItalic, faUnderline, faStrikethrough, faSuperscript, faSub @observer export default class RichTextMenu extends AntimodeMenu { static Instance: RichTextMenu; + @observable private isVisible: boolean = false; private view?: EditorView; private editorProps: FieldViewProps & FormattedTextBoxProps | undefined; @@ -53,7 +54,6 @@ export default class RichTextMenu extends AntimodeMenu { constructor(props: Readonly<{}>) { super(props); RichTextMenu.Instance = this; - this.Pinned = true; } @action @@ -73,6 +73,7 @@ export default class RichTextMenu extends AntimodeMenu { } this.view = view; const state = view.state; + this.isVisible = true; // DocumentDecorations.Instance.showTextBar(); props && (this.editorProps = props); // Don't do anything if the document/selection didn't change @@ -146,7 +147,6 @@ export default class RichTextMenu extends AntimodeMenu { } destroy() { - console.log("destroy"); } createButton(faIcon: string, title: string, command?: any, onclick?: any) { @@ -213,7 +213,6 @@ export default class RichTextMenu extends AntimodeMenu { } changeFontSize = (mark: Mark, view: EditorView) => { - console.log("change font size!!"); const size = mark.attrs.fontSize; if (this.editorProps) { const ruleProvider = this.editorProps.ruleProvider; @@ -241,9 +240,7 @@ export default class RichTextMenu extends AntimodeMenu { // TODO: remove doesn't work //remove all node type and apply the passed-in one to the selected text changeListType = (nodeType: NodeType | undefined) => { - console.log("change the list type "); if (!this.view) return; - console.log("change the list type has view"); if (nodeType === schema.nodes.bullet_list) { wrapInList(nodeType)(this.view.state, this.view.dispatch); @@ -354,7 +351,6 @@ export default class RichTextMenu extends AntimodeMenu { this.brushIsEmpty = !this.brushIsEmpty; } } - console.log("brush marks are ", this.brushMarks); } @action toggleColorDropdown() { this.showColorDropdown = !this.showColorDropdown; } @@ -397,13 +393,23 @@ export default class RichTextMenu extends AntimodeMenu { return (
- + {this.showColorDropdown ? (
- {colors.map(color => { - if (color) return ; - })} +

Change font color:

+
+ {colors.map(color => { + if (color) { + return this.activeFontColor === color ? + : + ; + } + })} +
) : <>}
@@ -459,13 +465,23 @@ export default class RichTextMenu extends AntimodeMenu { return (
- + {this.showHighlightDropdown ? (
- {colors.map(color => { - if (color) return ; - })} +

Change highlight color:

+
+ {colors.map(color => { + if (color) { + return this.activeHighlightColor === color ? + : + ; + } + })} +
) : <>}
@@ -492,9 +508,6 @@ export default class RichTextMenu extends AntimodeMenu { self.setCurrentLink(e.target.value); } - // const targetTitle = this.getTextLinkTargetTitle(); - console.log("link curr is ", this.currentLink); - // // this.setCurrentLink(targetTitle); const link = this.currentLink ? this.currentLink : ""; return ( @@ -502,11 +515,12 @@ export default class RichTextMenu extends AntimodeMenu { {this.showLinkDropdown ? - (
+ (

Linked to:

- - + +
+
) : <>}
@@ -634,6 +648,10 @@ export default class RichTextMenu extends AntimodeMenu { } render() { + // if (!this.isVisible) return <>; + SelectionManager.SelectedDocuments() + // if (this.Pinned || ) + const fontSizeOptions = [ { mark: schema.marks.pFontSize.create({ fontSize: 7 }), title: "Set font size", label: "7pt", command: this.changeFontSize }, { mark: schema.marks.pFontSize.create({ fontSize: 8 }), title: "Set font size", label: "8pt", command: this.changeFontSize }, diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index 0c733ac47..86a7a620e 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -3,6 +3,8 @@ import { Doc } from "../../new_fields/Doc"; import { DocumentView } from "../views/nodes/DocumentView"; import { computedFn } from "mobx-utils"; import { List } from "../../new_fields/List"; +import { DocumentDecorations } from "../views/DocumentDecorations"; +import RichTextMenu from "./RichTextMenu"; export namespace SelectionManager { @@ -14,7 +16,6 @@ export namespace SelectionManager { @action SelectDoc(docView: DocumentView, ctrlPressed: boolean): void { - console.log("select doc!!!"); // if doc is not in SelectedDocuments, add it if (!manager.SelectedDocuments.get(docView)) { if (!ctrlPressed) { diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx index 33257b658..2c4d08b82 100644 --- a/src/client/util/TooltipTextMenu.tsx +++ b/src/client/util/TooltipTextMenu.tsx @@ -20,6 +20,8 @@ import { PastelSchemaPalette, DarkPastelSchemaPalette } from '../../new_fields/S const { toggleMark, setBlockType } = require("prosemirror-commands"); const { openPrompt, TextField } = require("./ProsemirrorCopy/prompt.js"); +// deprecated in favor of richtextmenu + //appears above a selection of text in a RichTextBox to give user options such as Bold, Italics, etc. export class TooltipTextMenu { public static Toolbar: HTMLDivElement | undefined; diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 093761f1f..799b3695c 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -77,11 +77,6 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> DocumentDecorations.Instance = this; this._keyinput = React.createRef(); reaction(() => SelectionManager.SelectedDocuments().slice(), docs => this.titleBlur(false)); - console.log("constructing document decorations!!!"); - } - - componentDidMount() { - console.log("mounting deocument deoctirioeon!!!!"); } @action titleChanged = (event: any) => this._accumulatedTitle = event.target.value; @@ -579,9 +574,6 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> if (bounds.y > bounds.b) { bounds.y = bounds.b - (this._resizeBorderWidth + this._linkBoxHeight + this._titleHeight); } - // // RichTextMenu.Instance.jumpTo(this._lastX, this._lastY - 50); - // console.log("jump to "); - // RichTextMenu.Instance.jumpTo(500, 300); return (
this._editorView?.dispatch(this._editorView?.state.tr.setSelection(TextSelection.create(this._editorView.state.doc, pos)))); + + // jump rich text menu to this textbox + this._ref.current && RichTextMenu.Instance.jumpTo(this._ref.current.getBoundingClientRect().x, this._ref.current?.getBoundingClientRect().y - 70); } onPointerWheel = (e: React.WheelEvent): void => { // if a text note is not selected and scrollable, this prevents us from being able to scroll and zoom out at the same time @@ -1055,6 +1059,9 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & this._undoTyping = undefined; } this.doLinkOnDeselect(); + + // move the richtextmenu offscreen + if (!RichTextMenu.Instance.Pinned) RichTextMenu.Instance.jumpTo(-300, -300); } _lastTimedMark: Mark | undefined = undefined; -- cgit v1.2.3-70-g09d2 From e9dcc0f18498d9415d204dfd3e61465a70486374 Mon Sep 17 00:00:00 2001 From: vellichora Date: Tue, 7 Jan 2020 15:08:31 -0500 Subject: kind of hack to get selects in richtextmenu to be selectable again --- src/client/util/RichTextMenu.scss | 9 ++++++-- src/client/util/RichTextMenu.tsx | 35 ++++++++++++++++++----------- src/client/views/AntimodeMenu.scss | 9 ++++++++ src/client/views/AntimodeMenu.tsx | 10 +++++++++ src/client/views/nodes/FormattedTextBox.tsx | 5 +++-- 5 files changed, 51 insertions(+), 17 deletions(-) (limited to 'src/client/views') diff --git a/src/client/util/RichTextMenu.scss b/src/client/util/RichTextMenu.scss index 85d2765e3..5a57f4b98 100644 --- a/src/client/util/RichTextMenu.scss +++ b/src/client/util/RichTextMenu.scss @@ -20,6 +20,7 @@ box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.25); min-width: 150px; padding: 5px; + font-size: 12px; button { background-color: #323232; @@ -27,6 +28,7 @@ border-radius: 1px; padding: 6px; margin: 5px 0; + font-size: 12px; &:hover { background-color: black; @@ -78,8 +80,11 @@ select { background-color: #323232; color: white; border: 1px solid black; - border-top: none; - border-bottom: none; + // border-top: none; + // border-bottom: none; + font-size: 12px; + height: 100%; + margin-right: 3px; &:focus, &:hover { diff --git a/src/client/util/RichTextMenu.tsx b/src/client/util/RichTextMenu.tsx index 8c373b818..4538a77d6 100644 --- a/src/client/util/RichTextMenu.tsx +++ b/src/client/util/RichTextMenu.tsx @@ -29,7 +29,7 @@ library.add(faBold, faItalic, faUnderline, faStrikethrough, faSuperscript, faSub @observer export default class RichTextMenu extends AntimodeMenu { static Instance: RichTextMenu; - @observable private isVisible: boolean = false; + public overDropdown: boolean = false; // kind of hacky way to prevent selects not being selectable private view?: EditorView; private editorProps: FieldViewProps & FormattedTextBoxProps | undefined; @@ -73,7 +73,6 @@ export default class RichTextMenu extends AntimodeMenu { } this.view = view; const state = view.state; - this.isVisible = true; // DocumentDecorations.Instance.showTextBar(); props && (this.editorProps = props); // Don't do anything if the document/selection didn't change @@ -179,14 +178,19 @@ export default class RichTextMenu extends AntimodeMenu { }); const self = this; - function onChange(val: string) { + function onChange(e: React.ChangeEvent) { + e.stopPropagation(); + e.preventDefault(); + console.log("on change marks"); options.forEach(({ label, mark, command }) => { - if (val === label) { + if (e.target.value === label) { self.view && mark && command(mark, self.view); } }); } - return ; + function onPointerEnter() { self.overDropdown = true; } + function onPointerLeave() { self.overDropdown = false; } + return ; } createNodesDropdown(activeOption: string, options: { node: NodeType | any | null, title: string, label: string, command: (node: NodeType | any) => void, hidden?: boolean }[]): JSX.Element { @@ -209,7 +213,9 @@ export default class RichTextMenu extends AntimodeMenu { } }); } - return ; + function onPointerEnter() { self.overDropdown = true; } + function onPointerLeave() { self.overDropdown = false; } + return ; } changeFontSize = (mark: Mark, view: EditorView) => { @@ -274,8 +280,7 @@ export default class RichTextMenu extends AntimodeMenu { return true; } - @action - toggleBrushDropdown() { this.showBrushDropdown = !this.showBrushDropdown; } + @action toggleBrushDropdown() { this.showBrushDropdown = !this.showBrushDropdown; } createBrushButton() { const self = this; @@ -648,9 +653,6 @@ export default class RichTextMenu extends AntimodeMenu { } render() { - // if (!this.isVisible) return <>; - SelectionManager.SelectedDocuments() - // if (this.Pinned || ) const fontSizeOptions = [ { mark: schema.marks.pFontSize.create({ fontSize: 7 }), title: "Set font size", label: "7pt", command: this.changeFontSize }, @@ -689,7 +691,7 @@ export default class RichTextMenu extends AntimodeMenu { { node: undefined, title: "Set list type", label: "Remove", command: this.changeListType }, ]; - const buttons = [ + const row1 =
{[ this.createButton("bold", "Bold", toggleMark(schema.marks.strong)), this.createButton("italic", "Italic", toggleMark(schema.marks.em)), this.createButton("underline", "Underline", toggleMark(schema.marks.underline)), @@ -701,11 +703,18 @@ export default class RichTextMenu extends AntimodeMenu { this.createLinkButton(), this.createBrushButton(), this.createButton("indent", "Summarize", undefined, this.insertSummarizer), + ]}
+ + const row2 =
{[ this.createMarksDropdown(this.activeFontSize, fontSizeOptions), this.createMarksDropdown(this.activeFontFamily, fontFamilyOptions), this.createNodesDropdown(this.activeListType, listTypeOptions), + ]}
+ + const buttons = [ + row1, row2 ]; - return this.getElement(buttons); + return this.getElementWithRows(buttons, 2); } } \ No newline at end of file diff --git a/src/client/views/AntimodeMenu.scss b/src/client/views/AntimodeMenu.scss index a45f3346a..f78b1dbfb 100644 --- a/src/client/views/AntimodeMenu.scss +++ b/src/client/views/AntimodeMenu.scss @@ -8,6 +8,15 @@ // overflow: hidden; display: flex; + &.with-rows { + flex-direction: column + } + + .antimodeMenu-row { + display: flex; + height: 35px; + } + .antimodeMenu-button { background-color: transparent; width: 35px; diff --git a/src/client/views/AntimodeMenu.tsx b/src/client/views/AntimodeMenu.tsx index 2e9d29ef9..713a8a189 100644 --- a/src/client/views/AntimodeMenu.tsx +++ b/src/client/views/AntimodeMenu.tsx @@ -125,4 +125,14 @@ export default abstract class AntimodeMenu extends React.Component {
); } + + protected getElementWithRows(rows: JSX.Element[], numRows: number) { + return ( +
+ {rows} +
+
+ ); + } } \ No newline at end of file diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 7d48a0859..7291d2e8e 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -913,7 +913,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & keeplocation && setTimeout(() => this._editorView?.dispatch(this._editorView?.state.tr.setSelection(TextSelection.create(this._editorView.state.doc, pos)))); // jump rich text menu to this textbox - this._ref.current && RichTextMenu.Instance.jumpTo(this._ref.current.getBoundingClientRect().x, this._ref.current?.getBoundingClientRect().y - 70); + this._ref.current && RichTextMenu.Instance.jumpTo(this._ref.current.getBoundingClientRect().x, this._ref.current?.getBoundingClientRect().y - 105); } onPointerWheel = (e: React.WheelEvent): void => { // if a text note is not selected and scrollable, this prevents us from being able to scroll and zoom out at the same time @@ -1053,6 +1053,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & }); } onBlur = (e: any) => { + console.log("formated blur"); //DictationManager.Controls.stop(false); if (this._undoTyping) { this._undoTyping.end(); @@ -1061,7 +1062,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & this.doLinkOnDeselect(); // move the richtextmenu offscreen - if (!RichTextMenu.Instance.Pinned) RichTextMenu.Instance.jumpTo(-300, -300); + if (!RichTextMenu.Instance.Pinned && !RichTextMenu.Instance.overDropdown) RichTextMenu.Instance.jumpTo(-300, -300); } _lastTimedMark: Mark | undefined = undefined; -- cgit v1.2.3-70-g09d2 From 89d3ec54886a588f3b7c8e46e771830eeefc3c8b Mon Sep 17 00:00:00 2001 From: vellichora Date: Tue, 7 Jan 2020 15:58:10 -0500 Subject: added logic so that text nodes started on the very left still show the full richtextmenu --- src/client/util/RichTextMenu.scss | 9 ++++++ src/client/util/RichTextMenu.tsx | 49 ++++++++++++++++++++--------- src/client/views/AntimodeMenu.tsx | 6 +++- src/client/views/nodes/FormattedTextBox.tsx | 8 +++-- 4 files changed, 55 insertions(+), 17 deletions(-) (limited to 'src/client/views') diff --git a/src/client/util/RichTextMenu.scss b/src/client/util/RichTextMenu.scss index 5a57f4b98..ff9270829 100644 --- a/src/client/util/RichTextMenu.scss +++ b/src/client/util/RichTextMenu.scss @@ -94,4 +94,13 @@ select { &::-ms-expand { color: white; } +} + +.row-2 { + display: flex; + justify-content: space-between; + + >div { + display: flex; + } } \ No newline at end of file diff --git a/src/client/util/RichTextMenu.tsx b/src/client/util/RichTextMenu.tsx index 4538a77d6..ae55dbd30 100644 --- a/src/client/util/RichTextMenu.tsx +++ b/src/client/util/RichTextMenu.tsx @@ -29,7 +29,7 @@ library.add(faBold, faItalic, faUnderline, faStrikethrough, faSuperscript, faSub @observer export default class RichTextMenu extends AntimodeMenu { static Instance: RichTextMenu; - public overDropdown: boolean = false; // kind of hacky way to prevent selects not being selectable + public overMenu: boolean = false; // kind of hacky way to prevent selects not being selectable private view?: EditorView; private editorProps: FieldViewProps & FormattedTextBoxProps | undefined; @@ -188,9 +188,7 @@ export default class RichTextMenu extends AntimodeMenu { } }); } - function onPointerEnter() { self.overDropdown = true; } - function onPointerLeave() { self.overDropdown = false; } - return ; + return ; } createNodesDropdown(activeOption: string, options: { node: NodeType | any | null, title: string, label: string, command: (node: NodeType | any) => void, hidden?: boolean }[]): JSX.Element { @@ -213,9 +211,7 @@ export default class RichTextMenu extends AntimodeMenu { } }); } - function onPointerEnter() { self.overDropdown = true; } - function onPointerLeave() { self.overDropdown = false; } - return ; + return ; } changeFontSize = (mark: Mark, view: EditorView) => { @@ -311,7 +307,9 @@ export default class RichTextMenu extends AntimodeMenu { return (
- + {this.showBrushDropdown ? (
@@ -652,6 +650,17 @@ export default class RichTextMenu extends AntimodeMenu { return ref_node; } + @action onPointerEnter(e: React.PointerEvent) { RichTextMenu.Instance.overMenu = true; } + @action onPointerLeave(e: React.PointerEvent) { RichTextMenu.Instance.overMenu = false; } + + @action + toggleMenuPin = (e: React.MouseEvent) => { + this.Pinned = !this.Pinned; + if (!this.Pinned) { + this.fadeOut(true); + } + } + render() { const fontSizeOptions = [ @@ -705,16 +714,28 @@ export default class RichTextMenu extends AntimodeMenu { this.createButton("indent", "Summarize", undefined, this.insertSummarizer), ]}
- const row2 =
{[ - this.createMarksDropdown(this.activeFontSize, fontSizeOptions), - this.createMarksDropdown(this.activeFontFamily, fontFamilyOptions), - this.createNodesDropdown(this.activeListType, listTypeOptions), - ]}
+ const row2 =
+
{[ + this.createMarksDropdown(this.activeFontSize, fontSizeOptions), + this.createMarksDropdown(this.activeFontFamily, fontFamilyOptions), + this.createNodesDropdown(this.activeListType, listTypeOptions), + ]}
+
+ + {this.getDragger()} +
+
const buttons = [ row1, row2 ]; - return this.getElementWithRows(buttons, 2); + return ( +
+ {this.getElementWithRows(buttons, 2)} +
+ ); } } \ No newline at end of file diff --git a/src/client/views/AntimodeMenu.tsx b/src/client/views/AntimodeMenu.tsx index 713a8a189..62ecdffaf 100644 --- a/src/client/views/AntimodeMenu.tsx +++ b/src/client/views/AntimodeMenu.tsx @@ -116,6 +116,10 @@ export default abstract class AntimodeMenu extends React.Component { e.preventDefault(); } + protected getDragger = () => { + return
+ } + protected getElement(buttons: JSX.Element[]) { return (
{rows} -
+ {/*
*/}
); } diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 7291d2e8e..4712b1974 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -913,7 +913,11 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & keeplocation && setTimeout(() => this._editorView?.dispatch(this._editorView?.state.tr.setSelection(TextSelection.create(this._editorView.state.doc, pos)))); // jump rich text menu to this textbox - this._ref.current && RichTextMenu.Instance.jumpTo(this._ref.current.getBoundingClientRect().x, this._ref.current?.getBoundingClientRect().y - 105); + if (this._ref.current) { + let x = Math.min(Math.max(this._ref.current!.getBoundingClientRect().x, 0), window.innerWidth - 445); + let y = this._ref.current!.getBoundingClientRect().y - 105; + RichTextMenu.Instance.jumpTo(x, y); + } } onPointerWheel = (e: React.WheelEvent): void => { // if a text note is not selected and scrollable, this prevents us from being able to scroll and zoom out at the same time @@ -1062,7 +1066,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & this.doLinkOnDeselect(); // move the richtextmenu offscreen - if (!RichTextMenu.Instance.Pinned && !RichTextMenu.Instance.overDropdown) RichTextMenu.Instance.jumpTo(-300, -300); + if (!RichTextMenu.Instance.Pinned && !RichTextMenu.Instance.overMenu) RichTextMenu.Instance.jumpTo(-300, -300); } _lastTimedMark: Mark | undefined = undefined; -- cgit v1.2.3-70-g09d2 From 531147df4186df3d4326748a5d083579cbc9e4c6 Mon Sep 17 00:00:00 2001 From: vellichora Date: Thu, 9 Jan 2020 12:01:56 -0500 Subject: minor cleanup --- src/client/util/RichTextMenu.tsx | 3 ++- src/client/views/AntimodeMenu.tsx | 25 ++++++++++++++++--------- 2 files changed, 18 insertions(+), 10 deletions(-) (limited to 'src/client/views') diff --git a/src/client/util/RichTextMenu.tsx b/src/client/util/RichTextMenu.tsx index ae55dbd30..af2e7cc48 100644 --- a/src/client/util/RichTextMenu.tsx +++ b/src/client/util/RichTextMenu.tsx @@ -54,6 +54,7 @@ export default class RichTextMenu extends AntimodeMenu { constructor(props: Readonly<{}>) { super(props); RichTextMenu.Instance = this; + this._canFade = false; } @action @@ -734,7 +735,7 @@ export default class RichTextMenu extends AntimodeMenu { return (
- {this.getElementWithRows(buttons, 2)} + {this.getElementWithRows(buttons, 2, false)}
); } diff --git a/src/client/views/AntimodeMenu.tsx b/src/client/views/AntimodeMenu.tsx index 62ecdffaf..25bd90d87 100644 --- a/src/client/views/AntimodeMenu.tsx +++ b/src/client/views/AntimodeMenu.tsx @@ -18,6 +18,7 @@ export default abstract class AntimodeMenu extends React.Component { @observable protected _opacity: number = 1; @observable protected _transition: string = "opacity 0.5s"; @observable protected _transitionDelay: string = ""; + @observable protected _canFade: boolean = true; @observable public Pinned: boolean = false; @@ -43,7 +44,7 @@ export default abstract class AntimodeMenu extends React.Component { * Called when you want the menu to disappear */ public fadeOut = (forceOut: boolean) => { - if (!this.Pinned) { + if (!this.Pinned && this._canFade) { if (this._opacity === 0.2) { this._transition = "opacity 0.1s"; this._transitionDelay = ""; @@ -62,12 +63,12 @@ export default abstract class AntimodeMenu extends React.Component { @action protected pointerLeave = (e: React.PointerEvent) => { - // if (!this.Pinned) { - // this._transition = "opacity 0.5s"; - // this._transitionDelay = "1s"; - // this._opacity = 0.2; - // setTimeout(() => this.fadeOut(false), 3000); - // } + if (!this.Pinned && this._canFade) { + this._transition = "opacity 0.5s"; + this._transitionDelay = "1s"; + this._opacity = 0.2; + setTimeout(() => this.fadeOut(false), 3000); + } } @action @@ -100,6 +101,12 @@ export default abstract class AntimodeMenu extends React.Component { this._left = e.pageX - this._offsetX; this._top = e.pageY - this._offsetY; + // assumes dragger is on right + // let width = this._mainCont.current!.getBoundingClientRect().width; + // let height = this._mainCont.current!.getBoundingClientRect().width; + // this._left = Math.max(width, e.pageX - this._offsetX); + // this._top = Math.min(height, e.pageY - this._offsetY); + e.stopPropagation(); e.preventDefault(); } @@ -130,12 +137,12 @@ export default abstract class AntimodeMenu extends React.Component { ); } - protected getElementWithRows(rows: JSX.Element[], numRows: number) { + protected getElementWithRows(rows: JSX.Element[], numRows: number, hasDragger: boolean = true) { return (
{rows} - {/*
*/} + {hasDragger ?
: <>}
); } -- cgit v1.2.3-70-g09d2 From 8f030c9a8ca1f61f8430e5ea92c48a7a6b6f079f Mon Sep 17 00:00:00 2001 From: Fawn Date: Thu, 9 Jan 2020 13:32:13 -0500 Subject: bounded antimodemenu to the boundaries of the screen and minor styling of richtextmenu --- package-lock.json | 95 ++++++++++++----------------- src/client/util/RichTextMenu.scss | 7 ++- src/client/util/RichTextMenu.tsx | 19 +++--- src/client/views/AntimodeMenu.tsx | 25 ++++---- src/client/views/nodes/FormattedTextBox.tsx | 22 +++---- 5 files changed, 79 insertions(+), 89 deletions(-) (limited to 'src/client/views') diff --git a/package-lock.json b/package-lock.json index 2c70ba94d..cf61e6aab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2561,7 +2561,7 @@ }, "browserify-aes": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "requires": { "buffer-xor": "^1.0.3", @@ -2595,7 +2595,7 @@ }, "browserify-rsa": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "requires": { "bn.js": "^4.1.0", @@ -2632,7 +2632,7 @@ }, "buffer": { "version": "4.9.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "resolved": "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", "dev": true, "requires": { @@ -2779,7 +2779,7 @@ }, "camelcase-keys": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", "requires": { "camelcase": "^2.0.0", @@ -3563,7 +3563,7 @@ }, "create-hash": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "requires": { "cipher-base": "^1.0.1", @@ -3575,7 +3575,7 @@ }, "create-hmac": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "requires": { "cipher-base": "^1.0.3", @@ -4118,7 +4118,7 @@ }, "diffie-hellman": { "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "requires": { "bn.js": "^4.1.0", @@ -5361,8 +5361,7 @@ }, "ansi-regex": { "version": "2.1.1", - "bundled": true, - "optional": true + "bundled": true }, "aproba": { "version": "1.2.0", @@ -5380,13 +5379,11 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true, - "optional": true + "bundled": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5399,18 +5396,15 @@ }, "code-point-at": { "version": "1.1.0", - "bundled": true, - "optional": true + "bundled": true }, "concat-map": { "version": "0.0.1", - "bundled": true, - "optional": true + "bundled": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true, - "optional": true + "bundled": true }, "core-util-is": { "version": "1.0.2", @@ -5513,8 +5507,7 @@ }, "inherits": { "version": "2.0.3", - "bundled": true, - "optional": true + "bundled": true }, "ini": { "version": "1.3.5", @@ -5524,7 +5517,6 @@ "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -5537,20 +5529,17 @@ "minimatch": { "version": "3.0.4", "bundled": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "bundled": true, - "optional": true + "bundled": true }, "minipass": { "version": "2.3.5", "bundled": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -5567,7 +5556,6 @@ "mkdirp": { "version": "0.5.1", "bundled": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -5640,8 +5628,7 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true, - "optional": true + "bundled": true }, "object-assign": { "version": "4.1.1", @@ -5651,7 +5638,6 @@ "once": { "version": "1.4.0", "bundled": true, - "optional": true, "requires": { "wrappy": "1" } @@ -5727,8 +5713,7 @@ }, "safe-buffer": { "version": "5.1.2", - "bundled": true, - "optional": true + "bundled": true }, "safer-buffer": { "version": "2.1.2", @@ -5758,7 +5743,6 @@ "string-width": { "version": "1.0.2", "bundled": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -5776,7 +5760,6 @@ "strip-ansi": { "version": "3.0.1", "bundled": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -5815,13 +5798,11 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true, - "optional": true + "bundled": true }, "yallist": { "version": "3.0.3", - "bundled": true, - "optional": true + "bundled": true } } }, @@ -7073,7 +7054,7 @@ "babel-runtime": "^6.22.0", "bluebird": "^3.4.7", "boolify-string": "^2.0.2", - "emit-logger": "github:chocolateboy/emit-logger#better-emitter-name", + "emit-logger": "github:chocolateboy/emit-logger#b9d25a2d939e42f29c940861e9648bd0fb810070", "lodash": "^4.17.4", "semver": "^5.0.3", "source-map-support": "^0.5.9" @@ -7081,7 +7062,7 @@ }, "is-accessor-descriptor": { "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "requires": { "kind-of": "^3.0.2" @@ -7130,7 +7111,7 @@ }, "is-data-descriptor": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "requires": { "kind-of": "^3.0.2" @@ -7915,7 +7896,7 @@ }, "load-json-file": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "requires": { "graceful-fs": "^4.1.2", @@ -8229,7 +8210,7 @@ }, "media-typer": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, "mem": { @@ -8261,7 +8242,7 @@ }, "meow": { "version": "3.7.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz", "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", "requires": { "camelcase-keys": "^2.0.0", @@ -8454,7 +8435,7 @@ }, "mkdirp": { "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "requires": { "minimist": "0.0.8" @@ -8800,7 +8781,7 @@ }, "next-tick": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" }, "nice-try": { @@ -8964,7 +8945,7 @@ }, "semver": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "resolved": "http://registry.npmjs.org/semver/-/semver-5.3.0.tgz", "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" }, "tar": { @@ -12573,7 +12554,7 @@ }, "os-homedir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" }, "os-locale": { @@ -12586,7 +12567,7 @@ }, "os-tmpdir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" }, "osenv": { @@ -12826,7 +12807,7 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-is-inside": { @@ -14146,7 +14127,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "requires": { "core-util-is": "~1.0.0", @@ -14491,7 +14472,7 @@ }, "safe-regex": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "requires": { "ret": "~0.1.10" @@ -14756,7 +14737,7 @@ }, "sha.js": { "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "requires": { "inherits": "^2.0.1", @@ -15499,7 +15480,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "requires": { "safe-buffer": "~5.1.0" @@ -15529,7 +15510,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" @@ -15545,7 +15526,7 @@ }, "strip-eof": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" }, "strip-indent": { @@ -16298,7 +16279,7 @@ }, "tty-browserify": { "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "resolved": "http://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", "dev": true }, @@ -17740,7 +17721,7 @@ }, "wrap-ansi": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "requires": { "string-width": "^1.0.1", diff --git a/src/client/util/RichTextMenu.scss b/src/client/util/RichTextMenu.scss index ff9270829..6383e0b7b 100644 --- a/src/client/util/RichTextMenu.scss +++ b/src/client/util/RichTextMenu.scss @@ -21,6 +21,7 @@ min-width: 150px; padding: 5px; font-size: 12px; + z-index: 10001; button { background-color: #323232; @@ -28,11 +29,15 @@ border-radius: 1px; padding: 6px; margin: 5px 0; - font-size: 12px; + font-size: 10px; &:hover { background-color: black; } + + &:last-child { + margin-bottom: 0; + } } } diff --git a/src/client/util/RichTextMenu.tsx b/src/client/util/RichTextMenu.tsx index af2e7cc48..ca6b90e36 100644 --- a/src/client/util/RichTextMenu.tsx +++ b/src/client/util/RichTextMenu.tsx @@ -8,7 +8,7 @@ import { EditorView } from "prosemirror-view"; import { EditorState, NodeSelection, TextSelection } from "prosemirror-state"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { IconProp, library } from '@fortawesome/fontawesome-svg-core'; -import { faBold, faItalic, faUnderline, faStrikethrough, faSubscript, faSuperscript, faIndent, faEyeDropper, faCaretDown, faPalette, faHighlighter, faLink } from "@fortawesome/free-solid-svg-icons"; +import { faBold, faItalic, faUnderline, faStrikethrough, faSubscript, faSuperscript, faIndent, faEyeDropper, faCaretDown, faPalette, faHighlighter, faLink, faPaintRoller } from "@fortawesome/free-solid-svg-icons"; import { MenuItem, Dropdown } from "prosemirror-menu"; import { updateBullets } from "./ProsemirrorExampleTransfer"; import { FieldViewProps } from "../views/nodes/FieldView"; @@ -24,7 +24,7 @@ import { SelectionManager } from "./SelectionManager"; import { LinkManager } from "./LinkManager"; const { toggleMark, setBlockType } = require("prosemirror-commands"); -library.add(faBold, faItalic, faUnderline, faStrikethrough, faSuperscript, faSubscript, faIndent, faEyeDropper, faCaretDown, faPalette, faHighlighter, faLink); +library.add(faBold, faItalic, faUnderline, faStrikethrough, faSuperscript, faSubscript, faIndent, faEyeDropper, faCaretDown, faPalette, faHighlighter, faLink, faPaintRoller); @observer export default class RichTextMenu extends AntimodeMenu { @@ -86,8 +86,9 @@ export default class RichTextMenu extends AntimodeMenu { const activeFamilies = active && active.get("families"); const activeSizes = active && active.get("sizes"); - this.activeFontFamily = !activeFamilies || activeFamilies.length === 0 ? "default" : activeFamilies.length === 1 ? String(activeFamilies[0]) : "various"; - this.activeFontSize = !activeSizes || activeSizes.length === 0 ? "default" : activeSizes.length === 1 ? String(activeSizes[0]) + "pt" : "various"; + console.log("update from dash, activefontsize", this.activeFontSize, activeSizes, activeSizes && activeSizes.length, activeSizes && String(activeSizes[0])); + this.activeFontFamily = !activeFamilies || activeFamilies.length === 0 ? "Arial" : activeFamilies.length === 1 ? String(activeFamilies[0]) : "various"; + this.activeFontSize = !activeSizes || activeSizes.length === 0 ? "13pt" : activeSizes.length === 1 ? String(activeSizes[0]) + "pt" : "various"; // update link in current selection const targetTitle = await this.getTextLinkTargetTitle(); @@ -99,7 +100,7 @@ export default class RichTextMenu extends AntimodeMenu { setMark = (mark: Mark, state: EditorState, dispatch: any) => { if (mark) { const node = (state.selection as NodeSelection).node; - if (node?.type === schema.nodes.ordered_list) { + if (node ?.type === schema.nodes.ordered_list) { let attrs = node.attrs; if (mark.type === schema.marks.pFontFamily) attrs = { ...attrs, setFontFamily: mark.attrs.family }; if (mark.type === schema.marks.pFontSize) attrs = { ...attrs, setFontSize: mark.attrs.fontSize }; @@ -142,7 +143,7 @@ export default class RichTextMenu extends AntimodeMenu { getMarksInSelection(state: EditorState) { const found = new Set(); const { from, to } = state.selection as TextSelection; - state.doc.nodesBetween(from, to, (node) => node.marks?.forEach(m => found.add(m))); + state.doc.nodesBetween(from, to, (node) => node.marks ?.forEach(m => found.add(m))); return found; } @@ -309,7 +310,7 @@ export default class RichTextMenu extends AntimodeMenu { return (
{this.showBrushDropdown ? @@ -679,7 +680,7 @@ export default class RichTextMenu extends AntimodeMenu { { mark: schema.marks.pFontSize.create({ fontSize: 48 }), title: "Set font size", label: "48pt", command: this.changeFontSize }, { mark: schema.marks.pFontSize.create({ fontSize: 72 }), title: "Set font size", label: "72pt", command: this.changeFontSize }, { mark: null, title: "", label: "various", command: unimplementedFunction, hidden: true }, - { mark: null, title: "", label: "default", command: unimplementedFunction, hidden: true }, + { mark: null, title: "", label: "13pt", command: unimplementedFunction, hidden: true }, // this is here because the default size is 13, but there is no actual 13pt option ]; const fontFamilyOptions = [ @@ -691,7 +692,7 @@ export default class RichTextMenu extends AntimodeMenu { { mark: schema.marks.pFontFamily.create({ family: "Impact" }), title: "Set font family", label: "Impact", command: this.changeFontFamily }, { mark: schema.marks.pFontFamily.create({ family: "Crimson Text" }), title: "Set font family", label: "Crimson Text", command: this.changeFontFamily }, { mark: null, title: "", label: "various", command: unimplementedFunction, hidden: true }, - { mark: null, title: "", label: "default", command: unimplementedFunction, hidden: true }, + // { mark: null, title: "", label: "default", command: unimplementedFunction, hidden: true }, ]; const listTypeOptions = [ diff --git a/src/client/views/AntimodeMenu.tsx b/src/client/views/AntimodeMenu.tsx index 25bd90d87..e358d88cf 100644 --- a/src/client/views/AntimodeMenu.tsx +++ b/src/client/views/AntimodeMenu.tsx @@ -22,6 +22,9 @@ export default abstract class AntimodeMenu extends React.Component { @observable public Pinned: boolean = false; + get width() { return this._mainCont.current ? this._mainCont.current.getBoundingClientRect().width : 0; } + get height() { return this._mainCont.current ? this._mainCont.current.getBoundingClientRect().height : 0; } + @action /** * @param x @@ -44,7 +47,7 @@ export default abstract class AntimodeMenu extends React.Component { * Called when you want the menu to disappear */ public fadeOut = (forceOut: boolean) => { - if (!this.Pinned && this._canFade) { + if (!this.Pinned) { if (this._opacity === 0.2) { this._transition = "opacity 0.1s"; this._transitionDelay = ""; @@ -89,8 +92,8 @@ export default abstract class AntimodeMenu extends React.Component { document.removeEventListener("pointerup", this.dragEnd); document.addEventListener("pointerup", this.dragEnd); - this._offsetX = this._mainCont.current!.getBoundingClientRect().width - e.nativeEvent.offsetX; - this._offsetY = e.nativeEvent.offsetY; + this._offsetX = e.pageX - this._mainCont.current!.getBoundingClientRect().left; + this._offsetY = e.pageY - this._mainCont.current!.getBoundingClientRect().top; e.stopPropagation(); e.preventDefault(); @@ -98,14 +101,14 @@ export default abstract class AntimodeMenu extends React.Component { @action protected dragging = (e: PointerEvent) => { - this._left = e.pageX - this._offsetX; - this._top = e.pageY - this._offsetY; - - // assumes dragger is on right - // let width = this._mainCont.current!.getBoundingClientRect().width; - // let height = this._mainCont.current!.getBoundingClientRect().width; - // this._left = Math.max(width, e.pageX - this._offsetX); - // this._top = Math.min(height, e.pageY - this._offsetY); + const width = this._mainCont.current!.getBoundingClientRect().width; + const height = this._mainCont.current!.getBoundingClientRect().height; + + const left = e.pageX - this._offsetX; + const top = e.pageY - this._offsetY; + + this._left = Math.min(Math.max(left, 0), window.innerWidth - width); + this._top = Math.min(Math.max(top, 0), window.innerHeight - height); e.stopPropagation(); e.preventDefault(); diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 4712b1974..027bd492c 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -906,16 +906,16 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & this.tryUpdateHeight(); // see if we need to preserve the insertion point - const prosediv = this.ProseRef?.children?.[0] as any; - const keeplocation = prosediv?.keeplocation; + const prosediv = this.ProseRef ?.children ?.[0] as any; + const keeplocation = prosediv ?.keeplocation; prosediv && (prosediv.keeplocation = undefined); - const pos = this._editorView?.state.selection.$from.pos || 1; - keeplocation && setTimeout(() => this._editorView?.dispatch(this._editorView?.state.tr.setSelection(TextSelection.create(this._editorView.state.doc, pos)))); + const pos = this._editorView ?.state.selection.$from.pos || 1; + keeplocation && setTimeout(() => this._editorView ?.dispatch(this._editorView ?.state.tr.setSelection(TextSelection.create(this._editorView.state.doc, pos)))); // jump rich text menu to this textbox if (this._ref.current) { - let x = Math.min(Math.max(this._ref.current!.getBoundingClientRect().x, 0), window.innerWidth - 445); - let y = this._ref.current!.getBoundingClientRect().y - 105; + const x = Math.min(Math.max(this._ref.current!.getBoundingClientRect().left, 0), window.innerWidth - RichTextMenu.Instance.width); + const y = this._ref.current!.getBoundingClientRect().top - RichTextMenu.Instance.height - 50; RichTextMenu.Instance.jumpTo(x, y); } } @@ -933,7 +933,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & if ((this._editorView!.root as any).getSelection().isCollapsed) { // this is a hack to allow the cursor to be placed at the end of a document when the document ends in an inline dash comment. Apparently Chrome on Windows has a bug/feature which breaks this when clicking after the end of the text. const pcords = this._editorView!.posAtCoords({ left: e.clientX, top: e.clientY }); const node = pcords && this._editorView!.state.doc.nodeAt(pcords.pos); // get what prosemirror thinks the clicked node is (if it's null, then we didn't click on any text) - if (pcords && node?.type === this._editorView!.state.schema.nodes.dashComment) { + if (pcords && node ?.type === this._editorView!.state.schema.nodes.dashComment) { this._editorView!.dispatch(this._editorView!.state.tr.setSelection(TextSelection.create(this._editorView!.state.doc, pcords.pos + 2))); e.preventDefault(); } @@ -996,7 +996,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & for (let off = 1; off < 100; off++) { const pos = this._editorView!.posAtCoords({ left: x + off, top: y }); const node = pos && this._editorView!.state.doc.nodeAt(pos.pos); - if (node?.type === schema.nodes.list_item) { + if (node ?.type === schema.nodes.list_item) { list_node = node; break; } @@ -1088,7 +1088,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & } if (e.key === "Escape") { this._editorView!.dispatch(state.tr.setSelection(TextSelection.create(state.doc, state.selection.from, state.selection.from))); - (document.activeElement as any).blur?.(); + (document.activeElement as any).blur ?.(); SelectionManager.DeselectAll(); } e.stopPropagation(); @@ -1110,7 +1110,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & @action tryUpdateHeight(limitHeight?: number) { - let scrollHeight = this._ref.current?.scrollHeight; + let scrollHeight = this._ref.current ?.scrollHeight; if (!this.layoutDoc.animateToPos && this.layoutDoc.autoHeight && scrollHeight && getComputedStyle(this._ref.current!.parentElement!).top === "0px") { // if top === 0, then the text box is growing upward (as the overlay caption) which doesn't contribute to the height computation if (limitHeight && scrollHeight > limitHeight) { @@ -1173,7 +1173,7 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & {this.props.Document.hideSidebar ? (null) : this.sidebarWidthPercent === "0%" ?
this.toggleSidebar()} /> :
+ style={{ width: `${this.sidebarWidthPercent}`, backgroundColor: `${StrCast(this.extensionDoc ?.backgroundColor, "transparent")}` }}> this.sidebarWidth} -- cgit v1.2.3-70-g09d2 From 3b08b8c340bf889c99f7b2fa76cda0f8b2d4b0a1 Mon Sep 17 00:00:00 2001 From: Fawn Date: Thu, 9 Jan 2020 15:03:54 -0500 Subject: refactored dropdown buttons into a buttondropdown component for richtextmenu --- src/client/util/RichTextMenu.tsx | 382 +++++++++++++++------------- src/client/views/nodes/FormattedTextBox.tsx | 1 - 2 files changed, 206 insertions(+), 177 deletions(-) (limited to 'src/client/views') diff --git a/src/client/util/RichTextMenu.tsx b/src/client/util/RichTextMenu.tsx index ca6b90e36..2d4f0fc1b 100644 --- a/src/client/util/RichTextMenu.tsx +++ b/src/client/util/RichTextMenu.tsx @@ -34,6 +34,12 @@ export default class RichTextMenu extends AntimodeMenu { private view?: EditorView; private editorProps: FieldViewProps & FormattedTextBoxProps | undefined; + private fontSizeOptions: { mark: Mark | null, title: string, label: string, command: any, hidden?: boolean }[]; + private fontFamilyOptions: { mark: Mark | null, title: string, label: string, command: any, hidden?: boolean }[]; + private listTypeOptions: { node: NodeType | any | null, title: string, label: string, command: any }[]; + private fontColors: (string | undefined)[]; + private highlightColors: (string | undefined)[]; + @observable private activeFontSize: string = ""; @observable private activeFontFamily: string = ""; @observable private activeListType: string = ""; @@ -55,6 +61,69 @@ export default class RichTextMenu extends AntimodeMenu { super(props); RichTextMenu.Instance = this; this._canFade = false; + + this.fontSizeOptions = [ + { mark: schema.marks.pFontSize.create({ fontSize: 7 }), title: "Set font size", label: "7pt", command: this.changeFontSize }, + { mark: schema.marks.pFontSize.create({ fontSize: 8 }), title: "Set font size", label: "8pt", command: this.changeFontSize }, + { mark: schema.marks.pFontSize.create({ fontSize: 9 }), title: "Set font size", label: "8pt", command: this.changeFontSize }, + { mark: schema.marks.pFontSize.create({ fontSize: 10 }), title: "Set font size", label: "10pt", command: this.changeFontSize }, + { mark: schema.marks.pFontSize.create({ fontSize: 12 }), title: "Set font size", label: "12pt", command: this.changeFontSize }, + { mark: schema.marks.pFontSize.create({ fontSize: 14 }), title: "Set font size", label: "14pt", command: this.changeFontSize }, + { mark: schema.marks.pFontSize.create({ fontSize: 16 }), title: "Set font size", label: "16pt", command: this.changeFontSize }, + { mark: schema.marks.pFontSize.create({ fontSize: 18 }), title: "Set font size", label: "18pt", command: this.changeFontSize }, + { mark: schema.marks.pFontSize.create({ fontSize: 20 }), title: "Set font size", label: "20pt", command: this.changeFontSize }, + { mark: schema.marks.pFontSize.create({ fontSize: 24 }), title: "Set font size", label: "24pt", command: this.changeFontSize }, + { mark: schema.marks.pFontSize.create({ fontSize: 32 }), title: "Set font size", label: "32pt", command: this.changeFontSize }, + { mark: schema.marks.pFontSize.create({ fontSize: 48 }), title: "Set font size", label: "48pt", command: this.changeFontSize }, + { mark: schema.marks.pFontSize.create({ fontSize: 72 }), title: "Set font size", label: "72pt", command: this.changeFontSize }, + { mark: null, title: "", label: "various", command: unimplementedFunction, hidden: true }, + { mark: null, title: "", label: "13pt", command: unimplementedFunction, hidden: true }, // this is here because the default size is 13, but there is no actual 13pt option + ]; + + this.fontFamilyOptions = [ + { mark: schema.marks.pFontFamily.create({ family: "Times New Roman" }), title: "Set font family", label: "Times New Roman", command: this.changeFontFamily }, + { mark: schema.marks.pFontFamily.create({ family: "Arial" }), title: "Set font family", label: "Arial", command: this.changeFontFamily }, + { mark: schema.marks.pFontFamily.create({ family: "Georgia" }), title: "Set font family", label: "Georgia", command: this.changeFontFamily }, + { mark: schema.marks.pFontFamily.create({ family: "Comic Sans MS" }), title: "Set font family", label: "Comic Sans MS", command: this.changeFontFamily }, + { mark: schema.marks.pFontFamily.create({ family: "Tahoma" }), title: "Set font family", label: "Tahoma", command: this.changeFontFamily }, + { mark: schema.marks.pFontFamily.create({ family: "Impact" }), title: "Set font family", label: "Impact", command: this.changeFontFamily }, + { mark: schema.marks.pFontFamily.create({ family: "Crimson Text" }), title: "Set font family", label: "Crimson Text", command: this.changeFontFamily }, + { mark: null, title: "", label: "various", command: unimplementedFunction, hidden: true }, + // { mark: null, title: "", label: "default", command: unimplementedFunction, hidden: true }, + ]; + + this.listTypeOptions = [ + { node: schema.nodes.ordered_list.create({ mapStyle: "bullet" }), title: "Set list type", label: ":", command: this.changeListType }, + { node: schema.nodes.ordered_list.create({ mapStyle: "decimal" }), title: "Set list type", label: "1.1", command: this.changeListType }, + { node: schema.nodes.ordered_list.create({ mapStyle: "multi" }), title: "Set list type", label: "1.A", command: this.changeListType }, + { node: undefined, title: "Set list type", label: "Remove", command: this.changeListType }, + ]; + + this.fontColors = [ + DarkPastelSchemaPalette.get("pink2"), + DarkPastelSchemaPalette.get("purple4"), + DarkPastelSchemaPalette.get("bluegreen1"), + DarkPastelSchemaPalette.get("yellow4"), + DarkPastelSchemaPalette.get("red2"), + DarkPastelSchemaPalette.get("bluegreen7"), + DarkPastelSchemaPalette.get("bluegreen5"), + DarkPastelSchemaPalette.get("orange1"), + "#757472", + "#000" + ]; + + this.highlightColors = [ + PastelSchemaPalette.get("pink2"), + PastelSchemaPalette.get("purple4"), + PastelSchemaPalette.get("bluegreen1"), + PastelSchemaPalette.get("yellow4"), + PastelSchemaPalette.get("red2"), + PastelSchemaPalette.get("bluegreen7"), + PastelSchemaPalette.get("bluegreen5"), + PastelSchemaPalette.get("orange1"), + "white", + "transparent" + ]; } @action @@ -74,27 +143,23 @@ export default class RichTextMenu extends AntimodeMenu { } this.view = view; const state = view.state; - // DocumentDecorations.Instance.showTextBar(); props && (this.editorProps = props); + // Don't do anything if the document/selection didn't change if (lastState && lastState.doc.eq(state.doc) && lastState.selection.eq(state.selection)) return; - // this.reset_mark_doms(); // update active font family and size const active = this.getActiveFontStylesOnSelection(); const activeFamilies = active && active.get("families"); const activeSizes = active && active.get("sizes"); - console.log("update from dash, activefontsize", this.activeFontSize, activeSizes, activeSizes && activeSizes.length, activeSizes && String(activeSizes[0])); this.activeFontFamily = !activeFamilies || activeFamilies.length === 0 ? "Arial" : activeFamilies.length === 1 ? String(activeFamilies[0]) : "various"; this.activeFontSize = !activeSizes || activeSizes.length === 0 ? "13pt" : activeSizes.length === 1 ? String(activeSizes[0]) + "pt" : "various"; // update link in current selection const targetTitle = await this.getTextLinkTargetTitle(); this.setCurrentLink(targetTitle); - - // this.update_mark_doms(); } setMark = (mark: Mark, state: EditorState, dispatch: any) => { @@ -134,7 +199,7 @@ export default class RichTextMenu extends AntimodeMenu { }); } - let styles = new Map(); + const styles = new Map(); styles.set("families", activeFamilies); styles.set("sizes", activeSizes); return styles; @@ -183,7 +248,6 @@ export default class RichTextMenu extends AntimodeMenu { function onChange(e: React.ChangeEvent) { e.stopPropagation(); e.preventDefault(); - console.log("on change marks"); options.forEach(({ label, mark, command }) => { if (e.target.value === label) { self.view && mark && command(mark, self.view); @@ -230,7 +294,6 @@ export default class RichTextMenu extends AntimodeMenu { changeFontFamily = (mark: Mark, view: EditorView) => { const fontName = mark.attrs.family; - // if (fontName) { this.updateFontStyleDropdown(fontName); } if (this.editorProps) { const ruleProvider = this.editorProps.ruleProvider; const heading = NumCast(this.editorProps.Document.heading); @@ -288,12 +351,6 @@ export default class RichTextMenu extends AntimodeMenu { self.view && self.view.focus(); self.view && self.fillBrush(self.view.state, self.view.dispatch); } - function onDropdownClick(e: React.PointerEvent) { - e.preventDefault(); - e.stopPropagation(); - self.view && self.view.focus(); - self.toggleBrushDropdown(); - } let label = "Stored marks: "; if (this.brushMarks && this.brushMarks.size > 0) { @@ -307,20 +364,20 @@ export default class RichTextMenu extends AntimodeMenu { label = "No marks are currently stored"; } + const button = + ; + + const dropdownContent = +
+

{label}

+ + {/* */} +
; + return ( -
- - - {this.showBrushDropdown ? - (
-

{label}

- - {/* */} -
) - : <>} -
+ ); } @@ -340,7 +397,6 @@ export default class RichTextMenu extends AntimodeMenu { this.brushMarks = selected_marks; this.brushIsEmpty = !this.brushIsEmpty; } - // } } else { const { from, to, $from } = this.view.state.selection; @@ -369,12 +425,6 @@ export default class RichTextMenu extends AntimodeMenu { self.view && self.view.focus(); self.view && self.insertColor(self.activeFontColor, self.view.state, self.view.dispatch); } - function onDropdownClick(e: React.PointerEvent) { - e.preventDefault(); - e.stopPropagation(); - self.view && self.view.focus(); - self.toggleColorDropdown(); - } function changeColor(e: React.PointerEvent, color: string) { e.preventDefault(); e.stopPropagation(); @@ -383,41 +433,28 @@ export default class RichTextMenu extends AntimodeMenu { self.view && self.insertColor(self.activeFontColor, self.view.state, self.view.dispatch); } - const colors = [ - DarkPastelSchemaPalette.get("pink2"), - DarkPastelSchemaPalette.get("purple4"), - DarkPastelSchemaPalette.get("bluegreen1"), - DarkPastelSchemaPalette.get("yellow4"), - DarkPastelSchemaPalette.get("red2"), - DarkPastelSchemaPalette.get("bluegreen7"), - DarkPastelSchemaPalette.get("bluegreen5"), - DarkPastelSchemaPalette.get("orange1"), - "#757472", - "#000" - ]; + const button = + ; + + const dropdownContent = +
+

Change font color:

+
+ {this.fontColors.map(color => { + if (color) { + return this.activeFontColor === color ? + : + ; + } + })} +
+
; return ( -
- - - {this.showColorDropdown ? - (
-

Change font color:

-
- {colors.map(color => { - if (color) { - return this.activeFontColor === color ? - : - ; - } - })} -
-
) - : <>} -
+ ); } @@ -441,12 +478,6 @@ export default class RichTextMenu extends AntimodeMenu { self.view && self.view.focus(); self.view && self.insertHighlight(self.activeHighlightColor, self.view.state, self.view.dispatch); } - function onDropdownClick(e: React.PointerEvent) { - e.preventDefault(); - e.stopPropagation(); - self.view && self.view.focus(); - self.toggleHighlightDropdown(); - } function changeHighlight(e: React.PointerEvent, color: string) { e.preventDefault(); e.stopPropagation(); @@ -455,41 +486,28 @@ export default class RichTextMenu extends AntimodeMenu { self.view && self.insertHighlight(self.activeHighlightColor, self.view.state, self.view.dispatch); } - const colors = [ - PastelSchemaPalette.get("pink2"), - PastelSchemaPalette.get("purple4"), - PastelSchemaPalette.get("bluegreen1"), - PastelSchemaPalette.get("yellow4"), - PastelSchemaPalette.get("red2"), - PastelSchemaPalette.get("bluegreen7"), - PastelSchemaPalette.get("bluegreen5"), - PastelSchemaPalette.get("orange1"), - "white", - "transparent" - ]; + const button = + ; + + const dropdownContent = +
+

Change highlight color:

+
+ {this.highlightColors.map(color => { + if (color) { + return this.activeHighlightColor === color ? + : + ; + } + })} +
+
; return ( -
- - - {this.showHighlightDropdown ? - (
-

Change highlight color:

-
- {colors.map(color => { - if (color) { - return this.activeHighlightColor === color ? - : - ; - } - })} -
-
) - : <>} -
+ ); } @@ -503,32 +521,26 @@ export default class RichTextMenu extends AntimodeMenu { createLinkButton() { const self = this; - function onDropdownClick(e: React.PointerEvent) { - e.preventDefault(); - e.stopPropagation(); - self.view && self.view.focus(); - self.toggleLinkDropdown(); - } + function onLinkChange(e: React.ChangeEvent) { self.setCurrentLink(e.target.value); } const link = this.currentLink ? this.currentLink : ""; + const button = ; + + const dropdownContent = +
+

Linked to:

+ + +
+ +
; + return ( -
- - - {this.showLinkDropdown ? - (
-

Linked to:

- - -
- -
) - : <>} -
+ ); } @@ -598,7 +610,7 @@ export default class RichTextMenu extends AntimodeMenu { } } else { if (node) { - let extension = this.linkExtend(this.view!.state.selection.$anchor, href); + const extension = this.linkExtend(this.view!.state.selection.$anchor, href); this.view!.dispatch(this.view!.state.tr.removeMark(extension.from, extension.to, this.view!.state.schema.marks.link)); } } @@ -617,7 +629,7 @@ export default class RichTextMenu extends AntimodeMenu { let startPos = $start.start(); let endPos = startPos; for (let i = 0; i < endIndex; i++) { - let size = $start.parent.child(i).nodeSize; + const size = $start.parent.child(i).nodeSize; if (i < startIndex) startPos += size; endPos += size; } @@ -665,43 +677,6 @@ export default class RichTextMenu extends AntimodeMenu { render() { - const fontSizeOptions = [ - { mark: schema.marks.pFontSize.create({ fontSize: 7 }), title: "Set font size", label: "7pt", command: this.changeFontSize }, - { mark: schema.marks.pFontSize.create({ fontSize: 8 }), title: "Set font size", label: "8pt", command: this.changeFontSize }, - { mark: schema.marks.pFontSize.create({ fontSize: 9 }), title: "Set font size", label: "8pt", command: this.changeFontSize }, - { mark: schema.marks.pFontSize.create({ fontSize: 10 }), title: "Set font size", label: "10pt", command: this.changeFontSize }, - { mark: schema.marks.pFontSize.create({ fontSize: 12 }), title: "Set font size", label: "12pt", command: this.changeFontSize }, - { mark: schema.marks.pFontSize.create({ fontSize: 14 }), title: "Set font size", label: "14pt", command: this.changeFontSize }, - { mark: schema.marks.pFontSize.create({ fontSize: 16 }), title: "Set font size", label: "16pt", command: this.changeFontSize }, - { mark: schema.marks.pFontSize.create({ fontSize: 18 }), title: "Set font size", label: "18pt", command: this.changeFontSize }, - { mark: schema.marks.pFontSize.create({ fontSize: 20 }), title: "Set font size", label: "20pt", command: this.changeFontSize }, - { mark: schema.marks.pFontSize.create({ fontSize: 24 }), title: "Set font size", label: "24pt", command: this.changeFontSize }, - { mark: schema.marks.pFontSize.create({ fontSize: 32 }), title: "Set font size", label: "32pt", command: this.changeFontSize }, - { mark: schema.marks.pFontSize.create({ fontSize: 48 }), title: "Set font size", label: "48pt", command: this.changeFontSize }, - { mark: schema.marks.pFontSize.create({ fontSize: 72 }), title: "Set font size", label: "72pt", command: this.changeFontSize }, - { mark: null, title: "", label: "various", command: unimplementedFunction, hidden: true }, - { mark: null, title: "", label: "13pt", command: unimplementedFunction, hidden: true }, // this is here because the default size is 13, but there is no actual 13pt option - ]; - - const fontFamilyOptions = [ - { mark: schema.marks.pFontFamily.create({ family: "Times New Roman" }), title: "Set font family", label: "Times New Roman", command: this.changeFontFamily }, - { mark: schema.marks.pFontFamily.create({ family: "Arial" }), title: "Set font family", label: "Arial", command: this.changeFontFamily }, - { mark: schema.marks.pFontFamily.create({ family: "Georgia" }), title: "Set font family", label: "Georgia", command: this.changeFontFamily }, - { mark: schema.marks.pFontFamily.create({ family: "Comic Sans MS" }), title: "Set font family", label: "Comic Sans MS", command: this.changeFontFamily }, - { mark: schema.marks.pFontFamily.create({ family: "Tahoma" }), title: "Set font family", label: "Tahoma", command: this.changeFontFamily }, - { mark: schema.marks.pFontFamily.create({ family: "Impact" }), title: "Set font family", label: "Impact", command: this.changeFontFamily }, - { mark: schema.marks.pFontFamily.create({ family: "Crimson Text" }), title: "Set font family", label: "Crimson Text", command: this.changeFontFamily }, - { mark: null, title: "", label: "various", command: unimplementedFunction, hidden: true }, - // { mark: null, title: "", label: "default", command: unimplementedFunction, hidden: true }, - ]; - - const listTypeOptions = [ - { node: schema.nodes.ordered_list.create({ mapStyle: "bullet" }), title: "Set list type", label: ":", command: this.changeListType }, - { node: schema.nodes.ordered_list.create({ mapStyle: "decimal" }), title: "Set list type", label: "1.1", command: this.changeListType }, - { node: schema.nodes.ordered_list.create({ mapStyle: "multi" }), title: "Set list type", label: "1.A", command: this.changeListType }, - { node: undefined, title: "Set list type", label: "Remove", command: this.changeListType }, - ]; - const row1 =
{[ this.createButton("bold", "Bold", toggleMark(schema.marks.strong)), this.createButton("italic", "Italic", toggleMark(schema.marks.em)), @@ -714,30 +689,85 @@ export default class RichTextMenu extends AntimodeMenu { this.createLinkButton(), this.createBrushButton(), this.createButton("indent", "Summarize", undefined, this.insertSummarizer), - ]}
+ ]}
; const row2 =
-
{[ - this.createMarksDropdown(this.activeFontSize, fontSizeOptions), - this.createMarksDropdown(this.activeFontFamily, fontFamilyOptions), - this.createNodesDropdown(this.activeListType, listTypeOptions), - ]}
+
+ {[this.createMarksDropdown(this.activeFontSize, this.fontSizeOptions), + this.createMarksDropdown(this.activeFontFamily, this.fontFamilyOptions), + this.createNodesDropdown(this.activeListType, this.listTypeOptions)]} +
{this.getDragger()}
-
- - const buttons = [ - row1, row2 - ]; +
; return (
- {this.getElementWithRows(buttons, 2, false)} + {this.getElementWithRows([row1, row2], 2, false)}
); } +} + +interface ButtonDropdownProps { + // Document: Doc; + // remove: (self: ImportMetadataEntry) => void; + // next: () => void; + view?: EditorView; + button: JSX.Element; + dropdownContent: JSX.Element; + openDropdownOnButton?: boolean; +} + +@observer +class ButtonDropdown extends React.Component { + + @observable private showDropdown: boolean = false; + private ref: HTMLDivElement | null = null; + + componentDidMount() { + document.addEventListener("pointerdown", this.onBlur); + } + + componentWillUnmount() { + document.removeEventListener("pointerdown", this.onBlur); + } + + @action + setShowDropdown(show: boolean) { + this.showDropdown = show; + } + @action + toggleDropdown() { + this.showDropdown = !this.showDropdown; + } + + onDropdownClick = (e: React.PointerEvent) => { + e.preventDefault(); + e.stopPropagation(); + this.props.view && this.props.view.focus(); + this.toggleDropdown(); + } + + onBlur = (e: PointerEvent) => { + setTimeout(() => { + if (this.ref !== null && !this.ref.contains(e.target as Node)) { + this.setShowDropdown(false); + } + }, 0); + } + + render() { + return ( +
this.ref = node}> + {this.props.openDropdownOnButton ?
{this.props.button}
: this.props.button} + + {this.showDropdown ? this.props.dropdownContent : <>} +
+ ) + } } \ No newline at end of file diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 027bd492c..df055a2ab 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -1057,7 +1057,6 @@ export class FormattedTextBox extends DocAnnotatableComponent<(FieldViewProps & }); } onBlur = (e: any) => { - console.log("formated blur"); //DictationManager.Controls.stop(false); if (this._undoTyping) { this._undoTyping.end(); -- cgit v1.2.3-70-g09d2 From 5abc4de3c3495db71b0a9bcbe2468828f674eff3 Mon Sep 17 00:00:00 2001 From: Fawn Date: Thu, 9 Jan 2020 16:41:52 -0500 Subject: minor merge --- package-lock.json | 6 +----- src/client/util/RichTextMenu.tsx | 4 ++-- src/client/util/TooltipTextMenu.tsx | 14 ++++++-------- src/client/views/AntimodeMenu.tsx | 2 +- 4 files changed, 10 insertions(+), 16 deletions(-) (limited to 'src/client/views') diff --git a/package-lock.json b/package-lock.json index cad3edd82..6aa0ffc02 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7073,11 +7073,7 @@ "babel-runtime": "^6.22.0", "bluebird": "^3.4.7", "boolify-string": "^2.0.2", -<<<<<<< HEAD - "emit-logger": "github:chocolateboy/emit-logger#b9d25a2d939e42f29c940861e9648bd0fb810070", -======= "emit-logger": "github:chocolateboy/emit-logger#better-emitter-name", ->>>>>>> 540bda7295f6ee7c2eed848598de6f5df74b2723 "lodash": "^4.17.4", "semver": "^5.0.3", "source-map-support": "^0.5.9" @@ -18091,4 +18087,4 @@ } } } -} +} \ No newline at end of file diff --git a/src/client/util/RichTextMenu.tsx b/src/client/util/RichTextMenu.tsx index e367cf350..375c10da3 100644 --- a/src/client/util/RichTextMenu.tsx +++ b/src/client/util/RichTextMenu.tsx @@ -208,7 +208,7 @@ export default class RichTextMenu extends AntimodeMenu { getMarksInSelection(state: EditorState) { const found = new Set(); const { from, to } = state.selection as TextSelection; - state.doc.nodesBetween(from, to, (node) => node.marks ?.forEach(m => found.add(m))); + state.doc.nodesBetween(from, to, (node) => node.marks.forEach(m => found.add(m))); return found; } @@ -768,6 +768,6 @@ class ButtonDropdown extends React.Component { {this.showDropdown ? this.props.dropdownContent : <>}
- ) + ); } } \ No newline at end of file diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx index 8177593c2..1c15dca7f 100644 --- a/src/client/util/TooltipTextMenu.tsx +++ b/src/client/util/TooltipTextMenu.tsx @@ -18,8 +18,6 @@ import { SelectionManager } from './SelectionManager'; import { PastelSchemaPalette, DarkPastelSchemaPalette } from '../../new_fields/SchemaHeaderField'; const { toggleMark } = require("prosemirror-commands"); -// deprecated in favor of richtextmenu - //appears above a selection of text in a RichTextBox to give user options such as Bold, Italics, etc. export class TooltipTextMenu { public static Toolbar: HTMLDivElement | undefined; @@ -95,7 +93,7 @@ export class TooltipTextMenu { { mark: schema.marks.subscript, dom: svgIcon("subscript", "Subscript", "M496 448h-16V304a16 16 0 0 0-16-16h-48a16 16 0 0 0-14.29 8.83l-16 32A16 16 0 0 0 400 352h16v96h-16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h96a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM336 64h-67a16 16 0 0 0-13.14 6.87l-79.9 115-79.9-115A16 16 0 0 0 83 64H16A16 16 0 0 0 0 80v48a16 16 0 0 0 16 16h33.48l77.81 112-77.81 112H16a16 16 0 0 0-16 16v48a16 16 0 0 0 16 16h67a16 16 0 0 0 13.14-6.87l79.9-115 79.9 115A16 16 0 0 0 269 448h67a16 16 0 0 0 16-16v-48a16 16 0 0 0-16-16h-33.48l-77.81-112 77.81-112H336a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16z") }, ]; - basicItems.map(({ dom, mark }) => this.basicTools?.appendChild(dom.cloneNode(true))); + basicItems.map(({ dom, mark }) => this.basicTools ?.appendChild(dom.cloneNode(true))); basicItems.concat(items).forEach(({ dom, mark }) => { this.tooltip.appendChild(dom); this._marksToDoms.set(mark, dom); @@ -476,7 +474,7 @@ export class TooltipTextMenu { const node = self.view.state.selection.$from.nodeAfter; const link = node && node.marks.find(m => m.type === self.view.state.schema.marks.link); const href = link!.attrs.href; - if (href?.indexOf(Utils.prepend("/doc/")) === 0) { + if (href ?.indexOf(Utils.prepend("/doc/")) === 0) { const linkclicked = href.replace(Utils.prepend("/doc/"), "").split("?")[0]; linkclicked && DocServer.GetRefField(linkclicked).then(async linkDoc => { if (linkDoc instanceof Doc) { @@ -502,7 +500,7 @@ export class TooltipTextMenu { const link = this.view.state.schema.marks.link.create({ href: Utils.prepend("/doc/" + linkDocId), title: title, location: location, targetId: targetDocId }); this.view.dispatch(this.view.state.tr.removeMark(this.view.state.selection.from, this.view.state.selection.to, this.view.state.schema.marks.link). addMark(this.view.state.selection.from, this.view.state.selection.to, link)); - return this.view.state.selection.$from.nodeAfter?.text || ""; + return this.view.state.selection.$from.nodeAfter ?.text || ""; } // SUMMARIZER TOOL @@ -512,7 +510,7 @@ export class TooltipTextMenu { const tr = state.tr.addMark(state.selection.from, state.selection.to, mark); const content = tr.selection.content(); const newNode = state.schema.nodes.summary.create({ visibility: false, text: content, textslice: content.toJSON() }); - dispatch?.(tr.replaceSelectionWith(newNode).removeMark(tr.selection.from - 1, tr.selection.from, mark)); + dispatch ?.(tr.replaceSelectionWith(newNode).removeMark(tr.selection.from - 1, tr.selection.from, mark)); } } @@ -739,7 +737,7 @@ export class TooltipTextMenu { // get marks in the selection const selected_marks = new Set(); const { from, to } = state.selection as TextSelection; - state.doc.nodesBetween(from, to, (node) => node.marks?.forEach(m => selected_marks.add(m))); + state.doc.nodesBetween(from, to, (node) => node.marks ?.forEach(m => selected_marks.add(m))); if (this._brushdom && selected_marks.size >= 0) { TooltipTextMenuManager.Instance._brushMarks = selected_marks; @@ -851,7 +849,7 @@ export class TooltipTextMenu { static setMark = (mark: Mark, state: EditorState, dispatch: any) => { if (mark) { const node = (state.selection as NodeSelection).node; - if (node?.type === schema.nodes.ordered_list) { + if (node ?.type === schema.nodes.ordered_list) { let attrs = node.attrs; if (mark.type === schema.marks.pFontFamily) attrs = { ...attrs, setFontFamily: mark.attrs.family }; if (mark.type === schema.marks.pFontSize) attrs = { ...attrs, setFontSize: mark.attrs.fontSize }; diff --git a/src/client/views/AntimodeMenu.tsx b/src/client/views/AntimodeMenu.tsx index e358d88cf..4625eb92f 100644 --- a/src/client/views/AntimodeMenu.tsx +++ b/src/client/views/AntimodeMenu.tsx @@ -127,7 +127,7 @@ export default abstract class AntimodeMenu extends React.Component { } protected getDragger = () => { - return
+ return
; } protected getElement(buttons: JSX.Element[]) { -- cgit v1.2.3-70-g09d2 From 579010cc792ce961618406886961d257be2c74db Mon Sep 17 00:00:00 2001 From: Fawn Date: Thu, 9 Jan 2020 18:13:28 -0500 Subject: condensed the link button and made buttons dark when they are active in the selection --- package-lock.json | 91 +++++++++++++++----------------------- src/client/util/RichTextMenu.scss | 10 +++++ src/client/util/RichTextMenu.tsx | 67 +++++++++++++++++++++++----- src/client/views/AntimodeMenu.scss | 4 ++ 4 files changed, 105 insertions(+), 67 deletions(-) (limited to 'src/client/views') diff --git a/package-lock.json b/package-lock.json index 6aa0ffc02..cf61e6aab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1978,7 +1978,7 @@ }, "util": { "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "resolved": "http://registry.npmjs.org/util/-/util-0.10.3.tgz", "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", "dev": true, "requires": { @@ -2561,7 +2561,7 @@ }, "browserify-aes": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "requires": { "buffer-xor": "^1.0.3", @@ -2595,7 +2595,7 @@ }, "browserify-rsa": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "requires": { "bn.js": "^4.1.0", @@ -2779,7 +2779,7 @@ }, "camelcase-keys": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", "requires": { "camelcase": "^2.0.0", @@ -3563,7 +3563,7 @@ }, "create-hash": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "requires": { "cipher-base": "^1.0.1", @@ -3575,7 +3575,7 @@ }, "create-hmac": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "requires": { "cipher-base": "^1.0.3", @@ -4118,7 +4118,7 @@ }, "diffie-hellman": { "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "requires": { "bn.js": "^4.1.0", @@ -5361,8 +5361,7 @@ }, "ansi-regex": { "version": "2.1.1", - "bundled": true, - "optional": true + "bundled": true }, "aproba": { "version": "1.2.0", @@ -5380,13 +5379,11 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true, - "optional": true + "bundled": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -5399,18 +5396,15 @@ }, "code-point-at": { "version": "1.1.0", - "bundled": true, - "optional": true + "bundled": true }, "concat-map": { "version": "0.0.1", - "bundled": true, - "optional": true + "bundled": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true, - "optional": true + "bundled": true }, "core-util-is": { "version": "1.0.2", @@ -5513,8 +5507,7 @@ }, "inherits": { "version": "2.0.3", - "bundled": true, - "optional": true + "bundled": true }, "ini": { "version": "1.3.5", @@ -5524,7 +5517,6 @@ "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -5537,20 +5529,17 @@ "minimatch": { "version": "3.0.4", "bundled": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "bundled": true, - "optional": true + "bundled": true }, "minipass": { "version": "2.3.5", "bundled": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -5567,7 +5556,6 @@ "mkdirp": { "version": "0.5.1", "bundled": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -5640,8 +5628,7 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true, - "optional": true + "bundled": true }, "object-assign": { "version": "4.1.1", @@ -5651,7 +5638,6 @@ "once": { "version": "1.4.0", "bundled": true, - "optional": true, "requires": { "wrappy": "1" } @@ -5727,8 +5713,7 @@ }, "safe-buffer": { "version": "5.1.2", - "bundled": true, - "optional": true + "bundled": true }, "safer-buffer": { "version": "2.1.2", @@ -5758,7 +5743,6 @@ "string-width": { "version": "1.0.2", "bundled": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -5776,7 +5760,6 @@ "strip-ansi": { "version": "3.0.1", "bundled": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -5815,13 +5798,11 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true, - "optional": true + "bundled": true }, "yallist": { "version": "3.0.3", - "bundled": true, - "optional": true + "bundled": true } } }, @@ -7073,7 +7054,7 @@ "babel-runtime": "^6.22.0", "bluebird": "^3.4.7", "boolify-string": "^2.0.2", - "emit-logger": "github:chocolateboy/emit-logger#better-emitter-name", + "emit-logger": "github:chocolateboy/emit-logger#b9d25a2d939e42f29c940861e9648bd0fb810070", "lodash": "^4.17.4", "semver": "^5.0.3", "source-map-support": "^0.5.9" @@ -7081,7 +7062,7 @@ }, "is-accessor-descriptor": { "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "requires": { "kind-of": "^3.0.2" @@ -7130,7 +7111,7 @@ }, "is-data-descriptor": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "requires": { "kind-of": "^3.0.2" @@ -7915,7 +7896,7 @@ }, "load-json-file": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "requires": { "graceful-fs": "^4.1.2", @@ -8229,7 +8210,7 @@ }, "media-typer": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, "mem": { @@ -8261,7 +8242,7 @@ }, "meow": { "version": "3.7.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz", "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", "requires": { "camelcase-keys": "^2.0.0", @@ -8454,7 +8435,7 @@ }, "mkdirp": { "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "requires": { "minimist": "0.0.8" @@ -8800,7 +8781,7 @@ }, "next-tick": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" }, "nice-try": { @@ -8964,7 +8945,7 @@ }, "semver": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "resolved": "http://registry.npmjs.org/semver/-/semver-5.3.0.tgz", "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" }, "tar": { @@ -12573,7 +12554,7 @@ }, "os-homedir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" }, "os-locale": { @@ -12586,7 +12567,7 @@ }, "os-tmpdir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" }, "osenv": { @@ -12826,7 +12807,7 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-is-inside": { @@ -14491,7 +14472,7 @@ }, "safe-regex": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "requires": { "ret": "~0.1.10" @@ -14756,7 +14737,7 @@ }, "sha.js": { "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "requires": { "inherits": "^2.0.1", @@ -15499,7 +15480,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "requires": { "safe-buffer": "~5.1.0" @@ -15545,7 +15526,7 @@ }, "strip-eof": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" }, "strip-indent": { @@ -16298,7 +16279,7 @@ }, "tty-browserify": { "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "resolved": "http://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", "dev": true }, @@ -18087,4 +18068,4 @@ } } } -} \ No newline at end of file +} diff --git a/src/client/util/RichTextMenu.scss b/src/client/util/RichTextMenu.scss index 6383e0b7b..43cc23ecd 100644 --- a/src/client/util/RichTextMenu.scss +++ b/src/client/util/RichTextMenu.scss @@ -9,6 +9,16 @@ padding-right: 5px; } + .dropdown-button-combined { + width: 50px; + display: flex; + justify-content: space-between; + + svg:nth-child(2) { + margin-top: 2px; + } + } + .dropdown { position: absolute; top: 35px; diff --git a/src/client/util/RichTextMenu.tsx b/src/client/util/RichTextMenu.tsx index a5de8d7a9..ec79fbf85 100644 --- a/src/client/util/RichTextMenu.tsx +++ b/src/client/util/RichTextMenu.tsx @@ -8,7 +8,7 @@ import { EditorView } from "prosemirror-view"; import { EditorState, NodeSelection, TextSelection } from "prosemirror-state"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { IconProp, library } from '@fortawesome/fontawesome-svg-core'; -import { faBold, faItalic, faUnderline, faStrikethrough, faSubscript, faSuperscript, faIndent, faEyeDropper, faCaretDown, faPalette, faHighlighter, faLink, faPaintRoller } from "@fortawesome/free-solid-svg-icons"; +import { faBold, faItalic, faUnderline, faStrikethrough, faSubscript, faSuperscript, faIndent, faEyeDropper, faCaretDown, faPalette, faHighlighter, faLink, faPaintRoller, faSleigh } from "@fortawesome/free-solid-svg-icons"; import { MenuItem, Dropdown } from "prosemirror-menu"; import { updateBullets } from "./ProsemirrorExampleTransfer"; import { FieldViewProps } from "../views/nodes/FieldView"; @@ -40,6 +40,13 @@ export default class RichTextMenu extends AntimodeMenu { private fontColors: (string | undefined)[]; private highlightColors: (string | undefined)[]; + @observable private boldActive: boolean = false; + @observable private italicsActive: boolean = false; + @observable private underlineActive: boolean = false; + @observable private strikethroughActive: boolean = false; + @observable private subscriptActive: boolean = false; + @observable private superscriptActive: boolean = false; + @observable private activeFontSize: string = ""; @observable private activeFontFamily: string = ""; @observable private activeListType: string = ""; @@ -148,6 +155,9 @@ export default class RichTextMenu extends AntimodeMenu { // Don't do anything if the document/selection didn't change if (lastState && lastState.doc.eq(state.doc) && lastState.selection.eq(state.selection)) return; + // update active marks + const activeMarks = this.getMarksInSelection(this.view.state); + this.setActiveMarkButtons(activeMarks); // update active font family and size const active = this.getActiveFontStylesOnSelection(); @@ -208,14 +218,37 @@ export default class RichTextMenu extends AntimodeMenu { getMarksInSelection(state: EditorState) { const found = new Set(); const { from, to } = state.selection as TextSelection; + console.log(to - from, state.tr.storedMarks); state.doc.nodesBetween(from, to, (node) => node.marks.forEach(m => found.add(m))); + if (to - from === 0) { state.storedMarks && state.storedMarks.forEach(m => found.add(m)); } return found; } destroy() { } - createButton(faIcon: string, title: string, command?: any, onclick?: any) { + @action + setActiveMarkButtons(activeMarks: Set) { + this.boldActive = false; + this.italicsActive = false; + this.underlineActive = false; + this.strikethroughActive = false; + this.subscriptActive = false; + this.superscriptActive = false; + + activeMarks.forEach(mark => { + switch (mark.type.name) { + case "strong": this.boldActive = true; break; + case "em": this.italicsActive = true; break; + case "underline": this.underlineActive = true; break; + case "strikethrough": this.strikethroughActive = true; break; + case "subscript": this.subscriptActive = true; break; + case "superscript": this.superscriptActive = true; break; + } + }); + } + + createButton(faIcon: string, title: string, isActive: boolean = false, command?: any, onclick?: any) { const self = this; function onClick(e: React.PointerEvent) { e.preventDefault(); @@ -226,7 +259,7 @@ export default class RichTextMenu extends AntimodeMenu { } return ( - ); @@ -528,7 +561,7 @@ export default class RichTextMenu extends AntimodeMenu { const link = this.currentLink ? this.currentLink : ""; - const button = ; + const button = const dropdownContent =
@@ -678,12 +711,12 @@ export default class RichTextMenu extends AntimodeMenu { render() { const row1 =
{[ - this.createButton("bold", "Bold", toggleMark(schema.marks.strong)), - this.createButton("italic", "Italic", toggleMark(schema.marks.em)), - this.createButton("underline", "Underline", toggleMark(schema.marks.underline)), - this.createButton("strikethrough", "Strikethrough", toggleMark(schema.marks.strikethrough)), - this.createButton("superscript", "Superscript", toggleMark(schema.marks.superscript)), - this.createButton("subscript", "Subscript", toggleMark(schema.marks.subscript)), + this.createButton("bold", "Bold", this.boldActive, toggleMark(schema.marks.strong)), + this.createButton("italic", "Italic", this.italicsActive, toggleMark(schema.marks.em)), + this.createButton("underline", "Underline", this.underlineActive, toggleMark(schema.marks.underline)), + this.createButton("strikethrough", "Strikethrough", this.strikethroughActive, toggleMark(schema.marks.strikethrough)), + this.createButton("superscript", "Superscript", this.superscriptActive, toggleMark(schema.marks.superscript)), + this.createButton("subscript", "Subscript", this.subscriptActive, toggleMark(schema.marks.subscript)), this.createColorButton(), this.createHighlighterButton(), this.createLinkButton(), @@ -761,8 +794,18 @@ class ButtonDropdown extends React.Component { render() { return (
this.ref = node}> - {this.props.openDropdownOnButton ?
{this.props.button}
: this.props.button} - + {this.props.openDropdownOnButton ? + : + <> + {this.props.button} + + } + {this.showDropdown ? this.props.dropdownContent : <>}
); diff --git a/src/client/views/AntimodeMenu.scss b/src/client/views/AntimodeMenu.scss index f78b1dbfb..d4a76ee17 100644 --- a/src/client/views/AntimodeMenu.scss +++ b/src/client/views/AntimodeMenu.scss @@ -21,6 +21,10 @@ background-color: transparent; width: 35px; height: 35px; + + &.active { + background-color: #121212; + } } .antimodeMenu-button:hover { -- cgit v1.2.3-70-g09d2