@atlaskit/editor-plugin-hyperlink 0.0.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.
Files changed (59) hide show
  1. package/.eslintrc.js +6 -0
  2. package/CHANGELOG.md +1 -0
  3. package/LICENSE.md +13 -0
  4. package/README.md +7 -0
  5. package/dist/cjs/Toolbar.js +280 -0
  6. package/dist/cjs/commands.js +242 -0
  7. package/dist/cjs/index.js +12 -0
  8. package/dist/cjs/plugin.js +122 -0
  9. package/dist/cjs/pm-plugins/fake-curor-for-toolbar-plugin-key.js +9 -0
  10. package/dist/cjs/pm-plugins/fake-cursor-for-toolbar.js +68 -0
  11. package/dist/cjs/pm-plugins/input-rule.js +95 -0
  12. package/dist/cjs/pm-plugins/keymap.js +75 -0
  13. package/dist/cjs/pm-plugins/main.js +257 -0
  14. package/dist/cjs/pm-plugins/toolbar-buttons.js +43 -0
  15. package/dist/cjs/version.json +5 -0
  16. package/dist/es2019/Toolbar.js +260 -0
  17. package/dist/es2019/commands.js +225 -0
  18. package/dist/es2019/index.js +1 -0
  19. package/dist/es2019/plugin.js +106 -0
  20. package/dist/es2019/pm-plugins/fake-curor-for-toolbar-plugin-key.js +2 -0
  21. package/dist/es2019/pm-plugins/fake-cursor-for-toolbar.js +63 -0
  22. package/dist/es2019/pm-plugins/input-rule.js +80 -0
  23. package/dist/es2019/pm-plugins/keymap.js +65 -0
  24. package/dist/es2019/pm-plugins/main.js +261 -0
  25. package/dist/es2019/pm-plugins/toolbar-buttons.js +39 -0
  26. package/dist/es2019/version.json +5 -0
  27. package/dist/esm/Toolbar.js +271 -0
  28. package/dist/esm/commands.js +222 -0
  29. package/dist/esm/index.js +1 -0
  30. package/dist/esm/plugin.js +114 -0
  31. package/dist/esm/pm-plugins/fake-curor-for-toolbar-plugin-key.js +2 -0
  32. package/dist/esm/pm-plugins/fake-cursor-for-toolbar.js +61 -0
  33. package/dist/esm/pm-plugins/input-rule.js +85 -0
  34. package/dist/esm/pm-plugins/keymap.js +67 -0
  35. package/dist/esm/pm-plugins/main.js +248 -0
  36. package/dist/esm/pm-plugins/toolbar-buttons.js +34 -0
  37. package/dist/esm/version.json +5 -0
  38. package/dist/types/Toolbar.d.ts +8 -0
  39. package/dist/types/commands.d.ts +20 -0
  40. package/dist/types/index.d.ts +3 -0
  41. package/dist/types/plugin.d.ts +38 -0
  42. package/dist/types/pm-plugins/fake-curor-for-toolbar-plugin-key.d.ts +2 -0
  43. package/dist/types/pm-plugins/fake-cursor-for-toolbar.d.ts +3 -0
  44. package/dist/types/pm-plugins/input-rule.d.ts +8 -0
  45. package/dist/types/pm-plugins/keymap.d.ts +4 -0
  46. package/dist/types/pm-plugins/main.d.ts +7 -0
  47. package/dist/types/pm-plugins/toolbar-buttons.d.ts +21 -0
  48. package/dist/types-ts4.5/Toolbar.d.ts +8 -0
  49. package/dist/types-ts4.5/commands.d.ts +20 -0
  50. package/dist/types-ts4.5/index.d.ts +3 -0
  51. package/dist/types-ts4.5/plugin.d.ts +38 -0
  52. package/dist/types-ts4.5/pm-plugins/fake-curor-for-toolbar-plugin-key.d.ts +2 -0
  53. package/dist/types-ts4.5/pm-plugins/fake-cursor-for-toolbar.d.ts +3 -0
  54. package/dist/types-ts4.5/pm-plugins/input-rule.d.ts +8 -0
  55. package/dist/types-ts4.5/pm-plugins/keymap.d.ts +4 -0
  56. package/dist/types-ts4.5/pm-plugins/main.d.ts +7 -0
  57. package/dist/types-ts4.5/pm-plugins/toolbar-buttons.d.ts +21 -0
  58. package/package.json +107 -0
  59. package/tmp/api-report-tmp.d.ts +68 -0
