UNPKG

@atlaskit/editor-plugin-highlight

Version:

Highlight plugin for @atlaskit/editor-core

106 lines (102 loc) 4.14 kB
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray"; import { entireSelectionContainsMark } from '@atlaskit/editor-common/mark'; import { TextSelection } from '@atlaskit/editor-prosemirror/state'; import { CellSelection } from '@atlaskit/editor-tables/cell-selection'; /** * Value returned by `getActiveColor` when the selection spans more than one * distinct highlight (background) color. Callers can compare against this to * detect a multi-color selection. */ export var MULTIPLE_HIGHLIGHT_COLORS_SELECTED = 'multiple'; var getAllUniqueBackgroundColorMarksInRange = function getAllUniqueBackgroundColorMarksInRange(from, to, tr) { var doc = tr.doc; var backgroundColor = doc.type.schema.marks.backgroundColor; var colorMarks = []; var colorSet = new Set(); doc.nodesBetween(from, to, function (node) { if (node.isLeaf) { var mark = backgroundColor.isInSet(node.marks); if (mark && !colorSet.has(mark.attrs.color)) { colorMarks.push(mark); colorSet.add(mark.attrs.color); } } }); return colorMarks; }; var getAllUniqueBackgroundColorMarksInCellSelection = function getAllUniqueBackgroundColorMarksInCellSelection(selection, tr) { var colorMarks = []; var colorSet = new Set(); selection.forEachCell(function (cell, cellPos) { var from = cellPos; var to = cellPos + cell.nodeSize; var marks = getAllUniqueBackgroundColorMarksInRange(from, to, tr); marks.forEach(function (mark) { if (!colorSet.has(mark.attrs.color)) { colorMarks.push(mark); colorSet.add(mark.attrs.color); } }); }); return colorMarks; }; // For Cell Selections - find first instance of a backgroundColor mark // if all cells entirely contain this mark, set the color. // If the selection contains multiple colors, return null var getColorFromCellSelection = function getColorFromCellSelection(selection, tr) { var marks = getAllUniqueBackgroundColorMarksInCellSelection(selection, tr); if (marks.length > 1) { return MULTIPLE_HIGHLIGHT_COLORS_SELECTED; } var firstColorMark = marks.at(0); if (!firstColorMark) { return null; } var foundUncolouredNode = false; selection.forEachCell(function (cell, cellPos) { if (foundUncolouredNode) { return; } var from = cellPos; var to = cellPos + cell.nodeSize; if (!entireSelectionContainsMark(firstColorMark, tr.doc, from, to)) { foundUncolouredNode = true; } }); return foundUncolouredNode ? null : firstColorMark.attrs.color; }; // All other selections - find the first instance of a backgroundColor mark // if selection entirely contains this mark, set the color. // If the selection contains multiple colors, return null var getColorFromRange = function getColorFromRange(from, to, tr) { var marks = getAllUniqueBackgroundColorMarksInRange(from, to, tr); if (marks.length > 1) { return MULTIPLE_HIGHLIGHT_COLORS_SELECTED; } var firstColorMark = marks.at(0); if (firstColorMark && entireSelectionContainsMark(firstColorMark, tr.doc, from, to)) { return firstColorMark.attrs.color; } return null; }; // For Cursor selections - set color if it is found in the storedMarks or $cursor.marks var getColorFromCursor = function getColorFromCursor(selection, tr) { var _mark$attrs$color; if (!selection.$cursor) { return null; } var mark = tr.doc.type.schema.marks.backgroundColor.isInSet([].concat(_toConsumableArray(tr.storedMarks ? tr.storedMarks : []), _toConsumableArray(selection.$cursor.marks()))); return (_mark$attrs$color = mark === null || mark === void 0 ? void 0 : mark.attrs.color) !== null && _mark$attrs$color !== void 0 ? _mark$attrs$color : null; }; export var getActiveColor = function getActiveColor(tr) { var selection = tr.selection; var color = null; if (selection instanceof CellSelection) { color = getColorFromCellSelection(selection, tr); } else if (selection instanceof TextSelection && selection.$cursor) { color = getColorFromCursor(selection, tr); } else { color = getColorFromRange(selection.from, selection.to, tr); } return color; };