@atlaskit/editor-plugin-placeholder 12.0.20 → 12.0.21

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-placeholder
2
2
 
3
+ ## 12.0.21
4
+
5
+ ### Patch Changes
6
+
7
+ - [`12355710b809c`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/12355710b809c) -
8
+ Add the `platform_editor_sync_block_activation` boolean experiment API to
9
+ `@atlaskit/tmp-editor-statsig` for Confluence sync block activation checks. Consumers can gate
10
+ sync block activation behavior with
11
+ `expValEquals('platform_editor_sync_block_activation', 'isEnabled', true)`, for example to keep
12
+ source synced block placeholders visible only while the activation experiment is enabled.
13
+
14
+ Decoration-based placeholders now remain visible for empty source synced blocks while activation
15
+ is enabled.
16
+
17
+ The bodied synced block source nodeview now keeps its existing SSR streaming label-container fix
18
+ and only applies the non-SSR separate label container behavior when
19
+ `platform_synced_block_patch_14` is enabled.
20
+
21
+ - Updated dependencies
22
+
3
23
  ## 12.0.20
4
24
 
5
25
  ### Patch Changes
@@ -1,15 +1,20 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
3
4
  Object.defineProperty(exports, "__esModule", {
4
5
  value: true
5
6
  });
6
7
  exports.default = createPlugin;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
7
9
  var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
8
10
  var _expVal = require("@atlaskit/tmp-editor-statsig/expVal");
9
11
  var _placeholderPlugin = require("../placeholderPlugin");
10
12
  var _constants = require("./constants");
11
13
  var _decorations = require("./decorations");
14
+ var _sourceSyncBlockPlaceholderDecorations = require("./source-sync-block-placeholder-decorations");
12
15
  var _utils = require("./utils");
