@atlaskit/editor-plugin-emoji 3.4.0 → 3.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # @atlaskit/editor-plugin-emoji
2
2
 
3
+ ## 3.5.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#136443](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/136443)
8
+ [`884806f5c2215`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/884806f5c2215) -
9
+ [https://product-fabric.atlassian.net/browse/ED-27433](ED-27433) - fix vanilla JS emoji
10
+ implementation loading state issue
11
+ - Updated dependencies
12
+
13
+ ## 3.5.0
14
+
15
+ ### Minor Changes
16
+
17
+ - [#135687](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/135687)
18
+ [`e24c34980067a`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/e24c34980067a) -
19
+ [https://product-fabric.atlassian.net/browse/ED-27390](ED-27390) - add error handling for Editor
20
+ emoji vanilla JS implementation
21
+
22
+ ### Patch Changes
23
+
24
+ - Updated dependencies
25
+
3
26
  ## 3.4.0
4
27
 
5
28
  ### Minor Changes
@@ -11,6 +11,7 @@ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/cl
11
11
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
12
12
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
13
13
  var _emoji = require("@atlaskit/editor-common/emoji");
14
+ var _monitoring = require("@atlaskit/editor-common/monitoring");
14
15
  var _model = require("@atlaskit/editor-prosemirror/model");
15
16
  var _emojiNodeSpec = require("./emojiNodeSpec");
16
17
  var EmojiNodeView = exports.EmojiNodeView = /*#__PURE__*/function () {
@@ -60,8 +61,7 @@ var EmojiNodeView = exports.EmojiNodeView = /*#__PURE__*/function () {
60
61
  unsubscribe();
61
62
  };
62
63
  } catch (error) {
63
- // TODO: ED-27390 - send analytics event with error
64
-
64
+ EmojiNodeView.logError(error instanceof Error ? error : new Error('Unknown error on EmojiNodeView constructor'));
65
65
  this.renderFallback();
66
66
  }
67
67
  }
@@ -73,46 +73,46 @@ var EmojiNodeView = exports.EmojiNodeView = /*#__PURE__*/function () {
73
73
  return _regenerator.default.wrap(function _callee$(_context) {
74
74
  while (1) switch (_context.prev = _context.next) {
75
75
  case 0:
76
- // Clean up the DOM before rendering the new emoji
77
- this.dom.innerHTML = '';
78
- this.dom.style.cssText = '';
79
- this.dom.classList.remove(_emoji.EmojiSharedCssClassName.EMOJI_PLACEHOLDER);
80
- this.dom.removeAttribute('aria-label'); // The label is set in the renderEmoji method
81
- this.dom.removeAttribute('aria-busy');
82
-
83
- // Each vanilla JS node implementation should have this data attribute
84
- this.dom.setAttribute('data-prosemirror-node-view-type', 'vanilla');
85
- _context.prev = 6;
76
+ _context.prev = 0;
86
77
  _this$node$attrs = this.node.attrs, shortName = _this$node$attrs.shortName, id = _this$node$attrs.id, fallback = _this$node$attrs.text;
87
- _context.next = 10;
78
+ _context.next = 4;
88
79
  return emojiProvider === null || emojiProvider === void 0 ? void 0 : emojiProvider.fetchByEmojiId({
89
80
  id: id,
90
81
  shortName: shortName,
91
82
  fallback: fallback
92
83
  }, true);
93
- case 10:
84
+ case 4:
94
85
  emojiDescription = _context.sent;
86
+ if (emojiDescription) {
87
+ _context.next = 9;
88
+ break;
89
+ }
90
+ EmojiNodeView.logError(new Error('Emoji description is not loaded'));
91
+ this.renderFallback();
92
+ return _context.abrupt("return");
93
+ case 9:
95
94
  emojiRepresentation = emojiDescription === null || emojiDescription === void 0 ? void 0 : emojiDescription.representation;
96
- if (emojiDescription && this.isEmojiRepresentationSupported(emojiRepresentation)) {
97
- this.renderEmoji(emojiDescription, emojiRepresentation);
98
- } else {
99
- // TODO: ED-27390 - send analytics event with info that emoji description is not supported
100
-
101
- this.renderFallback();
95
+ if (EmojiNodeView.isEmojiRepresentationSupported(emojiRepresentation)) {
96
+ _context.next = 14;
97
+ break;
102
98
  }
103
- _context.next = 18;
99
+ EmojiNodeView.logError(new Error('Emoji representation is not supported'));
100
+ this.renderFallback();
101
+ return _context.abrupt("return");
102
+ case 14:
103
+ this.renderEmoji(emojiDescription, emojiRepresentation);
104
+ _context.next = 21;
104
105
  break;
105
- case 15:
106
- _context.prev = 15;
107
- _context.t0 = _context["catch"](6);
108
- // TODO: ED-27390 - send analytics event with error
109
-
106
+ case 17:
107
+ _context.prev = 17;
108
+ _context.t0 = _context["catch"](0);
109
+ EmojiNodeView.logError(_context.t0 instanceof Error ? _context.t0 : new Error('Unknown error on EmojiNodeView updateDom'));
110
110
  this.renderFallback();
111
- case 18:
111
+ case 21:
112
112
  case "end":
113
113
  return _context.stop();
114
114
  }
115
- }, _callee, this, [[6, 15]]);
115
+ }, _callee, this, [[0, 17]]);
116
116
  }));
