@atlaskit/editor-common 120.16.5 → 121.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/dist/cjs/ai-messages/ai-suggestions.js +5 -0
  3. package/dist/cjs/analytics/types/enums.js +1 -0
  4. package/dist/cjs/analytics/types/general-events.js +5 -1
  5. package/dist/cjs/mark/anyMarksActiveFromTr.js +35 -0
  6. package/dist/cjs/mark/getHadMarkAttributes.js +38 -0
  7. package/dist/cjs/mark/index.js +14 -0
  8. package/dist/cjs/monitoring/error.js +1 -1
  9. package/dist/cjs/node-anchor/should-enable-limited-mode.js +5 -4
  10. package/dist/cjs/ui/DropList/index.js +1 -1
  11. package/dist/cjs/utils/hyperlink.js +9 -5
  12. package/dist/es2019/ai-messages/ai-suggestions.js +5 -0
  13. package/dist/es2019/analytics/types/enums.js +1 -0
  14. package/dist/es2019/analytics/types/general-events.js +6 -1
  15. package/dist/es2019/mark/anyMarksActiveFromTr.js +31 -0
  16. package/dist/es2019/mark/getHadMarkAttributes.js +28 -0
  17. package/dist/es2019/mark/index.js +2 -0
  18. package/dist/es2019/monitoring/error.js +1 -1
  19. package/dist/es2019/node-anchor/should-enable-limited-mode.js +4 -3
  20. package/dist/es2019/ui/DropList/index.js +1 -1
  21. package/dist/es2019/utils/hyperlink.js +5 -2
  22. package/dist/esm/ai-messages/ai-suggestions.js +5 -0
  23. package/dist/esm/analytics/types/enums.js +1 -0
  24. package/dist/esm/analytics/types/general-events.js +6 -1
  25. package/dist/esm/mark/anyMarksActiveFromTr.js +30 -0
  26. package/dist/esm/mark/getHadMarkAttributes.js +32 -0
  27. package/dist/esm/mark/index.js +2 -0
  28. package/dist/esm/monitoring/error.js +1 -1
  29. package/dist/esm/node-anchor/should-enable-limited-mode.js +5 -4
  30. package/dist/esm/ui/DropList/index.js +1 -1
  31. package/dist/esm/utils/hyperlink.js +8 -3
  32. package/dist/types/ai-messages/ai-suggestions.d.ts +5 -0
  33. package/dist/types/analytics/types/enums.d.ts +1 -0
  34. package/dist/types/analytics/types/format-events.d.ts +1 -0
  35. package/dist/types/analytics/types/general-events.d.ts +45 -1
  36. package/dist/types/analytics/types/highlight-events.d.ts +2 -0
  37. package/dist/types/analytics/types/insert-events.d.ts +1 -0
  38. package/dist/types/analytics/types/paste-events.d.ts +1 -0
  39. package/dist/types/mark/anyMarksActiveFromTr.d.ts +6 -0
  40. package/dist/types/mark/getHadMarkAttributes.d.ts +15 -0
  41. package/dist/types/mark/index.d.ts +3 -0
  42. package/dist/types/node-anchor/should-enable-limited-mode.d.ts +4 -2
  43. package/dist/types/utils/hyperlink.d.ts +2 -1
  44. package/package.json +6 -6
  45. package/deprecated-platform-feature-experiments/package.json +0 -10
  46. package/dist/cjs/platform-feature-experiments/exp-val.js +0 -25
  47. package/dist/cjs/platform-feature-experiments/index.js +0 -26
  48. package/dist/cjs/platform-feature-experiments/is-experiment-enabled.js +0 -26
  49. package/dist/cjs/platform-feature-experiments/unsafe-exp-val-no-exposure.js +0 -22
  50. package/dist/es2019/platform-feature-experiments/exp-val.js +0 -19
  51. package/dist/es2019/platform-feature-experiments/index.js +0 -4
  52. package/dist/es2019/platform-feature-experiments/is-experiment-enabled.js +0 -20
  53. package/dist/es2019/platform-feature-experiments/unsafe-exp-val-no-exposure.js +0 -17
  54. package/dist/esm/platform-feature-experiments/exp-val.js +0 -19
  55. package/dist/esm/platform-feature-experiments/index.js +0 -4
  56. package/dist/esm/platform-feature-experiments/is-experiment-enabled.js +0 -20
  57. package/dist/esm/platform-feature-experiments/unsafe-exp-val-no-exposure.js +0 -17
  58. package/dist/types/platform-feature-experiments/exp-val.d.ts +0 -11
  59. package/dist/types/platform-feature-experiments/index.d.ts +0 -3
  60. package/dist/types/platform-feature-experiments/is-experiment-enabled.d.ts +0 -11
  61. package/dist/types/platform-feature-experiments/unsafe-exp-val-no-exposure.d.ts +0 -8
