UNPKG

@atlaskit/editor-plugin-media

Version:

Media plugin for @atlaskit/editor-core

651 lines (645 loc) 33.3 kB
"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(); }; };