@atlaskit/editor-plugin-synced-block 6.0.44 → 6.0.46
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 +28 -228
- package/CHANGELOG.md +18 -0
- package/dist/cjs/pm-plugins/main.js +75 -0
- package/dist/cjs/pm-plugins/utils/handle-bodied-sync-block-creation.js +1 -1
- package/dist/cjs/types/index.js +1 -0
- package/dist/cjs/ui/Flag.js +5 -1
- package/dist/es2019/pm-plugins/main.js +75 -0
- package/dist/es2019/pm-plugins/utils/handle-bodied-sync-block-creation.js +1 -1
- package/dist/es2019/types/index.js +1 -0
- package/dist/es2019/ui/Flag.js +5 -0
- package/dist/esm/pm-plugins/main.js +75 -0
- package/dist/esm/pm-plugins/utils/handle-bodied-sync-block-creation.js +1 -1
- package/dist/esm/types/index.js +1 -0
- package/dist/esm/ui/Flag.js +5 -1
- package/dist/types/types/index.d.ts +2 -1
- package/dist/types-ts4.5/types/index.d.ts +2 -1
- package/package.json +9 -9
package/AGENTS.md
CHANGED
|
@@ -1,133 +1,54 @@
|
|
|
1
|
-
# Synced Blocks — Developer Agent Guide
|
|
1
|
+
# Synced Blocks Plugin — Developer Agent Guide
|
|
2
2
|
|
|
3
|
-
> **
|
|
4
|
-
>
|
|
5
|
-
> locations, common patterns, and debugging guidance.
|
|
6
|
-
>
|
|
7
|
-
> **Full Knowledge Base**:
|
|
8
|
-
> [Synced Blocks — Comprehensive Knowledge Base](https://hello.atlassian.net/wiki/spaces/egcuc/pages/6679548384)
|
|
9
|
-
> (Confluence)
|
|
3
|
+
> **For workflow guidance, debugging, and cross-package task guides, load the `synced-blocks` skill:**
|
|
4
|
+
> `get_skill(skill_name_or_path="platform/packages/editor/.rovodev/skills/synced-blocks/SKILL.md")`
|
|
10
5
|
|
|
11
6
|
---
|
|
12
7
|
|
|
13
8
|
## Quick Context
|
|
14
9
|
|
|
15
10
|
**Synced Blocks** lets users create reusable content blocks (source) that can be referenced across
|
|
16
|
-
Confluence pages and Jira issue descriptions.
|
|
17
|
-
|
|
11
|
+
Confluence pages and Jira issue descriptions. This package is the core editor plugin — it registers
|
|
12
|
+
ADF nodes, toolbar/menu integration, commands, and ProseMirror plugins.
|
|
18
13
|
|
|
19
14
|
**Two ADF node types:**
|
|
20
15
|
|
|
21
16
|
- `bodiedSyncBlock` — **Source** sync block (contains the editable content)
|
|
22
|
-
- `syncBlock` — **Reference** sync block (renders content fetched from
|
|
17
|
+
- `syncBlock` — **Reference** sync block (renders content fetched from Block Service)
|
|
23
18
|
|
|
24
19
|
---
|
|
25
20
|
|
|
26
|
-
##
|
|
27
|
-
|
|
28
|
-
### Platform (shared across products)
|
|
29
|
-
|
|
30
|
-
| Package | Path | Purpose |
|
|
31
|
-
| ------------------ | -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
|
|
32
|
-
| **Plugin** | `platform/packages/editor/editor-plugin-synced-block/` | Core editor plugin — registers nodes, toolbar, commands, block menu integration |
|
|
33
|
-
| **Provider** | `platform/packages/editor/editor-synced-block-provider/` | Data layer — store managers, block service API client, ARI generation, permissions, media tokens |
|
|
34
|
-
| **Renderer** | `platform/packages/editor/editor-synced-block-renderer/` | View-mode rendering of reference sync blocks using nested renderer |
|
|
35
|
-
| **Plugin Tests** | `platform/packages/editor/editor-plugin-synced-block-tests/` | Integration tests for the plugin |
|
|
36
|
-
| **Provider Tests** | `platform/packages/editor/editor-synced-block-provider-tests/` | Tests for store managers and provider hooks |
|
|
37
|
-
| **Renderer Tests** | `platform/packages/editor/editor-synced-block-renderer-tests/` | Tests for renderer components |
|
|
38
|
-
|
|
39
|
-
Also touches:
|
|
40
|
-
|
|
41
|
-
- `platform/packages/editor/editor-common` — shared types
|
|
42
|
-
- `platform/packages/editor/editor-core` — plugin registration
|
|
43
|
-
- `platform/packages/renderer` — reference rendering in view mode
|
|
44
|
-
|
|
45
|
-
### Confluence
|
|
46
|
-
|
|
47
|
-
| File/Package | Path | Purpose |
|
|
48
|
-
| ------------------- | -------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
|
|
49
|
-
| SyncedBlockProvider | `confluence/next/packages/fabric-providers/src/SyncedBlockProvider.ts` | Wraps platform provider with Confluence config (AGG endpoint, media tokens, permissions) |
|
|
50
|
-
| SyncedBlockPreload | `confluence/next/packages/fabric-providers/src/SyncedBlockPreload.ts` | Preloads sync block data for SSR |
|
|
51
|
-
| SSR Data Loading | `confluence/next/packages/fabric-providers/src/SyncedBlockLoadSSRData.ts` | Loads SSR data |
|
|
52
|
-
| Edit Page Preload | `confluence/next/packages/load-edit-page/src/preload/preloadSyncedBlocksData.ts` | Preloads data for edit page |
|
|
53
|
-
| Editor Preload | `confluence/next/packages/load-edit-page/src/preload/preloadEditorSyncedBlocksData.ts` | Editor-specific preloading |
|
|
54
|
-
| Full Page Editor | `confluence/next/packages/full-page-editor/src/FullPageEditorComponent.tsx` | Integrates sync block plugin into editor |
|
|
55
|
-
|
|
56
|
-
### Jira
|
|
57
|
-
|
|
58
|
-
| File/Package | Path | Purpose |
|
|
59
|
-
| ------------------- | ----------------------------------------------------------- | --------------------------------------------- |
|
|
60
|
-
| Provider Package | `jira/src/packages/issue/issue-view-synced-block-provider/` | Core Jira integration package |
|
|
61
|
-
| Node Component Hook | `src/useSyncedBlockProviderNodeComponent.tsx` | Creates synced block node components for Jira |
|
|
62
|
-
| Editor HOC | `src/withSyncedBlockProviderEditor.tsx` | Wraps Jira editor with sync block support |
|
|
63
|
-
| Renderer HOC | `src/withSyncedBlockProviderRenderer.tsx` | Wraps Jira renderer with sync block support |
|
|
64
|
-
| Prefetch | `src/prefetchSyncedBlocks.ts` | Prefetches sync block data in issue view |
|
|
65
|
-
| Relay Fetch | `src/useRelaySyncBlockFetchProvider.tsx` | Real-time updates via Relay subscriptions |
|
|
66
|
-
|
|
67
|
-
---
|
|
68
|
-
|
|
69
|
-
## Key Concepts
|
|
70
|
-
|
|
71
|
-
### Source vs Reference
|
|
72
|
-
|
|
73
|
-
- **Source** (`bodiedSyncBlock`): The original content block. Content is stored in the page ADF AND
|
|
74
|
-
in the Block Service. Editable inline.
|
|
75
|
-
- **Reference** (`syncBlock`): A read-only copy that fetches content from Block Service. Rendered
|
|
76
|
-
via nested renderer. Shows "Synced from [page]" label.
|
|
77
|
-
|
|
78
|
-
### Data Flow
|
|
79
|
-
|
|
80
|
-
1. **Create source** → Content saved to Block Service via API → ARI generated from page ID + local
|
|
81
|
-
ID
|
|
82
|
-
2. **Create reference** → Copy source link → Paste → `syncBlock` node inserted with `resourceId`
|
|
83
|
-
3. **Edit source** → Content pushed to Block Service → AGG subscription notifies references →
|
|
84
|
-
References re-fetch and re-render
|
|
85
|
-
4. **SSR** → On page load, Confluence/Jira preloads sync block data from Block Service in bulk
|
|
86
|
-
|
|
87
|
-
### ARI Format
|
|
88
|
-
|
|
89
|
-
- Confluence: `ari:cloud:block::{cloudId}/confluence-page:{pageId}/{localId}`
|
|
90
|
-
- Jira: `ari:cloud:block::{cloudId}/jira-work-item:{issueId}/{localId}`
|
|
91
|
-
|
|
92
|
-
### Store Managers
|
|
93
|
-
|
|
94
|
-
- `SyncBlockStoreManager` — Manages source sync block state (create, update, delete, flush)
|
|
95
|
-
- `ReferenceSyncBlockStoreManager` — Manages reference sync block state (fetch, subscribe, cache)
|
|
96
|
-
- `SyncBlockInMemorySessionCache` — Caches data for view→edit transitions
|
|
97
|
-
|
|
98
|
-
---
|
|
99
|
-
|
|
100
|
-
## Plugin Internals (`editor-plugin-synced-block/src/`)
|
|
101
|
-
|
|
102
|
-
The plugin follows a layered architecture:
|
|
21
|
+
## Plugin Internals (`src/`)
|
|
103
22
|
|
|
104
23
|
```
|
|
105
|
-
|
|
106
|
-
├──
|
|
24
|
+
src/
|
|
25
|
+
├── index.ts # Re-exports plugin + type
|
|
26
|
+
├── syncedBlockPlugin.tsx # Top-level: registers nodes, commands, UI, pm-plugins
|
|
27
|
+
├── syncedBlockPluginType.ts # TypeScript interfaces for options, shared state, dependencies
|
|
107
28
|
├── editor-commands/
|
|
108
|
-
│ └── index.ts
|
|
29
|
+
│ └── index.ts # createSyncedBlock, copySyncedBlockReferenceToClipboardEditorCommand,
|
|
109
30
|
│ removeSyncedBlockAtPos, unsyncSyncBlock
|
|
110
31
|
├── nodeviews/
|
|
111
|
-
│ ├── syncedBlock.tsx
|
|
112
|
-
│ ├── bodiedSyncedBlock.tsx
|
|
113
|
-
│ └── bodiedSyncBlockNodeWithToDOMFixed.ts
|
|
32
|
+
│ ├── syncedBlock.tsx # NodeView for reference (syncBlock) — read-only, fetches from BE
|
|
33
|
+
│ ├── bodiedSyncedBlock.tsx # NodeView for source (bodiedSyncBlock) — nested editor with content
|
|
34
|
+
│ └── bodiedSyncBlockNodeWithToDOMFixed.ts # DOM serialization fix variant (experiment-gated)
|
|
114
35
|
├── pm-plugins/
|
|
115
|
-
│ ├── main.ts
|
|
116
|
-
│ ├── menu-and-toolbar-experiences.ts
|
|
36
|
+
│ ├── main.ts # Core state machine: sync block lifecycle, creation, deletion, cache
|
|
37
|
+
│ ├── menu-and-toolbar-experiences.ts # Experience tracking for menu/toolbar interactions
|
|
117
38
|
│ └── utils/
|
|
118
|
-
│ ├── track-sync-blocks.ts
|
|
119
|
-
│ ├── handle-bodied-sync-block-creation.ts
|
|
120
|
-
│ └── handle-bodied-sync-block-removal.ts
|
|
39
|
+
│ ├── track-sync-blocks.ts # Tracks mutations, updates shared state
|
|
40
|
+
│ ├── handle-bodied-sync-block-creation.ts # Creation flow, local cache, retry logic
|
|
41
|
+
│ └── handle-bodied-sync-block-removal.ts # Deletion flow, BE synchronization
|
|
121
42
|
├── ui/
|
|
122
|
-
│ ├── toolbar-components.tsx
|
|
123
|
-
│ ├── floating-toolbar.tsx
|
|
124
|
-
│ ├── block-menu-components.tsx
|
|
125
|
-
│ ├── quick-insert.tsx
|
|
126
|
-
│ ├── DeleteConfirmationModal.tsx
|
|
127
|
-
│ ├── SyncBlockRefresher.tsx
|
|
128
|
-
│ └── Flag.tsx
|
|
43
|
+
│ ├── toolbar-components.tsx # Primary toolbar button ("Create Synced Block")
|
|
44
|
+
│ ├── floating-toolbar.tsx # Node-level actions: delete, unsync, copy link, view locations
|
|
45
|
+
│ ├── block-menu-components.tsx # Block menu entry
|
|
46
|
+
│ ├── quick-insert.tsx # Slash command / quick insert config
|
|
47
|
+
│ ├── DeleteConfirmationModal.tsx # Deletion confirmation dialog
|
|
48
|
+
│ ├── SyncBlockRefresher.tsx # Periodic data refresh from backend
|
|
49
|
+
│ └── Flag.tsx # Error/info flags (offline, copy notifications)
|
|
129
50
|
└── types/
|
|
130
|
-
└── index.ts
|
|
51
|
+
└── index.ts # FLAG_ID, SyncedBlockSharedState, BodiedSyncBlockDeletionStatus
|
|
131
52
|
```
|
|
132
53
|
|
|
133
54
|
### Key Code Patterns
|
|
@@ -147,124 +68,3 @@ syncedBlockPlugin.tsx ← Top-level: registers nodes, commands, UI, pm-
|
|
|
147
68
|
2. Calls `ReferenceSyncBlockStoreManager.fetch(resourceId)` → Block Service API
|
|
148
69
|
3. Renders content via nested renderer from `editor-synced-block-renderer`
|
|
149
70
|
4. Subscribes to AGG WebSocket for real-time updates
|
|
150
|
-
|
|
151
|
-
---
|
|
152
|
-
|
|
153
|
-
## Common Tasks
|
|
154
|
-
|
|
155
|
-
### Implementing a new feature in sync blocks
|
|
156
|
-
|
|
157
|
-
1. **Identify scope**: Does it affect source, reference, or both? Editor, renderer, or both?
|
|
158
|
-
2. **Platform first**: Make changes in `editor-plugin-synced-block` or
|
|
159
|
-
`editor-synced-block-provider`
|
|
160
|
-
3. **Product integration**: Update Confluence (`fabric-providers`) and/or Jira
|
|
161
|
-
(`issue-view-synced-block-provider`)
|
|
162
|
-
4. **Feature gate**: Use a DnH **Experiment** (not a feature gate) for production changes. See
|
|
163
|
-
[Experiment and gates page](https://hello.atlassian.net/wiki/spaces/egcuc/pages/6390978659)
|
|
164
|
-
5. **Analytics**: Add experience tracking events (see `EDITOR-1665` pattern)
|
|
165
|
-
6. **Test**: Add tests in the corresponding test package
|
|
166
|
-
|
|
167
|
-
### Fixing a bug
|
|
168
|
-
|
|
169
|
-
1. **Check supported node types**:
|
|
170
|
-
[Edit at source](https://hello.atlassian.net/wiki/spaces/egcuc/pages/5926568979) |
|
|
171
|
-
[Edit anywhere](https://hello.atlassian.net/wiki/spaces/egcuc/pages/5864526866)
|
|
172
|
-
2. **Check unsupported content handling**:
|
|
173
|
-
[Unsupported content](https://hello.atlassian.net/wiki/spaces/egcuc/pages/5687277297)
|
|
174
|
-
3. **Debug with analytics**:
|
|
175
|
-
[HOW-TO: Use analytics to debug errors](https://hello.atlassian.net/wiki/spaces/egcuc/pages/6342760320)
|
|
176
|
-
4. **Gate the fix**: Use DnH Experiment, not a feature gate
|
|
177
|
-
5. **Test on staging**: Verify on Hello (hello.atlassian.net) with experiment enabled
|
|
178
|
-
|
|
179
|
-
### Cleaning up a feature gate
|
|
180
|
-
|
|
181
|
-
1. Find the gate key in
|
|
182
|
-
[Experiment and gates](https://hello.atlassian.net/wiki/spaces/egcuc/pages/6390978659)
|
|
183
|
-
2. Search codebase: `grep -r "gate_key_name" platform/ confluence/ jira/`
|
|
184
|
-
3. Remove conditional logic, keep the "enabled" code path
|
|
185
|
-
4. Remove the Switcheroo/Statsig configuration
|
|
186
|
-
5. Update the Confluence page to mark as "Cleaned up"
|
|
187
|
-
|
|
188
|
-
### Adding support for a new node type in sync blocks
|
|
189
|
-
|
|
190
|
-
1. Check if node is in the supported list:
|
|
191
|
-
[Supported node types](https://hello.atlassian.net/wiki/spaces/egcuc/pages/5926568979)
|
|
192
|
-
2. For **source**: Update the allowed node schema in `editor-plugin-synced-block`
|
|
193
|
-
3. For **reference**: Ensure nested renderer in `editor-synced-block-renderer` can render the node
|
|
194
|
-
4. Test in both classic pages and live pages
|
|
195
|
-
5. Test in Jira issue description renderer
|
|
196
|
-
|
|
197
|
-
---
|
|
198
|
-
|
|
199
|
-
## Performance Considerations
|
|
200
|
-
|
|
201
|
-
- **VC90**: Sync blocks can regress VC90 due to content shift (CLS). Reference blocks fetch content
|
|
202
|
-
async and shift the page. Use SSR preloading to mitigate.
|
|
203
|
-
- **SSR**: Bulk fetch endpoint reduces waterfall. Configurable via
|
|
204
|
-
`platform_editor_sync_block_ssr_config`.
|
|
205
|
-
- **View→Edit transition**: Cache sync block data in session storage (see
|
|
206
|
-
`SyncBlockInMemorySessionCache`)
|
|
207
|
-
- **Criterion tests**:
|
|
208
|
-
[Perf test page](https://hello.atlassian.net/wiki/spaces/egcuc/pages/6498888237)
|
|
209
|
-
|
|
210
|
-
---
|
|
211
|
-
|
|
212
|
-
## Analytics Events Quick Reference
|
|
213
|
-
|
|
214
|
-
**Experience events** (SLO-driving): `asyncOperation` type
|
|
215
|
-
|
|
216
|
-
- `fetchSyncedBlock`, `fetchSyncedBlockSourceInfo`, `fetchSyncedBlockReferencesInfo`
|
|
217
|
-
- `syncedBlockCreate`, `syncedBlockUpdate`, `syncedBlockDelete`
|
|
218
|
-
- `referenceSyncedBlockUpdate`
|
|
219
|
-
|
|
220
|
-
**Menu/toolbar events**: `menuAction` and `toolbarAction` types
|
|
221
|
-
|
|
222
|
-
- `syncedBlockCreate` (quickInsertMenu, blockMenu, primaryToolbar)
|
|
223
|
-
- `syncedBlockDelete`, `referenceSyncedBlockDelete` (syncedBlockToolbar)
|
|
224
|
-
- `syncedBlockUnsync`, `referenceSyncedBlockUnsync` (syncedBlockToolbar)
|
|
225
|
-
- `syncedBlockViewLocations`, `syncedBlockEditSource` (syncedBlockToolbar)
|
|
226
|
-
|
|
227
|
-
**Standard analytics events**: Track individual sync block operations
|
|
228
|
-
|
|
229
|
-
- `fetched/fetchSyncedBlock` — attributes: `resourceId`, `blockInstanceId`, `sourceProduct`
|
|
230
|
-
- `rendered/renderSyncedBlock` — attributes: `resourceId`, `sourceProduct`, state
|
|
231
|
-
(`loaded`/`error`/`permissionDenied`/`missingSource`)
|
|
232
|
-
- `inserted/documentInserted` (page save) — attributes: `numberOfSyncedBlocks`,
|
|
233
|
-
`numberOfReferencedSyncedBlocks`
|
|
234
|
-
|
|
235
|
-
Full catalogue:
|
|
236
|
-
[Synced Block Analytics Catalogue](https://hello.atlassian.net/wiki/spaces/egcuc/pages/6332253480)
|
|
237
|
-
|
|
238
|
-
---
|
|
239
|
-
|
|
240
|
-
## Key Jira Queries
|
|
241
|
-
|
|
242
|
-
```
|
|
243
|
-
# All synced block tickets
|
|
244
|
-
"Epic Link" in (EDITOR-1519, EDITOR-2441, EDITOR-1783, EDITOR-3936, EDITOR-3586, EDITOR-5010)
|
|
245
|
-
|
|
246
|
-
# Open bugs
|
|
247
|
-
... AND type = Bug AND status not in (Done, "Won't do") ORDER BY priority DESC
|
|
248
|
-
|
|
249
|
-
# M2 (Jira source creation)
|
|
250
|
-
"Epic Link" = EDITOR-5010 ORDER BY created DESC
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
---
|
|
254
|
-
|
|
255
|
-
## Key Confluence Pages
|
|
256
|
-
|
|
257
|
-
- **Architecture**: https://hello.atlassian.net/wiki/spaces/egcuc/pages/5505188521
|
|
258
|
-
- **Implementation view**: https://hello.atlassian.net/wiki/spaces/egcuc/pages/5997083214
|
|
259
|
-
- **Decisions record**: https://hello.atlassian.net/wiki/spaces/egcuc/pages/5882558842
|
|
260
|
-
- **Feature flags**: https://hello.atlassian.net/wiki/spaces/egcuc/pages/6390978659
|
|
261
|
-
- **Analytics catalogue**: https://hello.atlassian.net/wiki/spaces/egcuc/pages/6332253480
|
|
262
|
-
- **Debug errors HOW-TO**: https://hello.atlassian.net/wiki/spaces/egcuc/pages/6342760320
|
|
263
|
-
|
|
264
|
-
---
|
|
265
|
-
|
|
266
|
-
## Slack Channels
|
|
267
|
-
|
|
268
|
-
- **Engineering**: https://atlassian.enterprise.slack.com/archives/C09DZT1TBNW
|
|
269
|
-
- **Product & Design**: https://atlassian.enterprise.slack.com/archives/C091Y69RBGU
|
|
270
|
-
- **M2 / Jira**: https://atlassian.enterprise.slack.com/archives/C09RS7JCBED
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-synced-block
|
|
2
2
|
|
|
3
|
+
## 6.0.46
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`20b51bc2e61a4`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/20b51bc2e61a4) -
|
|
8
|
+
Remove duplicate source synced blocks when inserting block templates with existing resourceIds and
|
|
9
|
+
show error flag
|
|
10
|
+
- [`15deee785151b`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/15deee785151b) -
|
|
11
|
+
EDITOR-6174 Pass node to createBodiedSyncBlockNode to cache content on creation, preventing false
|
|
12
|
+
unsaved changes on page refresh
|
|
13
|
+
- Updated dependencies
|
|
14
|
+
|
|
15
|
+
## 6.0.45
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- Updated dependencies
|
|
20
|
+
|
|
3
21
|
## 6.0.44
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
|
@@ -17,6 +17,7 @@ var _syncBlock = require("@atlaskit/editor-common/sync-block");
|
|
|
17
17
|
var _utils = require("@atlaskit/editor-common/utils");
|
|
18
18
|
var _editorPluginConnectivity = require("@atlaskit/editor-plugin-connectivity");
|
|
19
19
|
var _state = require("@atlaskit/editor-prosemirror/state");
|
|
20
|
+
var _transform = require("@atlaskit/editor-prosemirror/transform");
|
|
20
21
|
var _view = require("@atlaskit/editor-prosemirror/view");
|
|
21
22
|
var _editorSyncedBlockProvider = require("@atlaskit/editor-synced-block-provider");
|
|
22
23
|
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
@@ -576,11 +577,85 @@ var createPlugin = exports.createPlugin = function createPlugin(options, pmPlugi
|
|
|
576
577
|
_ret = _loop();
|
|
577
578
|
if (_ret) return _ret.v;
|
|
578
579
|
}
|
|
580
|
+
|
|
581
|
+
// Detect and remove duplicate bodiedSyncBlock resourceIds.
|
|
582
|
+
// When a block template containing a source sync block is inserted into the
|
|
583
|
+
// same document, it creates a duplicate with the same resourceId. We keep the
|
|
584
|
+
// first occurrence and delete subsequent duplicates entirely (including their
|
|
585
|
+
// contents), since a document must not contain two source sync blocks with the
|
|
586
|
+
// same resourceId.
|
|
579
587
|
} catch (err) {
|
|
580
588
|
_iterator2.e(err);
|
|
581
589
|
} finally {
|
|
582
590
|
_iterator2.f();
|
|
583
591
|
}
|
|
592
|
+
if (trs.some(function (tr) {
|
|
593
|
+
return tr.docChanged && !tr.getMeta('isRemote');
|
|
594
|
+
}) && (0, _platformFeatureFlags.fg)('platform_synced_block_patch_8')) {
|
|
595
|
+
// Quick check: only walk the full document when at least one
|
|
596
|
+
// transaction inserted a source synced block. This avoids an
|
|
597
|
+
// expensive descendants() traversal on every local edit.
|
|
598
|
+
var hasInsertedSourceBlock = trs.some(function (tr) {
|
|
599
|
+
if (!tr.docChanged || tr.getMeta('isRemote')) {
|
|
600
|
+
return false;
|
|
601
|
+
}
|
|
602
|
+
return tr.steps.some(function (step) {
|
|
603
|
+
if (!(step instanceof _transform.ReplaceStep || step instanceof _transform.ReplaceAroundStep) || !('slice' in step)) {
|
|
604
|
+
return false;
|
|
605
|
+
}
|
|
606
|
+
var _ref0 = step,
|
|
607
|
+
slice = _ref0.slice;
|
|
608
|
+
var found = false;
|
|
609
|
+
slice.content.descendants(function (node) {
|
|
610
|
+
if (syncBlockStore.sourceManager.isSourceBlock(node) && node.attrs.resourceId) {
|
|
611
|
+
found = true;
|
|
612
|
+
}
|
|
613
|
+
return false;
|
|
614
|
+
});
|
|
615
|
+
return found;
|
|
616
|
+
});
|
|
617
|
+
});
|
|
618
|
+
if (!hasInsertedSourceBlock) {
|
|
619
|
+
return null;
|
|
620
|
+
}
|
|
621
|
+
var seenResourceIds = new Set();
|
|
622
|
+
var duplicates = [];
|
|
623
|
+
newState.doc.descendants(function (node, pos) {
|
|
624
|
+
if (syncBlockStore.sourceManager.isSourceBlock(node) && node.attrs.resourceId) {
|
|
625
|
+
if (seenResourceIds.has(node.attrs.resourceId)) {
|
|
626
|
+
duplicates.push({
|
|
627
|
+
pos: pos,
|
|
628
|
+
nodeSize: node.nodeSize
|
|
629
|
+
});
|
|
630
|
+
} else {
|
|
631
|
+
seenResourceIds.add(node.attrs.resourceId);
|
|
632
|
+
}
|
|
633
|
+
return false;
|
|
634
|
+
}
|
|
635
|
+
});
|
|
636
|
+
if (duplicates.length > 0) {
|
|
637
|
+
var tr = newState.tr;
|
|
638
|
+
|
|
639
|
+
// Delete in reverse document order so positions remain valid
|
|
640
|
+
for (var i = duplicates.length - 1; i >= 0; i--) {
|
|
641
|
+
var dup = duplicates[i];
|
|
642
|
+
tr.delete(dup.pos, dup.pos + dup.nodeSize);
|
|
643
|
+
}
|
|
644
|
+
tr.setMeta('addToHistory', false);
|
|
645
|
+
(0, _utils2.deferDispatch)(function () {
|
|
646
|
+
var _api$core;
|
|
647
|
+
api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(function (_ref1) {
|
|
648
|
+
var tr = _ref1.tr;
|
|
649
|
+
return tr.setMeta(syncedBlockPluginKey, {
|
|
650
|
+
activeFlag: {
|
|
651
|
+
id: _types.FLAG_ID.DUPLICATE_SOURCE_SYNC_BLOCK
|
|
652
|
+
}
|
|
653
|
+
});
|
|
654
|
+
});
|
|
655
|
+
});
|
|
656
|
+
return tr;
|
|
657
|
+
}
|
|
658
|
+
}
|
|
584
659
|
return null;
|
|
585
660
|
}
|
|
586
661
|
});
|
|
@@ -99,7 +99,7 @@ var handleBodiedSyncBlockCreation = exports.handleBodiedSyncBlockCreation = func
|
|
|
99
99
|
});
|
|
100
100
|
});
|
|
101
101
|
});
|
|
102
|
-
syncBlockStore.sourceManager.createBodiedSyncBlockNode(node.attrs, function (success) {
|
|
102
|
+
syncBlockStore.sourceManager.createBodiedSyncBlockNode(node.attrs, node.node, function (success) {
|
|
103
103
|
if (success) {
|
|
104
104
|
var _api$core4, _api$core5;
|
|
105
105
|
api === null || api === void 0 || (_api$core4 = api.core) === null || _api$core4 === void 0 || _api$core4.actions.execute(function (_ref3) {
|
package/dist/cjs/types/index.js
CHANGED
|
@@ -14,6 +14,7 @@ var FLAG_ID = exports.FLAG_ID = /*#__PURE__*/function (FLAG_ID) {
|
|
|
14
14
|
FLAG_ID["CANNOT_CREATE_SYNC_BLOCK"] = "cannot-create-sync-block";
|
|
15
15
|
FLAG_ID["INLINE_EXTENSION_IN_SYNC_BLOCK"] = "inline-extension-in-sync-block";
|
|
16
16
|
FLAG_ID["EXTENSION_IN_SYNC_BLOCK"] = "extension-in-sync-block";
|
|
17
|
+
FLAG_ID["DUPLICATE_SOURCE_SYNC_BLOCK"] = "duplicate-source-sync-block";
|
|
17
18
|
return FLAG_ID;
|
|
18
19
|
}({});
|
|
19
20
|
var SYNCED_BLOCK_BUTTON_TEST_ID = exports.SYNCED_BLOCK_BUTTON_TEST_ID = {
|
package/dist/cjs/ui/Flag.js
CHANGED
|
@@ -21,7 +21,7 @@ var _types = require("../types");
|
|
|
21
21
|
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); }
|
|
22
22
|
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; }
|
|
23
23
|
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; }
|
|
24
|
-
var flagMap = (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _types.FLAG_ID.CANNOT_DELETE_WHEN_OFFLINE, {
|
|
24
|
+
var flagMap = (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _types.FLAG_ID.CANNOT_DELETE_WHEN_OFFLINE, {
|
|
25
25
|
title: _messages.syncBlockMessages.failToDeleteTitle,
|
|
26
26
|
description: _messages.syncBlockMessages.failToDeleteWhenOfflineDescription,
|
|
27
27
|
type: 'error'
|
|
@@ -56,6 +56,10 @@ var flagMap = (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _d
|
|
|
56
56
|
title: _messages.syncBlockMessages.inlineExtensionInSyncBlockTitle,
|
|
57
57
|
description: _messages.syncBlockMessages.inlineExtensionInSyncBlockDescription,
|
|
58
58
|
type: 'error'
|
|
59
|
+
}), _types.FLAG_ID.DUPLICATE_SOURCE_SYNC_BLOCK, {
|
|
60
|
+
title: _messages.syncBlockMessages.duplicateSourceSyncBlockTitle,
|
|
61
|
+
description: _messages.syncBlockMessages.duplicateSourceSyncBlockDescription,
|
|
62
|
+
type: 'error'
|
|
59
63
|
});
|
|
60
64
|
var Flag = exports.Flag = function Flag(_ref) {
|
|
61
65
|
var api = _ref.api;
|
|
@@ -7,6 +7,7 @@ import { BodiedSyncBlockSharedCssClassName, SyncBlockStateCssClassName } from '@
|
|
|
7
7
|
import { mapSlice, pmHistoryPluginKey } from '@atlaskit/editor-common/utils';
|
|
8
8
|
import { isOfflineMode } from '@atlaskit/editor-plugin-connectivity';
|
|
9
9
|
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
10
|
+
import { ReplaceAroundStep, ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
|
|
10
11
|
import { DecorationSet, Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
11
12
|
import { convertPMNodesToSyncBlockNodes, rebaseTransaction } from '@atlaskit/editor-synced-block-provider';
|
|
12
13
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
@@ -526,6 +527,80 @@ export const createPlugin = (options, pmPluginFactoryParams, syncBlockStore, api
|
|
|
526
527
|
}
|
|
527
528
|
}
|
|
528
529
|
}
|
|
530
|
+
|
|
531
|
+
// Detect and remove duplicate bodiedSyncBlock resourceIds.
|
|
532
|
+
// When a block template containing a source sync block is inserted into the
|
|
533
|
+
// same document, it creates a duplicate with the same resourceId. We keep the
|
|
534
|
+
// first occurrence and delete subsequent duplicates entirely (including their
|
|
535
|
+
// contents), since a document must not contain two source sync blocks with the
|
|
536
|
+
// same resourceId.
|
|
537
|
+
if (trs.some(tr => tr.docChanged && !tr.getMeta('isRemote')) && fg('platform_synced_block_patch_8')) {
|
|
538
|
+
// Quick check: only walk the full document when at least one
|
|
539
|
+
// transaction inserted a source synced block. This avoids an
|
|
540
|
+
// expensive descendants() traversal on every local edit.
|
|
541
|
+
const hasInsertedSourceBlock = trs.some(tr => {
|
|
542
|
+
if (!tr.docChanged || tr.getMeta('isRemote')) {
|
|
543
|
+
return false;
|
|
544
|
+
}
|
|
545
|
+
return tr.steps.some(step => {
|
|
546
|
+
if (!(step instanceof ReplaceStep || step instanceof ReplaceAroundStep) || !('slice' in step)) {
|
|
547
|
+
return false;
|
|
548
|
+
}
|
|
549
|
+
const {
|
|
550
|
+
slice
|
|
551
|
+
} = step;
|
|
552
|
+
let found = false;
|
|
553
|
+
slice.content.descendants(node => {
|
|
554
|
+
if (syncBlockStore.sourceManager.isSourceBlock(node) && node.attrs.resourceId) {
|
|
555
|
+
found = true;
|
|
556
|
+
}
|
|
557
|
+
return false;
|
|
558
|
+
});
|
|
559
|
+
return found;
|
|
560
|
+
});
|
|
561
|
+
});
|
|
562
|
+
if (!hasInsertedSourceBlock) {
|
|
563
|
+
return null;
|
|
564
|
+
}
|
|
565
|
+
const seenResourceIds = new Set();
|
|
566
|
+
const duplicates = [];
|
|
567
|
+
newState.doc.descendants((node, pos) => {
|
|
568
|
+
if (syncBlockStore.sourceManager.isSourceBlock(node) && node.attrs.resourceId) {
|
|
569
|
+
if (seenResourceIds.has(node.attrs.resourceId)) {
|
|
570
|
+
duplicates.push({
|
|
571
|
+
pos,
|
|
572
|
+
nodeSize: node.nodeSize
|
|
573
|
+
});
|
|
574
|
+
} else {
|
|
575
|
+
seenResourceIds.add(node.attrs.resourceId);
|
|
576
|
+
}
|
|
577
|
+
return false;
|
|
578
|
+
}
|
|
579
|
+
});
|
|
580
|
+
if (duplicates.length > 0) {
|
|
581
|
+
const {
|
|
582
|
+
tr
|
|
583
|
+
} = newState;
|
|
584
|
+
|
|
585
|
+
// Delete in reverse document order so positions remain valid
|
|
586
|
+
for (let i = duplicates.length - 1; i >= 0; i--) {
|
|
587
|
+
const dup = duplicates[i];
|
|
588
|
+
tr.delete(dup.pos, dup.pos + dup.nodeSize);
|
|
589
|
+
}
|
|
590
|
+
tr.setMeta('addToHistory', false);
|
|
591
|
+
deferDispatch(() => {
|
|
592
|
+
var _api$core;
|
|
593
|
+
api === null || api === void 0 ? void 0 : (_api$core = api.core) === null || _api$core === void 0 ? void 0 : _api$core.actions.execute(({
|
|
594
|
+
tr
|
|
595
|
+
}) => tr.setMeta(syncedBlockPluginKey, {
|
|
596
|
+
activeFlag: {
|
|
597
|
+
id: FLAG_ID.DUPLICATE_SOURCE_SYNC_BLOCK
|
|
598
|
+
}
|
|
599
|
+
}));
|
|
600
|
+
});
|
|
601
|
+
return tr;
|
|
602
|
+
}
|
|
603
|
+
}
|
|
529
604
|
return null;
|
|
530
605
|
}
|
|
531
606
|
});
|
|
@@ -91,7 +91,7 @@ export const handleBodiedSyncBlockCreation = (bodiedSyncBlockAdded, editorState,
|
|
|
91
91
|
});
|
|
92
92
|
});
|
|
93
93
|
});
|
|
94
|
-
syncBlockStore.sourceManager.createBodiedSyncBlockNode(node.attrs, success => {
|
|
94
|
+
syncBlockStore.sourceManager.createBodiedSyncBlockNode(node.attrs, node.node, success => {
|
|
95
95
|
if (success) {
|
|
96
96
|
var _api$core4, _api$core5;
|
|
97
97
|
api === null || api === void 0 ? void 0 : (_api$core4 = api.core) === null || _api$core4 === void 0 ? void 0 : _api$core4.actions.execute(({
|
|
@@ -8,6 +8,7 @@ export let FLAG_ID = /*#__PURE__*/function (FLAG_ID) {
|
|
|
8
8
|
FLAG_ID["CANNOT_CREATE_SYNC_BLOCK"] = "cannot-create-sync-block";
|
|
9
9
|
FLAG_ID["INLINE_EXTENSION_IN_SYNC_BLOCK"] = "inline-extension-in-sync-block";
|
|
10
10
|
FLAG_ID["EXTENSION_IN_SYNC_BLOCK"] = "extension-in-sync-block";
|
|
11
|
+
FLAG_ID["DUPLICATE_SOURCE_SYNC_BLOCK"] = "duplicate-source-sync-block";
|
|
11
12
|
return FLAG_ID;
|
|
12
13
|
}({});
|
|
13
14
|
export const SYNCED_BLOCK_BUTTON_TEST_ID = {
|
package/dist/es2019/ui/Flag.js
CHANGED
|
@@ -53,6 +53,11 @@ const flagMap = {
|
|
|
53
53
|
title: messages.inlineExtensionInSyncBlockTitle,
|
|
54
54
|
description: messages.inlineExtensionInSyncBlockDescription,
|
|
55
55
|
type: 'error'
|
|
56
|
+
},
|
|
57
|
+
[FLAG_ID.DUPLICATE_SOURCE_SYNC_BLOCK]: {
|
|
58
|
+
title: messages.duplicateSourceSyncBlockTitle,
|
|
59
|
+
description: messages.duplicateSourceSyncBlockDescription,
|
|
60
|
+
type: 'error'
|
|
56
61
|
}
|
|
57
62
|
};
|
|
58
63
|
export const Flag = ({
|
|
@@ -15,6 +15,7 @@ import { BodiedSyncBlockSharedCssClassName, SyncBlockStateCssClassName } from '@
|
|
|
15
15
|
import { mapSlice, pmHistoryPluginKey } from '@atlaskit/editor-common/utils';
|
|
16
16
|
import { isOfflineMode } from '@atlaskit/editor-plugin-connectivity';
|
|
17
17
|
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
18
|
+
import { ReplaceAroundStep, ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
|
|
18
19
|
import { DecorationSet, Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
19
20
|
import { convertPMNodesToSyncBlockNodes, rebaseTransaction } from '@atlaskit/editor-synced-block-provider';
|
|
20
21
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
@@ -569,11 +570,85 @@ export var createPlugin = function createPlugin(options, pmPluginFactoryParams,
|
|
|
569
570
|
_ret = _loop();
|
|
570
571
|
if (_ret) return _ret.v;
|
|
571
572
|
}
|
|
573
|
+
|
|
574
|
+
// Detect and remove duplicate bodiedSyncBlock resourceIds.
|
|
575
|
+
// When a block template containing a source sync block is inserted into the
|
|
576
|
+
// same document, it creates a duplicate with the same resourceId. We keep the
|
|
577
|
+
// first occurrence and delete subsequent duplicates entirely (including their
|
|
578
|
+
// contents), since a document must not contain two source sync blocks with the
|
|
579
|
+
// same resourceId.
|
|
572
580
|
} catch (err) {
|
|
573
581
|
_iterator2.e(err);
|
|
574
582
|
} finally {
|
|
575
583
|
_iterator2.f();
|
|
576
584
|
}
|
|
585
|
+
if (trs.some(function (tr) {
|
|
586
|
+
return tr.docChanged && !tr.getMeta('isRemote');
|
|
587
|
+
}) && fg('platform_synced_block_patch_8')) {
|
|
588
|
+
// Quick check: only walk the full document when at least one
|
|
589
|
+
// transaction inserted a source synced block. This avoids an
|
|
590
|
+
// expensive descendants() traversal on every local edit.
|
|
591
|
+
var hasInsertedSourceBlock = trs.some(function (tr) {
|
|
592
|
+
if (!tr.docChanged || tr.getMeta('isRemote')) {
|
|
593
|
+
return false;
|
|
594
|
+
}
|
|
595
|
+
return tr.steps.some(function (step) {
|
|
596
|
+
if (!(step instanceof ReplaceStep || step instanceof ReplaceAroundStep) || !('slice' in step)) {
|
|
597
|
+
return false;
|
|
598
|
+
}
|
|
599
|
+
var _ref0 = step,
|
|
600
|
+
slice = _ref0.slice;
|
|
601
|
+
var found = false;
|
|
602
|
+
slice.content.descendants(function (node) {
|
|
603
|
+
if (syncBlockStore.sourceManager.isSourceBlock(node) && node.attrs.resourceId) {
|
|
604
|
+
found = true;
|
|
605
|
+
}
|
|
606
|
+
return false;
|
|
607
|
+
});
|
|
608
|
+
return found;
|
|
609
|
+
});
|
|
610
|
+
});
|
|
611
|
+
if (!hasInsertedSourceBlock) {
|
|
612
|
+
return null;
|
|
613
|
+
}
|
|
614
|
+
var seenResourceIds = new Set();
|
|
615
|
+
var duplicates = [];
|
|
616
|
+
newState.doc.descendants(function (node, pos) {
|
|
617
|
+
if (syncBlockStore.sourceManager.isSourceBlock(node) && node.attrs.resourceId) {
|
|
618
|
+
if (seenResourceIds.has(node.attrs.resourceId)) {
|
|
619
|
+
duplicates.push({
|
|
620
|
+
pos: pos,
|
|
621
|
+
nodeSize: node.nodeSize
|
|
622
|
+
});
|
|
623
|
+
} else {
|
|
624
|
+
seenResourceIds.add(node.attrs.resourceId);
|
|
625
|
+
}
|
|
626
|
+
return false;
|
|
627
|
+
}
|
|
628
|
+
});
|
|
629
|
+
if (duplicates.length > 0) {
|
|
630
|
+
var tr = newState.tr;
|
|
631
|
+
|
|
632
|
+
// Delete in reverse document order so positions remain valid
|
|
633
|
+
for (var i = duplicates.length - 1; i >= 0; i--) {
|
|
634
|
+
var dup = duplicates[i];
|
|
635
|
+
tr.delete(dup.pos, dup.pos + dup.nodeSize);
|
|
636
|
+
}
|
|
637
|
+
tr.setMeta('addToHistory', false);
|
|
638
|
+
deferDispatch(function () {
|
|
639
|
+
var _api$core;
|
|
640
|
+
api === null || api === void 0 || (_api$core = api.core) === null || _api$core === void 0 || _api$core.actions.execute(function (_ref1) {
|
|
641
|
+
var tr = _ref1.tr;
|
|
642
|
+
return tr.setMeta(syncedBlockPluginKey, {
|
|
643
|
+
activeFlag: {
|
|
644
|
+
id: FLAG_ID.DUPLICATE_SOURCE_SYNC_BLOCK
|
|
645
|
+
}
|
|
646
|
+
});
|
|
647
|
+
});
|
|
648
|
+
});
|
|
649
|
+
return tr;
|
|
650
|
+
}
|
|
651
|
+
}
|
|
577
652
|
return null;
|
|
578
653
|
}
|
|
579
654
|
});
|
|
@@ -92,7 +92,7 @@ export var handleBodiedSyncBlockCreation = function handleBodiedSyncBlockCreatio
|
|
|
92
92
|
});
|
|
93
93
|
});
|
|
94
94
|
});
|
|
95
|
-
syncBlockStore.sourceManager.createBodiedSyncBlockNode(node.attrs, function (success) {
|
|
95
|
+
syncBlockStore.sourceManager.createBodiedSyncBlockNode(node.attrs, node.node, function (success) {
|
|
96
96
|
if (success) {
|
|
97
97
|
var _api$core4, _api$core5;
|
|
98
98
|
api === null || api === void 0 || (_api$core4 = api.core) === null || _api$core4 === void 0 || _api$core4.actions.execute(function (_ref3) {
|
package/dist/esm/types/index.js
CHANGED
|
@@ -8,6 +8,7 @@ export var FLAG_ID = /*#__PURE__*/function (FLAG_ID) {
|
|
|
8
8
|
FLAG_ID["CANNOT_CREATE_SYNC_BLOCK"] = "cannot-create-sync-block";
|
|
9
9
|
FLAG_ID["INLINE_EXTENSION_IN_SYNC_BLOCK"] = "inline-extension-in-sync-block";
|
|
10
10
|
FLAG_ID["EXTENSION_IN_SYNC_BLOCK"] = "extension-in-sync-block";
|
|
11
|
+
FLAG_ID["DUPLICATE_SOURCE_SYNC_BLOCK"] = "duplicate-source-sync-block";
|
|
11
12
|
return FLAG_ID;
|
|
12
13
|
}({});
|
|
13
14
|
export var SYNCED_BLOCK_BUTTON_TEST_ID = {
|
package/dist/esm/ui/Flag.js
CHANGED
|
@@ -12,7 +12,7 @@ import StatusSuccessIcon from '@atlaskit/icon/core/status-success';
|
|
|
12
12
|
import StatusWarningIcon from '@atlaskit/icon/core/status-warning';
|
|
13
13
|
import { syncedBlockPluginKey } from '../pm-plugins/main';
|
|
14
14
|
import { FLAG_ID } from '../types';
|
|
15
|
-
var flagMap = _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({}, FLAG_ID.CANNOT_DELETE_WHEN_OFFLINE, {
|
|
15
|
+
var flagMap = _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({}, FLAG_ID.CANNOT_DELETE_WHEN_OFFLINE, {
|
|
16
16
|
title: messages.failToDeleteTitle,
|
|
17
17
|
description: messages.failToDeleteWhenOfflineDescription,
|
|
18
18
|
type: 'error'
|
|
@@ -47,6 +47,10 @@ var flagMap = _defineProperty(_defineProperty(_defineProperty(_defineProperty(_d
|
|
|
47
47
|
title: messages.inlineExtensionInSyncBlockTitle,
|
|
48
48
|
description: messages.inlineExtensionInSyncBlockDescription,
|
|
49
49
|
type: 'error'
|
|
50
|
+
}), FLAG_ID.DUPLICATE_SOURCE_SYNC_BLOCK, {
|
|
51
|
+
title: messages.duplicateSourceSyncBlockTitle,
|
|
52
|
+
description: messages.duplicateSourceSyncBlockDescription,
|
|
53
|
+
type: 'error'
|
|
50
54
|
});
|
|
51
55
|
export var Flag = function Flag(_ref) {
|
|
52
56
|
var api = _ref.api;
|
|
@@ -10,7 +10,8 @@ export declare enum FLAG_ID {
|
|
|
10
10
|
UNPUBLISHED_SYNC_BLOCK_PASTED = "unpublished-sync-block-pasted",
|
|
11
11
|
CANNOT_CREATE_SYNC_BLOCK = "cannot-create-sync-block",
|
|
12
12
|
INLINE_EXTENSION_IN_SYNC_BLOCK = "inline-extension-in-sync-block",
|
|
13
|
-
EXTENSION_IN_SYNC_BLOCK = "extension-in-sync-block"
|
|
13
|
+
EXTENSION_IN_SYNC_BLOCK = "extension-in-sync-block",
|
|
14
|
+
DUPLICATE_SOURCE_SYNC_BLOCK = "duplicate-source-sync-block"
|
|
14
15
|
}
|
|
15
16
|
type FlagConfig = {
|
|
16
17
|
id: FLAG_ID;
|
|
@@ -10,7 +10,8 @@ export declare enum FLAG_ID {
|
|
|
10
10
|
UNPUBLISHED_SYNC_BLOCK_PASTED = "unpublished-sync-block-pasted",
|
|
11
11
|
CANNOT_CREATE_SYNC_BLOCK = "cannot-create-sync-block",
|
|
12
12
|
INLINE_EXTENSION_IN_SYNC_BLOCK = "inline-extension-in-sync-block",
|
|
13
|
-
EXTENSION_IN_SYNC_BLOCK = "extension-in-sync-block"
|
|
13
|
+
EXTENSION_IN_SYNC_BLOCK = "extension-in-sync-block",
|
|
14
|
+
DUPLICATE_SOURCE_SYNC_BLOCK = "duplicate-source-sync-block"
|
|
14
15
|
}
|
|
15
16
|
type FlagConfig = {
|
|
16
17
|
id: FLAG_ID;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-synced-block",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.46",
|
|
4
4
|
"description": "SyncedBlock plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"atlaskit:src": "src/index.ts",
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@atlaskit/adf-schema": "^52.4.0",
|
|
32
|
-
"@atlaskit/button": "23.10.
|
|
33
|
-
"@atlaskit/dropdown-menu": "16.8.
|
|
32
|
+
"@atlaskit/button": "23.10.10",
|
|
33
|
+
"@atlaskit/dropdown-menu": "16.8.6",
|
|
34
34
|
"@atlaskit/editor-json-transformer": "^8.31.0",
|
|
35
35
|
"@atlaskit/editor-plugin-analytics": "^8.0.0",
|
|
36
36
|
"@atlaskit/editor-plugin-block-menu": "^7.0.0",
|
|
@@ -46,16 +46,16 @@
|
|
|
46
46
|
"@atlaskit/editor-synced-block-provider": "^4.3.0",
|
|
47
47
|
"@atlaskit/editor-toolbar": "^0.20.0",
|
|
48
48
|
"@atlaskit/flag": "^17.9.0",
|
|
49
|
-
"@atlaskit/icon": "34.0.
|
|
50
|
-
"@atlaskit/icon-lab": "^6.
|
|
49
|
+
"@atlaskit/icon": "34.0.2",
|
|
50
|
+
"@atlaskit/icon-lab": "^6.4.0",
|
|
51
51
|
"@atlaskit/logo": "^19.10.0",
|
|
52
52
|
"@atlaskit/lozenge": "^13.5.0",
|
|
53
53
|
"@atlaskit/modal-dialog": "^14.14.0",
|
|
54
54
|
"@atlaskit/platform-feature-flags": "^1.1.0",
|
|
55
55
|
"@atlaskit/primitives": "^18.1.0",
|
|
56
|
-
"@atlaskit/spinner": "19.0.
|
|
57
|
-
"@atlaskit/tmp-editor-statsig": "^54.
|
|
58
|
-
"@atlaskit/tokens": "11.4.
|
|
56
|
+
"@atlaskit/spinner": "19.0.14",
|
|
57
|
+
"@atlaskit/tmp-editor-statsig": "^54.4.0",
|
|
58
|
+
"@atlaskit/tokens": "11.4.3",
|
|
59
59
|
"@atlaskit/tooltip": "^21.1.0",
|
|
60
60
|
"@atlaskit/visually-hidden": "^3.0.0",
|
|
61
61
|
"@babel/runtime": "^7.0.0",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"react-intl-next": "npm:react-intl@^5.18.1"
|
|
66
66
|
},
|
|
67
67
|
"peerDependencies": {
|
|
68
|
-
"@atlaskit/editor-common": "^112.
|
|
68
|
+
"@atlaskit/editor-common": "^112.18.0",
|
|
69
69
|
"react": "^18.2.0"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|