package/CHANGELOG.md CHANGED
@@ -1,5 +1,58 @@
1
1
  # @atlaskit/editor-common
2
2
 
3
+ ## 121.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`aec3fcfe13ff9`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/aec3fcfe13ff9) -
8
+ EDITOR-8303 Add runtime input-latency trigger for limited mode behind
9
+ platform_editor_dynamic_limited_mode. Limited mode can now latch mid-session when sustained slow
10
+ input or repeated browser freezes indicate the device is struggling, in addition to the existing
11
+ document-size decision. The latch is one-way. Nothing is constructed when the experiment is off.
12
+
13
+ How much evidence is needed is a single tunable, `requiredConfirmations`: that many qualifying
14
+ windows, each separated from the last by `confirmationGapMs`. The hardware no longer feeds into
15
+ the decision — `navigator.hardwareConcurrency` and `navigator.deviceMemory` are reported with the
16
+ `limitedModeLatched` event instead, so which devices latch can be answered from the data rather
17
+ than assumed up front.
18
+
19
+ `LimitedModePluginState` gains a derived `enabled` flag, which is now the single thing consumers
20
+ should branch on — the individual reasons (`documentSizeBreachesThreshold`, `latchPolicyBreached`)
21
+ no longer need to be combined at each call site, so a future reason needs no change outside this
22
+ plugin. `sharedState.enabled` reads from it.
23
+
24
+ Under the experiment the document decision is also evaluated on load and on document replacement
25
+ only, rather than on every transaction that changes the document. That check walks the whole
26
+ document, so it was a full-document scan per keystroke on exactly the pages least able to afford
27
+ one. The trade-off is that a document editing its way past the thresholds is not re-judged until
28
+ it next loads.
29
+
30
+ Consumers updated to react to a mid-session change: table sticky headers now subscribe instead of
31
+ reading once at construction, block-controls resets rather than freezes its state on entry, and
32
+ the expand, media and table nodeviews read the derived flag so they no longer miss a runtime
33
+ latch.
34
+
35
+ ## 121.0.0
36
+
37
+ ### Major Changes
38
+
39
+ - [`35f8ff3c9ce4f`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/35f8ff3c9ce4f) -
40
+ Clean up the released `platform_editor_improve_inline_diffs` experiment and remove the obsolete
41
+ editor experiment migration entry point.
42
+
43
+ ### Minor Changes
44
+
45
+ - [`fb891566dfac2`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/fb891566dfac2) -
46
+ Add anyMarksActiveFromTr and getHadMarkAttributes so mark-active checks can run from a
47
+ transaction. Color, highlight, toolbar/Cmd+K link apply, and paste events include had-mark
48
+ attributes behind kill switch platform_editor_add_text_color_tracking.
49
+ - [`3e4b2877553a2`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/3e4b2877553a2) -
50
+ Display agent and user author identities on AI suggestion cards.
51
+
52
+ ### Patch Changes
53
+
54
+ - Updated dependencies
55
+
3
56
  ## 120.16.5
4
57
 
5
58
  ### Patch Changes
@@ -141,6 +141,11 @@ var aiSuggestionsMessages = exports.aiSuggestionsMessages = (0, _reactIntl.defin
141
141
  defaultMessage: 'Rovo',
142
142
  description: 'Deprecated title for Rovo branding on the AI suggestions card'
143
143
  },