117
117
  function updateDom(_x) {
118
118
  return _updateDom.apply(this, arguments);
@@ -120,26 +120,35 @@ var EmojiNodeView = exports.EmojiNodeView = /*#__PURE__*/function () {
120
120
  return updateDom;
121
121
  }()
122
122
  }, {
123
- key: "isEmojiRepresentationSupported",
124
- value: function isEmojiRepresentationSupported(representation) {
125
- return !!representation && ('sprite' in representation || 'imagePath' in representation || 'mediaPath' in representation);
123
+ key: "cleanUpAndRenderCommonAttributes",
124
+ value:
125
+ // Pay attention, this method should be called only when the emoji provider returns
126
+ // emoji data to prevent rendering empty emoji during loading.
127
+ function cleanUpAndRenderCommonAttributes() {
128
+ // Clean up the DOM before rendering the new emoji
129
+ this.dom.innerHTML = '';
130
+ this.dom.style.cssText = '';
131
+ this.dom.classList.remove(_emoji.EmojiSharedCssClassName.EMOJI_PLACEHOLDER);
132
+ this.dom.removeAttribute('aria-label'); // The label is set in the renderEmoji method
133
+ this.dom.removeAttribute('aria-busy');
134
+
135
+ // Each vanilla JS node implementation should have this data attribute
136
+ this.dom.setAttribute('data-prosemirror-node-view-type', 'vanilla');
126
137
  }
127
138
  }, {
128
139
  key: "renderFallback",
129
140
  value: function renderFallback() {
130
- // TODO: ED-27390 - send analytics event with info that fallback was used
131
-
141
+ this.cleanUpAndRenderCommonAttributes();
132
142
  var fallbackElement = document.createElement('span');
133
143
  fallbackElement.innerText = this.node.attrs.text || this.node.attrs.shortName;
134
- fallbackElement.setAttribute('data-testid', "sprite-emoji-".concat(this.node.attrs.shortName));
135
- fallbackElement.setAttribute('data-emoji-type', 'sprite');
144
+ fallbackElement.setAttribute('data-testid', "fallback-emoji-".concat(this.node.attrs.shortName));
145
+ fallbackElement.setAttribute('data-emoji-type', 'fallback');
136
146
  this.dom.appendChild(fallbackElement);
137
147
  }
138
148
  }, {
139
149
  key: "renderEmoji",
140
150
  value: function renderEmoji(description, representation) {
141
- // TODO: ED-27390 - Add necessary analytics UFO events
142
-
151
+ this.cleanUpAndRenderCommonAttributes();
143
152
  var emojiType = 'sprite' in representation ? 'sprite' : 'image';
144
153
 
145
154
  // Add wrapper for the emoji
@@ -185,5 +194,17 @@ var EmojiNodeView = exports.EmojiNodeView = /*#__PURE__*/function () {
185
194
  }
186
195
  return imageElement;
187
196
  }
197
+ }], [{
198
+ key: "logError",
199
+ value: function logError(error) {
200
+ void (0, _monitoring.logException)(error, {
201
+ location: 'editor-plugin-emoji/EmojiNodeView'
202
+ });
203
+ }
204
+ }, {
205
+ key: "isEmojiRepresentationSupported",
206
+ value: function isEmojiRepresentationSupported(representation) {
207
+ return !!representation && ('sprite' in representation || 'imagePath' in representation || 'mediaPath' in representation);
208
+ }
188
209
  }]);
