UNPKG

@atlaskit/renderer

Version:
406 lines (401 loc) • 20.5 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 = void 0; 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 _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var _react = _interopRequireWildcard(require("react")); var _react2 = require("@emotion/react"); var _analyticsNext = require("@atlaskit/analytics-next"); var _analyticsNamespacedContext = require("@atlaskit/analytics-namespaced-context"); var _providerFactory = require("@atlaskit/editor-common/provider-factory"); var _ui = require("@atlaskit/editor-common/ui"); var _platformFeatureFlags = require("@atlaskit/platform-feature-flags"); var _MediaCard = require("../../../ui/MediaCard"); var _adfSchema = require("@atlaskit/adf-schema"); var _editorPalette = require("@atlaskit/editor-palette"); var _utils = require("../../../utils"); var _analytics = require("@atlaskit/editor-common/analytics"); var _events = require("../../../analytics/events"); var _annotation = _interopRequireDefault(require("../../marks/annotation")); var _mediaSingle = require("@atlaskit/editor-common/media-single"); var _useInlineCommentsFilter = require("../../../ui/annotations/hooks/use-inline-comments-filter"); var _useInlineCommentSubscriber = require("../../../ui/annotations/hooks/use-inline-comment-subscriber"); var _types = require("@atlaskit/editor-common/types"); var _AnnotationRangeContext = require("../../../ui/annotations/contexts/AnnotationRangeContext"); var _excluded = ["marks", "mediaSingleElement", "isDrafting"]; /** * @jsxRuntime classic * @jsx jsx * @jsxFrag */ /* eslint-disable @typescript-eslint/consistent-type-imports, @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766; jsx required at runtime for @jsxRuntime classic */ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } 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; })(); } var linkStyle = (0, _react2.css)({ position: 'absolute', background: 'transparent', top: 0, right: 0, bottom: 0, left: 0, cursor: 'pointer', // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles width: '100% !important', // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles height: '100% !important' }); var borderStyle = (0, _react2.css)({ position: 'absolute', // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles width: '100% !important', // eslint-disable-next-line @atlaskit/ui-styling-standard/no-important-styles height: '100% !important' }); var MediaBorder = function MediaBorder(_ref) { var _mark$attrs$color, _mark$attrs$size; var mark = _ref.mark, children = _ref.children; if (!mark) { return (0, _react2.jsx)(_react.Fragment, null, children); } var borderColor = (_mark$attrs$color = mark === null || mark === void 0 ? void 0 : mark.attrs.color) !== null && _mark$attrs$color !== void 0 ? _mark$attrs$color : ''; var borderWidth = (_mark$attrs$size = mark === null || mark === void 0 ? void 0 : mark.attrs.size) !== null && _mark$attrs$size !== void 0 ? _mark$attrs$size : 0; var paletteColorValue = (0, _editorPalette.hexToEditorBorderPaletteColor)(borderColor) || borderColor; // [FEATURE FLAG: platform_editor_media_border_radius_fix] // Fixes border radius to properly match image with 8px radius // To clean up: keep only flag-on behavior ('8px') var borderRadius = (0, _platformFeatureFlags.fg)('platform_editor_media_border_radius_fix') ? "var(--ds-radius-large, 8px)" : "".concat(borderWidth, "px"); // OLD BEHAVIOR (to be removed when flag is cleaned up) return (0, _react2.jsx)("div", { "data-mark-type": "border", "data-color": borderColor, "data-size": borderWidth, css: borderStyle, style: { // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766 borderRadius: borderRadius, boxShadow: "0 0 0 ".concat(borderWidth, "px ").concat(paletteColorValue) } }, (0, _react2.jsx)(_ui.MediaBorderGapFiller, { borderColor: borderColor }), children); }; var MediaLink = function MediaLink(_ref2) { var mark = _ref2.mark, children = _ref2.children, onClick = _ref2.onClick; if (!mark) { return (0, _react2.jsx)(_react.Fragment, null, children); } var linkHref = mark === null || mark === void 0 ? void 0 : mark.attrs.href; return ( // eslint-disable-next-line @atlaskit/design-system/no-html-anchor (0, _react2.jsx)("a", { href: linkHref, rel: "noreferrer noopener", onClick: onClick, "data-block-link": linkHref, css: linkStyle }, children) ); }; var MediaAnnotation = function MediaAnnotation(_ref3) { var mark = _ref3.mark, children = _ref3.children; if (!mark) { return (0, _react2.jsx)(_react.Fragment, null, children); } return (0, _react2.jsx)(_annotation.default, { id: mark.attrs.id, annotationType: mark.attrs.annotationType // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed) , dataAttributes: { 'data-renderer-mark': true, 'data-block-mark': true } // This should be fine being empty [] since the serializer serializeFragmentChild getMarkProps call always passes // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed) , annotationParentIds: [], allowAnnotations: true, useBlockLevel: true }, children); }; var _MediaAnnotations = function MediaAnnotations(_ref4) { var _ref4$marks = _ref4.marks, marks = _ref4$marks === void 0 ? [] : _ref4$marks, children = _ref4.children; // Early Exit if (marks.length === 0) { return (0, _react2.jsx)(_react.Fragment, null, children); } // Recursive marks var currentMark = marks[0]; var otherMarks = marks.slice(1); return (0, _react2.jsx)(_react.Fragment, null, (0, _react2.jsx)(MediaAnnotation, { key: currentMark.attrs.id, mark: currentMark }, otherMarks.length ? (0, _react2.jsx)(_MediaAnnotations, { marks: otherMarks }, children) : (0, _react2.jsx)(_react.Fragment, null, children))); }; var CommentBadgeWrapper = function CommentBadgeWrapper(_ref5) { var _marks$map; var marks = _ref5.marks, mediaSingleElement = _ref5.mediaSingleElement, _ref5$isDrafting = _ref5.isDrafting, isDrafting = _ref5$isDrafting === void 0 ? false : _ref5$isDrafting, rest = (0, _objectWithoutProperties2.default)(_ref5, _excluded); var _useState = (0, _react.useState)('default'), _useState2 = (0, _slicedToArray2.default)(_useState, 2), status = _useState2[0], setStatus = _useState2[1]; var _useState3 = (0, _react.useState)(false), _useState4 = (0, _slicedToArray2.default)(_useState3, 2), entered = _useState4[0], setEntered = _useState4[1]; var updateSubscriber = (0, _useInlineCommentSubscriber.useInlineCommentSubscriberContext)(); var activeParentIds = (0, _useInlineCommentsFilter.useInlineCommentsFilter)({ annotationIds: (_marks$map = marks === null || marks === void 0 ? void 0 : marks.map(function (mark) { return mark.attrs.id; })) !== null && _marks$map !== void 0 ? _marks$map : [''], filter: { state: _adfSchema.AnnotationMarkStates.ACTIVE } }); (0, _react.useEffect)(function () { var observer = new MutationObserver(function (mutationList) { mutationList.forEach(function (mutation) { var parentNode = mutation.target.parentNode; if (mutation.attributeName === 'data-has-focus') { var isMediaCaption = parentNode === null || parentNode === void 0 ? void 0 : parentNode.closest('[data-media-caption="true"]'); var elementHasFocus = (parentNode === null || parentNode === void 0 ? void 0 : parentNode.querySelector('[data-has-focus="true"]')) && !isMediaCaption; elementHasFocus ? setStatus('active') : setStatus('default'); } }); }); if (mediaSingleElement) { observer.observe(mediaSingleElement, { attributes: true, subtree: true, attributeFilter: ['data-has-focus'] }); } return function () { observer.disconnect(); }; }, [mediaSingleElement, setStatus]); if (!isDrafting && !activeParentIds.length) { return null; } var onClick = function onClick(e) { e.preventDefault(); if (updateSubscriber) { updateSubscriber.emit(_types.AnnotationUpdateEvent.ON_ANNOTATION_CLICK, { annotationIds: activeParentIds, // Ignored via go/ees005 // eslint-disable-next-line @atlaskit/editor/no-as-casting eventTarget: e.target, // use mediaSingle here to align with annotation viewed event dispatched in editor eventTargetType: 'mediaSingle', viewMethod: _analytics.VIEW_METHOD.BADGE }); } }; return (0, _react2.jsx)(_mediaSingle.CommentBadgeNext // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed) , (0, _extends2.default)({ onMouseEnter: function onMouseEnter() { return setEntered(true); } // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed) , onMouseLeave: function onMouseLeave() { return setEntered(false); }, status: entered ? 'entered' : status, onClick: onClick, mediaSingleElement: mediaSingleElement // Ignored via go/ees005 // eslint-disable-next-line react/jsx-props-no-spreading }, rest)); }; // Ignored via go/ees005 // eslint-disable-next-line @repo/internal/react/no-class-components var Media = /*#__PURE__*/function (_PureComponent) { function Media(props) { var _this; (0, _classCallCheck2.default)(this, Media); _this = _callSuper(this, Media, [props]); (0, _defineProperty2.default)(_this, "renderCard", function () { var providers = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var contextIdentifierProvider = providers.contextIdentifierProvider; var _this$props = _this.props, allowAltTextOnImages = _this$props.allowAltTextOnImages, alt = _this$props.alt, featureFlags = _this$props.featureFlags, allowMediaViewer = _this$props.shouldOpenMediaViewer, enableDownloadButton = _this$props.enableDownloadButton, ssr = _this$props.ssr, width = _this$props.width, height = _this$props.height, mediaSingleElement = _this$props.mediaSingleElement, _this$props$isDraftin = _this$props.isDrafting, isDrafting = _this$props$isDraftin === void 0 ? false : _this$props$isDraftin; var annotationMarks = _this.props.isAnnotationMark ? _this.props.marks.filter(_this.props.isAnnotationMark) : undefined; var borderMark = _this.props.marks.find(_this.props.isBorderMark); var linkMark = _this.props.marks.find(_this.props.isLinkMark); var linkHref = linkMark === null || linkMark === void 0 ? void 0 : linkMark.attrs.href; var eventHandlers = linkHref ? undefined : _this.props.eventHandlers; var shouldOpenMediaViewer = !linkHref && allowMediaViewer; var isInPageInclude = mediaSingleElement === null || mediaSingleElement === void 0 ? void 0 : mediaSingleElement.closest('[data-node-type="include"]'); var isIncludeExcerpt = !!(mediaSingleElement !== null && mediaSingleElement !== void 0 && mediaSingleElement.closest('.ak-excerpt-include')); var showCommentBadge = !!annotationMarks && !isInPageInclude && !isIncludeExcerpt; return (0, _react2.jsx)(MediaLink, { mark: linkMark, onClick: _this.handleMediaLinkClickFn }, (0, _react2.jsx)(_MediaAnnotations, { marks: annotationMarks }, (0, _react2.jsx)(MediaBorder, { mark: borderMark }, (0, _react2.jsx)(_analyticsNext.AnalyticsContext // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed) , { data: (0, _defineProperty2.default)({}, _analyticsNamespacedContext.MEDIA_CONTEXT, { border: !!borderMark }) }, (0, _react2.jsx)(_mediaSingle.MediaBadges, { mediaElement: mediaSingleElement, mediaWidth: width, mediaHeight: height, useMinimumZIndex: true }, function (_ref7) { var visible = _ref7.visible; return (0, _react2.jsx)(_react.default.Fragment, null, visible && (0, _react2.jsx)(_mediaSingle.ExternalImageBadge, { type: _this.props.type, url: _this.props.type === 'external' ? _this.props.url : undefined }), showCommentBadge && (0, _react2.jsx)(CommentBadgeWrapper, { marks: annotationMarks, mediaSingleElement: mediaSingleElement, isDrafting: isDrafting })); }), (0, _react2.jsx)(_MediaCard.MediaCard, (0, _extends2.default)({ contextIdentifierProvider: contextIdentifierProvider // Ignored via go/ees005 // eslint-disable-next-line react/jsx-props-no-spreading }, _this.props, { shouldOpenMediaViewer: shouldOpenMediaViewer, eventHandlers: eventHandlers, alt: allowAltTextOnImages ? alt : undefined, featureFlags: featureFlags, shouldEnableDownloadButton: enableDownloadButton, ssr: ssr })))))); }); (0, _defineProperty2.default)(_this, "handleMediaLinkClick", function (event) { var _this$props2 = _this.props, fireAnalyticsEvent = _this$props2.fireAnalyticsEvent, isLinkMark = _this$props2.isLinkMark, marks = _this$props2.marks; if (fireAnalyticsEvent) { fireAnalyticsEvent({ action: _analytics.ACTION.VISITED, actionSubject: _analytics.ACTION_SUBJECT.MEDIA, actionSubjectId: _analytics.ACTION_SUBJECT_ID.LINK, eventType: _analytics.EVENT_TYPE.TRACK, attributes: { platform: _events.PLATFORM.WEB, mode: _events.MODE.RENDERER } }); } var linkMark = _this.props.marks.find(_this.props.isLinkMark); var linkHref = linkMark === null || linkMark === void 0 ? void 0 : linkMark.attrs.href; var handler = (0, _utils.getEventHandler)(_this.props.eventHandlers, 'link'); if (handler) { var _linkMark = marks.find(isLinkMark); handler(event, _linkMark && linkHref); } }); _this.handleMediaLinkClickFn = _this.handleMediaLinkClick.bind(_this); return _this; } (0, _inherits2.default)(Media, _PureComponent); return (0, _createClass2.default)(Media, [{ key: "render", value: function render() { var providers = this.props.providers; if (!providers) { return this.renderCard(); } return (0, _react2.jsx)(_providerFactory.WithProviders // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed) , { providers: ['mediaProvider', 'contextIdentifierProvider'], providerFactory: providers, renderNode: this.renderCard }); } }]); }(_react.PureComponent); var MediaWithDraftAnnotation = function MediaWithDraftAnnotation(props) { var _useAnnotationRangeSt = (0, _AnnotationRangeContext.useAnnotationRangeState)(), draftPosition = _useAnnotationRangeSt.hoverDraftDocumentPosition; var dataAttributes = props.dataAttributes; var pos = dataAttributes && dataAttributes['data-renderer-start-pos']; var _useState5 = (0, _react.useState)(), _useState6 = (0, _slicedToArray2.default)(_useState5, 2), position = _useState6[0], setPosition = _useState6[1]; var _useState7 = (0, _react.useState)(false), _useState8 = (0, _slicedToArray2.default)(_useState7, 2), shouldApplyDraftAnnotation = _useState8[0], setShouldApplyDraftAnnotation = _useState8[1]; (0, _react.useEffect)(function () { var _draftPosition$from; if (pos === undefined) { return; } var posToCheck = ((_draftPosition$from = draftPosition === null || draftPosition === void 0 ? void 0 : draftPosition.from) !== null && _draftPosition$from !== void 0 ? _draftPosition$from : 0) + 1; if (draftPosition !== null && posToCheck === pos) { // eslint-disable-next-line @atlassian/perf-linting/no-chain-state-updates -- Ignored via go/ees017 (to be fixed) setShouldApplyDraftAnnotation(true); // eslint-disable-next-line @atlassian/perf-linting/no-chain-state-updates -- Ignored via go/ees017 (to be fixed) setPosition(posToCheck); } else if (draftPosition === null && shouldApplyDraftAnnotation) { // eslint-disable-next-line @atlassian/perf-linting/no-chain-state-updates -- Ignored via go/ees017 (to be fixed) setShouldApplyDraftAnnotation(false); // eslint-disable-next-line @atlassian/perf-linting/no-chain-state-updates -- Ignored via go/ees017 (to be fixed) setPosition(undefined); } }, [draftPosition, pos, shouldApplyDraftAnnotation]); var applyDraftAnnotation = props.allowAnnotationsDraftMode && shouldApplyDraftAnnotation && position !== undefined; var dataAttributesWithDraftAnnotation = (0, _react.useMemo)(function () { return applyDraftAnnotation ? _objectSpread(_objectSpread({}, dataAttributes), {}, { 'data-annotation-draft-mark': true, 'data-renderer-mark': true }) : dataAttributes; }, [applyDraftAnnotation, dataAttributes]); return (0, _react2.jsx)(Media // Ignored via go/ees005 // eslint-disable-next-line react/jsx-props-no-spreading , (0, _extends2.default)({}, props, { dataAttributes: dataAttributesWithDraftAnnotation, isDrafting: shouldApplyDraftAnnotation })); }; var _default = exports.default = MediaWithDraftAnnotation;