144
+ cardAuthorsTooltipLabel: {
145
+ id: 'fabric.editor.ai.suggestions.card.authorsTooltipLabel.non-final',
146
+ defaultMessage: '{agentName} with {userName}',
147
+ description: 'Tooltip identifying the agent and user who authored an AI suggestion together'
148
+ },
144
149
  cardPrivateLabel: {
145
150
  id: 'fabric.editor.ai.suggestions.card.privateLabel.non-final',
146
151
  defaultMessage: 'Private',
@@ -95,6 +95,7 @@ var ACTION = exports.ACTION = /*#__PURE__*/function (ACTION) {
95
95
  /** used in @atlassian/editor-referentiality */
96
96
  ACTION["GOT_CONNECTIONS"] = "gotConnections";
97
97
  ACTION["LANGUAGE_SELECTED"] = "languageSelected";
98
+ ACTION["LIMITED_MODE_LATCHED"] = "limitedModeLatched";
98
99
  ACTION["LANGUAGE_AUTO_DETECTED"] = "languageAutoDetected";
99
100
  ACTION["LIST_ITEM_JOINED"] = "listItemJoined";
100
101
  ACTION["MATCHED"] = "matched";
@@ -26,4 +26,8 @@ var BROWSER_FREEZE_INTERACTION_TYPE = exports.BROWSER_FREEZE_INTERACTION_TYPE =
26
26
  BROWSER_FREEZE_INTERACTION_TYPE["CLICKING"] = "clicking";
27
27
  BROWSER_FREEZE_INTERACTION_TYPE["PASTING"] = "pasting";
28
28
  return BROWSER_FREEZE_INTERACTION_TYPE;
29
- }({});
29
+ }({});
30
+ /**
31
+ * Fired when the runtime performance detector decides the device is struggling badly enough to
32
+ * warrant limited mode.
33
+ */
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.anyMarksActiveFromTr = void 0;
7
+ var _cellSelection = require("@atlaskit/editor-tables/cell-selection");
8
+ /**
9
+ * Determine which of the given marks exist anywhere in the transaction selection.
10
+ */
11
+ var anyMarksActiveFromTr = exports.anyMarksActiveFromTr = function anyMarksActiveFromTr(tr, markTypes) {
12
+ var _tr$selection = tr.selection,
13
+ $from = _tr$selection.$from,
14
+ from = _tr$selection.from,
15
+ to = _tr$selection.to,
16
+ empty = _tr$selection.empty;
17
+ return markTypes.map(function (markType) {
18
+ if (empty) {
19
+ return !!markType.isInSet(tr.storedMarks || $from.marks());
20
+ }
21
+ var rangeHasMark = false;
22
+ if (tr.selection instanceof _cellSelection.CellSelection) {
23
+ tr.selection.forEachCell(function (cell, cellPos) {
24
+ var from = cellPos;
25
+ var to = cellPos + cell.nodeSize;
26
+ if (!rangeHasMark) {
27
+ rangeHasMark = tr.doc.rangeHasMark(from, to, markType);
28
+ }
29
+ });
30
+ } else {
31
+ rangeHasMark = tr.doc.rangeHasMark(from, to, markType);
32
+ }
33
+ return rangeHasMark;
34
+ });
35
+ };
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getHadMarkAttributes = void 0;
7
+ var _fg = require("@atlaskit/platform-feature-flags/fg");
8
+ var _anyMarksActiveFromTr = require("./anyMarksActiveFromTr");
9
+ var HAD_ATTRIBUTE = {
10
+ backgroundColor: 'hadBackgroundColor',
11
+ link: 'hadLink',
12
+ textColor: 'hadTextColor'
13
+ };
14
+ var isMarkName = function isMarkName(name) {
15
+ return name in HAD_ATTRIBUTE;
16
+ };
17
+
18
+ /**
19
+ * `had*` flags for color / highlight / link apply events.
20
+ * Kill switch `platform_editor_add_text_color_tracking`: gate on, new attributes off.
21
+ */
22
+ var getHadMarkAttributes = exports.getHadMarkAttributes = function getHadMarkAttributes(tr, markTypes) {
23
+ if ((0, _fg.fg)('platform_editor_add_text_color_tracking')) {
24
+ return {};
25
+ }
26
+ var definedMarkTypes = markTypes.filter(function (markType) {
27
+ return !!markType;
28
+ });
29
+ var found = (0, _anyMarksActiveFromTr.anyMarksActiveFromTr)(tr, definedMarkTypes);
30
+ var result = {};
31
+ for (var i = 0; i < definedMarkTypes.length; i++) {
32
+ var markName = definedMarkTypes[i].name;
33
+ if (isMarkName(markName)) {
34
+ result[HAD_ATTRIBUTE[markName]] = Boolean(found[i]);
35
+ }
36
+ }
37
+ return result;
38
+ };
@@ -9,6 +9,12 @@ Object.defineProperty(exports, "anyMarkActive", {
9
9
  return _anyMarkActive.anyMarkActive;
10
10
  }
11
11
  });
