@atlaskit/editor-plugin-block-type 4.0.14 → 4.1.0

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 (48) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/cjs/blockTypePlugin.js +3 -0
  3. package/dist/cjs/pm-plugins/block-types.js +3 -1
  4. package/dist/cjs/pm-plugins/commands/block-type.js +58 -10
  5. package/dist/cjs/pm-plugins/commands/clear-formatting.js +58 -0
  6. package/dist/cjs/pm-plugins/main.js +6 -3
  7. package/dist/cjs/pm-plugins/ui/FloatingToolbarComponent.js +5 -0
  8. package/dist/cjs/pm-plugins/ui/PrimaryToolbarComponent.js +6 -1
  9. package/dist/cjs/pm-plugins/ui/ToolbarBlockType/index.js +82 -45
  10. package/dist/cjs/pm-plugins/ui/ToolbarBlockType/styled.js +15 -1
  11. package/dist/cjs/pm-plugins/utils.js +41 -2
  12. package/dist/es2019/blockTypePlugin.js +4 -1
  13. package/dist/es2019/pm-plugins/block-types.js +2 -0
  14. package/dist/es2019/pm-plugins/commands/block-type.js +49 -0
  15. package/dist/es2019/pm-plugins/commands/clear-formatting.js +50 -0
  16. package/dist/es2019/pm-plugins/main.js +7 -4
  17. package/dist/es2019/pm-plugins/ui/FloatingToolbarComponent.js +5 -0
  18. package/dist/es2019/pm-plugins/ui/PrimaryToolbarComponent.js +6 -1
  19. package/dist/es2019/pm-plugins/ui/ToolbarBlockType/index.js +83 -48
  20. package/dist/es2019/pm-plugins/ui/ToolbarBlockType/styled.js +14 -0
  21. package/dist/es2019/pm-plugins/utils.js +43 -2
  22. package/dist/esm/blockTypePlugin.js +4 -1
  23. package/dist/esm/pm-plugins/block-types.js +2 -0
  24. package/dist/esm/pm-plugins/commands/block-type.js +55 -9
  25. package/dist/esm/pm-plugins/commands/clear-formatting.js +50 -0
  26. package/dist/esm/pm-plugins/main.js +7 -4
  27. package/dist/esm/pm-plugins/ui/FloatingToolbarComponent.js +5 -0
  28. package/dist/esm/pm-plugins/ui/PrimaryToolbarComponent.js +6 -1
  29. package/dist/esm/pm-plugins/ui/ToolbarBlockType/index.js +84 -47
  30. package/dist/esm/pm-plugins/ui/ToolbarBlockType/styled.js +14 -0
  31. package/dist/esm/pm-plugins/utils.js +41 -2
  32. package/dist/types/blockTypePluginType.d.ts +1 -0
  33. package/dist/types/pm-plugins/block-types.d.ts +2 -0
  34. package/dist/types/pm-plugins/commands/block-type.d.ts +1 -0
  35. package/dist/types/pm-plugins/commands/clear-formatting.d.ts +8 -0
  36. package/dist/types/pm-plugins/main.d.ts +2 -7
  37. package/dist/types/pm-plugins/ui/ToolbarBlockType/index.d.ts +1 -0
  38. package/dist/types/pm-plugins/ui/ToolbarBlockType/styled.d.ts +1 -0
  39. package/dist/types/pm-plugins/utils.d.ts +3 -0
  40. package/dist/types-ts4.5/blockTypePluginType.d.ts +1 -0
  41. package/dist/types-ts4.5/pm-plugins/block-types.d.ts +2 -0
  42. package/dist/types-ts4.5/pm-plugins/commands/block-type.d.ts +1 -0
  43. package/dist/types-ts4.5/pm-plugins/commands/clear-formatting.d.ts +8 -0
  44. package/dist/types-ts4.5/pm-plugins/main.d.ts +2 -7
  45. package/dist/types-ts4.5/pm-plugins/ui/ToolbarBlockType/index.d.ts +1 -0
  46. package/dist/types-ts4.5/pm-plugins/ui/ToolbarBlockType/styled.d.ts +1 -0
  47. package/dist/types-ts4.5/pm-plugins/utils.d.ts +3 -0
  48. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @atlaskit/editor-plugin-block-type
2
2
 
3
+ ## 4.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#96424](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/96424)
8
+ [`e14834ad65277`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/e14834ad65277) -
9
+ [ux] Add clear formatting option to text styling menu
10
+
3
11
  ## 4.0.14
4
12
 
5
13
  ### Patch Changes
@@ -191,6 +191,9 @@ var blockTypePlugin = exports.blockTypePlugin = function blockTypePlugin(_ref3)
191
191
  insertBlockQuote: function insertBlockQuote(inputMethod) {
192
192
  var _api$analytics5;
193
193
  return (0, _blockType.insertBlockQuoteWithAnalyticsCommand)(inputMethod, api === null || api === void 0 || (_api$analytics5 = api.analytics) === null || _api$analytics5 === void 0 ? void 0 : _api$analytics5.actions);
194
+ },
195
+ clearFormatting: function clearFormatting() {
196
+ return (0, _blockType.clearFormatting)();
194
197
  }
