@atlaskit/editor-plugin-media
Version:
Media plugin for @atlaskit/editor-core
651 lines (645 loc) • 33.3 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.ReactMediaSingleNode = void 0;
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
var _get2 = _interopRequireDefault(require("@babel/runtime/helpers/get"));
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = _interopRequireWildcard(require("react"));
var _react2 = require("@emotion/react");
var _hooks = require("@atlaskit/editor-common/hooks");
var _mediaSingle = require("@atlaskit/editor-common/media-single");
var _providerFactory = require("@atlaskit/editor-common/provider-factory");
var _reactNodeView = _interopRequireDefault(require("@atlaskit/editor-common/react-node-view"));
var _ui = require("@atlaskit/editor-common/ui");
var _utils = require("@atlaskit/editor-common/utils");
var _state = require("@atlaskit/editor-prosemirror/state");
var _utils2 = require("@atlaskit/editor-prosemirror/utils");
var _cellSelection = require("@atlaskit/editor-tables/cell-selection");
var _mediaClient = require("@atlaskit/media-client");
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
var _captions = require("../commands/captions");
var _main = require("../pm-plugins/main");
var _CaptionPlaceholder = _interopRequireDefault(require("../ui/CaptionPlaceholder"));
var _ResizableMediaSingle = _interopRequireDefault(require("../ui/ResizableMediaSingle"));
var _ResizableMediaSingleNext = _interopRequireDefault(require("../ui/ResizableMediaSingle/ResizableMediaSingleNext"));
var _mediaCommon = require("../utils/media-common");
var _helpers = require("./helpers");
var _mediaNodeUpdater = require("./mediaNodeUpdater");
var _styles = require("./styles");
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
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 _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } /** @jsx jsx */
// eslint-disable-next-line @repo/internal/react/no-class-components
var MediaSingleNode = exports.default = /*#__PURE__*/function (_Component) {
(0, _inherits2.default)(MediaSingleNode, _Component);
var _super = _createSuper(MediaSingleNode);
function MediaSingleNode() {
var _this;
(0, _classCallCheck2.default)(this, MediaSingleNode);
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
_this = _super.call.apply(_super, [this].concat(args));
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "mediaNodeUpdater", null);
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "state", {
width: undefined,
height: undefined,
viewMediaClientConfig: undefined,
isCopying: false
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "mediaSingleWrapperRef", /*#__PURE__*/_react.default.createRef());
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "captionPlaceHolderRef", /*#__PURE__*/_react.default.createRef());
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "createOrUpdateMediaNodeUpdater", function (props) {
var node = _this.props.node.firstChild;
var updaterProps = _objectSpread(_objectSpread({}, props), {}, {
isMediaSingle: true,
node: node ? node : _this.props.node,
dispatchAnalyticsEvent: _this.props.dispatchAnalyticsEvent
});
if (!_this.mediaNodeUpdater) {
_this.mediaNodeUpdater = new _mediaNodeUpdater.MediaNodeUpdater(updaterProps);
} else {
var _this$mediaNodeUpdate;
(_this$mediaNodeUpdate = _this.mediaNodeUpdater) === null || _this$mediaNodeUpdate === void 0 || _this$mediaNodeUpdate.setProps(updaterProps);
}
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "setViewMediaClientConfig", /*#__PURE__*/function () {
var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(props) {
var mediaProvider, viewMediaClientConfig;
return _regenerator.default.wrap(function _callee$(_context) {
while (1) switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return props.mediaProvider;
case 2:
mediaProvider = _context.sent;
if (mediaProvider) {
viewMediaClientConfig = mediaProvider.viewMediaClientConfig;
_this.setState({
viewMediaClientConfig: viewMediaClientConfig
});
}
case 4:
case "end":
return _context.stop();
}
}, _callee);
}));
return function (_x) {
return _ref.apply(this, arguments);
};
}());
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "updateMediaNodeAttributes", /*#__PURE__*/function () {
var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(props) {
var _this$mediaNodeUpdate2, _this$props$node$firs, _this$mediaNodeUpdate4, _this$mediaNodeUpdate6;
var addPendingTask, node, updatedDimensions, currentAttrs, _this$mediaNodeUpdate3, updatingNode, contextId, _this$mediaNodeUpdate5, hasDifferentContextId, copyNode;
return _regenerator.default.wrap(function _callee2$(_context2) {
while (1) switch (_context2.prev = _context2.next) {
case 0:
_this.createOrUpdateMediaNodeUpdater(props);
addPendingTask = _this.props.mediaPluginState.addPendingTask; // we want the first child of MediaSingle (type "media")
node = _this.props.node.firstChild;
if (node) {
_context2.next = 5;
break;
}
return _context2.abrupt("return");
case 5:
_context2.next = 7;
return (_this$mediaNodeUpdate2 = _this.mediaNodeUpdater) === null || _this$mediaNodeUpdate2 === void 0 ? void 0 : _this$mediaNodeUpdate2.getRemoteDimensions();
case 7:
updatedDimensions = _context2.sent;
currentAttrs = (_this$props$node$firs = _this.props.node.firstChild) === null || _this$props$node$firs === void 0 ? void 0 : _this$props$node$firs.attrs;
if (updatedDimensions && ((currentAttrs === null || currentAttrs === void 0 ? void 0 : currentAttrs.width) !== updatedDimensions.width || (currentAttrs === null || currentAttrs === void 0 ? void 0 : currentAttrs.height) !== updatedDimensions.height)) {
(_this$mediaNodeUpdate3 = _this.mediaNodeUpdater) === null || _this$mediaNodeUpdate3 === void 0 || _this$mediaNodeUpdate3.updateDimensions(updatedDimensions);
}
if (!(node.attrs.type === 'external' && node.attrs.__external)) {
_context2.next = 16;
break;
}
updatingNode = _this.mediaNodeUpdater.handleExternalMedia(_this.props.getPos);
addPendingTask(updatingNode);
_context2.next = 15;
return updatingNode;
case 15:
return _context2.abrupt("return");
case 16:
contextId = (_this$mediaNodeUpdate4 = _this.mediaNodeUpdater) === null || _this$mediaNodeUpdate4 === void 0 ? void 0 : _this$mediaNodeUpdate4.getNodeContextId();
if (contextId) {
_context2.next = 20;
break;
}
_context2.next = 20;
return (_this$mediaNodeUpdate5 = _this.mediaNodeUpdater) === null || _this$mediaNodeUpdate5 === void 0 ? void 0 : _this$mediaNodeUpdate5.updateContextId();
case 20:
_context2.next = 22;
return (_this$mediaNodeUpdate6 = _this.mediaNodeUpdater) === null || _this$mediaNodeUpdate6 === void 0 ? void 0 : _this$mediaNodeUpdate6.hasDifferentContextId();
case 22:
hasDifferentContextId = _context2.sent;
if (!hasDifferentContextId) {
_context2.next = 35;
break;
}
_this.setState({
isCopying: true
});
_context2.prev = 25;
copyNode = _this.mediaNodeUpdater.copyNode({
traceId: node.attrs.__mediaTraceId
});
addPendingTask(copyNode);
_context2.next = 30;
return copyNode;
case 30:
_context2.next = 35;
break;
case 32:
_context2.prev = 32;
_context2.t0 = _context2["catch"](25);
// if copyNode fails, let's set isCopying false so we can show the eventual error
_this.setState({
isCopying: false
});
case 35:
case "end":
return _context2.stop();
}
}, _callee2, null, [[25, 32]]);
}));
return function (_x2) {
return _ref2.apply(this, arguments);
};
}());
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "selectMediaSingle", function (_ref3) {
var event = _ref3.event;
var propPos = _this.props.getPos();
if (typeof propPos !== 'number') {
return;
}
// We need to call "stopPropagation" here in order to prevent the browser from navigating to
// another URL if the media node is wrapped in a link mark.
event.stopPropagation();
var state = _this.props.view.state;
if (event.shiftKey) {
// don't select text if there is current selection in a table (as this would override selected cells)
if (state.selection instanceof _cellSelection.CellSelection) {
return;
}
(0, _utils.setTextSelection)(_this.props.view, state.selection.from < propPos ? state.selection.from : propPos,
// + 3 needed for offset of the media inside mediaSingle and cursor to make whole mediaSingle selected
state.selection.to > propPos ? state.selection.to : propPos + 3);
} else {
(0, _utils.setNodeSelection)(_this.props.view, propPos);
}
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "updateSize", function (width, layout) {
var _this$props$view = _this.props.view,
state = _this$props$view.state,
dispatch = _this$props$view.dispatch;
var pos = _this.props.getPos();
if (typeof pos === 'undefined') {
return;
}
var tr = state.tr.setNodeMarkup(pos, undefined, _objectSpread(_objectSpread({}, _this.props.node.attrs), {}, {
layout: layout,
width: width,
widthType: 'pixel'
}));
tr.setMeta('scrollIntoView', false);
/**
* Any changes to attributes of a node count the node as "recreated" in Prosemirror[1]
* This makes it so Prosemirror resets the selection to the child i.e. "media" instead of "media-single"
* The recommended fix is to reset the selection.[2]
*
* [1] https://discuss.prosemirror.net/t/setnodemarkup-loses-current-nodeselection/976
* [2] https://discuss.prosemirror.net/t/setnodemarkup-and-deselect/3673
*/
tr.setSelection(_state.NodeSelection.create(tr.doc, pos));
return dispatch(tr);
});
// Workaround for iOS 16 Caption selection issue
// @see https://product-fabric.atlassian.net/browse/MEX-2012
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onMediaSingleClicked", function (event) {
var _this$captionPlaceHol;
if (!_utils.browser.ios) {
return;
}
if (_this.mediaSingleWrapperRef.current !== event.target) {
return;
}
(_this$captionPlaceHol = _this.captionPlaceHolderRef.current) === null || _this$captionPlaceHol === void 0 || _this$captionPlaceHol.click();
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "clickPlaceholder", function () {
var _pluginInjectionApi$a;
var _this$props = _this.props,
view = _this$props.view,
getPos = _this$props.getPos,
node = _this$props.node,
pluginInjectionApi = _this$props.pluginInjectionApi;
if (typeof getPos === 'boolean') {
return;
}
(0, _captions.insertAndSelectCaptionFromMediaSinglePos)(pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a === void 0 ? void 0 : _pluginInjectionApi$a.actions)(getPos(), node)(view.state, view.dispatch);
});
return _this;
}
(0, _createClass2.default)(MediaSingleNode, [{
key: "UNSAFE_componentWillReceiveProps",
value: function UNSAFE_componentWillReceiveProps(nextProps) {
if (!this.mediaNodeUpdater) {
this.createOrUpdateMediaNodeUpdater(nextProps);
}
if (nextProps.mediaProvider !== this.props.mediaProvider) {
this.setViewMediaClientConfig(nextProps);
}
// Forced updates not required on mobile
if (nextProps.isCopyPasteEnabled === false) {
return;
}
if (nextProps.mediaProvider !== this.props.mediaProvider) {
var _this$mediaNodeUpdate7;
this.createOrUpdateMediaNodeUpdater(nextProps);
(_this$mediaNodeUpdate7 = this.mediaNodeUpdater) === null || _this$mediaNodeUpdate7 === void 0 || _this$mediaNodeUpdate7.updateMediaSingleFileAttrs();
} else if (nextProps.node.firstChild && this.props.node.firstChild) {
var attrsChanged = (0, _helpers.hasPrivateAttrsChanged)(this.props.node.firstChild.attrs, nextProps.node.firstChild.attrs);
if (attrsChanged) {
var _this$mediaNodeUpdate8;
this.createOrUpdateMediaNodeUpdater(nextProps);
// We need to call this method on any prop change since attrs can get removed with collab editing
(_this$mediaNodeUpdate8 = this.mediaNodeUpdater) === null || _this$mediaNodeUpdate8 === void 0 || _this$mediaNodeUpdate8.updateMediaSingleFileAttrs();
}
}
}
}, {
key: "componentDidMount",
value: function () {
var _componentDidMount = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() {
var contextIdentifierProvider;
return _regenerator.default.wrap(function _callee3$(_context3) {
while (1) switch (_context3.prev = _context3.next) {
case 0:
contextIdentifierProvider = this.props.contextIdentifierProvider;
this.createOrUpdateMediaNodeUpdater(this.props);
_context3.next = 4;
return Promise.all([this.setViewMediaClientConfig(this.props), this.updateMediaNodeAttributes(this.props)]);
case 4:
_context3.t0 = this;
_context3.next = 7;
return contextIdentifierProvider;
case 7:
_context3.t1 = _context3.sent;
_context3.t2 = {
contextIdentifierProvider: _context3.t1
};
_context3.t0.setState.call(_context3.t0, _context3.t2);
case 10:
case "end":
return _context3.stop();
}
}, _callee3, this);
}));
function componentDidMount() {
return _componentDidMount.apply(this, arguments);
}
return componentDidMount;
}()
}, {
key: "render",
value: function render() {
var _pluginInjectionApi$m;
var _this$props2 = this.props,
selected = _this$props2.selected,
getPos = _this$props2.getPos,
node = _this$props2.node,
mediaOptions = _this$props2.mediaOptions,
fullWidthMode = _this$props2.fullWidthMode,
state = _this$props2.view.state,
view = _this$props2.view,
pluginInjectionApi = _this$props2.pluginInjectionApi,
containerWidth = _this$props2.width,
lineLength = _this$props2.lineLength,
dispatchAnalyticsEvent = _this$props2.dispatchAnalyticsEvent;
var _ref4 = node.attrs,
layout = _ref4.layout,
widthType = _ref4.widthType,
mediaSingleWidthAttribute = _ref4.width;
var childNode = node.firstChild;
var attrs = (childNode === null || childNode === void 0 ? void 0 : childNode.attrs) || {};
// original width and height of child media node (scaled)
var width = attrs.width,
height = attrs.height;
if (attrs.type === 'external') {
if ((0, _mediaCommon.isMediaBlobUrlFromAttrs)(attrs)) {
var urlAttrs = (0, _mediaClient.getAttrsFromUrl)(attrs.url);
if (urlAttrs) {
var urlWidth = urlAttrs.width,
urlHeight = urlAttrs.height;
width = width || urlWidth;
height = height || urlHeight;
}
}
var _this$state = this.state,
stateWidth = _this$state.width,
stateHeight = _this$state.height;
if (width === null) {
width = stateWidth || _mediaSingle.DEFAULT_IMAGE_WIDTH;
}
if (height === null) {
height = stateHeight || _mediaSingle.DEFAULT_IMAGE_HEIGHT;
}
}
if (!width || !height) {
width = _mediaSingle.DEFAULT_IMAGE_WIDTH;
height = _mediaSingle.DEFAULT_IMAGE_HEIGHT;
}
var isSelected = selected();
var currentMaxWidth = isSelected ? pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$m = pluginInjectionApi.media.sharedState.currentState()) === null || _pluginInjectionApi$m === void 0 ? void 0 : _pluginInjectionApi$m.currentMaxWidth : undefined;
var contentWidthForLegacyExperience = (0, _mediaSingle.getMaxWidthForNestedNode)(view, getPos()) || lineLength;
var contentWidth = currentMaxWidth || lineLength;
var mediaSingleProps = {
layout: layout,
width: width,
height: height,
containerWidth: containerWidth,
lineLength: contentWidth,
fullWidthMode: fullWidthMode,
hasFallbackContainer: false,
mediaSingleWidth: (0, _mediaSingle.calcMediaSinglePixelWidth)({
width: mediaSingleWidthAttribute,
widthType: widthType,
origWidth: width,
layout: layout,
// This will only be used when calculating legacy media single width
// thus we use the legacy value (exclude table as container node)
contentWidth: contentWidthForLegacyExperience,
containerWidth: containerWidth,
gutterOffset: _mediaSingle.MEDIA_SINGLE_GUTTER_SIZE
}),
allowCaptions: mediaOptions.allowCaptions
};
var resizableMediaSingleProps = _objectSpread({
view: view,
getPos: getPos,
updateSize: this.updateSize,
gridSize: 12,
viewMediaClientConfig: this.state.viewMediaClientConfig,
allowBreakoutSnapPoints: mediaOptions && mediaOptions.allowBreakoutSnapPoints,
selected: isSelected,
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
pluginInjectionApi: pluginInjectionApi
}, mediaSingleProps);
var canResize = !!this.props.mediaOptions.allowResizing;
if (!this.props.mediaOptions.allowResizingInTables) {
// If resizing not allowed in tables, check parents for tables
var pos = getPos();
if (pos) {
var $pos = state.doc.resolve(pos);
var table = state.schema.nodes.table;
var disabledNode = !!(0, _utils2.findParentNodeOfTypeClosestToPos)($pos, [table]);
canResize = canResize && !disabledNode;
}
}
var shouldShowPlaceholder = mediaOptions.allowCaptions && node.childCount !== 2 && isSelected && state.selection instanceof _state.NodeSelection;
var MediaChildren = (0, _react2.jsx)("figure", {
ref: this.mediaSingleWrapperRef,
css: [_styles.figureWrapper],
className: _styles.MediaSingleNodeSelector,
onClick: this.onMediaSingleClicked
}, (0, _react2.jsx)("div", {
ref: this.props.forwardRef
}), shouldShowPlaceholder && (0, _react2.jsx)(_CaptionPlaceholder.default, {
ref: this.captionPlaceHolderRef,
onClick: this.clickPlaceholder
}));
return canResize ? (0, _platformFeatureFlags.getBooleanFF)('platform.editor.media.extended-resize-experience') ? (0, _react2.jsx)(_ResizableMediaSingleNext.default, (0, _extends2.default)({}, resizableMediaSingleProps, {
showLegacyNotification: widthType !== 'pixel'
}), MediaChildren) : (0, _react2.jsx)(_ResizableMediaSingle.default, (0, _extends2.default)({}, resizableMediaSingleProps, {
lineLength: contentWidthForLegacyExperience,
pctWidth: mediaSingleWidthAttribute
}), MediaChildren) : (0, _react2.jsx)(_ui.MediaSingle, (0, _extends2.default)({}, mediaSingleProps, {
pctWidth: mediaSingleWidthAttribute
}), MediaChildren);
}
}]);
return MediaSingleNode;
}(_react.Component);
(0, _defineProperty2.default)(MediaSingleNode, "defaultProps", {
mediaOptions: {}
});
(0, _defineProperty2.default)(MediaSingleNode, "displayName", 'MediaSingleNode');
var MediaSingleNodeWrapper = function MediaSingleNodeWrapper(_ref5) {
var pluginInjectionApi = _ref5.pluginInjectionApi,
mediaProvider = _ref5.mediaProvider,
contextIdentifierProvider = _ref5.contextIdentifierProvider,
node = _ref5.node,
getPos = _ref5.getPos,
mediaOptions = _ref5.mediaOptions,
view = _ref5.view,
fullWidthMode = _ref5.fullWidthMode,
selected = _ref5.selected,
eventDispatcher = _ref5.eventDispatcher,
dispatchAnalyticsEvent = _ref5.dispatchAnalyticsEvent,
forwardRef = _ref5.forwardRef;
var _useSharedPluginState = (0, _hooks.useSharedPluginState)(pluginInjectionApi, ['width', 'media']),
widthState = _useSharedPluginState.widthState,
mediaState = _useSharedPluginState.mediaState;
return (0, _react2.jsx)(MediaSingleNode, {
width: widthState.width,
lineLength: widthState.lineLength,
node: node,
getPos: getPos,
mediaProvider: mediaProvider,
contextIdentifierProvider: contextIdentifierProvider,
mediaOptions: mediaOptions,
view: view,
fullWidthMode: fullWidthMode,
selected: selected,
eventDispatcher: eventDispatcher,
mediaPluginState: mediaState !== null && mediaState !== void 0 ? mediaState : undefined,
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
forwardRef: forwardRef,
pluginInjectionApi: pluginInjectionApi
});
};
var MediaSingleNodeView = /*#__PURE__*/function (_ReactNodeView) {
(0, _inherits2.default)(MediaSingleNodeView, _ReactNodeView);
var _super2 = _createSuper(MediaSingleNodeView);
function MediaSingleNodeView() {
var _this2;
(0, _classCallCheck2.default)(this, MediaSingleNodeView);
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
_this2 = _super2.call.apply(_super2, [this].concat(args));
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this2), "lastOffsetLeft", 0);
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this2), "forceViewUpdate", false);
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this2), "selectionType", null);
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this2), "checkAndUpdateSelectionType", function () {
var getPos = _this2.getPos;
var selection = _this2.view.state.selection;
/**
* ED-19831
* There is a getPos issue coming from this code. We need to apply this workaround for now and apply a patch
* directly to confluence since this bug is now in production.
*/
var pos;
try {
pos = getPos ? getPos() : undefined;
} catch (e) {
pos = undefined;
}
var isNodeSelected = (0, _utils.isNodeSelectedOrInRange)(selection.$anchor.pos, selection.$head.pos, pos, _this2.node.nodeSize);
_this2.selectionType = isNodeSelected;
return isNodeSelected;
});
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this2), "isNodeSelected", function () {
_this2.checkAndUpdateSelectionType();
return _this2.selectionType !== null;
});
return _this2;
}
(0, _createClass2.default)(MediaSingleNodeView, [{
key: "createDomRef",
value: function createDomRef() {
var domRef = document.createElement('div');
if (this.reactComponentProps.mediaOptions && this.reactComponentProps.mediaOptions.allowMediaSingleEditable) {
// workaround Chrome bug in https://product-fabric.atlassian.net/browse/ED-5379
// see also: https://github.com/ProseMirror/prosemirror/issues/884
domRef.contentEditable = 'true';
}
if ((0, _platformFeatureFlags.getBooleanFF)('platform.editor.media.extended-resize-experience')) {
domRef.classList.add('media-extended-resize-experience');
}
return domRef;
}
}, {
key: "getContentDOM",
value: function getContentDOM() {
var dom = document.createElement('div');
dom.classList.add(_main.MEDIA_CONTENT_WRAP_CLASS_NAME);
return {
dom: dom
};
}
}, {
key: "viewShouldUpdate",
value: function viewShouldUpdate(nextNode) {
if (this.forceViewUpdate) {
this.forceViewUpdate = false;
return true;
}
if (this.node.attrs !== nextNode.attrs) {
return true;
}
if (this.selectionType !== this.checkAndUpdateSelectionType()) {
return true;
}
if (this.node.childCount !== nextNode.childCount) {
return true;
}
return (0, _get2.default)((0, _getPrototypeOf2.default)(MediaSingleNodeView.prototype), "viewShouldUpdate", this).call(this, nextNode);
}
}, {
key: "getNodeMediaId",
value: function getNodeMediaId(node) {
if (node.firstChild) {
return node.firstChild.attrs.id;
}
return undefined;
}
}, {
key: "update",
value: function update(node, decorations, _innerDecorations, isValidUpdate) {
var _this3 = this;
if (!isValidUpdate) {
isValidUpdate = function isValidUpdate(currentNode, newNode) {
return _this3.getNodeMediaId(currentNode) === _this3.getNodeMediaId(newNode);
};
}
return (0, _get2.default)((0, _getPrototypeOf2.default)(MediaSingleNodeView.prototype), "update", this).call(this, node, decorations, _innerDecorations, isValidUpdate);
}
}, {
key: "render",
value: function render(props, forwardRef) {
var _this4 = this;
var _this$reactComponentP = this.reactComponentProps,
eventDispatcher = _this$reactComponentP.eventDispatcher,
fullWidthMode = _this$reactComponentP.fullWidthMode,
providerFactory = _this$reactComponentP.providerFactory,
mediaOptions = _this$reactComponentP.mediaOptions,
dispatchAnalyticsEvent = _this$reactComponentP.dispatchAnalyticsEvent,
pluginInjectionApi = _this$reactComponentP.pluginInjectionApi;
// getPos is a boolean for marks, since this is a node we know it must be a function
var getPos = this.getPos;
return (0, _react2.jsx)(_providerFactory.WithProviders, {
providers: ['mediaProvider', 'contextIdentifierProvider'],
providerFactory: providerFactory,
renderNode: function renderNode(_ref6) {
var mediaProvider = _ref6.mediaProvider,
contextIdentifierProvider = _ref6.contextIdentifierProvider;
return (0, _react2.jsx)(MediaSingleNodeWrapper, {
pluginInjectionApi: pluginInjectionApi,
mediaProvider: mediaProvider,
contextIdentifierProvider: contextIdentifierProvider,
node: _this4.node,
getPos: getPos,
mediaOptions: mediaOptions,
view: _this4.view,
fullWidthMode: fullWidthMode,
selected: _this4.isNodeSelected,
eventDispatcher: eventDispatcher,
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
forwardRef: forwardRef
});
}
});
}
}, {
key: "ignoreMutation",
value: function ignoreMutation() {
// DOM has changed; recalculate if we need to re-render
if (this.dom) {
var offsetLeft = this.dom.offsetLeft;
if (offsetLeft !== this.lastOffsetLeft) {
this.lastOffsetLeft = offsetLeft;
this.forceViewUpdate = true;
this.update(this.node, [], undefined, function () {
return true;
});
}
}
return true;
}
}]);
return MediaSingleNodeView;
}(_reactNodeView.default);
var ReactMediaSingleNode = exports.ReactMediaSingleNode = function ReactMediaSingleNode(portalProviderAPI, eventDispatcher, providerFactory, pluginInjectionApi, dispatchAnalyticsEvent) {
var mediaOptions = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
return function (node, view, getPos) {
var hasIntlContext = true;
return new MediaSingleNodeView(node, view, getPos, portalProviderAPI, eventDispatcher, {
eventDispatcher: eventDispatcher,
fullWidthMode: mediaOptions.fullWidthEnabled,
providerFactory: providerFactory,
mediaOptions: mediaOptions,
dispatchAnalyticsEvent: dispatchAnalyticsEvent,
isCopyPasteEnabled: mediaOptions.isCopyPasteEnabled,
pluginInjectionApi: pluginInjectionApi
}, undefined, undefined, undefined, hasIntlContext).init();
};
};