@atlaskit/editor-core 188.7.5 → 188.8.0
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 +16 -0
- package/dist/cjs/plugins/date/actions.js +8 -114
- package/dist/cjs/plugins/date/commands.js +118 -0
- package/dist/cjs/plugins/date/plugin.js +13 -7
- package/dist/cjs/plugins/insert-block/ui/ToolbarInsertBlock/index.js +34 -33
- package/dist/cjs/plugins/type-ahead/index.js +4 -372
- package/dist/cjs/plugins/type-ahead/plugin.js +382 -0
- package/dist/cjs/plugins/view-update-subscription/subscribe/toolbarAndPickerUpdates.js +17 -8
- package/dist/cjs/version-wrapper.js +1 -1
- package/dist/es2019/plugins/date/actions.js +3 -109
- package/dist/es2019/plugins/date/commands.js +113 -0
- package/dist/es2019/plugins/date/plugin.js +14 -8
- package/dist/es2019/plugins/insert-block/ui/ToolbarInsertBlock/index.js +5 -3
- package/dist/es2019/plugins/type-ahead/index.js +2 -375
- package/dist/es2019/plugins/type-ahead/plugin.js +381 -0
- package/dist/es2019/plugins/view-update-subscription/subscribe/toolbarAndPickerUpdates.js +17 -8
- package/dist/es2019/version-wrapper.js +1 -1
- package/dist/esm/plugins/date/actions.js +8 -114
- package/dist/esm/plugins/date/commands.js +112 -0
- package/dist/esm/plugins/date/plugin.js +14 -8
- package/dist/esm/plugins/insert-block/ui/ToolbarInsertBlock/index.js +34 -33
- package/dist/esm/plugins/type-ahead/index.js +2 -368
- package/dist/esm/plugins/type-ahead/plugin.js +374 -0
- package/dist/esm/plugins/view-update-subscription/subscribe/toolbarAndPickerUpdates.js +17 -8
- package/dist/esm/version-wrapper.js +1 -1
- package/dist/types/labs/next/presets/default.d.ts +30 -12
- package/dist/types/plugins/date/actions.d.ts +4 -10
- package/dist/types/plugins/date/commands.d.ts +20 -0
- package/dist/types/plugins/date/types.d.ts +4 -4
- package/dist/types/plugins/type-ahead/index.d.ts +3 -14
- package/dist/types/plugins/type-ahead/plugin.d.ts +10 -0
- package/dist/types/plugins/type-ahead/types.d.ts +51 -6
- package/dist/types-ts4.5/labs/next/presets/default.d.ts +30 -12
- package/dist/types-ts4.5/plugins/date/actions.d.ts +4 -10
- package/dist/types-ts4.5/plugins/date/commands.d.ts +22 -0
- package/dist/types-ts4.5/plugins/date/types.d.ts +4 -4
- package/dist/types-ts4.5/plugins/type-ahead/index.d.ts +3 -14
- package/dist/types-ts4.5/plugins/type-ahead/plugin.d.ts +10 -0
- package/dist/types-ts4.5/plugins/type-ahead/types.d.ts +53 -6
- package/package.json +2 -2
- package/dist/cjs/plugins/view-update-subscription/subscribe/type-ahead-updates.js +0 -33
- package/dist/es2019/plugins/view-update-subscription/subscribe/type-ahead-updates.js +0 -28
- package/dist/esm/plugins/view-update-subscription/subscribe/type-ahead-updates.js +0 -27
- package/dist/types/plugins/view-update-subscription/subscribe/type-ahead-updates.d.ts +0 -9
- package/dist/types-ts4.5/plugins/view-update-subscription/subscribe/type-ahead-updates.d.ts +0 -9
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* Revamped typeahead using decorations instead of the `typeAheadQuery` mark
|
|
4
|
+
*
|
|
5
|
+
* https://product-fabric.atlassian.net/wiki/spaces/E/pages/2992177582/Technical+TypeAhead+Data+Flow
|
|
6
|
+
*
|
|
7
|
+
*
|
|
8
|
+
*/
|
|
9
|
+
import React from 'react';
|
|
10
|
+
import { typeAheadQuery } from '@atlaskit/adf-schema';
|
|
11
|
+
import { ACTION, ACTION_SUBJECT, EVENT_TYPE, fireAnalyticsEvent, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
12
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
13
|
+
import { SelectItemMode } from '@atlaskit/editor-common/type-ahead';
|
|
14
|
+
import { WithPluginState } from '@atlaskit/editor-common/with-plugin-state';
|
|
15
|
+
import { insertTypeAheadItem } from './commands/insert-type-ahead-item';
|
|
16
|
+
import { updateSelectedIndex } from './commands/update-selected-index';
|
|
17
|
+
import { inputRulePlugin } from './pm-plugins/input-rules';
|
|
18
|
+
import { createPlugin as createInsertItemPlugin } from './pm-plugins/insert-item-plugin';
|
|
19
|
+
import { pluginKey as typeAheadPluginKey } from './pm-plugins/key';
|
|
20
|
+
import { createPlugin } from './pm-plugins/main';
|
|
21
|
+
import { StatsModifier } from './stats-modifier';
|
|
22
|
+
import { closeTypeAhead } from './transforms/close-type-ahead';
|
|
23
|
+
import { openTypeAheadAtCursor } from './transforms/open-typeahead-at-cursor';
|
|
24
|
+
import { useItemInsert } from './ui/hooks/use-item-insert';
|
|
25
|
+
import { TypeAheadPopup } from './ui/TypeAheadPopup';
|
|
26
|
+
import { findHandler, getPluginState, getTypeAheadHandler, getTypeAheadQuery, isTypeAheadAllowed, isTypeAheadOpen } from './utils';
|
|
27
|
+
const TypeAheadMenu = /*#__PURE__*/React.memo(({
|
|
28
|
+
editorView,
|
|
29
|
+
popupMountRef,
|
|
30
|
+
typeAheadState,
|
|
31
|
+
fireAnalyticsCallback
|
|
32
|
+
}) => {
|
|
33
|
+
var _popupMountRef$curren, _popupMountRef$curren2, _popupMountRef$curren3;
|
|
34
|
+
const isOpen = typeAheadState.decorationSet.find().length > 0;
|
|
35
|
+
const {
|
|
36
|
+
triggerHandler,
|
|
37
|
+
items,
|
|
38
|
+
selectedIndex,
|
|
39
|
+
decorationElement,
|
|
40
|
+
decorationSet,
|
|
41
|
+
query
|
|
42
|
+
} = typeAheadState;
|
|
43
|
+
const [onItemInsert, onTextInsert, onItemMatch] = useItemInsert(triggerHandler, editorView, items);
|
|
44
|
+
const setSelectedItem = React.useCallback(({
|
|
45
|
+
index: nextIndex
|
|
46
|
+
}) => {
|
|
47
|
+
queueMicrotask(() => {
|
|
48
|
+
updateSelectedIndex(nextIndex)(editorView.state, editorView.dispatch);
|
|
49
|
+
});
|
|
50
|
+
}, [editorView]);
|
|
51
|
+
const insertItem = React.useCallback((mode = SelectItemMode.SELECTED, index) => {
|
|
52
|
+
queueMicrotask(() => {
|
|
53
|
+
onItemInsert({
|
|
54
|
+
mode,
|
|
55
|
+
index,
|
|
56
|
+
query
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
}, [onItemInsert, query]);
|
|
60
|
+
const cancel = React.useCallback(({
|
|
61
|
+
setSelectionAt,
|
|
62
|
+
addPrefixTrigger,
|
|
63
|
+
forceFocusOnEditor
|
|
64
|
+
}) => {
|
|
65
|
+
const fullQuery = addPrefixTrigger ? `${triggerHandler === null || triggerHandler === void 0 ? void 0 : triggerHandler.trigger}${query}` : query;
|
|
66
|
+
onTextInsert({
|
|
67
|
+
forceFocusOnEditor,
|
|
68
|
+
setSelectionAt,
|
|
69
|
+
text: fullQuery
|
|
70
|
+
});
|
|
71
|
+
}, [triggerHandler, onTextInsert, query]);
|
|
72
|
+
React.useEffect(() => {
|
|
73
|
+
if (!isOpen || !query) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const isLastCharSpace = query[query.length - 1] === ' ';
|
|
77
|
+
if (!isLastCharSpace) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const result = onItemMatch({
|
|
81
|
+
mode: SelectItemMode.SPACE,
|
|
82
|
+
query: query.trim()
|
|
83
|
+
});
|
|
84
|
+
if (!result) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
}, [isOpen, query, onItemMatch]);
|
|
88
|
+
if (!isOpen || !triggerHandler || !(decorationElement instanceof HTMLElement) || items.length === 0) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
return /*#__PURE__*/React.createElement(TypeAheadPopup, {
|
|
92
|
+
editorView: editorView,
|
|
93
|
+
popupsMountPoint: (_popupMountRef$curren = popupMountRef.current) === null || _popupMountRef$curren === void 0 ? void 0 : _popupMountRef$curren.popupsMountPoint,
|
|
94
|
+
popupsBoundariesElement: (_popupMountRef$curren2 = popupMountRef.current) === null || _popupMountRef$curren2 === void 0 ? void 0 : _popupMountRef$curren2.popupsBoundariesElement,
|
|
95
|
+
popupsScrollableElement: (_popupMountRef$curren3 = popupMountRef.current) === null || _popupMountRef$curren3 === void 0 ? void 0 : _popupMountRef$curren3.popupsScrollableElement,
|
|
96
|
+
anchorElement: decorationElement,
|
|
97
|
+
triggerHandler: triggerHandler,
|
|
98
|
+
fireAnalyticsCallback: fireAnalyticsCallback,
|
|
99
|
+
items: items,
|
|
100
|
+
selectedIndex: selectedIndex,
|
|
101
|
+
setSelectedItem: setSelectedItem,
|
|
102
|
+
onItemInsert: insertItem,
|
|
103
|
+
decorationSet: decorationSet,
|
|
104
|
+
isEmptyQuery: !query,
|
|
105
|
+
cancel: cancel
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
const createOpenAtTransaction = editorAnalyticsAPI => props => tr => {
|
|
109
|
+
const {
|
|
110
|
+
triggerHandler,
|
|
111
|
+
inputMethod
|
|
112
|
+
} = props;
|
|
113
|
+
openTypeAheadAtCursor({
|
|
114
|
+
triggerHandler,
|
|
115
|
+
inputMethod
|
|
116
|
+
})({
|
|
117
|
+
tr
|
|
118
|
+
});
|
|
119
|
+
editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 ? void 0 : editorAnalyticsAPI.attachAnalyticsEvent({
|
|
120
|
+
action: ACTION.INVOKED,
|
|
121
|
+
actionSubject: ACTION_SUBJECT.TYPEAHEAD,
|
|
122
|
+
actionSubjectId: triggerHandler.id,
|
|
123
|
+
attributes: {
|
|
124
|
+
inputMethod
|
|
125
|
+
},
|
|
126
|
+
eventType: EVENT_TYPE.UI
|
|
127
|
+
})(tr);
|
|
128
|
+
return true;
|
|
129
|
+
};
|
|
130
|
+
const createOpenTypeAhead = (editorViewRef, editorAnalyticsAPI) => props => {
|
|
131
|
+
if (!editorViewRef.current) {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
const {
|
|
135
|
+
current: view
|
|
136
|
+
} = editorViewRef;
|
|
137
|
+
const {
|
|
138
|
+
tr
|
|
139
|
+
} = view.state;
|
|
140
|
+
createOpenAtTransaction(editorAnalyticsAPI)(props)(tr);
|
|
141
|
+
view.dispatch(tr);
|
|
142
|
+
return true;
|
|
143
|
+
};
|
|
144
|
+
const createInsertTypeAheadItem = editorViewRef => props => {
|
|
145
|
+
if (!editorViewRef.current) {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
const {
|
|
149
|
+
current: view
|
|
150
|
+
} = editorViewRef;
|
|
151
|
+
const {
|
|
152
|
+
triggerHandler,
|
|
153
|
+
contentItem,
|
|
154
|
+
query,
|
|
155
|
+
sourceListItem,
|
|
156
|
+
mode
|
|
157
|
+
} = props;
|
|
158
|
+
insertTypeAheadItem(view)({
|
|
159
|
+
handler: triggerHandler,
|
|
160
|
+
item: contentItem,
|
|
161
|
+
mode: mode || SelectItemMode.SELECTED,
|
|
162
|
+
query,
|
|
163
|
+
sourceListItem
|
|
164
|
+
});
|
|
165
|
+
return true;
|
|
166
|
+
};
|
|
167
|
+
const createFindHandlerByTrigger = editorViewRef => trigger => {
|
|
168
|
+
if (!editorViewRef.current) {
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
const {
|
|
172
|
+
current: view
|
|
173
|
+
} = editorViewRef;
|
|
174
|
+
return findHandler(trigger, view.state);
|
|
175
|
+
};
|
|
176
|
+
const createCloseTypeAhead = editorViewRef => options => {
|
|
177
|
+
if (!editorViewRef.current) {
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
const {
|
|
181
|
+
current: view
|
|
182
|
+
} = editorViewRef;
|
|
183
|
+
const currentQuery = getTypeAheadQuery(view.state) || '';
|
|
184
|
+
const {
|
|
185
|
+
state
|
|
186
|
+
} = view;
|
|
187
|
+
let tr = state.tr;
|
|
188
|
+
if (options.attachCommand) {
|
|
189
|
+
const fakeDispatch = customTr => {
|
|
190
|
+
tr = customTr;
|
|
191
|
+
};
|
|
192
|
+
options.attachCommand(state, fakeDispatch);
|
|
193
|
+
}
|
|
194
|
+
closeTypeAhead(tr);
|
|
195
|
+
if (options.insertCurrentQueryAsRawText && currentQuery && currentQuery.length > 0) {
|
|
196
|
+
const handler = getTypeAheadHandler(state);
|
|
197
|
+
if (!handler) {
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
const text = handler.trigger.concat(currentQuery);
|
|
201
|
+
tr.replaceSelectionWith(state.schema.text(text));
|
|
202
|
+
}
|
|
203
|
+
view.dispatch(tr);
|
|
204
|
+
if (!view.hasFocus()) {
|
|
205
|
+
view.focus();
|
|
206
|
+
}
|
|
207
|
+
return true;
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
*
|
|
212
|
+
* Revamped typeahead using decorations instead of the `typeAheadQuery` mark
|
|
213
|
+
*
|
|
214
|
+
* https://product-fabric.atlassian.net/wiki/spaces/E/pages/2992177582/Technical+TypeAhead+Data+Flow
|
|
215
|
+
*
|
|
216
|
+
*
|
|
217
|
+
*/
|
|
218
|
+
export const typeAheadPlugin = ({
|
|
219
|
+
config: options,
|
|
220
|
+
api
|
|
221
|
+
}) => {
|
|
222
|
+
var _api$analytics, _api$analytics2;
|
|
223
|
+
const fireAnalyticsCallback = fireAnalyticsEvent(options === null || options === void 0 ? void 0 : options.createAnalyticsEvent);
|
|
224
|
+
const popupMountRef = {
|
|
225
|
+
current: null
|
|
226
|
+
};
|
|
227
|
+
const editorViewRef = {
|
|
228
|
+
current: null
|
|
229
|
+
};
|
|
230
|
+
return {
|
|
231
|
+
name: 'typeAhead',
|
|
232
|
+
marks() {
|
|
233
|
+
// We need to keep this to make sure
|
|
234
|
+
// All documents with typeahead marks will be loaded normally
|
|
235
|
+
return [{
|
|
236
|
+
name: 'typeAheadQuery',
|
|
237
|
+
mark: typeAheadQuery
|
|
238
|
+
}];
|
|
239
|
+
},
|
|
240
|
+
pmPlugins(typeAhead = []) {
|
|
241
|
+
return [{
|
|
242
|
+
name: 'typeAhead',
|
|
243
|
+
plugin: ({
|
|
244
|
+
dispatch,
|
|
245
|
+
getIntl
|
|
246
|
+
}) => createPlugin({
|
|
247
|
+
getIntl,
|
|
248
|
+
popupMountRef,
|
|
249
|
+
reactDispatch: dispatch,
|
|
250
|
+
typeAheadHandlers: typeAhead,
|
|
251
|
+
createAnalyticsEvent: options === null || options === void 0 ? void 0 : options.createAnalyticsEvent
|
|
252
|
+
})
|
|
253
|
+
}, {
|
|
254
|
+
name: 'typeAheadEditorViewRef',
|
|
255
|
+
plugin: () => {
|
|
256
|
+
return new SafePlugin({
|
|
257
|
+
view(view) {
|
|
258
|
+
editorViewRef.current = view;
|
|
259
|
+
return {
|
|
260
|
+
destroy() {
|
|
261
|
+
editorViewRef.current = null;
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
}, {
|
|
268
|
+
name: 'typeAheadInsertItem',
|
|
269
|
+
plugin: createInsertItemPlugin
|
|
270
|
+
}, {
|
|
271
|
+
name: 'typeAheadInputRule',
|
|
272
|
+
plugin: ({
|
|
273
|
+
schema,
|
|
274
|
+
featureFlags
|
|
275
|
+
}) => inputRulePlugin(schema, typeAhead, featureFlags)
|
|
276
|
+
}];
|
|
277
|
+
},
|
|
278
|
+
getSharedState(editorState) {
|
|
279
|
+
if (!editorState) {
|
|
280
|
+
return {
|
|
281
|
+
query: '',
|
|
282
|
+
isOpen: false,
|
|
283
|
+
isAllowed: false,
|
|
284
|
+
currentHandler: undefined
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
const isOpen = isTypeAheadOpen(editorState);
|
|
288
|
+
return {
|
|
289
|
+
query: getTypeAheadQuery(editorState) || '',
|
|
290
|
+
currentHandler: getTypeAheadHandler(editorState),
|
|
291
|
+
isOpen,
|
|
292
|
+
isAllowed: !isOpen
|
|
293
|
+
};
|
|
294
|
+
},
|
|
295
|
+
actions: {
|
|
296
|
+
isOpen: isTypeAheadOpen,
|
|
297
|
+
isAllowed: isTypeAheadAllowed,
|
|
298
|
+
open: createOpenTypeAhead(editorViewRef, api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions),
|
|
299
|
+
openAtTransaction: createOpenAtTransaction(api === null || api === void 0 ? void 0 : (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : _api$analytics2.actions),
|
|
300
|
+
findHandlerByTrigger: createFindHandlerByTrigger(editorViewRef),
|
|
301
|
+
insert: createInsertTypeAheadItem(editorViewRef),
|
|
302
|
+
close: createCloseTypeAhead(editorViewRef)
|
|
303
|
+
},
|
|
304
|
+
contentComponent({
|
|
305
|
+
editorView,
|
|
306
|
+
containerElement,
|
|
307
|
+
popupsMountPoint,
|
|
308
|
+
popupsBoundariesElement,
|
|
309
|
+
popupsScrollableElement,
|
|
310
|
+
wrapperElement
|
|
311
|
+
}) {
|
|
312
|
+
popupMountRef.current = {
|
|
313
|
+
popupsMountPoint: popupsMountPoint || wrapperElement || undefined,
|
|
314
|
+
popupsBoundariesElement,
|
|
315
|
+
popupsScrollableElement: popupsScrollableElement || containerElement || undefined
|
|
316
|
+
};
|
|
317
|
+
return /*#__PURE__*/React.createElement(WithPluginState, {
|
|
318
|
+
plugins: {
|
|
319
|
+
typeAheadState: typeAheadPluginKey
|
|
320
|
+
},
|
|
321
|
+
render: ({
|
|
322
|
+
typeAheadState
|
|
323
|
+
}) => {
|
|
324
|
+
if (!typeAheadState) {
|
|
325
|
+
return null;
|
|
326
|
+
}
|
|
327
|
+
return /*#__PURE__*/React.createElement(TypeAheadMenu, {
|
|
328
|
+
editorView: editorView,
|
|
329
|
+
popupMountRef: popupMountRef,
|
|
330
|
+
typeAheadState: typeAheadState,
|
|
331
|
+
fireAnalyticsCallback: fireAnalyticsCallback
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
},
|
|
336
|
+
onEditorViewStateUpdated({
|
|
337
|
+
originalTransaction,
|
|
338
|
+
oldEditorState,
|
|
339
|
+
newEditorState
|
|
340
|
+
}) {
|
|
341
|
+
const oldPluginState = getPluginState(oldEditorState);
|
|
342
|
+
const newPluginState = getPluginState(newEditorState);
|
|
343
|
+
if (!oldPluginState || !newPluginState) {
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
const {
|
|
347
|
+
triggerHandler: oldTriggerHandler
|
|
348
|
+
} = oldPluginState;
|
|
349
|
+
const {
|
|
350
|
+
triggerHandler: newTriggerHandler
|
|
351
|
+
} = newPluginState;
|
|
352
|
+
const isANewHandler = oldTriggerHandler !== newTriggerHandler;
|
|
353
|
+
if (oldTriggerHandler !== null && oldTriggerHandler !== void 0 && oldTriggerHandler.dismiss && isANewHandler) {
|
|
354
|
+
const typeAheadMessage = originalTransaction.getMeta(typeAheadPluginKey);
|
|
355
|
+
const wasItemInserted = typeAheadMessage && typeAheadMessage.action === 'INSERT_RAW_QUERY';
|
|
356
|
+
oldTriggerHandler.dismiss({
|
|
357
|
+
editorState: newEditorState,
|
|
358
|
+
query: oldPluginState.query,
|
|
359
|
+
stats: (oldPluginState.stats || new StatsModifier()).serialize(),
|
|
360
|
+
wasItemInserted
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
if (newTriggerHandler !== null && newTriggerHandler !== void 0 && newTriggerHandler.onOpen && isANewHandler) {
|
|
364
|
+
newTriggerHandler.onOpen(newEditorState);
|
|
365
|
+
}
|
|
366
|
+
if (newTriggerHandler && isANewHandler && options !== null && options !== void 0 && options.createAnalyticsEvent) {
|
|
367
|
+
fireAnalyticsCallback({
|
|
368
|
+
payload: {
|
|
369
|
+
action: ACTION.INVOKED,
|
|
370
|
+
actionSubject: ACTION_SUBJECT.TYPEAHEAD,
|
|
371
|
+
actionSubjectId: newTriggerHandler.id || 'not_set',
|
|
372
|
+
attributes: {
|
|
373
|
+
inputMethod: newPluginState.inputMethod || INPUT_METHOD.KEYBOARD
|
|
374
|
+
},
|
|
375
|
+
eventType: EVENT_TYPE.UI
|
|
376
|
+
}
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { areSameItems } from '@atlaskit/editor-common/floating-toolbar';
|
|
2
|
-
import { isTypeAheadOpen } from '../../type-ahead/utils';
|
|
3
2
|
import { trackerStore } from '..';
|
|
4
3
|
const areToolbarsSame = (left, right) => {
|
|
5
4
|
if (!left && !right) {
|
|
@@ -25,14 +24,13 @@ export const subscribeToToolbarAndPickerUpdates = (editorView, cb) => {
|
|
|
25
24
|
const subscription = ({
|
|
26
25
|
newEditorState
|
|
27
26
|
}) => {
|
|
28
|
-
// TypeAhead has priority in the mobile-bridge
|
|
29
|
-
// In case it is open we don't need to send
|
|
30
|
-
// any toolbar updates don't need to be send
|
|
31
|
-
if (isTypeAheadOpen(newEditorState)) {
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
27
|
// Creating fake plugin keys for these plugins for the mean time until all these plugins are extracted.
|
|
28
|
+
const typeAheadPluginKey = {
|
|
29
|
+
key: 'typeAheadPlugin$',
|
|
30
|
+
getState: state => {
|
|
31
|
+
return state['typeAheadPlugin$'];
|
|
32
|
+
}
|
|
33
|
+
};
|
|
36
34
|
const datePluginKey = {
|
|
37
35
|
key: 'datePlugin$',
|
|
38
36
|
getState: state => {
|
|
@@ -51,6 +49,17 @@ export const subscribeToToolbarAndPickerUpdates = (editorView, cb) => {
|
|
|
51
49
|
return state['floatingToolbarPluginKey$'];
|
|
52
50
|
}
|
|
53
51
|
};
|
|
52
|
+
const isTypeAheadOpen = editorState => {
|
|
53
|
+
var _typeAheadState$decor;
|
|
54
|
+
const typeAheadState = typeAheadPluginKey.getState(newEditorState);
|
|
55
|
+
return !!((_typeAheadState$decor = typeAheadState.decorationSet) !== null && _typeAheadState$decor !== void 0 && _typeAheadState$decor.find().length);
|
|
56
|
+
};
|
|
57
|
+
// TypeAhead has priority in the mobile-bridge
|
|
58
|
+
// In case it is open we don't need to send
|
|
59
|
+
// any toolbar updates don't need to be send
|
|
60
|
+
if (isTypeAheadOpen(newEditorState)) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
54
63
|
const dateState = datePluginKey.getState(newEditorState);
|
|
55
64
|
const statusState = statusPluginKey.getState(newEditorState);
|
|
56
65
|
const {
|
|
@@ -2,9 +2,8 @@ import { NodeSelection, Selection } from '@atlaskit/editor-prosemirror/state';
|
|
|
2
2
|
import { Fragment } from '@atlaskit/editor-prosemirror/model';
|
|
3
3
|
import { todayTimestampInUTC } from '@atlaskit/editor-common/utils';
|
|
4
4
|
import { pluginKey } from './pm-plugins/plugin-key';
|
|
5
|
-
import { ACTION, ACTION_SUBJECT,
|
|
5
|
+
import { ACTION, ACTION_SUBJECT, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
6
6
|
import { isToday } from './utils/internal';
|
|
7
|
-
import { canInsert } from '@atlaskit/editor-prosemirror/utils';
|
|
8
7
|
export var createDate = function createDate(isQuickInsertAction) {
|
|
9
8
|
return function (insert, state) {
|
|
10
9
|
var dateNode = state.schema.nodes.date.createChecked({
|
|
@@ -25,25 +24,6 @@ export var createDate = function createDate(isQuickInsertAction) {
|
|
|
25
24
|
};
|
|
26
25
|
};
|
|
27
26
|
|
|
28
|
-
/** Delete the date and close the datepicker */
|
|
29
|
-
export var deleteDate = function deleteDate() {
|
|
30
|
-
return function (state, dispatch) {
|
|
31
|
-
var pluginState = pluginKey.getState(state);
|
|
32
|
-
if (!pluginState || pluginState.showDatePickerAt === null) {
|
|
33
|
-
return false;
|
|
34
|
-
}
|
|
35
|
-
var showDatePickerAt = pluginState.showDatePickerAt;
|
|
36
|
-
var tr = state.tr.delete(showDatePickerAt, showDatePickerAt + 1).setMeta(pluginKey, {
|
|
37
|
-
showDatePickerAt: null,
|
|
38
|
-
isNew: false
|
|
39
|
-
});
|
|
40
|
-
if (dispatch) {
|
|
41
|
-
dispatch(tr);
|
|
42
|
-
}
|
|
43
|
-
return true;
|
|
44
|
-
};
|
|
45
|
-
};
|
|
46
|
-
|
|
47
27
|
/** Focus input */
|
|
48
28
|
export var focusDateInput = function focusDateInput() {
|
|
49
29
|
return function (state, dispatch) {
|
|
@@ -61,92 +41,6 @@ export var focusDateInput = function focusDateInput() {
|
|
|
61
41
|
return true;
|
|
62
42
|
};
|
|
63
43
|
};
|
|
64
|
-
export var insertDate = function insertDate(date, inputMethod, commitMethod) {
|
|
65
|
-
var enterPressed = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
|
|
66
|
-
var pluginInjectionApi = arguments.length > 4 ? arguments[4] : undefined;
|
|
67
|
-
return function (state, dispatch) {
|
|
68
|
-
var schema = state.schema;
|
|
69
|
-
var timestamp;
|
|
70
|
-
if (date) {
|
|
71
|
-
timestamp = Date.UTC(date.year, date.month - 1, date.day).toString();
|
|
72
|
-
} else {
|
|
73
|
-
timestamp = todayTimestampInUTC();
|
|
74
|
-
}
|
|
75
|
-
var tr = state.tr;
|
|
76
|
-
if (inputMethod) {
|
|
77
|
-
var _pluginInjectionApi$a;
|
|
78
|
-
pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a === void 0 || (_pluginInjectionApi$a = _pluginInjectionApi$a.actions) === null || _pluginInjectionApi$a === void 0 || _pluginInjectionApi$a.attachAnalyticsEvent({
|
|
79
|
-
action: ACTION.INSERTED,
|
|
80
|
-
actionSubject: ACTION_SUBJECT.DOCUMENT,
|
|
81
|
-
actionSubjectId: ACTION_SUBJECT_ID.DATE,
|
|
82
|
-
eventType: EVENT_TYPE.TRACK,
|
|
83
|
-
attributes: {
|
|
84
|
-
inputMethod: inputMethod
|
|
85
|
-
}
|
|
86
|
-
})(tr);
|
|
87
|
-
}
|
|
88
|
-
if (commitMethod) {
|
|
89
|
-
var _pluginInjectionApi$a2;
|
|
90
|
-
pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a2 = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a2 === void 0 || (_pluginInjectionApi$a2 = _pluginInjectionApi$a2.actions) === null || _pluginInjectionApi$a2 === void 0 || _pluginInjectionApi$a2.attachAnalyticsEvent({
|
|
91
|
-
eventType: EVENT_TYPE.TRACK,
|
|
92
|
-
action: ACTION.COMMITTED,
|
|
93
|
-
actionSubject: ACTION_SUBJECT.DATE,
|
|
94
|
-
attributes: {
|
|
95
|
-
commitMethod: commitMethod,
|
|
96
|
-
isValid: date !== undefined,
|
|
97
|
-
isToday: isToday(date)
|
|
98
|
-
}
|
|
99
|
-
})(tr);
|
|
100
|
-
}
|
|
101
|
-
var _ref = pluginKey.getState(state) || {},
|
|
102
|
-
showDatePickerAt = _ref.showDatePickerAt;
|
|
103
|
-
if (!showDatePickerAt) {
|
|
104
|
-
var dateNode = schema.nodes.date.createChecked({
|
|
105
|
-
timestamp: timestamp
|
|
106
|
-
});
|
|
107
|
-
var textNode = state.schema.text(' ');
|
|
108
|
-
var fragment = Fragment.fromArray([dateNode, textNode]);
|
|
109
|
-
var _state$selection = state.selection,
|
|
110
|
-
from = _state$selection.from,
|
|
111
|
-
to = _state$selection.to;
|
|
112
|
-
var insertable = canInsert(tr.selection.$from, fragment);
|
|
113
|
-
if (!insertable) {
|
|
114
|
-
var parentSelection = NodeSelection.create(tr.doc, tr.selection.from - tr.selection.$anchor.parentOffset - 1);
|
|
115
|
-
tr.insert(parentSelection.to, fragment).setSelection(NodeSelection.create(tr.doc, parentSelection.to + 1));
|
|
116
|
-
} else {
|
|
117
|
-
tr.replaceWith(from, to, fragment).setSelection(NodeSelection.create(tr.doc, from));
|
|
118
|
-
}
|
|
119
|
-
if (dispatch) {
|
|
120
|
-
dispatch(tr.scrollIntoView().setMeta(pluginKey, {
|
|
121
|
-
isNew: true
|
|
122
|
-
}));
|
|
123
|
-
}
|
|
124
|
-
return true;
|
|
125
|
-
}
|
|
126
|
-
if (state.doc.nodeAt(showDatePickerAt)) {
|
|
127
|
-
if (enterPressed) {
|
|
128
|
-
// Setting selection to outside the date node causes showDatePickerAt
|
|
129
|
-
// to be set to null by the PM plugin (onSelectionChanged), which will
|
|
130
|
-
// immediately close the datepicker once a valid date is typed in.
|
|
131
|
-
// Adding this check forces it to stay open until the user presses Enter.
|
|
132
|
-
tr = tr.setSelection(Selection.near(tr.doc.resolve(showDatePickerAt + 2)));
|
|
133
|
-
}
|
|
134
|
-
tr = tr.setNodeMarkup(showDatePickerAt, schema.nodes.date, {
|
|
135
|
-
timestamp: timestamp
|
|
136
|
-
}).setMeta(pluginKey, {
|
|
137
|
-
isNew: false
|
|
138
|
-
}).scrollIntoView();
|
|
139
|
-
if (!enterPressed) {
|
|
140
|
-
tr = tr.setSelection(NodeSelection.create(tr.doc, showDatePickerAt));
|
|
141
|
-
}
|
|
142
|
-
if (dispatch) {
|
|
143
|
-
dispatch(tr);
|
|
144
|
-
}
|
|
145
|
-
return true;
|
|
146
|
-
}
|
|
147
|
-
return false;
|
|
148
|
-
};
|
|
149
|
-
};
|
|
150
44
|
export var setDatePickerAt = function setDatePickerAt(showDatePickerAt) {
|
|
151
45
|
return function (state, dispatch) {
|
|
152
46
|
dispatch(state.tr.setMeta(pluginKey, {
|
|
@@ -157,8 +51,8 @@ export var setDatePickerAt = function setDatePickerAt(showDatePickerAt) {
|
|
|
157
51
|
};
|
|
158
52
|
export var closeDatePicker = function closeDatePicker() {
|
|
159
53
|
return function (state, dispatch) {
|
|
160
|
-
var
|
|
161
|
-
showDatePickerAt =
|
|
54
|
+
var _ref = pluginKey.getState(state) || {},
|
|
55
|
+
showDatePickerAt = _ref.showDatePickerAt;
|
|
162
56
|
if (!dispatch) {
|
|
163
57
|
return false;
|
|
164
58
|
}
|
|
@@ -172,11 +66,11 @@ export var closeDatePicker = function closeDatePicker() {
|
|
|
172
66
|
return false;
|
|
173
67
|
};
|
|
174
68
|
};
|
|
175
|
-
export var closeDatePickerWithAnalytics = function closeDatePickerWithAnalytics(
|
|
176
|
-
var _pluginInjectionApi$
|
|
177
|
-
var date =
|
|
178
|
-
pluginInjectionApi =
|
|
179
|
-
pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$
|
|
69
|
+
export var closeDatePickerWithAnalytics = function closeDatePickerWithAnalytics(_ref2) {
|
|
70
|
+
var _pluginInjectionApi$a;
|
|
71
|
+
var date = _ref2.date,
|
|
72
|
+
pluginInjectionApi = _ref2.pluginInjectionApi;
|
|
73
|
+
pluginInjectionApi === null || pluginInjectionApi === void 0 || (_pluginInjectionApi$a = pluginInjectionApi.analytics) === null || _pluginInjectionApi$a === void 0 || (_pluginInjectionApi$a = _pluginInjectionApi$a.actions) === null || _pluginInjectionApi$a === void 0 || _pluginInjectionApi$a.attachAnalyticsEvent({
|
|
180
74
|
eventType: EVENT_TYPE.TRACK,
|
|
181
75
|
action: ACTION.COMMITTED,
|
|
182
76
|
actionSubject: ACTION_SUBJECT.DATE,
|