16
+ 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; }
17
+ 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; }
13
18
  function createPlugin(intl, defaultPlaceholderText, bracketPlaceholderText, emptyLinePlaceholder, placeholderPrompts, withEmptyParagraph, initialIsPlaceholderHidden, placeholderADF, isRovoLLMEnabled, api) {
14
19
  if (!defaultPlaceholderText && !placeholderPrompts && !bracketPlaceholderText && !placeholderADF) {
15
20
  return;
@@ -27,7 +32,7 @@ function createPlugin(intl, defaultPlaceholderText, bracketPlaceholderText, empt
27
32
  state: {
28
33
  init: function init(_, state) {
29
34
  var _api$focus, _api$typeAhead;
30
- return (0, _utils.createPlaceHolderStateFrom)({
35
+ return _objectSpread(_objectSpread({}, (0, _utils.createPlaceHolderStateFrom)({
31
36
  isInitial: true,
32
37
  isEditorFocused: Boolean(api === null || api === void 0 || (_api$focus = api.focus) === null || _api$focus === void 0 || (_api$focus = _api$focus.sharedState.currentState()) === null || _api$focus === void 0 ? void 0 : _api$focus.hasFocus),
33
38
  editorState: state,
@@ -42,6 +47,8 @@ function createPlugin(intl, defaultPlaceholderText, bracketPlaceholderText, empt
42
47
  intl: intl,
43
48
  withEmptyParagraph: withEmptyParagraph,
44
49
  isPlaceholderHidden: initialIsPlaceholderHidden
50
+ })), {}, {
51
+ sourceSyncBlockPlaceholderDecorations: (0, _sourceSyncBlockPlaceholderDecorations.createSourceSyncBlockPlaceholderDecorations)(state, intl)
45
52
  });
46
53
  },
47
54
  apply: function apply(tr, placeholderState, _oldEditorState, newEditorState) {
@@ -68,7 +75,7 @@ function createPlugin(intl, defaultPlaceholderText, bracketPlaceholderText, empt
68
75
  defaultPlaceholderText = meta.placeholderText;
69
76
  }
70
77
  }
71
- var newPlaceholderState = (0, _utils.createPlaceHolderStateFrom)({
78
+ var newPlaceholderState = _objectSpread(_objectSpread({}, (0, _utils.createPlaceHolderStateFrom)({
72
79
  isEditorFocused: isEditorFocused,
73
80
  editorState: newEditorState,
74
81
  isTypeAheadOpen: api === null || api === void 0 || (_api$typeAhead2 = api.typeAhead) === null || _api$typeAhead2 === void 0 ? void 0 : _api$typeAhead2.actions.isOpen,
@@ -83,6 +90,14 @@ function createPlugin(intl, defaultPlaceholderText, bracketPlaceholderText, empt
83
90
  isPlaceholderHidden: isPlaceholderHidden,
84
91
  withEmptyParagraph: withEmptyParagraph,
85
92
  showOnEmptyParagraph: (_meta$showOnEmptyPara = meta === null || meta === void 0 ? void 0 : meta.showOnEmptyParagraph) !== null && _meta$showOnEmptyPara !== void 0 ? _meta$showOnEmptyPara : placeholderState === null || placeholderState === void 0 ? void 0 : placeholderState.showOnEmptyParagraph
93
+ })), {}, {
94
+ sourceSyncBlockPlaceholderDecorations: (0, _sourceSyncBlockPlaceholderDecorations.updateSourceSyncBlockPlaceholderDecorations)({
95
+ currentDecorationSet: placeholderState === null || placeholderState === void 0 ? void 0 : placeholderState.sourceSyncBlockPlaceholderDecorations,
96
+ intl: intl,
97
+ newEditorState: newEditorState,
98
+ oldEditorState: _oldEditorState,
99
+ tr: tr
100
+ })
86
101
  });
87
102
 
88
103
  // Clear timeouts when hasPlaceholder becomes false
@@ -105,7 +120,8 @@ function createPlugin(intl, defaultPlaceholderText, bracketPlaceholderText, empt
105
120
  pos = _getPlaceholderState.pos,
106
121
  typedAndDeleted = _getPlaceholderState.typedAndDeleted,
107
122
  contextPlaceholderADF = _getPlaceholderState.contextPlaceholderADF,
108
- showOnEmptyParagraph = _getPlaceholderState.showOnEmptyParagraph;
123
+ showOnEmptyParagraph = _getPlaceholderState.showOnEmptyParagraph,
124
+ sourceSyncBlockPlaceholderDecorations = _getPlaceholderState.sourceSyncBlockPlaceholderDecorations;
109
125
 
110
126
  // Decorations is still called after plugin is destroyed
111
127
  // So we need to make sure decorations is not called if plugin has been destroyed to prevent the placeholder animations' setTimeouts called infinitely
@@ -114,13 +130,15 @@ function createPlugin(intl, defaultPlaceholderText, bracketPlaceholderText, empt
114
130
  }
115
131
  var compositionPluginState = api === null || api === void 0 || (_api$composition = api.composition) === null || _api$composition === void 0 ? void 0 : _api$composition.sharedState.currentState();
116
132
  var isShowingDiff = Boolean(api === null || api === void 0 || (_api$showDiff = api.showDiff) === null || _api$showDiff === void 0 || (_api$showDiff = _api$showDiff.sharedState.currentState()) === null || _api$showDiff === void 0 ? void 0 : _api$showDiff.isDisplayingChanges);
133
+ var syncBlockPlaceholderDecorations = !(compositionPluginState !== null && compositionPluginState !== void 0 && compositionPluginState.isComposing) && !isShowingDiff ? sourceSyncBlockPlaceholderDecorations : undefined;
117
134
  if (hasPlaceholder && ((placeholderText !== null && placeholderText !== void 0 ? placeholderText : '') || placeholderPrompts || placeholderADF || contextPlaceholderADF) && pos !== undefined && !(compositionPluginState !== null && compositionPluginState !== void 0 && compositionPluginState.isComposing) && !isShowingDiff) {
135
+ var _syncBlockPlaceholder;
118
136
  var initialDelayWhenUserTypedAndDeleted = typedAndDeleted ? _constants.TYPEWRITER_TYPED_AND_DELETED_DELAY : 0;
119
137
  // contextPlaceholderADF takes precedence over the global placeholderADF
120
138
  var placeholderAdfToUse = contextPlaceholderADF || placeholderADF;
121
- return (0, _decorations.createPlaceholderDecoration)(editorState, placeholderText !== null && placeholderText !== void 0 ? placeholderText : '', placeholderPrompts, activeTypewriterTimeouts, pos, initialDelayWhenUserTypedAndDeleted, placeholderAdfToUse, showOnEmptyParagraph);
139
+ return (0, _decorations.createPlaceholderDecoration)(editorState, placeholderText !== null && placeholderText !== void 0 ? placeholderText : '', placeholderPrompts, activeTypewriterTimeouts, pos, initialDelayWhenUserTypedAndDeleted, placeholderAdfToUse, showOnEmptyParagraph).add(editorState.doc, (_syncBlockPlaceholder = syncBlockPlaceholderDecorations === null || syncBlockPlaceholderDecorations === void 0 ? void 0 : syncBlockPlaceholderDecorations.find()) !== null && _syncBlockPlaceholder !== void 0 ? _syncBlockPlaceholder : []);
122
140
  }
123
- return;
141
+ return syncBlockPlaceholderDecorations;
124
142
  }
125
143
  },
126
144
  view: function view() {
@@ -0,0 +1,132 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createSourceSyncBlockPlaceholderDecorations = createSourceSyncBlockPlaceholderDecorations;
7
+ exports.updateSourceSyncBlockPlaceholderDecorations = updateSourceSyncBlockPlaceholderDecorations;
8
+ var _messages = require("@atlaskit/editor-common/messages");
9
+ var _view = require("@atlaskit/editor-prosemirror/view");
10
+ var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
11
+ var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
12
+ var _constants = require("./constants");
13
+ var isEmptySourceSyncBlock = function isEmptySourceSyncBlock(node) {
14
+ var _node$firstChild, _node$firstChild2;
15
+ return _constants.nodeTypesWithSyncBlockPlaceholderText.includes(node.type.name) && node.childCount === 1 && ((_node$firstChild = node.firstChild) === null || _node$firstChild === void 0 ? void 0 : _node$firstChild.content.size) === 0 && ((_node$firstChild2 = node.firstChild) === null || _node$firstChild2 === void 0 ? void 0 : _node$firstChild2.type.name) === 'paragraph';
16
+ };
17
+ var createSourceSyncBlockPlaceholderElement = function createSourceSyncBlockPlaceholderElement(intl) {
18
+ var placeholderDecoration = document.createElement('span');
19
+ placeholderDecoration.setAttribute('data-testid', _constants.placeholderTestId);
20
+ placeholderDecoration.className = 'placeholder-decoration';
21
+ placeholderDecoration.setAttribute('aria-hidden', 'true');
22
+ placeholderDecoration.textContent = intl.formatMessage(_messages.placeholderTextMessages.sourceSyncBlockPlaceholderText);
23
+ return placeholderDecoration;
24
+ };
25
+ var createSourceSyncBlockPlaceholderDecoration = function createSourceSyncBlockPlaceholderDecoration(pos, intl) {
26
+ return _view.Decoration.widget(pos + 2, function () {
27
+ return createSourceSyncBlockPlaceholderElement(intl);
28
+ }, {
29
+ side: 0,
30
+ key: "source-sync-block-placeholder-".concat(pos)
31
+ });
32
+ };
33
+ var isSourceSyncBlockPlaceholderEnabled = function isSourceSyncBlockPlaceholderEnabled() {
34
+ return (0, _expValEquals.expValEquals)('platform_editor_sync_block_activation', 'isEnabled', true) && (0, _experiments.editorExperiment)('platform_synced_block', true);
35
+ };
36
+ var getChangedRanges = function getChangedRanges(tr) {
37
+ var ranges = [];
38
+ tr.mapping.maps.forEach(function (stepMap, index) {
39
+ stepMap.forEach(function (_oldStart, _oldEnd, newStart, newEnd) {
40
+ var mappingAfterStep = tr.mapping.slice(index + 1);
41
+ ranges.push({
42
+ from: mappingAfterStep.map(newStart, -1),
43
+ to: mappingAfterStep.map(newEnd, 1)
44
+ });
45
+ });
46
+ });
47
+ return ranges;
48
+ };
49
+ var getSourceSyncBlockRange = function getSourceSyncBlockRange(doc, pos) {
50
+ var resolvedPos = doc.resolve(Math.max(0, Math.min(pos, doc.content.size)));
51
+ for (var depth = resolvedPos.depth; depth > 0; depth--) {
52
+ var node = resolvedPos.node(depth);
53
+ if (_constants.nodeTypesWithSyncBlockPlaceholderText.includes(node.type.name)) {
54
+ return {
55
+ from: resolvedPos.before(depth),
56
+ to: resolvedPos.after(depth)
57
+ };
58
+ }
59
+ }
60
+ return;
61
+ };
62
+ var getAffectedSourceSyncBlockRanges = function getAffectedSourceSyncBlockRanges(doc, ranges) {
63
+ var affectedRanges = new Map();
64
+ ranges.forEach(function (_ref) {
65
+ var from = _ref.from,
66
+ to = _ref.to;
67
+ [from, to].forEach(function (pos) {
68
+ var sourceSyncBlockRange = getSourceSyncBlockRange(doc, pos);
69
+ if (sourceSyncBlockRange) {
70
+ affectedRanges.set("".concat(sourceSyncBlockRange.from, "-").concat(sourceSyncBlockRange.to), sourceSyncBlockRange);
71
+ }
72
+ });
73
+ doc.nodesBetween(from, to, function (node, pos) {
74
+ if (_constants.nodeTypesWithSyncBlockPlaceholderText.includes(node.type.name)) {
75
+ var sourceSyncBlockRange = {
76
+ from: pos,
77
+ to: pos + node.nodeSize
78
+ };
79
+ affectedRanges.set("".concat(sourceSyncBlockRange.from, "-").concat(sourceSyncBlockRange.to), sourceSyncBlockRange);
80
+ return false;
81
+ }
82
+ return true;
83
+ });
84
+ });
85
+ return Array.from(affectedRanges.values());
86
+ };
87
+ function createSourceSyncBlockPlaceholderDecorations(editorState, intl) {
88
+ if (!isSourceSyncBlockPlaceholderEnabled()) {
89
+ return;
90
+ }
91
+ var decorations = [];
92
+ editorState.doc.descendants(function (node, pos) {
93
+ if (isEmptySourceSyncBlock(node)) {
94
+ decorations.push(createSourceSyncBlockPlaceholderDecoration(pos, intl));
95
+ return false;
96
+ }
97
+ return true;
98
+ });
99
+ return decorations.length > 0 ? _view.DecorationSet.create(editorState.doc, decorations) : _view.DecorationSet.empty;
100
+ }
101
+ function updateSourceSyncBlockPlaceholderDecorations(_ref2) {
102
+ var currentDecorationSet = _ref2.currentDecorationSet,
103
+ intl = _ref2.intl,
104
+ newEditorState = _ref2.newEditorState,
105
+ oldEditorState = _ref2.oldEditorState,
106
+ tr = _ref2.tr;
107
+ if (!isSourceSyncBlockPlaceholderEnabled()) {
108
+ return;
109
+ }
110
+ if (!currentDecorationSet) {
111
+ return createSourceSyncBlockPlaceholderDecorations(newEditorState, intl);
112
+ }
113
+ if (!tr.docChanged) {
114
+ return tr.mapping.maps.length > 0 ? currentDecorationSet.map(tr.mapping, newEditorState.doc) : currentDecorationSet;
115
+ }
116
+ var mappedDecorationSet = currentDecorationSet.map(tr.mapping, newEditorState.doc);
117
+ var affectedRanges = getAffectedSourceSyncBlockRanges(newEditorState.doc, getChangedRanges(tr));
118
+ if (affectedRanges.length === 0) {
119
+ return mappedDecorationSet;
120
+ }
121
+ var decorationsToRemove = affectedRanges.flatMap(function (_ref3) {
122
+ var from = _ref3.from,
123
+ to = _ref3.to;
124
+ return mappedDecorationSet.find(from, to);
125
+ });
126
+ var decorationsToAdd = affectedRanges.flatMap(function (_ref4) {
127
+ var from = _ref4.from;
128
+ var node = newEditorState.doc.nodeAt(from);
129
+ return node && isEmptySourceSyncBlock(node) ? [createSourceSyncBlockPlaceholderDecoration(from, intl)] : [];
130
+ });
131
+ return mappedDecorationSet.remove(decorationsToRemove).add(newEditorState.doc, decorationsToAdd);
132
+ }
@@ -199,7 +199,7 @@ function createPlaceHolderStateFrom(_ref3) {
199
199
  userHadTyped: userHadTyped
200
200
  });
201
201
  }
202
- if (_constants.nodeTypesWithSyncBlockPlaceholderText.includes(parentType) && isEmptyNode && (0, _experiments.editorExperiment)('platform_synced_block', true)) {
202
+ if (_constants.nodeTypesWithSyncBlockPlaceholderText.includes(parentType) && isEmptyNode && (0, _experiments.editorExperiment)('platform_synced_block', true) && !(0, _expValEquals.expValEquals)('platform_editor_sync_block_activation', 'isEnabled', true)) {
203
203
  return setPlaceHolderState({
204
204
  placeholderText: intl.formatMessage(_messages.placeholderTextMessages.sourceSyncBlockPlaceholderText),
205
205
  pos: $from.pos,
@@ -3,6 +3,7 @@ import { expVal } from '@atlaskit/tmp-editor-statsig/expVal';
3
3
  import { EMPTY_PARAGRAPH_TIMEOUT_DELAY, pluginKey } from '../placeholderPlugin';
4
4
  import { TYPEWRITER_TYPED_AND_DELETED_DELAY } from './constants';
5
5
  import { createPlaceholderDecoration } from './decorations';
6
+ import { createSourceSyncBlockPlaceholderDecorations, updateSourceSyncBlockPlaceholderDecorations } from './source-sync-block-placeholder-decorations';
6
7
  import { calculateUserInteractionState, createPlaceHolderStateFrom, getPlaceholderState } from './utils';
7
8
  export default function createPlugin(intl, defaultPlaceholderText, bracketPlaceholderText, emptyLinePlaceholder, placeholderPrompts, withEmptyParagraph, initialIsPlaceholderHidden, placeholderADF, isRovoLLMEnabled, api) {
8
9
  if (!defaultPlaceholderText && !placeholderPrompts && !bracketPlaceholderText && !placeholderADF) {
@@ -19,22 +20,25 @@ export default function createPlugin(intl, defaultPlaceholderText, bracketPlaceh
19
20
  state: {
20
21
  init: (_, state) => {
21
22
  var _api$focus, _api$focus$sharedStat, _api$typeAhead;
22
- return createPlaceHolderStateFrom({
23
- isInitial: true,
24
- isEditorFocused: Boolean(api === null || api === void 0 ? void 0 : (_api$focus = api.focus) === null || _api$focus === void 0 ? void 0 : (_api$focus$sharedStat = _api$focus.sharedState.currentState()) === null || _api$focus$sharedStat === void 0 ? void 0 : _api$focus$sharedStat.hasFocus),
25
- editorState: state,
26
- isTypeAheadOpen: api === null || api === void 0 ? void 0 : (_api$typeAhead = api.typeAhead) === null || _api$typeAhead === void 0 ? void 0 : _api$typeAhead.actions.isOpen,
27
- defaultPlaceholderText,
28
- bracketPlaceholderText,
29
- emptyLinePlaceholder,
30
- placeholderADF,
31
- placeholderPrompts,
32
- typedAndDeleted: false,
33
- userHadTyped: false,
34
- intl,
35
- withEmptyParagraph,
36
- isPlaceholderHidden: initialIsPlaceholderHidden
37
- });
23
+ return {
24
+ ...createPlaceHolderStateFrom({
25
+ isInitial: true,
26
+ isEditorFocused: Boolean(api === null || api === void 0 ? void 0 : (_api$focus = api.focus) === null || _api$focus === void 0 ? void 0 : (_api$focus$sharedStat = _api$focus.sharedState.currentState()) === null || _api$focus$sharedStat === void 0 ? void 0 : _api$focus$sharedStat.hasFocus),
27
+ editorState: state,
28
+ isTypeAheadOpen: api === null || api === void 0 ? void 0 : (_api$typeAhead = api.typeAhead) === null || _api$typeAhead === void 0 ? void 0 : _api$typeAhead.actions.isOpen,
29
+ defaultPlaceholderText,
30
+ bracketPlaceholderText,
31
+ emptyLinePlaceholder,
32
+ placeholderADF,
33
+ placeholderPrompts,
34
+ typedAndDeleted: false,
35
+ userHadTyped: false,
36
+ intl,
37
+ withEmptyParagraph,
38
+ isPlaceholderHidden: initialIsPlaceholderHidden
39
+ }),
40
+ sourceSyncBlockPlaceholderDecorations: createSourceSyncBlockPlaceholderDecorations(state, intl)
41
+ };
38
42
  },
39
43
  apply: (tr, placeholderState, _oldEditorState, newEditorState) => {
40
44
  var _api$focus2, _api$focus2$sharedSta, _placeholderState$isP, _api$typeAhead2, _ref, _meta$placeholderText, _ref2, _meta$placeholderProm, _meta$showOnEmptyPara;
@@ -61,22 +65,31 @@ export default function createPlugin(intl, defaultPlaceholderText, bracketPlaceh
61
65
  defaultPlaceholderText = meta.placeholderText;
62
66
  }
63
67
  }
64
- const newPlaceholderState = createPlaceHolderStateFrom({
65
- isEditorFocused,
66
- editorState: newEditorState,
67
- isTypeAheadOpen: api === null || api === void 0 ? void 0 : (_api$typeAhead2 = api.typeAhead) === null || _api$typeAhead2 === void 0 ? void 0 : _api$typeAhead2.actions.isOpen,
68
- defaultPlaceholderText: withEmptyParagraph ? defaultPlaceholderText : (_ref = (_meta$placeholderText = meta === null || meta === void 0 ? void 0 : meta.placeholderText) !== null && _meta$placeholderText !== void 0 ? _meta$placeholderText : placeholderState === null || placeholderState === void 0 ? void 0 : placeholderState.placeholderText) !== null && _ref !== void 0 ? _ref : defaultPlaceholderText,
69
- bracketPlaceholderText,
70
- emptyLinePlaceholder,
71
- placeholderADF,
72
- placeholderPrompts: (_ref2 = (_meta$placeholderProm = meta === null || meta === void 0 ? void 0 : meta.placeholderPrompts) !== null && _meta$placeholderProm !== void 0 ? _meta$placeholderProm : placeholderState === null || placeholderState === void 0 ? void 0 : placeholderState.placeholderPrompts) !== null && _ref2 !== void 0 ? _ref2 : placeholderPrompts,
73
- typedAndDeleted,
74
- userHadTyped,
75
- intl,
76
- isPlaceholderHidden,
77
- withEmptyParagraph,
78
- showOnEmptyParagraph: (_meta$showOnEmptyPara = meta === null || meta === void 0 ? void 0 : meta.showOnEmptyParagraph) !== null && _meta$showOnEmptyPara !== void 0 ? _meta$showOnEmptyPara : placeholderState === null || placeholderState === void 0 ? void 0 : placeholderState.showOnEmptyParagraph
79
- });
68
+ const newPlaceholderState = {
69
+ ...createPlaceHolderStateFrom({
70
+ isEditorFocused,
71
+ editorState: newEditorState,
72
+ isTypeAheadOpen: api === null || api === void 0 ? void 0 : (_api$typeAhead2 = api.typeAhead) === null || _api$typeAhead2 === void 0 ? void 0 : _api$typeAhead2.actions.isOpen,
73
+ defaultPlaceholderText: withEmptyParagraph ? defaultPlaceholderText : (_ref = (_meta$placeholderText = meta === null || meta === void 0 ? void 0 : meta.placeholderText) !== null && _meta$placeholderText !== void 0 ? _meta$placeholderText : placeholderState === null || placeholderState === void 0 ? void 0 : placeholderState.placeholderText) !== null && _ref !== void 0 ? _ref : defaultPlaceholderText,
74
+ bracketPlaceholderText,
75
+ emptyLinePlaceholder,
76
+ placeholderADF,
77
+ placeholderPrompts: (_ref2 = (_meta$placeholderProm = meta === null || meta === void 0 ? void 0 : meta.placeholderPrompts) !== null && _meta$placeholderProm !== void 0 ? _meta$placeholderProm : placeholderState === null || placeholderState === void 0 ? void 0 : placeholderState.placeholderPrompts) !== null && _ref2 !== void 0 ? _ref2 : placeholderPrompts,
78
+ typedAndDeleted,
79
+ userHadTyped,
80
+ intl,
81
+ isPlaceholderHidden,
82
+ withEmptyParagraph,
83
+ showOnEmptyParagraph: (_meta$showOnEmptyPara = meta === null || meta === void 0 ? void 0 : meta.showOnEmptyParagraph) !== null && _meta$showOnEmptyPara !== void 0 ? _meta$showOnEmptyPara : placeholderState === null || placeholderState === void 0 ? void 0 : placeholderState.showOnEmptyParagraph
84
+ }),
85
+ sourceSyncBlockPlaceholderDecorations: updateSourceSyncBlockPlaceholderDecorations({
86
+ currentDecorationSet: placeholderState === null || placeholderState === void 0 ? void 0 : placeholderState.sourceSyncBlockPlaceholderDecorations,
87
+ intl,
88
+ newEditorState,
89
+ oldEditorState: _oldEditorState,
90
+ tr
91
+ })
92
+ };
80
93
 
81
94
  // Clear timeouts when hasPlaceholder becomes false
82
95
  if (!newPlaceholderState.hasPlaceholder) {
@@ -98,7 +111,8 @@ export default function createPlugin(intl, defaultPlaceholderText, bracketPlaceh
98
111
  pos,
99
112
  typedAndDeleted,
100
113
  contextPlaceholderADF,
101
- showOnEmptyParagraph
114
+ showOnEmptyParagraph,
115
+ sourceSyncBlockPlaceholderDecorations
102
116
  } = getPlaceholderState(editorState);
103
117
 
104
118
  // Decorations is still called after plugin is destroyed
@@ -108,13 +122,15 @@ export default function createPlugin(intl, defaultPlaceholderText, bracketPlaceh
108
122
  }
109
123
  const compositionPluginState = api === null || api === void 0 ? void 0 : (_api$composition = api.composition) === null || _api$composition === void 0 ? void 0 : _api$composition.sharedState.currentState();
110
124
  const isShowingDiff = Boolean(api === null || api === void 0 ? void 0 : (_api$showDiff = api.showDiff) === null || _api$showDiff === void 0 ? void 0 : (_api$showDiff$sharedS = _api$showDiff.sharedState.currentState()) === null || _api$showDiff$sharedS === void 0 ? void 0 : _api$showDiff$sharedS.isDisplayingChanges);
125
+ const syncBlockPlaceholderDecorations = !(compositionPluginState !== null && compositionPluginState !== void 0 && compositionPluginState.isComposing) && !isShowingDiff ? sourceSyncBlockPlaceholderDecorations : undefined;
111
126
  if (hasPlaceholder && ((placeholderText !== null && placeholderText !== void 0 ? placeholderText : '') || placeholderPrompts || placeholderADF || contextPlaceholderADF) && pos !== undefined && !(compositionPluginState !== null && compositionPluginState !== void 0 && compositionPluginState.isComposing) && !isShowingDiff) {
127
+ var _syncBlockPlaceholder;
112
128
  const initialDelayWhenUserTypedAndDeleted = typedAndDeleted ? TYPEWRITER_TYPED_AND_DELETED_DELAY : 0;
113
129
  // contextPlaceholderADF takes precedence over the global placeholderADF
114
130
  const placeholderAdfToUse = contextPlaceholderADF || placeholderADF;
115
- return createPlaceholderDecoration(editorState, placeholderText !== null && placeholderText !== void 0 ? placeholderText : '', placeholderPrompts, activeTypewriterTimeouts, pos, initialDelayWhenUserTypedAndDeleted, placeholderAdfToUse, showOnEmptyParagraph);
131
+ return createPlaceholderDecoration(editorState, placeholderText !== null && placeholderText !== void 0 ? placeholderText : '', placeholderPrompts, activeTypewriterTimeouts, pos, initialDelayWhenUserTypedAndDeleted, placeholderAdfToUse, showOnEmptyParagraph).add(editorState.doc, (_syncBlockPlaceholder = syncBlockPlaceholderDecorations === null || syncBlockPlaceholderDecorations === void 0 ? void 0 : syncBlockPlaceholderDecorations.find()) !== null && _syncBlockPlaceholder !== void 0 ? _syncBlockPlaceholder : []);
116
132
  }
117
- return;
133
+ return syncBlockPlaceholderDecorations;
118
134
  }
119
135
  },
120
136
  view() {
@@ -0,0 +1,121 @@
1
+ import { placeholderTextMessages as messages } from '@atlaskit/editor-common/messages';
2
+ import { Decoration, DecorationSet } from '@atlaskit/editor-prosemirror/view';
3
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
4
+ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
5
+ import { nodeTypesWithSyncBlockPlaceholderText, placeholderTestId } from './constants';
6
+ const isEmptySourceSyncBlock = node => {
7
+ var _node$firstChild, _node$firstChild2;
8
+ return nodeTypesWithSyncBlockPlaceholderText.includes(node.type.name) && node.childCount === 1 && ((_node$firstChild = node.firstChild) === null || _node$firstChild === void 0 ? void 0 : _node$firstChild.content.size) === 0 && ((_node$firstChild2 = node.firstChild) === null || _node$firstChild2 === void 0 ? void 0 : _node$firstChild2.type.name) === 'paragraph';
9
+ };
10
+ const createSourceSyncBlockPlaceholderElement = intl => {
11
+ const placeholderDecoration = document.createElement('span');
12
+ placeholderDecoration.setAttribute('data-testid', placeholderTestId);
13
+ placeholderDecoration.className = 'placeholder-decoration';
14
+ placeholderDecoration.setAttribute('aria-hidden', 'true');
15
+ placeholderDecoration.textContent = intl.formatMessage(messages.sourceSyncBlockPlaceholderText);
16
+ return placeholderDecoration;
17
+ };
18
+ const createSourceSyncBlockPlaceholderDecoration = (pos, intl) => Decoration.widget(pos + 2, () => createSourceSyncBlockPlaceholderElement(intl), {
19
+ side: 0,
20
+ key: `source-sync-block-placeholder-${pos}`
21
+ });
22
+ const isSourceSyncBlockPlaceholderEnabled = () => expValEquals('platform_editor_sync_block_activation', 'isEnabled', true) && editorExperiment('platform_synced_block', true);
23
+ const getChangedRanges = tr => {
24
+ const ranges = [];
25
+ tr.mapping.maps.forEach((stepMap, index) => {
26
+ stepMap.forEach((_oldStart, _oldEnd, newStart, newEnd) => {
27
+ const mappingAfterStep = tr.mapping.slice(index + 1);
28
+ ranges.push({
29
+ from: mappingAfterStep.map(newStart, -1),
30
+ to: mappingAfterStep.map(newEnd, 1)
31
+ });
32
+ });
33
+ });
34
+ return ranges;
35
+ };
36
+ const getSourceSyncBlockRange = (doc, pos) => {
37
+ const resolvedPos = doc.resolve(Math.max(0, Math.min(pos, doc.content.size)));
38
+ for (let depth = resolvedPos.depth; depth > 0; depth--) {
39
+ const node = resolvedPos.node(depth);
40
+ if (nodeTypesWithSyncBlockPlaceholderText.includes(node.type.name)) {
41
+ return {
42
+ from: resolvedPos.before(depth),
43
+ to: resolvedPos.after(depth)
44
+ };
45
+ }
46
+ }
47
+ return;
48
+ };
49
+ const getAffectedSourceSyncBlockRanges = (doc, ranges) => {
50
+ const affectedRanges = new Map();
51
+ ranges.forEach(({
52
+ from,
53
+ to
54
+ }) => {
55
+ [from, to].forEach(pos => {
56
+ const sourceSyncBlockRange = getSourceSyncBlockRange(doc, pos);
57
+ if (sourceSyncBlockRange) {
58
+ affectedRanges.set(`${sourceSyncBlockRange.from}-${sourceSyncBlockRange.to}`, sourceSyncBlockRange);
59
+ }
60
+ });
61
+ doc.nodesBetween(from, to, (node, pos) => {
62
+ if (nodeTypesWithSyncBlockPlaceholderText.includes(node.type.name)) {
63
+ const sourceSyncBlockRange = {
64
+ from: pos,
65
+ to: pos + node.nodeSize
66
+ };
67
+ affectedRanges.set(`${sourceSyncBlockRange.from}-${sourceSyncBlockRange.to}`, sourceSyncBlockRange);
68
+ return false;
69
+ }
70
+ return true;
71
+ });
72
+ });
73
+ return Array.from(affectedRanges.values());
74
+ };
75
+ export function createSourceSyncBlockPlaceholderDecorations(editorState, intl) {
76
+ if (!isSourceSyncBlockPlaceholderEnabled()) {
77
+ return;
78
+ }
79
+ const decorations = [];
80
+ editorState.doc.descendants((node, pos) => {
81
+ if (isEmptySourceSyncBlock(node)) {
82
+ decorations.push(createSourceSyncBlockPlaceholderDecoration(pos, intl));
83
+ return false;
84
+ }
85
+ return true;
86
+ });
87
+ return decorations.length > 0 ? DecorationSet.create(editorState.doc, decorations) : DecorationSet.empty;
88
+ }
89
+ export function updateSourceSyncBlockPlaceholderDecorations({
90
+ currentDecorationSet,
91
+ intl,
92
+ newEditorState,
93
+ oldEditorState,
94
+ tr
95
+ }) {
96
+ if (!isSourceSyncBlockPlaceholderEnabled()) {
97
+ return;
98
+ }
99
+ if (!currentDecorationSet) {
100
+ return createSourceSyncBlockPlaceholderDecorations(newEditorState, intl);
101
+ }
102
+ if (!tr.docChanged) {
103
+ return tr.mapping.maps.length > 0 ? currentDecorationSet.map(tr.mapping, newEditorState.doc) : currentDecorationSet;
104
+ }
105
+ const mappedDecorationSet = currentDecorationSet.map(tr.mapping, newEditorState.doc);
106
+ const affectedRanges = getAffectedSourceSyncBlockRanges(newEditorState.doc, getChangedRanges(tr));
107
+ if (affectedRanges.length === 0) {
108
+ return mappedDecorationSet;
109
+ }
110
+ const decorationsToRemove = affectedRanges.flatMap(({
111
+ from,
112
+ to
113
+ }) => mappedDecorationSet.find(from, to));
114
+ const decorationsToAdd = affectedRanges.flatMap(({
115
+ from
116
+ }) => {
117
+ const node = newEditorState.doc.nodeAt(from);
118
+ return node && isEmptySourceSyncBlock(node) ? [createSourceSyncBlockPlaceholderDecoration(from, intl)] : [];
119
+ });
120
+ return mappedDecorationSet.remove(decorationsToRemove).add(newEditorState.doc, decorationsToAdd);
121
+ }
@@ -187,7 +187,7 @@ export function createPlaceHolderStateFrom({
187
187
  userHadTyped
188
188
  });
189
189
  }
190
- if (nodeTypesWithSyncBlockPlaceholderText.includes(parentType) && isEmptyNode && editorExperiment('platform_synced_block', true)) {
190
+ if (nodeTypesWithSyncBlockPlaceholderText.includes(parentType) && isEmptyNode && editorExperiment('platform_synced_block', true) && !expValEquals('platform_editor_sync_block_activation', 'isEnabled', true)) {
191
191
  return setPlaceHolderState({
192
192
  placeholderText: intl.formatMessage(messages.sourceSyncBlockPlaceholderText),
193
193
  pos: $from.pos,
@@ -1,8 +1,12 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ 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; }
3
+ 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) { _defineProperty(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; }
1
4
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
5
  import { expVal } from '@atlaskit/tmp-editor-statsig/expVal';
3
6
  import { EMPTY_PARAGRAPH_TIMEOUT_DELAY, pluginKey } from '../placeholderPlugin';
4
7
  import { TYPEWRITER_TYPED_AND_DELETED_DELAY } from './constants';
5
8
  import { createPlaceholderDecoration } from './decorations';
9
+ import { createSourceSyncBlockPlaceholderDecorations, updateSourceSyncBlockPlaceholderDecorations } from './source-sync-block-placeholder-decorations';
6
10
  import { calculateUserInteractionState, createPlaceHolderStateFrom, getPlaceholderState } from './utils';
7
11
  export default function createPlugin(intl, defaultPlaceholderText, bracketPlaceholderText, emptyLinePlaceholder, placeholderPrompts, withEmptyParagraph, initialIsPlaceholderHidden, placeholderADF, isRovoLLMEnabled, api) {
8
12
  if (!defaultPlaceholderText && !placeholderPrompts && !bracketPlaceholderText && !placeholderADF) {
@@ -21,7 +25,7 @@ export default function createPlugin(intl, defaultPlaceholderText, bracketPlaceh
21
25
  state: {
22
26
  init: function init(_, state) {
23
27
  var _api$focus, _api$typeAhead;
24
- return createPlaceHolderStateFrom({
28
+ return _objectSpread(_objectSpread({}, createPlaceHolderStateFrom({
25
29
  isInitial: true,
26
30
  isEditorFocused: Boolean(api === null || api === void 0 || (_api$focus = api.focus) === null || _api$focus === void 0 || (_api$focus = _api$focus.sharedState.currentState()) === null || _api$focus === void 0 ? void 0 : _api$focus.hasFocus),
27
31
  editorState: state,
@@ -36,6 +40,8 @@ export default function createPlugin(intl, defaultPlaceholderText, bracketPlaceh
36
40
  intl: intl,
37
41
  withEmptyParagraph: withEmptyParagraph,
38
42
  isPlaceholderHidden: initialIsPlaceholderHidden
43
+ })), {}, {
44
+ sourceSyncBlockPlaceholderDecorations: createSourceSyncBlockPlaceholderDecorations(state, intl)
39
45
  });
40
46
  },
41
47
  apply: function apply(tr, placeholderState, _oldEditorState, newEditorState) {
@@ -62,7 +68,7 @@ export default function createPlugin(intl, defaultPlaceholderText, bracketPlaceh
62
68
  defaultPlaceholderText = meta.placeholderText;
63
69
  }
64
70
  }
65
- var newPlaceholderState = createPlaceHolderStateFrom({
71
+ var newPlaceholderState = _objectSpread(_objectSpread({}, createPlaceHolderStateFrom({
66
72
  isEditorFocused: isEditorFocused,
67
73
  editorState: newEditorState,
68
74
  isTypeAheadOpen: api === null || api === void 0 || (_api$typeAhead2 = api.typeAhead) === null || _api$typeAhead2 === void 0 ? void 0 : _api$typeAhead2.actions.isOpen,
@@ -77,6 +83,14 @@ export default function createPlugin(intl, defaultPlaceholderText, bracketPlaceh
77
83
  isPlaceholderHidden: isPlaceholderHidden,
78
84
  withEmptyParagraph: withEmptyParagraph,
79
85
  showOnEmptyParagraph: (_meta$showOnEmptyPara = meta === null || meta === void 0 ? void 0 : meta.showOnEmptyParagraph) !== null && _meta$showOnEmptyPara !== void 0 ? _meta$showOnEmptyPara : placeholderState === null || placeholderState === void 0 ? void 0 : placeholderState.showOnEmptyParagraph
86
+ })), {}, {
87
+ sourceSyncBlockPlaceholderDecorations: updateSourceSyncBlockPlaceholderDecorations({
88
+ currentDecorationSet: placeholderState === null || placeholderState === void 0 ? void 0 : placeholderState.sourceSyncBlockPlaceholderDecorations,
89
+ intl: intl,
90
+ newEditorState: newEditorState,
91
+ oldEditorState: _oldEditorState,
92
+ tr: tr
93
+ })
80
94
  });
81
95
 
82
96
  // Clear timeouts when hasPlaceholder becomes false
@@ -99,7 +113,8 @@ export default function createPlugin(intl, defaultPlaceholderText, bracketPlaceh
99
113
  pos = _getPlaceholderState.pos,
100
114
  typedAndDeleted = _getPlaceholderState.typedAndDeleted,
101
115
  contextPlaceholderADF = _getPlaceholderState.contextPlaceholderADF,
102
- showOnEmptyParagraph = _getPlaceholderState.showOnEmptyParagraph;
116
+ showOnEmptyParagraph = _getPlaceholderState.showOnEmptyParagraph,
117
+ sourceSyncBlockPlaceholderDecorations = _getPlaceholderState.sourceSyncBlockPlaceholderDecorations;
103
118
 
104
119
  // Decorations is still called after plugin is destroyed
105
120
  // So we need to make sure decorations is not called if plugin has been destroyed to prevent the placeholder animations' setTimeouts called infinitely
@@ -108,13 +123,15 @@ export default function createPlugin(intl, defaultPlaceholderText, bracketPlaceh
108
123
  }
109
124
  var compositionPluginState = api === null || api === void 0 || (_api$composition = api.composition) === null || _api$composition === void 0 ? void 0 : _api$composition.sharedState.currentState();
110
125
  var isShowingDiff = Boolean(api === null || api === void 0 || (_api$showDiff = api.showDiff) === null || _api$showDiff === void 0 || (_api$showDiff = _api$showDiff.sharedState.currentState()) === null || _api$showDiff === void 0 ? void 0 : _api$showDiff.isDisplayingChanges);
126
+ var syncBlockPlaceholderDecorations = !(compositionPluginState !== null && compositionPluginState !== void 0 && compositionPluginState.isComposing) && !isShowingDiff ? sourceSyncBlockPlaceholderDecorations : undefined;
111
127
  if (hasPlaceholder && ((placeholderText !== null && placeholderText !== void 0 ? placeholderText : '') || placeholderPrompts || placeholderADF || contextPlaceholderADF) && pos !== undefined && !(compositionPluginState !== null && compositionPluginState !== void 0 && compositionPluginState.isComposing) && !isShowingDiff) {
128
+ var _syncBlockPlaceholder;
112
129
  var initialDelayWhenUserTypedAndDeleted = typedAndDeleted ? TYPEWRITER_TYPED_AND_DELETED_DELAY : 0;
113
130
  // contextPlaceholderADF takes precedence over the global placeholderADF
114
131
  var placeholderAdfToUse = contextPlaceholderADF || placeholderADF;
115
- return createPlaceholderDecoration(editorState, placeholderText !== null && placeholderText !== void 0 ? placeholderText : '', placeholderPrompts, activeTypewriterTimeouts, pos, initialDelayWhenUserTypedAndDeleted, placeholderAdfToUse, showOnEmptyParagraph);
132
+ return createPlaceholderDecoration(editorState, placeholderText !== null && placeholderText !== void 0 ? placeholderText : '', placeholderPrompts, activeTypewriterTimeouts, pos, initialDelayWhenUserTypedAndDeleted, placeholderAdfToUse, showOnEmptyParagraph).add(editorState.doc, (_syncBlockPlaceholder = syncBlockPlaceholderDecorations === null || syncBlockPlaceholderDecorations === void 0 ? void 0 : syncBlockPlaceholderDecorations.find()) !== null && _syncBlockPlaceholder !== void 0 ? _syncBlockPlaceholder : []);
116
133
  }
117
- return;
134
+ return syncBlockPlaceholderDecorations;
118
135
  }
119
136
  },
120
137
  view: function view() {
@@ -0,0 +1,125 @@
1
+ import { placeholderTextMessages as messages } from '@atlaskit/editor-common/messages';
2
+ import { Decoration, DecorationSet } from '@atlaskit/editor-prosemirror/view';
3
+ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
4
+ import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
5
+ import { nodeTypesWithSyncBlockPlaceholderText, placeholderTestId } from './constants';
6
+ var isEmptySourceSyncBlock = function isEmptySourceSyncBlock(node) {
7
+ var _node$firstChild, _node$firstChild2;
8
+ return nodeTypesWithSyncBlockPlaceholderText.includes(node.type.name) && node.childCount === 1 && ((_node$firstChild = node.firstChild) === null || _node$firstChild === void 0 ? void 0 : _node$firstChild.content.size) === 0 && ((_node$firstChild2 = node.firstChild) === null || _node$firstChild2 === void 0 ? void 0 : _node$firstChild2.type.name) === 'paragraph';
9
+ };
10
+ var createSourceSyncBlockPlaceholderElement = function createSourceSyncBlockPlaceholderElement(intl) {
11
+ var placeholderDecoration = document.createElement('span');
12
+ placeholderDecoration.setAttribute('data-testid', placeholderTestId);
13
+ placeholderDecoration.className = 'placeholder-decoration';
14
+ placeholderDecoration.setAttribute('aria-hidden', 'true');
15
+ placeholderDecoration.textContent = intl.formatMessage(messages.sourceSyncBlockPlaceholderText);
16
+ return placeholderDecoration;
17
+ };
18
+ var createSourceSyncBlockPlaceholderDecoration = function createSourceSyncBlockPlaceholderDecoration(pos, intl) {
19
+ return Decoration.widget(pos + 2, function () {
20
+ return createSourceSyncBlockPlaceholderElement(intl);
21
+ }, {
22
+ side: 0,
23
+ key: "source-sync-block-placeholder-".concat(pos)
24
+ });
25
+ };
26
+ var isSourceSyncBlockPlaceholderEnabled = function isSourceSyncBlockPlaceholderEnabled() {
27
+ return expValEquals('platform_editor_sync_block_activation', 'isEnabled', true) && editorExperiment('platform_synced_block', true);
28
+ };
29
+ var getChangedRanges = function getChangedRanges(tr) {
30
+ var ranges = [];
31
+ tr.mapping.maps.forEach(function (stepMap, index) {
32
+ stepMap.forEach(function (_oldStart, _oldEnd, newStart, newEnd) {
33
+ var mappingAfterStep = tr.mapping.slice(index + 1);
34
+ ranges.push({
35
+ from: mappingAfterStep.map(newStart, -1),
36
+ to: mappingAfterStep.map(newEnd, 1)
37
+ });
38
+ });
39
+ });
40
+ return ranges;
41
+ };
42
+ var getSourceSyncBlockRange = function getSourceSyncBlockRange(doc, pos) {
43
+ var resolvedPos = doc.resolve(Math.max(0, Math.min(pos, doc.content.size)));
44
+ for (var depth = resolvedPos.depth; depth > 0; depth--) {
45
+ var node = resolvedPos.node(depth);
46
+ if (nodeTypesWithSyncBlockPlaceholderText.includes(node.type.name)) {
47
+ return {
48
+ from: resolvedPos.before(depth),
49
+ to: resolvedPos.after(depth)
50
+ };
51
+ }
52
+ }
53
+ return;
54
+ };
55
+ var getAffectedSourceSyncBlockRanges = function getAffectedSourceSyncBlockRanges(doc, ranges) {
56
+ var affectedRanges = new Map();
57
+ ranges.forEach(function (_ref) {
58
+ var from = _ref.from,
59
+ to = _ref.to;
60
+ [from, to].forEach(function (pos) {
61
+ var sourceSyncBlockRange = getSourceSyncBlockRange(doc, pos);
62
+ if (sourceSyncBlockRange) {
63
+ affectedRanges.set("".concat(sourceSyncBlockRange.from, "-").concat(sourceSyncBlockRange.to), sourceSyncBlockRange);
64
+ }
65
+ });
66
+ doc.nodesBetween(from, to, function (node, pos) {
67
+ if (nodeTypesWithSyncBlockPlaceholderText.includes(node.type.name)) {
68
+ var sourceSyncBlockRange = {
69
+ from: pos,
70
+ to: pos + node.nodeSize
71
+ };
72
+ affectedRanges.set("".concat(sourceSyncBlockRange.from, "-").concat(sourceSyncBlockRange.to), sourceSyncBlockRange);
73
+ return false;
74
+ }
75
+ return true;
76
+ });
77
+ });
78
+ return Array.from(affectedRanges.values());
79
+ };
80
+ export function createSourceSyncBlockPlaceholderDecorations(editorState, intl) {
81
+ if (!isSourceSyncBlockPlaceholderEnabled()) {
82
+ return;
83
+ }
84
+ var decorations = [];
85
+ editorState.doc.descendants(function (node, pos) {
86
+ if (isEmptySourceSyncBlock(node)) {
87
+ decorations.push(createSourceSyncBlockPlaceholderDecoration(pos, intl));
88
+ return false;
89
+ }
90
+ return true;
91
+ });
92
+ return decorations.length > 0 ? DecorationSet.create(editorState.doc, decorations) : DecorationSet.empty;
93
+ }
94
+ export function updateSourceSyncBlockPlaceholderDecorations(_ref2) {
95
+ var currentDecorationSet = _ref2.currentDecorationSet,
96
+ intl = _ref2.intl,
97
+ newEditorState = _ref2.newEditorState,
98
+ oldEditorState = _ref2.oldEditorState,
99
+ tr = _ref2.tr;
100
+ if (!isSourceSyncBlockPlaceholderEnabled()) {
101
+ return;
102
+ }
103
+ if (!currentDecorationSet) {
104
+ return createSourceSyncBlockPlaceholderDecorations(newEditorState, intl);
105
+ }
106
+ if (!tr.docChanged) {
107
+ return tr.mapping.maps.length > 0 ? currentDecorationSet.map(tr.mapping, newEditorState.doc) : currentDecorationSet;
108
+ }
109
+ var mappedDecorationSet = currentDecorationSet.map(tr.mapping, newEditorState.doc);
110
+ var affectedRanges = getAffectedSourceSyncBlockRanges(newEditorState.doc, getChangedRanges(tr));
111
+ if (affectedRanges.length === 0) {
112
+ return mappedDecorationSet;
113
+ }
114
+ var decorationsToRemove = affectedRanges.flatMap(function (_ref3) {
115
+ var from = _ref3.from,
116
+ to = _ref3.to;
117
+ return mappedDecorationSet.find(from, to);
118
+ });
119
+ var decorationsToAdd = affectedRanges.flatMap(function (_ref4) {
120
+ var from = _ref4.from;
121
+ var node = newEditorState.doc.nodeAt(from);
122
+ return node && isEmptySourceSyncBlock(node) ? [createSourceSyncBlockPlaceholderDecoration(from, intl)] : [];
123
+ });
124
+ return mappedDecorationSet.remove(decorationsToRemove).add(newEditorState.doc, decorationsToAdd);
125
+ }
@@ -188,7 +188,7 @@ export function createPlaceHolderStateFrom(_ref3) {
188
188
  userHadTyped: userHadTyped
189
189
  });
190
190
  }
191
- if (nodeTypesWithSyncBlockPlaceholderText.includes(parentType) && isEmptyNode && editorExperiment('platform_synced_block', true)) {
191
+ if (nodeTypesWithSyncBlockPlaceholderText.includes(parentType) && isEmptyNode && editorExperiment('platform_synced_block', true) && !expValEquals('platform_editor_sync_block_activation', 'isEnabled', true)) {
192
192
  return setPlaceHolderState({
193
193
  placeholderText: intl.formatMessage(messages.sourceSyncBlockPlaceholderText),
194
194
  pos: $from.pos,
@@ -0,0 +1,17 @@
1
+ import type { IntlShape } from 'react-intl';
2
+ import type { EditorState } from '@atlaskit/editor-prosemirror/state';
3
+ import type { Mapping } from '@atlaskit/editor-prosemirror/transform';
4
+ import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
5
+ type SourceSyncBlockPlaceholderTransaction = {
6
+ mapping: Mapping;
7
+ docChanged: boolean;
8
+ };
9
+ export declare function createSourceSyncBlockPlaceholderDecorations(editorState: EditorState, intl: IntlShape): DecorationSet | undefined;
10
+ export declare function updateSourceSyncBlockPlaceholderDecorations({ currentDecorationSet, intl, newEditorState, oldEditorState, tr, }: {
11
+ currentDecorationSet?: DecorationSet;
12
+ intl: IntlShape;
13
+ newEditorState: EditorState;
14
+ oldEditorState: EditorState;
15
+ tr: SourceSyncBlockPlaceholderTransaction;
16
+ }): DecorationSet | undefined;
17
+ export {};
@@ -1,6 +1,7 @@
1
1
  import type { IntlShape } from 'react-intl';
2
2
  import type { DocNode } from '@atlaskit/adf-schema';
3
3
  import type { EditorState } from '@atlaskit/editor-prosemirror/state';
4
+ import type { DecorationSet } from '@atlaskit/editor-prosemirror/view';
4
5
  export interface PlaceHolderState {
5
6
  canShowOnEmptyParagraph?: boolean;
6
7
  contextPlaceholderADF?: DocNode;
@@ -10,6 +11,7 @@ export interface PlaceHolderState {
10
11
  placeholderText?: string;
11
12
  pos?: number;
12
13
  showOnEmptyParagraph?: boolean;
14
+ sourceSyncBlockPlaceholderDecorations?: DecorationSet;
13
15
  typedAndDeleted?: boolean;
14
16
  userHadTyped?: boolean;
15
17
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-placeholder",
3
- "version": "12.0.20",
3
+ "version": "12.0.21",
4
4
  "description": "Placeholder plugin for @atlaskit/editor-core.",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -23,18 +23,18 @@
23
23
  "@atlaskit/css": "^1.0.0",
24
24
  "@atlaskit/editor-plugin-composition": "^11.0.0",
25
25
  "@atlaskit/editor-plugin-focus": "^11.0.0",
26
- "@atlaskit/editor-plugin-show-diff": "^10.1.0",
26
+ "@atlaskit/editor-plugin-show-diff": "^10.4.0",
27
27
  "@atlaskit/editor-plugin-type-ahead": "^13.0.0",
28
28
  "@atlaskit/editor-prosemirror": "^8.0.0",
29
29
  "@atlaskit/platform-feature-flags": "^2.0.0",
30
- "@atlaskit/primitives": "^20.5.0",
30
+ "@atlaskit/primitives": "^20.6.0",
31
31
  "@atlaskit/spinner": "^20.1.0",
32
- "@atlaskit/tmp-editor-statsig": "^124.0.0",
33
- "@atlaskit/tokens": "^15.5.0",
32
+ "@atlaskit/tmp-editor-statsig": "^124.2.0",
33
+ "@atlaskit/tokens": "^15.6.0",
34
34
  "@babel/runtime": "^7.0.0"
35
35
  },
36
36
  "peerDependencies": {
37
- "@atlaskit/editor-common": "^116.24.0",
37
+ "@atlaskit/editor-common": "^116.26.0",
38
38
  "react": "^18.2.0",
39
39
  "react-dom": "^18.2.0",
40
40
  "react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"