@atlaskit/editor-plugin-card 0.3.4 → 0.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/cjs/analytics/create-events-queue.js +55 -0
  3. package/dist/cjs/{pm-plugins/analytics → analytics}/events-from-tr.js +90 -81
  4. package/dist/cjs/{pm-plugins/analytics → analytics}/index.js +3 -3
  5. package/dist/cjs/analytics/types.js +24 -0
  6. package/dist/cjs/analytics/utils.js +134 -0
  7. package/dist/cjs/nodeviews/datasource.js +1 -8
  8. package/dist/cjs/plugin.js +7 -4
  9. package/dist/cjs/pm-plugins/actions.js +1 -10
  10. package/dist/cjs/pm-plugins/doc.js +3 -0
  11. package/dist/cjs/pm-plugins/main.js +15 -13
  12. package/dist/cjs/pm-plugins/reducers.js +0 -7
  13. package/dist/cjs/ui/EditorLinkingPlatformAnalytics/DatasourceEvents.js +52 -0
  14. package/dist/cjs/ui/EditorLinkingPlatformAnalytics/LinkEvents.js +132 -0
  15. package/dist/cjs/ui/EditorLinkingPlatformAnalytics/common.js +65 -0
  16. package/dist/cjs/ui/EditorLinkingPlatformAnalytics/index.js +54 -0
  17. package/dist/cjs/version.json +1 -1
  18. package/dist/es2019/analytics/create-events-queue.js +43 -0
  19. package/dist/es2019/{pm-plugins/analytics → analytics}/events-from-tr.js +82 -72
  20. package/dist/es2019/analytics/index.js +2 -0
  21. package/dist/es2019/analytics/types.js +17 -0
  22. package/dist/es2019/analytics/utils.js +118 -0
  23. package/dist/es2019/nodeviews/datasource.js +2 -9
  24. package/dist/es2019/plugin.js +7 -6
  25. package/dist/es2019/pm-plugins/actions.js +0 -4
  26. package/dist/es2019/pm-plugins/doc.js +3 -0
  27. package/dist/es2019/pm-plugins/main.js +15 -15
  28. package/dist/es2019/pm-plugins/reducers.js +0 -8
  29. package/dist/es2019/ui/EditorLinkingPlatformAnalytics/DatasourceEvents.js +46 -0
  30. package/dist/es2019/ui/EditorLinkingPlatformAnalytics/LinkEvents.js +127 -0
  31. package/dist/es2019/ui/EditorLinkingPlatformAnalytics/common.js +60 -0
  32. package/dist/es2019/ui/EditorLinkingPlatformAnalytics/index.js +30 -0
  33. package/dist/es2019/version.json +1 -1
  34. package/dist/esm/analytics/create-events-queue.js +48 -0
  35. package/dist/esm/{pm-plugins/analytics → analytics}/events-from-tr.js +90 -80
  36. package/dist/esm/analytics/index.js +2 -0
  37. package/dist/esm/analytics/types.js +17 -0
  38. package/dist/esm/analytics/utils.js +118 -0
  39. package/dist/esm/nodeviews/datasource.js +2 -9
  40. package/dist/esm/plugin.js +7 -4
  41. package/dist/esm/pm-plugins/actions.js +0 -8
  42. package/dist/esm/pm-plugins/doc.js +3 -0
  43. package/dist/esm/pm-plugins/main.js +15 -13
  44. package/dist/esm/pm-plugins/reducers.js +0 -7
  45. package/dist/esm/ui/EditorLinkingPlatformAnalytics/DatasourceEvents.js +44 -0
  46. package/dist/esm/ui/EditorLinkingPlatformAnalytics/LinkEvents.js +125 -0
  47. package/dist/esm/ui/EditorLinkingPlatformAnalytics/common.js +55 -0
  48. package/dist/esm/ui/EditorLinkingPlatformAnalytics/index.js +47 -0
  49. package/dist/esm/version.json +1 -1
  50. package/dist/types/analytics/create-events-queue.d.ts +21 -0
  51. package/dist/types/analytics/events-from-tr.d.ts +19 -0
  52. package/dist/types/analytics/index.d.ts +2 -0
  53. package/dist/types/analytics/types.d.ts +66 -0
  54. package/dist/types/analytics/utils.d.ts +22 -0
  55. package/dist/types/nodeviews/datasource.d.ts +0 -2
  56. package/dist/types/pm-plugins/actions.d.ts +1 -2
  57. package/dist/types/pm-plugins/util/state.d.ts +0 -1
  58. package/dist/types/types.d.ts +4 -34
  59. package/dist/types/ui/EditorLinkingPlatformAnalytics/DatasourceEvents.d.ts +6 -0
  60. package/dist/types/ui/EditorLinkingPlatformAnalytics/LinkEvents.d.ts +6 -0
  61. package/dist/types/ui/EditorLinkingPlatformAnalytics/common.d.ts +20 -0
  62. package/dist/types/ui/EditorLinkingPlatformAnalytics/index.d.ts +9 -0
  63. package/dist/types-ts4.5/analytics/create-events-queue.d.ts +21 -0
  64. package/dist/types-ts4.5/analytics/events-from-tr.d.ts +19 -0
  65. package/dist/types-ts4.5/analytics/index.d.ts +2 -0
  66. package/dist/types-ts4.5/analytics/types.d.ts +66 -0
  67. package/dist/types-ts4.5/analytics/utils.d.ts +22 -0
  68. package/dist/types-ts4.5/nodeviews/datasource.d.ts +0 -2
  69. package/dist/types-ts4.5/pm-plugins/actions.d.ts +1 -2
  70. package/dist/types-ts4.5/pm-plugins/util/state.d.ts +0 -1
  71. package/dist/types-ts4.5/types.d.ts +4 -34
  72. package/dist/types-ts4.5/ui/EditorLinkingPlatformAnalytics/DatasourceEvents.d.ts +6 -0
  73. package/dist/types-ts4.5/ui/EditorLinkingPlatformAnalytics/LinkEvents.d.ts +6 -0
  74. package/dist/types-ts4.5/ui/EditorLinkingPlatformAnalytics/common.d.ts +20 -0
  75. package/dist/types-ts4.5/ui/EditorLinkingPlatformAnalytics/index.d.ts +9 -0
  76. package/package.json +3 -3
  77. package/report.api.md +84 -8
  78. package/tmp/api-report-tmp.d.ts +81 -8
  79. package/dist/cjs/pm-plugins/analytics/create-analytics-queue.js +0 -48
  80. package/dist/cjs/pm-plugins/analytics/types.js +0 -5
  81. package/dist/cjs/pm-plugins/analytics/utils.js +0 -178
  82. package/dist/cjs/ui/EditorSmartCardEventsNext.js +0 -204
  83. package/dist/es2019/pm-plugins/analytics/create-analytics-queue.js +0 -38
  84. package/dist/es2019/pm-plugins/analytics/index.js +0 -2
  85. package/dist/es2019/pm-plugins/analytics/types.js +0 -1
  86. package/dist/es2019/pm-plugins/analytics/utils.js +0 -160
  87. package/dist/es2019/ui/EditorSmartCardEventsNext.js +0 -188
  88. package/dist/esm/pm-plugins/analytics/create-analytics-queue.js +0 -41
  89. package/dist/esm/pm-plugins/analytics/index.js +0 -2
  90. package/dist/esm/pm-plugins/analytics/types.js +0 -1
  91. package/dist/esm/pm-plugins/analytics/utils.js +0 -160
  92. package/dist/esm/ui/EditorSmartCardEventsNext.js +0 -192
  93. package/dist/types/pm-plugins/analytics/create-analytics-queue.d.ts +0 -10
  94. package/dist/types/pm-plugins/analytics/events-from-tr.d.ts +0 -17
  95. package/dist/types/pm-plugins/analytics/index.d.ts +0 -2
  96. package/dist/types/pm-plugins/analytics/types.d.ts +0 -12
  97. package/dist/types/pm-plugins/analytics/utils.d.ts +0 -32
  98. package/dist/types/ui/EditorSmartCardEventsNext.d.ts +0 -18
  99. package/dist/types-ts4.5/pm-plugins/analytics/create-analytics-queue.d.ts +0 -10
  100. package/dist/types-ts4.5/pm-plugins/analytics/events-from-tr.d.ts +0 -17
  101. package/dist/types-ts4.5/pm-plugins/analytics/index.d.ts +0 -2
  102. package/dist/types-ts4.5/pm-plugins/analytics/types.d.ts +0 -12
  103. package/dist/types-ts4.5/pm-plugins/analytics/utils.d.ts +0 -32
  104. package/dist/types-ts4.5/ui/EditorSmartCardEventsNext.d.ts +0 -18
