@atlaskit/editor-plugin-table 2.7.2 → 2.8.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/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @atlaskit/editor-plugin-table
2
2
 
3
+ ## 2.8.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`7472b6ab3b4`](https://bitbucket.org/atlassian/atlassian-frontend/commits/7472b6ab3b4) - [ED-19329] Add analytics event for table resize framerate
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies
12
+
3
13
  ## 2.7.2
4
14
 
5
15
  ### Patch Changes
@@ -10,16 +10,14 @@ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/de
10
10
  var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
11
11
  var _react = _interopRequireWildcard(require("react"));
12
12
  var _rafSchd = _interopRequireDefault(require("raf-schd"));
13
- var _analytics = require("@atlaskit/editor-common/analytics");
14
13
  var _guideline = require("@atlaskit/editor-common/guideline");
15
14
  var _resizer = require("@atlaskit/editor-common/resizer");
16
15
  var _styles = require("@atlaskit/editor-common/styles");
17
- var _editorTables = require("@atlaskit/editor-tables");
18
16
  var _utils = require("@atlaskit/editor-tables/utils");
19
17
  var _utils2 = require("../pm-plugins/table-resizing/utils");
20
18
  var _tableWidth = require("../pm-plugins/table-width");
21
19
  var _consts = require("../ui/consts");
22
- var _utils3 = require("../utils");
20
+ var _analytics = require("../utils/analytics");
23
21
  var _guidelines = require("../utils/guidelines");
24
22
  var _snapping = require("../utils/snapping");
25
23
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
@@ -30,23 +28,6 @@ var handles = {
30
28
  right: true
31
29
  };
32
30
  var tableHandleMarginTop = 12;
