@atlaskit/editor-plugin-media 1.13.5 → 1.14.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.
Files changed (30) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/nodeviews/mediaNodeView/media.js +59 -1
  3. package/dist/cjs/nodeviews/mediaSingle.js +13 -0
  4. package/dist/cjs/pm-plugins/keymap.js +13 -1
  5. package/dist/cjs/pm-plugins/main.js +50 -1
  6. package/dist/cjs/toolbar/assets/commentWithDotIcon.js +43 -0
  7. package/dist/cjs/toolbar/comments.js +16 -7
  8. package/dist/es2019/nodeviews/mediaNodeView/media.js +56 -1
  9. package/dist/es2019/nodeviews/mediaSingle.js +11 -0
  10. package/dist/es2019/pm-plugins/keymap.js +14 -2
  11. package/dist/es2019/pm-plugins/main.js +54 -1
  12. package/dist/es2019/toolbar/assets/commentWithDotIcon.js +36 -0
  13. package/dist/es2019/toolbar/comments.js +14 -7
  14. package/dist/esm/nodeviews/mediaNodeView/media.js +59 -1
  15. package/dist/esm/nodeviews/mediaSingle.js +13 -0
  16. package/dist/esm/pm-plugins/keymap.js +14 -2
  17. package/dist/esm/pm-plugins/main.js +50 -1
  18. package/dist/esm/toolbar/assets/commentWithDotIcon.js +36 -0
  19. package/dist/esm/toolbar/comments.js +16 -7
  20. package/dist/types/nodeviews/mediaNodeView/media.d.ts +4 -0
  21. package/dist/types/nodeviews/mediaSingle.d.ts +1 -0
  22. package/dist/types/pm-plugins/types.d.ts +2 -1
  23. package/dist/types/toolbar/assets/commentWithDotIcon.d.ts +3 -0
  24. package/dist/types/toolbar/comments.d.ts +1 -1
  25. package/dist/types-ts4.5/nodeviews/mediaNodeView/media.d.ts +4 -0
  26. package/dist/types-ts4.5/nodeviews/mediaSingle.d.ts +1 -0
  27. package/dist/types-ts4.5/pm-plugins/types.d.ts +2 -1
  28. package/dist/types-ts4.5/toolbar/assets/commentWithDotIcon.d.ts +3 -0
  29. package/dist/types-ts4.5/toolbar/comments.d.ts +1 -1
  30. package/package.json +7 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @atlaskit/editor-plugin-media
2
2
 
3
+ ## 1.14.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#88137](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/88137) [`0a744349d5e6`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/0a744349d5e6) - [ux] [ED-22833] Change icon used for comment button in media floating toolbar when there are active comments associated with the media. The icon will now be comment icon with a dot at top right corner.
8
+
9
+ ## 1.14.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [#73901](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/73901) [`2aefab5730ab`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/2aefab5730ab) - ECA11Y-207 Added Tab navigation for video panel controls and handling key press on them
14
+
15
+ ### Patch Changes
16
+
17
+ - Updated dependencies
18
+
3
19
  ## 1.13.5
4
20
 
5
21
  ### Patch Changes
@@ -16,11 +16,13 @@ var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime
16
16
  var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
17
17
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
18
18
  var _react = _interopRequireWildcard(require("react"));
19
+ var _bindEventListener = require("bind-event-listener");
19
20
  var _analyticsNamespacedContext = require("@atlaskit/analytics-namespaced-context");
20
21
  var _analyticsNext = require("@atlaskit/analytics-next");
21
22
  var _utils = require("@atlaskit/editor-common/utils");
22
23
  var _cellSelection = require("@atlaskit/editor-tables/cell-selection");
23
24
  var _mediaCard = require("@atlaskit/media-card");
25
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
24
26
  var _pluginKey = require("../../pm-plugins/plugin-key");
25
27
  var _styles = require("../styles");
26
28
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
@@ -39,6 +41,8 @@ var MediaNode = exports.MediaNode = /*#__PURE__*/function (_Component) {
39
41
  (0, _classCallCheck2.default)(this, MediaNode);
40
42
  _this = _super.call(this, _props);
41
43
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "state", {});
44
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "videoControlsWrapperRef", /*#__PURE__*/_react.default.createRef());
45
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "unbindKeyDown", null);
42
46
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "setViewMediaClientConfig", /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
43
47
  var mediaProvider, viewMediaClientConfig;
44
48
  return _regenerator.default.wrap(function _callee$(_context) {
@@ -150,6 +154,9 @@ var MediaNode = exports.MediaNode = /*#__PURE__*/function (_Component) {
150
154
  var _this$mediaPluginStat3;
151
155
  var node = this.props.node;
152
156
  (_this$mediaPluginStat3 = this.mediaPluginState) === null || _this$mediaPluginStat3 === void 0 || _this$mediaPluginStat3.handleMediaNodeUnmount(node);
157
+ if ((0, _platformFeatureFlags.getBooleanFF)('platform.editor.a11y_video_controls_keyboard_support_yhcxh') && this.unbindKeyDown && typeof this.unbindKeyDown === 'function') {
158
+ this.unbindKeyDown();
159
+ }
153
160
  }
154
161
  }, {
155
162
  key: "componentDidUpdate",
@@ -162,6 +169,56 @@ var MediaNode = exports.MediaNode = /*#__PURE__*/function (_Component) {
162
169
  }
163
170
  (_this$mediaPluginStat5 = this.mediaPluginState) === null || _this$mediaPluginStat5 === void 0 || _this$mediaPluginStat5.updateElement();
164
171
  this.setViewMediaClientConfig();
172
+ // this.videoControlsWrapperRef is null on componentDidMount. We need to wait until it has value
173
+ if ((0, _platformFeatureFlags.getBooleanFF)('platform.editor.a11y_video_controls_keyboard_support_yhcxh') && this.videoControlsWrapperRef && this.videoControlsWrapperRef.current) {
174
+ var _this$mediaPluginStat6;
175
+ if (!((_this$mediaPluginStat6 = this.mediaPluginState) !== null && _this$mediaPluginStat6 !== void 0 && _this$mediaPluginStat6.videoControlsWrapperRef)) {
176
+ var _this$mediaPluginStat7;
177
+ this.bindKeydown();
178
+ (_this$mediaPluginStat7 = this.mediaPluginState) === null || _this$mediaPluginStat7 === void 0 || _this$mediaPluginStat7.updateAndDispatch({
179
+ videoControlsWrapperRef: this.videoControlsWrapperRef.current
180
+ });
181
+ }
182
+ }
183
+ }
184
+ }, {
185
+ key: "bindKeydown",
186
+ value: function bindKeydown() {
187
+ var _this2 = this;
188
+ if ((0, _platformFeatureFlags.getBooleanFF)('platform.editor.a11y_video_controls_keyboard_support_yhcxh')) {
189
+ var _this$videoControlsWr;
190
+ var onKeydown = function onKeydown(event) {
191
+ if (event.key === 'Tab') {
192
+ var _this2$videoControlsW;
193
+ // Add focus trap for controls panel
194
+ var firstElement;
195
+ var lastElement;
196
+ var focusableElements = (_this2$videoControlsW = _this2.videoControlsWrapperRef) === null || _this2$videoControlsW === void 0 || (_this2$videoControlsW = _this2$videoControlsW.current) === null || _this2$videoControlsW === void 0 ? void 0 : _this2$videoControlsW.querySelectorAll('button, input, [tabindex]:not([tabindex="-1"])');
197
+ if (focusableElements && focusableElements.length) {
198
+ firstElement = focusableElements[0];
199
+ lastElement = focusableElements[focusableElements.length - 1];
200
+ if (event.shiftKey && document.activeElement === firstElement) {
201
+ event.preventDefault();
202
+ lastElement.focus();
203
+ } else if (!event.shiftKey && document.activeElement === lastElement) {
204
+ var _firstElement;
205
+ event.preventDefault();
206
+ (_firstElement = firstElement) === null || _firstElement === void 0 || _firstElement.focus();
207
+ }
208
+ }
209
+ }
210
+ };
211
+ if ((_this$videoControlsWr = this.videoControlsWrapperRef) !== null && _this$videoControlsWr !== void 0 && _this$videoControlsWr.current) {
212
+ this.unbindKeyDown = (0, _bindEventListener.bind)(this.videoControlsWrapperRef.current, {
213
+ type: 'keydown',
214
+ listener: onKeydown,
215
+ options: {
216
+ capture: true,
217
+ passive: false
218
+ }
219
+ });
220
+ }
221
+ }
165
222
  }
166
223
  }, {
167
224
  key: "render",
@@ -233,7 +290,8 @@ var MediaNode = exports.MediaNode = /*#__PURE__*/function (_Component) {
233
290
  isLazy: mediaOptions && mediaOptions.allowLazyLoading,
234
291
  featureFlags: mediaOptions && mediaOptions.featureFlags,
235
292
  contextId: contextId,
236
- alt: alt
293
+ alt: alt,
294
+ videoControlsWrapperRef: this.videoControlsWrapperRef
237
295
  })));
238
296
  }
239
297
  }]);
@@ -599,6 +599,19 @@ var MediaSingleNodeView = /*#__PURE__*/function (_ReactNodeView) {
599
599
  }
600
600
  return undefined;
601
601
  }
