@atlaskit/editor-plugin-block-controls 2.3.0 → 2.4.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # @atlaskit/editor-plugin-block-controls
2
2
 
3
+ ## 2.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#151190](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/151190)
8
+ [`a3723b1cdede2`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/a3723b1cdede2) -
9
+ [ux] [ED-25037] this change bumps @atlaskit/adf-schema from 40.9.0 to 40.9.4 which makes the
10
+ blockquote selectable, adds missing marks to the PM node spec and fixes a bug that converted
11
+ pasted external images to media groups.
12
+
13
+ ### Patch Changes
14
+
15
+ - [#151190](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/151190)
16
+ [`a3723b1cdede2`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/a3723b1cdede2) -
17
+ [ux] [ED-25037] This change selects the blockquote node when the blockquote contains media, but
18
+ otherwise it will select all the inline content inside the blockquote (previous functionality)
19
+ when using the drag handle to select.
20
+ - [`28f31fcff6ff2`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/28f31fcff6ff2) -
21
+ Fix classList check
22
+ - Updated dependencies
23
+
24
+ ## 2.3.1
25
+
26
+ ### Patch Changes
27
+
28
+ - [#149764](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/149764)
29
+ [`f6226757e21b9`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/f6226757e21b9) -
30
+ Change move left/right shortcut for nested nodes
31
+
3
32
  ## 2.3.0
4
33
 
5
34
  ### Minor Changes
@@ -105,7 +105,9 @@ var moveNodeViaShortcut = exports.moveNodeViaShortcut = function moveNodeViaShor
105
105
  moveToPos = $pos.after($pos.depth) + 1;
106
106
  } else if (direction === _consts.DIRECTION.UP) {
107
107
  var nodeBefore = $pos.depth > 1 && nodeIndex === 0 && (0, _platformFeatureFlags.fg)('platform_editor_element_dnd_nested_a11y') ? $pos.node($pos.depth) : $pos.nodeBefore;
108
- moveToPos = $pos.depth > 1 && nodeIndex === 0 && (0, _platformFeatureFlags.fg)('platform_editor_element_dnd_nested_a11y') ? $pos.before($pos.depth) - 1 : nodeBefore ? currentNodePos - nodeBefore.nodeSize : moveToPos;
108
+ if (nodeBefore) {
109
+ moveToPos = currentNodePos - nodeBefore.nodeSize;
110
+ }
109
111
  } else {
110
112
  var endOfDoc = $pos.end();
111
113
  var nodeAfterPos = $pos.posAtIndex($pos.index() + 1);
@@ -19,7 +19,7 @@ var isDocFirstChildEmptyLine = function isDocFirstChildEmptyLine(elem) {
19
19
  return (parentElement === null || parentElement === void 0 ? void 0 : parentElement.classList.contains('ProseMirror')) && (parentElement === null || parentElement === void 0 ? void 0 : parentElement.firstElementChild) === elem && ['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6'].includes(elem.nodeName) && elem.childNodes.length === 1 && ((_elem$firstElementChi = elem.firstElementChild) === null || _elem$firstElementChi === void 0 ? void 0 : _elem$firstElementChi.classList.contains('ProseMirror-trailingBreak'));
20
20
  };
21
21
  var handleMouseOver = exports.handleMouseOver = function handleMouseOver(view, event, api) {
22
- var _api$blockControls;
22
+ var _api$blockControls, _target$classList;
23
23
  var _ref = (api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.sharedState.currentState()) || {},
24
24
  isDragging = _ref.isDragging,
25
25
  activeNode = _ref.activeNode;
@@ -30,7 +30,7 @@ var handleMouseOver = exports.handleMouseOver = function handleMouseOver(view, e
30
30
  return false;
31
31
  }
32
32
  var target = event.target;
33
- if (target.classList.contains('ProseMirror')) {
33
+ if (target !== null && target !== void 0 && (_target$classList = target.classList) !== null && _target$classList !== void 0 && _target$classList.contains('ProseMirror')) {
34
34
  return false;
35
35
  }
36
36
  var rootElement = target === null || target === void 0 ? void 0 : target.closest('[data-drag-handler-anchor-name]');
@@ -15,10 +15,10 @@ var getNestedNodePosition = exports.getNestedNodePosition = function getNestedNo
15
15
  if ($pos.depth < 1) {
16
16
  return nestedNodePos;
17
17
  }
18
- var parentNodeOfSpecificTypes = (0, _utils.findParentNodeOfType)([state.schema.nodes.bulletList, state.schema.nodes.orderedList, state.schema.nodes.blockquote, state.schema.nodes.taskList])(state.selection);
18
+ var parentNodeOfSpecificTypes = (0, _utils.findParentNodeOfType)([state.schema.nodes.bulletList, state.schema.nodes.orderedList, state.schema.nodes.blockquote, state.schema.nodes.taskList, state.schema.nodes.decisionList])(state.selection);
19
19
  if (parentNodeOfSpecificTypes) {
20
20
  var parentNodeType = parentNodeOfSpecificTypes.node.type.name;
21
- nestedNodePos = ['bulletList', 'orderedList'].includes(parentNodeType) ? $pos.before($pos.depth - 1) : ['blockquote', 'taskList'].includes(parentNodeType) ? $pos.before() : nestedNodePos;
21
+ nestedNodePos = ['bulletList', 'orderedList'].includes(parentNodeType) ? $pos.before($pos.depth - 1) : ['blockquote', 'taskList', 'decisionList'].includes(parentNodeType) ? $pos.before() : nestedNodePos;
22
22
  }
23
23
  } else {
24
24
  nestedNodePos = selection.$from.pos;
@@ -29,15 +29,26 @@ var getInlineNodePos = exports.getInlineNodePos = function getInlineNodePos(tr,
29
29
  inlineNodeEndPos: inlineNodeEndPos
30
30
  };
31
31
  };
32
+ var isNodeWithMedia = function isNodeWithMedia(tr, start, nodeSize) {
33
+ var $startPos = tr.doc.resolve(start);
34
+ var hasMedia = false;
35
+ tr.doc.nodesBetween($startPos.pos, $startPos.pos + nodeSize, function (n) {
36
+ if (n.type.name === 'media') {
37
+ hasMedia = true;
38
+ }
39
+ });
40
+ return hasMedia;
41
+ };
32
42
  var getSelection = exports.getSelection = function getSelection(tr, start) {
33
43
  var node = tr.doc.nodeAt(start);
34
44
  var isNodeSelection = node && _state.NodeSelection.isSelectable(node);
35
45
  var nodeSize = node ? node.nodeSize : 1;
36
46
  var $startPos = tr.doc.resolve(start);
37
47
  var nodeName = node === null || node === void 0 ? void 0 : node.type.name;
48
+ var isBlockQuoteWithMedia = nodeName === 'blockquote' && isNodeWithMedia(tr, start, nodeSize);
38
49
 
39
50
  // decisionList node is not selectable, but we want to select the whole node not just text
40
- if (isNodeSelection || nodeName === 'decisionList') {
51
+ if (isNodeSelection && nodeName !== 'blockquote' || isBlockQuoteWithMedia || nodeName === 'decisionList') {
41
52
  return new _state.NodeSelection($startPos);
42
53
  } else if (nodeName === 'mediaGroup' && (node === null || node === void 0 ? void 0 : node.childCount) === 1) {
43
54
  var $mediaStartPos = tr.doc.resolve(start + 1);
@@ -100,7 +100,9 @@ export const moveNodeViaShortcut = (api, direction, formatMessage) => {
100
100
  moveToPos = $pos.after($pos.depth) + 1;
101
101
  } else if (direction === DIRECTION.UP) {
102
102
  const nodeBefore = $pos.depth > 1 && nodeIndex === 0 && fg('platform_editor_element_dnd_nested_a11y') ? $pos.node($pos.depth) : $pos.nodeBefore;
103
- moveToPos = $pos.depth > 1 && nodeIndex === 0 && fg('platform_editor_element_dnd_nested_a11y') ? $pos.before($pos.depth) - 1 : nodeBefore ? currentNodePos - nodeBefore.nodeSize : moveToPos;
103
+ if (nodeBefore) {
104
+ moveToPos = currentNodePos - nodeBefore.nodeSize;
105
+ }
104
106
  } else {
105
107
  const endOfDoc = $pos.end();
106
108
  const nodeAfterPos = $pos.posAtIndex($pos.index() + 1);
@@ -13,7 +13,7 @@ const isDocFirstChildEmptyLine = elem => {
13
13
  return (parentElement === null || parentElement === void 0 ? void 0 : parentElement.classList.contains('ProseMirror')) && (parentElement === null || parentElement === void 0 ? void 0 : parentElement.firstElementChild) === elem && ['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6'].includes(elem.nodeName) && elem.childNodes.length === 1 && ((_elem$firstElementChi = elem.firstElementChild) === null || _elem$firstElementChi === void 0 ? void 0 : _elem$firstElementChi.classList.contains('ProseMirror-trailingBreak'));
14
14
  };
15
15
  export const handleMouseOver = (view, event, api) => {
16
- var _api$blockControls;
16
+ var _api$blockControls, _target$classList;
17
17
  const {
18
18
  isDragging,
19
19
  activeNode
@@ -25,7 +25,7 @@ export const handleMouseOver = (view, event, api) => {
25
25
  return false;
26
26
  }
27
27
  const target = event.target;
28
- if (target.classList.contains('ProseMirror')) {
28
+ if (target !== null && target !== void 0 && (_target$classList = target.classList) !== null && _target$classList !== void 0 && _target$classList.contains('ProseMirror')) {
29
29
  return false;
30
30
  }
31
31
  let rootElement = target === null || target === void 0 ? void 0 : target.closest('[data-drag-handler-anchor-name]');
@@ -11,10 +11,10 @@ export const getNestedNodePosition = state => {
11
11
  if ($pos.depth < 1) {
12
12
  return nestedNodePos;
13
13
  }
14
- const parentNodeOfSpecificTypes = findParentNodeOfType([state.schema.nodes.bulletList, state.schema.nodes.orderedList, state.schema.nodes.blockquote, state.schema.nodes.taskList])(state.selection);
14
+ const parentNodeOfSpecificTypes = findParentNodeOfType([state.schema.nodes.bulletList, state.schema.nodes.orderedList, state.schema.nodes.blockquote, state.schema.nodes.taskList, state.schema.nodes.decisionList])(state.selection);
15
15
  if (parentNodeOfSpecificTypes) {
16
16
  const parentNodeType = parentNodeOfSpecificTypes.node.type.name;
17
- nestedNodePos = ['bulletList', 'orderedList'].includes(parentNodeType) ? $pos.before($pos.depth - 1) : ['blockquote', 'taskList'].includes(parentNodeType) ? $pos.before() : nestedNodePos;
17
+ nestedNodePos = ['bulletList', 'orderedList'].includes(parentNodeType) ? $pos.before($pos.depth - 1) : ['blockquote', 'taskList', 'decisionList'].includes(parentNodeType) ? $pos.before() : nestedNodePos;
18
18
  }
19
19
  } else {
20
20
  nestedNodePos = selection.$from.pos;
@@ -23,15 +23,26 @@ export const getInlineNodePos = (tr, start, nodeSize) => {
23
23
  inlineNodeEndPos
24
24
  };
25
25
  };
26
+ const isNodeWithMedia = (tr, start, nodeSize) => {
27
+ const $startPos = tr.doc.resolve(start);
28
+ let hasMedia = false;
29
+ tr.doc.nodesBetween($startPos.pos, $startPos.pos + nodeSize, n => {
30
+ if (n.type.name === 'media') {
31
+ hasMedia = true;
32
+ }
33
+ });
34
+ return hasMedia;
35
+ };
26
36
  export const getSelection = (tr, start) => {
27
37
  const node = tr.doc.nodeAt(start);
28
38
  const isNodeSelection = node && NodeSelection.isSelectable(node);
29
39
  const nodeSize = node ? node.nodeSize : 1;
30
40
  const $startPos = tr.doc.resolve(start);
31
41
  const nodeName = node === null || node === void 0 ? void 0 : node.type.name;
42
+ const isBlockQuoteWithMedia = nodeName === 'blockquote' && isNodeWithMedia(tr, start, nodeSize);
32
43
 
33
44
  // decisionList node is not selectable, but we want to select the whole node not just text
34
- if (isNodeSelection || nodeName === 'decisionList') {
45
+ if (isNodeSelection && nodeName !== 'blockquote' || isBlockQuoteWithMedia || nodeName === 'decisionList') {
35
46
  return new NodeSelection($startPos);
36
47
  } else if (nodeName === 'mediaGroup' && (node === null || node === void 0 ? void 0 : node.childCount) === 1) {
37
48
  const $mediaStartPos = tr.doc.resolve(start + 1);
@@ -99,7 +99,9 @@ export var moveNodeViaShortcut = function moveNodeViaShortcut(api, direction, fo
99
99
  moveToPos = $pos.after($pos.depth) + 1;
100
100
  } else if (direction === DIRECTION.UP) {
101
101
  var nodeBefore = $pos.depth > 1 && nodeIndex === 0 && fg('platform_editor_element_dnd_nested_a11y') ? $pos.node($pos.depth) : $pos.nodeBefore;
102
- moveToPos = $pos.depth > 1 && nodeIndex === 0 && fg('platform_editor_element_dnd_nested_a11y') ? $pos.before($pos.depth) - 1 : nodeBefore ? currentNodePos - nodeBefore.nodeSize : moveToPos;
102
+ if (nodeBefore) {
103
+ moveToPos = currentNodePos - nodeBefore.nodeSize;
104
+ }
103
105
  } else {
104
106
  var endOfDoc = $pos.end();
105
107
  var nodeAfterPos = $pos.posAtIndex($pos.index() + 1);
@@ -13,7 +13,7 @@ var isDocFirstChildEmptyLine = function isDocFirstChildEmptyLine(elem) {
13
13
  return (parentElement === null || parentElement === void 0 ? void 0 : parentElement.classList.contains('ProseMirror')) && (parentElement === null || parentElement === void 0 ? void 0 : parentElement.firstElementChild) === elem && ['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6'].includes(elem.nodeName) && elem.childNodes.length === 1 && ((_elem$firstElementChi = elem.firstElementChild) === null || _elem$firstElementChi === void 0 ? void 0 : _elem$firstElementChi.classList.contains('ProseMirror-trailingBreak'));
14
14
  };
15
15
  export var handleMouseOver = function handleMouseOver(view, event, api) {
16
- var _api$blockControls;
16
+ var _api$blockControls, _target$classList;
17
17
  var _ref = (api === null || api === void 0 || (_api$blockControls = api.blockControls) === null || _api$blockControls === void 0 ? void 0 : _api$blockControls.sharedState.currentState()) || {},
18
18
  isDragging = _ref.isDragging,
19
19
  activeNode = _ref.activeNode;
@@ -24,7 +24,7 @@ export var handleMouseOver = function handleMouseOver(view, event, api) {
24
24
  return false;
25
25
  }
26
26
  var target = event.target;
27
- if (target.classList.contains('ProseMirror')) {
27
+ if (target !== null && target !== void 0 && (_target$classList = target.classList) !== null && _target$classList !== void 0 && _target$classList.contains('ProseMirror')) {
28
28
  return false;
29
29
  }
30
30
  var rootElement = target === null || target === void 0 ? void 0 : target.closest('[data-drag-handler-anchor-name]');
@@ -9,10 +9,10 @@ export var getNestedNodePosition = function getNestedNodePosition(state) {
9
9
  if ($pos.depth < 1) {
10
10
  return nestedNodePos;
11
11
  }
12
- var parentNodeOfSpecificTypes = findParentNodeOfType([state.schema.nodes.bulletList, state.schema.nodes.orderedList, state.schema.nodes.blockquote, state.schema.nodes.taskList])(state.selection);
12
+ var parentNodeOfSpecificTypes = findParentNodeOfType([state.schema.nodes.bulletList, state.schema.nodes.orderedList, state.schema.nodes.blockquote, state.schema.nodes.taskList, state.schema.nodes.decisionList])(state.selection);
13
13
  if (parentNodeOfSpecificTypes) {
14
14
  var parentNodeType = parentNodeOfSpecificTypes.node.type.name;
15
- nestedNodePos = ['bulletList', 'orderedList'].includes(parentNodeType) ? $pos.before($pos.depth - 1) : ['blockquote', 'taskList'].includes(parentNodeType) ? $pos.before() : nestedNodePos;
15
+ nestedNodePos = ['bulletList', 'orderedList'].includes(parentNodeType) ? $pos.before($pos.depth - 1) : ['blockquote', 'taskList', 'decisionList'].includes(parentNodeType) ? $pos.before() : nestedNodePos;
16
16
  }
17
17
  } else {
18
18
  nestedNodePos = selection.$from.pos;
@@ -23,15 +23,26 @@ export var getInlineNodePos = function getInlineNodePos(tr, start, nodeSize) {
23
23
  inlineNodeEndPos: inlineNodeEndPos
24
24
  };
25
25
  };
26
+ var isNodeWithMedia = function isNodeWithMedia(tr, start, nodeSize) {
27
+ var $startPos = tr.doc.resolve(start);
28
+ var hasMedia = false;
29
+ tr.doc.nodesBetween($startPos.pos, $startPos.pos + nodeSize, function (n) {
30
+ if (n.type.name === 'media') {
31
+ hasMedia = true;
32
+ }
33
+ });
34
+ return hasMedia;
35
+ };
26
36
  export var getSelection = function getSelection(tr, start) {
27
37
  var node = tr.doc.nodeAt(start);
28
38
  var isNodeSelection = node && NodeSelection.isSelectable(node);
29
39
  var nodeSize = node ? node.nodeSize : 1;
30
40
  var $startPos = tr.doc.resolve(start);
31
41
  var nodeName = node === null || node === void 0 ? void 0 : node.type.name;
42
+ var isBlockQuoteWithMedia = nodeName === 'blockquote' && isNodeWithMedia(tr, start, nodeSize);
32
43
 
33
44
  // decisionList node is not selectable, but we want to select the whole node not just text
34
- if (isNodeSelection || nodeName === 'decisionList') {
45
+ if (isNodeSelection && nodeName !== 'blockquote' || isBlockQuoteWithMedia || nodeName === 'decisionList') {
35
46
  return new NodeSelection($startPos);
36
47
  } else if (nodeName === 'mediaGroup' && (node === null || node === void 0 ? void 0 : node.childCount) === 1) {
37
48
  var $mediaStartPos = tr.doc.resolve(start + 1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-block-controls",
3
- "version": "2.3.0",
3
+ "version": "2.4.0",
4
4
  "description": "Block controls plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -30,10 +30,10 @@
30
30
  ".": "./src/index.ts"
31
31
  },
32
32
  "dependencies": {
33
- "@atlaskit/adf-schema": "^40.9.0",
34
- "@atlaskit/editor-common": "^93.2.0",
33
+ "@atlaskit/adf-schema": "^40.9.4",
34
+ "@atlaskit/editor-common": "^93.3.0",
35
35
  "@atlaskit/editor-plugin-accessibility-utils": "^1.2.0",
36
- "@atlaskit/editor-plugin-analytics": "^1.8.0",
36
+ "@atlaskit/editor-plugin-analytics": "^1.9.0",
37
37
  "@atlaskit/editor-plugin-editor-disabled": "^1.3.0",
38
38
  "@atlaskit/editor-plugin-feature-flags": "^1.2.0",
39
39
  "@atlaskit/editor-plugin-quick-insert": "^1.4.0",