@atlaskit/editor-plugin-list
Version:
List plugin for @atlaskit/editor-core
281 lines (278 loc) • 12.3 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.outdentListItemsSelected = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _analytics = require("@atlaskit/editor-common/analytics");
var _lists = require("@atlaskit/editor-common/lists");
var _selection = require("@atlaskit/editor-common/selection");
var _utils = require("@atlaskit/editor-common/utils");
var _model = require("@atlaskit/editor-prosemirror/model");
var _state = require("@atlaskit/editor-prosemirror/state");
var _transform = require("@atlaskit/editor-prosemirror/transform");
var _analytics2 = require("../utils/analytics");
var _find = require("../utils/find");
var _selection2 = require("../utils/selection");
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
var outdentListItemsSelected = exports.outdentListItemsSelected = function outdentListItemsSelected(tr) {
var originalSelection = tr.selection;
var normalizedSelection = (0, _lists.normalizeListItemsSelection)({
selection: tr.selection,
doc: tr.doc
});
var rootList = (0, _find.findRootParentListNode)(normalizedSelection.$from);
if (!rootList) {
return;
}
var commonList = normalizedSelection.$from.blockRange(rootList, _utils.isListNode);
if (!commonList) {
return;
}
var hasNormalizedToPositionLiftedOut = false;
var hasNormalizedFromPositionLiftedOut = false;
var oldFrom = normalizedSelection.from,
oldTo = normalizedSelection.to;
var nodeRanges = splitRangeSelection(normalizedSelection);
nodeRanges.forEach(function (range) {
var $from = tr.doc.resolve(tr.mapping.map(range.from));
var $to = tr.doc.resolve(tr.mapping.map(range.to));
var mappedRange = $from.blockRange($to, _utils.isListNode);
if (!mappedRange) {
return;
}
if ((0, _utils.isListItemNode)($from.node(mappedRange.depth - 1))) {
outdentRangeToParentList({
tr: tr,
range: mappedRange
});
} else {
extractListItemsRangeFromList({
tr: tr,
range: mappedRange
});
hasNormalizedToPositionLiftedOut = hasNormalizedToPositionLiftedOut || oldTo >= range.from && oldTo < range.to;
hasNormalizedFromPositionLiftedOut = hasNormalizedFromPositionLiftedOut || oldFrom >= range.from && oldFrom < range.to;
}
});
var hasCommonListMoved = commonList.start !== tr.mapping.map(commonList.start);
var nextSelection = calculateNewSelection({
originalSelection: originalSelection,
normalizedSelection: normalizedSelection,
tr: tr,
hasCommonListMoved: hasCommonListMoved,
hasNormalizedToPositionLiftedOut: hasNormalizedToPositionLiftedOut,
hasNormalizedFromPositionLiftedOut: hasNormalizedFromPositionLiftedOut
});
tr.setSelection(nextSelection);
// processNestedTaskListsInSameLevel(tr);
(0, _lists.joinSiblingLists)({
tr: tr,
direction: _lists.JoinDirection.RIGHT
});
};
var calculateNewSelection = function calculateNewSelection(_ref) {
var tr = _ref.tr,
originalSelection = _ref.originalSelection,
normalizedSelection = _ref.normalizedSelection,
hasCommonListMoved = _ref.hasCommonListMoved,
hasNormalizedToPositionLiftedOut = _ref.hasNormalizedToPositionLiftedOut,
hasNormalizedFromPositionLiftedOut = _ref.hasNormalizedFromPositionLiftedOut;
var $from = normalizedSelection.$from,
$to = normalizedSelection.$to;
var isCursorSelection = normalizedSelection.empty;
var from = tr.mapping.map($from.pos);
var to = tr.mapping.map($to.pos);
var LIST_STRUCTURE_CHANGED_OFFSET = 2;
var isToFromSameListItem = $from.sameParent($to);
if (hasNormalizedFromPositionLiftedOut) {
var fromMapped = isToFromSameListItem ? $from.pos : from;
from = hasNormalizedFromPositionLiftedOut ? $from.pos : fromMapped;
from = hasCommonListMoved ? from - LIST_STRUCTURE_CHANGED_OFFSET : from;
from = Math.max(from, 0);
}
if (hasNormalizedToPositionLiftedOut) {
var toMapped = isToFromSameListItem ? $to.pos : to;
to = hasNormalizedToPositionLiftedOut ? $to.pos : toMapped;
to = hasCommonListMoved ? to - LIST_STRUCTURE_CHANGED_OFFSET : to;
to = Math.min(to, tr.doc.nodeSize - 2);
}
if (normalizedSelection instanceof _selection.GapCursorSelection) {
var nextSelectionFrom = tr.doc.resolve(from);
return new _selection.GapCursorSelection(nextSelectionFrom, normalizedSelection.side);
}
if (originalSelection instanceof _state.NodeSelection) {
return _state.NodeSelection.create(tr.doc, from);
}
if (isCursorSelection) {
return _state.TextSelection.between(tr.doc.resolve(to), tr.doc.resolve(to), -1);
}
return _state.TextSelection.between(tr.doc.resolve(from), tr.doc.resolve(to), -1);
};
var splitRangeSelection = function splitRangeSelection(selection) {
var commonListRange = (0, _selection2.createListNodeRange)({
selection: selection
});
if (!commonListRange) {
return [];
}
var $from = selection.$from,
$to = selection.$to;
if ($from.pos === $to.pos && $from.sameParent($to)) {
return [{
from: commonListRange.start,
to: commonListRange.end,
depth: commonListRange.depth
}];
}
var lastListItem = findPreviousListItemSibling($from);
if (!lastListItem) {
return [];
}
var nodeRanges = [];
var doc = $from.doc;
var previousListItem = findPreviousListItemSibling($to);
while (previousListItem && previousListItem.pos >= lastListItem.pos && previousListItem.pos >= commonListRange.start) {
var node = doc.nodeAt(previousListItem.pos);
if (!node || !(0, _utils.isListItemNode)(node)) {
return [];
}
var offset = 0;
if (node && node.lastChild && (0, _utils.isListNode)(node.lastChild)) {
offset = node.lastChild.nodeSize;
}
var start = previousListItem.pos + 1;
nodeRanges.push({
from: start,
to: doc.resolve(start).end() - offset,
depth: previousListItem.depth
});
previousListItem = findPreviousListItemSibling(previousListItem);
}
return nodeRanges;
};
var outdentRangeToParentList = function outdentRangeToParentList(_ref2) {
var tr = _ref2.tr,
range = _ref2.range;
var end = range.end;
var endOfList = range.$to.end(range.depth);
var listItem = tr.doc.type.schema.nodes.listItem;
if (end < endOfList) {
var slice = new _model.Slice(_model.Fragment.from(listItem.create(null, range.parent.copy())), 1, 0);
var step = new _transform.ReplaceAroundStep(end - 1, endOfList, end, endOfList, slice, 1, true);
tr.step(step);
range = new _model.NodeRange(tr.doc.resolve(range.$from.pos), tr.doc.resolve(endOfList), range.depth);
}
var target = (0, _transform.liftTarget)(range);
if (target) {
tr.lift(range, target);
}
};
var extractListItemsRangeFromList = function extractListItemsRangeFromList(_ref3) {
var tr = _ref3.tr,
range = _ref3.range;
var list = range.parent;
var $start = tr.doc.resolve(range.start);
var listStart = $start.start(range.depth);
var listEnd = $start.end(range.depth);
var isAtTop = listStart === range.start;
var isAtBottom = listEnd === range.end;
var isTheEntireList = isAtTop && isAtBottom;
var listItemContent = isAtTop ? _model.Fragment.empty : _model.Fragment.from(list.copy(_model.Fragment.empty));
for (var i = range.startIndex; i < range.endIndex; i++) {
listItemContent = listItemContent.append(list.child(i).content);
}
if (isAtTop) {
for (var _i = 0; _i < listItemContent.childCount; _i++) {
var child = listItemContent.child(_i);
if (child && (0, _utils.isListNode)(child) && child.type !== list.type) {
var newNestedList = list.type.create(null, child.content);
listItemContent = listItemContent.replaceChild(_i, newNestedList);
}
}
}
var nextList = list.copy(_model.Fragment.empty);
var nextListStartNumber;
// if splitting a numbered list, keep the splitted item
// counter as the start of the next (second half) list (instead
// of reverting back to 1 as a starting number)
var order = (0, _utils.getOrderFromOrderedListNode)(list);
if (list.type.name === 'orderedList') {
nextListStartNumber = range.endIndex - 1 + order;
// @ts-ignore - [unblock prosemirror bump] assigning to readonly attrs
nextList.attrs = _objectSpread(_objectSpread({}, nextList.attrs), {}, {
order: nextListStartNumber
});
var _getRestartListsAttri = (0, _analytics2.getRestartListsAttributes)(tr),
splitListStartNumber = _getRestartListsAttri.splitListStartNumber;
if (typeof splitListStartNumber !== 'number') {
(0, _analytics2.storeRestartListsAttributes)(tr, {
splitListStartNumber: nextListStartNumber
});
}
}
var nextListFragment = listItemContent.append(_model.Fragment.from(nextList));
// if the split list with nextListStartNumber is below another list
// with order (e.g due to multi-level indent items being lifted), track the
// list above's order instead, as it will be the split list's order after sibling joins
nextListFragment.forEach(function (node, _offset, index) {
var _node$attrs;
if (node.type.name === 'orderedList' && ((_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.order) === nextListStartNumber) {
var _prev$attrs;
var prev = nextListFragment.child(index - 1);
if ((prev === null || prev === void 0 || (_prev$attrs = prev.attrs) === null || _prev$attrs === void 0 ? void 0 : _prev$attrs.order) >= 0) {
var _prev$attrs2;
(0, _analytics2.storeRestartListsAttributes)(tr, {
splitListStartNumber: prev === null || prev === void 0 || (_prev$attrs2 = prev.attrs) === null || _prev$attrs2 === void 0 ? void 0 : _prev$attrs2.order
});
}
}
});
if (isTheEntireList) {
var slice = new _model.Slice(listItemContent, 0, 0);
var step = new _transform.ReplaceStep($start.pos - 1, range.end + 1, slice, false);
(0, _analytics2.storeRestartListsAttributes)(tr, {
outdentScenario: undefined
});
tr.step(step);
} else if (isAtTop) {
var _slice = new _model.Slice(nextListFragment, 0, 1);
var _step = new _transform.ReplaceStep($start.pos - 1, range.end, _slice, false);
tr.step(_step);
} else if (isAtBottom) {
var _slice2 = new _model.Slice(listItemContent, 1, 0);
var _step2 = new _transform.ReplaceStep($start.pos, listEnd + 1, _slice2, false);
tr.step(_step2);
} else {
(0, _analytics2.storeRestartListsAttributes)(tr, {
outdentScenario: _analytics.OUTDENT_SCENARIOS.SPLIT_LIST
});
var _slice3 = new _model.Slice(nextListFragment, 1, 1);
var _step3 = new _transform.ReplaceAroundStep($start.pos, listEnd, range.end, listEnd, _slice3, _slice3.size, false);
tr.step(_step3);
}
};
var findPreviousListItemSibling = function findPreviousListItemSibling($pos) {
var doc = $pos.doc;
var isPositionListItem = (0, _utils.isListNode)($pos.node());
var listItemPosition = $pos;
if (!isPositionListItem) {
var listItem = (0, _find.findFirstParentListItemNode)($pos);
if (!listItem) {
return null;
}
return doc.resolve(listItem.pos);
}
var resolved = doc.resolve(listItemPosition.pos);
var foundPosition = _state.Selection.findFrom(resolved, -1);
if (!foundPosition) {
return null;
}
var parentListItemNode = (0, _find.findFirstParentListItemNode)(foundPosition.$from);
if (!parentListItemNode) {
return null;
}
return doc.resolve(parentListItemNode.pos);
};