189
210
  }();
@@ -1,8 +1,14 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import { messages, EmojiSharedCssClassName, defaultEmojiHeight } from '@atlaskit/editor-common/emoji';
3
+ import { logException } from '@atlaskit/editor-common/monitoring';
3
4
  import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
4
5
  import { emojiToDom } from './emojiNodeSpec';
5
6
  export class EmojiNodeView {
7
+ static logError(error) {
8
+ void logException(error, {
9
+ location: 'editor-plugin-emoji/EmojiNodeView'
10
+ });
11
+ }
6
12
  constructor(node, {
7
13
  intl,
8
14
  api
@@ -50,21 +56,11 @@ export class EmojiNodeView {
50
56
  unsubscribe();
51
57
  };
52
58
  } catch (error) {
53
- // TODO: ED-27390 - send analytics event with error
54
-
59
+ EmojiNodeView.logError(error instanceof Error ? error : new Error('Unknown error on EmojiNodeView constructor'));
55
60
  this.renderFallback();
56
61
  }
57
62
  }
58
63
  async updateDom(emojiProvider) {
59
- // Clean up the DOM before rendering the new emoji
60
- this.dom.innerHTML = '';
61
- this.dom.style.cssText = '';
62
- this.dom.classList.remove(EmojiSharedCssClassName.EMOJI_PLACEHOLDER);
63
- this.dom.removeAttribute('aria-label'); // The label is set in the renderEmoji method
64
- this.dom.removeAttribute('aria-busy');
65
-
66
- // Each vanilla JS node implementation should have this data attribute
67
- this.dom.setAttribute('data-prosemirror-node-view-type', 'vanilla');
68
64
  try {
69
65
  const {
70
66
  shortName,
@@ -76,35 +72,50 @@ export class EmojiNodeView {
76
72
  shortName,
77
73
  fallback
78
74
  }, true));
75
+ if (!emojiDescription) {
76
+ EmojiNodeView.logError(new Error('Emoji description is not loaded'));
77
+ this.renderFallback();
78
+ return;
79
+ }
79
80
  const emojiRepresentation = emojiDescription === null || emojiDescription === void 0 ? void 0 : emojiDescription.representation;
80
- if (emojiDescription && this.isEmojiRepresentationSupported(emojiRepresentation)) {
81
- this.renderEmoji(emojiDescription, emojiRepresentation);
82
- } else {
83
- // TODO: ED-27390 - send analytics event with info that emoji description is not supported
84
-
81
+ if (!EmojiNodeView.isEmojiRepresentationSupported(emojiRepresentation)) {
82
+ EmojiNodeView.logError(new Error('Emoji representation is not supported'));
85
83
  this.renderFallback();
84
+ return;
86
85
  }
86
+ this.renderEmoji(emojiDescription, emojiRepresentation);
87
87
  } catch (error) {
88
- // TODO: ED-27390 - send analytics event with error
89
-
88
+ EmojiNodeView.logError(error instanceof Error ? error : new Error('Unknown error on EmojiNodeView updateDom'));
90
89
  this.renderFallback();
91
90
  }
92
91
  }
93
- isEmojiRepresentationSupported(representation) {
92
+ static isEmojiRepresentationSupported(representation) {
94
93
  return !!representation && ('sprite' in representation || 'imagePath' in representation || 'mediaPath' in representation);
95
94
  }
96
- renderFallback() {
97
- // TODO: ED-27390 - send analytics event with info that fallback was used
98
95
 
96
+ // Pay attention, this method should be called only when the emoji provider returns
97
+ // emoji data to prevent rendering empty emoji during loading.
98
+ cleanUpAndRenderCommonAttributes() {
99
+ // Clean up the DOM before rendering the new emoji
100
+ this.dom.innerHTML = '';
101
+ this.dom.style.cssText = '';
102
+ this.dom.classList.remove(EmojiSharedCssClassName.EMOJI_PLACEHOLDER);
103
+ this.dom.removeAttribute('aria-label'); // The label is set in the renderEmoji method
104
+ this.dom.removeAttribute('aria-busy');
105
+
106
+ // Each vanilla JS node implementation should have this data attribute
107
+ this.dom.setAttribute('data-prosemirror-node-view-type', 'vanilla');
108
+ }
109
+ renderFallback() {
110
+ this.cleanUpAndRenderCommonAttributes();
99
111
  const fallbackElement = document.createElement('span');
100
112
  fallbackElement.innerText = this.node.attrs.text || this.node.attrs.shortName;
101
- fallbackElement.setAttribute('data-testid', `sprite-emoji-${this.node.attrs.shortName}`);
102
- fallbackElement.setAttribute('data-emoji-type', 'sprite');
113
+ fallbackElement.setAttribute('data-testid', `fallback-emoji-${this.node.attrs.shortName}`);
114
+ fallbackElement.setAttribute('data-emoji-type', 'fallback');
103
115
  this.dom.appendChild(fallbackElement);
104
116
  }
105
117
  renderEmoji(description, representation) {
106
- // TODO: ED-27390 - Add necessary analytics UFO events
107
-
118
+ this.cleanUpAndRenderCommonAttributes();
108
119
  const emojiType = 'sprite' in representation ? 'sprite' : 'image';
109
120
 
110
121
  // Add wrapper for the emoji
@@ -4,6 +4,7 @@ import _createClass from "@babel/runtime/helpers/createClass";
4
4
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
5
5
  import _regeneratorRuntime from "@babel/runtime/regenerator";
6
6
  import { messages, EmojiSharedCssClassName, defaultEmojiHeight } from '@atlaskit/editor-common/emoji';
7
+ import { logException } from '@atlaskit/editor-common/monitoring';
7
8
  import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
8
9
  import { emojiToDom } from './emojiNodeSpec';
9
10
  export var EmojiNodeView = /*#__PURE__*/function () {
@@ -53,8 +54,7 @@ export var EmojiNodeView = /*#__PURE__*/function () {
53
54
  unsubscribe();
54
55
  };
55
56
  } catch (error) {
56
- // TODO: ED-27390 - send analytics event with error
57
-
57
+ EmojiNodeView.logError(error instanceof Error ? error : new Error('Unknown error on EmojiNodeView constructor'));
58
58
  this.renderFallback();
59
59
  }
60
60
  }
@@ -66,46 +66,46 @@ export var EmojiNodeView = /*#__PURE__*/function () {
66
66
  return _regeneratorRuntime.wrap(function _callee$(_context) {
67
67
  while (1) switch (_context.prev = _context.next) {
68
68
  case 0:
69
- // Clean up the DOM before rendering the new emoji
70
- this.dom.innerHTML = '';
71
- this.dom.style.cssText = '';
72
- this.dom.classList.remove(EmojiSharedCssClassName.EMOJI_PLACEHOLDER);
73
- this.dom.removeAttribute('aria-label'); // The label is set in the renderEmoji method
74
- this.dom.removeAttribute('aria-busy');
75
-
76
- // Each vanilla JS node implementation should have this data attribute
77
- this.dom.setAttribute('data-prosemirror-node-view-type', 'vanilla');
78
- _context.prev = 6;
69
+ _context.prev = 0;
79
70
  _this$node$attrs = this.node.attrs, shortName = _this$node$attrs.shortName, id = _this$node$attrs.id, fallback = _this$node$attrs.text;
80
- _context.next = 10;
71
+ _context.next = 4;
81
72
  return emojiProvider === null || emojiProvider === void 0 ? void 0 : emojiProvider.fetchByEmojiId({
82
73
  id: id,
83
74
  shortName: shortName,
84
75
  fallback: fallback
85
76
  }, true);
86
- case 10:
77
+ case 4:
87
78
  emojiDescription = _context.sent;
79
+ if (emojiDescription) {
80
+ _context.next = 9;
81
+ break;
82
+ }
83
+ EmojiNodeView.logError(new Error('Emoji description is not loaded'));
84
+ this.renderFallback();
85
+ return _context.abrupt("return");
86
+ case 9:
88
87
  emojiRepresentation = emojiDescription === null || emojiDescription === void 0 ? void 0 : emojiDescription.representation;
89
- if (emojiDescription && this.isEmojiRepresentationSupported(emojiRepresentation)) {
90
- this.renderEmoji(emojiDescription, emojiRepresentation);
91
- } else {
92
- // TODO: ED-27390 - send analytics event with info that emoji description is not supported
93
-
94
- this.renderFallback();
88
+ if (EmojiNodeView.isEmojiRepresentationSupported(emojiRepresentation)) {
89
+ _context.next = 14;
90
+ break;
95
91
  }
96
- _context.next = 18;
92
+ EmojiNodeView.logError(new Error('Emoji representation is not supported'));
93
+ this.renderFallback();
94
+ return _context.abrupt("return");
95
+ case 14:
96
+ this.renderEmoji(emojiDescription, emojiRepresentation);
97
+ _context.next = 21;
97
98
  break;
98
- case 15:
99
- _context.prev = 15;
100
- _context.t0 = _context["catch"](6);
101
- // TODO: ED-27390 - send analytics event with error
102
-
99
+ case 17:
100
+ _context.prev = 17;
101
+ _context.t0 = _context["catch"](0);
102
+ EmojiNodeView.logError(_context.t0 instanceof Error ? _context.t0 : new Error('Unknown error on EmojiNodeView updateDom'));
103
103
  this.renderFallback();
104
- case 18:
104
+ case 21:
105
105
  case "end":
106
106
  return _context.stop();
107
107
  }
108
- }, _callee, this, [[6, 15]]);
108
+ }, _callee, this, [[0, 17]]);
109
109
  }));