602
+ }, {
603
+ key: "stopEvent",
604
+ value: function stopEvent(event) {
605
+ if ((0, _platformFeatureFlags.getBooleanFF)('platform.editor.a11y_video_controls_keyboard_support_yhcxh')) {
606
+ if (this.isNodeSelected() && event instanceof KeyboardEvent && (event === null || event === void 0 ? void 0 : event.target) instanceof HTMLElement) {
607
+ var targetType = event.target.type;
608
+ if (event.key === 'Enter' && targetType === 'button') {
609
+ return true;
610
+ }
611
+ }
612
+ }
613
+ return false;
614
+ }
602
615
  }, {
603
616
  key: "update",
604
617
  value: function update(node, decorations, _innerDecorations, isValidUpdate) {
@@ -20,7 +20,6 @@ var _utils = require("../toolbar/utils");
20
20
  function keymapPlugin(options, editorAnalyticsAPI, editorSelectionAPI, widthPlugin, getIntl) {
21
21
  var list = {};
22
22
  (0, _keymaps.bindKeymapWithCommand)(_keymaps.undo.common, ignoreLinksInSteps, list);
23
- (0, _keymaps.bindKeymapWithCommand)(_keymaps.enter.common, splitMediaGroup, list);
24
23
  if (options !== null && options !== void 0 && options.allowCaptions) {
25
24
  (0, _keymaps.bindKeymapWithCommand)(_keymaps.moveDown.common, insertAndSelectCaption(editorAnalyticsAPI), list);
26
25
  (0, _keymaps.bindKeymapWithCommand)(_keymaps.tab.common, insertAndSelectCaption(editorAnalyticsAPI), list);
@@ -28,12 +27,16 @@ function keymapPlugin(options, editorAnalyticsAPI, editorSelectionAPI, widthPlug
28
27
  (0, _keymaps.bindKeymapWithCommand)(_keymaps.moveRight.common, arrowRightFromMediaSingle(editorSelectionAPI), list);
29
28
  }
30
29
  (0, _keymaps.bindKeymapWithCommand)(_keymaps.insertNewLine.common, splitMediaGroup, list);
30
+ (0, _keymaps.bindKeymapWithCommand)(_keymaps.enter.common, splitMediaGroup, list);
31
31
  if ((0, _platformFeatureFlags.getBooleanFF)('platform.editor.media.extended-resize-experience')) {
32
32
  if ((0, _platformFeatureFlags.getBooleanFF)('platform.editor.a11y-media-resizing_b5v0o')) {
33
33
  (0, _keymaps.bindKeymapWithCommand)(_keymaps.increaseMediaSize.common, handleMediaIncrease(editorAnalyticsAPI, widthPlugin, options, getIntl), list);
34
34
  (0, _keymaps.bindKeymapWithCommand)(_keymaps.decreaseMediaSize.common, handleMediaDecrease(editorAnalyticsAPI, widthPlugin, options, getIntl), list);
35
35
  }
36
36
  }
37
+ if ((0, _platformFeatureFlags.getBooleanFF)('platform.editor.a11y_video_controls_keyboard_support_yhcxh')) {
38
+ (0, _keymaps.bindKeymapWithCommand)(_keymaps.activateVideoControls.common, focusPlayButton, list);
39
+ }
37
40
  return (0, _keymap.keymap)(list);
38
41
  }
39
42
  var ignoreLinksInSteps = function ignoreLinksInSteps(state) {
@@ -45,6 +48,15 @@ var splitMediaGroup = function splitMediaGroup(state) {
45
48
  var mediaPluginState = _pluginKey.stateKey.getState(state);
46
49
  return mediaPluginState.splitMediaGroup();
47
50
  };
51
+ var focusPlayButton = function focusPlayButton(state) {
52
+ var _stateKey$getState;
53
+ var videoControlsWrapperRef = (_stateKey$getState = _pluginKey.stateKey.getState(state)) === null || _stateKey$getState === void 0 ? void 0 : _stateKey$getState.element;
54
+ if (videoControlsWrapperRef) {
55
+ var firstButton = videoControlsWrapperRef === null || videoControlsWrapperRef === void 0 ? void 0 : videoControlsWrapperRef.querySelector('button, [tabindex]:not([tabindex="-1"])');
56
+ firstButton === null || firstButton === void 0 || firstButton.focus();
57
+ }
58
+ return true;
59
+ };
48
60
  var validationMaxMin = function validationMaxMin(newWidth, maxWidth, minWidth, validation) {
49
61
  var newWidthValidated;
50
62
  if (newWidth > maxWidth) {
@@ -848,7 +848,23 @@ var createPlugin = exports.createPlugin = function createPlugin(_schema, options
848
848
  return _view2.DecorationSet.create(state.doc, dropPlaceholders);
849
849
  },
850
850
  nodeViews: options.nodeViews,
851
- handleTextInput: function handleTextInput(view) {
851
+ handleTextInput: function handleTextInput(view, from, to, text) {
852
+ if ((0, _platformFeatureFlags.getBooleanFF)('platform.editor.a11y_video_controls_keyboard_support_yhcxh')) {
853
+ var selection = view.state.selection;
854
+ if (text === ' ' && selection instanceof _state2.NodeSelection && selection.node.type.name === 'mediaSingle') {
855
+ var _stateKey$getState;
856
+ var videoControlsWrapperRef = (_stateKey$getState = _pluginKey.stateKey.getState(view.state)) === null || _stateKey$getState === void 0 ? void 0 : _stateKey$getState.element;
857
+ var videoControls = videoControlsWrapperRef === null || videoControlsWrapperRef === void 0 ? void 0 : videoControlsWrapperRef.querySelectorAll('button, [tabindex]:not([tabindex="-1"])');
858
+ if (videoControls) {
859
+ var isVideoControl = Array.from(videoControls).some(function (videoControl) {
860
+ return document.activeElement === videoControl;
861
+ });
862
+ if (isVideoControl) {
863
+ return true;
864
+ }
865
+ }
866
+ }
867
+ }
852
868
  getMediaPluginState(view.state).splitMediaGroup();
853
869
  return false;
854
870
  },
@@ -870,6 +886,39 @@ var createPlugin = exports.createPlugin = function createPlugin(_schema, options
870
886
  return !!((_event$target2 = event.target) !== null && _event$target2 !== void 0 && _event$target2.closest("[class=\"".concat(MEDIA_CONTENT_WRAP_CLASS_NAME, "\"]")));
871
887
  }
872
888
  return false;
889
+ },
890
+ handleDOMEvents: {
891
+ keydown: function keydown(view, event) {
892
+ if ((0, _platformFeatureFlags.getBooleanFF)('platform.editor.a11y_video_controls_keyboard_support_yhcxh')) {
893
+ var selection = view.state.selection;
894
+ if (selection instanceof _state2.NodeSelection && selection.node.type.name === 'mediaSingle') {
895
+ // handle keydown events for video controls panel to prevent fire of rest prosemirror listeners;
896
+ if ((event === null || event === void 0 ? void 0 : event.target) instanceof HTMLElement) {
897
+ var a11yDefaultKeys = ['Tab', 'Space', 'Enter', 'Shift', 'Esc'];
898
+ var targetsAndButtons = {
899
+ button: a11yDefaultKeys,
900
+ range: [].concat(a11yDefaultKeys, ['ArrowDown', 'ArrowUp', 'ArrowLeft', 'ArrowRight']),
901
+ text: [].concat(a11yDefaultKeys, ['ArrowDown', 'ArrowUp', 'Esc'])
902
+ };
903
+ var targetType = event.target.type;
904
+ // only if targeting button or range/text input
905
+ if (targetType && targetType in targetsAndButtons) {
906
+ var targetRelatedA11YKeys = targetsAndButtons[targetType];
907
+ var allowedKeys = new Set(targetRelatedA11YKeys);
908
+ if (allowedKeys.has(event.key) || allowedKeys.has(event.code)) {
909
+ // allow event to bubble to be handled by react handlers
910
+ return true;
911
+ } else {
912
+ // otherwise focus editor to allow setting gapCursor. (e.g.: arrowRightFromMediaSingle)
913
+ view.focus();
914
+ }
915
+ }
916
+ }
917
+ }
918
+ // fire regular prosemirror listeners;
919
+ return false;
920
+ }
921
+ }
873
922
  }
874
923
  }
875
924
  });
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.CommentWithDotIcon = void 0;
8
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
9
+ var _react = _interopRequireDefault(require("react"));
10
+ var _icon = _interopRequireDefault(require("@atlaskit/icon"));
11
+ var _colors = require("@atlaskit/theme/colors");
12
+ var IconCommentWithDotGlyph = function IconCommentWithDotGlyph() {
13
+ return /*#__PURE__*/_react.default.createElement("svg", {
14
+ width: "24",
15
+ height: "24",
16
+ viewBox: "0 0 24 24",
17
+ fill: "none",
18
+ xmlns: "http://www.w3.org/2000/svg"
19
+ }, /*#__PURE__*/_react.default.createElement("path", {
20
+ fillRule: "evenodd",
21
+ clipRule: "evenodd",
22
+ d: "M4.998 11.513C4.998 8.475 8.139 6.003 12 6.003C15.861 6.003 19.002 8.475 19.002 11.513C19.002 14.552 15.861 17.023 12 17.023C8.139 17.023 4.998 14.552 4.998 11.513ZM19.838 19.284V19.282C19.838 19.282 18.274 17.022 19.071 16.166L19.034 16.186C20.261 14.902 21 13.279 21 11.513C21 7.371 16.963 4 12 4C7.037 4 3 7.37 3 11.513C3 15.656 7.037 19.027 12 19.027C13.42 19.027 14.76 18.742 15.957 18.251C16.96 19.273 18.244 19.823 19.197 19.97L19.199 19.967C19.2515 19.9867 19.3069 19.9979 19.363 20C19.448 20 19.5317 19.9789 19.6067 19.9386C19.6816 19.8984 19.7453 19.8402 19.7923 19.7693C19.8392 19.6984 19.8679 19.6169 19.8757 19.5323C19.8835 19.4476 19.8712 19.3623 19.838 19.284Z",
23
+ fill: "currentColor"
24
+ }), /*#__PURE__*/_react.default.createElement("path", {
25
+ d: "M16 9H8C7.44772 9 7 9.44772 7 10C7 10.5523 7.44772 11 8 11H16C16.5523 11 17 10.5523 17 10C17 9.44772 16.5523 9 16 9Z",
26
+ fill: "currentColor"
27
+ }), /*#__PURE__*/_react.default.createElement("path", {
28
+ d: "M11 12H8C7.44772 12 7 12.4477 7 13C7 13.5523 7.44772 14 8 14H11C11.5523 14 12 13.5523 12 13C12 12.4477 11.5523 12 11 12Z",
29
+ fill: "currentColor"
30
+ }), /*#__PURE__*/_react.default.createElement("rect", {
31
+ x: "14",
32
+ y: "2",
33
+ width: "8",
34
+ height: "8",
35
+ rx: "4",
36
+ fill: "var(--ds-background-warning-bold, ".concat(_colors.Y300, ")")
37
+ }));
38
+ };
39
+ var CommentWithDotIcon = exports.CommentWithDotIcon = function CommentWithDotIcon(props) {
40
+ return /*#__PURE__*/_react.default.createElement(_icon.default, (0, _extends2.default)({
41
+ glyph: IconCommentWithDotGlyph
42
+ }, props));
43
+ };
@@ -9,17 +9,26 @@ var _react = _interopRequireDefault(require("react"));
9
9
  var _analytics = require("@atlaskit/editor-common/analytics");
10
10
  var _keymaps = require("@atlaskit/editor-common/keymaps");
11
11
  var _media = require("@atlaskit/editor-common/media");
12
- var _state2 = require("@atlaskit/editor-prosemirror/state");
13
12
  var _comment = _interopRequireDefault(require("@atlaskit/icon/glyph/comment"));
14
- var commentButton = exports.commentButton = function commentButton(intl, _state, api) {
15
- var title = intl.formatMessage(_media.commentMessages.addCommentOnMedia);
13
+ var _commentWithDotIcon = require("./assets/commentWithDotIcon");
14
+ var _utils = require("./utils");
15
+ var commentButton = exports.commentButton = function commentButton(intl, state, api) {
16
+ var _getSelectedMediaSing, _api$annotation;
17
+ var selectMediaNode = (_getSelectedMediaSing = (0, _utils.getSelectedMediaSingle)(state)) === null || _getSelectedMediaSing === void 0 ? void 0 : _getSelectedMediaSing.node.firstChild;
18
+ var hasActiveComments = false;
19
+ var annotations = api === null || api === void 0 || (_api$annotation = api.annotation) === null || _api$annotation === void 0 || (_api$annotation = _api$annotation.sharedState.currentState()) === null || _api$annotation === void 0 ? void 0 : _api$annotation.annotations;
20
+ if (selectMediaNode && annotations) {
21
+ hasActiveComments = selectMediaNode.marks.some(function (mark) {
22
+ return mark.type.name === 'annotation' && !annotations[mark.attrs.id];
23
+ });
24
+ }
25
+ var title = intl.formatMessage(hasActiveComments ? _media.commentMessages.viewCommentsOnMedia : _media.commentMessages.addCommentOnMedia);
16
26
  var onClickHandler = function onClickHandler(state, dispatch) {
17
- if (api !== null && api !== void 0 && api.annotation && state.selection instanceof _state2.NodeSelection) {
18
- var mediaNode = state.selection.node.firstChild;
27
+ if (api !== null && api !== void 0 && api.annotation && selectMediaNode) {
19
28
  var _api$annotation$actio = api.annotation.actions,
20
29
  showCommentForBlockNode = _api$annotation$actio.showCommentForBlockNode,
21
30
  setInlineCommentDraftState = _api$annotation$actio.setInlineCommentDraftState;
22
- if (!showCommentForBlockNode(mediaNode)(state, dispatch)) {
31
+ if (!showCommentForBlockNode(selectMediaNode)(state, dispatch)) {
23
32
  setInlineCommentDraftState(true,
24
33
  // TODO: might need to update to reflect it's from media floating toolbar
25
34
  _analytics.INPUT_METHOD.FLOATING_TB, 'block', true)(state, dispatch);
@@ -30,7 +39,7 @@ var commentButton = exports.commentButton = function commentButton(intl, _state,
30
39
  return {
31
40
  type: 'button',
32
41
  testId: 'add-comment-media-button',
33
- icon: _comment.default,
42
+ icon: hasActiveComments ? _commentWithDotIcon.CommentWithDotIcon : _comment.default,
34
43
  title: title,
35
44
  onClick: onClickHandler,
36
45
  tooltipContent: /*#__PURE__*/_react.default.createElement(_keymaps.ToolTipContent, {
@@ -1,10 +1,12 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import React, { Component } from 'react';
3
+ import { bind } from 'bind-event-listener';
3
4
  import { MEDIA_CONTEXT } from '@atlaskit/analytics-namespaced-context';
4
5
  import { AnalyticsContext } from '@atlaskit/analytics-next';
5
6
  import { setNodeSelection, setTextSelection, withImageLoader } from '@atlaskit/editor-common/utils';
6
7
  import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
7
8
  import { Card, CardLoading } from '@atlaskit/media-card';
9
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
8
10
  import { stateKey as mediaStateKey } from '../../pm-plugins/plugin-key';
9
11
  import { MediaCardWrapper } from '../styles';
10
12
 
@@ -16,6 +18,8 @@ export class MediaNode extends Component {
16
18
  constructor(_props) {
17
19
  super(_props);
18
20
  _defineProperty(this, "state", {});
21
+ _defineProperty(this, "videoControlsWrapperRef", /*#__PURE__*/React.createRef());
22
+ _defineProperty(this, "unbindKeyDown", null);
19
23
  _defineProperty(this, "setViewMediaClientConfig", async () => {
20
24
  const mediaProvider = await this.props.mediaProvider;
21
25
  if (mediaProvider) {
@@ -95,6 +99,9 @@ export class MediaNode extends Component {
95
99
  node
96
100
  } = this.props;
97
101
  (_this$mediaPluginStat3 = this.mediaPluginState) === null || _this$mediaPluginStat3 === void 0 ? void 0 : _this$mediaPluginStat3.handleMediaNodeUnmount(node);
102
+ if (getBooleanFF('platform.editor.a11y_video_controls_keyboard_support_yhcxh') && this.unbindKeyDown && typeof this.unbindKeyDown === 'function') {
103
+ this.unbindKeyDown();
104
+ }
98
105
  }
99
106
  componentDidUpdate(prevProps) {
100
107
  var _this$mediaPluginStat5;
@@ -105,6 +112,53 @@ export class MediaNode extends Component {
105
112
  }
106
113
  (_this$mediaPluginStat5 = this.mediaPluginState) === null || _this$mediaPluginStat5 === void 0 ? void 0 : _this$mediaPluginStat5.updateElement();
107
114
  this.setViewMediaClientConfig();
115
+ // this.videoControlsWrapperRef is null on componentDidMount. We need to wait until it has value
116
+ if (getBooleanFF('platform.editor.a11y_video_controls_keyboard_support_yhcxh') && this.videoControlsWrapperRef && this.videoControlsWrapperRef.current) {
117
+ var _this$mediaPluginStat6;
118
+ if (!((_this$mediaPluginStat6 = this.mediaPluginState) !== null && _this$mediaPluginStat6 !== void 0 && _this$mediaPluginStat6.videoControlsWrapperRef)) {
119
+ var _this$mediaPluginStat7;
120
+ this.bindKeydown();
121
+ (_this$mediaPluginStat7 = this.mediaPluginState) === null || _this$mediaPluginStat7 === void 0 ? void 0 : _this$mediaPluginStat7.updateAndDispatch({
122
+ videoControlsWrapperRef: this.videoControlsWrapperRef.current
123
+ });
124
+ }
125
+ }
126
+ }
127
+ bindKeydown() {
128
+ if (getBooleanFF('platform.editor.a11y_video_controls_keyboard_support_yhcxh')) {
129
+ var _this$videoControlsWr3;
130
+ const onKeydown = event => {
131
+ if (event.key === 'Tab') {
132
+ var _this$videoControlsWr, _this$videoControlsWr2;
133
+ // Add focus trap for controls panel
134
+ let firstElement;
135
+ let lastElement;
136
+ const focusableElements = (_this$videoControlsWr = this.videoControlsWrapperRef) === null || _this$videoControlsWr === void 0 ? void 0 : (_this$videoControlsWr2 = _this$videoControlsWr.current) === null || _this$videoControlsWr2 === void 0 ? void 0 : _this$videoControlsWr2.querySelectorAll('button, input, [tabindex]:not([tabindex="-1"])');
137
+ if (focusableElements && focusableElements.length) {
138
+ firstElement = focusableElements[0];
139
+ lastElement = focusableElements[focusableElements.length - 1];
140
+ if (event.shiftKey && document.activeElement === firstElement) {
141
+ event.preventDefault();
142
+ lastElement.focus();
143
+ } else if (!event.shiftKey && document.activeElement === lastElement) {
144
+ var _firstElement;
145
+ event.preventDefault();
146
+ (_firstElement = firstElement) === null || _firstElement === void 0 ? void 0 : _firstElement.focus();
147
+ }
148
+ }
149
+ }
150
+ };
151
+ if ((_this$videoControlsWr3 = this.videoControlsWrapperRef) !== null && _this$videoControlsWr3 !== void 0 && _this$videoControlsWr3.current) {
152
+ this.unbindKeyDown = bind(this.videoControlsWrapperRef.current, {
153
+ type: 'keydown',
154
+ listener: onKeydown,
155
+ options: {
156
+ capture: true,
157
+ passive: false
158
+ }
159
+ });
160
+ }
161
+ }
108
162
  }
109
163
  render() {
110
164
  const {
@@ -175,7 +229,8 @@ export class MediaNode extends Component {
175
229
  isLazy: mediaOptions && mediaOptions.allowLazyLoading,
176
230
  featureFlags: mediaOptions && mediaOptions.featureFlags,
177
231
  contextId: contextId,
178
- alt: alt
232
+ alt: alt,
233
+ videoControlsWrapperRef: this.videoControlsWrapperRef
179
234
  })));
180
235
  }
181
236
  }
@@ -498,6 +498,17 @@ class MediaSingleNodeView extends ReactNodeView {
498
498
  }
499
499
  return undefined;
500
500
  }
501
+ stopEvent(event) {
502
+ if (getBooleanFF('platform.editor.a11y_video_controls_keyboard_support_yhcxh')) {
503
+ if (this.isNodeSelected() && event instanceof KeyboardEvent && (event === null || event === void 0 ? void 0 : event.target) instanceof HTMLElement) {
504
+ const targetType = event.target.type;
505
+ if (event.key === 'Enter' && targetType === 'button') {
506
+ return true;
507
+ }
508
+ }
509
+ }
510
+ return false;
511
+ }
501
512
  update(node, decorations, _innerDecorations, isValidUpdate) {
502
513
  if (!isValidUpdate) {
503
514
  isValidUpdate = (currentNode, newNode) => this.getNodeMediaId(currentNode) === this.getNodeMediaId(newNode);
@@ -1,4 +1,4 @@
1
- import { bindKeymapWithCommand, decreaseMediaSize, enter, increaseMediaSize, insertNewLine, moveDown, moveLeft, moveRight, tab, undo } from '@atlaskit/editor-common/keymaps';
1
+ import { activateVideoControls, bindKeymapWithCommand, decreaseMediaSize, enter, increaseMediaSize, insertNewLine, moveDown, moveLeft, moveRight, tab, undo } from '@atlaskit/editor-common/keymaps';
2
2
  import { mediaResizeAnnouncerMessMessages as mediaResizeAnnouncerMess } from '@atlaskit/editor-common/media';
3
3
  import { calcMediaSingleMaxWidth, MEDIA_SINGLE_DEFAULT_MIN_PIXEL_WIDTH } from '@atlaskit/editor-common/media-single';
4
4
  import { GapCursorSelection, Side } from '@atlaskit/editor-common/selection';
@@ -13,7 +13,6 @@ import { calcNewLayout, getSelectedMediaSingle } from '../toolbar/utils';
13
13
  export function keymapPlugin(options, editorAnalyticsAPI, editorSelectionAPI, widthPlugin, getIntl) {
14
14
  const list = {};
15
15
  bindKeymapWithCommand(undo.common, ignoreLinksInSteps, list);
16
- bindKeymapWithCommand(enter.common, splitMediaGroup, list);
17
16
  if (options !== null && options !== void 0 && options.allowCaptions) {
18
17
  bindKeymapWithCommand(moveDown.common, insertAndSelectCaption(editorAnalyticsAPI), list);
19
18
  bindKeymapWithCommand(tab.common, insertAndSelectCaption(editorAnalyticsAPI), list);
@@ -21,12 +20,16 @@ export function keymapPlugin(options, editorAnalyticsAPI, editorSelectionAPI, wi
21
20
  bindKeymapWithCommand(moveRight.common, arrowRightFromMediaSingle(editorSelectionAPI), list);
22
21
  }
23
22
  bindKeymapWithCommand(insertNewLine.common, splitMediaGroup, list);
23
+ bindKeymapWithCommand(enter.common, splitMediaGroup, list);
24
24
  if (getBooleanFF('platform.editor.media.extended-resize-experience')) {
25
25
  if (getBooleanFF('platform.editor.a11y-media-resizing_b5v0o')) {
26
26
  bindKeymapWithCommand(increaseMediaSize.common, handleMediaIncrease(editorAnalyticsAPI, widthPlugin, options, getIntl), list);
27
27
  bindKeymapWithCommand(decreaseMediaSize.common, handleMediaDecrease(editorAnalyticsAPI, widthPlugin, options, getIntl), list);
28
28
  }
29
29
  }
30
+ if (getBooleanFF('platform.editor.a11y_video_controls_keyboard_support_yhcxh')) {
31
+ bindKeymapWithCommand(activateVideoControls.common, focusPlayButton, list);
32
+ }
30
33
  return keymap(list);
31
34
  }
32
35
  const ignoreLinksInSteps = state => {
@@ -38,6 +41,15 @@ const splitMediaGroup = state => {
38
41
  const mediaPluginState = stateKey.getState(state);
39
42
  return mediaPluginState.splitMediaGroup();
40
43
  };
44
+ const focusPlayButton = state => {
45
+ var _stateKey$getState;
46
+ const videoControlsWrapperRef = (_stateKey$getState = stateKey.getState(state)) === null || _stateKey$getState === void 0 ? void 0 : _stateKey$getState.element;
47
+ if (videoControlsWrapperRef) {
48
+ const firstButton = videoControlsWrapperRef === null || videoControlsWrapperRef === void 0 ? void 0 : videoControlsWrapperRef.querySelector('button, [tabindex]:not([tabindex="-1"])');
49
+ firstButton === null || firstButton === void 0 ? void 0 : firstButton.focus();
50
+ }
51
+ return true;
52
+ };
41
53
  const validationMaxMin = (newWidth, maxWidth, minWidth, validation) => {
42
54
  let newWidthValidated;
43
55
  if (newWidth > maxWidth) {
@@ -733,7 +733,25 @@ export const createPlugin = (_schema, options, reactContext, getIntl, pluginInje
733
733
  return DecorationSet.create(state.doc, dropPlaceholders);
734
734
  },
735
735
  nodeViews: options.nodeViews,
736
- handleTextInput(view) {
736
+ handleTextInput(view, from, to, text) {
737
+ if (getBooleanFF('platform.editor.a11y_video_controls_keyboard_support_yhcxh')) {
738
+ const {
739
+ selection
740
+ } = view.state;
741
+ if (text === ' ' && selection instanceof NodeSelection && selection.node.type.name === 'mediaSingle') {
742
+ var _stateKey$getState;
743
+ const videoControlsWrapperRef = (_stateKey$getState = stateKey.getState(view.state)) === null || _stateKey$getState === void 0 ? void 0 : _stateKey$getState.element;
744
+ const videoControls = videoControlsWrapperRef === null || videoControlsWrapperRef === void 0 ? void 0 : videoControlsWrapperRef.querySelectorAll('button, [tabindex]:not([tabindex="-1"])');
745
+ if (videoControls) {
746
+ const isVideoControl = Array.from(videoControls).some(videoControl => {
747
+ return document.activeElement === videoControl;
748
+ });
749
+ if (isVideoControl) {
750
+ return true;
751
+ }
752
+ }
753
+ }
754
+ }
737
755
  getMediaPluginState(view.state).splitMediaGroup();
738
756
  return false;
739
757
  },
@@ -755,6 +773,41 @@ export const createPlugin = (_schema, options, reactContext, getIntl, pluginInje
755
773
  return !!((_event$target2 = event.target) !== null && _event$target2 !== void 0 && _event$target2.closest(`[class="${MEDIA_CONTENT_WRAP_CLASS_NAME}"]`));
756
774
  }
757
775
  return false;
776
+ },
777
+ handleDOMEvents: {
778
+ keydown: (view, event) => {
779
+ if (getBooleanFF('platform.editor.a11y_video_controls_keyboard_support_yhcxh')) {
780
+ const {
781
+ selection
782
+ } = view.state;
783
+ if (selection instanceof NodeSelection && selection.node.type.name === 'mediaSingle') {
784
+ // handle keydown events for video controls panel to prevent fire of rest prosemirror listeners;
785
+ if ((event === null || event === void 0 ? void 0 : event.target) instanceof HTMLElement) {
786
+ const a11yDefaultKeys = ['Tab', 'Space', 'Enter', 'Shift', 'Esc'];
787
+ const targetsAndButtons = {
788
+ button: a11yDefaultKeys,
789
+ range: [...a11yDefaultKeys, 'ArrowDown', 'ArrowUp', 'ArrowLeft', 'ArrowRight'],
790
+ text: [...a11yDefaultKeys, 'ArrowDown', 'ArrowUp', 'Esc']
791
+ };
792
+ const targetType = event.target.type;
793
+ // only if targeting button or range/text input
794
+ if (targetType && targetType in targetsAndButtons) {
795
+ let targetRelatedA11YKeys = targetsAndButtons[targetType];
796
+ const allowedKeys = new Set(targetRelatedA11YKeys);
797
+ if (allowedKeys.has(event.key) || allowedKeys.has(event.code)) {
798
+ // allow event to bubble to be handled by react handlers
799
+ return true;
800
+ } else {
801
+ // otherwise focus editor to allow setting gapCursor. (e.g.: arrowRightFromMediaSingle)
802
+ view.focus();
803
+ }
804
+ }
805
+ }
806
+ }
807
+ // fire regular prosemirror listeners;
808
+ return false;
809
+ }
810
+ }
758
811
  }
759
812
  }
760
813
  });
@@ -0,0 +1,36 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+ import React from 'react';
3
+ import Icon from '@atlaskit/icon';
4
+ import { Y300 } from '@atlaskit/theme/colors';
5
+ const IconCommentWithDotGlyph = () => {
6
+ return /*#__PURE__*/React.createElement("svg", {
7
+ width: "24",
8
+ height: "24",
9
+ viewBox: "0 0 24 24",
10
+ fill: "none",
11
+ xmlns: "http://www.w3.org/2000/svg"
12
+ }, /*#__PURE__*/React.createElement("path", {
13
+ fillRule: "evenodd",
14
+ clipRule: "evenodd",
15
+ d: "M4.998 11.513C4.998 8.475 8.139 6.003 12 6.003C15.861 6.003 19.002 8.475 19.002 11.513C19.002 14.552 15.861 17.023 12 17.023C8.139 17.023 4.998 14.552 4.998 11.513ZM19.838 19.284V19.282C19.838 19.282 18.274 17.022 19.071 16.166L19.034 16.186C20.261 14.902 21 13.279 21 11.513C21 7.371 16.963 4 12 4C7.037 4 3 7.37 3 11.513C3 15.656 7.037 19.027 12 19.027C13.42 19.027 14.76 18.742 15.957 18.251C16.96 19.273 18.244 19.823 19.197 19.97L19.199 19.967C19.2515 19.9867 19.3069 19.9979 19.363 20C19.448 20 19.5317 19.9789 19.6067 19.9386C19.6816 19.8984 19.7453 19.8402 19.7923 19.7693C19.8392 19.6984 19.8679 19.6169 19.8757 19.5323C19.8835 19.4476 19.8712 19.3623 19.838 19.284Z",
16
+ fill: "currentColor"
17
+ }), /*#__PURE__*/React.createElement("path", {
18
+ d: "M16 9H8C7.44772 9 7 9.44772 7 10C7 10.5523 7.44772 11 8 11H16C16.5523 11 17 10.5523 17 10C17 9.44772 16.5523 9 16 9Z",
19
+ fill: "currentColor"
20
+ }), /*#__PURE__*/React.createElement("path", {
21
+ d: "M11 12H8C7.44772 12 7 12.4477 7 13C7 13.5523 7.44772 14 8 14H11C11.5523 14 12 13.5523 12 13C12 12.4477 11.5523 12 11 12Z",
22
+ fill: "currentColor"
23
+ }), /*#__PURE__*/React.createElement("rect", {
24
+ x: "14",
25
+ y: "2",
26
+ width: "8",
27
+ height: "8",
28
+ rx: "4",
29
+ fill: `var(--ds-background-warning-bold, ${Y300})`
30
+ }));
31
+ };
32
+ export const CommentWithDotIcon = props => {
33
+ return /*#__PURE__*/React.createElement(Icon, _extends({
34
+ glyph: IconCommentWithDotGlyph
35
+ }, props));
36
+ };
@@ -2,18 +2,25 @@ import React from 'react';
2
2
  import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
3
3
  import { ToolTipContent } from '@atlaskit/editor-common/keymaps';
4
4
  import { commentMessages as messages } from '@atlaskit/editor-common/media';
5
- import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
6
5
  import CommentIcon from '@atlaskit/icon/glyph/comment';
7
- export const commentButton = (intl, _state, api) => {
8
- const title = intl.formatMessage(messages.addCommentOnMedia);
6
+ import { CommentWithDotIcon } from './assets/commentWithDotIcon';
7
+ import { getSelectedMediaSingle } from './utils';
8
+ export const commentButton = (intl, state, api) => {
9
+ var _getSelectedMediaSing, _api$annotation, _api$annotation$share;
10
+ const selectMediaNode = (_getSelectedMediaSing = getSelectedMediaSingle(state)) === null || _getSelectedMediaSing === void 0 ? void 0 : _getSelectedMediaSing.node.firstChild;
11
+ let hasActiveComments = false;
12
+ const annotations = api === null || api === void 0 ? void 0 : (_api$annotation = api.annotation) === null || _api$annotation === void 0 ? void 0 : (_api$annotation$share = _api$annotation.sharedState.currentState()) === null || _api$annotation$share === void 0 ? void 0 : _api$annotation$share.annotations;
13
+ if (selectMediaNode && annotations) {
14
+ hasActiveComments = selectMediaNode.marks.some(mark => mark.type.name === 'annotation' && !annotations[mark.attrs.id]);
15
+ }
16
+ const title = intl.formatMessage(hasActiveComments ? messages.viewCommentsOnMedia : messages.addCommentOnMedia);
9
17
  const onClickHandler = (state, dispatch) => {
10
- if (api !== null && api !== void 0 && api.annotation && state.selection instanceof NodeSelection) {
11
- const mediaNode = state.selection.node.firstChild;
18
+ if (api !== null && api !== void 0 && api.annotation && selectMediaNode) {
12
19
  const {
13
20
  showCommentForBlockNode,
14
21
  setInlineCommentDraftState
15
22
  } = api.annotation.actions;
16
- if (!showCommentForBlockNode(mediaNode)(state, dispatch)) {
23
+ if (!showCommentForBlockNode(selectMediaNode)(state, dispatch)) {
17
24
  setInlineCommentDraftState(true,
18
25
  // TODO: might need to update to reflect it's from media floating toolbar
19
26
  INPUT_METHOD.FLOATING_TB, 'block', true)(state, dispatch);
@@ -24,7 +31,7 @@ export const commentButton = (intl, _state, api) => {
24
31
  return {
25
32
  type: 'button',
26
33
  testId: 'add-comment-media-button',
27
- icon: CommentIcon,
34
+ icon: hasActiveComments ? CommentWithDotIcon : CommentIcon,
28
35
  title,
29
36
  onClick: onClickHandler,
30
37
  tooltipContent: /*#__PURE__*/React.createElement(ToolTipContent, {
@@ -10,11 +10,13 @@ import _regeneratorRuntime from "@babel/runtime/regenerator";
10
10
  function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
11
11
  function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
12
12
  import React, { Component } from 'react';
13
+ import { bind } from 'bind-event-listener';
13
14
  import { MEDIA_CONTEXT } from '@atlaskit/analytics-namespaced-context';
14
15
  import { AnalyticsContext } from '@atlaskit/analytics-next';
15
16
  import { setNodeSelection, setTextSelection, withImageLoader } from '@atlaskit/editor-common/utils';
16
17
  import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
17
18
  import { Card, CardLoading } from '@atlaskit/media-card';
19
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
18
20
  import { stateKey as mediaStateKey } from '../../pm-plugins/plugin-key';
19
21
  import { MediaCardWrapper } from '../styles';
20
22
 
@@ -30,6 +32,8 @@ export var MediaNode = /*#__PURE__*/function (_Component) {
30
32
  _classCallCheck(this, MediaNode);
31
33
  _this = _super.call(this, _props);
32
34
  _defineProperty(_assertThisInitialized(_this), "state", {});
35
+ _defineProperty(_assertThisInitialized(_this), "videoControlsWrapperRef", /*#__PURE__*/React.createRef());
36
+ _defineProperty(_assertThisInitialized(_this), "unbindKeyDown", null);
33
37
  _defineProperty(_assertThisInitialized(_this), "setViewMediaClientConfig", /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
34
38
  var mediaProvider, viewMediaClientConfig;
35
39
  return _regeneratorRuntime.wrap(function _callee$(_context) {
@@ -141,6 +145,9 @@ export var MediaNode = /*#__PURE__*/function (_Component) {
141
145
  var _this$mediaPluginStat3;
142
146
  var node = this.props.node;
143
147
  (_this$mediaPluginStat3 = this.mediaPluginState) === null || _this$mediaPluginStat3 === void 0 || _this$mediaPluginStat3.handleMediaNodeUnmount(node);
148
+ if (getBooleanFF('platform.editor.a11y_video_controls_keyboard_support_yhcxh') && this.unbindKeyDown && typeof this.unbindKeyDown === 'function') {
149
+ this.unbindKeyDown();
150
+ }
144
151
  }
145
152
  }, {
146
153
  key: "componentDidUpdate",
@@ -153,6 +160,56 @@ export var MediaNode = /*#__PURE__*/function (_Component) {
153
160
  }
154
161
  (_this$mediaPluginStat5 = this.mediaPluginState) === null || _this$mediaPluginStat5 === void 0 || _this$mediaPluginStat5.updateElement();
155
162
  this.setViewMediaClientConfig();
163
+ // this.videoControlsWrapperRef is null on componentDidMount. We need to wait until it has value
164
+ if (getBooleanFF('platform.editor.a11y_video_controls_keyboard_support_yhcxh') && this.videoControlsWrapperRef && this.videoControlsWrapperRef.current) {
165
+ var _this$mediaPluginStat6;
166
+ if (!((_this$mediaPluginStat6 = this.mediaPluginState) !== null && _this$mediaPluginStat6 !== void 0 && _this$mediaPluginStat6.videoControlsWrapperRef)) {
167
+ var _this$mediaPluginStat7;
168
+ this.bindKeydown();
169
+ (_this$mediaPluginStat7 = this.mediaPluginState) === null || _this$mediaPluginStat7 === void 0 || _this$mediaPluginStat7.updateAndDispatch({
170
+ videoControlsWrapperRef: this.videoControlsWrapperRef.current
171
+ });
172
+ }
173
+ }
174
+ }
175
+ }, {
176
+ key: "bindKeydown",
177
+ value: function bindKeydown() {
178
+ var _this2 = this;
179
+ if (getBooleanFF('platform.editor.a11y_video_controls_keyboard_support_yhcxh')) {
180
+ var _this$videoControlsWr;
181
+ var onKeydown = function onKeydown(event) {
182
+ if (event.key === 'Tab') {
183
+ var _this2$videoControlsW;
184
+ // Add focus trap for controls panel
185
+ var firstElement;
186
+ var lastElement;
187
+ var focusableElements = (_this2$videoControlsW = _this2.videoControlsWrapperRef) === null || _this2$videoControlsW === void 0 || (_this2$videoControlsW = _this2$videoControlsW.current) === null || _this2$videoControlsW === void 0 ? void 0 : _this2$videoControlsW.querySelectorAll('button, input, [tabindex]:not([tabindex="-1"])');
188
+ if (focusableElements && focusableElements.length) {
189
+ firstElement = focusableElements[0];
190
+ lastElement = focusableElements[focusableElements.length - 1];
191
+ if (event.shiftKey && document.activeElement === firstElement) {
192
+ event.preventDefault();
193
+ lastElement.focus();
194
+ } else if (!event.shiftKey && document.activeElement === lastElement) {
195
+ var _firstElement;
196
+ event.preventDefault();
197
+ (_firstElement = firstElement) === null || _firstElement === void 0 || _firstElement.focus();
198
+ }
199
+ }
200
+ }
201
+ };
202
+ if ((_this$videoControlsWr = this.videoControlsWrapperRef) !== null && _this$videoControlsWr !== void 0 && _this$videoControlsWr.current) {
203
+ this.unbindKeyDown = bind(this.videoControlsWrapperRef.current, {
204
+ type: 'keydown',
205
+ listener: onKeydown,
206
+ options: {
207
+ capture: true,
208
+ passive: false
209
+ }
210
+ });
211
+ }
212
+ }
156
213
  }
157
214
  }, {
158
215
  key: "render",
@@ -224,7 +281,8 @@ export var MediaNode = /*#__PURE__*/function (_Component) {
224
281
  isLazy: mediaOptions && mediaOptions.allowLazyLoading,
225
282
  featureFlags: mediaOptions && mediaOptions.featureFlags,
226
283
  contextId: contextId,
227
- alt: alt
284
+ alt: alt,
285
+ videoControlsWrapperRef: this.videoControlsWrapperRef
228
286
  })));
229
287
  }
230
288
  }]);
@@ -592,6 +592,19 @@ var MediaSingleNodeView = /*#__PURE__*/function (_ReactNodeView) {
592
592
  }
593
593
  return undefined;
594
594
  }
595
+ }, {
596
+ key: "stopEvent",
597
+ value: function stopEvent(event) {
598
+ if (getBooleanFF('platform.editor.a11y_video_controls_keyboard_support_yhcxh')) {
599
+ if (this.isNodeSelected() && event instanceof KeyboardEvent && (event === null || event === void 0 ? void 0 : event.target) instanceof HTMLElement) {
600
+ var targetType = event.target.type;
601
+ if (event.key === 'Enter' && targetType === 'button') {
602
+ return true;
603
+ }
604
+ }
605
+ }
606
+ return false;
607
+ }
595
608
  }, {
596
609
  key: "update",
597
610
  value: function update(node, decorations, _innerDecorations, isValidUpdate) {
@@ -1,4 +1,4 @@
1
- import { bindKeymapWithCommand, decreaseMediaSize, enter, increaseMediaSize, insertNewLine, moveDown, moveLeft, moveRight, tab, undo } from '@atlaskit/editor-common/keymaps';
1
+ import { activateVideoControls, bindKeymapWithCommand, decreaseMediaSize, enter, increaseMediaSize, insertNewLine, moveDown, moveLeft, moveRight, tab, undo } from '@atlaskit/editor-common/keymaps';
2
2
  import { mediaResizeAnnouncerMessMessages as mediaResizeAnnouncerMess } from '@atlaskit/editor-common/media';
3
3
  import { calcMediaSingleMaxWidth, MEDIA_SINGLE_DEFAULT_MIN_PIXEL_WIDTH } from '@atlaskit/editor-common/media-single';
4
4
  import { GapCursorSelection, Side } from '@atlaskit/editor-common/selection';
@@ -13,7 +13,6 @@ import { calcNewLayout, getSelectedMediaSingle } from '../toolbar/utils';
13
13
  export function keymapPlugin(options, editorAnalyticsAPI, editorSelectionAPI, widthPlugin, getIntl) {
14
14
  var list = {};
15
15
  bindKeymapWithCommand(undo.common, ignoreLinksInSteps, list);
16
- bindKeymapWithCommand(enter.common, splitMediaGroup, list);
17
16
  if (options !== null && options !== void 0 && options.allowCaptions) {
18
17
  bindKeymapWithCommand(moveDown.common, insertAndSelectCaption(editorAnalyticsAPI), list);
19
18
  bindKeymapWithCommand(tab.common, insertAndSelectCaption(editorAnalyticsAPI), list);
@@ -21,12 +20,16 @@ export function keymapPlugin(options, editorAnalyticsAPI, editorSelectionAPI, wi
21
20
  bindKeymapWithCommand(moveRight.common, arrowRightFromMediaSingle(editorSelectionAPI), list);
22
21
  }
23
22
  bindKeymapWithCommand(insertNewLine.common, splitMediaGroup, list);
23
+ bindKeymapWithCommand(enter.common, splitMediaGroup, list);
24
24
  if (getBooleanFF('platform.editor.media.extended-resize-experience')) {
25
25
  if (getBooleanFF('platform.editor.a11y-media-resizing_b5v0o')) {
26
26
  bindKeymapWithCommand(increaseMediaSize.common, handleMediaIncrease(editorAnalyticsAPI, widthPlugin, options, getIntl), list);
27
27
  bindKeymapWithCommand(decreaseMediaSize.common, handleMediaDecrease(editorAnalyticsAPI, widthPlugin, options, getIntl), list);
28
28
  }
29
29
  }
30
+ if (getBooleanFF('platform.editor.a11y_video_controls_keyboard_support_yhcxh')) {
31
+ bindKeymapWithCommand(activateVideoControls.common, focusPlayButton, list);
32
+ }
30
33
  return keymap(list);
31
34
  }
32
35
  var ignoreLinksInSteps = function ignoreLinksInSteps(state) {
@@ -38,6 +41,15 @@ var splitMediaGroup = function splitMediaGroup(state) {
38
41
  var mediaPluginState = stateKey.getState(state);
39
42
  return mediaPluginState.splitMediaGroup();
40
43
  };
44
+ var focusPlayButton = function focusPlayButton(state) {
45
+ var _stateKey$getState;
46
+ var videoControlsWrapperRef = (_stateKey$getState = stateKey.getState(state)) === null || _stateKey$getState === void 0 ? void 0 : _stateKey$getState.element;
47
+ if (videoControlsWrapperRef) {
48
+ var firstButton = videoControlsWrapperRef === null || videoControlsWrapperRef === void 0 ? void 0 : videoControlsWrapperRef.querySelector('button, [tabindex]:not([tabindex="-1"])');
49
+ firstButton === null || firstButton === void 0 || firstButton.focus();
50
+ }
51
+ return true;
52
+ };
41
53
  var validationMaxMin = function validationMaxMin(newWidth, maxWidth, minWidth, validation) {
42
54
  var newWidthValidated;
43
55
  if (newWidth > maxWidth) {
@@ -833,7 +833,23 @@ export var createPlugin = function createPlugin(_schema, options, reactContext,
833
833
  return DecorationSet.create(state.doc, dropPlaceholders);
834
834
  },
835
835
  nodeViews: options.nodeViews,
836
- handleTextInput: function handleTextInput(view) {
836
+ handleTextInput: function handleTextInput(view, from, to, text) {
837
+ if (getBooleanFF('platform.editor.a11y_video_controls_keyboard_support_yhcxh')) {
838
+ var selection = view.state.selection;
839
+ if (text === ' ' && selection instanceof NodeSelection && selection.node.type.name === 'mediaSingle') {
840
+ var _stateKey$getState;
841
+ var videoControlsWrapperRef = (_stateKey$getState = stateKey.getState(view.state)) === null || _stateKey$getState === void 0 ? void 0 : _stateKey$getState.element;
842
+ var videoControls = videoControlsWrapperRef === null || videoControlsWrapperRef === void 0 ? void 0 : videoControlsWrapperRef.querySelectorAll('button, [tabindex]:not([tabindex="-1"])');
843
+ if (videoControls) {
844
+ var isVideoControl = Array.from(videoControls).some(function (videoControl) {
845
+ return document.activeElement === videoControl;
846
+ });
847
+ if (isVideoControl) {
848
+ return true;
849
+ }
850
+ }
851
+ }
852
+ }
837
853
  getMediaPluginState(view.state).splitMediaGroup();
838
854
  return false;
839
855
  },
@@ -855,6 +871,39 @@ export var createPlugin = function createPlugin(_schema, options, reactContext,
855
871
  return !!((_event$target2 = event.target) !== null && _event$target2 !== void 0 && _event$target2.closest("[class=\"".concat(MEDIA_CONTENT_WRAP_CLASS_NAME, "\"]")));
856
872
  }
857
873
  return false;
874
+ },
875
+ handleDOMEvents: {
876
+ keydown: function keydown(view, event) {
877
+ if (getBooleanFF('platform.editor.a11y_video_controls_keyboard_support_yhcxh')) {
878
+ var selection = view.state.selection;
879
+ if (selection instanceof NodeSelection && selection.node.type.name === 'mediaSingle') {
880
+ // handle keydown events for video controls panel to prevent fire of rest prosemirror listeners;
881
+ if ((event === null || event === void 0 ? void 0 : event.target) instanceof HTMLElement) {
882
+ var a11yDefaultKeys = ['Tab', 'Space', 'Enter', 'Shift', 'Esc'];
883
+ var targetsAndButtons = {
884
+ button: a11yDefaultKeys,
885
+ range: [].concat(a11yDefaultKeys, ['ArrowDown', 'ArrowUp', 'ArrowLeft', 'ArrowRight']),
886
+ text: [].concat(a11yDefaultKeys, ['ArrowDown', 'ArrowUp', 'Esc'])
887
+ };
888
+ var targetType = event.target.type;
889
+ // only if targeting button or range/text input
890
+ if (targetType && targetType in targetsAndButtons) {
891
+ var targetRelatedA11YKeys = targetsAndButtons[targetType];
892
+ var allowedKeys = new Set(targetRelatedA11YKeys);
893
+ if (allowedKeys.has(event.key) || allowedKeys.has(event.code)) {
894
+ // allow event to bubble to be handled by react handlers
895
+ return true;
896
+ } else {
897
+ // otherwise focus editor to allow setting gapCursor. (e.g.: arrowRightFromMediaSingle)
898
+ view.focus();
899
+ }
900
+ }
901
+ }
902
+ }
903
+ // fire regular prosemirror listeners;
904
+ return false;
905
+ }
906
+ }
858
907
  }
859
908
  }
860
909
  });
@@ -0,0 +1,36 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+ import React from 'react';
3
+ import Icon from '@atlaskit/icon';
4
+ import { Y300 } from '@atlaskit/theme/colors';
5
+ var IconCommentWithDotGlyph = function IconCommentWithDotGlyph() {
6
+ return /*#__PURE__*/React.createElement("svg", {
7
+ width: "24",
8
+ height: "24",
9
+ viewBox: "0 0 24 24",
10
+ fill: "none",
11
+ xmlns: "http://www.w3.org/2000/svg"
12
+ }, /*#__PURE__*/React.createElement("path", {
13
+ fillRule: "evenodd",
14
+ clipRule: "evenodd",
15
+ d: "M4.998 11.513C4.998 8.475 8.139 6.003 12 6.003C15.861 6.003 19.002 8.475 19.002 11.513C19.002 14.552 15.861 17.023 12 17.023C8.139 17.023 4.998 14.552 4.998 11.513ZM19.838 19.284V19.282C19.838 19.282 18.274 17.022 19.071 16.166L19.034 16.186C20.261 14.902 21 13.279 21 11.513C21 7.371 16.963 4 12 4C7.037 4 3 7.37 3 11.513C3 15.656 7.037 19.027 12 19.027C13.42 19.027 14.76 18.742 15.957 18.251C16.96 19.273 18.244 19.823 19.197 19.97L19.199 19.967C19.2515 19.9867 19.3069 19.9979 19.363 20C19.448 20 19.5317 19.9789 19.6067 19.9386C19.6816 19.8984 19.7453 19.8402 19.7923 19.7693C19.8392 19.6984 19.8679 19.6169 19.8757 19.5323C19.8835 19.4476 19.8712 19.3623 19.838 19.284Z",
16
+ fill: "currentColor"
17
+ }), /*#__PURE__*/React.createElement("path", {
18
+ d: "M16 9H8C7.44772 9 7 9.44772 7 10C7 10.5523 7.44772 11 8 11H16C16.5523 11 17 10.5523 17 10C17 9.44772 16.5523 9 16 9Z",
19
+ fill: "currentColor"
20
+ }), /*#__PURE__*/React.createElement("path", {
21
+ d: "M11 12H8C7.44772 12 7 12.4477 7 13C7 13.5523 7.44772 14 8 14H11C11.5523 14 12 13.5523 12 13C12 12.4477 11.5523 12 11 12Z",
22
+ fill: "currentColor"
23
+ }), /*#__PURE__*/React.createElement("rect", {
24
+ x: "14",
25
+ y: "2",
26
+ width: "8",
27
+ height: "8",
28
+ rx: "4",
29
+ fill: "var(--ds-background-warning-bold, ".concat(Y300, ")")
30
+ }));
31
+ };
32
+ export var CommentWithDotIcon = function CommentWithDotIcon(props) {
33
+ return /*#__PURE__*/React.createElement(Icon, _extends({
34
+ glyph: IconCommentWithDotGlyph
35
+ }, props));
36
+ };
@@ -2,17 +2,26 @@ import React from 'react';
2
2
  import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
3
3
  import { ToolTipContent } from '@atlaskit/editor-common/keymaps';
4
4
  import { commentMessages as messages } from '@atlaskit/editor-common/media';
5
- import { NodeSelection } from '@atlaskit/editor-prosemirror/state';
6
5
  import CommentIcon from '@atlaskit/icon/glyph/comment';
7
- export var commentButton = function commentButton(intl, _state, api) {
8
- var title = intl.formatMessage(messages.addCommentOnMedia);
6
+ import { CommentWithDotIcon } from './assets/commentWithDotIcon';
7
+ import { getSelectedMediaSingle } from './utils';
8
+ export var commentButton = function commentButton(intl, state, api) {
9
+ var _getSelectedMediaSing, _api$annotation;
10
+ var selectMediaNode = (_getSelectedMediaSing = getSelectedMediaSingle(state)) === null || _getSelectedMediaSing === void 0 ? void 0 : _getSelectedMediaSing.node.firstChild;
11
+ var hasActiveComments = false;
12
+ var annotations = api === null || api === void 0 || (_api$annotation = api.annotation) === null || _api$annotation === void 0 || (_api$annotation = _api$annotation.sharedState.currentState()) === null || _api$annotation === void 0 ? void 0 : _api$annotation.annotations;
13
+ if (selectMediaNode && annotations) {
14
+ hasActiveComments = selectMediaNode.marks.some(function (mark) {
15
+ return mark.type.name === 'annotation' && !annotations[mark.attrs.id];
16
+ });
17
+ }
18
+ var title = intl.formatMessage(hasActiveComments ? messages.viewCommentsOnMedia : messages.addCommentOnMedia);
9
19
  var onClickHandler = function onClickHandler(state, dispatch) {
10
- if (api !== null && api !== void 0 && api.annotation && state.selection instanceof NodeSelection) {
11
- var mediaNode = state.selection.node.firstChild;
20
+ if (api !== null && api !== void 0 && api.annotation && selectMediaNode) {
12
21
  var _api$annotation$actio = api.annotation.actions,
13
22
  showCommentForBlockNode = _api$annotation$actio.showCommentForBlockNode,
14
23
  setInlineCommentDraftState = _api$annotation$actio.setInlineCommentDraftState;
15
- if (!showCommentForBlockNode(mediaNode)(state, dispatch)) {
24
+ if (!showCommentForBlockNode(selectMediaNode)(state, dispatch)) {
16
25
  setInlineCommentDraftState(true,
17
26
  // TODO: might need to update to reflect it's from media floating toolbar
18
27
  INPUT_METHOD.FLOATING_TB, 'block', true)(state, dispatch);
@@ -23,7 +32,7 @@ export var commentButton = function commentButton(intl, _state, api) {
23
32
  return {
24
33
  type: 'button',
25
34
  testId: 'add-comment-media-button',
26
- icon: CommentIcon,
35
+ icon: hasActiveComments ? CommentWithDotIcon : CommentIcon,
27
36
  title: title,
28
37
  onClick: onClickHandler,
29
38
  tooltipContent: /*#__PURE__*/React.createElement(ToolTipContent, {
@@ -1,4 +1,5 @@
1
1
  import React, { Component } from 'react';
2
+ import type { UnbindFn } from 'bind-event-listener';
2
3
  import type { ContextIdentifierProvider, MediaProvider } from '@atlaskit/editor-common/provider-factory';
3
4
  import type { ImageLoaderProps } from '@atlaskit/editor-common/utils';
4
5
  import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
@@ -28,11 +29,14 @@ interface MediaNodeState {
28
29
  export declare class MediaNode extends Component<MediaNodeProps, MediaNodeState> {
29
30
  private mediaPluginState;
30
31
  state: MediaNodeState;
32
+ videoControlsWrapperRef: React.RefObject<HTMLDivElement>;
33
+ unbindKeyDown: UnbindFn | null;
31
34
  constructor(props: MediaNodeProps);
32
35
  shouldComponentUpdate(nextProps: MediaNodeProps, nextState: MediaNodeState): boolean;
33
36
  componentDidMount(): Promise<void>;
34
37
  componentWillUnmount(): void;
35
38
  componentDidUpdate(prevProps: Readonly<MediaNodeProps>): void;
39
+ bindKeydown(): void;
36
40
  private setViewMediaClientConfig;
37
41
  private selectMediaSingleFromCard;
38
42
  private selectMediaSingle;
@@ -54,6 +54,7 @@ declare class MediaSingleNodeView extends ReactNodeView<MediaSingleNodeViewProps
54
54
  checkAndUpdateSelectionType: () => import("@atlaskit/editor-common/utils").SelectedState | null;
55
55
  isNodeSelected: () => boolean;
56
56
  getNodeMediaId(node: PMNode): string | undefined;
57
+ stopEvent(event: Event): boolean;
57
58
  update(node: PMNode, decorations: readonly Decoration[], _innerDecorations?: DecorationSource, isValidUpdate?: (currentNode: PMNode, newNode: PMNode) => boolean): boolean;
58
59
  render(props: MediaSingleNodeViewProps, forwardRef?: ForwardRef): jsx.JSX.Element;
59
60
  ignoreMutation(): boolean;
@@ -22,6 +22,7 @@ export interface MediaPluginState {
22
22
  showDropzone: boolean;
23
23
  isFullscreen: boolean;
24
24
  element?: HTMLElement;
25
+ videoControlsWrapperRef?: HTMLElement;
25
26
  layout: MediaSingleLayout;
26
27
  mediaNodes: MediaNodeWithPosHandler[];
27
28
  options: MediaPluginOptions;
@@ -64,7 +65,7 @@ export interface MediaPluginState {
64
65
  setResizingWidth(width: number): void;
65
66
  setView(view: EditorView): void;
66
67
  destroy(): void;
67
- updateAndDispatch(props: Partial<Pick<this, 'allowsUploads' | 'allUploadsFinished' | 'isFullscreen'>>): void;
68
+ updateAndDispatch(props: Partial<Pick<this, 'allowsUploads' | 'allUploadsFinished' | 'isFullscreen' | 'videoControlsWrapperRef'>>): void;
68
69
  clone(): MediaPluginState;
69
70
  subscribeToUploadInProgressState(fn: (isUploading: boolean) => void): void;
70
71
  unsubscribeFromUploadInProgressState(fn: (isUploading: boolean) => void): void;
@@ -0,0 +1,3 @@
1
+ /// <reference types="react" />
2
+ import type { GlyphProps } from '@atlaskit/icon/types';
3
+ export declare const CommentWithDotIcon: (props: GlyphProps) => JSX.Element;
@@ -2,4 +2,4 @@ import type { IntlShape } from 'react-intl-next';
2
2
  import type { Command, ExtractInjectionAPI, FloatingToolbarButton } from '@atlaskit/editor-common/types';
3
3
  import type { EditorState } from '@atlaskit/editor-prosemirror/state';
4
4
  import type { MediaNextEditorPluginType } from '../next-plugin-type';
5
- export declare const commentButton: (intl: IntlShape, _state: EditorState, api: ExtractInjectionAPI<MediaNextEditorPluginType> | undefined) => FloatingToolbarButton<Command>;
5
+ export declare const commentButton: (intl: IntlShape, state: EditorState, api: ExtractInjectionAPI<MediaNextEditorPluginType> | undefined) => FloatingToolbarButton<Command>;
@@ -1,4 +1,5 @@
1
1
  import React, { Component } from 'react';
2
+ import type { UnbindFn } from 'bind-event-listener';
2
3
  import type { ContextIdentifierProvider, MediaProvider } from '@atlaskit/editor-common/provider-factory';
3
4
  import type { ImageLoaderProps } from '@atlaskit/editor-common/utils';
4
5
  import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
@@ -28,11 +29,14 @@ interface MediaNodeState {
28
29
  export declare class MediaNode extends Component<MediaNodeProps, MediaNodeState> {
29
30
  private mediaPluginState;
30
31
  state: MediaNodeState;
32
+ videoControlsWrapperRef: React.RefObject<HTMLDivElement>;
33
+ unbindKeyDown: UnbindFn | null;
31
34
  constructor(props: MediaNodeProps);
32
35
  shouldComponentUpdate(nextProps: MediaNodeProps, nextState: MediaNodeState): boolean;
33
36
  componentDidMount(): Promise<void>;
34
37
  componentWillUnmount(): void;
35
38
  componentDidUpdate(prevProps: Readonly<MediaNodeProps>): void;
39
+ bindKeydown(): void;
36
40
  private setViewMediaClientConfig;
37
41
  private selectMediaSingleFromCard;
38
42
  private selectMediaSingle;
@@ -54,6 +54,7 @@ declare class MediaSingleNodeView extends ReactNodeView<MediaSingleNodeViewProps
54
54
  checkAndUpdateSelectionType: () => import("@atlaskit/editor-common/utils").SelectedState | null;
55
55
  isNodeSelected: () => boolean;
56
56
  getNodeMediaId(node: PMNode): string | undefined;
57
+ stopEvent(event: Event): boolean;
57
58
  update(node: PMNode, decorations: readonly Decoration[], _innerDecorations?: DecorationSource, isValidUpdate?: (currentNode: PMNode, newNode: PMNode) => boolean): boolean;
58
59
  render(props: MediaSingleNodeViewProps, forwardRef?: ForwardRef): jsx.JSX.Element;
59
60
  ignoreMutation(): boolean;
@@ -22,6 +22,7 @@ export interface MediaPluginState {
22
22
  showDropzone: boolean;
23
23
  isFullscreen: boolean;
24
24
  element?: HTMLElement;
25
+ videoControlsWrapperRef?: HTMLElement;
25
26
  layout: MediaSingleLayout;
26
27
  mediaNodes: MediaNodeWithPosHandler[];
27
28
  options: MediaPluginOptions;
@@ -64,7 +65,7 @@ export interface MediaPluginState {
64
65
  setResizingWidth(width: number): void;
65
66
  setView(view: EditorView): void;
66
67
  destroy(): void;
67
- updateAndDispatch(props: Partial<Pick<this, 'allowsUploads' | 'allUploadsFinished' | 'isFullscreen'>>): void;
68
+ updateAndDispatch(props: Partial<Pick<this, 'allowsUploads' | 'allUploadsFinished' | 'isFullscreen' | 'videoControlsWrapperRef'>>): void;
68
69
  clone(): MediaPluginState;
69
70
  subscribeToUploadInProgressState(fn: (isUploading: boolean) => void): void;
70
71
  unsubscribeFromUploadInProgressState(fn: (isUploading: boolean) => void): void;
@@ -0,0 +1,3 @@
1
+ /// <reference types="react" />
2
+ import type { GlyphProps } from '@atlaskit/icon/types';
3
+ export declare const CommentWithDotIcon: (props: GlyphProps) => JSX.Element;
@@ -2,4 +2,4 @@ import type { IntlShape } from 'react-intl-next';
2
2
  import type { Command, ExtractInjectionAPI, FloatingToolbarButton } from '@atlaskit/editor-common/types';
3
3
  import type { EditorState } from '@atlaskit/editor-prosemirror/state';
4
4
  import type { MediaNextEditorPluginType } from '../next-plugin-type';
5
- export declare const commentButton: (intl: IntlShape, _state: EditorState, api: ExtractInjectionAPI<MediaNextEditorPluginType> | undefined) => FloatingToolbarButton<Command>;
5
+ export declare const commentButton: (intl: IntlShape, state: EditorState, api: ExtractInjectionAPI<MediaNextEditorPluginType> | undefined) => FloatingToolbarButton<Command>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-media",
3
- "version": "1.13.5",
3
+ "version": "1.14.1",
4
4
  "description": "Media plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -36,7 +36,7 @@
36
36
  "@atlaskit/adf-schema": "^35.8.0",
37
37
  "@atlaskit/analytics-namespaced-context": "^6.9.0",
38
38
  "@atlaskit/analytics-next": "^9.2.0",
39
- "@atlaskit/button": "^17.10.0",
39
+ "@atlaskit/button": "^17.11.0",
40
40
  "@atlaskit/editor-common": "^78.23.0",
41
41
  "@atlaskit/editor-palette": "1.5.3",
42
42
  "@atlaskit/editor-plugin-analytics": "^1.0.0",
@@ -61,7 +61,7 @@
61
61
  "@atlaskit/media-common": "^11.1.0",
62
62
  "@atlaskit/media-filmstrip": "^47.0.0",
63
63
  "@atlaskit/media-picker": "^66.4.0",
64
- "@atlaskit/media-ui": "^25.5.0",
64
+ "@atlaskit/media-ui": "^25.6.0",
65
65
  "@atlaskit/media-viewer": "^48.4.0",
66
66
  "@atlaskit/platform-feature-flags": "^0.2.0",
67
67
  "@atlaskit/primitives": "^5.5.0",
@@ -71,6 +71,7 @@
71
71
  "@atlaskit/tooltip": "^18.1.0",
72
72
  "@babel/runtime": "^7.0.0",
73
73
  "@emotion/react": "^11.7.1",
74
+ "bind-event-listener": "^2.1.1",
74
75
  "classnames": "^2.2.5",
75
76
  "lodash": "^4.17.21",
76
77
  "memoize-one": "^6.0.0",
@@ -141,6 +142,9 @@
141
142
  "platform.editor.allow-extended-panel": {
142
143
  "type": "boolean"
143
144
  },
145
+ "platform.editor.a11y_video_controls_keyboard_support_yhcxh": {
146
+ "type": "boolean"
147
+ },
144
148
  "platform.editor.media.fix-copy-paste-excel_62g4s": {
145
149
  "type": "boolean"
146
150
  },