@atlaskit/react-ufo 4.12.2 → 4.12.4

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 (20) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/cjs/create-payload/utils/get-browser-metadata.js +9 -0
  3. package/dist/cjs/vc/vc-observer/observers/non-visual-styles/is-dnd-style-mutation.js +0 -4
  4. package/dist/cjs/vc/vc-observer/observers/ssr-placeholders/index.js +53 -3
  5. package/dist/cjs/vc/vc-observer/observers/ssr-placeholders/ssr-scripts/collectSSRPlaceholderDimensions.js +54 -4
  6. package/dist/es2019/create-payload/utils/get-browser-metadata.js +9 -0
  7. package/dist/es2019/vc/vc-observer/observers/non-visual-styles/is-dnd-style-mutation.js +0 -4
  8. package/dist/es2019/vc/vc-observer/observers/ssr-placeholders/index.js +51 -3
  9. package/dist/es2019/vc/vc-observer/observers/ssr-placeholders/ssr-scripts/collectSSRPlaceholderDimensions.js +55 -4
  10. package/dist/esm/create-payload/utils/get-browser-metadata.js +9 -0
  11. package/dist/esm/vc/vc-observer/observers/non-visual-styles/is-dnd-style-mutation.js +0 -4
  12. package/dist/esm/vc/vc-observer/observers/ssr-placeholders/index.js +53 -3
  13. package/dist/esm/vc/vc-observer/observers/ssr-placeholders/ssr-scripts/collectSSRPlaceholderDimensions.js +55 -4
  14. package/dist/types/common/react-ufo-payload-schema.d.ts +1 -0
  15. package/dist/types/create-payload/utils/get-browser-metadata.d.ts +1 -0
  16. package/dist/types/vc/vc-observer/observers/ssr-placeholders/index.d.ts +5 -0
  17. package/dist/types-ts4.5/common/react-ufo-payload-schema.d.ts +1 -0
  18. package/dist/types-ts4.5/create-payload/utils/get-browser-metadata.d.ts +1 -0
  19. package/dist/types-ts4.5/vc/vc-observer/observers/ssr-placeholders/index.d.ts +5 -0
  20. package/package.json +8 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @atlaskit/ufo-interaction-ignore
2
2
 
3
+ ## 4.12.4
4
+
5
+ ### Patch Changes
6
+
7
+ - [`189df14145d27`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/189df14145d27) -
8
+ Handle elements that are both display: contents and SSR placeholder replacement
9
+
10
+ ## 4.12.3
11
+
12
+ ### Patch Changes
13
+
14
+ - [`5f70b8e74f5f3`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/5f70b8e74f5f3) -
15
+ tidy up feature flag platform_editor_tables_scaling_css
16
+
3
17
  ## 4.12.2
4
18
 
5
19
  ### Patch Changes
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.default = getBrowserMetadata;
8
8
  exports.getBrowserMetadataToLegacyFormat = getBrowserMetadataToLegacyFormat;
9
9
  var _bowserUltralight = _interopRequireDefault(require("bowser-ultralight"));