110
110
  function updateDom(_x) {
111
111
  return _updateDom.apply(this, arguments);
@@ -113,26 +113,35 @@ export var EmojiNodeView = /*#__PURE__*/function () {
113
113
  return updateDom;
114
114
  }()
115
115
  }, {
116
- key: "isEmojiRepresentationSupported",
117
- value: function isEmojiRepresentationSupported(representation) {
118
- return !!representation && ('sprite' in representation || 'imagePath' in representation || 'mediaPath' in representation);
116
+ key: "cleanUpAndRenderCommonAttributes",
117
+ value:
118
+ // Pay attention, this method should be called only when the emoji provider returns
119
+ // emoji data to prevent rendering empty emoji during loading.
120
+ function cleanUpAndRenderCommonAttributes() {
121
+ // Clean up the DOM before rendering the new emoji
122
+ this.dom.innerHTML = '';
123
+ this.dom.style.cssText = '';
124
+ this.dom.classList.remove(EmojiSharedCssClassName.EMOJI_PLACEHOLDER);
125
+ this.dom.removeAttribute('aria-label'); // The label is set in the renderEmoji method
126
+ this.dom.removeAttribute('aria-busy');
127
+
128
+ // Each vanilla JS node implementation should have this data attribute
129
+ this.dom.setAttribute('data-prosemirror-node-view-type', 'vanilla');
119
130
  }
120
131
  }, {
121
132
  key: "renderFallback",
122
133
  value: function renderFallback() {
123
- // TODO: ED-27390 - send analytics event with info that fallback was used
124
-
134
+ this.cleanUpAndRenderCommonAttributes();
125
135
  var fallbackElement = document.createElement('span');
126
136
  fallbackElement.innerText = this.node.attrs.text || this.node.attrs.shortName;
127
- fallbackElement.setAttribute('data-testid', "sprite-emoji-".concat(this.node.attrs.shortName));
128
- fallbackElement.setAttribute('data-emoji-type', 'sprite');
137
+ fallbackElement.setAttribute('data-testid', "fallback-emoji-".concat(this.node.attrs.shortName));
138
+ fallbackElement.setAttribute('data-emoji-type', 'fallback');
129
139
  this.dom.appendChild(fallbackElement);
130
140
  }
131
141
  }, {
132
142
  key: "renderEmoji",
133
143
  value: function renderEmoji(description, representation) {
134
- // TODO: ED-27390 - Add necessary analytics UFO events
135
-
144
+ this.cleanUpAndRenderCommonAttributes();
136
145
  var emojiType = 'sprite' in representation ? 'sprite' : 'image';
137
146
 
138
147
  // Add wrapper for the emoji
@@ -178,5 +187,17 @@ export var EmojiNodeView = /*#__PURE__*/function () {
178
187
  }
179
188
  return imageElement;
180
189
  }
190
+ }], [{
191
+ key: "logError",
192
+ value: function logError(error) {
193
+ void logException(error, {
194
+ location: 'editor-plugin-emoji/EmojiNodeView'
195
+ });
196
+ }
197
+ }, {
198
+ key: "isEmojiRepresentationSupported",
199
+ value: function isEmojiRepresentationSupported(representation) {
200
+ return !!representation && ('sprite' in representation || 'imagePath' in representation || 'mediaPath' in representation);
201
+ }
181
202
  }]);
