UNPKG

@atlaskit/editor-plugin-caption

Version:

Caption plugin for @atlaskit/editor-core

75 lines (74 loc) 3.5 kB
import _defineProperty from "@babel/runtime/helpers/defineProperty"; import React from 'react'; import { SelectionBasedNodeView } from '@atlaskit/editor-common/selection-based-node-view'; import { Caption } from '@atlaskit/editor-common/ui'; export class CaptionNodeView extends SelectionBasedNodeView { constructor(node, view, getPos, portalProviderAPI, eventDispatcher, reactComponentProps, reactComponent, viewShouldUpdate, pluginInjectionApi) { super(node, view, getPos, portalProviderAPI, eventDispatcher, reactComponentProps, reactComponent, viewShouldUpdate); _defineProperty(this, "selected", this.insideSelection()); this.pluginInjectionApi = pluginInjectionApi; this.handleEditorDisabledChanged(); } createDomRef() { const domRef = document.createElement('figcaption'); domRef.setAttribute('data-caption', 'true'); return domRef; } getContentDOM() { var _this$pluginInjection, _this$pluginInjection2, _this$pluginInjection3; const dom = document.createElement('div'); // setting a className prevents PM/Chrome mutation observer from // incorrectly deleting nodes dom.className = 'caption-wrapper'; dom.setAttribute('contenteditable', (_this$pluginInjection = this.pluginInjectionApi) !== null && _this$pluginInjection !== void 0 && (_this$pluginInjection2 = _this$pluginInjection.editorDisabled) !== null && _this$pluginInjection2 !== void 0 && (_this$pluginInjection3 = _this$pluginInjection2.sharedState.currentState()) !== null && _this$pluginInjection3 !== void 0 && _this$pluginInjection3.editorDisabled ? 'false' : 'true'); return { dom }; } // ED-24114: We need to ignore mutations that are not related to the caption node // since these mutations can cause an infinite loop in React 18 when using createRoot ignoreMutation(mutation) { if (!this.contentDOM) { return true; } return !this.contentDOM.contains(mutation.target) && mutation.type !== 'selection'; } handleEditorDisabledChanged() { var _this$pluginInjection4; if ((_this$pluginInjection4 = this.pluginInjectionApi) !== null && _this$pluginInjection4 !== void 0 && _this$pluginInjection4.editorDisabled) { this.cleanupEditorDisabledListener = this.pluginInjectionApi.editorDisabled.sharedState.onChange(sharedState => { if (this.contentDOM) { this.contentDOM.setAttribute('contenteditable', sharedState.nextSharedState.editorDisabled ? 'false' : 'true'); } }); } } render(_props, forwardRef) { return /*#__PURE__*/React.createElement(Caption, { selected: this.insideSelection(), hasContent: this.node.content.childCount > 0 }, /*#__PURE__*/React.createElement("div", { ref: forwardRef })); } viewShouldUpdate(nextNode) { if (this.node.childCount !== nextNode.childCount) { return true; } const newSelected = this.insideSelection(); const selectedStateChange = this.selected !== newSelected; this.selected = newSelected; return selectedStateChange; } destroy() { if (this.cleanupEditorDisabledListener) { this.cleanupEditorDisabledListener(); } this.cleanupEditorDisabledListener = undefined; } } export default function captionNodeView(portalProviderAPI, eventDispatcher, pluginInjectionApi) { return (node, view, getPos) => { return new CaptionNodeView(node, view, getPos, portalProviderAPI, eventDispatcher, {}, undefined, undefined, pluginInjectionApi).init(); }; }