@atlaskit/react-ufo 3.14.5 → 3.14.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,13 @@
1
1
  # @atlaskit/ufo-interaction-ignore
2
2
 
3
+ ## 3.14.6
4
+
5
+ ### Patch Changes
6
+
7
+ - [#179156](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/179156)
8
+ [`81f5605b925fc`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/81f5605b925fc) -
9
+ AFO-4081 ufo vc ignore if no layout shift marker
10
+
3
11
  ## 3.14.5
4
12
 
5
13
  ### Patch Changes
@@ -8,6 +8,7 @@ exports.default = 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 _vcUtils = require("../../vc-observer/media-wrapper/vc-utils");
12
13
  var _isNonVisualStyleMutation = _interopRequireDefault(require("../../vc-observer/observers/non-visual-styles/is-non-visual-style-mutation"));
13
14
  var _rllPlaceholders = require("../../vc-observer/observers/rll-placeholders");
@@ -15,6 +16,7 @@ var _intersectionObserver = require("./intersection-observer");
15
16
  var _mutationObserver = _interopRequireDefault(require("./mutation-observer"));
16
17
  var _performanceObserver = _interopRequireDefault(require("./performance-observer"));
17
18
  var _getComponentNameAndChildProps = require("./utils/get-component-name-and-child-props");
19
+ var _isInVcIgnoreIfNoLayoutShiftMarker = _interopRequireDefault(require("./utils/is-in-vc-ignore-if-no-layout-shift-marker"));
18
20
  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; } } }; }
19
21
  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; } }
20
22
  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; }
@@ -49,15 +51,23 @@ function sameRectDimensions(a, b) {
49
51
  }
