Shared link mark update logic with color controls

This commit is contained in:
Dan Brown 2022-01-19 23:54:59 +00:00
parent bb12541179
commit b1f5495a7f
No known key found for this signature in database
GPG key ID: 46D9F943C24A2EF9
3 changed files with 48 additions and 17 deletions

View file

@ -1,6 +1,8 @@
import crel from "crelt" import crel from "crelt"
import {prefix} from "./menu-utils"; import {prefix} from "./menu-utils";
import {toggleMark} from "prosemirror-commands"; import {TextSelection} from "prosemirror-state"
import {expandSelectionToMark} from "../util";
class ColorPickerGrid { class ColorPickerGrid {
@ -24,8 +26,7 @@ class ColorPickerGrid {
wrap.addEventListener('click', event => { wrap.addEventListener('click', event => {
if (event.target.classList.contains(prefix + "-color-grid-item")) { if (event.target.classList.contains(prefix + "-color-grid-item")) {
const color = event.target.style.backgroundColor; const color = event.target.style.backgroundColor;
const attrs = {[this.attrName]: color}; this.onColorSelect(view, color);
toggleMark(this.markType, attrs)(view.state, view.dispatch, view, event);
} }
}); });
@ -35,6 +36,27 @@ class ColorPickerGrid {
return {dom: wrap, update} 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; export default ColorPickerGrid;

View file

@ -6,7 +6,7 @@ import schema from "../schema";
import {MenuItem} from "./menu"; import {MenuItem} from "./menu";
import {icons} from "./icons"; import {icons} from "./icons";
import {markRangeAtPosition, nullifyEmptyValues} from "../util"; import {expandSelectionToMark, nullifyEmptyValues} from "../util";
/** /**
* @param {PmMarkType} markType * @param {PmMarkType} markType
@ -74,17 +74,7 @@ function applyLink(formData, state, dispatch) {
if (!dispatch) return true; if (!dispatch) return true;
const tr = state.tr; const tr = state.tr;
const noRange = (selection.from - selection.to === 0); const {from, to} = expandSelectionToMark(state, selection, schema.marks.link);
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;
}
}
if (attrs.href) { if (attrs.href) {
tr.addMark(from, to, schema.marks.link.create(attrs)); tr.addMark(from, to, schema.marks.link.create(attrs));

View file

@ -45,6 +45,25 @@ export function nullifyEmptyValues(object) {
return clean; 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 {PmEditorState} state
* @param {PmMarkType} markType * @param {PmMarkType} markType