33
- var generateResizedPayload = function generateResizedPayload(props) {
34
- var _props$originalNode$a;
35
- var tableMap = _editorTables.TableMap.get(props.resizedNode);
36
- return {
37
- action: _analytics.TABLE_ACTION.RESIZED,
38
- actionSubject: _analytics.ACTION_SUBJECT.TABLE,
39
- eventType: _analytics.EVENT_TYPE.TRACK,
40
- attributes: {
41
- newWidth: props.resizedNode.attrs.width,
42
- prevWidth: (_props$originalNode$a = props.originalNode.attrs.width) !== null && _props$originalNode$a !== void 0 ? _props$originalNode$a : null,
43
- nodeSize: props.resizedNode.nodeSize,
44
- totalTableWidth: (0, _utils2.hasTableBeenResized)(props.resizedNode) ? (0, _utils3.getTableWidth)(props.resizedNode) : null,
45
- totalRowCount: tableMap.height,
46
- totalColumnCount: tableMap.width
47
- }
48
- };
49
- };
50
31
  var getResizerHandleHeight = function getResizerHandleHeight(tableRef) {
51
32
  var tableHeight = tableRef === null || tableRef === void 0 ? void 0 : tableRef.clientHeight;
52
33
  var handleHeightSize = 'small';
@@ -89,6 +70,10 @@ var TableResizer = function TableResizer(_ref) {
89
70
  setSnappingEnabled = _useState2[1];
90
71
  var resizerMinWidth = getResizerMinWidth(node);
91
72
  var handleHeightSize = getResizerHandleHeight(tableRef);
73
+ var _useMeasureFramerate = (0, _analytics.useMeasureFramerate)(),
74
+ startMeasure = _useMeasureFramerate.startMeasure,
75
+ endMeasure = _useMeasureFramerate.endMeasure,
76
+ countFrames = _useMeasureFramerate.countFrames;
92
77
  var updateActiveGuidelines = (0, _react.useCallback)(function (_ref2) {
93
78
  var gap = _ref2.gap,
94
79
  keys = _ref2.keys;
@@ -103,13 +88,14 @@ var TableResizer = function TableResizer(_ref) {
103
88
  } : undefined;
104
89
  }, [snappingEnabled]);
105
90
  var handleResizeStart = (0, _react.useCallback)(function () {
91
+ startMeasure();
106
92
  var dispatch = editorView.dispatch,
107
93
  tr = editorView.state.tr;
108
94
  dispatch(tr.setMeta(_tableWidth.pluginKey, {
109
95
  resizing: true
110
96
  }));
111
97
  setSnappingEnabled(displayGuideline(_guidelines.defaultGuidelines));
112
- }, [displayGuideline, editorView]);
98
+ }, [displayGuideline, editorView, startMeasure]);
113
99
  var handleResizeStop = (0, _react.useCallback)(function (originalState, delta) {
114
100
  var newWidth = originalState.width + delta.width;
115
101
  var state = editorView.state,
@@ -118,8 +104,20 @@ var TableResizer = function TableResizer(_ref) {
118
104
  var tr = state.tr.setMeta(_tableWidth.pluginKey, {
119
105
  resizing: false
120
106
  });
107
+ var frameRateSamples = endMeasure();
108
+ if (frameRateSamples.length > 0) {
109
+ var resizeFrameRatePayloads = (0, _analytics.generateResizeFrameRatePayloads)({
110
+ docSize: state.doc.nodeSize,
111
+ frameRateSamples: frameRateSamples,
112
+ originalNode: node
113
+ });
114
+ resizeFrameRatePayloads.forEach(function (payload) {
115
+ var _attachAnalyticsEvent;
116
+ (_attachAnalyticsEvent = attachAnalyticsEvent(payload)) === null || _attachAnalyticsEvent === void 0 ? void 0 : _attachAnalyticsEvent(tr);
117
+ });
118
+ }
121
119
  if (typeof pos === 'number') {
122
- var _attachAnalyticsEvent;
120
+ var _attachAnalyticsEvent2;
123
121
  tr = tr.setNodeMarkup(pos, undefined, _objectSpread(_objectSpread({}, node.attrs), {}, {
124
122
  width: newWidth
125
123
  }));
@@ -131,10 +129,10 @@ var TableResizer = function TableResizer(_ref) {
131
129
  parentWidth: newWidth
132
130
  }, editorView.domAtPos.bind(editorView))(tr);
133
131
  var scaledNode = tr.doc.nodeAt(pos);
134
- (_attachAnalyticsEvent = attachAnalyticsEvent(generateResizedPayload({
132
+ (_attachAnalyticsEvent2 = attachAnalyticsEvent((0, _analytics.generateResizedPayload)({
135
133
  originalNode: node,
136
134
  resizedNode: scaledNode
137
- }))) === null || _attachAnalyticsEvent === void 0 ? void 0 : _attachAnalyticsEvent(tr);
135
+ }))) === null || _attachAnalyticsEvent2 === void 0 ? void 0 : _attachAnalyticsEvent2(tr);
138
136
  }
139
137
  dispatch(tr);
140
138
 
@@ -142,8 +140,9 @@ var TableResizer = function TableResizer(_ref) {
142
140
  displayGuideline([]);
143
141
  updateWidth(newWidth);
144
142
  return newWidth;
145
- }, [updateWidth, editorView, getPos, node, tableRef, displayGuideline, attachAnalyticsEvent]);
143
+ }, [updateWidth, editorView, getPos, node, tableRef, displayGuideline, attachAnalyticsEvent, endMeasure]);
146
144
  var handleResize = (0, _react.useCallback)(function (originalState, delta) {
145
+ countFrames();
147
146
  var newWidth = originalState.width + delta.width;
148
147
  var pos = getPos();
149
148
  if (typeof pos !== 'number') {
@@ -158,7 +157,7 @@ var TableResizer = function TableResizer(_ref) {
158
157
  updateActiveGuidelines((0, _snapping.findClosestSnap)(newWidth, _guidelines.defaultGuidelineWidths, _guidelines.defaultGuidelines, _consts.TABLE_HIGHLIGHT_GAP));
159
158
  updateWidth(newWidth);
160
159
  return newWidth;
161
- }, [editorView, getPos, node, tableRef, updateWidth, updateActiveGuidelines]);
160
+ }, [editorView, getPos, node, tableRef, updateWidth, updateActiveGuidelines, countFrames]);
162
161
  var scheduleResize = (0, _react.useMemo)(function () {
163
162
  return (0, _rafSchd.default)(handleResize);
164
163
  }, [handleResize]);
@@ -3,11 +3,16 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.generateResizedPayload = exports.generateResizeFrameRatePayloads = void 0;
6
7
  exports.getSelectedCellInfo = getSelectedCellInfo;
7
8
  exports.getSelectedTableInfo = getSelectedTableInfo;
