@atlaskit/react-ufo 4.12.3 → 4.12.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 +14 -0
- package/dist/cjs/create-payload/utils/get-browser-metadata.js +9 -0
- package/dist/cjs/vc/vc-observer/observers/ssr-placeholders/index.js +53 -3
- package/dist/cjs/vc/vc-observer/observers/ssr-placeholders/ssr-scripts/collectSSRPlaceholderDimensions.js +54 -4
- package/dist/cjs/vc/vc-observer-new/viewport-observer/index.js +247 -89
- package/dist/es2019/create-payload/utils/get-browser-metadata.js +9 -0
- package/dist/es2019/vc/vc-observer/observers/ssr-placeholders/index.js +51 -3
- package/dist/es2019/vc/vc-observer/observers/ssr-placeholders/ssr-scripts/collectSSRPlaceholderDimensions.js +55 -4
- package/dist/es2019/vc/vc-observer-new/viewport-observer/index.js +175 -80
- package/dist/esm/create-payload/utils/get-browser-metadata.js +9 -0
- package/dist/esm/vc/vc-observer/observers/ssr-placeholders/index.js +53 -3
- package/dist/esm/vc/vc-observer/observers/ssr-placeholders/ssr-scripts/collectSSRPlaceholderDimensions.js +55 -4
- package/dist/esm/vc/vc-observer-new/viewport-observer/index.js +247 -89
- package/dist/types/common/react-ufo-payload-schema.d.ts +1 -0
- package/dist/types/create-payload/utils/get-browser-metadata.d.ts +1 -0
- package/dist/types/resource-timing/index.d.ts +1 -1
- package/dist/types/vc/vc-observer/observers/ssr-placeholders/index.d.ts +5 -0
- package/dist/types-ts4.5/common/react-ufo-payload-schema.d.ts +1 -0
- package/dist/types-ts4.5/create-payload/utils/get-browser-metadata.d.ts +1 -0
- package/dist/types-ts4.5/resource-timing/index.d.ts +1 -1
- package/dist/types-ts4.5/vc/vc-observer/observers/ssr-placeholders/index.d.ts +5 -0
- package/package.json +8 -1
|
@@ -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
|
-
|
|
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
|
-
|
|
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 _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 isDnDStyleMutation from '../../vc-observer/observers/non-visual-styles/is-dnd-style-mutation';
|
|
4
5
|
import isNonVisualStyleMutation from '../../vc-observer/observers/non-visual-styles/is-non-visual-style-mutation';
|
|
@@ -80,95 +81,189 @@ export default class ViewportObserver {
|
|
|
80
81
|
if (!addedNode) {
|
|
81
82
|
continue;
|
|
82
83
|
}
|
|
84
|
+
if (fg('platform_ufo_ssr_placeholders_for_display_contents')) {
|
|
85
|
+
for (const {
|
|
86
|
+
isDisplayContentsElementChildren,
|
|
87
|
+
element
|
|
88
|
+
} of getMutatedElements(addedNode)) {
|
|
89
|
+
// SSR hydration logic
|
|
90
|
+
if (this.getSSRState) {
|
|
91
|
+
const ssrState = this.getSSRState();
|
|
92
|
+
const SSRStateEnum = {
|
|
93
|
+
normal: 1,
|
|
94
|
+
waitingForFirstRender: 2,
|
|
95
|
+
ignoring: 3
|
|
96
|
+
};
|
|
97
|
+
if (ssrState.state === SSRStateEnum.waitingForFirstRender && timestamp > ssrState.renderStart && targetNode === ssrState.reactRootElement) {
|
|
98
|
+
var _this$intersectionObs;
|
|
99
|
+
ssrState.state = SSRStateEnum.ignoring;
|
|
100
|
+
if (ssrState.renderStop === -1) {
|
|
101
|
+
// arbitrary 500ms DOM update window
|
|
102
|
+
ssrState.renderStop = timestamp + 500;
|
|
103
|
+
}
|
|
104
|
+
(_this$intersectionObs = this.intersectionObserver) === null || _this$intersectionObs === void 0 ? void 0 : _this$intersectionObs.watchAndTag(element, 'ssr-hydration');
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
if (ssrState.state === SSRStateEnum.ignoring && timestamp > ssrState.renderStart && targetNode === ssrState.reactRootElement) {
|
|
108
|
+
if (timestamp <= ssrState.renderStop) {
|
|
109
|
+
var _this$intersectionObs2;
|
|
110
|
+
(_this$intersectionObs2 = this.intersectionObserver) === null || _this$intersectionObs2 === void 0 ? void 0 : _this$intersectionObs2.watchAndTag(element, 'ssr-hydration');
|
|
111
|
+
continue;
|
|
112
|
+
} else {
|
|
113
|
+
ssrState.state = SSRStateEnum.normal;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
83
117
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
118
|
+
// SSR placeholder logic - check and handle with await
|
|
119
|
+
if (this.getSSRPlaceholderHandler) {
|
|
120
|
+
const ssrPlaceholderHandler = this.getSSRPlaceholderHandler();
|
|
121
|
+
if (ssrPlaceholderHandler) {
|
|
122
|
+
if (ssrPlaceholderHandler.isPlaceholder(element) || ssrPlaceholderHandler.isPlaceholderIgnored(element)) {
|
|
123
|
+
if (ssrPlaceholderHandler.checkIfExistedAndSizeMatchingV3(element)) {
|
|
124
|
+
var _this$intersectionObs3;
|
|
125
|
+
(_this$intersectionObs3 = this.intersectionObserver) === null || _this$intersectionObs3 === void 0 ? void 0 : _this$intersectionObs3.watchAndTag(element, 'mutation:ssr-placeholder');
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
// If result is false, continue to normal mutation logic below
|
|
129
|
+
}
|
|
130
|
+
if (ssrPlaceholderHandler.isPlaceholderReplacement(element) || ssrPlaceholderHandler.isPlaceholderIgnored(element)) {
|
|
131
|
+
const result = await ssrPlaceholderHandler.validateReactComponentMatchToPlaceholder(element);
|
|
132
|
+
if (result !== false) {
|
|
133
|
+
var _this$intersectionObs4;
|
|
134
|
+
(_this$intersectionObs4 = this.intersectionObserver) === null || _this$intersectionObs4 === void 0 ? void 0 : _this$intersectionObs4.watchAndTag(element, 'mutation:ssr-placeholder');
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
// If result is false, continue to normal mutation logic below
|
|
138
|
+
}
|
|
139
|
+
}
|
|
98
140
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
141
|
+
const sameDeletedNode = removedNodes.find(ref => {
|
|
142
|
+
const n = ref.deref();
|
|
143
|
+
if (!n || !element) {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
return n.isEqualNode(element);
|
|
147
|
+
});
|
|
148
|
+
const isInIgnoreLsMarker = element instanceof HTMLElement ? isInVCIgnoreIfNoLayoutShiftMarker(element) : false;
|
|
149
|
+
if (sameDeletedNode && isInIgnoreLsMarker) {
|
|
150
|
+
var _this$intersectionObs5;
|
|
151
|
+
(_this$intersectionObs5 = this.intersectionObserver) === null || _this$intersectionObs5 === void 0 ? void 0 : _this$intersectionObs5.watchAndTag(element, 'mutation:remount');
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
if (isContainedWithinMediaWrapper(element)) {
|
|
155
|
+
var _this$intersectionObs6;
|
|
156
|
+
(_this$intersectionObs6 = this.intersectionObserver) === null || _this$intersectionObs6 === void 0 ? void 0 : _this$intersectionObs6.watchAndTag(element, 'mutation:media');
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
const {
|
|
160
|
+
isWithin: isWithinThirdPartySegment
|
|
161
|
+
} = element instanceof HTMLElement ? checkWithinComponent(element, 'UFOThirdPartySegment', this.mapIs3pResult) : {
|
|
162
|
+
isWithin: false
|
|
163
|
+
};
|
|
164
|
+
if (isWithinThirdPartySegment) {
|
|
165
|
+
var _this$intersectionObs7;
|
|
166
|
+
(_this$intersectionObs7 = this.intersectionObserver) === null || _this$intersectionObs7 === void 0 ? void 0 : _this$intersectionObs7.watchAndTag(element, 'mutation:third-party-element');
|
|
106
167
|
continue;
|
|
168
|
+
}
|
|
169
|
+
if (isDisplayContentsElementChildren) {
|
|
170
|
+
var _this$intersectionObs8;
|
|
171
|
+
(_this$intersectionObs8 = this.intersectionObserver) === null || _this$intersectionObs8 === void 0 ? void 0 : _this$intersectionObs8.watchAndTag(element, 'mutation:display-contents-children-element');
|
|
107
172
|
} else {
|
|
108
|
-
|
|
173
|
+
var _this$intersectionObs9;
|
|
174
|
+
(_this$intersectionObs9 = this.intersectionObserver) === null || _this$intersectionObs9 === void 0 ? void 0 : _this$intersectionObs9.watchAndTag(element, createElementMutationsWatcher(removedNodeRects));
|
|
109
175
|
}
|
|
110
176
|
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
177
|
+
} else {
|
|
178
|
+
// SSR hydration logic
|
|
179
|
+
if (this.getSSRState) {
|
|
180
|
+
const ssrState = this.getSSRState();
|
|
181
|
+
const SSRStateEnum = {
|
|
182
|
+
normal: 1,
|
|
183
|
+
waitingForFirstRender: 2,
|
|
184
|
+
ignoring: 3
|
|
185
|
+
};
|
|
186
|
+
if (ssrState.state === SSRStateEnum.waitingForFirstRender && timestamp > ssrState.renderStart && targetNode === ssrState.reactRootElement) {
|
|
187
|
+
var _this$intersectionObs0;
|
|
188
|
+
ssrState.state = SSRStateEnum.ignoring;
|
|
189
|
+
if (ssrState.renderStop === -1) {
|
|
190
|
+
// arbitrary 500ms DOM update window
|
|
191
|
+
ssrState.renderStop = timestamp + 500;
|
|
122
192
|
}
|
|
123
|
-
|
|
193
|
+
(_this$intersectionObs0 = this.intersectionObserver) === null || _this$intersectionObs0 === void 0 ? void 0 : _this$intersectionObs0.watchAndTag(addedNode, 'ssr-hydration');
|
|
194
|
+
continue;
|
|
124
195
|
}
|
|
125
|
-
if (
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
(_this$intersectionObs4 = this.intersectionObserver) === null || _this$intersectionObs4 === void 0 ? void 0 : _this$intersectionObs4.watchAndTag(addedNode, 'mutation:ssr-placeholder');
|
|
196
|
+
if (ssrState.state === SSRStateEnum.ignoring && timestamp > ssrState.renderStart && targetNode === ssrState.reactRootElement) {
|
|
197
|
+
if (timestamp <= ssrState.renderStop) {
|
|
198
|
+
var _this$intersectionObs1;
|
|
199
|
+
(_this$intersectionObs1 = this.intersectionObserver) === null || _this$intersectionObs1 === void 0 ? void 0 : _this$intersectionObs1.watchAndTag(addedNode, 'ssr-hydration');
|
|
130
200
|
continue;
|
|
201
|
+
} else {
|
|
202
|
+
ssrState.state = SSRStateEnum.normal;
|
|
131
203
|
}
|
|
132
|
-
// If result is false, continue to normal mutation logic below
|
|
133
204
|
}
|
|
134
205
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
206
|
+
|
|
207
|
+
// SSR placeholder logic - check and handle with await
|
|
208
|
+
if (this.getSSRPlaceholderHandler) {
|
|
209
|
+
const ssrPlaceholderHandler = this.getSSRPlaceholderHandler();
|
|
210
|
+
if (ssrPlaceholderHandler) {
|
|
211
|
+
if (ssrPlaceholderHandler.isPlaceholder(addedNode) || ssrPlaceholderHandler.isPlaceholderIgnored(addedNode)) {
|
|
212
|
+
if (ssrPlaceholderHandler.checkIfExistedAndSizeMatchingV3(addedNode)) {
|
|
213
|
+
var _this$intersectionObs10;
|
|
214
|
+
(_this$intersectionObs10 = this.intersectionObserver) === null || _this$intersectionObs10 === void 0 ? void 0 : _this$intersectionObs10.watchAndTag(addedNode, 'mutation:ssr-placeholder');
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
// If result is false, continue to normal mutation logic below
|
|
218
|
+
}
|
|
219
|
+
if (ssrPlaceholderHandler.isPlaceholderReplacement(addedNode) || ssrPlaceholderHandler.isPlaceholderIgnored(addedNode)) {
|
|
220
|
+
const result = await ssrPlaceholderHandler.validateReactComponentMatchToPlaceholder(addedNode);
|
|
221
|
+
if (result !== false) {
|
|
222
|
+
var _this$intersectionObs11;
|
|
223
|
+
(_this$intersectionObs11 = this.intersectionObserver) === null || _this$intersectionObs11 === void 0 ? void 0 : _this$intersectionObs11.watchAndTag(addedNode, 'mutation:ssr-placeholder');
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
// If result is false, continue to normal mutation logic below
|
|
227
|
+
}
|
|
228
|
+
}
|
|
140
229
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
(
|
|
230
|
+
const sameDeletedNode = removedNodes.find(ref => {
|
|
231
|
+
const n = ref.deref();
|
|
232
|
+
if (!n || !addedNode) {
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
return n.isEqualNode(addedNode);
|
|
236
|
+
});
|
|
237
|
+
const isInIgnoreLsMarker = isInVCIgnoreIfNoLayoutShiftMarker(addedNode);
|
|
238
|
+
if (sameDeletedNode && isInIgnoreLsMarker) {
|
|
239
|
+
var _this$intersectionObs12;
|
|
240
|
+
(_this$intersectionObs12 = this.intersectionObserver) === null || _this$intersectionObs12 === void 0 ? void 0 : _this$intersectionObs12.watchAndTag(addedNode, 'mutation:remount');
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
if (isContainedWithinMediaWrapper(addedNode)) {
|
|
244
|
+
var _this$intersectionObs13;
|
|
245
|
+
(_this$intersectionObs13 = this.intersectionObserver) === null || _this$intersectionObs13 === void 0 ? void 0 : _this$intersectionObs13.watchAndTag(addedNode, 'mutation:media');
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
const {
|
|
249
|
+
isWithin: isWithinThirdPartySegment
|
|
250
|
+
} = checkWithinComponent(addedNode, 'UFOThirdPartySegment', this.mapIs3pResult);
|
|
251
|
+
if (isWithinThirdPartySegment) {
|
|
252
|
+
var _this$intersectionObs14;
|
|
253
|
+
(_this$intersectionObs14 = this.intersectionObserver) === null || _this$intersectionObs14 === void 0 ? void 0 : _this$intersectionObs14.watchAndTag(addedNode, 'mutation:third-party-element');
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
for (const {
|
|
257
|
+
isDisplayContentsElementChildren,
|
|
258
|
+
element
|
|
259
|
+
} of getMutatedElements(addedNode)) {
|
|
260
|
+
if (isDisplayContentsElementChildren) {
|
|
261
|
+
var _this$intersectionObs15;
|
|
262
|
+
(_this$intersectionObs15 = this.intersectionObserver) === null || _this$intersectionObs15 === void 0 ? void 0 : _this$intersectionObs15.watchAndTag(element, 'mutation:display-contents-children-element');
|
|
263
|
+
} else {
|
|
264
|
+
var _this$intersectionObs16;
|
|
265
|
+
(_this$intersectionObs16 = this.intersectionObserver) === null || _this$intersectionObs16 === void 0 ? void 0 : _this$intersectionObs16.watchAndTag(element, createElementMutationsWatcher(removedNodeRects));
|
|
266
|
+
}
|
|
172
267
|
}
|
|
173
268
|
}
|
|
174
269
|
}
|
|
@@ -179,8 +274,8 @@ export default class ViewportObserver {
|
|
|
179
274
|
oldValue,
|
|
180
275
|
newValue
|
|
181
276
|
}) => {
|
|
182
|
-
var _this$
|
|
183
|
-
(_this$
|
|
277
|
+
var _this$intersectionObs17;
|
|
278
|
+
(_this$intersectionObs17 = this.intersectionObserver) === null || _this$intersectionObs17 === void 0 ? void 0 : _this$intersectionObs17.watchAndTag(target, ({
|
|
184
279
|
target,
|
|
185
280
|
rect
|
|
186
281
|
}) => {
|
|
@@ -322,12 +417,12 @@ export default class ViewportObserver {
|
|
|
322
417
|
this.isStarted = true;
|
|
323
418
|
}
|
|
324
419
|
stop() {
|
|
325
|
-
var _this$mutationObserve2, _this$
|
|
420
|
+
var _this$mutationObserve2, _this$intersectionObs18, _this$performanceObse2;
|
|
326
421
|
if (!this.isStarted) {
|
|
327
422
|
return;
|
|
328
423
|
}
|
|
329
424
|
(_this$mutationObserve2 = this.mutationObserver) === null || _this$mutationObserve2 === void 0 ? void 0 : _this$mutationObserve2.disconnect();
|
|
330
|
-
(_this$
|
|
425
|
+
(_this$intersectionObs18 = this.intersectionObserver) === null || _this$intersectionObs18 === void 0 ? void 0 : _this$intersectionObs18.disconnect();
|
|
331
426
|
(_this$performanceObse2 = this.performanceObserver) === null || _this$performanceObse2 === void 0 ? void 0 : _this$performanceObse2.disconnect();
|
|
332
427
|
this.isStarted = false;
|
|
333
428
|
// Clean up caches when stopping
|
|
@@ -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) {
|
|
@@ -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 =
|
|
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 =
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
}
|