@atlaskit/editor-common 119.16.0 → 119.16.2
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 +25 -0
- package/dist/cjs/monitoring/error.js +1 -1
- package/dist/cjs/react-node-view/index.js +36 -1
- package/dist/cjs/ui/DropList/index.js +1 -1
- package/dist/es2019/monitoring/error.js +1 -1
- package/dist/es2019/react-node-view/index.js +34 -1
- package/dist/es2019/ui/DropList/index.js +1 -1
- package/dist/esm/monitoring/error.js +1 -1
- package/dist/esm/react-node-view/index.js +36 -1
- package/dist/esm/ui/DropList/index.js +1 -1
- package/dist/types/react-node-view/index.d.ts +6 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# @atlaskit/editor-common
|
|
2
2
|
|
|
3
|
+
## 119.16.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`288e340380dbb`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/288e340380dbb) -
|
|
8
|
+
Behind experiment platform_editor_reduce_event_listener_count: cut the number of native DOM event
|
|
9
|
+
listeners the editor registers per node. React 18 registers a bubble and a capture listener for
|
|
10
|
+
every supported event type on each portal container (~130 listeners) and never removes them, so
|
|
11
|
+
(1) node views whose render() returns null no longer mount a portal at all, and (2) the breakout
|
|
12
|
+
resize handle tooltip portal is deferred until the pointer enters the node instead of being
|
|
13
|
+
mounted for every resizable node up front.
|
|
14
|
+
|
|
15
|
+
Also reduces the work the layout column divider decorations do on every `decorations(state)` read:
|
|
16
|
+
the mousedown listener is unbound when the widget decoration is destroyed, the widget DOM is built
|
|
17
|
+
lazily rather than once per call, the document walk no longer descends into node types that cannot
|
|
18
|
+
contain a layout, and the decoration key is derived from the layout's ordinal rather than its
|
|
19
|
+
position so an edit above a layout no longer invalidates and rebuilds every divider below it. The
|
|
20
|
+
widget now resolves its own layout section and column index from its live position at mousedown.
|
|
21
|
+
|
|
22
|
+
## 119.16.1
|
|
23
|
+
|
|
24
|
+
### Patch Changes
|
|
25
|
+
|
|
26
|
+
- Updated dependencies
|
|
27
|
+
|
|
3
28
|
## 119.16.0
|
|
4
29
|
|
|
5
30
|
### Minor Changes
|
|
@@ -28,7 +28,7 @@ var NETWORK_FAILURE_REGEX = /^network failure/i;
|
|
|
28
28
|
var RESIZE_OBSERVER_LOOP_REGEX = /ResizeObserver loop completed with undelivered notifications/;
|
|
29
29
|
var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
|
|
30
30
|
var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
|
|
31
|
-
var packageVersion = "119.
|
|
31
|
+
var packageVersion = "119.16.1";
|
|
32
32
|
var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
|
|
33
33
|
// Remove URL as it has UGC
|
|
34
34
|
// Ignored via go/ees007
|
|
@@ -28,6 +28,7 @@ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/cl
|
|
|
28
28
|
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
29
29
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
30
30
|
var _react = _interopRequireDefault(require("react"));
|
|
31
|
+
var _isExperimentEnabled = require("@atlaskit/platform-feature-experiments/is-experiment-enabled");
|
|
31
32
|
var _analytics = require("../analytics");
|
|
32
33
|
var _coreUtils = require("../core-utils");
|
|
33
34
|
var _eventDispatcher = require("../event-dispatcher");
|
|
@@ -50,6 +51,12 @@ var ReactNodeView = exports.default = /*#__PURE__*/function () {
|
|
|
50
51
|
// Spreading props to pass through dynamic component props
|
|
51
52
|
// Ignored via go/ees005
|
|
52
53
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
54
|
+
/**
|
|
55
|
+
* Tracks whether a React portal is currently mounted into `domRef`. Only used under
|
|
56
|
+
* `platform_editor_reduce_event_listener_count`, where a node view whose `render()`
|
|
57
|
+
* returns `null` does not mount one at all.
|
|
58
|
+
*/
|
|
59
|
+
(0, _defineProperty2.default)(this, "hasMountedPortal", false);
|
|
53
60
|
(0, _defineProperty2.default)(this, "decorations", []);
|
|
54
61
|
(0, _defineProperty2.default)(this, "handleRef", function (node) {
|
|
55
62
|
return _this._handleRef(node);
|
|
@@ -153,13 +160,41 @@ var ReactNodeView = exports.default = /*#__PURE__*/function () {
|
|
|
153
160
|
if (!this.domRef || !component) {
|
|
154
161
|
return;
|
|
155
162
|
}
|
|
163
|
+
|
|
164
|
+
// React 18 does event delegation per portal container: `createPortal` calls
|
|
165
|
+
// `listenToAllSupportedEvents(container)`, which registers a bubble *and* a capture
|
|
166
|
+
// listener for every supported event type — roughly 130 real `addEventListener` calls
|
|
167
|
+
// on the container element. Those listeners are never removed (React has no
|
|
168
|
+
// un-listen path), so mounting a portal for a node view that renders nothing is pure
|
|
169
|
+
// overhead that scales with the number of such nodes in the document.
|
|
170
|
+
//
|
|
171
|
+
// `PortalProviderAPI.render` already invokes the thunk eagerly (see
|
|
172
|
+
// `getPortalProviderAPI`), so evaluating the element here does not change *when*
|
|
173
|
+
// `render()` runs — the pre-evaluated element is handed to the same render call below.
|
|
174
|
+
// If a node view starts out empty and later renders something, `update()` calls back into
|
|
175
|
+
// this method and the portal is mounted at that point.
|
|
176
|
+
var renderComponent = component;
|
|
177
|
+
if ((0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_reduce_event_listener_count')) {
|
|
178
|
+
var element = component();
|
|
179
|
+
if (element === null) {
|
|
180
|
+
if (this.hasMountedPortal) {
|
|
181
|
+
this.portalProviderAPI.remove(this.key);
|
|
182
|
+
this.hasMountedPortal = false;
|
|
183
|
+
}
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
this.hasMountedPortal = true;
|
|
187
|
+
renderComponent = function renderComponent() {
|
|
188
|
+
return element;
|
|
189
|
+
};
|
|
190
|
+
}
|
|
156
191
|
var componentWithErrorBoundary = function componentWithErrorBoundary() {
|
|
157
192
|
var _this3$node$type$name, _this3$node;
|
|
158
193
|
return /*#__PURE__*/_react.default.createElement(_ErrorBoundary.ErrorBoundary, {
|
|
159
194
|
component: _analytics.ACTION_SUBJECT.REACT_NODE_VIEW,
|
|
160
195
|
componentId: (_this3$node$type$name = _this3 === null || _this3 === void 0 || (_this3$node = _this3.node) === null || _this3$node === void 0 || (_this3$node = _this3$node.type) === null || _this3$node === void 0 ? void 0 : _this3$node.name) !== null && _this3$node$type$name !== void 0 ? _this3$node$type$name : _analytics.ACTION_SUBJECT_ID.UNKNOWN_NODE,
|
|
161
196
|
dispatchAnalyticsEvent: _this3.dispatchAnalyticsEvent
|
|
162
|
-
},
|
|
197
|
+
}, renderComponent());
|
|
163
198
|
};
|
|
164
199
|
this.portalProviderAPI.render(componentWithErrorBoundary,
|
|
165
200
|
// Spreading props to pass through dynamic component props
|
|
@@ -24,7 +24,7 @@ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.
|
|
|
24
24
|
* @jsx jsx
|
|
25
25
|
*/ // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
|
|
26
26
|
var packageName = "@atlaskit/editor-common";
|
|
27
|
-
var packageVersion = "119.
|
|
27
|
+
var packageVersion = "119.16.1";
|
|
28
28
|
var halfFocusRing = 1;
|
|
29
29
|
var dropOffset = '0, 8';
|
|
30
30
|
var fadeIn = (0, _react2.keyframes)({
|
|
@@ -14,7 +14,7 @@ const NETWORK_FAILURE_REGEX = /^network failure/i;
|
|
|
14
14
|
const RESIZE_OBSERVER_LOOP_REGEX = /ResizeObserver loop completed with undelivered notifications/;
|
|
15
15
|
const SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
|
|
16
16
|
const packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
|
|
17
|
-
const packageVersion = "119.
|
|
17
|
+
const packageVersion = "119.16.1";
|
|
18
18
|
const sanitiseSentryEvents = (data, _hint) => {
|
|
19
19
|
// Remove URL as it has UGC
|
|
20
20
|
// Ignored via go/ees007
|
|
@@ -4,6 +4,7 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
|
4
4
|
/* eslint-disable @atlaskit/editor/no-re-export */
|
|
5
5
|
|
|
6
6
|
import React from 'react';
|
|
7
|
+
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
7
8
|
import { ACTION_SUBJECT, ACTION_SUBJECT_ID } from '../analytics';
|
|
8
9
|
import { isSSR } from '../core-utils';
|
|
9
10
|
import { createDispatch } from '../event-dispatcher';
|
|
@@ -22,6 +23,12 @@ export default class ReactNodeView {
|
|
|
22
23
|
// Spreading props to pass through dynamic component props
|
|
23
24
|
// Ignored via go/ees005
|
|
24
25
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
26
|
+
/**
|
|
27
|
+
* Tracks whether a React portal is currently mounted into `domRef`. Only used under
|
|
28
|
+
* `platform_editor_reduce_event_listener_count`, where a node view whose `render()`
|
|
29
|
+
* returns `null` does not mount one at all.
|
|
30
|
+
*/
|
|
31
|
+
_defineProperty(this, "hasMountedPortal", false);
|
|
25
32
|
_defineProperty(this, "decorations", []);
|
|
26
33
|
_defineProperty(this, "handleRef", node => this._handleRef(node));
|
|
27
34
|
_defineProperty(this, "dispatchAnalyticsEvent", payload => {
|
|
@@ -116,13 +123,39 @@ export default class ReactNodeView {
|
|
|
116
123
|
if (!this.domRef || !component) {
|
|
117
124
|
return;
|
|
118
125
|
}
|
|
126
|
+
|
|
127
|
+
// React 18 does event delegation per portal container: `createPortal` calls
|
|
128
|
+
// `listenToAllSupportedEvents(container)`, which registers a bubble *and* a capture
|
|
129
|
+
// listener for every supported event type — roughly 130 real `addEventListener` calls
|
|
130
|
+
// on the container element. Those listeners are never removed (React has no
|
|
131
|
+
// un-listen path), so mounting a portal for a node view that renders nothing is pure
|
|
132
|
+
// overhead that scales with the number of such nodes in the document.
|
|
133
|
+
//
|
|
134
|
+
// `PortalProviderAPI.render` already invokes the thunk eagerly (see
|
|
135
|
+
// `getPortalProviderAPI`), so evaluating the element here does not change *when*
|
|
136
|
+
// `render()` runs — the pre-evaluated element is handed to the same render call below.
|
|
137
|
+
// If a node view starts out empty and later renders something, `update()` calls back into
|
|
138
|
+
// this method and the portal is mounted at that point.
|
|
139
|
+
let renderComponent = component;
|
|
140
|
+
if (isExperimentEnabled('platform_editor_reduce_event_listener_count')) {
|
|
141
|
+
const element = component();
|
|
142
|
+
if (element === null) {
|
|
143
|
+
if (this.hasMountedPortal) {
|
|
144
|
+
this.portalProviderAPI.remove(this.key);
|
|
145
|
+
this.hasMountedPortal = false;
|
|
146
|
+
}
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
this.hasMountedPortal = true;
|
|
150
|
+
renderComponent = () => element;
|
|
151
|
+
}
|
|
119
152
|
const componentWithErrorBoundary = () => {
|
|
120
153
|
var _this$node$type$name, _this$node, _this$node$type;
|
|
121
154
|
return /*#__PURE__*/React.createElement(ErrorBoundary, {
|
|
122
155
|
component: ACTION_SUBJECT.REACT_NODE_VIEW,
|
|
123
156
|
componentId: (_this$node$type$name = this === null || this === void 0 ? void 0 : (_this$node = this.node) === null || _this$node === void 0 ? void 0 : (_this$node$type = _this$node.type) === null || _this$node$type === void 0 ? void 0 : _this$node$type.name) !== null && _this$node$type$name !== void 0 ? _this$node$type$name : ACTION_SUBJECT_ID.UNKNOWN_NODE,
|
|
124
157
|
dispatchAnalyticsEvent: this.dispatchAnalyticsEvent
|
|
125
|
-
},
|
|
158
|
+
}, renderComponent());
|
|
126
159
|
};
|
|
127
160
|
this.portalProviderAPI.render(componentWithErrorBoundary,
|
|
128
161
|
// Spreading props to pass through dynamic component props
|
|
@@ -14,7 +14,7 @@ import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
|
|
|
14
14
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
15
15
|
import Layer from '../Layer';
|
|
16
16
|
const packageName = "@atlaskit/editor-common";
|
|
17
|
-
const packageVersion = "119.
|
|
17
|
+
const packageVersion = "119.16.1";
|
|
18
18
|
const halfFocusRing = 1;
|
|
19
19
|
const dropOffset = '0, 8';
|
|
20
20
|
const fadeIn = keyframes({
|
|
@@ -20,7 +20,7 @@ var NETWORK_FAILURE_REGEX = /^network failure/i;
|
|
|
20
20
|
var RESIZE_OBSERVER_LOOP_REGEX = /ResizeObserver loop completed with undelivered notifications/;
|
|
21
21
|
var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
|
|
22
22
|
var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
|
|
23
|
-
var packageVersion = "119.
|
|
23
|
+
var packageVersion = "119.16.1";
|
|
24
24
|
var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
|
|
25
25
|
// Remove URL as it has UGC
|
|
26
26
|
// Ignored via go/ees007
|
|
@@ -6,6 +6,7 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
|
6
6
|
/* eslint-disable @atlaskit/editor/no-re-export */
|
|
7
7
|
|
|
8
8
|
import React from 'react';
|
|
9
|
+
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
9
10
|
import { ACTION_SUBJECT, ACTION_SUBJECT_ID } from '../analytics';
|
|
10
11
|
import { isSSR } from '../core-utils';
|
|
11
12
|
import { createDispatch } from '../event-dispatcher';
|
|
@@ -26,6 +27,12 @@ var ReactNodeView = /*#__PURE__*/function () {
|
|
|
26
27
|
// Spreading props to pass through dynamic component props
|
|
27
28
|
// Ignored via go/ees005
|
|
28
29
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
30
|
+
/**
|
|
31
|
+
* Tracks whether a React portal is currently mounted into `domRef`. Only used under
|
|
32
|
+
* `platform_editor_reduce_event_listener_count`, where a node view whose `render()`
|
|
33
|
+
* returns `null` does not mount one at all.
|
|
34
|
+
*/
|
|
35
|
+
_defineProperty(this, "hasMountedPortal", false);
|
|
29
36
|
_defineProperty(this, "decorations", []);
|
|
30
37
|
_defineProperty(this, "handleRef", function (node) {
|
|
31
38
|
return _this._handleRef(node);
|
|
@@ -129,13 +136,41 @@ var ReactNodeView = /*#__PURE__*/function () {
|
|
|
129
136
|
if (!this.domRef || !component) {
|
|
130
137
|
return;
|
|
131
138
|
}
|
|
139
|
+
|
|
140
|
+
// React 18 does event delegation per portal container: `createPortal` calls
|
|
141
|
+
// `listenToAllSupportedEvents(container)`, which registers a bubble *and* a capture
|
|
142
|
+
// listener for every supported event type — roughly 130 real `addEventListener` calls
|
|
143
|
+
// on the container element. Those listeners are never removed (React has no
|
|
144
|
+
// un-listen path), so mounting a portal for a node view that renders nothing is pure
|
|
145
|
+
// overhead that scales with the number of such nodes in the document.
|
|
146
|
+
//
|
|
147
|
+
// `PortalProviderAPI.render` already invokes the thunk eagerly (see
|
|
148
|
+
// `getPortalProviderAPI`), so evaluating the element here does not change *when*
|
|
149
|
+
// `render()` runs — the pre-evaluated element is handed to the same render call below.
|
|
150
|
+
// If a node view starts out empty and later renders something, `update()` calls back into
|
|
151
|
+
// this method and the portal is mounted at that point.
|
|
152
|
+
var renderComponent = component;
|
|
153
|
+
if (isExperimentEnabled('platform_editor_reduce_event_listener_count')) {
|
|
154
|
+
var element = component();
|
|
155
|
+
if (element === null) {
|
|
156
|
+
if (this.hasMountedPortal) {
|
|
157
|
+
this.portalProviderAPI.remove(this.key);
|
|
158
|
+
this.hasMountedPortal = false;
|
|
159
|
+
}
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
this.hasMountedPortal = true;
|
|
163
|
+
renderComponent = function renderComponent() {
|
|
164
|
+
return element;
|
|
165
|
+
};
|
|
166
|
+
}
|
|
132
167
|
var componentWithErrorBoundary = function componentWithErrorBoundary() {
|
|
133
168
|
var _this3$node$type$name, _this3$node;
|
|
134
169
|
return /*#__PURE__*/React.createElement(ErrorBoundary, {
|
|
135
170
|
component: ACTION_SUBJECT.REACT_NODE_VIEW,
|
|
136
171
|
componentId: (_this3$node$type$name = _this3 === null || _this3 === void 0 || (_this3$node = _this3.node) === null || _this3$node === void 0 || (_this3$node = _this3$node.type) === null || _this3$node === void 0 ? void 0 : _this3$node.name) !== null && _this3$node$type$name !== void 0 ? _this3$node$type$name : ACTION_SUBJECT_ID.UNKNOWN_NODE,
|
|
137
172
|
dispatchAnalyticsEvent: _this3.dispatchAnalyticsEvent
|
|
138
|
-
},
|
|
173
|
+
}, renderComponent());
|
|
139
174
|
};
|
|
140
175
|
this.portalProviderAPI.render(componentWithErrorBoundary,
|
|
141
176
|
// Spreading props to pass through dynamic component props
|
|
@@ -21,7 +21,7 @@ import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
|
|
|
21
21
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
22
22
|
import Layer from '../Layer';
|
|
23
23
|
var packageName = "@atlaskit/editor-common";
|
|
24
|
-
var packageVersion = "119.
|
|
24
|
+
var packageVersion = "119.16.1";
|
|
25
25
|
var halfFocusRing = 1;
|
|
26
26
|
var dropOffset = '0, 8';
|
|
27
27
|
var fadeIn = keyframes({
|
|
@@ -14,6 +14,12 @@ export default class ReactNodeView<P = ReactComponentProps> implements NodeView
|
|
|
14
14
|
private reactComponent?;
|
|
15
15
|
private portalProviderAPI;
|
|
16
16
|
private _viewShouldUpdate?;
|
|
17
|
+
/**
|
|
18
|
+
* Tracks whether a React portal is currently mounted into `domRef`. Only used under
|
|
19
|
+
* `platform_editor_reduce_event_listener_count`, where a node view whose `render()`
|
|
20
|
+
* returns `null` does not mount one at all.
|
|
21
|
+
*/
|
|
22
|
+
private hasMountedPortal;
|
|
17
23
|
protected eventDispatcher?: EventDispatcher;
|
|
18
24
|
protected decorations: ReadonlyArray<Decoration>;
|
|
19
25
|
reactComponentProps: P;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-common",
|
|
3
|
-
"version": "119.16.
|
|
3
|
+
"version": "119.16.2",
|
|
4
4
|
"description": "A package that contains common classes and components for editor and renderer",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"@atlaskit/task-decision": "^21.8.0",
|
|
85
85
|
"@atlaskit/teams-app-config": "^2.2.0",
|
|
86
86
|
"@atlaskit/textfield": "^10.1.0",
|
|
87
|
-
"@atlaskit/tmp-editor-statsig": "^
|
|
87
|
+
"@atlaskit/tmp-editor-statsig": "^159.0.0",
|
|
88
88
|
"@atlaskit/tokens": "^16.8.0",
|
|
89
89
|
"@atlaskit/tooltip": "^24.2.0",
|
|
90
90
|
"@atlaskit/width-detector": "^7.1.0",
|