@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.
- package/.eslintrc.js +6 -0
- package/CHANGELOG.md +1 -0
- package/LICENSE.md +13 -0
- package/README.md +7 -0
- package/dist/cjs/Toolbar.js +280 -0
- package/dist/cjs/commands.js +242 -0
- package/dist/cjs/index.js +12 -0
- package/dist/cjs/plugin.js +122 -0
- package/dist/cjs/pm-plugins/fake-curor-for-toolbar-plugin-key.js +9 -0
- package/dist/cjs/pm-plugins/fake-cursor-for-toolbar.js +68 -0
- package/dist/cjs/pm-plugins/input-rule.js +95 -0
- package/dist/cjs/pm-plugins/keymap.js +75 -0
- package/dist/cjs/pm-plugins/main.js +257 -0
- package/dist/cjs/pm-plugins/toolbar-buttons.js +43 -0
- package/dist/cjs/version.json +5 -0
- package/dist/es2019/Toolbar.js +260 -0
- package/dist/es2019/commands.js +225 -0
- package/dist/es2019/index.js +1 -0
- package/dist/es2019/plugin.js +106 -0
- package/dist/es2019/pm-plugins/fake-curor-for-toolbar-plugin-key.js +2 -0
- package/dist/es2019/pm-plugins/fake-cursor-for-toolbar.js +63 -0
- package/dist/es2019/pm-plugins/input-rule.js +80 -0
- package/dist/es2019/pm-plugins/keymap.js +65 -0
- package/dist/es2019/pm-plugins/main.js +261 -0
- package/dist/es2019/pm-plugins/toolbar-buttons.js +39 -0
- package/dist/es2019/version.json +5 -0
- package/dist/esm/Toolbar.js +271 -0
- package/dist/esm/commands.js +222 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/plugin.js +114 -0
- package/dist/esm/pm-plugins/fake-curor-for-toolbar-plugin-key.js +2 -0
- package/dist/esm/pm-plugins/fake-cursor-for-toolbar.js +61 -0
- package/dist/esm/pm-plugins/input-rule.js +85 -0
- package/dist/esm/pm-plugins/keymap.js +67 -0
- package/dist/esm/pm-plugins/main.js +248 -0
- package/dist/esm/pm-plugins/toolbar-buttons.js +34 -0
- package/dist/esm/version.json +5 -0
- package/dist/types/Toolbar.d.ts +8 -0
- package/dist/types/commands.d.ts +20 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/plugin.d.ts +38 -0
- package/dist/types/pm-plugins/fake-curor-for-toolbar-plugin-key.d.ts +2 -0
- package/dist/types/pm-plugins/fake-cursor-for-toolbar.d.ts +3 -0
- package/dist/types/pm-plugins/input-rule.d.ts +8 -0
- package/dist/types/pm-plugins/keymap.d.ts +4 -0
- package/dist/types/pm-plugins/main.d.ts +7 -0
- package/dist/types/pm-plugins/toolbar-buttons.d.ts +21 -0
- package/dist/types-ts4.5/Toolbar.d.ts +8 -0
- package/dist/types-ts4.5/commands.d.ts +20 -0
- package/dist/types-ts4.5/index.d.ts +3 -0
- package/dist/types-ts4.5/plugin.d.ts +38 -0
- package/dist/types-ts4.5/pm-plugins/fake-curor-for-toolbar-plugin-key.d.ts +2 -0
- package/dist/types-ts4.5/pm-plugins/fake-cursor-for-toolbar.d.ts +3 -0
- package/dist/types-ts4.5/pm-plugins/input-rule.d.ts +8 -0
- package/dist/types-ts4.5/pm-plugins/keymap.d.ts +4 -0
- package/dist/types-ts4.5/pm-plugins/main.d.ts +7 -0
- package/dist/types-ts4.5/pm-plugins/toolbar-buttons.d.ts +21 -0
- package/package.json +107 -0
- 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;
|