@atlaskit/editor-plugin-toolbar 3.4.9 → 3.4.11

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,22 @@
1
1
  # @atlaskit/editor-plugin-toolbar
2
2
 
3
+ ## 3.4.11
4
+
5
+ ### Patch Changes
6
+
7
+ - [`4d676bbdb3ce6`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/4d676bbdb3ce6) -
8
+ ts-ignore added temporarily to unblock local consumption for help-center, will be removed once
9
+ project refs are setup
10
+ - Updated dependencies
11
+
12
+ ## 3.4.10
13
+
14
+ ### Patch Changes
15
+
16
+ - [`7af1ad7f6bb6b`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/7af1ad7f6bb6b) -
17
+ Fix toolbar experience tracking failures
18
+ - Updated dependencies
19
+
3
20
  ## 3.4.9
4
21
 
5
22
  ### Patch Changes
@@ -23,36 +23,47 @@ var ABORT_REASON = {
23
23
  * This experience tracks when the selection toolbar is opened.
24
24
  *
25
25
  * Start: When user makes a selection via mouseup or shift+arrow key down
26
- * Success: When the selection toolbar is added to the DOM within 500ms of start
27
- * Failure: When 500ms passes without the selection toolbar being added to the DOM
28
- * Abort: When selection transition to empty or block menu is opened
26
+ * Success: When the selection toolbar is added to the DOM within 1000ms of start
27
+ * Failure: When 1000ms passes without the selection toolbar being added to the DOM
28
+ * Abort: When selection transitions to empty or block menu is opened
29
29
  */
30
30
  var getSelectionToolbarOpenExperiencePlugin = exports.getSelectionToolbarOpenExperiencePlugin = function getSelectionToolbarOpenExperiencePlugin(_ref) {
31
31
  var refs = _ref.refs,
32
32
  dispatchAnalyticsEvent = _ref.dispatchAnalyticsEvent;
33
+ var editorView;
33
34
  var targetEl;
34
- var editorViewEl;
35
+ var shiftArrowKeyPressed = false;
36
+ var mouseDownPos;
35
37
  var getTarget = function getTarget() {
36
38
  if (!targetEl) {
37
- targetEl = refs.popupsMountPoint || (0, _experiences.getPopupContainerFromEditorView)(editorViewEl);
39
+ var _editorView;
40
+ targetEl = refs.popupsMountPoint || (0, _experiences.getPopupContainerFromEditorView)((_editorView = editorView) === null || _editorView === void 0 ? void 0 : _editorView.dom);
38
41
  }
39
42
  return targetEl;
40
43
  };
41
44
  var experience = new _experiences.Experience('selection-toolbar-open', {
42
45
  dispatchAnalyticsEvent: dispatchAnalyticsEvent,
43
46
  checks: [new _experiences.ExperienceCheckTimeout({
44
- durationMs: 500,
47
+ durationMs: 1000,
45
48
  onTimeout: function onTimeout() {
49
+ var _editorView2;
46
50
  if (isBlockMenuWithinNode(getTarget())) {
47
51
  return {
48
52
  status: 'abort',
49
53
  reason: ABORT_REASON.BLOCK_MENU_OPENED
50
54
  };
55
+ } else if (isSelectionWithoutTextContent((_editorView2 = editorView) === null || _editorView2 === void 0 ? void 0 : _editorView2.state.selection)) {
56
+ return {
57
+ status: 'abort',
58
+ reason: ABORT_REASON.SELECTION_CLEARED
59
+ };
51
60
  }
52
61
  }
53
62
  }), new _experiences.ExperienceCheckDomMutation({
54
63
  onDomMutation: function onDomMutation(_ref2) {
55
64
  var mutations = _ref2.mutations;
65
+ // @ts-ignore - Workaround for help-center local consumption
66
+
56
67
  if (mutations.some(isSelectionToolbarAddedInMutation)) {
57
68
  return {
58
69
  status: 'success'
@@ -75,37 +86,63 @@ var getSelectionToolbarOpenExperiencePlugin = exports.getSelectionToolbarOpenExp
75
86
  init: function init() {
76
87
  return {};
77
88
  },
89
+ // @ts-ignore - Workaround for help-center local consumption
90
+
78
91
  apply: function apply(_tr, pluginState, oldState, newState) {
79
- if (!oldState.selection.empty && newState.selection.empty) {
92
+ if (!oldState.selection.empty && isSelectionWithoutTextContent(newState.selection)) {
80
93
  experience.abort({
81
94
  reason: ABORT_REASON.SELECTION_CLEARED
82
95
  });
83
96
  }
97
+ if (shiftArrowKeyPressed && !newState.selection.eq(oldState.selection) && !isSelectionWithoutTextContent(newState.selection)) {
98
+ experience.start({
99
+ method: START_METHOD.KEY_DOWN
100
+ });
101
+ shiftArrowKeyPressed = false;
102
+ }
84
103
  return pluginState;
85
104
  }
86
105
  },
87
106
  props: {
107
+ // @ts-ignore - Workaround for help-center local consumption
108
+
88
109
  handleDOMEvents: {
89
- mouseup: function mouseup(view) {
90
- if (!view.state.selection.empty && !isSelectionToolbarWithinNode(getTarget())) {
110
+ mousedown: function mousedown(_view, e) {
111
+ mouseDownPos = {
112
+ x: e.clientX,
113
+ y: e.clientY
114
+ };
115
+ },
116
+ mouseup: function mouseup(view, e) {
117
+ if (!mouseDownPos || isSelectionWithoutTextContent(view.state.selection) || isSelectionWithinCodeBlock(view.state.selection) || isSelectionToolbarWithinNode(getTarget())) {
118
+ return;
119
+ }
120
+ if (e.clientX !== mouseDownPos.x || e.clientY !== mouseDownPos.y) {
91
121
  experience.start({
92
122
  method: START_METHOD.MOUSE_UP
93
123
  });
94
124
  }
95
125
  },
126
+ dblclick: function dblclick(view, e) {
127
+ if (isSelectionWithoutTextContent(view.state.selection) || isSelectionWithinCodeBlock(view.state.selection) || isSelectionToolbarWithinNode(getTarget())) {
128
+ return;
129
+ }
130
+ experience.start({
131
+ method: START_METHOD.MOUSE_UP
132
+ });
133
+ },
96
134
  keydown: function keydown(_view, _ref3) {
97
135
  var shiftKey = _ref3.shiftKey,
98
136
  key = _ref3.key;
99
- if (shiftKey && key.includes('Arrow') && !isSelectionToolbarWithinNode(getTarget())) {
100
- experience.start({
101
- method: START_METHOD.KEY_DOWN
102
- });
103
- }
137
+ shiftArrowKeyPressed = shiftKey && key.includes('Arrow') && !isSelectionToolbarWithinNode(getTarget());
138
+ },
139
+ keyup: function keyup() {
140
+ shiftArrowKeyPressed = false;
104
141
  }
105
142
  }
106
143
  },
107
144
  view: function view(_view2) {
108
- editorViewEl = _view2.dom;
145
+ editorView = _view2;
109
146
  return {
110
147
  destroy: function destroy() {
111
148
  experience.abort({
@@ -119,6 +156,8 @@ var getSelectionToolbarOpenExperiencePlugin = exports.getSelectionToolbarOpenExp
119
156
  var isSelectionToolbarAddedInMutation = function isSelectionToolbarAddedInMutation(_ref4) {
120
157
  var type = _ref4.type,
121
158
  addedNodes = _ref4.addedNodes;
159
+ // @ts-ignore - Workaround for help-center local consumption
160
+
122
161
  return type === 'childList' && (0, _toConsumableArray2.default)(addedNodes).some(isSelectionToolbarWithinNode);
123
162
  };
124
163
  var isSelectionToolbarWithinNode = function isSelectionToolbarWithinNode(node) {
@@ -126,4 +165,26 @@ var isSelectionToolbarWithinNode = function isSelectionToolbarWithinNode(node) {
126
165
  };
127
166
  var isBlockMenuWithinNode = function isBlockMenuWithinNode(node) {
128
167
  return (0, _experiences.containsPopupWithNestedElement)(node, '[data-testid="editor-block-menu"]');
168
+ };
169
+ var isSelectionWithoutTextContent = function isSelectionWithoutTextContent(selection) {
170
+ if (!selection || selection.empty) {
171
+ return true;
172
+ }
173
+ var hasText = false;
174
+ selection.$from.doc.nodesBetween(selection.from, selection.to, function (node) {
175
+ if (hasText) {
176
+ return false;
177
+ }
178
+ if (node.isText && node.text && node.text.length > 0) {
179
+ hasText = true;
180
+ return false;
181
+ }
182
+ return true;
183
+ });
184
+ return !hasText;
185
+ };
186
+ var isSelectionWithinCodeBlock = function isSelectionWithinCodeBlock(selection) {
187
+ var $from = selection.$from,
188
+ $to = selection.$to;
189
+ return $from.sameParent($to) && $from.parent.type.name === 'codeBlock';
129
190
  };
@@ -30,6 +30,8 @@ function getSelectedNode(editorState) {
30
30
  node: selection.node,
31
31
  pos: selection.from,
32
32
  nodeType: selection.node.type.name,
33
+ // @ts-ignore - Workaround for help-center local consumption
34
+
33
35
  marks: selection.node.marks.map(function (mark) {
34
36
  return "".concat(mark.type.name, ":").concat(JSON.stringify(mark.attrs));
35
37
  })
@@ -42,6 +44,8 @@ function getSelectedNode(editorState) {
42
44
  node: selectedNode.node,
43
45
  pos: selectedNode.pos,
44
46
  nodeType: selectedNode.node.type.name,
47
+ // @ts-ignore - Workaround for help-center local consumption
48
+
45
49
  marks: selectedNode.node.marks.map(function (mark) {
46
50
  return "".concat(mark.type.name, ":").concat(JSON.stringify(mark.attrs));
47
51
  })
@@ -53,6 +57,8 @@ function getSelectedNode(editorState) {
53
57
  node: parentNode.node,
54
58
  pos: parentNode.pos,
55
59
  nodeType: parentNode.node.type.name,
60
+ // @ts-ignore - Workaround for help-center local consumption
61
+
56
62
  marks: parentNode.node.marks.map(function (mark) {
57
63
  return "".concat(mark.type.name, ":").concat(JSON.stringify(mark.attrs));
58
64
  })
@@ -63,6 +69,8 @@ function getSelectedNode(editorState) {
63
69
  node: $pos.parent,
64
70
  pos: $pos.pos,
65
71
  nodeType: $pos.parent.type.name,
72
+ // @ts-ignore - Workaround for help-center local consumption
73
+
66
74
  marks: $pos.marks().map(function (mark) {
67
75
  return "".concat(mark.type.name, ":").concat(JSON.stringify(mark.attrs));
68
76
  })
@@ -117,12 +125,14 @@ var toolbarPlugin = exports.toolbarPlugin = function toolbarPlugin(_ref) {
117
125
  return new _safePlugin.SafePlugin({
118
126
  key: _pluginKey.editorToolbarPluginKey,
119
127
  state: {
128
+ // @ts-ignore - Workaround for help-center local consumption
120
129
  init: function init(_, editorState) {
121
130
  return {
122
131
  shouldShowToolbar: false,
123
132
  selectedNode: getSelectedNode(editorState)
124
133
  };
125
134
  },
135
+ // @ts-ignore - Workaround for help-center local consumption
126
136
  apply: function apply(tr, pluginState, _, newState) {
127
137
  var meta = tr.getMeta(_pluginKey.editorToolbarPluginKey);
128
138
  var newPluginState = _objectSpread({}, pluginState);
@@ -143,6 +153,7 @@ var toolbarPlugin = exports.toolbarPlugin = function toolbarPlugin(_ref) {
143
153
  return newPluginState;
144
154
  }
145
155
  },
156
+ // @ts-ignore - Workaround for help-center local consumption
146
157
  view: function view(_view) {
147
158
  var unbind = (0, _bindEventListener.bind)(_view.root, {
148
159
  type: 'mouseup',
@@ -171,6 +182,7 @@ var toolbarPlugin = exports.toolbarPlugin = function toolbarPlugin(_ref) {
171
182
  }
172
183
  });
173
184
  return {
185
+ // @ts-ignore - Workaround for help-center local consumption
174
186
  destroy: function destroy() {
175
187
  unbind();
176
188
  unbindEditorViewFocus();
@@ -178,7 +190,11 @@ var toolbarPlugin = exports.toolbarPlugin = function toolbarPlugin(_ref) {
178
190
  };
179
191
  },
180
192
  props: {
193
+ // @ts-ignore - Workaround for help-center local consumption
194
+
181
195
  handleDOMEvents: {
196
+ // @ts-ignore - Workaround for help-center local consumption
197
+
182
198
  mousedown: function mousedown(view) {
183
199
  view.dispatch(view.state.tr.setMeta(_pluginKey.editorToolbarPluginKey, {
184
200
  shouldShowToolbar: false
@@ -15,38 +15,49 @@ const ABORT_REASON = {
15
15
  * This experience tracks when the selection toolbar is opened.
16
16
  *
17
17
  * Start: When user makes a selection via mouseup or shift+arrow key down
18
- * Success: When the selection toolbar is added to the DOM within 500ms of start
19
- * Failure: When 500ms passes without the selection toolbar being added to the DOM
20
- * Abort: When selection transition to empty or block menu is opened
18
+ * Success: When the selection toolbar is added to the DOM within 1000ms of start
19
+ * Failure: When 1000ms passes without the selection toolbar being added to the DOM
20
+ * Abort: When selection transitions to empty or block menu is opened
21
21
  */
22
22
  export const getSelectionToolbarOpenExperiencePlugin = ({
23
23
  refs,
24
24
  dispatchAnalyticsEvent
25
25
  }) => {
26
+ let editorView;
26
27
  let targetEl;
27
- let editorViewEl;
28
+ let shiftArrowKeyPressed = false;
29
+ let mouseDownPos;
28
30
  const getTarget = () => {
29
31
  if (!targetEl) {
30
- targetEl = refs.popupsMountPoint || getPopupContainerFromEditorView(editorViewEl);
32
+ var _editorView;
33
+ targetEl = refs.popupsMountPoint || getPopupContainerFromEditorView((_editorView = editorView) === null || _editorView === void 0 ? void 0 : _editorView.dom);
31
34
  }
32
35
  return targetEl;
33
36
  };
34
37
  const experience = new Experience('selection-toolbar-open', {
35
38
  dispatchAnalyticsEvent,
36
39
  checks: [new ExperienceCheckTimeout({
37
- durationMs: 500,
40
+ durationMs: 1000,
38
41
  onTimeout: () => {
42
+ var _editorView2;
39
43
  if (isBlockMenuWithinNode(getTarget())) {
40
44
  return {
41
45
  status: 'abort',
42
46
  reason: ABORT_REASON.BLOCK_MENU_OPENED
43
47
  };
48
+ } else if (isSelectionWithoutTextContent((_editorView2 = editorView) === null || _editorView2 === void 0 ? void 0 : _editorView2.state.selection)) {
49
+ return {
50
+ status: 'abort',
51
+ reason: ABORT_REASON.SELECTION_CLEARED
52
+ };
44
53
  }
45
54
  }
46
55
  }), new ExperienceCheckDomMutation({
47
56
  onDomMutation: ({
48
57
  mutations
49
58
  }) => {
59
+ // @ts-ignore - Workaround for help-center local consumption
60
+
50
61
  if (mutations.some(isSelectionToolbarAddedInMutation)) {
51
62
  return {
52
63
  status: 'success'
@@ -65,38 +76,64 @@ export const getSelectionToolbarOpenExperiencePlugin = ({
65
76
  key: pluginKey,
66
77
  state: {
67
78
  init: () => ({}),
79
+ // @ts-ignore - Workaround for help-center local consumption
80
+
68
81
  apply: (_tr, pluginState, oldState, newState) => {
69
- if (!oldState.selection.empty && newState.selection.empty) {
82
+ if (!oldState.selection.empty && isSelectionWithoutTextContent(newState.selection)) {
70
83
  experience.abort({
71
84
  reason: ABORT_REASON.SELECTION_CLEARED
72
85
  });
73
86
  }
87
+ if (shiftArrowKeyPressed && !newState.selection.eq(oldState.selection) && !isSelectionWithoutTextContent(newState.selection)) {
88
+ experience.start({
89
+ method: START_METHOD.KEY_DOWN
90
+ });
91
+ shiftArrowKeyPressed = false;
92
+ }
74
93
  return pluginState;
75
94
  }
76
95
  },
77
96
  props: {
97
+ // @ts-ignore - Workaround for help-center local consumption
98
+
78
99
  handleDOMEvents: {
79
- mouseup: view => {
80
- if (!view.state.selection.empty && !isSelectionToolbarWithinNode(getTarget())) {
100
+ mousedown: (_view, e) => {
101
+ mouseDownPos = {
102
+ x: e.clientX,
103
+ y: e.clientY
104
+ };
105
+ },
106
+ mouseup: (view, e) => {
107
+ if (!mouseDownPos || isSelectionWithoutTextContent(view.state.selection) || isSelectionWithinCodeBlock(view.state.selection) || isSelectionToolbarWithinNode(getTarget())) {
108
+ return;
109
+ }
110
+ if (e.clientX !== mouseDownPos.x || e.clientY !== mouseDownPos.y) {
81
111
  experience.start({
82
112
  method: START_METHOD.MOUSE_UP
83
113
  });
84
114
  }
85
115
  },
116
+ dblclick: (view, e) => {
117
+ if (isSelectionWithoutTextContent(view.state.selection) || isSelectionWithinCodeBlock(view.state.selection) || isSelectionToolbarWithinNode(getTarget())) {
118
+ return;
119
+ }
120
+ experience.start({
121
+ method: START_METHOD.MOUSE_UP
122
+ });
123
+ },
86
124
  keydown: (_view, {
87
125
  shiftKey,
88
126
  key
89
127
  }) => {
90
- if (shiftKey && key.includes('Arrow') && !isSelectionToolbarWithinNode(getTarget())) {
91
- experience.start({
92
- method: START_METHOD.KEY_DOWN
93
- });
94
- }
128
+ shiftArrowKeyPressed = shiftKey && key.includes('Arrow') && !isSelectionToolbarWithinNode(getTarget());
129
+ },
130
+ keyup: () => {
131
+ shiftArrowKeyPressed = false;
95
132
  }
96
133
  }
97
134
  },
98
135
  view: view => {
99
- editorViewEl = view.dom;
136
+ editorView = view;
100
137
  return {
101
138
  destroy: () => {
102
139
  experience.abort({
@@ -111,6 +148,8 @@ const isSelectionToolbarAddedInMutation = ({
111
148
  type,
112
149
  addedNodes
113
150
  }) => {
151
+ // @ts-ignore - Workaround for help-center local consumption
152
+
114
153
  return type === 'childList' && [...addedNodes].some(isSelectionToolbarWithinNode);
115
154
  };
116
155
  const isSelectionToolbarWithinNode = node => {
@@ -118,4 +157,28 @@ const isSelectionToolbarWithinNode = node => {
118
157
  };
119
158
  const isBlockMenuWithinNode = node => {
120
159
  return containsPopupWithNestedElement(node, '[data-testid="editor-block-menu"]');
160
+ };
161
+ const isSelectionWithoutTextContent = selection => {
162
+ if (!selection || selection.empty) {
163
+ return true;
164
+ }
165
+ let hasText = false;
166
+ selection.$from.doc.nodesBetween(selection.from, selection.to, node => {
167
+ if (hasText) {
168
+ return false;
169
+ }
170
+ if (node.isText && node.text && node.text.length > 0) {
171
+ hasText = true;
172
+ return false;
173
+ }
174
+ return true;
175
+ });
176
+ return !hasText;
177
+ };
178
+ const isSelectionWithinCodeBlock = selection => {
179
+ const {
180
+ $from,
181
+ $to
182
+ } = selection;
183
+ return $from.sameParent($to) && $from.parent.type.name === 'codeBlock';
121
184
  };
@@ -21,6 +21,8 @@ function getSelectedNode(editorState) {
21
21
  node: selection.node,
22
22
  pos: selection.from,
23
23
  nodeType: selection.node.type.name,
24
+ // @ts-ignore - Workaround for help-center local consumption
25
+
24
26
  marks: selection.node.marks.map(mark => `${mark.type.name}:${JSON.stringify(mark.attrs)}`)
25
27
  };
26
28
  }
@@ -33,6 +35,8 @@ function getSelectedNode(editorState) {
33
35
  node: selectedNode.node,
34
36
  pos: selectedNode.pos,
35
37
  nodeType: selectedNode.node.type.name,
38
+ // @ts-ignore - Workaround for help-center local consumption
39
+
36
40
  marks: selectedNode.node.marks.map(mark => `${mark.type.name}:${JSON.stringify(mark.attrs)}`)
37
41
  };
38
42
  }
@@ -42,6 +46,8 @@ function getSelectedNode(editorState) {
42
46
  node: parentNode.node,
43
47
  pos: parentNode.pos,
44
48
  nodeType: parentNode.node.type.name,
49
+ // @ts-ignore - Workaround for help-center local consumption
50
+
45
51
  marks: parentNode.node.marks.map(mark => `${mark.type.name}:${JSON.stringify(mark.attrs)}`)
46
52
  };
47
53
  }
@@ -50,6 +56,8 @@ function getSelectedNode(editorState) {
50
56
  node: $pos.parent,
51
57
  pos: $pos.pos,
52
58
  nodeType: $pos.parent.type.name,
59
+ // @ts-ignore - Workaround for help-center local consumption
60
+
53
61
  marks: $pos.marks().map(mark => `${mark.type.name}:${JSON.stringify(mark.attrs)}`)
54
62
  };
55
63
  }
@@ -102,12 +110,16 @@ export const toolbarPlugin = ({
102
110
  return new SafePlugin({
103
111
  key: editorToolbarPluginKey,
104
112
  state: {
113
+ // @ts-ignore - Workaround for help-center local consumption
114
+
105
115
  init(_, editorState) {
106
116
  return {
107
117
  shouldShowToolbar: false,
108
118
  selectedNode: getSelectedNode(editorState)
109
119
  };
110
120
  },
121
+ // @ts-ignore - Workaround for help-center local consumption
122
+
111
123
  apply(tr, pluginState, _, newState) {
112
124
  const meta = tr.getMeta(editorToolbarPluginKey);
113
125
  let newPluginState = {
@@ -133,6 +145,8 @@ export const toolbarPlugin = ({
133
145
  return newPluginState;
134
146
  }
135
147
  },
148
+ // @ts-ignore - Workaround for help-center local consumption
149
+
136
150
  view(view) {
137
151
  const unbind = bind(view.root, {
138
152
  type: 'mouseup',
@@ -161,6 +175,8 @@ export const toolbarPlugin = ({
161
175
  }
162
176
  });
163
177
  return {
178
+ // @ts-ignore - Workaround for help-center local consumption
179
+
164
180
  destroy() {
165
181
  unbind();
166
182
  unbindEditorViewFocus();
@@ -168,7 +184,11 @@ export const toolbarPlugin = ({
168
184
  };
169
185
  },
170
186
  props: {
187
+ // @ts-ignore - Workaround for help-center local consumption
188
+
171
189
  handleDOMEvents: {
190
+ // @ts-ignore - Workaround for help-center local consumption
191
+
172
192
  mousedown: view => {
173
193
  view.dispatch(view.state.tr.setMeta(editorToolbarPluginKey, {
174
194
  shouldShowToolbar: false
@@ -16,36 +16,47 @@ var ABORT_REASON = {
16
16
  * This experience tracks when the selection toolbar is opened.
17
17
  *
18
18
  * Start: When user makes a selection via mouseup or shift+arrow key down
19
- * Success: When the selection toolbar is added to the DOM within 500ms of start
20
- * Failure: When 500ms passes without the selection toolbar being added to the DOM
21
- * Abort: When selection transition to empty or block menu is opened
19
+ * Success: When the selection toolbar is added to the DOM within 1000ms of start
20
+ * Failure: When 1000ms passes without the selection toolbar being added to the DOM
21
+ * Abort: When selection transitions to empty or block menu is opened
22
22
  */
23
23
  export var getSelectionToolbarOpenExperiencePlugin = function getSelectionToolbarOpenExperiencePlugin(_ref) {
24
24
  var refs = _ref.refs,
25
25
  dispatchAnalyticsEvent = _ref.dispatchAnalyticsEvent;
26
+ var editorView;
26
27
  var targetEl;
27
- var editorViewEl;
28
+ var shiftArrowKeyPressed = false;
29
+ var mouseDownPos;
28
30
  var getTarget = function getTarget() {
29
31
  if (!targetEl) {
30
- targetEl = refs.popupsMountPoint || getPopupContainerFromEditorView(editorViewEl);
32
+ var _editorView;
33
+ targetEl = refs.popupsMountPoint || getPopupContainerFromEditorView((_editorView = editorView) === null || _editorView === void 0 ? void 0 : _editorView.dom);
31
34
  }
32
35
  return targetEl;
33
36
  };
34
37
  var experience = new Experience('selection-toolbar-open', {
35
38
  dispatchAnalyticsEvent: dispatchAnalyticsEvent,
36
39
  checks: [new ExperienceCheckTimeout({
37
- durationMs: 500,
40
+ durationMs: 1000,
38
41
  onTimeout: function onTimeout() {
42
+ var _editorView2;
39
43
  if (isBlockMenuWithinNode(getTarget())) {
40
44
  return {
41
45
  status: 'abort',
42
46
  reason: ABORT_REASON.BLOCK_MENU_OPENED
43
47
  };
48
+ } else if (isSelectionWithoutTextContent((_editorView2 = editorView) === null || _editorView2 === void 0 ? void 0 : _editorView2.state.selection)) {
49
+ return {
50
+ status: 'abort',
51
+ reason: ABORT_REASON.SELECTION_CLEARED
52
+ };
44
53
  }
45
54
  }
46
55
  }), new ExperienceCheckDomMutation({
47
56
  onDomMutation: function onDomMutation(_ref2) {
48
57
  var mutations = _ref2.mutations;
58
+ // @ts-ignore - Workaround for help-center local consumption
59
+
49
60
  if (mutations.some(isSelectionToolbarAddedInMutation)) {
50
61
  return {
51
62
  status: 'success'
@@ -68,37 +79,63 @@ export var getSelectionToolbarOpenExperiencePlugin = function getSelectionToolba
68
79
  init: function init() {
69
80
  return {};
70
81
  },
82
+ // @ts-ignore - Workaround for help-center local consumption
83
+
71
84
  apply: function apply(_tr, pluginState, oldState, newState) {
72
- if (!oldState.selection.empty && newState.selection.empty) {
85
+ if (!oldState.selection.empty && isSelectionWithoutTextContent(newState.selection)) {
73
86
  experience.abort({
74
87
  reason: ABORT_REASON.SELECTION_CLEARED
75
88
  });
76
89
  }
90
+ if (shiftArrowKeyPressed && !newState.selection.eq(oldState.selection) && !isSelectionWithoutTextContent(newState.selection)) {
91
+ experience.start({
92
+ method: START_METHOD.KEY_DOWN
93
+ });
94
+ shiftArrowKeyPressed = false;
95
+ }
77
96
  return pluginState;
78
97
  }
79
98
  },
80
99
  props: {
100
+ // @ts-ignore - Workaround for help-center local consumption
101
+
81
102
  handleDOMEvents: {
82
- mouseup: function mouseup(view) {
83
- if (!view.state.selection.empty && !isSelectionToolbarWithinNode(getTarget())) {
103
+ mousedown: function mousedown(_view, e) {
104
+ mouseDownPos = {
105
+ x: e.clientX,
106
+ y: e.clientY
107
+ };
108
+ },
109
+ mouseup: function mouseup(view, e) {
110
+ if (!mouseDownPos || isSelectionWithoutTextContent(view.state.selection) || isSelectionWithinCodeBlock(view.state.selection) || isSelectionToolbarWithinNode(getTarget())) {
111
+ return;
112
+ }
113
+ if (e.clientX !== mouseDownPos.x || e.clientY !== mouseDownPos.y) {
84
114
  experience.start({
85
115
  method: START_METHOD.MOUSE_UP
86
116
  });
87
117
  }
88
118
  },
119
+ dblclick: function dblclick(view, e) {
120
+ if (isSelectionWithoutTextContent(view.state.selection) || isSelectionWithinCodeBlock(view.state.selection) || isSelectionToolbarWithinNode(getTarget())) {
121
+ return;
122
+ }
123
+ experience.start({
124
+ method: START_METHOD.MOUSE_UP
125
+ });
126
+ },
89
127
  keydown: function keydown(_view, _ref3) {
90
128
  var shiftKey = _ref3.shiftKey,
91
129
  key = _ref3.key;
92
- if (shiftKey && key.includes('Arrow') && !isSelectionToolbarWithinNode(getTarget())) {
93
- experience.start({
94
- method: START_METHOD.KEY_DOWN
95
- });
96
- }
130
+ shiftArrowKeyPressed = shiftKey && key.includes('Arrow') && !isSelectionToolbarWithinNode(getTarget());
131
+ },
132
+ keyup: function keyup() {
133
+ shiftArrowKeyPressed = false;
97
134
  }
98
135
  }
99
136
  },
100
137
  view: function view(_view2) {
101
- editorViewEl = _view2.dom;
138
+ editorView = _view2;
102
139
  return {
103
140
  destroy: function destroy() {
104
141
  experience.abort({
@@ -112,6 +149,8 @@ export var getSelectionToolbarOpenExperiencePlugin = function getSelectionToolba
112
149
  var isSelectionToolbarAddedInMutation = function isSelectionToolbarAddedInMutation(_ref4) {
113
150
  var type = _ref4.type,
114
151
  addedNodes = _ref4.addedNodes;
152
+ // @ts-ignore - Workaround for help-center local consumption
153
+
115
154
  return type === 'childList' && _toConsumableArray(addedNodes).some(isSelectionToolbarWithinNode);
116
155
  };
117
156
  var isSelectionToolbarWithinNode = function isSelectionToolbarWithinNode(node) {
@@ -119,4 +158,26 @@ var isSelectionToolbarWithinNode = function isSelectionToolbarWithinNode(node) {
119
158
  };
120
159
  var isBlockMenuWithinNode = function isBlockMenuWithinNode(node) {
121
160
  return containsPopupWithNestedElement(node, '[data-testid="editor-block-menu"]');
161
+ };
162
+ var isSelectionWithoutTextContent = function isSelectionWithoutTextContent(selection) {
163
+ if (!selection || selection.empty) {
164
+ return true;
165
+ }
166
+ var hasText = false;
167
+ selection.$from.doc.nodesBetween(selection.from, selection.to, function (node) {
168
+ if (hasText) {
169
+ return false;
170
+ }
171
+ if (node.isText && node.text && node.text.length > 0) {
172
+ hasText = true;
173
+ return false;
174
+ }
175
+ return true;
176
+ });
177
+ return !hasText;
178
+ };
179
+ var isSelectionWithinCodeBlock = function isSelectionWithinCodeBlock(selection) {
180
+ var $from = selection.$from,
181
+ $to = selection.$to;
182
+ return $from.sameParent($to) && $from.parent.type.name === 'codeBlock';
122
183
  };
@@ -23,6 +23,8 @@ function getSelectedNode(editorState) {
23
23
  node: selection.node,
24
24
  pos: selection.from,
25
25
  nodeType: selection.node.type.name,
26
+ // @ts-ignore - Workaround for help-center local consumption
27
+
26
28
  marks: selection.node.marks.map(function (mark) {
27
29
  return "".concat(mark.type.name, ":").concat(JSON.stringify(mark.attrs));
28
30
  })
@@ -35,6 +37,8 @@ function getSelectedNode(editorState) {
35
37
  node: selectedNode.node,
36
38
  pos: selectedNode.pos,
37
39
  nodeType: selectedNode.node.type.name,
40
+ // @ts-ignore - Workaround for help-center local consumption
41
+
38
42
  marks: selectedNode.node.marks.map(function (mark) {
39
43
  return "".concat(mark.type.name, ":").concat(JSON.stringify(mark.attrs));
40
44
  })
@@ -46,6 +50,8 @@ function getSelectedNode(editorState) {
46
50
  node: parentNode.node,
47
51
  pos: parentNode.pos,
48
52
  nodeType: parentNode.node.type.name,
53
+ // @ts-ignore - Workaround for help-center local consumption
54
+
49
55
  marks: parentNode.node.marks.map(function (mark) {
50
56
  return "".concat(mark.type.name, ":").concat(JSON.stringify(mark.attrs));
51
57
  })
@@ -56,6 +62,8 @@ function getSelectedNode(editorState) {
56
62
  node: $pos.parent,
57
63
  pos: $pos.pos,
58
64
  nodeType: $pos.parent.type.name,
65
+ // @ts-ignore - Workaround for help-center local consumption
66
+
59
67
  marks: $pos.marks().map(function (mark) {
60
68
  return "".concat(mark.type.name, ":").concat(JSON.stringify(mark.attrs));
61
69
  })
@@ -110,12 +118,14 @@ export var toolbarPlugin = function toolbarPlugin(_ref) {
110
118
  return new SafePlugin({
111
119
  key: editorToolbarPluginKey,
112
120
  state: {
121
+ // @ts-ignore - Workaround for help-center local consumption
113
122
  init: function init(_, editorState) {
114
123
  return {
115
124
  shouldShowToolbar: false,
116
125
  selectedNode: getSelectedNode(editorState)
117
126
  };
118
127
  },
128
+ // @ts-ignore - Workaround for help-center local consumption
119
129
  apply: function apply(tr, pluginState, _, newState) {
120
130
  var meta = tr.getMeta(editorToolbarPluginKey);
121
131
  var newPluginState = _objectSpread({}, pluginState);
@@ -136,6 +146,7 @@ export var toolbarPlugin = function toolbarPlugin(_ref) {
136
146
  return newPluginState;
137
147
  }
138
148
  },
149
+ // @ts-ignore - Workaround for help-center local consumption
139
150
  view: function view(_view) {
140
151
  var unbind = bind(_view.root, {
141
152
  type: 'mouseup',
@@ -164,6 +175,7 @@ export var toolbarPlugin = function toolbarPlugin(_ref) {
164
175
  }
165
176
  });
166
177
  return {
178
+ // @ts-ignore - Workaround for help-center local consumption
167
179
  destroy: function destroy() {
168
180
  unbind();
169
181
  unbindEditorViewFocus();
@@ -171,7 +183,11 @@ export var toolbarPlugin = function toolbarPlugin(_ref) {
171
183
  };
172
184
  },
173
185
  props: {
186
+ // @ts-ignore - Workaround for help-center local consumption
187
+
174
188
  handleDOMEvents: {
189
+ // @ts-ignore - Workaround for help-center local consumption
190
+
175
191
  mousedown: function mousedown(view) {
176
192
  view.dispatch(view.state.tr.setMeta(editorToolbarPluginKey, {
177
193
  shouldShowToolbar: false
@@ -10,9 +10,9 @@ type SelectionToolbarOpenExperienceOptions = {
10
10
  * This experience tracks when the selection toolbar is opened.
11
11
  *
12
12
  * Start: When user makes a selection via mouseup or shift+arrow key down
13
- * Success: When the selection toolbar is added to the DOM within 500ms of start
14
- * Failure: When 500ms passes without the selection toolbar being added to the DOM
15
- * Abort: When selection transition to empty or block menu is opened
13
+ * Success: When the selection toolbar is added to the DOM within 1000ms of start
14
+ * Failure: When 1000ms passes without the selection toolbar being added to the DOM
15
+ * Abort: When selection transitions to empty or block menu is opened
16
16
  */
17
17
  export declare const getSelectionToolbarOpenExperiencePlugin: ({ refs, dispatchAnalyticsEvent, }: SelectionToolbarOpenExperienceOptions) => SafePlugin<{}>;
18
18
  export {};
@@ -10,9 +10,9 @@ type SelectionToolbarOpenExperienceOptions = {
10
10
  * This experience tracks when the selection toolbar is opened.
11
11
  *
12
12
  * Start: When user makes a selection via mouseup or shift+arrow key down
13
- * Success: When the selection toolbar is added to the DOM within 500ms of start
14
- * Failure: When 500ms passes without the selection toolbar being added to the DOM
15
- * Abort: When selection transition to empty or block menu is opened
13
+ * Success: When the selection toolbar is added to the DOM within 1000ms of start
14
+ * Failure: When 1000ms passes without the selection toolbar being added to the DOM
15
+ * Abort: When selection transitions to empty or block menu is opened
16
16
  */
17
17
  export declare const getSelectionToolbarOpenExperiencePlugin: ({ refs, dispatchAnalyticsEvent, }: SelectionToolbarOpenExperienceOptions) => SafePlugin<{}>;
18
18
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-toolbar",
3
- "version": "3.4.9",
3
+ "version": "3.4.11",
4
4
  "description": "Toolbar plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -40,13 +40,13 @@
40
40
  "@atlaskit/editor-toolbar-model": "^0.2.0",
41
41
  "@atlaskit/platform-feature-flags": "^1.1.0",
42
42
  "@atlaskit/platform-feature-flags-react": "^0.4.0",
43
- "@atlaskit/tmp-editor-statsig": "^13.38.0",
43
+ "@atlaskit/tmp-editor-statsig": "^13.42.0",
44
44
  "@babel/runtime": "^7.0.0",
45
45
  "bind-event-listener": "^3.0.0",
46
46
  "react-intl-next": "npm:react-intl@^5.18.1"
47
47
  },
48
48
  "peerDependencies": {
49
- "@atlaskit/editor-common": "^110.32.0",
49
+ "@atlaskit/editor-common": "^110.34.0",
50
50
  "react": "^18.2.0"
51
51
  },
52
52
  "platform-feature-flags": {