From bff0093163bdc05fb661eb744c2333069544dc89 Mon Sep 17 00:00:00 2001
From: laurawilsonri <laura_wilson@brown.edu>
Date: Mon, 11 Mar 2019 18:48:58 -0400
Subject: added a method to check if block has a syle ie bullets

---
 src/client/util/RichTextSchema.tsx | 44 ++++++++++++++++++++++++++++++++------
 1 file changed, 38 insertions(+), 6 deletions(-)

(limited to 'src/client/util/RichTextSchema.tsx')

diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx
index abf448c9f..341d5a443 100644
--- a/src/client/util/RichTextSchema.tsx
+++ b/src/client/util/RichTextSchema.tsx
@@ -1,12 +1,31 @@
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { Schema, NodeSpec, MarkSpec, DOMOutputSpecArray } from "prosemirror-model"
+import { Schema, NodeSpec, MarkSpec, DOMOutputSpecArray, NodeType } from "prosemirror-model"
 import { joinUp, lift, setBlockType, toggleMark, wrapIn } from 'prosemirror-commands'
 import { redo, undo } from 'prosemirror-history'
-import { orderedList, bulletList, listItem } from 'prosemirror-schema-list'
+import { orderedList, bulletList, listItem, } from 'prosemirror-schema-list'
+import { EditorState, Transaction, NodeSelection, } from "prosemirror-state";
+import { EditorView, } from "prosemirror-view";
 
 const pDOM: DOMOutputSpecArray = ["p", 0], blockquoteDOM: DOMOutputSpecArray = ["blockquote", 0], hrDOM: DOMOutputSpecArray = ["hr"],
   preDOM: DOMOutputSpecArray = ["pre", ["code", 0]], brDOM: DOMOutputSpecArray = ["br"], ulDOM: DOMOutputSpecArray = ["ul", 0]
 
+//adapted this method - use it to check if block has a tag (ie bulleting)
+const blockActive = (type: NodeType<Schema<string, string>>, attrs = {}) => (state: EditorState) => {
+
+  if (state.selection instanceof NodeSelection) {
+    const sel: NodeSelection = state.selection;
+    let $from = sel.$from;
+    let to = sel.to;
+    let node = sel.node;
+
+    if (node) {
+      return node.hasMarkup(type, attrs);
+    }
+
+    return to <= $from.end() && $from.parent.hasMarkup(type, attrs);
+  }
+};
+
 // :: Object
 // [Specs](#model.NodeSpec) for the nodes defined in this schema.
 export const nodes: { [index: string]: NodeSpec } = {
@@ -113,11 +132,24 @@ export const nodes: { [index: string]: NodeSpec } = {
     content: 'list_item+',
     group: 'block'
   },
+  //bullet_list: {
+  //  ...bulletList,
+  //  content: 'list_item+',
+  //  group: 'block',
+  //parseDOM: [{ tag: "ul" }, { style: 'list-style-type=disc' }],
+  //toDOM() { return ulDOM }
+  //},
   bullet_list: {
-    content: 'list_item+',
-    group: 'block',
-    parseDOM: [{ tag: "ul" }, { style: "list-style-type=disc;" }],
-    toDOM() { return ulDOM }
+    title: "Wrap in bullet list",
+    content: icons.bullet_list,
+    active: blockActive(state.config.schema.nodes.bullet_list),
+    enable: state => wrapInList(state.config.schema.nodes.bullet_list),
+    run: state => wrapInList(state.config.schema.nodes.bullet_list),
+    active: blockActive(schema.nodes.bullet_list),
+    enable: wrapInList(schema.nodes.bullet_list),
+    run: wrapInList(schema.nodes.bullet_list),
+    select: state => true,
+    menu: props => <Button key={uuid()} {...props} />
   },
   list_item: {
     ...listItem,
-- 
cgit v1.2.3-70-g09d2


From 50477f0a9b0b371b4f381b6cef14030a9d7de21e Mon Sep 17 00:00:00 2001
From: laurawilsonri <laura_wilson@brown.edu>
Date: Tue, 12 Mar 2019 16:14:13 -0400
Subject: added some helpful comments

---
 package-lock.json                           |  9 ++++++
 package.json                                |  1 +
 src/client/util/RichTextRules.ts            | 43 ++++++++++++++++++++++++++
 src/client/util/RichTextSchema.tsx          | 47 +++++++++--------------------
 src/client/util/TooltipTextMenu.tsx         | 24 ++++++++++++---
 src/client/views/nodes/FormattedTextBox.tsx |  2 ++
 6 files changed, 88 insertions(+), 38 deletions(-)
 create mode 100644 src/client/util/RichTextRules.ts

(limited to 'src/client/util/RichTextSchema.tsx')

diff --git a/package-lock.json b/package-lock.json
index 9343a2e88..e780b247f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -320,6 +320,15 @@
         "@types/prosemirror-state": "*"
       }
     },
