@atlaskit/editor-core 182.0.2 → 182.1.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 +2 -0
- package/CHANGELOG.md +46 -0
- package/README.md +20 -0
- package/architecture/0001-record-architecture-decisions.md +25 -0
- package/architecture/0002-deep-equality-check-for-getsharedstate.md +67 -0
- package/architecture/0003-explicit-plugin-dependencies.md +291 -0
- package/dist/cjs/actions/index.js +17 -6
- package/dist/cjs/analytics-api/attach-payload-into-transaction.js +2 -1
- package/dist/cjs/create-editor/ErrorBoundary.js +1 -16
- package/dist/cjs/create-editor/ReactEditorViewInternal.js +3 -3
- package/dist/cjs/editor-next/editor-internal.js +2 -1
- package/dist/cjs/editor-next/index.js +5 -1
- package/dist/cjs/editor.js +9 -5
- package/dist/cjs/keymaps/index.js +12 -0
- package/dist/cjs/labs/next/internal/hooks/use-editor/index.js +5 -7
- package/dist/cjs/labs/next/presets/default.js +1 -2
- package/dist/cjs/plugins/card/index.js +16 -5
- package/dist/cjs/plugins/card/pm-plugins/actions.js +10 -1
- package/dist/cjs/plugins/card/pm-plugins/analytics/create-analytics-queue.js +48 -0
- package/dist/cjs/plugins/card/pm-plugins/analytics/events-from-tr.js +337 -0
- package/dist/cjs/plugins/card/pm-plugins/analytics/index.js +19 -0
- package/dist/cjs/plugins/card/pm-plugins/analytics/types.js +5 -0
- package/dist/cjs/plugins/card/pm-plugins/analytics/utils.js +139 -0
- package/dist/cjs/plugins/card/pm-plugins/doc.js +99 -22
- package/dist/cjs/plugins/card/pm-plugins/main.js +16 -10
- package/dist/cjs/plugins/card/pm-plugins/reducers.js +7 -0
- package/dist/cjs/plugins/card/pm-plugins/util/resolve.js +3 -7
- package/dist/cjs/plugins/card/toolbar.js +18 -8
- package/dist/cjs/plugins/card/ui/EditLinkToolbar.js +12 -8
- package/dist/cjs/plugins/card/ui/EditorSmartCardEventsNext.js +202 -0
- package/dist/cjs/plugins/card/ui/LinkToolbarAppearance.js +12 -4
- package/dist/cjs/plugins/card/utils.js +4 -2
- package/dist/cjs/plugins/extension/context-panel.js +3 -2
- package/dist/cjs/plugins/extension/index.js +4 -1
- package/dist/cjs/plugins/help-dialog/ui/index.js +29 -8
- package/dist/cjs/plugins/hyperlink/Toolbar.js +12 -2
- package/dist/cjs/plugins/hyperlink/commands.js +9 -5
- package/dist/cjs/plugins/hyperlink/pm-plugins/input-rule.js +4 -0
- package/dist/cjs/plugins/hyperlink/ui/HyperlinkAddToolbar/index.js +2 -2
- package/dist/cjs/plugins/index.js +0 -7
- package/dist/cjs/plugins/insert-block/index.js +5 -1
- package/dist/cjs/plugins/insert-block/ui/ToolbarInsertBlock/index.js +25 -23
- package/dist/cjs/plugins/media/index.js +9 -5
- package/dist/cjs/plugins/media/nodeviews/mediaNodeView/media.js +7 -1
- package/dist/cjs/plugins/media/pm-plugins/main.js +5 -4
- package/dist/cjs/plugins/media/utils/media-single.js +1 -4
- package/dist/cjs/plugins/panel/pm-plugins/keymaps.js +2 -1
- package/dist/cjs/plugins/paste/handlers.js +5 -5
- package/dist/cjs/plugins/paste/index.js +4 -2
- package/dist/cjs/plugins/paste/pm-plugins/main.js +6 -4
- package/dist/cjs/plugins/rule/commands.js +2 -2
- package/dist/cjs/plugins/rule/index.js +5 -4
- package/dist/cjs/plugins/rule/pm-plugins/input-rule.js +6 -8
- package/dist/cjs/plugins/rule/pm-plugins/keymap.js +2 -2
- package/dist/cjs/plugins/text-color/index.js +5 -2
- package/dist/cjs/plugins/text-color/ui/ToolbarTextColor/index.js +3 -4
- package/dist/cjs/plugins/text-formatting/ui/Toolbar/toolbar-messages.js +10 -0
- package/dist/cjs/ui/Appearance/FullPage/FullPage.js +2 -4
- package/dist/cjs/ui/ColorPalette/index.js +6 -0
- package/dist/cjs/ui/ConfigPanel/ConfigPanel.js +15 -10
- package/dist/cjs/ui/ConfigPanel/ConfigPanelFieldsLoader.js +3 -1
- package/dist/cjs/ui/ConfigPanel/Fields/ColorPicker.js +248 -17
- package/dist/cjs/ui/ConfigPanel/FormContent.js +12 -6
- package/dist/cjs/ui/ConfigPanel/utils.js +2 -12
- package/dist/cjs/ui/ContentStyles/index.js +2 -5
- package/dist/cjs/ui/MediaAndEmbedsToolbar/index.js +16 -8
- package/dist/cjs/utils/document.js +5 -3
- package/dist/cjs/version-wrapper.js +1 -1
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/actions/index.js +10 -4
- package/dist/es2019/analytics-api/attach-payload-into-transaction.js +2 -1
- package/dist/es2019/create-editor/ErrorBoundary.js +1 -13
- package/dist/es2019/create-editor/ReactEditorViewInternal.js +2 -2
- package/dist/es2019/editor-next/editor-internal.js +2 -1
- package/dist/es2019/editor-next/index.js +5 -1
- package/dist/es2019/editor.js +5 -2
- package/dist/es2019/keymaps/index.js +1 -1
- package/dist/es2019/labs/next/internal/hooks/use-editor/index.js +4 -6
- package/dist/es2019/labs/next/presets/default.js +1 -2
- package/dist/es2019/plugins/card/index.js +15 -5
- package/dist/es2019/plugins/card/pm-plugins/actions.js +4 -0
- package/dist/es2019/plugins/card/pm-plugins/analytics/create-analytics-queue.js +38 -0
- package/dist/es2019/plugins/card/pm-plugins/analytics/events-from-tr.js +316 -0
- package/dist/es2019/plugins/card/pm-plugins/analytics/index.js +2 -0
- package/dist/es2019/plugins/card/pm-plugins/analytics/types.js +1 -0
- package/dist/es2019/plugins/card/pm-plugins/analytics/utils.js +124 -0
- package/dist/es2019/plugins/card/pm-plugins/doc.js +94 -20
- package/dist/es2019/plugins/card/pm-plugins/main.js +17 -8
- package/dist/es2019/plugins/card/pm-plugins/reducers.js +8 -0
- package/dist/es2019/plugins/card/pm-plugins/util/resolve.js +3 -7
- package/dist/es2019/plugins/card/toolbar.js +16 -8
- package/dist/es2019/plugins/card/ui/EditLinkToolbar.js +13 -9
- package/dist/es2019/plugins/card/ui/EditorSmartCardEventsNext.js +180 -0
- package/dist/es2019/plugins/card/ui/LinkToolbarAppearance.js +11 -2
- package/dist/es2019/plugins/card/utils.js +6 -2
- package/dist/es2019/plugins/extension/context-panel.js +3 -2
- package/dist/es2019/plugins/extension/index.js +45 -41
- package/dist/es2019/plugins/help-dialog/ui/index.js +17 -1
- package/dist/es2019/plugins/hyperlink/Toolbar.js +13 -4
- package/dist/es2019/plugins/hyperlink/commands.js +9 -6
- package/dist/es2019/plugins/hyperlink/pm-plugins/input-rule.js +4 -0
- package/dist/es2019/plugins/hyperlink/ui/HyperlinkAddToolbar/index.js +2 -2
- package/dist/es2019/plugins/index.js +0 -1
- package/dist/es2019/plugins/insert-block/index.js +96 -91
- package/dist/es2019/plugins/insert-block/ui/ToolbarInsertBlock/index.js +3 -2
- package/dist/es2019/plugins/media/index.js +202 -198
- package/dist/es2019/plugins/media/nodeviews/mediaNodeView/media.js +9 -1
- package/dist/es2019/plugins/media/pm-plugins/main.js +5 -4
- package/dist/es2019/plugins/media/utils/media-single.js +1 -5
- package/dist/es2019/plugins/panel/pm-plugins/keymaps.js +3 -2
- package/dist/es2019/plugins/paste/handlers.js +6 -6
- package/dist/es2019/plugins/paste/index.js +18 -14
- package/dist/es2019/plugins/paste/pm-plugins/main.js +7 -5
- package/dist/es2019/plugins/rule/commands.js +2 -2
- package/dist/es2019/plugins/rule/index.js +49 -46
- package/dist/es2019/plugins/rule/pm-plugins/input-rule.js +6 -7
- package/dist/es2019/plugins/rule/pm-plugins/keymap.js +2 -2
- package/dist/es2019/plugins/text-color/index.js +49 -44
- package/dist/es2019/plugins/text-color/ui/ToolbarTextColor/index.js +3 -3
- package/dist/es2019/plugins/text-formatting/ui/Toolbar/toolbar-messages.js +10 -0
- package/dist/es2019/ui/Appearance/FullPage/FullPage.js +2 -4
- package/dist/es2019/ui/ColorPalette/index.js +2 -2
- package/dist/es2019/ui/ConfigPanel/ConfigPanel.js +8 -4
- package/dist/es2019/ui/ConfigPanel/ConfigPanelFieldsLoader.js +3 -1
- package/dist/es2019/ui/ConfigPanel/Fields/ColorPicker.js +238 -13
- package/dist/es2019/ui/ConfigPanel/FormContent.js +12 -6
- package/dist/es2019/ui/ConfigPanel/utils.js +1 -11
- package/dist/es2019/ui/ContentStyles/index.js +2 -5
- package/dist/es2019/ui/MediaAndEmbedsToolbar/index.js +12 -10
- package/dist/es2019/utils/document.js +5 -3
- package/dist/es2019/version-wrapper.js +1 -1
- package/dist/es2019/version.json +1 -1
- package/dist/esm/actions/index.js +17 -6
- package/dist/esm/analytics-api/attach-payload-into-transaction.js +2 -1
- package/dist/esm/create-editor/ErrorBoundary.js +1 -16
- package/dist/esm/create-editor/ReactEditorViewInternal.js +2 -2
- package/dist/esm/editor-next/editor-internal.js +2 -1
- package/dist/esm/editor-next/index.js +5 -1
- package/dist/esm/editor.js +9 -5
- package/dist/esm/keymaps/index.js +1 -1
- package/dist/esm/labs/next/internal/hooks/use-editor/index.js +4 -6
- package/dist/esm/labs/next/presets/default.js +1 -2
- package/dist/esm/plugins/card/index.js +13 -5
- package/dist/esm/plugins/card/pm-plugins/actions.js +8 -0
- package/dist/esm/plugins/card/pm-plugins/analytics/create-analytics-queue.js +41 -0
- package/dist/esm/plugins/card/pm-plugins/analytics/events-from-tr.js +328 -0
- package/dist/esm/plugins/card/pm-plugins/analytics/index.js +2 -0
- package/dist/esm/plugins/card/pm-plugins/analytics/types.js +1 -0
- package/dist/esm/plugins/card/pm-plugins/analytics/utils.js +124 -0
- package/dist/esm/plugins/card/pm-plugins/doc.js +98 -22
- package/dist/esm/plugins/card/pm-plugins/main.js +16 -10
- package/dist/esm/plugins/card/pm-plugins/reducers.js +7 -0
- package/dist/esm/plugins/card/pm-plugins/util/resolve.js +3 -7
- package/dist/esm/plugins/card/toolbar.js +18 -8
- package/dist/esm/plugins/card/ui/EditLinkToolbar.js +13 -9
- package/dist/esm/plugins/card/ui/EditorSmartCardEventsNext.js +191 -0
- package/dist/esm/plugins/card/ui/LinkToolbarAppearance.js +12 -4
- package/dist/esm/plugins/card/utils.js +4 -2
- package/dist/esm/plugins/extension/context-panel.js +3 -2
- package/dist/esm/plugins/extension/index.js +4 -1
- package/dist/esm/plugins/help-dialog/ui/index.js +29 -8
- package/dist/esm/plugins/hyperlink/Toolbar.js +13 -3
- package/dist/esm/plugins/hyperlink/commands.js +9 -5
- package/dist/esm/plugins/hyperlink/pm-plugins/input-rule.js +4 -0
- package/dist/esm/plugins/hyperlink/ui/HyperlinkAddToolbar/index.js +2 -2
- package/dist/esm/plugins/index.js +0 -1
- package/dist/esm/plugins/insert-block/index.js +5 -1
- package/dist/esm/plugins/insert-block/ui/ToolbarInsertBlock/index.js +25 -23
- package/dist/esm/plugins/media/index.js +9 -5
- package/dist/esm/plugins/media/nodeviews/mediaNodeView/media.js +7 -1
- package/dist/esm/plugins/media/pm-plugins/main.js +5 -4
- package/dist/esm/plugins/media/utils/media-single.js +1 -4
- package/dist/esm/plugins/panel/pm-plugins/keymaps.js +3 -2
- package/dist/esm/plugins/paste/handlers.js +6 -6
- package/dist/esm/plugins/paste/index.js +4 -2
- package/dist/esm/plugins/paste/pm-plugins/main.js +7 -5
- package/dist/esm/plugins/rule/commands.js +2 -2
- package/dist/esm/plugins/rule/index.js +5 -4
- package/dist/esm/plugins/rule/pm-plugins/input-rule.js +6 -8
- package/dist/esm/plugins/rule/pm-plugins/keymap.js +2 -2
- package/dist/esm/plugins/text-color/index.js +5 -2
- package/dist/esm/plugins/text-color/ui/ToolbarTextColor/index.js +3 -4
- package/dist/esm/plugins/text-formatting/ui/Toolbar/toolbar-messages.js +10 -0
- package/dist/esm/ui/Appearance/FullPage/FullPage.js +2 -4
- package/dist/esm/ui/ColorPalette/index.js +2 -2
- package/dist/esm/ui/ConfigPanel/ConfigPanel.js +15 -10
- package/dist/esm/ui/ConfigPanel/ConfigPanelFieldsLoader.js +3 -1
- package/dist/esm/ui/ConfigPanel/Fields/ColorPicker.js +244 -19
- package/dist/esm/ui/ConfigPanel/FormContent.js +12 -6
- package/dist/esm/ui/ConfigPanel/utils.js +0 -10
- package/dist/esm/ui/ContentStyles/index.js +2 -5
- package/dist/esm/ui/MediaAndEmbedsToolbar/index.js +16 -8
- package/dist/esm/utils/document.js +5 -3
- package/dist/esm/version-wrapper.js +1 -1
- package/dist/esm/version.json +1 -1
- package/dist/types/actions/index.d.ts +3 -2
- package/dist/types/create-editor/ErrorBoundary.d.ts +2 -2
- package/dist/types/editor-next/index.d.ts +1 -0
- package/dist/types/editor.d.ts +1 -0
- package/dist/types/keymaps/index.d.ts +1 -1
- package/dist/types/labs/next/internal/hooks/use-editor/index.d.ts +2 -1
- package/dist/types/labs/next/presets/cxhtml.d.ts +1 -5
- package/dist/types/labs/next/presets/default.d.ts +2 -10
- package/dist/types/labs/next/presets/mobile.d.ts +1 -5
- package/dist/types/plugins/card/pm-plugins/actions.d.ts +2 -1
- package/dist/types/plugins/card/pm-plugins/analytics/create-analytics-queue.d.ts +10 -0
- package/dist/types/plugins/card/pm-plugins/analytics/events-from-tr.d.ts +17 -0
- package/dist/types/plugins/card/pm-plugins/analytics/index.d.ts +2 -0
- package/dist/types/plugins/card/pm-plugins/analytics/types.d.ts +10 -0
- package/dist/types/plugins/card/pm-plugins/analytics/utils.d.ts +26 -0
- package/dist/types/plugins/card/pm-plugins/doc.d.ts +8 -7
- package/dist/types/plugins/card/pm-plugins/main.d.ts +1 -1
- package/dist/types/plugins/card/pm-plugins/util/resolve.d.ts +2 -2
- package/dist/types/plugins/card/pm-plugins/util/state.d.ts +3 -0
- package/dist/types/plugins/card/types.d.ts +81 -7
- package/dist/types/plugins/card/ui/EditLinkToolbar.d.ts +2 -1
- package/dist/types/plugins/card/ui/EditorSmartCardEventsNext.d.ts +18 -0
- package/dist/types/plugins/card/utils.d.ts +1 -1
- package/dist/types/plugins/extension/context-panel.d.ts +2 -1
- package/dist/types/plugins/extension/index.d.ts +2 -0
- package/dist/types/plugins/hyperlink/commands.d.ts +3 -2
- package/dist/types/plugins/hyperlink/ui/HyperlinkAddToolbar/index.d.ts +2 -1
- package/dist/types/plugins/index.d.ts +0 -1
- package/dist/types/plugins/insert-block/index.d.ts +2 -0
- package/dist/types/plugins/insert-block/ui/ToolbarInsertBlock/types.d.ts +2 -1
- package/dist/types/plugins/media/index.d.ts +2 -0
- package/dist/types/plugins/media/pm-plugins/main.d.ts +3 -2
- package/dist/types/plugins/media/utils/media-single.d.ts +1 -1
- package/dist/types/plugins/paste/index.d.ts +2 -0
- package/dist/types/plugins/paste/pm-plugins/main.d.ts +2 -1
- package/dist/types/plugins/rule/commands.d.ts +2 -1
- package/dist/types/plugins/rule/index.d.ts +5 -1
- package/dist/types/plugins/rule/pm-plugins/input-rule.d.ts +1 -1
- package/dist/types/plugins/rule/pm-plugins/keymap.d.ts +2 -1
- package/dist/types/plugins/text-color/index.d.ts +2 -0
- package/dist/types/plugins/text-color/ui/ToolbarTextColor/index.d.ts +2 -0
- package/dist/types/plugins/text-formatting/ui/Toolbar/toolbar-messages.d.ts +10 -0
- package/dist/types/types/editor-appearance-component.d.ts +1 -1
- package/dist/types/types/editor-props.d.ts +1 -0
- package/dist/types/ui/Appearance/FullPage/FullPage.d.ts +2 -0
- package/dist/types/ui/ColorPalette/index.d.ts +2 -2
- package/dist/types/ui/ConfigPanel/ConfigPanel.d.ts +3 -1
- package/dist/types/ui/ConfigPanel/ConfigPanelFieldsLoader.d.ts +3 -1
- package/dist/types/ui/ConfigPanel/Fields/ColorPicker.d.ts +12 -1
- package/dist/types/ui/ConfigPanel/FormContent.d.ts +2 -2
- package/dist/types/ui/ConfigPanel/types.d.ts +3 -0
- package/dist/types/ui/ConfigPanel/utils.d.ts +0 -1
- package/dist/types/ui/MediaAndEmbedsToolbar/index.d.ts +1 -1
- package/package.json +14 -13
- package/report.api.md +10 -0
- package/dist/cjs/plugins/feature-flags-context/get-enabled-feature-flag-keys.js +0 -12
- package/dist/cjs/plugins/feature-flags-context/get-feature-flags.js +0 -11
- package/dist/cjs/plugins/feature-flags-context/index.js +0 -50
- package/dist/cjs/plugins/feature-flags-context/plugin-key.js +0 -9
- package/dist/es2019/plugins/feature-flags-context/get-enabled-feature-flag-keys.js +0 -1
- package/dist/es2019/plugins/feature-flags-context/get-feature-flags.js +0 -2
- package/dist/es2019/plugins/feature-flags-context/index.js +0 -29
- package/dist/es2019/plugins/feature-flags-context/plugin-key.js +0 -2
- package/dist/esm/plugins/feature-flags-context/get-enabled-feature-flag-keys.js +0 -1
- package/dist/esm/plugins/feature-flags-context/get-feature-flags.js +0 -4
- package/dist/esm/plugins/feature-flags-context/index.js +0 -40
- package/dist/esm/plugins/feature-flags-context/plugin-key.js +0 -2
- package/dist/types/plugins/feature-flags-context/get-enabled-feature-flag-keys.d.ts +0 -1
- package/dist/types/plugins/feature-flags-context/get-feature-flags.d.ts +0 -3
- package/dist/types/plugins/feature-flags-context/index.d.ts +0 -9
- package/dist/types/plugins/feature-flags-context/plugin-key.d.ts +0 -2
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { NodeSelection, TextSelection } from 'prosemirror-state';
|
|
2
2
|
import { closeHistory } from 'prosemirror-history';
|
|
3
3
|
import { isSafeUrl } from '@atlaskit/adf-schema';
|
|
4
|
+
import { addLinkMetadata } from '@atlaskit/editor-common/card';
|
|
4
5
|
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, addAnalytics, EVENT_TYPE, INPUT_METHOD } from '../../../plugins/analytics';
|
|
5
6
|
import { SMART_LINK_TYPE } from '../../../plugins/analytics/types/node-events';
|
|
6
7
|
import { getLinkCreationAnalyticsEvent } from '../../../plugins/hyperlink/analytics';
|
|
7
8
|
import { nodesBetweenChanged, processRawValue } from '../../../utils';
|
|
8
9
|
import { unlinkPayload } from '../../../utils/linking-utils';
|
|
9
10
|
import { isFromCurrentDomain } from '../../hyperlink/utils';
|
|
10
|
-
import { appearanceForNodeType } from '../utils';
|
|
11
|
+
import { appearanceForNodeType, selectedCardAppearance } from '../utils';
|
|
11
12
|
import { queueCards, resolveCard } from './actions';
|
|
12
13
|
import { pluginKey } from './plugin-key';
|
|
13
14
|
import { shouldReplaceLink } from './shouldReplaceLink';
|
|
@@ -46,7 +47,7 @@ function replaceLinksToCards(tr, cardAdf, schema, request) {
|
|
|
46
47
|
tr.replaceWith(pos, pos + (node.text || url).length, nodes);
|
|
47
48
|
return $pos.node($pos.depth - 1).type.name;
|
|
48
49
|
}
|
|
49
|
-
export const replaceQueuedUrlWithCard = (url, cardData, analyticsAction
|
|
50
|
+
export const replaceQueuedUrlWithCard = (url, cardData, analyticsAction) => (editorState, dispatch) => {
|
|
50
51
|
const state = pluginKey.getState(editorState);
|
|
51
52
|
if (!state) {
|
|
52
53
|
return false;
|
|
@@ -73,15 +74,22 @@ export const replaceQueuedUrlWithCard = (url, cardData, analyticsAction, createA
|
|
|
73
74
|
if (state.smartLinkEvents) {
|
|
74
75
|
state.smartLinkEvents.insertSmartLink(domainName, 'inline', state.createAnalyticsEvent);
|
|
75
76
|
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* TODO:
|
|
80
|
+
* What if each request has a different source?
|
|
81
|
+
* Unlikely, but need to define behaviour.
|
|
82
|
+
* Ignore analytics event? take first? provide 'mixed' as well?
|
|
83
|
+
*/
|
|
84
|
+
const inputMethod = requests[0].source;
|
|
85
|
+
const sourceEvent = requests[0].sourceEvent;
|
|
76
86
|
addAnalytics(editorState, tr, {
|
|
77
87
|
action: analyticsAction || ACTION.INSERTED,
|
|
78
88
|
actionSubject: ACTION_SUBJECT.DOCUMENT,
|
|
79
89
|
actionSubjectId: ACTION_SUBJECT_ID.SMART_LINK,
|
|
80
90
|
eventType: EVENT_TYPE.TRACK,
|
|
81
91
|
attributes: {
|
|
82
|
-
inputMethod
|
|
83
|
-
unlikely, but need to define behaviour.
|
|
84
|
-
ignore analytics event? take first? provide 'mixed' as well?*/,
|
|
92
|
+
inputMethod,
|
|
85
93
|
nodeType,
|
|
86
94
|
nodeContext: nodeContext,
|
|
87
95
|
fromCurrentDomain: isFromCurrentDomain(url)
|
|
@@ -90,6 +98,12 @@ export const replaceQueuedUrlWithCard = (url, cardData, analyticsAction, createA
|
|
|
90
98
|
domainName
|
|
91
99
|
}
|
|
92
100
|
});
|
|
101
|
+
addLinkMetadata(editorState.selection, tr, {
|
|
102
|
+
action: analyticsAction,
|
|
103
|
+
inputMethod,
|
|
104
|
+
cardAction: 'RESOLVE',
|
|
105
|
+
sourceEvent
|
|
106
|
+
});
|
|
93
107
|
}
|
|
94
108
|
}
|
|
95
109
|
if (dispatch) {
|
|
@@ -97,19 +111,25 @@ export const replaceQueuedUrlWithCard = (url, cardData, analyticsAction, createA
|
|
|
97
111
|
}
|
|
98
112
|
return true;
|
|
99
113
|
};
|
|
100
|
-
export const handleFallbackWithAnalytics =
|
|
101
|
-
const
|
|
102
|
-
if (!
|
|
114
|
+
export const handleFallbackWithAnalytics = request => (state, dispatch) => {
|
|
115
|
+
const cardState = pluginKey.getState(state);
|
|
116
|
+
if (!cardState) {
|
|
103
117
|
return false;
|
|
104
118
|
}
|
|
105
|
-
const tr =
|
|
106
|
-
|
|
119
|
+
const tr = state.tr;
|
|
120
|
+
if (request.source !== INPUT_METHOD.FLOATING_TB) {
|
|
121
|
+
addAnalytics(state, tr, getLinkCreationAnalyticsEvent(request.source, request.url));
|
|
122
|
+
}
|
|
123
|
+
addLinkMetadata(state.selection, tr, {
|
|
124
|
+
action: request.analyticsAction,
|
|
125
|
+
inputMethod: request.source
|
|
126
|
+
});
|
|
107
127
|
if (dispatch) {
|
|
108
|
-
dispatch(resolveCard(url)(tr));
|
|
128
|
+
dispatch(resolveCard(request.url)(tr));
|
|
109
129
|
}
|
|
110
130
|
return true;
|
|
111
131
|
};
|
|
112
|
-
export const queueCardsFromChangedTr = (state, tr, source, normalizeLinkText = true) => {
|
|
132
|
+
export const queueCardsFromChangedTr = (state, tr, source, analyticsAction, normalizeLinkText = true, sourceEvent = undefined) => {
|
|
113
133
|
const {
|
|
114
134
|
schema
|
|
115
135
|
} = state;
|
|
@@ -131,11 +151,51 @@ export const queueCardsFromChangedTr = (state, tr, source, normalizeLinkText = t
|
|
|
131
151
|
pos,
|
|
132
152
|
appearance: 'inline',
|
|
133
153
|
compareLinkText: normalizeLinkText,
|
|
134
|
-
source
|
|
154
|
+
source,
|
|
155
|
+
analyticsAction,
|
|
156
|
+
sourceEvent
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
return false;
|
|
160
|
+
});
|
|
161
|
+
addLinkMetadata(state.selection, tr, {
|
|
162
|
+
action: analyticsAction
|
|
163
|
+
});
|
|
164
|
+
return queueCards(requests)(tr);
|
|
165
|
+
};
|
|
166
|
+
export const queueCardFromChangedTr = (state, tr, source, analyticsAction, normalizeLinkText = true, sourceEvent = undefined, previousAppearance) => {
|
|
167
|
+
const {
|
|
168
|
+
schema
|
|
169
|
+
} = state;
|
|
170
|
+
const {
|
|
171
|
+
link
|
|
172
|
+
} = schema.marks;
|
|
173
|
+
let requests = [];
|
|
174
|
+
nodesBetweenChanged(tr, (node, pos) => {
|
|
175
|
+
if (!node.isText) {
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
178
|
+
const linkMark = node.marks.find(mark => mark.type === link);
|
|
179
|
+
if (linkMark) {
|
|
180
|
+
if (!shouldReplaceLink(node, normalizeLinkText)) {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
requests.push({
|
|
184
|
+
url: linkMark.attrs.href,
|
|
185
|
+
pos,
|
|
186
|
+
appearance: 'inline',
|
|
187
|
+
previousAppearance: previousAppearance,
|
|
188
|
+
compareLinkText: normalizeLinkText,
|
|
189
|
+
source,
|
|
190
|
+
analyticsAction,
|
|
191
|
+
sourceEvent
|
|
135
192
|
});
|
|
136
193
|
}
|
|
137
194
|
return false;
|
|
138
195
|
});
|
|
196
|
+
addLinkMetadata(state.selection, tr, {
|
|
197
|
+
action: analyticsAction
|
|
198
|
+
});
|
|
139
199
|
return queueCards(requests)(tr);
|
|
140
200
|
};
|
|
141
201
|
export const convertHyperlinkToSmartCard = (state, source, appearance, normalizeLinkText = true) => {
|
|
@@ -149,18 +209,21 @@ export const convertHyperlinkToSmartCard = (state, source, appearance, normalize
|
|
|
149
209
|
state.tr.doc.nodesBetween(state.selection.from, state.selection.to, (node, pos) => {
|
|
150
210
|
const linkMark = node.marks.find(mark => mark.type === link);
|
|
151
211
|
if (linkMark) {
|
|
152
|
-
|
|
212
|
+
requests.push({
|
|
153
213
|
url: linkMark.attrs.href,
|
|
154
214
|
pos,
|
|
155
215
|
appearance,
|
|
216
|
+
previousAppearance: 'url',
|
|
156
217
|
compareLinkText: normalizeLinkText,
|
|
157
218
|
source,
|
|
158
219
|
analyticsAction: ACTION.CHANGED_TYPE,
|
|
159
220
|
shouldReplaceLink: true
|
|
160
|
-
};
|
|
161
|
-
requests.push(request);
|
|
221
|
+
});
|
|
162
222
|
}
|
|
163
223
|
});
|
|
224
|
+
addLinkMetadata(state.selection, state.tr, {
|
|
225
|
+
action: ACTION.CHANGED_TYPE
|
|
226
|
+
});
|
|
164
227
|
return queueCards(requests)(state.tr);
|
|
165
228
|
};
|
|
166
229
|
export const changeSelectedCardToLink = (text, href, sendAnalytics, node, pos) => (state, dispatch) => {
|
|
@@ -211,13 +274,14 @@ export const changeSelectedCardToLinkFallback = (text, href, sendAnalytics, node
|
|
|
211
274
|
}
|
|
212
275
|
return true;
|
|
213
276
|
};
|
|
214
|
-
export const updateCard = href => (state, dispatch) => {
|
|
277
|
+
export const updateCard = (href, sourceEvent) => (state, dispatch) => {
|
|
215
278
|
const selectedNode = state.selection instanceof NodeSelection && state.selection.node;
|
|
216
279
|
if (!selectedNode) {
|
|
217
280
|
return false;
|
|
218
281
|
}
|
|
282
|
+
const cardAppearance = selectedCardAppearance(state);
|
|
219
283
|
const tr = cardToLinkWithTransaction(state, href, href);
|
|
220
|
-
|
|
284
|
+
queueCardFromChangedTr(state, tr, INPUT_METHOD.MANUAL, ACTION.UPDATED, undefined, sourceEvent, cardAppearance);
|
|
221
285
|
if (dispatch) {
|
|
222
286
|
dispatch(tr.scrollIntoView());
|
|
223
287
|
}
|
|
@@ -253,7 +317,11 @@ export const changeSelectedCardToText = text => (state, dispatch) => {
|
|
|
253
317
|
}
|
|
254
318
|
const tr = state.tr.replaceSelectionWith(state.schema.text(text), false);
|
|
255
319
|
if (dispatch) {
|
|
256
|
-
|
|
320
|
+
addLinkMetadata(state.selection, tr, {
|
|
321
|
+
action: ACTION.UNLINK
|
|
322
|
+
});
|
|
323
|
+
addAnalytics(state, tr.scrollIntoView(), unlinkPayload(ACTION_SUBJECT_ID.CARD_INLINE));
|
|
324
|
+
dispatch(tr);
|
|
257
325
|
}
|
|
258
326
|
return true;
|
|
259
327
|
};
|
|
@@ -263,8 +331,11 @@ export const setSelectedCardAppearance = appearance => (state, dispatch) => {
|
|
|
263
331
|
if (!selectedNode) {
|
|
264
332
|
// When there is no selected node, we insert a new one
|
|
265
333
|
// and replace the existing blue link
|
|
266
|
-
const tr = convertHyperlinkToSmartCard(state, INPUT_METHOD.
|
|
334
|
+
const tr = convertHyperlinkToSmartCard(state, INPUT_METHOD.FLOATING_TB, appearance);
|
|
267
335
|
if (dispatch) {
|
|
336
|
+
addLinkMetadata(state.selection, tr, {
|
|
337
|
+
action: ACTION.CHANGED_TYPE
|
|
338
|
+
});
|
|
268
339
|
dispatch(tr.scrollIntoView());
|
|
269
340
|
}
|
|
270
341
|
return false;
|
|
@@ -303,6 +374,9 @@ export const setSelectedCardAppearance = appearance => (state, dispatch) => {
|
|
|
303
374
|
previousType: appearanceForNodeType(selectedNode.type)
|
|
304
375
|
}
|
|
305
376
|
});
|
|
377
|
+
addLinkMetadata(state.selection, tr, {
|
|
378
|
+
action: ACTION.CHANGED_TYPE
|
|
379
|
+
});
|
|
306
380
|
if (dispatch) {
|
|
307
381
|
dispatch(tr.scrollIntoView());
|
|
308
382
|
}
|
|
@@ -8,8 +8,13 @@ import { pluginKey } from './plugin-key';
|
|
|
8
8
|
import reducer from './reducers';
|
|
9
9
|
import { handleProvider, resolveWithProvider } from './util/resolve';
|
|
10
10
|
import { getNewRequests, getPluginState, getPluginStateWithUpdatedPos } from './util/state';
|
|
11
|
+
import { createAnalyticsQueue, eventsFromTransaction } from './analytics';
|
|
11
12
|
export { pluginKey } from './plugin-key';
|
|
12
13
|
export const createPlugin = options => pmPluginFactoryParams => {
|
|
14
|
+
const {
|
|
15
|
+
lpAnalyticsEventsNext
|
|
16
|
+
} = pmPluginFactoryParams.featureFlags;
|
|
17
|
+
const analyticsQueue = createAnalyticsQueue(!!lpAnalyticsEventsNext);
|
|
13
18
|
const {
|
|
14
19
|
editorAppearance,
|
|
15
20
|
platform,
|
|
@@ -28,25 +33,31 @@ export const createPlugin = options => pmPluginFactoryParams => {
|
|
|
28
33
|
cards: [],
|
|
29
34
|
showLinkingToolbar: false,
|
|
30
35
|
smartLinkEvents: undefined,
|
|
36
|
+
smartLinkEventsNext: undefined,
|
|
31
37
|
createAnalyticsEvent,
|
|
32
38
|
editorAppearance
|
|
33
39
|
};
|
|
34
40
|
},
|
|
35
|
-
apply(tr, pluginState) {
|
|
41
|
+
apply(tr, pluginState, prevEditorState) {
|
|
36
42
|
// Update all the positions of outstanding requests and
|
|
37
43
|
// cards in the plugin state.
|
|
38
44
|
const pluginStateWithUpdatedPos = getPluginStateWithUpdatedPos(pluginState, tr);
|
|
45
|
+
|
|
39
46
|
// apply any actions
|
|
40
47
|
const meta = tr.getMeta(pluginKey);
|
|
48
|
+
const events = eventsFromTransaction(tr, prevEditorState);
|
|
49
|
+
analyticsQueue.push(...events);
|
|
41
50
|
if (meta) {
|
|
42
|
-
const
|
|
43
|
-
|
|
51
|
+
const nextState = reducer(pluginStateWithUpdatedPos, meta);
|
|
52
|
+
if (!pluginState.smartLinkEventsNext && nextState.smartLinkEventsNext) {
|
|
53
|
+
analyticsQueue.setCallbacks(nextState.smartLinkEventsNext);
|
|
54
|
+
}
|
|
55
|
+
return nextState;
|
|
44
56
|
}
|
|
45
57
|
return pluginStateWithUpdatedPos;
|
|
46
58
|
}
|
|
47
59
|
},
|
|
48
60
|
view(view) {
|
|
49
|
-
const outstandingRequests = {};
|
|
50
61
|
const subscriptionHandler = (name, provider) => handleProvider(name, provider, view);
|
|
51
62
|
const rafCancellationCallbacks = [];
|
|
52
63
|
pmPluginFactoryParams.providerFactory.subscribe('cardProvider', subscriptionHandler);
|
|
@@ -71,16 +82,14 @@ export const createPlugin = options => pmPluginFactoryParams => {
|
|
|
71
82
|
* By using this approach, the browser is free to schedule the resolution of the promises below in between rendering/network/
|
|
72
83
|
* other tasks as per common implementations of the JavaScript event loop in browsers.
|
|
73
84
|
*/
|
|
74
|
-
const invoke = rafSchedule(() => resolveWithProvider(view,
|
|
85
|
+
const invoke = rafSchedule(() => resolveWithProvider(view, provider, request, options));
|
|
75
86
|
rafCancellationCallbacks.push(invoke.cancel);
|
|
76
87
|
invoke();
|
|
77
88
|
});
|
|
78
89
|
}
|
|
90
|
+
analyticsQueue.flush();
|
|
79
91
|
},
|
|
80
92
|
destroy() {
|
|
81
|
-
// Cancel all outstanding requests
|
|
82
|
-
Object.keys(outstandingRequests).forEach(url => Promise.reject(outstandingRequests[url]));
|
|
83
|
-
|
|
84
93
|
// Cancel any outstanding raf callbacks.
|
|
85
94
|
rafCancellationCallbacks.forEach(cancellationCallback => cancellationCallback());
|
|
86
95
|
pmPluginFactoryParams.providerFactory.unsubscribe('cardProvider', subscriptionHandler);
|
|
@@ -34,6 +34,12 @@ const registerEvents = (state, action) => {
|
|
|
34
34
|
smartLinkEvents: action.smartLinkEvents
|
|
35
35
|
};
|
|
36
36
|
};
|
|
37
|
+
const registerEventsNext = (state, action) => {
|
|
38
|
+
return {
|
|
39
|
+
...state,
|
|
40
|
+
smartLinkEventsNext: action.smartLinkEvents
|
|
41
|
+
};
|
|
42
|
+
};
|
|
37
43
|
const setLinkToolbar = (state, action) => {
|
|
38
44
|
return {
|
|
39
45
|
...state,
|
|
@@ -52,6 +58,8 @@ export default ((state, action) => {
|
|
|
52
58
|
return register(state, action);
|
|
53
59
|
case 'REGISTER_EVENTS':
|
|
54
60
|
return registerEvents(state, action);
|
|
61
|
+
case 'REGISTER_EVENTS_NEXT':
|
|
62
|
+
return registerEventsNext(state, action);
|
|
55
63
|
case 'SHOW_LINK_TOOLBAR':
|
|
56
64
|
case 'HIDE_LINK_TOOLBAR':
|
|
57
65
|
return setLinkToolbar(state, action);
|
|
@@ -5,18 +5,14 @@ import { replaceQueuedUrlWithCard, handleFallbackWithAnalytics } from '../doc';
|
|
|
5
5
|
// ============================================================================ //
|
|
6
6
|
// Used for all interactions with the EditorCardProvider.
|
|
7
7
|
// ============================================================================ //
|
|
8
|
-
export const resolveWithProvider = (view,
|
|
8
|
+
export const resolveWithProvider = (view, provider, request, options) => {
|
|
9
9
|
// When user manually changes appearance from blue link to smart link, we should respect that,
|
|
10
10
|
let shouldForceAppearance =
|
|
11
11
|
// This flag is set to true only in one place atm:
|
|
12
12
|
// packages/editor/editor-core/src/plugins/card/pm-plugins/doc.ts @ convertHyperlinkToSmartCard
|
|
13
13
|
// Which is used when user switching from URL to smart link appearance.
|
|
14
14
|
!!request.shouldReplaceLink;
|
|
15
|
-
const handleResolve = provider.resolve(request.url, request.appearance, shouldForceAppearance).then(
|
|
16
|
-
delete outstandingRequests[request.url];
|
|
17
|
-
return resolvedCard;
|
|
18
|
-
}).then(handleResolved(view, request, options), handleRejected(view, request));
|
|
19
|
-
outstandingRequests[request.url] = handleResolve;
|
|
15
|
+
const handleResolve = provider.resolve(request.url, request.appearance, shouldForceAppearance).then(handleResolved(view, request, options), handleRejected(view, request));
|
|
20
16
|
return handleResolve;
|
|
21
17
|
};
|
|
22
18
|
const updateCardType = (resolvedCard, options) => {
|
|
@@ -34,7 +30,7 @@ const handleResolved = (view, request, options) => resolvedCard => {
|
|
|
34
30
|
return resolvedCard;
|
|
35
31
|
};
|
|
36
32
|
const handleRejected = (view, request) => () => {
|
|
37
|
-
handleFallbackWithAnalytics(request
|
|
33
|
+
handleFallbackWithAnalytics(request)(view.state, view.dispatch);
|
|
38
34
|
};
|
|
39
35
|
|
|
40
36
|
// listen for card provider changes
|
|
@@ -10,6 +10,7 @@ import { linkToolbarMessages, linkMessages } from '../../messages';
|
|
|
10
10
|
import commonMessages from '../../messages';
|
|
11
11
|
import { hoverDecoration } from '../base/pm-plugins/decoration';
|
|
12
12
|
import { changeSelectedCardToText } from './pm-plugins/doc';
|
|
13
|
+
import { commandWithMetadata } from '@atlaskit/editor-common/card';
|
|
13
14
|
import { pluginKey } from './pm-plugins/main';
|
|
14
15
|
import { richMediaClassName } from '@atlaskit/editor-common/styles';
|
|
15
16
|
import { buildEditLinkToolbar, editLink, editLinkToolbarConfig } from './ui/EditLinkToolbar';
|
|
@@ -20,7 +21,7 @@ import { messages } from './messages';
|
|
|
20
21
|
import buildLayoutButtons from '../../ui/MediaAndEmbedsToolbar';
|
|
21
22
|
import { buildOpenedSettingsPayload, buildVisitedLinkPayload } from '../../utils/linking-utils';
|
|
22
23
|
import { FLOATING_TOOLBAR_LINKPICKER_CLASSNAME } from './styles';
|
|
23
|
-
export const removeCard = (state, dispatch) => {
|
|
24
|
+
export const removeCard = commandWithMetadata((state, dispatch) => {
|
|
24
25
|
if (!(state.selection instanceof NodeSelection)) {
|
|
25
26
|
return false;
|
|
26
27
|
}
|
|
@@ -39,7 +40,9 @@ export const removeCard = (state, dispatch) => {
|
|
|
39
40
|
dispatch(addAnalytics(state, removeSelectedNode(state.tr), payload));
|
|
40
41
|
}
|
|
41
42
|
return true;
|
|
42
|
-
}
|
|
43
|
+
}, {
|
|
44
|
+
action: ACTION.DELETED
|
|
45
|
+
});
|
|
43
46
|
export const visitCardLink = (state, dispatch) => {
|
|
44
47
|
if (!(state.selection instanceof NodeSelection)) {
|
|
45
48
|
return false;
|
|
@@ -135,13 +138,18 @@ const unlinkCard = (node, state) => {
|
|
|
135
138
|
const displayInfo = displayInfoForCard(node, findCardInfo(state));
|
|
136
139
|
const text = displayInfo.title || displayInfo.url;
|
|
137
140
|
if (text) {
|
|
138
|
-
return changeSelectedCardToText(text)
|
|
141
|
+
return commandWithMetadata(changeSelectedCardToText(text), {
|
|
142
|
+
action: ACTION.UNLINK
|
|
143
|
+
});
|
|
139
144
|
}
|
|
140
145
|
return () => false;
|
|
141
146
|
};
|
|
142
|
-
const buildAlignmentOptions = (state, intl) => {
|
|
143
|
-
return buildLayoutButtons(state, intl, state.schema.nodes.embedCard, true, true);
|
|
147
|
+
const buildAlignmentOptions = (state, intl, cardOptions) => {
|
|
148
|
+
return buildLayoutButtons(state, intl, state.schema.nodes.embedCard, true, true, cardOptions === null || cardOptions === void 0 ? void 0 : cardOptions.allowWrapping, cardOptions === null || cardOptions === void 0 ? void 0 : cardOptions.allowAlignment);
|
|
144
149
|
};
|
|
150
|
+
const withToolbarMetadata = command => commandWithMetadata(command, {
|
|
151
|
+
inputMethod: INPUT_METHOD.FLOATING_TB
|
|
152
|
+
});
|
|
145
153
|
const generateToolbarItems = (state, featureFlags, intl, providerFactory, cardOptions, platform, linkPicker) => node => {
|
|
146
154
|
const {
|
|
147
155
|
url
|
|
@@ -214,10 +222,10 @@ const generateToolbarItems = (state, featureFlags, intl, providerFactory, cardOp
|
|
|
214
222
|
onFocus: hoverDecoration(node.type, true),
|
|
215
223
|
onBlur: hoverDecoration(node.type, false),
|
|
216
224
|
title: intl.formatMessage(commonMessages.remove),
|
|
217
|
-
onClick: removeCard
|
|
225
|
+
onClick: withToolbarMetadata(removeCard)
|
|
218
226
|
}];
|
|
219
227
|
if (currentAppearance === 'embed') {
|
|
220
|
-
const alignmentOptions = buildAlignmentOptions(state, intl);
|
|
228
|
+
const alignmentOptions = buildAlignmentOptions(state, intl, cardOptions);
|
|
221
229
|
if (alignmentOptions.length) {
|
|
222
230
|
alignmentOptions.push({
|
|
223
231
|
type: 'separator'
|
|
@@ -261,7 +269,7 @@ const getUnlinkButtonGroup = (state, intl, node, inlineCard) => {
|
|
|
261
269
|
type: 'button',
|
|
262
270
|
title: intl.formatMessage(linkToolbarMessages.unlink),
|
|
263
271
|
icon: UnlinkIcon,
|
|
264
|
-
onClick: unlinkCard(node, state)
|
|
272
|
+
onClick: withToolbarMetadata(unlinkCard(node, state))
|
|
265
273
|
}, {
|
|
266
274
|
type: 'separator'
|
|
267
275
|
}] : [];
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
2
|
import React from 'react';
|
|
3
|
+
import { withOuterListeners } from '@atlaskit/editor-common/ui';
|
|
4
|
+
import { commandWithMetadata } from '@atlaskit/editor-common/card';
|
|
3
5
|
import HyperlinkToolbar from '../../hyperlink/ui/HyperlinkAddToolbar';
|
|
4
6
|
import { showLinkToolbar, hideLinkToolbar } from '../pm-plugins/actions';
|
|
5
|
-
import { addAnalytics, INPUT_METHOD } from '../../analytics';
|
|
7
|
+
import { addAnalytics, INPUT_METHOD, ACTION } from '../../analytics';
|
|
6
8
|
import { LINKPICKER_HEIGHT_IN_PX, RECENT_SEARCH_HEIGHT_IN_PX, RECENT_SEARCH_WIDTH_IN_PX } from '../../../ui/LinkSearch/ToolbarComponents';
|
|
7
9
|
import { changeSelectedCardToLink, updateCard } from '../pm-plugins/doc';
|
|
8
10
|
import { findCardInfo, displayInfoForCard } from '../utils';
|
|
9
11
|
import { NodeSelection } from 'prosemirror-state';
|
|
10
12
|
import { buildEditLinkPayload } from '../../../utils/linking-utils';
|
|
11
13
|
import { forceFocusSelector } from '../../floating-toolbar/pm-plugins/force-focus';
|
|
12
|
-
import { withOuterListeners } from '@atlaskit/editor-common/ui';
|
|
13
14
|
import { linkToolbarMessages } from '../../../messages';
|
|
14
15
|
const HyperLinkToolbarWithListeners = withOuterListeners(HyperlinkToolbar);
|
|
15
16
|
export class EditLinkToolbar extends React.Component {
|
|
@@ -60,10 +61,10 @@ export class EditLinkToolbar extends React.Component {
|
|
|
60
61
|
,
|
|
61
62
|
invokeMethod: INPUT_METHOD.FLOATING_TB,
|
|
62
63
|
featureFlags: featureFlags,
|
|
63
|
-
onSubmit: (href, title, displayText) => {
|
|
64
|
+
onSubmit: (href, title, displayText, _, analytic) => {
|
|
64
65
|
this.hideLinkToolbar();
|
|
65
66
|
if (onSubmit) {
|
|
66
|
-
onSubmit(href, displayText || title);
|
|
67
|
+
onSubmit(href, displayText || title, analytic);
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
70
|
});
|
|
@@ -104,19 +105,22 @@ export const buildEditLinkToolbar = ({
|
|
|
104
105
|
text: displayInfo.title || '',
|
|
105
106
|
node: node,
|
|
106
107
|
featureFlags: featureFlags,
|
|
107
|
-
onSubmit: (newHref, newText) => {
|
|
108
|
+
onSubmit: (newHref, newText, analytic) => {
|
|
108
109
|
const urlChanged = newHref !== displayInfo.url;
|
|
109
110
|
const titleChanged = newText !== displayInfo.title;
|
|
110
111
|
|
|
111
112
|
// If the title is changed in a smartlink, convert to standard blue hyperlink
|
|
112
113
|
// (even if the url was also changed) - we don't want to lose the custom title.
|
|
113
114
|
if (titleChanged) {
|
|
114
|
-
return changeSelectedCardToLink(newText, newHref)
|
|
115
|
-
|
|
115
|
+
return commandWithMetadata(changeSelectedCardToLink(newText, newHref), {
|
|
116
|
+
action: ACTION.UPDATED,
|
|
117
|
+
sourceEvent: analytic
|
|
118
|
+
})(view.state, view.dispatch);
|
|
119
|
+
}
|
|
120
|
+
if (urlChanged) {
|
|
116
121
|
// If *only* the url is changed in a smart link, reresolve
|
|
117
|
-
return updateCard(newHref)(view.state, view.dispatch);
|
|
122
|
+
return updateCard(newHref, analytic)(view.state, view.dispatch);
|
|
118
123
|
}
|
|
119
|
-
return;
|
|
120
124
|
}
|
|
121
125
|
});
|
|
122
126
|
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { useEffect, useMemo } from 'react';
|
|
4
|
+
import PropTypes from 'prop-types';
|
|
5
|
+
import { useSmartLinkLifecycleAnalytics } from '@atlaskit/link-analytics';
|
|
6
|
+
import { INPUT_METHOD, ACTION } from '@atlaskit/editor-common/analytics';
|
|
7
|
+
import { UIAnalyticsEvent } from '@atlaskit/analytics-next';
|
|
8
|
+
import { registerSmartCardEventsNext } from '../pm-plugins/actions';
|
|
9
|
+
/**
|
|
10
|
+
* If the metadata is for a history event,
|
|
11
|
+
* returns undo/redo instead of instead of what fn(metadata) would have otherwise
|
|
12
|
+
* returned
|
|
13
|
+
*/
|
|
14
|
+
const withHistoryMethod = fn => {
|
|
15
|
+
return metadata => {
|
|
16
|
+
const {
|
|
17
|
+
isUndo,
|
|
18
|
+
isRedo
|
|
19
|
+
} = metadata;
|
|
20
|
+
if (isUndo) {
|
|
21
|
+
return 'undo';
|
|
22
|
+
}
|
|
23
|
+
if (isRedo) {
|
|
24
|
+
return 'redo';
|
|
25
|
+
}
|
|
26
|
+
return fn(metadata);
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
const getMethod = withHistoryMethod(({
|
|
30
|
+
inputMethod,
|
|
31
|
+
sourceEvent
|
|
32
|
+
}) => {
|
|
33
|
+
/**
|
|
34
|
+
* If sourceEvent is present, don't provide a custom method
|
|
35
|
+
*/
|
|
36
|
+
if (sourceEvent) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
switch (inputMethod) {
|
|
40
|
+
case INPUT_METHOD.CLIPBOARD:
|
|
41
|
+
return 'editor_paste';
|
|
42
|
+
case INPUT_METHOD.FLOATING_TB:
|
|
43
|
+
return 'editor_floatingToolbar';
|
|
44
|
+
case INPUT_METHOD.AUTO_DETECT:
|
|
45
|
+
return 'editor_type';
|
|
46
|
+
default:
|
|
47
|
+
return 'unknown';
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
const getUpdateType = withHistoryMethod(({
|
|
51
|
+
action,
|
|
52
|
+
sourceEvent
|
|
53
|
+
}) => {
|
|
54
|
+
/**
|
|
55
|
+
* If sourceEvent is present, don't provide a custom method
|
|
56
|
+
*/
|
|
57
|
+
if (sourceEvent) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
switch (action) {
|
|
61
|
+
case ACTION.CHANGED_TYPE:
|
|
62
|
+
return 'display_update';
|
|
63
|
+
case ACTION.UPDATED:
|
|
64
|
+
return 'link_update';
|
|
65
|
+
default:
|
|
66
|
+
return 'unknown';
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
const getDeleteType = withHistoryMethod(({
|
|
70
|
+
action
|
|
71
|
+
}) => {
|
|
72
|
+
if (action === ACTION.UNLINK) {
|
|
73
|
+
return 'unlink';
|
|
74
|
+
}
|
|
75
|
+
return 'delete';
|
|
76
|
+
});
|
|
77
|
+
const getSourceEventFromMetadata = metadata => {
|
|
78
|
+
return metadata.sourceEvent instanceof UIAnalyticsEvent ? metadata.sourceEvent : null;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Set display category as `link` if not displaying the link as a smart card
|
|
83
|
+
*/
|
|
84
|
+
const displayCategoryFromDisplay = display => {
|
|
85
|
+
if (display === 'url') {
|
|
86
|
+
return 'link';
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Binds the @atlaskit/link-analytics callbacks
|
|
92
|
+
* to the editor card plugin state events callbacks interfaces
|
|
93
|
+
*/
|
|
94
|
+
export const EventsBinding = ({
|
|
95
|
+
editorView
|
|
96
|
+
}) => {
|
|
97
|
+
/**
|
|
98
|
+
* These callbacks internally use window.requestIdleCallback/requestAnimationFrame
|
|
99
|
+
* to defer any heavy operations involving network
|
|
100
|
+
*
|
|
101
|
+
* The callbacks themselves should not be deferred, they should be called syncronously the moment
|
|
102
|
+
* the events take place.
|
|
103
|
+
*/
|
|
104
|
+
const {
|
|
105
|
+
linkCreated,
|
|
106
|
+
linkUpdated,
|
|
107
|
+
linkDeleted
|
|
108
|
+
} = useSmartLinkLifecycleAnalytics();
|
|
109
|
+
const events = useMemo(() => {
|
|
110
|
+
return {
|
|
111
|
+
created: ({
|
|
112
|
+
url,
|
|
113
|
+
display,
|
|
114
|
+
...metadata
|
|
115
|
+
}) => {
|
|
116
|
+
linkCreated({
|
|
117
|
+
url,
|
|
118
|
+
displayCategory: displayCategoryFromDisplay(display)
|
|
119
|
+
}, getSourceEventFromMetadata(metadata), {
|
|
120
|
+
display,
|
|
121
|
+
creationMethod: getMethod(metadata)
|
|
122
|
+
});
|
|
123
|
+
},
|
|
124
|
+
updated: ({
|
|
125
|
+
url,
|
|
126
|
+
display,
|
|
127
|
+
previousDisplay,
|
|
128
|
+
...metadata
|
|
129
|
+
}) => {
|
|
130
|
+
linkUpdated({
|
|
131
|
+
url,
|
|
132
|
+
displayCategory: displayCategoryFromDisplay(display)
|
|
133
|
+
}, getSourceEventFromMetadata(metadata), {
|
|
134
|
+
display,
|
|
135
|
+
previousDisplay,
|
|
136
|
+
updateMethod: getMethod(metadata),
|
|
137
|
+
updateType: getUpdateType(metadata)
|
|
138
|
+
});
|
|
139
|
+
},
|
|
140
|
+
deleted: ({
|
|
141
|
+
url,
|
|
142
|
+
display,
|
|
143
|
+
...metadata
|
|
144
|
+
}) => {
|
|
145
|
+
linkDeleted({
|
|
146
|
+
url,
|
|
147
|
+
displayCategory: displayCategoryFromDisplay(display)
|
|
148
|
+
}, getSourceEventFromMetadata(metadata), {
|
|
149
|
+
display,
|
|
150
|
+
deleteMethod: getMethod(metadata),
|
|
151
|
+
deleteType: getDeleteType(metadata)
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
}, [linkCreated, linkUpdated, linkDeleted]);
|
|
156
|
+
useEffect(() => {
|
|
157
|
+
editorView.dispatch(registerSmartCardEventsNext(events)(editorView.state.tr));
|
|
158
|
+
}, [events, editorView]);
|
|
159
|
+
return null;
|
|
160
|
+
};
|
|
161
|
+
export class EditorSmartCardEventsNext extends React.PureComponent {
|
|
162
|
+
render() {
|
|
163
|
+
const cardContext = this.context.contextAdapter.card;
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* The analytics hook needs to be able to communicate with the card context
|
|
167
|
+
* If we can't access it, don't mount the event bindings
|
|
168
|
+
* This effectively entirely disables all tracking behaviour
|
|
169
|
+
*/
|
|
170
|
+
if (!cardContext) {
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
return /*#__PURE__*/React.createElement(cardContext.Provider, {
|
|
174
|
+
value: cardContext.value
|
|
175
|
+
}, /*#__PURE__*/React.createElement(EventsBinding, this.props));
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
_defineProperty(EditorSmartCardEventsNext, "contextTypes", {
|
|
179
|
+
contextAdapter: PropTypes.object
|
|
180
|
+
});
|