@atlaskit/editor-plugin-autocomplete 2.4.0 → 2.5.1
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 +39 -0
- package/afm-cc/tsconfig.json +3 -0
- package/afm-products/tsconfig.json +3 -0
- package/dist/cjs/analytics/ufo.js +111 -0
- package/dist/cjs/pm-plugins/autocomplete-plugin.js +126 -64
- package/dist/cjs/pm-plugins/local-slow-lane-client.js +452 -0
- package/dist/cjs/pm-plugins/slow-lane-client.js +45 -16
- package/dist/cjs/pm-plugins/text-predictor.js +72 -40
- package/dist/es2019/analytics/ufo.js +110 -0
- package/dist/es2019/pm-plugins/autocomplete-plugin.js +132 -72
- package/dist/es2019/pm-plugins/local-slow-lane-client.js +361 -0
- package/dist/es2019/pm-plugins/slow-lane-client.js +29 -2
- package/dist/es2019/pm-plugins/text-predictor.js +48 -15
- package/dist/esm/analytics/ufo.js +105 -0
- package/dist/esm/pm-plugins/autocomplete-plugin.js +126 -64
- package/dist/esm/pm-plugins/local-slow-lane-client.js +443 -0
- package/dist/esm/pm-plugins/slow-lane-client.js +45 -16
- package/dist/esm/pm-plugins/text-predictor.js +73 -40
- package/dist/types/analytics/ufo.d.ts +38 -0
- package/dist/types/pm-plugins/autocomplete-plugin.d.ts +5 -0
- package/dist/types/pm-plugins/local-slow-lane-client.d.ts +102 -0
- package/dist/types-ts4.5/analytics/ufo.d.ts +38 -0
- package/dist/types-ts4.5/pm-plugins/autocomplete-plugin.d.ts +5 -0
- package/dist/types-ts4.5/pm-plugins/local-slow-lane-client.d.ts +102 -0
- package/package.json +7 -2
- package/src/analytics/ufo.ts +132 -0
- package/src/pm-plugins/autocomplete-plugin.ts +125 -64
- package/src/pm-plugins/local-slow-lane-client.ts +487 -0
- package/src/pm-plugins/slow-lane-client.ts +28 -2
- package/src/pm-plugins/text-predictor.ts +42 -12
- package/tsconfig.app.json +3 -0
|
@@ -2,16 +2,20 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
|
2
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
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; }
|
|
4
4
|
import { ACTION, ACTION_SUBJECT, EVENT_TYPE } from '@atlaskit/editor-common/analytics';
|
|
5
|
+
import { logException } from '@atlaskit/editor-common/monitoring';
|
|
5
6
|
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
6
7
|
import { keydownHandler } from '@atlaskit/editor-prosemirror/keymap';
|
|
7
8
|
import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
8
9
|
import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
9
10
|
import { createGhostTextDecorationSet } from './ghost-text-decoration';
|
|
11
|
+
import { createLocalSlowLaneClient } from './local-slow-lane-client';
|
|
10
12
|
import { createSlowLaneClient, setDefaultSlowLaneClient, isWordBoundary } from './slow-lane-client';
|
|
11
13
|
import { predict, loadDefaultVocabulary, loadVectorsAsync, incrementSessionFreq, ingestDocumentPage } from './text-predictor';
|
|
12
|
-
var SLOW_LANE_ENDPOINT = '/gateway/api/v1/autocomplete/typeahead-encodings';
|
|
13
14
|
export var autocompletePluginKey = new PluginKey('autocomplete');
|
|
14
15
|
var DEBOUNCE_MS = 150;
|
|
16
|
+
var hasDestroy = function hasDestroy(client) {
|
|
17
|
+
return 'destroy' in client && typeof client.destroy === 'function';
|
|
18
|
+
};
|
|
15
19
|
var createInitialState = function createInitialState() {
|
|
16
20
|
return {
|
|
17
21
|
ghostText: '',
|
|
@@ -64,15 +68,21 @@ var setAutocompleteMeta = function setAutocompleteMeta(tr, meta) {
|
|
|
64
68
|
*/
|
|
65
69
|
var lastShownGhostText = '';
|
|
66
70
|
var showGhostText = function showGhostText(view, text, position) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
71
|
+
try {
|
|
72
|
+
var state = view.state,
|
|
73
|
+
dispatch = view.dispatch;
|
|
74
|
+
var decorationSet = createGhostTextDecorationSet(state, position, text);
|
|
75
|
+
var tr = setAutocompleteMeta(state.tr, {
|
|
76
|
+
ghostText: text,
|
|
77
|
+
ghostPosition: position,
|
|
78
|
+
decorationSet: decorationSet
|
|
79
|
+
});
|
|
80
|
+
dispatch(tr);
|
|
81
|
+
} catch (error) {
|
|
82
|
+
logException(error, {
|
|
83
|
+
location: 'editor-plugin-autocomplete/showGhostText'
|
|
84
|
+
});
|
|
85
|
+
}
|
|
76
86
|
};
|
|
77
87
|
|
|
78
88
|
/**
|
|
@@ -84,12 +94,19 @@ var clearGhostText = function clearGhostText(state, dispatch) {
|
|
|
84
94
|
return false;
|
|
85
95
|
}
|
|
86
96
|
if (dispatch) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
97
|
+
try {
|
|
98
|
+
var tr = setAutocompleteMeta(state.tr, {
|
|
99
|
+
ghostText: '',
|
|
100
|
+
ghostPosition: -1,
|
|
101
|
+
decorationSet: DecorationSet.empty
|
|
102
|
+
});
|
|
103
|
+
dispatch(tr);
|
|
104
|
+
} catch (error) {
|
|
105
|
+
logException(error, {
|
|
106
|
+
location: 'editor-plugin-autocomplete/clearGhostText'
|
|
107
|
+
});
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
93
110
|
}
|
|
94
111
|
return true;
|
|
95
112
|
};
|
|
@@ -103,15 +120,22 @@ var acceptGhostText = function acceptGhostText(state, dispatch) {
|
|
|
103
120
|
return false;
|
|
104
121
|
}
|
|
105
122
|
if (dispatch) {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
123
|
+
try {
|
|
124
|
+
var ghostText = pluginState.ghostText,
|
|
125
|
+
ghostPosition = pluginState.ghostPosition;
|
|
126
|
+
var tr = state.tr.insertText(ghostText, ghostPosition);
|
|
127
|
+
tr = setAutocompleteMeta(tr, {
|
|
128
|
+
ghostText: '',
|
|
129
|
+
ghostPosition: -1,
|
|
130
|
+
decorationSet: DecorationSet.empty
|
|
131
|
+
});
|
|
132
|
+
dispatch(tr);
|
|
133
|
+
} catch (error) {
|
|
134
|
+
logException(error, {
|
|
135
|
+
location: 'editor-plugin-autocomplete/acceptGhostText'
|
|
136
|
+
});
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
115
139
|
}
|
|
116
140
|
return true;
|
|
117
141
|
};
|
|
@@ -170,12 +194,23 @@ export var createAutocompletePlugin = function createAutocompletePlugin(options,
|
|
|
170
194
|
var dismissedContext = null;
|
|
171
195
|
var lastSuggestionTypedLength = 0;
|
|
172
196
|
var lastSuggestionLength = 0;
|
|
173
|
-
var
|
|
197
|
+
var fireSuggestionDismissedAnalytics = function fireSuggestionDismissedAnalytics(reason) {
|
|
174
198
|
var _api$analytics;
|
|
199
|
+
api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || _api$analytics.actions.fireAnalyticsEvent({
|
|
200
|
+
action: ACTION.SUGGESTION_DISMISSED,
|
|
201
|
+
actionSubject: ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
|
|
202
|
+
eventType: EVENT_TYPE.TRACK,
|
|
203
|
+
attributes: {
|
|
204
|
+
reason: reason
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
};
|
|
208
|
+
var fireSuggestionInsertedAnalytics = function fireSuggestionInsertedAnalytics(ghostText) {
|
|
209
|
+
var _api$analytics2;
|
|
175
210
|
var typedLength = lastSuggestionTypedLength;
|
|
176
211
|
var suggestionLength = lastSuggestionLength || typedLength + ghostText.length;
|
|
177
212
|
var kssDelta = suggestionLength - typedLength;
|
|
178
|
-
api === null || api === void 0 || (_api$
|
|
213
|
+
api === null || api === void 0 || (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 || _api$analytics2.actions.fireAnalyticsEvent({
|
|
179
214
|
action: ACTION.SUGGESTION_INSERTED,
|
|
180
215
|
actionSubject: ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
|
|
181
216
|
eventType: EVENT_TYPE.TRACK,
|
|
@@ -186,9 +221,11 @@ export var createAutocompletePlugin = function createAutocompletePlugin(options,
|
|
|
186
221
|
}
|
|
187
222
|
});
|
|
188
223
|
};
|
|
189
|
-
var slowLaneClient =
|
|
224
|
+
var slowLaneClient = options !== null && options !== void 0 && options.useLocalModel ? createLocalSlowLaneClient({
|
|
225
|
+
debounceMs: 300
|
|
226
|
+
}) : createSlowLaneClient({
|
|
190
227
|
baseUrl: '',
|
|
191
|
-
|
|
228
|
+
debounceMs: 300
|
|
192
229
|
});
|
|
193
230
|
setDefaultSlowLaneClient(slowLaneClient);
|
|
194
231
|
|
|
@@ -202,43 +239,49 @@ export var createAutocompletePlugin = function createAutocompletePlugin(options,
|
|
|
202
239
|
clearTimeout(debounceTimer);
|
|
203
240
|
}
|
|
204
241
|
debounceTimer = setTimeout(function () {
|
|
205
|
-
|
|
206
|
-
|
|
242
|
+
try {
|
|
243
|
+
var state = view.state;
|
|
244
|
+
var selection = state.selection;
|
|
207
245
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
246
|
+
// Only predict for cursor selections (not range selections)
|
|
247
|
+
if (!selection.empty) {
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
var textBefore = getTextBeforeCursor(state);
|
|
213
251
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
252
|
+
// Suppress re-showing the same suggestion the user just dismissed.
|
|
253
|
+
// Once the text context changes (user types or deletes), this clears automatically.
|
|
254
|
+
if (textBefore === dismissedContext) {
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
dismissedContext = null;
|
|
220
258
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
259
|
+
// Don't predict if there's not enough context
|
|
260
|
+
if (textBefore.trim().length < 3) {
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
225
263
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
264
|
+
// Tier 1 prediction is synchronous -- no async needed
|
|
265
|
+
var prediction = predict(textBefore);
|
|
266
|
+
if (prediction && prediction.length > 0) {
|
|
267
|
+
var typedLength = getTypedLengthForPrediction(textBefore);
|
|
268
|
+
lastSuggestionTypedLength = typedLength;
|
|
269
|
+
lastSuggestionLength = typedLength + prediction.length;
|
|
270
|
+
showGhostText(view, prediction, selection.from);
|
|
271
|
+
if (prediction !== lastShownGhostText) {
|
|
272
|
+
var _api$analytics3;
|
|
273
|
+
lastShownGhostText = prediction;
|
|
274
|
+
api === null || api === void 0 || (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 || _api$analytics3.actions.fireAnalyticsEvent({
|
|
275
|
+
action: ACTION.SUGGESTION_VIEWED,
|
|
276
|
+
actionSubject: ACTION_SUBJECT.CONTEXTUAL_TYPEAHEAD,
|
|
277
|
+
eventType: EVENT_TYPE.TRACK
|
|
278
|
+
});
|
|
279
|
+
}
|
|
241
280
|
}
|
|
281
|
+
} catch (error) {
|
|
282
|
+
logException(error, {
|
|
283
|
+
location: 'editor-plugin-autocomplete/schedulePrediction'
|
|
284
|
+
});
|
|
242
285
|
}
|
|
243
286
|
}, DEBOUNCE_MS);
|
|
244
287
|
};
|
|
@@ -336,6 +379,7 @@ export var createAutocompletePlugin = function createAutocompletePlugin(options,
|
|
|
336
379
|
var didClear = clearGhostText(state, dispatch);
|
|
337
380
|
if (didClear) {
|
|
338
381
|
dismissedContext = getTextBeforeCursor(state);
|
|
382
|
+
fireSuggestionDismissedAnalytics('escape');
|
|
339
383
|
}
|
|
340
384
|
return didClear;
|
|
341
385
|
}
|
|
@@ -345,14 +389,25 @@ export var createAutocompletePlugin = function createAutocompletePlugin(options,
|
|
|
345
389
|
var pluginState = autocompletePluginKey.getState(view.state);
|
|
346
390
|
if (pluginState !== null && pluginState !== void 0 && pluginState.ghostText) {
|
|
347
391
|
clearGhostText(view.state, view.dispatch);
|
|
392
|
+
fireSuggestionDismissedAnalytics('blur');
|
|
348
393
|
}
|
|
349
394
|
return false;
|
|
350
395
|
},
|
|
351
396
|
focus: function focus() {
|
|
352
|
-
|
|
397
|
+
try {
|
|
398
|
+
loadDefaultVocabulary();
|
|
399
|
+
} catch (error) {
|
|
400
|
+
logException(error, {
|
|
401
|
+
location: 'editor-plugin-autocomplete/loadDefaultVocabulary'
|
|
402
|
+
});
|
|
403
|
+
}
|
|
353
404
|
loadVectorsAsync({
|
|
354
405
|
getBinaryUrl: options === null || options === void 0 ? void 0 : options.getVectorsBinaryUrl
|
|
355
|
-
}).catch(function () {
|
|
406
|
+
}).catch(function (error) {
|
|
407
|
+
logException(error, {
|
|
408
|
+
location: 'editor-plugin-autocomplete/loadVectorsAsync'
|
|
409
|
+
});
|
|
410
|
+
});
|
|
356
411
|
if (!hasIngestedPage) {
|
|
357
412
|
hasIngestedPage = true;
|
|
358
413
|
if (options !== null && options !== void 0 && options.getContext) {
|
|
@@ -369,7 +424,11 @@ export var createAutocompletePlugin = function createAutocompletePlugin(options,
|
|
|
369
424
|
ingestDocumentPage(context.parentCommentContent);
|
|
370
425
|
}
|
|
371
426
|
(_context$siblingComme4 = context.siblingCommentsContents) === null || _context$siblingComme4 === void 0 || _context$siblingComme4.forEach(ingestDocumentPage);
|
|
372
|
-
}).catch(function () {
|
|
427
|
+
}).catch(function (error) {
|
|
428
|
+
logException(error, {
|
|
429
|
+
location: 'editor-plugin-autocomplete/getContext'
|
|
430
|
+
});
|
|
431
|
+
});
|
|
373
432
|
}
|
|
374
433
|
}
|
|
375
434
|
return false;
|
|
@@ -406,6 +465,9 @@ export var createAutocompletePlugin = function createAutocompletePlugin(options,
|
|
|
406
465
|
if (debounceTimer) {
|
|
407
466
|
clearTimeout(debounceTimer);
|
|
408
467
|
}
|
|
468
|
+
if (hasDestroy(slowLaneClient)) {
|
|
469
|
+
slowLaneClient.destroy();
|
|
470
|
+
}
|
|
409
471
|
setDefaultSlowLaneClient(null);
|
|
410
472
|
}
|
|
411
473
|
};
|