UNPKG

@atlaskit/editor-plugin-emoji

Version:

Emoji plugin for @atlaskit/editor-core

180 lines (178 loc) 9.3 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.EmojiNodeDataProvider = void 0; var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); 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 _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 _coreUtils = require("@atlaskit/editor-common/core-utils"); var _emoji = require("@atlaskit/emoji"); var _nodeDataProvider = require("@atlaskit/node-data-provider"); 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 EmojiNodeDataProvider = exports.EmojiNodeDataProvider = /*#__PURE__*/function (_NodeDataProvider) { function EmojiNodeDataProvider(resource) { var _this; (0, _classCallCheck2.default)(this, EmojiNodeDataProvider); _this = _callSuper(this, EmojiNodeDataProvider); (0, _defineProperty2.default)(_this, "name", 'emojiNodeDataProvider'); _this.emojiResource = resource; _this.emojiProvider = resource.getEmojiProvider(); return _this; } (0, _inherits2.default)(EmojiNodeDataProvider, _NodeDataProvider); return (0, _createClass2.default)(EmojiNodeDataProvider, [{ key: "isNodeSupported", value: function isNodeSupported(node) { return node.type === 'emoji'; } }, { key: "nodeDataKey", value: function nodeDataKey(node) { return node.attrs.id || node.attrs.shortName; } /** * Implementing different re-fetching strategy for emoji. * * Default strategy for NodeDataProvider is to: * 1. If entry is in cache = return from cache * 2. Re-fetch data. * 3. Update cache * 4. Re-render node with fresh data. * * This is similar, but doesn't update the node. * 1. If entry is in cache = return from cache * 2. Re-fetch data. * 3. Update cache */ }, { key: "getData", value: function getData(node, callback) { var _this2 = this; var cached = this.getNodeDataFromCache(node); if (cached !== null && cached !== void 0 && cached.data) { callback(cached); if (!(0, _coreUtils.isSSR)() && typeof requestAnimationFrame !== 'undefined') { requestAnimationFrame(function () { return void _this2.getDataAsync(node, function () {}); }); } } else { void this.getDataAsync(node, callback); } } }, { key: "fetchNodesData", value: function () { var _fetchNodesData = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(nodes) { var _this$emojiResource$e; var getOptimisticImageUrl, emojiProvider, fetches; return _regenerator.default.wrap(function _callee2$(_context2) { while (1) switch (_context2.prev = _context2.next) { case 0: // If we have an `optimisticImageApi`, use it to generate a URL immediately. // This is how emojis are server-side rendered in Confluence. // Without this, the emoji server response will hit timeout on SSR and the emoji will not be rendered. // // We are using this optimization only in SSR because on client side we need to know a valid emoji size // which is not possible to get from optimisticImageApi. // // Check platform/packages/editor/renderer/src/react/nodes/emoji.tsx // and platform/packages/elements/emoji/src/components/common/ResourcedEmojiComponent.tsx getOptimisticImageUrl = (_this$emojiResource$e = this.emojiResource.emojiProviderConfig.optimisticImageApi) === null || _this$emojiResource$e === void 0 ? void 0 : _this$emojiResource$e.getUrl; if (!((0, _coreUtils.isSSR)() && getOptimisticImageUrl)) { _context2.next = 3; break; } return _context2.abrupt("return", nodes.map(function (node) { var emojiId = { id: node.attrs.id, shortName: node.attrs.shortName, fallback: node.attrs.text }; var optimisticImageURL = getOptimisticImageUrl(emojiId); return { id: node.attrs.id, shortName: node.attrs.shortName, fallback: node.attrs.text, representation: { height: _emoji.defaultEmojiHeight, width: _emoji.defaultEmojiHeight, imagePath: optimisticImageURL }, searchable: true, // Type and category are unknown at this point. // It's not a big deal, because EmojiNodeView doesn't use them. type: '', category: '' }; })); case 3: _context2.next = 5; return this.emojiProvider; case 5: emojiProvider = _context2.sent; fetches = nodes.map( /*#__PURE__*/function () { var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(node) { var emojiId, result, optimisticImageURL; return _regenerator.default.wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: emojiId = { id: node.attrs.id, shortName: node.attrs.shortName, fallback: node.attrs.text }; // This usually fast because the emojiProvider already has all emojis fetched. _context.next = 3; return emojiProvider.fetchByEmojiId(emojiId, true); case 3: result = _context.sent; if (!(getOptimisticImageUrl && result)) { _context.next = 8; break; } optimisticImageURL = getOptimisticImageUrl(emojiId); if (!(result.representation && 'imagePath' in result.representation)) { _context.next = 8; break; } return _context.abrupt("return", _objectSpread(_objectSpread({}, result), {}, { representation: _objectSpread(_objectSpread({}, result.representation), {}, { imagePath: optimisticImageURL }) })); case 8: return _context.abrupt("return", result); case 9: case "end": return _context.stop(); } }, _callee); })); return function (_x2) { return _ref.apply(this, arguments); }; }()); return _context2.abrupt("return", Promise.all(fetches)); case 8: case "end": return _context2.stop(); } }, _callee2, this); })); function fetchNodesData(_x) { return _fetchNodesData.apply(this, arguments); } return fetchNodesData; }() }]); }(_nodeDataProvider.NodeDataProvider);