From 29f9cedd937697c56ce3b400931b26c82a23721d Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Mon, 29 Jun 2020 00:21:07 -0400 Subject: changed a lot of collection keys to start with "_" -- particularly for Stacking and Schema views. Also added filtering to facet filters. enabled facet filter for sidebar library. --- src/client/views/nodes/formattedText/RichTextRules.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/client/views/nodes/formattedText/RichTextRules.ts') diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts index ba3230801..6a85e3b7c 100644 --- a/src/client/views/nodes/formattedText/RichTextRules.ts +++ b/src/client/views/nodes/formattedText/RichTextRules.ts @@ -275,7 +275,7 @@ export class RichTextRules { if (!fieldKey) { if (docid) { DocServer.GetRefField(docid).then(docx => { - const target = ((docx instanceof Doc) && docx) || Docs.Create.FreeformDocument([], { title: docid, _width: 500, _height: 500, _LODdisable: true, }, docid); + const target = ((docx instanceof Doc) && docx) || Docs.Create.FreeformDocument([], { title: docid, _width: 500, _height: 500, }, docid); DocUtils.Publish(target, docid, returnFalse, returnFalse); DocUtils.MakeLink({ doc: this.Document }, { doc: target }, "portal to"); }); @@ -305,7 +305,7 @@ export class RichTextRules { if (!fieldKey && !docid) return state.tr; docid && DocServer.GetRefField(docid).then(docx => { if (!(docx instanceof Doc && docx)) { - const docx = Docs.Create.FreeformDocument([], { title: docid, _width: 500, _height: 500, _LODdisable: true }, docid); + const docx = Docs.Create.FreeformDocument([], { title: docid, _width: 500, _height: 500 }, docid); DocUtils.Publish(docx, docid, returnFalse, returnFalse); } }); -- cgit v1.2.3-70-g09d2 From 6af97864aabe89153487d37bf78391ff525deadd Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Tue, 30 Jun 2020 23:57:47 -0400 Subject: added left/right/center justify text buttons. changed unpinned text menu --- src/client/views/MainView.tsx | 4 +- .../formattedText/ProsemirrorExampleTransfer.ts | 24 +++--------- .../views/nodes/formattedText/RichTextMenu.tsx | 45 +++++++++++++++++----- .../views/nodes/formattedText/RichTextRules.ts | 3 -- 4 files changed, 44 insertions(+), 32 deletions(-) (limited to 'src/client/views/nodes/formattedText/RichTextRules.ts') diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 200486279..f6db1af66 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -5,7 +5,7 @@ import { faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt, faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter, faLongArrowAltRight, faMicrophone, faMousePointer, faMusic, faObjectGroup, faPause, faPen, faPenNib, faPhone, faPlay, faPortrait, faRedoAlt, faStamp, faStickyNote, - faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faArrowsAlt, faQuoteLeft, faSortAmountDown + faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faArrowsAlt, faQuoteLeft, faSortAmountDown, faAlignLeft, faAlignCenter, faAlignRight } from '@fortawesome/free-solid-svg-icons'; import { ANTIMODEMENU_HEIGHT } from './globalCssVariables.scss'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; @@ -142,7 +142,7 @@ export class MainView extends React.Component { faQuestionCircle, faArrowLeft, faArrowRight, faArrowDown, faArrowUp, faBolt, faBullseye, faCaretUp, faCat, faCheck, faChevronRight, faClipboard, faClone, faCloudUploadAlt, faCommentAlt, faCompressArrowsAlt, faCut, faEllipsisV, faEraser, faExclamation, faFileAlt, faFileAudio, faFilePdf, faFilm, faFilter, faFont, faGlobeAsia, faHighlighter, faLongArrowAltRight, faMicrophone, faMousePointer, faMusic, faObjectGroup, faPause, faPen, faPenNib, faPhone, faPlay, faPortrait, faRedoAlt, faStamp, faStickyNote, faTrashAlt, faAngleRight, faBell, - faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faArrowsAlt, faQuoteLeft, faSortAmountDown); + faThumbtack, faTree, faTv, faUndoAlt, faVideo, faAsterisk, faBrain, faImage, faPaintBrush, faTimes, faEye, faArrowsAlt, faQuoteLeft, faSortAmountDown, faAlignLeft, faAlignCenter, faAlignRight); this.initEventListeners(); this.initAuthenticationRouters(); } diff --git a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts index 1bbcb9fa8..9d69f4be7 100644 --- a/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts +++ b/src/client/views/nodes/formattedText/ProsemirrorExampleTransfer.ts @@ -1,7 +1,6 @@ import { chainCommands, exitCode, joinDown, joinUp, lift, deleteSelection, joinBackward, selectNodeBackward, setBlockType, splitBlockKeepMarks, toggleMark, wrapIn, newlineInCode } from "prosemirror-commands"; import { liftTarget } from "prosemirror-transform"; import { redo, undo } from "prosemirror-history"; -import { undoInputRule } from "prosemirror-inputrules"; import { Schema } from "prosemirror-model"; import { liftListItem, sinkListItem } from "./prosemirrorPatches.js"; import { splitListItem, wrapInList, } from "prosemirror-schema-list"; @@ -12,7 +11,6 @@ import { Doc, DataSym } from "../../../../fields/Doc"; import { FormattedTextBox } from "./FormattedTextBox"; import { Id } from "../../../../fields/FieldSymbols"; import { Docs } from "../../../documents/Documents"; -import { update } from "lodash"; const mac = typeof navigator !== "undefined" ? /Mac/.test(navigator.platform) : false; @@ -215,10 +213,13 @@ export default function buildKeymap>(schema: S, props: any marks && tx3.setStoredMarks([...marks]); dispatch(tx3); })) { + const fromattrs = state.selection.$from.node().attrs; if (!splitBlockKeepMarks(state, (tx3: Transaction) => { - splitMetadata(marks, tx3); - if (!liftListItem(schema.nodes.list_item)(tx3, dispatch as ((tx: Transaction>) => void))) { - dispatch(tx3); + const tonode = tx3.selection.$to.node(); + const tx4 = tx3.setNodeMarkup(tx3.selection.to - 1, tonode.type, fromattrs, tonode.marks); + splitMetadata(marks, tx4); + if (!liftListItem(schema.nodes.list_item)(tx4, dispatch as ((tx: Transaction>) => void))) { + dispatch(tx4); } })) { return false; @@ -281,19 +282,6 @@ export default function buildKeymap>(schema: S, props: any return false; }); - // bind("^", (state: EditorState, dispatch: (tx: Transaction) => void) => { - // let newNode = schema.nodes.footnote.create({}); - // if (dispatch && state.selection.from === state.selection.to) { - // let tr = state.tr; - // tr.replaceSelectionWith(newNode); // replace insertion with a footnote. - // dispatch(tr.setSelection(new NodeSelection( // select the footnote node to open its display - // tr.doc.resolve( // get the location of the footnote node by subtracting the nodesize of the footnote from the current insertion point anchor (which will be immediately after the footnote node) - // tr.selection.anchor - tr.selection.$anchor.nodeBefore!.nodeSize)))); - // return true; - // } - // return false; - // }); - return keys; } diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx index 839943aac..a06fcec9a 100644 --- a/src/client/views/nodes/formattedText/RichTextMenu.tsx +++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx @@ -412,6 +412,28 @@ export default class RichTextMenu extends AntimodeMenu { dispatch?.(tr.replaceSelectionWith(newNode).removeMark(tr.selection.from - 1, tr.selection.from, mark)); return true; } + alignCenter = (state: EditorState, dispatch: any) => { + return this.alignParagraphs(state, "center", dispatch); + } + alignLeft = (state: EditorState, dispatch: any) => { + return this.alignParagraphs(state, "left", dispatch); + } + alignRight = (state: EditorState, dispatch: any) => { + return this.alignParagraphs(state, "right", dispatch); + } + + alignParagraphs(state: EditorState, align: "left" | "right" | "center", dispatch: any) { + var tr = state.tr; + state.doc.nodesBetween(state.selection.from, state.selection.to, (node, pos, parent, index) => { + if (node.type === schema.nodes.paragraph) { + tr = tr.setNodeMarkup(pos, node.type, { ...node.attrs, align }, node.marks); + return false; + } + return true; + }); + dispatch?.(tr); + return true; + } insertBlockquote(state: EditorState, dispatch: any) { const path = (state.selection.$from as any).path; @@ -768,18 +790,21 @@ export default class RichTextMenu extends AntimodeMenu { TraceMobx(); const row1 =
{[ !this.collapsed ? this.getDragger() : (null), - this.createButton("bold", "Bold", this.boldActive, toggleMark(schema.marks.strong)), - this.createButton("italic", "Italic", this.italicsActive, toggleMark(schema.marks.em)), - this.createButton("underline", "Underline", this.underlineActive, toggleMark(schema.marks.underline)), - this.createButton("strikethrough", "Strikethrough", this.strikethroughActive, toggleMark(schema.marks.strikethrough)), - this.createButton("superscript", "Superscript", this.superscriptActive, toggleMark(schema.marks.superscript)), - this.createButton("subscript", "Subscript", this.subscriptActive, toggleMark(schema.marks.subscript)), + !this.Pinned ? (null) : <> {[ + this.createButton("bold", "Bold", this.boldActive, toggleMark(schema.marks.strong)), + this.createButton("italic", "Italic", this.italicsActive, toggleMark(schema.marks.em)), + this.createButton("underline", "Underline", this.underlineActive, toggleMark(schema.marks.underline)), + this.createButton("strikethrough", "Strikethrough", this.strikethroughActive, toggleMark(schema.marks.strikethrough)), + this.createButton("superscript", "Superscript", this.superscriptActive, toggleMark(schema.marks.superscript)), + this.createButton("subscript", "Subscript", this.subscriptActive, toggleMark(schema.marks.subscript)), + ]}, this.createColorButton(), this.createHighlighterButton(), this.createLinkButton(), this.createBrushButton(), - this.createButton("sort-amount-down", "Summarize", undefined, this.insertSummarizer), - this.createButton("quote-left", "Blockquote", undefined, this.insertBlockquote), + this.createButton("align-left", "Align Left", undefined, this.alignLeft), + this.createButton("align-center", "Align Center", undefined, this.alignCenter), + this.createButton("align-right", "Align Right", undefined, this.alignRight), ]}
; const row2 =
@@ -787,7 +812,9 @@ export default class RichTextMenu extends AntimodeMenu {
{[this.createMarksDropdown(this.activeFontSize, this.fontSizeOptions, "font size"), this.createMarksDropdown(this.activeFontFamily, this.fontFamilyOptions, "font family"), - this.createNodesDropdown(this.activeListType, this.listTypeOptions, "nodes")]} + this.createNodesDropdown(this.activeListType, this.listTypeOptions, "nodes"), + this.createButton("sort-amount-down", "Summarize", undefined, this.insertSummarizer), + this.createButton("quote-left", "Blockquote", undefined, this.insertBlockquote),]}
{/*
diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts index 6a85e3b7c..612a824fc 100644 --- a/src/client/views/nodes/formattedText/RichTextRules.ts +++ b/src/client/views/nodes/formattedText/RichTextRules.ts @@ -315,8 +315,6 @@ export class RichTextRules { return node ? state.tr.replaceRangeWith(start, end, dashDoc).setStoredMarks([...node.marks, ...(sm ? sm : [])]) : state.tr; }), - - // create an inline view of a tag stored under the '#' field new InputRule( new RegExp(/#([a-zA-Z_\-]+[a-zA-Z_;\-0-9]*)\s$/), @@ -374,7 +372,6 @@ export class RichTextRules { new InputRule( new RegExp(/%\)/), (state, match, start, end) => { - return state.tr.deleteRange(start, end).removeStoredMark(state.schema.marks.summarizeInclusive.create()); }), -- cgit v1.2.3-70-g09d2 From 19a48bfe9b2087d23ab6bbb384f8edc18ed07d81 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Wed, 1 Jul 2020 21:26:35 -0400 Subject: renamed link to linkAnchor and allHrefs to allLinks in rich text code --- .../views/nodes/formattedText/FormattedTextBox.tsx | 36 +++++++++++----------- .../formattedText/FormattedTextBoxComment.tsx | 4 +-- .../views/nodes/formattedText/RichTextMenu.tsx | 18 +++++------ .../views/nodes/formattedText/RichTextRules.ts | 2 +- src/client/views/nodes/formattedText/marks_rts.ts | 20 ++++++------ src/fields/RichTextUtils.ts | 2 +- 6 files changed, 41 insertions(+), 41 deletions(-) (limited to 'src/client/views/nodes/formattedText/RichTextRules.ts') diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index f32c17563..9c7c46ae9 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -149,24 +149,24 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp public RemoveLinkFromDoc(linkDoc?: Doc) { const state = this._editorView?.state; if (state && linkDoc && this._editorView) { - var allHrefs: any[] = []; + var allLinks: any[] = []; state.doc.nodesBetween(0, state.doc.nodeSize - 2, (node: any, pos: number, parent: any) => { const foundMark = findLinkMark(node.marks); - const newHrefs = foundMark?.attrs.allHrefs.filter((a: any) => a.href.includes(linkDoc[Id])) || []; - allHrefs = newHrefs.length ? newHrefs : allHrefs; + const newHrefs = foundMark?.attrs.allLinks.filter((a: any) => a.href.includes(linkDoc[Id])) || []; + allLinks = newHrefs.length ? newHrefs : allLinks; return true; }); - if (allHrefs.length) { - this._editorView.dispatch(removeMarkWithAttrs(state.tr, 0, state.doc.nodeSize - 2, state.schema.marks.link, { allHrefs })); + if (allLinks.length) { + this._editorView.dispatch(removeMarkWithAttrs(state.tr, 0, state.doc.nodeSize - 2, state.schema.marks.linkAnchor, { allLinks })); } } } // removes all the specified link referneces from the selection. // NOTE: as above, this won't work correctly if there are marks with overlapping but not exact sets of link references. - public RemoveLinkFromSelection(allHrefs: { href: string, title: string, linkId: string, targetId: string }[]) { + public RemoveLinkFromSelection(allLinks: { href: string, title: string, linkId: string, targetId: string }[]) { const state = this._editorView?.state; if (state && this._editorView) { - this._editorView.dispatch(removeMarkWithAttrs(state.tr, state.selection.from, state.selection.to, state.schema.marks.link, { allHrefs })); + this._editorView.dispatch(removeMarkWithAttrs(state.tr, state.selection.from, state.selection.to, state.schema.marks.link, { allLinks })); } } @@ -206,8 +206,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp this.linkOnDeselect.set(key, value); const id = Utils.GenerateDeterministicGuid(this.dataDoc[Id] + key); - const allHrefs = [{ href: Utils.prepend("/doc/" + id), title: value, targetId: id }]; - const link = this._editorView.state.schema.marks.link.create({ allHrefs, location: "onRight", title: value }); + const allLinks = [{ href: Utils.prepend("/doc/" + id), title: value, targetId: id }]; + const link = this._editorView.state.schema.marks.linkAnchor.create({ allLinks, location: "onRight", title: value }); const mval = this._editorView.state.schema.marks.metadataVal.create(); const offset = (tx.selection.to === range!.end - 1 ? -1 : 0); tx = tx.addMark(textEndSelection - value.length + offset, textEndSelection, link).addMark(textEndSelection - value.length + offset, textEndSelection, mval); @@ -275,8 +275,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp const lastSel = Math.min(flattened.length - 1, this._searchIndex); this._searchIndex = ++this._searchIndex > flattened.length - 1 ? 0 : this._searchIndex; const alink = DocUtils.MakeLink({ doc: this.rootDoc }, { doc: target }, "automatic")!; - const allHrefs = [{ href: Utils.prepend("/doc/" + alink[Id]), title: "a link", targetId: target[Id], linkId: alink[Id] }]; - const link = this._editorView.state.schema.marks.link.create({ allHrefs, title: "a link", location }); + const allLinks = [{ href: Utils.prepend("/doc/" + alink[Id]), title: "a link", targetId: target[Id], linkId: alink[Id] }]; + const link = this._editorView.state.schema.marks.linkAnchor.create({ allLinks, title: "a link", location }); this._editorView.dispatch(tr.addMark(flattened[lastSel].from, flattened[lastSel].to, link)); } } @@ -643,9 +643,9 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp let tr = state.tr.addMark(sel.from, sel.to, splitter); sel.from !== sel.to && tr.doc.nodesBetween(sel.from, sel.to, (node: any, pos: number, parent: any) => { if (node.firstChild === null && node.marks.find((m: Mark) => m.type.name === schema.marks.splitter.name)) { - const allHrefs = [{ href, title, targetId, linkId }]; - allHrefs.push(...(node.marks.find((m: Mark) => m.type.name === schema.marks.link.name)?.attrs.allHrefs ?? [])); - const link = state.schema.marks.link.create({ allHrefs, title, location, linkId }); + const allLinks = [{ href, title, targetId, linkId }]; + allLinks.push(...(node.marks.find((m: Mark) => m.type.name === schema.marks.linkAnchor.name)?.attrs.allLinks ?? [])); + const link = state.schema.marks.linkAnchor.create({ allLinks, title, location, linkId }); tr = tr.addMark(pos, pos + node.nodeSize, link); } }); @@ -766,8 +766,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp return node.copy(content.frag); } const marks = [...node.marks]; - const linkIndex = marks.findIndex(mark => mark.type === editor.state.schema.marks.link); - return linkIndex !== -1 && marks[linkIndex].attrs.allHrefs.find((item: { href: string }) => scrollToLinkID === item.href.replace(/.*\/doc\//, "")) ? node : undefined; + const linkIndex = marks.findIndex(mark => mark.type === editor.state.schema.marks.linkAnchor); + return linkIndex !== -1 && marks[linkIndex].attrs.allLinks.find((item: { href: string }) => scrollToLinkID === item.href.replace(/.*\/doc\//, "")) ? node : undefined; }; let start = 0; @@ -949,8 +949,8 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<(FieldViewProp } const marks = [...node.marks]; const linkIndex = marks.findIndex(mark => mark.type.name === "link"); - const allHrefs = [{ href: Utils.prepend(`/doc/${linkId}`), title, linkId }]; - const link = view.state.schema.mark(view.state.schema.marks.link, { allHrefs, location: "onRight", title, docref: true }); + const allLinks = [{ href: Utils.prepend(`/doc/${linkId}`), title, linkId }]; + const link = view.state.schema.mark(view.state.schema.marks.linkAnchor, { allLinks, location: "onRight", title, docref: true }); marks.splice(linkIndex === -1 ? 0 : linkIndex, 1, link); return node.mark(marks); } diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx index 90f2c0aa6..4c90b6afd 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx @@ -27,7 +27,7 @@ export function findUserMark(marks: Mark[]): Mark | undefined { return marks.find(m => m.attrs.userid); } export function findLinkMark(marks: Mark[]): Mark | undefined { - return marks.find(m => m.type === schema.marks.link); + return marks.find(m => m.type === schema.marks.linkAnchor); } export function findStartOfMark(rpos: ResolvedPos, view: EditorView, finder: (marks: Mark[]) => Mark | undefined) { let before = 0; @@ -182,7 +182,7 @@ export class FormattedTextBoxComment { state.doc.nodesBetween(state.selection.from, state.selection.to, (node: any, pos: number, parent: any) => !child && node.marks.length && (child = node)); child = child || (nbef && state.selection.$from.nodeBefore); const mark = child ? findLinkMark(child.marks) : undefined; - const href = (!mark?.attrs.docref || naft === nbef) && mark?.attrs.allHrefs.find((item: { href: string }) => item.href)?.href || forceUrl; + const href = (!mark?.attrs.docref || naft === nbef) && mark?.attrs.allLinks.find((item: { href: string }) => item.href)?.href || forceUrl; if (forceUrl || (href && child && nbef && naft && mark?.attrs.showPreview)) { FormattedTextBoxComment.tooltipText.textContent = "external => " + href; (FormattedTextBoxComment.tooltipText as any).href = href; diff --git a/src/client/views/nodes/formattedText/RichTextMenu.tsx b/src/client/views/nodes/formattedText/RichTextMenu.tsx index 6366f299d..3ec75e680 100644 --- a/src/client/views/nodes/formattedText/RichTextMenu.tsx +++ b/src/client/views/nodes/formattedText/RichTextMenu.tsx @@ -737,7 +737,7 @@ export default class RichTextMenu extends AntimodeMenu { const node = this.view.state.selection.$from.nodeAfter; const link = node && node.marks.find(m => m.type.name === "link"); if (link) { - const href = link.attrs.allHrefs.length > 0 ? link.attrs.allHrefs[0].href : undefined; + const href = link.attrs.allLinks.length > 0 ? link.attrs.allLinks[0].href : undefined; if (href) { if (href.indexOf(Utils.prepend("/doc/")) === 0) { const linkclicked = href.replace(Utils.prepend("/doc/"), "").split("?")[0]; @@ -773,27 +773,27 @@ export default class RichTextMenu extends AntimodeMenu { deleteLink = () => { if (this.view) { - const link = this.view.state.selection.$from.nodeAfter?.marks.find(m => m.type === this.view!.state.schema.marks.link); + const link = this.view.state.selection.$from.nodeAfter?.marks.find(m => m.type === this.view!.state.schema.marks.linkAnchor); if (link) { - const allHrefs = link.attrs.allHrefs.slice(); - this.TextView.RemoveLinkFromSelection(link.attrs.allHrefs); + const allLinks = link.attrs.allLinks.slice(); + this.TextView.RemoveLinkFromSelection(link.attrs.allLinks); // bcz: Argh ... this will remove the link from the document even it's anchored somewhere else in the text which happens if only part of the anchor text was selected. - allHrefs.filter((aref: any) => aref?.href.indexOf(Utils.prepend("/doc/")) === 0).forEach((aref: any) => { + allLinks.filter((aref: any) => aref?.href.indexOf(Utils.prepend("/doc/")) === 0).forEach((aref: any) => { const linkId = aref.href.replace(Utils.prepend("/doc/"), "").split("?")[0]; - linkId && DocServer.GetRefField(linkId).then(linkDoc => LinkManager.Instance.deleteLink(linkDoc as Doc)) + linkId && DocServer.GetRefField(linkId).then(linkDoc => LinkManager.Instance.deleteLink(linkDoc as Doc)); }); } } } linkExtend($start: ResolvedPos, href: string) { - const mark = this.view!.state.schema.marks.link; + const mark = this.view!.state.schema.marks.linkAnchor; let startIndex = $start.index(); let endIndex = $start.indexAfter(); - while (startIndex > 0 && $start.parent.child(startIndex - 1).marks.filter(m => m.type === mark && m.attrs.allHrefs.find((item: { href: string }) => item.href === href)).length) startIndex--; - while (endIndex < $start.parent.childCount && $start.parent.child(endIndex).marks.filter(m => m.type === mark && m.attrs.allHrefs.find((item: { href: string }) => item.href === href)).length) endIndex++; + while (startIndex > 0 && $start.parent.child(startIndex - 1).marks.filter(m => m.type === mark && m.attrs.allLinks.find((item: { href: string }) => item.href === href)).length) startIndex--; + while (endIndex < $start.parent.childCount && $start.parent.child(endIndex).marks.filter(m => m.type === mark && m.attrs.allLinks.find((item: { href: string }) => item.href === href)).length) endIndex++; let startPos = $start.start(); let endPos = startPos; diff --git a/src/client/views/nodes/formattedText/RichTextRules.ts b/src/client/views/nodes/formattedText/RichTextRules.ts index 612a824fc..ca30dde9d 100644 --- a/src/client/views/nodes/formattedText/RichTextRules.ts +++ b/src/client/views/nodes/formattedText/RichTextRules.ts @@ -279,7 +279,7 @@ export class RichTextRules { DocUtils.Publish(target, docid, returnFalse, returnFalse); DocUtils.MakeLink({ doc: this.Document }, { doc: target }, "portal to"); }); - const link = state.schema.marks.link.create({ href: Utils.prepend("/doc/" + docid), location: "onRight", title: docid, targetId: docid }); + const link = state.schema.marks.linkAnchor.create({ href: Utils.prepend("/doc/" + docid), location: "onRight", title: docid, targetId: docid }); return state.tr.deleteRange(end - 1, end).deleteRange(start, start + 2).addMark(start, end - 3, link); } return state.tr; diff --git a/src/client/views/nodes/formattedText/marks_rts.ts b/src/client/views/nodes/formattedText/marks_rts.ts index 54b61aa20..3d7d71b14 100644 --- a/src/client/views/nodes/formattedText/marks_rts.ts +++ b/src/client/views/nodes/formattedText/marks_rts.ts @@ -17,12 +17,12 @@ export const marks: { [index: string]: MarkSpec } = { return ["div", { className: "dummy" }, 0]; } }, - // :: MarkSpec A link. Has `href` and `title` attributes. `title` + // :: MarkSpec A linkAnchor. The anchor can have multiple links, where each link has an href URL and a title for use in menus and hover (Dash links have linkIDs & targetIDs). `title` // defaults to the empty string. Rendered and parsed as an `` // element. - link: { + linkAnchor: { attrs: { - allHrefs: { default: [] as { href: string, title: string, linkId: string, targetId: string }[] }, + allLinks: { default: [] as { href: string, title: string, linkId: string, targetId: string }[] }, showPreview: { default: true }, location: { default: null }, title: { default: null }, @@ -31,22 +31,22 @@ export const marks: { [index: string]: MarkSpec } = { inclusive: false, parseDOM: [{ tag: "a[href]", getAttrs(dom: any) { - return { allHrefs: [{ href: dom.getAttribute("href"), title: dom.getAttribute("title"), linkId: dom.getAttribute("linkids"), targetId: dom.getAttribute("targetids") }], location: dom.getAttribute("location"), }; + return { allLinks: [{ href: dom.getAttribute("href"), title: dom.getAttribute("title"), linkId: dom.getAttribute("linkids"), targetId: dom.getAttribute("targetids") }], location: dom.getAttribute("location"), }; } }], toDOM(node: any) { - const targetids = node.attrs.allHrefs.reduce((p: string, item: { href: string, title: string, targetId: string, linkId: string }) => p + " " + item.targetId, ""); - const linkids = node.attrs.allHrefs.reduce((p: string, item: { href: string, title: string, targetId: string, linkId: string }) => p + " " + item.linkId, ""); + const targetids = node.attrs.allLinks.reduce((p: string, item: { href: string, title: string, targetId: string, linkId: string }) => p + " " + item.targetId, ""); + const linkids = node.attrs.allLinks.reduce((p: string, item: { href: string, title: string, targetId: string, linkId: string }) => p + " " + item.linkId, ""); return node.attrs.docref && node.attrs.title ? - ["div", ["span", `"`], ["span", 0], ["span", `"`], ["br"], ["a", { ...node.attrs, href: node.attrs.allHrefs[0].href, class: "prosemirror-attribution" }, node.attrs.title], ["br"]] : - node.attrs.allHrefs.length === 1 ? - ["a", { ...node.attrs, class: linkids, targetids, title: `${node.attrs.title}`, href: node.attrs.allHrefs[0].href }, 0] : + ["div", ["span", `"`], ["span", 0], ["span", `"`], ["br"], ["a", { ...node.attrs, href: node.attrs.allLinks[0].href, class: "prosemirror-attribution" }, node.attrs.title], ["br"]] : + node.attrs.allLinks.length === 1 ? + ["a", { ...node.attrs, class: linkids, targetids, title: `${node.attrs.title}`, href: node.attrs.allLinks[0].href }, 0] : ["div", { class: "prosemirror-anchor" }, ["span", { class: "prosemirror-linkBtn" }, ["a", { ...node.attrs, class: linkids, targetids, title: `${node.attrs.title}` }, 0], ["input", { class: "prosemirror-hrefoptions" }], ], - ["div", { class: "prosemirror-links" }, ...node.attrs.allHrefs.map((item: { href: string, title: string }) => + ["div", { class: "prosemirror-links" }, ...node.attrs.allLinks.map((item: { href: string, title: string }) => ["a", { class: "prosemirror-dropdownlink", href: item.href }, item.title] )] ]; diff --git a/src/fields/RichTextUtils.ts b/src/fields/RichTextUtils.ts index 7c7bf3e12..a590c88c4 100644 --- a/src/fields/RichTextUtils.ts +++ b/src/fields/RichTextUtils.ts @@ -392,7 +392,7 @@ export namespace RichTextUtils { const { attrs } = mark; switch (converted) { case "link": - let url = attrs.allHrefs.length ? attrs.allHrefs[0].href : ""; + let url = attrs.allLinks.length ? attrs.allLinks[0].href : ""; const delimiter = "/doc/"; const alreadyShared = "?sharing=true"; if (new RegExp(window.location.origin + delimiter).test(url) && !url.endsWith(alreadyShared)) { -- cgit v1.2.3-70-g09d2