diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/util/ProsemirrorExampleTransfer.ts | 74 | ||||
-rw-r--r-- | src/client/util/RichTextSchema.tsx | 72 | ||||
-rw-r--r-- | src/client/util/TooltipTextMenu.tsx | 3 | ||||
-rw-r--r-- | src/client/views/DocumentDecorations.tsx | 17 | ||||
-rw-r--r-- | src/client/views/MainOverlayTextBox.tsx | 14 | ||||
-rw-r--r-- | src/client/views/collections/CollectionStackingView.tsx | 3 | ||||
-rw-r--r-- | src/client/views/collections/CollectionStackingViewFieldColumn.tsx | 2 | ||||
-rw-r--r-- | src/client/views/nodes/FormattedTextBox.scss | 18 |
8 files changed, 107 insertions, 96 deletions
diff --git a/src/client/util/ProsemirrorExampleTransfer.ts b/src/client/util/ProsemirrorExampleTransfer.ts index 3cdfba59a..8b6936748 100644 --- a/src/client/util/ProsemirrorExampleTransfer.ts +++ b/src/client/util/ProsemirrorExampleTransfer.ts @@ -79,43 +79,43 @@ export default function buildKeymap<S extends Schema<any>>(schema: S, mapKeys?: bind("Mod-s", TooltipTextMenu.insertStar); + // let nodeTypeMark = depth == 2 ? "upper-alpha" : depth == 4 ? "lower-roman" : depth == 6 ? "lower-alpha" : "decimal"; + let nodeTypeMark = (depth: number) => { return depth == 2 ? "decimal2" : depth == 4 ? "decimal3" : depth == 6 ? "decimal4" : "decimal" } - let levelMark = (depth: number) => { - let p10 = schema.marks.pFontSize.create({ fontSize: 10 }); - let p14 = schema.marks.pFontSize.create({ fontSize: 14 }); - let p18 = schema.marks.pFontSize.create({ fontSize: 18 }); - let p24 = schema.marks.pFontSize.create({ fontSize: 24 }); - return depth == 0 ? p24 : depth == 2 ? p18 : depth == 4 ? p14 : p10; - } 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; - let nodeTypeMark = depth == 2 ? schema.marks.mcap_alphabet_list : depth == 4 ? schema.marks.mroman_list : depth == 6 ? schema.marks.malphabet_list : schema.marks.mordered_list; - let created = levelMark(depth); - if (!sinkListItem(nodeType /*schema.nodes.list_item */)(state, (tx2: Transaction) => { + if (!sinkListItem(schema.nodes.list_item)(state, (tx2: Transaction) => { const resolvedPos = tx2.doc.resolve(range!.start); - let ns = new NodeSelection(resolvedPos); - let tx3 = tx2.addMark(ns.from - 1, ns.to, created).addMark(ns.from - 1, ns.to, nodeTypeMark as any).setSelection(TextSelection.create(tx2.doc, ns.to - (depth == 0 ? 3 : 1))); - marks && tx3.ensureMarks([...marks, created]); - marks && tx3.setStoredMarks([...marks, created]); - - dispatch(tx3); + let path = (resolvedPos as any).path as any; + 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); })) { let sxf = state.tr.setSelection(TextSelection.create(state.doc, range!.start, range!.end)); let newstate = state.applyTransaction(sxf); - if (!wrapInList(nodeType)(newstate.state, (tx2: Transaction) => { - const resolvedPos = tx2.doc.resolve(range!.start); - let ns = new TextSelection(resolvedPos, tx2.doc.resolve(range!.end + 1)); // new NodeSelection(resolvedPos); - let tx3 = tx2.setSelection(ns).removeMark(ns.from, ns.to, created).addMark(ns.from, ns.to, created).setSelection(TextSelection.create(tx2.doc, ns.to)); - let tx4 = depth > 0 ? tx3.insertText(" ").setSelection(TextSelection.create(tx2.doc, ns.to - 2, ns.to + 2)).deleteSelection() : tx3; - marks && tx4.ensureMarks([...marks, created]); - marks && tx4.setStoredMarks([...marks, created]); - - dispatch(tx4); + 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 as any; + 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"); } @@ -127,18 +127,22 @@ export default function buildKeymap<S extends Schema<any>>(schema: S, mapKeys?: var ref = state.selection; var range = ref.$from.blockRange(ref.$to); var marks = state.storedMarks || (state.selection.$to.parentOffset && state.selection.$from.marks()); - let created = levelMark(range && range.depth ? range.depth - 4 : 0); + 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 nodeIndex = resolvedPos.pos - (resolvedPos.nodeBefore && resolvedPos.nodeBefore.type.name === "text" ? resolvedPos.nodeBefore!.nodeSize : 0); - let ns = new NodeSelection(tx2.doc.resolve(nodeIndex)); - if (resolvedPos.nodeAfter && resolvedPos.nodeAfter.type.name === "list_item") - ns = new NodeSelection(tx2.doc.resolve(nodeIndex + 1)); - let tx3 = tx2.setSelection(ns).removeMark(ns.from, ns.to, created).addMark(ns.from, ns.to, created).setSelection(TextSelection.create(tx2.doc, ns.to)); - marks && tx3.ensureMarks([...marks, created]); - marks && tx3.setStoredMarks([...marks, created]); - dispatch(tx3); + + let path = (resolvedPos as any).path as any; + 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); } diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx index f128162c2..bbced3b77 100644 --- a/src/client/util/RichTextSchema.tsx +++ b/src/client/util/RichTextSchema.tsx @@ -175,43 +175,12 @@ export const nodes: { [index: string]: NodeSpec } = { content: 'list_item+', group: 'block', attrs: { - bulletStyle: { default: "decimal" }, + bulletStyle: { default: "" }, }, 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] + for (let i = 0; i < node.childCount; i++) node.child(i).attrs.className = node.attrs.bulletStyle; + return ['ol', { class: `${node.attrs.bulletStyle}-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 +189,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 +204,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]; + } }, }; @@ -267,7 +243,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; } }, @@ -319,13 +295,15 @@ export const marks: { [index: string]: MarkSpec } = { toDOM: () => ['sup'] }, - malphabet_list: { - }, - mcap_alphabet_list: { - }, - mroman_list: { - }, - mo_list: { + 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: { diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx index 77396c829..7f6ba3aac 100644 --- a/src/client/util/TooltipTextMenu.tsx +++ b/src/client/util/TooltipTextMenu.tsx @@ -180,9 +180,6 @@ 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.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.bullet_list, "⬜"); this.listTypes = Array.from(this.listTypeToIcon.keys()); diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 579806a89..e93893586 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -200,14 +200,22 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> this.onBackgroundUp(e); } + @observable _forceUpdate = 0; + _lastBox = { x: 0, y: 0, r: 0, b: 0 } @computed get Bounds(): { x: number, y: number, b: number, r: number } { - return SelectionManager.SelectedDocuments().reduce((bounds, documentView) => { + let x = this._forceUpdate; + this._lastBox = SelectionManager.SelectedDocuments().reduce((bounds, documentView) => { if (documentView.props.renderDepth === 0 || Doc.AreProtosEqual(documentView.props.Document, CurrentUserUtils.UserDocument)) { return bounds; } let transform = (documentView.props.ScreenToLocalTransform().scale(documentView.props.ContentScaling())).inverse(); + if (transform.TranslateX === 0 && transform.TranslateY === 0) { + setTimeout(action(() => this._forceUpdate++), 0); // bcz: fix CollectionStackingView's getTransform() somehow... + return this._lastBox; + } + var [sptX, sptY] = transform.transformPoint(0, 0); let [bptX, bptY] = transform.transformPoint(documentView.props.PanelWidth(), documentView.props.PanelHeight()); return { @@ -215,6 +223,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> r: Math.max(bptX, bounds.r), b: Math.max(bptY, bounds.b) }; }, { x: Number.MAX_VALUE, y: Number.MAX_VALUE, r: Number.MIN_VALUE, b: Number.MIN_VALUE }); + return this._lastBox; } onBackgroundDown = (e: React.PointerEvent): void => { @@ -821,11 +830,7 @@ export class DocumentDecorations extends React.Component<{}, { value: string }> let templates: Map<Template, boolean> = new Map(); Array.from(Object.values(Templates.TemplateList)).map(template => { - let sorted = SelectionManager.ViewsSortedVertically(); // slice().sort((doc1, doc2) => { - // if (NumCast(doc1.props.Document.y) > NumCast(doc2.props.Document.x)) return 1; - // if (NumCast(doc1.props.Document.x) < NumCast(doc2.props.Document.x)) return -1; - // return 0; - // }); + let sorted = SelectionManager.ViewsSortedVertically(); let docTemps = sorted.reduce((res: string[], doc: DocumentView, i) => { let temps = doc.props.Document.templates; if (temps instanceof List) { diff --git a/src/client/views/MainOverlayTextBox.tsx b/src/client/views/MainOverlayTextBox.tsx index e95e5b777..65a291d99 100644 --- a/src/client/views/MainOverlayTextBox.tsx +++ b/src/client/views/MainOverlayTextBox.tsx @@ -2,7 +2,7 @@ import { action, observable, reaction, trace } from 'mobx'; import { observer } from 'mobx-react'; import "normalize.css"; import * as React from 'react'; -import { Doc } from '../../new_fields/Doc'; +import { Doc, DocListCast } from '../../new_fields/Doc'; import { BoolCast } from '../../new_fields/Types'; import { emptyFunction, returnTrue, returnZero, Utils, returnOne } from '../../Utils'; import { DragManager } from '../util/DragManager'; @@ -42,13 +42,23 @@ export class MainOverlayTextBox extends React.Component<MainOverlayTextBoxProps> return this._textBox && this._textBox.setFontColor(color); } - constructor(props: MainOverlayTextBoxProps) { super(props); this._textProxyDiv = React.createRef(); MainOverlayTextBox.Instance = this; reaction(() => FormattedTextBox.InputBoxOverlay, (box?: FormattedTextBox) => { + const tb = this._textBox; + const container = tb && tb.props.ContainingCollectionView; + if (tb && container) { // this hacky section is needed to force the edited text box to completely recreate itself since things can get out synch -- specifically, the bullet label state which is computed when the dom elements are created + var dl = DocListCast(container.props.Document[container.props.fieldKey]); + let dli = dl.indexOf(tb.props.Document); + if (dli !== -1) { + let prev = dli > 0 ? dl[dli - 1] : undefined; + tb.props.removeDocument && tb.props.removeDocument(tb.props.Document); + setTimeout(() => Doc.AddDocToList(container.props.Document, container.props.fieldKey, tb.props.Document, prev, false, dli === 0), 0); + } + } this._textBox = box; if (box) { this.ChromeHeight = box.props.ChromeHeight; diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx index 6f22f2d2a..97b31bf2a 100644 --- a/src/client/views/collections/CollectionStackingView.tsx +++ b/src/client/views/collections/CollectionStackingView.tsx @@ -278,7 +278,8 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) { } getDocTransform(doc: Doc, dref: HTMLDivElement) { - let y = this._scroll; + if (!dref) return Transform.Identity(); + let y = this._scroll; // required for document decorations to update when the text box container is scrolled let { scale, translateX, translateY } = Utils.GetScreenTransform(dref); let outerXf = Utils.GetScreenTransform(this._masonryGridRef!); let offset = this.props.ScreenToLocalTransform().transformDirection(outerXf.translateX - translateX, outerXf.translateY - translateY); diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx index f30e99362..bc4fe7dd7 100644 --- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx +++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx @@ -2,7 +2,7 @@ import React = require("react"); import { library } from '@fortawesome/fontawesome-svg-core'; import { faPalette } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { action, observable } from "mobx"; +import { action, observable, trace } from "mobx"; import { observer } from "mobx-react"; import { Doc, WidthSym } from "../../../new_fields/Doc"; import { Id } from "../../../new_fields/FieldSymbols"; diff --git a/src/client/views/nodes/FormattedTextBox.scss b/src/client/views/nodes/FormattedTextBox.scss index 1b537cc52..e93ceda21 100644 --- a/src/client/views/nodes/FormattedTextBox.scss +++ b/src/client/views/nodes/FormattedTextBox.scss @@ -65,4 +65,20 @@ .em { font-style: italic; -}
\ No newline at end of file +} + +ol { counter-reset: deci 0;} +.decimal-ol { counter-reset: deci 0; p { display: inline }; font-size: 24 } +.decimal2-ol {counter-reset: deci2; p { display: inline }; font-size: 18 } +.decimal3-ol {counter-reset: deci3; p { display: inline }; font-size: 14 } +.decimal4-ol {counter-reset: deci4; p { display: inline }; font-size: 10 } +.upper-alpha-ol {counter-reset: ualph; p { display: inline }; font-size: 18 } +.lower-roman-ol {counter-reset: lroman; p { display: inline }; font-size: 14; } +.lower-alpha-ol {counter-reset: lalpha; p { display: inline }; font-size: 10;} +.decimal:before { content: counter(deci) " "; counter-increment: deci; display:inline-block; width: 30} +.decimal2:before { content: counter(deci) "." counter(deci2) " "; counter-increment: deci2; display:inline-block; width: 35} +.decimal3:before { content: counter(deci) "." counter(deci2) "." counter(deci3) " "; counter-increment: deci3; display:inline-block; width: 35} +.decimal4:before { content: counter(deci) "." counter(deci2) "." counter(deci3) "." counter(deci4) " "; counter-increment: deci4; display:inline-block; width: 40} +.upper-alpha:before { content: counter(deci) "." counter(ualph, upper-alpha) " "; counter-increment: ualph; display:inline-block; width: 35 } +.lower-roman:before { content: counter(deci) "." counter(ualph, upper-alpha) "." counter(lroman, lower-roman) " "; counter-increment: lroman;display:inline-block; width: 50 } +.lower-alpha:before { content: counter(deci) "." counter(ualph, upper-alpha) "." counter(lroman, lower-roman) "." counter(lalpha, lower-alpha)" "; counter-increment: lalpha; display:inline-block; width: 35} |