UNPKG

@atlaskit/editor-plugin-media

Version:

Media plugin for @atlaskit/editor-core

181 lines (177 loc) 8.04 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.splitMediaGroup = exports.removeMediaNode = exports.posOfPrecedingMediaGroup = exports.posOfParentMediaGroup = exports.posOfMediaGroupNearby = exports.isSelectionNonMediaBlockNode = exports.isSelectionMediaSingleNode = exports.isMediaBlobUrlFromAttrs = exports.isInsidePotentialEmptyParagraph = exports.getMediaNodeFromSelection = exports.copyOptionalAttrsFromMediaState = void 0; var _selection = require("@atlaskit/editor-common/selection"); var _utils = require("@atlaskit/editor-common/utils"); var _commands = require("@atlaskit/editor-prosemirror/commands"); var _state = require("@atlaskit/editor-prosemirror/state"); var _utils2 = require("@atlaskit/editor-prosemirror/utils"); var _mediaClient = require("@atlaskit/media-client"); var isTemporary = function isTemporary(id) { return id.indexOf('temporary:') === 0; }; var isMediaBlobUrlFromAttrs = exports.isMediaBlobUrlFromAttrs = function isMediaBlobUrlFromAttrs(attrs) { return !!(attrs && attrs.type === 'external' && (0, _mediaClient.isMediaBlobUrl)(attrs.url)); }; var posOfMediaGroupNearby = exports.posOfMediaGroupNearby = function posOfMediaGroupNearby(state) { return posOfParentMediaGroup(state) || posOfFollowingMediaGroup(state) || posOfPrecedingMediaGroup(state) || posOfMediaGroupNextToGapCursor(state); }; var isSelectionNonMediaBlockNode = exports.isSelectionNonMediaBlockNode = function isSelectionNonMediaBlockNode(state) { var _ref = state.selection, node = _ref.node; return node && node.type !== state.schema.nodes.media && node.isBlock; }; var isSelectionMediaSingleNode = exports.isSelectionMediaSingleNode = function isSelectionMediaSingleNode(state) { var _ref2 = state.selection, node = _ref2.node; return node && node.type === state.schema.nodes.mediaSingle; }; var posOfPrecedingMediaGroup = exports.posOfPrecedingMediaGroup = function posOfPrecedingMediaGroup(state) { if (!(0, _selection.atTheBeginningOfBlock)(state)) { return; } return posOfMediaGroupAbove(state, state.selection.$from); }; var posOfMediaGroupNextToGapCursor = function posOfMediaGroupNextToGapCursor(state) { var selection = state.selection; if (selection instanceof _selection.GapCursorSelection) { var $pos = state.selection.$from; var mediaGroupType = state.schema.nodes.mediaGroup; return posOfImmediatePrecedingMediaGroup($pos, mediaGroupType) || posOfImmediateFollowingMediaGroup($pos, mediaGroupType); } }; var posOfImmediatePrecedingMediaGroup = function posOfImmediatePrecedingMediaGroup($pos, mediaGroupType) { if ($pos.nodeBefore && $pos.nodeBefore.type === mediaGroupType) { return $pos.pos - $pos.nodeBefore.nodeSize + 1; } }; var posOfImmediateFollowingMediaGroup = function posOfImmediateFollowingMediaGroup($pos, mediaGroupType) { if ($pos.nodeAfter && $pos.nodeAfter.type === mediaGroupType) { return $pos.pos + 1; } }; var posOfFollowingMediaGroup = function posOfFollowingMediaGroup(state) { if (!(0, _selection.atTheEndOfBlock)(state)) { return; } return posOfMediaGroupBelow(state, state.selection.$to); }; var posOfMediaGroupAbove = function posOfMediaGroupAbove(state, $pos) { var adjacentPos; var adjacentNode; if (isSelectionNonMediaBlockNode(state)) { adjacentPos = $pos.pos; adjacentNode = $pos.nodeBefore; } else { adjacentPos = (0, _selection.startPositionOfParent)($pos) - 1; adjacentNode = state.doc.resolve(adjacentPos).nodeBefore; } if (adjacentNode && adjacentNode.type === state.schema.nodes.mediaGroup) { return adjacentPos - adjacentNode.nodeSize + 1; } return; }; /** * Determine whether the cursor is inside empty paragraph * or the selection is the entire paragraph */ var isInsidePotentialEmptyParagraph = exports.isInsidePotentialEmptyParagraph = function isInsidePotentialEmptyParagraph(state) { var $from = state.selection.$from; return $from.parent.type === state.schema.nodes.paragraph && (0, _selection.atTheBeginningOfBlock)(state) && (0, _selection.atTheEndOfBlock)(state); }; var posOfMediaGroupBelow = function posOfMediaGroupBelow(state, $pos) { var prepend = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; var adjacentPos; var adjacentNode; if (isSelectionNonMediaBlockNode(state)) { adjacentPos = $pos.pos; adjacentNode = $pos.nodeAfter; } else { adjacentPos = (0, _selection.endPositionOfParent)($pos); adjacentNode = state.doc.nodeAt(adjacentPos); } if (adjacentNode && adjacentNode.type === state.schema.nodes.mediaGroup) { return prepend ? adjacentPos + 1 : adjacentPos + adjacentNode.nodeSize - 1; } return; }; var posOfParentMediaGroup = exports.posOfParentMediaGroup = function posOfParentMediaGroup(state, $pos) { var prepend = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; var $from = state.selection.$from; $pos = $pos || $from; if ($pos.parent.type === state.schema.nodes.mediaGroup) { return prepend ? (0, _selection.startPositionOfParent)($pos) : (0, _selection.endPositionOfParent)($pos) - 1; } return; }; var removeMediaNode = exports.removeMediaNode = function removeMediaNode(view, node, getPos) { var id = node.attrs.id; var state = view.state; var tr = state.tr, selection = state.selection, doc = state.doc; var currentMediaNodePos = getPos(); if (typeof currentMediaNodePos !== 'number') { return; } tr.deleteRange(currentMediaNodePos, currentMediaNodePos + node.nodeSize); if (isTemporary(id)) { tr.setMeta('addToHistory', false); } var $currentMediaNodePos = doc.resolve(currentMediaNodePos); var nodeBefore = $currentMediaNodePos.nodeBefore, parent = $currentMediaNodePos.parent; var isLastMediaNode = $currentMediaNodePos.index() === parent.childCount - 1; // If deleting a selected media node, we need to tell where the cursor to go next. // Prosemirror didn't gave us the behaviour of moving left if the media node is not the last one. // So we handle it ourselves. if (selection.from === currentMediaNodePos && !isLastMediaNode && !(0, _selection.atTheBeginningOfDoc)(state) && nodeBefore && nodeBefore.type.name === 'media') { var _nodeBefore = (0, _utils2.findPositionOfNodeBefore)(tr.selection); if (_nodeBefore) { tr.setSelection(_state.NodeSelection.create(tr.doc, _nodeBefore)); } } view.dispatch(tr); }; var splitMediaGroup = exports.splitMediaGroup = function splitMediaGroup(view) { var selection = view.state.selection; // if selection is not a media node, do nothing. if (!(selection instanceof _state.NodeSelection) || selection.node.type !== view.state.schema.nodes.media) { return false; } (0, _commands.deleteSelection)(view.state, view.dispatch); if (selection.$to.nodeAfter) { (0, _commands.splitBlock)(view.state, view.dispatch); (0, _utils.createParagraphNear)(false)(view.state, view.dispatch); } else { (0, _utils.createNewParagraphBelow)(view.state, view.dispatch); } return true; }; var isOptionalAttr = function isOptionalAttr(attr) { return attr.length > 1 && attr[0] === '_' && attr[1] === '_'; }; var copyOptionalAttrsFromMediaState = exports.copyOptionalAttrsFromMediaState = function copyOptionalAttrsFromMediaState(mediaState, node) { Object.keys(node.attrs).filter(isOptionalAttr).forEach(function (key) { var mediaStateKey = key.substring(2); var attrValue = mediaState[mediaStateKey]; if (attrValue !== undefined) { // @ts-ignore - [unblock prosemirror bump] assigning to readonly prop node.attrs[key] = attrValue; } }); }; var getMediaNodeFromSelection = exports.getMediaNodeFromSelection = function getMediaNodeFromSelection(state) { if (!isSelectionMediaSingleNode(state)) { return null; } var tr = state.tr; var pos = tr.selection.from + 1; var mediaNode = tr.doc.nodeAt(pos); if (mediaNode && mediaNode.type === state.schema.nodes.media) { return mediaNode; } return null; };