@atlaskit/editor-plugin-card
Version:
Card plugin for @atlaskit/editor-core
744 lines (738 loc) • 36.8 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.isPreviewPanelResponsivenessEnabled = exports.getAspectRatioForUrl = exports.embedCardNodeView = exports.EmbedOrBlockCardComponent = exports.EmbedCardComponent = exports.EmbedCard = void 0;
var _get2 = _interopRequireDefault(require("@babel/runtime/helpers/get"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _react = _interopRequireDefault(require("react"));
var _rafSchd = _interopRequireDefault(require("raf-schd"));
var _uuid = require("uuid");
var _setAttrs = require("@atlaskit/adf-schema/steps/set-attrs");
var _urlCheckers = require("@atlaskit/editor-card-provider/url-checkers");
var _MediaSingle = _interopRequireDefault(require("@atlaskit/editor-common/MediaSingle"));
var _utils = require("@atlaskit/editor-common/Popup/utils");
var _reactNodeView = _interopRequireDefault(require("@atlaskit/editor-common/react-node-view"));
var _UnsupportedBlock = _interopRequireDefault(require("@atlaskit/editor-common/UnsupportedBlock"));
var _useSharedPluginStateSelector = require("@atlaskit/editor-common/useSharedPluginStateSelector");
var _useSharedPluginStateWithSelector = require("@atlaskit/editor-common/useSharedPluginStateWithSelector");
var _utils2 = require("@atlaskit/editor-common/utils");
var _constants = require("@atlaskit/editor-shared-styles/constants");
var _editorSmartLinkDraggable = require("@atlaskit/editor-smart-link-draggable");
var _isExperimentEnabled = require("@atlaskit/platform-feature-experiments/is-experiment-enabled");
var _componentWithCondition = require("@atlaskit/platform-feature-flags-react/component-with-condition");
var _fg = require("@atlaskit/platform-feature-flags/fg");
var _lazy = require("@atlaskit/smart-card/card/lazy");
var _embedResizeMessageListener = require("@atlaskit/smart-card/embed-resize-message-listener");
var _ssr = require("@atlaskit/smart-card/ssr");
var _editorExperiment = require("@atlaskit/tmp-editor-statsig/editor-experiment");
var _expValEqualsNoExposure = require("@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure");
var _actions = require("../pm-plugins/actions");
var _ResizableEmbedCard = _interopRequireDefault(require("../ui/ResizableEmbedCard"));
var _SmartCardSSRReactContextsProvider = require("../ui/SmartCardSSRReactContextsProvider");
var _blockCard = require("./blockCard");
var _genericCard = require("./genericCard");
var _isIntersectionObserverSupported = require("./isIntersectionObserverSupported");
function _superPropGet(t, o, e, r) { var p = (0, _get2.default)((0, _getPrototypeOf2.default)(1 & r ? t.prototype : t), o, e); return 2 & r && "function" == typeof p ? function (t) { return p.apply(e, t); } : p; }
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; }
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); } // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
/**
* Returns a forced aspect ratio for URLs that have a known canvas shape,
* overriding the generic value returned by the link resolver.
* Add new URL checks here as more content types get fixed aspect ratios.
*/
/**
* Returns a forced aspect ratio for URLs that have a known canvas shape,
* or `undefined` to use the default resolver-provided ratio.
*
* @internal Exported for testing only.
*/
var getAspectRatioForUrl = exports.getAspectRatioForUrl = function getAspectRatioForUrl(url) {
if (url && (0, _urlCheckers.isConfluenceSlideUrl)(url) && !(0, _fg.fg)('cc-mui-slides-opted-out') && (0, _expValEqualsNoExposure.expValEqualsNoExposure)('cc-mui-slides-experiment', 'isEnabled', true)) {
// Slides have a 16:9 canvas
return 16 / 9;
}
return undefined;
};
var selector = function selector(states) {
var _states$widthState, _states$widthState2, _states$editorDisable;
return {
widthStateLineLength: ((_states$widthState = states.widthState) === null || _states$widthState === void 0 ? void 0 : _states$widthState.lineLength) || 0,
widthStateWidth: ((_states$widthState2 = states.widthState) === null || _states$widthState2 === void 0 ? void 0 : _states$widthState2.width) || 0,
editorDisabled: (_states$editorDisable = states.editorDisabledState) === null || _states$editorDisable === void 0 ? void 0 : _states$editorDisable.editorDisabled
};
};
var CardInner = function CardInner(_ref) {
var pluginInjectionApi = _ref.pluginInjectionApi,
getPosSafely = _ref.getPosSafely,
getLineLength = _ref.getLineLength,
view = _ref.view,
smartCard = _ref.smartCard,
updateSize = _ref.updateSize,
getPos = _ref.getPos,
aspectRatio = _ref.aspectRatio,
allowResizing = _ref.allowResizing,
hasPreview = _ref.hasPreview,
heightAlone = _ref.heightAlone,
cardProps = _ref.cardProps,
dispatchAnalyticsEvent = _ref.dispatchAnalyticsEvent;
var _useSharedPluginState = (0, _useSharedPluginStateWithSelector.useSharedPluginStateWithSelector)(pluginInjectionApi, ['width', 'editorDisabled'], selector),
widthStateLineLength = _useSharedPluginState.widthStateLineLength,
widthStateWidth = _useSharedPluginState.widthStateWidth,
editorDisabled = _useSharedPluginState.editorDisabled;
var pos = getPosSafely();
if (pos === undefined) {
return null;
}
var lineLength = getLineLength(view, pos, widthStateLineLength);
var containerWidth = (0, _utils2.isRichMediaInsideOfBlockNode)(view, pos) ? lineLength : widthStateWidth;
if (!allowResizing || !hasPreview) {
// There are two ways `width` and `height` can be defined here:
// 1) Either as `heightAlone` as height value and no width
// 2) or as `1` for height and aspectRation (defined or a default one) as a width
// See above for how aspectRation is calculated.
var defaultAspectRatio = _constants.DEFAULT_EMBED_CARD_WIDTH / _constants.DEFAULT_EMBED_CARD_HEIGHT;
var richMediaWrapperHeight = 1;
var richMediaWrapperWidth = aspectRatio || defaultAspectRatio;
if (heightAlone) {
richMediaWrapperHeight = heightAlone;
richMediaWrapperWidth = undefined;
}
return /*#__PURE__*/_react.default.createElement(_MediaSingle.default
// Ignored via go/ees005
// eslint-disable-next-line react/jsx-props-no-spreading
, (0, _extends2.default)({}, cardProps, {
height: richMediaWrapperHeight,
width: richMediaWrapperWidth,
nodeType: "embedCard",
hasFallbackContainer: hasPreview,
lineLength: lineLength,
containerWidth: containerWidth
}), smartCard);
}
var displayGrid = function displayGrid(visible, gridType, highlight) {
var _pluginInjectionApi$g;
return pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$g = pluginInjectionApi.grid) === null || _pluginInjectionApi$g === void 0 || (_pluginInjectionApi$g = _pluginInjectionApi$g.actions) === null || _pluginInjectionApi$g === void 0 ? void 0 : _pluginInjectionApi$g.displayGrid(view)({
visible: visible,
gridType: gridType,
highlight: highlight
});
};
return /*#__PURE__*/_react.default.createElement(_ResizableEmbedCard.default
// Ignored via go/ees005
// eslint-disable-next-line react/jsx-props-no-spreading
, (0, _extends2.default)({}, cardProps, {
height: heightAlone,
aspectRatio: aspectRatio,
view: view,
getPos: getPos,
lineLength: lineLength,
gridSize: 12,
containerWidth: containerWidth,
displayGrid: displayGrid,
updateSize: updateSize,
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
isResizeDisabled: editorDisabled
}), smartCard);
};
// eslint-disable-next-line @repo/internal/react/no-class-components
var EmbedCardComponent = exports.EmbedCardComponent = /*#__PURE__*/function (_React$PureComponent) {
function EmbedCardComponent(props) {
var _this;
(0, _classCallCheck2.default)(this, EmbedCardComponent);
_this = _callSuper(this, EmbedCardComponent, [props]);
(0, _defineProperty2.default)(_this, "embedIframeRef", /*#__PURE__*/_react.default.createRef());
(0, _defineProperty2.default)(_this, "getPosSafely", function () {
var getPos = _this.props.getPos;
if (!getPos || typeof getPos === 'boolean') {
return;
}
try {
return getPos();
} catch (_unused) {
// Can blow up in rare cases, when node has been removed.
}
});
(0, _defineProperty2.default)(_this, "onResolve", function (data) {
if ((0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_preserve_smart_card_embeds')) {
_this.resolvedCardData = {
title: data.title,
url: data.url,
nodeUrl: _this.props.node.attrs.url
};
}
_this.resolveCard(data);
});
(0, _defineProperty2.default)(_this, "resolveCard", function (data) {
var _getAspectRatioForUrl;
var view = _this.props.view;
var title = data.title,
url = data.url,
resolvedAspectRatio = data.aspectRatio;
var _this$props$node$attr = _this.props.node.attrs,
originalHeight = _this$props$node$attr.originalHeight,
originalWidth = _this$props$node$attr.originalWidth;
var aspectRatio = (_getAspectRatioForUrl = getAspectRatioForUrl(url)) !== null && _getAspectRatioForUrl !== void 0 ? _getAspectRatioForUrl : resolvedAspectRatio;
if (aspectRatio && !originalHeight && !originalWidth) {
// Assumption here is if ADF already have both height and width set,
// we will going to use that later on in this class as aspectRatio
// Most likely we dealing with an embed that received aspectRatio via onResolve previously
// and now this information already stored in ADF.
_this.setState({
initialAspectRatio: aspectRatio
});
_this.saveOriginalDimensionsAttributes(_constants.DEFAULT_EMBED_CARD_HEIGHT, _constants.DEFAULT_EMBED_CARD_HEIGHT * aspectRatio);
}
// don't dispatch immediately since we might be in the middle of
// rendering a nodeview
(0, _rafSchd.default)(function () {
if ((0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_reduce_forced_layout_2')) {
var _pluginInjectionApi$c;
if (_this.removeCardDispatched || _this.getPosSafely() === undefined) {
return;
}
var _this$props = _this.props,
pluginInjectionApi = _this$props.pluginInjectionApi,
id = _this$props.id;
pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$c = pluginInjectionApi.card.actions) === null || _pluginInjectionApi$c === void 0 || _pluginInjectionApi$c.registerCard({
id: id,
title: title,
url: url,
getPos: _this.getPosSafely
});
} else {
var pos = _this.getPosSafely();
if (pos === undefined) {
return;
}
return view.dispatch((0, _actions.registerCard)({
title: title,
url: url,
pos: pos,
id: _this.props.id
})(view.state.tr));
}
})();
try {
var _this$props$cardConte, _this$props$cardConte2;
var cardContext = (_this$props$cardConte = _this.props.cardContext) !== null && _this$props$cardConte !== void 0 && _this$props$cardConte.value ? (_this$props$cardConte2 = _this.props.cardContext) === null || _this$props$cardConte2 === void 0 ? void 0 : _this$props$cardConte2.value : undefined;
var hasPreview = url && cardContext && cardContext.extractors.getPreview(url, 'web');
if (!hasPreview) {
_this.setState({
hasPreview: false
});
}
} catch (_unused2) {}
});
(0, _defineProperty2.default)(_this, "registerResolvedCard", function (_ref2) {
var _pluginInjectionApi$c2;
var title = _ref2.title,
url = _ref2.url;
if (_this.removeCardDispatched || _this.props.view.isDestroyed || _this.getPosSafely() === undefined) {
return;
}
var _this$props2 = _this.props,
pluginInjectionApi = _this$props2.pluginInjectionApi,
id = _this$props2.id;
pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$c2 = pluginInjectionApi.card.actions) === null || _pluginInjectionApi$c2 === void 0 || _pluginInjectionApi$c2.registerCard({
id: id,
title: title,
url: url,
getPos: _this.getPosSafely
});
});
(0, _defineProperty2.default)(_this, "updateSize", function (pctWidth, layout) {
var _this$props$view = _this.props.view,
state = _this$props$view.state,
dispatch = _this$props$view.dispatch;
var pos = _this.getPosSafely();
if (pos === undefined) {
return;
}
var tr = state.tr.setNodeMarkup(pos, undefined, _objectSpread(_objectSpread({}, _this.props.node.attrs), {}, {
width: pctWidth,
layout: layout
}));
tr.setMeta('scrollIntoView', false);
dispatch(tr);
return true;
});
/**
* Defers line-length measurement until the embed card DOM has fully rendered.
*
* When put embed in the expand, reload the page and open that expand, the embed was collapsed.
* Because the `.rich-media-item` can temporarily report `offsetWidth = 1`, as proportional width styles have not been applied yet.
* Measuring at that moment would cache the bogus width and break resize calculations.
* Scheduling a measurement on the next animation frame ensures layout has
* settled. We then force the node view to re-render so `getLineLength`
* re-runs and captures the correct width.
*/
(0, _defineProperty2.default)(_this, "scheduleLineLengthRemeasureRaf", (0, _rafSchd.default)(function (view) {
if (view) {
_this.forceUpdate();
}
}));
(0, _defineProperty2.default)(_this, "getLineLength", function (view, pos, originalLineLength) {
if (typeof pos === 'number' && (0, _utils2.isRichMediaInsideOfBlockNode)(view, pos)) {
var $pos = view.state.doc.resolve(pos);
var domNode = view.nodeDOM($pos.pos);
if ($pos.nodeAfter && _utils2.floatingLayouts.indexOf($pos.nodeAfter.attrs.layout) > -1 && domNode && domNode.parentElement) {
return domNode.parentElement.offsetWidth;
}
if (domNode instanceof HTMLElement) {
var measuredWidth = domNode.offsetWidth;
if (measuredWidth <= 1) {
_this.scheduleLineLengthRemeasureRaf(view);
return originalLineLength;
}
return measuredWidth;
}
}
return originalLineLength;
});
/**
* Even though render is capable of listening and reacting to iframely wrapper iframe sent `resize` events
* it's good idea to store latest actual height in ADF, so that when renderer (well, editor as well) is loading
* we will show embed window of appropriate size and avoid unnecessary content jumping.
*/
(0, _defineProperty2.default)(_this, "saveOriginalDimensionsAttributes", function (height, width) {
var view = _this.props.view;
// Please, do not copy or use this kind of code below
// @ts-ignore
var fakeTableResizePluginKey = {
key: 'tableFlexiColumnResizing$',
getState: function getState(state) {
// eslint-disable-next-line
return state['tableFlexiColumnResizing$'];
}
};
var fakeTableResizeState = fakeTableResizePluginKey.getState(view.state);
// We are not updating ADF when this function fired while table is resizing.
// Changing ADF in the middle of resize will break table resize plugin logic
// (tables will be considered different at the end of the drag and cell size won't be stored)
// But this is not a big problem, editor user will be seeing latest height anyway (via updated state)
// And even if page to be saved with slightly outdated height, renderer is capable of reading latest height value
// when embed loads, and so it won't be a problem.
if (fakeTableResizeState !== null && fakeTableResizeState !== void 0 && fakeTableResizeState.dragging) {
return;
}
(0, _rafSchd.default)(function () {
var pos = _this.getPosSafely();
if (pos === undefined) {
return;
}
view.dispatch(view.state.tr.step(new _setAttrs.SetAttrsStep(pos, {
originalHeight: height,
originalWidth: width
})).setMeta('addToHistory', false));
})();
});
(0, _defineProperty2.default)(_this, "onHeightUpdate", function (height) {
_this.setState({
liveHeight: height
});
_this.saveOriginalDimensionsAttributes(height, undefined);
});
(0, _defineProperty2.default)(_this, "onError", function (_ref3) {
var err = _ref3.err;
if (err) {
throw err;
}
});
(0, _defineProperty2.default)(_this, "removeCardDispatched", false);
_this.scrollContainer = (0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_reduce_forced_layout_2') && (0, _isIntersectionObserverSupported.isIntersectionObserverSupported)() ? undefined :
// eslint-disable-next-line @atlaskit/editor/no-as-casting
(0, _utils.findOverflowScrollParent)(props.view.dom) || undefined;
_this.state = {
hasPreview: true
};
return _this;
}
(0, _inherits2.default)(EmbedCardComponent, _React$PureComponent);
return (0, _createClass2.default)(EmbedCardComponent, [{
key: "componentDidUpdate",
value: function componentDidUpdate(prevProps) {
var _this2 = this;
if ((0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_preserve_smart_card_embeds')) {
var _this$resolvedCardDat;
if (((_this$resolvedCardDat = this.resolvedCardData) === null || _this$resolvedCardDat === void 0 ? void 0 : _this$resolvedCardDat.nodeUrl) !== this.props.node.attrs.url) {
this.resolvedCardData = undefined;
}
if ((0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_reduce_forced_layout_2') && this.props.getPos !== prevProps.getPos && this.resolvedCardData) {
var resolvedCardData = this.resolvedCardData;
(0, _rafSchd.default)(function () {
return _this2.registerResolvedCard(resolvedCardData);
})();
}
}
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
this.removeCard();
}
}, {
key: "removeCard",
value: function removeCard() {
if (this.removeCardDispatched) {
return;
}
this.removeCardDispatched = true;
this.removeCardRegistration();
}
}, {
key: "removeCardRegistration",
value: function removeCardRegistration() {
if ((0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_preserve_smart_card_embeds') && this.props.view.isDestroyed) {
return;
}
if ((0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_reduce_forced_layout_2')) {
var _pluginInjectionApi$c3;
var _this$props3 = this.props,
pluginInjectionApi = _this$props3.pluginInjectionApi,
id = _this$props3.id;
pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$c3 = pluginInjectionApi.card.actions) === null || _pluginInjectionApi$c3 === void 0 || _pluginInjectionApi$c3.removeRegisteredCard(id);
} else {
var tr = this.props.view.state.tr;
(0, _actions.removeCard)({
id: this.props.id
})(tr);
this.props.view.dispatch(tr);
}
}
}, {
key: "render",
value: function render() {
var _this$props4 = this.props,
node = _this$props4.node,
allowResizing = _this$props4.allowResizing,
fullWidthMode = _this$props4.fullWidthMode,
view = _this$props4.view,
dispatchAnalyticsEvent = _this$props4.dispatchAnalyticsEvent,
getPos = _this$props4.getPos,
pluginInjectionApi = _this$props4.pluginInjectionApi,
actionOptions = _this$props4.actionOptions,
onClick = _this$props4.onClick,
CompetitorPrompt = _this$props4.CompetitorPrompt,
isPageSSRed = _this$props4.isPageSSRed;
var _node$attrs = node.attrs,
url = _node$attrs.url,
pctWidth = _node$attrs.width,
layout = _node$attrs.layout,
originalHeight = _node$attrs.originalHeight,
originalWidth = _node$attrs.originalWidth;
var _this$state = this.state,
hasPreview = _this$state.hasPreview,
liveHeight = _this$state.liveHeight,
initialAspectRatio = _this$state.initialAspectRatio;
// We don't want to use `originalHeight` when `originalWidth` also present,
// since `heightAlone` is defined only when just height is available.
var heightAlone = liveHeight !== null && liveHeight !== void 0 ? liveHeight : !originalWidth && originalHeight || undefined;
var aspectRatio = !heightAlone && (
// No need getting aspectRatio if heightAlone defined already
initialAspectRatio ||
// If we have initialAspectRatio (coming from iframely) we should go with that
originalHeight && originalWidth && originalWidth / originalHeight) ||
// If ADF contains both width and height we get ratio from that
undefined;
var cardProps = {
layout: layout,
pctWidth: pctWidth,
fullWidthMode: fullWidthMode
};
var smartCard = isPageSSRed ? /*#__PURE__*/_react.default.createElement(_ssr.CardSSR, {
key: url,
url: url,
appearance: "embed",
onClick: onClick,
onResolve: this.onResolve,
onError: this.onError,
frameStyle: "show",
inheritDimensions: true,
platform: 'web',
container: this.scrollContainer,
embedIframeRef: this.embedIframeRef,
actionOptions: actionOptions,
CompetitorPrompt: CompetitorPrompt,
hideIconLoadingSkeleton: true
}) : /*#__PURE__*/_react.default.createElement(_lazy.Card, {
key: url,
url: url,
appearance: "embed",
onClick: onClick,
onResolve: this.onResolve,
onError: this.onError,
frameStyle: "show",
inheritDimensions: true,
platform: 'web',
container: this.scrollContainer,
embedIframeRef: this.embedIframeRef,
actionOptions: actionOptions,
CompetitorPrompt: CompetitorPrompt
});
return /*#__PURE__*/_react.default.createElement(_editorSmartLinkDraggable.SmartLinkDraggable, {
url: url,
appearance: _editorSmartLinkDraggable.SMART_LINK_APPEARANCE.EMBED,
source: _editorSmartLinkDraggable.SMART_LINK_DRAG_TYPES.EDITOR
}, /*#__PURE__*/_react.default.createElement(_embedResizeMessageListener.EmbedResizeMessageListener, {
embedIframeRef: this.embedIframeRef,
onHeightUpdate: this.onHeightUpdate
}, /*#__PURE__*/_react.default.createElement(CardInner, {
pluginInjectionApi: pluginInjectionApi,
smartCard: smartCard,
hasPreview: hasPreview,
getPosSafely: this.getPosSafely,
view: view,
getLineLength: this.getLineLength,
eventDispatcher: this.props.eventDispatcher,
updateSize: this.updateSize,
getPos: getPos,
aspectRatio: aspectRatio,
allowResizing: allowResizing,
heightAlone: heightAlone,
cardProps: cardProps,
dispatchAnalyticsEvent: dispatchAnalyticsEvent
})));
}
}]);
}(_react.default.PureComponent);
var EmbedOrBlockCardComponent = exports.EmbedOrBlockCardComponent = function EmbedOrBlockCardComponent(props) {
var width = (0, _useSharedPluginStateSelector.useSharedPluginStateSelector)(props.pluginInjectionApi, 'width.width');
var viewAsBlockCard = width && width <= _constants.akEditorFullPageNarrowBreakout;
return viewAsBlockCard ? /*#__PURE__*/_react.default.createElement(_blockCard.BlockCardComponent, {
id: props.id,
node: props.node,
view: props.view,
getPos: props.getPos,
pluginInjectionApi: props.pluginInjectionApi,
actionOptions: props.actionOptions,
onClick: props.onClick,
CompetitorPrompt: props.CompetitorPrompt,
allowResizing: props.allowResizing,
fullWidthMode: props.fullWidthMode,
dispatchAnalyticsEvent: props.dispatchAnalyticsEvent,
eventDispatcher: props.eventDispatcher,
cardContext: props.cardContext,
smartCard: props.smartCard,
hasPreview: props.hasPreview,
liveHeight: props.liveHeight,
initialAspectRatio: props.initialAspectRatio,
isPageSSRed: props.isPageSSRed,
provider: props.provider
}) : /*#__PURE__*/_react.default.createElement(EmbedCardComponent, {
id: props.id,
node: props.node,
view: props.view,
getPos: props.getPos,
pluginInjectionApi: props.pluginInjectionApi,
actionOptions: props.actionOptions,
onClick: props.onClick,
CompetitorPrompt: props.CompetitorPrompt,
allowResizing: props.allowResizing,
fullWidthMode: props.fullWidthMode,
dispatchAnalyticsEvent: props.dispatchAnalyticsEvent,
eventDispatcher: props.eventDispatcher,
cardContext: props.cardContext,
smartCard: props.smartCard,
hasPreview: props.hasPreview,
liveHeight: props.liveHeight,
initialAspectRatio: props.initialAspectRatio,
isPageSSRed: props.isPageSSRed,
provider: props.provider
});
};
var isPreviewPanelResponsivenessEnabled = exports.isPreviewPanelResponsivenessEnabled = function isPreviewPanelResponsivenessEnabled() {
return (0, _editorExperiment.editorExperiment)('platform_editor_preview_panel_responsiveness', true, {
exposure: true
});
};
var WrappedEmbedCardWithCondition = (0, _componentWithCondition.componentWithCondition)(function () {
return (0, _editorExperiment.editorExperiment)('platform_editor_preview_panel_responsiveness', true, {
exposure: true
});
}, EmbedOrBlockCardComponent, EmbedCardComponent);
var WrappedEmbedCard = (0, _genericCard.Card)(WrappedEmbedCardWithCondition, _UnsupportedBlock.default);
var EmbedCard = exports.EmbedCard = /*#__PURE__*/function (_ReactNodeView) {
function EmbedCard() {
var _this3;
(0, _classCallCheck2.default)(this, EmbedCard);
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_this3 = _callSuper(this, EmbedCard, [].concat(args));
// eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
(0, _defineProperty2.default)(_this3, "id", (0, _uuid.v4)());
(0, _defineProperty2.default)(_this3, "updateContentEditable", function (editorViewModeState, divElement) {
divElement.contentEditable = (editorViewModeState === null || editorViewModeState === void 0 ? void 0 : editorViewModeState.mode) === 'view' ? 'false' : 'true';
if ((0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_preserve_smart_card_embeds') && _this3.preservationSlot) {
_this3.preservationSlot.contentEditable = divElement.contentEditable;
}
});
return _this3;
}
(0, _inherits2.default)(EmbedCard, _ReactNodeView);
return (0, _createClass2.default)(EmbedCard, [{
key: "viewShouldUpdate",
value: function viewShouldUpdate(nextNode) {
if (this.node.attrs !== nextNode.attrs) {
return true;
}
return _superPropGet(EmbedCard, "viewShouldUpdate", this, 3)([nextNode]);
}
}, {
key: "createDomRef",
value: function createDomRef() {
var _this$reactComponentP,
_this4 = this,
_this$reactComponentP2;
var domRef = document.createElement('div');
// It is a tradeoff for the bug mentioned that occurs in Chrome: https://product-fabric.atlassian.net/browse/ED-5379, https://github.com/ProseMirror/prosemirror/issues/884
this.unsubscribe = (_this$reactComponentP = this.reactComponentProps.pluginInjectionApi) === null || _this$reactComponentP === void 0 || (_this$reactComponentP = _this$reactComponentP.editorViewMode) === null || _this$reactComponentP === void 0 ? void 0 : _this$reactComponentP.sharedState.onChange(function (_ref4) {
var nextSharedState = _ref4.nextSharedState;
return _this4.updateContentEditable(nextSharedState, domRef);
});
this.updateContentEditable((_this$reactComponentP2 = this.reactComponentProps.pluginInjectionApi) === null || _this$reactComponentP2 === void 0 || (_this$reactComponentP2 = _this$reactComponentP2.editorViewMode) === null || _this$reactComponentP2 === void 0 ? void 0 : _this$reactComponentP2.sharedState.currentState(), domRef);
domRef.setAttribute('spellcheck', 'false');
return domRef;
}
}, {
key: "setDomAttrs",
value: function setDomAttrs(node, element) {
_superPropGet(EmbedCard, "setDomAttrs", this, 3)([node, element]);
if ((0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_preserve_smart_card_embeds') && this.preservationSlot) {
_superPropGet(EmbedCard, "setDomAttrs", this, 3)([node, this.preservationSlot]);
if (element !== this.preservationSlot) {
Object.keys(node.attrs || {}).forEach(function (attr) {
return element.removeAttribute(attr);
});
}
}
}
}, {
key: "attachPreservationSlot",
value: function attachPreservationSlot(slot, getPos) {
var _this$unsubscribe,
_this$reactComponentP3,
_this5 = this;
this.getPos = getPos;
this.preservationSlot = slot;
slot.classList.add("".concat(this.node.type.name, "View-content-wrap"));
this.dom.classList.remove("".concat(this.node.type.name, "View-content-wrap"));
this.setDomAttrs(this.node, this.dom);
(_this$unsubscribe = this.unsubscribe) === null || _this$unsubscribe === void 0 || _this$unsubscribe.call(this);
var editorViewMode = (_this$reactComponentP3 = this.reactComponentProps.pluginInjectionApi) === null || _this$reactComponentP3 === void 0 || (_this$reactComponentP3 = _this$reactComponentP3.editorViewMode) === null || _this$reactComponentP3 === void 0 ? void 0 : _this$reactComponentP3.sharedState;
this.unsubscribe = editorViewMode === null || editorViewMode === void 0 ? void 0 : editorViewMode.onChange(function (_ref5) {
var nextSharedState = _ref5.nextSharedState;
return _this5.updateContentEditable(nextSharedState, _this5.dom);
});
this.updateContentEditable(editorViewMode === null || editorViewMode === void 0 ? void 0 : editorViewMode.currentState(), this.dom);
}
}, {
key: "canReuseWith",
value: function canReuseWith(provider, eventDispatcher) {
return this.reactComponentProps.provider === provider && this.eventDispatcher === eventDispatcher;
}
}, {
key: "render",
value: function render() {
var _this$reactComponentP4 = this.reactComponentProps,
eventDispatcher = _this$reactComponentP4.eventDispatcher,
allowResizing = _this$reactComponentP4.allowResizing,
fullWidthMode = _this$reactComponentP4.fullWidthMode,
dispatchAnalyticsEvent = _this$reactComponentP4.dispatchAnalyticsEvent,
pluginInjectionApi = _this$reactComponentP4.pluginInjectionApi,
onClickCallback = _this$reactComponentP4.onClickCallback,
CompetitorPrompt = _this$reactComponentP4.CompetitorPrompt,
isPageSSRed = _this$reactComponentP4.isPageSSRed,
provider = _this$reactComponentP4.provider,
intl = _this$reactComponentP4.intl,
smartCardContext = _this$reactComponentP4.smartCardContext;
return /*#__PURE__*/_react.default.createElement(_SmartCardSSRReactContextsProvider.SmartCardSSRReactContextsProvider, {
intl: intl,
smartCardContext: smartCardContext
}, /*#__PURE__*/_react.default.createElement(WrappedEmbedCard, {
node: this.node,
view: this.view,
eventDispatcher: eventDispatcher,
getPos: this.getPos,
allowResizing: allowResizing,
fullWidthMode: fullWidthMode,
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
pluginInjectionApi: pluginInjectionApi,
onClickCallback: onClickCallback,
id: this.id,
CompetitorPrompt: CompetitorPrompt,
isPageSSRed: isPageSSRed,
provider: provider
}));
}
/**
* Prevent ProseMirror from handling drag events on the smart-element-link,
* allowing native drag to work so SmartLinkDraggable can intercept it.
* @see {@link https://prosemirror.net/docs/ref/#view.NodeView.stopEvent}
*/
}, {
key: "stopEvent",
value: function stopEvent(event) {
if (event.type === 'dragstart') {
var target = event.target;
if (target instanceof HTMLElement && target.closest('[data-smart-element-link]')) {
return true;
}
}
return false;
}
}, {
key: "destroy",
value: function destroy() {
var _this$unsubscribe2;
(_this$unsubscribe2 = this.unsubscribe) === null || _this$unsubscribe2 === void 0 || _this$unsubscribe2.call(this);
if ((0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_preserve_smart_card_embeds')) {
this.preservationSlot = undefined;
}
_superPropGet(EmbedCard, "destroy", this, 3)([]);
}
}]);
}(_reactNodeView.default);
var embedCardNodeView = exports.embedCardNodeView = function embedCardNodeView(_ref6) {
var allowResizing = _ref6.allowResizing,
fullWidthMode = _ref6.fullWidthMode,
pmPluginFactoryParams = _ref6.pmPluginFactoryParams,
pluginInjectionApi = _ref6.pluginInjectionApi,
actionOptions = _ref6.actionOptions,
onClickCallback = _ref6.onClickCallback,
CompetitorPrompt = _ref6.CompetitorPrompt,
isPageSSRed = _ref6.isPageSSRed,
provider = _ref6.provider,
intl = _ref6.intl,
smartCardContext = _ref6.smartCardContext;
return function (node, view, getPos) {
var portalProviderAPI = pmPluginFactoryParams.portalProviderAPI,
eventDispatcher = pmPluginFactoryParams.eventDispatcher,
dispatchAnalyticsEvent = pmPluginFactoryParams.dispatchAnalyticsEvent;
var reactComponentProps = {
eventDispatcher: eventDispatcher,
allowResizing: allowResizing,
fullWidthMode: fullWidthMode,
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
pluginInjectionApi: pluginInjectionApi,
actionOptions: actionOptions,
onClickCallback: onClickCallback,
CompetitorPrompt: CompetitorPrompt,
isPageSSRed: isPageSSRed,
provider: provider,
intl: intl,
smartCardContext: smartCardContext
};
return new EmbedCard(node, view, getPos, portalProviderAPI, eventDispatcher, reactComponentProps).init();
};
};