@atlaskit/react-ufo 4.15.4 → 4.15.5
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 +9 -0
- package/dist/cjs/vc/vc-observer/observers/ssr-placeholders/index.js +7 -0
- package/dist/cjs/vc/vc-observer-new/metric-calculator/vcnext/index.js +4 -1
- package/dist/cjs/vc/vc-observer-new/viewport-observer/index.js +290 -191
- package/dist/cjs/vc/vc-observer-new/viewport-observer/intersection-observer/index.js +45 -2
- package/dist/cjs/vc/vc-observer-new/viewport-observer/utils/get-mutated-elements.js +15 -4
- package/dist/cjs/vc/vc-observer-new/viewport-observer/utils/is-zero-dimension-rectangle.js +9 -0
- package/dist/es2019/vc/vc-observer/observers/ssr-placeholders/index.js +5 -0
- package/dist/es2019/vc/vc-observer-new/metric-calculator/vcnext/index.js +4 -1
- package/dist/es2019/vc/vc-observer-new/viewport-observer/index.js +158 -81
- package/dist/es2019/vc/vc-observer-new/viewport-observer/intersection-observer/index.js +33 -2
- package/dist/es2019/vc/vc-observer-new/viewport-observer/utils/get-mutated-elements.js +15 -4
- package/dist/es2019/vc/vc-observer-new/viewport-observer/utils/is-zero-dimension-rectangle.js +3 -0
- package/dist/esm/vc/vc-observer/observers/ssr-placeholders/index.js +7 -0
- package/dist/esm/vc/vc-observer-new/metric-calculator/vcnext/index.js +4 -1
- package/dist/esm/vc/vc-observer-new/viewport-observer/index.js +288 -189
- package/dist/esm/vc/vc-observer-new/viewport-observer/intersection-observer/index.js +45 -2
- package/dist/esm/vc/vc-observer-new/viewport-observer/utils/get-mutated-elements.js +15 -4
- package/dist/esm/vc/vc-observer-new/viewport-observer/utils/is-zero-dimension-rectangle.js +3 -0
- package/dist/types/vc/vc-observer/observers/ssr-placeholders/index.d.ts +1 -0
- package/dist/types/vc/vc-observer-new/types.d.ts +1 -1
- package/dist/types/vc/vc-observer-new/viewport-observer/utils/is-zero-dimension-rectangle.d.ts +1 -0
- package/dist/types-ts4.5/vc/vc-observer/observers/ssr-placeholders/index.d.ts +1 -0
- package/dist/types-ts4.5/vc/vc-observer-new/types.d.ts +1 -1
- package/dist/types-ts4.5/vc/vc-observer-new/viewport-observer/utils/is-zero-dimension-rectangle.d.ts +1 -0
- package/package.json +7 -1
|
@@ -4,6 +4,11 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.createIntersectionObserver = createIntersectionObserver;
|
|
7
|
+
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
8
|
+
var _isZeroDimensionRectangle = require("../utils/is-zero-dimension-rectangle");
|
|
9
|
+
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
|
+
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
|
+
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
12
|
function isValidEntry(entry) {
|
|
8
13
|
return entry.isIntersecting && entry.intersectionRect.width > 0 && entry.intersectionRect.height > 0;
|
|
9
14
|
}
|
|
@@ -18,12 +23,50 @@ function createIntersectionObserver(_ref) {
|
|
|
18
23
|
var validEntries = [];
|
|
19
24
|
var startTime = performance.now();
|
|
20
25
|
entries.forEach(function (entry) {
|
|
21
|
-
if (!(entry.target instanceof HTMLElement)
|
|
26
|
+
if (!(entry.target instanceof HTMLElement)) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
var tagOrCallback = callbacksPerElement.get(entry.target);
|
|
30
|
+
if ((0, _platformFeatureFlags.fg)('platform_ufo_detect_zero_dimension_rectangles')) {
|
|
31
|
+
if ((0, _isZeroDimensionRectangle.isZeroDimensionRectangle)(entry.intersectionRect)) {
|
|
32
|
+
var zeroDimensionRectangleTagCallback = function zeroDimensionRectangleTagCallback(props) {
|
|
33
|
+
var tagOrCallbackResult = typeof tagOrCallback === 'function' ? tagOrCallback(props) : tagOrCallback;
|
|
34
|
+
|
|
35
|
+
// override as display-contents mutation
|
|
36
|
+
if (tagOrCallbackResult === 'mutation:element') {
|
|
37
|
+
return 'mutation:display-contents-children-element';
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// override as display-contents mutation
|
|
41
|
+
if (tagOrCallbackResult && typeof tagOrCallbackResult !== 'string' && tagOrCallbackResult.type === 'mutation:attribute') {
|
|
42
|
+
return {
|
|
43
|
+
type: 'mutation:display-contents-children-attribute',
|
|
44
|
+
mutationData: tagOrCallbackResult.mutationData
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
return tagOrCallbackResult;
|
|
48
|
+
};
|
|
49
|
+
var _iterator = _createForOfIteratorHelper(entry.target.children),
|
|
50
|
+
_step;
|
|
51
|
+
try {
|
|
52
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
53
|
+
var child = _step.value;
|
|
54
|
+
observer.observe(child);
|
|
55
|
+
callbacksPerElement.set(child, zeroDimensionRectangleTagCallback);
|
|
56
|
+
}
|
|
57
|
+
} catch (err) {
|
|
58
|
+
_iterator.e(err);
|
|
59
|
+
} finally {
|
|
60
|
+
_iterator.f();
|
|
61
|
+
}
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (!isValidEntry(entry)) {
|
|
22
66
|
return;
|
|
23
67
|
}
|
|
24
68
|
var mutationTag = null;
|
|
25
69
|
var mutationData = null;
|
|
26
|
-
var tagOrCallback = callbacksPerElement.get(entry.target);
|
|
27
70
|
if (typeof tagOrCallback === 'function') {
|
|
28
71
|
var tagOrCallbackResult = tagOrCallback({
|
|
29
72
|
target: entry.target,
|
|
@@ -10,9 +10,21 @@ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
|
10
10
|
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; } } }; }
|
|
11
11
|
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; } }
|
|
12
12
|
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; }
|
|
13
|
+
function isElementStyledWithDisplayContents(element) {
|
|
14
|
+
var _window2;
|
|
15
|
+
// To minimise calling `getComputedStyle`, we are making an assumption that if an element is from the Entrypoints framework, then it will have `display: contents` styling
|
|
16
|
+
// as per https://bitbucket.org/atlassian/atlassian-frontend-monorepo/src/e4ccf437262ef4c0fd3c651ffb7ad4770b15aed4/jira/src/packages/platform/entry-points/entry-point-placeholder/src/index.tsx#lines-136
|
|
17
|
+
if ((0, _platformFeatureFlags.fg)('platform_ufo_detect_entrypoint_parent')) {
|
|
18
|
+
var _window;
|
|
19
|
+
if (element.hasAttribute('data-ep-placeholder-id')) {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
return ((_window = window) === null || _window === void 0 || (_window = _window.getComputedStyle(element)) === null || _window === void 0 ? void 0 : _window.display) === 'contents';
|
|
23
|
+
}
|
|
24
|
+
return ((_window2 = window) === null || _window2 === void 0 || (_window2 = _window2.getComputedStyle(element)) === null || _window2 === void 0 ? void 0 : _window2.display) === 'contents';
|
|
25
|
+
}
|
|
13
26
|
var MAX_NESTED_LEVELS_OF_DISPLAY_CONTENT_ELEMENTS_HANDLED = 3;
|
|
14
27
|
function getMutatedElements(element) {
|
|
15
|
-
var _window;
|
|
16
28
|
var depthLevel = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
17
29
|
if ((0, _platformFeatureFlags.fg)('platform_ufo_disable_vcnext_observations')) {
|
|
18
30
|
return [{
|
|
@@ -20,16 +32,15 @@ function getMutatedElements(element) {
|
|
|
20
32
|
isDisplayContentsElementChildren: false
|
|
21
33
|
}];
|
|
22
34
|
}
|
|
23
|
-
if ((
|
|
35
|
+
if (isElementStyledWithDisplayContents(element)) {
|
|
24
36
|
var mutatedElements = [];
|
|
25
37
|
var nestedDisplayContentsElementChildren = [];
|
|
26
38
|
var _iterator = _createForOfIteratorHelper(element.children),
|
|
27
39
|
_step;
|
|
28
40
|
try {
|
|
29
41
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
30
|
-
var _window2;
|
|
31
42
|
var child = _step.value;
|
|
32
|
-
if ((
|
|
43
|
+
if (isElementStyledWithDisplayContents(child)) {
|
|
33
44
|
nestedDisplayContentsElementChildren.push(child);
|
|
34
45
|
}
|
|
35
46
|
mutatedElements.push({
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.isZeroDimensionRectangle = isZeroDimensionRectangle;
|
|
7
|
+
function isZeroDimensionRectangle(rect) {
|
|
8
|
+
return rect.bottom === 0 && rect.top === 0 && rect.left === 0 && rect.right === 0 && rect.x === 0 && rect.y === 0 && rect.width === 0 && rect.height === 0;
|
|
9
|
+
}
|
|
@@ -233,6 +233,11 @@ export class SSRPlaceholderHandlers {
|
|
|
233
233
|
}
|
|
234
234
|
});
|
|
235
235
|
}
|
|
236
|
+
validateReactComponentMatchToPlaceholderV4(el) {
|
|
237
|
+
el = this.findNearestPlaceholderContainerIfIgnored(el);
|
|
238
|
+
const id = this.getPlaceholderReplacementId(el);
|
|
239
|
+
return this.staticPlaceholders.has(id);
|
|
240
|
+
}
|
|
236
241
|
hasSameSizePosition(rect, boundingClientRect) {
|
|
237
242
|
if (!rect) {
|
|
238
243
|
return false;
|
|
@@ -8,7 +8,10 @@ const getConsideredEntryTypes = () => {
|
|
|
8
8
|
if (fg('platform_ufo_remove_ssr_placeholder_in_ttvc_v4')) {
|
|
9
9
|
consideredEntryTypes.push('mutation:ssr-placeholder');
|
|
10
10
|
}
|
|
11
|
-
|
|
11
|
+
if (fg('platform_ufo_detect_zero_dimension_rectangles')) {
|
|
12
|
+
consideredEntryTypes.push('mutation:display-contents-children-attribute');
|
|
13
|
+
}
|
|
14
|
+
return consideredEntryTypes;
|
|
12
15
|
};
|
|
13
16
|
const getExcludedEntryTypes = () => {
|
|
14
17
|
const excludedEntryTypes = ['layout-shift:same-rect'];
|
|
@@ -31,6 +31,67 @@ const createElementMutationsWatcher = removedNodeRects => ({
|
|
|
31
31
|
}
|
|
32
32
|
return 'mutation:element';
|
|
33
33
|
};
|
|
34
|
+
const createElementMutationsWatcherV4 = (removedNodeRects, isWithinThirdPartySegment, hasSameDeletedNode, timestamp, isTargetReactRoot, getSSRState, getSSRPlaceholderHandler) => ({
|
|
35
|
+
target,
|
|
36
|
+
rect
|
|
37
|
+
}) => {
|
|
38
|
+
if (getSSRState) {
|
|
39
|
+
const ssrState = getSSRState();
|
|
40
|
+
const SSRStateEnum = {
|
|
41
|
+
normal: 1,
|
|
42
|
+
waitingForFirstRender: 2,
|
|
43
|
+
ignoring: 3
|
|
44
|
+
};
|
|
45
|
+
if (ssrState.state === SSRStateEnum.waitingForFirstRender && timestamp > ssrState.renderStart && isTargetReactRoot) {
|
|
46
|
+
ssrState.state = SSRStateEnum.ignoring;
|
|
47
|
+
if (ssrState.renderStop === -1) {
|
|
48
|
+
// arbitrary 500ms DOM update window
|
|
49
|
+
ssrState.renderStop = timestamp + 500;
|
|
50
|
+
}
|
|
51
|
+
return 'ssr-hydration';
|
|
52
|
+
}
|
|
53
|
+
if (ssrState.state === SSRStateEnum.ignoring && timestamp > ssrState.renderStart && isTargetReactRoot) {
|
|
54
|
+
if (timestamp <= ssrState.renderStop) {
|
|
55
|
+
return 'ssr-hydration';
|
|
56
|
+
} else {
|
|
57
|
+
ssrState.state = SSRStateEnum.normal;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (getSSRPlaceholderHandler) {
|
|
62
|
+
const ssrPlaceholderHandler = getSSRPlaceholderHandler();
|
|
63
|
+
if (ssrPlaceholderHandler) {
|
|
64
|
+
if ((ssrPlaceholderHandler.isPlaceholder(target) || ssrPlaceholderHandler.isPlaceholderIgnored(target)) && ssrPlaceholderHandler.checkIfExistedAndSizeMatchingV3(target)) {
|
|
65
|
+
return 'mutation:ssr-placeholder';
|
|
66
|
+
}
|
|
67
|
+
if ((ssrPlaceholderHandler.isPlaceholderReplacement(target) || ssrPlaceholderHandler.isPlaceholderIgnored(target)) && ssrPlaceholderHandler.validateReactComponentMatchToPlaceholderV4(target)) {
|
|
68
|
+
return 'mutation:ssr-placeholder';
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (hasSameDeletedNode && isInVCIgnoreIfNoLayoutShiftMarker(target)) {
|
|
73
|
+
return 'mutation:remount';
|
|
74
|
+
}
|
|
75
|
+
if (isContainedWithinMediaWrapper(target)) {
|
|
76
|
+
return 'mutation:media';
|
|
77
|
+
}
|
|
78
|
+
if (isWithinThirdPartySegment) {
|
|
79
|
+
return 'mutation:third-party-element';
|
|
80
|
+
}
|
|
81
|
+
const isInIgnoreLsMarker = isInVCIgnoreIfNoLayoutShiftMarker(target);
|
|
82
|
+
if (!isInIgnoreLsMarker) {
|
|
83
|
+
return 'mutation:element';
|
|
84
|
+
}
|
|
85
|
+
const isRLLPlaceholder = RLLPlaceholderHandlers.getInstance().isRLLPlaceholderHydration(rect);
|
|
86
|
+
if (isRLLPlaceholder && isInIgnoreLsMarker) {
|
|
87
|
+
return 'mutation:rll-placeholder';
|
|
88
|
+
}
|
|
89
|
+
const wasDeleted = removedNodeRects.some(nr => isSameRectDimensions(nr, rect));
|
|
90
|
+
if (wasDeleted && isInIgnoreLsMarker) {
|
|
91
|
+
return 'mutation:element-replacement';
|
|
92
|
+
}
|
|
93
|
+
return 'mutation:element';
|
|
94
|
+
};
|
|
34
95
|
export default class ViewportObserver {
|
|
35
96
|
// SSR context functions
|
|
36
97
|
|
|
@@ -81,96 +142,112 @@ export default class ViewportObserver {
|
|
|
81
142
|
if (!addedNode) {
|
|
82
143
|
continue;
|
|
83
144
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
const ssrState = this.getSSRState();
|
|
91
|
-
const SSRStateEnum = {
|
|
92
|
-
normal: 1,
|
|
93
|
-
waitingForFirstRender: 2,
|
|
94
|
-
ignoring: 3
|
|
95
|
-
};
|
|
96
|
-
if (ssrState.state === SSRStateEnum.waitingForFirstRender && timestamp > ssrState.renderStart && targetNode === ssrState.reactRootElement) {
|
|
97
|
-
var _this$intersectionObs;
|
|
98
|
-
ssrState.state = SSRStateEnum.ignoring;
|
|
99
|
-
if (ssrState.renderStop === -1) {
|
|
100
|
-
// arbitrary 500ms DOM update window
|
|
101
|
-
ssrState.renderStop = timestamp + 500;
|
|
102
|
-
}
|
|
103
|
-
(_this$intersectionObs = this.intersectionObserver) === null || _this$intersectionObs === void 0 ? void 0 : _this$intersectionObs.watchAndTag(element, 'ssr-hydration');
|
|
104
|
-
continue;
|
|
145
|
+
if (fg('platform_ufo_detect_zero_dimension_rectangles')) {
|
|
146
|
+
var _this$getSSRState, _this$getSSRState$cal, _this$intersectionObs;
|
|
147
|
+
const hasSameDeletedNode = removedNodes.find(ref => {
|
|
148
|
+
const n = ref.deref();
|
|
149
|
+
if (!n || !addedNode) {
|
|
150
|
+
return false;
|
|
105
151
|
}
|
|
106
|
-
|
|
107
|
-
|
|
152
|
+
return n.isEqualNode(addedNode);
|
|
153
|
+
});
|
|
154
|
+
const {
|
|
155
|
+
isWithin: isWithinThirdPartySegment
|
|
156
|
+
} = checkWithinComponent(addedNode, 'UFOThirdPartySegment', this.mapIs3pResult);
|
|
157
|
+
const isTargetReactRoot = targetNode === ((_this$getSSRState = this.getSSRState) === null || _this$getSSRState === void 0 ? void 0 : (_this$getSSRState$cal = _this$getSSRState.call(this)) === null || _this$getSSRState$cal === void 0 ? void 0 : _this$getSSRState$cal.reactRootElement);
|
|
158
|
+
(_this$intersectionObs = this.intersectionObserver) === null || _this$intersectionObs === void 0 ? void 0 : _this$intersectionObs.watchAndTag(addedNode, createElementMutationsWatcherV4(removedNodeRects, isWithinThirdPartySegment, !!hasSameDeletedNode, timestamp, isTargetReactRoot, this.getSSRState, this.getSSRPlaceholderHandler));
|
|
159
|
+
} else {
|
|
160
|
+
for (const {
|
|
161
|
+
isDisplayContentsElementChildren,
|
|
162
|
+
element
|
|
163
|
+
} of getMutatedElements(addedNode)) {
|
|
164
|
+
// SSR hydration logic
|
|
165
|
+
if (this.getSSRState) {
|
|
166
|
+
const ssrState = this.getSSRState();
|
|
167
|
+
const SSRStateEnum = {
|
|
168
|
+
normal: 1,
|
|
169
|
+
waitingForFirstRender: 2,
|
|
170
|
+
ignoring: 3
|
|
171
|
+
};
|
|
172
|
+
if (ssrState.state === SSRStateEnum.waitingForFirstRender && timestamp > ssrState.renderStart && targetNode === ssrState.reactRootElement) {
|
|
108
173
|
var _this$intersectionObs2;
|
|
174
|
+
ssrState.state = SSRStateEnum.ignoring;
|
|
175
|
+
if (ssrState.renderStop === -1) {
|
|
176
|
+
// arbitrary 500ms DOM update window
|
|
177
|
+
ssrState.renderStop = timestamp + 500;
|
|
178
|
+
}
|
|
109
179
|
(_this$intersectionObs2 = this.intersectionObserver) === null || _this$intersectionObs2 === void 0 ? void 0 : _this$intersectionObs2.watchAndTag(element, 'ssr-hydration');
|
|
110
180
|
continue;
|
|
111
|
-
} else {
|
|
112
|
-
ssrState.state = SSRStateEnum.normal;
|
|
113
181
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
// SSR placeholder logic - check and handle with await
|
|
118
|
-
if (this.getSSRPlaceholderHandler) {
|
|
119
|
-
const ssrPlaceholderHandler = this.getSSRPlaceholderHandler();
|
|
120
|
-
if (ssrPlaceholderHandler) {
|
|
121
|
-
if (ssrPlaceholderHandler.isPlaceholder(element) || ssrPlaceholderHandler.isPlaceholderIgnored(element)) {
|
|
122
|
-
if (ssrPlaceholderHandler.checkIfExistedAndSizeMatchingV3(element)) {
|
|
182
|
+
if (ssrState.state === SSRStateEnum.ignoring && timestamp > ssrState.renderStart && targetNode === ssrState.reactRootElement) {
|
|
183
|
+
if (timestamp <= ssrState.renderStop) {
|
|
123
184
|
var _this$intersectionObs3;
|
|
124
|
-
(_this$intersectionObs3 = this.intersectionObserver) === null || _this$intersectionObs3 === void 0 ? void 0 : _this$intersectionObs3.watchAndTag(element, '
|
|
185
|
+
(_this$intersectionObs3 = this.intersectionObserver) === null || _this$intersectionObs3 === void 0 ? void 0 : _this$intersectionObs3.watchAndTag(element, 'ssr-hydration');
|
|
125
186
|
continue;
|
|
187
|
+
} else {
|
|
188
|
+
ssrState.state = SSRStateEnum.normal;
|
|
126
189
|
}
|
|
127
|
-
// If result is false, continue to normal mutation logic below
|
|
128
190
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// SSR placeholder logic - check and handle with await
|
|
194
|
+
if (this.getSSRPlaceholderHandler) {
|
|
195
|
+
const ssrPlaceholderHandler = this.getSSRPlaceholderHandler();
|
|
196
|
+
if (ssrPlaceholderHandler) {
|
|
197
|
+
if (ssrPlaceholderHandler.isPlaceholder(element) || ssrPlaceholderHandler.isPlaceholderIgnored(element)) {
|
|
198
|
+
if (ssrPlaceholderHandler.checkIfExistedAndSizeMatchingV3(element)) {
|
|
199
|
+
var _this$intersectionObs4;
|
|
200
|
+
(_this$intersectionObs4 = this.intersectionObserver) === null || _this$intersectionObs4 === void 0 ? void 0 : _this$intersectionObs4.watchAndTag(element, 'mutation:ssr-placeholder');
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
// If result is false, continue to normal mutation logic below
|
|
204
|
+
}
|
|
205
|
+
if (ssrPlaceholderHandler.isPlaceholderReplacement(element) || ssrPlaceholderHandler.isPlaceholderIgnored(element)) {
|
|
206
|
+
const result = await ssrPlaceholderHandler.validateReactComponentMatchToPlaceholder(element);
|
|
207
|
+
if (result !== false) {
|
|
208
|
+
var _this$intersectionObs5;
|
|
209
|
+
(_this$intersectionObs5 = this.intersectionObserver) === null || _this$intersectionObs5 === void 0 ? void 0 : _this$intersectionObs5.watchAndTag(element, 'mutation:ssr-placeholder');
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
// If result is false, continue to normal mutation logic below
|
|
135
213
|
}
|
|
136
|
-
// If result is false, continue to normal mutation logic below
|
|
137
214
|
}
|
|
138
215
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
216
|
+
const sameDeletedNode = removedNodes.find(ref => {
|
|
217
|
+
const n = ref.deref();
|
|
218
|
+
if (!n || !element) {
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
return n.isEqualNode(element);
|
|
222
|
+
});
|
|
223
|
+
const isInIgnoreLsMarker = element instanceof HTMLElement ? isInVCIgnoreIfNoLayoutShiftMarker(element) : false;
|
|
224
|
+
if (sameDeletedNode && isInIgnoreLsMarker) {
|
|
225
|
+
var _this$intersectionObs6;
|
|
226
|
+
(_this$intersectionObs6 = this.intersectionObserver) === null || _this$intersectionObs6 === void 0 ? void 0 : _this$intersectionObs6.watchAndTag(element, 'mutation:remount');
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
if (isContainedWithinMediaWrapper(element)) {
|
|
230
|
+
var _this$intersectionObs7;
|
|
231
|
+
(_this$intersectionObs7 = this.intersectionObserver) === null || _this$intersectionObs7 === void 0 ? void 0 : _this$intersectionObs7.watchAndTag(element, 'mutation:media');
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
const {
|
|
235
|
+
isWithin: isWithinThirdPartySegment
|
|
236
|
+
} = element instanceof HTMLElement ? checkWithinComponent(element, 'UFOThirdPartySegment', this.mapIs3pResult) : {
|
|
237
|
+
isWithin: false
|
|
238
|
+
};
|
|
239
|
+
if (isWithinThirdPartySegment) {
|
|
240
|
+
var _this$intersectionObs8;
|
|
241
|
+
(_this$intersectionObs8 = this.intersectionObserver) === null || _this$intersectionObs8 === void 0 ? void 0 : _this$intersectionObs8.watchAndTag(element, 'mutation:third-party-element');
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
if (isDisplayContentsElementChildren) {
|
|
245
|
+
var _this$intersectionObs9;
|
|
246
|
+
(_this$intersectionObs9 = this.intersectionObserver) === null || _this$intersectionObs9 === void 0 ? void 0 : _this$intersectionObs9.watchAndTag(element, 'mutation:display-contents-children-element');
|
|
247
|
+
} else {
|
|
248
|
+
var _this$intersectionObs0;
|
|
249
|
+
(_this$intersectionObs0 = this.intersectionObserver) === null || _this$intersectionObs0 === void 0 ? void 0 : _this$intersectionObs0.watchAndTag(element, createElementMutationsWatcher(removedNodeRects));
|
|
144
250
|
}
|
|
145
|
-
return n.isEqualNode(element);
|
|
146
|
-
});
|
|
147
|
-
const isInIgnoreLsMarker = element instanceof HTMLElement ? isInVCIgnoreIfNoLayoutShiftMarker(element) : false;
|
|
148
|
-
if (sameDeletedNode && isInIgnoreLsMarker) {
|
|
149
|
-
var _this$intersectionObs5;
|
|
150
|
-
(_this$intersectionObs5 = this.intersectionObserver) === null || _this$intersectionObs5 === void 0 ? void 0 : _this$intersectionObs5.watchAndTag(element, 'mutation:remount');
|
|
151
|
-
continue;
|
|
152
|
-
}
|
|
153
|
-
if (isContainedWithinMediaWrapper(element)) {
|
|
154
|
-
var _this$intersectionObs6;
|
|
155
|
-
(_this$intersectionObs6 = this.intersectionObserver) === null || _this$intersectionObs6 === void 0 ? void 0 : _this$intersectionObs6.watchAndTag(element, 'mutation:media');
|
|
156
|
-
continue;
|
|
157
|
-
}
|
|
158
|
-
const {
|
|
159
|
-
isWithin: isWithinThirdPartySegment
|
|
160
|
-
} = element instanceof HTMLElement ? checkWithinComponent(element, 'UFOThirdPartySegment', this.mapIs3pResult) : {
|
|
161
|
-
isWithin: false
|
|
162
|
-
};
|
|
163
|
-
if (isWithinThirdPartySegment) {
|
|
164
|
-
var _this$intersectionObs7;
|
|
165
|
-
(_this$intersectionObs7 = this.intersectionObserver) === null || _this$intersectionObs7 === void 0 ? void 0 : _this$intersectionObs7.watchAndTag(element, 'mutation:third-party-element');
|
|
166
|
-
continue;
|
|
167
|
-
}
|
|
168
|
-
if (isDisplayContentsElementChildren) {
|
|
169
|
-
var _this$intersectionObs8;
|
|
170
|
-
(_this$intersectionObs8 = this.intersectionObserver) === null || _this$intersectionObs8 === void 0 ? void 0 : _this$intersectionObs8.watchAndTag(element, 'mutation:display-contents-children-element');
|
|
171
|
-
} else {
|
|
172
|
-
var _this$intersectionObs9;
|
|
173
|
-
(_this$intersectionObs9 = this.intersectionObserver) === null || _this$intersectionObs9 === void 0 ? void 0 : _this$intersectionObs9.watchAndTag(element, createElementMutationsWatcher(removedNodeRects));
|
|
174
251
|
}
|
|
175
252
|
}
|
|
176
253
|
}
|
|
@@ -181,8 +258,8 @@ export default class ViewportObserver {
|
|
|
181
258
|
oldValue,
|
|
182
259
|
newValue
|
|
183
260
|
}) => {
|
|
184
|
-
var _this$
|
|
185
|
-
(_this$
|
|
261
|
+
var _this$intersectionObs1;
|
|
262
|
+
(_this$intersectionObs1 = this.intersectionObserver) === null || _this$intersectionObs1 === void 0 ? void 0 : _this$intersectionObs1.watchAndTag(target, ({
|
|
186
263
|
target,
|
|
187
264
|
rect
|
|
188
265
|
}) => {
|
|
@@ -339,12 +416,12 @@ export default class ViewportObserver {
|
|
|
339
416
|
this.isStarted = true;
|
|
340
417
|
}
|
|
341
418
|
stop() {
|
|
342
|
-
var _this$mutationObserve2, _this$
|
|
419
|
+
var _this$mutationObserve2, _this$intersectionObs10, _this$performanceObse2;
|
|
343
420
|
if (!this.isStarted) {
|
|
344
421
|
return;
|
|
345
422
|
}
|
|
346
423
|
(_this$mutationObserve2 = this.mutationObserver) === null || _this$mutationObserve2 === void 0 ? void 0 : _this$mutationObserve2.disconnect();
|
|
347
|
-
(_this$
|
|
424
|
+
(_this$intersectionObs10 = this.intersectionObserver) === null || _this$intersectionObs10 === void 0 ? void 0 : _this$intersectionObs10.disconnect();
|
|
348
425
|
(_this$performanceObse2 = this.performanceObserver) === null || _this$performanceObse2 === void 0 ? void 0 : _this$performanceObse2.disconnect();
|
|
349
426
|
this.isStarted = false;
|
|
350
427
|
// Clean up caches when stopping
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
2
|
+
import { isZeroDimensionRectangle } from '../utils/is-zero-dimension-rectangle';
|
|
1
3
|
function isValidEntry(entry) {
|
|
2
4
|
return entry.isIntersecting && entry.intersectionRect.width > 0 && entry.intersectionRect.height > 0;
|
|
3
5
|
}
|
|
@@ -14,12 +16,41 @@ export function createIntersectionObserver({
|
|
|
14
16
|
const startTime = performance.now();
|
|
15
17
|
entries.forEach(entry => {
|
|
16
18
|
var _mutationTag;
|
|
17
|
-
if (!(entry.target instanceof HTMLElement)
|
|
19
|
+
if (!(entry.target instanceof HTMLElement)) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const tagOrCallback = callbacksPerElement.get(entry.target);
|
|
23
|
+
if (fg('platform_ufo_detect_zero_dimension_rectangles')) {
|
|
24
|
+
if (isZeroDimensionRectangle(entry.intersectionRect)) {
|
|
25
|
+
const zeroDimensionRectangleTagCallback = props => {
|
|
26
|
+
const tagOrCallbackResult = typeof tagOrCallback === 'function' ? tagOrCallback(props) : tagOrCallback;
|
|
27
|
+
|
|
28
|
+
// override as display-contents mutation
|
|
29
|
+
if (tagOrCallbackResult === 'mutation:element') {
|
|
30
|
+
return 'mutation:display-contents-children-element';
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// override as display-contents mutation
|
|
34
|
+
if (tagOrCallbackResult && typeof tagOrCallbackResult !== 'string' && tagOrCallbackResult.type === 'mutation:attribute') {
|
|
35
|
+
return {
|
|
36
|
+
type: 'mutation:display-contents-children-attribute',
|
|
37
|
+
mutationData: tagOrCallbackResult.mutationData
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
return tagOrCallbackResult;
|
|
41
|
+
};
|
|
42
|
+
for (const child of entry.target.children) {
|
|
43
|
+
observer.observe(child);
|
|
44
|
+
callbacksPerElement.set(child, zeroDimensionRectangleTagCallback);
|
|
45
|
+
}
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (!isValidEntry(entry)) {
|
|
18
50
|
return;
|
|
19
51
|
}
|
|
20
52
|
let mutationTag = null;
|
|
21
53
|
let mutationData = null;
|
|
22
|
-
const tagOrCallback = callbacksPerElement.get(entry.target);
|
|
23
54
|
if (typeof tagOrCallback === 'function') {
|
|
24
55
|
const tagOrCallbackResult = tagOrCallback({
|
|
25
56
|
target: entry.target,
|
|
@@ -1,19 +1,30 @@
|
|
|
1
1
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
2
|
+
function isElementStyledWithDisplayContents(element) {
|
|
3
|
+
var _window2, _window2$getComputedS;
|
|
4
|
+
// To minimise calling `getComputedStyle`, we are making an assumption that if an element is from the Entrypoints framework, then it will have `display: contents` styling
|
|
5
|
+
// as per https://bitbucket.org/atlassian/atlassian-frontend-monorepo/src/e4ccf437262ef4c0fd3c651ffb7ad4770b15aed4/jira/src/packages/platform/entry-points/entry-point-placeholder/src/index.tsx#lines-136
|
|
6
|
+
if (fg('platform_ufo_detect_entrypoint_parent')) {
|
|
7
|
+
var _window, _window$getComputedSt;
|
|
8
|
+
if (element.hasAttribute('data-ep-placeholder-id')) {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
return ((_window = window) === null || _window === void 0 ? void 0 : (_window$getComputedSt = _window.getComputedStyle(element)) === null || _window$getComputedSt === void 0 ? void 0 : _window$getComputedSt.display) === 'contents';
|
|
12
|
+
}
|
|
13
|
+
return ((_window2 = window) === null || _window2 === void 0 ? void 0 : (_window2$getComputedS = _window2.getComputedStyle(element)) === null || _window2$getComputedS === void 0 ? void 0 : _window2$getComputedS.display) === 'contents';
|
|
14
|
+
}
|
|
2
15
|
const MAX_NESTED_LEVELS_OF_DISPLAY_CONTENT_ELEMENTS_HANDLED = 3;
|
|
3
16
|
export function getMutatedElements(element, depthLevel = 0) {
|
|
4
|
-
var _window, _window$getComputedSt;
|
|
5
17
|
if (fg('platform_ufo_disable_vcnext_observations')) {
|
|
6
18
|
return [{
|
|
7
19
|
element,
|
|
8
20
|
isDisplayContentsElementChildren: false
|
|
9
21
|
}];
|
|
10
22
|
}
|
|
11
|
-
if ((
|
|
23
|
+
if (isElementStyledWithDisplayContents(element)) {
|
|
12
24
|
const mutatedElements = [];
|
|
13
25
|
const nestedDisplayContentsElementChildren = [];
|
|
14
26
|
for (const child of element.children) {
|
|
15
|
-
|
|
16
|
-
if (((_window2 = window) === null || _window2 === void 0 ? void 0 : (_window2$getComputedS = _window2.getComputedStyle(child)) === null || _window2$getComputedS === void 0 ? void 0 : _window2$getComputedS.display) === 'contents') {
|
|
27
|
+
if (isElementStyledWithDisplayContents(child)) {
|
|
17
28
|
nestedDisplayContentsElementChildren.push(child);
|
|
18
29
|
}
|
|
19
30
|
mutatedElements.push({
|
|
@@ -266,6 +266,13 @@ export var SSRPlaceholderHandlers = /*#__PURE__*/function () {
|
|
|
266
266
|
}
|
|
267
267
|
});
|
|
268
268
|
}
|
|
269
|
+
}, {
|
|
270
|
+
key: "validateReactComponentMatchToPlaceholderV4",
|
|
271
|
+
value: function validateReactComponentMatchToPlaceholderV4(el) {
|
|
272
|
+
el = this.findNearestPlaceholderContainerIfIgnored(el);
|
|
273
|
+
var id = this.getPlaceholderReplacementId(el);
|
|
274
|
+
return this.staticPlaceholders.has(id);
|
|
275
|
+
}
|
|
269
276
|
}, {
|
|
270
277
|
key: "hasSameSizePosition",
|
|
271
278
|
value: function hasSameSizePosition(rect, boundingClientRect) {
|
|
@@ -17,7 +17,10 @@ var getConsideredEntryTypes = function getConsideredEntryTypes() {
|
|
|
17
17
|
if (fg('platform_ufo_remove_ssr_placeholder_in_ttvc_v4')) {
|
|
18
18
|
consideredEntryTypes.push('mutation:ssr-placeholder');
|
|
19
19
|
}
|
|
20
|
-
|
|
20
|
+
if (fg('platform_ufo_detect_zero_dimension_rectangles')) {
|
|
21
|
+
consideredEntryTypes.push('mutation:display-contents-children-attribute');
|
|
22
|
+
}
|
|
23
|
+
return consideredEntryTypes;
|
|
21
24
|
};
|
|
22
25
|
var getExcludedEntryTypes = function getExcludedEntryTypes() {
|
|
23
26
|
var excludedEntryTypes = ['layout-shift:same-rect'];
|