@atlaskit/editor-common 110.34.4 → 110.34.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @atlaskit/editor-common
2
2
 
3
+ ## 110.34.6
4
+
5
+ ### Patch Changes
6
+
7
+ - [`43d1dfc88c1de`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/43d1dfc88c1de) -
8
+ Clean up platform_editor_block_menu_format_rank_revised
9
+ - Updated dependencies
10
+
11
+ ## 110.34.5
12
+
13
+ ### Patch Changes
14
+
15
+ - [`cfa9f26687992`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/cfa9f26687992) -
16
+ Enable breadcrumbs in Sentry for Editor
17
+ - [`34ebbcd3440c2`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/34ebbcd3440c2) -
18
+ NO-ISSUE Split by action subject id for experience tracking
19
+
3
20
  ## 110.34.4
4
21
 
5
22
  ### Patch Changes
@@ -9,7 +9,7 @@ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/de
9
9
  var _key = require("./key");
10
10
  var _keyDeprecated = require("./key-deprecated");
11
11
  var _FORMAT_NESTED_MENU_R, _FORMAT_NESTED_MENU_R2;
12
- var FORMAT_NESTED_MENU_RANK = exports.FORMAT_NESTED_MENU_RANK = (_FORMAT_NESTED_MENU_R = {}, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)(_FORMAT_NESTED_MENU_R, _key.FORMAT_HEADING_1_MENU_ITEM.key, 50), _key.FORMAT_HEADING_2_MENU_ITEM.key, 100), _key.FORMAT_HEADING_3_MENU_ITEM.key, 150), _key.FORMAT_PARAGRAPH_MENU_ITEM.key, 200), _key.FORMAT_QUOTE_MENU_ITEM.key, 250), _key.FORMAT_EXPAND_MENU_ITEM.key, 300), _key.FORMAT_LAYOUT_MENU_ITEM.key, 350), _key.FORMAT_PANEL_MENU_ITEM.key, 400), _key.FORMAT_CODE_BLOCK_MENU_ITEM.key, 450), _key.FORMAT_BULLETED_LIST_MENU_ITEM.key, 500), (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)(_FORMAT_NESTED_MENU_R, _key.FORMAT_NUMBERED_LIST_MENU_ITEM.key, 550), _key.FORMAT_TASK_LIST_MENU_ITEM.key, 600), _key.FORMAT_HEADING_4_MENU_ITEM.key, 650), _key.FORMAT_HEADING_5_MENU_ITEM.key, 700), _key.FORMAT_HEADING_6_MENU_ITEM.key, 750));
12
+ var FORMAT_NESTED_MENU_RANK = exports.FORMAT_NESTED_MENU_RANK = (_FORMAT_NESTED_MENU_R = {}, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)(_FORMAT_NESTED_MENU_R, _key.FORMAT_PARAGRAPH_MENU_ITEM.key, 50), _key.FORMAT_QUOTE_MENU_ITEM.key, 100), _key.FORMAT_EXPAND_MENU_ITEM.key, 150), _key.FORMAT_LAYOUT_MENU_ITEM.key, 200), _key.FORMAT_PANEL_MENU_ITEM.key, 250), _key.FORMAT_CODE_BLOCK_MENU_ITEM.key, 300), _key.FORMAT_BULLETED_LIST_MENU_ITEM.key, 350), _key.FORMAT_NUMBERED_LIST_MENU_ITEM.key, 400), _key.FORMAT_TASK_LIST_MENU_ITEM.key, 450), _key.FORMAT_HEADING_1_MENU_ITEM.key, 500), (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)(_FORMAT_NESTED_MENU_R, _key.FORMAT_HEADING_2_MENU_ITEM.key, 550), _key.FORMAT_HEADING_3_MENU_ITEM.key, 600), _key.FORMAT_HEADING_4_MENU_ITEM.key, 650), _key.FORMAT_HEADING_5_MENU_ITEM.key, 700), _key.FORMAT_HEADING_6_MENU_ITEM.key, 750));
13
13
  var FORMAT_NESTED_MENU_RANK_REVISED = exports.FORMAT_NESTED_MENU_RANK_REVISED = (_FORMAT_NESTED_MENU_R2 = {}, (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)(_FORMAT_NESTED_MENU_R2, _key.FORMAT_PARAGRAPH_MENU_ITEM.key, 50), _key.FORMAT_QUOTE_MENU_ITEM.key, 100), _key.FORMAT_EXPAND_MENU_ITEM.key, 150), _key.FORMAT_LAYOUT_MENU_ITEM.key, 200), _key.FORMAT_PANEL_MENU_ITEM.key, 250), _key.FORMAT_CODE_BLOCK_MENU_ITEM.key, 300), _key.FORMAT_BULLETED_LIST_MENU_ITEM.key, 350), _key.FORMAT_NUMBERED_LIST_MENU_ITEM.key, 400), _key.FORMAT_TASK_LIST_MENU_ITEM.key, 450), _key.FORMAT_HEADING_1_MENU_ITEM.key, 500), (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)(_FORMAT_NESTED_MENU_R2, _key.FORMAT_HEADING_2_MENU_ITEM.key, 550), _key.FORMAT_HEADING_3_MENU_ITEM.key, 600), _key.FORMAT_HEADING_4_MENU_ITEM.key, 650), _key.FORMAT_HEADING_5_MENU_ITEM.key, 700), _key.FORMAT_HEADING_6_MENU_ITEM.key, 750));
14
14
  var BLOCK_MENU_SECTION_RANK = exports.BLOCK_MENU_SECTION_RANK = (0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)((0, _defineProperty2.default)({}, _key.PRIMARY_MENU_SECTION.key, 100), _key.ADD_BLOCKS_MENU_SECTION.key, 200), _key.COPY_MENU_SECTION.key, 300), _key.MOVE_UP_DOWN_MENU_SECTION.key, 400), _key.DELETE_MENU_SECTION.key, 500);
15
15
  var PRIMARY_MENU_SECTION_RANK = exports.PRIMARY_MENU_SECTION_RANK = (0, _defineProperty2.default)((0, _defineProperty2.default)({}, _keyDeprecated.FORMAT_MENU_ITEM.key, 50), _key.TRANSFORM_MENU_ITEM.key, 50);