10
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
10
11
  function getBrowserMetadata() {
11
12
  var data = {
12
13
  time: {
@@ -48,6 +49,9 @@ function getBrowserMetadata() {
48
49
  downlink: navigator.connection.downlink
49
50
  };
50
51
  }
52
+ if (typeof navigator !== 'undefined' && (0, _platformFeatureFlags.fg)('react_ufo_add_webdriver_info')) {
53
+ data.webdriver = Boolean(navigator.webdriver);
54
+ }
51
55
  return data;
52
56
  }
53
57
 
@@ -67,6 +71,11 @@ function getBrowserMetadataToLegacyFormat() {
67
71
  legacyFormat['event:browser:version'] = metadata.browser.version;
68
72
  }
69
73
 
74
+ // Webdriver data
75
+ if (metadata.webdriver !== undefined) {
76
+ legacyFormat['event:browser:webdriver'] = metadata.webdriver;
77
+ }
78
+
70
79
  // Device data
71
80
  if (metadata.device) {
72
81
  if (metadata.device.cpus !== undefined) {
@@ -5,7 +5,6 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
8
- var _expVal = require("../../../expVal");
9
8
  function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
10
9
  function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
11
10
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
@@ -50,9 +49,6 @@ function isDnDStyleMutation(_ref) {
50
49
  if (!(0, _platformFeatureFlags.fg)('platform_editor_exclude_dnd_anchor_name_from_ttvc')) {
51
50
  return false;
52
51
  }
53
- if (!(0, _expVal.expVal)('platform_editor_tables_scaling_css', 'excludeDnD', false)) {
54
- return false;
55
- }
56
52
  if (!(target instanceof Element)) {
57
53
  return false;
58
54
  }
@@ -8,6 +8,7 @@ exports.SSRPlaceholderHandlers = 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");
11
12
  var ANCESTOR_LOOKUP_LIMIT = 10;
12
13
  var PAGE_LAYOUT_ID = 'page-layout.root';
13
14
  var SSRPlaceholderHandlers = exports.SSRPlaceholderHandlers = /*#__PURE__*/function () {
@@ -66,7 +67,7 @@ var SSRPlaceholderHandlers = exports.SSRPlaceholderHandlers = /*#__PURE__*/funct
66
67
  _resolve(hasSameSizePosition);
67
68
  } else {
68
69
  requestAnimationFrame(function () {
69
- var targetRect = target.getBoundingClientRect();
70
+ var targetRect = _this.getEffectiveBoundingRect(target);
70
71
  var hasSameSizePosition = _this.hasSameSizePosition(rect, targetRect);
71
72
  _resolve(hasSameSizePosition);
72
73
  });
@@ -85,7 +86,7 @@ var SSRPlaceholderHandlers = exports.SSRPlaceholderHandlers = /*#__PURE__*/funct
85
86
  _resolve2(_hasSameSizePosition);
86
87
  } else {
87
88
  requestAnimationFrame(function () {
88
- var targetRect = target.getBoundingClientRect();
89
+ var targetRect = _this.getEffectiveBoundingRect(target);
89
90
  var hasSameSizePosition = _this.hasSameSizePosition(_rect, targetRect);
90
91
  _resolve2(hasSameSizePosition);
91
92
  });
@@ -243,7 +244,7 @@ var SSRPlaceholderHandlers = exports.SSRPlaceholderHandlers = /*#__PURE__*/funct
243
244
  if (!placeholderRects) {
244
245
  return false;
245
246
  }
246
- return this.hasSameSizePosition(placeholderRects, el.getBoundingClientRect());
247
+ return this.hasSameSizePosition(placeholderRects, this.getEffectiveBoundingRect(el));
247
248
  }
248
249
  }, {
249
250
  key: "getSize",
@@ -282,6 +283,55 @@ var SSRPlaceholderHandlers = exports.SSRPlaceholderHandlers = /*#__PURE__*/funct
282
283
  var verticalCheck = Math.abs(rect.y - boundingClientRect.y) < this.EQUALITY_THRESHOLD && Math.abs(rect.height - boundingClientRect.height) < this.EQUALITY_THRESHOLD;
283
284
  return horizontalCheck && verticalCheck || false;
284
285
  }
286
+
287
+ /**
288
+ * Gets the effective bounding rectangle for an element, handling display: contents elements
289
+ * by collecting dimensions from their children instead
290
+ */
291
+ }, {
292
+ key: "getEffectiveBoundingRect",
293
+ value: function getEffectiveBoundingRect(el) {
294
+ var enableDisplayContentsSupport = (0, _platformFeatureFlags.fg)('platform_ufo_ssr_placeholders_for_display_contents');
295
+
296
+ // Only handle display: contents if feature flag is enabled
297
+ if (enableDisplayContentsSupport) {
298
+ var computedStyle = window.getComputedStyle(el);
299
+
300
+ // If element has display: contents, collect bounding rect from children
301
+ if (computedStyle.display === 'contents') {
302
+ var children = Array.from(el.children);
303
+ if (children.length === 0) {
304
+ // No children, return zero rect
305
+ return new DOMRect(0, 0, 0, 0);
306
+ }
307
+
308
+ // Calculate union of all children's bounding rects
309
+ var minX = Infinity;
310
+ var minY = Infinity;
311
+ var maxX = -Infinity;
312
+ var maxY = -Infinity;
313
+ children.forEach(function (child) {
314
+ var childRect = child.getBoundingClientRect();
315
+ // Skip children with zero dimensions (likely also display: contents)
316
+ if (childRect.width > 0 || childRect.height > 0) {
317
+ minX = Math.min(minX, childRect.left);
318
+ minY = Math.min(minY, childRect.top);
319
+ maxX = Math.max(maxX, childRect.right);
320
+ maxY = Math.max(maxY, childRect.bottom);
321
+ }
322
+ });
323
+
324
+ // If no children with dimensions found, return zero rect
325
+ if (minX === Infinity) {
326
+ return new DOMRect(0, 0, 0, 0);
327
+ }
328
+ return new DOMRect(minX, minY, maxX - minX, maxY - minY);
329
+ }
330
+ }
331
+
332
+ // Normal element or feature flag disabled, return its bounding rect
333
+ return el.getBoundingClientRect();
334
+ }
285
335
  }, {
286
336
  key: "isDummyRect",
287
337
  value: function isDummyRect(rect) {
@@ -4,26 +4,76 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.collectSSRPlaceholderDimensions = collectSSRPlaceholderDimensions;
7
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
7
8
  // lightweight script to scan the SSR response and collect all elements with data-ssr-placeholder attribute
8
9
  // and save their size/positions in a map __SSR_PLACEHOLDERS_DIMENSIONS__ on the Window object. Each placeholderId is
9
10
  // unique and maps to its corresponding elements bounding client rectangle dimensions.
10
11
  function collectSSRPlaceholderDimensions(document, window) {
11
12
  var enablePageLayoutPlaceholder = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
13
+ var enableDisplayContentsSupport = (0, _platformFeatureFlags.fg)('platform_ufo_ssr_placeholders_for_display_contents');
12
14
  var ssrPlaceholders = document === null || document === void 0 ? void 0 : document.querySelectorAll('[data-ssr-placeholder]');
13
15
  ssrPlaceholders.forEach(function (elem) {
14
16
  var placeholderId = elem.getAttribute('data-ssr-placeholder');
15
- var boundingClient = elem.getBoundingClientRect();
16
17
  if (placeholderId) {
17
18
  window.__SSR_PLACEHOLDERS_DIMENSIONS__ = window.__SSR_PLACEHOLDERS_DIMENSIONS__ || {};
18
- window.__SSR_PLACEHOLDERS_DIMENSIONS__[placeholderId] = boundingClient;
19
+ if (enableDisplayContentsSupport) {
20
+ window.__SSR_PLACEHOLDERS_DIMENSIONS__[placeholderId] = getEffectiveBoundingRect(elem, window);
21
+ } else {
22
+ window.__SSR_PLACEHOLDERS_DIMENSIONS__[placeholderId] = elem.getBoundingClientRect();
23
+ }
19
24
  }
20
25
  });
21
26
  if (enablePageLayoutPlaceholder) {
22
27
  var pageLayoutRoot = document === null || document === void 0 ? void 0 : document.getElementById('unsafe-design-system-page-layout-root');
23
28
  if (pageLayoutRoot) {
24
- var boundingClient = pageLayoutRoot.getBoundingClientRect();
25
29
  window.__SSR_PLACEHOLDERS_DIMENSIONS__ = window.__SSR_PLACEHOLDERS_DIMENSIONS__ || {};
26
- window.__SSR_PLACEHOLDERS_DIMENSIONS__['page-layout.root'] = boundingClient;
30
+ if (enableDisplayContentsSupport) {
31
+ window.__SSR_PLACEHOLDERS_DIMENSIONS__['page-layout.root'] = getEffectiveBoundingRect(pageLayoutRoot, window);
32
+ } else {
33
+ window.__SSR_PLACEHOLDERS_DIMENSIONS__['page-layout.root'] = pageLayoutRoot.getBoundingClientRect();
34
+ }
27
35
  }
28
36
  }
37
+ }
38
+
39
+ /**
40
+ * Gets the effective bounding rectangle for an element, handling display: contents elements
41
+ * by collecting dimensions from their children instead
42
+ */
43
+ function getEffectiveBoundingRect(elem, window) {
44
+ var computedStyle = window.getComputedStyle(elem);
45
+
46
+ // If element has display: contents, collect bounding rect from children
47
+ if (computedStyle.display === 'contents') {
48
+ var children = Array.from(elem.children);
49
+ if (children.length === 0) {
50
+ // No children, return zero rect
51
+ return new DOMRect(0, 0, 0, 0);
52
+ }
53
+
54
+ // Calculate union of all children's bounding rects
55
+ var minX = Infinity;
56
+ var minY = Infinity;
57
+ var maxX = -Infinity;
58
+ var maxY = -Infinity;
59
+ children.forEach(function (child) {
60
+ var childRect = child.getBoundingClientRect();
61
+ // Skip children with zero dimensions (likely also display: contents)
62
+ if (childRect.width > 0 || childRect.height > 0) {
63
+ minX = Math.min(minX, childRect.left);
64
+ minY = Math.min(minY, childRect.top);
65
+ maxX = Math.max(maxX, childRect.right);
66
+ maxY = Math.max(maxY, childRect.bottom);
67
+ }
68
+ });
69
+
70
+ // If no children with dimensions found, return zero rect
71
+ if (minX === Infinity) {
72
+ return new DOMRect(0, 0, 0, 0);
73
+ }
74
+ return new DOMRect(minX, minY, maxX - minX, maxY - minY);
75
+ }
76
+
77
+ // Normal element, return its bounding rect
78
+ return elem.getBoundingClientRect();
29
79
  }
@@ -1,4 +1,5 @@
1
1
  import Bowser from 'bowser-ultralight';
2
+ import { fg } from '@atlaskit/platform-feature-flags';
2
3
  export default function getBrowserMetadata() {
3
4
  const data = {
4
5
  time: {
@@ -40,6 +41,9 @@ export default function getBrowserMetadata() {
40
41
  downlink: navigator.connection.downlink
41
42
  };
42
43
  }
44
+ if (typeof navigator !== 'undefined' && fg('react_ufo_add_webdriver_info')) {
45
+ data.webdriver = Boolean(navigator.webdriver);
46
+ }
43
47
  return data;
44
48
  }
45
49
 
@@ -59,6 +63,11 @@ export function getBrowserMetadataToLegacyFormat() {
59
63
  legacyFormat['event:browser:version'] = metadata.browser.version;
60
64
  }
61
65
 
66
+ // Webdriver data
67
+ if (metadata.webdriver !== undefined) {
68
+ legacyFormat['event:browser:webdriver'] = metadata.webdriver;
69
+ }
70
+
62
71
  // Device data
63
72
  if (metadata.device) {
64
73
  if (metadata.device.cpus !== undefined) {
@@ -1,5 +1,4 @@
1
1
  import { fg } from '@atlaskit/platform-feature-flags';
2
- import { expVal } from '../../../expVal';
3
2
  const isDnDStyleChange = style => {
4
3
  return style.startsWith('anchor-name: --node-anchor');
5
4
  };
@@ -33,9 +32,6 @@ function isDnDStyleMutation({
33
32
  if (!fg('platform_editor_exclude_dnd_anchor_name_from_ttvc')) {
34
33
  return false;
35
34
  }
36
- if (!expVal('platform_editor_tables_scaling_css', 'excludeDnD', false)) {
37
- return false;
38
- }
39
35
  if (!(target instanceof Element)) {
40
36
  return false;
41
37
  }
@@ -1,4 +1,5 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import { fg } from '@atlaskit/platform-feature-flags';
2
3
  const ANCESTOR_LOOKUP_LIMIT = 10;
3
4
  const PAGE_LAYOUT_ID = 'page-layout.root';
4
5
  export class SSRPlaceholderHandlers {
@@ -56,7 +57,7 @@ export class SSRPlaceholderHandlers {
56
57
  resolve(hasSameSizePosition);
57
58
  } else {
58
59
  requestAnimationFrame(() => {
59
- const targetRect = target.getBoundingClientRect();
60
+ const targetRect = this.getEffectiveBoundingRect(target);
60
61
  const hasSameSizePosition = this.hasSameSizePosition(rect, targetRect);
61
62
  resolve(hasSameSizePosition);
62
63
  });
@@ -75,7 +76,7 @@ export class SSRPlaceholderHandlers {
75
76
  resolve(hasSameSizePosition);
76
77
  } else {
77
78
  requestAnimationFrame(() => {
78
- const targetRect = target.getBoundingClientRect();
79
+ const targetRect = this.getEffectiveBoundingRect(target);
79
80
  const hasSameSizePosition = this.hasSameSizePosition(rect, targetRect);
80
81
  resolve(hasSameSizePosition);
81
82
  });
@@ -209,7 +210,7 @@ export class SSRPlaceholderHandlers {
209
210
  if (!placeholderRects) {
210
211
  return false;
211
212
  }
212
- return this.hasSameSizePosition(placeholderRects, el.getBoundingClientRect());
213
+ return this.hasSameSizePosition(placeholderRects, this.getEffectiveBoundingRect(el));
213
214
  }
214
215
  getSize(el) {
215
216
  return new Promise(resolve => {
@@ -240,6 +241,53 @@ export class SSRPlaceholderHandlers {
240
241
  const verticalCheck = Math.abs(rect.y - boundingClientRect.y) < this.EQUALITY_THRESHOLD && Math.abs(rect.height - boundingClientRect.height) < this.EQUALITY_THRESHOLD;
241
242
  return horizontalCheck && verticalCheck || false;
242
243
  }
244
+
245
+ /**
246
+ * Gets the effective bounding rectangle for an element, handling display: contents elements
247
+ * by collecting dimensions from their children instead
248
+ */
249
+ getEffectiveBoundingRect(el) {
250
+ const enableDisplayContentsSupport = fg('platform_ufo_ssr_placeholders_for_display_contents');
251
+
252
+ // Only handle display: contents if feature flag is enabled
253
+ if (enableDisplayContentsSupport) {
254
+ const computedStyle = window.getComputedStyle(el);
255
+
256
+ // If element has display: contents, collect bounding rect from children
257
+ if (computedStyle.display === 'contents') {
258
+ const children = Array.from(el.children);
259
+ if (children.length === 0) {
260
+ // No children, return zero rect
261
+ return new DOMRect(0, 0, 0, 0);
262
+ }
263
+
264
+ // Calculate union of all children's bounding rects
265
+ let minX = Infinity;
266
+ let minY = Infinity;
267
+ let maxX = -Infinity;
268
+ let maxY = -Infinity;
269
+ children.forEach(child => {
270
+ const childRect = child.getBoundingClientRect();
271
+ // Skip children with zero dimensions (likely also display: contents)
272
+ if (childRect.width > 0 || childRect.height > 0) {
273
+ minX = Math.min(minX, childRect.left);
274
+ minY = Math.min(minY, childRect.top);
275
+ maxX = Math.max(maxX, childRect.right);
276
+ maxY = Math.max(maxY, childRect.bottom);
277
+ }
278
+ });
279
+
280
+ // If no children with dimensions found, return zero rect
281
+ if (minX === Infinity) {
282
+ return new DOMRect(0, 0, 0, 0);
283
+ }
284
+ return new DOMRect(minX, minY, maxX - minX, maxY - minY);
285
+ }
286
+ }
287
+
288
+ // Normal element or feature flag disabled, return its bounding rect
289
+ return el.getBoundingClientRect();
290
+ }
243
291
  isDummyRect(rect) {
244
292
  return rect && rect.width < 0 && rect.height < 0 || false;
245
293
  }
@@ -1,22 +1,73 @@
1
+ import { fg } from '@atlaskit/platform-feature-flags';
2
+
1
3
  // lightweight script to scan the SSR response and collect all elements with data-ssr-placeholder attribute
2
4
  // and save their size/positions in a map __SSR_PLACEHOLDERS_DIMENSIONS__ on the Window object. Each placeholderId is
3
5
  // unique and maps to its corresponding elements bounding client rectangle dimensions.
4
6
  export function collectSSRPlaceholderDimensions(document, window, enablePageLayoutPlaceholder = false) {
7
+ const enableDisplayContentsSupport = fg('platform_ufo_ssr_placeholders_for_display_contents');
5
8
  const ssrPlaceholders = document === null || document === void 0 ? void 0 : document.querySelectorAll('[data-ssr-placeholder]');
6
9
  ssrPlaceholders.forEach(elem => {
7
10
  const placeholderId = elem.getAttribute('data-ssr-placeholder');
8
- const boundingClient = elem.getBoundingClientRect();
9
11
  if (placeholderId) {
10
12
  window.__SSR_PLACEHOLDERS_DIMENSIONS__ = window.__SSR_PLACEHOLDERS_DIMENSIONS__ || {};
11
- window.__SSR_PLACEHOLDERS_DIMENSIONS__[placeholderId] = boundingClient;
13
+ if (enableDisplayContentsSupport) {
14
+ window.__SSR_PLACEHOLDERS_DIMENSIONS__[placeholderId] = getEffectiveBoundingRect(elem, window);
15
+ } else {
16
+ window.__SSR_PLACEHOLDERS_DIMENSIONS__[placeholderId] = elem.getBoundingClientRect();
17
+ }
12
18
  }
13
19
  });
14
20
  if (enablePageLayoutPlaceholder) {
15
21
  const pageLayoutRoot = document === null || document === void 0 ? void 0 : document.getElementById('unsafe-design-system-page-layout-root');
16
22
  if (pageLayoutRoot) {
17
- const boundingClient = pageLayoutRoot.getBoundingClientRect();
18
23
  window.__SSR_PLACEHOLDERS_DIMENSIONS__ = window.__SSR_PLACEHOLDERS_DIMENSIONS__ || {};
19
- window.__SSR_PLACEHOLDERS_DIMENSIONS__['page-layout.root'] = boundingClient;
24
+ if (enableDisplayContentsSupport) {
25
+ window.__SSR_PLACEHOLDERS_DIMENSIONS__['page-layout.root'] = getEffectiveBoundingRect(pageLayoutRoot, window);
26
+ } else {
27
+ window.__SSR_PLACEHOLDERS_DIMENSIONS__['page-layout.root'] = pageLayoutRoot.getBoundingClientRect();
28
+ }
20
29
  }
21
30
  }
31
+ }
32
+
33
+ /**
34
+ * Gets the effective bounding rectangle for an element, handling display: contents elements
35
+ * by collecting dimensions from their children instead
36
+ */
37
+ function getEffectiveBoundingRect(elem, window) {
38
+ const computedStyle = window.getComputedStyle(elem);
39
+
40
+ // If element has display: contents, collect bounding rect from children
41
+ if (computedStyle.display === 'contents') {
42
+ const children = Array.from(elem.children);
43
+ if (children.length === 0) {
44
+ // No children, return zero rect
45
+ return new DOMRect(0, 0, 0, 0);
46
+ }
47
+
48
+ // Calculate union of all children's bounding rects
49
+ let minX = Infinity;
50
+ let minY = Infinity;
51
+ let maxX = -Infinity;
52
+ let maxY = -Infinity;
53
+ children.forEach(child => {
54
+ const childRect = child.getBoundingClientRect();
55
+ // Skip children with zero dimensions (likely also display: contents)
56
+ if (childRect.width > 0 || childRect.height > 0) {
57
+ minX = Math.min(minX, childRect.left);
58
+ minY = Math.min(minY, childRect.top);
59
+ maxX = Math.max(maxX, childRect.right);
60
+ maxY = Math.max(maxY, childRect.bottom);
61
+ }
62
+ });
63
+
64
+ // If no children with dimensions found, return zero rect
65
+ if (minX === Infinity) {
66
+ return new DOMRect(0, 0, 0, 0);
67
+ }
68
+ return new DOMRect(minX, minY, maxX - minX, maxY - minY);
69
+ }
70
+
71
+ // Normal element, return its bounding rect
72
+ return elem.getBoundingClientRect();
22
73
  }
@@ -1,4 +1,5 @@
1
1
  import Bowser from 'bowser-ultralight';
2
+ import { fg } from '@atlaskit/platform-feature-flags';
2
3
  export default function getBrowserMetadata() {
3
4
  var data = {
4
5
  time: {
@@ -40,6 +41,9 @@ export default function getBrowserMetadata() {
40
41
  downlink: navigator.connection.downlink
41
42
  };
42
43
  }
44
+ if (typeof navigator !== 'undefined' && fg('react_ufo_add_webdriver_info')) {
45
+ data.webdriver = Boolean(navigator.webdriver);
46
+ }
43
47
  return data;
44
48
  }
45
49
 
@@ -59,6 +63,11 @@ export function getBrowserMetadataToLegacyFormat() {
59
63
  legacyFormat['event:browser:version'] = metadata.browser.version;
60
64
  }
61
65
 
66
+ // Webdriver data
67
+ if (metadata.webdriver !== undefined) {
68
+ legacyFormat['event:browser:webdriver'] = metadata.webdriver;
69
+ }
70
+
62
71
  // Device data
63
72
  if (metadata.device) {
64
73
  if (metadata.device.cpus !== undefined) {
@@ -2,7 +2,6 @@ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol
2
2
  function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
3
3
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
4
4
  import { fg } from '@atlaskit/platform-feature-flags';
5
- import { expVal } from '../../../expVal';
6
5
  var isDnDStyleChange = function isDnDStyleChange(style) {
7
6
  return style.startsWith('anchor-name: --node-anchor');
8
7
  };
@@ -44,9 +43,6 @@ function isDnDStyleMutation(_ref) {
44
43
  if (!fg('platform_editor_exclude_dnd_anchor_name_from_ttvc')) {
45
44
  return false;
46
45
  }
47
- if (!expVal('platform_editor_tables_scaling_css', 'excludeDnD', false)) {
48
- return false;
49
- }
50
46
  if (!(target instanceof Element)) {
51
47
  return false;
52
48
  }
@@ -1,6 +1,7 @@
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';
4
5
  var ANCESTOR_LOOKUP_LIMIT = 10;
5
6
  var PAGE_LAYOUT_ID = 'page-layout.root';
6
7
  export var SSRPlaceholderHandlers = /*#__PURE__*/function () {
@@ -59,7 +60,7 @@ export var SSRPlaceholderHandlers = /*#__PURE__*/function () {
59
60
  _resolve(hasSameSizePosition);
60
61
  } else {
61
62
  requestAnimationFrame(function () {
62
- var targetRect = target.getBoundingClientRect();
63
+ var targetRect = _this.getEffectiveBoundingRect(target);
63
64
  var hasSameSizePosition = _this.hasSameSizePosition(rect, targetRect);
64
65
  _resolve(hasSameSizePosition);
65
66
  });
@@ -78,7 +79,7 @@ export var SSRPlaceholderHandlers = /*#__PURE__*/function () {
78
79
  _resolve2(_hasSameSizePosition);
79
80
  } else {
80
81
  requestAnimationFrame(function () {
81
- var targetRect = target.getBoundingClientRect();
82
+ var targetRect = _this.getEffectiveBoundingRect(target);
82
83
  var hasSameSizePosition = _this.hasSameSizePosition(_rect, targetRect);
83
84
  _resolve2(hasSameSizePosition);
84
85
  });
@@ -236,7 +237,7 @@ export var SSRPlaceholderHandlers = /*#__PURE__*/function () {
236
237
  if (!placeholderRects) {
237
238
  return false;
238
239
  }
239
- return this.hasSameSizePosition(placeholderRects, el.getBoundingClientRect());
240
+ return this.hasSameSizePosition(placeholderRects, this.getEffectiveBoundingRect(el));
240
241
  }
241
242
  }, {
242
243
  key: "getSize",
@@ -275,6 +276,55 @@ export var SSRPlaceholderHandlers = /*#__PURE__*/function () {
275
276
  var verticalCheck = Math.abs(rect.y - boundingClientRect.y) < this.EQUALITY_THRESHOLD && Math.abs(rect.height - boundingClientRect.height) < this.EQUALITY_THRESHOLD;
276
277
  return horizontalCheck && verticalCheck || false;
277
278
  }
279
+
280
+ /**
281
+ * Gets the effective bounding rectangle for an element, handling display: contents elements
282
+ * by collecting dimensions from their children instead
283
+ */
284
+ }, {
285
+ key: "getEffectiveBoundingRect",
286
+ value: function getEffectiveBoundingRect(el) {
287
+ var enableDisplayContentsSupport = fg('platform_ufo_ssr_placeholders_for_display_contents');
288
+
289
+ // Only handle display: contents if feature flag is enabled
290
+ if (enableDisplayContentsSupport) {
291
+ var computedStyle = window.getComputedStyle(el);
292
+
293
+ // If element has display: contents, collect bounding rect from children
294
+ if (computedStyle.display === 'contents') {
295
+ var children = Array.from(el.children);
296
+ if (children.length === 0) {
297
+ // No children, return zero rect
298
+ return new DOMRect(0, 0, 0, 0);
299
+ }
300
+
301
+ // Calculate union of all children's bounding rects
302
+ var minX = Infinity;
303
+ var minY = Infinity;
304
+ var maxX = -Infinity;
305
+ var maxY = -Infinity;
306
+ children.forEach(function (child) {
307
+ var childRect = child.getBoundingClientRect();
308
+ // Skip children with zero dimensions (likely also display: contents)
309
+ if (childRect.width > 0 || childRect.height > 0) {
310
+ minX = Math.min(minX, childRect.left);
311
+ minY = Math.min(minY, childRect.top);
312
+ maxX = Math.max(maxX, childRect.right);
313
+ maxY = Math.max(maxY, childRect.bottom);
314
+ }
315
+ });
316
+
317
+ // If no children with dimensions found, return zero rect
318
+ if (minX === Infinity) {
319
+ return new DOMRect(0, 0, 0, 0);
320
+ }
321
+ return new DOMRect(minX, minY, maxX - minX, maxY - minY);
322
+ }
323
+ }
324
+
325
+ // Normal element or feature flag disabled, return its bounding rect
326
+ return el.getBoundingClientRect();
327
+ }
278
328
  }, {
279
329
  key: "isDummyRect",
280
330
  value: function isDummyRect(rect) {
@@ -1,23 +1,74 @@
1
+ import { fg } from '@atlaskit/platform-feature-flags';
2
+
1
3
  // lightweight script to scan the SSR response and collect all elements with data-ssr-placeholder attribute
2
4
  // and save their size/positions in a map __SSR_PLACEHOLDERS_DIMENSIONS__ on the Window object. Each placeholderId is
3
5
  // unique and maps to its corresponding elements bounding client rectangle dimensions.
4
6
  export function collectSSRPlaceholderDimensions(document, window) {
5
7
  var enablePageLayoutPlaceholder = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
8
+ var enableDisplayContentsSupport = fg('platform_ufo_ssr_placeholders_for_display_contents');
6
9
  var ssrPlaceholders = document === null || document === void 0 ? void 0 : document.querySelectorAll('[data-ssr-placeholder]');
7
10
  ssrPlaceholders.forEach(function (elem) {
8
11
  var placeholderId = elem.getAttribute('data-ssr-placeholder');
9
- var boundingClient = elem.getBoundingClientRect();
10
12
  if (placeholderId) {
11
13
  window.__SSR_PLACEHOLDERS_DIMENSIONS__ = window.__SSR_PLACEHOLDERS_DIMENSIONS__ || {};
12
- window.__SSR_PLACEHOLDERS_DIMENSIONS__[placeholderId] = boundingClient;
14
+ if (enableDisplayContentsSupport) {
15
+ window.__SSR_PLACEHOLDERS_DIMENSIONS__[placeholderId] = getEffectiveBoundingRect(elem, window);
16
+ } else {
17
+ window.__SSR_PLACEHOLDERS_DIMENSIONS__[placeholderId] = elem.getBoundingClientRect();
18
+ }
13
19
  }
14
20
  });
15
21
  if (enablePageLayoutPlaceholder) {
16
22
  var pageLayoutRoot = document === null || document === void 0 ? void 0 : document.getElementById('unsafe-design-system-page-layout-root');
17
23
  if (pageLayoutRoot) {
18
- var boundingClient = pageLayoutRoot.getBoundingClientRect();
19
24
  window.__SSR_PLACEHOLDERS_DIMENSIONS__ = window.__SSR_PLACEHOLDERS_DIMENSIONS__ || {};
20
- window.__SSR_PLACEHOLDERS_DIMENSIONS__['page-layout.root'] = boundingClient;
25
+ if (enableDisplayContentsSupport) {
26
+ window.__SSR_PLACEHOLDERS_DIMENSIONS__['page-layout.root'] = getEffectiveBoundingRect(pageLayoutRoot, window);
27
+ } else {
28
+ window.__SSR_PLACEHOLDERS_DIMENSIONS__['page-layout.root'] = pageLayoutRoot.getBoundingClientRect();
29
+ }
21
30
  }
22
31
  }
32
+ }
33
+
34
+ /**
35
+ * Gets the effective bounding rectangle for an element, handling display: contents elements
36
+ * by collecting dimensions from their children instead
37
+ */
38
+ function getEffectiveBoundingRect(elem, window) {
39
+ var computedStyle = window.getComputedStyle(elem);
40
+
41
+ // If element has display: contents, collect bounding rect from children
42
+ if (computedStyle.display === 'contents') {
43
+ var children = Array.from(elem.children);
44
+ if (children.length === 0) {
45
+ // No children, return zero rect
46
+ return new DOMRect(0, 0, 0, 0);
47
+ }
48
+
49
+ // Calculate union of all children's bounding rects
50
+ var minX = Infinity;
51
+ var minY = Infinity;
52
+ var maxX = -Infinity;
53
+ var maxY = -Infinity;
54
+ children.forEach(function (child) {
55
+ var childRect = child.getBoundingClientRect();
56
+ // Skip children with zero dimensions (likely also display: contents)
57
+ if (childRect.width > 0 || childRect.height > 0) {
58
+ minX = Math.min(minX, childRect.left);
59
+ minY = Math.min(minY, childRect.top);
60
+ maxX = Math.max(maxX, childRect.right);
61
+ maxY = Math.max(maxY, childRect.bottom);
62
+ }
63
+ });
64
+
65
+ // If no children with dimensions found, return zero rect
66
+ if (minX === Infinity) {
67
+ return new DOMRect(0, 0, 0, 0);
68
+ }
69
+ return new DOMRect(minX, minY, maxX - minX, maxY - minY);
70
+ }
71
+
72
+ // Normal element, return its bounding rect
73
+ return elem.getBoundingClientRect();
23
74
  }
@@ -79,6 +79,7 @@ export type ReactUFOPayload = {
79
79
  'event:localTimezoneOffset': number;
80
80
  'event:browser:name': string;
81
81
  'event:browser:version': string;
82
+ 'event:webdriver:enabled'?: boolean;
82
83
  'event:cpus': number;
83
84
  'event:memory': 0.25 | 0.5 | 1 | 2 | 4 | 8;
84
85
  'event:network:effectiveType': 'slow-2g' | '2g' | '3g' | '4g';
@@ -12,6 +12,7 @@ export default function getBrowserMetadata(): {
12
12
  rtt: number;
13
13
  downlink: number;
14
14
  };
15
+ webdriver?: boolean;
15
16
  time: {
16
17
  localHour: number;
17
18
  localDayOfWeek: number;
@@ -34,6 +34,11 @@ export declare class SSRPlaceholderHandlers {
34
34
  getSize(el: HTMLElement): Promise<Rect>;
35
35
  validateReactComponentMatchToPlaceholder(el: HTMLElement): Promise<unknown>;
36
36
  hasSameSizePosition(rect: Rect | undefined, boundingClientRect: DOMRectReadOnly): boolean;
37
+ /**
38
+ * Gets the effective bounding rectangle for an element, handling display: contents elements
39
+ * by collecting dimensions from their children instead
40
+ */
41
+ private getEffectiveBoundingRect;
37
42
  isDummyRect(rect: Rect | undefined): boolean;
38
43
  intersectionObserverCallback: ({ target, boundingClientRect }: IntersectionObserverEntry) => void;
39
44
  }
@@ -81,6 +81,7 @@ export type ReactUFOPayload = {
81
81
  'event:localTimezoneOffset': number;
82
82
  'event:browser:name': string;
83
83
  'event:browser:version': string;
84
+ 'event:webdriver:enabled'?: boolean;
84
85
  'event:cpus': number;
85
86
  'event:memory': 0.25 | 0.5 | 1 | 2 | 4 | 8;
86
87
  'event:network:effectiveType': 'slow-2g' | '2g' | '3g' | '4g';
@@ -12,6 +12,7 @@ export default function getBrowserMetadata(): {
12
12
  rtt: number;
13
13
  downlink: number;
14
14
  };
15
+ webdriver?: boolean;
15
16
  time: {
16
17
  localHour: number;
17
18
  localDayOfWeek: number;
@@ -34,6 +34,11 @@ export declare class SSRPlaceholderHandlers {
34
34
  getSize(el: HTMLElement): Promise<Rect>;
35
35
  validateReactComponentMatchToPlaceholder(el: HTMLElement): Promise<unknown>;
36
36
  hasSameSizePosition(rect: Rect | undefined, boundingClientRect: DOMRectReadOnly): boolean;
37
+ /**
38
+ * Gets the effective bounding rectangle for an element, handling display: contents elements
39
+ * by collecting dimensions from their children instead
40
+ */
41
+ private getEffectiveBoundingRect;
37
42
  isDummyRect(rect: Rect | undefined): boolean;
38
43
  intersectionObserverCallback: ({ target, boundingClientRect }: IntersectionObserverEntry) => void;
39
44
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/react-ufo",
3
- "version": "4.12.2",
3
+ "version": "4.12.4",
4
4
  "description": "Parts of React UFO that are publicly available",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -42,6 +42,7 @@
42
42
  },
43
43
  "devDependencies": {
44
44
  "@af/integration-testing": "workspace:^",
45
+ "@atlassian/feature-flags-test-utils": "^1.0.0",
45
46
  "@testing-library/react": "^13.4.0",
46
47
  "@types/is-ci": "^3.0.0",
47
48
  "is-ci": "^3.0.1"
@@ -109,6 +110,9 @@
109
110
  "platform_ufo_critical_metrics_payload": {
110
111
  "type": "boolean"
111
112
  },
113
+ "platform_ufo_ssr_placeholders_for_display_contents": {
114
+ "type": "boolean"
115
+ },
112
116
  "platform_ufo_enable_interactivity_jsm": {
113
117
  "type": "boolean"
114
118
  },
@@ -162,6 +166,9 @@
162
166
  },
163
167
  "media-perf-uplift-mutation-fix": {
164
168
  "type": "boolean"
169
+ },
170
+ "react_ufo_add_webdriver_info": {
171
+ "type": "boolean"
165
172
  }
166
173
  }
167
174
  }