@atlaskit/editor-plugin-synced-block 4.2.8 → 4.2.10

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-synced-block
2
2
 
3
+ ## 4.2.10
4
+
5
+ ### Patch Changes
6
+
7
+ - [`f727550ca4b3d`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/f727550ca4b3d) -
8
+ [ux] [EDITOR-2738] Disable creation/deletion/data fetching of reference sync block in offline mode
9
+ - Updated dependencies
10
+
11
+ ## 4.2.9
12
+
13
+ ### Patch Changes
14
+
15
+ - [`b7d44770ef1bf`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/b7d44770ef1bf) -
16
+ EDITOR-2913 fix error nodetype create cannot create text nodes by filtering out text nodes
17
+
3
18
  ## 4.2.8
4
19
 
5
20
  ### Patch Changes
@@ -34,6 +34,9 @@
34
34
  {
35
35
  "path": "../../editor-plugin-block-menu/afm-jira/tsconfig.json"
36
36
  },
37
+ {
38
+ "path": "../../editor-plugin-connectivity/afm-jira/tsconfig.json"
39
+ },
37
40
  {
38
41
  "path": "../../editor-plugin-decorations/afm-jira/tsconfig.json"
39
42
  },
@@ -55,6 +58,9 @@
55
58
  {
56
59
  "path": "../../editor-toolbar/afm-jira/tsconfig.json"
57
60
  },
61
+ {
62
+ "path": "../../../design-system/flag/afm-jira/tsconfig.json"
63
+ },
58
64
  {
59
65
  "path": "../../../design-system/icon/afm-jira/tsconfig.json"
60
66
  },
@@ -73,6 +79,9 @@
73
79
  {
74
80
  "path": "../../../design-system/primitives/afm-jira/tsconfig.json"
75
81
  },
82
+ {
83
+ "path": "../../../design-system/tokens/afm-jira/tsconfig.json"
84
+ },
76
85
  {
77
86
  "path": "../../../design-system/tooltip/afm-jira/tsconfig.json"
78
87
  },
@@ -34,6 +34,9 @@
34
34
  {
35
35
  "path": "../../editor-plugin-block-menu/afm-products/tsconfig.json"
36
36
  },
37
+ {
38
+ "path": "../../editor-plugin-connectivity/afm-products/tsconfig.json"
39
+ },
37
40
  {
38
41
  "path": "../../editor-plugin-decorations/afm-products/tsconfig.json"
39
42
  },
@@ -55,6 +58,9 @@
55
58
  {
56
59
  "path": "../../editor-toolbar/afm-products/tsconfig.json"
57
60
  },
61
+ {
62
+ "path": "../../../design-system/flag/afm-products/tsconfig.json"
63
+ },
58
64
  {
59
65
  "path": "../../../design-system/icon/afm-products/tsconfig.json"
60
66
  },
@@ -73,6 +79,9 @@
73
79
  {
74
80
  "path": "../../../design-system/primitives/afm-products/tsconfig.json"
75
81
  },
82
+ {
83
+ "path": "../../../design-system/tokens/afm-products/tsconfig.json"
84
+ },
76
85
  {
77
86
  "path": "../../../design-system/tooltip/afm-products/tsconfig.json"
78
87
  },
@@ -16,7 +16,7 @@ var _lazySyncedBlock = require("../nodeviews/lazySyncedBlock");
16
16
  var _types = require("../types");
17
17
  var _ignoreDomEvent = require("./utils/ignore-dom-event");
18
18
  var _selectionDecorations = require("./utils/selection-decorations");
19
- var _trackSyncBlocks2 = require("./utils/track-sync-blocks");
19
+ var _trackSyncBlocks3 = require("./utils/track-sync-blocks");
20
20
  var syncedBlockPluginKey = exports.syncedBlockPluginKey = new _state.PluginKey('syncedBlockPlugin');
21
21
  var createPlugin = exports.createPlugin = function createPlugin(options, pmPluginFactoryParams, syncBlockStore, api) {
22
22
  var _ref = options || {},
@@ -114,19 +114,19 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
114
114
  if (!tr.docChanged || !(syncBlockStore !== null && syncBlockStore !== void 0 && syncBlockStore.requireConfirmationBeforeDelete()) && !syncBlockStore.hasPendingCreation() || Boolean(tr.getMeta('isRemote')) || Boolean(tr.getMeta('isCommitSyncBlockCreation')) || !isOffline && isConfirmedSyncBlockDeletion) {
115
115
  return true;
116
116
  }
117
- var _trackSyncBlocks = (0, _trackSyncBlocks2.trackSyncBlocks)(syncBlockStore, tr, state),
118
- removed = _trackSyncBlocks.removed,
119
- added = _trackSyncBlocks.added;
117
+ var _trackSyncBlocks = (0, _trackSyncBlocks3.trackSyncBlocks)(syncBlockStore.isSourceBlock, tr, state),
118
+ bodiedSyncBlockRemoved = _trackSyncBlocks.removed,
119
+ bodiedSyncBlockAdded = _trackSyncBlocks.added;
120
120
  if (!isOffline) {
121
- if (removed.length > 0) {
121
+ if (bodiedSyncBlockRemoved.length > 0) {
122
122
  // If there are source sync blocks being removed, and we need to confirm with user before deleting,
123
123
  // we block the transaction here, and wait for user confirmation to proceed with deletion.
124
124
  // See editor-common/src/sync-block/sync-block-store-manager.ts for how we handle user confirmation and
125
125
  // proceed with deletion.
126
- syncBlockStore.deleteSyncBlocksWithConfirmation(tr, removed);
126
+ syncBlockStore.deleteSyncBlocksWithConfirmation(tr, bodiedSyncBlockRemoved);
127
127
  return false;
128
128
  }
129
- if (added.length > 0) {
129
+ if (bodiedSyncBlockAdded.length > 0) {
130
130
  // If there is bodiedSyncBlock node addition and it's waiting for the result of saving the node to backend (syncBlockStore.hasPendingCreation()),
131
131
  // we need to intercept the transaction and save it in insert callback so that we only insert it to the document when backend call if backend call is successful
132
132
  // The callback will be evoked by in SourceSyncBlockStoreManager.commitPendingCreation
@@ -140,23 +140,30 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
140
140
  return false;
141
141
  }
142
142
  } else {
143
- // Disable node deletion/creation/edition in offline mode and trigger an error flag instead
143
+ // Disable (bodied)syncBlock node deletion/creation/edition in offline mode and trigger an error flag instead
144
+ var _trackSyncBlocks2 = (0, _trackSyncBlocks3.trackSyncBlocks)(function (node) {
145
+ return node.type.name === 'syncBlock';
146
+ }, tr, state),
147
+ syncBlockRemoved = _trackSyncBlocks2.removed,
148
+ syncBlockAdded = _trackSyncBlocks2.added;
144
149
  var errorFlag = false;
145
- if (isConfirmedSyncBlockDeletion || removed.length > 0) {
150
+ if (isConfirmedSyncBlockDeletion || bodiedSyncBlockRemoved.length > 0 || syncBlockRemoved.length > 0) {
146
151
  errorFlag = _types.FLAG_ID.CANNOT_DELETE_WHEN_OFFLINE;
147
- } else if (added.length > 0) {
152
+ } else if (bodiedSyncBlockAdded.length > 0 || syncBlockAdded.length > 0) {
148
153
  errorFlag = _types.FLAG_ID.CANNOT_CREATE_WHEN_OFFLINE;
149
- } else if ((0, _trackSyncBlocks2.hasEditInSyncBlock)(tr, state)) {
154
+ } else if ((0, _trackSyncBlocks3.hasEditInSyncBlock)(tr, state)) {
150
155
  errorFlag = _types.FLAG_ID.CANNOT_EDIT_WHEN_OFFLINE;
151
156
  }
152
157
  if (errorFlag) {
153
- api === null || api === void 0 || api.core.actions.execute(function (_ref2) {
154
- var tr = _ref2.tr;
155
- tr.setMeta(syncedBlockPluginKey, {
156
- showFlag: errorFlag
158
+ // Use setTimeout to dispatch transaction in next tick and avoid re-entrant dispatch
159
+ setTimeout(function () {
160
+ api === null || api === void 0 || api.core.actions.execute(function (_ref2) {
161
+ var tr = _ref2.tr;
162
+ return tr.setMeta(syncedBlockPluginKey, {
163
+ showFlag: errorFlag
164
+ });
157
165
  });
158
- return tr;
159
- });
166
+ }, 0);
160
167
  return false;
161
168
  }
162
169
  }
@@ -9,9 +9,9 @@ var _utils = require("@atlaskit/editor-prosemirror/utils");
9
9
  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; } } }; }
10
10
  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; } }