+    "@types/prosemirror-inputrules": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@types/prosemirror-inputrules/-/prosemirror-inputrules-1.0.2.tgz",
+      "integrity": "sha512-bKFneQUPnkZmzCJ1uoitpKH6PFW0hc4q55NsC7mFUCvX0eZl0GRKxyfV47jkJbsbyUQoO/QFv0WwLDz2bo15sA==",
+      "requires": {
+        "@types/prosemirror-model": "*",
+        "@types/prosemirror-state": "*"
+      }
+    },
     "@types/prosemirror-keymap": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/@types/prosemirror-keymap/-/prosemirror-keymap-1.0.1.tgz",
diff --git a/package.json b/package.json
index a89d82645..841796bb4 100644
--- a/package.json
+++ b/package.json
@@ -54,6 +54,7 @@
     "@types/passport-local": "^1.0.33",
     "@types/prosemirror-commands": "^1.0.1",
     "@types/prosemirror-history": "^1.0.1",
+    "@types/prosemirror-inputrules": "^1.0.2",
     "@types/prosemirror-keymap": "^1.0.1",
     "@types/prosemirror-model": "^1.7.0",
     "@types/prosemirror-schema-basic": "^1.0.1",
diff --git a/src/client/util/RichTextRules.ts b/src/client/util/RichTextRules.ts
new file mode 100644
index 000000000..3b8396510
--- /dev/null
+++ b/src/client/util/RichTextRules.ts
@@ -0,0 +1,43 @@
+import {
+    inputRules,
+    wrappingInputRule,
+    textblockTypeInputRule,
+    smartQuotes,
+    emDash,
+    ellipsis
+} from "prosemirror-inputrules";
+import { Schema, NodeSpec, MarkSpec, DOMOutputSpecArray, NodeType } from "prosemirror-model";
+
+import { schema } from "./RichTextSchema";
+
+export const inpRules = {
+    rules: [
+        ...smartQuotes,
+        ellipsis,
+        emDash,
+
+        // > blockquote
+        wrappingInputRule(/^\s*>\s$/, schema.nodes.blockquote),
+
+        // 1. ordered list
+        wrappingInputRule(
+            /^(\d+)\.\s$/,
+            schema.nodes.ordered_list,
+            match => ({ order: +match[1] }),
+            (match, node) => node.childCount + node.attrs.order === +match[1]
+        ),
+
+        // * bullet list
+        wrappingInputRule(/^\s*([-+*])\s$/, schema.nodes.bullet_list),
+
+        // ``` code block
+        textblockTypeInputRule(/^```$/, schema.nodes.code_block),
+
+        // # heading
+        textblockTypeInputRule(
+            new RegExp("^(#{1,6})\\s$"),
+            schema.nodes.heading,
+            match => ({ level: match[1].length })
+        )
+    ]
+};
diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx
index 341d5a443..2a3c1da6e 100644
--- a/src/client/util/RichTextSchema.tsx
+++ b/src/client/util/RichTextSchema.tsx
@@ -9,22 +9,6 @@ import { EditorView, } from "prosemirror-view";
 const pDOM: DOMOutputSpecArray = ["p", 0], blockquoteDOM: DOMOutputSpecArray = ["blockquote", 0], hrDOM: DOMOutputSpecArray = ["hr"],
   preDOM: DOMOutputSpecArray = ["pre", ["code", 0]], brDOM: DOMOutputSpecArray = ["br"], ulDOM: DOMOutputSpecArray = ["ul", 0]
 
-//adapted this method - use it to check if block has a tag (ie bulleting)
-const blockActive = (type: NodeType<Schema<string, string>>, attrs = {}) => (state: EditorState) => {
-
-  if (state.selection instanceof NodeSelection) {
-    const sel: NodeSelection = state.selection;
-    let $from = sel.$from;
-    let to = sel.to;
-    let node = sel.node;
-
-    if (node) {
-      return node.hasMarkup(type, attrs);
-    }
-
-    return to <= $from.end() && $from.parent.hasMarkup(type, attrs);
-  }
-};
 
 // :: Object
 // [Specs](#model.NodeSpec) for the nodes defined in this schema.
@@ -132,25 +116,22 @@ export const nodes: { [index: string]: NodeSpec } = {
     content: 'list_item+',
     group: 'block'
   },
-  //bullet_list: {
-  //  ...bulletList,
-  //  content: 'list_item+',
-  //  group: 'block',
-  //parseDOM: [{ tag: "ul" }, { style: 'list-style-type=disc' }],
-  //toDOM() { return ulDOM }
-  //},
+  //this doesn't currently work for some reason
   bullet_list: {
-    title: "Wrap in bullet list",
-    content: icons.bullet_list,
-    active: blockActive(state.config.schema.nodes.bullet_list),
-    enable: state => wrapInList(state.config.schema.nodes.bullet_list),
-    run: state => wrapInList(state.config.schema.nodes.bullet_list),
-    active: blockActive(schema.nodes.bullet_list),
-    enable: wrapInList(schema.nodes.bullet_list),
-    run: wrapInList(schema.nodes.bullet_list),
-    select: state => true,
-    menu: props => <Button key={uuid()} {...props} />
+    ...bulletList,
+    content: 'list_item+',
+    group: 'block',
+    // parseDOM: [{ tag: "ul" }, { style: 'list-style-type=disc' }],
+    // toDOM() { return ulDOM }
   },
+  //bullet_list: {
+  //  content: 'list_item+',
+  // group: 'block',
+  //active: blockActive(schema.nodes.bullet_list),
+  //enable: wrapInList(schema.nodes.bullet_list),
+  //run: wrapInList(schema.nodes.bullet_list),
+  //select: state => true,
+  // },
   list_item: {
     ...listItem,
     content: 'paragraph block*'
diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx
index 90b10a3ce..d771ed13f 100644
--- a/src/client/util/TooltipTextMenu.tsx
+++ b/src/client/util/TooltipTextMenu.tsx
@@ -2,9 +2,10 @@ import { action, IReactionDisposer, reaction } from "mobx";
 import { baseKeymap } from "prosemirror-commands";
 import { history, redo, undo } from "prosemirror-history";
 import { keymap } from "prosemirror-keymap";
-import { EditorState, Transaction, } from "prosemirror-state";
+import { EditorState, Transaction, NodeSelection } from "prosemirror-state";
 import { EditorView } from "prosemirror-view";
 import { schema } from "./RichTextSchema";
+import { Schema, NodeType } from "prosemirror-model"
 import React = require("react")
 import "./TooltipTextMenu.scss";
 const { toggleMark, setBlockType, wrapIn } = require("prosemirror-commands");
@@ -15,7 +16,7 @@ import {
 } from '@fortawesome/free-solid-svg-icons';
 
 
-
+//appears above a selection of text in a RichTextBox to give user options such as Bold, Italics, etc.
 export class TooltipTextMenu {
 
   private tooltip: HTMLElement;
@@ -38,6 +39,7 @@ export class TooltipTextMenu {
       { 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") },
+      //this doesn't work currently - look into notion of active block
       { command: wrapInList(schema.nodes.bullet_list), dom: this.icon(":", "bullets") },
     ]
     items.forEach(({ dom }) => this.tooltip.appendChild(dom));
@@ -65,10 +67,22 @@ export class TooltipTextMenu {
     return span;
   }
 
-  blockActive(view: EditorView) {
-    const { $from, to } = view.state.selection
+  //adapted this method - use it to check if block has a tag (ie bulleting)
+  blockActive(type: NodeType<Schema<string, string>>, state: EditorState) {
+    let attrs = {};
+
+    if (state.selection instanceof NodeSelection) {
+      const sel: NodeSelection = state.selection;
+      let $from = sel.$from;
+      let to = sel.to;
+      let node = sel.node;
 
-    return to <= $from.end() && $from.parent.hasMarkup(schema.nodes.bulletList);
+      if (node) {
+        return node.hasMarkup(type, attrs);
+      }
+
+      return to <= $from.end() && $from.parent.hasMarkup(type, attrs);
+    }
   }
 
   //this doesn't currently work but hopefully will soon
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index d3184612c..7419b3a60 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -14,6 +14,7 @@ import { Plugin } from 'prosemirror-state'
 import { Decoration, DecorationSet } from 'prosemirror-view'
 import { TooltipTextMenu } from "../../util/TooltipTextMenu"
 import { ContextMenu } from "../../views/ContextMenu";
+import { inpRules } from "../../util/RichTextRules";
 const { buildMenuItems } = require("prosemirror-example-setup");
 const { menuBar } = require("prosemirror-menu");
 
@@ -62,6 +63,7 @@ export class FormattedTextBox extends React.Component<FieldViewProps> {
         let state: EditorState;
         const config = {
             schema,
+            inpRules, //these currently don't do anything, but could eventually be helpful
             plugins: [
                 history(),
                 keymap({ "Mod-z": undo, "Mod-y": redo }),
-- 
cgit v1.2.3-70-g09d2

