UNPKG

@atlaskit/editor-plugin-block-controls

Version:

Block controls plugin for @atlaskit/editor-core

104 lines (95 loc) 4.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getMatchingBlockMarks = exports.getActiveBlockMarks = void 0; var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals"); /** * Remove this when platform_editor_clean_up_widget_mark_logic is cleaned up. * * Returns list of block marks on schema that widgets are allowed to render inside * Currently * - indent * - alignment * @param state - The editor state * @returns The block marks * @example * ```ts * const marks = getBlockMarks(state); * console.log(marks); * // [indent, alignment] * ``` */ var getActiveBlockMarks = exports.getActiveBlockMarks = function getActiveBlockMarks(state, pos) { var alignment = state.schema.marks.alignment; var resolvedPos = state.doc.resolve(pos); // find all active marks at the position var marks = resolvedPos.marks(); var supportedMarks = marks.filter(function (mark) { return mark.type === alignment; }); /** * Fix for widget positioning at alignment mark boundaries. * When the previous node has alignment but the next node doesn't, we need to prevent * the widget from inheriting alignment marks. This ensures the widget is positioned * correctly at the boundary rather than being absorbed into the alignment wrapper. */ if (supportedMarks.length > 0 && (0, _expValEquals.expValEquals)('platform_editor_native_anchor_with_dnd', 'isEnabled', true)) { var _resolvedPos$nodeAfte; var nextNodeMarks = ((_resolvedPos$nodeAfte = resolvedPos.nodeAfter) === null || _resolvedPos$nodeAfte === void 0 ? void 0 : _resolvedPos$nodeAfte.marks.filter(function (mark) { return mark.type === alignment; })) || []; // Compare alignment values to ensure they are the same var alignmentValuesMatch = supportedMarks.length === nextNodeMarks.length && supportedMarks.some(function (mark) { return nextNodeMarks.some(function (nextMark) { return nextMark.eq(mark); }); }); // previous node has alignment but next node does not have alignment or alignment values differ if (nextNodeMarks.length === 0 || !alignmentValuesMatch) { return []; } } return supportedMarks; }; /** True when `mark` has an equal counterpart (type + attrs) in `marks`. */ var hasMatchingMark = function hasMatchingMark(mark, marks) { var found = mark.type.isInSet(marks); return !!found && mark.eq(found); }; /** * Returns supported block marks at `pos` only when both adjacent siblings * share the exact same set of those marks. Returns `[]` when they differ, * so the widget sits outside all mark wrappers and avoids mis-nesting. */ var getMatchingBlockMarks = exports.getMatchingBlockMarks = function getMatchingBlockMarks(state, pos, supportedMarkTypes) { var _nodeAfter$marks, _nodeBefore$marks; var resolvedPos = state.doc.resolve(pos); var validMarkTypes = supportedMarkTypes.filter(Boolean); var supportedMarks = resolvedPos.marks().filter(function (mark) { return validMarkTypes.includes(mark.type); }); if (supportedMarks.length === 0) { return []; } var nodeAfter = resolvedPos.nodeAfter, nodeBefore = resolvedPos.nodeBefore; var nextMarks = (_nodeAfter$marks = nodeAfter === null || nodeAfter === void 0 ? void 0 : nodeAfter.marks) !== null && _nodeAfter$marks !== void 0 ? _nodeAfter$marks : []; var prevMarks = (_nodeBefore$marks = nodeBefore === null || nodeBefore === void 0 ? void 0 : nodeBefore.marks) !== null && _nodeBefore$marks !== void 0 ? _nodeBefore$marks : []; var nextSupported = nextMarks.filter(function (m) { return validMarkTypes.includes(m.type); }); var allMatchNext = supportedMarks.every(function (m) { return hasMatchingMark(m, nextMarks); }); // First node — no previous sibling to compare against. if (!nodeBefore) { return nextSupported.length === supportedMarks.length && allMatchNext ? supportedMarks : []; } // `supportedMarks` already comes from `nodeBefore` (via resolvedPos.marks()). // Compare counts to guard against extra supported marks on either side. var prevSupported = prevMarks.filter(function (m) { return validMarkTypes.includes(m.type); }); return prevSupported.length === nextSupported.length && allMatchNext ? supportedMarks : []; };