aboutsummaryrefslogtreecommitdiff
path: root/src/client/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/util')
-rw-r--r--src/client/util/DocumentManager.ts2
-rw-r--r--src/client/util/ProsemirrorExampleTransfer.ts84
-rw-r--r--src/client/util/RichTextRules.ts3
-rw-r--r--src/client/util/RichTextSchema.tsx98
-rw-r--r--src/client/util/TooltipTextMenu.tsx44
5 files changed, 158 insertions, 73 deletions
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index 124faf266..ec731da84 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -204,4 +204,4 @@ export class DocumentManager {
}
}
}
-Scripting.addGlobal(function focus(doc: any) { DocumentManager.Instance.getDocumentViews(Doc.GetProto(doc)).map(view => view.props.focus(doc, true)) }) \ No newline at end of file
+Scripting.addGlobal(function focus(doc: any) { DocumentManager.Instance.getDocumentViews(Doc.GetProto(doc)).map(view => view.props.focus(doc, true)); }); \ No newline at end of file
diff --git a/src/client/util/ProsemirrorExampleTransfer.ts b/src/client/util/ProsemirrorExampleTransfer.ts
index b928532d6..3979d8a49 100644
--- a/src/client/util/ProsemirrorExampleTransfer.ts
+++ b/src/client/util/ProsemirrorExampleTransfer.ts
@@ -2,8 +2,8 @@ import { chainCommands, exitCode, joinDown, joinUp, lift, selectParentNode, setB
import { redo, undo } from "prosemirror-history";
import { undoInputRule } from "prosemirror-inputrules";
import { Schema } from "prosemirror-model";
-import { liftListItem, splitListItem, wrapInList } from "prosemirror-schema-list";
-import { EditorState, Transaction } from "prosemirror-state";
+import { liftListItem, splitListItem, wrapInList, sinkListItem } from "prosemirror-schema-list";
+import { EditorState, Transaction, TextSelection, NodeSelection } from "prosemirror-state";
import { TooltipTextMenu } from "./TooltipTextMenu";
const mac = typeof navigator !== "undefined" ? /Mac/.test(navigator.platform) : false;
@@ -79,31 +79,76 @@ export default function buildKeymap<S extends Schema<any>>(schema: S, mapKeys?:
bind("Mod-s", TooltipTextMenu.insertStar);
- bind("Shift-Tab", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => {
- var marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks());
- liftListItem(schema.nodes.list_item)(state, (tx2: Transaction) => {
- marks && tx2.ensureMarks(marks);
- marks && tx2.setStoredMarks(marks);
- dispatch(tx2);
- });
- });
+ let nodeTypeMark = (depth: number) => depth === 2 ? "indent2" : depth === 4 ? "indent3" : depth === 6 ? "indent4" : "indent1";
let bulletFunc = (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => {
var ref = state.selection;
var range = ref.$from.blockRange(ref.$to);
var marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks());
let depth = range && range.depth ? range.depth : 0;
- let nodeType = depth == 2 ? schema.nodes.cap_alphabet_list : depth == 4 ? schema.nodes.roman_list : depth == 6 ? schema.nodes.alphabet_list : schema.nodes.ordered_list;
-
- if (!wrapInList(nodeType)(state, (tx2: Transaction) => {
- marks && tx2.ensureMarks(marks);
- marks && tx2.setStoredMarks(marks);
+ if (!sinkListItem(schema.nodes.list_item)(state, (tx2: Transaction) => {
+ const resolvedPos = tx2.doc.resolve(range!.start);
+
+ let path = (resolvedPos as any).path;
+ for (let i = path.length - 1; i > 0; i--) {
+ if (path[i].type === schema.nodes.ordered_list) {
+ path[i].attrs.bulletStyle = nodeTypeMark(depth);
+ break;
+ }
+ }
+ marks && tx2.ensureMarks([...marks]);
+ marks && tx2.setStoredMarks([...marks]);
dispatch(tx2);
})) {
- console.log("bullet fail");
+ let sxf = state.tr.setSelection(TextSelection.create(state.doc, range!.start, range!.end));
+ let newstate = state.applyTransaction(sxf);
+ if (!wrapInList(schema.nodes.ordered_list)(newstate.state, (tx2: Transaction) => {
+ const resolvedPos = tx2.doc.resolve(Math.round((range!.start + range!.end) / 2));
+ let path = (resolvedPos as any).path;
+ for (let i = path.length - 1; i > 0; i--) {
+ if (path[i].type === schema.nodes.ordered_list) {
+ path[i].attrs.bulletStyle = nodeTypeMark(depth);
+ break;
+ }
+ }
+ // when promoting to a list, assume list will format things so don't copy the stored marks.
+ // marks && tx2.ensureMarks([...marks]);
+ // marks && tx2.setStoredMarks([...marks]);
+
+ dispatch(tx2);
+ })) {
+ console.log("bullet fail");
+ }
}
- }
- bind("Tab", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => bulletFunc(state, dispatch));
+ };
+
+ bind("Tab", bulletFunc);
+
+ bind("Shift-Tab", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => {
+ var ref = state.selection;
+ var range = ref.$from.blockRange(ref.$to);
+ var marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks());
+ let depth = range && range.depth > 3 ? range.depth - 4 : 0;
+ liftListItem(schema.nodes.list_item)(state, (tx2: Transaction) => {
+ try {
+ const resolvedPos = tx2.doc.resolve(Math.round((range!.start + range!.end) / 2));
+
+ let path = (resolvedPos as any).path;
+ for (let i = path.length - 1; i > 0; i--) {
+ if (path[i].type === schema.nodes.ordered_list) {
+ path[i].attrs.bulletStyle = nodeTypeMark(depth);
+ break;
+ }
+ }
+
+ marks && tx2.ensureMarks([...marks]);
+ marks && tx2.setStoredMarks([...marks]);
+ dispatch(tx2);
+ } catch (e) {
+ dispatch(tx2);
+ }
+ });
+ });
bind("Enter", (state: EditorState<S>, dispatch: (tx: Transaction<S>) => void) => {
var marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks());
@@ -115,7 +160,8 @@ export default function buildKeymap<S extends Schema<any>>(schema: S, mapKeys?:
if (!splitBlockKeepMarks(state, (tx3: Transaction) => {
marks && tx3.ensureMarks(marks);
marks && tx3.setStoredMarks(marks);
- if (!liftListItem(schema.nodes.list_item)(state, (tx4: Transaction) => dispatch(tx4))) {
+ if (!liftListItem(schema.nodes.list_item)(state, dispatch as ((tx: Transaction<Schema<any, any>>) => void))
+ ) {
dispatch(tx3);
}
})) {
diff --git a/src/client/util/RichTextRules.ts b/src/client/util/RichTextRules.ts
index 89933650b..8c4c76027 100644
--- a/src/client/util/RichTextRules.ts
+++ b/src/client/util/RichTextRules.ts
@@ -26,7 +26,7 @@ export const inpRules = {
match => ({ order: +match[1] }),
(match, node) => node.childCount + node.attrs.order === +match[1]
),
- // 1. ordered list
+ // a. alphabbetical list
wrappingInputRule(
/^([a-z]+)\.\s$/,
schema.nodes.alphabet_list,
@@ -34,7 +34,6 @@ export const inpRules = {
(match, node) => node.childCount + node.attrs.order === +match[1]
),
-
// * bullet list
wrappingInputRule(/^\s*([-+*])\s$/, schema.nodes.bullet_list),
diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx
index d9e1d6ae1..df33589bf 100644
--- a/src/client/util/RichTextSchema.tsx
+++ b/src/client/util/RichTextSchema.tsx
@@ -1,6 +1,7 @@
import { DOMOutputSpecArray, MarkSpec, Node, NodeSpec, Schema, Slice } from "prosemirror-model";
import { bulletList, listItem, orderedList } from 'prosemirror-schema-list';
import { TextSelection } from "prosemirror-state";
+import { Doc } from "../../new_fields/Doc";
const pDOM: DOMOutputSpecArray = ["p", 0], blockquoteDOM: DOMOutputSpecArray = ["blockquote", 0], hrDOM: DOMOutputSpecArray = ["hr"],
preDOM: DOMOutputSpecArray = ["pre", ["code", 0]], brDOM: DOMOutputSpecArray = ["br"], ulDOM: DOMOutputSpecArray = ["ul", 0];
@@ -175,43 +176,17 @@ export const nodes: { [index: string]: NodeSpec } = {
content: 'list_item+',
group: 'block',
attrs: {
- bulletStyle: { default: "decimal" },
+ bulletStyle: { default: "" },
+ mapStyle: { default: "decimal" }
},
toDOM(node: Node<any>) {
- return ['ol', { style: `list-style: ${node.attrs.bulletStyle}` }, 0]
- }
- },
- alphabet_list: {
- ...orderedList,
- content: 'list_item+',
- group: 'block',
- attrs: {
- bulletStyle: { default: "lower-alpha" },
- },
- toDOM(node: Node<any>) {
- return ['ol', { style: `list-style: ${node.attrs.bulletStyle}` }, 0]
- }
- },
- cap_alphabet_list: {
- ...orderedList,
- content: 'list_item+',
- group: 'block',
- attrs: {
- bulletStyle: { default: "upper-alpha" },
- },
- toDOM(node: Node<any>) {
- return ['ol', { style: `list-style: ${node.attrs.bulletStyle}` }, 0]
- }
- },
- roman_list: {
- ...orderedList,
- content: 'list_item+',
- group: 'block',
- attrs: {
- bulletStyle: { default: "lower-roman" },
- },
- toDOM(node: Node<any>) {
- return ['ol', { style: `list-style: ${node.attrs.bulletStyle}` }, 0]
+ const bs = node.attrs.bulletStyle;
+ const decMap = bs === "indent1" ? "decimal" : bs === "indent2" ? "decimal2" : bs === "indent3" ? "decimal3" : bs === "indent4" ? "decimal4" : "";
+ const multiMap = bs === "indent1" ? "decimal" : bs === "indent2" ? "upper-alpha" : bs === "indent3" ? "lower-roman" : bs === "indent4" ? "lower-alpha" : "";
+ let map = node.attrs.mapStyle === "decimal" ? decMap : multiMap;
+ for (let i = 0; i < node.childCount; i++) node.child(i).attrs.className = map;
+ return ['ol', { class: `${map}-ol`, style: `list-style: none;` }, 0];
+ //return ['ol', { class: `${node.attrs.bulletStyle}`, style: `list-style: ${node.attrs.bulletStyle};`, 0]
}
},
//this doesn't currently work for some reason
@@ -220,9 +195,10 @@ export const nodes: { [index: string]: NodeSpec } = {
content: 'list_item+',
group: 'block',
// parseDOM: [{ tag: "ul" }, { style: 'list-style-type=disc' }],
- // toDOM() { return ['ol', {
- // style: 'list-type: hebrew'
- // }] }
+ toDOM(node: Node<any>) {
+ for (let i = 0; i < node.childCount; i++) node.child(i).attrs.className = "";
+ return ['ul', 0];
+ }
},
//bullet_list: {
@@ -234,8 +210,14 @@ export const nodes: { [index: string]: NodeSpec } = {
//select: state => true,
// },
list_item: {
+ attrs: {
+ className: { default: "" }
+ },
...listItem,
- content: 'paragraph block*'
+ content: 'paragraph block*',
+ toDOM(node: any) {
+ return ["li", { class: node.attrs.className }, 0];
+ }
},
};
@@ -268,7 +250,7 @@ export const marks: { [index: string]: MarkSpec } = {
// :: MarkSpec An emphasis mark. Rendered as an `<em>` element.
// Has parse rules that also match `<i>` and `font-style: italic`.
em: {
- parseDOM: [{ tag: "i" }, { tag: "em" }, { style: "font-style=italic" }],
+ parseDOM: [{ tag: "i" }, { tag: "em" }, { style: "font-style: italic" }],
toDOM() { return emDOM; }
},
@@ -320,6 +302,17 @@ export const marks: { [index: string]: MarkSpec } = {
toDOM: () => ['sup']
},
+ mbulletType: {
+ attrs: {
+ bulletType: { default: "decimal" }
+ },
+ toDOM(node: any) {
+ return ['span', {
+ style: `background: ${node.attrs.bulletType === "decimal" ? "yellow" : node.attrs.bulletType === "upper-alpha" ? "blue" : "green"}`
+ }];
+ }
+ },
+
highlight: {
parseDOM: [{ style: 'color: blue' }],
toDOM() {
@@ -338,6 +331,28 @@ export const marks: { [index: string]: MarkSpec } = {
}
},
+ // the id of the user who entered the text
+ user_mark: {
+ attrs: {
+ userid: { default: "" },
+ hide_users: { default: [] },
+ opened: { default: true },
+ modified: { default: "when?" }
+ },
+ group: "inline",
+ inclusive: false,
+ toDOM(node: any) {
+ let hideUsers = node.attrs.hide_users;
+ let hidden = hideUsers.indexOf(node.attrs.userid) !== -1 || (hideUsers.length === 0 && node.attrs.userid !== Doc.CurrentUserEmail);
+ return hidden ?
+ (node.attrs.opened ?
+ ['span', { class: "userMarkOpen" }, 0] :
+ ['span', { class: "userMark" }, ['span', { style: "font-size:2" }, 0]]
+ ) :
+ ['span', 0];
+ }
+ },
+
// :: MarkSpec Code font mark. Represented as a `<code>` element.
code: {
@@ -413,7 +428,6 @@ export const marks: { [index: string]: MarkSpec } = {
attrs: {
fontSize: { default: 10 }
},
- inclusive: false,
parseDOM: [{ style: 'font-size: 10px;' }],
toDOM: (node) => ['span', {
style: `font-size: ${node.attrs.fontSize}px;`
@@ -592,6 +606,8 @@ export class SummarizedView {
attrs.textslice = newSelection.content().toJSON();
view.dispatch(view.state.tr.setNodeMarkup(y, undefined, attrs));
view.dispatch(view.state.tr.setSelection(newSelection).deleteSelection(view.state, () => { }));
+ let marks = view.state.storedMarks.filter((m: any) => m.type !== view.state.schema.marks.highlight);
+ view.state.storedMarks = marks;
self._collapsed.textContent = "㊉";
} else {
// node.attrs.visibility = !node.attrs.visibility;
diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx
index 4eaee35d7..eda5fe09c 100644
--- a/src/client/util/TooltipTextMenu.tsx
+++ b/src/client/util/TooltipTextMenu.tsx
@@ -28,11 +28,11 @@ export class TooltipTextMenu {
private view: EditorView;
private fontStyles: MarkType[];
private fontSizes: MarkType[];
- private listTypes: NodeType[];
+ private listTypes: (NodeType | any)[];
private editorProps: FieldViewProps & FormattedTextBoxProps;
private fontSizeToNum: Map<MarkType, number>;
private fontStylesToName: Map<MarkType, string>;
- private listTypeToIcon: Map<NodeType, string>;
+ private listTypeToIcon: Map<NodeType | any, string>;
//private link: HTMLAnchorElement;
private wrapper: HTMLDivElement;
private extras: HTMLDivElement;
@@ -165,16 +165,22 @@ export class TooltipTextMenu {
this.fontSizeToNum.set(schema.marks.p48, 48);
this.fontSizeToNum.set(schema.marks.p72, 72);
this.fontSizeToNum.set(schema.marks.pFontSize, 10);
- this.fontSizeToNum.set(schema.marks.pFontSize, 10);
+ // this.fontSizeToNum.set(schema.marks.pFontSize, 12);
+ // this.fontSizeToNum.set(schema.marks.pFontSize, 14);
+ // this.fontSizeToNum.set(schema.marks.pFontSize, 16);
+ // this.fontSizeToNum.set(schema.marks.pFontSize, 18);
+ // this.fontSizeToNum.set(schema.marks.pFontSize, 20);
+ // this.fontSizeToNum.set(schema.marks.pFontSize, 24);
+ // this.fontSizeToNum.set(schema.marks.pFontSize, 32);
+ // this.fontSizeToNum.set(schema.marks.pFontSize, 48);
+ // this.fontSizeToNum.set(schema.marks.pFontSize, 72);
this.fontSizes = Array.from(this.fontSizeToNum.keys());
//list types
this.listTypeToIcon = new Map();
this.listTypeToIcon.set(schema.nodes.bullet_list, ":");
- this.listTypeToIcon.set(schema.nodes.ordered_list, "1)");
- this.listTypeToIcon.set(schema.nodes.alphabet_list, "a)");
- this.listTypeToIcon.set(schema.nodes.cap_alphabet_list, "A)");
- this.listTypeToIcon.set(schema.nodes.roman_list, "i.");
+ this.listTypeToIcon.set(schema.nodes.ordered_list.create({ mapStyle: "decimal" }), "1.1");
+ this.listTypeToIcon.set(schema.nodes.ordered_list.create({ mapStyle: "multi" }), "1.A");
// this.listTypeToIcon.set(schema.nodes.bullet_list, "⬜");
this.listTypes = Array.from(this.listTypeToIcon.keys());
@@ -509,10 +515,28 @@ export class TooltipTextMenu {
//remove all node typeand apply the passed-in one to the selected text
changeToNodeType(nodeType: NodeType | undefined, view: EditorView) {
- //remove old
- liftListItem(schema.nodes.list_item)(view.state, view.dispatch);
- if (nodeType) { //add new
+ //remove oldif (nodeType) { //add new
+ if (nodeType === schema.nodes.bullet_list) {
wrapInList(nodeType)(view.state, view.dispatch);
+ } else {
+ var ref = view.state.selection;
+ var range = ref.$from.blockRange(ref.$to);
+ var marks = view.state.storedMarks || (view.state.selection.$to.parentOffset && view.state.selection.$from.marks());
+ wrapInList(schema.nodes.ordered_list)(view.state, (tx2: any) => {
+ const resolvedPos = tx2.doc.resolve(Math.round((range!.start + range!.end) / 2));
+ let path = resolvedPos.path;
+ for (let i = path.length - 1; i > 0; i--) {
+ if (path[i].type === schema.nodes.ordered_list) {
+ path[i].attrs.bulletStyle = "indent1";
+ path[i].attrs.mapStyle = (nodeType as any).attrs.mapStyle;
+ break;
+ }
+ }
+ marks && tx2.ensureMarks([...marks]);
+ marks && tx2.setStoredMarks([...marks]);
+
+ view.dispatch(tx2);
+ });
}
}