From: Dan Brown Date: Wed, 19 Jan 2022 23:54:59 +0000 (+0000) Subject: Shared link mark update logic with color controls X-Git-Url: http://source.bookstackapp.com/bookstack/commitdiff_plain/b1f5495a7f46e83c39a856417e4c2524c9425438 Shared link mark update logic with color controls --- diff --git a/resources/js/editor/menu/ColorPickerGrid.js b/resources/js/editor/menu/ColorPickerGrid.js index c5eacc335..306c65c56 100644 --- a/resources/js/editor/menu/ColorPickerGrid.js +++ b/resources/js/editor/menu/ColorPickerGrid.js @@ -1,6 +1,8 @@ import crel from "crelt" import {prefix} from "./menu-utils"; -import {toggleMark} from "prosemirror-commands"; +import {TextSelection} from "prosemirror-state" +import {expandSelectionToMark} from "../util"; + class ColorPickerGrid { @@ -24,8 +26,7 @@ class ColorPickerGrid { wrap.addEventListener('click', event => { if (event.target.classList.contains(prefix + "-color-grid-item")) { const color = event.target.style.backgroundColor; - const attrs = {[this.attrName]: color}; - toggleMark(this.markType, attrs)(view.state, view.dispatch, view, event); + this.onColorSelect(view, color); } }); @@ -35,6 +36,27 @@ class ColorPickerGrid { return {dom: wrap, update} } + + onColorSelect(view, color) { + const attrs = {[this.attrName]: color}; + const selection = view.state.selection; + const {from, to} = expandSelectionToMark(view.state, selection, this.markType); + const tr = view.state.tr; + + const currentColorMarks = selection.$from.marksAcross(selection.$to) || []; + const activeRelevantMark = currentColorMarks.filter(mark => { + return mark.type === this.markType; + })[0]; + const colorIsActive = activeRelevantMark && activeRelevantMark.attrs[this.attrName] === color; + + tr.removeMark(from, to, this.markType); + if (!colorIsActive) { + tr.addMark(from, to, this.markType.create(attrs)); + } + + tr.setSelection(TextSelection.create(tr.doc, from, to)); + view.dispatch(tr); + } } export default ColorPickerGrid; \ No newline at end of file diff --git a/resources/js/editor/menu/item-anchor-button.js b/resources/js/editor/menu/item-anchor-button.js index 405d3ab4d..0fa819c19 100644 --- a/resources/js/editor/menu/item-anchor-button.js +++ b/resources/js/editor/menu/item-anchor-button.js @@ -6,7 +6,7 @@ import schema from "../schema"; import {MenuItem} from "./menu"; import {icons} from "./icons"; -import {markRangeAtPosition, nullifyEmptyValues} from "../util"; +import {expandSelectionToMark, nullifyEmptyValues} from "../util"; /** * @param {PmMarkType} markType @@ -74,17 +74,7 @@ function applyLink(formData, state, dispatch) { if (!dispatch) return true; const tr = state.tr; - const noRange = (selection.from - selection.to === 0); - let from = selection.from; - let to = selection.to; - - if (noRange) { - const linkRange = markRangeAtPosition(state, schema.marks.link, selection.from); - if (linkRange.from !== -1) { - from = linkRange.from; - to = linkRange.to; - } - } + const {from, to} = expandSelectionToMark(state, selection, schema.marks.link); if (attrs.href) { tr.addMark(from, to, schema.marks.link.create(attrs)); diff --git a/resources/js/editor/util.js b/resources/js/editor/util.js index e1746a725..ad077b923 100644 --- a/resources/js/editor/util.js +++ b/resources/js/editor/util.js @@ -45,6 +45,25 @@ export function nullifyEmptyValues(object) { return clean; } +/** + * @param {PmEditorState} state + * @param {PmSelection} selection + * @param {PmMarkType} markType + * @return {{from: Number, to: Number}} + */ +export function expandSelectionToMark(state, selection, markType) { + let {from, to} = selection; + const noRange = (from === to); + if (noRange) { + const markRange = markRangeAtPosition(state, markType, from); + if (markRange.from !== -1) { + from = markRange.from; + to = markRange.to; + } + } + return {from, to}; +} + /** * @param {PmEditorState} state * @param {PmMarkType} markType @@ -54,7 +73,7 @@ export function nullifyEmptyValues(object) { export function markRangeAtPosition(state, markType, pos) { const $pos = state.doc.resolve(pos); - const { parent, parentOffset } = $pos; + const {parent, parentOffset} = $pos; const start = parent.childAfter(parentOffset); if (!start.node) return {from: -1, to: -1}; @@ -73,7 +92,7 @@ export function markRangeAtPosition(state, markType, pos) { endPos += parent.child(endIndex).nodeSize; endIndex += 1; } - return { from: startPos, to: endPos }; + return {from: startPos, to: endPos}; } /**