8
- exports.withEditorAnalyticsAPI = void 0;
9
+ exports.withEditorAnalyticsAPI = exports.useMeasureFramerate = exports.reduceResizeFrameRateSamples = void 0;
10
+ var _react = require("react");
11
+ var _analytics = require("@atlaskit/editor-common/analytics");
9
12
  var _tableMap = require("@atlaskit/editor-tables/table-map");
10
13
  var _utils = require("@atlaskit/editor-tables/utils");
14
+ var _utils2 = require("../pm-plugins/table-resizing/utils");
15
+ var _utils3 = require("../utils");
11
16
  function getSelectedTableInfo(selection) {
12
17
  var map;
13
18
  var totalRowCount = 0;
@@ -68,4 +73,143 @@ var withEditorAnalyticsAPI = function withEditorAnalyticsAPI(payload) {
68
73
  };
69
74
  };
70
75
  };
71
- exports.withEditorAnalyticsAPI = withEditorAnalyticsAPI;
76
+ exports.withEditorAnalyticsAPI = withEditorAnalyticsAPI;
77
+ var generateResizedPayload = function generateResizedPayload(props) {
78
+ var _props$originalNode$a;
79
+ var tableMap = _tableMap.TableMap.get(props.resizedNode);
80
+ return {
81
+ action: _analytics.TABLE_ACTION.RESIZED,
82
+ actionSubject: _analytics.ACTION_SUBJECT.TABLE,
83
+ eventType: _analytics.EVENT_TYPE.TRACK,
84
+ attributes: {
85
+ newWidth: props.resizedNode.attrs.width,
86
+ prevWidth: (_props$originalNode$a = props.originalNode.attrs.width) !== null && _props$originalNode$a !== void 0 ? _props$originalNode$a : null,
87
+ nodeSize: props.resizedNode.nodeSize,
88
+ totalTableWidth: (0, _utils2.hasTableBeenResized)(props.resizedNode) ? (0, _utils3.getTableWidth)(props.resizedNode) : null,
89
+ totalRowCount: tableMap.height,
90
+ totalColumnCount: tableMap.width
91
+ }
92
+ };
93
+ };
94
+ exports.generateResizedPayload = generateResizedPayload;
95
+ var reduceResizeFrameRateSamples = function reduceResizeFrameRateSamples(frameRateSamples) {
96
+ if (frameRateSamples.length > 1) {
97
+ var frameRateSum = frameRateSamples.reduce(function (sum, frameRate, index) {
98
+ if (index === 0) {
99
+ return sum;
100
+ } else {
101
+ return sum + frameRate;
102
+ }
103
+ }, 0);
104
+ var averageFrameRate = Math.round(frameRateSum / (frameRateSamples.length - 1));
105
+ return [frameRateSamples[0], averageFrameRate];
106
+ } else {
107
+ return frameRateSamples;
108
+ }
109
+ };
110
+ exports.reduceResizeFrameRateSamples = reduceResizeFrameRateSamples;
111
+ var generateResizeFrameRatePayloads = function generateResizeFrameRatePayloads(props) {
112
+ var reducedResizeFrameRateSamples = reduceResizeFrameRateSamples(props.frameRateSamples);
113
+ return reducedResizeFrameRateSamples.map(function (frameRateSample, index) {
114
+ return {
115
+ action: _analytics.TABLE_ACTION.RESIZE_PERF_SAMPLING,
116
+ actionSubject: _analytics.ACTION_SUBJECT.TABLE,
117
+ eventType: _analytics.EVENT_TYPE.OPERATIONAL,
118
+ attributes: {
119
+ frameRate: frameRateSample,
120
+ nodeSize: props.originalNode.nodeSize,
121
+ docSize: props.docSize,
122
+ isInitialSample: index === 0
123
+ }
124
+ };
125
+ });
126
+ };
127
+
128
+ /**
129
+ * Measures the framerate of a component over a given time period.
130
+ */
131
+ exports.generateResizeFrameRatePayloads = generateResizeFrameRatePayloads;
132
+ var useMeasureFramerate = function useMeasureFramerate() {
133
+ var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
134
+ var _config$maxSamples = config.maxSamples,
135
+ maxSamples = _config$maxSamples === void 0 ? 10 : _config$maxSamples,
136
+ _config$minFrames = config.minFrames,
137
+ minFrames = _config$minFrames === void 0 ? 5 : _config$minFrames,
138
+ _config$minTimeMs = config.minTimeMs,
139
+ minTimeMs = _config$minTimeMs === void 0 ? 500 : _config$minTimeMs,
140
+ _config$sampleRateMs = config.sampleRateMs,
141
+ sampleRateMs = _config$sampleRateMs === void 0 ? 1000 : _config$sampleRateMs,
142
+ _config$timeoutMs = config.timeoutMs,
143
+ timeoutMs = _config$timeoutMs === void 0 ? 200 : _config$timeoutMs;
144
+ var frameCount = (0, _react.useRef)(0);
145
+ var lastTime = (0, _react.useRef)(0);
146
+ var timeoutId = (0, _react.useRef)();
147
+ var frameRateSamples = (0, _react.useRef)([]);
148
+ (0, _react.useEffect)(function () {
149
+ return function () {
150
+ if (timeoutId.current) {
151
+ clearTimeout(timeoutId.current);
152
+ }
153
+ };
154
+ }, []);
155
+ var startMeasure = function startMeasure() {
156
+ frameCount.current = 0;
157
+ lastTime.current = performance.now();
158
+ };
159
+
160
+ /**
161
+ * Returns an array of frame rate samples as integers.
162
+ */
163
+ var endMeasure = function endMeasure() {
164
+ var samples = frameRateSamples.current;
165
+ frameRateSamples.current = [];
166
+ return samples;
167
+ };
168
+ var sampleFrameRate = function sampleFrameRate() {
169
+ var delay = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
170
+ var currentTime = performance.now();
171
+ var deltaTime = currentTime - lastTime.current - delay;
172
+ var isValidSample = deltaTime > minTimeMs && frameCount.current >= minFrames;
173
+ if (isValidSample) {
174
+ var frameRate = Math.round(frameCount.current / (deltaTime / 1000));
175
+ frameRateSamples.current.push(frameRate);
176
+ }
177
+ frameCount.current = 0;
178
+ lastTime.current = 0;
179
+ };
180
+
181
+ /**
182
+ * Counts the number of frames that occur within a given time period. Intended to be called
183
+ * inside a `requestAnimationFrame` callback.
184
+ */
185
+ var countFrames = function countFrames() {
186
+ if (frameRateSamples.current.length >= maxSamples && timeoutId.current) {
187
+ clearTimeout(timeoutId.current);
188
+ return;
189
+ }
190
+
191
+ /**
192
+ * Allows us to keep counting frames even if `startMeasure` is not called
193
+ */
194
+ if (lastTime.current === 0) {
195
+ lastTime.current = performance.now();
196
+ }
197
+ frameCount.current++;
198
+ if (timeoutId.current) {
199
+ clearTimeout(timeoutId.current);
200
+ }
201
+ if (performance.now() - lastTime.current > sampleRateMs) {
202
+ sampleFrameRate();
203
+ } else {
204
+ timeoutId.current = setTimeout(function () {
205
+ return sampleFrameRate(timeoutMs);
206
+ }, timeoutMs);
207
+ }
208
+ };
209
+ return {
210
+ startMeasure: startMeasure,
211
+ endMeasure: endMeasure,
212
+ countFrames: countFrames
213
+ };
214
+ };
215
+ exports.useMeasureFramerate = useMeasureFramerate;
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-table",
3
- "version": "2.7.2",
3
+ "version": "2.8.0",
4
4
  "sideEffects": false