@@ -0,0 +1,127 @@
1
+ import { useEffect, useMemo } from 'react';
2
+ import { useSmartLinkLifecycleAnalytics } from '@atlaskit/link-analytics';
3
+ import { EVENT, EVENT_SUBJECT } from '../../analytics/types';
4
+ import { appearanceForLink, getUrl } from '../../analytics/utils';
5
+ import { getDeleteType, getMethod, getSourceEventFromMetadata, getUpdateType } from './common';
6
+
7
+ /**
8
+ * Set display category as `link` if not displaying the link as a smart card
9
+ */
10
+ const displayCategoryFromDisplay = display => {
11
+ if (display === 'url') {
12
+ return 'link';
13
+ }
14
+ };
15
+ /**
16
+ * Subscribes to the events occuring in the card
17
+ * plugin and fires analytics events accordingly
18
+ */
19
+ export const LinkEventsBinding = ({
20
+ cardPluginEvents
21
+ }) => {
22
+ /**
23
+ * These callbacks internally use window.requestIdleCallback/requestAnimationFrame
24
+ * to defer any heavy operations involving network
25
+ *
26
+ * The callbacks themselves should not be deferred, they should be called syncronously the moment
27
+ * the events take place.
28
+ */
29
+ const {
30
+ linkCreated,
31
+ linkUpdated,
32
+ linkDeleted
33
+ } = useSmartLinkLifecycleAnalytics();
34
+ const linkEvents = useMemo(() => {
35
+ return {
36
+ [EVENT.CREATED]: ({
37
+ node,
38
+ nodeContext,
39
+ ...metadata
40
+ }) => {
41
+ const url = getUrl(node);
42
+ if (!url) {
43
+ return;
44
+ }
45
+ const display = appearanceForLink(node);
46
+ const displayCategory = displayCategoryFromDisplay(display);
47
+ const sourceEvent = getSourceEventFromMetadata(metadata);
48
+ const creationMethod = getMethod(metadata);
49
+ linkCreated({
50
+ url,
51
+ displayCategory
52
+ }, sourceEvent, {
53
+ display,
54
+ nodeContext,
55
+ creationMethod
56
+ });
57
+ },
58
+ [EVENT.UPDATED]: ({
59
+ node,
60
+ nodeContext,
61
+ previousDisplay,
62
+ ...metadata
63
+ }) => {
64
+ const url = getUrl(node);
65
+ if (!url) {
66
+ return;
67
+ }
68
+ const display = appearanceForLink(node);
69
+ const displayCategory = displayCategoryFromDisplay(display);
70
+ const sourceEvent = getSourceEventFromMetadata(metadata);
71
+ const updateMethod = getMethod(metadata);
72
+ const updateType = getUpdateType(metadata);
73
+ linkUpdated({
74
+ url,
75
+ displayCategory
76
+ }, sourceEvent, {
77
+ display,
78
+ previousDisplay,
79
+ nodeContext,
80
+ updateMethod,
81
+ updateType
82
+ });
83
+ },
84
+ [EVENT.DELETED]: ({
85
+ node,
86
+ nodeContext,
87
+ ...metadata
88
+ }) => {
89
+ const url = getUrl(node);
90
+ if (!url) {
91
+ return;
92
+ }
93
+ const display = appearanceForLink(node);
94
+ const displayCategory = displayCategoryFromDisplay(display);
95
+ const sourceEvent = getSourceEventFromMetadata(metadata);
96
+ const deleteMethod = getMethod(metadata);
97
+ const deleteType = getDeleteType(metadata);
98
+ linkDeleted({
99
+ url,
100
+ displayCategory
101
+ }, sourceEvent, {
102
+ display,
103
+ nodeContext,
104
+ deleteMethod,
105
+ deleteType
106
+ });
107
+ }
108
+ };
109
+ }, [linkCreated, linkUpdated, linkDeleted]);
110
+
111
+ /**
112
+ * Subscribe to link events
113
+ */
114
+ useEffect(() => {
115
+ const unsubscribe = cardPluginEvents.subscribe(({
116
+ event,
117
+ subject,
118
+ data
119
+ }) => {
120
+ if (subject === EVENT_SUBJECT.LINK) {
121
+ linkEvents[event](data);
122
+ }
123
+ });
124
+ return () => unsubscribe();
125
+ }, [linkEvents, cardPluginEvents]);
126
+ return null;
127
+ };
@@ -0,0 +1,60 @@
1
+ import { UIAnalyticsEvent } from '@atlaskit/analytics-next';
2
+ import { ACTION, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
3
+ /**
4
+ * If the metadata is for a history event,
5
+ * returns undo/redo instead of instead of what fn(metadata) would have otherwise
6
+ * returned
7
+ */
8
+ const withHistoryMethod = fn => {
9
+ return metadata => {
10
+ const {
11
+ isUndo,
12
+ isRedo
13
+ } = metadata;
14
+ if (isUndo) {
15
+ return 'undo';
16
+ }
17
+ if (isRedo) {
18
+ return 'redo';
19
+ }
20
+ return fn(metadata);
21
+ };
22
+ };
23
+ export const getMethod = withHistoryMethod(({
24
+ inputMethod
25
+ }) => {
26
+ switch (inputMethod) {
27
+ case INPUT_METHOD.CLIPBOARD:
28
+ return 'editor_paste';
29
+ case INPUT_METHOD.FLOATING_TB:
30
+ return 'editor_floatingToolbar';
31
+ case INPUT_METHOD.AUTO_DETECT:
32
+ case INPUT_METHOD.FORMATTING:
33
+ return 'editor_type';
34
+ default:
35
+ return 'unknown';
36
+ }
37
+ });
38
+ export const getUpdateType = withHistoryMethod(({
39
+ action
40
+ }) => {
41
+ switch (action) {
42
+ case ACTION.CHANGED_TYPE:
43
+ return 'display_update';
44
+ case ACTION.UPDATED:
45
+ return 'link_update';
46
+ default:
47
+ return 'unknown';
48
+ }
49
+ });
50
+ export const getDeleteType = withHistoryMethod(({
51
+ action
52
+ }) => {
53
+ if (action === ACTION.UNLINK) {
54
+ return 'unlink';
55
+ }
56
+ return 'delete';
57
+ });
58
+ export const getSourceEventFromMetadata = metadata => {
59
+ return metadata.sourceEvent instanceof UIAnalyticsEvent ? metadata.sourceEvent : null;
60
+ };
@@ -0,0 +1,30 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import React from 'react';
3
+ import PropTypes from 'prop-types';
4
+ import { EditorAnalyticsContext } from '../EditorAnalyticsContext';
5
+ import { DatasourceEventsBinding } from './DatasourceEvents';
6
+ import { LinkEventsBinding } from './LinkEvents';
7
+
8
+ // eslint-disable-next-line @repo/internal/react/no-class-components
9
+ export class EditorLinkingPlatformAnalytics extends React.PureComponent {
10
+ render() {
11
+ const cardContext = this.context.contextAdapter.card;
12
+
13
+ /**
14
+ * The analytics hook needs to be able to communicate with the card context
15
+ * If we can't access it, don't mount the event bindings
16
+ * This effectively entirely disables all tracking behaviour
17
+ */
18
+ if (!cardContext) {
19
+ return null;
20
+ }
21
+ return /*#__PURE__*/React.createElement(cardContext.Provider, {
22
+ value: cardContext.value
23
+ }, /*#__PURE__*/React.createElement(EditorAnalyticsContext, {
24
+ editorView: this.props.editorView
25
+ }, /*#__PURE__*/React.createElement(LinkEventsBinding, this.props), /*#__PURE__*/React.createElement(DatasourceEventsBinding, this.props)));
26
+ }
27
+ }
28
+ _defineProperty(EditorLinkingPlatformAnalytics, "contextTypes", {
29
+ contextAdapter: PropTypes.object
30
+ });
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-card",
3
- "version": "0.3.4",
3
+ "version": "0.3.6",
4
4
  "sideEffects": false
5
5
  }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Simple mechanism to defer event related callbacks