12
+ Object.defineProperty(exports, "anyMarksActiveFromTr", {
13
+ enumerable: true,
14
+ get: function get() {
15
+ return _anyMarksActiveFromTr.anyMarksActiveFromTr;
16
+ }
17
+ });
12
18
  Object.defineProperty(exports, "applyMarkOnRange", {
13
19
  enumerable: true,
14
20
  get: function get() {
@@ -27,6 +33,12 @@ Object.defineProperty(exports, "filterChildrenBetween", {
27
33
  return _filterChildrenBetween.filterChildrenBetween;
28
34
  }
29
35
  });
36
+ Object.defineProperty(exports, "getHadMarkAttributes", {
37
+ enumerable: true,
38
+ get: function get() {
39
+ return _getHadMarkAttributes.getHadMarkAttributes;
40
+ }
41
+ });
30
42
  Object.defineProperty(exports, "isMarkAllowedInRange", {
31
43
  enumerable: true,
32
44
  get: function get() {
@@ -68,6 +80,8 @@ var _entireSelectionContainsMark = require("./entireSelectionContainsMark");
68
80
  var _filterChildrenBetween = require("./filterChildrenBetween");
69
81
  var _removeMark = require("./removeMark");
70
82
  var _anyMarkActive = require("./anyMarkActive");
83
+ var _anyMarksActiveFromTr = require("./anyMarksActiveFromTr");
84
+ var _getHadMarkAttributes = require("./getHadMarkAttributes");
71
85
  var _isMarkAllowedInRange = require("./isMarkAllowedInRange");
72
86
  var _isMarkExcluded = require("./isMarkExcluded");
73
87
  var _textFormatting = require("./text-formatting");
@@ -27,7 +27,7 @@ var NETWORK_FAILURE_REGEX = /^network failure/i;
27
27
  var RESIZE_OBSERVER_LOOP_REGEX = /ResizeObserver loop completed with undelivered notifications/;
28
28
  var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
29
29
  var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
30
- var packageVersion = "120.16.4";
30
+ var packageVersion = "121.0.0";
31
31
  var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
32
32
  // Remove URL as it has UGC
33
33
  // Ignored via go/ees007
@@ -20,16 +20,17 @@ var LEGACY_CONTENT_EXTENSION_KEY = 'legacy-content';
20
20
  * 2. the document contains a legacy-content macro (LCM)
21
21
  * 3. node count exceeds the node-count threshold
22
22
  *
23
- * The thresholds come from `getLimitedModeThresholds()`, which is where the
23
+ * Thresholds default to `getLimitedModeThresholds()` but can be passed in, which is how the
24
+ * limited-mode plugin's latch policy supplies them from its own config. That default is where the
24
25
  * `platform_editor_limited_threshold_tweaks` cohort is resolved — see
25
26
  * `limited-mode-document-thresholds.ts` for the values and the data behind them.
26
27
  *
27
28
  * Performance: doc size is checked first so an oversized document skips the traversal entirely.
28
29
  */
29
30
  var shouldEnableLimitedModeForDocument = exports.shouldEnableLimitedModeForDocument = function shouldEnableLimitedModeForDocument(doc) {
30
- var _getLimitedModeThresh = (0, _limitedModeDocumentThresholds.getLimitedModeThresholds)(),
31
- docSizeThreshold = _getLimitedModeThresh.docSizeThreshold,
32
- nodeCountThreshold = _getLimitedModeThresh.nodeCountThreshold;
31
+ var thresholds = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : (0, _limitedModeDocumentThresholds.getLimitedModeThresholds)();
32
+ var docSizeThreshold = thresholds.docSizeThreshold,
33
+ nodeCountThreshold = thresholds.nodeCountThreshold;
33
34
  if (doc.nodeSize > docSizeThreshold) {
34
35
  return true;
35
36
  }
@@ -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 = "120.16.4";
27
+ var packageVersion = "121.0.0";
28
28
  var halfFocusRing = 1;
29
29
  var dropOffset = '0, 8';
30
30
  var fadeIn = (0, _react2.keyframes)({
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
3
4
  Object.defineProperty(exports, "__esModule", {
4
5
  value: true
5
6
  });
@@ -39,8 +40,10 @@ Object.defineProperty(exports, "normalizeUrl", {
39
40
  return _normalizeUrl.normalizeUrl;
40
41
  }
41
42
  });
43
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
42
44
  var _url = require("@atlaskit/adf-schema/url");
43
45
  var _enums = require("../analytics/types/enums");
46
+ var _getHadMarkAttributes = require("../mark/getHadMarkAttributes");
44
47
  var _FILEPATH_REGEXP = require("./FILEPATH_REGEXP");
45
48
  var _getLinkDomain = require("./getLinkDomain");
46
49
  var _normalizeUrl = require("./normalizeUrl");
@@ -48,9 +51,9 @@ var _shouldAutoLinkifyTld = require("./should-auto-linkify-tld");
48
51
  var _slice = require("./slice");
49
52
  var _LinkMatcher = require("./LinkMatcher");
50
53
  var _canLinkBeCreatedInRange = require("./canLinkBeCreatedInRange");
51
- // File has been copied to packages/editor/editor-plugin-ai/src/provider/markdown-transformer/utils/hyperlink.ts
54
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
55
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } // File has been copied to packages/editor/editor-plugin-ai/src/provider/markdown-transformer/utils/hyperlink.ts
52
56
  // If changes are made to this file, please make the same update in the linked file.
53
-
54
57
  // Don't linkify if starts with $ or {
55
58
  // Ignored via go/ees005
56
59
  // eslint-disable-next-line require-unicode-regexp
@@ -156,15 +159,16 @@ var isLinkInMatches = exports.isLinkInMatches = function isLinkInMatches(linkSta
156
159
  };
157
160
 
158
161
  // eslint-disable-next-line jsdoc/require-jsdoc, @atlaskit/volt-strict-mode/no-multiple-exports
159
- function getLinkCreationAnalyticsEvent(inputMethod, url) {
162
+ function getLinkCreationAnalyticsEvent(inputMethod, url, tr) {
163
+ var backgroundColor = tr === null || tr === void 0 ? void 0 : tr.doc.type.schema.marks.backgroundColor;
160
164
  return {
161
165
  action: _enums.ACTION.INSERTED,
162
166
  actionSubject: _enums.ACTION_SUBJECT.DOCUMENT,
163
167
  actionSubjectId: _enums.ACTION_SUBJECT_ID.LINK,
164
- attributes: {
168
+ attributes: _objectSpread({
165
169
  inputMethod: inputMethod,
166
170
  fromCurrentDomain: isFromCurrentDomain(url)
167
- },
171
+ }, tr && backgroundColor ? (0, _getHadMarkAttributes.getHadMarkAttributes)(tr, [backgroundColor]) : {}),
168
172
  eventType: _enums.EVENT_TYPE.TRACK,
169
173
  nonPrivacySafeAttributes: {
170
174
  linkDomain: (0, _getLinkDomain.getLinkDomain)(url)
@@ -135,6 +135,11 @@ export const aiSuggestionsMessages = defineMessages({
135
135
  defaultMessage: 'Rovo',
136
136
  description: 'Deprecated title for Rovo branding on the AI suggestions card'
137
137
  },
138
+ cardAuthorsTooltipLabel: {
139
+ id: 'fabric.editor.ai.suggestions.card.authorsTooltipLabel.non-final',
140
+ defaultMessage: '{agentName} with {userName}',
141
+ description: 'Tooltip identifying the agent and user who authored an AI suggestion together'
142
+ },
138
143
  cardPrivateLabel: {
139
144
  id: 'fabric.editor.ai.suggestions.card.privateLabel.non-final',
140
145
  defaultMessage: 'Private',
@@ -91,6 +91,7 @@ export let ACTION = /*#__PURE__*/function (ACTION) {
91
91
  /** used in @atlassian/editor-referentiality */
92
92
  ACTION["GOT_CONNECTIONS"] = "gotConnections";
93
93
  ACTION["LANGUAGE_SELECTED"] = "languageSelected";
94
+ ACTION["LIMITED_MODE_LATCHED"] = "limitedModeLatched";
94
95
  ACTION["LANGUAGE_AUTO_DETECTED"] = "languageAutoDetected";
95
96
  ACTION["LIST_ITEM_JOINED"] = "listItemJoined";
96
97
  ACTION["MATCHED"] = "matched";
@@ -26,4 +26,9 @@ export let BROWSER_FREEZE_INTERACTION_TYPE = /*#__PURE__*/function (BROWSER_FREE
26
26
  BROWSER_FREEZE_INTERACTION_TYPE["CLICKING"] = "clicking";
27
27
  BROWSER_FREEZE_INTERACTION_TYPE["PASTING"] = "pasting";
28
28
  return BROWSER_FREEZE_INTERACTION_TYPE;
29
- }({});
29
+ }({});
30
+
31
+ /**
32
+ * Fired when the runtime performance detector decides the device is struggling badly enough to
33
+ * warrant limited mode.
34
+ */
@@ -0,0 +1,31 @@
1
+ import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
2
+
3
+ /**
4
+ * Determine which of the given marks exist anywhere in the transaction selection.
5
+ */
6
+ export const anyMarksActiveFromTr = (tr, markTypes) => {
7
+ const {
8
+ $from,
9
+ from,
10
+ to,
11
+ empty
12
+ } = tr.selection;
13
+ return markTypes.map(markType => {
14
+ if (empty) {
15
+ return !!markType.isInSet(tr.storedMarks || $from.marks());
16
+ }
17
+ let rangeHasMark = false;
18
+ if (tr.selection instanceof CellSelection) {
19
+ tr.selection.forEachCell((cell, cellPos) => {
20
+ const from = cellPos;
21
+ const to = cellPos + cell.nodeSize;
22
+ if (!rangeHasMark) {
23
+ rangeHasMark = tr.doc.rangeHasMark(from, to, markType);
24
+ }
25
+ });
26
+ } else {
27
+ rangeHasMark = tr.doc.rangeHasMark(from, to, markType);
28
+ }
29
+ return rangeHasMark;
30
+ });
31
+ };
@@ -0,0 +1,28 @@
1
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
2
+ import { anyMarksActiveFromTr } from './anyMarksActiveFromTr';
3
+ const HAD_ATTRIBUTE = {
4
+ backgroundColor: 'hadBackgroundColor',
5
+ link: 'hadLink',
6
+ textColor: 'hadTextColor'
7
+ };
8
+ const isMarkName = name => name in HAD_ATTRIBUTE;
9
+
10
+ /**
11
+ * `had*` flags for color / highlight / link apply events.
12
+ * Kill switch `platform_editor_add_text_color_tracking`: gate on, new attributes off.
13
+ */
14
+ export const getHadMarkAttributes = (tr, markTypes) => {
15
+ if (fg('platform_editor_add_text_color_tracking')) {
16
+ return {};
17
+ }
18
+ const definedMarkTypes = markTypes.filter(markType => !!markType);
19
+ const found = anyMarksActiveFromTr(tr, definedMarkTypes);
20
+ const result = {};
21
+ for (let i = 0; i < definedMarkTypes.length; i++) {
22
+ const markName = definedMarkTypes[i].name;
23
+ if (isMarkName(markName)) {
24
+ result[HAD_ATTRIBUTE[markName]] = Boolean(found[i]);
25
+ }
26
+ }
27
+ return result;
28
+ };
@@ -6,6 +6,8 @@ export { entireSelectionContainsMark } from './entireSelectionContainsMark';
6
6
  export { filterChildrenBetween } from './filterChildrenBetween';
7
7
  export { removeMark } from './removeMark';
8
8
  export { anyMarkActive } from './anyMarkActive';
9
+ export { anyMarksActiveFromTr } from './anyMarksActiveFromTr';
10
+ export { getHadMarkAttributes } from './getHadMarkAttributes';
9
11
  export { isMarkAllowedInRange } from './isMarkAllowedInRange';
10
12
  export { isMarkExcluded } from './isMarkExcluded';
11
13
  export { wholeSelectionHasMarks } from './text-formatting';
@@ -13,7 +13,7 @@ const NETWORK_FAILURE_REGEX = /^network failure/i;
13
13
  const RESIZE_OBSERVER_LOOP_REGEX = /ResizeObserver loop completed with undelivered notifications/;
14
14
  const SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
15
15
  const packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
16
- const packageVersion = "120.16.4";
16
+ const packageVersion = "121.0.0";
17
17
  const sanitiseSentryEvents = (data, _hint) => {
18
18
  // Remove URL as it has UGC
19
19
  // Ignored via go/ees007
@@ -14,17 +14,18 @@ const LEGACY_CONTENT_EXTENSION_KEY = 'legacy-content';
14
14
  * 2. the document contains a legacy-content macro (LCM)
15
15
  * 3. node count exceeds the node-count threshold
16
16
  *
17
- * The thresholds come from `getLimitedModeThresholds()`, which is where the
17
+ * Thresholds default to `getLimitedModeThresholds()` but can be passed in, which is how the
18
+ * limited-mode plugin's latch policy supplies them from its own config. That default is where the
18
19
  * `platform_editor_limited_threshold_tweaks` cohort is resolved — see
19
20
  * `limited-mode-document-thresholds.ts` for the values and the data behind them.
20
21
  *
21
22
  * Performance: doc size is checked first so an oversized document skips the traversal entirely.
22
23
  */
23
- export const shouldEnableLimitedModeForDocument = doc => {
24
+ export const shouldEnableLimitedModeForDocument = (doc, thresholds = getLimitedModeThresholds()) => {
24
25
  const {
25
26
  docSizeThreshold,
26
27
  nodeCountThreshold
27
- } = getLimitedModeThresholds();
28
+ } = thresholds;
28
29
  if (doc.nodeSize > docSizeThreshold) {
29
30
  return true;
30
31
  }
@@ -14,7 +14,7 @@ import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
14
14
  import { fg } from '@atlaskit/platform-feature-flags/fg';
15
15
  import Layer from '../Layer';
16
16
  const packageName = "@atlaskit/editor-common";
17
- const packageVersion = "120.16.4";
17
+ const packageVersion = "121.0.0";
18
18
  const halfFocusRing = 1;
19
19
  const dropOffset = '0, 8';
20
20
  const fadeIn = keyframes({
@@ -3,6 +3,7 @@
3
3
 
4
4
  import { linkify } from '@atlaskit/adf-schema/url';
5
5
  import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE } from '../analytics/types/enums';
6
+ import { getHadMarkAttributes } from '../mark/getHadMarkAttributes';
6
7
  import { FILEPATH_REGEXP } from './FILEPATH_REGEXP';
7
8
  import { getLinkDomain } from './getLinkDomain';
8
9
  import { normalizeUrl } from './normalizeUrl';
@@ -111,14 +112,16 @@ export const isLinkInMatches = (linkStart, matchesList) => {
111
112
  };
112
113
 
113
114
  // eslint-disable-next-line jsdoc/require-jsdoc, @atlaskit/volt-strict-mode/no-multiple-exports
114
- export function getLinkCreationAnalyticsEvent(inputMethod, url) {
115
+ export function getLinkCreationAnalyticsEvent(inputMethod, url, tr) {
116
+ const backgroundColor = tr === null || tr === void 0 ? void 0 : tr.doc.type.schema.marks.backgroundColor;
115
117
  return {
116
118
  action: ACTION.INSERTED,
117
119
  actionSubject: ACTION_SUBJECT.DOCUMENT,
118
120
  actionSubjectId: ACTION_SUBJECT_ID.LINK,
119
121
  attributes: {
120
122
  inputMethod,
121
- fromCurrentDomain: isFromCurrentDomain(url)
123
+ fromCurrentDomain: isFromCurrentDomain(url),
124
+ ...(tr && backgroundColor ? getHadMarkAttributes(tr, [backgroundColor]) : {})
122
125
  },
123
126
  eventType: EVENT_TYPE.TRACK,
124
127
  nonPrivacySafeAttributes: {
@@ -135,6 +135,11 @@ export var aiSuggestionsMessages = defineMessages({
135
135
  defaultMessage: 'Rovo',
136
136
  description: 'Deprecated title for Rovo branding on the AI suggestions card'
137
137
  },
138
+ cardAuthorsTooltipLabel: {
139
+ id: 'fabric.editor.ai.suggestions.card.authorsTooltipLabel.non-final',
140
+ defaultMessage: '{agentName} with {userName}',
141
+ description: 'Tooltip identifying the agent and user who authored an AI suggestion together'
142
+ },
138
143
  cardPrivateLabel: {
139
144
  id: 'fabric.editor.ai.suggestions.card.privateLabel.non-final',
140
145
  defaultMessage: 'Private',
@@ -91,6 +91,7 @@ export var ACTION = /*#__PURE__*/function (ACTION) {
91
91
  /** used in @atlassian/editor-referentiality */
92
92
  ACTION["GOT_CONNECTIONS"] = "gotConnections";
93
93
  ACTION["LANGUAGE_SELECTED"] = "languageSelected";
94
+ ACTION["LIMITED_MODE_LATCHED"] = "limitedModeLatched";
94
95
  ACTION["LANGUAGE_AUTO_DETECTED"] = "languageAutoDetected";
95
96
  ACTION["LIST_ITEM_JOINED"] = "listItemJoined";
96
97
  ACTION["MATCHED"] = "matched";
@@ -26,4 +26,9 @@ export var BROWSER_FREEZE_INTERACTION_TYPE = /*#__PURE__*/function (BROWSER_FREE
26
26
  BROWSER_FREEZE_INTERACTION_TYPE["CLICKING"] = "clicking";
27
27
  BROWSER_FREEZE_INTERACTION_TYPE["PASTING"] = "pasting";
28
28
  return BROWSER_FREEZE_INTERACTION_TYPE;
29
- }({});
29
+ }({});
30
+
31
+ /**
32
+ * Fired when the runtime performance detector decides the device is struggling badly enough to
33
+ * warrant limited mode.
34
+ */
@@ -0,0 +1,30 @@
1
+ import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
2
+
3
+ /**
4
+ * Determine which of the given marks exist anywhere in the transaction selection.
5
+ */
6
+ export var anyMarksActiveFromTr = function anyMarksActiveFromTr(tr, markTypes) {
7
+ var _tr$selection = tr.selection,
8
+ $from = _tr$selection.$from,
9
+ from = _tr$selection.from,
10
+ to = _tr$selection.to,
11
+ empty = _tr$selection.empty;
12
+ return markTypes.map(function (markType) {
13
+ if (empty) {
14
+ return !!markType.isInSet(tr.storedMarks || $from.marks());
15
+ }
16
+ var rangeHasMark = false;
17
+ if (tr.selection instanceof CellSelection) {
18
+ tr.selection.forEachCell(function (cell, cellPos) {
19
+ var from = cellPos;
20
+ var to = cellPos + cell.nodeSize;
21
+ if (!rangeHasMark) {
22
+ rangeHasMark = tr.doc.rangeHasMark(from, to, markType);
23
+ }
24
+ });
25
+ } else {
26
+ rangeHasMark = tr.doc.rangeHasMark(from, to, markType);
27
+ }
28
+ return rangeHasMark;
29
+ });
30
+ };
@@ -0,0 +1,32 @@
1
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
2
+ import { anyMarksActiveFromTr } from './anyMarksActiveFromTr';
3
+ var HAD_ATTRIBUTE = {
4
+ backgroundColor: 'hadBackgroundColor',
5
+ link: 'hadLink',
6
+ textColor: 'hadTextColor'
7
+ };
8
+ var isMarkName = function isMarkName(name) {
9
+ return name in HAD_ATTRIBUTE;
10
+ };
11
+
12
+ /**
13
+ * `had*` flags for color / highlight / link apply events.
14
+ * Kill switch `platform_editor_add_text_color_tracking`: gate on, new attributes off.
15
+ */
16
+ export var getHadMarkAttributes = function getHadMarkAttributes(tr, markTypes) {
17
+ if (fg('platform_editor_add_text_color_tracking')) {
18
+ return {};
19
+ }
20
+ var definedMarkTypes = markTypes.filter(function (markType) {
21
+ return !!markType;
22
+ });
23
+ var found = anyMarksActiveFromTr(tr, definedMarkTypes);
24
+ var result = {};
25
+ for (var i = 0; i < definedMarkTypes.length; i++) {
26
+ var markName = definedMarkTypes[i].name;
27
+ if (isMarkName(markName)) {
28
+ result[HAD_ATTRIBUTE[markName]] = Boolean(found[i]);
29
+ }
30
+ }
31
+ return result;
32
+ };
@@ -6,6 +6,8 @@ export { entireSelectionContainsMark } from './entireSelectionContainsMark';
6
6
  export { filterChildrenBetween } from './filterChildrenBetween';
7
7
  export { removeMark } from './removeMark';
8
8
  export { anyMarkActive } from './anyMarkActive';
9
+ export { anyMarksActiveFromTr } from './anyMarksActiveFromTr';
10
+ export { getHadMarkAttributes } from './getHadMarkAttributes';
9
11
  export { isMarkAllowedInRange } from './isMarkAllowedInRange';
10
12
  export { isMarkExcluded } from './isMarkExcluded';
11
13
  export { wholeSelectionHasMarks } from './text-formatting';
@@ -19,7 +19,7 @@ var NETWORK_FAILURE_REGEX = /^network failure/i;
19
19
  var RESIZE_OBSERVER_LOOP_REGEX = /ResizeObserver loop completed with undelivered notifications/;
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 = "120.16.4";
22
+ var packageVersion = "121.0.0";
23
23
  var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
24
24
  // Remove URL as it has UGC
25
25
  // Ignored via go/ees007
@@ -14,16 +14,17 @@ var LEGACY_CONTENT_EXTENSION_KEY = 'legacy-content';
14
14
  * 2. the document contains a legacy-content macro (LCM)
15
15
  * 3. node count exceeds the node-count threshold
16
16
  *
17
- * The thresholds come from `getLimitedModeThresholds()`, which is where the
17
+ * Thresholds default to `getLimitedModeThresholds()` but can be passed in, which is how the
18
+ * limited-mode plugin's latch policy supplies them from its own config. That default is where the
18
19
  * `platform_editor_limited_threshold_tweaks` cohort is resolved — see
19
20
  * `limited-mode-document-thresholds.ts` for the values and the data behind them.
20
21
  *
21
22
  * Performance: doc size is checked first so an oversized document skips the traversal entirely.
22
23
  */
23
24
  export var shouldEnableLimitedModeForDocument = function shouldEnableLimitedModeForDocument(doc) {
24
- var _getLimitedModeThresh = getLimitedModeThresholds(),
25
- docSizeThreshold = _getLimitedModeThresh.docSizeThreshold,
26
- nodeCountThreshold = _getLimitedModeThresh.nodeCountThreshold;
25
+ var thresholds = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getLimitedModeThresholds();
26
+ var docSizeThreshold = thresholds.docSizeThreshold,
27
+ nodeCountThreshold = thresholds.nodeCountThreshold;
27
28
  if (doc.nodeSize > docSizeThreshold) {
28
29
  return true;
29
30
  }
@@ -21,7 +21,7 @@ import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
21
21
  import { fg } from '@atlaskit/platform-feature-flags/fg';
22
22
  import Layer from '../Layer';
23
23
  var packageName = "@atlaskit/editor-common";
24
- var packageVersion = "120.16.4";
24
+ var packageVersion = "121.0.0";
25
25
  var halfFocusRing = 1;
26
26
  var dropOffset = '0, 8';
27
27
  var fadeIn = keyframes({