UNPKG

@atlaskit/editor-plugin-unsupported-content

Version:

Unsupported Content plugin for @atlaskit/editor-core

121 lines (118 loc) • 5.64 kB
import _defineProperty from "@babel/runtime/helpers/defineProperty"; import { bind } from 'bind-event-listener'; import { ACTION_SUBJECT_ID } from '@atlaskit/editor-common/analytics/types/enums'; import { getBrowserInfo } from '@atlaskit/editor-common/browser'; import { unsupportedContentMessages } from '@atlaskit/editor-common/messages/unsupportedContent'; import { trackUnsupportedContentTooltipDisplayedFor } from '@atlaskit/editor-common/utils/track-unsupported-content'; import { VANILLA_TOOLTIP_DEFAULT_CLASS, VanillaTooltip } from '@atlaskit/editor-common/vanilla-tooltip'; import { ZERO_WIDTH_SPACE } from '@atlaskit/editor-common/whitespace/whitespace'; import { DOMSerializer } from '@atlaskit/editor-prosemirror/model'; import { getUnsupportedContent } from './get-unsupported-content'; import { getUnsupportedContentIconSpec } from './get-unsupported-content-icon-spec'; const VanillaUnsupportedInlineCssClassName = { INNER: 'unsupported-inline-vanilla-inner', ICON: 'unsupported-vanilla-icon' }; /** Identifies this tooltip for tests and debugging. */ const TOOLTIP_CLASS_NAME = 'unsupported-content-tooltip'; /** Distinct from the block node view's prefix, so the counter fallback below cannot collide. */ const TOOLTIP_ID_PREFIX = 'unsupported-inline-content-tooltip'; /** Classes applied to the tooltip element: the shared default look, plus our own hook. */ const TOOLTIP_CLASS_NAMES = `${VANILLA_TOOLTIP_DEFAULT_CLASS} ${TOOLTIP_CLASS_NAME}`; const INLINE_NODE_VIEW_CLASS_NAME = 'inlineNodeView'; const ZERO_WIDTH_SPACE_CONTAINER_CLASS_NAME = 'zeroWidthSpaceContainer'; const ADD_ZERO_WIDTH_SPACE_CLASS_NAME = `${INLINE_NODE_VIEW_CLASS_NAME}AddZeroWidthSpace`; const nextTooltipId = (() => { let count = 0; return () => typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function' ? `${TOOLTIP_ID_PREFIX}-${crypto.randomUUID()}` : `${TOOLTIP_ID_PREFIX}-${count += 1}`; })(); function getInlineSpec(node, label) { const browser = getBrowserInfo(); const trailingSpec = browser.android ? ['span', { class: ZERO_WIDTH_SPACE_CONTAINER_CLASS_NAME, contentEditable: 'false' }, ['span', { class: ADD_ZERO_WIDTH_SPACE_CLASS_NAME }], ZERO_WIDTH_SPACE] : ['span', { class: ADD_ZERO_WIDTH_SPACE_CLASS_NAME }]; return ['span', { class: `${node.type.name}View-content-wrap ${INLINE_NODE_VIEW_CLASS_NAME}`, contentEditable: 'false' }, ['span', { class: ZERO_WIDTH_SPACE_CONTAINER_CLASS_NAME }, ['span', { class: ADD_ZERO_WIDTH_SPACE_CLASS_NAME }], ZERO_WIDTH_SPACE], ['span', { class: VanillaUnsupportedInlineCssClassName.INNER }, label, getUnsupportedContentIconSpec(VanillaUnsupportedInlineCssClassName.ICON)], trailingSpec]; } function createUnsupportedInlineDOM(node, intl) { var _domElement$querySele; const label = getUnsupportedContent(unsupportedContentMessages.unsupportedInlineContent, 'Unsupported', node, intl); const { dom } = DOMSerializer.renderSpec(document, getInlineSpec(node, label)); const domElement = dom instanceof HTMLElement ? dom : undefined; const icon = (_domElement$querySele = domElement === null || domElement === void 0 ? void 0 : domElement.querySelector(`.${VanillaUnsupportedInlineCssClassName.ICON}`)) !== null && _domElement$querySele !== void 0 ? _domElement$querySele : null; return { dom, icon }; } export class UnsupportedInlineNodeViewVanilla { constructor(node, intl, dispatchAnalyticsEvent) { _defineProperty(this, "tooltip", null); _defineProperty(this, "unbindMouseenter", null); this.node = node; const { dom, icon } = createUnsupportedInlineDOM(node, intl); this.dom = dom; if (!icon) { return; } this.unbindMouseenter = bind(icon, { type: 'mouseenter', options: { once: true }, listener: event => { var _this$unbindMouseente; (_this$unbindMouseente = this.unbindMouseenter) === null || _this$unbindMouseente === void 0 ? void 0 : _this$unbindMouseente.call(this); this.unbindMouseenter = null; const tooltipText = intl.formatMessage(unsupportedContentMessages.unsupportedContentTooltip); this.tooltip = new VanillaTooltip(icon, tooltipText, nextTooltipId(), TOOLTIP_CLASS_NAMES, 300, // Use default style by having the default tooltip class name. undefined, () => { if (dispatchAnalyticsEvent) { var _this$node, _this$node$attrs, _this$node$attrs$orig; trackUnsupportedContentTooltipDisplayedFor(dispatchAnalyticsEvent, ACTION_SUBJECT_ID.ON_UNSUPPORTED_INLINE, (_this$node = this.node) === null || _this$node === void 0 ? void 0 : (_this$node$attrs = _this$node.attrs) === null || _this$node$attrs === void 0 ? void 0 : (_this$node$attrs$orig = _this$node$attrs.originalValue) === null || _this$node$attrs$orig === void 0 ? void 0 : _this$node$attrs$orig.type); } }); icon.dispatchEvent(new Event(event.type)); } }); } update(node) { if (node.type !== this.node.type) { return false; } if (!this.node.sameMarkup(node)) { return false; } this.node = node; return true; } ignoreMutation(mutation) { return mutation.type !== 'selection'; } destroy() { var _this$tooltip, _this$unbindMouseente2; (_this$tooltip = this.tooltip) === null || _this$tooltip === void 0 ? void 0 : _this$tooltip.destroy(); this.tooltip = null; (_this$unbindMouseente2 = this.unbindMouseenter) === null || _this$unbindMouseente2 === void 0 ? void 0 : _this$unbindMouseente2.call(this); this.unbindMouseenter = null; } }