5
5
  }
@@ -1,38 +1,19 @@
1
1
  import React, { useCallback, useMemo, useRef, useState } from 'react';
2
2
  import rafSchd from 'raf-schd';
3
- import { ACTION_SUBJECT, EVENT_TYPE, TABLE_ACTION } from '@atlaskit/editor-common/analytics';
4
3
  import { getGuidelinesWithHighlights } from '@atlaskit/editor-common/guideline';
5
4
  import { ResizerNext } from '@atlaskit/editor-common/resizer';
6
5
  import { resizerHandleShadowClassName } from '@atlaskit/editor-common/styles';
7
- import { TableMap } from '@atlaskit/editor-tables';
8
6
  import { findTable } from '@atlaskit/editor-tables/utils';
9
- import { COLUMN_MIN_WIDTH, getColgroupChildrenLength, hasTableBeenResized, previewScaleTable, scaleTable } from '../pm-plugins/table-resizing/utils';
7
+ import { COLUMN_MIN_WIDTH, getColgroupChildrenLength, previewScaleTable, scaleTable } from '../pm-plugins/table-resizing/utils';
10
8
  import { pluginKey as tableWidthPluginKey } from '../pm-plugins/table-width';
11
9
  import { TABLE_HIGHLIGHT_GAP, TABLE_SNAP_GAP } from '../ui/consts';
