@atlaskit/editor-plugin-extension
Version:
editor-plugin-extension plugin for @atlaskit/editor-core
198 lines (194 loc) • 11.2 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.setMacroProvider = exports.runMacroAutoConvert = exports.resolveMacro = exports.insertMacroFromMacroBrowser = void 0;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _assert = _interopRequireDefault(require("assert"));
var _analytics = require("@atlaskit/editor-common/analytics");
var _insert = require("@atlaskit/editor-common/insert");
var _validator = require("@atlaskit/editor-common/validator");
var _state = require("@atlaskit/editor-prosemirror/state");
var _utils = require("@atlaskit/editor-prosemirror/utils");
var _pluginFactory = require("../plugin-factory");
var _pluginKey = require("./plugin-key");
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 insertMacroFromMacroBrowser = exports.insertMacroFromMacroBrowser = function insertMacroFromMacroBrowser(editorAnalyticsAPI) {
return function (macroProvider, macroNode, isEditing) {
return /*#__PURE__*/function () {
var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(view) {
var newMacro, state, dispatch, currentLayout, node, selection, schema, _schema$nodes, extension, inlineExtension, bodiedExtension, multiBodiedExtension, updateSelectionsByNodeType, extensionState, targetSelectionSource, tr, isBodiedExtensionSelected, isMultiBodiedExtensionSelected, pos, _macroNode$attrs, extensionType, extensionKey, layout, localId;
return _regenerator.default.wrap(function _callee$(_context) {
while (1) switch (_context.prev = _context.next) {
case 0:
if (macroProvider) {
_context.next = 2;
break;
}
return _context.abrupt("return", false);
case 2:
_context.next = 4;
return macroProvider.openMacroBrowser(macroNode);
case 4:
newMacro = _context.sent;
if (!(newMacro && macroNode)) {
_context.next = 22;
break;
}
state = view.state, dispatch = view.dispatch;
currentLayout = macroNode && macroNode.attrs.layout || 'default';
node = resolveMacro(newMacro, state, {
layout: currentLayout
});
if (node) {
_context.next = 11;
break;
}
return _context.abrupt("return", false);
case 11:
selection = state.selection, schema = state.schema;
_schema$nodes = schema.nodes, extension = _schema$nodes.extension, inlineExtension = _schema$nodes.inlineExtension, bodiedExtension = _schema$nodes.bodiedExtension, multiBodiedExtension = _schema$nodes.multiBodiedExtension;
updateSelectionsByNodeType = function updateSelectionsByNodeType(nodeType) {
// `isEditing` is `false` when we are inserting from insert-block toolbar
tr = isEditing ? (0, _utils.replaceParentNodeOfType)(nodeType, node)(tr) : (0, _utils.safeInsert)(node)(tr);
// Replacing selected node doesn't update the selection. `selection.node` still returns the old node
tr.setSelection(_state.TextSelection.create(tr.doc, state.selection.anchor));
};
extensionState = (0, _pluginFactory.getPluginState)(state);
targetSelectionSource = _analytics.TARGET_SELECTION_SOURCE.CURRENT_SELECTION;
tr = state.tr;
isBodiedExtensionSelected = !!(0, _utils.findSelectedNodeOfType)([bodiedExtension])(selection);
isMultiBodiedExtensionSelected = !!(0, _utils.findSelectedNodeOfType)([multiBodiedExtension])(selection); // When it's a bodiedExtension but not selected
if (macroNode.type === bodiedExtension && !isBodiedExtensionSelected) {
updateSelectionsByNodeType(state.schema.nodes.bodiedExtension);
}
// When it's a multiBodiedExtension but not selected
else if (macroNode.type === multiBodiedExtension && !isMultiBodiedExtensionSelected) {
updateSelectionsByNodeType(state.schema.nodes.multiBodiedExtension);
}
// If any extension is currently selected
else if ((0, _utils.findSelectedNodeOfType)([extension, bodiedExtension, inlineExtension, multiBodiedExtension])(selection)) {
tr = (0, _utils.replaceSelectedNode)(node)(tr);
// Replacing selected node doesn't update the selection. `selection.node` still returns the old node
tr.setSelection(_state.NodeSelection.create(tr.doc, tr.mapping.map(state.selection.anchor)));
}
// When we loose the selection. This usually happens when Synchrony resets or changes
// the selection when user is in the middle of updating an extension.
else if (extensionState.element) {
pos = view.posAtDOM(extensionState.element, -1);
if (pos > -1) {
tr = tr.replaceWith(pos, pos + macroNode.nodeSize, node);
tr.setSelection(_state.Selection.near(tr.doc.resolve(pos)));
targetSelectionSource = _analytics.TARGET_SELECTION_SOURCE.HTML_ELEMENT;
}
}
// Only scroll if we have anything to update, best to avoid surprise scroll
if (dispatch && tr.docChanged) {
_macroNode$attrs = macroNode.attrs, extensionType = _macroNode$attrs.extensionType, extensionKey = _macroNode$attrs.extensionKey, layout = _macroNode$attrs.layout, localId = _macroNode$attrs.localId;
editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.attachAnalyticsEvent({
action: _analytics.ACTION.UPDATED,
actionSubject: _analytics.ACTION_SUBJECT.EXTENSION,
actionSubjectId: macroNode.type.name,
eventType: _analytics.EVENT_TYPE.TRACK,
attributes: {
// @ts-expect-error - Type is not assignable to parameter of type 'AnalyticsEventPayload'
// This error was introduced after upgrading to TypeScript 5
inputMethod: isEditing ? _analytics.INPUT_METHOD.MACRO_BROWSER : _analytics.INPUT_METHOD.TOOLBAR,
extensionType: extensionType,
extensionKey: extensionKey,
layout: layout,
localId: localId,
selection: tr.selection.toJSON(),
targetSelectionSource: targetSelectionSource
}
})(tr);
dispatch(tr.scrollIntoView());
}
return _context.abrupt("return", true);
case 22:
return _context.abrupt("return", false);
case 23:
case "end":
return _context.stop();
}
}, _callee);
}));
return function (_x) {
return _ref.apply(this, arguments);
};
}();
};
};
var resolveMacro = exports.resolveMacro = function resolveMacro(macro, state, optionalAttrs) {
if (!macro || !state) {
return null;
}
var schema = state.schema;
var _getValidNode = (0, _validator.getValidNode)(macro, schema),
type = _getValidNode.type,
attrs = _getValidNode.attrs;
var node = null;
if (type === 'extension') {
node = schema.nodes.extension.create(_objectSpread(_objectSpread({}, attrs), optionalAttrs));
} else if (type === 'bodiedExtension') {
node = schema.nodes.bodiedExtension.create(_objectSpread(_objectSpread({}, attrs), optionalAttrs), schema.nodeFromJSON(macro).content);
} else if (type === 'inlineExtension') {
node = schema.nodes.inlineExtension.create(attrs);
} else if (type === 'multiBodiedExtension') {
node = schema.nodes.multiBodiedExtension.create(_objectSpread(_objectSpread({}, attrs), optionalAttrs), schema.nodeFromJSON(macro).content);
}
return node && (0, _insert.normaliseNestedLayout)(state, node);
};
// gets the macroProvider from the state and tries to autoConvert a given text
var runMacroAutoConvert = exports.runMacroAutoConvert = function runMacroAutoConvert(state, text) {
var macroPluginState = _pluginKey.pluginKey.getState(state);
var macroProvider = macroPluginState && macroPluginState.macroProvider;
if (!macroProvider || !macroProvider.autoConvert) {
return null;
}
var macroAttributes = macroProvider.autoConvert(text);
if (!macroAttributes) {
return null;
}
// decides which kind of macro to render (inline|bodied|bodyless)
return resolveMacro(macroAttributes, state);
};
var setMacroProvider = exports.setMacroProvider = function setMacroProvider(provider) {
return /*#__PURE__*/function () {
var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(view) {
var resolvedProvider;
return _regenerator.default.wrap(function _callee2$(_context2) {
while (1) switch (_context2.prev = _context2.next) {
case 0:
_context2.prev = 0;
_context2.next = 3;
return provider;
case 3:
resolvedProvider = _context2.sent;
(0, _assert.default)(resolvedProvider && resolvedProvider.openMacroBrowser, "MacroProvider promise did not resolve to a valid instance of MacroProvider - ".concat(resolvedProvider));
_context2.next = 10;
break;
case 7:
_context2.prev = 7;
_context2.t0 = _context2["catch"](0);
resolvedProvider = null;
case 10:
view.dispatch(view.state.tr.setMeta(_pluginKey.pluginKey, {
macroProvider: resolvedProvider
}));
return _context2.abrupt("return", true);
case 12:
case "end":
return _context2.stop();
}
}, _callee2, null, [[0, 7]]);
}));
return function (_x2) {
return _ref2.apply(this, arguments);
};
}();
};