@atlaskit/editor-plugin-emoji
Version:
Emoji plugin for @atlaskit/editor-core
180 lines (178 loc) • 9.3 kB
JavaScript
;
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);