@atlaskit/editor-plugin-synced-block 8.3.3 → 8.3.4
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/AGENTS.md +1 -2
- package/CHANGELOG.md +8 -0
- package/dist/cjs/nodeviews/bodiedSyncedBlock.js +7 -25
- package/dist/cjs/nodeviews/syncedBlock.js +1 -4
- package/dist/cjs/pm-plugins/main.js +54 -60
- package/dist/cjs/pm-plugins/menu-and-toolbar-experiences.js +10 -19
- package/dist/cjs/pm-plugins/utils/utils.js +3 -10
- package/dist/cjs/syncedBlockPlugin.js +1 -7
- package/dist/cjs/ui/DeleteConfirmationModal.js +29 -93
- package/dist/cjs/ui/SyncBlockLabel.js +1 -4
- package/dist/cjs/ui/SyncedLocationDropdown.js +2 -2
- package/dist/cjs/ui/floating-toolbar.js +1 -2
- package/dist/cjs/ui/quick-insert.js +2 -3
- package/dist/es2019/nodeviews/bodiedSyncedBlock.js +7 -23
- package/dist/es2019/nodeviews/syncedBlock.js +1 -4
- package/dist/es2019/pm-plugins/main.js +42 -48
- package/dist/es2019/pm-plugins/menu-and-toolbar-experiences.js +7 -19
- package/dist/es2019/pm-plugins/utils/utils.js +3 -11
- package/dist/es2019/syncedBlockPlugin.js +1 -7
- package/dist/es2019/ui/DeleteConfirmationModal.js +36 -77
- package/dist/es2019/ui/SyncBlockLabel.js +1 -4
- package/dist/es2019/ui/SyncedLocationDropdown.js +2 -2
- package/dist/es2019/ui/floating-toolbar.js +1 -2
- package/dist/es2019/ui/quick-insert.js +2 -2
- package/dist/esm/nodeviews/bodiedSyncedBlock.js +7 -25
- package/dist/esm/nodeviews/syncedBlock.js +1 -4
- package/dist/esm/pm-plugins/main.js +54 -60
- package/dist/esm/pm-plugins/menu-and-toolbar-experiences.js +10 -19
- package/dist/esm/pm-plugins/utils/utils.js +3 -11
- package/dist/esm/syncedBlockPlugin.js +1 -7
- package/dist/esm/ui/DeleteConfirmationModal.js +29 -93
- package/dist/esm/ui/SyncBlockLabel.js +1 -4
- package/dist/esm/ui/SyncedLocationDropdown.js +2 -2
- package/dist/esm/ui/floating-toolbar.js +1 -2
- package/dist/esm/ui/quick-insert.js +2 -3
- package/dist/types/nodeviews/bodiedSyncedBlock.d.ts +1 -3
- package/dist/types-ts4.5/nodeviews/bodiedSyncedBlock.d.ts +1 -3
- package/docs/0-intro.tsx +1 -1
- package/package.json +2 -17
- package/dist/cjs/nodeviews/bodiedSyncBlockNodeWithToDOMFixed.js +0 -35
- package/dist/es2019/nodeviews/bodiedSyncBlockNodeWithToDOMFixed.js +0 -27
- package/dist/esm/nodeviews/bodiedSyncBlockNodeWithToDOMFixed.js +0 -28
- package/dist/types/nodeviews/bodiedSyncBlockNodeWithToDOMFixed.d.ts +0 -6
- package/dist/types-ts4.5/nodeviews/bodiedSyncBlockNodeWithToDOMFixed.d.ts +0 -6
package/AGENTS.md
CHANGED
|
@@ -35,8 +35,7 @@ src/
|
|
|
35
35
|
├── nodeviews/
|
|
36
36
|
│ ├── syncedBlock.tsx # NodeView for reference (syncBlock) — read-only, fetches from BE
|
|
37
37
|
│ ├── lazySyncedBlock.tsx # Lazy-loaded wrapper for syncedBlock (EDITOR-6928)
|
|
38
|
-
│
|
|
39
|
-
│ └── bodiedSyncBlockNodeWithToDOMFixed.ts # DOM serialization fix variant (experiment-gated)
|
|
38
|
+
│ └── bodiedSyncedBlock.tsx # NodeView for source (bodiedSyncBlock) — nested editor with content
|
|
40
39
|
├── pm-plugins/
|
|
41
40
|
│ ├── main.ts # Core state machine: lifecycle, creation, deletion, cache,
|
|
42
41
|
│ │ status decoration apply path (gated by editor_synced_block_perf)
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-synced-block
|
|
2
2
|
|
|
3
|
+
## 8.3.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`4c459a2718b67`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/4c459a2718b67) -
|
|
8
|
+
Clean up synced block feature gates
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
|
|
3
11
|
## 8.3.3
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
|
@@ -17,7 +17,6 @@ var _reactNodeView = _interopRequireDefault(require("@atlaskit/editor-common/rea
|
|
|
17
17
|
var _syncBlock = require("@atlaskit/editor-common/sync-block");
|
|
18
18
|
var _editorPluginConnectivity = require("@atlaskit/editor-plugin-connectivity");
|
|
19
19
|
var _model = require("@atlaskit/editor-prosemirror/model");
|
|
20
|
-
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
21
20
|
var _BodiedSyncBlockWrapper = require("../ui/BodiedSyncBlockWrapper");
|
|
22
21
|
var _SyncBlockLabel = require("../ui/SyncBlockLabel");
|
|
23
22
|
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
|
|
@@ -172,14 +171,13 @@ var toDOM = function toDOM(node) {
|
|
|
172
171
|
}, 0]];
|
|
173
172
|
};
|
|
174
173
|
var BodiedSyncBlock = exports.BodiedSyncBlock = /*#__PURE__*/function () {
|
|
175
|
-
function BodiedSyncBlock(node, view, getPos, api, nodeViewPortalProviderAPI
|
|
174
|
+
function BodiedSyncBlock(node, view, getPos, api, nodeViewPortalProviderAPI) {
|
|
176
175
|
var _this4 = this;
|
|
177
176
|
(0, _classCallCheck2.default)(this, BodiedSyncBlock);
|
|
178
177
|
this.node = node;
|
|
179
178
|
this.view = view;
|
|
180
179
|
this.getPos = getPos;
|
|
181
180
|
this.api = api;
|
|
182
|
-
this.syncBlockStore = syncBlockStore;
|
|
183
181
|
this.nodeViewPortalProviderAPI = nodeViewPortalProviderAPI;
|
|
184
182
|
var _DOMSerializer$render2 = _model.DOMSerializer.renderSpec(document, toDOM(this.node)),
|
|
185
183
|
dom = _DOMSerializer$render2.dom,
|
|
@@ -205,12 +203,8 @@ var BodiedSyncBlock = exports.BodiedSyncBlock = /*#__PURE__*/function () {
|
|
|
205
203
|
this.handleConnectivityModeChange();
|
|
206
204
|
this.handleViewModeChange();
|
|
207
205
|
|
|
208
|
-
//
|
|
209
|
-
//
|
|
210
|
-
if (!(0, _platformFeatureFlags.fg)('platform_synced_block_update_refactor')) {
|
|
211
|
-
var _this$syncedBlockStor;
|
|
212
|
-
(_this$syncedBlockStor = this.syncedBlockStore) === null || _this$syncedBlockStor === void 0 || _this$syncedBlockStor.sourceManager.updateSyncBlockData(node, false);
|
|
213
|
-
}
|
|
206
|
+
// Cache is populated in state.init() and updated in appendTransaction,
|
|
207
|
+
// so no additional updateSyncBlockData call is needed here.
|
|
214
208
|
}
|
|
215
209
|
return (0, _createClass2.default)(BodiedSyncBlock, [{
|
|
216
210
|
key: "updateContentEditable",
|
|
@@ -253,26 +247,15 @@ var BodiedSyncBlock = exports.BodiedSyncBlock = /*#__PURE__*/function () {
|
|
|
253
247
|
});
|
|
254
248
|
}
|
|
255
249
|
}
|
|
256
|
-
}, {
|
|
257
|
-
key: "syncedBlockStore",
|
|
258
|
-
get: function get() {
|
|
259
|
-
var _this$api$syncedBlock2, _this$api1;
|
|
260
|
-
return (_this$api$syncedBlock2 = (_this$api1 = this.api) === null || _this$api1 === void 0 || (_this$api1 = _this$api1.syncedBlock.sharedState) === null || _this$api1 === void 0 || (_this$api1 = _this$api1.currentState()) === null || _this$api1 === void 0 ? void 0 : _this$api1.syncBlockStore) !== null && _this$api$syncedBlock2 !== void 0 ? _this$api$syncedBlock2 : this.syncBlockStore;
|
|
261
|
-
}
|
|
262
250
|
}, {
|
|
263
251
|
key: "update",
|
|
264
252
|
value: function update(node) {
|
|
265
253
|
if (this.node.type !== node.type) {
|
|
266
254
|
return false;
|
|
267
255
|
}
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
if (!(0, _platformFeatureFlags.fg)('platform_synced_block_update_refactor')) {
|
|
272
|
-
var _this$syncedBlockStor2;
|
|
273
|
-
(_this$syncedBlockStor2 = this.syncedBlockStore) === null || _this$syncedBlockStor2 === void 0 || _this$syncedBlockStor2.sourceManager.updateSyncBlockData(node, false);
|
|
274
|
-
}
|
|
275
|
-
}
|
|
256
|
+
|
|
257
|
+
// Cache updates are handled in appendTransaction where we can
|
|
258
|
+
// filter out non-user changes (remote collab, table auto-scale, etc.)
|
|
276
259
|
this.node = node;
|
|
277
260
|
return true;
|
|
278
261
|
}
|
|
@@ -296,9 +279,8 @@ var BodiedSyncBlock = exports.BodiedSyncBlock = /*#__PURE__*/function () {
|
|
|
296
279
|
}();
|
|
297
280
|
var bodiedSyncBlockNodeView = exports.bodiedSyncBlockNodeView = function bodiedSyncBlockNodeView(props) {
|
|
298
281
|
var api = props.api,
|
|
299
|
-
syncBlockStore = props.syncBlockStore,
|
|
300
282
|
nodeViewPortalProviderAPI = props.pmPluginFactoryParams.nodeViewPortalProviderAPI;
|
|
301
283
|
return function (node, view, getPos) {
|
|
302
|
-
return new BodiedSyncBlock(node, view, getPos, api, nodeViewPortalProviderAPI
|
|
284
|
+
return new BodiedSyncBlock(node, view, getPos, api, nodeViewPortalProviderAPI);
|
|
303
285
|
};
|
|
304
286
|
};
|
|
@@ -18,7 +18,6 @@ var _errorBoundary = require("@atlaskit/editor-common/error-boundary");
|
|
|
18
18
|
var _reactNodeView = _interopRequireDefault(require("@atlaskit/editor-common/react-node-view"));
|
|
19
19
|
var _syncBlock = require("@atlaskit/editor-common/sync-block");
|
|
20
20
|
var _expValEqualsNoExposure = require("@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure");
|
|
21
|
-
var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
|
|
22
21
|
var _editorCommands = require("../editor-commands");
|
|
23
22
|
var _SyncBlockRendererWrapper = require("../ui/SyncBlockRendererWrapper");
|
|
24
23
|
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
|
|
@@ -68,9 +67,7 @@ var SyncBlock = exports.SyncBlock = /*#__PURE__*/function (_ReactNodeView) {
|
|
|
68
67
|
}, {
|
|
69
68
|
key: "update",
|
|
70
69
|
value: function update(node, decorations, innerDecorations) {
|
|
71
|
-
return _superPropGet(SyncBlock, "update", this, 3)([node, decorations, innerDecorations,
|
|
72
|
-
exposure: true
|
|
73
|
-
}) ? this.validUpdate : undefined]);
|
|
70
|
+
return _superPropGet(SyncBlock, "update", this, 3)([node, decorations, innerDecorations, this.validUpdate]);
|
|
74
71
|
}
|
|
75
72
|
}, {
|
|
76
73
|
key: "render",
|
|
@@ -369,18 +369,14 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
|
|
|
369
369
|
|
|
370
370
|
// Populate source sync block cache from initial document
|
|
371
371
|
// When fg is ON, this replaces the constructor call in the nodeview
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
syncBlockStore.sourceManager.updateSyncBlockData(node, false);
|
|
376
|
-
}
|
|
377
|
-
});
|
|
378
|
-
|
|
379
|
-
// Fetch statuses from the backend so we can identify unpublished blocks on cancel
|
|
380
|
-
if ((0, _platformFeatureFlags.fg)('platform_synced_block_patch_10')) {
|
|
381
|
-
syncBlockStore.sourceManager.fetchAndCacheStatuses();
|
|
372
|
+
instance.doc.forEach(function (node) {
|
|
373
|
+
if (syncBlockStore.sourceManager.isSourceBlock(node)) {
|
|
374
|
+
syncBlockStore.sourceManager.updateSyncBlockData(node, false);
|
|
382
375
|
}
|
|
383
|
-
}
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
// Fetch statuses from the backend so we can identify unpublished blocks on cancel
|
|
379
|
+
syncBlockStore.sourceManager.fetchAndCacheStatuses();
|
|
384
380
|
}
|
|
385
381
|
|
|
386
382
|
// Read initial shared-state signals for status decorations
|
|
@@ -693,7 +689,7 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
|
|
|
693
689
|
}
|
|
694
690
|
}
|
|
695
691
|
var viewMode = api === null || api === void 0 || (_api$editorViewMode4 = api.editorViewMode) === null || _api$editorViewMode4 === void 0 || (_api$editorViewMode4 = _api$editorViewMode4.sharedState.currentState()) === null || _api$editorViewMode4 === void 0 ? void 0 : _api$editorViewMode4.mode;
|
|
696
|
-
if (viewMode === 'view'
|
|
692
|
+
if (viewMode === 'view') {
|
|
697
693
|
return true;
|
|
698
694
|
}
|
|
699
695
|
var isOffline = (0, _editorPluginConnectivity.isOfflineMode)(api === null || api === void 0 || (_api$connectivity5 = api.connectivity) === null || _api$connectivity5 === void 0 || (_api$connectivity5 = _api$connectivity5.sharedState.currentState()) === null || _api$connectivity5 === void 0 ? void 0 : _api$connectivity5.mode);
|
|
@@ -710,40 +706,39 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
|
|
|
710
706
|
}
|
|
711
707
|
});
|
|
712
708
|
}
|
|
713
|
-
if ((0, _platformFeatureFlags.fg)('platform_synced_block_update_refactor')) {
|
|
714
|
-
// if doc changed and it's a remote transaction, check if any synced block were added,
|
|
715
|
-
// and if so, for source synced blocks, ensure we update the cache with them
|
|
716
|
-
// and for reference synced blocks, ensure we fetch the data from the server
|
|
717
|
-
if (tr.docChanged && tr.getMeta('isRemote')) {
|
|
718
|
-
var _trackSyncBlocks4 = (0, _trackSyncBlocks7.trackSyncBlocks)(function (node) {
|
|
719
|
-
return syncBlockStore.isSyncBlock(node);
|
|
720
|
-
}, tr, state),
|
|
721
|
-
_added = _trackSyncBlocks4.added;
|
|
722
|
-
var sourceSyncBlockNodes = _added.filter(function (nodeInfo) {
|
|
723
|
-
return nodeInfo.node && syncBlockStore.sourceManager.isSourceBlock(nodeInfo.node);
|
|
724
|
-
});
|
|
725
|
-
var referenceSyncBlockNodes = _added.filter(function (nodeInfo) {
|
|
726
|
-
return nodeInfo.node && syncBlockStore.referenceManager.isReferenceBlock(nodeInfo.node);
|
|
727
|
-
});
|
|
728
|
-
sourceSyncBlockNodes.forEach(function (nodeInfo) {
|
|
729
|
-
var _nodeInfo$attrs2;
|
|
730
|
-
if ((_nodeInfo$attrs2 = nodeInfo.attrs) !== null && _nodeInfo$attrs2 !== void 0 && _nodeInfo$attrs2.resourceId && nodeInfo.node) {
|
|
731
|
-
syncBlockStore.sourceManager.updateSyncBlockData(nodeInfo.node, tr.getMeta('isRemote'));
|
|
732
|
-
}
|
|
733
|
-
});
|
|
734
709
|
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
710
|
+
// if doc changed and it's a remote transaction, check if any synced block were added,
|
|
711
|
+
// and if so, for source synced blocks, ensure we update the cache with them
|
|
712
|
+
// and for reference synced blocks, ensure we fetch the data from the server
|
|
713
|
+
if (tr.docChanged && tr.getMeta('isRemote')) {
|
|
714
|
+
var _trackSyncBlocks4 = (0, _trackSyncBlocks7.trackSyncBlocks)(function (node) {
|
|
715
|
+
return syncBlockStore.isSyncBlock(node);
|
|
716
|
+
}, tr, state),
|
|
717
|
+
_added = _trackSyncBlocks4.added;
|
|
718
|
+
var sourceSyncBlockNodes = _added.filter(function (nodeInfo) {
|
|
719
|
+
return nodeInfo.node && syncBlockStore.sourceManager.isSourceBlock(nodeInfo.node);
|
|
720
|
+
});
|
|
721
|
+
var referenceSyncBlockNodes = _added.filter(function (nodeInfo) {
|
|
722
|
+
return nodeInfo.node && syncBlockStore.referenceManager.isReferenceBlock(nodeInfo.node);
|
|
723
|
+
});
|
|
724
|
+
sourceSyncBlockNodes.forEach(function (nodeInfo) {
|
|
725
|
+
var _nodeInfo$attrs2;
|
|
726
|
+
if ((_nodeInfo$attrs2 = nodeInfo.attrs) !== null && _nodeInfo$attrs2 !== void 0 && _nodeInfo$attrs2.resourceId && nodeInfo.node) {
|
|
727
|
+
syncBlockStore.sourceManager.updateSyncBlockData(nodeInfo.node, tr.getMeta('isRemote'));
|
|
739
728
|
}
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
syncBlockStore.
|
|
729
|
+
});
|
|
730
|
+
|
|
731
|
+
// Fetch statuses for remotely-added source sync blocks
|
|
732
|
+
// so we can identify unpublished blocks on cancel
|
|
733
|
+
if (sourceSyncBlockNodes.length > 0) {
|
|
734
|
+
syncBlockStore.sourceManager.fetchAndCacheStatuses();
|
|
746
735
|
}
|
|
736
|
+
var syncBlockNodes = referenceSyncBlockNodes.map(function (nodeInfo) {
|
|
737
|
+
return nodeInfo.node;
|
|
738
|
+
}).filter(function (node) {
|
|
739
|
+
return node !== undefined;
|
|
740
|
+
});
|
|
741
|
+
syncBlockStore.referenceManager.fetchSyncBlocksData((0, _editorSyncedBlockProvider.convertPMNodesToSyncBlockNodes)(syncBlockNodes));
|
|
747
742
|
}
|
|
748
743
|
if (!tr.docChanged || Boolean(tr.getMeta('isRemote')) || !isOffline && isConfirmedSyncBlockDeletion) {
|
|
749
744
|
return true;
|
|
@@ -785,26 +780,25 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
|
|
|
785
780
|
}
|
|
786
781
|
}
|
|
787
782
|
var viewMode = api === null || api === void 0 || (_api$editorViewMode5 = api.editorViewMode) === null || _api$editorViewMode5 === void 0 || (_api$editorViewMode5 = _api$editorViewMode5.sharedState.currentState()) === null || _api$editorViewMode5 === void 0 ? void 0 : _api$editorViewMode5.mode;
|
|
788
|
-
if (viewMode === 'view'
|
|
783
|
+
if (viewMode === 'view') {
|
|
789
784
|
return null;
|
|
790
785
|
}
|
|
791
786
|
|
|
792
|
-
// Update source sync block cache for user-initiated changes only
|
|
793
|
-
//
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
787
|
+
// Update source sync block cache for user-initiated changes only.
|
|
788
|
+
// Cache updates are handled here instead of in the nodeview update() so we
|
|
789
|
+
// can filter out non-user changes (remote collab, dirty programmatic txns).
|
|
790
|
+
var isUserChange = function isUserChange(tr) {
|
|
791
|
+
return tr.docChanged && !(0, _collab.isDirtyTransaction)(tr) && !tr.getMeta('isRemote');
|
|
792
|
+
};
|
|
793
|
+
var hasSourceBlockEdit = trs.some(function (tr) {
|
|
794
|
+
return isUserChange(tr) && (0, _trackSyncBlocks7.hasEditInSyncBlock)(tr, oldState);
|
|
795
|
+
});
|
|
796
|
+
if (hasSourceBlockEdit) {
|
|
797
|
+
newState.doc.forEach(function (node) {
|
|
798
|
+
if (syncBlockStore.sourceManager.isSourceBlock(node)) {
|
|
799
|
+
syncBlockStore.sourceManager.updateSyncBlockData(node, false);
|
|
800
|
+
}
|
|
800
801
|
});
|
|
801
|
-
if (hasSourceBlockEdit) {
|
|
802
|
-
newState.doc.forEach(function (node) {
|
|
803
|
-
if (syncBlockStore.sourceManager.isSourceBlock(node)) {
|
|
804
|
-
syncBlockStore.sourceManager.updateSyncBlockData(node, false);
|
|
805
|
-
}
|
|
806
|
-
});
|
|
807
|
-
}
|
|
808
802
|
}
|
|
809
803
|
trs.filter(function (tr) {
|
|
810
804
|
return tr.docChanged;
|
|
@@ -855,7 +849,7 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
|
|
|
855
849
|
}
|
|
856
850
|
if (trs.some(function (tr) {
|
|
857
851
|
return tr.docChanged && !tr.getMeta('isRemote');
|
|
858
|
-
})
|
|
852
|
+
})) {
|
|
859
853
|
// Quick check: only walk the full document when at least one
|
|
860
854
|
// transaction inserted a source synced block. This avoids an
|
|
861
855
|
// expensive descendants() traversal on every local edit.
|
|
@@ -11,7 +11,6 @@ var _analytics = require("@atlaskit/editor-common/analytics");
|
|
|
11
11
|
var _experiences = require("@atlaskit/editor-common/experiences");
|
|
12
12
|
var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
|
|
13
13
|
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
14
|
-
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
15
14
|
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
16
15
|
var _types = require("../types");
|
|
17
16
|
var _main = require("./main");
|
|
@@ -19,7 +18,6 @@ var TIMEOUT_DURATION = 30000;
|
|
|
19
18
|
var pluginKey = new _state.PluginKey('syncedBlockMenuAndToolbarExperience');
|
|
20
19
|
var SYNCED_BLOCK_BUTTON_TEST_IDS = Object.values(_types.SYNCED_BLOCK_BUTTON_TEST_ID);
|
|
21
20
|
var syncedBlockButtonIds = new Set(SYNCED_BLOCK_BUTTON_TEST_IDS);
|
|
22
|
-
var targetEl;
|
|
23
21
|
var getMenuAndToolbarExperiencesPlugin = exports.getMenuAndToolbarExperiencesPlugin = function getMenuAndToolbarExperiencesPlugin(_ref) {
|
|
24
22
|
var refs = _ref.refs,
|
|
25
23
|
dispatchAnalyticsEvent = _ref.dispatchAnalyticsEvent;
|
|
@@ -146,7 +144,7 @@ var getMenuAndToolbarExperiencesPlugin = exports.getMenuAndToolbarExperiencesPlu
|
|
|
146
144
|
if (!typeaheadPopup || !(typeaheadPopup instanceof HTMLElement)) {
|
|
147
145
|
return;
|
|
148
146
|
}
|
|
149
|
-
var targetElement =
|
|
147
|
+
var targetElement = typeaheadPopup.querySelector('[role="option"][aria-selected="true"]');
|
|
150
148
|
if (!targetElement || !(targetElement instanceof HTMLElement)) {
|
|
151
149
|
return;
|
|
152
150
|
}
|
|
@@ -303,16 +301,6 @@ var handleButtonClick = function handleButtonClick(_ref2) {
|
|
|
303
301
|
var isEnterKey = function isEnterKey(key) {
|
|
304
302
|
return key === 'Enter';
|
|
305
303
|
};
|
|
306
|
-
var getTarget = function getTarget(containerElement) {
|
|
307
|
-
if (!targetEl) {
|
|
308
|
-
var element = containerElement === null || containerElement === void 0 ? void 0 : containerElement.querySelector('.ProseMirror');
|
|
309
|
-
if (!element || !(element instanceof HTMLElement)) {
|
|
310
|
-
return null;
|
|
311
|
-
}
|
|
312
|
-
targetEl = element;
|
|
313
|
-
}
|
|
314
|
-
return targetEl;
|
|
315
|
-
};
|
|
316
304
|
var syncedBlockAddedToDomCheck = function syncedBlockAddedToDomCheck(refs, editorViewRef) {
|
|
317
305
|
return new _experiences.ExperienceCheckDomMutation({
|
|
318
306
|
onDomMutation: function onDomMutation(_ref3) {
|
|
@@ -327,17 +315,20 @@ var syncedBlockAddedToDomCheck = function syncedBlockAddedToDomCheck(refs, edito
|
|
|
327
315
|
observeConfig: function observeConfig() {
|
|
328
316
|
var _editorViewRef$curren2;
|
|
329
317
|
return [{
|
|
330
|
-
target:
|
|
318
|
+
target: editorViewRef === null || editorViewRef === void 0 || (_editorViewRef$curren2 = editorViewRef.current) === null || _editorViewRef$curren2 === void 0 ? void 0 : _editorViewRef$curren2.dom,
|
|
331
319
|
options: {
|
|
332
320
|
childList: true
|
|
333
321
|
}
|
|
334
|
-
}
|
|
322
|
+
},
|
|
323
|
+
// When wrapping a node with breakout mark with sync block, breakout dom is reused
|
|
324
|
+
// hence we need to observe subtree to catch sync block mutation
|
|
325
|
+
{
|
|
335
326
|
target: (0, _experiences.getSelectionAncestorDOM)(editorViewRef === null || editorViewRef === void 0 ? void 0 : editorViewRef.current),
|
|
336
327
|
options: {
|
|
337
328
|
childList: true,
|
|
338
329
|
subtree: true
|
|
339
330
|
}
|
|
340
|
-
}]
|
|
331
|
+
}];
|
|
341
332
|
}
|
|
342
333
|
});
|
|
343
334
|
};
|
|
@@ -363,17 +354,17 @@ var referenceSyncBlockRemovedFromDomCheck = function referenceSyncBlockRemovedFr
|
|
|
363
354
|
observeConfig: function observeConfig() {
|
|
364
355
|
var _editorViewRef$curren3;
|
|
365
356
|
return [{
|
|
366
|
-
target:
|
|
357
|
+
target: editorViewRef === null || editorViewRef === void 0 || (_editorViewRef$curren3 = editorViewRef.current) === null || _editorViewRef$curren3 === void 0 ? void 0 : _editorViewRef$curren3.dom,
|
|
367
358
|
options: {
|
|
368
359
|
childList: true
|
|
369
360
|
}
|
|
370
|
-
}
|
|
361
|
+
}, {
|
|
371
362
|
target: (0, _experiences.getSelectionAncestorDOM)(editorViewRef === null || editorViewRef === void 0 ? void 0 : editorViewRef.current),
|
|
372
363
|
options: {
|
|
373
364
|
childList: true,
|
|
374
365
|
subtree: true
|
|
375
366
|
}
|
|
376
|
-
}]
|
|
367
|
+
}];
|
|
377
368
|
}
|
|
378
369
|
});
|
|
379
370
|
};
|
|
@@ -8,7 +8,6 @@ var _selection = require("@atlaskit/editor-common/selection");
|
|
|
8
8
|
var _model = require("@atlaskit/editor-prosemirror/model");
|
|
9
9
|
var _transform = require("@atlaskit/editor-prosemirror/transform");
|
|
10
10
|
var _utils = require("@atlaskit/editor-prosemirror/utils");
|
|
11
|
-
var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
|
|
12
11
|
/**
|
|
13
12
|
* Defers a callback to the next microtask (when gated) or next macrotask via setTimeout(0).
|
|
14
13
|
* Used to avoid re-entrant ProseMirror dispatch cycles.
|
|
@@ -102,9 +101,7 @@ var _fragmentContainsExtension = function fragmentContainsExtension(fragment) {
|
|
|
102
101
|
if (found) {
|
|
103
102
|
return;
|
|
104
103
|
}
|
|
105
|
-
if ((
|
|
106
|
-
exposure: true
|
|
107
|
-
}) ? EXTENSION_NODES.has(node.type.name) : node.type.name === 'inlineExtension') {
|
|
104
|
+
if (EXTENSION_NODES.has(node.type.name)) {
|
|
108
105
|
found = true;
|
|
109
106
|
} else if (node.content.size) {
|
|
110
107
|
if (_fragmentContainsExtension(node.content)) {
|
|
@@ -165,17 +162,13 @@ var wasExtensionInsertedInBodiedSyncBlock = exports.wasExtensionInsertedInBodied
|
|
|
165
162
|
if (resourceId !== undefined) {
|
|
166
163
|
return false;
|
|
167
164
|
}
|
|
168
|
-
if ((
|
|
169
|
-
exposure: true
|
|
170
|
-
}) ? EXTENSION_NODES.has(node.type.name) : node.type.name === 'inlineExtension') {
|
|
165
|
+
if (EXTENSION_NODES.has(node.type.name)) {
|
|
171
166
|
var _$pos = tr.doc.resolve(pos);
|
|
172
167
|
var _parent = (0, _utils.findParentNodeOfTypeClosestToPos)(_$pos, bodiedSyncBlock);
|
|
173
168
|
if (_parent !== null && _parent !== void 0 && _parent.node.attrs.resourceId) {
|
|
174
169
|
var mappedPos = tr.mapping.invert().map(pos);
|
|
175
170
|
var nodeBefore = state.doc.nodeAt(mappedPos);
|
|
176
|
-
if (!nodeBefore || (
|
|
177
|
-
exposure: true
|
|
178
|
-
}) ? EXTENSION_NODES.has(nodeBefore.type.name) : nodeBefore.type.name !== 'inlineExtension')) {
|
|
171
|
+
if (!nodeBefore || EXTENSION_NODES.has(nodeBefore.type.name)) {
|
|
179
172
|
resourceId = _parent.node.attrs.resourceId;
|
|
180
173
|
return false;
|
|
181
174
|
}
|
|
@@ -11,10 +11,8 @@ var _hooks = require("@atlaskit/editor-common/hooks");
|
|
|
11
11
|
var _editorSyncedBlockProvider = require("@atlaskit/editor-synced-block-provider");
|
|
12
12
|
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
13
13
|
var _expValEqualsNoExposure = require("@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure");
|
|
14
|
-
var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
|
|
15
14
|
var _editorActions = require("./editor-actions");
|
|
16
15
|
var _editorCommands = require("./editor-commands");
|
|
17
|
-
var _bodiedSyncBlockNodeWithToDOMFixed = require("./nodeviews/bodiedSyncBlockNodeWithToDOMFixed");
|
|
18
16
|
var _main = require("./pm-plugins/main");
|
|
19
17
|
var _menuAndToolbarExperiences = require("./pm-plugins/menu-and-toolbar-experiences");
|
|
20
18
|
var _blockMenuComponents = require("./ui/block-menu-components");
|
|
@@ -82,11 +80,7 @@ var syncedBlockPlugin = exports.syncedBlockPlugin = function syncedBlockPlugin(_
|
|
|
82
80
|
node: _adfSchema.syncBlock
|
|
83
81
|
}, {
|
|
84
82
|
name: 'bodiedSyncBlock',
|
|
85
|
-
node:
|
|
86
|
-
exposure: true
|
|
87
|
-
}) ?
|
|
88
|
-
// delete bodiedSyncBlockNodeWithToDOMFixed when cleaning up platform_synced_block_patch_6
|
|
89
|
-
(0, _bodiedSyncBlockNodeWithToDOMFixed.bodiedSyncBlockNodeWithToDOMFixed)() : _adfSchema.bodiedSyncBlock
|
|
83
|
+
node: _adfSchema.bodiedSyncBlock
|
|
90
84
|
}];
|
|
91
85
|
},
|
|
92
86
|
pmPlugins: function pmPlugins() {
|
|
@@ -20,36 +20,12 @@ var _hooks = require("@atlaskit/editor-common/hooks");
|
|
|
20
20
|
var _messages = require("@atlaskit/editor-common/messages");
|
|
21
21
|
var _editorPluginConnectivity = require("@atlaskit/editor-plugin-connectivity");
|
|
22
22
|
var _modalDialog = _interopRequireWildcard(require("@atlaskit/modal-dialog"));
|
|
23
|
-
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
24
23
|
var _compiled = require("@atlaskit/primitives/compiled");
|
|
25
24
|
var _spinner = _interopRequireDefault(require("@atlaskit/spinner"));
|
|
26
25
|
var _main = require("../pm-plugins/main");
|
|
27
26
|
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); }
|
|
28
27
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
29
28
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
30
|
-
var modalContentMapOld = {
|
|
31
|
-
'source-block-deleted': {
|
|
32
|
-
titleMultiple: _messages.syncBlockMessages.deleteConfirmationModalTitleMultiple,
|
|
33
|
-
titleSingle: _messages.syncBlockMessages.deletionConfirmationModalTitleSingle,
|
|
34
|
-
descriptionSingle: _messages.syncBlockMessages.deletionConfirmationModalDescriptionNoRef,
|
|
35
|
-
descriptionMultiple: _messages.syncBlockMessages.deletionConfirmationModalDescription,
|
|
36
|
-
confirmButtonLabel: _messages.syncBlockMessages.deleteConfirmationModalDeleteButton
|
|
37
|
-
},
|
|
38
|
-
'source-block-unpublished': {
|
|
39
|
-
titleMultiple: _messages.syncBlockMessages.deleteConfirmationModalTitleMultiple,
|
|
40
|
-
titleSingle: _messages.syncBlockMessages.deletionConfirmationModalTitleSingle,
|
|
41
|
-
descriptionSingle: _messages.syncBlockMessages.deletionConfirmationModalDescriptionNoRef,
|
|
42
|
-
descriptionMultiple: _messages.syncBlockMessages.deletionConfirmationModalDescription,
|
|
43
|
-
confirmButtonLabel: _messages.syncBlockMessages.deleteConfirmationModalDeleteButton
|
|
44
|
-
},
|
|
45
|
-
'source-block-unsynced': {
|
|
46
|
-
titleMultiple: _messages.syncBlockMessages.unsyncConfirmationModalTitle,
|
|
47
|
-
titleSingle: _messages.syncBlockMessages.unsyncConfirmationModalTitle,
|
|
48
|
-
descriptionSingle: _messages.syncBlockMessages.unsyncConfirmModalDescriptionSingle,
|
|
49
|
-
descriptionMultiple: _messages.syncBlockMessages.unsyncConfirmModalDescriptionMultiple,
|
|
50
|
-
confirmButtonLabel: _messages.syncBlockMessages.deleteConfirmationModalUnsyncButton
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
29
|
var modalContentMap = {
|
|
54
30
|
'source-block-deleted': {
|
|
55
31
|
titleMultiple: _messages.syncBlockMessages.deleteConfirmationModalTitleMultiple,
|
|
@@ -111,10 +87,9 @@ var DeleteConfirmationModal = exports.DeleteConfirmationModal = function DeleteC
|
|
|
111
87
|
formatMessage = _useIntl.formatMessage;
|
|
112
88
|
var resolverRef = _react.default.useRef(undefined);
|
|
113
89
|
|
|
114
|
-
// When
|
|
115
|
-
//
|
|
116
|
-
//
|
|
117
|
-
// close the modal (which was never open).
|
|
90
|
+
// When a source block with no references is deleted, the modal is never shown but
|
|
91
|
+
// onDeleteCompleted still sets bodiedSyncBlockDeletionStatus to 'completed'. This ref signals
|
|
92
|
+
// the useEffect to silently reset the status without trying to close the modal (which was never open).
|
|
118
93
|
var skipModalOnCompletedRef = _react.default.useRef(false);
|
|
119
94
|
var handleClick = (0, _react.useCallback)(function (confirm) {
|
|
120
95
|
return function () {
|
|
@@ -206,24 +181,20 @@ var DeleteConfirmationModal = exports.DeleteConfirmationModal = function DeleteC
|
|
|
206
181
|
return _regenerator.default.wrap(function _callee3$(_context3) {
|
|
207
182
|
while (1) switch (_context3.prev = _context3.next) {
|
|
208
183
|
case 0:
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
break;
|
|
212
|
-
}
|
|
213
|
-
_context3.prev = 1;
|
|
214
|
-
_context3.next = 4;
|
|
184
|
+
_context3.prev = 0;
|
|
185
|
+
_context3.next = 3;
|
|
215
186
|
return fetchReferenceCountRef.current(syncBlockIds);
|
|
216
|
-
case
|
|
187
|
+
case 3:
|
|
217
188
|
count = _context3.sent;
|
|
218
|
-
_context3.next =
|
|
189
|
+
_context3.next = 9;
|
|
219
190
|
break;
|
|
220
|
-
case
|
|
221
|
-
_context3.prev =
|
|
222
|
-
_context3.t0 = _context3["catch"](
|
|
191
|
+
case 6:
|
|
192
|
+
_context3.prev = 6;
|
|
193
|
+
_context3.t0 = _context3["catch"](0);
|
|
223
194
|
count = 1;
|
|
224
|
-
case
|
|
195
|
+
case 9:
|
|
225
196
|
if (!(count === 0)) {
|
|
226
|
-
_context3.next =
|
|
197
|
+
_context3.next = 13;
|
|
227
198
|
break;
|
|
228
199
|
}
|
|
229
200
|
// No references — auto-confirm without showing the modal.
|
|
@@ -240,9 +211,8 @@ var DeleteConfirmationModal = exports.DeleteConfirmationModal = function DeleteC
|
|
|
240
211
|
} : {}));
|
|
241
212
|
});
|
|
242
213
|
return _context3.abrupt("return", true);
|
|
243
|
-
case
|
|
214
|
+
case 13:
|
|
244
215
|
setReferenceCount(count);
|
|
245
|
-
case 15:
|
|
246
216
|
setIsOpen(true);
|
|
247
217
|
setSyncBlockIds(syncBlockIds);
|
|
248
218
|
if (deleteReason) {
|
|
@@ -261,11 +231,11 @@ var DeleteConfirmationModal = exports.DeleteConfirmationModal = function DeleteC
|
|
|
261
231
|
});
|
|
262
232
|
}
|
|
263
233
|
return _context3.abrupt("return", confirmedPromise);
|
|
264
|
-
case
|
|
234
|
+
case 20:
|
|
265
235
|
case "end":
|
|
266
236
|
return _context3.stop();
|
|
267
237
|
}
|
|
268
|
-
}, _callee3, null, [[
|
|
238
|
+
}, _callee3, null, [[0, 6]]);
|
|
269
239
|
}));
|
|
270
240
|
return function (_x3, _x4) {
|
|
271
241
|
return _ref5.apply(this, arguments);
|
|
@@ -282,7 +252,7 @@ var DeleteConfirmationModal = exports.DeleteConfirmationModal = function DeleteC
|
|
|
282
252
|
};
|
|
283
253
|
}, [syncBlockStoreManager, confirmationCallback]);
|
|
284
254
|
(0, _react.useEffect)(function () {
|
|
285
|
-
if (skipModalOnCompletedRef.current
|
|
255
|
+
if (skipModalOnCompletedRef.current) {
|
|
286
256
|
if (bodiedSyncBlockDeletionStatus === 'completed') {
|
|
287
257
|
var _api$core6;
|
|
288
258
|
// Deletion was auto-confirmed without showing the modal (no references).
|
|
@@ -317,44 +287,10 @@ var DeleteConfirmationModal = exports.DeleteConfirmationModal = function DeleteC
|
|
|
317
287
|
});
|
|
318
288
|
}
|
|
319
289
|
}, [api === null || api === void 0 || (_api$core8 = api.core) === null || _api$core8 === void 0 ? void 0 : _api$core8.actions, bodiedSyncBlockDeletionStatus, isOpen]);
|
|
320
|
-
(0, _react.useEffect)(function () {
|
|
321
|
-
// When the flag is off, fetch references after the modal opens (original behaviour).
|
|
322
|
-
// When the flag is on, references are fetched and set before the modal opens in
|
|
323
|
-
// confirmationCallback, so this useEffect is skipped to avoid a duplicate fetch.
|
|
324
|
-
if (isOpen && syncBlockIds !== undefined && !(0, _platformFeatureFlags.fg)('platform_synced_block_patch_9')) {
|
|
325
|
-
var fetchReferences = /*#__PURE__*/function () {
|
|
326
|
-
var _ref0 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4() {
|
|
327
|
-
var totalCount;
|
|
328
|
-
return _regenerator.default.wrap(function _callee4$(_context4) {
|
|
329
|
-
while (1) switch (_context4.prev = _context4.next) {
|
|
330
|
-
case 0:
|
|
331
|
-
_context4.prev = 0;
|
|
332
|
-
_context4.next = 3;
|
|
333
|
-
return fetchReferenceCountRef.current(syncBlockIds);
|
|
334
|
-
case 3:
|
|
335
|
-
totalCount = _context4.sent;
|
|
336
|
-
setReferenceCount(totalCount);
|
|
337
|
-
_context4.next = 10;
|
|
338
|
-
break;
|
|
339
|
-
case 7:
|
|
340
|
-
_context4.prev = 7;
|
|
341
|
-
_context4.t0 = _context4["catch"](0);
|
|
342
|
-
setReferenceCount(0);
|
|
343
|
-
case 10:
|
|
344
|
-
case "end":
|
|
345
|
-
return _context4.stop();
|
|
346
|
-
}
|
|
347
|
-
}, _callee4, null, [[0, 7]]);
|
|
348
|
-
}));
|
|
349
|
-
return function fetchReferences() {
|
|
350
|
-
return _ref0.apply(this, arguments);
|
|
351
|
-
};
|
|
352
|
-
}();
|
|
353
290
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
}, [isOpen, syncBlockIds]);
|
|
291
|
+
// References are fetched and set before the modal opens in
|
|
292
|
+
// confirmationCallback, so no additional fetch is needed here.
|
|
293
|
+
|
|
358
294
|
return /*#__PURE__*/_react.default.createElement(_modalDialog.ModalTransition, null, isOpen && /*#__PURE__*/_react.default.createElement(_modalDialog.default, {
|
|
359
295
|
onClose: handleClick(false),
|
|
360
296
|
testId: "sync-block-delete-confirmation",
|
|
@@ -364,7 +300,7 @@ var DeleteConfirmationModal = exports.DeleteConfirmationModal = function DeleteC
|
|
|
364
300
|
}, /*#__PURE__*/_react.default.createElement(_spinner.default, {
|
|
365
301
|
size: "large"
|
|
366
302
|
})) : /*#__PURE__*/_react.default.createElement(ModalContent, {
|
|
367
|
-
content:
|
|
303
|
+
content: modalContentMap[deleteReason],
|
|
368
304
|
referenceCount: referenceCount,
|
|
369
305
|
handleClick: handleClick,
|
|
370
306
|
formatMessage: formatMessage,
|
|
@@ -374,15 +310,15 @@ var DeleteConfirmationModal = exports.DeleteConfirmationModal = function DeleteC
|
|
|
374
310
|
sourceCount: (syncBlockIds === null || syncBlockIds === void 0 ? void 0 : syncBlockIds.length) || 0
|
|
375
311
|
}))));
|
|
376
312
|
};
|
|
377
|
-
var ModalContent = function ModalContent(
|
|
378
|
-
var content =
|
|
379
|
-
referenceCount =
|
|
380
|
-
handleClick =
|
|
381
|
-
formatMessage =
|
|
382
|
-
isDeleting =
|
|
383
|
-
isDisabled =
|
|
384
|
-
deleteReason =
|
|
385
|
-
sourceCount =
|
|
313
|
+
var ModalContent = function ModalContent(_ref0) {
|
|
314
|
+
var content = _ref0.content,
|
|
315
|
+
referenceCount = _ref0.referenceCount,
|
|
316
|
+
handleClick = _ref0.handleClick,
|
|
317
|
+
formatMessage = _ref0.formatMessage,
|
|
318
|
+
isDeleting = _ref0.isDeleting,
|
|
319
|
+
isDisabled = _ref0.isDisabled,
|
|
320
|
+
deleteReason = _ref0.deleteReason,
|
|
321
|
+
sourceCount = _ref0.sourceCount;
|
|
386
322
|
var titleMultiple = content.titleMultiple,
|
|
387
323
|
titleSingle = content.titleSingle,
|
|
388
324
|
descriptionSingle = content.descriptionSingle,
|