From 0d10fd88041334a20cf37a57808a8b9c58f35f25 Mon Sep 17 00:00:00 2001 From: ab Date: Tue, 4 Jun 2019 15:06:56 -0400 Subject: exploring prosemirror --- src/client/util/ProsemirrorKeymap.ts | 2 +- src/client/util/TooltipTextMenu.tsx | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/client/util/ProsemirrorKeymap.ts b/src/client/util/ProsemirrorKeymap.ts index 00d086b97..71644cd88 100644 --- a/src/client/util/ProsemirrorKeymap.ts +++ b/src/client/util/ProsemirrorKeymap.ts @@ -50,7 +50,7 @@ export default function buildKeymap>(schema: S, mapKeys?: } if (type = schema.nodes.bullet_list) { - bind("Ctrl-b", wrapInList(type)); + bind("Ctrl-.", wrapInList(type)); } if (type = schema.nodes.ordered_list) { bind("Ctrl-n", wrapInList(type)); diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx index f517f757a..625f5ee54 100644 --- a/src/client/util/TooltipTextMenu.tsx +++ b/src/client/util/TooltipTextMenu.tsx @@ -68,12 +68,12 @@ export class TooltipTextMenu { library.add(faListUl); //add the buttons to the tooltip let items = [ - { command: toggleMark(schema.marks.strong), dom: this.icon("B", "strong") }, - { command: toggleMark(schema.marks.em), dom: this.icon("i", "em") }, - { command: toggleMark(schema.marks.underline), dom: this.icon("U", "underline") }, - { command: toggleMark(schema.marks.strikethrough), dom: this.icon("S", "strikethrough") }, - { command: toggleMark(schema.marks.superscript), dom: this.icon("s", "superscript") }, - { command: toggleMark(schema.marks.subscript), dom: this.icon("s", "subscript") }, + { command: toggleMark(schema.marks.strong), dom: this.icon("B", "strong", "Bold") }, + { command: toggleMark(schema.marks.em), dom: this.icon("i", "em", "Italic") }, + { command: toggleMark(schema.marks.underline), dom: this.icon("U", "underline", "Underline") }, + { command: toggleMark(schema.marks.strikethrough), dom: this.icon("S", "strikethrough", "Strikethrough") }, + { command: toggleMark(schema.marks.superscript), dom: this.icon("s", "superscript", "Superscript") }, + { command: toggleMark(schema.marks.subscript), dom: this.icon("s", "subscript", "Subscript") }, // { command: wrapInList(schema.nodes.bullet_list), dom: this.icon(":", "bullets") }, // { command: wrapInList(schema.nodes.ordered_list), dom: this.icon("1)", "bullets") }, // { command: lift, dom: this.icon("<", "lift") }, @@ -349,10 +349,10 @@ export class TooltipTextMenu { } // Helper function to create menu icons - icon(text: string, name: string) { + icon(text: string, name: string, title: string = name) { let span = document.createElement("span"); span.className = name + " menuicon"; - span.title = name; + span.title = title; span.textContent = text; span.style.color = "white"; return span; -- cgit v1.2.3-70-g09d2 From 5a494838844f297139e506fae2f3cd7986b8b964 Mon Sep 17 00:00:00 2001 From: ab Date: Wed, 5 Jun 2019 11:07:51 -0400 Subject: still exploring --- src/client/views/nodes/FormattedTextBox.tsx | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 5c635cc0c..77e8bc92a 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -151,6 +151,10 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe ] }; + const config2 = { + + }; + if (this.props.isOverlay) { this._inputReactionDisposer = reaction(() => FormattedTextBox.InputBoxOverlay, () => { -- cgit v1.2.3-70-g09d2 From 3fa27ef718ff3ed855e0ae2b4fc35d51fe60fb25 Mon Sep 17 00:00:00 2001 From: ab Date: Wed, 5 Jun 2019 15:25:30 -0400 Subject: menu doesn't flicker --- src/client/util/TooltipTextMenu.scss | 23 +++++++++--------- src/client/util/TooltipTextMenu.tsx | 33 ++++++++++++++------------ src/client/views/nodes/FormattedTextBox.tsx | 36 +++++++++++------------------ 3 files changed, 44 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/client/util/TooltipTextMenu.scss b/src/client/util/TooltipTextMenu.scss index 437da0d63..e2862f093 100644 --- a/src/client/util/TooltipTextMenu.scss +++ b/src/client/util/TooltipTextMenu.scss @@ -36,7 +36,7 @@ position: relative; padding-right: 15px; margin: 3px; - background: #333333; + background: white; border-radius: 3px; text-align: center; } @@ -69,6 +69,7 @@ .ProseMirror-menu-dropdown-menu { z-index: 15; min-width: 6em; + background: white; } .linking { @@ -82,7 +83,7 @@ } .ProseMirror-menu-dropdown-item:hover { - background: #2e2b2b; + background: white; } .ProseMirror-menu-submenu-wrap { @@ -155,7 +156,7 @@ } .ProseMirror-icon svg { - fill: currentColor; + fill:white; height: 1em; } @@ -184,7 +185,7 @@ position: fixed; border-radius: 3px; z-index: 11; - box-shadow: -.5px 2px 5px rgba(0, 0, 0, .2); + box-shadow: -.5px 2px 5px white(255, 255, 255, 0.2); } .ProseMirror-prompt h5 { @@ -196,7 +197,7 @@ .ProseMirror-prompt input[type="text"], .ProseMirror-prompt textarea { - background: #eee; + background: white; border: none; outline: none; } @@ -233,12 +234,12 @@ .tooltipMenu { position: absolute; - z-index: 200; - background: $dark-color; + z-index: 50; + background: whitesmoke; border: 1px solid silver; - border-radius: 4px; + border-radius: 15px; padding: 2px 10px; - margin-bottom: 7px; + margin-bottom: 15px; -webkit-transform: translateX(-50%); transform: translateX(-50%); pointer-events: all; @@ -282,9 +283,9 @@ .menuicon { display: inline-block; - border-right: 1px solid rgba(0, 0, 0, 0.2); + border-right: 1px solid white(0, 0, 0, 0.2); //color: rgb(19, 18, 18); - color: white; + color: rgb(226, 21, 21); line-height: 1; padding: 0px 2px; margin: 1px; diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx index 625f5ee54..7c5437510 100644 --- a/src/client/util/TooltipTextMenu.tsx +++ b/src/client/util/TooltipTextMenu.tsx @@ -86,7 +86,10 @@ export class TooltipTextMenu { dom.addEventListener("pointerdown", e => { e.preventDefault(); view.focus(); - command(view.state, view.dispatch, view); + if (dom.contains(e.target as Node)) { + e.stopPropagation(); + command(view.state, view.dispatch, view); + } }); }); @@ -131,13 +134,13 @@ export class TooltipTextMenu { //font SIZES let fontSizeBtns: MenuItem[] = []; this.fontSizeToNum.forEach((number, mark) => { - fontSizeBtns.push(this.dropdownMarkBtn(String(number), "width: 50px;", mark, this.view, this.changeToMarkInGroup, this.fontSizes)); + fontSizeBtns.push(this.dropdownMarkBtn(String(number), "color: black; width: 50px;", mark, this.view, this.changeToMarkInGroup, this.fontSizes)); }); if (this.fontSizeDom) { this.tooltip.removeChild(this.fontSizeDom); } this.fontSizeDom = (new Dropdown(cut(fontSizeBtns), { label: label, - css: "color:white; min-width: 60px; padding-left: 5px; margin-right: 0;" + css: "color:black; min-width: 60px; padding-left: 5px; margin-right: 0;" }) as MenuItem).render(this.view).dom; this.tooltip.appendChild(this.fontSizeDom); } @@ -150,13 +153,13 @@ export class TooltipTextMenu { //font STYLES let fontBtns: MenuItem[] = []; this.fontStylesToName.forEach((name, mark) => { - fontBtns.push(this.dropdownMarkBtn(name, "font-family: " + name + ", sans-serif; width: 125px;", mark, this.view, this.changeToMarkInGroup, this.fontStyles)); + fontBtns.push(this.dropdownMarkBtn(name, "color: black; font-family: " + name + ", sans-serif; width: 125px;", mark, this.view, this.changeToMarkInGroup, this.fontStyles)); }); if (this.fontStyleDom) { this.tooltip.removeChild(this.fontStyleDom); } this.fontStyleDom = (new Dropdown(cut(fontBtns), { label: label, - css: "color:white; width: 125px; margin-left: -3px; padding-left: 2px;" + css: "color:black; width: 125px; margin-left: -3px; padding-left: 2px;" }) as MenuItem).render(this.view).dom; this.tooltip.appendChild(this.fontStyleDom); @@ -165,7 +168,7 @@ export class TooltipTextMenu { updateLinkMenu() { if (!this.linkEditor || !this.linkText) { this.linkEditor = document.createElement("div"); - this.linkEditor.style.color = "white"; + this.linkEditor.style.color = "black"; this.linkText = document.createElement("div"); this.linkText.style.cssFloat = "left"; this.linkText.style.marginRight = "5px"; @@ -174,13 +177,13 @@ export class TooltipTextMenu { this.linkText.style.whiteSpace = "nowrap"; this.linkText.style.width = "150px"; this.linkText.style.overflow = "hidden"; - this.linkText.style.color = "white"; + this.linkText.style.color = "black"; this.linkText.onpointerdown = (e: PointerEvent) => { e.stopPropagation(); }; let linkBtn = document.createElement("div"); linkBtn.textContent = ">>"; - linkBtn.style.width = "20px"; - linkBtn.style.height = "20px"; - linkBtn.style.color = "white"; + linkBtn.style.width = "10px"; + linkBtn.style.height = "10px"; + linkBtn.style.color = "black"; linkBtn.style.cssFloat = "left"; linkBtn.onpointerdown = (e: PointerEvent) => { let node = this.view.state.selection.$from.nodeAfter; @@ -207,7 +210,7 @@ export class TooltipTextMenu { this.linkDrag.src = "https://seogurusnyc.com/wp-content/uploads/2016/12/link-1.png"; this.linkDrag.style.width = "20px"; this.linkDrag.style.height = "20px"; - this.linkDrag.style.color = "white"; + this.linkDrag.style.color = "black"; this.linkDrag.style.background = "black"; this.linkDrag.style.cssFloat = "left"; this.linkDrag.onpointerdown = (e: PointerEvent) => { @@ -261,14 +264,14 @@ export class TooltipTextMenu { //Make a dropdown of all list types let toAdd: MenuItem[] = []; this.listTypeToIcon.forEach((icon, type) => { - toAdd.push(this.dropdownNodeBtn(icon, "width: 40px;", type, this.view, this.listTypes, this.changeToNodeType)); + toAdd.push(this.dropdownNodeBtn(icon, "color: black; width: 40px;", type, this.view, this.listTypes, this.changeToNodeType)); }); //option to remove the list formatting - toAdd.push(this.dropdownNodeBtn("X", "width: 40px;", undefined, this.view, this.listTypes, this.changeToNodeType)); + toAdd.push(this.dropdownNodeBtn("X", "color: black; width: 40px;", undefined, this.view, this.listTypes, this.changeToNodeType)); listTypeBtn = (new Dropdown(toAdd, { label: label, - css: "color:white; width: 40px;" + css: "color:black; width: 40px;" }) as MenuItem).render(this.view).dom; //add this new button and return it @@ -354,7 +357,7 @@ export class TooltipTextMenu { span.className = name + " menuicon"; span.title = title; span.textContent = text; - span.style.color = "white"; + span.style.color = "black"; return span; } diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index e6617bf65..5c635cc0c 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -7,12 +7,11 @@ import { history } from "prosemirror-history"; import { keymap } from "prosemirror-keymap"; import { EditorState, Plugin, Transaction } from "prosemirror-state"; import { EditorView } from "prosemirror-view"; -import { Doc, Opt } from "../../../new_fields/Doc"; +import { Doc, Field, Opt, WidthSym, HeightSym } from "../../../new_fields/Doc"; import { RichTextField } from "../../../new_fields/RichTextField"; import { createSchema, makeInterface } from "../../../new_fields/Schema"; import { Cast, NumCast, StrCast } from "../../../new_fields/Types"; import { DocServer } from "../../DocServer"; -import { DocUtils } from '../../documents/Documents'; import { DocumentManager } from "../../util/DocumentManager"; import { DragManager } from "../../util/DragManager"; import buildKeymap from "../../util/ProsemirrorKeymap"; @@ -22,11 +21,14 @@ import { SelectionManager } from "../../util/SelectionManager"; import { TooltipLinkingMenu } from "../../util/TooltipLinkingMenu"; import { TooltipTextMenu } from "../../util/TooltipTextMenu"; import { undoBatch, UndoManager } from "../../util/UndoManager"; +import { ContextMenu } from "../../views/ContextMenu"; +import { CollectionDockingView } from "../collections/CollectionDockingView"; import { DocComponent } from "../DocComponent"; import { InkingControl } from "../InkingControl"; import { FieldView, FieldViewProps } from "./FieldView"; import "./FormattedTextBox.scss"; import React = require("react"); +import { DocUtils } from '../../documents/Documents'; library.add(faEdit); library.add(faSmile); @@ -149,10 +151,6 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe ] }; - const config2 = { - - }; - if (this.props.isOverlay) { this._inputReactionDisposer = reaction(() => FormattedTextBox.InputBoxOverlay, () => { @@ -225,7 +223,6 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe } } - _linkClicked = ""; onPointerDown = (e: React.PointerEvent): void => { if (e.button === 0 && this.props.isSelected() && !e.altKey && !e.ctrlKey && !e.metaKey) { e.stopPropagation(); @@ -233,17 +230,23 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe this._toolTipTextMenu.tooltip.style.opacity = "0"; } } - this._linkClicked = ""; + let ctrlKey = e.ctrlKey; if (e.button === 0 && ((!this.props.isSelected() && !e.ctrlKey) || (this.props.isSelected() && e.ctrlKey)) && !e.metaKey && e.target) { let href = (e.target as any).href; for (let parent = (e.target as any).parentNode; !href && parent; parent = parent.parentNode) { href = parent.childNodes[0].href; } - if (href && href.indexOf(DocServer.prepend("/doc/")) === 0) { - this._linkClicked = href.replace(DocServer.prepend("/doc/"), "").split("?")[0]; + if (href) { + if (href.indexOf(DocServer.prepend("/doc/")) === 0) { + let docid = href.replace(DocServer.prepend("/doc/"), "").split("?")[0]; + DocServer.GetRefField(docid).then(f => { + (f instanceof Doc) && DocumentManager.Instance.jumpToDocument(f, ctrlKey, document => this.props.addDocTab(document, "inTab")) + }); + } e.stopPropagation(); e.preventDefault(); } + } if (e.button === 2 || (e.button === 0 && e.ctrlKey)) { this._gotDown = true; @@ -254,14 +257,6 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe if (this._toolTipTextMenu && this._toolTipTextMenu.tooltip) { this._toolTipTextMenu.tooltip.style.opacity = "1"; } - let ctrlKey = e.ctrlKey; - if (this._linkClicked) { - DocServer.GetRefField(this._linkClicked).then(f => { - (f instanceof Doc) && DocumentManager.Instance.jumpToDocument(f, ctrlKey, document => this.props.addDocTab(document, "inTab")); - }); - e.stopPropagation(); - e.preventDefault(); - } if (e.buttons === 1 && this.props.isSelected() && !e.altKey) { e.stopPropagation(); } @@ -285,10 +280,6 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe onClick = (e: React.MouseEvent): void => { this._proseRef.current!.focus(); - if (this._linkClicked) { - e.preventDefault(); - e.stopPropagation(); - } } onMouseDown = (e: React.MouseEvent): void => { if (!this.props.isSelected()) { // preventing default allows the onClick to be generated instead of being swallowed by the text box itself @@ -372,6 +363,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe onPointerUp={this.onPointerUp} onPointerDown={this.onPointerDown} onMouseDown={this.onMouseDown} + onContextMenu={this.specificContextMenu} // tfs: do we need this event handler onWheel={this.onPointerWheel} onPointerEnter={this.onPointerEnter} -- cgit v1.2.3-70-g09d2 From 08134c962bab2cd62507415f1a67cd921069d8e3 Mon Sep 17 00:00:00 2001 From: ab Date: Fri, 7 Jun 2019 15:00:36 -0400 Subject: fixed marquee --- src/client/util/ProsemirrorKeymap.ts | 19 ++++++++++++- src/client/util/RichTextSchema.tsx | 17 ++++++++++++ src/client/util/TooltipTextMenu.scss | 6 +++-- src/client/util/TooltipTextMenu.tsx | 31 +++++++++++++++++++++- src/client/views/MainOverlayTextBox.tsx | 2 +- .../collections/collectionFreeForm/MarqueeView.tsx | 9 ++++--- 6 files changed, 76 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/client/util/ProsemirrorKeymap.ts b/src/client/util/ProsemirrorKeymap.ts index 71644cd88..89d01486e 100644 --- a/src/client/util/ProsemirrorKeymap.ts +++ b/src/client/util/ProsemirrorKeymap.ts @@ -1,4 +1,4 @@ -import { Schema } from "prosemirror-model"; +import { Schema, NodeType } from "prosemirror-model"; import { wrapIn, setBlockType, chainCommands, toggleMark, exitCode, joinUp, joinDown, lift, selectParentNode @@ -24,6 +24,22 @@ export default function buildKeymap>(schema: S, mapKeys?: keys[key] = cmd; } + function insertStar(state: EditorState, dispatch: ((tr: Transaction) => void)) { + console.log("creating star..."); + let type = schema.nodes.star as NodeType; + let { $from } = state.selection; + if (!$from.parent.canReplaceWith($from.index(), $from.index(), type)) { + return false; + } + if (dispatch) { + dispatch(state.tr.replaceSelectionWith(type.create())); + } + return true; + } + + console.log("star? hullo"); + bind("Mod-space", insertStar); + bind("Mod-z", undo); bind("Shift-Mod-z", redo); bind("Backspace", undoInputRule); @@ -79,6 +95,7 @@ export default function buildKeymap>(schema: S, mapKeys?: } if (type = schema.nodes.paragraph) { bind("Shift-Ctrl-0", setBlockType(type)); + bind("Mod-space", insertStar); } if (type = schema.nodes.code_block) { bind("Shift-Ctrl-\\", setBlockType(type)); diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index 3e3e98206..8fae821a5 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -26,6 +26,13 @@ export const nodes: { [index: string]: NodeSpec } = { toDOM() { return pDOM; } }, + star: { + inline: true, + group: "inline", + toDOM() { return ["star", "🟊"]; }, + parseDOM: [{ tag: "star" }] + }, + // :: NodeSpec A blockquote (`
`) wrapping one or more blocks. blockquote: { content: "block+", @@ -222,6 +229,15 @@ export const marks: { [index: string]: MarkSpec } = { toDOM: () => ['sup'] }, + collapse: { + parseDOM: [{ style: 'color: blue' }], + toDOM() { + return ['span', { + style: 'color: blue' + }] + } + }, + // :: MarkSpec Code font mark. Represented as a `` element. code: { @@ -280,6 +296,7 @@ export const marks: { [index: string]: MarkSpec } = { }] }, + /** FONT SIZES */ p10: { diff --git a/src/client/util/TooltipTextMenu.scss b/src/client/util/TooltipTextMenu.scss index e2862f093..0720a73a3 100644 --- a/src/client/util/TooltipTextMenu.scss +++ b/src/client/util/TooltipTextMenu.scss @@ -133,7 +133,7 @@ position: relative; min-height: 1em; color: white; - padding: 1px 6px; + padding: 10px 10px; top: 0; left: 0; right: 0; border-bottom: 1px solid silver; background:$dark-color; @@ -239,10 +239,12 @@ border: 1px solid silver; border-radius: 15px; padding: 2px 10px; - margin-bottom: 15px; + margin-bottom: 60px; -webkit-transform: translateX(-50%); transform: translateX(-50%); pointer-events: all; + height: 100px; + width:500px; .ProseMirror-example-setup-style hr { padding: 2px 10px; border: none; diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx index 7c5437510..1f1ad9cd4 100644 --- a/src/client/util/TooltipTextMenu.tsx +++ b/src/client/util/TooltipTextMenu.tsx @@ -22,12 +22,12 @@ import { throwStatement } from "babel-types"; import { View } from "@react-pdf/renderer"; import { DragManager } from "./DragManager"; import { Doc, Opt, Field } from "../../new_fields/Doc"; -import { Utils } from "../northstar/utils/Utils"; import { DocServer } from "../DocServer"; import { CollectionFreeFormDocumentView } from "../views/nodes/CollectionFreeFormDocumentView"; import { CollectionDockingView } from "../views/collections/CollectionDockingView"; import { DocumentManager } from "./DocumentManager"; import { Id } from "../../new_fields/FieldSymbols"; +import { Utils } from "../../Utils"; const SVG = "http://www.w3.org/2000/svg"; @@ -74,6 +74,7 @@ export class TooltipTextMenu { { command: toggleMark(schema.marks.strikethrough), dom: this.icon("S", "strikethrough", "Strikethrough") }, { command: toggleMark(schema.marks.superscript), dom: this.icon("s", "superscript", "Superscript") }, { command: toggleMark(schema.marks.subscript), dom: this.icon("s", "subscript", "Subscript") }, + { command: toggleMark(schema.marks.collapse), dom: this.icon("C", 'collapse', 'Collapse') } // { command: wrapInList(schema.nodes.bullet_list), dom: this.icon(":", "bullets") }, // { command: wrapInList(schema.nodes.ordered_list), dom: this.icon("1)", "bullets") }, // { command: lift, dom: this.icon("<", "lift") }, @@ -231,6 +232,15 @@ export class TooltipTextMenu { this.linkEditor.appendChild(this.linkText); this.linkEditor.appendChild(linkBtn); this.tooltip.appendChild(this.linkEditor); + + let starButton = document.createElement("button"); + starButton.textContent = "ST"; + starButton.onclick = () => { + let state = this.view.state; + this.insertStar(state, this.view.dispatch); + } + + this.tooltip.appendChild(starButton); } let node = this.view.state.selection.$from.nodeAfter; @@ -256,6 +266,19 @@ export class TooltipTextMenu { link = node && node.marks.find(m => m.type.name === "link"); } + insertStar(state: any, dispatch: any) { + console.log("creating star..."); + let type = schema.nodes.star; + let { $from } = state.selection; + if (!$from.parent.canReplaceWith($from.index(), $from.index(), type)) { + return false; + } + if (dispatch) { + dispatch(state.tr.replaceSelectionWith(type.create())); + } + return true; + } + //will display a remove-list-type button if selection is in list, otherwise will show list type dropdown updateListItemDropdown(label: string, listTypeBtn: Node) { //remove old btn @@ -426,6 +449,12 @@ export class TooltipTextMenu { this.tooltip.style.width = 225 + "px"; this.tooltip.style.bottom = (box.bottom - start.top) * this.editorProps.ScreenToLocalTransform().Scale + "px"; + this.tooltip.style.top = "-100px"; + //this.tooltip.style.height = "100px"; + + // let transform = this.editorProps.ScreenToLocalTransform(); + // this.tooltip.style.width = `${225 / transform.Scale}px`; + // Utils //UPDATE LIST ITEM DROPDOWN this.listTypeBtnDom = this.updateListItemDropdown(":", this.listTypeBtnDom!); diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx index 24327b995..d1224febe 100644 --- a/src/client/views/MainOverlayTextBox.tsx +++ b/src/client/views/MainOverlayTextBox.tsx @@ -102,6 +102,6 @@ export class MainOverlayTextBox extends React.Component ; } - else return (null); Z + else return (null); } } \ No newline at end of file diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 9ec941eff..563fbb186 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -45,12 +45,14 @@ export class MarqueeView extends React.Component _commandExecuted = false; @action - cleanupInteractions = (all: boolean = false) => { + cleanupInteractions = (all: boolean = false, rem_keydown: boolean = true) => { if (all) { document.removeEventListener("pointerup", this.onPointerUp, true); document.removeEventListener("pointermove", this.onPointerMove, true); } - document.removeEventListener("keydown", this.marqueeCommand, true); + if (rem_keydown) { + document.removeEventListener("keydown", this.marqueeCommand, true); + } this._visible = false; } @@ -180,6 +182,7 @@ export class MarqueeView extends React.Component @action onPointerUp = (e: PointerEvent): void => { + console.log("pointer up!"); if (this._visible) { let mselect = this.marqueeSelect(); if (!e.shiftKey) { @@ -187,7 +190,7 @@ export class MarqueeView extends React.Component } this.props.selectDocuments(mselect.length ? mselect : [this.props.container.props.Document]); } - this.cleanupInteractions(true); + this.cleanupInteractions(true, false); if (e.altKey) { e.preventDefault(); } -- cgit v1.2.3-70-g09d2 From ef24cc445aa466cae3b6c40029f7d7bc9baa81b7 Mon Sep 17 00:00:00 2001 From: ab Date: Fri, 7 Jun 2019 16:37:10 -0400 Subject: frustrated! --- src/client/util/ProsemirrorKeymap.ts | 17 --------------- src/client/util/TooltipTextMenu.scss | 11 +++++----- src/client/util/TooltipTextMenu.tsx | 24 +++++++++++++++------- .../collections/collectionFreeForm/MarqueeView.tsx | 9 +++++++- 4 files changed, 31 insertions(+), 30 deletions(-) (limited to 'src') diff --git a/src/client/util/ProsemirrorKeymap.ts b/src/client/util/ProsemirrorKeymap.ts index 89d01486e..cf656dc17 100644 --- a/src/client/util/ProsemirrorKeymap.ts +++ b/src/client/util/ProsemirrorKeymap.ts @@ -24,22 +24,6 @@ export default function buildKeymap>(schema: S, mapKeys?: keys[key] = cmd; } - function insertStar(state: EditorState, dispatch: ((tr: Transaction) => void)) { - console.log("creating star..."); - let type = schema.nodes.star as NodeType; - let { $from } = state.selection; - if (!$from.parent.canReplaceWith($from.index(), $from.index(), type)) { - return false; - } - if (dispatch) { - dispatch(state.tr.replaceSelectionWith(type.create())); - } - return true; - } - - console.log("star? hullo"); - bind("Mod-space", insertStar); - bind("Mod-z", undo); bind("Shift-Mod-z", redo); bind("Backspace", undoInputRule); @@ -95,7 +79,6 @@ export default function buildKeymap>(schema: S, mapKeys?: } if (type = schema.nodes.paragraph) { bind("Shift-Ctrl-0", setBlockType(type)); - bind("Mod-space", insertStar); } if (type = schema.nodes.code_block) { bind("Shift-Ctrl-\\", setBlockType(type)); diff --git a/src/client/util/TooltipTextMenu.scss b/src/client/util/TooltipTextMenu.scss index 0720a73a3..0099c1e4d 100644 --- a/src/client/util/TooltipTextMenu.scss +++ b/src/client/util/TooltipTextMenu.scss @@ -239,12 +239,13 @@ border: 1px solid silver; border-radius: 15px; padding: 2px 10px; - margin-bottom: 60px; - -webkit-transform: translateX(-50%); - transform: translateX(-50%); + //margin-bottom: 100px; + //-webkit-transform: translateX(-50%); + //transform: translateX(-50%); + transform: translateY(-50%); pointer-events: all; - height: 100px; - width:500px; + height: 125px; + width:400px; .ProseMirror-example-setup-style hr { padding: 2px 10px; border: none; diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx index 1f1ad9cd4..366105ad9 100644 --- a/src/client/util/TooltipTextMenu.tsx +++ b/src/client/util/TooltipTextMenu.tsx @@ -234,7 +234,12 @@ export class TooltipTextMenu { this.tooltip.appendChild(this.linkEditor); let starButton = document.createElement("button"); - starButton.textContent = "ST"; + // starButton.style.width = '10px'; + // starButton.style.height = '10px'; + starButton.style.marginLeft = '10px'; + starButton.textContent = "Summarize"; + starButton.style.color = 'black'; + starButton.style.backgroundColor = 'white'; starButton.onclick = () => { let state = this.view.state; this.insertStar(state, this.view.dispatch); @@ -266,16 +271,21 @@ export class TooltipTextMenu { link = node && node.marks.find(m => m.type.name === "link"); } - insertStar(state: any, dispatch: any) { + insertStar(state: EditorState, dispatch: any) { console.log("creating star..."); let type = schema.nodes.star; - let { $from } = state.selection; - if (!$from.parent.canReplaceWith($from.index(), $from.index(), type)) { - return false; - } + //let {$from} = state.selection; + let select = state.selection; if (dispatch) { - dispatch(state.tr.replaceSelectionWith(type.create())); + dispatch(state.tr.setMeta('select.visible', false)); } + // console.log($from); + // if (!$from.parent.canReplaceWith($from.index(), $from.index(), type)) { + // return false; + // } + // if (dispatch) { + // dispatch(state.tr.replaceSelectionWith(type.create())); + // } return true; } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index 563fbb186..6b81cc597 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -147,6 +147,7 @@ export class MarqueeView extends React.Component this._downY = this._lastY = e.pageY; this._commandExecuted = false; PreviewCursor.Visible = false; + this.cleanupInteractions(true); if (e.button === 2 || (e.button === 0 && e.altKey)) { if (!this.props.container.props.active()) this.props.selectDocuments([this.props.container.props.Document]); document.addEventListener("pointermove", this.onPointerMove, true); @@ -184,13 +185,19 @@ export class MarqueeView extends React.Component onPointerUp = (e: PointerEvent): void => { console.log("pointer up!"); if (this._visible) { + console.log("visible"); let mselect = this.marqueeSelect(); if (!e.shiftKey) { SelectionManager.DeselectAll(mselect.length ? undefined : this.props.container.props.Document); } this.props.selectDocuments(mselect.length ? mselect : [this.props.container.props.Document]); + mselect.length ? this.cleanupInteractions(true, false) : this.cleanupInteractions(true); } - this.cleanupInteractions(true, false); + else { + console.log("invisible"); + this.cleanupInteractions(true); + } + if (e.altKey) { e.preventDefault(); } -- cgit v1.2.3-70-g09d2 From bf73b629c78d0db0b8d4bcf6aadd6609b3fe1689 Mon Sep 17 00:00:00 2001 From: ab Date: Tue, 11 Jun 2019 12:02:00 -0400 Subject: star node, trying to set selection as its attribute for copy/paste like behavior --- src/client/util/RichTextSchema.tsx | 13 +++++++++++++ src/client/util/TooltipTextMenu.tsx | 23 ++++++++++++----------- src/client/views/nodes/FormattedTextBox.tsx | 6 ++++-- 3 files changed, 29 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index 8fae821a5..a29036f19 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -28,6 +28,7 @@ export const nodes: { [index: string]: NodeSpec } = { star: { inline: true, + attrs: { oldtext: { default: "suhhhh" } }, group: "inline", toDOM() { return ["star", "🟊"]; }, parseDOM: [{ tag: "star" }] @@ -424,6 +425,18 @@ export class ImageResizeView { this._handle.style.display = "none"; } } + +export class SummarizedView { + _collapsed: HTMLElement; + _selection: any; + constructor(node: any) { + this._collapsed = document.createElement("star"); + this._collapsed.onpointerdown = function (e: any) { + console.log("star pressed!"); + }; + + } +} // :: Schema // This schema rougly corresponds to the document schema used by // [CommonMark](http://commonmark.org/), minus the list elements, diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx index 366105ad9..c5d016547 100644 --- a/src/client/util/TooltipTextMenu.tsx +++ b/src/client/util/TooltipTextMenu.tsx @@ -1,6 +1,6 @@ import { action, IReactionDisposer, reaction } from "mobx"; import { Dropdown, DropdownSubmenu, MenuItem, MenuItemSpec, renderGrouped, icons, } from "prosemirror-menu"; //no import css -import { baseKeymap, lift } from "prosemirror-commands"; +import { baseKeymap, lift, deleteSelection } from "prosemirror-commands"; import { history, redo, undo } from "prosemirror-history"; import { keymap } from "prosemirror-keymap"; import { EditorState, Transaction, NodeSelection, TextSelection } from "prosemirror-state"; @@ -28,6 +28,7 @@ import { CollectionDockingView } from "../views/collections/CollectionDockingVie import { DocumentManager } from "./DocumentManager"; import { Id } from "../../new_fields/FieldSymbols"; import { Utils } from "../../Utils"; +// import { wrap } from "module"; const SVG = "http://www.w3.org/2000/svg"; @@ -74,7 +75,7 @@ export class TooltipTextMenu { { command: toggleMark(schema.marks.strikethrough), dom: this.icon("S", "strikethrough", "Strikethrough") }, { command: toggleMark(schema.marks.superscript), dom: this.icon("s", "superscript", "Superscript") }, { command: toggleMark(schema.marks.subscript), dom: this.icon("s", "subscript", "Subscript") }, - { command: toggleMark(schema.marks.collapse), dom: this.icon("C", 'collapse', 'Collapse') } + { command: deleteSelection, dom: this.icon("C", 'collapse', 'Collapse') } // { command: wrapInList(schema.nodes.bullet_list), dom: this.icon(":", "bullets") }, // { command: wrapInList(schema.nodes.ordered_list), dom: this.icon("1)", "bullets") }, // { command: lift, dom: this.icon("<", "lift") }, @@ -274,18 +275,18 @@ export class TooltipTextMenu { insertStar(state: EditorState, dispatch: any) { console.log("creating star..."); let type = schema.nodes.star; - //let {$from} = state.selection; let select = state.selection; + let node = select.$from.nodeAfter; + if (node) { + console.log("node"); + console.log(node.type.name); + if (node.type.name === "star") { + console.log(node.attrs.oldtext); + } + } if (dispatch) { - dispatch(state.tr.setMeta('select.visible', false)); + dispatch(state.tr.replaceSelectionWith(type.create({ attrs: { oldtext: select } }))); } - // console.log($from); - // if (!$from.parent.canReplaceWith($from.index(), $from.index(), type)) { - // return false; - // } - // if (dispatch) { - // dispatch(state.tr.replaceSelectionWith(type.create())); - // } return true; } diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 5c635cc0c..b40c6d580 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -16,7 +16,7 @@ import { DocumentManager } from "../../util/DocumentManager"; import { DragManager } from "../../util/DragManager"; import buildKeymap from "../../util/ProsemirrorKeymap"; import { inpRules } from "../../util/RichTextRules"; -import { ImageResizeView, schema } from "../../util/RichTextSchema"; +import { SummarizedView, ImageResizeView, schema } from "../../util/RichTextSchema"; import { SelectionManager } from "../../util/SelectionManager"; import { TooltipLinkingMenu } from "../../util/TooltipLinkingMenu"; import { TooltipTextMenu } from "../../util/TooltipTextMenu"; @@ -29,6 +29,7 @@ import { FieldView, FieldViewProps } from "./FieldView"; import "./FormattedTextBox.scss"; import React = require("react"); import { DocUtils } from '../../documents/Documents'; +import { start } from 'repl'; library.add(faEdit); library.add(faSmile); @@ -189,7 +190,8 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe state: field && field.Data ? EditorState.fromJSON(config, JSON.parse(field.Data)) : EditorState.create(config), dispatchTransaction: this.dispatchTransaction, nodeViews: { - image(node, view, getPos) { return new ImageResizeView(node, view, getPos); } + image(node, view, getPos) { return new ImageResizeView(node, view, getPos); }, + //star(node, view, getPos) { return new SummarizedView(node); } } }); let text = StrCast(this.props.Document.documentText); -- cgit v1.2.3-70-g09d2 From 366ac7e434be306ffd979d7f22ef50ad77fbc1eb Mon Sep 17 00:00:00 2001 From: ab Date: Tue, 11 Jun 2019 14:13:22 -0400 Subject: lolz --- src/client/util/TooltipTextMenu.tsx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx index c5d016547..905f1969c 100644 --- a/src/client/util/TooltipTextMenu.tsx +++ b/src/client/util/TooltipTextMenu.tsx @@ -278,14 +278,18 @@ export class TooltipTextMenu { let select = state.selection; let node = select.$from.nodeAfter; if (node) { - console.log("node"); - console.log(node.type.name); if (node.type.name === "star") { - console.log(node.attrs.oldtext); + let oldselection = node.attrs.oldtext; + if (dispatch) { + dispatch(state.tr.replaceSelection(oldselection.content())); + } + return true; } } if (dispatch) { - dispatch(state.tr.replaceSelectionWith(type.create({ attrs: { oldtext: select } }))); + let newNode = type.create(); + newNode.attrs.oldtext = select; + dispatch(state.tr.replaceSelectionWith(newNode)); } return true; } -- cgit v1.2.3-70-g09d2 From fcae0da16f9413059d03638ba10ab30cdc460a42 Mon Sep 17 00:00:00 2001 From: bob Date: Tue, 11 Jun 2019 16:45:48 -0400 Subject: fixed text input to allow typing from the bottom (caption) and to allow text boxes to grow vertically (autoHeight) --- src/client/documents/Documents.ts | 2 +- src/client/views/DocumentDecorations.tsx | 7 +++--- src/client/views/MainOverlayTextBox.tsx | 22 ++++++++++++------ .../collectionFreeForm/CollectionFreeFormView.scss | 1 + .../collections/collectionFreeForm/MarqueeView.tsx | 3 ++- src/client/views/nodes/DocumentView.tsx | 8 +++---- src/client/views/nodes/FormattedTextBox.tsx | 27 +++++++++++++++++++--- 7 files changed, 51 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 2ae127e21..b1df89dbd 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -166,7 +166,7 @@ export namespace Docs { } function CreateTextPrototype(): Doc { let textProto = setupPrototypeOptions(textProtoId, "TEXT_PROTO", FormattedTextBox.LayoutString(), - { x: 0, y: 0, width: 300, height: 150, backgroundColor: "#f1efeb" }); + { x: 0, y: 0, width: 300, backgroundColor: "#f1efeb" }); return textProto; } function CreatePdfPrototype(): Doc { diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 7260b00cf..1111cd2f5 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -442,11 +442,11 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> let actualdH = Math.max(height + (dH * scale), 20); doc.x = (doc.x || 0) + dX * (actualdW - width); doc.y = (doc.y || 0) + dY * (actualdH - height); - let proto = Doc.GetProto(doc); + let proto = Doc.GetProto(element.props.Document); let fixedAspect = e.ctrlKey || (!BoolCast(proto.ignoreAspect, false) && nwidth && nheight); if (fixedAspect && (!nwidth || !nheight)) { - proto.nativeWidth = doc.width; - proto.nativeHeight = doc.height; + proto.nativeWidth = nwidth = doc.width || 0; + proto.nativeHeight = nheight = doc.height || 0; proto.ignoreAspect = true; } if (nwidth > 0 && nheight > 0) { @@ -469,6 +469,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> } else { doc.width = zoomBasis * actualdW; doc.height = zoomBasis * actualdH; + proto.autoHeight = undefined; } } }); diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx index a0359419b..afa72d56e 100644 --- a/src/client/views/MainOverlayTextBox.tsx +++ b/src/client/views/MainOverlayTextBox.tsx @@ -9,6 +9,8 @@ import "./MainOverlayTextBox.scss"; import { FormattedTextBox } from './nodes/FormattedTextBox'; import { CollectionDockingView } from './collections/CollectionDockingView'; import { Doc } from '../../new_fields/Doc'; +import { BoolCast } from '../../new_fields/Types'; +import { auto } from 'async'; interface MainOverlayTextBoxProps { } @@ -22,6 +24,7 @@ export class MainOverlayTextBox extends React.Component private _textHideOnLeave?: boolean; private _textTargetDiv: HTMLDivElement | undefined; private _textProxyDiv: React.RefObject; + private _textBottom: boolean | undefined; public TextDoc?: Doc; constructor(props: MainOverlayTextBoxProps) { @@ -49,10 +52,12 @@ export class MainOverlayTextBox extends React.Component this._textTargetDiv.style.color = this._textColor; } this.TextFieldKey = textFieldKey!; - this._textXf = tx ? tx : () => Transform.Identity(); + let txf = tx ? tx : () => Transform.Identity(); + this._textXf = txf; this._textTargetDiv = div; this._textHideOnLeave = FormattedTextBox.InputBoxOverlay && FormattedTextBox.InputBoxOverlay.props.hideOnLeave; if (div) { + this._textBottom = textFieldKey === "caption" ? true : false; // (getComputedStyle(div) as any).bottom; this._textColor = (getComputedStyle(div) as any).color; div.style.color = "transparent"; } @@ -102,13 +107,16 @@ export class MainOverlayTextBox extends React.Component if (FormattedTextBox.InputBoxOverlay && this._textTargetDiv) { let textRect = this._textTargetDiv.getBoundingClientRect(); let s = this._textXf().Scale; - let auto = FormattedTextBox.InputBoxOverlay.props.height; - return
+ let bottom = this._textBottom ? textRect.bottom : textRect.top; + let hgt = 0; + return
- + style={{ width: `${textRect.width * s}px`, height: hgt }}> +
+ +
; } diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss index e10ba9d7e..5ac2e1f9c 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.scss @@ -57,6 +57,7 @@ } >.jsx-parser { + position:absolute; z-index:0; } diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx index c699b3437..01bbbba4c 100644 --- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx +++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx @@ -93,7 +93,8 @@ export class MarqueeView extends React.Component } }); } else if (!e.ctrlKey) { - let newBox = Docs.TextDocument({ width: 200, height: 100, x: x, y: y, title: "-typed text-" }); + let newBox = Docs.TextDocument({ width: 200, height: 30, x: x, y: y, title: "-typed text-" }); + newBox.proto!.autoHeight = true; this.props.addLiveTextDocument(newBox); } e.stopPropagation(); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 19f5c7d36..2428103d1 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -317,13 +317,13 @@ export class DocumentView extends DocComponent(Docu makeBtnClicked = (): void => { let doc = Doc.GetProto(this.props.Document); doc.isButton = !BoolCast(doc.isButton, false); - if (StrCast(doc.layout).indexOf("Formatted") !== -1) { // only need to freeze the dimensions of text boxes since they don't have a native width and height naturally - if (doc.isButton && !doc.nativeWidth) { + if (doc.isButton) { + if (!doc.nativeWidth) { doc.nativeWidth = this.props.Document[WidthSym](); doc.nativeHeight = this.props.Document[HeightSym](); - } else { - doc.nativeWidth = doc.nativeHeight = undefined; } + } else { + doc.nativeWidth = doc.nativeHeight = undefined; } } fullScreenClicked = (): void => { diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 2923fd378..20e175031 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -10,7 +10,7 @@ import { EditorView } from "prosemirror-view"; import { Doc, Opt } from "../../../new_fields/Doc"; import { RichTextField } from "../../../new_fields/RichTextField"; import { createSchema, makeInterface } from "../../../new_fields/Schema"; -import { Cast, NumCast, StrCast } from "../../../new_fields/Types"; +import { Cast, NumCast, StrCast, BoolCast } from "../../../new_fields/Types"; import { DocServer } from "../../DocServer"; import { DocUtils, Docs } from '../../documents/Documents'; import { DocumentManager } from "../../util/DocumentManager"; @@ -29,6 +29,9 @@ import "./FormattedTextBox.scss"; import React = require("react"); import { Id } from '../../../new_fields/FieldSymbols'; import { MainOverlayTextBox } from '../MainOverlayTextBox'; +import { Utils } from '../../../Utils'; +import { ContextMenuProps } from '../ContextMenuItem'; +import { ContextMenu } from '../ContextMenu'; library.add(faEdit); library.add(faSmile); @@ -212,8 +215,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe } if (this.props.selectOnLoad) { - console.log("Sel on load " + this.props.Document.title + " " + doc!.title); - this.props.select(false); + //this.props.select(false); this._editorView!.focus(); } } @@ -351,6 +353,15 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe if (!this._undoTyping) { this._undoTyping = UndoManager.StartBatch("undoTyping"); } + if (this.props.isOverlay && this.props.Document.autoHeight) { + let xf = this._ref.current!.getBoundingClientRect(); + let scrBounds = this.props.ScreenToLocalTransform().transformBounds(0, 0, xf.width, xf.height); + let nh = NumCast(this.props.Document.nativeHeight, 0); + let dh = NumCast(this.props.Document.height, 0); + let sh = scrBounds.height; + this.props.Document.height = nh ? dh / nh * sh : sh; + this.props.Document.proto!.nativeHeight = nh ? sh : undefined; + } } @action @@ -361,6 +372,15 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe onPointerLeave = (e: React.PointerEvent) => { this._entered = false; } + + specificContextMenu = (e: React.MouseEvent): void => { + let subitems: ContextMenuProps[] = []; + subitems.push({ + description: BoolCast(this.props.Document.autoHeight, false) ? "Manual Height" : "Auto Height", + event: action(() => this.props.Document.autoHeight = !BoolCast(this.props.Document.autoHeight, false)), icon: "expand-arrows-alt" + }); + ContextMenu.Instance.addItem({ description: "Text Funcs...", subitems: subitems }); + } render() { let style = this.props.isOverlay ? "scroll" : "hidden"; let rounded = NumCast(this.props.Document.borderRounding) < 0 ? "-rounded" : ""; @@ -378,6 +398,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe onKeyPress={this.onKeyPress} onFocus={this.onFocused} onClick={this.onClick} + onContextMenu={this.specificContextMenu} onBlur={this.onBlur} onPointerUp={this.onPointerUp} onPointerDown={this.onPointerDown} -- cgit v1.2.3-70-g09d2 From b0390a9d3e9201a16e06cf46196688026f949d9f Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 11 Jun 2019 22:01:53 -0400 Subject: fixed issues with text box overlay and templates --- src/client/views/MainOverlayTextBox.tsx | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx index afa72d56e..1b35fd40e 100644 --- a/src/client/views/MainOverlayTextBox.tsx +++ b/src/client/views/MainOverlayTextBox.tsx @@ -10,7 +10,6 @@ import { FormattedTextBox } from './nodes/FormattedTextBox'; import { CollectionDockingView } from './collections/CollectionDockingView'; import { Doc } from '../../new_fields/Doc'; import { BoolCast } from '../../new_fields/Types'; -import { auto } from 'async'; interface MainOverlayTextBoxProps { } @@ -25,6 +24,7 @@ export class MainOverlayTextBox extends React.Component private _textTargetDiv: HTMLDivElement | undefined; private _textProxyDiv: React.RefObject; private _textBottom: boolean | undefined; + private _textAutoHeight: boolean | undefined; public TextDoc?: Doc; constructor(props: MainOverlayTextBoxProps) { @@ -37,7 +37,7 @@ export class MainOverlayTextBox extends React.Component this.TextDoc = box.props.Document; let sxf = Utils.GetScreenTransform(box ? box.CurrentDiv : undefined); let xf = () => { box.props.ScreenToLocalTransform(); return new Transform(-sxf.translateX, -sxf.translateY, 1 / sxf.scale); }; - this.setTextDoc(box.props.fieldKey, box.CurrentDiv, xf) + this.setTextDoc(box.props.fieldKey, box.CurrentDiv, xf, BoolCast(box.props.Document.autoHeight, false) || box.props.height === "min-content") } else { this.TextDoc = undefined; @@ -47,17 +47,18 @@ export class MainOverlayTextBox extends React.Component } @action - private setTextDoc(textFieldKey?: string, div?: HTMLDivElement, tx?: () => Transform) { + private setTextDoc(textFieldKey?: string, div?: HTMLDivElement, tx?: () => Transform, autoHeight?: boolean) { if (this._textTargetDiv) { this._textTargetDiv.style.color = this._textColor; } + this._textAutoHeight = autoHeight; this.TextFieldKey = textFieldKey!; let txf = tx ? tx : () => Transform.Identity(); this._textXf = txf; this._textTargetDiv = div; this._textHideOnLeave = FormattedTextBox.InputBoxOverlay && FormattedTextBox.InputBoxOverlay.props.hideOnLeave; if (div) { - this._textBottom = textFieldKey === "caption" ? true : false; // (getComputedStyle(div) as any).bottom; + this._textBottom = div.parentElement && div.parentElement.style.bottom ? true : false; this._textColor = (getComputedStyle(div) as any).color; div.style.color = "transparent"; } @@ -107,12 +108,12 @@ export class MainOverlayTextBox extends React.Component if (FormattedTextBox.InputBoxOverlay && this._textTargetDiv) { let textRect = this._textTargetDiv.getBoundingClientRect(); let s = this._textXf().Scale; - let bottom = this._textBottom ? textRect.bottom : textRect.top; - let hgt = 0; - return
+ let location = this._textBottom ? textRect.bottom : textRect.top; + let hgt = this._textAutoHeight || this._textBottom ? "auto" : this._textTargetDiv.clientHeight; + return
-
+ style={{ width: `${textRect.width * s}px`, height: "0px" }}> +
-- cgit v1.2.3-70-g09d2 From a7cb61db19c3e34dcf3c91152c04d4aea2980682 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 12 Jun 2019 03:00:59 -0400 Subject: prototyep working version of elision -- however, it doesn't work once the text box is deselected/reloaded. didn't look into why --- src/client/util/RichTextSchema.tsx | 64 +++++++++++++++++++++++------ src/client/util/TooltipTextMenu.tsx | 18 ++------ src/client/views/nodes/FormattedTextBox.tsx | 2 +- 3 files changed, 57 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index a29036f19..84c2fd5c3 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -1,9 +1,9 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Schema, NodeSpec, MarkSpec, DOMOutputSpecArray, NodeType } from "prosemirror-model"; -import { joinUp, lift, setBlockType, toggleMark, wrapIn } from 'prosemirror-commands'; +import { joinUp, lift, setBlockType, toggleMark, wrapIn, selectNodeForward, deleteSelection } from 'prosemirror-commands'; import { redo, undo } from 'prosemirror-history'; import { orderedList, bulletList, listItem, } from 'prosemirror-schema-list'; -import { EditorState, Transaction, NodeSelection, } from "prosemirror-state"; +import { EditorState, Transaction, NodeSelection, TextSelection, Selection, } from "prosemirror-state"; import { EditorView, } from "prosemirror-view"; const pDOM: DOMOutputSpecArray = ["p", 0], blockquoteDOM: DOMOutputSpecArray = ["blockquote", 0], hrDOM: DOMOutputSpecArray = ["hr"], @@ -26,13 +26,6 @@ export const nodes: { [index: string]: NodeSpec } = { toDOM() { return pDOM; } }, - star: { - inline: true, - attrs: { oldtext: { default: "suhhhh" } }, - group: "inline", - toDOM() { return ["star", "🟊"]; }, - parseDOM: [{ tag: "star" }] - }, // :: NodeSpec A blockquote (`
`) wrapping one or more blocks. blockquote: { @@ -85,6 +78,29 @@ export const nodes: { [index: string]: NodeSpec } = { group: "inline" }, + star: { + inline: true, + attrs: { + visibility: { default: false }, + oldtext: { default: undefined }, + oldtextlen: { default: 0 } + + }, + group: "inline", + toDOM(node) { + const attrs = { style: `width: 40px` }; + return ["span", { ...node.attrs, ...attrs }]; + }, + parseDOM: [{ + tag: "span", getAttrs(dom: any) { + return { + visibility: dom.getAttribute("visibility"), + oldtext: dom.getAttribute("oldtext"), + oldtextlen: dom.getAttribute("oldtextlen"), + } + } + }] + }, // :: NodeSpec An inline image (``) node. Supports `src`, // `alt`, and `href` attributes. The latter two default to the empty // string. @@ -428,13 +444,37 @@ export class ImageResizeView { export class SummarizedView { _collapsed: HTMLElement; - _selection: any; - constructor(node: any) { - this._collapsed = document.createElement("star"); + constructor(node: any, view: any, getPos: any) { + this._collapsed = document.createElement("span"); + this._collapsed.textContent = "..."; + this._collapsed.style.opacity = "0.5"; + this._collapsed.style.background = "yellow"; + this._collapsed.style.position = "relative"; + this._collapsed.style.width = "40px"; + this._collapsed.style.height = "20px"; this._collapsed.onpointerdown = function (e: any) { console.log("star pressed!"); + if (node.attrs.visibility) { + let y = getPos(); + view.dispatch(view.state.tr.setSelection(TextSelection.create(view.state.doc, y + 1, y + 1 + node.attrs.oldtextlen))); + view.dispatch(view.state.tr.deleteSelection(view.state, () => { })); + + } else { + let y = getPos(); + view.dispatch(view.state.tr.setSelection(TextSelection.create(view.state.doc, y + 1, y + 1))); + view.dispatch(view.state.tr.replaceSelection(node.attrs.oldtext)); + } + node.attrs.visibility = !node.attrs.visibility; + e.preventDefault(); + e.stopPropagation(); }; + (this as any).dom = this._collapsed; + + } + selectNode() { + } + deselectNode() { } } // :: Schema diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx index 905f1969c..6cc71be39 100644 --- a/src/client/util/TooltipTextMenu.tsx +++ b/src/client/util/TooltipTextMenu.tsx @@ -274,21 +274,11 @@ export class TooltipTextMenu { insertStar(state: EditorState, dispatch: any) { console.log("creating star..."); - let type = schema.nodes.star; - let select = state.selection; - let node = select.$from.nodeAfter; - if (node) { - if (node.type.name === "star") { - let oldselection = node.attrs.oldtext; - if (dispatch) { - dispatch(state.tr.replaceSelection(oldselection.content())); - } - return true; - } - } + let newNode = schema.nodes.star.create(); if (dispatch) { - let newNode = type.create(); - newNode.attrs.oldtext = select; + newNode.attrs.visibility = false; + newNode.attrs.oldtext = state.selection.content(); + newNode.attrs.oldtextlen = state.selection.to - state.selection.from; dispatch(state.tr.replaceSelectionWith(newNode)); } return true; diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index b40c6d580..3ba108a57 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -191,7 +191,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe dispatchTransaction: this.dispatchTransaction, nodeViews: { image(node, view, getPos) { return new ImageResizeView(node, view, getPos); }, - //star(node, view, getPos) { return new SummarizedView(node); } + star(node, view, getPos) { return new SummarizedView(node, view, getPos); } } }); let text = StrCast(this.props.Document.documentText); -- cgit v1.2.3-70-g09d2 From a638c12cde39a3ea5193a8038f72a55d706d9af8 Mon Sep 17 00:00:00 2001 From: bob Date: Wed, 12 Jun 2019 10:32:45 -0400 Subject: a bunch of cleanup and fixes to formattedtextbox & mainoverlaytextbox --- src/client/util/SelectionManager.ts | 8 +-- src/client/views/MainOverlayTextBox.tsx | 16 +++--- src/client/views/collections/CollectionSubView.tsx | 2 +- src/client/views/nodes/DocumentView.tsx | 7 +-- src/client/views/nodes/FormattedTextBox.tsx | 60 +++++----------------- 5 files changed, 28 insertions(+), 65 deletions(-) (limited to 'src') diff --git a/src/client/util/SelectionManager.ts b/src/client/util/SelectionManager.ts index b26032b04..09bccb1a0 100644 --- a/src/client/util/SelectionManager.ts +++ b/src/client/util/SelectionManager.ts @@ -12,11 +12,11 @@ export namespace SelectionManager { @action SelectDoc(docView: DocumentView, ctrlPressed: boolean): void { // if doc is not in SelectedDocuments, add it - if (!ctrlPressed) { - this.DeselectAll(); - } - if (manager.SelectedDocuments.indexOf(docView) === -1) { + if (!ctrlPressed) { + this.DeselectAll(); + } + manager.SelectedDocuments.push(docView); docView.props.whenActiveChanged(true); } diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx index 1b35fd40e..23e90ece5 100644 --- a/src/client/views/MainOverlayTextBox.tsx +++ b/src/client/views/MainOverlayTextBox.tsx @@ -1,15 +1,15 @@ import { action, observable, reaction } from 'mobx'; import { observer } from 'mobx-react'; +import "normalize.css"; import * as React from 'react'; +import { Doc } from '../../new_fields/Doc'; +import { BoolCast } from '../../new_fields/Types'; import { emptyFunction, returnTrue, returnZero, Utils } from '../../Utils'; import { DragManager } from '../util/DragManager'; import { Transform } from '../util/Transform'; -import "normalize.css"; +import { CollectionDockingView } from './collections/CollectionDockingView'; import "./MainOverlayTextBox.scss"; import { FormattedTextBox } from './nodes/FormattedTextBox'; -import { CollectionDockingView } from './collections/CollectionDockingView'; -import { Doc } from '../../new_fields/Doc'; -import { BoolCast } from '../../new_fields/Types'; interface MainOverlayTextBoxProps { } @@ -25,7 +25,7 @@ export class MainOverlayTextBox extends React.Component private _textProxyDiv: React.RefObject; private _textBottom: boolean | undefined; private _textAutoHeight: boolean | undefined; - public TextDoc?: Doc; + @observable public TextDoc?: Doc; constructor(props: MainOverlayTextBoxProps) { super(props); @@ -105,6 +105,7 @@ export class MainOverlayTextBox extends React.Component } } render() { + this.TextDoc; if (FormattedTextBox.InputBoxOverlay && this._textTargetDiv) { let textRect = this._textTargetDiv.getBoundingClientRect(); let s = this._textXf().Scale; @@ -114,8 +115,9 @@ export class MainOverlayTextBox extends React.Component
-
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx index 762955a08..93a1a8cda 100644 --- a/src/client/views/collections/CollectionSubView.tsx +++ b/src/client/views/collections/CollectionSubView.tsx @@ -170,7 +170,7 @@ export function CollectionSubView(schemaCtor: (doc: Doc) => T) { this.props.addDocument && this.props.addDocument(Docs.WebDocument(href, options)); } } else if (text) { - this.props.addDocument && this.props.addDocument(Docs.TextDocument({ ...options, documentText: "@@@" + text }), false); + this.props.addDocument && this.props.addDocument(Docs.TextDocument({ ...options, width: 100, height: 25, documentText: "@@@" + text }), false); } return; } diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 2428103d1..051940cc4 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -125,10 +125,8 @@ export class DocumentView extends DocComponent(Docu constructor(props: DocumentViewProps) { super(props); - this.selectOnLoad = props.selectOnLoad; } - _reactionDisposer?: IReactionDisposer; @action componentDidMount() { @@ -442,14 +440,13 @@ export class DocumentView extends DocComponent(Docu onPointerLeave = (e: React.PointerEvent): void => { this.props.Document.libraryBrush = false; }; isSelected = () => SelectionManager.IsSelected(this); - @action select = (ctrlPressed: boolean) => { this.selectOnLoad = false; SelectionManager.SelectDoc(this, ctrlPressed); } + @action select = (ctrlPressed: boolean) => { SelectionManager.SelectDoc(this, ctrlPressed); } - @observable selectOnLoad: boolean = false; @computed get nativeWidth() { return this.Document.nativeWidth || 0; } @computed get nativeHeight() { return this.Document.nativeHeight || 0; } @computed get contents() { return ( - ); + ); } render() { diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 20e175031..6a51db4ac 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -8,11 +8,12 @@ import { keymap } from "prosemirror-keymap"; import { EditorState, Plugin, Transaction } from "prosemirror-state"; import { EditorView } from "prosemirror-view"; import { Doc, Opt } from "../../../new_fields/Doc"; +import { Id } from '../../../new_fields/FieldSymbols'; import { RichTextField } from "../../../new_fields/RichTextField"; import { createSchema, makeInterface } from "../../../new_fields/Schema"; -import { Cast, NumCast, StrCast, BoolCast } from "../../../new_fields/Types"; +import { BoolCast, Cast, NumCast, StrCast } from "../../../new_fields/Types"; import { DocServer } from "../../DocServer"; -import { DocUtils, Docs } from '../../documents/Documents'; +import { Docs } from '../../documents/Documents'; import { DocumentManager } from "../../util/DocumentManager"; import { DragManager } from "../../util/DragManager"; import buildKeymap from "../../util/ProsemirrorKeymap"; @@ -21,37 +22,20 @@ import { ImageResizeView, schema } from "../../util/RichTextSchema"; import { SelectionManager } from "../../util/SelectionManager"; import { TooltipLinkingMenu } from "../../util/TooltipLinkingMenu"; import { TooltipTextMenu } from "../../util/TooltipTextMenu"; -import { undoBatch, UndoManager } from "../../util/UndoManager"; +import { UndoManager } from "../../util/UndoManager"; +import { ContextMenu } from '../ContextMenu'; +import { ContextMenuProps } from '../ContextMenuItem'; import { DocComponent } from "../DocComponent"; import { InkingControl } from "../InkingControl"; import { FieldView, FieldViewProps } from "./FieldView"; import "./FormattedTextBox.scss"; import React = require("react"); -import { Id } from '../../../new_fields/FieldSymbols'; -import { MainOverlayTextBox } from '../MainOverlayTextBox'; -import { Utils } from '../../../Utils'; -import { ContextMenuProps } from '../ContextMenuItem'; -import { ContextMenu } from '../ContextMenu'; library.add(faEdit); library.add(faSmile); // FormattedTextBox: Displays an editable plain text node that maps to a specified Key of a Document // -// HTML Markup: Key} />"); -// and the node's binding to the specified document KEYNAME as: -// document.SetField(KeyStore.LayoutKeys, new ListField([KeyStore.])); -// The Jsx parser at run time will bind: -// 'fieldKey' property to the Key stored in LayoutKeys -// and 'doc' property to the document that is being rendered -// -// When rendered() by React, this extracts the TextController from the Document stored at the -// specified Key and assigns it to an HTML input node. When changes are made to this node, -// this will edit the document and assign the new value to that field. -//] export interface FormattedTextBoxProps { isOverlay?: boolean; @@ -76,11 +60,9 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe private _proseRef: React.RefObject; private _editorView: Opt; private _toolTipTextMenu: TooltipTextMenu | undefined = undefined; - private _lastState: any = undefined; private _applyingChange: boolean = false; private _linkClicked = ""; private _reactionDisposer: Opt; - private _inputReactionDisposer: Opt; private _proxyReactionDisposer: Opt; public get CurrentDiv(): HTMLDivElement { return this._ref.current!; } @observable _entered = false; @@ -119,10 +101,9 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe } } - dispatchTransaction = (tx: Transaction) => { if (this._editorView) { - const state = this._lastState = this._editorView.state.apply(tx); + const state = this._editorView.state.apply(tx); this._editorView.updateState(state); this._applyingChange = true; Doc.SetOnPrototype(this.props.Document, this.props.fieldKey, new RichTextField(JSON.stringify(state.toJSON()))); @@ -160,18 +141,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe ] }; - if (this.props.isOverlay) { - this._inputReactionDisposer = reaction(() => FormattedTextBox.InputBoxOverlay, - () => { - if (this._editorView) { - this._editorView.destroy(); - } - this.setupEditor(config, // bcz: not sure why, but the order of events is such that this.props.Document hasn't updated yet, so without forcing the editor to the MainOverlayTextBox, it will display the previously focused textbox - MainOverlayTextBox.Instance.TextDoc ? MainOverlayTextBox.Instance.TextDoc : this.props.Document, - MainOverlayTextBox.Instance.TextFieldKey ? MainOverlayTextBox.Instance.TextFieldKey : this.props.fieldKey); - } - ); - } else { + if (!this.props.isOverlay) { this._proxyReactionDisposer = reaction(() => this.props.isSelected(), () => { if (this.props.isSelected()) { @@ -181,13 +151,12 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe }); } - this._reactionDisposer = reaction( () => { const field = this.props.Document ? Cast(this.props.Document[this.props.fieldKey], RichTextField) : undefined; - return field ? field.Data : undefined; + return field ? field.Data : `{"doc":{"type":"doc","content":[]},"selection":{"type":"text","anchor":0,"head":0}}`; }, - field => field && this._editorView && !this._applyingChange && + field => this._editorView && !this._applyingChange && this._editorView.updateState(EditorState.fromJSON(config, JSON.parse(field))) ); this.setupEditor(config, this.props.Document, this.props.fieldKey); @@ -215,8 +184,8 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe } if (this.props.selectOnLoad) { - //this.props.select(false); - this._editorView!.focus(); + if (!this.props.isOverlay) this.props.select(false); + else this._editorView!.focus(); } } @@ -227,9 +196,6 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe if (this._reactionDisposer) { this._reactionDisposer(); } - if (this._inputReactionDisposer) { - this._inputReactionDisposer(); - } if (this._proxyReactionDisposer) { this._proxyReactionDisposer(); } @@ -394,7 +360,6 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe color: this.props.color ? this.props.color : this.props.hideOnLeave ? "white" : "initial", pointerEvents: interactive ? "all" : "none", }} - // onKeyDown={this.onKeyPress} onKeyPress={this.onKeyPress} onFocus={this.onFocused} onClick={this.onClick} @@ -403,7 +368,6 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe onPointerUp={this.onPointerUp} onPointerDown={this.onPointerDown} onMouseDown={this.onMouseDown} - // tfs: do we need this event handler onWheel={this.onPointerWheel} onPointerEnter={this.onPointerEnter} onPointerLeave={this.onPointerLeave} -- cgit v1.2.3-70-g09d2 From 258be09fcfa48f355751cbe99291892018a91ffc Mon Sep 17 00:00:00 2001 From: ab Date: Wed, 12 Jun 2019 10:35:36 -0400 Subject: plus sign --- src/client/util/RichTextSchema.tsx | 26 +++++++++++++------------- src/client/views/nodes/FormattedTextBox.tsx | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index a29036f19..f10188c9e 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -28,9 +28,9 @@ export const nodes: { [index: string]: NodeSpec } = { star: { inline: true, - attrs: { oldtext: { default: "suhhhh" } }, + attrs: { oldtext: { default: "" } }, group: "inline", - toDOM() { return ["star", "🟊"]; }, + toDOM() { return ["star", "㊉"]; }, parseDOM: [{ tag: "star" }] }, @@ -426,17 +426,17 @@ export class ImageResizeView { } } -export class SummarizedView { - _collapsed: HTMLElement; - _selection: any; - constructor(node: any) { - this._collapsed = document.createElement("star"); - this._collapsed.onpointerdown = function (e: any) { - console.log("star pressed!"); - }; - - } -} +// export class SummarizedView { +// _collapsed: HTMLElement; +// _selection: any; +// constructor(node: any) { +// this._collapsed = document.createElement("star"); +// this._collapsed.onpointerdown = function (e: any) { +// console.log("star pressed!"); +// }; + +// } +// } // :: Schema // This schema rougly corresponds to the document schema used by // [CommonMark](http://commonmark.org/), minus the list elements, diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index b40c6d580..14597dbf1 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -16,7 +16,7 @@ import { DocumentManager } from "../../util/DocumentManager"; import { DragManager } from "../../util/DragManager"; import buildKeymap from "../../util/ProsemirrorKeymap"; import { inpRules } from "../../util/RichTextRules"; -import { SummarizedView, ImageResizeView, schema } from "../../util/RichTextSchema"; +import { ImageResizeView, schema } from "../../util/RichTextSchema"; import { SelectionManager } from "../../util/SelectionManager"; import { TooltipLinkingMenu } from "../../util/TooltipLinkingMenu"; import { TooltipTextMenu } from "../../util/TooltipTextMenu"; -- cgit v1.2.3-70-g09d2 From a4f5005fedae93bd4bb1529561acaa8d4f0474c5 Mon Sep 17 00:00:00 2001 From: bob Date: Wed, 12 Jun 2019 12:35:59 -0400 Subject: "fixed" prosemirror serialization of 'star' schema node --- src/client/util/RichTextSchema.tsx | 10 +++++----- src/client/util/TooltipTextMenu.tsx | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index db62f3ac1..d1282403f 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -90,6 +90,7 @@ export const nodes: { [index: string]: NodeSpec } = { attrs: { visibility: { default: false }, oldtext: { default: undefined }, + oldtextslice: { default: undefined }, oldtextlen: { default: 0 } }, @@ -502,10 +503,9 @@ export const schema = new Schema({ nodes, marks }); const fromJson = schema.nodeFromJSON; schema.nodeFromJSON = (json: any) => { - if (json.type !== "star") { - return fromJson(json); + let node = fromJson(json); + if (json.type === "star") { + node.attrs.oldtext = Slice.fromJSON(schema, node.attrs.oldtextslice); } - let x = fromJson(json); - x.attrs.oldtext = Slice.fromJSON(x.attrs.oldtext); - return x; + return node; } \ No newline at end of file diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx index a2288a496..87a4c33a1 100644 --- a/src/client/util/TooltipTextMenu.tsx +++ b/src/client/util/TooltipTextMenu.tsx @@ -274,7 +274,7 @@ export class TooltipTextMenu { insertStar(state: EditorState, dispatch: any) { console.log("creating star..."); - let newNode = schema.nodes.star.create({ visibility: false, oldtext: state.selection.content(), oldtextlen: state.selection.to - state.selection.from }); + let newNode = schema.nodes.star.create({ visibility: false, oldtext: state.selection.content(), oldtextslice: state.selection.content().toJSON(), oldtextlen: state.selection.to - state.selection.from }); if (dispatch) { console.log(newNode.attrs.oldtext.toString()); dispatch(state.tr.replaceSelectionWith(newNode)); -- cgit v1.2.3-70-g09d2 From 22306895d56bcd59f7e993dee570b9b0722bd35d Mon Sep 17 00:00:00 2001 From: ab Date: Wed, 12 Jun 2019 13:11:30 -0400 Subject: summarized text is underlined --- src/client/util/RichTextSchema.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index d1282403f..70729c0d9 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -451,6 +451,7 @@ export class ImageResizeView { } export class SummarizedView { + // TODO: highlight _collapsed: HTMLElement; constructor(node: any, view: any, getPos: any) { this._collapsed = document.createElement("span"); @@ -473,9 +474,10 @@ export class SummarizedView { node.attrs.visibility = !node.attrs.visibility; console.log("content is invisible"); let y = getPos(); + let mark = view.state.schema.mark(view.state.schema.marks.underline); console.log("PASTING " + node.attrs.oldtext.toString()); view.dispatch(view.state.tr.setSelection(TextSelection.create(view.state.doc, y + 1, y + 1))); - view.dispatch(view.state.tr.replaceSelection(node.attrs.oldtext)); + view.dispatch(view.state.tr.replaceSelection(node.attrs.oldtext).addMark(view.state.selection.from, view.state.selection.from + node.attrs.oldtextlen, mark)); //this._collapsed.textContent = "㊉"; } e.preventDefault(); -- cgit v1.2.3-70-g09d2 From f6bb5f269e04753669858e0994140984bc9d3915 Mon Sep 17 00:00:00 2001 From: ab Date: Wed, 12 Jun 2019 13:13:11 -0400 Subject: todo --- src/client/util/RichTextSchema.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index 70729c0d9..2c3fd8320 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -451,7 +451,7 @@ export class ImageResizeView { } export class SummarizedView { - // TODO: highlight + // TODO: highlight text that is summarized. to find end of region, walk along mark _collapsed: HTMLElement; constructor(node: any, view: any, getPos: any) { this._collapsed = document.createElement("span"); -- cgit v1.2.3-70-g09d2 From d6abc733fa6f0bffdbceb4a7bd4c7f449607ea21 Mon Sep 17 00:00:00 2001 From: bob Date: Wed, 12 Jun 2019 13:51:28 -0400 Subject: don't want to parse all 'spans' as stars --- src/client/util/RichTextSchema.tsx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index 2c3fd8320..61ca4af5e 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -99,15 +99,15 @@ export const nodes: { [index: string]: NodeSpec } = { const attrs = { style: `width: 40px` }; return ["span", { ...node.attrs, ...attrs }]; }, - parseDOM: [{ - tag: "span", getAttrs(dom: any) { - return { - visibility: dom.getAttribute("visibility"), - oldtext: dom.getAttribute("oldtext"), - oldtextlen: dom.getAttribute("oldtextlen"), - } - } - }] + // parseDOM: [{ + // tag: "star", getAttrs(dom: any) { + // return { + // visibility: dom.getAttribute("visibility"), + // oldtext: dom.getAttribute("oldtext"), + // oldtextlen: dom.getAttribute("oldtextlen"), + // } + // } + // }] }, // :: NodeSpec An inline image (``) node. Supports `src`, // `alt`, and `href` attributes. The latter two default to the empty -- cgit v1.2.3-70-g09d2 From b3144df1abdd4919d3a04c85fe9a75de1cdc2782 Mon Sep 17 00:00:00 2001 From: Abdullah Ahmed Date: Wed, 12 Jun 2019 17:40:23 -0400 Subject: ui changes --- src/client/util/TooltipTextMenu.scss | 48 ++++++++++++++++++------------------ src/client/util/TooltipTextMenu.tsx | 6 +++-- 2 files changed, 28 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/client/util/TooltipTextMenu.scss b/src/client/util/TooltipTextMenu.scss index 0099c1e4d..4d4eb386d 100644 --- a/src/client/util/TooltipTextMenu.scss +++ b/src/client/util/TooltipTextMenu.scss @@ -244,8 +244,8 @@ //transform: translateX(-50%); transform: translateY(-50%); pointer-events: all; - height: 125px; - width:400px; + height: auto; + width:inherit; .ProseMirror-example-setup-style hr { padding: 2px 10px; border: none; @@ -261,28 +261,28 @@ } } -.tooltipMenu:before { - content: ""; - height: 0; width: 0; - position: absolute; - left: 50%; - margin-left: -5px; - bottom: -6px; - border: 5px solid transparent; - border-bottom-width: 0; - border-top-color: silver; - } - .tooltipMenu:after { - content: ""; - height: 0; width: 0; - position: absolute; - left: 50%; - margin-left: -5px; - bottom: -4.5px; - border: 5px solid transparent; - border-bottom-width: 0; - border-top-color: $dark-color; - } +// .tooltipMenu:before { +// content: ""; +// height: 0; width: 0; +// position: absolute; +// left: 50%; +// margin-left: -5px; +// bottom: -6px; +// border: 5px solid transparent; +// border-bottom-width: 0; +// border-top-color: silver; +// } +// .tooltipMenu:after { +// content: ""; +// height: 0; width: 0; +// position: absolute; +// left: 50%; +// margin-left: -5px; +// bottom: -4.5px; +// border: 5px solid transparent; +// border-bottom-width: 0; +// border-top-color: $dark-color; +// } .menuicon { display: inline-block; diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx index 87a4c33a1..e12d4ed3c 100644 --- a/src/client/util/TooltipTextMenu.tsx +++ b/src/client/util/TooltipTextMenu.tsx @@ -234,13 +234,15 @@ export class TooltipTextMenu { this.linkEditor.appendChild(linkBtn); this.tooltip.appendChild(this.linkEditor); - let starButton = document.createElement("button"); + let starButton = document.createElement("span"); // starButton.style.width = '10px'; // starButton.style.height = '10px'; starButton.style.marginLeft = '10px'; starButton.textContent = "Summarize"; starButton.style.color = 'black'; + starButton.style.height = '20px'; starButton.style.backgroundColor = 'white'; + starButton.style.textAlign = 'center'; starButton.onclick = () => { let state = this.view.state; this.insertStar(state, this.view.dispatch); @@ -450,7 +452,7 @@ export class TooltipTextMenu { let width = Math.abs(start.left - end.left) / 2 * this.editorProps.ScreenToLocalTransform().Scale; let mid = Math.min(start.left, end.left) + width; - this.tooltip.style.width = 225 + "px"; + //this.tooltip.style.width = 225 + "px"; this.tooltip.style.bottom = (box.bottom - start.top) * this.editorProps.ScreenToLocalTransform().Scale + "px"; this.tooltip.style.top = "-100px"; //this.tooltip.style.height = "100px"; -- cgit v1.2.3-70-g09d2 From 27efc9b078b3301ebf73a9ba7dc881bd354e71d9 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 12 Jun 2019 23:29:34 -0400 Subject: cleaned up UI --- src/client/views/InkingControl.scss | 4 ++-- src/client/views/MainView.tsx | 27 ++++----------------------- 2 files changed, 6 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/client/views/InkingControl.scss b/src/client/views/InkingControl.scss index ba4ec41af..2c53dc031 100644 --- a/src/client/views/InkingControl.scss +++ b/src/client/views/InkingControl.scss @@ -1,8 +1,8 @@ @import "globalCssVariables"; .inking-control { position: absolute; - left: 70px; - bottom: 70px; + right: 0px; + bottom: 20px; margin: 0; padding: 0; display: flex; diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 42d5929bf..4b328f286 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -221,33 +221,15 @@ export class MainView extends React.Component { nodesMenu() { let imgurl = "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg"; - let pdfurl = "http://www.adobe.com/support/products/enterprise/knowledgecenter/media/c27211_sample_explain.pdf"; - let weburl = "https://cs.brown.edu/courses/cs166/"; - let audiourl = "http://techslides.com/demos/samples/sample.mp3"; - let videourl = "http://techslides.com/demos/sample-videos/small.mp4"; - let addTextNode = action(() => Docs.TextDocument({ borderRounding: -1, width: 200, height: 200, title: "a text note" })); let addColNode = action(() => Docs.FreeformDocument([], { width: this.pwidth * .7, height: this.pheight, title: "a freeform collection" })); - let addSchemaNode = action(() => Docs.SchemaDocument(["title"], [], { width: 200, height: 200, title: "a schema collection" })); let addTreeNode = action(() => CurrentUserUtils.UserDocument); - //let addTreeNode = action(() => Docs.TreeDocument([CurrentUserUtils.UserDocument], { width: 250, height: 400, title: "Library:" + CurrentUserUtils.email, dropAction: "alias" })); - // let addTreeNode = action(() => Docs.TreeDocument(this._northstarSchemas, { width: 250, height: 400, title: "northstar schemas", dropAction: "copy" })); - let addVideoNode = action(() => Docs.VideoDocument(videourl, { width: 200, title: "video node" })); - let addPDFNode = action(() => Docs.PdfDocument(pdfurl, { width: 200, height: 200, title: "a pdf doc" })); let addImageNode = action(() => Docs.ImageDocument(imgurl, { width: 200, title: "an image of a cat" })); - let addWebNode = action(() => Docs.WebDocument(weburl, { width: 200, height: 200, title: "a sample web page" })); - let addAudioNode = action(() => Docs.AudioDocument(audiourl, { width: 200, height: 200, title: "audio node" })); let btns: [React.RefObject, IconName, string, () => Doc][] = [ - [React.createRef(), "font", "Add Textbox", addTextNode], [React.createRef(), "image", "Add Image", addImageNode], - [React.createRef(), "file-pdf", "Add PDF", addPDFNode], - [React.createRef(), "film", "Add Video", addVideoNode], - [React.createRef(), "music", "Add Audio", addAudioNode], - [React.createRef(), "globe-asia", "Add Web Clipping", addWebNode], [React.createRef(), "object-group", "Add Collection", addColNode], [React.createRef(), "tree", "Add Tree", addTreeNode], - [React.createRef(), "table", "Add Schema", addSchemaNode], ]; return < div id="add-nodes-menu" > @@ -256,12 +238,16 @@ export class MainView extends React.Component {
    +
  • +
  • +
  • {btns.map(btn =>
  • )} +
; @@ -276,7 +262,6 @@ export class MainView extends React.Component { let logoutRef = React.createRef(); return [ - ,
- - - -
, this.isSearchVisible ?
: null,
-- cgit v1.2.3-70-g09d2 From cedecd26f899fdf7baf251791f9938914a24047f Mon Sep 17 00:00:00 2001 From: bob Date: Thu, 13 Jun 2019 11:10:43 -0400 Subject: moved ink controls into main panel of buttons. --- src/client/views/InkingControl.scss | 8 ++------ src/client/views/InkingControl.tsx | 16 +--------------- src/client/views/Main.scss | 10 +++++----- src/client/views/MainView.tsx | 17 +++++++++++++++-- 4 files changed, 23 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/client/views/InkingControl.scss b/src/client/views/InkingControl.scss index 2c53dc031..465e14d07 100644 --- a/src/client/views/InkingControl.scss +++ b/src/client/views/InkingControl.scss @@ -1,7 +1,5 @@ @import "globalCssVariables"; .inking-control { - position: absolute; - right: 0px; bottom: 20px; margin: 0; padding: 0; @@ -63,10 +61,9 @@ margin-top: 4px; } .ink-panel { - margin: 6px 12px 6px 0; - height: 30px; + height: 24px; vertical-align: middle; - line-height: 36px; + line-height: 28px; padding: 0 10px; color: $intermediate-color; &:first { @@ -114,7 +111,6 @@ border-radius: 11px; width: 22px; height: 22px; - margin-top: 6px; cursor: pointer; text-align: center; // span { // color: $light-color; diff --git a/src/client/views/InkingControl.tsx b/src/client/views/InkingControl.tsx index d1a6eb7fd..e7f0968af 100644 --- a/src/client/views/InkingControl.tsx +++ b/src/client/views/InkingControl.tsx @@ -57,16 +57,10 @@ export class InkingControl extends React.Component { return this._selectedWidth; } - selected = (tool: InkTool) => { - if (this._selectedTool === tool) { - return { color: "#61aaa3" }; - } - return {}; - } - @action toggleDisplay = () => { this._open = !this._open; + this.switchTool(this._open ? InkTool.Pen : InkTool.None); } @@ -78,14 +72,6 @@ export class InkingControl extends React.Component { render() { return (
    -
  • -
    - - - - -
    -
  • label { background: $dark-color; color: $light-color; display: inline-block; @@ -155,15 +155,15 @@ button:hover { transform: scale(1.15); } - input { + > input { display: none; } - input:not(:checked)~#add-options-content { + > input:not(:checked)~#add-options-content { display: none; } - input:checked~label { + > input:checked~label { transform: rotate(45deg); transition: transform 0.5s; cursor: pointer; @@ -207,7 +207,7 @@ ul#add-options-list { list-style: none; padding: 5 0 0 0; - li { + > li { display: inline-block; padding: 0; } diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 4b328f286..8a6790677 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -32,6 +32,8 @@ import { listSpec } from '../../new_fields/Schema'; import { Id } from '../../new_fields/FieldSymbols'; import { HistoryUtil } from '../util/History'; import { CollectionBaseView } from './collections/CollectionBaseView'; +import { InkTool } from '../../new_fields/InkField'; +import { InkingCanvas } from './InkingCanvas'; @observer @@ -217,6 +219,14 @@ export class MainView extends React.Component { ; } + selected = (tool: InkTool) => { + if (!InkingControl.Instance || InkingControl.Instance.selectedTool === InkTool.None) return { display: "none" }; + if (InkingControl.Instance.selectedTool === tool) { + return { color: "#61aaa3", fontSize: "50%" }; + } + return { fontSize: "50%" }; + } + /* for the expandable add nodes menu. Not included with the miscbuttons because once it expands it expands the whole div with it, making canvas interactions limited. */ nodesMenu() { @@ -247,7 +257,11 @@ export class MainView extends React.Component {
  • )} -
  • +
  • +
  • +
  • +
  • +
; @@ -295,7 +309,6 @@ export class MainView extends React.Component { {this.nodesMenu()} {this.miscButtons} -
); -- cgit v1.2.3-70-g09d2 From e81e116b89fad0f3fcfb76039b0b802073307478 Mon Sep 17 00:00:00 2001 From: bob Date: Thu, 13 Jun 2019 11:50:52 -0400 Subject: tweaked link following --- src/client/views/nodes/DocumentView.tsx | 3 ++- src/new_fields/Doc.ts | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 051940cc4..6fe01963a 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -269,7 +269,8 @@ export class DocumentView extends DocComponent(Docu if (!linkedFwdDocs.some(l => l instanceof Promise)) { let maxLocation = StrCast(linkedFwdDocs[altKey ? 1 : 0].maximizeLocation, "inTab"); - DocumentManager.Instance.jumpToDocument(linkedFwdDocs[altKey ? 1 : 0], ctrlKey, document => this.props.addDocTab(document, maxLocation), linkedFwdPage[altKey ? 1 : 0], linkedFwdContextDocs[altKey ? 1 : 0]); + let targetContext = !Doc.AreProtosEqual(linkedFwdContextDocs[altKey ? 1 : 0], this.props.ContainingCollectionView && this.props.ContainingCollectionView.props.Document) ? linkedFwdContextDocs[altKey ? 1 : 0] : undefined; + DocumentManager.Instance.jumpToDocument(linkedFwdDocs[altKey ? 1 : 0], ctrlKey, document => this.props.addDocTab(document, maxLocation), linkedFwdPage[altKey ? 1 : 0], targetContext); } } } diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts index 7e02a5bc5..c2cfda079 100644 --- a/src/new_fields/Doc.ts +++ b/src/new_fields/Doc.ts @@ -186,7 +186,8 @@ export namespace Doc { } // compare whether documents or their protos match - export function AreProtosEqual(doc: Doc, other: Doc) { + export function AreProtosEqual(doc?: Doc, other?: Doc) { + if (!doc || !other) return false; let r = (doc === other); let r2 = (doc.proto === other); let r3 = (other.proto === doc); -- cgit v1.2.3-70-g09d2