195
198
  },
196
199
  getSharedState: function getSharedState(editorState) {
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.getBlockTypesInDropdown = exports.WRAPPER_BLOCK_TYPES = exports.TEXT_BLOCK_TYPES = exports.PANEL = exports.OTHER = exports.NORMAL_TEXT = exports.HEADING_6 = exports.HEADING_5 = exports.HEADING_4 = exports.HEADING_3 = exports.HEADING_2 = exports.HEADING_1 = exports.HEADINGS_BY_NAME = exports.HEADINGS_BY_LEVEL = exports.CODE_BLOCK = exports.BLOCK_QUOTE = exports.ALL_BLOCK_TYPES = void 0;
6
+ exports.getBlockTypesInDropdown = exports.WRAPPER_BLOCK_TYPES = exports.TEXT_BLOCK_TYPES = exports.PANEL = exports.OTHER = exports.NORMAL_TEXT = exports.HEADING_6 = exports.HEADING_5 = exports.HEADING_4 = exports.HEADING_3 = exports.HEADING_2 = exports.HEADING_1 = exports.HEADINGS_BY_NAME = exports.HEADINGS_BY_LEVEL = exports.FORMATTING_NODE_TYPES = exports.FORMATTING_MARK_TYPES = exports.CODE_BLOCK = exports.BLOCK_QUOTE = exports.ALL_BLOCK_TYPES = void 0;
7
7
  var _messages = require("@atlaskit/editor-common/messages");
8
8
  var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
9
9
  var NORMAL_TEXT = exports.NORMAL_TEXT = {
@@ -76,6 +76,8 @@ var OTHER = exports.OTHER = {
76
76
  nodeName: ''
77
77
  };
78
78
  var TEXT_BLOCK_TYPES = exports.TEXT_BLOCK_TYPES = [NORMAL_TEXT, HEADING_1, HEADING_2, HEADING_3, HEADING_4, HEADING_5, HEADING_6];
79
+ var FORMATTING_NODE_TYPES = exports.FORMATTING_NODE_TYPES = ['heading', 'blockquote'];
80
+ var FORMATTING_MARK_TYPES = exports.FORMATTING_MARK_TYPES = ['em', 'code', 'strike', 'strong', 'underline', 'textColor', 'subsup', 'backgroundColor'];
79
81
  var WRAPPER_BLOCK_TYPES = exports.WRAPPER_BLOCK_TYPES = [BLOCK_QUOTE, CODE_BLOCK, PANEL];
80
82
  var ALL_BLOCK_TYPES = exports.ALL_BLOCK_TYPES = TEXT_BLOCK_TYPES.concat(WRAPPER_BLOCK_TYPES);
81
83
  var getBlockTypesInDropdown = exports.getBlockTypesInDropdown = function getBlockTypesInDropdown(includeBlockQuoteAsTextstyleOption) {
@@ -3,7 +3,9 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.insertBlockQuoteWithAnalytics = exports.cleanUpAtTheStartOfDocument = void 0;
6
+ exports.cleanUpAtTheStartOfDocument = void 0;
7
+ exports.clearFormatting = clearFormatting;
8
+ exports.insertBlockQuoteWithAnalytics = void 0;
7
9
  exports.insertBlockQuoteWithAnalyticsCommand = insertBlockQuoteWithAnalyticsCommand;
8
10
  exports.setBlockType = setBlockType;
9
11
  exports.setBlockTypeWithAnalytics = setBlockTypeWithAnalytics;
@@ -17,6 +19,7 @@ var _utils = require("@atlaskit/editor-common/utils");
17
19
  var _model = require("@atlaskit/editor-prosemirror/model");
18
20
  var _editorTables = require("@atlaskit/editor-tables");
19
21
  var _blockTypes = require("../block-types");
22
+ var _clearFormatting = require("./clear-formatting");
20
23
  var _wrapSelectionIn = require("./wrapSelectionIn");
21
24
  function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
22
25
  function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
@@ -111,9 +114,54 @@ function setNormalText(fromBlockQuote) {
111
114
  return tr;
112
115
  };
113
116
  }
114
- function withCurrentHeadingLevel(fn) {
117
+ function clearFormatting() {
115
118
  return function (_ref7) {
116
119
  var tr = _ref7.tr;
120
+ var formattingCleared = [];
121
+ var schema = tr.doc.type.schema;
122
+ _clearFormatting.FORMATTING_MARK_TYPES.forEach(function (mark) {
123
+ var _tr$selection = tr.selection,
124
+ from = _tr$selection.from,
125
+ to = _tr$selection.to;
126
+ var markType = schema.marks[mark];
127
+ if (!markType) {
128
+ return;
129
+ }
130
+ if (tr.selection instanceof _editorTables.CellSelection) {
131
+ (0, _clearFormatting.cellSelectionNodesBetween)(tr.selection, tr.doc, function (node, pos) {
132
+ var isTableCell = node.type === schema.nodes.tableCell || node.type === schema.nodes.tableHeader;
133
+ if (!isTableCell) {
134
+ return true;
135
+ }
136
+ if (tr.doc.rangeHasMark(pos, pos + node.nodeSize, markType)) {
137
+ formattingCleared.push(_clearFormatting.formatTypes[mark]);
138
+ tr.removeMark(pos, pos + node.nodeSize, markType);
139
+ }
140
+ return false;
141
+ });
142
+ } else if (tr.doc.rangeHasMark(from, to, markType)) {
143
+ formattingCleared.push(_clearFormatting.formatTypes[mark]);
144
+ tr.removeMark(from, to, markType);
145
+ }
146
+ });
147
+ _clearFormatting.FORMATTING_NODE_TYPES.forEach(function (nodeName) {
148
+ var formattedNodeType = schema.nodes[nodeName];
149
+ var _tr$selection2 = tr.selection,
150
+ $from = _tr$selection2.$from,
151
+ $to = _tr$selection2.$to;
152
+ if (tr.selection instanceof _editorTables.CellSelection) {
153
+ (0, _clearFormatting.cellSelectionNodesBetween)(tr.selection, tr.doc, (0, _clearFormatting.clearNodeFormattingOnSelection)(schema, tr, formattedNodeType, nodeName, formattingCleared));
154
+ } else {
155
+ tr.doc.nodesBetween($from.pos, $to.pos, (0, _clearFormatting.clearNodeFormattingOnSelection)(schema, tr, formattedNodeType, nodeName, formattingCleared));
156
+ }
157
+ });
158
+ tr.setStoredMarks([]);
159
+ return tr;
160
+ };
161
+ }
162
+ function withCurrentHeadingLevel(fn) {
163
+ return function (_ref8) {
164
+ var tr = _ref8.tr;
117
165
  // Find all headings and paragraphs of text
118
166
  var _tr$doc$type$schema$n = tr.doc.type.schema.nodes,
119
167
  heading = _tr$doc$type$schema$n.heading,
@@ -150,8 +198,8 @@ function withCurrentHeadingLevel(fn) {
150
198
  }
151
199
  function setNormalTextWithAnalytics(inputMethod, editorAnalyticsApi, fromBlockQuote) {
152
200
  return withCurrentHeadingLevel(function (previousHeadingLevel) {
153
- return function (_ref8) {
154
- var tr = _ref8.tr;
201
+ return function (_ref9) {
202
+ var tr = _ref9.tr;
155
203
  editorAnalyticsApi === null || editorAnalyticsApi === void 0 || editorAnalyticsApi.attachAnalyticsEvent({
156
204
  action: _analytics.ACTION.FORMATTED,
157
205
  actionSubject: _analytics.ACTION_SUBJECT.TEXT,
@@ -174,8 +222,8 @@ var setHeadingWithAnalytics = exports.setHeadingWithAnalytics = function setHead
174
222
  // eslint-disable-next-line @typescript-eslint/max-params
175
223
  ) {
176
224
  return withCurrentHeadingLevel(function (previousHeadingLevel) {
177
- return function (_ref9) {
178
- var tr = _ref9.tr;
225
+ return function (_ref10) {
226
+ var tr = _ref10.tr;
179
227
  editorAnalyticsApi === null || editorAnalyticsApi === void 0 || editorAnalyticsApi.attachAnalyticsEvent({
180
228
  action: _analytics.ACTION.FORMATTED,
181
229
  actionSubject: _analytics.ACTION_SUBJECT.TEXT,
@@ -224,8 +272,8 @@ var insertBlockQuoteWithAnalytics = exports.insertBlockQuoteWithAnalytics = func
224
272
  };
225
273
  function insertBlockQuoteWithAnalyticsCommand(inputMethod, editorAnalyticsApi) {
226
274
  return withCurrentHeadingLevel(function (previousHeadingLevel) {
227
- return function (_ref10) {
228
- var tr = _ref10.tr;
275
+ return function (_ref11) {
276
+ var tr = _ref11.tr;
229
277
  var nodes = tr.doc.type.schema.nodes;
230
278
 
231
279
  // TODO: analytics event
@@ -247,8 +295,8 @@ function insertBlockQuoteWithAnalyticsCommand(inputMethod, editorAnalyticsApi) {
247
295
  });
248
296
  }
249
297
  var cleanUpAtTheStartOfDocument = exports.cleanUpAtTheStartOfDocument = function cleanUpAtTheStartOfDocument(state, dispatch) {
250
- var _ref11 = state.selection,
251
- $cursor = _ref11.$cursor;
298
+ var _ref12 = state.selection,
299
+ $cursor = _ref12.$cursor;
252
300
  if ($cursor && !$cursor.nodeBefore && !$cursor.nodeAfter && $cursor.pos === 1) {
253
301
  var tr = state.tr,
254
302
  schema = state.schema;
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.cellSelectionNodesBetween = exports.FORMATTING_NODE_TYPES = exports.FORMATTING_MARK_TYPES = void 0;
7
+ exports.clearNodeFormattingOnSelection = clearNodeFormattingOnSelection;
8
+ exports.formatTypes = void 0;
9
+ var _analytics = require("@atlaskit/editor-common/analytics");
10
+ var _transform = require("@atlaskit/editor-prosemirror/transform");
11
+ // Functions duplicated from platform/packages/editor/editor-plugin-text-formatting/src/editor-commands/clear-formatting.ts
12
+ // TODO: Refactor to avoid duplication if platform_editor_blockquote_in_text_formatting_menu experiment is productionalised
13
+ var FORMATTING_NODE_TYPES = exports.FORMATTING_NODE_TYPES = ['heading', 'blockquote'];
14
+ var FORMATTING_MARK_TYPES = exports.FORMATTING_MARK_TYPES = ['em', 'code', 'strike', 'strong', 'underline', 'textColor', 'subsup', 'backgroundColor'];
15
+ var formatTypes = exports.formatTypes = {
16
+ em: _analytics.ACTION_SUBJECT_ID.FORMAT_ITALIC,
17
+ code: _analytics.ACTION_SUBJECT_ID.FORMAT_CODE,
18
+ strike: _analytics.ACTION_SUBJECT_ID.FORMAT_STRIKE,
19
+ strong: _analytics.ACTION_SUBJECT_ID.FORMAT_STRONG,
20
+ underline: _analytics.ACTION_SUBJECT_ID.FORMAT_UNDERLINE,
21
+ textColor: _analytics.ACTION_SUBJECT_ID.FORMAT_COLOR,
22
+ subsup: 'subsup',
23
+ backgroundColor: _analytics.ACTION_SUBJECT_ID.FORMAT_BACKGROUND_COLOR
24
+ };
25
+ var cellSelectionNodesBetween = exports.cellSelectionNodesBetween = function cellSelectionNodesBetween(selection, doc, f, startPos
26
+ // eslint-disable-next-line @typescript-eslint/max-params
27
+ ) {
28
+ selection.forEachCell(function (cell, cellPos) {
29
+ doc.nodesBetween(cellPos, cellPos + cell.nodeSize, f, startPos);
30
+ });
31
+ };
32
+
33
+ // eslint-disable-next-line @typescript-eslint/max-params
34
+ function clearNodeFormattingOnSelection(schema, tr, formattedNodeType, nodeName, formattingCleared) {
35
+ return function (node, pos) {
36
+ if (node.type === formattedNodeType) {
37
+ if (formattedNodeType.isTextblock) {
38
+ tr.setNodeMarkup(pos, schema.nodes.paragraph);
39
+ formattingCleared.push(nodeName);
40
+ return false;
41
+ } else {
42
+ // In case of panel or blockquote
43
+ var fromPos = tr.doc.resolve(pos + 1);
44
+ var toPos = tr.doc.resolve(pos + node.nodeSize - 1);
45
+ var nodeRange = fromPos.blockRange(toPos);
46
+ if (nodeRange) {
47
+ var targetLiftDepth = (0, _transform.liftTarget)(nodeRange);
48
+ if (targetLiftDepth || targetLiftDepth === 0) {
49
+ formattingCleared.push(nodeName);
50
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
51
+ tr.lift(nodeRange, targetLiftDepth);
52
+ }
53
+ }
54
+ }
55
+ }
56
+ return true;
57
+ };
58
+ }
@@ -111,12 +111,14 @@ var createPlugin = exports.createPlugin = function createPlugin(editorAPI, dispa
111
111
  var availableBlockTypesInDropdown = BLOCK_TYPES_IN_DROPDOWN.filter(function (blockType) {
112
112
  return isBlockTypeSchemaSupported(blockType, state);
113
113
  });
114
+ var formattingIsPresent = (0, _utils.hasBlockQuoteInOptions)(availableBlockTypesInDropdown) ? (0, _utils.checkFormattingIsPresent)(state) : undefined;
114
115
  return {
115
116
  currentBlockType: detectBlockType(availableBlockTypesInDropdown, state),
116
117
  blockTypesDisabled: (0, _utils.areBlockTypesDisabled)(state),
117
118
  availableBlockTypes: availableBlockTypes,
118
119
  availableWrapperBlockTypes: availableWrapperBlockTypes,
119
- availableBlockTypesInDropdown: availableBlockTypesInDropdown
120
+ availableBlockTypesInDropdown: availableBlockTypesInDropdown,
121
+ formattingIsPresent: formattingIsPresent
120
122
  };
121
123
  },
122
124
  // Ignored via go/ees005
@@ -124,9 +126,10 @@ var createPlugin = exports.createPlugin = function createPlugin(editorAPI, dispa
124
126
  apply: function apply(_tr, oldPluginState, _oldState, newState) {
125
127
  var newPluginState = _objectSpread(_objectSpread({}, oldPluginState), {}, {
126
128
  currentBlockType: detectBlockType(oldPluginState.availableBlockTypesInDropdown, newState),
127
- blockTypesDisabled: (0, _utils.areBlockTypesDisabled)(newState)
129
+ blockTypesDisabled: (0, _utils.areBlockTypesDisabled)(newState),
130
+ formattingIsPresent: (0, _utils.hasBlockQuoteInOptions)(oldPluginState.availableBlockTypesInDropdown) ? (0, _utils.checkFormattingIsPresent)(newState) : undefined
128
131
  });
129
- if (newPluginState.currentBlockType !== oldPluginState.currentBlockType || newPluginState.blockTypesDisabled !== oldPluginState.blockTypesDisabled) {
132
+ if (newPluginState.currentBlockType !== oldPluginState.currentBlockType || newPluginState.blockTypesDisabled !== oldPluginState.blockTypesDisabled || newPluginState.formattingIsPresent !== oldPluginState.formattingIsPresent) {
130
133
  dispatch(pluginKey, newPluginState);
131
134
  }
132
135
  return newPluginState;
@@ -30,6 +30,10 @@ function FloatingToolbarComponent(_ref) {
30
30
  var _api$core2, _api$blockType2;
31
31
  return api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 ? void 0 : _api$core2.actions.execute(api === null || api === void 0 || (_api$blockType2 = api.blockType) === null || _api$blockType2 === void 0 || (_api$blockType2 = _api$blockType2.commands) === null || _api$blockType2 === void 0 ? void 0 : _api$blockType2.insertBlockQuote(_analytics.INPUT_METHOD.TOOLBAR));
32
32
  }, [api]);
33
+ var clearFormatting = (0, _react.useCallback)(function () {
34
+ var _api$core3, _api$blockType3;
35
+ return api === null || api === void 0 || (_api$core3 = api.core) === null || _api$core3 === void 0 ? void 0 : _api$core3.actions.execute(api === null || api === void 0 || (_api$blockType3 = api.blockType) === null || _api$blockType3 === void 0 || (_api$blockType3 = _api$blockType3.commands) === null || _api$blockType3 === void 0 ? void 0 : _api$blockType3.clearFormatting());
36
+ }, [api]);
33
37
  return /*#__PURE__*/_react.default.createElement(_ToolbarBlockType.default, {
34
38
  isSmall: FloatingToolbarSettings.isSmall,
35
39
  isDisabled: FloatingToolbarSettings.disabled,
@@ -40,6 +44,7 @@ function FloatingToolbarComponent(_ref) {
40
44
  ,
41
45
  pluginState: blockTypeState,
42
46
  wrapBlockQuote: wrapBlockQuote,
47
+ clearFormatting: clearFormatting,
43
48
  shouldUseDefaultRole: FloatingToolbarSettings.shouldUseDefaultRole,
44
49
  api: api
45
50
  });
@@ -28,12 +28,17 @@ function PrimaryToolbarComponent(_ref) {
28
28
  var _api$core2, _api$blockType2;
29
29
  return api === null || api === void 0 || (_api$core2 = api.core) === null || _api$core2 === void 0 ? void 0 : _api$core2.actions.execute(api === null || api === void 0 || (_api$blockType2 = api.blockType) === null || _api$blockType2 === void 0 || (_api$blockType2 = _api$blockType2.commands) === null || _api$blockType2 === void 0 ? void 0 : _api$blockType2.insertBlockQuote(_analytics.INPUT_METHOD.TOOLBAR));
30
30
  };
31
+ var clearFormatting = function clearFormatting() {
32
+ var _api$core3, _api$blockType3;
33
+ return api === null || api === void 0 || (_api$core3 = api.core) === null || _api$core3 === void 0 ? void 0 : _api$core3.actions.execute(api === null || api === void 0 || (_api$blockType3 = api.blockType) === null || _api$blockType3 === void 0 || (_api$blockType3 = _api$blockType3.commands) === null || _api$blockType3 === void 0 ? void 0 : _api$blockType3.clearFormatting());
34
+ };
31
35
  return /*#__PURE__*/_react.default.createElement(_ToolbarBlockType.default, {
32
36
  isSmall: isSmall,
33
37
  isDisabled: disabled,
34
38
  isReducedSpacing: isToolbarReducedSpacing,
35
39
  setTextLevel: boundSetBlockType,
36
- wrapBlockQuote: wrapBlockQuote
40
+ wrapBlockQuote: wrapBlockQuote,
41
+ clearFormatting: clearFormatting
37
42
  // Ignored via go/ees005
38
43
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
39
44
  ,
@@ -15,10 +15,13 @@ var _react = _interopRequireDefault(require("react"));
15
15
  var _react2 = require("@emotion/react");
16
16
  var _reactIntlNext = require("react-intl-next");
17
17
  var _keymaps = require("@atlaskit/editor-common/keymaps");
18
+ var _messages = require("@atlaskit/editor-common/messages");
18
19
  var _styles = require("@atlaskit/editor-common/styles");
19
20
  var _uiMenu = require("@atlaskit/editor-common/ui-menu");
20
21
  var _editorSharedStyles = require("@atlaskit/editor-shared-styles");
22
+ var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
21
23
  var _tokens = require("@atlaskit/tokens");
24
+ var _blockTypes = require("../../block-types");
22
25
  var _blocktypeButton = require("./blocktype-button");
23
26
  var _styled = require("./styled");
24
27
  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; }
@@ -69,22 +72,21 @@ var ToolbarBlockType = /*#__PURE__*/function (_React$PureComponent) {
69
72
  var formatMessage = _this.props.intl.formatMessage;
70
73
  var _this$props$pluginSta = _this.props.pluginState,
71
74
  currentBlockType = _this$props$pluginSta.currentBlockType,
72
- availableBlockTypesInDropdown = _this$props$pluginSta.availableBlockTypesInDropdown;
75
+ availableBlockTypesInDropdown = _this$props$pluginSta.availableBlockTypesInDropdown,
76
+ formattingIsPresent = _this$props$pluginSta.formattingIsPresent;
73
77
  var items = availableBlockTypesInDropdown.map(function (blockType, index) {
74
78
  var isActive = currentBlockType === blockType;
75
79
  var tagName = blockType.tagName || 'p';
76
80
  var Tag = tagName;
77
81
  var keyMap = (0, _keymaps.findKeymapByDescription)(blockType.title.defaultMessage);
78
- return {
82
+ var item = {
79
83
  content:
80
84
  // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
81
85
  (0, _react2.jsx)("div", {
82
86
  css: (0, _styled.blockTypeMenuItemStyle)(tagName, isActive, _this.state.typographyTheme)
83
87
  }, (0, _react2.jsx)(Tag, null, formatMessage(blockType.title))),
84
88
  value: blockType,
85
- label: formatMessage(blockType.title),
86
89
  'aria-label': (0, _keymaps.tooltip)(keyMap, formatMessage(blockType.title)),
87
- keyShortcuts: (0, _keymaps.getAriaKeyshortcuts)(keyMap),
88
90
  key: "".concat(blockType.name, "-").concat(index),
89
91
  elemAfter:
90
92
  // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
@@ -93,7 +95,32 @@ var ToolbarBlockType = /*#__PURE__*/function (_React$PureComponent) {
93
95
  }, (0, _keymaps.tooltip)(keyMap)),
94
96
  isActive: isActive
95
97
  };
98
+ return item;
96
99
  });
100
+ if (availableBlockTypesInDropdown.map(function (blockType) {
101
+ return blockType.name;
102
+ }).includes('blockquote')) {
103
+ var clearFormattingItem = {
104
+ content: (0, _react2.jsx)("div", null, (0, _react2.jsx)("p", null, _messages.toolbarMessages.clearFormatting.defaultMessage)),
105
+ value: {
106
+ name: 'clearFormatting'
107
+ },
108
+ 'aria-label': (0, _keymaps.tooltip)(_keymaps.clearFormatting, _messages.toolbarMessages.clearFormatting.defaultMessage),
109
+ key: 'clear-formatting',
110
+ elemAfter:
111
+ // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
112
+ (0, _react2.jsx)("div", {
113
+ css: [_styled.keyboardShortcut]
114
+ }, (0, _keymaps.tooltip)(_keymaps.clearFormatting)),
115
+ isActive: false,
116
+ isDisabled: currentBlockType === _blockTypes.NORMAL_TEXT && !formattingIsPresent
117
+ };
118
+ return [{
119
+ items: items
120
+ }, {
121
+ items: [clearFormattingItem]
122
+ }];
123
+ }
97
124
  return [{
98
125
  items: items
99
126
  }];
@@ -106,8 +133,12 @@ var ToolbarBlockType = /*#__PURE__*/function (_React$PureComponent) {
106
133
  if (blockType.name === 'blockquote') {
107
134
  _this.props.wrapBlockQuote(blockType.name);
108
135
  } else {
109
- var fromBlockQuote = _this.props.pluginState.currentBlockType.name === 'blockquote';
110
- _this.props.setTextLevel(blockType.name, fromBlockQuote);
136
+ if (blockType.name === 'clearFormatting') {
137
+ _this.props.clearFormatting();
138
+ } else {
139
+ var fromBlockQuote = _this.props.pluginState.currentBlockType.name === 'blockquote';
140
+ _this.props.setTextLevel(blockType.name, fromBlockQuote);
141
+ }
111
142
  }
112
143
  if (shouldCloseMenu) {
113
144
  _this.setState(_objectSpread(_objectSpread({}, _this.state), {}, {
@@ -175,47 +206,53 @@ var ToolbarBlockType = /*#__PURE__*/function (_React$PureComponent) {
175
206
  });
176
207
  if (!this.props.isDisabled && !blockTypesDisabled) {
177
208
  var items = this.createItems();
178
- return (
209
+ return (0, _react2.jsx)("span", {
210
+ css: (0, _experiments.editorExperiment)('platform_editor_blockquote_in_text_formatting_menu', true) ?
211
+ // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
212
+ [_styles.wrapperStyle, _styled.floatingToolbarWrapperStyle] :
179
213
  // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
180
- (0, _react2.jsx)("span", {
181
- css: _styles.wrapperStyle
182
- }, (0, _react2.jsx)(_uiMenu.DropdownMenuWithKeyboardNavigation, {
183
- items: items,
184
- onOpenChange: this.onOpenChange,
185
- onItemActivated: this.handleSelectBlockType,
186
- isOpen: active,
187
- mountTo: popupsMountPoint,
188
- boundariesElement: popupsBoundariesElement,
189
- scrollableElement: popupsScrollableElement,
190
- zIndex: _editorSharedStyles.akEditorMenuZIndex,
191
- fitHeight: 360,
192
- fitWidth: 106,
193
- shouldUseDefaultRole: shouldUseDefaultRole,
194
- shouldFocusFirstItem: function shouldFocusFirstItem() {
195
- if (isOpenedByKeyboard) {
196
- // eslint-disable-next-line @repo/internal/react/no-set-state-inside-render
197
- _this3.setState(_objectSpread(_objectSpread({}, _this3.state), {}, {
198
- isOpenedByKeyboard: false
199
- }));
200
- }
201
- return isOpenedByKeyboard;
214
+ _styles.wrapperStyle
215
+ }, (0, _react2.jsx)(_uiMenu.DropdownMenuWithKeyboardNavigation, {
216
+ items: items,
217
+ onOpenChange: this.onOpenChange,
218
+ onItemActivated: this.handleSelectBlockType,
219
+ isOpen: active,
220
+ mountTo: popupsMountPoint,
221
+ boundariesElement: popupsBoundariesElement,
222
+ scrollableElement: popupsScrollableElement,
223
+ zIndex: _editorSharedStyles.akEditorMenuZIndex,
224
+ fitHeight: 360,
225
+ fitWidth: 106,
226
+ section: {
227
+ hasSeparator: true
228
+ },
229
+ shouldUseDefaultRole: shouldUseDefaultRole
230
+ // hasSeparator={true}
231
+ ,
232
+ shouldFocusFirstItem: function shouldFocusFirstItem() {
233
+ if (isOpenedByKeyboard) {
234
+ // eslint-disable-next-line @repo/internal/react/no-set-state-inside-render
235
+ _this3.setState(_objectSpread(_objectSpread({}, _this3.state), {}, {
236
+ isOpenedByKeyboard: false
237
+ }));
202
238
  }
203
- }, (0, _react2.jsx)(_blocktypeButton.BlockTypeButton, {
204
- isSmall: isSmall,
205
- isReducedSpacing: isReducedSpacing,
206
- selected: active,
207
- disabled: false,
208
- title: blockTypeTitles[0],
209
- onClick: this.handleTriggerClick,
210
- onKeyDown: this.handleTriggerByKeyboard,
211
- formatMessage: formatMessage,
212
- "aria-expanded": active,
213
- blockTypeName: currentBlockType.name
214
- })), !(api !== null && api !== void 0 && api.primaryToolbar) && (0, _react2.jsx)("span", {
215
- // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
216
- css: _styles.separatorStyles
217
- }))
218
- );
239
+ return isOpenedByKeyboard;
240
+ }
241
+ }, (0, _react2.jsx)(_blocktypeButton.BlockTypeButton, {
242
+ isSmall: isSmall,
243
+ isReducedSpacing: isReducedSpacing,
244
+ selected: active,
245
+ disabled: false,
246
+ title: blockTypeTitles[0],
247
+ onClick: this.handleTriggerClick,
248
+ onKeyDown: this.handleTriggerByKeyboard,
249
+ formatMessage: formatMessage,
250
+ "aria-expanded": active,
251
+ blockTypeName: currentBlockType.name
252
+ })), !(api !== null && api !== void 0 && api.primaryToolbar) && (0, _react2.jsx)("span", {
253
+ // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
254
+ css: _styles.separatorStyles
255
+ }));
219
256
  }
220
257
  return (
221
258
  // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage, @atlaskit/ui-styling-standard/no-imported-style-values -- Ignored via go/DSP-18766
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.wrapperSmallStyle = exports.keyboardShortcutSelect = exports.keyboardShortcut = exports.expandIconWrapperStyle = exports.blockTypeMenuItemStyle = void 0;
6
+ exports.wrapperSmallStyle = exports.keyboardShortcutSelect = exports.keyboardShortcut = exports.floatingToolbarWrapperStyle = exports.expandIconWrapperStyle = exports.blockTypeMenuItemStyle = void 0;
7
7
  var _react = require("@emotion/react");
8
8
  var _styles = require("@atlaskit/editor-common/styles");
9
9
  var _shortcut = require("@atlaskit/editor-shared-styles/shortcut");
@@ -26,6 +26,12 @@ var blockTypeMenuItemStyle = exports.blockTypeMenuItemStyle = function blockType
26
26
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
27
27
  'h1, h2, h3, h4, h5, h6': {
28
28
  marginTop: 0
29
+ },
30
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors -- Ignored via go/DSP-18766
31
+ blockquote: {
32
+ paddingTop: 0,
33
+ paddingBottom: 0,
34
+ marginTop: 0
29
35
  }
30
36
  }
31
37
  },
@@ -54,4 +60,12 @@ var wrapperSmallStyle = exports.wrapperSmallStyle = (0, _react.css)({
54
60
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-exported-styles -- Ignored via go/DSP-18766
55
61
  var expandIconWrapperStyle = exports.expandIconWrapperStyle = (0, _react.css)({
56
62
  marginLeft: "var(--ds-space-negative-100, -8px)"
63
+ });
64
+
65
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-exported-styles
66
+ var floatingToolbarWrapperStyle = exports.floatingToolbarWrapperStyle = (0, _react.css)({
67
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-nested-selectors
68
+ "[data-role='droplistContent']": {
69
+ maxHeight: '90vh'
70
+ }
57
71
  });
@@ -4,7 +4,8 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.areBlockTypesDisabled = areBlockTypesDisabled;
7
- exports.isNodeAWrappingBlockNode = exports.createWrappingTextBlockRule = exports.createJoinNodesRule = void 0;
7
+ exports.isNodeAWrappingBlockNode = exports.hasBlockQuoteInOptions = exports.createWrappingTextBlockRule = exports.createJoinNodesRule = exports.checkFormattingIsPresent = void 0;
8
+ var _mark = require("@atlaskit/editor-common/mark");
8
9
  var _utils = require("@atlaskit/editor-common/utils");
9
10
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
10
11
  var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
@@ -117,4 +118,42 @@ function areBlockTypesDisabled(state) {
117
118
  return nodesTypes.filter(function (type) {
118
119
  return type !== panel;
119
120
  }).length > 0;
120
- }
121
+ }
122
+ var blockStylingIsPresent = function blockStylingIsPresent(state) {
123
+ var _state$selection3 = state.selection,
124
+ from = _state$selection3.from,
125
+ to = _state$selection3.to;
126
+ var isBlockStyling = false;
127
+ state.doc.nodesBetween(from, to, function (node) {
128
+ if (_blockTypes.FORMATTING_NODE_TYPES.indexOf(node.type.name) !== -1) {
129
+ isBlockStyling = true;
130
+ return false;
131
+ }
132
+ return true;
133
+ });
134
+ return isBlockStyling;
135
+ };
136
+ var marksArePresent = function marksArePresent(state) {
137
+ var activeMarkTypes = _blockTypes.FORMATTING_MARK_TYPES.filter(function (mark) {
138
+ if (!!state.schema.marks[mark]) {
139
+ var _state$selection4 = state.selection,
140
+ $from = _state$selection4.$from,
141
+ empty = _state$selection4.empty;
142
+ var marks = state.schema.marks;
143
+ if (empty) {
144
+ return !!marks[mark].isInSet(state.storedMarks || $from.marks());
145
+ }
146
+ return (0, _mark.anyMarkActive)(state, marks[mark]);
147
+ }
148
+ return false;
149
+ });
150
+ return activeMarkTypes.length > 0;
151
+ };
152
+ var checkFormattingIsPresent = exports.checkFormattingIsPresent = function checkFormattingIsPresent(state) {
153
+ return marksArePresent(state) || blockStylingIsPresent(state);
154
+ };
155
+ var hasBlockQuoteInOptions = exports.hasBlockQuoteInOptions = function hasBlockQuoteInOptions(dropdownOptions) {
156
+ return !!dropdownOptions.find(function (blockType) {
157
+ return blockType.name === 'blockquote';
158
+ });
159
+ };
@@ -7,7 +7,7 @@ import { IconHeading, IconQuote } from '@atlaskit/editor-common/quick-insert';
7
7
  import { ToolbarSize } from '@atlaskit/editor-common/types';
8
8
  import { fg } from '@atlaskit/platform-feature-flags';
9
9
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
10
- import { setBlockTypeWithAnalytics, insertBlockQuoteWithAnalytics, insertBlockQuoteWithAnalyticsCommand } from './pm-plugins/commands/block-type';
10
+ import { setBlockTypeWithAnalytics, insertBlockQuoteWithAnalytics, insertBlockQuoteWithAnalyticsCommand, clearFormatting } from './pm-plugins/commands/block-type';
11
11
  import inputRulePlugin from './pm-plugins/input-rule';
12
12
  import keymapPlugin from './pm-plugins/keymap';
13
13
  import { createPlugin, pluginKey } from './pm-plugins/main';
@@ -181,6 +181,9 @@ const blockTypePlugin = ({
181
181
  insertBlockQuote(inputMethod) {
182
182
  var _api$analytics5;
183
183
  return insertBlockQuoteWithAnalyticsCommand(inputMethod, api === null || api === void 0 ? void 0 : (_api$analytics5 = api.analytics) === null || _api$analytics5 === void 0 ? void 0 : _api$analytics5.actions);
184
+ },
185
+ clearFormatting() {
186
+ return clearFormatting();
184
187
  }
185
188
  },
186
189
  getSharedState(editorState) {
@@ -70,6 +70,8 @@ export const OTHER = {
70
70
  nodeName: ''
71
71
  };
72
72
  export const TEXT_BLOCK_TYPES = [NORMAL_TEXT, HEADING_1, HEADING_2, HEADING_3, HEADING_4, HEADING_5, HEADING_6];
73
+ export const FORMATTING_NODE_TYPES = ['heading', 'blockquote'];
74
+ export const FORMATTING_MARK_TYPES = ['em', 'code', 'strike', 'strong', 'underline', 'textColor', 'subsup', 'backgroundColor'];
73
75
  export const WRAPPER_BLOCK_TYPES = [BLOCK_QUOTE, CODE_BLOCK, PANEL];
74
76
  export const ALL_BLOCK_TYPES = TEXT_BLOCK_TYPES.concat(WRAPPER_BLOCK_TYPES);
75
77
  export const getBlockTypesInDropdown = includeBlockQuoteAsTextstyleOption => {