@atlaskit/editor-common 110.48.1 → 110.49.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 +7 -0
- package/dist/cjs/monitoring/error.js +1 -1
- package/dist/cjs/node-anchor/index.js +12 -0
- package/dist/cjs/node-anchor/node-anchor-provider.js +93 -4
- package/dist/cjs/ui/DropList/index.js +1 -1
- package/dist/es2019/monitoring/error.js +1 -1
- package/dist/es2019/node-anchor/index.js +4 -0
- package/dist/es2019/node-anchor/node-anchor-provider.js +82 -2
- package/dist/es2019/ui/DropList/index.js +1 -1
- package/dist/esm/monitoring/error.js +1 -1
- package/dist/esm/node-anchor/index.js +4 -0
- package/dist/esm/node-anchor/node-anchor-provider.js +93 -4
- package/dist/esm/ui/DropList/index.js +1 -1
- package/dist/types/node-anchor/index.d.ts +1 -0
- package/dist/types/node-anchor/node-anchor-provider.d.ts +8 -1
- package/dist/types-ts4.5/node-anchor/index.d.ts +1 -0
- package/dist/types-ts4.5/node-anchor/node-anchor-provider.d.ts +8 -1
- package/node-anchor/package.json +17 -0
- package/package.json +4 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# @atlaskit/editor-common
|
|
2
2
|
|
|
3
|
+
## 110.49.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`6668fda9b38d7`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/6668fda9b38d7) -
|
|
8
|
+
ED-29716 add limited mode support to native anchor
|
|
9
|
+
|
|
3
10
|
## 110.48.1
|
|
4
11
|
|
|
5
12
|
### Patch Changes
|
|
@@ -19,7 +19,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
19
19
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
|
|
20
20
|
var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
|
|
21
21
|
var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
|
|
22
|
-
var packageVersion = "110.48.
|
|
22
|
+
var packageVersion = "110.48.1";
|
|
23
23
|
var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
|
|
24
24
|
// Remove URL as it has UGC
|
|
25
25
|
// Ignored via go/ees007
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "getNodeIdProvider", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function get() {
|
|
9
|
+
return _nodeAnchorProvider.getNodeIdProvider;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
var _nodeAnchorProvider = require("./node-anchor-provider");
|
|
@@ -8,20 +8,47 @@ exports.getNodeIdProvider = exports.NodeAnchorProvider = void 0;
|
|
|
8
8
|
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
9
9
|
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
10
10
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
11
|
+
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
12
|
+
var _expVal = require("@atlaskit/tmp-editor-statsig/expVal");
|
|
13
|
+
var _utils = require("../utils");
|
|
11
14
|
var _dynamicBitArray = require("./dynamic-bit-array");
|
|
12
15
|
var NodeAnchorProvider = exports.NodeAnchorProvider = /*#__PURE__*/function () {
|
|
13
16
|
function NodeAnchorProvider() {
|
|
17
|
+
var limitedMode = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
18
|
+
var emptyDoc = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
14
19
|
(0, _classCallCheck2.default)(this, NodeAnchorProvider);
|
|
15
20
|
(0, _defineProperty2.default)(this, "cache", new WeakMap());
|
|
16
21
|
(0, _defineProperty2.default)(this, "count", BigInt(0));
|
|
17
22
|
(0, _defineProperty2.default)(this, "existingPos", new _dynamicBitArray.DynamicBitArray());
|
|
23
|
+
(0, _defineProperty2.default)(this, "limitedMode", false);
|
|
24
|
+
(0, _defineProperty2.default)(this, "emptyDoc", false);
|
|
25
|
+
this.limitedMode = limitedMode;
|
|
26
|
+
this.emptyDoc = emptyDoc;
|
|
18
27
|
}
|
|
19
28
|
return (0, _createClass2.default)(NodeAnchorProvider, [{
|
|
20
|
-
key: "
|
|
21
|
-
value:
|
|
29
|
+
key: "isEmptyDoc",
|
|
30
|
+
value: function isEmptyDoc() {
|
|
31
|
+
return this.emptyDoc;
|
|
32
|
+
}
|
|
33
|
+
}, {
|
|
34
|
+
key: "setEmptyDoc",
|
|
35
|
+
value: function setEmptyDoc(isEmpty) {
|
|
36
|
+
this.emptyDoc = isEmpty;
|
|
37
|
+
}
|
|
38
|
+
}, {
|
|
39
|
+
key: "isLimitedMode",
|
|
40
|
+
value: function isLimitedMode() {
|
|
41
|
+
return this.limitedMode;
|
|
42
|
+
}
|
|
43
|
+
|
|
22
44
|
// We use pos to generate unique ids for each node at a specific position
|
|
23
45
|
// This is to ensure the same ADF will always generate the same DOM initially
|
|
24
|
-
|
|
46
|
+
}, {
|
|
47
|
+
key: "getOrGenerateId",
|
|
48
|
+
value: function getOrGenerateId(node, pos) {
|
|
49
|
+
if (this.limitedMode) {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
25
52
|
if (this.cache.has(node)) {
|
|
26
53
|
return this.cache.get(node);
|
|
27
54
|
}
|
|
@@ -38,20 +65,82 @@ var NodeAnchorProvider = exports.NodeAnchorProvider = /*#__PURE__*/function () {
|
|
|
38
65
|
}, {
|
|
39
66
|
key: "getIdForNode",
|
|
40
67
|
value: function getIdForNode(node) {
|
|
41
|
-
|
|
68
|
+
if (this.limitedMode) {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
return this.cache.get(node);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// After set to limited mode, we clear the cache to free up memory
|
|
75
|
+
// and prevent further ids from being generated
|
|
76
|
+
// Once in limited mode, we won't exit it
|
|
77
|
+
}, {
|
|
78
|
+
key: "setLimitedMode",
|
|
79
|
+
value: function setLimitedMode() {
|
|
80
|
+
this.limitedMode = true;
|
|
81
|
+
this.cache = new WeakMap();
|
|
82
|
+
this.existingPos = new _dynamicBitArray.DynamicBitArray();
|
|
83
|
+
this.count = BigInt(0);
|
|
42
84
|
}
|
|
43
85
|
}]);
|
|
44
86
|
}();
|
|
45
87
|
var nodeIdProviderMap = new WeakMap();
|
|
46
88
|
|
|
89
|
+
// This is duplicate from the limited mode plugin to avoid circular dependency
|
|
90
|
+
// We can refactor this later to have a shared util package
|
|
91
|
+
var isLimitedModeEnabled = function isLimitedModeEnabled(editorView) {
|
|
92
|
+
var nodeSizeLimit = (0, _expVal.expVal)('cc_editor_limited_mode', 'nodeSize', 100);
|
|
93
|
+
var limitedMode = false;
|
|
94
|
+
// some tests have nodeSizeLimit as boolean
|
|
95
|
+
if (typeof nodeSizeLimit === 'number') {
|
|
96
|
+
// duplicate logic from limited mode plugin to determine if we're in limited mode
|
|
97
|
+
// @ts-expect-error - true is not allowed as a default value
|
|
98
|
+
if ((0, _expVal.expVal)('cc_editor_limited_mode_include_lcm', 'isEnabled', true)) {
|
|
99
|
+
var customDocSize = editorView.state.doc.nodeSize;
|
|
100
|
+
editorView.state.doc.descendants(function (node) {
|
|
101
|
+
var _node$attrs;
|
|
102
|
+
if (((_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.extensionKey) === 'legacy-content') {
|
|
103
|
+
var _node$attrs$parameter, _node$attrs2;
|
|
104
|
+
customDocSize += (_node$attrs$parameter = (_node$attrs2 = node.attrs) === null || _node$attrs2 === void 0 || (_node$attrs2 = _node$attrs2.parameters) === null || _node$attrs2 === void 0 || (_node$attrs2 = _node$attrs2.adf) === null || _node$attrs2 === void 0 ? void 0 : _node$attrs2.length) !== null && _node$attrs$parameter !== void 0 ? _node$attrs$parameter : 0;
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
limitedMode = customDocSize > nodeSizeLimit;
|
|
108
|
+
} else {
|
|
109
|
+
limitedMode = editorView.state.doc.nodeSize > nodeSizeLimit;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return limitedMode;
|
|
113
|
+
};
|
|
114
|
+
|
|
47
115
|
// Get the NodeIdProvider for a specific EditorView instance.
|
|
48
116
|
// This allows access to the node ids anywhere.
|
|
49
117
|
var getNodeIdProvider = exports.getNodeIdProvider = function getNodeIdProvider(editorView) {
|
|
50
118
|
if (!nodeIdProviderMap.has(editorView)) {
|
|
119
|
+
if ((0, _platformFeatureFlags.fg)('platform_editor_native_anchor_patch_2')) {
|
|
120
|
+
// if the limited mode flag is on, enable limited mode based on document size
|
|
121
|
+
// only for the first time
|
|
122
|
+
var limitedMode = isLimitedModeEnabled(editorView);
|
|
123
|
+
var isEmptyDoc = (0, _utils.isEmptyDocument)(editorView.state.doc);
|
|
124
|
+
var _provider = new NodeAnchorProvider(limitedMode, isEmptyDoc);
|
|
125
|
+
nodeIdProviderMap.set(editorView, _provider);
|
|
126
|
+
return _provider;
|
|
127
|
+
}
|
|
51
128
|
var provider = new NodeAnchorProvider();
|
|
52
129
|
nodeIdProviderMap.set(editorView, provider);
|
|
53
130
|
return provider;
|
|
54
131
|
}
|
|
132
|
+
var nodeIdProvider = nodeIdProviderMap.get(editorView);
|
|
133
|
+
|
|
134
|
+
// in some cases we need to re-check limited mode state
|
|
135
|
+
// Confluence editor can start with an empty doc and then load content later
|
|
136
|
+
// so we need to check first time from an empty doc to a non-empty doc
|
|
137
|
+
if (nodeIdProvider.isEmptyDoc() && !(0, _utils.isEmptyDocument)(editorView.state.doc) && (0, _platformFeatureFlags.fg)('platform_editor_native_anchor_patch_2')) {
|
|
138
|
+
// set empty doc to false regardless of limited mode state
|
|
139
|
+
nodeIdProvider.setEmptyDoc(false);
|
|
140
|
+
if (!nodeIdProvider.isLimitedMode() && isLimitedModeEnabled(editorView)) {
|
|
141
|
+
nodeIdProvider.setLimitedMode();
|
|
142
|
+
}
|
|
143
|
+
}
|
|
55
144
|
|
|
56
145
|
// This is based on the fact that editorView is a singleton.
|
|
57
146
|
return nodeIdProviderMap.get(editorView);
|
|
@@ -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 = "110.48.
|
|
27
|
+
var packageVersion = "110.48.1";
|
|
28
28
|
var halfFocusRing = 1;
|
|
29
29
|
var dropOffset = '0, 8';
|
|
30
30
|
var fadeIn = (0, _react2.keyframes)({
|
|
@@ -4,7 +4,7 @@ import { isFedRamp } from './environment';
|
|
|
4
4
|
import { normaliseSentryBreadcrumbs, SERIALIZABLE_ATTRIBUTES } from './normalise-sentry-breadcrumbs';
|
|
5
5
|
const SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
|
|
6
6
|
const packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
|
|
7
|
-
const packageVersion = "110.48.
|
|
7
|
+
const packageVersion = "110.48.1";
|
|
8
8
|
const sanitiseSentryEvents = (data, _hint) => {
|
|
9
9
|
// Remove URL as it has UGC
|
|
10
10
|
// Ignored via go/ees007
|
|
@@ -1,14 +1,34 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
3
|
+
import { expVal } from '@atlaskit/tmp-editor-statsig/expVal';
|
|
4
|
+
import { isEmptyDocument } from '../utils';
|
|
2
5
|
import { DynamicBitArray } from './dynamic-bit-array';
|
|
3
6
|
export class NodeAnchorProvider {
|
|
4
|
-
constructor() {
|
|
7
|
+
constructor(limitedMode = false, emptyDoc = false) {
|
|
5
8
|
_defineProperty(this, "cache", new WeakMap());
|
|
6
9
|
_defineProperty(this, "count", BigInt(0));
|
|
7
10
|
_defineProperty(this, "existingPos", new DynamicBitArray());
|
|
11
|
+
_defineProperty(this, "limitedMode", false);
|
|
12
|
+
_defineProperty(this, "emptyDoc", false);
|
|
13
|
+
this.limitedMode = limitedMode;
|
|
14
|
+
this.emptyDoc = emptyDoc;
|
|
8
15
|
}
|
|
16
|
+
isEmptyDoc() {
|
|
17
|
+
return this.emptyDoc;
|
|
18
|
+
}
|
|
19
|
+
setEmptyDoc(isEmpty) {
|
|
20
|
+
this.emptyDoc = isEmpty;
|
|
21
|
+
}
|
|
22
|
+
isLimitedMode() {
|
|
23
|
+
return this.limitedMode;
|
|
24
|
+
}
|
|
25
|
+
|
|
9
26
|
// We use pos to generate unique ids for each node at a specific position
|
|
10
27
|
// This is to ensure the same ADF will always generate the same DOM initially
|
|
11
28
|
getOrGenerateId(node, pos) {
|
|
29
|
+
if (this.limitedMode) {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
12
32
|
if (this.cache.has(node)) {
|
|
13
33
|
return this.cache.get(node);
|
|
14
34
|
}
|
|
@@ -23,19 +43,79 @@ export class NodeAnchorProvider {
|
|
|
23
43
|
return anchorName;
|
|
24
44
|
}
|
|
25
45
|
getIdForNode(node) {
|
|
26
|
-
|
|
46
|
+
if (this.limitedMode) {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
return this.cache.get(node);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// After set to limited mode, we clear the cache to free up memory
|
|
53
|
+
// and prevent further ids from being generated
|
|
54
|
+
// Once in limited mode, we won't exit it
|
|
55
|
+
setLimitedMode() {
|
|
56
|
+
this.limitedMode = true;
|
|
57
|
+
this.cache = new WeakMap();
|
|
58
|
+
this.existingPos = new DynamicBitArray();
|
|
59
|
+
this.count = BigInt(0);
|
|
27
60
|
}
|
|
28
61
|
}
|
|
29
62
|
const nodeIdProviderMap = new WeakMap();
|
|
30
63
|
|
|
64
|
+
// This is duplicate from the limited mode plugin to avoid circular dependency
|
|
65
|
+
// We can refactor this later to have a shared util package
|
|
66
|
+
const isLimitedModeEnabled = editorView => {
|
|
67
|
+
const nodeSizeLimit = expVal('cc_editor_limited_mode', 'nodeSize', 100);
|
|
68
|
+
let limitedMode = false;
|
|
69
|
+
// some tests have nodeSizeLimit as boolean
|
|
70
|
+
if (typeof nodeSizeLimit === 'number') {
|
|
71
|
+
// duplicate logic from limited mode plugin to determine if we're in limited mode
|
|
72
|
+
// @ts-expect-error - true is not allowed as a default value
|
|
73
|
+
if (expVal('cc_editor_limited_mode_include_lcm', 'isEnabled', true)) {
|
|
74
|
+
let customDocSize = editorView.state.doc.nodeSize;
|
|
75
|
+
editorView.state.doc.descendants(node => {
|
|
76
|
+
var _node$attrs;
|
|
77
|
+
if (((_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.extensionKey) === 'legacy-content') {
|
|
78
|
+
var _node$attrs$parameter, _node$attrs2, _node$attrs2$paramete, _node$attrs2$paramete2;
|
|
79
|
+
customDocSize += (_node$attrs$parameter = (_node$attrs2 = node.attrs) === null || _node$attrs2 === void 0 ? void 0 : (_node$attrs2$paramete = _node$attrs2.parameters) === null || _node$attrs2$paramete === void 0 ? void 0 : (_node$attrs2$paramete2 = _node$attrs2$paramete.adf) === null || _node$attrs2$paramete2 === void 0 ? void 0 : _node$attrs2$paramete2.length) !== null && _node$attrs$parameter !== void 0 ? _node$attrs$parameter : 0;
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
limitedMode = customDocSize > nodeSizeLimit;
|
|
83
|
+
} else {
|
|
84
|
+
limitedMode = editorView.state.doc.nodeSize > nodeSizeLimit;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return limitedMode;
|
|
88
|
+
};
|
|
89
|
+
|
|
31
90
|
// Get the NodeIdProvider for a specific EditorView instance.
|
|
32
91
|
// This allows access to the node ids anywhere.
|
|
33
92
|
export const getNodeIdProvider = editorView => {
|
|
34
93
|
if (!nodeIdProviderMap.has(editorView)) {
|
|
94
|
+
if (fg('platform_editor_native_anchor_patch_2')) {
|
|
95
|
+
// if the limited mode flag is on, enable limited mode based on document size
|
|
96
|
+
// only for the first time
|
|
97
|
+
const limitedMode = isLimitedModeEnabled(editorView);
|
|
98
|
+
const isEmptyDoc = isEmptyDocument(editorView.state.doc);
|
|
99
|
+
const provider = new NodeAnchorProvider(limitedMode, isEmptyDoc);
|
|
100
|
+
nodeIdProviderMap.set(editorView, provider);
|
|
101
|
+
return provider;
|
|
102
|
+
}
|
|
35
103
|
const provider = new NodeAnchorProvider();
|
|
36
104
|
nodeIdProviderMap.set(editorView, provider);
|
|
37
105
|
return provider;
|
|
38
106
|
}
|
|
107
|
+
const nodeIdProvider = nodeIdProviderMap.get(editorView);
|
|
108
|
+
|
|
109
|
+
// in some cases we need to re-check limited mode state
|
|
110
|
+
// Confluence editor can start with an empty doc and then load content later
|
|
111
|
+
// so we need to check first time from an empty doc to a non-empty doc
|
|
112
|
+
if (nodeIdProvider.isEmptyDoc() && !isEmptyDocument(editorView.state.doc) && fg('platform_editor_native_anchor_patch_2')) {
|
|
113
|
+
// set empty doc to false regardless of limited mode state
|
|
114
|
+
nodeIdProvider.setEmptyDoc(false);
|
|
115
|
+
if (!nodeIdProvider.isLimitedMode() && isLimitedModeEnabled(editorView)) {
|
|
116
|
+
nodeIdProvider.setLimitedMode();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
39
119
|
|
|
40
120
|
// This is based on the fact that editorView is a singleton.
|
|
41
121
|
return nodeIdProviderMap.get(editorView);
|
|
@@ -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 = "110.48.
|
|
17
|
+
const packageVersion = "110.48.1";
|
|
18
18
|
const halfFocusRing = 1;
|
|
19
19
|
const dropOffset = '0, 8';
|
|
20
20
|
const fadeIn = keyframes({
|
|
@@ -10,7 +10,7 @@ import { isFedRamp } from './environment';
|
|
|
10
10
|
import { normaliseSentryBreadcrumbs, SERIALIZABLE_ATTRIBUTES } from './normalise-sentry-breadcrumbs';
|
|
11
11
|
var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
|
|
12
12
|
var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
|
|
13
|
-
var packageVersion = "110.48.
|
|
13
|
+
var packageVersion = "110.48.1";
|
|
14
14
|
var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
|
|
15
15
|
// Remove URL as it has UGC
|
|
16
16
|
// Ignored via go/ees007
|
|
@@ -1,20 +1,47 @@
|
|
|
1
1
|
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
|
2
2
|
import _createClass from "@babel/runtime/helpers/createClass";
|
|
3
3
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
4
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
5
|
+
import { expVal } from '@atlaskit/tmp-editor-statsig/expVal';
|
|
6
|
+
import { isEmptyDocument } from '../utils';
|
|
4
7
|
import { DynamicBitArray } from './dynamic-bit-array';
|
|
5
8
|
export var NodeAnchorProvider = /*#__PURE__*/function () {
|
|
6
9
|
function NodeAnchorProvider() {
|
|
10
|
+
var limitedMode = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
11
|
+
var emptyDoc = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
7
12
|
_classCallCheck(this, NodeAnchorProvider);
|
|
8
13
|
_defineProperty(this, "cache", new WeakMap());
|
|
9
14
|
_defineProperty(this, "count", BigInt(0));
|
|
10
15
|
_defineProperty(this, "existingPos", new DynamicBitArray());
|
|
16
|
+
_defineProperty(this, "limitedMode", false);
|
|
17
|
+
_defineProperty(this, "emptyDoc", false);
|
|
18
|
+
this.limitedMode = limitedMode;
|
|
19
|
+
this.emptyDoc = emptyDoc;
|
|
11
20
|
}
|
|
12
21
|
return _createClass(NodeAnchorProvider, [{
|
|
13
|
-
key: "
|
|
14
|
-
value:
|
|
22
|
+
key: "isEmptyDoc",
|
|
23
|
+
value: function isEmptyDoc() {
|
|
24
|
+
return this.emptyDoc;
|
|
25
|
+
}
|
|
26
|
+
}, {
|
|
27
|
+
key: "setEmptyDoc",
|
|
28
|
+
value: function setEmptyDoc(isEmpty) {
|
|
29
|
+
this.emptyDoc = isEmpty;
|
|
30
|
+
}
|
|
31
|
+
}, {
|
|
32
|
+
key: "isLimitedMode",
|
|
33
|
+
value: function isLimitedMode() {
|
|
34
|
+
return this.limitedMode;
|
|
35
|
+
}
|
|
36
|
+
|
|
15
37
|
// We use pos to generate unique ids for each node at a specific position
|
|
16
38
|
// This is to ensure the same ADF will always generate the same DOM initially
|
|
17
|
-
|
|
39
|
+
}, {
|
|
40
|
+
key: "getOrGenerateId",
|
|
41
|
+
value: function getOrGenerateId(node, pos) {
|
|
42
|
+
if (this.limitedMode) {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
18
45
|
if (this.cache.has(node)) {
|
|
19
46
|
return this.cache.get(node);
|
|
20
47
|
}
|
|
@@ -31,20 +58,82 @@ export var NodeAnchorProvider = /*#__PURE__*/function () {
|
|
|
31
58
|
}, {
|
|
32
59
|
key: "getIdForNode",
|
|
33
60
|
value: function getIdForNode(node) {
|
|
34
|
-
|
|
61
|
+
if (this.limitedMode) {
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
return this.cache.get(node);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// After set to limited mode, we clear the cache to free up memory
|
|
68
|
+
// and prevent further ids from being generated
|
|
69
|
+
// Once in limited mode, we won't exit it
|
|
70
|
+
}, {
|
|
71
|
+
key: "setLimitedMode",
|
|
72
|
+
value: function setLimitedMode() {
|
|
73
|
+
this.limitedMode = true;
|
|
74
|
+
this.cache = new WeakMap();
|
|
75
|
+
this.existingPos = new DynamicBitArray();
|
|
76
|
+
this.count = BigInt(0);
|
|
35
77
|
}
|
|
36
78
|
}]);
|
|
37
79
|
}();
|
|
38
80
|
var nodeIdProviderMap = new WeakMap();
|
|
39
81
|
|
|
82
|
+
// This is duplicate from the limited mode plugin to avoid circular dependency
|
|
83
|
+
// We can refactor this later to have a shared util package
|
|
84
|
+
var isLimitedModeEnabled = function isLimitedModeEnabled(editorView) {
|
|
85
|
+
var nodeSizeLimit = expVal('cc_editor_limited_mode', 'nodeSize', 100);
|
|
86
|
+
var limitedMode = false;
|
|
87
|
+
// some tests have nodeSizeLimit as boolean
|
|
88
|
+
if (typeof nodeSizeLimit === 'number') {
|
|
89
|
+
// duplicate logic from limited mode plugin to determine if we're in limited mode
|
|
90
|
+
// @ts-expect-error - true is not allowed as a default value
|
|
91
|
+
if (expVal('cc_editor_limited_mode_include_lcm', 'isEnabled', true)) {
|
|
92
|
+
var customDocSize = editorView.state.doc.nodeSize;
|
|
93
|
+
editorView.state.doc.descendants(function (node) {
|
|
94
|
+
var _node$attrs;
|
|
95
|
+
if (((_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.extensionKey) === 'legacy-content') {
|
|
96
|
+
var _node$attrs$parameter, _node$attrs2;
|
|
97
|
+
customDocSize += (_node$attrs$parameter = (_node$attrs2 = node.attrs) === null || _node$attrs2 === void 0 || (_node$attrs2 = _node$attrs2.parameters) === null || _node$attrs2 === void 0 || (_node$attrs2 = _node$attrs2.adf) === null || _node$attrs2 === void 0 ? void 0 : _node$attrs2.length) !== null && _node$attrs$parameter !== void 0 ? _node$attrs$parameter : 0;
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
limitedMode = customDocSize > nodeSizeLimit;
|
|
101
|
+
} else {
|
|
102
|
+
limitedMode = editorView.state.doc.nodeSize > nodeSizeLimit;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return limitedMode;
|
|
106
|
+
};
|
|
107
|
+
|
|
40
108
|
// Get the NodeIdProvider for a specific EditorView instance.
|
|
41
109
|
// This allows access to the node ids anywhere.
|
|
42
110
|
export var getNodeIdProvider = function getNodeIdProvider(editorView) {
|
|
43
111
|
if (!nodeIdProviderMap.has(editorView)) {
|
|
112
|
+
if (fg('platform_editor_native_anchor_patch_2')) {
|
|
113
|
+
// if the limited mode flag is on, enable limited mode based on document size
|
|
114
|
+
// only for the first time
|
|
115
|
+
var limitedMode = isLimitedModeEnabled(editorView);
|
|
116
|
+
var isEmptyDoc = isEmptyDocument(editorView.state.doc);
|
|
117
|
+
var _provider = new NodeAnchorProvider(limitedMode, isEmptyDoc);
|
|
118
|
+
nodeIdProviderMap.set(editorView, _provider);
|
|
119
|
+
return _provider;
|
|
120
|
+
}
|
|
44
121
|
var provider = new NodeAnchorProvider();
|
|
45
122
|
nodeIdProviderMap.set(editorView, provider);
|
|
46
123
|
return provider;
|
|
47
124
|
}
|
|
125
|
+
var nodeIdProvider = nodeIdProviderMap.get(editorView);
|
|
126
|
+
|
|
127
|
+
// in some cases we need to re-check limited mode state
|
|
128
|
+
// Confluence editor can start with an empty doc and then load content later
|
|
129
|
+
// so we need to check first time from an empty doc to a non-empty doc
|
|
130
|
+
if (nodeIdProvider.isEmptyDoc() && !isEmptyDocument(editorView.state.doc) && fg('platform_editor_native_anchor_patch_2')) {
|
|
131
|
+
// set empty doc to false regardless of limited mode state
|
|
132
|
+
nodeIdProvider.setEmptyDoc(false);
|
|
133
|
+
if (!nodeIdProvider.isLimitedMode() && isLimitedModeEnabled(editorView)) {
|
|
134
|
+
nodeIdProvider.setLimitedMode();
|
|
135
|
+
}
|
|
136
|
+
}
|
|
48
137
|
|
|
49
138
|
// This is based on the fact that editorView is a singleton.
|
|
50
139
|
return nodeIdProviderMap.get(editorView);
|
|
@@ -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 = "110.48.
|
|
24
|
+
var packageVersion = "110.48.1";
|
|
25
25
|
var halfFocusRing = 1;
|
|
26
26
|
var dropOffset = '0, 8';
|
|
27
27
|
var fadeIn = keyframes({
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { getNodeIdProvider } from './node-anchor-provider';
|
|
@@ -4,7 +4,14 @@ export declare class NodeAnchorProvider {
|
|
|
4
4
|
private cache;
|
|
5
5
|
private count;
|
|
6
6
|
private existingPos;
|
|
7
|
-
|
|
7
|
+
private limitedMode;
|
|
8
|
+
private emptyDoc;
|
|
9
|
+
constructor(limitedMode?: boolean, emptyDoc?: boolean);
|
|
10
|
+
isEmptyDoc(): boolean;
|
|
11
|
+
setEmptyDoc(isEmpty: boolean): void;
|
|
12
|
+
isLimitedMode(): boolean;
|
|
13
|
+
getOrGenerateId(node: PMNode, pos: number): string | undefined;
|
|
8
14
|
getIdForNode(node: PMNode): string | undefined;
|
|
15
|
+
setLimitedMode(): void;
|
|
9
16
|
}
|
|
10
17
|
export declare const getNodeIdProvider: (editorView: EditorView) => NodeAnchorProvider;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { getNodeIdProvider } from './node-anchor-provider';
|
|
@@ -4,7 +4,14 @@ export declare class NodeAnchorProvider {
|
|
|
4
4
|
private cache;
|
|
5
5
|
private count;
|
|
6
6
|
private existingPos;
|
|
7
|
-
|
|
7
|
+
private limitedMode;
|
|
8
|
+
private emptyDoc;
|
|
9
|
+
constructor(limitedMode?: boolean, emptyDoc?: boolean);
|
|
10
|
+
isEmptyDoc(): boolean;
|
|
11
|
+
setEmptyDoc(isEmpty: boolean): void;
|
|
12
|
+
isLimitedMode(): boolean;
|
|
13
|
+
getOrGenerateId(node: PMNode, pos: number): string | undefined;
|
|
8
14
|
getIdForNode(node: PMNode): string | undefined;
|
|
15
|
+
setLimitedMode(): void;
|
|
9
16
|
}
|
|
10
17
|
export declare const getNodeIdProvider: (editorView: EditorView) => NodeAnchorProvider;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@atlaskit/editor-common/node-anchor",
|
|
3
|
+
"main": "../dist/cjs/node-anchor/index.js",
|
|
4
|
+
"module": "../dist/esm/node-anchor/index.js",
|
|
5
|
+
"module:es2019": "../dist/es2019/node-anchor/index.js",
|
|
6
|
+
"sideEffects": [
|
|
7
|
+
"**/*.compiled.css"
|
|
8
|
+
],
|
|
9
|
+
"types": "../dist/types/node-anchor/index.d.ts",
|
|
10
|
+
"typesVersions": {
|
|
11
|
+
">=4.5 <5.9": {
|
|
12
|
+
"*": [
|
|
13
|
+
"../dist/types-ts4.5/node-anchor/index.d.ts"
|
|
14
|
+
]
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-common",
|
|
3
|
-
"version": "110.
|
|
3
|
+
"version": "110.49.0",
|
|
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/"
|
|
@@ -275,6 +275,9 @@
|
|
|
275
275
|
},
|
|
276
276
|
"platform_editor_dec_a11y_fixes": {
|
|
277
277
|
"type": "boolean"
|
|
278
|
+
},
|
|
279
|
+
"platform_editor_native_anchor_patch_2": {
|
|
280
|
+
"type": "boolean"
|
|
278
281
|
}
|
|
279
282
|
}
|
|
280
283
|
}
|