182
203
  }();
@@ -12,9 +12,11 @@ export declare class EmojiNodeView implements NodeView {
12
12
  private readonly intl;
13
13
  readonly destroy: () => void;
14
14
  readonly dom: HTMLElement;
15
+ private static logError;
15
16
  constructor(node: PMNode, { intl, api }: Params);
16
17
  private updateDom;
17
- private isEmojiRepresentationSupported;
18
+ private static isEmojiRepresentationSupported;
19
+ private cleanUpAndRenderCommonAttributes;
18
20
  private renderFallback;
19
21
  private renderEmoji;
20
22
  private createSpriteEmojiElement;
@@ -12,9 +12,11 @@ export declare class EmojiNodeView implements NodeView {
12
12
  private readonly intl;
13
13
  readonly destroy: () => void;
14
14
  readonly dom: HTMLElement;
15
+ private static logError;
15
16
  constructor(node: PMNode, { intl, api }: Params);
16
17
  private updateDom;
17
- private isEmojiRepresentationSupported;
18
+ private static isEmojiRepresentationSupported;
19
+ private cleanUpAndRenderCommonAttributes;
18
20
  private renderFallback;
19
21
  private renderEmoji;
20
22
  private createSpriteEmojiElement;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-emoji",
3
- "version": "3.4.0",
3
+ "version": "3.5.1",
4
4
  "description": "Emoji plugin for @atlaskit/editor-core",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"