@atlaskit/editor-plugin-block-type
Version:
BlockType plugin for @atlaskit/editor-core
182 lines (181 loc) • 10.8 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.pluginKey = exports.createPlugin = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _analytics = require("@atlaskit/editor-common/analytics");
var _browser = require("@atlaskit/editor-common/browser");
var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
var _state = require("@atlaskit/editor-prosemirror/state");
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
var _blockTypes = require("./block-types");
var _blockType = require("./commands/block-type");
var _consts = require("./consts");
var _utils = require("./utils");
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 blockTypeForNode = function blockTypeForNode(node, schema) {
if (node.type === schema.nodes.heading) {
var maybeNode = _blockTypes.HEADINGS_BY_LEVEL[node.attrs['level']];
if (maybeNode) {
return maybeNode;
}
} else if (node.marks.some(function (m) {
return m.type.name === 'fontSize' && m.attrs.fontSize === 'small';
}) && (0, _expValEquals.expValEquals)('platform_editor_small_font_size', 'isEnabled', true)) {
return _blockTypes.SMALL_TEXT;
} else if (node.type === schema.nodes.paragraph) {
return _blockTypes.NORMAL_TEXT;
} else if (node.type === schema.nodes.blockquote) {
return _blockTypes.BLOCK_QUOTE;
}
return _blockTypes.OTHER;
};
var isBlockTypeSchemaSupported = function isBlockTypeSchemaSupported(blockType, state) {
switch (blockType) {
case _blockTypes.NORMAL_TEXT:
return !!state.schema.nodes.paragraph;
case _blockTypes.HEADING_1:
case _blockTypes.HEADING_2:
case _blockTypes.HEADING_3:
case _blockTypes.HEADING_4:
case _blockTypes.HEADING_5:
case _blockTypes.HEADING_6:
return !!state.schema.nodes.heading;
case _blockTypes.SMALL_TEXT:
return !!state.schema.marks.fontSize && (0, _expValEquals.expValEquals)('platform_editor_small_font_size', 'isEnabled', true);
case _blockTypes.BLOCK_QUOTE:
return !!state.schema.nodes.blockquote;
case _blockTypes.CODE_BLOCK:
return !!state.schema.nodes.codeBlock;
case _blockTypes.PANEL:
return !!state.schema.nodes.panel;
}
return;
};
var detectBlockType = function detectBlockType(availableBlockTypes, state) {
// Before a document is loaded, there is no selection.
if (!state.selection) {
return _blockTypes.NORMAL_TEXT;
}
var blockType;
var _state$selection = state.selection,
$from = _state$selection.$from,
$to = _state$selection.$to;
state.doc.nodesBetween($from.pos, $to.pos, function (node) {
var nodeBlockType = availableBlockTypes.filter(function (blockType) {
return blockType === blockTypeForNode(node, state.schema);
});
if (nodeBlockType.length > 0) {
if (!blockType) {
blockType = nodeBlockType[0];
} else if (blockType !== _blockTypes.OTHER && blockType !== nodeBlockType[0]) {
blockType = _blockTypes.OTHER;
}
return false;
}
});
return blockType || _blockTypes.OTHER;
};
var autoformatHeading = function autoformatHeading(headingLevel, editorAnalyticsApi) {
if (headingLevel === 0) {
return (0, _blockType.setNormalTextWithAnalytics)(_analytics.INPUT_METHOD.FORMATTING, editorAnalyticsApi);
}
return (0, _blockType.setHeadingWithAnalytics)(headingLevel, _analytics.INPUT_METHOD.FORMATTING, editorAnalyticsApi);
};
var pluginKey = exports.pluginKey = new _state.PluginKey('blockTypePlugin');
var createPlugin = exports.createPlugin = function createPlugin(editorAPI, dispatch, lastNodeMustBeParagraph, includeBlockQuoteAsTextstyleOption, allowFontSize) {
var _editorAPI$analytics;
var editorAnalyticsApi = editorAPI === null || editorAPI === void 0 || (_editorAPI$analytics = editorAPI.analytics) === null || _editorAPI$analytics === void 0 ? void 0 : _editorAPI$analytics.actions;
var altKeyLocation = 0;
return new _safePlugin.SafePlugin({
appendTransaction: function appendTransaction(_transactions, _oldState, newState) {
if (lastNodeMustBeParagraph) {
var pos = newState.doc.resolve(newState.doc.content.size - 1);
var lastNode = pos.node(1);
var paragraph = newState.schema.nodes.paragraph;
if (lastNode && lastNode.isBlock && lastNode.type !== paragraph) {
return newState.tr.insert(newState.doc.content.size, newState.schema.nodes.paragraph.create());
}
}
},
state: {
init: function init(_config, state) {
var availableBlockTypes = _blockTypes.TEXT_BLOCK_TYPES.filter(function (blockType) {
return isBlockTypeSchemaSupported(blockType, state);
});
var availableWrapperBlockTypes = _blockTypes.WRAPPER_BLOCK_TYPES.filter(function (blockType) {
return isBlockTypeSchemaSupported(blockType, state);
});
var BLOCK_TYPES_IN_DROPDOWN = (0, _blockTypes.getBlockTypesInDropdown)(includeBlockQuoteAsTextstyleOption);
var availableBlockTypesInDropdown = BLOCK_TYPES_IN_DROPDOWN.filter(function (blockType) {
return isBlockTypeSchemaSupported(blockType, state);
});
var formattingIsPresent = (0, _utils.hasBlockQuoteInOptions)(availableBlockTypesInDropdown) ? (0, _utils.checkFormattingIsPresent)(state) : undefined;
return {
currentBlockType: detectBlockType(availableBlockTypesInDropdown, state),
blockTypesDisabled: (0, _utils.areBlockTypesDisabled)(state, allowFontSize),
availableBlockTypes: availableBlockTypes,
availableWrapperBlockTypes: availableWrapperBlockTypes,
availableBlockTypesInDropdown: availableBlockTypesInDropdown,
formattingIsPresent: formattingIsPresent
};
},
apply: function apply(_tr, oldPluginState, _oldState, newState) {
var newPluginState = _objectSpread(_objectSpread({}, oldPluginState), {}, {
currentBlockType: detectBlockType(oldPluginState.availableBlockTypesInDropdown, newState),
blockTypesDisabled: (0, _utils.areBlockTypesDisabled)(newState, allowFontSize),
formattingIsPresent: (0, _utils.hasBlockQuoteInOptions)(oldPluginState.availableBlockTypesInDropdown) ? (0, _utils.checkFormattingIsPresent)(newState) : undefined
});
if (newPluginState.currentBlockType !== oldPluginState.currentBlockType || newPluginState.blockTypesDisabled !== oldPluginState.blockTypesDisabled || newPluginState.formattingIsPresent !== oldPluginState.formattingIsPresent) {
dispatch(pluginKey, newPluginState);
}
return newPluginState;
}
},
key: pluginKey,
props: {
/**
* As we only want the left alt key to work for headings shortcuts on Windows
* we can't use prosemirror-keymap and need to handle these shortcuts specially
* Shortcut on Mac: Cmd-Opt-{heading level}
* Shortcut on Windows: Ctrl-LeftAlt-{heading level}
*/
handleKeyDown: function handleKeyDown(view, event) {
var headingLevel = _consts.HEADING_KEYS.indexOf(event.keyCode);
if (headingLevel === -1) {
// Check for numpad keys if not found in digits row
headingLevel = _consts.HEADING_NUMPAD_KEYS.indexOf(event.keyCode);
}
var browser = (0, _browser.getBrowserInfo)();
if (headingLevel > -1 && event.altKey) {
if (browser.mac && event.metaKey) {
var _editorAPI$core$actio, _editorAPI$core;
return (_editorAPI$core$actio = editorAPI === null || editorAPI === void 0 || (_editorAPI$core = editorAPI.core) === null || _editorAPI$core === void 0 ? void 0 : _editorAPI$core.actions.execute(autoformatHeading(headingLevel, editorAnalyticsApi))) !== null && _editorAPI$core$actio !== void 0 ? _editorAPI$core$actio : false;
} else if (!browser.mac && event.ctrlKey && altKeyLocation !== event.DOM_KEY_LOCATION_RIGHT) {
var _editorAPI$core$actio2, _editorAPI$core2;
return (_editorAPI$core$actio2 = editorAPI === null || editorAPI === void 0 || (_editorAPI$core2 = editorAPI.core) === null || _editorAPI$core2 === void 0 ? void 0 : _editorAPI$core2.actions.execute(autoformatHeading(headingLevel, editorAnalyticsApi))) !== null && _editorAPI$core$actio2 !== void 0 ? _editorAPI$core$actio2 : false;
}
} else if (event.keyCode === _consts.KEY_7 && event.altKey && (0, _expValEquals.expValEquals)('platform_editor_small_font_size', 'isEnabled', true)) {
if (browser.mac && event.metaKey) {
var _editorAPI$core$actio3, _editorAPI$core3;
return (_editorAPI$core$actio3 = editorAPI === null || editorAPI === void 0 || (_editorAPI$core3 = editorAPI.core) === null || _editorAPI$core3 === void 0 ? void 0 : _editorAPI$core3.actions.execute((0, _blockType.setSmallTextWithAnalytics)(_analytics.INPUT_METHOD.SHORTCUT, editorAnalyticsApi))) !== null && _editorAPI$core$actio3 !== void 0 ? _editorAPI$core$actio3 : false;
} else if (!browser.mac && event.ctrlKey && altKeyLocation !== event.DOM_KEY_LOCATION_RIGHT) {
var _editorAPI$core$actio4, _editorAPI$core4;
return (_editorAPI$core$actio4 = editorAPI === null || editorAPI === void 0 || (_editorAPI$core4 = editorAPI.core) === null || _editorAPI$core4 === void 0 ? void 0 : _editorAPI$core4.actions.execute((0, _blockType.setSmallTextWithAnalytics)(_analytics.INPUT_METHOD.SHORTCUT, editorAnalyticsApi))) !== null && _editorAPI$core$actio4 !== void 0 ? _editorAPI$core$actio4 : false;
}
} else if (event.key === 'Alt') {
// event.location is for the current key only; when a user hits Ctrl-Alt-1 the
// location refers to the location of the '1' key
// We store the location of the Alt key when it is hit to check against later
altKeyLocation = event.location;
} else if (!event.altKey) {
altKeyLocation = 0;
}
return false;
}
}
});
};