@atlaskit/editor-plugin-block-controls
Version:
Block controls plugin for @atlaskit/editor-core
104 lines (95 loc) • 4.3 kB
JavaScript
;
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 : [];
};