12
- import { getTableWidth } from '../utils';
10
+ import { generateResizedPayload, generateResizeFrameRatePayloads, useMeasureFramerate } from '../utils/analytics';
13
11
  import { defaultGuidelines, defaultGuidelineWidths } from '../utils/guidelines';
14
12
  import { findClosestSnap } from '../utils/snapping';
15
13
  const handles = {
16
14
  right: true
17
15
  };
18
16
  const tableHandleMarginTop = 12;
19
- const generateResizedPayload = props => {
20
- var _props$originalNode$a;
21
- const tableMap = TableMap.get(props.resizedNode);
22
- return {
23
- action: TABLE_ACTION.RESIZED,
24
- actionSubject: ACTION_SUBJECT.TABLE,
25
- eventType: EVENT_TYPE.TRACK,
26
- attributes: {
27
- newWidth: props.resizedNode.attrs.width,
28
- prevWidth: (_props$originalNode$a = props.originalNode.attrs.width) !== null && _props$originalNode$a !== void 0 ? _props$originalNode$a : null,
29
- nodeSize: props.resizedNode.nodeSize,
30
- totalTableWidth: hasTableBeenResized(props.resizedNode) ? getTableWidth(props.resizedNode) : null,
31
- totalRowCount: tableMap.height,
32
- totalColumnCount: tableMap.width
33
- }
34
- };
35
- };
36
17
  const getResizerHandleHeight = tableRef => {
37
18
  const tableHeight = tableRef === null || tableRef === void 0 ? void 0 : tableRef.clientHeight;
38
19
  let handleHeightSize = 'small';
@@ -73,6 +54,11 @@ export const TableResizer = ({
73
54
  const [snappingEnabled, setSnappingEnabled] = useState(false);
74
55
  const resizerMinWidth = getResizerMinWidth(node);
75
56
  const handleHeightSize = getResizerHandleHeight(tableRef);
57
+ const {
58
+ startMeasure,
59
+ endMeasure,
60
+ countFrames
61
+ } = useMeasureFramerate();
76
62
  const updateActiveGuidelines = useCallback(({
77
63
  gap,
78
64
  keys
@@ -86,6 +72,7 @@ export const TableResizer = ({
86
72
  x: defaultGuidelineWidths
87
73
  } : undefined, [snappingEnabled]);
88
74
  const handleResizeStart = useCallback(() => {
75
+ startMeasure();
89
76
  const {
90
77
  dispatch,
91
78
  state: {
@@ -96,7 +83,7 @@ export const TableResizer = ({
96
83
  resizing: true
97
84
  }));
98
85
  setSnappingEnabled(displayGuideline(defaultGuidelines));
99
- }, [displayGuideline, editorView]);
86
+ }, [displayGuideline, editorView, startMeasure]);
100
87
  const handleResizeStop = useCallback((originalState, delta) => {
101
88
  const newWidth = originalState.width + delta.width;
102
89
  const {
@@ -107,8 +94,20 @@ export const TableResizer = ({
107
94
  let tr = state.tr.setMeta(tableWidthPluginKey, {
108
95
  resizing: false
109
96
  });
97
+ const frameRateSamples = endMeasure();
98
+ if (frameRateSamples.length > 0) {
99
+ const resizeFrameRatePayloads = generateResizeFrameRatePayloads({
100
+ docSize: state.doc.nodeSize,
101
+ frameRateSamples,
102
+ originalNode: node
103
+ });
104
+ resizeFrameRatePayloads.forEach(payload => {
105
+ var _attachAnalyticsEvent;
106
+ (_attachAnalyticsEvent = attachAnalyticsEvent(payload)) === null || _attachAnalyticsEvent === void 0 ? void 0 : _attachAnalyticsEvent(tr);
107
+ });
108
+ }
110
109
  if (typeof pos === 'number') {
111
- var _attachAnalyticsEvent;
110
+ var _attachAnalyticsEvent2;
112
111
  tr = tr.setNodeMarkup(pos, undefined, {
113
112
  ...node.attrs,
114
113
  width: newWidth
@@ -121,10 +120,10 @@ export const TableResizer = ({
121
120
  parentWidth: newWidth
122
121
  }, editorView.domAtPos.bind(editorView))(tr);
123
122
  const scaledNode = tr.doc.nodeAt(pos);
124
- (_attachAnalyticsEvent = attachAnalyticsEvent(generateResizedPayload({
123
+ (_attachAnalyticsEvent2 = attachAnalyticsEvent(generateResizedPayload({
125
124
  originalNode: node,
126
125
  resizedNode: scaledNode
127
- }))) === null || _attachAnalyticsEvent === void 0 ? void 0 : _attachAnalyticsEvent(tr);
126
+ }))) === null || _attachAnalyticsEvent2 === void 0 ? void 0 : _attachAnalyticsEvent2(tr);
128
127
  }
129
128
  dispatch(tr);
130
129
 
@@ -132,8 +131,9 @@ export const TableResizer = ({
132
131
  displayGuideline([]);
133
132
  updateWidth(newWidth);
134
133
  return newWidth;
135
- }, [updateWidth, editorView, getPos, node, tableRef, displayGuideline, attachAnalyticsEvent]);
134
+ }, [updateWidth, editorView, getPos, node, tableRef, displayGuideline, attachAnalyticsEvent, endMeasure]);
136
135
  const handleResize = useCallback((originalState, delta) => {
136
+ countFrames();
137
137
  const newWidth = originalState.width + delta.width;
138
138
  const pos = getPos();
139
139
  if (typeof pos !== 'number') {
@@ -148,7 +148,7 @@ export const TableResizer = ({
148
148
  updateActiveGuidelines(findClosestSnap(newWidth, defaultGuidelineWidths, defaultGuidelines, TABLE_HIGHLIGHT_GAP));
149
149
  updateWidth(newWidth);
150
150
  return newWidth;
151
- }, [editorView, getPos, node, tableRef, updateWidth, updateActiveGuidelines]);
151
+ }, [editorView, getPos, node, tableRef, updateWidth, updateActiveGuidelines, countFrames]);
152
152
  const scheduleResize = useMemo(() => rafSchd(handleResize), [handleResize]);
153
153
  const handleComponent = useMemo(() => ({
154
154
  left: /*#__PURE__*/React.createElement("div", {
@@ -1,5 +1,9 @@
1
+ import { useEffect, useRef } from 'react';
2
+ import { ACTION_SUBJECT, EVENT_TYPE, TABLE_ACTION } from '@atlaskit/editor-common/analytics';
1
3
  import { TableMap } from '@atlaskit/editor-tables/table-map';
2
4
  import { findTable, getSelectionRect } from '@atlaskit/editor-tables/utils';
5
+ import { hasTableBeenResized } from '../pm-plugins/table-resizing/utils';
6
+ import { getTableWidth } from '../utils';
3
7
  export function getSelectedTableInfo(selection) {
4
8
  let map;
5
9
  let totalRowCount = 0;
@@ -54,4 +58,130 @@ export const withEditorAnalyticsAPI = payload => editorAnalyticsAPI => {
54
58
  }
55
59
  return true;
56
60
  }, view);
61
+ };
62
+ export const generateResizedPayload = props => {
63
+ var _props$originalNode$a;
64
+ const tableMap = TableMap.get(props.resizedNode);
65
+ return {
66
+ action: TABLE_ACTION.RESIZED,
67
+ actionSubject: ACTION_SUBJECT.TABLE,
68
+ eventType: EVENT_TYPE.TRACK,
69
+ attributes: {
70
+ newWidth: props.resizedNode.attrs.width,
71
+ prevWidth: (_props$originalNode$a = props.originalNode.attrs.width) !== null && _props$originalNode$a !== void 0 ? _props$originalNode$a : null,
72
+ nodeSize: props.resizedNode.nodeSize,
73
+ totalTableWidth: hasTableBeenResized(props.resizedNode) ? getTableWidth(props.resizedNode) : null,
74
+ totalRowCount: tableMap.height,
75
+ totalColumnCount: tableMap.width
76
+ }
77
+ };
78
+ };
79
+ export const reduceResizeFrameRateSamples = frameRateSamples => {
80
+ if (frameRateSamples.length > 1) {
81
+ const frameRateSum = frameRateSamples.reduce((sum, frameRate, index) => {
82
+ if (index === 0) {
83
+ return sum;
84
+ } else {
85
+ return sum + frameRate;
86
+ }
87
+ }, 0);
88
+ const averageFrameRate = Math.round(frameRateSum / (frameRateSamples.length - 1));
89
+ return [frameRateSamples[0], averageFrameRate];
90
+ } else {
91
+ return frameRateSamples;
92
+ }
93
+ };
94
+ export const generateResizeFrameRatePayloads = props => {
95
+ const reducedResizeFrameRateSamples = reduceResizeFrameRateSamples(props.frameRateSamples);
96
+ return reducedResizeFrameRateSamples.map((frameRateSample, index) => ({
97
+ action: TABLE_ACTION.RESIZE_PERF_SAMPLING,
98
+ actionSubject: ACTION_SUBJECT.TABLE,
99
+ eventType: EVENT_TYPE.OPERATIONAL,
100
+ attributes: {
101
+ frameRate: frameRateSample,
102
+ nodeSize: props.originalNode.nodeSize,
103
+ docSize: props.docSize,
104
+ isInitialSample: index === 0
105
+ }
106
+ }));
107
+ };
108
+
109
+ /**
110
+ * Measures the framerate of a component over a given time period.
111
+ */
112
+ export const useMeasureFramerate = (config = {}) => {
113
+ const {
114
+ maxSamples = 10,
115
+ minFrames = 5,
116
+ minTimeMs = 500,
117
+ sampleRateMs = 1000,
118
+ timeoutMs = 200
119
+ } = config;
120
+ let frameCount = useRef(0);
121
+ let lastTime = useRef(0);
122
+ let timeoutId = useRef();
123
+ let frameRateSamples = useRef([]);
124
+ useEffect(() => {
125
+ return () => {
126
+ if (timeoutId.current) {
127
+ clearTimeout(timeoutId.current);
128
+ }
129
+ };
130
+ }, []);
131
+ const startMeasure = () => {
132
+ frameCount.current = 0;
133
+ lastTime.current = performance.now();
134
+ };
135
+
136
+ /**
137
+ * Returns an array of frame rate samples as integers.
138
+ */
139
+ const endMeasure = () => {
140
+ const samples = frameRateSamples.current;
141
+ frameRateSamples.current = [];
142
+ return samples;
143
+ };
144
+ const sampleFrameRate = (delay = 0) => {
145
+ const currentTime = performance.now();
146
+ const deltaTime = currentTime - lastTime.current - delay;
147
+ const isValidSample = deltaTime > minTimeMs && frameCount.current >= minFrames;
148
+ if (isValidSample) {
149
+ const frameRate = Math.round(frameCount.current / (deltaTime / 1000));
150
+ frameRateSamples.current.push(frameRate);
151
+ }
152
+ frameCount.current = 0;
153
+ lastTime.current = 0;
154
+ };
155
+
156
+ /**
157
+ * Counts the number of frames that occur within a given time period. Intended to be called
158
+ * inside a `requestAnimationFrame` callback.
159
+ */
160
+ const countFrames = () => {
161
+ if (frameRateSamples.current.length >= maxSamples && timeoutId.current) {
162
+ clearTimeout(timeoutId.current);
163
+ return;
164
+ }
165
+
166
+ /**
167
+ * Allows us to keep counting frames even if `startMeasure` is not called
168
+ */
169
+ if (lastTime.current === 0) {
170
+ lastTime.current = performance.now();
171
+ }
172
+ frameCount.current++;
173
+ if (timeoutId.current) {
174
+ clearTimeout(timeoutId.current);
175
+ }
176
+ if (performance.now() - lastTime.current > sampleRateMs) {
177
+ sampleFrameRate();
178
+ } else {
179
+ timeoutId.current = setTimeout(() => sampleFrameRate(timeoutMs), timeoutMs);
180
+ }
181
+ };
182
+ return {
183
+ startMeasure,
184
+ endMeasure,
185
+ countFrames
186
+ };
57
187
  };
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-table",
3
- "version": "2.7.2",
3
+ "version": "2.8.0",
4
4
  "sideEffects": false
5
5
  }