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 {
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);
}
});
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
import {MenuItem} from "./menu";
import {icons} from "./icons";
-import {markRangeAtPosition, nullifyEmptyValues} from "../util";
+import {expandSelectionToMark, nullifyEmptyValues} from "../util";
/**
* @param {PmMarkType} markType
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));
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
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};
endPos += parent.child(endIndex).nodeSize;
endIndex += 1;
}
- return { from: startPos, to: endPos };
+ return {from: startPos, to: endPos};
}
/**