@@ -0,0 +1,271 @@
1
+ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
4
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
5
+ import React from 'react';
6
+ import { isSafeUrl } from '@atlaskit/adf-schema';
7
+ import { ACTION, ACTION_SUBJECT_ID, buildOpenedSettingsPayload, buildVisitedLinkPayload, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
8
+ import { commandWithMetadata } from '@atlaskit/editor-common/card';
9
+ import { useSharedPluginState } from '@atlaskit/editor-common/hooks';
10
+ import { HyperlinkAddToolbar } from '@atlaskit/editor-common/link';
11
+ import { linkMessages, linkToolbarMessages as linkToolbarCommonMessages } from '@atlaskit/editor-common/messages';
12
+ import { LINKPICKER_HEIGHT_IN_PX, RECENT_SEARCH_HEIGHT_IN_PX, RECENT_SEARCH_WIDTH_IN_PX } from '@atlaskit/editor-common/ui';
13
+ import { normalizeUrl } from '@atlaskit/editor-common/utils';
14
+ import CogIcon from '@atlaskit/icon/glyph/editor/settings';
15
+ import UnlinkIcon from '@atlaskit/icon/glyph/editor/unlink';
16
+ import OpenIcon from '@atlaskit/icon/glyph/shortcut';
17
+ import { editInsertedLink, insertLinkWithAnalytics, onClickAwayCallback, onEscapeCallback, removeLink, updateLink } from './commands';
18
+ import { stateKey } from './pm-plugins/main';
19
+ import { toolbarKey } from './pm-plugins/toolbar-buttons';
20
+ /* type guard for edit links */
21
+ function isEditLink(linkMark) {
22
+ return linkMark.pos !== undefined;
23
+ }
24
+ var dispatchAnalytics = function dispatchAnalytics(dispatch, state, analyticsBuilder, editorAnalyticsApi) {
25
+ if (dispatch) {
26
+ var tr = state.tr;
27
+ editorAnalyticsApi === null || editorAnalyticsApi === void 0 ? void 0 : editorAnalyticsApi.attachAnalyticsEvent(analyticsBuilder(ACTION_SUBJECT_ID.HYPERLINK))(tr);
28
+ dispatch(tr);
29
+ }
30
+ };
31
+ var visitHyperlink = function visitHyperlink(editorAnalyticsApi) {
32
+ return function (state, dispatch) {
33
+ dispatchAnalytics(dispatch, state, buildVisitedLinkPayload, editorAnalyticsApi);
34
+ return true;
35
+ };
36
+ };
37
+ var openLinkSettings = function openLinkSettings(editorAnalyticsApi) {
38
+ return function (state, dispatch) {
39
+ dispatchAnalytics(dispatch, state, buildOpenedSettingsPayload, editorAnalyticsApi);
40
+ return true;
41
+ };
42
+ };
43
+ function getLinkText(activeLinkMark, state) {
44
+ if (!activeLinkMark.node) {
45
+ return undefined;
46
+ }
47
+ var textToUrl = normalizeUrl(activeLinkMark.node.text);
48
+ var linkMark = activeLinkMark.node.marks.find(function (mark) {
49
+ return mark.type === state.schema.marks.link;
50
+ });
51
+ var linkHref = linkMark && linkMark.attrs.href;
52
+ if (textToUrl === linkHref) {
53
+ return undefined;
54
+ }
55
+ return activeLinkMark.node.text;
56
+ }
57
+ export function HyperlinkAddToolbarWithState(_ref) {
58
+ var _ref$linkPickerOption = _ref.linkPickerOptions,
59
+ linkPickerOptions = _ref$linkPickerOption === void 0 ? {} : _ref$linkPickerOption,
60
+ onSubmit = _ref.onSubmit,
61
+ displayText = _ref.displayText,
62
+ displayUrl = _ref.displayUrl,
63
+ providerFactory = _ref.providerFactory,
64
+ view = _ref.view,
65
+ onCancel = _ref.onCancel,
66
+ invokeMethod = _ref.invokeMethod,
67
+ featureFlags = _ref.featureFlags,
68
+ onClose = _ref.onClose,
69
+ onEscapeCallback = _ref.onEscapeCallback,
70
+ onClickAwayCallback = _ref.onClickAwayCallback,
71
+ pluginInjectionApi = _ref.pluginInjectionApi;
72
+ var _useSharedPluginState = useSharedPluginState(pluginInjectionApi, ['hyperlink']),
73
+ hyperlinkState = _useSharedPluginState.hyperlinkState;
74
+ return /*#__PURE__*/React.createElement(HyperlinkAddToolbar, {
75
+ linkPickerOptions: linkPickerOptions,
76
+ onSubmit: onSubmit,
77
+ displayText: displayText,
78
+ displayUrl: displayUrl,
79
+ providerFactory: providerFactory,
80
+ view: view,
81
+ onCancel: onCancel,
82
+ invokeMethod: invokeMethod,
83
+ featureFlags: featureFlags,
84
+ onClose: onClose,
85
+ onEscapeCallback: onEscapeCallback,
86
+ onClickAwayCallback: onClickAwayCallback,
87
+ hyperlinkPluginState: hyperlinkState
88
+ });
89
+ }
90
+ var getSettingsButtonGroup = function getSettingsButtonGroup(state, intl, featureFlags, editorAnalyticsApi) {
91
+ var floatingToolbarLinkSettingsButton = featureFlags.floatingToolbarLinkSettingsButton;
92
+ return floatingToolbarLinkSettingsButton === 'true' ? [{
93
+ type: 'separator'
94
+ }, {
95
+ id: 'editor.link.settings',
96
+ type: 'button',
97
+ icon: CogIcon,
98
+ title: intl.formatMessage(linkToolbarCommonMessages.settingsLink),
99
+ onClick: openLinkSettings(editorAnalyticsApi),
100
+ href: 'https://id.atlassian.com/manage-profile/link-preferences',
101
+ target: '_blank'
102
+ }] : [];
103
+ };
104
+ export var getToolbarConfig = function getToolbarConfig(options, featureFlags, pluginInjectionApi) {
105
+ return function (state, intl, providerFactory) {
106
+ var _pluginInjectionApi$d;
107
+ var formatMessage = intl.formatMessage;
108
+ var linkState = stateKey.getState(state);
109
+ var editorAnalyticsApi = pluginInjectionApi === null || pluginInjectionApi === void 0 ? void 0 : (_pluginInjectionApi$d = pluginInjectionApi.dependencies.analytics) === null || _pluginInjectionApi$d === void 0 ? void 0 : _pluginInjectionApi$d.actions;
110
+
111
+ /**
112
+ * Enable focus trap only if feature flag is enabled AND for the new version of the picker
113
+ */
114
+ var lpLinkPicker = featureFlags.lpLinkPicker,
115
+ lpLinkPickerFocusTrap = featureFlags.lpLinkPickerFocusTrap,
116
+ preventPopupOverflow = featureFlags.preventPopupOverflow;
117
+ var shouldEnableFocusTrap = Boolean(lpLinkPicker && lpLinkPickerFocusTrap);
118
+ if (linkState && linkState.activeLinkMark) {
119
+ var activeLinkMark = linkState.activeLinkMark;
120
+ var hyperLinkToolbar = {
121
+ title: 'Hyperlink floating controls',
122
+ nodeType: [state.schema.nodes.text, state.schema.nodes.paragraph, state.schema.nodes.heading, state.schema.nodes.taskItem, state.schema.nodes.decisionItem, state.schema.nodes.caption].filter(function (nodeType) {
123
+ return !!nodeType;
124
+ }),
125
+ // Use only the node types existing in the schema ED-6745
126
+ align: 'left',
127
+ className: activeLinkMark.type.match('INSERT|EDIT_INSERTED') ? 'hyperlink-floating-toolbar' : ''
128
+ };
129
+ switch (activeLinkMark.type) {
130
+ case 'EDIT':
131
+ {
132
+ var _toolbarKey$getState$, _toolbarKey$getState;
133
+ var pos = activeLinkMark.pos,
134
+ node = activeLinkMark.node;
135
+ var linkMark = node.marks.filter(function (mark) {
136
+ return mark.type === state.schema.marks.link;
137
+ });
138
+ var link = linkMark[0] && linkMark[0].attrs.href;
139
+ var isValidUrl = isSafeUrl(link);
140
+ var labelOpenLink = formatMessage(isValidUrl ? linkMessages.openLink : linkToolbarCommonMessages.unableToOpenLink);
141
+ // TODO: ED-14403 investigate why these are not translating?
142
+ var labelUnlink = formatMessage(linkToolbarCommonMessages.unlink);
143
+ var editLink = formatMessage(linkToolbarCommonMessages.editLink);
144
+ var metadata = {
145
+ url: link,
146
+ title: ''
147
+ };
148
+ if (activeLinkMark.node.text) {
149
+ metadata.title = activeLinkMark.node.text;
150
+ }
151
+ return _objectSpread(_objectSpread({}, hyperLinkToolbar), {}, {
152
+ height: 32,
153
+ width: 250,
154
+ items: [].concat(_toConsumableArray((_toolbarKey$getState$ = (_toolbarKey$getState = toolbarKey.getState(state)) === null || _toolbarKey$getState === void 0 ? void 0 : _toolbarKey$getState.items(state, intl, providerFactory, link)) !== null && _toolbarKey$getState$ !== void 0 ? _toolbarKey$getState$ : []), [{
155
+ id: 'editor.link.edit',
156
+ type: 'button',
157
+ onClick: editInsertedLink(editorAnalyticsApi),
158
+ selected: false,
159
+ title: editLink,
160
+ showTitle: true,
161
+ metadata: metadata
162
+ }, {
163
+ type: 'separator'
164
+ }, {
165
+ id: 'editor.link.openLink',
166
+ type: 'button',
167
+ disabled: !isValidUrl,
168
+ target: '_blank',
169
+ href: isValidUrl ? link : undefined,
170
+ onClick: visitHyperlink(editorAnalyticsApi),
171
+ selected: false,
172
+ title: labelOpenLink,
173
+ icon: OpenIcon,
174
+ className: 'hyperlink-open-link',
175
+ metadata: metadata,
176
+ tabIndex: null
177
+ }, {
178
+ type: 'separator'
179
+ }, {
180
+ id: 'editor.link.unlink',
181
+ type: 'button',
182
+ onClick: commandWithMetadata(removeLink(pos, editorAnalyticsApi), {
183
+ inputMethod: INPUT_METHOD.FLOATING_TB
184
+ }),
185
+ selected: false,
186
+ title: labelUnlink,
187
+ icon: UnlinkIcon,
188
+ tabIndex: null
189
+ }, {
190
+ type: 'copy-button',
191
+ items: [{
192
+ type: 'separator'
193
+ }, {
194
+ state: state,
195
+ formatMessage: formatMessage,
196
+ markType: state.schema.marks.link
197
+ }]
198
+ }], _toConsumableArray(getSettingsButtonGroup(state, intl, featureFlags, editorAnalyticsApi))),
199
+ scrollable: true
200
+ });
201
+ }
202
+ case 'EDIT_INSERTED':
203
+ case 'INSERT':
204
+ {
205
+ var _link;
206
+ if (isEditLink(activeLinkMark) && activeLinkMark.node) {
207
+ var _linkMark = activeLinkMark.node.marks.filter(function (mark) {
208
+ return mark.type === state.schema.marks.link;
209
+ });
210
+ _link = _linkMark[0] && _linkMark[0].attrs.href;
211
+ }
212
+ var displayText = isEditLink(activeLinkMark) ? getLinkText(activeLinkMark, state) : linkState.activeText;
213
+ var popupHeight = lpLinkPicker ? LINKPICKER_HEIGHT_IN_PX : RECENT_SEARCH_HEIGHT_IN_PX;
214
+ return _objectSpread(_objectSpread({}, hyperLinkToolbar), {}, {
215
+ preventPopupOverflow: preventPopupOverflow,
216
+ height: popupHeight,
217
+ width: RECENT_SEARCH_WIDTH_IN_PX,
218
+ focusTrap: shouldEnableFocusTrap,
219
+ items: [{
220
+ type: 'custom',
221
+ fallback: [],
222
+ disableArrowNavigation: true,
223
+ render: function render(view, idx) {
224
+ if (!view) {
225
+ return null;
226
+ }
227
+ return /*#__PURE__*/React.createElement(HyperlinkAddToolbarWithState, {
228
+ pluginInjectionApi: pluginInjectionApi,
229
+ view: view,
230
+ key: idx,
231
+ linkPickerOptions: options === null || options === void 0 ? void 0 : options.linkPicker,
232
+ featureFlags: featureFlags,
233
+ displayUrl: _link,
234
+ displayText: displayText || '',
235
+ providerFactory: providerFactory,
236
+ onCancel: function onCancel() {
237
+ return view.focus();
238
+ },
239
+ onClose: lpLinkPickerFocusTrap ? function () {
240
+ return view.focus();
241
+ } : undefined,
242
+ onEscapeCallback: onEscapeCallback,
243
+ onClickAwayCallback: onClickAwayCallback,
244
+ onSubmit: function onSubmit(href) {
245
+ var _options$cardOptions;
246
+ var title = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
247
+ var displayText = arguments.length > 2 ? arguments[2] : undefined;
248
+ var inputMethod = arguments.length > 3 ? arguments[3] : undefined;
249
+ var analytic = arguments.length > 4 ? arguments[4] : undefined;
250
+ var isEdit = isEditLink(activeLinkMark);
251
+ var action = isEdit ? ACTION.UPDATED : ACTION.INSERTED;
252
+ var command = isEdit ? commandWithMetadata(updateLink(href, displayText || title, activeLinkMark.pos), {
253
+ action: action,
254
+ inputMethod: inputMethod,
255
+ sourceEvent: analytic
256
+ }) : insertLinkWithAnalytics(inputMethod, activeLinkMark.from, activeLinkMark.to, href, editorAnalyticsApi, title, displayText, !!(options !== null && options !== void 0 && (_options$cardOptions = options.cardOptions) !== null && _options$cardOptions !== void 0 && _options$cardOptions.provider), analytic);
257
+ command(view.state, view.dispatch, view);
258
+ if (!lpLinkPickerFocusTrap) {
259
+ view.focus();
260
+ }
261
+ }
262
+ });
263
+ }
264
+ }]
265
+ });
266
+ }
267
+ }
268
+ }
269
+ return;
270
+ };
271
+ };
@@ -0,0 +1,222 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
3
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
4
+ import { Selection } from 'prosemirror-state';
5
+ import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, buildEditLinkPayload, EVENT_TYPE, INPUT_METHOD, unlinkPayload } from '@atlaskit/editor-common/analytics';
6
+ import { addLinkMetadata, commandWithMetadata } from '@atlaskit/editor-common/card';
7
+ import { withAnalytics } from '@atlaskit/editor-common/editor-analytics';
8
+ import { isTextAtPos, LinkAction } from '@atlaskit/editor-common/link';
9
+ import { filterCommands as filter, getLinkCreationAnalyticsEvent, normalizeUrl } from '@atlaskit/editor-common/utils';
10
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
11
+ import { stateKey } from './pm-plugins/main';
12
+ import { toolbarKey } from './pm-plugins/toolbar-buttons';
13
+ export function setLinkHref(href, pos, editorAnalyticsApi, to, isTabPressed) {
14
+ return filter(isTextAtPos(pos), function (state, dispatch) {
15
+ var $pos = state.doc.resolve(pos);
16
+ var node = state.doc.nodeAt(pos);
17
+ var linkMark = state.schema.marks.link;
18
+ var mark = linkMark.isInSet(node.marks);
19
+ var url = normalizeUrl(href);
20
+ if (mark && mark.attrs.href === url) {
21
+ return false;
22
+ }
23
+ var rightBound = to && pos !== to ? to : pos - $pos.textOffset + node.nodeSize;
24
+ var tr = state.tr.removeMark(pos, rightBound, linkMark);
25
+ if (href.trim()) {
26
+ tr.addMark(pos, rightBound, linkMark.create(_objectSpread(_objectSpread({}, mark && mark.attrs || {}), {}, {
27
+ href: url
28
+ })));
29
+ } else {
30
+ editorAnalyticsApi === null || editorAnalyticsApi === void 0 ? void 0 : editorAnalyticsApi.attachAnalyticsEvent(unlinkPayload(ACTION_SUBJECT_ID.HYPERLINK))(tr);
31
+ }
32
+ if (!isTabPressed) {
33
+ tr.setMeta(stateKey, {
34
+ type: LinkAction.HIDE_TOOLBAR
35
+ });
36
+ }
37
+ if (dispatch) {
38
+ dispatch(tr);
39
+ }
40
+ return true;
41
+ });
42
+ }
43
+ export function updateLink(href, text, pos, to) {
44
+ return function (state, dispatch) {
45
+ var $pos = state.doc.resolve(pos);
46
+ var node = state.doc.nodeAt(pos);
47
+ if (!node) {
48
+ return false;
49
+ }
50
+ var url = normalizeUrl(href);
51
+ var mark = state.schema.marks.link.isInSet(node.marks);
52
+ var linkMark = state.schema.marks.link;
53
+ var rightBound = to && pos !== to ? to : pos - $pos.textOffset + node.nodeSize;
54
+ var tr = state.tr;
55
+ if (!url && text) {
56
+ tr.removeMark(pos, rightBound, linkMark);
57
+ tr.insertText(text, pos, rightBound);
58
+ } else if (!url) {
59
+ return false;
60
+ } else {
61
+ tr.insertText(text, pos, rightBound);
62
+ // Casting to LinkAttributes to prevent wrong attributes been passed (Example ED-7951)
63
+ var linkAttrs = _objectSpread(_objectSpread({}, mark && mark.attrs || {}), {}, {
64
+ href: url
65
+ });
66
+ tr.addMark(pos, pos + text.length, linkMark.create(linkAttrs));
67
+ tr.setMeta(stateKey, {
68
+ type: LinkAction.HIDE_TOOLBAR
69
+ });
70
+ }
71
+ if (dispatch) {
72
+ dispatch(tr);
73
+ }
74
+ return true;
75
+ };
76
+ }
77
+ export function insertLink(from, to, incomingHref, incomingTitle, displayText, source, sourceEvent) {
78
+ return function (state, dispatch) {
79
+ var link = state.schema.marks.link;
80
+ var tr = state.tr;
81
+ if (incomingHref.trim()) {
82
+ var _stateKey$getState;
83
+ var normalizedUrl = normalizeUrl(incomingHref);
84
+ // NB: in this context, `currentText` represents text which has been
85
+ // highlighted in the Editor, upon which a link is is being added.
86
+ var currentText = (_stateKey$getState = stateKey.getState(state)) === null || _stateKey$getState === void 0 ? void 0 : _stateKey$getState.activeText;
87
+ var markEnd = to;
88
+ var text = displayText || incomingTitle || incomingHref;
89
+ if (!displayText || displayText !== currentText) {
90
+ tr.insertText(text, from, to);
91
+ if (!isTextAtPos(from)(state)) {
92
+ markEnd = from + text.length + 1;
93
+ } else {
94
+ markEnd = from + text.length;
95
+ }
96
+ }
97
+ tr.addMark(from, markEnd, link.create({
98
+ href: normalizedUrl
99
+ }));
100
+ tr.setSelection(Selection.near(tr.doc.resolve(markEnd)));
101
+ if (!displayText || displayText === incomingHref) {
102
+ var _toolbarKey$getState;
103
+ var queueCardsFromChangedTr = (_toolbarKey$getState = toolbarKey.getState(state)) === null || _toolbarKey$getState === void 0 ? void 0 : _toolbarKey$getState.onInsertLinkCallback;
104
+ if (queueCardsFromChangedTr) {
105
+ queueCardsFromChangedTr === null || queueCardsFromChangedTr === void 0 ? void 0 : queueCardsFromChangedTr(state, tr, source, ACTION.INSERTED, false, sourceEvent);
106
+ } else {
107
+ addLinkMetadata(state.selection, tr, {
108
+ action: ACTION.INSERTED,
109
+ inputMethod: source,
110
+ sourceEvent: sourceEvent
111
+ });
112
+ }
113
+ } else if (getBooleanFF('platform.linking-platform.editor.fix-link-insert-analytics')) {
114
+ /**
115
+ * Add link metadata because queue cards would have otherwise handled this for us
116
+ */
117
+ addLinkMetadata(state.selection, tr, {
118
+ action: ACTION.INSERTED,
119
+ inputMethod: source,
120
+ sourceEvent: sourceEvent
121
+ });
122
+ }
123
+ tr.setMeta(stateKey, {
124
+ type: LinkAction.HIDE_TOOLBAR
125
+ });
126
+ if (dispatch) {
127
+ dispatch(tr);
128
+ }
129
+ return true;
130
+ }
131
+ tr.setMeta(stateKey, {
132
+ type: LinkAction.HIDE_TOOLBAR
133
+ });
134
+ if (dispatch) {
135
+ dispatch(tr);
136
+ }
137
+ return false;
138
+ };
139
+ }
140
+ export var insertLinkWithAnalytics = function insertLinkWithAnalytics(inputMethod, from, to, href, editorAnalyticsApi, title, displayText) {
141
+ var cardsAvailable = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : false;
142
+ var sourceEvent = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : undefined;
143
+ // If smart cards are available, we send analytics for hyperlinks when a smart link is rejected.
144
+ if (cardsAvailable && !title && !displayText) {
145
+ return insertLink(from, to, href, title, displayText, inputMethod, sourceEvent);
146
+ }
147
+ return withAnalytics(editorAnalyticsApi, getLinkCreationAnalyticsEvent(inputMethod, href))(insertLink(from, to, href, title, displayText, inputMethod, sourceEvent));
148
+ };
149
+ export var insertLinkWithAnalyticsMobileNative = function insertLinkWithAnalyticsMobileNative(inputMethod, from, to, href, editorAnalyticsApi, title, displayText) {
150
+ return withAnalytics(editorAnalyticsApi, getLinkCreationAnalyticsEvent(inputMethod, href))(insertLink(from, to, href, title, displayText, inputMethod));
151
+ };
152
+ export function removeLink(pos, editorAnalyticsApi) {
153
+ return commandWithMetadata(setLinkHref('', pos, editorAnalyticsApi), {
154
+ action: ACTION.UNLINK
155
+ });
156
+ }
157
+ export function editInsertedLink(editorAnalyticsApi) {
158
+ return function (state, dispatch) {
159
+ if (dispatch) {
160
+ var _tr = state.tr;
161
+ _tr.setMeta(stateKey, {
162
+ type: LinkAction.EDIT_INSERTED_TOOLBAR,
163
+ inputMethod: INPUT_METHOD.FLOATING_TB
164
+ });
165
+ editorAnalyticsApi === null || editorAnalyticsApi === void 0 ? void 0 : editorAnalyticsApi.attachAnalyticsEvent(buildEditLinkPayload(ACTION_SUBJECT_ID.HYPERLINK))(_tr);
166
+ dispatch(_tr);
167
+ }
168
+ return true;
169
+ };
170
+ }
171
+ export function showLinkToolbar(inputMethod, editorAnalyticsApi) {
172
+ return function (state, dispatch) {
173
+ if (dispatch) {
174
+ var _tr2 = state.tr.setMeta(stateKey, {
175
+ type: LinkAction.SHOW_INSERT_TOOLBAR,
176
+ inputMethod: inputMethod
177
+ });
178
+ editorAnalyticsApi === null || editorAnalyticsApi === void 0 ? void 0 : editorAnalyticsApi.attachAnalyticsEvent({
179
+ action: ACTION.INVOKED,
180
+ actionSubject: ACTION_SUBJECT.TYPEAHEAD,
181
+ actionSubjectId: ACTION_SUBJECT_ID.TYPEAHEAD_LINK,
182
+ attributes: {
183
+ inputMethod: inputMethod
184
+ },
185
+ eventType: EVENT_TYPE.UI
186
+ })(_tr2);
187
+ dispatch(_tr2);
188
+ }
189
+ return true;
190
+ };
191
+ }
192
+ export function hideLinkToolbar() {
193
+ return function (state, dispatch) {
194
+ if (dispatch) {
195
+ dispatch(hideLinkToolbarSetMeta(state.tr));
196
+ }
197
+ return true;
198
+ };
199
+ }
200
+ export var hideLinkToolbarSetMeta = function hideLinkToolbarSetMeta(tr) {
201
+ return tr.setMeta(stateKey, {
202
+ type: LinkAction.HIDE_TOOLBAR
203
+ });
204
+ };
205
+ export var onEscapeCallback = function onEscapeCallback(state, dispatch) {
206
+ var _toolbarKey$getState2, _toolbarKey$getState3;
207
+ var tr = state.tr;
208
+ hideLinkToolbarSetMeta(tr);
209
+ (_toolbarKey$getState2 = toolbarKey.getState(state)) === null || _toolbarKey$getState2 === void 0 ? void 0 : (_toolbarKey$getState3 = _toolbarKey$getState2.onEscapeCallback) === null || _toolbarKey$getState3 === void 0 ? void 0 : _toolbarKey$getState3.call(_toolbarKey$getState2, tr);
210
+ if (dispatch) {
211
+ dispatch(tr);
212
+ return true;
213
+ }
214
+ return false;
215
+ };
216
+ export var onClickAwayCallback = function onClickAwayCallback(state, dispatch) {
217
+ if (dispatch) {
218
+ hideLinkToolbar()(state, dispatch);
219
+ return true;
220
+ }
221
+ return false;
222
+ };
@@ -0,0 +1 @@
1
+ export { hyperlinkPlugin } from './plugin';
@@ -0,0 +1,114 @@
1
+ import React from 'react';
2
+ import { link } from '@atlaskit/adf-schema';
3
+ import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
4
+ import { addLink, tooltip } from '@atlaskit/editor-common/keymaps';
5
+ import { LinkAction } from '@atlaskit/editor-common/link';
6
+ import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages';
7
+ import { IconLink } from '@atlaskit/editor-common/quick-insert';
8
+ import { hideLinkToolbarSetMeta, showLinkToolbar as _showLinkToolbar } from './commands';
9
+ import fakeCursorToolbarPlugin from './pm-plugins/fake-cursor-for-toolbar';
10
+ import { createInputRulePlugin } from './pm-plugins/input-rule';
11
+ import { createKeymapPlugin } from './pm-plugins/keymap';
12
+ import { plugin as _plugin, stateKey } from './pm-plugins/main';
13
+ import { prependToolbarButtons, toolbarButtonsPlugin } from './pm-plugins/toolbar-buttons';
14
+ import { getToolbarConfig } from './Toolbar';
15
+ export var hyperlinkPlugin = function hyperlinkPlugin() {
16
+ var _api$dependencies, _api$dependencies$fea;
17
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
18
+ var api = arguments.length > 1 ? arguments[1] : undefined;
19
+ var featureFlags = (api === null || api === void 0 ? void 0 : (_api$dependencies = api.dependencies) === null || _api$dependencies === void 0 ? void 0 : (_api$dependencies$fea = _api$dependencies.featureFlags) === null || _api$dependencies$fea === void 0 ? void 0 : _api$dependencies$fea.sharedState.currentState()) || {};
20
+ return {
21
+ name: 'hyperlink',
22
+ marks: function marks() {
23
+ return [{
24
+ name: 'link',
25
+ mark: link
26
+ }];
27
+ },
28
+ actions: {
29
+ prependToolbarButtons: prependToolbarButtons,
30
+ showLinkToolbar: function showLinkToolbar() {
31
+ var _api$dependencies$ana;
32
+ var inputMethod = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : INPUT_METHOD.TOOLBAR;
33
+ return _showLinkToolbar(inputMethod, api === null || api === void 0 ? void 0 : (_api$dependencies$ana = api.dependencies.analytics) === null || _api$dependencies$ana === void 0 ? void 0 : _api$dependencies$ana.actions);
34
+ },
35
+ hideLinkToolbar: hideLinkToolbarSetMeta
36
+ },
37
+ getSharedState: function getSharedState(editorState) {
38
+ if (!editorState) {
39
+ return undefined;
40
+ }
41
+ return stateKey.getState(editorState);
42
+ },
43
+ pmPlugins: function pmPlugins() {
44
+ var _options$cardOptions;
45
+ // Skip analytics if card provider is available, as they will be
46
+ // sent on handleRejected upon attempting to resolve smart link.
47
+ var skipAnalytics = !!(options !== null && options !== void 0 && (_options$cardOptions = options.cardOptions) !== null && _options$cardOptions !== void 0 && _options$cardOptions.provider);
48
+ return [{
49
+ name: 'hyperlink',
50
+ plugin: function plugin(_ref) {
51
+ var dispatch = _ref.dispatch;
52
+ return _plugin(dispatch, options === null || options === void 0 ? void 0 : options.editorAppearance);
53
+ }
54
+ }, {
55
+ name: 'fakeCursorToolbarPlugin',
56
+ plugin: function plugin() {
57
+ return fakeCursorToolbarPlugin;
58
+ }
59
+ }, {
60
+ name: 'hyperlinkInputRule',
61
+ plugin: function plugin(_ref2) {
62
+ var _api$dependencies$ana2;
63
+ var schema = _ref2.schema,
64
+ featureFlags = _ref2.featureFlags;
65
+ return createInputRulePlugin(schema, skipAnalytics, featureFlags, api === null || api === void 0 ? void 0 : (_api$dependencies$ana2 = api.dependencies.analytics) === null || _api$dependencies$ana2 === void 0 ? void 0 : _api$dependencies$ana2.actions);
66
+ }
67
+ }, {
68
+ name: 'hyperlinkKeymap',
69
+ plugin: function plugin() {
70
+ var _api$dependencies$ana3;
71
+ return createKeymapPlugin(skipAnalytics, api === null || api === void 0 ? void 0 : (_api$dependencies$ana3 = api.dependencies.analytics) === null || _api$dependencies$ana3 === void 0 ? void 0 : _api$dependencies$ana3.actions);
72
+ }
73
+ }, {
74
+ name: 'hyperlinkToolbarButtons',
75
+ plugin: toolbarButtonsPlugin
76
+ }];
77
+ },
78
+ pluginsOptions: {
79
+ quickInsert: function quickInsert(_ref3) {
80
+ var formatMessage = _ref3.formatMessage;
81
+ return [{
82
+ id: 'hyperlink',
83
+ title: formatMessage(messages.link),
84
+ description: formatMessage(messages.linkDescription),
85
+ keywords: ['hyperlink', 'url'],
86
+ priority: 1200,
87
+ keyshortcut: tooltip(addLink),
88
+ icon: function icon() {
89
+ return /*#__PURE__*/React.createElement(IconLink, null);
90
+ },
91
+ action: function action(insert, state) {
92
+ var _api$dependencies2, _api$dependencies2$an, _api$dependencies2$an2, _api$dependencies2$an3;
93
+ var tr = insert(undefined);
94
+ tr.setMeta(stateKey, {
95
+ type: LinkAction.SHOW_INSERT_TOOLBAR,
96
+ inputMethod: INPUT_METHOD.QUICK_INSERT
97
+ });
98
+ var analyticsAttached = api === null || api === void 0 ? void 0 : (_api$dependencies2 = api.dependencies) === null || _api$dependencies2 === void 0 ? void 0 : (_api$dependencies2$an = _api$dependencies2.analytics) === null || _api$dependencies2$an === void 0 ? void 0 : (_api$dependencies2$an2 = _api$dependencies2$an.actions) === null || _api$dependencies2$an2 === void 0 ? void 0 : (_api$dependencies2$an3 = _api$dependencies2$an2.attachAnalyticsEvent) === null || _api$dependencies2$an3 === void 0 ? void 0 : _api$dependencies2$an3.call(_api$dependencies2$an2, {
99
+ action: ACTION.INVOKED,
100
+ actionSubject: ACTION_SUBJECT.TYPEAHEAD,
101
+ actionSubjectId: ACTION_SUBJECT_ID.TYPEAHEAD_LINK,
102
+ attributes: {
103
+ inputMethod: INPUT_METHOD.QUICK_INSERT
104
+ },
105
+ eventType: EVENT_TYPE.UI
106
+ })(tr);
107
+ return analyticsAttached !== false ? tr : false;
108
+ }
109
+ }];
110
+ },
111
+ floatingToolbar: getToolbarConfig(options, featureFlags, api)
112
+ }
113
+ };
114
+ };
@@ -0,0 +1,2 @@
1
+ import { PluginKey } from 'prosemirror-state';
2
+ export var fakeCursorForToolbarPluginKey = new PluginKey('fakeCursorToolbarPlugin');
@@ -0,0 +1,61 @@
1
+ import { Decoration, DecorationSet } from 'prosemirror-view';
2
+ import { InsertStatus } from '@atlaskit/editor-common/link';
3
+ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
4
+ import { fakeCursorForToolbarPluginKey } from './fake-curor-for-toolbar-plugin-key';
5
+ import { stateKey as hyperlinkStateKey } from './main';
6
+ var createTextCursor = function createTextCursor(pos) {
7
+ var node = document.createElement('div');
8
+ node.className = 'ProseMirror-fake-text-cursor';
9
+ return Decoration.widget(pos, node, {
10
+ key: 'hyperlink-text-cursor'
11
+ });
12
+ };
13
+ var createTextSelection = function createTextSelection(from, to) {
14
+ return Decoration.inline(from, to, {
15
+ class: 'ProseMirror-fake-text-selection'
16
+ });
17
+ };
18
+ var getInsertLinkToolbarState = function getInsertLinkToolbarState(editorState) {
19
+ var state = hyperlinkStateKey.getState(editorState);
20
+ if (state && state.activeLinkMark) {
21
+ if (state.activeLinkMark.type === InsertStatus.INSERT_LINK_TOOLBAR) {
22
+ return state.activeLinkMark;
23
+ }
24
+ }
25
+ return undefined;
26
+ };
27
+ var fakeCursorToolbarPlugin = new SafePlugin({
28
+ key: fakeCursorForToolbarPluginKey,
29
+ state: {
30
+ init: function init() {
31
+ return DecorationSet.empty;
32
+ },
33
+ apply: function apply(tr, pluginState, oldState, newState) {
34
+ var oldInsertToolbarState = getInsertLinkToolbarState(oldState);
35
+ var insertToolbarState = getInsertLinkToolbarState(newState);
36
+ // Map DecorationSet if it still refers to the same position in the document
37
+ if (oldInsertToolbarState && insertToolbarState) {
38
+ var from = insertToolbarState.from,
39
+ to = insertToolbarState.to;
40
+ var oldFrom = tr.mapping.map(oldInsertToolbarState.from);
41
+ var oldTo = tr.mapping.map(oldInsertToolbarState.to);
42
+ if (oldFrom === from && oldTo === to) {
43
+ return pluginState.map(tr.mapping, tr.doc);
44
+ }
45
+ }
46
+ // Update DecorationSet if new insert toolbar, or if we have moved to a different position in the doc
47
+ if (insertToolbarState) {
48
+ var _from = insertToolbarState.from,
49
+ _to = insertToolbarState.to;
50
+ return DecorationSet.create(tr.doc, [_from === _to ? createTextCursor(_from) : createTextSelection(_from, _to)]);
51
+ }
52
+ return DecorationSet.empty;
53
+ }
54
+ },
55
+ props: {
56
+ decorations: function decorations(state) {
57
+ return fakeCursorForToolbarPluginKey.getState(state);
58
+ }
59
+ }
60
+ });
61
+ export default fakeCursorToolbarPlugin;