@atlaskit/editor-plugin-show-diff 10.4.0 → 10.4.2

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,25 @@
1
1
  # @atlaskit/editor-plugin-show-diff
2
2
 
3
+ ## 10.4.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [`a41c9b243974d`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/a41c9b243974d) -
8
+ Fix smart diff fabricating a phantom whole-block deletion when a new block is inserted at a
9
+ top-level boundary (e.g. a paragraph added immediately before a bulletList). topLevelBlocksInRange
10
+ now treats a zero-width insertion anchor sitting exactly on a top-level block boundary as touching
11
+ no block, so a pure insertion is no longer mis-paired with the following block and converted into
12
+ a whole-block replacement. This also lets pure whole-block deletions surface under smart diff.
13
+ - Updated dependencies
14
+
15
+ ## 10.4.1
16
+
17
+ ### Patch Changes
18
+
19
+ - [`81ce4d8f5cd8a`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/81ce4d8f5cd8a) -
20
+ Show blue indicators for new added paragraphs and headings
21
+ - Updated dependencies
22
+
3
23
  ## 10.4.0
4
24
 
5
25
  ### Minor Changes
@@ -168,14 +168,24 @@ var topLevelBlocksInRange = function topLevelBlocksInRange(doc, from, to) {
168
168
  var node = doc.child(i);
169
169
  var blockFrom = offset;
170
170
  var blockTo = offset + node.nodeSize;
171
- // Overlap test; include a zero-width touch at the block start (pure insertion point).
172
- if (blockFrom < hi && blockTo > lo) {
173
- refs.push({
174
- node: node,
175
- from: blockFrom,
176
- to: blockTo
177
- });
178
- } else if (blockFrom === lo && blockFrom === hi) {
171
+ // Non-empty range: standard half-open overlap test.
172
+ if (lo < hi) {
173
+ if (blockFrom < hi && blockTo > lo) {
174
+ refs.push({
175
+ node: node,
176
+ from: blockFrom,
177
+ to: blockTo
178
+ });
179
+ }
180
+ } else if (blockFrom < lo && lo < blockTo) {
181
+ // Zero-width range (an insertion anchor): only match a block whose INTERIOR strictly
182
+ // contains the point. A point sitting exactly on a top-level block boundary
183
+ // (`blockFrom === lo`, i.e. between two sibling blocks) is a pure insertion BETWEEN
184
+ // blocks — it must resolve to NO block, otherwise `groupByTopLevelBlock` pairs the
185
+ // insertion with the following block and `classifyBlockGroup` converts the insert into a
186
+ // whole-block replacement, fabricating a phantom deletion of that untouched block.
187
+ // Interior points (a nested insertion inside a container being edited) still resolve
188
+ // their container so the classifier can recurse into it.
179
189
  refs.push({
180
190
  node: node,
181
191
  from: blockFrom,
@@ -176,17 +176,7 @@ var createLeftAnchorWidget = exports.createLeftAnchorWidget = function createLef
176
176
  side: -999
177
177
  }));
178
178
  };
179
- var isFullNodeRange = function isFullNodeRange(doc, from, to) {
180
- var matchesFullNodeRange = false;
181
- doc.nodesBetween(from, to, function (node, pos) {
182
- if (pos === from && pos + node.nodeSize === to) {
183
- matchesFullNodeRange = true;
184
- return false;
185
- }
186
- return true;
187
- });
188
- return matchesFullNodeRange;
189
- };
179
+
190
180
  /**
191
181
  * Creates invisible anchor widgets for a single block-changed diff so that the
192
182
  * `IndicatorBar` can use CSS anchor positioning to align itself with the diff.
@@ -197,8 +187,6 @@ var isFullNodeRange = function isFullNodeRange(doc, from, to) {
197
187
  * - An optional `left` anchor is placed inside a resizable container (table,
198
188
  * layout, expand) so the bar aligns within the container boundary.
199
189
  *
200
- * Unlike the inline variant there is no `isFullNodeRange` guard — block diffs
201
- * always span exactly one block node so the anchors are always needed.
202
190
  */
203
191
  var createBlockIndicatorAnchorWidgets = exports.createBlockIndicatorAnchorWidgets = function createBlockIndicatorAnchorWidgets(_ref2) {
204
192
  var doc = _ref2.doc,
@@ -309,9 +297,6 @@ var createInlineIndicatorAnchorWidgets = exports.createInlineIndicatorAnchorWidg
309
297
  from = _ref3.from,
310
298
  to = _ref3.to,
311
299
  diffId = _ref3.diffId;
312
- if (isFullNodeRange(doc, from, to)) {
313
- return [];
314
- }
315
300
  var leftAnchor = createLeftAnchorWidget({
316
301
  doc: doc,
317
302
  from: from,
@@ -141,14 +141,24 @@ const topLevelBlocksInRange = (doc, from, to) => {
141
141
  const node = doc.child(i);
142
142
  const blockFrom = offset;
143
143
  const blockTo = offset + node.nodeSize;
144
- // Overlap test; include a zero-width touch at the block start (pure insertion point).
145
- if (blockFrom < hi && blockTo > lo) {
146
- refs.push({
147
- node,
148
- from: blockFrom,
149
- to: blockTo
150
- });
151
- } else if (blockFrom === lo && blockFrom === hi) {
144
+ // Non-empty range: standard half-open overlap test.
145
+ if (lo < hi) {
146
+ if (blockFrom < hi && blockTo > lo) {
147
+ refs.push({
148
+ node,
149
+ from: blockFrom,
150
+ to: blockTo
151
+ });
152
+ }
153
+ } else if (blockFrom < lo && lo < blockTo) {
154
+ // Zero-width range (an insertion anchor): only match a block whose INTERIOR strictly
155
+ // contains the point. A point sitting exactly on a top-level block boundary
156
+ // (`blockFrom === lo`, i.e. between two sibling blocks) is a pure insertion BETWEEN
157
+ // blocks — it must resolve to NO block, otherwise `groupByTopLevelBlock` pairs the
158
+ // insertion with the following block and `classifyBlockGroup` converts the insert into a
159
+ // whole-block replacement, fabricating a phantom deletion of that untouched block.
160
+ // Interior points (a nested insertion inside a container being edited) still resolve
161
+ // their container so the classifier can recurse into it.
152
162
  refs.push({
153
163
  node,
154
164
  from: blockFrom,
@@ -174,17 +174,7 @@ export const createLeftAnchorWidget = ({
174
174
  side: -999
175
175
  }));
176
176
  };
177
- const isFullNodeRange = (doc, from, to) => {
178
- let matchesFullNodeRange = false;
179
- doc.nodesBetween(from, to, (node, pos) => {
180
- if (pos === from && pos + node.nodeSize === to) {
181
- matchesFullNodeRange = true;
182
- return false;
183
- }
184
- return true;
185
- });
186
- return matchesFullNodeRange;
187
- };
177
+
188
178
  /**
189
179
  * Creates invisible anchor widgets for a single block-changed diff so that the
190
180
  * `IndicatorBar` can use CSS anchor positioning to align itself with the diff.
@@ -195,8 +185,6 @@ const isFullNodeRange = (doc, from, to) => {
195
185
  * - An optional `left` anchor is placed inside a resizable container (table,
196
186
  * layout, expand) so the bar aligns within the container boundary.
197
187
  *
198
- * Unlike the inline variant there is no `isFullNodeRange` guard — block diffs
199
- * always span exactly one block node so the anchors are always needed.
200
188
  */
201
189
  export const createBlockIndicatorAnchorWidgets = ({
202
190
  doc,
@@ -305,9 +293,6 @@ export const createInlineIndicatorAnchorWidgets = ({
305
293
  to,
306
294
  diffId
307
295
  }) => {
308
- if (isFullNodeRange(doc, from, to)) {
309
- return [];
310
- }
311
296
  const leftAnchor = createLeftAnchorWidget({
312
297
  doc,
313
298
  from,
@@ -161,14 +161,24 @@ var topLevelBlocksInRange = function topLevelBlocksInRange(doc, from, to) {
161
161
  var node = doc.child(i);
162
162
  var blockFrom = offset;
163
163
  var blockTo = offset + node.nodeSize;
164
- // Overlap test; include a zero-width touch at the block start (pure insertion point).
165
- if (blockFrom < hi && blockTo > lo) {
166
- refs.push({
167
- node: node,
168
- from: blockFrom,
169
- to: blockTo
170
- });
171
- } else if (blockFrom === lo && blockFrom === hi) {
164
+ // Non-empty range: standard half-open overlap test.
165
+ if (lo < hi) {
166
+ if (blockFrom < hi && blockTo > lo) {
167
+ refs.push({
168
+ node: node,
169
+ from: blockFrom,
170
+ to: blockTo
171
+ });
172
+ }
173
+ } else if (blockFrom < lo && lo < blockTo) {
174
+ // Zero-width range (an insertion anchor): only match a block whose INTERIOR strictly
175
+ // contains the point. A point sitting exactly on a top-level block boundary
176
+ // (`blockFrom === lo`, i.e. between two sibling blocks) is a pure insertion BETWEEN
177
+ // blocks — it must resolve to NO block, otherwise `groupByTopLevelBlock` pairs the
178
+ // insertion with the following block and `classifyBlockGroup` converts the insert into a
179
+ // whole-block replacement, fabricating a phantom deletion of that untouched block.
180
+ // Interior points (a nested insertion inside a container being edited) still resolve
181
+ // their container so the classifier can recurse into it.
172
182
  refs.push({
173
183
  node: node,
174
184
  from: blockFrom,
@@ -171,17 +171,7 @@ export var createLeftAnchorWidget = function createLeftAnchorWidget(_ref) {
171
171
  side: -999
172
172
  }));
173
173
  };
174
- var isFullNodeRange = function isFullNodeRange(doc, from, to) {
175
- var matchesFullNodeRange = false;
176
- doc.nodesBetween(from, to, function (node, pos) {
177
- if (pos === from && pos + node.nodeSize === to) {
178
- matchesFullNodeRange = true;
179
- return false;
180
- }
181
- return true;
182
- });
183
- return matchesFullNodeRange;
184
- };
174
+
185
175
  /**
186
176
  * Creates invisible anchor widgets for a single block-changed diff so that the
187
177
  * `IndicatorBar` can use CSS anchor positioning to align itself with the diff.
@@ -192,8 +182,6 @@ var isFullNodeRange = function isFullNodeRange(doc, from, to) {
192
182
  * - An optional `left` anchor is placed inside a resizable container (table,
193
183
  * layout, expand) so the bar aligns within the container boundary.
194
184
  *
195
- * Unlike the inline variant there is no `isFullNodeRange` guard — block diffs
196
- * always span exactly one block node so the anchors are always needed.
197
185
  */
198
186
  export var createBlockIndicatorAnchorWidgets = function createBlockIndicatorAnchorWidgets(_ref2) {
199
187
  var doc = _ref2.doc,
@@ -304,9 +292,6 @@ export var createInlineIndicatorAnchorWidgets = function createInlineIndicatorAn
304
292
  from = _ref3.from,
305
293
  to = _ref3.to,
306
294
  diffId = _ref3.diffId;
307
- if (isFullNodeRange(doc, from, to)) {
308
- return [];
309
- }
310
295
  var leftAnchor = createLeftAnchorWidget({
311
296
  doc: doc,
312
297
  from: from,
@@ -31,8 +31,6 @@ export declare const createLeftAnchorWidget: ({ doc, from, diffId, }: {
31
31
  * - An optional `left` anchor is placed inside a resizable container (table,
32
32
  * layout, expand) so the bar aligns within the container boundary.
33
33
  *
34
- * Unlike the inline variant there is no `isFullNodeRange` guard — block diffs
35
- * always span exactly one block node so the anchors are always needed.
36
34
  */
37
35
  export declare const createBlockIndicatorAnchorWidgets: ({ doc, from, to, diffId, }: {
38
36
  diffId: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-show-diff",
3
- "version": "10.4.0",
3
+ "version": "10.4.2",
4
4
  "description": "ShowDiff plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -28,8 +28,8 @@
28
28
  "@atlaskit/editor-prosemirror": "^8.0.0",
29
29
  "@atlaskit/editor-tables": "^3.0.0",
30
30
  "@atlaskit/platform-feature-flags": "^2.0.0",
31
- "@atlaskit/tmp-editor-statsig": "^124.1.0",
32
- "@atlaskit/tokens": "^15.6.0",
31
+ "@atlaskit/tmp-editor-statsig": "^124.4.0",
32
+ "@atlaskit/tokens": "^15.7.0",
33
33
  "@babel/runtime": "^7.0.0",
34
34
  "@compiled/react": "^0.20.0",
35
35
  "lodash": "^4.17.21",
@@ -41,7 +41,7 @@
41
41
  "@atlaskit/button": "^24.3.0",
42
42
  "@atlaskit/css": "^1.0.0",
43
43
  "@atlaskit/dropdown-menu": "^17.1.0",
44
- "@atlaskit/editor-core": "^221.8.0",
44
+ "@atlaskit/editor-core": "^221.9.0",
45
45
  "@atlaskit/editor-json-transformer": "^9.0.0",
46
46
  "@atlaskit/form": "^16.1.0",
47
47
  "@atlaskit/primitives": "^20.6.0",
@@ -54,7 +54,7 @@
54
54
  "react-intl": "^7.0.0"
55
55
  },
56
56
  "peerDependencies": {
57
- "@atlaskit/editor-common": "^116.25.0",
57
+ "@atlaskit/editor-common": "^116.27.0",
58
58
  "react": "^18.2.0"
59
59
  },
60
60
  "techstack": {