@atlaskit/editor-plugin-paste 1.0.5 → 1.0.7

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,20 @@
1
1
  # @atlaskit/editor-plugin-paste
2
2
 
3
+ ## 1.0.7
4
+
5
+ ### Patch Changes
6
+
7
+ - [#78224](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/78224) [`6b4c9dd4ad34`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/6b4c9dd4ad34) - ED-22219: adf-schema updated to 35.5.2
8
+ - [#76560](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/76560) [`ecab0d093882`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/ecab0d093882) - Fixed misplaced cursor positon when code block is pasted into extended nested expand
9
+ - [#78176](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/78176) [`7482f69bb25f`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/7482f69bb25f) - ED-21833: Stop showing paste options toolbar for smart links
10
+ - Updated dependencies
11
+
12
+ ## 1.0.6
13
+
14
+ ### Patch Changes
15
+
16
+ - [#75436](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/75436) [`bfcf32bb4fa3`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/bfcf32bb4fa3) - [ux] ED-21941 Disable resize/layout options for table, media and extension when added to MBE. Table rendering fixed for Confluence editor
17
+
3
18
  ## 1.0.5
4
19
 
5
20
  ### Patch Changes
@@ -818,13 +818,18 @@ function handleParagraphBlockMarks(state, slice) {
818
818
  return new _model.Slice(slice.content, openStart, slice.openEnd);
819
819
  }
820
820
 
821
- // If the paragraph contains marks forbidden by the parent node (e.g. alignment/indentation),
822
- // drop those marks from the slice
821
+ // If the paragraph or heading contains marks forbidden by the parent node
822
+ // (e.g. alignment/indentation), drop those marks from the slice
823
823
  return (0, _utils.mapSlice)(slice, function (node) {
824
824
  if (node.type === schema.nodes.paragraph) {
825
825
  return schema.nodes.paragraph.createChecked(undefined, node.content, node.marks.filter(function (mark) {
826
826
  return !forbiddenMarkTypes.includes(mark.type);
827
827
  }));
828
+ } else if (node.type === schema.nodes.heading) {
829
+ // Preserve heading attributes to keep formatting
830
+ return schema.nodes.heading.createChecked(node.attrs, node.content, node.marks.filter(function (mark) {
831
+ return !forbiddenMarkTypes.includes(mark.type);
832
+ }));
828
833
  }
829
834
  return node;
830
835
  });
@@ -926,7 +931,12 @@ function handleRichText(slice, queueCardsFromChangedTr) {
926
931
  // need to make sure the cursor position is is right after the panel, expand, or decisionList
927
932
  // still in the same table cell, see issue: https://product-fabric.atlassian.net/browse/ED-17862
928
933
  var shouldUpdateCursorPosAfterPaste = ['panel', 'nestedExpand', 'decisionList', 'codeBlock'].includes(((_slice$content$lastCh = slice.content.lastChild) === null || _slice$content$lastCh === void 0 || (_slice$content$lastCh = _slice$content$lastCh.type) === null || _slice$content$lastCh === void 0 ? void 0 : _slice$content$lastCh.name) || '');
929
- if ((0, _utils.insideTableCell)(state) && shouldUpdateCursorPosAfterPaste) {
934
+ var lastChild = slice.content.lastChild;
935
+ var $nextPos = tr.doc.resolve(tr.mapping.map(selection.from));
936
+ var nextSelection = lastChild !== null && lastChild !== void 0 && lastChild.type.isTextblock ? _state.TextSelection.findFrom($nextPos, -1, true) : new _selection.GapCursorSelection($nextPos, _selection.Side.RIGHT);
937
+ if ((0, _platformFeatureFlags.getBooleanFF)('platform.editor.place-cursor-inside-text-block') && nextSelection) {
938
+ tr.setSelection(nextSelection);
939
+ } else if ((0, _utils.insideTableCell)(state) && shouldUpdateCursorPosAfterPaste) {
930
940
  var nextPos = tr.doc.resolve(tr.mapping.map(selection.$from.pos));
931
941
  tr.setSelection(new _selection.GapCursorSelection(nextPos, _selection.Side.RIGHT));
932
942
  }
@@ -207,7 +207,7 @@ function createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFlags, pl
207
207
  }
208
208
  // creating a custom dispatch because we want to add a meta whenever we do a paste.
209
209
  var dispatch = function dispatch(tr) {
210
- var _state$doc$resolve$no, _input;
210
+ var _state$doc$resolve$no;
211
211
  // https://product-fabric.atlassian.net/browse/ED-12633
212
212
  // don't add closeHistory call if we're pasting a text inside placeholder text as we want the whole action
213
213
  // to be atomic
@@ -238,28 +238,36 @@ function createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFlags, pl
238
238
  var _pluginInjectionApi$b;
239
239
  tr = pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$b = pluginInjectionApi.betterTypeHistory) === null || _pluginInjectionApi$b === void 0 ? void 0 : _pluginInjectionApi$b.actions.flagPasteEvent(tr);
240
240
  }
241
+ var isDocChanged = tr.docChanged;
241
242
  (0, _card.addLinkMetadata)(view.state.selection, tr, {
242
243
  action: isPlainText ? _analytics.ACTION.PASTED_AS_PLAIN : _analytics.ACTION.PASTED,
243
244
  inputMethod: _analytics.INPUT_METHOD.CLIPBOARD
244
245
  });
245
- var pasteStartPos = Math.min(state.selection.anchor, state.selection.head);
246
- var pasteEndPos = tr.selection.to;
247
- var contentPasted = {
248
- pasteStartPos: pasteStartPos,
249
- pasteEndPos: pasteEndPos,
250
- text: text,
251
- isShiftPressed: Boolean(
252
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
253
- view.shiftKey || ((_input = view.input) === null || _input === void 0 ? void 0 : _input.shiftKey)),
254
- isPlainText: Boolean(isPlainText),
255
- pastedSlice: tr.doc.slice(pasteStartPos, pasteEndPos),
256
- pastedAt: Date.now(),
257
- pasteSource: (0, _util.getPasteSource)(event)
258
- };
259
- tr.setMeta(_pluginFactory.pluginKey, {
260
- type: _actions.PastePluginActionTypes.ON_PASTE,
261
- contentPasted: contentPasted
262
- });
246
+
247
+ // handleMacroAutoConvert dispatches twice
248
+ // we make sure to call paste options toolbar
249
+ // only for a valid paste action
250
+ if (isDocChanged) {
251
+ var _input;
252
+ var pasteStartPos = Math.min(state.selection.anchor, state.selection.head);
253
+ var pasteEndPos = tr.selection.to;
254
+ var contentPasted = {
255
+ pasteStartPos: pasteStartPos,
256
+ pasteEndPos: pasteEndPos,
257
+ text: text,
258
+ isShiftPressed: Boolean(
259
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
260
+ view.shiftKey || ((_input = view.input) === null || _input === void 0 ? void 0 : _input.shiftKey)),
261
+ isPlainText: Boolean(isPlainText),
262
+ pastedSlice: tr.doc.slice(pasteStartPos, pasteEndPos),
263
+ pastedAt: Date.now(),
264
+ pasteSource: (0, _util.getPasteSource)(event)
265
+ };
266
+ tr.setMeta(_pluginFactory.pluginKey, {
267
+ type: _actions.PastePluginActionTypes.ON_PASTE,
268
+ contentPasted: contentPasted
269
+ });
270
+ }
263
271
  view.dispatch(tr);
264
272
  };
265
273
  slice = (0, _handlers.handleParagraphBlockMarks)(state, slice);
@@ -796,11 +796,14 @@ export function handleParagraphBlockMarks(state, slice) {
796
796
  return new Slice(slice.content, openStart, slice.openEnd);
797
797
  }
798
798
 
799
- // If the paragraph contains marks forbidden by the parent node (e.g. alignment/indentation),
800
- // drop those marks from the slice
799
+ // If the paragraph or heading contains marks forbidden by the parent node
800
+ // (e.g. alignment/indentation), drop those marks from the slice
801
801
  return mapSlice(slice, node => {
802
802
  if (node.type === schema.nodes.paragraph) {
803
803
  return schema.nodes.paragraph.createChecked(undefined, node.content, node.marks.filter(mark => !forbiddenMarkTypes.includes(mark.type)));
804
+ } else if (node.type === schema.nodes.heading) {
805
+ // Preserve heading attributes to keep formatting
806
+ return schema.nodes.heading.createChecked(node.attrs, node.content, node.marks.filter(mark => !forbiddenMarkTypes.includes(mark.type)));
804
807
  }
805
808
  return node;
806
809
  });
@@ -905,7 +908,12 @@ export function handleRichText(slice, queueCardsFromChangedTr) {
905
908
  // need to make sure the cursor position is is right after the panel, expand, or decisionList
906
909
  // still in the same table cell, see issue: https://product-fabric.atlassian.net/browse/ED-17862
907
910
  const shouldUpdateCursorPosAfterPaste = ['panel', 'nestedExpand', 'decisionList', 'codeBlock'].includes(((_slice$content$lastCh = slice.content.lastChild) === null || _slice$content$lastCh === void 0 ? void 0 : (_slice$content$lastCh2 = _slice$content$lastCh.type) === null || _slice$content$lastCh2 === void 0 ? void 0 : _slice$content$lastCh2.name) || '');
908
- if (insideTableCell(state) && shouldUpdateCursorPosAfterPaste) {
911
+ const lastChild = slice.content.lastChild;
912
+ const $nextPos = tr.doc.resolve(tr.mapping.map(selection.from));
913
+ const nextSelection = lastChild !== null && lastChild !== void 0 && lastChild.type.isTextblock ? TextSelection.findFrom($nextPos, -1, true) : new GapCursorSelection($nextPos, Side.RIGHT);
914
+ if (getBooleanFF('platform.editor.place-cursor-inside-text-block') && nextSelection) {
915
+ tr.setSelection(nextSelection);
916
+ } else if (insideTableCell(state) && shouldUpdateCursorPosAfterPaste) {
909
917
  const nextPos = tr.doc.resolve(tr.mapping.map(selection.$from.pos));
910
918
  tr.setSelection(new GapCursorSelection(nextPos, Side.RIGHT));
911
919
  }
@@ -174,7 +174,7 @@ export function createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFl
174
174
  }
175
175
  // creating a custom dispatch because we want to add a meta whenever we do a paste.
176
176
  const dispatch = tr => {
177
- var _state$doc$resolve$no, _input;
177
+ var _state$doc$resolve$no;
178
178
  // https://product-fabric.atlassian.net/browse/ED-12633
179
179
  // don't add closeHistory call if we're pasting a text inside placeholder text as we want the whole action
180
180
  // to be atomic
@@ -207,28 +207,36 @@ export function createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFl
207
207
  var _pluginInjectionApi$b;
208
208
  tr = pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$b = pluginInjectionApi.betterTypeHistory) === null || _pluginInjectionApi$b === void 0 ? void 0 : _pluginInjectionApi$b.actions.flagPasteEvent(tr);
209
209
  }
210
+ const isDocChanged = tr.docChanged;
210
211
  addLinkMetadata(view.state.selection, tr, {
211
212
  action: isPlainText ? ACTION.PASTED_AS_PLAIN : ACTION.PASTED,
212
213
  inputMethod: INPUT_METHOD.CLIPBOARD
213
214
  });
214
- const pasteStartPos = Math.min(state.selection.anchor, state.selection.head);
215
- const pasteEndPos = tr.selection.to;
216
- const contentPasted = {
217
- pasteStartPos,
218
- pasteEndPos,
219
- text,
220
- isShiftPressed: Boolean(
221
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
222
- view.shiftKey || ((_input = view.input) === null || _input === void 0 ? void 0 : _input.shiftKey)),
223
- isPlainText: Boolean(isPlainText),
224
- pastedSlice: tr.doc.slice(pasteStartPos, pasteEndPos),
225
- pastedAt: Date.now(),
226
- pasteSource: getPasteSource(event)
227
- };
228
- tr.setMeta(stateKey, {
229
- type: PastePluginActionTypes.ON_PASTE,
230
- contentPasted
231
- });
215
+
216
+ // handleMacroAutoConvert dispatches twice
217
+ // we make sure to call paste options toolbar
218
+ // only for a valid paste action
219
+ if (isDocChanged) {
220
+ var _input;
221
+ const pasteStartPos = Math.min(state.selection.anchor, state.selection.head);
222
+ const pasteEndPos = tr.selection.to;
223
+ const contentPasted = {
224
+ pasteStartPos,
225
+ pasteEndPos,
226
+ text,
227
+ isShiftPressed: Boolean(
228
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
229
+ view.shiftKey || ((_input = view.input) === null || _input === void 0 ? void 0 : _input.shiftKey)),
230
+ isPlainText: Boolean(isPlainText),
231
+ pastedSlice: tr.doc.slice(pasteStartPos, pasteEndPos),
232
+ pastedAt: Date.now(),
233
+ pasteSource: getPasteSource(event)
234
+ };
235
+ tr.setMeta(stateKey, {
236
+ type: PastePluginActionTypes.ON_PASTE,
237
+ contentPasted
238
+ });
239
+ }
232
240
  view.dispatch(tr);
233
241
  };
234
242
  slice = handleParagraphBlockMarks(state, slice);
@@ -796,13 +796,18 @@ export function handleParagraphBlockMarks(state, slice) {
796
796
  return new Slice(slice.content, openStart, slice.openEnd);
797
797
  }
798
798
 
799
- // If the paragraph contains marks forbidden by the parent node (e.g. alignment/indentation),
800
- // drop those marks from the slice
799
+ // If the paragraph or heading contains marks forbidden by the parent node
800
+ // (e.g. alignment/indentation), drop those marks from the slice
801
801
  return mapSlice(slice, function (node) {
802
802
  if (node.type === schema.nodes.paragraph) {
803
803
  return schema.nodes.paragraph.createChecked(undefined, node.content, node.marks.filter(function (mark) {
804
804
  return !forbiddenMarkTypes.includes(mark.type);
805
805
  }));
806
+ } else if (node.type === schema.nodes.heading) {
807
+ // Preserve heading attributes to keep formatting
808
+ return schema.nodes.heading.createChecked(node.attrs, node.content, node.marks.filter(function (mark) {
809
+ return !forbiddenMarkTypes.includes(mark.type);
810
+ }));
806
811
  }
807
812
  return node;
808
813
  });
@@ -904,7 +909,12 @@ export function handleRichText(slice, queueCardsFromChangedTr) {
904
909
  // need to make sure the cursor position is is right after the panel, expand, or decisionList
905
910
  // still in the same table cell, see issue: https://product-fabric.atlassian.net/browse/ED-17862
906
911
  var shouldUpdateCursorPosAfterPaste = ['panel', 'nestedExpand', 'decisionList', 'codeBlock'].includes(((_slice$content$lastCh = slice.content.lastChild) === null || _slice$content$lastCh === void 0 || (_slice$content$lastCh = _slice$content$lastCh.type) === null || _slice$content$lastCh === void 0 ? void 0 : _slice$content$lastCh.name) || '');
907
- if (insideTableCell(state) && shouldUpdateCursorPosAfterPaste) {
912
+ var lastChild = slice.content.lastChild;
913
+ var $nextPos = tr.doc.resolve(tr.mapping.map(selection.from));
914
+ var nextSelection = lastChild !== null && lastChild !== void 0 && lastChild.type.isTextblock ? TextSelection.findFrom($nextPos, -1, true) : new GapCursorSelection($nextPos, Side.RIGHT);
915
+ if (getBooleanFF('platform.editor.place-cursor-inside-text-block') && nextSelection) {
916
+ tr.setSelection(nextSelection);
917
+ } else if (insideTableCell(state) && shouldUpdateCursorPosAfterPaste) {
908
918
  var nextPos = tr.doc.resolve(tr.mapping.map(selection.$from.pos));
909
919
  tr.setSelection(new GapCursorSelection(nextPos, Side.RIGHT));
910
920
  }
@@ -194,7 +194,7 @@ export function createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFl
194
194
  }
195
195
  // creating a custom dispatch because we want to add a meta whenever we do a paste.
196
196
  var dispatch = function dispatch(tr) {
197
- var _state$doc$resolve$no, _input;
197
+ var _state$doc$resolve$no;
198
198
  // https://product-fabric.atlassian.net/browse/ED-12633
199
199
  // don't add closeHistory call if we're pasting a text inside placeholder text as we want the whole action
200
200
  // to be atomic
@@ -225,28 +225,36 @@ export function createPlugin(schema, dispatchAnalyticsEvent, dispatch, featureFl
225
225
  var _pluginInjectionApi$b;
226
226
  tr = pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$b = pluginInjectionApi.betterTypeHistory) === null || _pluginInjectionApi$b === void 0 ? void 0 : _pluginInjectionApi$b.actions.flagPasteEvent(tr);
227
227
  }
228
+ var isDocChanged = tr.docChanged;
228
229
  addLinkMetadata(view.state.selection, tr, {
229
230
  action: isPlainText ? ACTION.PASTED_AS_PLAIN : ACTION.PASTED,
230
231
  inputMethod: INPUT_METHOD.CLIPBOARD
231
232
  });
232
- var pasteStartPos = Math.min(state.selection.anchor, state.selection.head);
233
- var pasteEndPos = tr.selection.to;
234
- var contentPasted = {
235
- pasteStartPos: pasteStartPos,
236
- pasteEndPos: pasteEndPos,
237
- text: text,
238
- isShiftPressed: Boolean(
239
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
240
- view.shiftKey || ((_input = view.input) === null || _input === void 0 ? void 0 : _input.shiftKey)),
241
- isPlainText: Boolean(isPlainText),
242
- pastedSlice: tr.doc.slice(pasteStartPos, pasteEndPos),
243
- pastedAt: Date.now(),
244
- pasteSource: getPasteSource(event)
245
- };
246
- tr.setMeta(stateKey, {
247
- type: PastePluginActionTypes.ON_PASTE,
248
- contentPasted: contentPasted
249
- });
233
+
234
+ // handleMacroAutoConvert dispatches twice
235
+ // we make sure to call paste options toolbar
236
+ // only for a valid paste action
237
+ if (isDocChanged) {
238
+ var _input;
239
+ var pasteStartPos = Math.min(state.selection.anchor, state.selection.head);
240
+ var pasteEndPos = tr.selection.to;
241
+ var contentPasted = {
242
+ pasteStartPos: pasteStartPos,
243
+ pasteEndPos: pasteEndPos,
244
+ text: text,
245
+ isShiftPressed: Boolean(
246
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
247
+ view.shiftKey || ((_input = view.input) === null || _input === void 0 ? void 0 : _input.shiftKey)),
248
+ isPlainText: Boolean(isPlainText),
249
+ pastedSlice: tr.doc.slice(pasteStartPos, pasteEndPos),
250
+ pastedAt: Date.now(),
251
+ pasteSource: getPasteSource(event)
252
+ };
253
+ tr.setMeta(stateKey, {
254
+ type: PastePluginActionTypes.ON_PASTE,
255
+ contentPasted: contentPasted
256
+ });
257
+ }
250
258
  view.dispatch(tr);
251
259
  };
252
260
  slice = handleParagraphBlockMarks(state, slice);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-paste",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "Paste plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -33,15 +33,15 @@
33
33
  ".": "./src/index.ts"
34
34
  },
35
35
  "dependencies": {
36
- "@atlaskit/editor-common": "^78.4.0",
37
- "@atlaskit/editor-markdown-transformer": "^5.3.0",
36
+ "@atlaskit/editor-common": "^78.10.0",
37
+ "@atlaskit/editor-markdown-transformer": "^5.4.0",
38
38
  "@atlaskit/editor-plugin-analytics": "^1.0.0",
39
39
  "@atlaskit/editor-plugin-annotation": "^1.0.0",
40
40
  "@atlaskit/editor-plugin-better-type-history": "^1.0.0",
41
- "@atlaskit/editor-plugin-card": "^1.0.0",
41
+ "@atlaskit/editor-plugin-card": "^1.1.0",
42
42
  "@atlaskit/editor-plugin-feature-flags": "^1.0.0",
43
43
  "@atlaskit/editor-plugin-list": "^3.1.0",
44
- "@atlaskit/editor-plugin-media": "^1.2.0",
44
+ "@atlaskit/editor-plugin-media": "^1.6.0",
45
45
  "@atlaskit/editor-prosemirror": "3.0.0",
46
46
  "@atlaskit/editor-tables": "^2.5.0",
47
47
  "@atlaskit/media-client": "^26.2.0",
@@ -56,7 +56,7 @@
56
56
  },
57
57
  "devDependencies": {
58
58
  "@af/visual-regression": "*",
59
- "@atlaskit/adf-schema": "^35.5.1",
59
+ "@atlaskit/adf-schema": "^35.5.2",
60
60
  "@atlaskit/editor-plugin-block-type": "^3.0.0",
61
61
  "@atlaskit/editor-plugin-history": "^1.0.0",
62
62
  "@atlaskit/editor-plugin-type-ahead": "^1.0.0",
@@ -128,6 +128,9 @@
128
128
  },
129
129
  "platform.editor.handle-paste-for-action-in-panel": {
130
130
  "type": "boolean"
131
+ },
132
+ "platform.editor.place-cursor-inside-text-block": {
133
+ "type": "boolean"
131
134
  }
132
135
  }
133
136
  }