3
+ *
4
+ * Probably think twice whether your event should use this instead of
5
+ * editor's built-in `editor-plugin-analytics`
6
+ *
7
+ * Editor-Plugin-Analytics provides methods methods to dispatch events, and attach events into prosemiror transactions
8
+ * However we do not have access to the smart card context in prosemirror
9
+ *
10
+ * We are using this queue to relay events occurring in prosemirror (which does not have access to the react context)
11
+ * to be subscribed to elsewhere where the react context is available (contentComponent or otherwise) (smart card context)
12
+ * in order to be able to annotate events with additional attributes to events
13
+ */
14
+ export var createEventsQueue = function createEventsQueue() {
15
+ var queue = [];
16
+ var subscribers = new Set();
17
+ var subscribe = function subscribe(subscriber) {
18
+ subscribers.add(subscriber);
19
+ return function () {
20
+ subscribers.delete(subscriber);
21
+ };
22
+ };
23
+ var push = function push() {
24
+ queue.push.apply(queue, arguments);
25
+ };
26
+ var flush = function flush() {
27
+ var _loop = function _loop() {
28
+ var event = queue.shift();
29
+ if (event) {
30
+ subscribers.forEach(function (subscriber) {
31
+ subscriber(event);
32
+ });
33
+ }
34
+ };
35
+ while (queue.length) {
36
+ _loop();
37
+ }
38
+ };
39
+ var getSize = function getSize() {
40
+ return queue.length;
41
+ };
42
+ return {
43
+ push: push,
44
+ flush: flush,
45
+ subscribe: subscribe,
46
+ getSize: getSize
47
+ };
48
+ };
@@ -1,35 +1,28 @@
1
- import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
1
  import _typeof from "@babel/runtime/helpers/typeof";