@@ -38,13 +38,14 @@ var Experience = exports.Experience = /*#__PURE__*/function () {
38
38
  /**
39
39
  * Creates a new Experience instance for tracking user experiences.
40
40
  *
41
- * @param id - Unique identifier for the experience
41
+ * @param id - Unique identifier for the experience e.g. 'toolbar-open' 'menu-action'
42
42
  * @param options - Configuration options for the experience
43
43
  * @param options.checks - Experience checks to monitor for completion
44
44
  * @param options.dispatchAnalyticsEvent - Function to dispatch analytics events
45
45
  * @param options.sampleRate - Sample rate for experienceSampled events
46
46
  * @param options.metadata - Global metadata to attach to all events
47
- * @param options.action - Optional sub identifier for the specific experience action
47
+ * @param options.action - Optional sub identifier for the specific experience action e.g. 'bold' 'insert-table'
48
+ * @param options.actionSubjectId - Optional sub identifier for the experience action subject e.g. 'selection-toolbar' 'quick-insert'
48
49
  */
49
50
  function Experience(id, options) {
50
51
  var _options$sampleRate;
@@ -57,6 +58,7 @@ var Experience = exports.Experience = /*#__PURE__*/function () {
57
58
  */
58
59
  (0, _defineProperty2.default)(this, "statesSeen", new Set());
59
60
  this.id = id;
61
+ this.actionSubjectId = options.actionSubjectId;
60
62
  this.dispatchAnalyticsEvent = options.dispatchAnalyticsEvent;
61
63
  this.sampleRate = (_options$sampleRate = options.sampleRate) !== null && _options$sampleRate !== void 0 ? _options$sampleRate : _consts.DEFAULT_EXPERIENCE_SAMPLE_RATE;
62
64
  this.globalMetadata = _objectSpread(_objectSpread({}, options.metadata), {}, {
@@ -161,7 +163,7 @@ var Experience = exports.Experience = /*#__PURE__*/function () {
161
163
  var experienceMeasuredEvent = {
162
164
  action: _analytics.ACTION.EXPERIENCE_MEASURED,
163
165
  actionSubject: _analytics.ACTION_SUBJECT.EDITOR,
164
- actionSubjectId: undefined,
166
+ actionSubjectId: this.actionSubjectId,
165
167
  eventType: _analytics.EVENT_TYPE.OPERATIONAL,
166
168
  attributes: attributes
167
169
  };
@@ -170,7 +172,7 @@ var Experience = exports.Experience = /*#__PURE__*/function () {
170
172
  var experienceSampledEvent = {
171
173
  action: _analytics.ACTION.EXPERIENCE_SAMPLED,
172
174
  actionSubject: _analytics.ACTION_SUBJECT.EDITOR,
173
- actionSubjectId: undefined,
175
+ actionSubjectId: this.actionSubjectId,
174
176
  eventType: _analytics.EVENT_TYPE.OPERATIONAL,
175
177
  attributes: attributes
176
178
  };
@@ -10,13 +10,16 @@ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"))
10
10
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
11
11
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
12
12
  var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
13
+ var _browser = require("@sentry/browser");
14
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
13
15
  var _environment = require("./environment");
16
+ var _normaliseSentryBreadcrumbs = require("./normalise-sentry-breadcrumbs");
14
17
  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; }
15
18
  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; }
16
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); }
17
20
  var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
18
21
  var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
19
- var packageVersion = "0.0.0-development";
22
+ var packageVersion = "110.34.5";
20
23
  var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
21
24
  // Remove URL as it has UGC
22
25
  // Ignored via go/ees007
@@ -29,7 +32,7 @@ var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
29
32
  };
30
33
  var logException = exports.logException = /*#__PURE__*/function () {
31
34
  var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(error, tags) {
32
- var _process$env$CLOUD_EN, _yield$import, BrowserClient, defaultIntegrations, getCurrentHub, _yield$import2, ExtraErrorData, sentryOptions, client, hub;
35
+ var _process$env$CLOUD_EN, _yield$import, BrowserClient, defaultIntegrations, getCurrentHub, _yield$import2, ExtraErrorData, breadcrumbsIntegration, sentryOptions, client, hub;
33
36
  return _regenerator.default.wrap(function _callee$(_context) {
34
37
  while (1) switch (_context.prev = _context.next) {
35
38
  case 0:
@@ -56,10 +59,23 @@ var logException = exports.logException = /*#__PURE__*/function () {
56
59
  case 11:
57
60
  _yield$import2 = _context.sent;
58
61
  ExtraErrorData = _yield$import2.ExtraErrorData;
62
+ breadcrumbsIntegration = (0, _platformFeatureFlags.fg)('platform_editor_sentry_breadcrumbs') ? new _browser.Integrations.Breadcrumbs({
63
+ // only enable breadcrumbs for dom (UI clicks and inputs)
64
+ // include 'data-test-id', 'data-testid' in the breadcrumbs if they are found
65
+ dom: {
66
+ serializeAttribute: _normaliseSentryBreadcrumbs.SERIALIZABLE_ATTRIBUTES
67
+ },
68
+ fetch: false,
69
+ xhr: false,
70
+ console: false,
71
+ history: false,
72
+ sentry: false
73
+ }) : undefined;
59
74
  sentryOptions = {
60
75
  dsn: (0, _environment.isFedRamp)() ? undefined : SENTRY_DSN,
61
76
  release: "".concat(packageName, "@").concat(packageVersion),
62
77
  environment: (_process$env$CLOUD_EN = process.env.CLOUD_ENV) !== null && _process$env$CLOUD_EN !== void 0 ? _process$env$CLOUD_EN : 'unknown',
78
+ beforeBreadcrumb: (0, _platformFeatureFlags.fg)('platform_editor_sentry_breadcrumbs') ? _normaliseSentryBreadcrumbs.normaliseSentryBreadcrumbs : undefined,
63
79
  ignoreErrors: [
64
80
  // Network issues
65
81
  // Ignored via go/ees005
@@ -78,7 +94,7 @@ var logException = exports.logException = /*#__PURE__*/function () {
78
94
  return [].concat((0, _toConsumableArray2.default)(defaultIntegrations.filter(function (_ref2) {
79
95
  var name = _ref2.name;
80
96
  return name !== 'Breadcrumbs';
81
- })), [
97
+ })), (0, _toConsumableArray2.default)(breadcrumbsIntegration ? [breadcrumbsIntegration] : []), [
82
98
  // Extracts all non-native attributes from the error object and attaches them to the event as the extra data
83
99
  // https://docs.sentry.io/platforms/javascript/configuration/integrations/plugin/?original_referrer=https%3A%2F%2Fduckduckgo.com%2F#extraerrordata
84
100
  new ExtraErrorData()]);
@@ -113,14 +129,14 @@ var logException = exports.logException = /*#__PURE__*/function () {
113
129
 
114
130
  // @ts-ignore - TypeScript 5.9.2 upgrade
115
131
  return _context.abrupt("return", client.close());
116
- case 21:
117
- _context.prev = 21;
132
+ case 22:
133
+ _context.prev = 22;
118
134
  _context.t0 = _context["catch"](0);
119
- case 23:
135
+ case 24:
120
136
  case "end":
121
137
  return _context.stop();
122
138
  }
123
- }, _callee, null, [[0, 21]]);
139
+ }, _callee, null, [[0, 22]]);
124
140
  }));
125
141
  return function logException(_x, _x2) {
126
142
  return _ref.apply(this, arguments);
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.normaliseSentryBreadcrumbs = exports.SERIALIZABLE_ATTRIBUTES = void 0;
7
+ var SERIALIZABLE_ATTRIBUTES = exports.SERIALIZABLE_ATTRIBUTES = ['data-test-id', 'data-testid'];
8
+ var WHITELISTED_ATTRIBNUTES = ['type', 'name'].concat(SERIALIZABLE_ATTRIBUTES);
9
+ var REG_MATCH_NOTALLOWED_ATTRIBUTES = new RegExp("\\[(?!".concat(WHITELISTED_ATTRIBNUTES.join('|'), ").*?\\]"), 'gmu');
10
+
11
+ // attributes may contain UGC that we need to strip out
12
+ // only allow type and name attributes
13
+ var sanitiseUiBreadcrumbMessage = function sanitiseUiBreadcrumbMessage(message) {
14
+ return message.replace(REG_MATCH_NOTALLOWED_ATTRIBUTES, '');
15
+ };
16
+ /**
17
+ * Sanitizes messages within UI category breadcrumbs to ensure user-generated content is
18
+ * appropriately cleaned before being logged by Sentry. This helps in maintaining
19
+ * privacy and security by preventing sensitive data exposure.
20
+ */
21
+ var normaliseSentryBreadcrumbs = exports.normaliseSentryBreadcrumbs = function normaliseSentryBreadcrumbs(breadcrumb) {
22
+ var _ref = breadcrumb || {},
23
+ category = _ref.category;
24
+
25
+ // allow "ui*"" category breadcrumbs, that include clicks and inputs on DOM elements
26
+ // they may contain UGC that needs to be stripped out
27
+ if (category !== null && category !== void 0 && category.startsWith('ui')) {
28
+ // sentry can include the element attributes in the data
29
+ // which may contain UGC that we need to strip out
30
+ var sanitisedBreadCrumb = breadcrumb;
31
+ var message = sanitisedBreadCrumb.message;
32
+ if (message !== null && message !== undefined) {
33
+ sanitisedBreadCrumb.message = sanitiseUiBreadcrumbMessage(message);
34
+ }
35
+ return breadcrumb;
36
+ }
37
+ return breadcrumb;
38
+ };
@@ -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 = "0.0.0-development";
27
+ var packageVersion = "110.34.5";
28
28
  var halfFocusRing = 1;
29
29
  var dropOffset = '0, 8';
30
30
  var fadeIn = (0, _react2.keyframes)({
@@ -1,18 +1,18 @@
1
1
  import { FORMAT_HEADING_1_MENU_ITEM, FORMAT_HEADING_2_MENU_ITEM, FORMAT_HEADING_3_MENU_ITEM, FORMAT_HEADING_4_MENU_ITEM, FORMAT_HEADING_5_MENU_ITEM, FORMAT_HEADING_6_MENU_ITEM, FORMAT_PARAGRAPH_MENU_ITEM, FORMAT_QUOTE_MENU_ITEM, FORMAT_EXPAND_MENU_ITEM, FORMAT_LAYOUT_MENU_ITEM, FORMAT_PANEL_MENU_ITEM, FORMAT_CODE_BLOCK_MENU_ITEM, FORMAT_BULLETED_LIST_MENU_ITEM, FORMAT_NUMBERED_LIST_MENU_ITEM, FORMAT_TASK_LIST_MENU_ITEM, COPY_BLOCK_MENU_ITEM, COPY_LINK_MENU_ITEM, MOVE_UP_MENU_ITEM, MOVE_DOWN_MENU_ITEM, DELETE_MENU_ITEM, PRIMARY_MENU_SECTION, COPY_MENU_SECTION, DELETE_MENU_SECTION, MOVE_UP_DOWN_MENU_SECTION, ADD_BLOCKS_MENU_SECTION, CREATE_SYNCED_BLOCK_MENU_ITEM, TRANSFORM_MENU_ITEM, TRANSFORM_HEADINGS_MENU_SECTION, TRANSFORM_CREATE_MENU_SECTION, TRANSFORM_SUGGESTED_MENU_SECTION, TRANSFORM_STRUCTURE_MENU_SECTION } from './key';
2
2
  import { FORMAT_MENU_ITEM } from './key-deprecated';
3
3
  export const FORMAT_NESTED_MENU_RANK = {
4
- [FORMAT_HEADING_1_MENU_ITEM.key]: 50,
5
- [FORMAT_HEADING_2_MENU_ITEM.key]: 100,
6
- [FORMAT_HEADING_3_MENU_ITEM.key]: 150,
7
- [FORMAT_PARAGRAPH_MENU_ITEM.key]: 200,
8
- [FORMAT_QUOTE_MENU_ITEM.key]: 250,
9
- [FORMAT_EXPAND_MENU_ITEM.key]: 300,
10
- [FORMAT_LAYOUT_MENU_ITEM.key]: 350,
11
- [FORMAT_PANEL_MENU_ITEM.key]: 400,
12
- [FORMAT_CODE_BLOCK_MENU_ITEM.key]: 450,
13
- [FORMAT_BULLETED_LIST_MENU_ITEM.key]: 500,
14
- [FORMAT_NUMBERED_LIST_MENU_ITEM.key]: 550,
15
- [FORMAT_TASK_LIST_MENU_ITEM.key]: 600,
4
+ [FORMAT_PARAGRAPH_MENU_ITEM.key]: 50,
5
+ [FORMAT_QUOTE_MENU_ITEM.key]: 100,
6
+ [FORMAT_EXPAND_MENU_ITEM.key]: 150,
7
+ [FORMAT_LAYOUT_MENU_ITEM.key]: 200,
8
+ [FORMAT_PANEL_MENU_ITEM.key]: 250,
9
+ [FORMAT_CODE_BLOCK_MENU_ITEM.key]: 300,
10
+ [FORMAT_BULLETED_LIST_MENU_ITEM.key]: 350,
11
+ [FORMAT_NUMBERED_LIST_MENU_ITEM.key]: 400,
12
+ [FORMAT_TASK_LIST_MENU_ITEM.key]: 450,
13
+ [FORMAT_HEADING_1_MENU_ITEM.key]: 500,
14
+ [FORMAT_HEADING_2_MENU_ITEM.key]: 550,
15
+ [FORMAT_HEADING_3_MENU_ITEM.key]: 600,
16
16
  [FORMAT_HEADING_4_MENU_ITEM.key]: 650,
17
17
  [FORMAT_HEADING_5_MENU_ITEM.key]: 700,
18
18
  [FORMAT_HEADING_6_MENU_ITEM.key]: 750
@@ -27,13 +27,14 @@ export class Experience {
27
27
  /**
28
28
  * Creates a new Experience instance for tracking user experiences.
29
29
  *
30
- * @param id - Unique identifier for the experience
30
+ * @param id - Unique identifier for the experience e.g. 'toolbar-open' 'menu-action'
31
31
  * @param options - Configuration options for the experience
32
32
  * @param options.checks - Experience checks to monitor for completion
33
33
  * @param options.dispatchAnalyticsEvent - Function to dispatch analytics events
34
34
  * @param options.sampleRate - Sample rate for experienceSampled events
35
35
  * @param options.metadata - Global metadata to attach to all events
36
- * @param options.action - Optional sub identifier for the specific experience action
36
+ * @param options.action - Optional sub identifier for the specific experience action e.g. 'bold' 'insert-table'
37
+ * @param options.actionSubjectId - Optional sub identifier for the experience action subject e.g. 'selection-toolbar' 'quick-insert'
37
38
  */
38
39
  constructor(id, options) {
39
40
  var _options$sampleRate;
@@ -45,6 +46,7 @@ export class Experience {
45
46
  */
46
47
  _defineProperty(this, "statesSeen", new Set());
47
48
  this.id = id;
49
+ this.actionSubjectId = options.actionSubjectId;
48
50
  this.dispatchAnalyticsEvent = options.dispatchAnalyticsEvent;
49
51
  this.sampleRate = (_options$sampleRate = options.sampleRate) !== null && _options$sampleRate !== void 0 ? _options$sampleRate : DEFAULT_EXPERIENCE_SAMPLE_RATE;
50
52
  this.globalMetadata = {
@@ -145,7 +147,7 @@ export class Experience {
145
147
  const experienceMeasuredEvent = {
146
148
  action: ACTION.EXPERIENCE_MEASURED,
147
149
  actionSubject: ACTION_SUBJECT.EDITOR,
148
- actionSubjectId: undefined,
150
+ actionSubjectId: this.actionSubjectId,
149
151
  eventType: EVENT_TYPE.OPERATIONAL,
150
152
  attributes
151
153
  };
@@ -154,7 +156,7 @@ export class Experience {
154
156
  const experienceSampledEvent = {
155
157
  action: ACTION.EXPERIENCE_SAMPLED,
156
158
  actionSubject: ACTION_SUBJECT.EDITOR,
157
- actionSubjectId: undefined,
159
+ actionSubjectId: this.actionSubjectId,
158
160
  eventType: EVENT_TYPE.OPERATIONAL,
159
161
  attributes
160
162
  };
@@ -1,7 +1,10 @@
1
+ import { Integrations } from '@sentry/browser';
2
+ import { fg } from '@atlaskit/platform-feature-flags';
1
3
  import { isFedRamp } from './environment';
4
+ import { normaliseSentryBreadcrumbs, SERIALIZABLE_ATTRIBUTES } from './normalise-sentry-breadcrumbs';
2
5
  const SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
3
6
  const packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
4
- const packageVersion = "0.0.0-development";
7
+ const packageVersion = "110.34.5";
5
8
  const sanitiseSentryEvents = (data, _hint) => {
6
9
  // Remove URL as it has UGC
7
10
  // Ignored via go/ees007
@@ -27,10 +30,23 @@ export const logException = async (error, tags) => {
27
30
  const {
28
31
  ExtraErrorData
29
32
  } = await import( /* webpackChunkName: "@atlaskit-internal_editor-sentryintegrations" */'@sentry/integrations');
33
+ const breadcrumbsIntegration = fg('platform_editor_sentry_breadcrumbs') ? new Integrations.Breadcrumbs({
34
+ // only enable breadcrumbs for dom (UI clicks and inputs)
35
+ // include 'data-test-id', 'data-testid' in the breadcrumbs if they are found
36
+ dom: {
37
+ serializeAttribute: SERIALIZABLE_ATTRIBUTES
38
+ },
39
+ fetch: false,
40
+ xhr: false,
41
+ console: false,
42
+ history: false,
43
+ sentry: false
44
+ }) : undefined;
30
45
  const sentryOptions = {
31
46
  dsn: isFedRamp() ? undefined : SENTRY_DSN,
32
47
  release: `${packageName}@${packageVersion}`,
33
48
  environment: (_process$env$CLOUD_EN = process.env.CLOUD_ENV) !== null && _process$env$CLOUD_EN !== void 0 ? _process$env$CLOUD_EN : 'unknown',
49
+ beforeBreadcrumb: fg('platform_editor_sentry_breadcrumbs') ? normaliseSentryBreadcrumbs : undefined,
34
50
  ignoreErrors: [
35
51
  // Network issues
36
52
  // Ignored via go/ees005
@@ -50,7 +66,7 @@ export const logException = async (error, tags) => {
50
66
  // https://docs.sentry.io/platforms/javascript/configuration/integrations/default/
51
67
  ...defaultIntegrations.filter(({
52
68
  name
53
- }) => name !== 'Breadcrumbs'),
69
+ }) => name !== 'Breadcrumbs'), ...(breadcrumbsIntegration ? [breadcrumbsIntegration] : []),
54
70
  // Extracts all non-native attributes from the error object and attaches them to the event as the extra data
55
71
  // https://docs.sentry.io/platforms/javascript/configuration/integrations/plugin/?original_referrer=https%3A%2F%2Fduckduckgo.com%2F#extraerrordata
56
72
  new ExtraErrorData()],
@@ -0,0 +1,33 @@
1
+ export const SERIALIZABLE_ATTRIBUTES = ['data-test-id', 'data-testid'];
2
+ const WHITELISTED_ATTRIBNUTES = ['type', 'name', ...SERIALIZABLE_ATTRIBUTES];
3
+ const REG_MATCH_NOTALLOWED_ATTRIBUTES = new RegExp(`\\[(?!${WHITELISTED_ATTRIBNUTES.join('|')}).*?\\]`, 'gmu');
4
+
5
+ // attributes may contain UGC that we need to strip out
6
+ // only allow type and name attributes
7
+ const sanitiseUiBreadcrumbMessage = message => message.replace(REG_MATCH_NOTALLOWED_ATTRIBUTES, '');
8
+ /**
9
+ * Sanitizes messages within UI category breadcrumbs to ensure user-generated content is
10
+ * appropriately cleaned before being logged by Sentry. This helps in maintaining
11
+ * privacy and security by preventing sensitive data exposure.
12
+ */
13
+ export const normaliseSentryBreadcrumbs = breadcrumb => {
14
+ const {
15
+ category
16
+ } = breadcrumb || {};
17
+
18
+ // allow "ui*"" category breadcrumbs, that include clicks and inputs on DOM elements
19
+ // they may contain UGC that needs to be stripped out
20
+ if (category !== null && category !== void 0 && category.startsWith('ui')) {
21
+ // sentry can include the element attributes in the data
22
+ // which may contain UGC that we need to strip out
23
+ const sanitisedBreadCrumb = breadcrumb;
24
+ const {
25
+ message
26
+ } = sanitisedBreadCrumb;
27
+ if (message !== null && message !== undefined) {
28
+ sanitisedBreadCrumb.message = sanitiseUiBreadcrumbMessage(message);
29
+ }
30
+ return breadcrumb;
31
+ }
32
+ return breadcrumb;
33
+ };
@@ -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 = "0.0.0-development";
17
+ const packageVersion = "110.34.5";
18
18
  const halfFocusRing = 1;
19
19
  const dropOffset = '0, 8';
20
20
  const fadeIn = keyframes({
@@ -2,7 +2,7 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  var _FORMAT_NESTED_MENU_R, _FORMAT_NESTED_MENU_R2;
3
3
  import { FORMAT_HEADING_1_MENU_ITEM, FORMAT_HEADING_2_MENU_ITEM, FORMAT_HEADING_3_MENU_ITEM, FORMAT_HEADING_4_MENU_ITEM, FORMAT_HEADING_5_MENU_ITEM, FORMAT_HEADING_6_MENU_ITEM, FORMAT_PARAGRAPH_MENU_ITEM, FORMAT_QUOTE_MENU_ITEM, FORMAT_EXPAND_MENU_ITEM, FORMAT_LAYOUT_MENU_ITEM, FORMAT_PANEL_MENU_ITEM, FORMAT_CODE_BLOCK_MENU_ITEM, FORMAT_BULLETED_LIST_MENU_ITEM, FORMAT_NUMBERED_LIST_MENU_ITEM, FORMAT_TASK_LIST_MENU_ITEM, COPY_BLOCK_MENU_ITEM, COPY_LINK_MENU_ITEM, MOVE_UP_MENU_ITEM, MOVE_DOWN_MENU_ITEM, DELETE_MENU_ITEM, PRIMARY_MENU_SECTION, COPY_MENU_SECTION, DELETE_MENU_SECTION, MOVE_UP_DOWN_MENU_SECTION, ADD_BLOCKS_MENU_SECTION, CREATE_SYNCED_BLOCK_MENU_ITEM, TRANSFORM_MENU_ITEM, TRANSFORM_HEADINGS_MENU_SECTION, TRANSFORM_CREATE_MENU_SECTION, TRANSFORM_SUGGESTED_MENU_SECTION, TRANSFORM_STRUCTURE_MENU_SECTION } from './key';
4
4
  import { FORMAT_MENU_ITEM } from './key-deprecated';
5
- export var FORMAT_NESTED_MENU_RANK = (_FORMAT_NESTED_MENU_R = {}, _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_FORMAT_NESTED_MENU_R, FORMAT_HEADING_1_MENU_ITEM.key, 50), FORMAT_HEADING_2_MENU_ITEM.key, 100), FORMAT_HEADING_3_MENU_ITEM.key, 150), FORMAT_PARAGRAPH_MENU_ITEM.key, 200), FORMAT_QUOTE_MENU_ITEM.key, 250), FORMAT_EXPAND_MENU_ITEM.key, 300), FORMAT_LAYOUT_MENU_ITEM.key, 350), FORMAT_PANEL_MENU_ITEM.key, 400), FORMAT_CODE_BLOCK_MENU_ITEM.key, 450), FORMAT_BULLETED_LIST_MENU_ITEM.key, 500), _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_FORMAT_NESTED_MENU_R, FORMAT_NUMBERED_LIST_MENU_ITEM.key, 550), FORMAT_TASK_LIST_MENU_ITEM.key, 600), FORMAT_HEADING_4_MENU_ITEM.key, 650), FORMAT_HEADING_5_MENU_ITEM.key, 700), FORMAT_HEADING_6_MENU_ITEM.key, 750));
5
+ export var FORMAT_NESTED_MENU_RANK = (_FORMAT_NESTED_MENU_R = {}, _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_FORMAT_NESTED_MENU_R, FORMAT_PARAGRAPH_MENU_ITEM.key, 50), FORMAT_QUOTE_MENU_ITEM.key, 100), FORMAT_EXPAND_MENU_ITEM.key, 150), FORMAT_LAYOUT_MENU_ITEM.key, 200), FORMAT_PANEL_MENU_ITEM.key, 250), FORMAT_CODE_BLOCK_MENU_ITEM.key, 300), FORMAT_BULLETED_LIST_MENU_ITEM.key, 350), FORMAT_NUMBERED_LIST_MENU_ITEM.key, 400), FORMAT_TASK_LIST_MENU_ITEM.key, 450), FORMAT_HEADING_1_MENU_ITEM.key, 500), _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_FORMAT_NESTED_MENU_R, FORMAT_HEADING_2_MENU_ITEM.key, 550), FORMAT_HEADING_3_MENU_ITEM.key, 600), FORMAT_HEADING_4_MENU_ITEM.key, 650), FORMAT_HEADING_5_MENU_ITEM.key, 700), FORMAT_HEADING_6_MENU_ITEM.key, 750));
6
6
  export var FORMAT_NESTED_MENU_RANK_REVISED = (_FORMAT_NESTED_MENU_R2 = {}, _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_FORMAT_NESTED_MENU_R2, FORMAT_PARAGRAPH_MENU_ITEM.key, 50), FORMAT_QUOTE_MENU_ITEM.key, 100), FORMAT_EXPAND_MENU_ITEM.key, 150), FORMAT_LAYOUT_MENU_ITEM.key, 200), FORMAT_PANEL_MENU_ITEM.key, 250), FORMAT_CODE_BLOCK_MENU_ITEM.key, 300), FORMAT_BULLETED_LIST_MENU_ITEM.key, 350), FORMAT_NUMBERED_LIST_MENU_ITEM.key, 400), FORMAT_TASK_LIST_MENU_ITEM.key, 450), FORMAT_HEADING_1_MENU_ITEM.key, 500), _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_FORMAT_NESTED_MENU_R2, FORMAT_HEADING_2_MENU_ITEM.key, 550), FORMAT_HEADING_3_MENU_ITEM.key, 600), FORMAT_HEADING_4_MENU_ITEM.key, 650), FORMAT_HEADING_5_MENU_ITEM.key, 700), FORMAT_HEADING_6_MENU_ITEM.key, 750));
