@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,85 @@
|
|
|
1
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
2
|
+
import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
3
|
+
import { addLinkMetadata } from '@atlaskit/editor-common/card';
|
|
4
|
+
import { findFilepaths, getLinkCreationAnalyticsEvent, isLinkInMatches, LinkMatcher, normalizeUrl } from '@atlaskit/editor-common/utils';
|
|
5
|
+
import { createPlugin, createRule } from '@atlaskit/prosemirror-input-rules';
|
|
6
|
+
export function createLinkInputRule(regexp) {
|
|
7
|
+
var skipAnalytics = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
8
|
+
var editorAnalyticsApi = arguments.length > 2 ? arguments[2] : undefined;
|
|
9
|
+
// Plain typed text (eg, typing 'www.google.com') should convert to a hyperlink
|
|
10
|
+
return createRule(regexp, function (state, match, start, end) {
|
|
11
|
+
var schema = state.schema;
|
|
12
|
+
if (state.doc.rangeHasMark(start, end, schema.marks.link)) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
var link = match;
|
|
16
|
+
var url = normalizeUrl(link.url);
|
|
17
|
+
var markType = schema.mark('link', {
|
|
18
|
+
href: url
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// Need access to complete text to check if last URL is part of a filepath before linkifying
|
|
22
|
+
var nodeBefore = state.selection.$from.nodeBefore;
|
|
23
|
+
if (!nodeBefore || !nodeBefore.isText || !nodeBefore.text) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
var filepaths = findFilepaths(nodeBefore.text,
|
|
27
|
+
// The position referenced by 'start' is relative to the start of the document, findFilepaths deals with index in a node only.
|
|
28
|
+
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
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
if (isLinkInMatches(start, filepaths)) {
|
|
32
|
+
var _tr = state.tr;
|
|
33
|
+
return _tr;
|
|
34
|
+
}
|
|
35
|
+
var from = start;
|
|
36
|
+
var to = Math.min(start + link.text.length, state.doc.content.size);
|
|
37
|
+
var tr = state.tr.addMark(from, to, markType);
|
|
38
|
+
|
|
39
|
+
// Keep old behavior that will delete the space after the link
|
|
40
|
+
if (to === end) {
|
|
41
|
+
tr.insertText(' ');
|
|
42
|
+
}
|
|
43
|
+
addLinkMetadata(state.selection, tr, {
|
|
44
|
+
inputMethod: INPUT_METHOD.AUTO_DETECT
|
|
45
|
+
});
|
|
46
|
+
if (skipAnalytics) {
|
|
47
|
+
return tr;
|
|
48
|
+
}
|
|
49
|
+
editorAnalyticsApi === null || editorAnalyticsApi === void 0 ? void 0 : editorAnalyticsApi.attachAnalyticsEvent(getLinkCreationAnalyticsEvent(INPUT_METHOD.AUTO_DETECT, url))(tr);
|
|
50
|
+
return tr;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
export function createInputRulePlugin(schema) {
|
|
54
|
+
var skipAnalytics = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
55
|
+
var featureFlags = arguments.length > 2 ? arguments[2] : undefined;
|
|
56
|
+
var editorAnalyticsApi = arguments.length > 3 ? arguments[3] : undefined;
|
|
57
|
+
if (!schema.marks.link) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
var urlWithASpaceRule = createLinkInputRule(LinkMatcher.create(), skipAnalytics, editorAnalyticsApi);
|
|
61
|
+
|
|
62
|
+
// [something](link) should convert to a hyperlink
|
|
63
|
+
var markdownLinkRule = createRule(/(^|[^!])\[(.*?)\]\((\S+)\)$/, function (state, match, start, end) {
|
|
64
|
+
var schema = state.schema;
|
|
65
|
+
var _match = _slicedToArray(match, 4),
|
|
66
|
+
prefix = _match[1],
|
|
67
|
+
linkText = _match[2],
|
|
68
|
+
linkUrl = _match[3];
|
|
69
|
+
var url = normalizeUrl(linkUrl).trim();
|
|
70
|
+
var markType = schema.mark('link', {
|
|
71
|
+
href: url
|
|
72
|
+
});
|
|
73
|
+
var tr = state.tr.replaceWith(start + prefix.length, end, schema.text((linkText || '').trim(), [markType]));
|
|
74
|
+
addLinkMetadata(state.selection, tr, {
|
|
75
|
+
inputMethod: INPUT_METHOD.FORMATTING
|
|
76
|
+
});
|
|
77
|
+
if (skipAnalytics) {
|
|
78
|
+
return tr;
|
|
79
|
+
}
|
|
80
|
+
editorAnalyticsApi === null || editorAnalyticsApi === void 0 ? void 0 : editorAnalyticsApi.attachAnalyticsEvent(getLinkCreationAnalyticsEvent(INPUT_METHOD.FORMATTING, url))(tr);
|
|
81
|
+
return tr;
|
|
82
|
+
});
|
|
83
|
+
return createPlugin('hyperlink', [urlWithASpaceRule, markdownLinkRule]);
|
|
84
|
+
}
|
|
85
|
+
export default createInputRulePlugin;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { keymap } from 'prosemirror-keymap';
|
|
2
|
+
import { getLinkMatch } from '@atlaskit/adf-schema';
|
|
3
|
+
import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
4
|
+
import { addLink, bindKeymapWithCommand, enter, escape, insertNewLine } from '@atlaskit/editor-common/keymaps';
|
|
5
|
+
import { findFilepaths, getLinkCreationAnalyticsEvent, isLinkInMatches } from '@atlaskit/editor-common/utils';
|
|
6
|
+
import { hideLinkToolbar, showLinkToolbar } from '../commands';
|
|
7
|
+
import { stateKey } from '../pm-plugins/main';
|
|
8
|
+
export function createKeymapPlugin() {
|
|
9
|
+
var skipAnalytics = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
10
|
+
var editorAnalyticsApi = arguments.length > 1 ? arguments[1] : undefined;
|
|
11
|
+
var list = {};
|
|
12
|
+
bindKeymapWithCommand(addLink.common, showLinkToolbar(INPUT_METHOD.SHORTCUT, editorAnalyticsApi), list);
|
|
13
|
+
bindKeymapWithCommand(enter.common, mayConvertLastWordToHyperlink(skipAnalytics, editorAnalyticsApi), list);
|
|
14
|
+
bindKeymapWithCommand(insertNewLine.common, mayConvertLastWordToHyperlink(skipAnalytics, editorAnalyticsApi), list);
|
|
15
|
+
bindKeymapWithCommand(escape.common, function (state, dispatch, view) {
|
|
16
|
+
var hyperlinkPlugin = stateKey.getState(state);
|
|
17
|
+
if (hyperlinkPlugin.activeLinkMark) {
|
|
18
|
+
hideLinkToolbar()(state, dispatch);
|
|
19
|
+
if (view) {
|
|
20
|
+
view.focus();
|
|
21
|
+
}
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
return false;
|
|
25
|
+
}, list);
|
|
26
|
+
return keymap(list);
|
|
27
|
+
}
|
|
28
|
+
var mayConvertLastWordToHyperlink = function mayConvertLastWordToHyperlink(skipAnalytics, editorAnalyticsApi) {
|
|
29
|
+
return function (state, dispatch) {
|
|
30
|
+
var nodeBefore = state.selection.$from.nodeBefore;
|
|
31
|
+
if (!nodeBefore || !nodeBefore.isText || !nodeBefore.text) {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
var words = nodeBefore.text.split(' ');
|
|
35
|
+
var lastWord = words[words.length - 1];
|
|
36
|
+
var match = getLinkMatch(lastWord);
|
|
37
|
+
if (match) {
|
|
38
|
+
var hyperlinkedText = match.raw;
|
|
39
|
+
var start = state.selection.$from.pos - hyperlinkedText.length;
|
|
40
|
+
var end = state.selection.$from.pos;
|
|
41
|
+
if (state.doc.rangeHasMark(start, end, state.schema.marks.link)) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
var url = match.url;
|
|
45
|
+
var markType = state.schema.mark('link', {
|
|
46
|
+
href: url
|
|
47
|
+
});
|
|
48
|
+
var filepaths = 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.
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
if (isLinkInMatches(start, filepaths)) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
var tr = state.tr.addMark(start, end, markType);
|
|
55
|
+
if (dispatch) {
|
|
56
|
+
if (skipAnalytics) {
|
|
57
|
+
dispatch(tr);
|
|
58
|
+
} else {
|
|
59
|
+
editorAnalyticsApi === null || editorAnalyticsApi === void 0 ? void 0 : editorAnalyticsApi.attachAnalyticsEvent(getLinkCreationAnalyticsEvent(INPUT_METHOD.AUTO_DETECT, url))(tr);
|
|
60
|
+
dispatch(tr);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return false;
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
export default createKeymapPlugin;
|
|
@@ -0,0 +1,248 @@
|
|
|
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 { PluginKey, TextSelection } from 'prosemirror-state';
|
|
5
|
+
import uuid from 'uuid';
|
|
6
|
+
import { InsertStatus, LinkAction } from '@atlaskit/editor-common/link';
|
|
7
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
8
|
+
import { canLinkBeCreatedInRange, shallowEqual } from '@atlaskit/editor-common/utils';
|
|
9
|
+
var isSelectionInsideLink = function isSelectionInsideLink(state) {
|
|
10
|
+
return !!state.doc.type.schema.marks.link.isInSet(state.selection.$from.marks());
|
|
11
|
+
};
|
|
12
|
+
var isSelectionAroundLink = function isSelectionAroundLink(state) {
|
|
13
|
+
var _state$selection = state.selection,
|
|
14
|
+
$from = _state$selection.$from,
|
|
15
|
+
$to = _state$selection.$to;
|
|
16
|
+
var node = $from.nodeAfter;
|
|
17
|
+
return !!node && $from.textOffset === 0 && $to.pos - $from.pos === node.nodeSize && !!state.doc.type.schema.marks.link.isInSet(node.marks);
|
|
18
|
+
};
|
|
19
|
+
var mapTransactionToState = function mapTransactionToState(state, tr) {
|
|
20
|
+
if (!state) {
|
|
21
|
+
return undefined;
|
|
22
|
+
} else if (state.type === InsertStatus.EDIT_LINK_TOOLBAR || state.type === InsertStatus.EDIT_INSERTED_TOOLBAR) {
|
|
23
|
+
var _tr$mapping$mapResult = tr.mapping.mapResult(state.pos, 1),
|
|
24
|
+
pos = _tr$mapping$mapResult.pos,
|
|
25
|
+
deleted = _tr$mapping$mapResult.deleted;
|
|
26
|
+
var node = tr.doc.nodeAt(pos);
|
|
27
|
+
// If the position was not deleted & it is still a link
|
|
28
|
+
if (!deleted && !!node.type.schema.marks.link.isInSet(node.marks)) {
|
|
29
|
+
if (node === state.node && pos === state.pos) {
|
|
30
|
+
return state;
|
|
31
|
+
}
|
|
32
|
+
return _objectSpread(_objectSpread({}, state), {}, {
|
|
33
|
+
pos: pos,
|
|
34
|
+
node: node
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
// If the position has been deleted, then require a navigation to show the toolbar again
|
|
38
|
+
return;
|
|
39
|
+
} else if (state.type === InsertStatus.INSERT_LINK_TOOLBAR) {
|
|
40
|
+
return _objectSpread(_objectSpread({}, state), {}, {
|
|
41
|
+
from: tr.mapping.map(state.from),
|
|
42
|
+
to: tr.mapping.map(state.to)
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
return;
|
|
46
|
+
};
|
|
47
|
+
var toState = function toState(state, action, editorState) {
|
|
48
|
+
// Show insert or edit toolbar
|
|
49
|
+
if (!state) {
|
|
50
|
+
switch (action) {
|
|
51
|
+
case LinkAction.SHOW_INSERT_TOOLBAR:
|
|
52
|
+
{
|
|
53
|
+
var _editorState$selectio = editorState.selection,
|
|
54
|
+
from = _editorState$selectio.from,
|
|
55
|
+
to = _editorState$selectio.to;
|
|
56
|
+
if (canLinkBeCreatedInRange(from, to)(editorState)) {
|
|
57
|
+
return {
|
|
58
|
+
type: InsertStatus.INSERT_LINK_TOOLBAR,
|
|
59
|
+
from: from,
|
|
60
|
+
to: to
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
case LinkAction.SELECTION_CHANGE:
|
|
66
|
+
// If the user has moved their cursor, see if they're in a link
|
|
67
|
+
var link = getActiveLinkMark(editorState);
|
|
68
|
+
if (link) {
|
|
69
|
+
return _objectSpread(_objectSpread({}, link), {}, {
|
|
70
|
+
type: InsertStatus.EDIT_LINK_TOOLBAR
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
return undefined;
|
|
74
|
+
default:
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// Update toolbar state if selection changes, or if toolbar is hidden
|
|
79
|
+
if (state.type === InsertStatus.EDIT_LINK_TOOLBAR) {
|
|
80
|
+
switch (action) {
|
|
81
|
+
case LinkAction.EDIT_INSERTED_TOOLBAR:
|
|
82
|
+
{
|
|
83
|
+
var _link = getActiveLinkMark(editorState);
|
|
84
|
+
if (_link) {
|
|
85
|
+
if (_link.pos === state.pos && _link.node === state.node) {
|
|
86
|
+
return _objectSpread(_objectSpread({}, state), {}, {
|
|
87
|
+
type: InsertStatus.EDIT_INSERTED_TOOLBAR
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
return _objectSpread(_objectSpread({}, _link), {}, {
|
|
91
|
+
type: InsertStatus.EDIT_INSERTED_TOOLBAR
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
case LinkAction.SELECTION_CHANGE:
|
|
97
|
+
var _link2 = getActiveLinkMark(editorState);
|
|
98
|
+
if (_link2) {
|
|
99
|
+
if (_link2.pos === state.pos && _link2.node === state.node) {
|
|
100
|
+
// Make sure we return the same object, if it's the same link
|
|
101
|
+
return state;
|
|
102
|
+
}
|
|
103
|
+
return _objectSpread(_objectSpread({}, _link2), {}, {
|
|
104
|
+
type: InsertStatus.EDIT_LINK_TOOLBAR
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
return undefined;
|
|
108
|
+
case LinkAction.HIDE_TOOLBAR:
|
|
109
|
+
return undefined;
|
|
110
|
+
default:
|
|
111
|
+
return state;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Remove toolbar if user changes selection or toolbar is hidden
|
|
116
|
+
if (state.type === InsertStatus.INSERT_LINK_TOOLBAR) {
|
|
117
|
+
switch (action) {
|
|
118
|
+
case LinkAction.SELECTION_CHANGE:
|
|
119
|
+
case LinkAction.HIDE_TOOLBAR:
|
|
120
|
+
return undefined;
|
|
121
|
+
default:
|
|
122
|
+
return state;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return;
|
|
126
|
+
};
|
|
127
|
+
var getActiveLinkMark = function getActiveLinkMark(state) {
|
|
128
|
+
var $from = state.selection.$from;
|
|
129
|
+
if (isSelectionInsideLink(state) || isSelectionAroundLink(state)) {
|
|
130
|
+
var pos = $from.pos - $from.textOffset;
|
|
131
|
+
var node = state.doc.nodeAt(pos);
|
|
132
|
+
return node && node.isText ? {
|
|
133
|
+
node: node,
|
|
134
|
+
pos: pos
|
|
135
|
+
} : undefined;
|
|
136
|
+
}
|
|
137
|
+
return undefined;
|
|
138
|
+
};
|
|
139
|
+
var getActiveText = function getActiveText(selection) {
|
|
140
|
+
var currentSlice = selection.content();
|
|
141
|
+
if (currentSlice.size === 0) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
if (currentSlice.content.childCount === 1 && currentSlice.content.firstChild && selection instanceof TextSelection) {
|
|
145
|
+
return currentSlice.content.firstChild.textContent;
|
|
146
|
+
}
|
|
147
|
+
return;
|
|
148
|
+
};
|
|
149
|
+
export var stateKey = new PluginKey('hyperlinkPlugin');
|
|
150
|
+
export var plugin = function plugin(dispatch, editorAppearance) {
|
|
151
|
+
return new SafePlugin({
|
|
152
|
+
state: {
|
|
153
|
+
init: function init(_, state) {
|
|
154
|
+
var canInsertLink = canLinkBeCreatedInRange(state.selection.from, state.selection.to)(state);
|
|
155
|
+
return {
|
|
156
|
+
activeText: getActiveText(state.selection),
|
|
157
|
+
canInsertLink: canInsertLink,
|
|
158
|
+
timesViewed: 0,
|
|
159
|
+
activeLinkMark: toState(undefined, LinkAction.SELECTION_CHANGE, state),
|
|
160
|
+
editorAppearance: editorAppearance
|
|
161
|
+
};
|
|
162
|
+
},
|
|
163
|
+
apply: function apply(tr, pluginState, oldState, newState) {
|
|
164
|
+
var state = pluginState;
|
|
165
|
+
var action = tr.getMeta(stateKey) && tr.getMeta(stateKey).type;
|
|
166
|
+
var inputMethod = tr.getMeta(stateKey) && tr.getMeta(stateKey).inputMethod;
|
|
167
|
+
if (tr.docChanged) {
|
|
168
|
+
state = {
|
|
169
|
+
activeText: state.activeText,
|
|
170
|
+
canInsertLink: canLinkBeCreatedInRange(newState.selection.from, newState.selection.to)(newState),
|
|
171
|
+
timesViewed: state.timesViewed,
|
|
172
|
+
inputMethod: inputMethod,
|
|
173
|
+
activeLinkMark: mapTransactionToState(state.activeLinkMark, tr),
|
|
174
|
+
editorAppearance: editorAppearance
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
if (action) {
|
|
178
|
+
var stateForAnalytics = [LinkAction.SHOW_INSERT_TOOLBAR, LinkAction.EDIT_INSERTED_TOOLBAR].includes(action) ? {
|
|
179
|
+
timesViewed: ++state.timesViewed,
|
|
180
|
+
searchSessionId: uuid()
|
|
181
|
+
} : {
|
|
182
|
+
timesViewed: state.timesViewed,
|
|
183
|
+
searchSessionId: state.searchSessionId
|
|
184
|
+
};
|
|
185
|
+
state = _objectSpread({
|
|
186
|
+
activeText: state.activeText,
|
|
187
|
+
canInsertLink: state.canInsertLink,
|
|
188
|
+
inputMethod: inputMethod,
|
|
189
|
+
activeLinkMark: toState(state.activeLinkMark, action, newState),
|
|
190
|
+
editorAppearance: editorAppearance
|
|
191
|
+
}, stateForAnalytics);
|
|
192
|
+
}
|
|
193
|
+
var hasPositionChanged = oldState.selection.from !== newState.selection.from || oldState.selection.to !== newState.selection.to;
|
|
194
|
+
if (tr.selectionSet && hasPositionChanged) {
|
|
195
|
+
state = {
|
|
196
|
+
activeText: getActiveText(newState.selection),
|
|
197
|
+
canInsertLink: canLinkBeCreatedInRange(newState.selection.from, newState.selection.to)(newState),
|
|
198
|
+
activeLinkMark: toState(state.activeLinkMark, LinkAction.SELECTION_CHANGE, newState),
|
|
199
|
+
timesViewed: state.timesViewed,
|
|
200
|
+
searchSessionId: state.searchSessionId,
|
|
201
|
+
inputMethod: inputMethod,
|
|
202
|
+
editorAppearance: editorAppearance
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
if (!shallowEqual(state, pluginState)) {
|
|
206
|
+
dispatch(stateKey, state);
|
|
207
|
+
}
|
|
208
|
+
return state;
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
key: stateKey,
|
|
212
|
+
props: {
|
|
213
|
+
handleDOMEvents: {
|
|
214
|
+
mouseup: function mouseup(_, event) {
|
|
215
|
+
// this prevents redundant selection transaction when clicking on link
|
|
216
|
+
// link state will be update on slection change which happens on mousedown
|
|
217
|
+
if (isLinkDirectTarget(event)) {
|
|
218
|
+
event.preventDefault();
|
|
219
|
+
return true;
|
|
220
|
+
}
|
|
221
|
+
return false;
|
|
222
|
+
},
|
|
223
|
+
mousedown: function mousedown(view, event) {
|
|
224
|
+
// since link clicks are disallowed by browsers inside contenteditable
|
|
225
|
+
// so we need to handle shift+click selection ourselves in this case
|
|
226
|
+
if (!event.shiftKey || !isLinkDirectTarget(event)) {
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
229
|
+
var state = view.state;
|
|
230
|
+
var $anchor = state.selection.$anchor;
|
|
231
|
+
var newPosition = view.posAtCoords({
|
|
232
|
+
left: event.clientX,
|
|
233
|
+
top: event.clientY
|
|
234
|
+
});
|
|
235
|
+
if ((newPosition === null || newPosition === void 0 ? void 0 : newPosition.pos) != null && newPosition.pos !== $anchor.pos) {
|
|
236
|
+
var tr = state.tr.setSelection(TextSelection.create(state.doc, $anchor.pos, newPosition.pos));
|
|
237
|
+
view.dispatch(tr);
|
|
238
|
+
return true;
|
|
239
|
+
}
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
};
|
|
246
|
+
function isLinkDirectTarget(event) {
|
|
247
|
+
return (event === null || event === void 0 ? void 0 : event.target) instanceof HTMLElement && event.target.tagName === 'A';
|
|
248
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { PluginKey } from 'prosemirror-state';
|
|
2
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
3
|
+
export var toolbarKey = new PluginKey('hyperlinkToolbarItems');
|
|
4
|
+
export var prependToolbarButtons = function prependToolbarButtons(_ref) {
|
|
5
|
+
var items = _ref.items,
|
|
6
|
+
onEscapeCallback = _ref.onEscapeCallback,
|
|
7
|
+
onInsertLinkCallback = _ref.onInsertLinkCallback,
|
|
8
|
+
view = _ref.view;
|
|
9
|
+
var tr = view.state.tr,
|
|
10
|
+
dispatch = view.dispatch;
|
|
11
|
+
tr.setMeta(toolbarKey, {
|
|
12
|
+
items: items,
|
|
13
|
+
onEscapeCallback: onEscapeCallback,
|
|
14
|
+
onInsertLinkCallback: onInsertLinkCallback
|
|
15
|
+
});
|
|
16
|
+
dispatch(tr);
|
|
17
|
+
};
|
|
18
|
+
export var toolbarButtonsPlugin = function toolbarButtonsPlugin() {
|
|
19
|
+
return new SafePlugin({
|
|
20
|
+
key: toolbarKey,
|
|
21
|
+
state: {
|
|
22
|
+
init: function init(_, state) {
|
|
23
|
+
return undefined;
|
|
24
|
+
},
|
|
25
|
+
apply: function apply(tr, pluginState) {
|
|
26
|
+
var metaState = tr.getMeta(toolbarKey);
|
|
27
|
+
if (metaState) {
|
|
28
|
+
return metaState;
|
|
29
|
+
}
|
|
30
|
+
return pluginState;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { HyperlinkAddToolbarProps } from '@atlaskit/editor-common/link';
|
|
3
|
+
import type { ExtractInjectionAPI, FeatureFlags, FloatingToolbarHandler, HyperlinkPluginOptions } from '@atlaskit/editor-common/types';
|
|
4
|
+
import type { hyperlinkPlugin } from './index';
|
|
5
|
+
export declare function HyperlinkAddToolbarWithState({ linkPickerOptions, onSubmit, displayText, displayUrl, providerFactory, view, onCancel, invokeMethod, featureFlags, onClose, onEscapeCallback, onClickAwayCallback, pluginInjectionApi, }: HyperlinkAddToolbarProps & {
|
|
6
|
+
pluginInjectionApi: any;
|
|
7
|
+
}): JSX.Element;
|
|
8
|
+
export declare const getToolbarConfig: (options: HyperlinkPluginOptions, featureFlags: FeatureFlags, pluginInjectionApi: ExtractInjectionAPI<typeof hyperlinkPlugin> | undefined) => FloatingToolbarHandler;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Transaction } from 'prosemirror-state';
|
|
2
|
+
import { UIAnalyticsEvent } from '@atlaskit/analytics-next';
|
|
3
|
+
import { EditorAnalyticsAPI, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
4
|
+
import type { Command, LinkInputType } from '@atlaskit/editor-common/types';
|
|
5
|
+
export declare function setLinkHref(href: string, pos: number, editorAnalyticsApi: EditorAnalyticsAPI | undefined, to?: number, isTabPressed?: boolean): Command;
|
|
6
|
+
export declare function updateLink(href: string, text: string, pos: number, to?: number): Command;
|
|
7
|
+
export declare function insertLink(from: number, to: number, incomingHref: string, incomingTitle?: string, displayText?: string, source?: LinkInputType, sourceEvent?: UIAnalyticsEvent | null | undefined): Command;
|
|
8
|
+
export declare const insertLinkWithAnalytics: (inputMethod: LinkInputType, from: number, to: number, href: string, editorAnalyticsApi: EditorAnalyticsAPI | undefined, title?: string, displayText?: string, cardsAvailable?: boolean, sourceEvent?: UIAnalyticsEvent | null | undefined) => Command;
|
|
9
|
+
export declare const insertLinkWithAnalyticsMobileNative: (inputMethod: LinkInputType, from: number, to: number, href: string, editorAnalyticsApi: EditorAnalyticsAPI | undefined, title?: string, displayText?: string) => Command;
|
|
10
|
+
export declare function removeLink(pos: number, editorAnalyticsApi: EditorAnalyticsAPI | undefined): Command;
|
|
11
|
+
export declare function editInsertedLink(editorAnalyticsApi: EditorAnalyticsAPI | undefined): Command;
|
|
12
|
+
type InputMethod = INPUT_METHOD.TOOLBAR | INPUT_METHOD.QUICK_INSERT | INPUT_METHOD.SHORTCUT | INPUT_METHOD.INSERT_MENU;
|
|
13
|
+
export type ShowLinkToolbar = (inputMethod: InputMethod) => Command;
|
|
14
|
+
export declare function showLinkToolbar(inputMethod: InputMethod, editorAnalyticsApi: EditorAnalyticsAPI | undefined): Command;
|
|
15
|
+
export declare function hideLinkToolbar(): Command;
|
|
16
|
+
export type HideLinkToolbar = (tr: Transaction) => Transaction;
|
|
17
|
+
export declare const hideLinkToolbarSetMeta: HideLinkToolbar;
|
|
18
|
+
export declare const onEscapeCallback: Command;
|
|
19
|
+
export declare const onClickAwayCallback: Command;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { HyperlinkState } from '@atlaskit/editor-common/link';
|
|
2
|
+
import type { HyperlinkPluginOptions, NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/types';
|
|
3
|
+
import type { analyticsPlugin } from '@atlaskit/editor-plugin-analytics';
|
|
4
|
+
import type featureFlagsPlugin from '@atlaskit/editor-plugin-feature-flags';
|
|
5
|
+
import { HideLinkToolbar, ShowLinkToolbar } from './commands';
|
|
6
|
+
import { PrependToolbarButtons } from './pm-plugins/toolbar-buttons';
|
|
7
|
+
export declare const hyperlinkPlugin: NextEditorPlugin<'hyperlink', {
|
|
8
|
+
pluginConfiguration: HyperlinkPluginOptions | undefined;
|
|
9
|
+
dependencies: [
|
|
10
|
+
typeof featureFlagsPlugin,
|
|
11
|
+
OptionalPlugin<typeof analyticsPlugin>
|
|
12
|
+
];
|
|
13
|
+
actions: {
|
|
14
|
+
/**
|
|
15
|
+
* Add items to the left of the hyperlink floating toolbar
|
|
16
|
+
* @param props
|
|
17
|
+
* -
|
|
18
|
+
* - items: Retrieve floating toolbar items to add
|
|
19
|
+
* - onEscapeCallback (optional): To be called when the link picker is escaped.
|
|
20
|
+
* - onInsertLinkCallback (optional): To be called when a link is inserted and it can be changed into a card.
|
|
21
|
+
*/
|
|
22
|
+
prependToolbarButtons: PrependToolbarButtons;
|
|
23
|
+
/**
|
|
24
|
+
* Higher-order Command to show link toolbar.
|
|
25
|
+
*
|
|
26
|
+
* Example:
|
|
27
|
+
*
|
|
28
|
+
* ```
|
|
29
|
+
* pluginInjectionApi?.dependencies.hyperlink.actions.showLinkToolbar(
|
|
30
|
+
* inputMethod
|
|
31
|
+
* )(state, dispatch)
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
showLinkToolbar: ShowLinkToolbar;
|
|
35
|
+
hideLinkToolbar: HideLinkToolbar;
|
|
36
|
+
};
|
|
37
|
+
sharedState: HyperlinkState | undefined;
|
|
38
|
+
}>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Schema } from 'prosemirror-model';
|
|
2
|
+
import { EditorAnalyticsAPI } from '@atlaskit/editor-common/analytics';
|
|
3
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
4
|
+
import type { FeatureFlags } from '@atlaskit/editor-common/types';
|
|
5
|
+
import type { InputRuleWrapper } from '@atlaskit/prosemirror-input-rules';
|
|
6
|
+
export declare function createLinkInputRule(regexp: RegExp, skipAnalytics: boolean | undefined, editorAnalyticsApi: EditorAnalyticsAPI | undefined): InputRuleWrapper;
|
|
7
|
+
export declare function createInputRulePlugin(schema: Schema, skipAnalytics: boolean | undefined, featureFlags: FeatureFlags, editorAnalyticsApi: EditorAnalyticsAPI | undefined): SafePlugin | undefined;
|
|
8
|
+
export default createInputRulePlugin;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { EditorAnalyticsAPI } from '@atlaskit/editor-common/analytics';
|
|
2
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
3
|
+
export declare function createKeymapPlugin(skipAnalytics: boolean | undefined, editorAnalyticsApi: EditorAnalyticsAPI | undefined): SafePlugin | undefined;
|
|
4
|
+
export default createKeymapPlugin;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { PluginKey } from 'prosemirror-state';
|
|
2
|
+
import { Dispatch } from '@atlaskit/editor-common/event-dispatcher';
|
|
3
|
+
import { HyperlinkState } from '@atlaskit/editor-common/link';
|
|
4
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
5
|
+
import { EditorAppearance } from '@atlaskit/editor-common/types';
|
|
6
|
+
export declare const stateKey: PluginKey<HyperlinkState>;
|
|
7
|
+
export declare const plugin: (dispatch: Dispatch, editorAppearance?: EditorAppearance) => SafePlugin<HyperlinkState>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { EditorState, PluginKey, Transaction } from 'prosemirror-state';
|
|
2
|
+
import { EditorView } from 'prosemirror-view';
|
|
3
|
+
import type { IntlShape } from 'react-intl-next';
|
|
4
|
+
import type { QueueCardsFromTransactionAction } from '@atlaskit/editor-common/card';
|
|
5
|
+
import type { ProviderFactory } from '@atlaskit/editor-common/provider-factory';
|
|
6
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
7
|
+
import { FloatingToolbarItem } from '@atlaskit/editor-common/types';
|
|
8
|
+
type HyperlinkToolbarItemsState = {
|
|
9
|
+
items: GetToolbarItems;
|
|
10
|
+
onEscapeCallback: ((tr: Transaction) => Transaction) | undefined;
|
|
11
|
+
onInsertLinkCallback: QueueCardsFromTransactionAction | undefined;
|
|
12
|
+
};
|
|
13
|
+
export declare const toolbarKey: PluginKey<HyperlinkToolbarItemsState | undefined>;
|
|
14
|
+
type GetToolbarItems = (state: EditorState, intl: IntlShape, providerFactory: ProviderFactory, link: string) => FloatingToolbarItem<any>[];
|
|
15
|
+
interface PrependToolbarButtonsProps extends HyperlinkToolbarItemsState {
|
|
16
|
+
view: EditorView;
|
|
17
|
+
}
|
|
18
|
+
export type PrependToolbarButtons = (props: PrependToolbarButtonsProps) => void;
|
|
19
|
+
export declare const prependToolbarButtons: ({ items, onEscapeCallback, onInsertLinkCallback, view, }: PrependToolbarButtonsProps) => void;
|
|
20
|
+
export declare const toolbarButtonsPlugin: () => SafePlugin<HyperlinkToolbarItemsState | undefined>;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { HyperlinkAddToolbarProps } from '@atlaskit/editor-common/link';
|
|
3
|
+
import type { ExtractInjectionAPI, FeatureFlags, FloatingToolbarHandler, HyperlinkPluginOptions } from '@atlaskit/editor-common/types';
|
|
4
|
+
import type { hyperlinkPlugin } from './index';
|
|
5
|
+
export declare function HyperlinkAddToolbarWithState({ linkPickerOptions, onSubmit, displayText, displayUrl, providerFactory, view, onCancel, invokeMethod, featureFlags, onClose, onEscapeCallback, onClickAwayCallback, pluginInjectionApi, }: HyperlinkAddToolbarProps & {
|
|
6
|
+
pluginInjectionApi: any;
|
|
7
|
+
}): JSX.Element;
|
|
8
|
+
export declare const getToolbarConfig: (options: HyperlinkPluginOptions, featureFlags: FeatureFlags, pluginInjectionApi: ExtractInjectionAPI<typeof hyperlinkPlugin> | undefined) => FloatingToolbarHandler;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Transaction } from 'prosemirror-state';
|
|
2
|
+
import { UIAnalyticsEvent } from '@atlaskit/analytics-next';
|
|
3
|
+
import { EditorAnalyticsAPI, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
4
|
+
import type { Command, LinkInputType } from '@atlaskit/editor-common/types';
|
|
5
|
+
export declare function setLinkHref(href: string, pos: number, editorAnalyticsApi: EditorAnalyticsAPI | undefined, to?: number, isTabPressed?: boolean): Command;
|
|
6
|
+
export declare function updateLink(href: string, text: string, pos: number, to?: number): Command;
|
|
7
|
+
export declare function insertLink(from: number, to: number, incomingHref: string, incomingTitle?: string, displayText?: string, source?: LinkInputType, sourceEvent?: UIAnalyticsEvent | null | undefined): Command;
|
|
8
|
+
export declare const insertLinkWithAnalytics: (inputMethod: LinkInputType, from: number, to: number, href: string, editorAnalyticsApi: EditorAnalyticsAPI | undefined, title?: string, displayText?: string, cardsAvailable?: boolean, sourceEvent?: UIAnalyticsEvent | null | undefined) => Command;
|
|
9
|
+
export declare const insertLinkWithAnalyticsMobileNative: (inputMethod: LinkInputType, from: number, to: number, href: string, editorAnalyticsApi: EditorAnalyticsAPI | undefined, title?: string, displayText?: string) => Command;
|
|
10
|
+
export declare function removeLink(pos: number, editorAnalyticsApi: EditorAnalyticsAPI | undefined): Command;
|
|
11
|
+
export declare function editInsertedLink(editorAnalyticsApi: EditorAnalyticsAPI | undefined): Command;
|
|
12
|
+
type InputMethod = INPUT_METHOD.TOOLBAR | INPUT_METHOD.QUICK_INSERT | INPUT_METHOD.SHORTCUT | INPUT_METHOD.INSERT_MENU;
|
|
13
|
+
export type ShowLinkToolbar = (inputMethod: InputMethod) => Command;
|
|
14
|
+
export declare function showLinkToolbar(inputMethod: InputMethod, editorAnalyticsApi: EditorAnalyticsAPI | undefined): Command;
|
|
15
|
+
export declare function hideLinkToolbar(): Command;
|
|
16
|
+
export type HideLinkToolbar = (tr: Transaction) => Transaction;
|
|
17
|
+
export declare const hideLinkToolbarSetMeta: HideLinkToolbar;
|
|
18
|
+
export declare const onEscapeCallback: Command;
|
|
19
|
+
export declare const onClickAwayCallback: Command;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { HyperlinkState } from '@atlaskit/editor-common/link';
|
|
2
|
+
import type { HyperlinkPluginOptions, NextEditorPlugin, OptionalPlugin } from '@atlaskit/editor-common/types';
|
|
3
|
+
import type { analyticsPlugin } from '@atlaskit/editor-plugin-analytics';
|
|
4
|
+
import type featureFlagsPlugin from '@atlaskit/editor-plugin-feature-flags';
|
|
5
|
+
import { HideLinkToolbar, ShowLinkToolbar } from './commands';
|
|
6
|
+
import { PrependToolbarButtons } from './pm-plugins/toolbar-buttons';
|
|
7
|
+
export declare const hyperlinkPlugin: NextEditorPlugin<'hyperlink', {
|
|
8
|
+
pluginConfiguration: HyperlinkPluginOptions | undefined;
|
|
9
|
+
dependencies: [
|
|
10
|
+
typeof featureFlagsPlugin,
|
|
11
|
+
OptionalPlugin<typeof analyticsPlugin>
|
|
12
|
+
];
|
|
13
|
+
actions: {
|
|
14
|
+
/**
|
|
15
|
+
* Add items to the left of the hyperlink floating toolbar
|
|
16
|
+
* @param props
|
|
17
|
+
* -
|
|
18
|
+
* - items: Retrieve floating toolbar items to add
|
|
19
|
+
* - onEscapeCallback (optional): To be called when the link picker is escaped.
|
|
20
|
+
* - onInsertLinkCallback (optional): To be called when a link is inserted and it can be changed into a card.
|
|
21
|
+
*/
|
|
22
|
+
prependToolbarButtons: PrependToolbarButtons;
|
|
23
|
+
/**
|
|
24
|
+
* Higher-order Command to show link toolbar.
|
|
25
|
+
*
|
|
26
|
+
* Example:
|
|
27
|
+
*
|
|
28
|
+
* ```
|
|
29
|
+
* pluginInjectionApi?.dependencies.hyperlink.actions.showLinkToolbar(
|
|
30
|
+
* inputMethod
|
|
31
|
+
* )(state, dispatch)
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
showLinkToolbar: ShowLinkToolbar;
|
|
35
|
+
hideLinkToolbar: HideLinkToolbar;
|
|
36
|
+
};
|
|
37
|
+
sharedState: HyperlinkState | undefined;
|
|
38
|
+
}>;
|