3
2
  import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
4
- 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; }
5
- 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; }
6
3
  import { LinkMetaStep, TableSortStep } from '@atlaskit/adf-schema/steps';
7
4
  import { ACTION } from '@atlaskit/editor-common/analytics';
8
5
  import { getLinkMetadataFromTransaction } from '@atlaskit/editor-common/card';
9
6
  import { isLinkMark, pmHistoryPluginKey } from '@atlaskit/editor-common/utils';
10
7
  import { AddMarkStep, RemoveMarkStep } from '@atlaskit/editor-prosemirror/transform';
11
- import { pluginKey } from '../plugin-key';
12
- import { getPluginState } from '../util/state';
13
- import { appearanceForLink, areSameLinks, findLinksAtPositions, getLinkNodeContext, getLinkUrl, isLink, linkObjectFromNode } from './utils';
14
- var findLinksInNodeRange = function findLinksInNodeRange(doc, schema, from, to) {
15
- var links = [];
16
- doc.nodesBetween(from, to, function (node, pos) {
17
- if (isLink(schema, node)) {
18
- var entireLinkInRange = pos >= from && pos + node.nodeSize <= to;
19
- if (entireLinkInRange) {
20
- var link = linkObjectFromNode(doc, schema, node, pos);
21
- if (link) {
22
- links.push(link);
23
- }
24
- }
25
- }
26
- });
27
- return links;
28
- };
29
- export var findChangedLinks = function findChangedLinks(tr, state) {
8
+ import { pluginKey } from '../pm-plugins/plugin-key';
9
+ import { getPluginState } from '../pm-plugins/util/state';
10
+ import { EVENT } from './types';
11
+ import { appearanceForLink, areSameNodes, findAtPositions, findInNodeRange, getNodeContext, getNodeSubject } from './utils';
12
+
13
+ /**
14
+ * Find the links, smartLinks, datasources that were changed in a transaction
15
+ */
16
+ export var findChanged = function findChanged(tr, state) {
30
17
  var schema = tr.doc.type.schema;
31
18
  var removed = [];
32
19
  var inserted = [];
20
+ /**
21
+ * Ideally we have the "before" and "after" states of the "entity"
22
+ * being updated, but if the update is via a "queue for upgrade"
23
+ * then we no longer have access to the "before" state, because the "before"
24
+ * state was replaced with a blue link to be upgraded
25
+ */
33
26
  var updated = [];
34
27
  var queuedForUpgrade = isTransactionQueuedForUpgrade(tr);
35
28
  var isResolveReplace = isTransactionResolveReplace(tr);
@@ -56,26 +49,30 @@ export var findChangedLinks = function findChangedLinks(tr, state) {
56
49
  if (step instanceof AddMarkStep) {
57
50
  var addMarkStep = step;
58
51
  if (isLinkMark(addMarkStep.mark, schema)) {
59
- /**
60
- * For url text pasted on plain text
61
- */
62
- insertedInStep.push({
63
- type: 'mark',
64
- pos: addMarkStep.from,
65
- mark: addMarkStep.mark,
66
- nodeContext: getLinkNodeContext(after, addMarkStep.from)
67
- });
52
+ var node = after.nodeAt(addMarkStep.from);
53
+ if (node) {
54
+ /**
55
+ * For url text pasted on plain text
56
+ */
57
+ insertedInStep.push({
58
+ pos: addMarkStep.from,
59
+ node: node,
60
+ nodeContext: getNodeContext(after, addMarkStep.from)
61
+ });
62
+ }
68
63
  }
69
64
  }
70
65
  if (step instanceof RemoveMarkStep) {
71
66
  var removeMarkStep = step;
72
67
  if (isLinkMark(removeMarkStep.mark, schema)) {
73
- removedInStep.push({
74
- type: 'mark',
75
- pos: removeMarkStep.from,
76
- mark: removeMarkStep.mark,
77
- nodeContext: getLinkNodeContext(before, removeMarkStep.from)
78
- });
68
+ var _node = before.nodeAt(removeMarkStep.from);
69
+ if (_node) {
70
+ removedInStep.push({
71
+ pos: removeMarkStep.from,
72
+ node: _node,
73
+ nodeContext: getNodeContext(before, removeMarkStep.from)
74
+ });
75
+ }
79
76
  }
80
77
  }
81
78
  stepMap.forEach(function (oldStart, oldEnd, newStart, newEnd) {
@@ -86,13 +83,17 @@ export var findChangedLinks = function findChangedLinks(tr, state) {
86
83
  var insertedInRange = [];
87
84
 
88
85
  // Removed
89
- removedInRange.push.apply(removedInRange, _toConsumableArray(findLinksInNodeRange(before, schema, oldStart, oldEnd)));
86
+ removedInRange.push.apply(removedInRange, _toConsumableArray(findInNodeRange(before, oldStart, oldEnd, function (node) {
87
+ return !!getNodeSubject(node);
88
+ })));
90
89
  // Inserted
91
- insertedInRange.push.apply(insertedInRange, _toConsumableArray(findLinksInNodeRange(after, schema, newStart, newEnd)));
90
+ insertedInRange.push.apply(insertedInRange, _toConsumableArray(findInNodeRange(after, newStart, newEnd, function (node) {
91
+ return !!getNodeSubject(node);
92
+ })));
92
93
  removedInStep.push.apply(removedInStep, removedInRange);
93
94
  insertedInStep.push.apply(insertedInStep, insertedInRange);
94
95
  });
95
- var omitQueuedLinks = function omitQueuedLinks(links) {
96
+ var omitRequestsForUpgrade = function omitRequestsForUpgrade(links) {
96
97
  if (!queuedForUpgrade) {
97
98
  return links;
98
99
  }
@@ -114,7 +115,7 @@ export var findChangedLinks = function findChangedLinks(tr, state) {
114
115
  if (!isResolveReplace) {
115
116
  removed.push.apply(removed, removedInStep);
116
117
  }
117
- inserted.push.apply(inserted, _toConsumableArray(omitQueuedLinks(insertedInStep)));
118
+ inserted.push.apply(inserted, _toConsumableArray(omitRequestsForUpgrade(insertedInStep)));
118
119
  };
119
120
  for (var i = 0; i < tr.steps.length; i++) {
120
121
  _loop(i);
@@ -127,7 +128,7 @@ export var findChangedLinks = function findChangedLinks(tr, state) {
127
128
  */
128
129
  if (inserted.length === 0 && isResolveReplace) {
129
130
  var positions = getResolvePositions(tr, state);
130
- inserted.push.apply(inserted, _toConsumableArray(findLinksAtPositions(tr, positions)));
131
+ inserted.push.apply(inserted, _toConsumableArray(findAtPositions(tr, positions)));
131
132
  }
132
133
  if (!isUpdate) {
133
134
  var _getLinkMetadataFromT = getLinkMetadataFromTransaction(tr),
@@ -136,7 +137,7 @@ export var findChangedLinks = function findChangedLinks(tr, state) {
136
137
  * If there is no identifiable input method, and the links inserted and removed appear to be the same,
137
138
  * then this transaction likely is not intended to be consided to be the insertion and removal of links
138
139
  */
139
- if (!inputMethod && areSameLinks(removed, inserted)) {
140
+ if (!inputMethod && areSameNodes(removed, inserted)) {
140
141
  return {
141
142
  removed: [],
142
143
  inserted: [],
@@ -291,17 +292,10 @@ export function eventsFromTransaction(tr, state) {
291
292
  action = _getLinkMetadataFromT2.action,
292
293
  inputMethod = _getLinkMetadataFromT2.inputMethod,
293
294
  sourceEvent = _getLinkMetadataFromT2.sourceEvent;
294
- var contextualData = {
295
- action: action,
296
- inputMethod: inputMethod,
297
- sourceEvent: sourceEvent,
298
- isUndo: isUndo,
299
- isRedo: isRedo
300
- };
301
- var _findChangedLinks = findChangedLinks(tr, state),
302
- removed = _findChangedLinks.removed,
303
- inserted = _findChangedLinks.inserted,
304
- updated = _findChangedLinks.updated;
295
+ var _findChanged = findChanged(tr, state),
296
+ removed = _findChanged.removed,
297
+ inserted = _findChanged.inserted,
298
+ updated = _findChanged.updated;
305
299
  var MAX_LINK_EVENTS = 50;
306
300
  if ([removed, inserted, updated].some(function (arr) {
307
301
  return arr.length > MAX_LINK_EVENTS;
@@ -311,41 +305,57 @@ export function eventsFromTransaction(tr, state) {
311
305
  for (var i = 0; i < updated.length; i++) {
312
306
  var _update$previous$disp;
313
307
  var update = updated[i];
314
- var link = update.inserted;
315
- var url = getLinkUrl(link);
316
- var display = appearanceForLink(link);
317
- var previousDisplay = 'removed' in update ? appearanceForLink(update.removed) : (_update$previous$disp = update.previous.display) !== null && _update$previous$disp !== void 0 ? _update$previous$disp : 'unknown';
318
- if (url) {
308
+ var _inserted = update.inserted;
309
+ var node = _inserted.node,
310
+ nodeContext = _inserted.nodeContext;
311
+ var subject = getNodeSubject(node);
312
+
313
+ /**
314
+ * Not great, wish we had the previous node but we never stored it
315
+ */
316
+ var previousDisplay = 'removed' in update ? appearanceForLink(update.removed.node) : (_update$previous$disp = update.previous.display) !== null && _update$previous$disp !== void 0 ? _update$previous$disp : 'unknown';
317
+ if (subject) {
319
318
  events.push({
320
- type: 'updated',
321
- data: _objectSpread(_objectSpread({}, contextualData), {}, {
322
- url: url,
323
- display: display,
324
- previousDisplay: previousDisplay,
325
- nodeContext: link.nodeContext
326
- })
319
+ event: EVENT.UPDATED,
320
+ subject: subject,
321
+ data: {
322
+ node: node,
323
+ nodeContext: nodeContext,
324
+ action: action,
325
+ inputMethod: inputMethod,
326
+ sourceEvent: sourceEvent,
327
+ isUndo: isUndo,
328
+ isRedo: isRedo,
329
+ previousDisplay: previousDisplay
330
+ }
327
331
  });
328
332
  }
329
333
  }
330
- var pushEvents = function pushEvents(links, type) {
331
- for (var _i2 = 0; _i2 < links.length; _i2++) {
332
- var _link = links[_i2];
333
- var _url = getLinkUrl(_link);
334
- var _display = appearanceForLink(_link);
335
- if (_url) {
334
+ var pushEvents = function pushEvents(entities, event) {
335
+ for (var _i2 = 0; _i2 < entities.length; _i2++) {
336
+ var _entities$_i = entities[_i2],
337
+ _node2 = _entities$_i.node,
338
+ _nodeContext = _entities$_i.nodeContext;
339
+ var _subject = getNodeSubject(_node2);
340
+ if (_subject) {
336
341
  events.push({
337
- type: type,
338
- data: _objectSpread(_objectSpread({}, contextualData), {}, {
339
- url: _url,
340
- display: _display,
341
- nodeContext: _link.nodeContext
342
- })
342
+ event: event,
343
+ subject: _subject,
344
+ data: {
345
+ node: _node2,
346
+ nodeContext: _nodeContext,
347
+ action: action,
348
+ inputMethod: inputMethod,
349
+ sourceEvent: sourceEvent,
350
+ isUndo: isUndo,
351
+ isRedo: isRedo
352
+ }
343
353
  });
344
354
  }
345
355
  }
346
356
  };
347
- pushEvents(removed, 'deleted');
348
- pushEvents(inserted, 'created');
357
+ pushEvents(removed, EVENT.DELETED);
358
+ pushEvents(inserted, EVENT.CREATED);
349
359
  return events;
350
360
  } catch (err) {
351
361
  return events;
@@ -0,0 +1,2 @@
1
+ export { createEventsQueue } from './create-events-queue';
2
+ export { eventsFromTransaction } from './events-from-tr';
@@ -0,0 +1,17 @@
1
+ export var EVENT = /*#__PURE__*/function (EVENT) {
2
+ EVENT["CREATED"] = "created";
3
+ EVENT["UPDATED"] = "updated";
4
+ EVENT["DELETED"] = "deleted";
5
+ return EVENT;
6
+ }({});
7
+ export var EVENT_SUBJECT = /*#__PURE__*/function (EVENT_SUBJECT) {
8
+ EVENT_SUBJECT["LINK"] = "link";
9
+ EVENT_SUBJECT["DATASOURCE"] = "datasource";
10
+ return EVENT_SUBJECT;
11
+ }({});
12
+
13
+ /**
14
+ * These are not GASv3 events
15
+ * But they share a similar in shape so that GASv3
16
+ * events can be derived from them / think of them in the same way
17
+ */
@@ -0,0 +1,118 @@
1
+ import { appearanceForNodeType } from '../utils';
2
+ import { EVENT_SUBJECT } from './types';
3
+ export function isDatasourceNode(node) {
4
+ return 'datasource' in node.attrs && !!node.attrs.datasource;
5
+ }
6
+
7
+ /**
8
+ * Determine if a node is considered to be a link
9
+ */
10
+ export var isLinkNode = function isLinkNode(node) {
11
+ if (isDatasourceNode(node)) {
12
+ return false;
13
+ }
14
+ if (!!appearanceForNodeType(node.type)) {
15
+ return true;
16
+ }
17
+ return hasLinkMark(node);
18
+ };
19
+ export function getNodeSubject(node) {
20
+ if (isDatasourceNode(node)) {
21
+ return EVENT_SUBJECT.DATASOURCE;
22
+ }
23
+ if (isLinkNode(node)) {
24
+ return EVENT_SUBJECT.LINK;
25
+ }
26
+ return null;
27
+ }
28
+
29
+ /**
30
+ * Analytics appearance for link object
31
+ */
32
+ export function appearanceForLink(node) {
33
+ var appearance = appearanceForNodeType(node.type);
34
+ if (appearance) {
35
+ return appearance;
36
+ }
37
+ return 'url';
38
+ }
39
+ var getLinkMark = function getLinkMark(node) {
40
+ if (node.marks) {
41
+ for (var i = 0; i < node.marks.length; i++) {
42
+ var mark = node.marks[i];
43
+ if (mark.type.name === 'link') {
44
+ return mark;
45
+ }
46
+ }
47
+ }
48
+ };
49
+ var hasLinkMark = function hasLinkMark(node) {
50
+ return !!getLinkMark(node);
51
+ };
52
+ export function getUrl(node) {
53
+ var _node$attrs$url, _node$attrs, _getLinkMark, _getLinkMark$attrs;
54
+ return (_node$attrs$url = (_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.url) !== null && _node$attrs$url !== void 0 ? _node$attrs$url : (_getLinkMark = getLinkMark(node)) === null || _getLinkMark === void 0 ? void 0 : (_getLinkMark$attrs = _getLinkMark.attrs) === null || _getLinkMark$attrs === void 0 ? void 0 : _getLinkMark$attrs.href;
55
+ }
56
+ export var getNodeContext = function getNodeContext(doc, pos) {
57
+ var $pos = doc.resolve(pos);
58
+ var maxDepth = 3;
59
+ for (var i = 0; i <= maxDepth; i++) {
60
+ var _node = $pos.node($pos.depth - i);
61
+ if (_node && _node.type.name !== 'paragraph') {
62
+ return _node.type.name;
63
+ }
64
+ }
65
+ return 'unknown';
66
+ };
67
+ export var findAtPositions = function findAtPositions(tr, positions) {
68
+ var entities = [];
69
+ for (var i = 0; i < positions.length; i++) {
70
+ var pos = positions[i];
71
+ var _node2 = tr.doc.nodeAt(pos);
72
+ if (!_node2) {
73
+ continue;
74
+ }
75
+ var nodeContext = getNodeContext(tr.doc, pos);
76
+ entities.push({
77
+ pos: pos,
78
+ node: _node2,
79
+ nodeContext: nodeContext
80
+ });
81
+ }
82
+ return entities;
83
+ };
84
+ export var findInNodeRange = function findInNodeRange(doc, from, to, predicate) {
85
+ var entities = [];
86
+ doc.nodesBetween(from, to, function (node, pos) {
87
+ if (predicate(node)) {
88
+ var entirelyInRange = pos >= from && pos + node.nodeSize <= to;
89
+ if (entirelyInRange) {
90
+ var nodeContext = getNodeContext(doc, pos);
91
+ entities.push({
92
+ pos: pos,
93
+ node: node,
94
+ nodeContext: nodeContext
95
+ });
96
+ }
97
+ }
98
+ });
99
+ return entities;
100
+ };
101
+
102
+ /**
103
+ * Returns whether or not two sets of links appear to likely be the same set of links
104
+ * That they are in the same order and that both their hrefs and appearances match
105
+ */
106
+ export var areSameNodes = function areSameNodes(setA, setB) {
107
+ if (setA.length !== setB.length) {
108
+ return false;
109
+ }
110
+ for (var i = 0; i < setA.length; i++) {
111
+ var a = setA[i];
112
+ var b = setB[i];
113
+ if (getUrl(a.node) !== getUrl(b.node) || appearanceForLink(a.node) !== appearanceForLink(b.node)) {
114
+ return false;
115
+ }
116
+ }
117
+ return true;
118
+ };