7
7
  export var BLOCK_MENU_SECTION_RANK = _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({}, PRIMARY_MENU_SECTION.key, 100), ADD_BLOCKS_MENU_SECTION.key, 200), COPY_MENU_SECTION.key, 300), MOVE_UP_DOWN_MENU_SECTION.key, 400), DELETE_MENU_SECTION.key, 500);
8
8
  export var PRIMARY_MENU_SECTION_RANK = _defineProperty(_defineProperty({}, FORMAT_MENU_ITEM.key, 50), TRANSFORM_MENU_ITEM.key, 50);
@@ -31,13 +31,14 @@ export var Experience = /*#__PURE__*/function () {
31
31
  /**
32
32
  * Creates a new Experience instance for tracking user experiences.
33
33
  *
34
- * @param id - Unique identifier for the experience
34
+ * @param id - Unique identifier for the experience e.g. 'toolbar-open' 'menu-action'
35
35
  * @param options - Configuration options for the experience
36
36
  * @param options.checks - Experience checks to monitor for completion
37
37
  * @param options.dispatchAnalyticsEvent - Function to dispatch analytics events
38
38
  * @param options.sampleRate - Sample rate for experienceSampled events
39
39
  * @param options.metadata - Global metadata to attach to all events
40
- * @param options.action - Optional sub identifier for the specific experience action
40
+ * @param options.action - Optional sub identifier for the specific experience action e.g. 'bold' 'insert-table'
41
+ * @param options.actionSubjectId - Optional sub identifier for the experience action subject e.g. 'selection-toolbar' 'quick-insert'
41
42
  */
42
43
  function Experience(id, options) {
43
44
  var _options$sampleRate;
@@ -50,6 +51,7 @@ export var Experience = /*#__PURE__*/function () {
50
51
  */
51
52
  _defineProperty(this, "statesSeen", new Set());
52
53
  this.id = id;
54
+ this.actionSubjectId = options.actionSubjectId;
53
55
  this.dispatchAnalyticsEvent = options.dispatchAnalyticsEvent;
54
56
  this.sampleRate = (_options$sampleRate = options.sampleRate) !== null && _options$sampleRate !== void 0 ? _options$sampleRate : DEFAULT_EXPERIENCE_SAMPLE_RATE;
55
57
  this.globalMetadata = _objectSpread(_objectSpread({}, options.metadata), {}, {
@@ -154,7 +156,7 @@ export var Experience = /*#__PURE__*/function () {
154
156
  var experienceMeasuredEvent = {
155
157
  action: ACTION.EXPERIENCE_MEASURED,
156
158
  actionSubject: ACTION_SUBJECT.EDITOR,
157
- actionSubjectId: undefined,
159
+ actionSubjectId: this.actionSubjectId,
158
160
  eventType: EVENT_TYPE.OPERATIONAL,
159
161
  attributes: attributes
160
162
  };
@@ -163,7 +165,7 @@ export var Experience = /*#__PURE__*/function () {
163
165
  var experienceSampledEvent = {
164
166
  action: ACTION.EXPERIENCE_SAMPLED,
165
167
  actionSubject: ACTION_SUBJECT.EDITOR,
166
- actionSubjectId: undefined,
168
+ actionSubjectId: this.actionSubjectId,
167
169
  eventType: EVENT_TYPE.OPERATIONAL,
168
170
  attributes: attributes
169
171
  };
@@ -4,10 +4,13 @@ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
4
4
  import _regeneratorRuntime from "@babel/runtime/regenerator";
5
5
  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; }
6
6
  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) { _defineProperty(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; }
7
+ import { Integrations } from '@sentry/browser';
8
+ import { fg } from '@atlaskit/platform-feature-flags';
7
9
  import { isFedRamp } from './environment';
10
+ import { normaliseSentryBreadcrumbs, SERIALIZABLE_ATTRIBUTES } from './normalise-sentry-breadcrumbs';
8
11
  var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
9
12
  var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
10
- var packageVersion = "0.0.0-development";
13
+ var packageVersion = "110.34.5";
11
14
  var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
12
15
  // Remove URL as it has UGC
13
16
  // Ignored via go/ees007
@@ -20,7 +23,7 @@ var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
20
23
  };
21
24
  export var logException = /*#__PURE__*/function () {
22
25
  var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(error, tags) {
23
- var _process$env$CLOUD_EN, _yield$import, BrowserClient, defaultIntegrations, getCurrentHub, _yield$import2, ExtraErrorData, sentryOptions, client, hub;
26
+ var _process$env$CLOUD_EN, _yield$import, BrowserClient, defaultIntegrations, getCurrentHub, _yield$import2, ExtraErrorData, breadcrumbsIntegration, sentryOptions, client, hub;
24
27
  return _regeneratorRuntime.wrap(function _callee$(_context) {
25
28
  while (1) switch (_context.prev = _context.next) {
26
29
  case 0:
@@ -43,10 +46,23 @@ export var logException = /*#__PURE__*/function () {
43
46
  case 11:
44
47
  _yield$import2 = _context.sent;
45
48
  ExtraErrorData = _yield$import2.ExtraErrorData;
49
+ breadcrumbsIntegration = fg('platform_editor_sentry_breadcrumbs') ? new Integrations.Breadcrumbs({
50
+ // only enable breadcrumbs for dom (UI clicks and inputs)
51
+ // include 'data-test-id', 'data-testid' in the breadcrumbs if they are found
52
+ dom: {
53
+ serializeAttribute: SERIALIZABLE_ATTRIBUTES
54
+ },
55
+ fetch: false,
56
+ xhr: false,
57
+ console: false,
58
+ history: false,
59
+ sentry: false
60
+ }) : undefined;
46
61
  sentryOptions = {
47
62
  dsn: isFedRamp() ? undefined : SENTRY_DSN,
48
63
  release: "".concat(packageName, "@").concat(packageVersion),
49
64
  environment: (_process$env$CLOUD_EN = process.env.CLOUD_ENV) !== null && _process$env$CLOUD_EN !== void 0 ? _process$env$CLOUD_EN : 'unknown',
65
+ beforeBreadcrumb: fg('platform_editor_sentry_breadcrumbs') ? normaliseSentryBreadcrumbs : undefined,
50
66
  ignoreErrors: [
51
67
  // Network issues
52
68
  // Ignored via go/ees005
@@ -65,7 +81,7 @@ export var logException = /*#__PURE__*/function () {
65
81
  return [].concat(_toConsumableArray(defaultIntegrations.filter(function (_ref2) {
66
82
  var name = _ref2.name;
67
83
  return name !== 'Breadcrumbs';
68
- })), [
84
+ })), _toConsumableArray(breadcrumbsIntegration ? [breadcrumbsIntegration] : []), [
69
85
  // Extracts all non-native attributes from the error object and attaches them to the event as the extra data
70
86
  // https://docs.sentry.io/platforms/javascript/configuration/integrations/plugin/?original_referrer=https%3A%2F%2Fduckduckgo.com%2F#extraerrordata
71
87
  new ExtraErrorData()]);
@@ -100,14 +116,14 @@ export var logException = /*#__PURE__*/function () {
100
116
 
101
117
  // @ts-ignore - TypeScript 5.9.2 upgrade
102
118
  return _context.abrupt("return", client.close());
103
- case 21:
104
- _context.prev = 21;
119
+ case 22:
120
+ _context.prev = 22;
105
121
  _context.t0 = _context["catch"](0);
106
- case 23:
122
+ case 24:
107
123
  case "end":
108
124
  return _context.stop();
109
125
  }
110
- }, _callee, null, [[0, 21]]);
126
+ }, _callee, null, [[0, 22]]);
111
127
  }));
112
128
  return function logException(_x, _x2) {
113
129
  return _ref.apply(this, arguments);
@@ -0,0 +1,32 @@
1
+ export var SERIALIZABLE_ATTRIBUTES = ['data-test-id', 'data-testid'];
2
+ var WHITELISTED_ATTRIBNUTES = ['type', 'name'].concat(SERIALIZABLE_ATTRIBUTES);
3
+ var REG_MATCH_NOTALLOWED_ATTRIBUTES = new RegExp("\\[(?!".concat(WHITELISTED_ATTRIBNUTES.join('|'), ").*?\\]"), 'gmu');
4
+
5
+ // attributes may contain UGC that we need to strip out
6
+ // only allow type and name attributes
7
+ var sanitiseUiBreadcrumbMessage = function sanitiseUiBreadcrumbMessage(message) {
8
+ return message.replace(REG_MATCH_NOTALLOWED_ATTRIBUTES, '');
9
+ };
10
+ /**
11
+ * Sanitizes messages within UI category breadcrumbs to ensure user-generated content is
12
+ * appropriately cleaned before being logged by Sentry. This helps in maintaining
13
+ * privacy and security by preventing sensitive data exposure.
14
+ */
15
+ export var normaliseSentryBreadcrumbs = function normaliseSentryBreadcrumbs(breadcrumb) {
16
+ var _ref = breadcrumb || {},
17
+ category = _ref.category;
18
+
19
+ // allow "ui*"" category breadcrumbs, that include clicks and inputs on DOM elements
20
+ // they may contain UGC that needs to be stripped out
21
+ if (category !== null && category !== void 0 && category.startsWith('ui')) {
22
+ // sentry can include the element attributes in the data
23
+ // which may contain UGC that we need to strip out
24
+ var sanitisedBreadCrumb = breadcrumb;
25
+ var message = sanitisedBreadCrumb.message;
26
+ if (message !== null && message !== undefined) {
27
+ sanitisedBreadCrumb.message = sanitiseUiBreadcrumbMessage(message);
28
+ }
29
+ return breadcrumb;
30
+ }
31
+ return breadcrumb;
32
+ };
@@ -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 = "0.0.0-development";
24
+ var packageVersion = "110.34.5";
25
25
  var halfFocusRing = 1;
26
26
  var dropOffset = '0, 8';
27
27
  var fadeIn = keyframes({
@@ -6,52 +6,52 @@ import type { OperationalAEP } from './utils';
6
6
  */
7
7
  export type ExperienceEventAttributes = CustomExperienceMetadata & {
8
8
  /**
9
- * The unique key identifying the experience being tracked.
10
- */
11
- experienceKey: string;
12
- /**
13
- * The state the experience transitioned to.
14
- */
15
- experienceStatus: ExperienceState;
16
- /**
17
- * Whether this is the first transition to this status for this experience
18
- * in the current editor session.
19
- */
20
- experienceStatusFirstSeen: boolean;
21
- /**
22
- * Timestamp when the experience started.
23
- *
24
- * Milliseconds since epoch.
9
+ * Optional action that triggered the experience, if applicable.
25
10
  */
26
- experienceStartTime: number;
11
+ experienceAction?: string;
27
12
  /**
28
13
  * Duration from experience start to current status transition.
29
14
  *
30
15
  * Measured in milliseconds.
31
16
  */
32
17
  experienceDuration: number;
18
+ /**
19
+ * Optional reason for experience end, e.g., abort or failure reason.
20
+ */
21
+ experienceEndReason?: string;
22
+ /**
23
+ * The unique key identifying the experience being tracked.
24
+ */
25
+ experienceKey: string;
33
26
  /**
34
27
  * Optional method for experience start, e.g., how the experience was initiated.
35
28
  */
36
29
  experienceStartMethod?: string;
37
30
  /**
38
- * Optional reason for experience end, e.g., abort or failure reason.
31
+ * Timestamp when the experience started.
32
+ *
33
+ * Milliseconds since epoch.
39
34
  */
40
- experienceEndReason?: string;
35
+ experienceStartTime: number;
41
36
  /**
42
- * Optional action that triggered the experience, if applicable.
37
+ * The state the experience transitioned to.
43
38
  */
44
- experienceAction?: string;
39
+ experienceStatus: ExperienceState;
40
+ /**
41
+ * Whether this is the first transition to this status for this experience
42
+ * in the current editor session.
43
+ */
44
+ experienceStatusFirstSeen: boolean;
45
45
  };
46
46
  /**
47
47
  * Event fired on every successful experience state transition.
48
48
  * Used for data analysis in Databricks.
49
49
  */
50
- type ExperienceMeasuredAEP = OperationalAEP<ACTION.EXPERIENCE_MEASURED, ACTION_SUBJECT.EDITOR, undefined, ExperienceEventAttributes>;
50
+ type ExperienceMeasuredAEP = OperationalAEP<ACTION.EXPERIENCE_MEASURED, ACTION_SUBJECT.EDITOR, string, ExperienceEventAttributes>;
51
51
  /**
52
52
  * Event fired on sampled experience state transitions (e.g., 1 in 1000).
53
53
  * Can be forwarded to Signal FX, Statsig, etc. for use in SLOs and defining experiment metrics.
54
54
  */
55
- type ExperienceSampledAEP = OperationalAEP<ACTION.EXPERIENCE_SAMPLED, ACTION_SUBJECT.EDITOR, undefined, ExperienceEventAttributes>;
55
+ type ExperienceSampledAEP = OperationalAEP<ACTION.EXPERIENCE_SAMPLED, ACTION_SUBJECT.EDITOR, string, ExperienceEventAttributes>;
56
56
  export type ExperienceEventPayload = ExperienceMeasuredAEP | ExperienceSampledAEP;
57
57
  export {};
@@ -1,9 +1,6 @@
1
1
  import { FORMAT_HEADING_1_MENU_ITEM, FORMAT_HEADING_2_MENU_ITEM, FORMAT_HEADING_3_MENU_ITEM, FORMAT_HEADING_4_MENU_ITEM, FORMAT_HEADING_5_MENU_ITEM, FORMAT_HEADING_6_MENU_ITEM, FORMAT_PARAGRAPH_MENU_ITEM, FORMAT_QUOTE_MENU_ITEM, FORMAT_EXPAND_MENU_ITEM, FORMAT_LAYOUT_MENU_ITEM, FORMAT_PANEL_MENU_ITEM, FORMAT_CODE_BLOCK_MENU_ITEM, FORMAT_BULLETED_LIST_MENU_ITEM, FORMAT_NUMBERED_LIST_MENU_ITEM, FORMAT_TASK_LIST_MENU_ITEM, COPY_BLOCK_MENU_ITEM, COPY_LINK_MENU_ITEM, MOVE_UP_MENU_ITEM, MOVE_DOWN_MENU_ITEM, DELETE_MENU_ITEM, PRIMARY_MENU_SECTION, COPY_MENU_SECTION, DELETE_MENU_SECTION, MOVE_UP_DOWN_MENU_SECTION, ADD_BLOCKS_MENU_SECTION, CREATE_SYNCED_BLOCK_MENU_ITEM, TRANSFORM_MENU_ITEM, TRANSFORM_HEADINGS_MENU_SECTION, TRANSFORM_CREATE_MENU_SECTION, TRANSFORM_SUGGESTED_MENU_SECTION, TRANSFORM_STRUCTURE_MENU_SECTION } from './key';
2
2
  import { FORMAT_MENU_ITEM } from './key-deprecated';
3
3
  export declare const FORMAT_NESTED_MENU_RANK: {
4
- [FORMAT_HEADING_1_MENU_ITEM.key]: number;
5
- [FORMAT_HEADING_2_MENU_ITEM.key]: number;
6
- [FORMAT_HEADING_3_MENU_ITEM.key]: number;
7
4
  [FORMAT_PARAGRAPH_MENU_ITEM.key]: number;
8
5
  [FORMAT_QUOTE_MENU_ITEM.key]: number;
9
6
  [FORMAT_EXPAND_MENU_ITEM.key]: number;
@@ -13,6 +10,9 @@ export declare const FORMAT_NESTED_MENU_RANK: {
13
10
  [FORMAT_BULLETED_LIST_MENU_ITEM.key]: number;
14
11
  [FORMAT_NUMBERED_LIST_MENU_ITEM.key]: number;
15
12
  [FORMAT_TASK_LIST_MENU_ITEM.key]: number;
13
+ [FORMAT_HEADING_1_MENU_ITEM.key]: number;
14
+ [FORMAT_HEADING_2_MENU_ITEM.key]: number;
15
+ [FORMAT_HEADING_3_MENU_ITEM.key]: number;
16
16
  [FORMAT_HEADING_4_MENU_ITEM.key]: number;
17
17
  [FORMAT_HEADING_5_MENU_ITEM.key]: number;
18
18
  [FORMAT_HEADING_6_MENU_ITEM.key]: number;
@@ -2,6 +2,18 @@ import type { DispatchAnalyticsEvent } from '../analytics';
2
2
  import type { ExperienceCheck } from './ExperienceCheck';
3
3
  import type { CustomExperienceMetadata } from './types';
4
4
  type ExperienceOptions = {
5
+ /**
6
+ * An optional sub identifier to further classify the specific experience action taken
7
+ *
8
+ * e.g. 'bold' 'bullet' 'insert-table'
9
+ */
10
+ action?: string;
11
+ /**
12
+ * An optional sub identifier to further classify the specific experience action subject
13
+ *
14
+ * e.g. 'selection-toolbar' 'quick-insert'
15
+ */
16
+ actionSubjectId?: string;
5
17
  /**
6
18
  * Checks used to control experience transition to various states.
7
19
  * Once the experience is in progress, these checks can automatically trigger
@@ -13,6 +25,12 @@ type ExperienceOptions = {
13
25
  * Required for tracking experienceMeasured and experienceSampled events.
14
26
  */
15
27
  dispatchAnalyticsEvent: DispatchAnalyticsEvent;
28
+ /**
29
+ * Optional global metadata to attach to all analytics events for this experience.
30
+ *
31
+ * Can be overridden by metadata provided in individual start/abort/fail/success calls.
32
+ */
33
+ metadata?: CustomExperienceMetadata;
16
34
  /**
17
35
  * Sample rate for experienceSampled events.
18
36
  * Determines how frequently we should track events for the experience based on
@@ -25,30 +43,19 @@ type ExperienceOptions = {
25
43
  * instrumentation, then the sample rate can be tuned up to a safe threshold.
26
44
  */
27
45
  sampleRate?: number;
28
- /**
29
- * Optional global metadata to attach to all analytics events for this experience.
30
- *
31
- * Can be overridden by metadata provided in individual start/abort/fail/success calls.
32
- */
33
- metadata?: CustomExperienceMetadata;
34
- /**
35
- * An optional sub identifier to further classify the specific experience action taken
36
- *
37
- * e.g. 'bold' 'bullet' 'insert-table'
38
- */
39
- action?: string;
40
46
  };
41
47
  type ExperienceStartOptions = {
48
+ forceRestart?: boolean;
42
49
  metadata?: CustomExperienceMetadata;
43
50
  method?: string;
44
- forceRestart?: boolean;
45
51
  };
46
52
  type ExperienceEndOptions = {
47
- reason?: string;
48
53
  metadata?: CustomExperienceMetadata;
54
+ reason?: string;
49
55
  };
50
56
  export declare class Experience {
51
57
  private readonly id;
58
+ private readonly actionSubjectId;
52
59
  private readonly dispatchAnalyticsEvent;
53
60
  private readonly sampleRate;
54
61
  private readonly globalMetadata;
@@ -83,13 +90,14 @@ export declare class Experience {
83
90
  /**
84
91
  * Creates a new Experience instance for tracking user experiences.
85
92
  *
86
- * @param id - Unique identifier for the experience
93
+ * @param id - Unique identifier for the experience e.g. 'toolbar-open' 'menu-action'
87
94
  * @param options - Configuration options for the experience
88
95
  * @param options.checks - Experience checks to monitor for completion
89
96
  * @param options.dispatchAnalyticsEvent - Function to dispatch analytics events
90
97
  * @param options.sampleRate - Sample rate for experienceSampled events
91
98
  * @param options.metadata - Global metadata to attach to all events
92
- * @param options.action - Optional sub identifier for the specific experience action
99
+ * @param options.action - Optional sub identifier for the specific experience action e.g. 'bold' 'insert-table'
100
+ * @param options.actionSubjectId - Optional sub identifier for the experience action subject e.g. 'selection-toolbar' 'quick-insert'
93
101
  */
94
102
  constructor(id: string, options: ExperienceOptions);
95
103
  private startCheck;
@@ -0,0 +1,8 @@
1
+ import type { Breadcrumb } from '@sentry/types';
2
+ export declare const SERIALIZABLE_ATTRIBUTES: string[];
3
+ /**
4
+ * Sanitizes messages within UI category breadcrumbs to ensure user-generated content is
5
+ * appropriately cleaned before being logged by Sentry. This helps in maintaining
6
+ * privacy and security by preventing sensitive data exposure.
7
+ */
8
+ export declare const normaliseSentryBreadcrumbs: (breadcrumb: Breadcrumb) => Breadcrumb;
@@ -6,52 +6,52 @@ import type { OperationalAEP } from './utils';
6
6
  */
7
7
  export type ExperienceEventAttributes = CustomExperienceMetadata & {
8
8
  /**
9
- * The unique key identifying the experience being tracked.
10
- */
11
- experienceKey: string;
12
- /**
13
- * The state the experience transitioned to.
14
- */
15
- experienceStatus: ExperienceState;
16
- /**
17
- * Whether this is the first transition to this status for this experience
18
- * in the current editor session.
19
- */
20
- experienceStatusFirstSeen: boolean;
21
- /**
22
- * Timestamp when the experience started.
23
- *
24
- * Milliseconds since epoch.
9
+ * Optional action that triggered the experience, if applicable.
25
10
  */
26
- experienceStartTime: number;
11
+ experienceAction?: string;
27
12
  /**
28
13
  * Duration from experience start to current status transition.
29
14
  *
30
15
  * Measured in milliseconds.
31
16
  */
32
17
  experienceDuration: number;
18
+ /**
19
+ * Optional reason for experience end, e.g., abort or failure reason.
20
+ */
21
+ experienceEndReason?: string;
22
+ /**
23
+ * The unique key identifying the experience being tracked.
24
+ */
25
+ experienceKey: string;
33
26
  /**
34
27
  * Optional method for experience start, e.g., how the experience was initiated.
35
28
  */
36
29
  experienceStartMethod?: string;
37
30
  /**
38
- * Optional reason for experience end, e.g., abort or failure reason.
31
+ * Timestamp when the experience started.
32
+ *
33
+ * Milliseconds since epoch.
39
34
  */
40
- experienceEndReason?: string;
35
+ experienceStartTime: number;
41
36
  /**
42
- * Optional action that triggered the experience, if applicable.
37
+ * The state the experience transitioned to.
43
38
  */
44
- experienceAction?: string;
39
+ experienceStatus: ExperienceState;
40
+ /**
41
+ * Whether this is the first transition to this status for this experience
42
+ * in the current editor session.
43
+ */
44
+ experienceStatusFirstSeen: boolean;
45
45
  };
46
46
  /**
47
47
  * Event fired on every successful experience state transition.
48
48
  * Used for data analysis in Databricks.
49
49
  */
50
- type ExperienceMeasuredAEP = OperationalAEP<ACTION.EXPERIENCE_MEASURED, ACTION_SUBJECT.EDITOR, undefined, ExperienceEventAttributes>;
50
+ type ExperienceMeasuredAEP = OperationalAEP<ACTION.EXPERIENCE_MEASURED, ACTION_SUBJECT.EDITOR, string, ExperienceEventAttributes>;
51
51
  /**
52
52
  * Event fired on sampled experience state transitions (e.g., 1 in 1000).
53
53
  * Can be forwarded to Signal FX, Statsig, etc. for use in SLOs and defining experiment metrics.
54
54
  */
55
- type ExperienceSampledAEP = OperationalAEP<ACTION.EXPERIENCE_SAMPLED, ACTION_SUBJECT.EDITOR, undefined, ExperienceEventAttributes>;
55
+ type ExperienceSampledAEP = OperationalAEP<ACTION.EXPERIENCE_SAMPLED, ACTION_SUBJECT.EDITOR, string, ExperienceEventAttributes>;
56
56
  export type ExperienceEventPayload = ExperienceMeasuredAEP | ExperienceSampledAEP;
57
57
  export {};
@@ -1,9 +1,6 @@
1
1
  import { FORMAT_HEADING_1_MENU_ITEM, FORMAT_HEADING_2_MENU_ITEM, FORMAT_HEADING_3_MENU_ITEM, FORMAT_HEADING_4_MENU_ITEM, FORMAT_HEADING_5_MENU_ITEM, FORMAT_HEADING_6_MENU_ITEM, FORMAT_PARAGRAPH_MENU_ITEM, FORMAT_QUOTE_MENU_ITEM, FORMAT_EXPAND_MENU_ITEM, FORMAT_LAYOUT_MENU_ITEM, FORMAT_PANEL_MENU_ITEM, FORMAT_CODE_BLOCK_MENU_ITEM, FORMAT_BULLETED_LIST_MENU_ITEM, FORMAT_NUMBERED_LIST_MENU_ITEM, FORMAT_TASK_LIST_MENU_ITEM, COPY_BLOCK_MENU_ITEM, COPY_LINK_MENU_ITEM, MOVE_UP_MENU_ITEM, MOVE_DOWN_MENU_ITEM, DELETE_MENU_ITEM, PRIMARY_MENU_SECTION, COPY_MENU_SECTION, DELETE_MENU_SECTION, MOVE_UP_DOWN_MENU_SECTION, ADD_BLOCKS_MENU_SECTION, CREATE_SYNCED_BLOCK_MENU_ITEM, TRANSFORM_MENU_ITEM, TRANSFORM_HEADINGS_MENU_SECTION, TRANSFORM_CREATE_MENU_SECTION, TRANSFORM_SUGGESTED_MENU_SECTION, TRANSFORM_STRUCTURE_MENU_SECTION } from './key';
2
2
  import { FORMAT_MENU_ITEM } from './key-deprecated';
3
3
  export declare const FORMAT_NESTED_MENU_RANK: {
4
- [FORMAT_HEADING_1_MENU_ITEM.key]: number;
5
- [FORMAT_HEADING_2_MENU_ITEM.key]: number;
6
- [FORMAT_HEADING_3_MENU_ITEM.key]: number;
7
4
  [FORMAT_PARAGRAPH_MENU_ITEM.key]: number;
8
5
  [FORMAT_QUOTE_MENU_ITEM.key]: number;
9
6
  [FORMAT_EXPAND_MENU_ITEM.key]: number;
@@ -13,6 +10,9 @@ export declare const FORMAT_NESTED_MENU_RANK: {
13
10
  [FORMAT_BULLETED_LIST_MENU_ITEM.key]: number;
14
11
  [FORMAT_NUMBERED_LIST_MENU_ITEM.key]: number;
15
12
  [FORMAT_TASK_LIST_MENU_ITEM.key]: number;
13
+ [FORMAT_HEADING_1_MENU_ITEM.key]: number;
14
+ [FORMAT_HEADING_2_MENU_ITEM.key]: number;
15
+ [FORMAT_HEADING_3_MENU_ITEM.key]: number;
16
16
  [FORMAT_HEADING_4_MENU_ITEM.key]: number;
17
17
  [FORMAT_HEADING_5_MENU_ITEM.key]: number;
18
18
  [FORMAT_HEADING_6_MENU_ITEM.key]: number;
@@ -2,6 +2,18 @@ import type { DispatchAnalyticsEvent } from '../analytics';
2
2
  import type { ExperienceCheck } from './ExperienceCheck';
3
3
  import type { CustomExperienceMetadata } from './types';
4
4
  type ExperienceOptions = {
5
+ /**
6
+ * An optional sub identifier to further classify the specific experience action taken
7
+ *
8
+ * e.g. 'bold' 'bullet' 'insert-table'
9
+ */
10
+ action?: string;
11
+ /**
12
+ * An optional sub identifier to further classify the specific experience action subject
13
+ *
14
+ * e.g. 'selection-toolbar' 'quick-insert'
15
+ */
16
+ actionSubjectId?: string;
5
17
  /**
6
18
  * Checks used to control experience transition to various states.
7
19
  * Once the experience is in progress, these checks can automatically trigger
@@ -13,6 +25,12 @@ type ExperienceOptions = {
13
25
  * Required for tracking experienceMeasured and experienceSampled events.
14
26
  */
15
27
  dispatchAnalyticsEvent: DispatchAnalyticsEvent;
28
+ /**
29
+ * Optional global metadata to attach to all analytics events for this experience.
30
+ *
31
+ * Can be overridden by metadata provided in individual start/abort/fail/success calls.
32
+ */
33
+ metadata?: CustomExperienceMetadata;
16
34
  /**
17
35
  * Sample rate for experienceSampled events.
18
36
  * Determines how frequently we should track events for the experience based on
@@ -25,30 +43,19 @@ type ExperienceOptions = {
25
43
  * instrumentation, then the sample rate can be tuned up to a safe threshold.
26
44
  */
27
45
  sampleRate?: number;
28
- /**
29
- * Optional global metadata to attach to all analytics events for this experience.
30
- *
31
- * Can be overridden by metadata provided in individual start/abort/fail/success calls.
32
- */
33
- metadata?: CustomExperienceMetadata;
34
- /**
35
- * An optional sub identifier to further classify the specific experience action taken
36
- *
37
- * e.g. 'bold' 'bullet' 'insert-table'
38
- */
39
- action?: string;
40
46
  };
41
47
  type ExperienceStartOptions = {
48
+ forceRestart?: boolean;
42
49
  metadata?: CustomExperienceMetadata;
43
50
  method?: string;
44
- forceRestart?: boolean;
45
51
  };
46
52
  type ExperienceEndOptions = {
47
- reason?: string;
48
53
  metadata?: CustomExperienceMetadata;
54
+ reason?: string;
49
55
  };
50
56
  export declare class Experience {
51
57
  private readonly id;
58
+ private readonly actionSubjectId;
52
59
  private readonly dispatchAnalyticsEvent;
53
60
  private readonly sampleRate;
54
61
  private readonly globalMetadata;
@@ -83,13 +90,14 @@ export declare class Experience {
83
90
  /**
84
91
  * Creates a new Experience instance for tracking user experiences.
85
92
  *
86
- * @param id - Unique identifier for the experience
93
+ * @param id - Unique identifier for the experience e.g. 'toolbar-open' 'menu-action'
87
94
  * @param options - Configuration options for the experience
88
95
  * @param options.checks - Experience checks to monitor for completion
89
96
  * @param options.dispatchAnalyticsEvent - Function to dispatch analytics events
90
97
  * @param options.sampleRate - Sample rate for experienceSampled events
91
98
  * @param options.metadata - Global metadata to attach to all events
92
- * @param options.action - Optional sub identifier for the specific experience action
99
+ * @param options.action - Optional sub identifier for the specific experience action e.g. 'bold' 'insert-table'
100
+ * @param options.actionSubjectId - Optional sub identifier for the experience action subject e.g. 'selection-toolbar' 'quick-insert'
93
101
  */
94
102
  constructor(id: string, options: ExperienceOptions);
95
103
  private startCheck;
@@ -0,0 +1,8 @@
1
+ import type { Breadcrumb } from '@sentry/types';
2
+ export declare const SERIALIZABLE_ATTRIBUTES: string[];
3
+ /**
4
+ * Sanitizes messages within UI category breadcrumbs to ensure user-generated content is
5
+ * appropriately cleaned before being logged by Sentry. This helps in maintaining
6
+ * privacy and security by preventing sensitive data exposure.
7
+ */
8
+ export declare const normaliseSentryBreadcrumbs: (breadcrumb: Breadcrumb) => Breadcrumb;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-common",
3
- "version": "110.34.4",
3
+ "version": "110.34.6",
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/"
@@ -75,14 +75,14 @@
75
75
  "@atlaskit/prosemirror-history": "^0.2.0",
76
76
  "@atlaskit/react-ufo": "^4.15.0",
77
77
  "@atlaskit/section-message": "^8.9.0",
78
- "@atlaskit/smart-card": "^43.10.0",
78
+ "@atlaskit/smart-card": "^43.11.0",
79
79
  "@atlaskit/smart-user-picker": "^8.4.0",
80
80
  "@atlaskit/spinner": "^19.0.0",
81
81
  "@atlaskit/status": "^3.0.0",
82
82
  "@atlaskit/task-decision": "^19.2.0",
83
83
  "@atlaskit/textfield": "^8.1.0",
84
84
  "@atlaskit/theme": "^21.0.0",
85
- "@atlaskit/tmp-editor-statsig": "^13.42.0",
85
+ "@atlaskit/tmp-editor-statsig": "^13.43.0",
86
86
  "@atlaskit/tokens": "^8.3.0",
87
87
  "@atlaskit/tooltip": "^20.10.0",
88
88
  "@atlaskit/ufo": "^0.4.0",
@@ -263,6 +263,9 @@
263
263
  },
264
264
  "platform_editor_transform_invalid_media_width": {
265
265
  "type": "boolean"
266
+ },
267
+ "platform_editor_sentry_breadcrumbs": {
268
+ "type": "boolean"
266
269
  }
267
270
  }
268
271
  }