UNPKG

@atlaskit/editor-plugin-code-bidi-warning

Version:

Code bidi warning plugin for @atlaskit/editor-core.

123 lines (120 loc) 5.73 kB
import _defineProperty from "@babel/runtime/helpers/defineProperty"; 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) { _defineProperty(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; } import React from 'react'; // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead import uuid from 'uuid/v4'; import CodeBidiWarning from '@atlaskit/code/bidi-warning'; import codeBidiWarningDecorator from '@atlaskit/code/bidi-warning-decorator'; import { pluginFactory, stepHasSlice } from '@atlaskit/editor-common/utils'; import { Decoration, DecorationSet } from '@atlaskit/editor-prosemirror/view'; import { codeBidiWarningPluginKey } from './plugin-key'; import reducer from './reducer'; export var pluginFactoryCreator = function pluginFactoryCreator(nodeViewPortalProviderAPI) { return pluginFactory(codeBidiWarningPluginKey, reducer, { onDocChanged: function onDocChanged(tr, pluginState) { if (!tr.steps.find(stepHasSlice)) { return pluginState; } var newBidiWarningsDecorationSet = createBidiWarningsDecorationSetFromDoc({ doc: tr.doc, codeBidiWarningLabel: pluginState.codeBidiWarningLabel, tooltipEnabled: pluginState.tooltipEnabled, nodeViewPortalProviderAPI: nodeViewPortalProviderAPI }); return _objectSpread(_objectSpread({}, pluginState), {}, { decorationSet: newBidiWarningsDecorationSet }); } }); }; export function createBidiWarningsDecorationSetFromDoc(_ref) { var doc = _ref.doc, codeBidiWarningLabel = _ref.codeBidiWarningLabel, tooltipEnabled = _ref.tooltipEnabled, nodeViewPortalProviderAPI = _ref.nodeViewPortalProviderAPI; var bidiCharactersAndTheirPositions = []; doc.descendants(function (node, pos) { var isTextWithCodeMark = node.type.name === 'text' && node.marks && node.marks.some(function (mark) { return mark.type.name === 'code'; }); if (isTextWithCodeMark) { codeBidiWarningDecorator(node.textContent, function (_ref2) { var bidiCharacter = _ref2.bidiCharacter, index = _ref2.index; bidiCharactersAndTheirPositions.push({ // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion position: pos + index, bidiCharacter: bidiCharacter }); }); return false; } var isCodeBlock = node.type.name === 'codeBlock'; if (isCodeBlock) { codeBidiWarningDecorator(node.textContent, function (_ref3) { var bidiCharacter = _ref3.bidiCharacter, index = _ref3.index; bidiCharactersAndTheirPositions.push({ // Ignored via go/ees005 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion position: pos + index + 1, bidiCharacter: bidiCharacter }); }); } }); // Bidi characters are not expected to commonly appear in code snippets, so recreating the decoration set // for documents rather than reusing existing decorations seems a reasonable performance/complexity tradeoff. if (bidiCharactersAndTheirPositions.length === 0) { return DecorationSet.empty; } var newBidiWarningsDecorationSet = DecorationSet.create(doc, bidiCharactersAndTheirPositions.map(function (_ref4) { var position = _ref4.position, bidiCharacter = _ref4.bidiCharacter; // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead var renderKey = uuid(); return Decoration.widget(position, function (_el) { return renderDOM({ bidiCharacter: bidiCharacter, codeBidiWarningLabel: codeBidiWarningLabel, tooltipEnabled: tooltipEnabled, nodeViewPortalProviderAPI: nodeViewPortalProviderAPI, renderKey: renderKey }); }, { destroy: function destroy(_el) { // removing portalprovider clean up due to a rendering bug // with this plugin under React 18. This matches the previous // React 16 behaviour which never cleaned up rendering. // // This will mean CodeBidi instances are not cleaned up, but // this is expected to be minimal due to the low frequency of // bidi characters in code blocks. // // We will fix this in a follow up ticket to rewrite the plugin // to use pure toDOM -> ED-26540 // nodeViewPortalProviderAPI.remove(renderKey); } }); })); return newBidiWarningsDecorationSet; } function renderDOM(_ref5) { var bidiCharacter = _ref5.bidiCharacter, codeBidiWarningLabel = _ref5.codeBidiWarningLabel, tooltipEnabled = _ref5.tooltipEnabled, nodeViewPortalProviderAPI = _ref5.nodeViewPortalProviderAPI, renderKey = _ref5.renderKey; var element = document.createElement('span'); nodeViewPortalProviderAPI.render(function () { return /*#__PURE__*/React.createElement(CodeBidiWarning, { bidiCharacter: bidiCharacter, skipChildren: true, label: codeBidiWarningLabel, tooltipEnabled: tooltipEnabled }); }, element, renderKey); return element; }