UNPKG

@atlaskit/editor-plugin-card

Version:

Card plugin for @atlaskit/editor-core

195 lines (190 loc) 9.78 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.Card = Card; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); 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 _react = _interopRequireWildcard(require("react")); var _adfSchema = require("@atlaskit/adf-schema"); var _analyticsNext = require("@atlaskit/analytics-next"); var _hooks = require("@atlaskit/editor-common/hooks"); var _utils = require("@atlaskit/editor-common/utils"); var _link = _interopRequireDefault(require("@atlaskit/link")); var _platformFeatureFlags = require("@atlaskit/platform-feature-flags"); var _doc = require("../pm-plugins/doc"); var _state = require("../pm-plugins/util/state"); var _utils2 = require("../pm-plugins/utils"); var _WithCardContext = require("../ui/WithCardContext"); 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 _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 fatalErrorPositionMap = new Map(); var WithClickHandler = function WithClickHandler(_ref) { var pluginInjectionApi = _ref.pluginInjectionApi, url = _ref.url, onClickCallback = _ref.onClickCallback, children = _ref.children; var _useSharedPluginState = (0, _hooks.useSharedPluginStateWithSelector)(pluginInjectionApi, ['editorViewMode'], function (states) { var _states$editorViewMod; return { mode: (_states$editorViewMod = states.editorViewModeState) === null || _states$editorViewMod === void 0 ? void 0 : _states$editorViewMod.mode }; }), mode = _useSharedPluginState.mode; var onClick = (0, _react.useCallback)(function (event) { if (typeof onClickCallback === 'function') { try { onClickCallback({ event: event, url: url }); } catch (_unused) {} } }, [url, onClickCallback]); // Setting `onClick` to `undefined` ensures clicks on smartcards navigate to the URL. // If in view mode and not overriding with onClickCallback option, then allow smartlinks to navigate on click. var allowNavigation = mode === 'view' && !onClickCallback; return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, children({ onClick: allowNavigation ? undefined : onClick })); }; /** * * @param SmartCardComponent * @param UnsupportedComponent * @example */ function Card(SmartCardComponent, UnsupportedComponent) { return /*#__PURE__*/function (_React$Component) { function _class() { var _this; (0, _classCallCheck2.default)(this, _class); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _callSuper(this, _class, [].concat(args)); (0, _defineProperty2.default)(_this, "state", { isError: false }); return _this; } (0, _inherits2.default)(_class, _React$Component); return (0, _createClass2.default)(_class, [{ key: "render", value: function render() { var _getPluginState, _this2 = this; var _this$props = this.props, pluginInjectionApi = _this$props.pluginInjectionApi, onClickCallback = _this$props.onClickCallback; var _titleUrlPairFromNode = (0, _utils2.titleUrlPairFromNode)(this.props.node), url = _titleUrlPairFromNode.url; if (url && !(0, _adfSchema.isSafeUrl)(url)) { return /*#__PURE__*/_react.default.createElement(UnsupportedComponent, null); } if (this.state.isError) { if (url) { return (0, _platformFeatureFlags.fg)('dst-a11y__replace-anchor-with-link__linking-platfo') ? /*#__PURE__*/_react.default.createElement(_link.default, { href: url // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed) , onClick: function onClick(e) { e.preventDefault(); } }, url) : /*#__PURE__*/ // eslint-disable-next-line @atlaskit/design-system/no-html-anchor _react.default.createElement("a", { href: url, onClick: function onClick(e) { e.preventDefault(); } }, url); } else { return /*#__PURE__*/_react.default.createElement(UnsupportedComponent, null); } } var editorAppearance = (_getPluginState = (0, _state.getPluginState)(this.props.view.state)) === null || _getPluginState === void 0 ? void 0 : _getPluginState.editorAppearance; var analyticsEditorAppearance = (0, _utils.getAnalyticsEditorAppearance)(editorAppearance); return /*#__PURE__*/_react.default.createElement(_analyticsNext.AnalyticsContext // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed) , { data: { attributes: { location: analyticsEditorAppearance }, // Below is added for the future implementation of Linking Platform namespaced analytics context location: analyticsEditorAppearance } }, /*#__PURE__*/_react.default.createElement(WithClickHandler, { pluginInjectionApi: pluginInjectionApi, onClickCallback: onClickCallback, url: url }, function (_ref2) { var onClick = _ref2.onClick; return /*#__PURE__*/_react.default.createElement(_WithCardContext.WithCardContext, null, function (cardContext) { return /*#__PURE__*/_react.default.createElement(SmartCardComponent, (0, _extends2.default)({ key: url, cardContext: cardContext // Ignored via go/ees005 // eslint-disable-next-line react/jsx-props-no-spreading }, _this2.props, { onClick: onClick })); }); })); } }, { key: "componentDidCatch", value: function componentDidCatch(error) { var maybeAPIError = error; // NB: errors received in this component are propagated by the `@atlaskit/smart-card` component. // Depending on the kind of error, the expectation for this component is to either: // (1) Render a blue link whilst retaining `inlineCard` in the ADF (non-fatal errs); // (2) Render a blue link whilst downgrading to `link` in the ADF (fatal errs). if (maybeAPIError.kind && maybeAPIError.kind === 'fatal') { var _pluginInjectionApi$a; this.setState({ isError: true }); var _this$props2 = this.props, view = _this$props2.view, node = _this$props2.node, getPos = _this$props2.getPos, pluginInjectionApi = _this$props2.pluginInjectionApi; var _titleUrlPairFromNode2 = (0, _utils2.titleUrlPairFromNode)(node), url = _titleUrlPairFromNode2.url; if (!getPos || typeof getPos === 'boolean') { return; } var pos = getPos(); /** * We cache fatal errors by position to avoid retrying the same errors * on the same links at the same position. */ if (url && pos && fatalErrorPositionMap.get(url) === pos) { return null; } (0, _doc.changeSelectedCardToLinkFallback)(undefined, url, true, node, getPos(), pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a === void 0 ? void 0 : _pluginInjectionApi$a.actions)(view.state, view.dispatch); if (url && pos) { fatalErrorPositionMap.set(url, pos); } return null; } else { // Otherwise, render a blue link as fallback (above in render()). this.setState({ isError: true }); } } }]); }(_react.default.Component); }