@atlaskit/editor-plugin-block-controls 8.5.1 → 8.6.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 +11 -0
- package/dist/cjs/pm-plugins/selection-preservation/pm-plugin.js +15 -35
- package/dist/cjs/pm-plugins/selection-preservation/utils.js +26 -45
- package/dist/es2019/pm-plugins/selection-preservation/pm-plugin.js +15 -35
- package/dist/es2019/pm-plugins/selection-preservation/utils.js +26 -45
- package/dist/esm/pm-plugins/selection-preservation/pm-plugin.js +15 -35
- package/dist/esm/pm-plugins/selection-preservation/utils.js +26 -45
- package/dist/types/pm-plugins/selection-preservation/utils.d.ts +2 -2
- package/dist/types-ts4.5/pm-plugins/selection-preservation/utils.d.ts +2 -2
- package/package.json +2 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-block-controls
|
|
2
2
|
|
|
3
|
+
## 8.6.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`0190ead71b6e6`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/0190ead71b6e6) -
|
|
8
|
+
[ux] Cleanup fg: platform_editor_selection_sync_fix
|
|
9
|
+
|
|
10
|
+
### Patch Changes
|
|
11
|
+
|
|
12
|
+
- Updated dependencies
|
|
13
|
+
|
|
3
14
|
## 8.5.1
|
|
4
15
|
|
|
5
16
|
### Patch Changes
|
|
@@ -10,7 +10,6 @@ var _bindEventListener = require("bind-event-listener");
|
|
|
10
10
|
var _browserApis = require("@atlaskit/browser-apis");
|
|
11
11
|
var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
|
|
12
12
|
var _styles = require("@atlaskit/editor-common/styles");
|
|
13
|
-
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
14
13
|
var _main = require("../main");
|
|
15
14
|
var _selection = require("../utils/selection");
|
|
16
15
|
var _editorCommands = require("./editor-commands");
|
|
@@ -159,42 +158,23 @@ var createSelectionPreservationPlugin = exports.createSelectionPreservationPlugi
|
|
|
159
158
|
});
|
|
160
159
|
return {
|
|
161
160
|
update: function update(updateView, prevState) {
|
|
161
|
+
var _selectionPreservatio, _selectionPreservatio2, _key$getState, _key$getState2;
|
|
162
162
|
view = updateView;
|
|
163
|
+
var prevPreservedSelection = (_selectionPreservatio = _pluginKey.selectionPreservationPluginKey.getState(prevState)) === null || _selectionPreservatio === void 0 ? void 0 : _selectionPreservatio.preservedSelection;
|
|
164
|
+
var currPreservedSelection = (_selectionPreservatio2 = _pluginKey.selectionPreservationPluginKey.getState(view.state)) === null || _selectionPreservatio2 === void 0 ? void 0 : _selectionPreservatio2.preservedSelection;
|
|
165
|
+
var prevActiveNode = (_key$getState = _main.key.getState(prevState)) === null || _key$getState === void 0 ? void 0 : _key$getState.activeNode;
|
|
166
|
+
var currActiveNode = (_key$getState2 = _main.key.getState(view.state)) === null || _key$getState2 === void 0 ? void 0 : _key$getState2.activeNode;
|
|
163
167
|
|
|
164
|
-
//
|
|
165
|
-
//
|
|
166
|
-
// This prevents
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
// Sync DOM selection when the preserved selection or active node changes
|
|
176
|
-
// AND the document has changed (e.g., nodes moved)
|
|
177
|
-
// This prevents stealing focus during menu navigation while still fixing ghost highlighting
|
|
178
|
-
var hasPreservedSelection = !!currPreservedSelection;
|
|
179
|
-
var preservedSelectionChanged = !(0, _utils.compareSelections)(prevPreservedSelection, currPreservedSelection);
|
|
180
|
-
var activeNodeChanged = prevActiveNode !== currActiveNode;
|
|
181
|
-
var docChanged = prevState.doc !== view.state.doc;
|
|
182
|
-
var shouldSyncDOMSelection = hasPreservedSelection && (preservedSelectionChanged || activeNodeChanged) && docChanged;
|
|
183
|
-
if (shouldSyncDOMSelection) {
|
|
184
|
-
(0, _utils.syncDOMSelection)(view.state.selection, view);
|
|
185
|
-
}
|
|
186
|
-
} else {
|
|
187
|
-
var _selectionPreservatio3, _selectionPreservatio4, _key$getState3, _key$getState4;
|
|
188
|
-
// OLD BEHAVIOR (to be removed when flag is cleaned up)
|
|
189
|
-
// Only synced when editor had focus, causing ghost highlighting issues
|
|
190
|
-
var _prevPreservedSelection = (_selectionPreservatio3 = _pluginKey.selectionPreservationPluginKey.getState(prevState)) === null || _selectionPreservatio3 === void 0 ? void 0 : _selectionPreservatio3.preservedSelection;
|
|
191
|
-
var _currPreservedSelection = (_selectionPreservatio4 = _pluginKey.selectionPreservationPluginKey.getState(view.state)) === null || _selectionPreservatio4 === void 0 ? void 0 : _selectionPreservatio4.preservedSelection;
|
|
192
|
-
var _prevActiveNode = (_key$getState3 = _main.key.getState(prevState)) === null || _key$getState3 === void 0 ? void 0 : _key$getState3.activeNode;
|
|
193
|
-
var _currActiveNode = (_key$getState4 = _main.key.getState(view.state)) === null || _key$getState4 === void 0 ? void 0 : _key$getState4.activeNode;
|
|
194
|
-
if (_currPreservedSelection && view.hasFocus() && (!(0, _utils.compareSelections)(_prevPreservedSelection, _currPreservedSelection) || _prevActiveNode !== _currActiveNode)) {
|
|
195
|
-
// Old syncDOMSelection signature (to be removed)
|
|
196
|
-
(0, _utils.syncDOMSelection)(view.state.selection);
|
|
197
|
-
}
|
|
168
|
+
// Sync DOM selection when the preserved selection or active node changes
|
|
169
|
+
// AND the document has changed (e.g., nodes moved)
|
|
170
|
+
// This prevents stealing focus during menu navigation while still fixing ghost highlighting
|
|
171
|
+
var hasPreservedSelection = !!currPreservedSelection;
|
|
172
|
+
var preservedSelectionChanged = !(0, _utils.compareSelections)(prevPreservedSelection, currPreservedSelection);
|
|
173
|
+
var activeNodeChanged = prevActiveNode !== currActiveNode;
|
|
174
|
+
var docChanged = prevState.doc !== view.state.doc;
|
|
175
|
+
var shouldSyncDOMSelection = hasPreservedSelection && (preservedSelectionChanged || activeNodeChanged) && docChanged;
|
|
176
|
+
if (shouldSyncDOMSelection) {
|
|
177
|
+
(0, _utils.syncDOMSelection)(view.state.selection, view);
|
|
198
178
|
}
|
|
199
179
|
},
|
|
200
180
|
destroy: function destroy() {
|
|
@@ -5,7 +5,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.syncDOMSelection = exports.hasUserSelectionChange = exports.getSelectionPreservationMeta = exports.compareSelections = void 0;
|
|
7
7
|
var _browserApis = require("@atlaskit/browser-apis");
|
|
8
|
-
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
9
8
|
var _pluginKey = require("./plugin-key");
|
|
10
9
|
/**
|
|
11
10
|
* Detects if any of the transactions include user-driven selection changes.
|
|
@@ -41,54 +40,36 @@ var compareSelections = exports.compareSelections = function compareSelections(a
|
|
|
41
40
|
* the browser's native selection remains at the old position, causing ghost highlighting.
|
|
42
41
|
*
|
|
43
42
|
* @param selection The current ProseMirror selection state to sync to DOM.
|
|
44
|
-
* @param view The EditorView instance used to convert ProseMirror positions to DOM positions
|
|
43
|
+
* @param view The EditorView instance used to convert ProseMirror positions to DOM positions.
|
|
45
44
|
*/
|
|
46
45
|
var syncDOMSelection = exports.syncDOMSelection = function syncDOMSelection(selection, view) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
var doc = (0, _browserApis.getDocument)();
|
|
58
|
-
if (!doc) {
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
46
|
+
try {
|
|
47
|
+
var domSelection = window.getSelection();
|
|
48
|
+
if (!domSelection) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
var doc = (0, _browserApis.getDocument)();
|
|
52
|
+
if (!doc) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
61
55
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
56
|
+
// Convert ProseMirror selection to DOM selection using view.domAtPos
|
|
57
|
+
var anchor = view.domAtPos(selection.anchor);
|
|
58
|
+
var head = view.domAtPos(selection.head);
|
|
59
|
+
if (!anchor || !head) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
68
62
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
63
|
+
// Create a new DOM range from the ProseMirror selection
|
|
64
|
+
var range = doc.createRange();
|
|
65
|
+
range.setStart(anchor.node, anchor.offset);
|
|
66
|
+
range.setEnd(head.node, head.offset);
|
|
73
67
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
} else {
|
|
82
|
-
// OLD BEHAVIOR (to be removed when flag is cleaned up)
|
|
83
|
-
// Only checked if selection was out of sync using incorrect offset comparison
|
|
84
|
-
var _domSelection = window.getSelection();
|
|
85
|
-
var domRange = _domSelection && _domSelection.rangeCount === 1 && _domSelection.getRangeAt(0).cloneRange();
|
|
86
|
-
var isOutOfSync = domRange && (selection.from !== domRange.startOffset || selection.to !== domRange.endOffset);
|
|
87
|
-
if (isOutOfSync && _domSelection && domRange) {
|
|
88
|
-
// Force the DOM selection to refresh, setting it to the same range
|
|
89
|
-
// This will trigger ProseMirror to re-apply its selection logic based on the current state
|
|
90
|
-
_domSelection.removeAllRanges();
|
|
91
|
-
_domSelection.addRange(domRange);
|
|
92
|
-
}
|
|
68
|
+
// Update the DOM selection to match ProseMirror's selection
|
|
69
|
+
domSelection.removeAllRanges();
|
|
70
|
+
domSelection.addRange(range);
|
|
71
|
+
} catch (_unused) {
|
|
72
|
+
// Silently fail if DOM selection sync fails
|
|
73
|
+
// This can happen if positions are invalid or DOM hasn't updated yet
|
|
93
74
|
}
|
|
94
75
|
};
|
|
@@ -2,7 +2,6 @@ import { bind } from 'bind-event-listener';
|
|
|
2
2
|
import { getDocument } from '@atlaskit/browser-apis';
|
|
3
3
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
4
4
|
import { DRAG_HANDLE_SELECTOR } from '@atlaskit/editor-common/styles';
|
|
5
|
-
import { fg } from '@atlaskit/platform-feature-flags';
|
|
6
5
|
import { key } from '../main';
|
|
7
6
|
import { createPreservedSelection, mapPreservedSelection } from '../utils/selection';
|
|
8
7
|
import { stopPreservingSelection } from './editor-commands';
|
|
@@ -152,42 +151,23 @@ export const createSelectionPreservationPlugin = api => () => {
|
|
|
152
151
|
});
|
|
153
152
|
return {
|
|
154
153
|
update(updateView, prevState) {
|
|
154
|
+
var _selectionPreservatio, _selectionPreservatio2, _key$getState, _key$getState2;
|
|
155
155
|
view = updateView;
|
|
156
|
+
const prevPreservedSelection = (_selectionPreservatio = selectionPreservationPluginKey.getState(prevState)) === null || _selectionPreservatio === void 0 ? void 0 : _selectionPreservatio.preservedSelection;
|
|
157
|
+
const currPreservedSelection = (_selectionPreservatio2 = selectionPreservationPluginKey.getState(view.state)) === null || _selectionPreservatio2 === void 0 ? void 0 : _selectionPreservatio2.preservedSelection;
|
|
158
|
+
const prevActiveNode = (_key$getState = key.getState(prevState)) === null || _key$getState === void 0 ? void 0 : _key$getState.activeNode;
|
|
159
|
+
const currActiveNode = (_key$getState2 = key.getState(view.state)) === null || _key$getState2 === void 0 ? void 0 : _key$getState2.activeNode;
|
|
156
160
|
|
|
157
|
-
//
|
|
158
|
-
//
|
|
159
|
-
// This prevents
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
// Sync DOM selection when the preserved selection or active node changes
|
|
169
|
-
// AND the document has changed (e.g., nodes moved)
|
|
170
|
-
// This prevents stealing focus during menu navigation while still fixing ghost highlighting
|
|
171
|
-
const hasPreservedSelection = !!currPreservedSelection;
|
|
172
|
-
const preservedSelectionChanged = !compareSelections(prevPreservedSelection, currPreservedSelection);
|
|
173
|
-
const activeNodeChanged = prevActiveNode !== currActiveNode;
|
|
174
|
-
const docChanged = prevState.doc !== view.state.doc;
|
|
175
|
-
const shouldSyncDOMSelection = hasPreservedSelection && (preservedSelectionChanged || activeNodeChanged) && docChanged;
|
|
176
|
-
if (shouldSyncDOMSelection) {
|
|
177
|
-
syncDOMSelection(view.state.selection, view);
|
|
178
|
-
}
|
|
179
|
-
} else {
|
|
180
|
-
var _selectionPreservatio3, _selectionPreservatio4, _key$getState3, _key$getState4;
|
|
181
|
-
// OLD BEHAVIOR (to be removed when flag is cleaned up)
|
|
182
|
-
// Only synced when editor had focus, causing ghost highlighting issues
|
|
183
|
-
const prevPreservedSelection = (_selectionPreservatio3 = selectionPreservationPluginKey.getState(prevState)) === null || _selectionPreservatio3 === void 0 ? void 0 : _selectionPreservatio3.preservedSelection;
|
|
184
|
-
const currPreservedSelection = (_selectionPreservatio4 = selectionPreservationPluginKey.getState(view.state)) === null || _selectionPreservatio4 === void 0 ? void 0 : _selectionPreservatio4.preservedSelection;
|
|
185
|
-
const prevActiveNode = (_key$getState3 = key.getState(prevState)) === null || _key$getState3 === void 0 ? void 0 : _key$getState3.activeNode;
|
|
186
|
-
const currActiveNode = (_key$getState4 = key.getState(view.state)) === null || _key$getState4 === void 0 ? void 0 : _key$getState4.activeNode;
|
|
187
|
-
if (currPreservedSelection && view.hasFocus() && (!compareSelections(prevPreservedSelection, currPreservedSelection) || prevActiveNode !== currActiveNode)) {
|
|
188
|
-
// Old syncDOMSelection signature (to be removed)
|
|
189
|
-
syncDOMSelection(view.state.selection);
|
|
190
|
-
}
|
|
161
|
+
// Sync DOM selection when the preserved selection or active node changes
|
|
162
|
+
// AND the document has changed (e.g., nodes moved)
|
|
163
|
+
// This prevents stealing focus during menu navigation while still fixing ghost highlighting
|
|
164
|
+
const hasPreservedSelection = !!currPreservedSelection;
|
|
165
|
+
const preservedSelectionChanged = !compareSelections(prevPreservedSelection, currPreservedSelection);
|
|
166
|
+
const activeNodeChanged = prevActiveNode !== currActiveNode;
|
|
167
|
+
const docChanged = prevState.doc !== view.state.doc;
|
|
168
|
+
const shouldSyncDOMSelection = hasPreservedSelection && (preservedSelectionChanged || activeNodeChanged) && docChanged;
|
|
169
|
+
if (shouldSyncDOMSelection) {
|
|
170
|
+
syncDOMSelection(view.state.selection, view);
|
|
191
171
|
}
|
|
192
172
|
},
|
|
193
173
|
destroy() {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { getDocument } from '@atlaskit/browser-apis';
|
|
2
|
-
import { fg } from '@atlaskit/platform-feature-flags';
|
|
3
2
|
import { selectionPreservationPluginKey } from './plugin-key';
|
|
4
3
|
/**
|
|
5
4
|
* Detects if any of the transactions include user-driven selection changes.
|
|
@@ -33,54 +32,36 @@ export const compareSelections = (a, b) => {
|
|
|
33
32
|
* the browser's native selection remains at the old position, causing ghost highlighting.
|
|
34
33
|
*
|
|
35
34
|
* @param selection The current ProseMirror selection state to sync to DOM.
|
|
36
|
-
* @param view The EditorView instance used to convert ProseMirror positions to DOM positions
|
|
35
|
+
* @param view The EditorView instance used to convert ProseMirror positions to DOM positions.
|
|
37
36
|
*/
|
|
38
37
|
export const syncDOMSelection = (selection, view) => {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
const doc = getDocument();
|
|
50
|
-
if (!doc) {
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
38
|
+
try {
|
|
39
|
+
const domSelection = window.getSelection();
|
|
40
|
+
if (!domSelection) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const doc = getDocument();
|
|
44
|
+
if (!doc) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
53
47
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
48
|
+
// Convert ProseMirror selection to DOM selection using view.domAtPos
|
|
49
|
+
const anchor = view.domAtPos(selection.anchor);
|
|
50
|
+
const head = view.domAtPos(selection.head);
|
|
51
|
+
if (!anchor || !head) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
60
54
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
55
|
+
// Create a new DOM range from the ProseMirror selection
|
|
56
|
+
const range = doc.createRange();
|
|
57
|
+
range.setStart(anchor.node, anchor.offset);
|
|
58
|
+
range.setEnd(head.node, head.offset);
|
|
65
59
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
} else {
|
|
74
|
-
// OLD BEHAVIOR (to be removed when flag is cleaned up)
|
|
75
|
-
// Only checked if selection was out of sync using incorrect offset comparison
|
|
76
|
-
const domSelection = window.getSelection();
|
|
77
|
-
const domRange = domSelection && domSelection.rangeCount === 1 && domSelection.getRangeAt(0).cloneRange();
|
|
78
|
-
const isOutOfSync = domRange && (selection.from !== domRange.startOffset || selection.to !== domRange.endOffset);
|
|
79
|
-
if (isOutOfSync && domSelection && domRange) {
|
|
80
|
-
// Force the DOM selection to refresh, setting it to the same range
|
|
81
|
-
// This will trigger ProseMirror to re-apply its selection logic based on the current state
|
|
82
|
-
domSelection.removeAllRanges();
|
|
83
|
-
domSelection.addRange(domRange);
|
|
84
|
-
}
|
|
60
|
+
// Update the DOM selection to match ProseMirror's selection
|
|
61
|
+
domSelection.removeAllRanges();
|
|
62
|
+
domSelection.addRange(range);
|
|
63
|
+
} catch {
|
|
64
|
+
// Silently fail if DOM selection sync fails
|
|
65
|
+
// This can happen if positions are invalid or DOM hasn't updated yet
|
|
85
66
|
}
|
|
86
67
|
};
|
|
@@ -5,7 +5,6 @@ import { bind } from 'bind-event-listener';
|
|
|
5
5
|
import { getDocument } from '@atlaskit/browser-apis';
|
|
6
6
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
7
7
|
import { DRAG_HANDLE_SELECTOR } from '@atlaskit/editor-common/styles';
|
|
8
|
-
import { fg } from '@atlaskit/platform-feature-flags';
|
|
9
8
|
import { key } from '../main';
|
|
10
9
|
import { createPreservedSelection, mapPreservedSelection } from '../utils/selection';
|
|
11
10
|
import { stopPreservingSelection } from './editor-commands';
|
|
@@ -153,42 +152,23 @@ export var createSelectionPreservationPlugin = function createSelectionPreservat
|
|
|
153
152
|
});
|
|
154
153
|
return {
|
|
155
154
|
update: function update(updateView, prevState) {
|
|
155
|
+
var _selectionPreservatio, _selectionPreservatio2, _key$getState, _key$getState2;
|
|
156
156
|
view = updateView;
|
|
157
|
+
var prevPreservedSelection = (_selectionPreservatio = selectionPreservationPluginKey.getState(prevState)) === null || _selectionPreservatio === void 0 ? void 0 : _selectionPreservatio.preservedSelection;
|
|
158
|
+
var currPreservedSelection = (_selectionPreservatio2 = selectionPreservationPluginKey.getState(view.state)) === null || _selectionPreservatio2 === void 0 ? void 0 : _selectionPreservatio2.preservedSelection;
|
|
159
|
+
var prevActiveNode = (_key$getState = key.getState(prevState)) === null || _key$getState === void 0 ? void 0 : _key$getState.activeNode;
|
|
160
|
+
var currActiveNode = (_key$getState2 = key.getState(view.state)) === null || _key$getState2 === void 0 ? void 0 : _key$getState2.activeNode;
|
|
157
161
|
|
|
158
|
-
//
|
|
159
|
-
//
|
|
160
|
-
// This prevents
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
// Sync DOM selection when the preserved selection or active node changes
|
|
170
|
-
// AND the document has changed (e.g., nodes moved)
|
|
171
|
-
// This prevents stealing focus during menu navigation while still fixing ghost highlighting
|
|
172
|
-
var hasPreservedSelection = !!currPreservedSelection;
|
|
173
|
-
var preservedSelectionChanged = !compareSelections(prevPreservedSelection, currPreservedSelection);
|
|
174
|
-
var activeNodeChanged = prevActiveNode !== currActiveNode;
|
|
175
|
-
var docChanged = prevState.doc !== view.state.doc;
|
|
176
|
-
var shouldSyncDOMSelection = hasPreservedSelection && (preservedSelectionChanged || activeNodeChanged) && docChanged;
|
|
177
|
-
if (shouldSyncDOMSelection) {
|
|
178
|
-
syncDOMSelection(view.state.selection, view);
|
|
179
|
-
}
|
|
180
|
-
} else {
|
|
181
|
-
var _selectionPreservatio3, _selectionPreservatio4, _key$getState3, _key$getState4;
|
|
182
|
-
// OLD BEHAVIOR (to be removed when flag is cleaned up)
|
|
183
|
-
// Only synced when editor had focus, causing ghost highlighting issues
|
|
184
|
-
var _prevPreservedSelection = (_selectionPreservatio3 = selectionPreservationPluginKey.getState(prevState)) === null || _selectionPreservatio3 === void 0 ? void 0 : _selectionPreservatio3.preservedSelection;
|
|
185
|
-
var _currPreservedSelection = (_selectionPreservatio4 = selectionPreservationPluginKey.getState(view.state)) === null || _selectionPreservatio4 === void 0 ? void 0 : _selectionPreservatio4.preservedSelection;
|
|
186
|
-
var _prevActiveNode = (_key$getState3 = key.getState(prevState)) === null || _key$getState3 === void 0 ? void 0 : _key$getState3.activeNode;
|
|
187
|
-
var _currActiveNode = (_key$getState4 = key.getState(view.state)) === null || _key$getState4 === void 0 ? void 0 : _key$getState4.activeNode;
|
|
188
|
-
if (_currPreservedSelection && view.hasFocus() && (!compareSelections(_prevPreservedSelection, _currPreservedSelection) || _prevActiveNode !== _currActiveNode)) {
|
|
189
|
-
// Old syncDOMSelection signature (to be removed)
|
|
190
|
-
syncDOMSelection(view.state.selection);
|
|
191
|
-
}
|
|
162
|
+
// Sync DOM selection when the preserved selection or active node changes
|
|
163
|
+
// AND the document has changed (e.g., nodes moved)
|
|
164
|
+
// This prevents stealing focus during menu navigation while still fixing ghost highlighting
|
|
165
|
+
var hasPreservedSelection = !!currPreservedSelection;
|
|
166
|
+
var preservedSelectionChanged = !compareSelections(prevPreservedSelection, currPreservedSelection);
|
|
167
|
+
var activeNodeChanged = prevActiveNode !== currActiveNode;
|
|
168
|
+
var docChanged = prevState.doc !== view.state.doc;
|
|
169
|
+
var shouldSyncDOMSelection = hasPreservedSelection && (preservedSelectionChanged || activeNodeChanged) && docChanged;
|
|
170
|
+
if (shouldSyncDOMSelection) {
|
|
171
|
+
syncDOMSelection(view.state.selection, view);
|
|
192
172
|
}
|
|
193
173
|
},
|
|
194
174
|
destroy: function destroy() {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { getDocument } from '@atlaskit/browser-apis';
|
|
2
|
-
import { fg } from '@atlaskit/platform-feature-flags';
|
|
3
2
|
import { selectionPreservationPluginKey } from './plugin-key';
|
|
4
3
|
/**
|
|
5
4
|
* Detects if any of the transactions include user-driven selection changes.
|
|
@@ -35,54 +34,36 @@ export var compareSelections = function compareSelections(a, b) {
|
|
|
35
34
|
* the browser's native selection remains at the old position, causing ghost highlighting.
|
|
36
35
|
*
|
|
37
36
|
* @param selection The current ProseMirror selection state to sync to DOM.
|
|
38
|
-
* @param view The EditorView instance used to convert ProseMirror positions to DOM positions
|
|
37
|
+
* @param view The EditorView instance used to convert ProseMirror positions to DOM positions.
|
|
39
38
|
*/
|
|
40
39
|
export var syncDOMSelection = function syncDOMSelection(selection, view) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
var doc = getDocument();
|
|
52
|
-
if (!doc) {
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
40
|
+
try {
|
|
41
|
+
var domSelection = window.getSelection();
|
|
42
|
+
if (!domSelection) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
var doc = getDocument();
|
|
46
|
+
if (!doc) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
55
49
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
50
|
+
// Convert ProseMirror selection to DOM selection using view.domAtPos
|
|
51
|
+
var anchor = view.domAtPos(selection.anchor);
|
|
52
|
+
var head = view.domAtPos(selection.head);
|
|
53
|
+
if (!anchor || !head) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
62
56
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
57
|
+
// Create a new DOM range from the ProseMirror selection
|
|
58
|
+
var range = doc.createRange();
|
|
59
|
+
range.setStart(anchor.node, anchor.offset);
|
|
60
|
+
range.setEnd(head.node, head.offset);
|
|
67
61
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
} else {
|
|
76
|
-
// OLD BEHAVIOR (to be removed when flag is cleaned up)
|
|
77
|
-
// Only checked if selection was out of sync using incorrect offset comparison
|
|
78
|
-
var _domSelection = window.getSelection();
|
|
79
|
-
var domRange = _domSelection && _domSelection.rangeCount === 1 && _domSelection.getRangeAt(0).cloneRange();
|
|
80
|
-
var isOutOfSync = domRange && (selection.from !== domRange.startOffset || selection.to !== domRange.endOffset);
|
|
81
|
-
if (isOutOfSync && _domSelection && domRange) {
|
|
82
|
-
// Force the DOM selection to refresh, setting it to the same range
|
|
83
|
-
// This will trigger ProseMirror to re-apply its selection logic based on the current state
|
|
84
|
-
_domSelection.removeAllRanges();
|
|
85
|
-
_domSelection.addRange(domRange);
|
|
86
|
-
}
|
|
62
|
+
// Update the DOM selection to match ProseMirror's selection
|
|
63
|
+
domSelection.removeAllRanges();
|
|
64
|
+
domSelection.addRange(range);
|
|
65
|
+
} catch (_unused) {
|
|
66
|
+
// Silently fail if DOM selection sync fails
|
|
67
|
+
// This can happen if positions are invalid or DOM hasn't updated yet
|
|
87
68
|
}
|
|
88
69
|
};
|
|
@@ -25,6 +25,6 @@ export declare const compareSelections: (a?: Selection, b?: Selection) => boolea
|
|
|
25
25
|
* the browser's native selection remains at the old position, causing ghost highlighting.
|
|
26
26
|
*
|
|
27
27
|
* @param selection The current ProseMirror selection state to sync to DOM.
|
|
28
|
-
* @param view The EditorView instance used to convert ProseMirror positions to DOM positions
|
|
28
|
+
* @param view The EditorView instance used to convert ProseMirror positions to DOM positions.
|
|
29
29
|
*/
|
|
30
|
-
export declare const syncDOMSelection: (selection: Selection, view
|
|
30
|
+
export declare const syncDOMSelection: (selection: Selection, view: EditorView) => void;
|
|
@@ -25,6 +25,6 @@ export declare const compareSelections: (a?: Selection, b?: Selection) => boolea
|
|
|
25
25
|
* the browser's native selection remains at the old position, causing ghost highlighting.
|
|
26
26
|
*
|
|
27
27
|
* @param selection The current ProseMirror selection state to sync to DOM.
|
|
28
|
-
* @param view The EditorView instance used to convert ProseMirror positions to DOM positions
|
|
28
|
+
* @param view The EditorView instance used to convert ProseMirror positions to DOM positions.
|
|
29
29
|
*/
|
|
30
|
-
export declare const syncDOMSelection: (selection: Selection, view
|
|
30
|
+
export declare const syncDOMSelection: (selection: Selection, view: EditorView) => void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-block-controls",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.6.0",
|
|
4
4
|
"description": "Block controls plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"@atlaskit/pragmatic-drag-and-drop-react-drop-indicator": "^3.2.0",
|
|
57
57
|
"@atlaskit/primitives": "^18.0.0",
|
|
58
58
|
"@atlaskit/theme": "^21.0.0",
|
|
59
|
-
"@atlaskit/tmp-editor-statsig": "^29.
|
|
59
|
+
"@atlaskit/tmp-editor-statsig": "^29.6.0",
|
|
60
60
|
"@atlaskit/tokens": "^11.0.0",
|
|
61
61
|
"@atlaskit/tooltip": "^20.14.0",
|
|
62
62
|
"@babel/runtime": "^7.0.0",
|
|
@@ -146,9 +146,6 @@
|
|
|
146
146
|
},
|
|
147
147
|
"platform_editor_native_anchor_patch_2": {
|
|
148
148
|
"type": "boolean"
|
|
149
|
-
},
|
|
150
|
-
"platform_editor_selection_sync_fix": {
|
|
151
|
-
"type": "boolean"
|
|
152
149
|
}
|
|
153
150
|
}
|
|
154
151
|
}
|