11
11
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
12
- var trackSyncBlocks = exports.trackSyncBlocks = function trackSyncBlocks(storeManager, tr, state) {
13
- var sourceSyncBlockRemoved = {};
14
- var sourceSyncBlockAdded = {};
12
+ var trackSyncBlocks = exports.trackSyncBlocks = function trackSyncBlocks(predicate, tr, state) {
13
+ var removed = {};
14
+ var added = {};
15
15
 
16
16
  // and cast to specific step types
17
17
  var replaceSteps = tr.steps.filter(function (step) {
@@ -27,15 +27,16 @@ var trackSyncBlocks = exports.trackSyncBlocks = function trackSyncBlocks(storeMa
27
27
  if (oldStart !== oldEnd) {
28
28
  var deletedSlice = state.doc.slice(oldStart, oldEnd);
29
29
  deletedSlice.content.nodesBetween(0, deletedSlice.content.size, function (node) {
30
- if (storeManager.isSourceBlock(node)) {
31
- if (sourceSyncBlockAdded[node.attrs.localId]) {
30
+ if (predicate(node)) {
31
+ if (added[node.attrs.localId]) {
32
32
  // If a source block added and then removed in the same transaction,
33
33
  // we treat it as no-op.
34
- delete sourceSyncBlockAdded[node.attrs.localId];
34
+ delete added[node.attrs.localId];
35
35
  } else {
36
- sourceSyncBlockRemoved[node.attrs.localId] = node.attrs;
36
+ removed[node.attrs.localId] = node.attrs;
37
37
  }
38
38
  }
39
+
39
40
  // we don't need to go deeper
40
41
  return false;
41
42
  });
@@ -47,13 +48,13 @@ var trackSyncBlocks = exports.trackSyncBlocks = function trackSyncBlocks(storeMa
47
48
  // if only one replace step, we have already checked the entire replaced range above
48
49
  if (step.slice.content.size > 0) {
49
50
  step.slice.content.nodesBetween(0, step.slice.content.size, function (node) {
50
- if (storeManager.isSourceBlock(node)) {
51
- if (sourceSyncBlockRemoved[node.attrs.localId]) {
51
+ if (predicate(node)) {
52
+ if (removed[node.attrs.localId]) {
52
53
  // If a source block is removed and added back in the same transaction,
53
54
  // we treat it as no-op.
54
- delete sourceSyncBlockRemoved[node.attrs.localId];
55
+ delete removed[node.attrs.localId];
55
56
  } else {
56
- sourceSyncBlockAdded[node.attrs.localId] = node.attrs;
57
+ added[node.attrs.localId] = node.attrs;
57
58
  }
58
59
  }
59
60
  // we don't need to go deeper
@@ -62,8 +63,8 @@ var trackSyncBlocks = exports.trackSyncBlocks = function trackSyncBlocks(storeMa
62
63
  }
63
64
  });
64
65
  return {
65
- removed: Object.values(sourceSyncBlockRemoved),
66
- added: Object.values(sourceSyncBlockAdded)
66
+ removed: Object.values(removed),
67
+ added: Object.values(added)
67
68
  };
68
69
  };
69
70
 
@@ -78,8 +78,12 @@ var removeBreakoutMarks = function removeBreakoutMarks(content) {
78
78
  var filteredMarks = node.marks.filter(function (mark) {
79
79
  return mark.type.name !== 'breakout';
80
80
  });
81
- var newNode = node.type.create(node.attrs, node.content, filteredMarks);
82
- nodes.push(newNode);
81
+ if (node.isText) {
82
+ nodes.push(node);
83
+ } else {
84
+ var newNode = node.type.create(node.attrs, node.content, filteredMarks);
85
+ nodes.push(newNode);
86
+ }
83
87
  });
84
88
  return _model.Fragment.from(nodes);
85
89
  };
@@ -99,7 +99,8 @@ var syncedBlockPlugin = exports.syncedBlockPlugin = function syncedBlockPlugin(_
99
99
  },
100
100
  contentComponent: function contentComponent() {
101
101
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_SyncBlockRefresher.SyncBlockRefresher, {
102
- syncBlockStoreManager: syncBlockStore
102
+ syncBlockStoreManager: syncBlockStore,
103
+ api: api
103
104
  }), /*#__PURE__*/_react.default.createElement(_DeleteConfirmationModal.DeleteConfirmationModal, {
104
105
  syncBlockStoreManager: syncBlockStore,
105
106
  api: api
@@ -12,7 +12,6 @@ var _hooks = require("@atlaskit/editor-common/hooks");
12
12
  var _messages = require("@atlaskit/editor-common/messages");
13
13
  var _editorToolbar = require("@atlaskit/editor-toolbar");
14
14
  var _lozenge = _interopRequireDefault(require("@atlaskit/lozenge"));
15
- var _compiled = require("@atlaskit/primitives/compiled");
16
15
  var _utils = require("../pm-plugins/utils/utils");
17
16
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
18
17
  var CreateSyncedBlockDropdownItem = function CreateSyncedBlockDropdownItem(_ref) {
@@ -60,6 +59,13 @@ var CopySyncedBlockDropdownItem = function CopySyncedBlockDropdownItem(_ref2) {
60
59
  var api = _ref2.api;
61
60
  var _useIntl2 = (0, _reactIntlNext.useIntl)(),
62
61
  formatMessage = _useIntl2.formatMessage;
62
+ var _useSharedPluginState2 = (0, _hooks.useSharedPluginStateWithSelector)(api, ['connectivity'], function (states) {
63
+ var _states$connectivityS2;
64
+ return {
65
+ mode: (_states$connectivityS2 = states.connectivityState) === null || _states$connectivityS2 === void 0 ? void 0 : _states$connectivityS2.mode
66
+ };
67
+ }),
68
+ mode = _useSharedPluginState2.mode;
63
69
  var onClick = function onClick() {
64
70
  var _api$core3, _api$core4, _api$blockControls2;
65
71
  api === null || api === void 0 || (_api$core3 = api.core) === null || _api$core3 === void 0 || _api$core3.actions.execute(api === null || api === void 0 ? void 0 : api.syncedBlock.commands.copySyncedBlockReferenceToClipboard());
@@ -71,23 +77,22 @@ var CopySyncedBlockDropdownItem = function CopySyncedBlockDropdownItem(_ref2) {
71
77
  elemBefore: /*#__PURE__*/_react.default.createElement(_editorToolbar.SyncBlocksIcon, {
72
78
  label: ""
73
79
  }),
74
- onClick: onClick
75
- }, /*#__PURE__*/_react.default.createElement(_compiled.Flex, {
76
- alignItems: "center",
77
- gap: "space.050"
78
- }, /*#__PURE__*/_react.default.createElement(_compiled.Text, null, formatMessage(_messages.blockMenuMessages.copySyncedBlock)), /*#__PURE__*/_react.default.createElement(_lozenge.default, {
79
- appearance: "new"
80
- }, formatMessage(_messages.blockMenuMessages.newLozenge))));
80
+ onClick: onClick,
81
+ isDisabled: mode === 'offline',
82
+ elemAfter: /*#__PURE__*/_react.default.createElement(_lozenge.default, {
83
+ appearance: "new"
84
+ }, formatMessage(_messages.blockMenuMessages.newLozenge))
85
+ }, formatMessage(_messages.blockMenuMessages.copySyncedBlock));
81
86
  };
82
87
  var CreateOrCopySyncedBlockDropdownItem = exports.CreateOrCopySyncedBlockDropdownItem = function CreateOrCopySyncedBlockDropdownItem(_ref3) {
83
88
  var api = _ref3.api;
84
- var _useSharedPluginState2 = (0, _hooks.useSharedPluginStateWithSelector)(api, ['blockControls'], function (states) {
89
+ var _useSharedPluginState3 = (0, _hooks.useSharedPluginStateWithSelector)(api, ['blockControls'], function (states) {
85
90
  var _states$blockControls3, _states$blockControls4;
86
91
  return {
87
92
  menuTriggerByNode: (_states$blockControls3 = (_states$blockControls4 = states.blockControlsState) === null || _states$blockControls4 === void 0 ? void 0 : _states$blockControls4.menuTriggerByNode) !== null && _states$blockControls3 !== void 0 ? _states$blockControls3 : undefined
88
93
  };
89
94
  }),
90
- menuTriggerByNode = _useSharedPluginState2.menuTriggerByNode;
95
+ menuTriggerByNode = _useSharedPluginState3.menuTriggerByNode;
91
96
  if ((menuTriggerByNode === null || menuTriggerByNode === void 0 ? void 0 : menuTriggerByNode.nodeType) === 'syncBlock' || (menuTriggerByNode === null || menuTriggerByNode === void 0 ? void 0 : menuTriggerByNode.nodeType) === 'bodiedSyncBlock') {
92
97
  return /*#__PURE__*/_react.default.createElement(CopySyncedBlockDropdownItem, {
93
98
  api: api
@@ -5,23 +5,37 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.SyncBlockRefresher = exports.SYNC_BLOCK_FETCH_INTERVAL = void 0;
7
7
  var _react = require("react");
8
+ var _hooks = require("@atlaskit/editor-common/hooks");
8
9
  var SYNC_BLOCK_FETCH_INTERVAL = exports.SYNC_BLOCK_FETCH_INTERVAL = 3000;
9
10
 
10
11
  // Component that refreshes synced block subscriptions at regular intervals
11
12
  // this is a workaround for the subscription mechanism not being real-time
12
13
  var SyncBlockRefresher = exports.SyncBlockRefresher = function SyncBlockRefresher(_ref) {
13
- var syncBlockStoreManager = _ref.syncBlockStoreManager;
14
+ var syncBlockStoreManager = _ref.syncBlockStoreManager,
15
+ api = _ref.api;
16
+ var _useSharedPluginState = (0, _hooks.useSharedPluginStateWithSelector)(api, ['connectivity'], function (states) {
17
+ var _states$connectivityS;
18
+ return {
19
+ mode: (_states$connectivityS = states.connectivityState) === null || _states$connectivityS === void 0 ? void 0 : _states$connectivityS.mode
20
+ };
21
+ }),
22
+ mode = _useSharedPluginState.mode;
14
23
  (0, _react.useEffect)(function () {
15
- var interval = window.setInterval(function () {
16
- var _document;
17
- // check if document is visible to avoid unnecessary refreshes
18
- if (((_document = document) === null || _document === void 0 ? void 0 : _document.visibilityState) === 'visible') {
19
- syncBlockStoreManager.refreshSubscriptions();
20
- }
21
- }, SYNC_BLOCK_FETCH_INTERVAL);
24
+ var interval = -1;
25
+ if (mode !== 'offline') {
26
+ interval = window.setInterval(function () {
27
+ var _document;
28
+ // check if document is visible to avoid unnecessary refreshes
29
+ if (((_document = document) === null || _document === void 0 ? void 0 : _document.visibilityState) === 'visible') {
30
+ syncBlockStoreManager.refreshSubscriptions();
31
+ }
32
+ }, SYNC_BLOCK_FETCH_INTERVAL);
33
+ } else if (interval !== -1) {
34
+ window.clearInterval(interval);
35
+ }
22
36
  return function () {
23
37
  window.clearInterval(interval);
24
38
  };
25
- }, [syncBlockStoreManager]);
39
+ }, [syncBlockStoreManager, mode]);
26
40
  return null;
27
41
  };
@@ -107,19 +107,19 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
107
107
  return true;
108
108
  }
109
109
  const {
110
- removed,
111
- added
112
- } = trackSyncBlocks(syncBlockStore, tr, state);
110
+ removed: bodiedSyncBlockRemoved,
111
+ added: bodiedSyncBlockAdded
112
+ } = trackSyncBlocks(syncBlockStore.isSourceBlock, tr, state);
113
113
  if (!isOffline) {
114
- if (removed.length > 0) {
114
+ if (bodiedSyncBlockRemoved.length > 0) {
115
115
  // If there are source sync blocks being removed, and we need to confirm with user before deleting,
116
116
  // we block the transaction here, and wait for user confirmation to proceed with deletion.
117
117
  // See editor-common/src/sync-block/sync-block-store-manager.ts for how we handle user confirmation and
118
118
  // proceed with deletion.
119
- syncBlockStore.deleteSyncBlocksWithConfirmation(tr, removed);
119
+ syncBlockStore.deleteSyncBlocksWithConfirmation(tr, bodiedSyncBlockRemoved);
120
120
  return false;
121
121
  }
122
- if (added.length > 0) {
122
+ if (bodiedSyncBlockAdded.length > 0) {
123
123
  // If there is bodiedSyncBlock node addition and it's waiting for the result of saving the node to backend (syncBlockStore.hasPendingCreation()),
124
124
  // we need to intercept the transaction and save it in insert callback so that we only insert it to the document when backend call if backend call is successful
125
125
  // The callback will be evoked by in SourceSyncBlockStoreManager.commitPendingCreation
@@ -133,24 +133,30 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
133
133
  return false;
134
134
  }
135
135
  } else {
136
- // Disable node deletion/creation/edition in offline mode and trigger an error flag instead
136
+ // Disable (bodied)syncBlock node deletion/creation/edition in offline mode and trigger an error flag instead
137
+ const {
138
+ removed: syncBlockRemoved,
139
+ added: syncBlockAdded
140
+ } = trackSyncBlocks(node => node.type.name === 'syncBlock', tr, state);
137
141
  let errorFlag = false;
138
- if (isConfirmedSyncBlockDeletion || removed.length > 0) {
142
+ if (isConfirmedSyncBlockDeletion || bodiedSyncBlockRemoved.length > 0 || syncBlockRemoved.length > 0) {
139
143
  errorFlag = FLAG_ID.CANNOT_DELETE_WHEN_OFFLINE;
140
- } else if (added.length > 0) {
144
+ } else if (bodiedSyncBlockAdded.length > 0 || syncBlockAdded.length > 0) {
141
145
  errorFlag = FLAG_ID.CANNOT_CREATE_WHEN_OFFLINE;
142
146
  } else if (hasEditInSyncBlock(tr, state)) {
143
147
  errorFlag = FLAG_ID.CANNOT_EDIT_WHEN_OFFLINE;
144
148
  }
145
149
  if (errorFlag) {
146
- api === null || api === void 0 ? void 0 : api.core.actions.execute(({
147
- tr
148
- }) => {
149
- tr.setMeta(syncedBlockPluginKey, {
150
- showFlag: errorFlag
150
+ // Use setTimeout to dispatch transaction in next tick and avoid re-entrant dispatch
151
+ setTimeout(() => {
152
+ api === null || api === void 0 ? void 0 : api.core.actions.execute(({
153
+ tr
154
+ }) => {
155
+ return tr.setMeta(syncedBlockPluginKey, {
156
+ showFlag: errorFlag
157
+ });
151
158
  });
152
- return tr;
153
- });
159
+ }, 0);
154
160
  return false;
155
161
  }
156
162
  }
@@ -1,8 +1,8 @@
1
1
  import { ReplaceAroundStep, ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
2
2
  import { findParentNodeOfTypeClosestToPos } from '@atlaskit/editor-prosemirror/utils';
3
- export const trackSyncBlocks = (storeManager, tr, state) => {
4
- const sourceSyncBlockRemoved = {};
5
- const sourceSyncBlockAdded = {};
3
+ export const trackSyncBlocks = (predicate, tr, state) => {
4
+ const removed = {};
5
+ const added = {};
6
6
 
7
7
  // and cast to specific step types
8
8
  const replaceSteps = tr.steps.filter(step => step instanceof ReplaceStep || step instanceof ReplaceAroundStep);
@@ -18,15 +18,16 @@ export const trackSyncBlocks = (storeManager, tr, state) => {
18
18
  if (oldStart !== oldEnd) {
19
19
  const deletedSlice = state.doc.slice(oldStart, oldEnd);
20
20
  deletedSlice.content.nodesBetween(0, deletedSlice.content.size, node => {
21
- if (storeManager.isSourceBlock(node)) {
22
- if (sourceSyncBlockAdded[node.attrs.localId]) {
21
+ if (predicate(node)) {
22
+ if (added[node.attrs.localId]) {
23
23
  // If a source block added and then removed in the same transaction,
24
24
  // we treat it as no-op.
25
- delete sourceSyncBlockAdded[node.attrs.localId];
25
+ delete added[node.attrs.localId];
26
26
  } else {
27
- sourceSyncBlockRemoved[node.attrs.localId] = node.attrs;
27
+ removed[node.attrs.localId] = node.attrs;
28
28
  }
29
29
  }
30
+
30
31
  // we don't need to go deeper
31
32
  return false;
32
33
  });
@@ -38,13 +39,13 @@ export const trackSyncBlocks = (storeManager, tr, state) => {
38
39
  // if only one replace step, we have already checked the entire replaced range above
39
40
  if (step.slice.content.size > 0) {
40
41
  step.slice.content.nodesBetween(0, step.slice.content.size, node => {
41
- if (storeManager.isSourceBlock(node)) {
42
- if (sourceSyncBlockRemoved[node.attrs.localId]) {
42
+ if (predicate(node)) {
43
+ if (removed[node.attrs.localId]) {
43
44
  // If a source block is removed and added back in the same transaction,
44
45
  // we treat it as no-op.
45
- delete sourceSyncBlockRemoved[node.attrs.localId];
46
+ delete removed[node.attrs.localId];
46
47
  } else {
47
- sourceSyncBlockAdded[node.attrs.localId] = node.attrs;
48
+ added[node.attrs.localId] = node.attrs;
48
49
  }
49
50
  }
50
51
  // we don't need to go deeper
@@ -53,8 +54,8 @@ export const trackSyncBlocks = (storeManager, tr, state) => {
53
54
  }
54
55
  });
55
56
  return {
56
- removed: Object.values(sourceSyncBlockRemoved),
57
- added: Object.values(sourceSyncBlockAdded)
57
+ removed: Object.values(removed),
58
+ added: Object.values(added)
58
59
  };
59
60
  };
60
61
 
@@ -72,8 +72,12 @@ const removeBreakoutMarks = content => {
72
72
  // we only need to recurse at the top level, because breakout has to be on a top level
73
73
  content.forEach(node => {
74
74
  const filteredMarks = node.marks.filter(mark => mark.type.name !== 'breakout');
75
- const newNode = node.type.create(node.attrs, node.content, filteredMarks);
76
- nodes.push(newNode);
75
+ if (node.isText) {
76
+ nodes.push(node);
77
+ } else {
78
+ const newNode = node.type.create(node.attrs, node.content, filteredMarks);
79
+ nodes.push(newNode);
80
+ }
77
81
  });
78
82
  return Fragment.from(nodes);
79
83
  };
@@ -81,7 +81,8 @@ export const syncedBlockPlugin = ({
81
81
  },
82
82
  contentComponent: () => {
83
83
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(SyncBlockRefresher, {
84
- syncBlockStoreManager: syncBlockStore
84
+ syncBlockStoreManager: syncBlockStore,
85
+ api: api
85
86
  }), /*#__PURE__*/React.createElement(DeleteConfirmationModal, {
86
87
  syncBlockStoreManager: syncBlockStore,
87
88
  api: api
@@ -4,7 +4,6 @@ import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks'
4
4
  import { blockMenuMessages } from '@atlaskit/editor-common/messages';
5
5
  import { SyncBlocksIcon, ToolbarDropdownItem } from '@atlaskit/editor-toolbar';
6
6
  import Lozenge from '@atlaskit/lozenge';
7
- import { Flex, Text } from '@atlaskit/primitives/compiled';
8
7
  import { canBeConvertedToSyncBlock } from '../pm-plugins/utils/utils';
9
8
  const CreateSyncedBlockDropdownItem = ({
10
9
  api
@@ -54,6 +53,14 @@ const CopySyncedBlockDropdownItem = ({
54
53
  const {
55
54
  formatMessage
56
55
  } = useIntl();
56
+ const {
57
+ mode
58
+ } = useSharedPluginStateWithSelector(api, ['connectivity'], states => {
59
+ var _states$connectivityS2;
60
+ return {
61
+ mode: (_states$connectivityS2 = states.connectivityState) === null || _states$connectivityS2 === void 0 ? void 0 : _states$connectivityS2.mode
62
+ };
63
+ });
57
64
  const onClick = () => {
58
65
  var _api$core3, _api$core4, _api$blockControls2, _api$blockControls2$c;
59
66
  api === null || api === void 0 ? void 0 : (_api$core3 = api.core) === null || _api$core3 === void 0 ? void 0 : _api$core3.actions.execute(api === null || api === void 0 ? void 0 : api.syncedBlock.commands.copySyncedBlockReferenceToClipboard());
@@ -65,13 +72,12 @@ const CopySyncedBlockDropdownItem = ({
65
72
  elemBefore: /*#__PURE__*/React.createElement(SyncBlocksIcon, {
66
73
  label: ""
67
74
  }),
68
- onClick: onClick
69
- }, /*#__PURE__*/React.createElement(Flex, {
70
- alignItems: "center",
71
- gap: "space.050"
72
- }, /*#__PURE__*/React.createElement(Text, null, formatMessage(blockMenuMessages.copySyncedBlock)), /*#__PURE__*/React.createElement(Lozenge, {
73
- appearance: "new"
74
- }, formatMessage(blockMenuMessages.newLozenge))));
75
+ onClick: onClick,
76
+ isDisabled: mode === 'offline',
77
+ elemAfter: /*#__PURE__*/React.createElement(Lozenge, {
78
+ appearance: "new"
79
+ }, formatMessage(blockMenuMessages.newLozenge))
80
+ }, formatMessage(blockMenuMessages.copySyncedBlock));
75
81
  };
76
82
  export const CreateOrCopySyncedBlockDropdownItem = ({
77
83
  api
@@ -1,22 +1,37 @@
1
1
  import { useEffect } from 'react';
2
+ import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
2
3
  export const SYNC_BLOCK_FETCH_INTERVAL = 3000;
3
4
 
4
5
  // Component that refreshes synced block subscriptions at regular intervals
5
6
  // this is a workaround for the subscription mechanism not being real-time
6
7
  export const SyncBlockRefresher = ({
7
- syncBlockStoreManager
8
+ syncBlockStoreManager,
9
+ api
8
10
  }) => {
11
+ const {
12
+ mode
13
+ } = useSharedPluginStateWithSelector(api, ['connectivity'], states => {
14
+ var _states$connectivityS;
15
+ return {
16
+ mode: (_states$connectivityS = states.connectivityState) === null || _states$connectivityS === void 0 ? void 0 : _states$connectivityS.mode
17
+ };
18
+ });
9
19
  useEffect(() => {
10
- const interval = window.setInterval(() => {
11
- var _document;
12
- // check if document is visible to avoid unnecessary refreshes
13
- if (((_document = document) === null || _document === void 0 ? void 0 : _document.visibilityState) === 'visible') {
14
- syncBlockStoreManager.refreshSubscriptions();
15
- }
16
- }, SYNC_BLOCK_FETCH_INTERVAL);
20
+ let interval = -1;
21
+ if (mode !== 'offline') {
22
+ interval = window.setInterval(() => {
23
+ var _document;
24
+ // check if document is visible to avoid unnecessary refreshes
25
+ if (((_document = document) === null || _document === void 0 ? void 0 : _document.visibilityState) === 'visible') {
26
+ syncBlockStoreManager.refreshSubscriptions();
27
+ }
28
+ }, SYNC_BLOCK_FETCH_INTERVAL);
29
+ } else if (interval !== -1) {
30
+ window.clearInterval(interval);
31
+ }
17
32
  return () => {
18
33
  window.clearInterval(interval);
19
34
  };
20
- }, [syncBlockStoreManager]);
35
+ }, [syncBlockStoreManager, mode]);
21
36
  return null;
22
37
  };
@@ -107,19 +107,19 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
107
107
  if (!tr.docChanged || !(syncBlockStore !== null && syncBlockStore !== void 0 && syncBlockStore.requireConfirmationBeforeDelete()) && !syncBlockStore.hasPendingCreation() || Boolean(tr.getMeta('isRemote')) || Boolean(tr.getMeta('isCommitSyncBlockCreation')) || !isOffline && isConfirmedSyncBlockDeletion) {
108
108
  return true;
109
109
  }
110
- var _trackSyncBlocks = trackSyncBlocks(syncBlockStore, tr, state),
111
- removed = _trackSyncBlocks.removed,
112
- added = _trackSyncBlocks.added;
110
+ var _trackSyncBlocks = trackSyncBlocks(syncBlockStore.isSourceBlock, tr, state),
111
+ bodiedSyncBlockRemoved = _trackSyncBlocks.removed,
112
+ bodiedSyncBlockAdded = _trackSyncBlocks.added;
113
113
  if (!isOffline) {
114
- if (removed.length > 0) {
114
+ if (bodiedSyncBlockRemoved.length > 0) {
115
115
  // If there are source sync blocks being removed, and we need to confirm with user before deleting,
116
116
  // we block the transaction here, and wait for user confirmation to proceed with deletion.
117
117
  // See editor-common/src/sync-block/sync-block-store-manager.ts for how we handle user confirmation and
118
118
  // proceed with deletion.
119
- syncBlockStore.deleteSyncBlocksWithConfirmation(tr, removed);
119
+ syncBlockStore.deleteSyncBlocksWithConfirmation(tr, bodiedSyncBlockRemoved);
120
120
  return false;
121
121
  }
122
- if (added.length > 0) {
122
+ if (bodiedSyncBlockAdded.length > 0) {
123
123
  // If there is bodiedSyncBlock node addition and it's waiting for the result of saving the node to backend (syncBlockStore.hasPendingCreation()),
124
124
  // we need to intercept the transaction and save it in insert callback so that we only insert it to the document when backend call if backend call is successful
125
125
  // The callback will be evoked by in SourceSyncBlockStoreManager.commitPendingCreation
@@ -133,23 +133,30 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
133
133
  return false;
134
134
  }
135
135
  } else {
136
- // Disable node deletion/creation/edition in offline mode and trigger an error flag instead
136
+ // Disable (bodied)syncBlock node deletion/creation/edition in offline mode and trigger an error flag instead
137
+ var _trackSyncBlocks2 = trackSyncBlocks(function (node) {
138
+ return node.type.name === 'syncBlock';
139
+ }, tr, state),
140
+ syncBlockRemoved = _trackSyncBlocks2.removed,
141
+ syncBlockAdded = _trackSyncBlocks2.added;
137
142
  var errorFlag = false;
138
- if (isConfirmedSyncBlockDeletion || removed.length > 0) {
143
+ if (isConfirmedSyncBlockDeletion || bodiedSyncBlockRemoved.length > 0 || syncBlockRemoved.length > 0) {
139
144
  errorFlag = FLAG_ID.CANNOT_DELETE_WHEN_OFFLINE;
140
- } else if (added.length > 0) {
145
+ } else if (bodiedSyncBlockAdded.length > 0 || syncBlockAdded.length > 0) {
141
146
  errorFlag = FLAG_ID.CANNOT_CREATE_WHEN_OFFLINE;
142
147
  } else if (hasEditInSyncBlock(tr, state)) {
143
148
  errorFlag = FLAG_ID.CANNOT_EDIT_WHEN_OFFLINE;
144
149
  }
145
150
  if (errorFlag) {
146
- api === null || api === void 0 || api.core.actions.execute(function (_ref2) {
147
- var tr = _ref2.tr;
148
- tr.setMeta(syncedBlockPluginKey, {
149
- showFlag: errorFlag
151
+ // Use setTimeout to dispatch transaction in next tick and avoid re-entrant dispatch
152
+ setTimeout(function () {
153
+ api === null || api === void 0 || api.core.actions.execute(function (_ref2) {
154
+ var tr = _ref2.tr;
155
+ return tr.setMeta(syncedBlockPluginKey, {
156
+ showFlag: errorFlag
157
+ });
150
158
  });
151
- return tr;
152
- });
159
+ }, 0);
153
160
  return false;
154
161
  }
155
162
  }
@@ -3,9 +3,9 @@ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r)
3
3
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
4
4
  import { ReplaceAroundStep, ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
5
5
  import { findParentNodeOfTypeClosestToPos } from '@atlaskit/editor-prosemirror/utils';
6
- export var trackSyncBlocks = function trackSyncBlocks(storeManager, tr, state) {
7
- var sourceSyncBlockRemoved = {};
8
- var sourceSyncBlockAdded = {};
6
+ export var trackSyncBlocks = function trackSyncBlocks(predicate, tr, state) {
7
+ var removed = {};
8
+ var added = {};
9
9
 
10
10
  // and cast to specific step types
11
11
  var replaceSteps = tr.steps.filter(function (step) {
@@ -21,15 +21,16 @@ export var trackSyncBlocks = function trackSyncBlocks(storeManager, tr, state) {
21
21
  if (oldStart !== oldEnd) {
22
22
  var deletedSlice = state.doc.slice(oldStart, oldEnd);
23
23
  deletedSlice.content.nodesBetween(0, deletedSlice.content.size, function (node) {
24
- if (storeManager.isSourceBlock(node)) {
25
- if (sourceSyncBlockAdded[node.attrs.localId]) {
24
+ if (predicate(node)) {
25
+ if (added[node.attrs.localId]) {
26
26
  // If a source block added and then removed in the same transaction,
27
27
  // we treat it as no-op.
28
- delete sourceSyncBlockAdded[node.attrs.localId];
28
+ delete added[node.attrs.localId];
29
29
  } else {
30
- sourceSyncBlockRemoved[node.attrs.localId] = node.attrs;
30
+ removed[node.attrs.localId] = node.attrs;
31
31
  }
32
32
  }
33
+
33
34
  // we don't need to go deeper
34
35
  return false;
35
36
  });
@@ -41,13 +42,13 @@ export var trackSyncBlocks = function trackSyncBlocks(storeManager, tr, state) {
41
42
  // if only one replace step, we have already checked the entire replaced range above
42
43
  if (step.slice.content.size > 0) {
43
44
  step.slice.content.nodesBetween(0, step.slice.content.size, function (node) {
44
- if (storeManager.isSourceBlock(node)) {
45
- if (sourceSyncBlockRemoved[node.attrs.localId]) {
45
+ if (predicate(node)) {
46
+ if (removed[node.attrs.localId]) {
46
47
  // If a source block is removed and added back in the same transaction,
47
48
  // we treat it as no-op.
48
- delete sourceSyncBlockRemoved[node.attrs.localId];
49
+ delete removed[node.attrs.localId];
49
50
  } else {
50
- sourceSyncBlockAdded[node.attrs.localId] = node.attrs;
51
+ added[node.attrs.localId] = node.attrs;
51
52
  }
52
53
  }
53
54
  // we don't need to go deeper
@@ -56,8 +57,8 @@ export var trackSyncBlocks = function trackSyncBlocks(storeManager, tr, state) {
56
57
  }
57
58
  });
58
59
  return {
59
- removed: Object.values(sourceSyncBlockRemoved),
60
- added: Object.values(sourceSyncBlockAdded)
60
+ removed: Object.values(removed),
61
+ added: Object.values(added)
61
62
  };
62
63
  };
63
64
 
@@ -72,8 +72,12 @@ var removeBreakoutMarks = function removeBreakoutMarks(content) {
72
72
  var filteredMarks = node.marks.filter(function (mark) {
73
73
  return mark.type.name !== 'breakout';
74
74
  });
75
- var newNode = node.type.create(node.attrs, node.content, filteredMarks);
76
- nodes.push(newNode);
75
+ if (node.isText) {
76
+ nodes.push(node);
77
+ } else {
78
+ var newNode = node.type.create(node.attrs, node.content, filteredMarks);
79
+ nodes.push(newNode);
80
+ }
77
81
  });
78
82
  return Fragment.from(nodes);
79
83
  };
@@ -92,7 +92,8 @@ export var syncedBlockPlugin = function syncedBlockPlugin(_ref) {
92
92
  },
93
93
  contentComponent: function contentComponent() {
94
94
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(SyncBlockRefresher, {
95
- syncBlockStoreManager: syncBlockStore
95
+ syncBlockStoreManager: syncBlockStore,
96
+ api: api
96
97
  }), /*#__PURE__*/React.createElement(DeleteConfirmationModal, {
97
98
  syncBlockStoreManager: syncBlockStore,
98
99
  api: api
@@ -4,7 +4,6 @@ import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks'
4
4
  import { blockMenuMessages } from '@atlaskit/editor-common/messages';
5
5
  import { SyncBlocksIcon, ToolbarDropdownItem } from '@atlaskit/editor-toolbar';
6
6
  import Lozenge from '@atlaskit/lozenge';
7
- import { Flex, Text } from '@atlaskit/primitives/compiled';
8
7
  import { canBeConvertedToSyncBlock } from '../pm-plugins/utils/utils';
9
8
  var CreateSyncedBlockDropdownItem = function CreateSyncedBlockDropdownItem(_ref) {
10
9
  var api = _ref.api;
@@ -51,6 +50,13 @@ var CopySyncedBlockDropdownItem = function CopySyncedBlockDropdownItem(_ref2) {
51
50
  var api = _ref2.api;
52
51
  var _useIntl2 = useIntl(),
53
52
  formatMessage = _useIntl2.formatMessage;
53
+ var _useSharedPluginState2 = useSharedPluginStateWithSelector(api, ['connectivity'], function (states) {
54
+ var _states$connectivityS2;
55
+ return {
56
+ mode: (_states$connectivityS2 = states.connectivityState) === null || _states$connectivityS2 === void 0 ? void 0 : _states$connectivityS2.mode
57
+ };
58
+ }),
59
+ mode = _useSharedPluginState2.mode;
54
60
  var onClick = function onClick() {
55
61
  var _api$core3, _api$core4, _api$blockControls2;
56
62
  api === null || api === void 0 || (_api$core3 = api.core) === null || _api$core3 === void 0 || _api$core3.actions.execute(api === null || api === void 0 ? void 0 : api.syncedBlock.commands.copySyncedBlockReferenceToClipboard());
@@ -62,23 +68,22 @@ var CopySyncedBlockDropdownItem = function CopySyncedBlockDropdownItem(_ref2) {
62
68
  elemBefore: /*#__PURE__*/React.createElement(SyncBlocksIcon, {
63
69
  label: ""
64
70
  }),
65
- onClick: onClick
66
- }, /*#__PURE__*/React.createElement(Flex, {
67
- alignItems: "center",
68
- gap: "space.050"
69
- }, /*#__PURE__*/React.createElement(Text, null, formatMessage(blockMenuMessages.copySyncedBlock)), /*#__PURE__*/React.createElement(Lozenge, {
70
- appearance: "new"
71
- }, formatMessage(blockMenuMessages.newLozenge))));
71
+ onClick: onClick,
72
+ isDisabled: mode === 'offline',
73
+ elemAfter: /*#__PURE__*/React.createElement(Lozenge, {
74
+ appearance: "new"
75
+ }, formatMessage(blockMenuMessages.newLozenge))
76
+ }, formatMessage(blockMenuMessages.copySyncedBlock));
72
77
  };
73
78
  export var CreateOrCopySyncedBlockDropdownItem = function CreateOrCopySyncedBlockDropdownItem(_ref3) {
74
79
  var api = _ref3.api;
75
- var _useSharedPluginState2 = useSharedPluginStateWithSelector(api, ['blockControls'], function (states) {
80
+ var _useSharedPluginState3 = useSharedPluginStateWithSelector(api, ['blockControls'], function (states) {
76
81
  var _states$blockControls3, _states$blockControls4;
77
82
  return {
78
83
  menuTriggerByNode: (_states$blockControls3 = (_states$blockControls4 = states.blockControlsState) === null || _states$blockControls4 === void 0 ? void 0 : _states$blockControls4.menuTriggerByNode) !== null && _states$blockControls3 !== void 0 ? _states$blockControls3 : undefined
79
84
  };
80
85
  }),
81
- menuTriggerByNode = _useSharedPluginState2.menuTriggerByNode;
86
+ menuTriggerByNode = _useSharedPluginState3.menuTriggerByNode;
82
87
  if ((menuTriggerByNode === null || menuTriggerByNode === void 0 ? void 0 : menuTriggerByNode.nodeType) === 'syncBlock' || (menuTriggerByNode === null || menuTriggerByNode === void 0 ? void 0 : menuTriggerByNode.nodeType) === 'bodiedSyncBlock') {
83
88
  return /*#__PURE__*/React.createElement(CopySyncedBlockDropdownItem, {
84
89
  api: api
@@ -1,21 +1,35 @@
1
1
  import { useEffect } from 'react';
2
+ import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
2
3
  export var SYNC_BLOCK_FETCH_INTERVAL = 3000;
3
4
 
4
5
  // Component that refreshes synced block subscriptions at regular intervals
5
6
  // this is a workaround for the subscription mechanism not being real-time
6
7
  export var SyncBlockRefresher = function SyncBlockRefresher(_ref) {
7
- var syncBlockStoreManager = _ref.syncBlockStoreManager;
8
+ var syncBlockStoreManager = _ref.syncBlockStoreManager,
9
+ api = _ref.api;
10
+ var _useSharedPluginState = useSharedPluginStateWithSelector(api, ['connectivity'], function (states) {
11
+ var _states$connectivityS;
12
+ return {
13
+ mode: (_states$connectivityS = states.connectivityState) === null || _states$connectivityS === void 0 ? void 0 : _states$connectivityS.mode
14
+ };
15
+ }),
16
+ mode = _useSharedPluginState.mode;
8
17
  useEffect(function () {
9
- var interval = window.setInterval(function () {
10
- var _document;
11
- // check if document is visible to avoid unnecessary refreshes
12
- if (((_document = document) === null || _document === void 0 ? void 0 : _document.visibilityState) === 'visible') {
13
- syncBlockStoreManager.refreshSubscriptions();
14
- }
15
- }, SYNC_BLOCK_FETCH_INTERVAL);
18
+ var interval = -1;
19
+ if (mode !== 'offline') {
20
+ interval = window.setInterval(function () {
21
+ var _document;
22
+ // check if document is visible to avoid unnecessary refreshes
23
+ if (((_document = document) === null || _document === void 0 ? void 0 : _document.visibilityState) === 'visible') {
24
+ syncBlockStoreManager.refreshSubscriptions();
25
+ }
26
+ }, SYNC_BLOCK_FETCH_INTERVAL);
27
+ } else if (interval !== -1) {
28
+ window.clearInterval(interval);
29
+ }
16
30
  return function () {
17
31
  window.clearInterval(interval);
18
32
  };
19
- }, [syncBlockStoreManager]);
33
+ }, [syncBlockStoreManager, mode]);
20
34
  return null;
21
35
  };
@@ -1,7 +1,7 @@
1
+ import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
1
2
  import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/state';
2
- import type { SyncBlockStoreManager } from '@atlaskit/editor-synced-block-provider';
3
3
  import type { SyncBlockAttrs } from '../../syncedBlockPluginType';
4
- export declare const trackSyncBlocks: (storeManager: SyncBlockStoreManager, tr: Transaction, state: EditorState) => {
4
+ export declare const trackSyncBlocks: (predicate: (node: PMNode) => boolean, tr: Transaction, state: EditorState) => {
5
5
  removed: SyncBlockAttrs[];
6
6
  added: SyncBlockAttrs[];
7
7
  };
@@ -1,5 +1,8 @@
1
+ import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
1
2
  import type { SyncBlockStoreManager } from '@atlaskit/editor-synced-block-provider';
3
+ import type { SyncedBlockPlugin } from '../syncedBlockPluginType';
2
4
  export declare const SYNC_BLOCK_FETCH_INTERVAL = 3000;
3
- export declare const SyncBlockRefresher: ({ syncBlockStoreManager, }: {
5
+ export declare const SyncBlockRefresher: ({ syncBlockStoreManager, api, }: {
6
+ api?: ExtractInjectionAPI<SyncedBlockPlugin>;
4
7
  syncBlockStoreManager: SyncBlockStoreManager;
5
8
  }) => null;
@@ -1,7 +1,7 @@
1
+ import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
1
2
  import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/state';
2
- import type { SyncBlockStoreManager } from '@atlaskit/editor-synced-block-provider';
3
3
  import type { SyncBlockAttrs } from '../../syncedBlockPluginType';
4
- export declare const trackSyncBlocks: (storeManager: SyncBlockStoreManager, tr: Transaction, state: EditorState) => {
4
+ export declare const trackSyncBlocks: (predicate: (node: PMNode) => boolean, tr: Transaction, state: EditorState) => {
5
5
  removed: SyncBlockAttrs[];
6
6
  added: SyncBlockAttrs[];
7
7
  };
@@ -1,5 +1,8 @@
1
+ import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
1
2
  import type { SyncBlockStoreManager } from '@atlaskit/editor-synced-block-provider';
3
+ import type { SyncedBlockPlugin } from '../syncedBlockPluginType';
2
4
  export declare const SYNC_BLOCK_FETCH_INTERVAL = 3000;
3
- export declare const SyncBlockRefresher: ({ syncBlockStoreManager, }: {
5
+ export declare const SyncBlockRefresher: ({ syncBlockStoreManager, api, }: {
6
+ api?: ExtractInjectionAPI<SyncedBlockPlugin>;
4
7
  syncBlockStoreManager: SyncBlockStoreManager;
5
8
  }) => null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-synced-block",
3
- "version": "4.2.8",
3
+ "version": "4.2.10",
4
4
  "description": "SyncedBlock plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -50,13 +50,13 @@
50
50
  "@atlaskit/modal-dialog": "^14.7.0",
51
51
  "@atlaskit/primitives": "^16.1.0",
52
52
  "@atlaskit/tokens": "8.0.0",
53
- "@atlaskit/tooltip": "^20.8.0",
53
+ "@atlaskit/tooltip": "^20.9.0",
54
54
  "@atlaskit/visually-hidden": "^3.0.0",
55
55
  "@babel/runtime": "^7.0.0",
56
56
  "react-intl-next": "npm:react-intl@^5.18.1"
57
57
  },
58
58
  "peerDependencies": {
59
- "@atlaskit/editor-common": "^110.30.0",
59
+ "@atlaskit/editor-common": "^110.31.0",
60
60
  "react": "^18.2.0"
61
61
  },
62
62
  "devDependencies": {