50
52
  var createElementMutationsWatcher = function createElementMutationsWatcher(removedNodeRects) {
51
53
  return function (_ref) {
52
- var rect = _ref.rect;
54
+ var target = _ref.target,
55
+ rect = _ref.rect;
56
+ var isNoLsMarkerEnabled = (0, _platformFeatureFlags.fg)('platform_vc_ignore_no_ls_mutation_marker');
57
+ var isInIgnoreLsMarker = (0, _isInVcIgnoreIfNoLayoutShiftMarker.default)(target);
58
+ if (!isInIgnoreLsMarker && isNoLsMarkerEnabled) {
59
+ return 'mutation:element';
60
+ }
53
61
  var isRLLPlaceholder = _rllPlaceholders.RLLPlaceholderHandlers.getInstance().isRLLPlaceholderHydration(rect);
54
- if (isRLLPlaceholder) {
62
+ if (isRLLPlaceholder && (!isNoLsMarkerEnabled || isInIgnoreLsMarker)) {
55
63
  return 'mutation:rll-placeholder';
56
64
  }
57
65
  var wasDeleted = removedNodeRects.some(function (nr) {
58
66
  return sameRectDimensions(nr, rect);
59
67
  });
60
- if (wasDeleted) {
68
+ // When fg('platform_vc_ignore_no_ls_mutation_marker') is not enabled,
69
+ // no layout shift mutation is excluded as per existing fy25.03 logic
70
+ if (wasDeleted && (!isNoLsMarkerEnabled || isInIgnoreLsMarker)) {
61
71
  return 'mutation:element-replacement';
62
72
  }
63
73
  return 'mutation:element';
@@ -113,7 +123,12 @@ var ViewportObserver = exports.default = /*#__PURE__*/function () {
113
123
  }
114
124
  return n.isEqualNode(addedNode);
115
125
  });
116
- if (sameDeletedNode) {
126
+ var isInIgnoreLsMarker = (0, _isInVcIgnoreIfNoLayoutShiftMarker.default)(addedNode);
127
+ var isNoLsMarkerEnabled = (0, _platformFeatureFlags.fg)('platform_vc_ignore_no_ls_mutation_marker');
128
+
129
+ // When fg('platform_vc_ignore_no_ls_mutation_marker') is not enabled,
130
+ // no layout shift mutation is excluded as per existing fy25.03 logic
131
+ if (sameDeletedNode && (!isNoLsMarkerEnabled || isInIgnoreLsMarker)) {
117
132
  var _this$intersectionObs;
118
133
  (_this$intersectionObs = _this.intersectionObserver) === null || _this$intersectionObs === void 0 || _this$intersectionObs.watchAndTag(addedNode, 'mutation:remount');
119
134
  return;
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
7
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; } } }; }
8
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; } }
9
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; }
@@ -17,16 +18,17 @@ function createMutationObserver(_ref) {
17
18
  var mutationObserverCallback = function mutationObserverCallback(mutations) {
18
19
  var addedNodes = [];
19
20
  var removedNodes = [];
21
+ var attributeMutations = [];
20
22
  var targets = [];
21
23
  var _iterator = _createForOfIteratorHelper(mutations),
22
24
  _step;
23
25
  try {
24
26
  for (_iterator.s(); !(_step = _iterator.n()).done;) {
25
- var mut = _step.value;
26
- if (!(mut.target instanceof HTMLElement)) {
27
+ var _mut = _step.value;
28
+ if (!(_mut.target instanceof HTMLElement)) {
27
29
  continue;
28
30
  }
29
- if (mut.type === 'attributes') {
31
+ if (_mut.type === 'attributes') {
30
32
  var _mut$oldValue;
31
33
  /*
32
34
  "MutationObserver was explicitly designed to work that way, but I can't now recall the reasoning.
@@ -36,32 +38,42 @@ function createMutationObserver(_ref) {
36
38
  And Custom elements should work the same way as MutationObserver."
37
39
  https://github.com/whatwg/dom/issues/520#issuecomment-336574796
38
40
  */
39
- var oldValue = (_mut$oldValue = mut.oldValue) !== null && _mut$oldValue !== void 0 ? _mut$oldValue : undefined;
40
- var newValue = mut.attributeName ? mut.target.getAttribute(mut.attributeName) : undefined;
41
+ var oldValue = (_mut$oldValue = _mut.oldValue) !== null && _mut$oldValue !== void 0 ? _mut$oldValue : undefined;
42
+ var newValue = _mut.attributeName ? _mut.target.getAttribute(_mut.attributeName) : undefined;
41
43
  if (oldValue !== newValue) {
42
- var _mut$attributeName;
43
- onAttributeMutation({
44
- target: mut.target,
45
- attributeName: (_mut$attributeName = mut.attributeName) !== null && _mut$attributeName !== void 0 ? _mut$attributeName : 'unknown',
46
- oldValue: oldValue,
47
- newValue: newValue
48
- });
44
+ if ((0, _platformFeatureFlags.fg)('platform_vc_ignore_no_ls_mutation_marker')) {
45
+ var _mut$attributeName;
46
+ attributeMutations.push({
47
+ target: new WeakRef(_mut.target),
48
+ attributeName: (_mut$attributeName = _mut.attributeName) !== null && _mut$attributeName !== void 0 ? _mut$attributeName : 'unknown',
49
+ oldValue: oldValue,
50
+ newValue: newValue
51
+ });
52
+ } else {
53
+ var _mut$attributeName2;
54
+ onAttributeMutation({
55
+ target: _mut.target,
56
+ attributeName: (_mut$attributeName2 = _mut.attributeName) !== null && _mut$attributeName2 !== void 0 ? _mut$attributeName2 : 'unknown',
57
+ oldValue: oldValue,
58
+ newValue: newValue
59
+ });
60
+ }
49
61
  }
50
62
  continue;
51
- } else if (mut.type === 'childList') {
63
+ } else if (_mut.type === 'childList') {
52
64
  var _mut$addedNodes, _mut$removedNodes;
53
- ((_mut$addedNodes = mut.addedNodes) !== null && _mut$addedNodes !== void 0 ? _mut$addedNodes : []).forEach(function (node) {
65
+ ((_mut$addedNodes = _mut.addedNodes) !== null && _mut$addedNodes !== void 0 ? _mut$addedNodes : []).forEach(function (node) {
54
66
  if (node instanceof HTMLElement) {
55
67
  addedNodes.push(new WeakRef(node));
56
68
  }
57
69
  });
58
- ((_mut$removedNodes = mut.removedNodes) !== null && _mut$removedNodes !== void 0 ? _mut$removedNodes : []).forEach(function (node) {
70
+ ((_mut$removedNodes = _mut.removedNodes) !== null && _mut$removedNodes !== void 0 ? _mut$removedNodes : []).forEach(function (node) {
59
71
  if (node instanceof HTMLElement) {
60
72
  removedNodes.push(new WeakRef(node));
61
73
  }
62
74
  });
63
75
  }
64
- targets.push(mut.target);
76
+ targets.push(_mut.target);
65
77
  }
66
78
  } catch (err) {
67
79
  _iterator.e(err);
@@ -72,6 +84,15 @@ function createMutationObserver(_ref) {
72
84
  addedNodes: addedNodes,
73
85
  removedNodes: removedNodes
74
86
  });
87
+ for (var _i = 0, _attributeMutations = attributeMutations; _i < _attributeMutations.length; _i++) {
88
+ var mut = _attributeMutations[_i];
89
+ onAttributeMutation({
90
+ target: mut.target.deref(),
91
+ attributeName: mut.attributeName,
92
+ oldValue: mut.oldValue,
93
+ newValue: mut.newValue
94
+ });
95
+ }
75
96
  onMutationFinished === null || onMutationFinished === void 0 || onMutationFinished({
76
97
  targets: targets
77
98
  });
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = isInVCIgnoreIfNoLayoutShiftMarker;
7
+ /**
8
+ * Check if the element is in the VC ignore if no layout shift marker.
9
+ * @param element - The element to check.
10
+ * @returns True if the element has the data-vc-ignore-if-no-layout-shift attribute == 'true or its parent has it, false otherwise.
11
+ */
12
+ function isInVCIgnoreIfNoLayoutShiftMarker(element) {
13
+ if (!element) {
14
+ return false;
15
+ }
16
+ return element.getAttribute('data-vc-ignore-if-no-layout-shift') === 'true' || isInVCIgnoreIfNoLayoutShiftMarker(element.parentElement);
17
+ }
@@ -1,4 +1,5 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import { fg } from '@atlaskit/platform-feature-flags';
2
3
  import { isContainedWithinMediaWrapper } from '../../vc-observer/media-wrapper/vc-utils';
3
4
  import isNonVisualStyleMutation from '../../vc-observer/observers/non-visual-styles/is-non-visual-style-mutation';
4
5
  import { RLLPlaceholderHandlers } from '../../vc-observer/observers/rll-placeholders';
@@ -6,6 +7,7 @@ import { createIntersectionObserver } from './intersection-observer';
6
7
  import createMutationObserver from './mutation-observer';
7
8
  import createPerformanceObserver from './performance-observer';
8
9
  import { checkThirdPartySegmentWithIgnoreReason, createMutationTypeWithIgnoredReason } from './utils/get-component-name-and-child-props';
10
+ import isInVCIgnoreIfNoLayoutShiftMarker from './utils/is-in-vc-ignore-if-no-layout-shift-marker';
9
11
  function isElementVisible(element) {
10
12
  if (!(element instanceof HTMLElement)) {
11
13
  return true;
@@ -36,14 +38,22 @@ function sameRectDimensions(a, b) {
36
38
  return a.width === b.width && a.height === b.height && a.x === b.x && a.y === b.y;
37
39
  }
38
40
  const createElementMutationsWatcher = removedNodeRects => ({
41
+ target,
39
42
  rect
40
43
  }) => {
44
+ const isNoLsMarkerEnabled = fg('platform_vc_ignore_no_ls_mutation_marker');
45
+ const isInIgnoreLsMarker = isInVCIgnoreIfNoLayoutShiftMarker(target);
46
+ if (!isInIgnoreLsMarker && isNoLsMarkerEnabled) {
47
+ return 'mutation:element';
48
+ }
41
49
  const isRLLPlaceholder = RLLPlaceholderHandlers.getInstance().isRLLPlaceholderHydration(rect);
42
- if (isRLLPlaceholder) {
50
+ if (isRLLPlaceholder && (!isNoLsMarkerEnabled || isInIgnoreLsMarker)) {
43
51
  return 'mutation:rll-placeholder';
44
52
  }
45
53
  const wasDeleted = removedNodeRects.some(nr => sameRectDimensions(nr, rect));
46
- if (wasDeleted) {
54
+ // When fg('platform_vc_ignore_no_ls_mutation_marker') is not enabled,
55
+ // no layout shift mutation is excluded as per existing fy25.03 logic
56
+ if (wasDeleted && (!isNoLsMarkerEnabled || isInIgnoreLsMarker)) {
47
57
  return 'mutation:element-replacement';
48
58
  }
49
59
  return 'mutation:element';
@@ -99,7 +109,12 @@ export default class ViewportObserver {
99
109
  }
100
110
  return n.isEqualNode(addedNode);
101
111
  });
102
- if (sameDeletedNode) {
112
+ const isInIgnoreLsMarker = isInVCIgnoreIfNoLayoutShiftMarker(addedNode);
113
+ const isNoLsMarkerEnabled = fg('platform_vc_ignore_no_ls_mutation_marker');
114
+
115
+ // When fg('platform_vc_ignore_no_ls_mutation_marker') is not enabled,
116
+ // no layout shift mutation is excluded as per existing fy25.03 logic
117
+ if (sameDeletedNode && (!isNoLsMarkerEnabled || isInIgnoreLsMarker)) {
103
118
  var _this$intersectionObs;
104
119
  (_this$intersectionObs = this.intersectionObserver) === null || _this$intersectionObs === void 0 ? void 0 : _this$intersectionObs.watchAndTag(addedNode, 'mutation:remount');
105
120
  return;
@@ -1,3 +1,4 @@
1
+ import { fg } from '@atlaskit/platform-feature-flags';
1
2
  function createMutationObserver({
2
3
  onAttributeMutation,
3
4
  onChildListMutation,
@@ -9,6 +10,7 @@ function createMutationObserver({
9
10
  const mutationObserverCallback = mutations => {
10
11
  const addedNodes = [];
11
12
  const removedNodes = [];
13
+ const attributeMutations = [];
12
14
  const targets = [];
13
15
  for (const mut of mutations) {
14
16
  if (!(mut.target instanceof HTMLElement)) {
@@ -27,13 +29,23 @@ function createMutationObserver({
27
29
  const oldValue = (_mut$oldValue = mut.oldValue) !== null && _mut$oldValue !== void 0 ? _mut$oldValue : undefined;
28
30
  const newValue = mut.attributeName ? mut.target.getAttribute(mut.attributeName) : undefined;
29
31
  if (oldValue !== newValue) {
30
- var _mut$attributeName;
31
- onAttributeMutation({
32
- target: mut.target,
33
- attributeName: (_mut$attributeName = mut.attributeName) !== null && _mut$attributeName !== void 0 ? _mut$attributeName : 'unknown',
34
- oldValue,
35
- newValue
36
- });
32
+ if (fg('platform_vc_ignore_no_ls_mutation_marker')) {
33
+ var _mut$attributeName;
34
+ attributeMutations.push({
35
+ target: new WeakRef(mut.target),
36
+ attributeName: (_mut$attributeName = mut.attributeName) !== null && _mut$attributeName !== void 0 ? _mut$attributeName : 'unknown',
37
+ oldValue,
38
+ newValue
39
+ });
40
+ } else {
41
+ var _mut$attributeName2;
42
+ onAttributeMutation({
43
+ target: mut.target,
44
+ attributeName: (_mut$attributeName2 = mut.attributeName) !== null && _mut$attributeName2 !== void 0 ? _mut$attributeName2 : 'unknown',
45
+ oldValue,
46
+ newValue
47
+ });
48
+ }
37
49
  }
38
50
  continue;
39
51
  } else if (mut.type === 'childList') {
@@ -55,6 +67,14 @@ function createMutationObserver({
55
67
  addedNodes,
56
68
  removedNodes
57
69
  });
70
+ for (const mut of attributeMutations) {
71
+ onAttributeMutation({
72
+ target: mut.target.deref(),
73
+ attributeName: mut.attributeName,
74
+ oldValue: mut.oldValue,
75
+ newValue: mut.newValue
76
+ });
77
+ }
58
78
  onMutationFinished === null || onMutationFinished === void 0 ? void 0 : onMutationFinished({
59
79
  targets
60
80
  });
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Check if the element is in the VC ignore if no layout shift marker.
3
+ * @param element - The element to check.
4
+ * @returns True if the element has the data-vc-ignore-if-no-layout-shift attribute == 'true or its parent has it, false otherwise.
5
+ */
6
+ export default function isInVCIgnoreIfNoLayoutShiftMarker(element) {
7
+ if (!element) {
8
+ return false;
9
+ }
10
+ return element.getAttribute('data-vc-ignore-if-no-layout-shift') === 'true' || isInVCIgnoreIfNoLayoutShiftMarker(element.parentElement);
11
+ }
@@ -4,6 +4,7 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
4
4
  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; } } }; }
5
5
  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; } }
6
6
  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; }
7
+ import { fg } from '@atlaskit/platform-feature-flags';
7
8
  import { isContainedWithinMediaWrapper } from '../../vc-observer/media-wrapper/vc-utils';
8
9
  import isNonVisualStyleMutation from '../../vc-observer/observers/non-visual-styles/is-non-visual-style-mutation';
9
10
  import { RLLPlaceholderHandlers } from '../../vc-observer/observers/rll-placeholders';
@@ -11,6 +12,7 @@ import { createIntersectionObserver } from './intersection-observer';
11
12
  import createMutationObserver from './mutation-observer';
12
13
  import createPerformanceObserver from './performance-observer';
13
14
  import { checkThirdPartySegmentWithIgnoreReason, createMutationTypeWithIgnoredReason } from './utils/get-component-name-and-child-props';
15
+ import isInVCIgnoreIfNoLayoutShiftMarker from './utils/is-in-vc-ignore-if-no-layout-shift-marker';
14
16
  function isElementVisible(element) {
15
17
  if (!(element instanceof HTMLElement)) {
16
18
  return true;
@@ -42,15 +44,23 @@ function sameRectDimensions(a, b) {
42
44
  }
43
45
  var createElementMutationsWatcher = function createElementMutationsWatcher(removedNodeRects) {
44
46
  return function (_ref) {
45
- var rect = _ref.rect;
47
+ var target = _ref.target,
48
+ rect = _ref.rect;
49
+ var isNoLsMarkerEnabled = fg('platform_vc_ignore_no_ls_mutation_marker');
50
+ var isInIgnoreLsMarker = isInVCIgnoreIfNoLayoutShiftMarker(target);
51
+ if (!isInIgnoreLsMarker && isNoLsMarkerEnabled) {
52
+ return 'mutation:element';
53
+ }
46
54
  var isRLLPlaceholder = RLLPlaceholderHandlers.getInstance().isRLLPlaceholderHydration(rect);
47
- if (isRLLPlaceholder) {
55
+ if (isRLLPlaceholder && (!isNoLsMarkerEnabled || isInIgnoreLsMarker)) {
48
56
  return 'mutation:rll-placeholder';
49
57
  }
50
58
  var wasDeleted = removedNodeRects.some(function (nr) {
51
59
  return sameRectDimensions(nr, rect);
52
60
  });
53
- if (wasDeleted) {
61
+ // When fg('platform_vc_ignore_no_ls_mutation_marker') is not enabled,
62
+ // no layout shift mutation is excluded as per existing fy25.03 logic
63
+ if (wasDeleted && (!isNoLsMarkerEnabled || isInIgnoreLsMarker)) {
54
64
  return 'mutation:element-replacement';
55
65
  }
56
66
  return 'mutation:element';
@@ -106,7 +116,12 @@ var ViewportObserver = /*#__PURE__*/function () {
106
116
  }
107
117
  return n.isEqualNode(addedNode);
108
118
  });
109
- if (sameDeletedNode) {
119
+ var isInIgnoreLsMarker = isInVCIgnoreIfNoLayoutShiftMarker(addedNode);
120
+ var isNoLsMarkerEnabled = fg('platform_vc_ignore_no_ls_mutation_marker');
121
+
122
+ // When fg('platform_vc_ignore_no_ls_mutation_marker') is not enabled,
123
+ // no layout shift mutation is excluded as per existing fy25.03 logic
124
+ if (sameDeletedNode && (!isNoLsMarkerEnabled || isInIgnoreLsMarker)) {
110
125
  var _this$intersectionObs;
111
126
  (_this$intersectionObs = _this.intersectionObserver) === null || _this$intersectionObs === void 0 || _this$intersectionObs.watchAndTag(addedNode, 'mutation:remount');
112
127
  return;
@@ -1,6 +1,7 @@
1
1
  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; } } }; }
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
+ import { fg } from '@atlaskit/platform-feature-flags';
4
5
  function createMutationObserver(_ref) {
5
6
  var onAttributeMutation = _ref.onAttributeMutation,
6
7
  onChildListMutation = _ref.onChildListMutation,
@@ -11,16 +12,17 @@ function createMutationObserver(_ref) {
11
12
  var mutationObserverCallback = function mutationObserverCallback(mutations) {
12
13
  var addedNodes = [];
13
14
  var removedNodes = [];
15
+ var attributeMutations = [];
14
16
  var targets = [];
15
17
  var _iterator = _createForOfIteratorHelper(mutations),
16
18
  _step;
17
19
  try {
18
20
  for (_iterator.s(); !(_step = _iterator.n()).done;) {
19
- var mut = _step.value;
20
- if (!(mut.target instanceof HTMLElement)) {
21
+ var _mut = _step.value;
22
+ if (!(_mut.target instanceof HTMLElement)) {
21
23
  continue;
22
24
  }
23
- if (mut.type === 'attributes') {
25
+ if (_mut.type === 'attributes') {
24
26
  var _mut$oldValue;
25
27
  /*
26
28
  "MutationObserver was explicitly designed to work that way, but I can't now recall the reasoning.
@@ -30,32 +32,42 @@ function createMutationObserver(_ref) {
30
32
  And Custom elements should work the same way as MutationObserver."
31
33
  https://github.com/whatwg/dom/issues/520#issuecomment-336574796
32
34
  */
33
- var oldValue = (_mut$oldValue = mut.oldValue) !== null && _mut$oldValue !== void 0 ? _mut$oldValue : undefined;
34
- var newValue = mut.attributeName ? mut.target.getAttribute(mut.attributeName) : undefined;
35
+ var oldValue = (_mut$oldValue = _mut.oldValue) !== null && _mut$oldValue !== void 0 ? _mut$oldValue : undefined;
36
+ var newValue = _mut.attributeName ? _mut.target.getAttribute(_mut.attributeName) : undefined;
35
37
  if (oldValue !== newValue) {
36
- var _mut$attributeName;
37
- onAttributeMutation({
38
- target: mut.target,
39
- attributeName: (_mut$attributeName = mut.attributeName) !== null && _mut$attributeName !== void 0 ? _mut$attributeName : 'unknown',
40
- oldValue: oldValue,
41
- newValue: newValue
42
- });
38
+ if (fg('platform_vc_ignore_no_ls_mutation_marker')) {
39
+ var _mut$attributeName;
40
+ attributeMutations.push({
41
+ target: new WeakRef(_mut.target),
42
+ attributeName: (_mut$attributeName = _mut.attributeName) !== null && _mut$attributeName !== void 0 ? _mut$attributeName : 'unknown',
43
+ oldValue: oldValue,
44
+ newValue: newValue
45
+ });
46
+ } else {
47
+ var _mut$attributeName2;
48
+ onAttributeMutation({
49
+ target: _mut.target,
50
+ attributeName: (_mut$attributeName2 = _mut.attributeName) !== null && _mut$attributeName2 !== void 0 ? _mut$attributeName2 : 'unknown',
51
+ oldValue: oldValue,
52
+ newValue: newValue
53
+ });
54
+ }
43
55
  }
44
56
  continue;
45
- } else if (mut.type === 'childList') {
57
+ } else if (_mut.type === 'childList') {
46
58
  var _mut$addedNodes, _mut$removedNodes;
47
- ((_mut$addedNodes = mut.addedNodes) !== null && _mut$addedNodes !== void 0 ? _mut$addedNodes : []).forEach(function (node) {
59
+ ((_mut$addedNodes = _mut.addedNodes) !== null && _mut$addedNodes !== void 0 ? _mut$addedNodes : []).forEach(function (node) {
48
60
  if (node instanceof HTMLElement) {
49
61
  addedNodes.push(new WeakRef(node));
50
62
  }
51
63
  });
52
- ((_mut$removedNodes = mut.removedNodes) !== null && _mut$removedNodes !== void 0 ? _mut$removedNodes : []).forEach(function (node) {
64
+ ((_mut$removedNodes = _mut.removedNodes) !== null && _mut$removedNodes !== void 0 ? _mut$removedNodes : []).forEach(function (node) {
53
65
  if (node instanceof HTMLElement) {
54
66
  removedNodes.push(new WeakRef(node));
55
67
  }
56
68
  });
57
69
  }
58
- targets.push(mut.target);
70
+ targets.push(_mut.target);
59
71
  }
60
72
  } catch (err) {
61
73
  _iterator.e(err);
@@ -66,6 +78,15 @@ function createMutationObserver(_ref) {
66
78
  addedNodes: addedNodes,
67
79
  removedNodes: removedNodes
68
80
  });
81
+ for (var _i = 0, _attributeMutations = attributeMutations; _i < _attributeMutations.length; _i++) {
82
+ var mut = _attributeMutations[_i];
83
+ onAttributeMutation({
84
+ target: mut.target.deref(),
85
+ attributeName: mut.attributeName,
86
+ oldValue: mut.oldValue,
87
+ newValue: mut.newValue
88
+ });
89
+ }
69
90
  onMutationFinished === null || onMutationFinished === void 0 || onMutationFinished({
70
91
  targets: targets
71
92
  });
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Check if the element is in the VC ignore if no layout shift marker.
3
+ * @param element - The element to check.
4
+ * @returns True if the element has the data-vc-ignore-if-no-layout-shift attribute == 'true or its parent has it, false otherwise.
5
+ */
6
+ export default function isInVCIgnoreIfNoLayoutShiftMarker(element) {
7
+ if (!element) {
8
+ return false;
9
+ }
10
+ return element.getAttribute('data-vc-ignore-if-no-layout-shift') === 'true' || isInVCIgnoreIfNoLayoutShiftMarker(element.parentElement);
11
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Check if the element is in the VC ignore if no layout shift marker.
3
+ * @param element - The element to check.
4
+ * @returns True if the element has the data-vc-ignore-if-no-layout-shift attribute == 'true or its parent has it, false otherwise.
5
+ */
6
+ export default function isInVCIgnoreIfNoLayoutShiftMarker(element: HTMLElement | null | undefined): boolean;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Check if the element is in the VC ignore if no layout shift marker.
3
+ * @param element - The element to check.
4
+ * @returns True if the element has the data-vc-ignore-if-no-layout-shift attribute == 'true or its parent has it, false otherwise.
5
+ */
6
+ export default function isInVCIgnoreIfNoLayoutShiftMarker(element: HTMLElement | null | undefined): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/react-ufo",
3
- "version": "3.14.5",
3
+ "version": "3.14.6",
4
4
  "description": "Parts of React UFO that are publicly available",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -205,6 +205,9 @@
205
205
  },
206
206
  "platform_ufo_add_type_for_3p_segments": {
207
207
  "type": "boolean"
208
+ },
209
+ "platform_vc_ignore_no_ls_mutation_marker": {
210
+ "type": "boolean"
208
211
  }
209
212
  }
210
213
  }