@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,122 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.hyperlinkPlugin = void 0;
8
+ var _react = _interopRequireDefault(require("react"));
9
+ var _adfSchema = require("@atlaskit/adf-schema");
10
+ var _analytics = require("@atlaskit/editor-common/analytics");
11
+ var _keymaps = require("@atlaskit/editor-common/keymaps");
12
+ var _link = require("@atlaskit/editor-common/link");
13
+ var _messages = require("@atlaskit/editor-common/messages");
14
+ var _quickInsert = require("@atlaskit/editor-common/quick-insert");
15
+ var _commands = require("./commands");
16
+ var _fakeCursorForToolbar = _interopRequireDefault(require("./pm-plugins/fake-cursor-for-toolbar"));
17
+ var _inputRule = require("./pm-plugins/input-rule");
18
+ var _keymap = require("./pm-plugins/keymap");
19
+ var _main = require("./pm-plugins/main");
20
+ var _toolbarButtons = require("./pm-plugins/toolbar-buttons");
21
+ var _Toolbar = require("./Toolbar");
22
+ var hyperlinkPlugin = function hyperlinkPlugin() {
23
+ var _api$dependencies, _api$dependencies$fea;
24
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
25
+ var api = arguments.length > 1 ? arguments[1] : undefined;
26
+ 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()) || {};
27
+ return {
28
+ name: 'hyperlink',
29
+ marks: function marks() {
30
+ return [{
31
+ name: 'link',
32
+ mark: _adfSchema.link
33
+ }];
34
+ },
35
+ actions: {
36
+ prependToolbarButtons: _toolbarButtons.prependToolbarButtons,
37
+ showLinkToolbar: function showLinkToolbar() {
38
+ var _api$dependencies$ana;
39
+ var inputMethod = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _analytics.INPUT_METHOD.TOOLBAR;
40
+ return (0, _commands.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);
41
+ },
42
+ hideLinkToolbar: _commands.hideLinkToolbarSetMeta
43
+ },
44
+ getSharedState: function getSharedState(editorState) {
45
+ if (!editorState) {
46
+ return undefined;
47
+ }
48
+ return _main.stateKey.getState(editorState);
49
+ },
50
+ pmPlugins: function pmPlugins() {
51
+ var _options$cardOptions;
52
+ // Skip analytics if card provider is available, as they will be
53
+ // sent on handleRejected upon attempting to resolve smart link.
54
+ var skipAnalytics = !!(options !== null && options !== void 0 && (_options$cardOptions = options.cardOptions) !== null && _options$cardOptions !== void 0 && _options$cardOptions.provider);
55
+ return [{
56
+ name: 'hyperlink',
57
+ plugin: function plugin(_ref) {
58
+ var dispatch = _ref.dispatch;
59
+ return (0, _main.plugin)(dispatch, options === null || options === void 0 ? void 0 : options.editorAppearance);
60
+ }
61
+ }, {
62
+ name: 'fakeCursorToolbarPlugin',
63
+ plugin: function plugin() {
64
+ return _fakeCursorForToolbar.default;
65
+ }
66
+ }, {
67
+ name: 'hyperlinkInputRule',
68
+ plugin: function plugin(_ref2) {
69
+ var _api$dependencies$ana2;
70
+ var schema = _ref2.schema,
71
+ featureFlags = _ref2.featureFlags;
72
+ return (0, _inputRule.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);
73
+ }
74
+ }, {
75
+ name: 'hyperlinkKeymap',
76
+ plugin: function plugin() {
77
+ var _api$dependencies$ana3;
78
+ return (0, _keymap.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);
79
+ }
80
+ }, {
81
+ name: 'hyperlinkToolbarButtons',
82
+ plugin: _toolbarButtons.toolbarButtonsPlugin
83
+ }];
84
+ },
85
+ pluginsOptions: {
86
+ quickInsert: function quickInsert(_ref3) {
87
+ var formatMessage = _ref3.formatMessage;
88
+ return [{
89
+ id: 'hyperlink',
90
+ title: formatMessage(_messages.toolbarInsertBlockMessages.link),
91
+ description: formatMessage(_messages.toolbarInsertBlockMessages.linkDescription),
92
+ keywords: ['hyperlink', 'url'],
93
+ priority: 1200,
94
+ keyshortcut: (0, _keymaps.tooltip)(_keymaps.addLink),
95
+ icon: function icon() {
96
+ return /*#__PURE__*/_react.default.createElement(_quickInsert.IconLink, null);
97
+ },
98
+ action: function action(insert, state) {
99
+ var _api$dependencies2, _api$dependencies2$an, _api$dependencies2$an2, _api$dependencies2$an3;
100
+ var tr = insert(undefined);
101
+ tr.setMeta(_main.stateKey, {
102
+ type: _link.LinkAction.SHOW_INSERT_TOOLBAR,
103
+ inputMethod: _analytics.INPUT_METHOD.QUICK_INSERT
104
+ });
105
+ 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, {
106
+ action: _analytics.ACTION.INVOKED,
107
+ actionSubject: _analytics.ACTION_SUBJECT.TYPEAHEAD,
108
+ actionSubjectId: _analytics.ACTION_SUBJECT_ID.TYPEAHEAD_LINK,
109
+ attributes: {
110
+ inputMethod: _analytics.INPUT_METHOD.QUICK_INSERT
111
+ },
112
+ eventType: _analytics.EVENT_TYPE.UI
113
+ })(tr);
114
+ return analyticsAttached !== false ? tr : false;
115
+ }
116
+ }];
117
+ },
118
+ floatingToolbar: (0, _Toolbar.getToolbarConfig)(options, featureFlags, api)
119
+ }
120
+ };
121
+ };
122
+ exports.hyperlinkPlugin = hyperlinkPlugin;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.fakeCursorForToolbarPluginKey = void 0;
7
+ var _prosemirrorState = require("prosemirror-state");
8
+ var fakeCursorForToolbarPluginKey = new _prosemirrorState.PluginKey('fakeCursorToolbarPlugin');
9
+ exports.fakeCursorForToolbarPluginKey = fakeCursorForToolbarPluginKey;
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _prosemirrorView = require("prosemirror-view");
8
+ var _link = require("@atlaskit/editor-common/link");
9
+ var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
10
+ var _fakeCurorForToolbarPluginKey = require("./fake-curor-for-toolbar-plugin-key");
11
+ var _main = require("./main");
12
+ var createTextCursor = function createTextCursor(pos) {
13
+ var node = document.createElement('div');
14
+ node.className = 'ProseMirror-fake-text-cursor';
15
+ return _prosemirrorView.Decoration.widget(pos, node, {
16
+ key: 'hyperlink-text-cursor'
17
+ });
18
+ };
19
+ var createTextSelection = function createTextSelection(from, to) {
20
+ return _prosemirrorView.Decoration.inline(from, to, {
21
+ class: 'ProseMirror-fake-text-selection'
22
+ });
23
+ };
24
+ var getInsertLinkToolbarState = function getInsertLinkToolbarState(editorState) {
25
+ var state = _main.stateKey.getState(editorState);
26
+ if (state && state.activeLinkMark) {
27
+ if (state.activeLinkMark.type === _link.InsertStatus.INSERT_LINK_TOOLBAR) {
28
+ return state.activeLinkMark;
29
+ }
30
+ }
31
+ return undefined;
32
+ };
33
+ var fakeCursorToolbarPlugin = new _safePlugin.SafePlugin({
34
+ key: _fakeCurorForToolbarPluginKey.fakeCursorForToolbarPluginKey,
35
+ state: {
36
+ init: function init() {
37
+ return _prosemirrorView.DecorationSet.empty;
38
+ },
39
+ apply: function apply(tr, pluginState, oldState, newState) {
40
+ var oldInsertToolbarState = getInsertLinkToolbarState(oldState);
41
+ var insertToolbarState = getInsertLinkToolbarState(newState);
42
+ // Map DecorationSet if it still refers to the same position in the document
43
+ if (oldInsertToolbarState && insertToolbarState) {
44
+ var from = insertToolbarState.from,
45
+ to = insertToolbarState.to;
46
+ var oldFrom = tr.mapping.map(oldInsertToolbarState.from);
47
+ var oldTo = tr.mapping.map(oldInsertToolbarState.to);
48
+ if (oldFrom === from && oldTo === to) {
49
+ return pluginState.map(tr.mapping, tr.doc);
50
+ }
51
+ }
52
+ // Update DecorationSet if new insert toolbar, or if we have moved to a different position in the doc
53
+ if (insertToolbarState) {
54
+ var _from = insertToolbarState.from,
55
+ _to = insertToolbarState.to;
56
+ return _prosemirrorView.DecorationSet.create(tr.doc, [_from === _to ? createTextCursor(_from) : createTextSelection(_from, _to)]);
57
+ }
58
+ return _prosemirrorView.DecorationSet.empty;
59
+ }
60
+ },
61
+ props: {
62
+ decorations: function decorations(state) {
63
+ return _fakeCurorForToolbarPluginKey.fakeCursorForToolbarPluginKey.getState(state);
64
+ }
65
+ }
66
+ });
67
+ var _default = fakeCursorToolbarPlugin;
68
+ exports.default = _default;
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.createInputRulePlugin = createInputRulePlugin;
8
+ exports.createLinkInputRule = createLinkInputRule;
9
+ exports.default = void 0;
10
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
11
+ var _analytics = require("@atlaskit/editor-common/analytics");
12
+ var _card = require("@atlaskit/editor-common/card");
13
+ var _utils = require("@atlaskit/editor-common/utils");
14
+ var _prosemirrorInputRules = require("@atlaskit/prosemirror-input-rules");
15
+ function createLinkInputRule(regexp) {
16
+ var skipAnalytics = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
17
+ var editorAnalyticsApi = arguments.length > 2 ? arguments[2] : undefined;
18
+ // Plain typed text (eg, typing 'www.google.com') should convert to a hyperlink
19
+ return (0, _prosemirrorInputRules.createRule)(regexp, function (state, match, start, end) {
20
+ var schema = state.schema;
21
+ if (state.doc.rangeHasMark(start, end, schema.marks.link)) {
22
+ return null;
23
+ }
24
+ var link = match;
25
+ var url = (0, _utils.normalizeUrl)(link.url);
26
+ var markType = schema.mark('link', {
27
+ href: url
28
+ });
29
+
30
+ // Need access to complete text to check if last URL is part of a filepath before linkifying
31
+ var nodeBefore = state.selection.$from.nodeBefore;
32
+ if (!nodeBefore || !nodeBefore.isText || !nodeBefore.text) {
33
+ return null;
34
+ }
35
+ var filepaths = (0, _utils.findFilepaths)(nodeBefore.text,
36
+ // The position referenced by 'start' is relative to the start of the document, findFilepaths deals with index in a node only.
37
+ start - (nodeBefore.text.length - link.text.length) // (start of link match) - (whole node text length - link length) gets start of text node, which is used as offset
38
+ );
39
+
40
+ if ((0, _utils.isLinkInMatches)(start, filepaths)) {
41
+ var _tr = state.tr;
42
+ return _tr;
43
+ }
44
+ var from = start;
45
+ var to = Math.min(start + link.text.length, state.doc.content.size);
46
+ var tr = state.tr.addMark(from, to, markType);
47
+
48
+ // Keep old behavior that will delete the space after the link
49
+ if (to === end) {
50
+ tr.insertText(' ');
51
+ }
52
+ (0, _card.addLinkMetadata)(state.selection, tr, {
53
+ inputMethod: _analytics.INPUT_METHOD.AUTO_DETECT
54
+ });
55
+ if (skipAnalytics) {
56
+ return tr;
57
+ }
58
+ editorAnalyticsApi === null || editorAnalyticsApi === void 0 ? void 0 : editorAnalyticsApi.attachAnalyticsEvent((0, _utils.getLinkCreationAnalyticsEvent)(_analytics.INPUT_METHOD.AUTO_DETECT, url))(tr);
59
+ return tr;
60
+ });
61
+ }
62
+ function createInputRulePlugin(schema) {
63
+ var skipAnalytics = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
64
+ var featureFlags = arguments.length > 2 ? arguments[2] : undefined;
65
+ var editorAnalyticsApi = arguments.length > 3 ? arguments[3] : undefined;
66
+ if (!schema.marks.link) {
67
+ return;
68
+ }
69
+ var urlWithASpaceRule = createLinkInputRule(_utils.LinkMatcher.create(), skipAnalytics, editorAnalyticsApi);
70
+
71
+ // [something](link) should convert to a hyperlink
72
+ var markdownLinkRule = (0, _prosemirrorInputRules.createRule)(/(^|[^!])\[(.*?)\]\((\S+)\)$/, function (state, match, start, end) {
73
+ var schema = state.schema;
74
+ var _match = (0, _slicedToArray2.default)(match, 4),
75
+ prefix = _match[1],
76
+ linkText = _match[2],
77
+ linkUrl = _match[3];
78
+ var url = (0, _utils.normalizeUrl)(linkUrl).trim();
79
+ var markType = schema.mark('link', {
80
+ href: url
81
+ });
82
+ var tr = state.tr.replaceWith(start + prefix.length, end, schema.text((linkText || '').trim(), [markType]));
83
+ (0, _card.addLinkMetadata)(state.selection, tr, {
84
+ inputMethod: _analytics.INPUT_METHOD.FORMATTING
85
+ });
86
+ if (skipAnalytics) {
87
+ return tr;
88
+ }
89
+ editorAnalyticsApi === null || editorAnalyticsApi === void 0 ? void 0 : editorAnalyticsApi.attachAnalyticsEvent((0, _utils.getLinkCreationAnalyticsEvent)(_analytics.INPUT_METHOD.FORMATTING, url))(tr);
90
+ return tr;
91
+ });
92
+ return (0, _prosemirrorInputRules.createPlugin)('hyperlink', [urlWithASpaceRule, markdownLinkRule]);
93
+ }
94
+ var _default = createInputRulePlugin;
95
+ exports.default = _default;
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createKeymapPlugin = createKeymapPlugin;
7
+ exports.default = void 0;
8
+ var _prosemirrorKeymap = require("prosemirror-keymap");
9
+ var _adfSchema = require("@atlaskit/adf-schema");
10
+ var _analytics = require("@atlaskit/editor-common/analytics");
11
+ var _keymaps = require("@atlaskit/editor-common/keymaps");
12
+ var _utils = require("@atlaskit/editor-common/utils");
13
+ var _commands = require("../commands");
14
+ var _main = require("../pm-plugins/main");
15
+ function createKeymapPlugin() {
16
+ var skipAnalytics = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
17
+ var editorAnalyticsApi = arguments.length > 1 ? arguments[1] : undefined;
18
+ var list = {};
19
+ (0, _keymaps.bindKeymapWithCommand)(_keymaps.addLink.common, (0, _commands.showLinkToolbar)(_analytics.INPUT_METHOD.SHORTCUT, editorAnalyticsApi), list);
20
+ (0, _keymaps.bindKeymapWithCommand)(_keymaps.enter.common, mayConvertLastWordToHyperlink(skipAnalytics, editorAnalyticsApi), list);
21
+ (0, _keymaps.bindKeymapWithCommand)(_keymaps.insertNewLine.common, mayConvertLastWordToHyperlink(skipAnalytics, editorAnalyticsApi), list);
22
+ (0, _keymaps.bindKeymapWithCommand)(_keymaps.escape.common, function (state, dispatch, view) {
23
+ var hyperlinkPlugin = _main.stateKey.getState(state);
24
+ if (hyperlinkPlugin.activeLinkMark) {
25
+ (0, _commands.hideLinkToolbar)()(state, dispatch);
26
+ if (view) {
27
+ view.focus();
28
+ }
29
+ return false;
30
+ }
31
+ return false;
32
+ }, list);
33
+ return (0, _prosemirrorKeymap.keymap)(list);
34
+ }
35
+ var mayConvertLastWordToHyperlink = function mayConvertLastWordToHyperlink(skipAnalytics, editorAnalyticsApi) {
36
+ return function (state, dispatch) {
37
+ var nodeBefore = state.selection.$from.nodeBefore;
38
+ if (!nodeBefore || !nodeBefore.isText || !nodeBefore.text) {
39
+ return false;
40
+ }
41
+ var words = nodeBefore.text.split(' ');
42
+ var lastWord = words[words.length - 1];
43
+ var match = (0, _adfSchema.getLinkMatch)(lastWord);
44
+ if (match) {
45
+ var hyperlinkedText = match.raw;
46
+ var start = state.selection.$from.pos - hyperlinkedText.length;
47
+ var end = state.selection.$from.pos;
48
+ if (state.doc.rangeHasMark(start, end, state.schema.marks.link)) {
49
+ return false;
50
+ }
51
+ var url = match.url;
52
+ var markType = state.schema.mark('link', {
53
+ href: url
54
+ });
55
+ var filepaths = (0, _utils.findFilepaths)(nodeBefore.text, start - (nodeBefore.text.length - hyperlinkedText.length) // The position referenced by 'start' is relative to the start of the document, findFilepaths deals with index in a node only.
56
+ );
57
+
58
+ if ((0, _utils.isLinkInMatches)(start, filepaths)) {
59
+ return false;
60
+ }
61
+ var tr = state.tr.addMark(start, end, markType);
62
+ if (dispatch) {
63
+ if (skipAnalytics) {
64
+ dispatch(tr);
65
+ } else {
66
+ editorAnalyticsApi === null || editorAnalyticsApi === void 0 ? void 0 : editorAnalyticsApi.attachAnalyticsEvent((0, _utils.getLinkCreationAnalyticsEvent)(_analytics.INPUT_METHOD.AUTO_DETECT, url))(tr);
67
+ dispatch(tr);
68
+ }
69
+ }
70
+ }
71
+ return false;
72
+ };
73
+ };
74
+ var _default = createKeymapPlugin;
75
+ exports.default = _default;
@@ -0,0 +1,257 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.stateKey = exports.plugin = void 0;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
+ var _prosemirrorState = require("prosemirror-state");
10
+ var _uuid = _interopRequireDefault(require("uuid"));
11
+ var _link3 = require("@atlaskit/editor-common/link");
12
+ var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
13
+ var _utils = require("@atlaskit/editor-common/utils");
14
+ 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; }
15
+ 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) { (0, _defineProperty2.default)(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; }
16
+ var isSelectionInsideLink = function isSelectionInsideLink(state) {
17
+ return !!state.doc.type.schema.marks.link.isInSet(state.selection.$from.marks());
18
+ };
19
+ var isSelectionAroundLink = function isSelectionAroundLink(state) {
20
+ var _state$selection = state.selection,
21
+ $from = _state$selection.$from,
22
+ $to = _state$selection.$to;
23
+ var node = $from.nodeAfter;
24
+ return !!node && $from.textOffset === 0 && $to.pos - $from.pos === node.nodeSize && !!state.doc.type.schema.marks.link.isInSet(node.marks);
25
+ };
26
+ var mapTransactionToState = function mapTransactionToState(state, tr) {
27
+ if (!state) {
28
+ return undefined;
29
+ } else if (state.type === _link3.InsertStatus.EDIT_LINK_TOOLBAR || state.type === _link3.InsertStatus.EDIT_INSERTED_TOOLBAR) {
30
+ var _tr$mapping$mapResult = tr.mapping.mapResult(state.pos, 1),
31
+ pos = _tr$mapping$mapResult.pos,
32
+ deleted = _tr$mapping$mapResult.deleted;
33
+ var node = tr.doc.nodeAt(pos);
34
+ // If the position was not deleted & it is still a link
35
+ if (!deleted && !!node.type.schema.marks.link.isInSet(node.marks)) {
36
+ if (node === state.node && pos === state.pos) {
37
+ return state;
38
+ }
39
+ return _objectSpread(_objectSpread({}, state), {}, {
40
+ pos: pos,
41
+ node: node
42
+ });
43
+ }
44
+ // If the position has been deleted, then require a navigation to show the toolbar again
45
+ return;
46
+ } else if (state.type === _link3.InsertStatus.INSERT_LINK_TOOLBAR) {
47
+ return _objectSpread(_objectSpread({}, state), {}, {
48
+ from: tr.mapping.map(state.from),
49
+ to: tr.mapping.map(state.to)
50
+ });
51
+ }
52
+ return;
53
+ };
54
+ var toState = function toState(state, action, editorState) {
55
+ // Show insert or edit toolbar
56
+ if (!state) {
57
+ switch (action) {
58
+ case _link3.LinkAction.SHOW_INSERT_TOOLBAR:
59
+ {
60
+ var _editorState$selectio = editorState.selection,
61
+ from = _editorState$selectio.from,
62
+ to = _editorState$selectio.to;
63
+ if ((0, _utils.canLinkBeCreatedInRange)(from, to)(editorState)) {
64
+ return {
65
+ type: _link3.InsertStatus.INSERT_LINK_TOOLBAR,
66
+ from: from,
67
+ to: to
68
+ };
69
+ }
70
+ return undefined;
71
+ }
72
+ case _link3.LinkAction.SELECTION_CHANGE:
73
+ // If the user has moved their cursor, see if they're in a link
74
+ var link = getActiveLinkMark(editorState);
75
+ if (link) {
76
+ return _objectSpread(_objectSpread({}, link), {}, {
77
+ type: _link3.InsertStatus.EDIT_LINK_TOOLBAR
78
+ });
79
+ }
80
+ return undefined;
81
+ default:
82
+ return undefined;
83
+ }
84
+ }
85
+ // Update toolbar state if selection changes, or if toolbar is hidden
86
+ if (state.type === _link3.InsertStatus.EDIT_LINK_TOOLBAR) {
87
+ switch (action) {
88
+ case _link3.LinkAction.EDIT_INSERTED_TOOLBAR:
89
+ {
90
+ var _link = getActiveLinkMark(editorState);
91
+ if (_link) {
92
+ if (_link.pos === state.pos && _link.node === state.node) {
93
+ return _objectSpread(_objectSpread({}, state), {}, {
94
+ type: _link3.InsertStatus.EDIT_INSERTED_TOOLBAR
95
+ });
96
+ }
97
+ return _objectSpread(_objectSpread({}, _link), {}, {
98
+ type: _link3.InsertStatus.EDIT_INSERTED_TOOLBAR
99
+ });
100
+ }
101
+ return undefined;
102
+ }
103
+ case _link3.LinkAction.SELECTION_CHANGE:
104
+ var _link2 = getActiveLinkMark(editorState);
105
+ if (_link2) {
106
+ if (_link2.pos === state.pos && _link2.node === state.node) {
107
+ // Make sure we return the same object, if it's the same link
108
+ return state;
109
+ }
110
+ return _objectSpread(_objectSpread({}, _link2), {}, {
111
+ type: _link3.InsertStatus.EDIT_LINK_TOOLBAR
112
+ });
113
+ }
114
+ return undefined;
115
+ case _link3.LinkAction.HIDE_TOOLBAR:
116
+ return undefined;
117
+ default:
118
+ return state;
119
+ }
120
+ }
121
+
122
+ // Remove toolbar if user changes selection or toolbar is hidden
123
+ if (state.type === _link3.InsertStatus.INSERT_LINK_TOOLBAR) {
124
+ switch (action) {
125
+ case _link3.LinkAction.SELECTION_CHANGE:
126
+ case _link3.LinkAction.HIDE_TOOLBAR:
127
+ return undefined;
128
+ default:
129
+ return state;
130
+ }
131
+ }
132
+ return;
133
+ };
134
+ var getActiveLinkMark = function getActiveLinkMark(state) {
135
+ var $from = state.selection.$from;
136
+ if (isSelectionInsideLink(state) || isSelectionAroundLink(state)) {
137
+ var pos = $from.pos - $from.textOffset;
138
+ var node = state.doc.nodeAt(pos);
139
+ return node && node.isText ? {
140
+ node: node,
141
+ pos: pos
142
+ } : undefined;
143
+ }
144
+ return undefined;
145
+ };
146
+ var getActiveText = function getActiveText(selection) {
147
+ var currentSlice = selection.content();
148
+ if (currentSlice.size === 0) {
149
+ return;
150
+ }
151
+ if (currentSlice.content.childCount === 1 && currentSlice.content.firstChild && selection instanceof _prosemirrorState.TextSelection) {
152
+ return currentSlice.content.firstChild.textContent;
153
+ }
154
+ return;
155
+ };
156
+ var stateKey = new _prosemirrorState.PluginKey('hyperlinkPlugin');
157
+ exports.stateKey = stateKey;
158
+ var plugin = function plugin(dispatch, editorAppearance) {
159
+ return new _safePlugin.SafePlugin({
160
+ state: {
161
+ init: function init(_, state) {
162
+ var canInsertLink = (0, _utils.canLinkBeCreatedInRange)(state.selection.from, state.selection.to)(state);
163
+ return {
164
+ activeText: getActiveText(state.selection),
165
+ canInsertLink: canInsertLink,
166
+ timesViewed: 0,
167
+ activeLinkMark: toState(undefined, _link3.LinkAction.SELECTION_CHANGE, state),
168
+ editorAppearance: editorAppearance
169
+ };
170
+ },
171
+ apply: function apply(tr, pluginState, oldState, newState) {
172
+ var state = pluginState;
173
+ var action = tr.getMeta(stateKey) && tr.getMeta(stateKey).type;
174
+ var inputMethod = tr.getMeta(stateKey) && tr.getMeta(stateKey).inputMethod;
175
+ if (tr.docChanged) {
176
+ state = {
177
+ activeText: state.activeText,
178
+ canInsertLink: (0, _utils.canLinkBeCreatedInRange)(newState.selection.from, newState.selection.to)(newState),
179
+ timesViewed: state.timesViewed,
180
+ inputMethod: inputMethod,
181
+ activeLinkMark: mapTransactionToState(state.activeLinkMark, tr),
182
+ editorAppearance: editorAppearance
183
+ };
184
+ }
185
+ if (action) {
186
+ var stateForAnalytics = [_link3.LinkAction.SHOW_INSERT_TOOLBAR, _link3.LinkAction.EDIT_INSERTED_TOOLBAR].includes(action) ? {
187
+ timesViewed: ++state.timesViewed,
188
+ searchSessionId: (0, _uuid.default)()
189
+ } : {
190
+ timesViewed: state.timesViewed,
191
+ searchSessionId: state.searchSessionId
192
+ };
193
+ state = _objectSpread({
194
+ activeText: state.activeText,
195
+ canInsertLink: state.canInsertLink,
196
+ inputMethod: inputMethod,
197
+ activeLinkMark: toState(state.activeLinkMark, action, newState),
198
+ editorAppearance: editorAppearance
199
+ }, stateForAnalytics);
200
+ }
201
+ var hasPositionChanged = oldState.selection.from !== newState.selection.from || oldState.selection.to !== newState.selection.to;
202
+ if (tr.selectionSet && hasPositionChanged) {
203
+ state = {
204
+ activeText: getActiveText(newState.selection),
205
+ canInsertLink: (0, _utils.canLinkBeCreatedInRange)(newState.selection.from, newState.selection.to)(newState),
206
+ activeLinkMark: toState(state.activeLinkMark, _link3.LinkAction.SELECTION_CHANGE, newState),
207
+ timesViewed: state.timesViewed,
208
+ searchSessionId: state.searchSessionId,
209
+ inputMethod: inputMethod,
210
+ editorAppearance: editorAppearance
211
+ };
212
+ }
213
+ if (!(0, _utils.shallowEqual)(state, pluginState)) {
214
+ dispatch(stateKey, state);
215
+ }
216
+ return state;
217
+ }
218
+ },
219
+ key: stateKey,
220
+ props: {
221
+ handleDOMEvents: {
222
+ mouseup: function mouseup(_, event) {
223
+ // this prevents redundant selection transaction when clicking on link
224
+ // link state will be update on slection change which happens on mousedown
225
+ if (isLinkDirectTarget(event)) {
226
+ event.preventDefault();
227
+ return true;
228
+ }
229
+ return false;
230
+ },
231
+ mousedown: function mousedown(view, event) {
232
+ // since link clicks are disallowed by browsers inside contenteditable
233
+ // so we need to handle shift+click selection ourselves in this case
234
+ if (!event.shiftKey || !isLinkDirectTarget(event)) {
235
+ return false;
236
+ }
237
+ var state = view.state;
238
+ var $anchor = state.selection.$anchor;
239
+ var newPosition = view.posAtCoords({
240
+ left: event.clientX,
241
+ top: event.clientY
242
+ });
243
+ if ((newPosition === null || newPosition === void 0 ? void 0 : newPosition.pos) != null && newPosition.pos !== $anchor.pos) {
244
+ var tr = state.tr.setSelection(_prosemirrorState.TextSelection.create(state.doc, $anchor.pos, newPosition.pos));
245
+ view.dispatch(tr);
246
+ return true;
247
+ }
248
+ return false;
249
+ }
250
+ }
251
+ }
252
+ });
253
+ };
254
+ exports.plugin = plugin;
255
+ function isLinkDirectTarget(event) {
256
+ return (event === null || event === void 0 ? void 0 : event.target) instanceof HTMLElement && event.target.tagName === 'A';
257
+ }
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.toolbarKey = exports.toolbarButtonsPlugin = exports.prependToolbarButtons = void 0;
7
+ var _prosemirrorState = require("prosemirror-state");
8
+ var _safePlugin = require("@atlaskit/editor-common/safe-plugin");
9
+ var toolbarKey = new _prosemirrorState.PluginKey('hyperlinkToolbarItems');
10
+ exports.toolbarKey = toolbarKey;
11
+ var prependToolbarButtons = function prependToolbarButtons(_ref) {
12
+ var items = _ref.items,
13
+ onEscapeCallback = _ref.onEscapeCallback,
14
+ onInsertLinkCallback = _ref.onInsertLinkCallback,
15
+ view = _ref.view;
16
+ var tr = view.state.tr,
17
+ dispatch = view.dispatch;
18
+ tr.setMeta(toolbarKey, {
19
+ items: items,
20
+ onEscapeCallback: onEscapeCallback,
21
+ onInsertLinkCallback: onInsertLinkCallback
22
+ });
23
+ dispatch(tr);
24
+ };
25
+ exports.prependToolbarButtons = prependToolbarButtons;
26
+ var toolbarButtonsPlugin = function toolbarButtonsPlugin() {
27
+ return new _safePlugin.SafePlugin({
28
+ key: toolbarKey,
29
+ state: {
30
+ init: function init(_, state) {
31
+ return undefined;
32
+ },
33
+ apply: function apply(tr, pluginState) {
34
+ var metaState = tr.getMeta(toolbarKey);
35
+ if (metaState) {
36
+ return metaState;
37
+ }
38
+ return pluginState;
39
+ }
40
+ }
41
+ });
42
+ };
43
+ exports.toolbarButtonsPlugin = toolbarButtonsPlugin;
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "@atlaskit/editor-plugin-hyperlink",
3
+ "version": "0.1.0",
4
+ "sideEffects": false
5
+ }