diff options
-rw-r--r-- | src/Utils.ts | 13 | ||||
-rw-r--r-- | src/client/util/RichTextSchema.tsx | 11 | ||||
-rw-r--r-- | src/client/views/nodes/FormattedTextBox.tsx | 37 |
3 files changed, 37 insertions, 24 deletions
diff --git a/src/Utils.ts b/src/Utils.ts index 4b892aa70..f6ab434a8 100644 --- a/src/Utils.ts +++ b/src/Utils.ts @@ -337,4 +337,17 @@ export default function smoothScroll(duration: number, element: HTMLElement, to: } }; animateScroll(); +} +export function addStyleSheet(styleType: string = "text/css") { + let style = document.createElement("style"); + style.type = styleType; + var sheets = document.head.appendChild(style); + return (sheets as any).sheet; +} +export function addStyleSheetRule(sheet: any, selector: any, css: any) { + var propText = typeof css === "string" ? css : Object.keys(css).map(p => p + ":" + (p === "content" ? "'" + css[p] + "'" : css[p])).join(";"); + return sheet.insertRule("." + selector + "{" + propText + "}", sheet.cssRules.length); +} +export function removeStyleSheetRule(sheet: any, rule: number) { + sheet.removeRule(rule); }
\ No newline at end of file diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index 836713c01..bc1ad5070 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -4,7 +4,7 @@ import { redo, undo } from "prosemirror-history"; import { keymap } from "prosemirror-keymap"; import { DOMOutputSpecArray, Fragment, MarkSpec, Node, NodeSpec, Schema, Slice } from "prosemirror-model"; import { bulletList, listItem, orderedList } from 'prosemirror-schema-list'; -import { EditorState, NodeSelection, TextSelection } from "prosemirror-state"; +import { EditorState, NodeSelection, TextSelection, Plugin } from "prosemirror-state"; import { StepMap } from "prosemirror-transform"; import { EditorView } from "prosemirror-view"; import * as ReactDOM from 'react-dom'; @@ -847,7 +847,14 @@ export class FootnoteView { "Mod-z": () => undo(this.outerView.state, this.outerView.dispatch), "Mod-y": () => redo(this.outerView.state, this.outerView.dispatch), "Mod-b": toggleMark(schema.marks.strong) - })] + }), + new Plugin({ + view(newView) { + return FormattedTextBox.getToolTip(newView); + } + }) + ], + }), // This is the magic part dispatchTransaction: this.dispatchInner.bind(this), diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 41bd29422..96b434708 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -18,7 +18,7 @@ import { RichTextField } from "../../../new_fields/RichTextField"; import { RichTextUtils } from '../../../new_fields/RichTextUtils'; import { createSchema, makeInterface } from "../../../new_fields/Schema"; import { Cast, DateCast, NumCast, StrCast } from "../../../new_fields/Types"; -import { numberRange, timenow, Utils, emptyFunction } from '../../../Utils'; +import { numberRange, timenow, Utils, addStyleSheet, addStyleSheetRule, removeStyleSheetRule } from '../../../Utils'; import { GoogleApiClientUtils, Pulls, Pushes } from '../../apis/google_docs/GoogleApiClientUtils'; import { DocServer } from "../../DocServer"; import { Docs, DocUtils } from '../../documents/Documents'; @@ -781,18 +781,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe } } - static _sheet: any = undefined; - static addRule = ((style) => { - style.type = "text/css" - var sheets = document.head.appendChild(style); - FormattedTextBox._sheet = (sheets as any).sheet; - return function (selector: any, css: any) { - var propText = typeof css === "string" ? css : Object.keys(css).map(function (p) { - return p + ":" + (p === "content" ? "'" + css[p] + "'" : css[p]); - }).join(";"); - return FormattedTextBox._sheet.insertRule("." + selector + "{" + propText + "}", FormattedTextBox._sheet.cssRules.length); - }; - })(document.createElement("style")); + static _sheet: any = addStyleSheet(); onClick = (e: React.MouseEvent): void => { if ((e.nativeEvent as any).formattedHandled) { e.stopPropagation(); return; } @@ -830,12 +819,16 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe } } + this.hitBulletTargets(e.clientX, e.clientY, e.nativeEvent.offsetX, e.shiftKey); + } + + // this hackiness handles clicking on the list item bullets to do expand/collapse. the bullets are ::before pseudo elements so there's no real way to hit test against them. + hitBulletTargets(x: number, y: number, offsetX: number, select: boolean = false) { if (FormattedTextBox._sheet.rules.length) { - FormattedTextBox._sheet.removeRule(0); + removeStyleSheetRule(FormattedTextBox._sheet, 0); } - // this hackiness handles clicking on the list item bullets to do expand/collapse. the bullets are ::before pseudo elements so there's no real way to hit test against them. - if (this.props.isSelected() && e.nativeEvent.offsetX < 40) { - let pos = this._editorView!.posAtCoords({ left: e.clientX, top: e.clientY }); + if (this.props.isSelected() && offsetX < 40) { + let pos = this._editorView!.posAtCoords({ left: x, top: y }); if (pos && pos.pos > 0) { let node = this._editorView!.state.doc.nodeAt(pos.pos); let node2 = node && node.type === schema.nodes.paragraph ? this._editorView!.state.doc.nodeAt(pos.pos - 1) : undefined; @@ -843,11 +836,11 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe let hit = this._editorView!.domAtPos(pos.pos).node as any; // let beforeEle = document.querySelector("." + hit.className) as Element; let before = hit ? window.getComputedStyle(hit, ':before') : undefined; let beforeWidth = before ? Number(before.getPropertyValue('width').replace("px", "")) : undefined; - if (beforeWidth && e.nativeEvent.offsetX < beforeWidth) { + if (beforeWidth && offsetX < beforeWidth) { let ol = this._editorView!.state.doc.nodeAt(pos.pos - 2) ? this._editorView!.state.doc.nodeAt(pos.pos - 2) : undefined; - if (ol && ol.type === schema.nodes.ordered_list && e.shiftKey) { + if (ol && ol.type === schema.nodes.ordered_list && select) { this._editorView!.dispatch(this._editorView!.state.tr.setSelection(new NodeSelection(this._editorView!.state.doc.resolve(pos.pos - 2)))); - FormattedTextBox.addRule(hit.className + ":before", { background: "gray" }); + addStyleSheetRule(FormattedTextBox._sheet, hit.className + ":before", { background: "gray" }); } else { this._editorView!.dispatch(this._editorView!.state.tr.setNodeMarkup(pos.pos - 1, node2.type, { ...node2.attrs, visibility: !node2.attrs.visibility })); } @@ -875,8 +868,8 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe tooltipTextMenuPlugin() { let self = FormattedTextBox; return new Plugin({ - view(_editorView) { - return self._toolTipTextMenu = FormattedTextBox.getToolTip(_editorView); + view(newView) { + return self._toolTipTextMenu = FormattedTextBox.getToolTip(newView); } }); } |