@atlaskit/renderer
Version:
Renderer component
406 lines (401 loc) • 20.5 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 = 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;