@atlaskit/editor-plugin-emoji
Version:
Emoji plugin for @atlaskit/editor-core
173 lines (172 loc) • 8.65 kB
JavaScript
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
import _inherits from "@babel/runtime/helpers/inherits";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _regeneratorRuntime from "@babel/runtime/regenerator";
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) { _defineProperty(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 = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(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; })(); }
import { isSSR } from '@atlaskit/editor-common/core-utils';
import { defaultEmojiHeight } from '@atlaskit/emoji';
import { NodeDataProvider } from '@atlaskit/node-data-provider';
export var EmojiNodeDataProvider = /*#__PURE__*/function (_NodeDataProvider) {
function EmojiNodeDataProvider(resource) {
var _this;
_classCallCheck(this, EmojiNodeDataProvider);
_this = _callSuper(this, EmojiNodeDataProvider);
_defineProperty(_this, "name", 'emojiNodeDataProvider');
_this.emojiResource = resource;
_this.emojiProvider = resource.getEmojiProvider();
return _this;
}
_inherits(EmojiNodeDataProvider, _NodeDataProvider);
return _createClass(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 (!isSSR() && typeof requestAnimationFrame !== 'undefined') {
requestAnimationFrame(function () {
return void _this2.getDataAsync(node, function () {});
});
}
} else {
void this.getDataAsync(node, callback);
}
}
}, {
key: "fetchNodesData",
value: function () {
var _fetchNodesData = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(nodes) {
var _this$emojiResource$e;
var getOptimisticImageUrl, emojiProvider, fetches;
return _regeneratorRuntime.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 (!(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: defaultEmojiHeight,
width: 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 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(node) {
var emojiId, result, optimisticImageURL;
return _regeneratorRuntime.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);