diff options
-rw-r--r-- | src/client/util/RichTextSchema.tsx | 83 | ||||
-rw-r--r-- | src/client/util/TooltipTextMenu.tsx | 32 | ||||
-rw-r--r-- | src/client/views/collections/CollectionViewChromes.tsx | 2 | ||||
-rw-r--r-- | src/client/views/nodes/FormattedTextBox.tsx | 9 |
4 files changed, 122 insertions, 4 deletions
diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index ce9e29b26..733c50d20 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -6,6 +6,7 @@ import { orderedList, bulletList, listItem, } from 'prosemirror-schema-list'; import { EditorState, Transaction, NodeSelection, TextSelection, Selection, } from "prosemirror-state"; import { EditorView, } from "prosemirror-view"; import { View } from '@react-pdf/renderer'; +import { TooltipTextMenu } from './TooltipTextMenu'; const pDOM: DOMOutputSpecArray = ["p", 0], blockquoteDOM: DOMOutputSpecArray = ["blockquote", 0], hrDOM: DOMOutputSpecArray = ["hr"], preDOM: DOMOutputSpecArray = ["pre", ["code", 0]], brDOM: DOMOutputSpecArray = ["br"], ulDOM: DOMOutputSpecArray = ["ul", 0]; @@ -110,6 +111,19 @@ export const nodes: { [index: string]: NodeSpec } = { // } // }] }, + + checkbox: { + inline: true, + attrs: { + visibility: { default: false } + }, + group: "inline", + toDOM(node) { + const attrs = { style: `width: 40px` }; + return ["span", { ...node.attrs, ...attrs }]; + }, + }, + // :: NodeSpec An inline image (`<img>`) node. Supports `src`, // `alt`, and `href` attributes. The latter two default to the empty // string. @@ -188,6 +202,20 @@ export const nodes: { [index: string]: NodeSpec } = { // parseDOM: [{ tag: "ul" }, { style: 'list-style-type=disc' }], // toDOM() { return ulDOM } }, + + checkbox_list: { + content: 'checklist_item+', + marks: '_', + group: 'block', + // inline: true, + parseDOM: [ + { tag: "ul" } + ], + toDOM() { + return ["ul", { style: 'list-style: none' }, 0]; + }, + }, + //bullet_list: { // content: 'list_item+', // group: 'block', @@ -199,6 +227,18 @@ export const nodes: { [index: string]: NodeSpec } = { list_item: { ...listItem, content: 'paragraph block*' + }, + + checklist_item: { + content: 'paragraph block*', + parseDOM: [{ tag: "li" }], + // toDOM() { + // return ["li", { style: 'content: checkbox' }, 0]; + // }, + toDOM() { + return ["li", 0]; + }, + defining: true } }; @@ -522,6 +562,49 @@ export class ImageResizeView { } } +export class CheckboxView { + _view: any; + _collapsed: HTMLElement; + + constructor(node: any, view: any, getPos: any) { + this._collapsed = document.createElement("span"); + this._collapsed.textContent = node.attrs.visibility ? "⬛" : "⬜"; + this._collapsed.style.position = "relative"; + // this._collapsed.style.width = "80px"; + this._collapsed.style.height = "20px"; + let self = this; + this._view = view; + const js = node.toJSON; + node.toJSON = function () { + + return js.apply(this, arguments); + }; + this._collapsed.onpointerdown = function (e: any) { + console.log(node.attrs.visibility) + if (node.attrs.visibility) { + let y = getPos(); + const attrs = { ...node.attrs }; + attrs.visibility = !attrs.visibility; + view.dispatch(view.state.tr.setNodeMarkup(y, undefined, attrs)); + self._collapsed.textContent = "⬜"; + } else { + let y = getPos(); + const attrs = { ...node.attrs }; + attrs.visibility = !attrs.visibility; + console.log(attrs.visibility) + view.dispatch(view.state.tr.setNodeMarkup(y, undefined, attrs)); + self._collapsed.textContent = "⬛"; + } + e.preventDefault(); + e.stopPropagation(); + console.log(node.attrs.visibility) + + }; + (this as any).dom = this._collapsed; + } + +} + export class SummarizedView { // TODO: highlight text that is summarized. to find end of region, walk along mark _collapsed: HTMLElement; diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx index d33a52d7f..8112ed868 100644 --- a/src/client/util/TooltipTextMenu.tsx +++ b/src/client/util/TooltipTextMenu.tsx @@ -10,7 +10,7 @@ import { Node as ProsNode } from "prosemirror-model"; import "./TooltipTextMenu.scss"; const { toggleMark, setBlockType } = require("prosemirror-commands"); import { library } from '@fortawesome/fontawesome-svg-core'; -import { wrapInList, liftListItem, } from 'prosemirror-schema-list'; +import { wrapInList, liftListItem, bulletList, } from 'prosemirror-schema-list'; import { faListUl } from '@fortawesome/free-solid-svg-icons'; import { FieldViewProps } from "../views/nodes/FieldView"; const { openPrompt, TextField } = require("./ProsemirrorCopy/prompt.js"); @@ -177,6 +177,7 @@ export class TooltipTextMenu { this.listTypeToIcon = new Map(); this.listTypeToIcon.set(schema.nodes.bullet_list, ":"); this.listTypeToIcon.set(schema.nodes.ordered_list, "1)"); + // this.listTypeToIcon.set(schema.nodes.bullet_list, "⬜"); this.listTypes = Array.from(this.listTypeToIcon.keys()); //custom tools @@ -186,6 +187,7 @@ export class TooltipTextMenu { this.tooltip.appendChild(this._brushdom); this.tooltip.appendChild(this.createLink().render(this.view).dom); this.tooltip.appendChild(this.createStar().render(this.view).dom); + this.tooltip.appendChild(this.createCheckbox().render(this.view).dom); this.updateListItemDropdown(":", this.listTypeBtnDom); @@ -439,6 +441,14 @@ export class TooltipTextMenu { return true; } + public static insertCheckbox(state: EditorState<any>, dispatch: any) { + let newNode = schema.nodes.checkbox.create({ visibility: false }); + if (dispatch) { + dispatch(state.tr.replaceSelectionWith(newNode)); + } + return true; + } + //will display a remove-list-type button if selection is in list, otherwise will show list type dropdown updateListItemDropdown(label: string, listTypeBtn: any) { //remove old btn @@ -451,6 +461,7 @@ export class TooltipTextMenu { }); //option to remove the list formatting toAdd.push(this.dropdownNodeBtn("X", "color: black; width: 40px;", undefined, this.view, this.listTypes, this.changeToNodeType)); + toAdd.push(this.dropdownNodeBtn("⬜", "color:black; width:40px;", schema.nodes.checkbox_list, this.view, this.listTypes, this.changeToNodeType)) listTypeBtn = (new Dropdown(toAdd, { label: label, @@ -514,6 +525,11 @@ export class TooltipTextMenu { liftListItem(schema.nodes.list_item)(view.state, view.dispatch); if (nodeType) { //add new wrapInList(nodeType)(view.state, view.dispatch); + // console.log(nodeType === schema.nodes.checkbox_list) + // if (nodeType === schema.nodes.checkbox_list) { + // TooltipTextMenu.insertCheckbox(view.state, view.dispatch) + // } + } } @@ -548,6 +564,20 @@ export class TooltipTextMenu { }); } + createCheckbox() { + return new MenuItem({ + title: "Checkbox", + label: "Checkbox", + icon: icons.code, + css: "color:white", + class: "checkbox", + execEvent: "", + run: (state, dispatch) => { + TooltipTextMenu.insertCheckbox(state, dispatch); + } + }) + } + deleteLinkItem() { const icon = { height: 16, width: 16, diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx index 52c47e7e8..5b673c8ec 100644 --- a/src/client/views/collections/CollectionViewChromes.tsx +++ b/src/client/views/collections/CollectionViewChromes.tsx @@ -33,6 +33,8 @@ let stopPropagation = (e: React.SyntheticEvent) => e.stopPropagation(); @observer export class CollectionViewBaseChrome extends React.Component<CollectionViewChromeProps> { + //.*?doc\.(\w+).*?\("(\w+) + @observable private _viewSpecsOpen: boolean = false; @observable private _dateWithinValue: string = ""; @observable private _dateValue: Date | string = ""; diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index 44b5d2c21..d1771eb0f 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -8,7 +8,7 @@ import { keymap } from "prosemirror-keymap"; import { Node as ProsNode } from "prosemirror-model"; import { EditorState, Plugin, Transaction, Selection } from "prosemirror-state"; import { NodeType, Slice, Node, Fragment } from 'prosemirror-model'; -import { EditorView } from "prosemirror-view"; +import { EditorView, NodeView } from "prosemirror-view"; import { Doc, Opt, DocListCast } from "../../../new_fields/Doc"; import { Id, Copy } from '../../../new_fields/FieldSymbols'; import { List } from '../../../new_fields/List'; @@ -21,7 +21,7 @@ import { DocumentManager } from '../../util/DocumentManager'; import { DragManager } from "../../util/DragManager"; import buildKeymap from "../../util/ProsemirrorExampleTransfer"; import { inpRules } from "../../util/RichTextRules"; -import { ImageResizeView, schema, SummarizedView } from "../../util/RichTextSchema"; +import { ImageResizeView, schema, SummarizedView, CheckboxView } from "../../util/RichTextSchema"; import { SelectionManager } from "../../util/SelectionManager"; import { TooltipLinkingMenu } from "../../util/TooltipLinkingMenu"; import { TooltipTextMenu } from "../../util/TooltipTextMenu"; @@ -38,6 +38,7 @@ import { For } from 'babel-types'; import { DateField } from '../../../new_fields/DateField'; import { Utils } from '../../../Utils'; import { MainOverlayTextBox } from '../MainOverlayTextBox'; +import { CheckBox } from '../search/CheckBox'; library.add(faEdit); library.add(faSmile, faTextHeight); @@ -176,6 +177,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe this._editorView.updateState(state); if (state.selection.empty && FormattedTextBox._toolTipTextMenu) { const marks = tx.storedMarks; + console.log(marks) if (marks) { FormattedTextBox._toolTipTextMenu.mark_key_pressed(marks); } } this._applyingChange = true; @@ -461,7 +463,8 @@ 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, view, getPos); } + star(node, view, getPos) { return new SummarizedView(node, view, getPos); }, + checkbox(node, view, getPos) { return new CheckboxView(node, view, getPos) as NodeView<any>; } }, clipboardTextSerializer: this.clipboardTextSerializer, handlePaste: this.handlePaste, |