@atlaskit/media-file-preview 0.11.6 → 0.11.8
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 +18 -0
- package/dist/cjs/getPreview/getPreview.js +15 -5
- package/dist/cjs/globalScope/globalScope.js +62 -11
- package/dist/cjs/globalScope/printScript.js +2 -1
- package/dist/cjs/useFilePreview.js +25 -6
- package/dist/es2019/getPreview/getPreview.js +16 -5
- package/dist/es2019/globalScope/globalScope.js +52 -10
- package/dist/es2019/globalScope/printScript.js +3 -1
- package/dist/es2019/useFilePreview.js +25 -6
- package/dist/esm/getPreview/getPreview.js +15 -5
- package/dist/esm/globalScope/globalScope.js +61 -11
- package/dist/esm/globalScope/printScript.js +2 -1
- package/dist/esm/useFilePreview.js +25 -6
- package/dist/types/analytics.d.ts +1 -1
- package/dist/types/getPreview/getPreview.d.ts +1 -1
- package/dist/types/getPreview/helpers.d.ts +1 -1
- package/dist/types/globalScope/globalScope.d.ts +6 -2
- package/dist/types/globalScope/printScript.d.ts +1 -1
- package/dist/types/globalScope/types.d.ts +1 -0
- package/dist/types/types.d.ts +1 -0
- package/dist/types/useFilePreview.d.ts +1 -2
- package/dist/types/useMediaImage.d.ts +0 -1
- package/dist/types-ts4.5/analytics.d.ts +1 -1
- package/dist/types-ts4.5/getPreview/getPreview.d.ts +1 -1
- package/dist/types-ts4.5/getPreview/helpers.d.ts +1 -1
- package/dist/types-ts4.5/globalScope/globalScope.d.ts +6 -2
- package/dist/types-ts4.5/globalScope/printScript.d.ts +1 -1
- package/dist/types-ts4.5/globalScope/types.d.ts +1 -0
- package/dist/types-ts4.5/types.d.ts +1 -0
- package/dist/types-ts4.5/useFilePreview.d.ts +1 -2
- package/dist/types-ts4.5/useMediaImage.d.ts +0 -1
- package/package.json +8 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @atlaskit/media-file-preview
|
|
2
2
|
|
|
3
|
+
## 0.11.8
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`eec573b4a7a6a`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/eec573b4a7a6a) -
|
|
8
|
+
Added srcset for Media to remove dual fetching and implememted invisible image along blob
|
|
9
|
+
converison during SSR phase prior to hydration to avoid VC offenses
|
|
10
|
+
- Updated dependencies
|
|
11
|
+
|
|
12
|
+
## 0.11.7
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- [`e0cc5dd07934c`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/e0cc5dd07934c) -
|
|
17
|
+
Fixed perpetual loading of Media Card when SSR failed or when an unsupported media file was
|
|
18
|
+
requested.
|
|
19
|
+
- Updated dependencies
|
|
20
|
+
|
|
3
21
|
## 0.11.6
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
|
@@ -37,17 +37,27 @@ var extendAndCachePreview = function extendAndCachePreview(id, mode, preview, me
|
|
|
37
37
|
dataURI: dataURI
|
|
38
38
|
});
|
|
39
39
|
};
|
|
40
|
+
var getDataUri = function getDataUri(mediaClient, id, params, mediaBlobUrlAttrs) {
|
|
41
|
+
var rawDataURI = mediaClient.getImageUrlSync(id, params);
|
|
42
|
+
return mediaBlobUrlAttrs ? (0, _mediaClient.addFileAttrsToUrl)(rawDataURI, mediaBlobUrlAttrs) : rawDataURI;
|
|
43
|
+
};
|
|
40
44
|
var getSSRPreview = exports.getSSRPreview = function getSSRPreview(ssr, mediaClient, id, params, mediaBlobUrlAttrs) {
|
|
41
|
-
var dataURI;
|
|
42
45
|
try {
|
|
43
|
-
var
|
|
44
|
-
|
|
45
|
-
|
|
46
|
+
var dataURI = getDataUri(mediaClient, id, params, mediaBlobUrlAttrs);
|
|
47
|
+
var srcSet = "".concat(dataURI, " 1x");
|
|
48
|
+
if (params.width) {
|
|
49
|
+
var doubleDataURI = getDataUri(mediaClient, id, _objectSpread(_objectSpread({}, params), {}, {
|
|
50
|
+
width: params.width * 2
|
|
51
|
+
}), mediaBlobUrlAttrs);
|
|
52
|
+
// We want to embed some meta context into dataURI for Copy/Paste to work.
|
|
53
|
+
srcSet += ", ".concat(doubleDataURI, " 2x");
|
|
54
|
+
}
|
|
46
55
|
var source = ssr === 'client' ? 'ssr-client' : 'ssr-server';
|
|
47
56
|
return {
|
|
48
57
|
dataURI: dataURI,
|
|
49
58
|
source: source,
|
|
50
|
-
orientation: 1
|
|
59
|
+
orientation: 1,
|
|
60
|
+
srcSet: srcSet
|
|
51
61
|
};
|
|
52
62
|
} catch (e) {
|
|
53
63
|
var reason = ssr === 'server' ? 'ssr-server-uri' : 'ssr-client-uri';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
3
4
|
Object.defineProperty(exports, "__esModule", {
|
|
4
5
|
value: true
|
|
5
6
|
});
|
|
@@ -7,7 +8,10 @@ exports.getKey = exports.generateScriptProps = exports.GLOBAL_MEDIA_NAMESPACE =
|
|
|
7
8
|
exports.getMediaCardSSR = getMediaCardSSR;
|
|
8
9
|
exports.getMediaGlobalScope = getMediaGlobalScope;
|
|
9
10
|
exports.storeDataURI = void 0;
|
|
11
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
10
12
|
var _printScript = require("./printScript");
|
|
13
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
14
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
11
15
|
// ----- WARNING -----
|
|
12
16
|
// This is a very sensitive fraction of code.
|
|
13
17
|
// Any changes to this file must be tested directly in product before merging.
|
|
@@ -44,23 +48,70 @@ var getKey = exports.getKey = function getKey(_ref) {
|
|
|
44
48
|
occurrenceKey = _ref.occurrenceKey;
|
|
45
49
|
return "".concat(id).concat(dashed(collectionName)).concat(dashed(occurrenceKey));
|
|
46
50
|
};
|
|
47
|
-
var storeDataURI = exports.storeDataURI = function storeDataURI(key,
|
|
48
|
-
var globalScope = arguments.length >
|
|
51
|
+
var storeDataURI = exports.storeDataURI = function storeDataURI(key, paramDataURI, paramSrcSet, dimensions, error) {
|
|
52
|
+
var globalScope = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : window;
|
|
53
|
+
var featureFlags = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : {};
|
|
49
54
|
var mediaCardSsr = getMediaCardSSR(globalScope);
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
+
if (featureFlags['media-perf-uplift-mutation-fix']) {
|
|
56
|
+
var _prevData$dimensions, _script;
|
|
57
|
+
var prevData = mediaCardSsr[key];
|
|
58
|
+
var isPreviousImageLarger = prevData && ((_prevData$dimensions = prevData.dimensions) === null || _prevData$dimensions === void 0 ? void 0 : _prevData$dimensions.width) && (dimensions === null || dimensions === void 0 ? void 0 : dimensions.width) && prevData.dimensions.width > dimensions.width;
|
|
59
|
+
var srcSet = isPreviousImageLarger ? prevData === null || prevData === void 0 ? void 0 : prevData.srcSet : paramSrcSet;
|
|
60
|
+
var dataURI = isPreviousImageLarger ? prevData === null || prevData === void 0 ? void 0 : prevData.dataURI : paramDataURI;
|
|
61
|
+
var img = (_script = script) === null || _script === void 0 || (_script = _script.parentElement) === null || _script === void 0 ? void 0 : _script.querySelector('img');
|
|
62
|
+
if (img && dataURI) {
|
|
63
|
+
img.src = dataURI;
|
|
64
|
+
}
|
|
65
|
+
if (img && srcSet) {
|
|
66
|
+
img.srcset = srcSet;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
70
|
+
img === null || img === void 0 || img.addEventListener('load', function () {
|
|
71
|
+
if (img.currentSrc.startsWith('blob:')) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
fetch(img.currentSrc).then(function (res) {
|
|
75
|
+
return res.blob();
|
|
76
|
+
}).then(function (blob) {
|
|
77
|
+
return URL.createObjectURL(blob);
|
|
78
|
+
}).then(function (blobUrl) {
|
|
79
|
+
img.src = blobUrl;
|
|
80
|
+
img.srcset = '';
|
|
81
|
+
mediaCardSsr[key] = _objectSpread(_objectSpread({}, mediaCardSsr[key]), {}, {
|
|
82
|
+
dataURI: blobUrl,
|
|
83
|
+
srcSet: ''
|
|
84
|
+
});
|
|
85
|
+
}).catch(function (err) {
|
|
86
|
+
mediaCardSsr[key] = _objectSpread(_objectSpread({}, mediaCardSsr[key]), {}, {
|
|
87
|
+
error: err
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
mediaCardSsr[key] = isPreviousImageLarger ? prevData : {
|
|
92
|
+
dataURI: dataURI,
|
|
93
|
+
dimensions: dimensions,
|
|
94
|
+
error: error,
|
|
95
|
+
srcSet: srcSet
|
|
96
|
+
};
|
|
97
|
+
} else {
|
|
98
|
+
mediaCardSsr[key] = {
|
|
99
|
+
dataURI: paramDataURI,
|
|
100
|
+
dimensions: dimensions,
|
|
101
|
+
error: error
|
|
102
|
+
};
|
|
103
|
+
}
|
|
55
104
|
};
|
|
56
|
-
var generateScript = function generateScript(identifier, dataURI, dimensions, error) {
|
|
57
|
-
var
|
|
105
|
+
var generateScript = function generateScript(identifier, dataURI, srcSet, dimensions, error) {
|
|
106
|
+
var featureFlags = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
|
|
107
|
+
var functionCall = (0, _printScript.printFunctionCall)(storeDataURI, getKey(identifier), dataURI, srcSet, dimensions, error, featureFlags);
|
|
58
108
|
return (0, _printScript.printScript)([getMediaCardSSR.toString(), getMediaGlobalScope.toString(), functionCall]);
|
|
59
109
|
};
|
|
60
|
-
var generateScriptProps = exports.generateScriptProps = function generateScriptProps(identifier, dataURI, dimensions, error) {
|
|
110
|
+
var generateScriptProps = exports.generateScriptProps = function generateScriptProps(identifier, dataURI, srcSet, dimensions, error) {
|
|
111
|
+
var featureFlags = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
|
|
61
112
|
return {
|
|
62
113
|
dangerouslySetInnerHTML: {
|
|
63
|
-
__html: generateScript(identifier, dataURI, dimensions, error)
|
|
114
|
+
__html: generateScript(identifier, dataURI, srcSet, dimensions, error, featureFlags)
|
|
64
115
|
}
|
|
65
116
|
};
|
|
66
117
|
};
|
|
@@ -31,6 +31,7 @@ var printFunctionCall = exports.printFunctionCall = function printFunctionCall(f
|
|
|
31
31
|
// Removing the script tag after execution to prevent hydration
|
|
32
32
|
// mismatch issues after SSR. We don't want to render different
|
|
33
33
|
// HTML on the client and server https://react.dev/reference/react-dom/client/hydrateRoot
|
|
34
|
+
// Note: document.currentScript gets incorrectly transpiled to globalThis.currentScript so we need to use it here to avoid transpilation
|
|
34
35
|
var printScript = exports.printScript = function printScript(statements) {
|
|
35
|
-
return "(function(){\n \t\t\t ".concat(statements.join(';'), "\n
|
|
36
|
+
return "(function(){\n\t\t\t let script = document.currentScript;\n \t\t\t ".concat(statements.join(';'), "\n\t\t\t document.currentScript.remove();\n\t\t})();\n\t\t");
|
|
36
37
|
};
|
|
@@ -20,6 +20,16 @@ var _globalScope = require("./globalScope");
|
|
|
20
20
|
var _helpers = require("./helpers");
|
|
21
21
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
22
22
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
23
|
+
// invisible gif for SSR preview to show the underlying spinner until the src is replaced by
|
|
24
|
+
// the actual image src in the inline script
|
|
25
|
+
var DEFAULT_SSR_PREVIEW = {
|
|
26
|
+
dataURI: 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==',
|
|
27
|
+
dimensions: {
|
|
28
|
+
width: 100,
|
|
29
|
+
height: 100
|
|
30
|
+
},
|
|
31
|
+
source: 'ssr-server'
|
|
32
|
+
};
|
|
23
33
|
var useFilePreview = exports.useFilePreview = function useFilePreview(_ref) {
|
|
24
34
|
var _ref$resizeMode = _ref.resizeMode,
|
|
25
35
|
resizeMode = _ref$resizeMode === void 0 ? 'crop' : _ref$resizeMode,
|
|
@@ -110,11 +120,13 @@ var useFilePreview = exports.useFilePreview = function useFilePreview(_ref) {
|
|
|
110
120
|
}
|
|
111
121
|
} else {
|
|
112
122
|
var _dimensions = ssrData.dimensions,
|
|
113
|
-
dataURI = ssrData.dataURI
|
|
123
|
+
dataURI = ssrData.dataURI,
|
|
124
|
+
srcSet = ssrData.srcSet;
|
|
114
125
|
return {
|
|
115
126
|
dataURI: dataURI,
|
|
116
127
|
dimensions: _dimensions,
|
|
117
|
-
source: 'ssr-data'
|
|
128
|
+
source: 'ssr-data',
|
|
129
|
+
srcSet: srcSet
|
|
118
130
|
};
|
|
119
131
|
}
|
|
120
132
|
}
|
|
@@ -235,6 +247,10 @@ var useFilePreview = exports.useFilePreview = function useFilePreview(_ref) {
|
|
|
235
247
|
else if (!error && !nonCriticalError && (!preview || (0, _helpers.isBigger)(preview.dimensions, requestDimensions) ||
|
|
236
248
|
// We always refetch SSR preview to be able to browser-cache a version without the token in the query parameters
|
|
237
249
|
(0, _getPreview.isSSRPreview)(preview)) && !skipRemote && upfrontPreviewStatus === 'resolved' && isBackendPreviewReady) {
|
|
250
|
+
// If the preview is SSR and it's a blob URL, we can skip the refetch
|
|
251
|
+
if (preview && (0, _getPreview.isSSRPreview)(preview) && preview.dataURI.startsWith('blob:') && (0, _platformFeatureFlags.fg)('media-perf-uplift-mutation-fix')) {
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
238
254
|
setIsLoading(true);
|
|
239
255
|
getAndCacheRemotePreviewRef.current().then(setPreview).catch(function (e) {
|
|
240
256
|
var wrappedError = (0, _errors.ensureMediaFilePreviewError)('preview-fetch', e);
|
|
@@ -262,9 +278,10 @@ var useFilePreview = exports.useFilePreview = function useFilePreview(_ref) {
|
|
|
262
278
|
if ((0, _getPreview.isSSRClientPreview)(failedPreview)) {
|
|
263
279
|
ssrReliabilityRef.current.client = (0, _analytics.createFailedSSRObject)(failedPreview, traceContext);
|
|
264
280
|
}
|
|
281
|
+
var isSSR = (0, _getPreview.isSSRDataPreview)(failedPreview);
|
|
265
282
|
|
|
266
283
|
// If the preview failed and it comes from server (global scope / ssrData), it means that we have reused it in client and the error counts for both: server & client.
|
|
267
|
-
if (
|
|
284
|
+
if (isSSR) {
|
|
268
285
|
ssrReliabilityRef.current.server = (0, _analytics.createFailedSSRObject)(failedPreview, traceContext);
|
|
269
286
|
ssrReliabilityRef.current.client = (0, _analytics.createFailedSSRObject)(failedPreview, traceContext);
|
|
270
287
|
}
|
|
@@ -275,7 +292,7 @@ var useFilePreview = exports.useFilePreview = function useFilePreview(_ref) {
|
|
|
275
292
|
}
|
|
276
293
|
var isLocal = (0, _getPreview.isLocalPreview)(failedPreview);
|
|
277
294
|
var isRemote = (0, _getPreview.isRemotePreview)(failedPreview);
|
|
278
|
-
if (isLocal || isRemote) {
|
|
295
|
+
if (isLocal || isRemote || isSSR) {
|
|
279
296
|
var _error = new _errors.ImageLoadError(failedPreview === null || failedPreview === void 0 ? void 0 : failedPreview.source);
|
|
280
297
|
_getPreview.mediaFilePreviewCache.remove(identifier.id, resizeMode);
|
|
281
298
|
if (isLocal) {
|
|
@@ -319,7 +336,9 @@ var useFilePreview = exports.useFilePreview = function useFilePreview(_ref) {
|
|
|
319
336
|
// FOR SSR
|
|
320
337
|
var getSsrScriptProps = ssr === 'server' ? function () {
|
|
321
338
|
var _ssrReliabilityRef$cu;
|
|
322
|
-
return (0, _globalScope.generateScriptProps)(identifier, preview === null || preview === void 0 ? void 0 : preview.dataURI, requestDimensions, ((_ssrReliabilityRef$cu = ssrReliabilityRef.current.server) === null || _ssrReliabilityRef$cu === void 0 ? void 0 : _ssrReliabilityRef$cu.status) === 'fail' ? ssrReliabilityRef.current.server : undefined
|
|
339
|
+
return (0, _globalScope.generateScriptProps)(identifier, preview === null || preview === void 0 ? void 0 : preview.dataURI, preview === null || preview === void 0 ? void 0 : preview.srcSet, requestDimensions, ((_ssrReliabilityRef$cu = ssrReliabilityRef.current.server) === null || _ssrReliabilityRef$cu === void 0 ? void 0 : _ssrReliabilityRef$cu.status) === 'fail' ? ssrReliabilityRef.current.server : undefined, {
|
|
340
|
+
'media-perf-uplift-mutation-fix': (0, _platformFeatureFlags.fg)('media-perf-uplift-mutation-fix')
|
|
341
|
+
});
|
|
323
342
|
} : undefined;
|
|
324
343
|
var _useCopyIntent = (0, _mediaClientReact.useCopyIntent)(identifier.id, {
|
|
325
344
|
collectionName: identifier.collectionName
|
|
@@ -329,7 +348,7 @@ var useFilePreview = exports.useFilePreview = function useFilePreview(_ref) {
|
|
|
329
348
|
// CXP-2723 TODO: should consider simplifying our analytics, and how
|
|
330
349
|
// we might get rid of ssrReliabiltyRef from our hook
|
|
331
350
|
return {
|
|
332
|
-
preview: preview,
|
|
351
|
+
preview: ssr === 'server' && (0, _platformFeatureFlags.fg)('media-perf-uplift-mutation-fix') ? DEFAULT_SSR_PREVIEW : preview,
|
|
333
352
|
status: status,
|
|
334
353
|
error: error,
|
|
335
354
|
nonCriticalError: nonCriticalError,
|
|
@@ -27,17 +27,28 @@ const extendAndCachePreview = (id, mode, preview, mediaBlobUrlAttrs) => {
|
|
|
27
27
|
dataURI
|
|
28
28
|
};
|
|
29
29
|
};
|
|
30
|
+
const getDataUri = (mediaClient, id, params, mediaBlobUrlAttrs) => {
|
|
31
|
+
const rawDataURI = mediaClient.getImageUrlSync(id, params);
|
|
32
|
+
return mediaBlobUrlAttrs ? addFileAttrsToUrl(rawDataURI, mediaBlobUrlAttrs) : rawDataURI;
|
|
33
|
+
};
|
|
30
34
|
export const getSSRPreview = (ssr, mediaClient, id, params, mediaBlobUrlAttrs) => {
|
|
31
|
-
let dataURI;
|
|
32
35
|
try {
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
const dataURI = getDataUri(mediaClient, id, params, mediaBlobUrlAttrs);
|
|
37
|
+
let srcSet = `${dataURI} 1x`;
|
|
38
|
+
if (params.width) {
|
|
39
|
+
const doubleDataURI = getDataUri(mediaClient, id, {
|
|
40
|
+
...params,
|
|
41
|
+
width: params.width * 2
|
|
42
|
+
}, mediaBlobUrlAttrs);
|
|
43
|
+
// We want to embed some meta context into dataURI for Copy/Paste to work.
|
|
44
|
+
srcSet += `, ${doubleDataURI} 2x`;
|
|
45
|
+
}
|
|
36
46
|
const source = ssr === 'client' ? 'ssr-client' : 'ssr-server';
|
|
37
47
|
return {
|
|
38
48
|
dataURI,
|
|
39
49
|
source,
|
|
40
|
-
orientation: 1
|
|
50
|
+
orientation: 1,
|
|
51
|
+
srcSet
|
|
41
52
|
};
|
|
42
53
|
} catch (e) {
|
|
43
54
|
const reason = ssr === 'server' ? 'ssr-server-uri' : 'ssr-client-uri';
|
|
@@ -30,20 +30,62 @@ export const getKey = ({
|
|
|
30
30
|
collectionName,
|
|
31
31
|
occurrenceKey
|
|
32
32
|
}) => `${id}${dashed(collectionName)}${dashed(occurrenceKey)}`;
|
|
33
|
-
export const storeDataURI = (key,
|
|
33
|
+
export const storeDataURI = (key, paramDataURI, paramSrcSet, dimensions, error, globalScope = window, featureFlags = {}) => {
|
|
34
34
|
const mediaCardSsr = getMediaCardSSR(globalScope);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
if (featureFlags['media-perf-uplift-mutation-fix']) {
|
|
36
|
+
var _prevData$dimensions, _script, _script$parentElement;
|
|
37
|
+
const prevData = mediaCardSsr[key];
|
|
38
|
+
const isPreviousImageLarger = prevData && ((_prevData$dimensions = prevData.dimensions) === null || _prevData$dimensions === void 0 ? void 0 : _prevData$dimensions.width) && (dimensions === null || dimensions === void 0 ? void 0 : dimensions.width) && prevData.dimensions.width > dimensions.width;
|
|
39
|
+
const srcSet = isPreviousImageLarger ? prevData === null || prevData === void 0 ? void 0 : prevData.srcSet : paramSrcSet;
|
|
40
|
+
const dataURI = isPreviousImageLarger ? prevData === null || prevData === void 0 ? void 0 : prevData.dataURI : paramDataURI;
|
|
41
|
+
const img = (_script = script) === null || _script === void 0 ? void 0 : (_script$parentElement = _script.parentElement) === null || _script$parentElement === void 0 ? void 0 : _script$parentElement.querySelector('img');
|
|
42
|
+
if (img && dataURI) {
|
|
43
|
+
img.src = dataURI;
|
|
44
|
+
}
|
|
45
|
+
if (img && srcSet) {
|
|
46
|
+
img.srcset = srcSet;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
50
|
+
img === null || img === void 0 ? void 0 : img.addEventListener('load', () => {
|
|
51
|
+
if (img.currentSrc.startsWith('blob:')) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
fetch(img.currentSrc).then(res => res.blob()).then(blob => URL.createObjectURL(blob)).then(blobUrl => {
|
|
55
|
+
img.src = blobUrl;
|
|
56
|
+
img.srcset = '';
|
|
57
|
+
mediaCardSsr[key] = {
|
|
58
|
+
...mediaCardSsr[key],
|
|
59
|
+
dataURI: blobUrl,
|
|
60
|
+
srcSet: ''
|
|
61
|
+
};
|
|
62
|
+
}).catch(err => {
|
|
63
|
+
mediaCardSsr[key] = {
|
|
64
|
+
...mediaCardSsr[key],
|
|
65
|
+
error: err
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
mediaCardSsr[key] = isPreviousImageLarger ? prevData : {
|
|
70
|
+
dataURI,
|
|
71
|
+
dimensions,
|
|
72
|
+
error,
|
|
73
|
+
srcSet
|
|
74
|
+
};
|
|
75
|
+
} else {
|
|
76
|
+
mediaCardSsr[key] = {
|
|
77
|
+
dataURI: paramDataURI,
|
|
78
|
+
dimensions,
|
|
79
|
+
error
|
|
80
|
+
};
|
|
81
|
+
}
|
|
40
82
|
};
|
|
41
|
-
const generateScript = (identifier, dataURI, dimensions, error) => {
|
|
42
|
-
const functionCall = printFunctionCall(storeDataURI, getKey(identifier), dataURI, dimensions, error);
|
|
83
|
+
const generateScript = (identifier, dataURI, srcSet, dimensions, error, featureFlags = {}) => {
|
|
84
|
+
const functionCall = printFunctionCall(storeDataURI, getKey(identifier), dataURI, srcSet, dimensions, error, featureFlags);
|
|
43
85
|
return printScript([getMediaCardSSR.toString(), getMediaGlobalScope.toString(), functionCall]);
|
|
44
86
|
};
|
|
45
|
-
export const generateScriptProps = (identifier, dataURI, dimensions, error) => ({
|
|
87
|
+
export const generateScriptProps = (identifier, dataURI, srcSet, dimensions, error, featureFlags = {}) => ({
|
|
46
88
|
dangerouslySetInnerHTML: {
|
|
47
|
-
__html: generateScript(identifier, dataURI, dimensions, error)
|
|
89
|
+
__html: generateScript(identifier, dataURI, srcSet, dimensions, error, featureFlags)
|
|
48
90
|
}
|
|
49
91
|
});
|
|
@@ -14,8 +14,10 @@ export const printFunctionCall = (fn, ...args) => `(${fn.toString()})(${printPar
|
|
|
14
14
|
// Removing the script tag after execution to prevent hydration
|
|
15
15
|
// mismatch issues after SSR. We don't want to render different
|
|
16
16
|
// HTML on the client and server https://react.dev/reference/react-dom/client/hydrateRoot
|
|
17
|
+
// Note: document.currentScript gets incorrectly transpiled to globalThis.currentScript so we need to use it here to avoid transpilation
|
|
17
18
|
export const printScript = statements => `(function(){
|
|
19
|
+
let script = document.currentScript;
|
|
18
20
|
${statements.join(';')}
|
|
19
|
-
|
|
21
|
+
document.currentScript.remove();
|
|
20
22
|
})();
|
|
21
23
|
`;
|
|
@@ -9,6 +9,16 @@ import { ensureMediaFilePreviewError, ImageLoadError, MediaFilePreviewError } fr
|
|
|
9
9
|
import { getAndCacheLocalPreview, getAndCacheRemotePreview, getSSRPreview, isLocalPreview, isRemotePreview, isSSRClientPreview, isSSRDataPreview, isSSRPreview, isSupportedLocalPreview, mediaFilePreviewCache } from './getPreview';
|
|
10
10
|
import { generateScriptProps, getSSRData } from './globalScope';
|
|
11
11
|
import { createRequestDimensions, isBigger, useCurrentValueRef } from './helpers';
|
|
12
|
+
// invisible gif for SSR preview to show the underlying spinner until the src is replaced by
|
|
13
|
+
// the actual image src in the inline script
|
|
14
|
+
const DEFAULT_SSR_PREVIEW = {
|
|
15
|
+
dataURI: 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==',
|
|
16
|
+
dimensions: {
|
|
17
|
+
width: 100,
|
|
18
|
+
height: 100
|
|
19
|
+
},
|
|
20
|
+
source: 'ssr-server'
|
|
21
|
+
};
|
|
12
22
|
export const useFilePreview = ({
|
|
13
23
|
resizeMode = 'crop',
|
|
14
24
|
identifier,
|
|
@@ -83,12 +93,14 @@ export const useFilePreview = ({
|
|
|
83
93
|
} else {
|
|
84
94
|
const {
|
|
85
95
|
dimensions,
|
|
86
|
-
dataURI
|
|
96
|
+
dataURI,
|
|
97
|
+
srcSet
|
|
87
98
|
} = ssrData;
|
|
88
99
|
return {
|
|
89
100
|
dataURI,
|
|
90
101
|
dimensions,
|
|
91
|
-
source: 'ssr-data'
|
|
102
|
+
source: 'ssr-data',
|
|
103
|
+
srcSet
|
|
92
104
|
};
|
|
93
105
|
}
|
|
94
106
|
}
|
|
@@ -207,6 +219,10 @@ export const useFilePreview = ({
|
|
|
207
219
|
else if (!error && !nonCriticalError && (!preview || isBigger(preview.dimensions, requestDimensions) ||
|
|
208
220
|
// We always refetch SSR preview to be able to browser-cache a version without the token in the query parameters
|
|
209
221
|
isSSRPreview(preview)) && !skipRemote && upfrontPreviewStatus === 'resolved' && isBackendPreviewReady) {
|
|
222
|
+
// If the preview is SSR and it's a blob URL, we can skip the refetch
|
|
223
|
+
if (preview && isSSRPreview(preview) && preview.dataURI.startsWith('blob:') && fg('media-perf-uplift-mutation-fix')) {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
210
226
|
setIsLoading(true);
|
|
211
227
|
getAndCacheRemotePreviewRef.current().then(setPreview).catch(e => {
|
|
212
228
|
const wrappedError = ensureMediaFilePreviewError('preview-fetch', e);
|
|
@@ -234,9 +250,10 @@ export const useFilePreview = ({
|
|
|
234
250
|
if (isSSRClientPreview(failedPreview)) {
|
|
235
251
|
ssrReliabilityRef.current.client = createFailedSSRObject(failedPreview, traceContext);
|
|
236
252
|
}
|
|
253
|
+
const isSSR = isSSRDataPreview(failedPreview);
|
|
237
254
|
|
|
238
255
|
// If the preview failed and it comes from server (global scope / ssrData), it means that we have reused it in client and the error counts for both: server & client.
|
|
239
|
-
if (
|
|
256
|
+
if (isSSR) {
|
|
240
257
|
ssrReliabilityRef.current.server = createFailedSSRObject(failedPreview, traceContext);
|
|
241
258
|
ssrReliabilityRef.current.client = createFailedSSRObject(failedPreview, traceContext);
|
|
242
259
|
}
|
|
@@ -247,7 +264,7 @@ export const useFilePreview = ({
|
|
|
247
264
|
}
|
|
248
265
|
const isLocal = isLocalPreview(failedPreview);
|
|
249
266
|
const isRemote = isRemotePreview(failedPreview);
|
|
250
|
-
if (isLocal || isRemote) {
|
|
267
|
+
if (isLocal || isRemote || isSSR) {
|
|
251
268
|
const error = new ImageLoadError(failedPreview === null || failedPreview === void 0 ? void 0 : failedPreview.source);
|
|
252
269
|
mediaFilePreviewCache.remove(identifier.id, resizeMode);
|
|
253
270
|
if (isLocal) {
|
|
@@ -291,7 +308,9 @@ export const useFilePreview = ({
|
|
|
291
308
|
// FOR SSR
|
|
292
309
|
const getSsrScriptProps = ssr === 'server' ? () => {
|
|
293
310
|
var _ssrReliabilityRef$cu;
|
|
294
|
-
return generateScriptProps(identifier, preview === null || preview === void 0 ? void 0 : preview.dataURI, requestDimensions, ((_ssrReliabilityRef$cu = ssrReliabilityRef.current.server) === null || _ssrReliabilityRef$cu === void 0 ? void 0 : _ssrReliabilityRef$cu.status) === 'fail' ? ssrReliabilityRef.current.server : undefined
|
|
311
|
+
return generateScriptProps(identifier, preview === null || preview === void 0 ? void 0 : preview.dataURI, preview === null || preview === void 0 ? void 0 : preview.srcSet, requestDimensions, ((_ssrReliabilityRef$cu = ssrReliabilityRef.current.server) === null || _ssrReliabilityRef$cu === void 0 ? void 0 : _ssrReliabilityRef$cu.status) === 'fail' ? ssrReliabilityRef.current.server : undefined, {
|
|
312
|
+
'media-perf-uplift-mutation-fix': fg('media-perf-uplift-mutation-fix')
|
|
313
|
+
});
|
|
295
314
|
} : undefined;
|
|
296
315
|
const {
|
|
297
316
|
copyNodeRef
|
|
@@ -302,7 +321,7 @@ export const useFilePreview = ({
|
|
|
302
321
|
// CXP-2723 TODO: should consider simplifying our analytics, and how
|
|
303
322
|
// we might get rid of ssrReliabiltyRef from our hook
|
|
304
323
|
return {
|
|
305
|
-
preview,
|
|
324
|
+
preview: ssr === 'server' && fg('media-perf-uplift-mutation-fix') ? DEFAULT_SSR_PREVIEW : preview,
|
|
306
325
|
status,
|
|
307
326
|
error,
|
|
308
327
|
nonCriticalError,
|
|
@@ -30,17 +30,27 @@ var extendAndCachePreview = function extendAndCachePreview(id, mode, preview, me
|
|
|
30
30
|
dataURI: dataURI
|
|
31
31
|
});
|
|
32
32
|
};
|
|
33
|
+
var getDataUri = function getDataUri(mediaClient, id, params, mediaBlobUrlAttrs) {
|
|
34
|
+
var rawDataURI = mediaClient.getImageUrlSync(id, params);
|
|
35
|
+
return mediaBlobUrlAttrs ? addFileAttrsToUrl(rawDataURI, mediaBlobUrlAttrs) : rawDataURI;
|
|
36
|
+
};
|
|
33
37
|
export var getSSRPreview = function getSSRPreview(ssr, mediaClient, id, params, mediaBlobUrlAttrs) {
|
|
34
|
-
var dataURI;
|
|
35
38
|
try {
|
|
36
|
-
var
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
var dataURI = getDataUri(mediaClient, id, params, mediaBlobUrlAttrs);
|
|
40
|
+
var srcSet = "".concat(dataURI, " 1x");
|
|
41
|
+
if (params.width) {
|
|
42
|
+
var doubleDataURI = getDataUri(mediaClient, id, _objectSpread(_objectSpread({}, params), {}, {
|
|
43
|
+
width: params.width * 2
|
|
44
|
+
}), mediaBlobUrlAttrs);
|
|
45
|
+
// We want to embed some meta context into dataURI for Copy/Paste to work.
|
|
46
|
+
srcSet += ", ".concat(doubleDataURI, " 2x");
|
|
47
|
+
}
|
|
39
48
|
var source = ssr === 'client' ? 'ssr-client' : 'ssr-server';
|
|
40
49
|
return {
|
|
41
50
|
dataURI: dataURI,
|
|
42
51
|
source: source,
|
|
43
|
-
orientation: 1
|
|
52
|
+
orientation: 1,
|
|
53
|
+
srcSet: srcSet
|
|
44
54
|
};
|
|
45
55
|
} catch (e) {
|
|
46
56
|
var reason = ssr === 'server' ? 'ssr-server-uri' : 'ssr-client-uri';
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
3
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
1
4
|
import { printFunctionCall, printScript } from './printScript';
|
|
2
5
|
// ----- WARNING -----
|
|
3
6
|
// This is a very sensitive fraction of code.
|
|
@@ -35,23 +38,70 @@ export var getKey = function getKey(_ref) {
|
|
|
35
38
|
occurrenceKey = _ref.occurrenceKey;
|
|
36
39
|
return "".concat(id).concat(dashed(collectionName)).concat(dashed(occurrenceKey));
|
|
37
40
|
};
|
|
38
|
-
export var storeDataURI = function storeDataURI(key,
|
|
39
|
-
var globalScope = arguments.length >
|
|
41
|
+
export var storeDataURI = function storeDataURI(key, paramDataURI, paramSrcSet, dimensions, error) {
|
|
42
|
+
var globalScope = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : window;
|
|
43
|
+
var featureFlags = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : {};
|
|
40
44
|
var mediaCardSsr = getMediaCardSSR(globalScope);
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
if (featureFlags['media-perf-uplift-mutation-fix']) {
|
|
46
|
+
var _prevData$dimensions, _script;
|
|
47
|
+
var prevData = mediaCardSsr[key];
|
|
48
|
+
var isPreviousImageLarger = prevData && ((_prevData$dimensions = prevData.dimensions) === null || _prevData$dimensions === void 0 ? void 0 : _prevData$dimensions.width) && (dimensions === null || dimensions === void 0 ? void 0 : dimensions.width) && prevData.dimensions.width > dimensions.width;
|
|
49
|
+
var srcSet = isPreviousImageLarger ? prevData === null || prevData === void 0 ? void 0 : prevData.srcSet : paramSrcSet;
|
|
50
|
+
var dataURI = isPreviousImageLarger ? prevData === null || prevData === void 0 ? void 0 : prevData.dataURI : paramDataURI;
|
|
51
|
+
var img = (_script = script) === null || _script === void 0 || (_script = _script.parentElement) === null || _script === void 0 ? void 0 : _script.querySelector('img');
|
|
52
|
+
if (img && dataURI) {
|
|
53
|
+
img.src = dataURI;
|
|
54
|
+
}
|
|
55
|
+
if (img && srcSet) {
|
|
56
|
+
img.srcset = srcSet;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// eslint-disable-next-line @repo/internal/dom-events/no-unsafe-event-listeners
|
|
60
|
+
img === null || img === void 0 || img.addEventListener('load', function () {
|
|
61
|
+
if (img.currentSrc.startsWith('blob:')) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
fetch(img.currentSrc).then(function (res) {
|
|
65
|
+
return res.blob();
|
|
66
|
+
}).then(function (blob) {
|
|
67
|
+
return URL.createObjectURL(blob);
|
|
68
|
+
}).then(function (blobUrl) {
|
|
69
|
+
img.src = blobUrl;
|
|
70
|
+
img.srcset = '';
|
|
71
|
+
mediaCardSsr[key] = _objectSpread(_objectSpread({}, mediaCardSsr[key]), {}, {
|
|
72
|
+
dataURI: blobUrl,
|
|
73
|
+
srcSet: ''
|
|
74
|
+
});
|
|
75
|
+
}).catch(function (err) {
|
|
76
|
+
mediaCardSsr[key] = _objectSpread(_objectSpread({}, mediaCardSsr[key]), {}, {
|
|
77
|
+
error: err
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
mediaCardSsr[key] = isPreviousImageLarger ? prevData : {
|
|
82
|
+
dataURI: dataURI,
|
|
83
|
+
dimensions: dimensions,
|
|
84
|
+
error: error,
|
|
85
|
+
srcSet: srcSet
|
|
86
|
+
};
|
|
87
|
+
} else {
|
|
88
|
+
mediaCardSsr[key] = {
|
|
89
|
+
dataURI: paramDataURI,
|
|
90
|
+
dimensions: dimensions,
|
|
91
|
+
error: error
|
|
92
|
+
};
|
|
93
|
+
}
|
|
46
94
|
};
|
|
47
|
-
var generateScript = function generateScript(identifier, dataURI, dimensions, error) {
|
|
48
|
-
var
|
|
95
|
+
var generateScript = function generateScript(identifier, dataURI, srcSet, dimensions, error) {
|
|
96
|
+
var featureFlags = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
|
|
97
|
+
var functionCall = printFunctionCall(storeDataURI, getKey(identifier), dataURI, srcSet, dimensions, error, featureFlags);
|
|
49
98
|
return printScript([getMediaCardSSR.toString(), getMediaGlobalScope.toString(), functionCall]);
|
|
50
99
|
};
|
|
51
|
-
export var generateScriptProps = function generateScriptProps(identifier, dataURI, dimensions, error) {
|
|
100
|
+
export var generateScriptProps = function generateScriptProps(identifier, dataURI, srcSet, dimensions, error) {
|
|
101
|
+
var featureFlags = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
|
|
52
102
|
return {
|
|
53
103
|
dangerouslySetInnerHTML: {
|
|
54
|
-
__html: generateScript(identifier, dataURI, dimensions, error)
|
|
104
|
+
__html: generateScript(identifier, dataURI, srcSet, dimensions, error, featureFlags)
|
|
55
105
|
}
|
|
56
106
|
};
|
|
57
107
|
};
|
|
@@ -24,6 +24,7 @@ export var printFunctionCall = function printFunctionCall(fn) {
|
|
|
24
24
|
// Removing the script tag after execution to prevent hydration
|
|
25
25
|
// mismatch issues after SSR. We don't want to render different
|
|
26
26
|
// HTML on the client and server https://react.dev/reference/react-dom/client/hydrateRoot
|
|
27
|
+
// Note: document.currentScript gets incorrectly transpiled to globalThis.currentScript so we need to use it here to avoid transpilation
|
|
27
28
|
export var printScript = function printScript(statements) {
|
|
28
|
-
return "(function(){\n \t\t\t ".concat(statements.join(';'), "\n
|
|
29
|
+
return "(function(){\n\t\t\t let script = document.currentScript;\n \t\t\t ".concat(statements.join(';'), "\n\t\t\t document.currentScript.remove();\n\t\t})();\n\t\t");
|
|
29
30
|
};
|
|
@@ -13,6 +13,16 @@ import { ensureMediaFilePreviewError, ImageLoadError, MediaFilePreviewError } fr
|
|
|
13
13
|
import { getAndCacheLocalPreview, getAndCacheRemotePreview, getSSRPreview, isLocalPreview, isRemotePreview, isSSRClientPreview, isSSRDataPreview, isSSRPreview, isSupportedLocalPreview, mediaFilePreviewCache } from './getPreview';
|
|
14
14
|
import { generateScriptProps, getSSRData } from './globalScope';
|
|
15
15
|
import { createRequestDimensions, isBigger, useCurrentValueRef } from './helpers';
|
|
16
|
+
// invisible gif for SSR preview to show the underlying spinner until the src is replaced by
|
|
17
|
+
// the actual image src in the inline script
|
|
18
|
+
var DEFAULT_SSR_PREVIEW = {
|
|
19
|
+
dataURI: 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==',
|
|
20
|
+
dimensions: {
|
|
21
|
+
width: 100,
|
|
22
|
+
height: 100
|
|
23
|
+
},
|
|
24
|
+
source: 'ssr-server'
|
|
25
|
+
};
|
|
16
26
|
export var useFilePreview = function useFilePreview(_ref) {
|
|
17
27
|
var _ref$resizeMode = _ref.resizeMode,
|
|
18
28
|
resizeMode = _ref$resizeMode === void 0 ? 'crop' : _ref$resizeMode,
|
|
@@ -103,11 +113,13 @@ export var useFilePreview = function useFilePreview(_ref) {
|
|
|
103
113
|
}
|
|
104
114
|
} else {
|
|
105
115
|
var _dimensions = ssrData.dimensions,
|
|
106
|
-
dataURI = ssrData.dataURI
|
|
116
|
+
dataURI = ssrData.dataURI,
|
|
117
|
+
srcSet = ssrData.srcSet;
|
|
107
118
|
return {
|
|
108
119
|
dataURI: dataURI,
|
|
109
120
|
dimensions: _dimensions,
|
|
110
|
-
source: 'ssr-data'
|
|
121
|
+
source: 'ssr-data',
|
|
122
|
+
srcSet: srcSet
|
|
111
123
|
};
|
|
112
124
|
}
|
|
113
125
|
}
|
|
@@ -228,6 +240,10 @@ export var useFilePreview = function useFilePreview(_ref) {
|
|
|
228
240
|
else if (!error && !nonCriticalError && (!preview || isBigger(preview.dimensions, requestDimensions) ||
|
|
229
241
|
// We always refetch SSR preview to be able to browser-cache a version without the token in the query parameters
|
|
230
242
|
isSSRPreview(preview)) && !skipRemote && upfrontPreviewStatus === 'resolved' && isBackendPreviewReady) {
|
|
243
|
+
// If the preview is SSR and it's a blob URL, we can skip the refetch
|
|
244
|
+
if (preview && isSSRPreview(preview) && preview.dataURI.startsWith('blob:') && fg('media-perf-uplift-mutation-fix')) {
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
231
247
|
setIsLoading(true);
|
|
232
248
|
getAndCacheRemotePreviewRef.current().then(setPreview).catch(function (e) {
|
|
233
249
|
var wrappedError = ensureMediaFilePreviewError('preview-fetch', e);
|
|
@@ -255,9 +271,10 @@ export var useFilePreview = function useFilePreview(_ref) {
|
|
|
255
271
|
if (isSSRClientPreview(failedPreview)) {
|
|
256
272
|
ssrReliabilityRef.current.client = createFailedSSRObject(failedPreview, traceContext);
|
|
257
273
|
}
|
|
274
|
+
var isSSR = isSSRDataPreview(failedPreview);
|
|
258
275
|
|
|
259
276
|
// If the preview failed and it comes from server (global scope / ssrData), it means that we have reused it in client and the error counts for both: server & client.
|
|
260
|
-
if (
|
|
277
|
+
if (isSSR) {
|
|
261
278
|
ssrReliabilityRef.current.server = createFailedSSRObject(failedPreview, traceContext);
|
|
262
279
|
ssrReliabilityRef.current.client = createFailedSSRObject(failedPreview, traceContext);
|
|
263
280
|
}
|
|
@@ -268,7 +285,7 @@ export var useFilePreview = function useFilePreview(_ref) {
|
|
|
268
285
|
}
|
|
269
286
|
var isLocal = isLocalPreview(failedPreview);
|
|
270
287
|
var isRemote = isRemotePreview(failedPreview);
|
|
271
|
-
if (isLocal || isRemote) {
|
|
288
|
+
if (isLocal || isRemote || isSSR) {
|
|
272
289
|
var _error = new ImageLoadError(failedPreview === null || failedPreview === void 0 ? void 0 : failedPreview.source);
|
|
273
290
|
mediaFilePreviewCache.remove(identifier.id, resizeMode);
|
|
274
291
|
if (isLocal) {
|
|
@@ -312,7 +329,9 @@ export var useFilePreview = function useFilePreview(_ref) {
|
|
|
312
329
|
// FOR SSR
|
|
313
330
|
var getSsrScriptProps = ssr === 'server' ? function () {
|
|
314
331
|
var _ssrReliabilityRef$cu;
|
|
315
|
-
return generateScriptProps(identifier, preview === null || preview === void 0 ? void 0 : preview.dataURI, requestDimensions, ((_ssrReliabilityRef$cu = ssrReliabilityRef.current.server) === null || _ssrReliabilityRef$cu === void 0 ? void 0 : _ssrReliabilityRef$cu.status) === 'fail' ? ssrReliabilityRef.current.server : undefined
|
|
332
|
+
return generateScriptProps(identifier, preview === null || preview === void 0 ? void 0 : preview.dataURI, preview === null || preview === void 0 ? void 0 : preview.srcSet, requestDimensions, ((_ssrReliabilityRef$cu = ssrReliabilityRef.current.server) === null || _ssrReliabilityRef$cu === void 0 ? void 0 : _ssrReliabilityRef$cu.status) === 'fail' ? ssrReliabilityRef.current.server : undefined, {
|
|
333
|
+
'media-perf-uplift-mutation-fix': fg('media-perf-uplift-mutation-fix')
|
|
334
|
+
});
|
|
316
335
|
} : undefined;
|
|
317
336
|
var _useCopyIntent = useCopyIntent(identifier.id, {
|
|
318
337
|
collectionName: identifier.collectionName
|
|
@@ -322,7 +341,7 @@ export var useFilePreview = function useFilePreview(_ref) {
|
|
|
322
341
|
// CXP-2723 TODO: should consider simplifying our analytics, and how
|
|
323
342
|
// we might get rid of ssrReliabiltyRef from our hook
|
|
324
343
|
return {
|
|
325
|
-
preview: preview,
|
|
344
|
+
preview: ssr === 'server' && fg('media-perf-uplift-mutation-fix') ? DEFAULT_SSR_PREVIEW : preview,
|
|
326
345
|
status: status,
|
|
327
346
|
error: error,
|
|
328
347
|
nonCriticalError: nonCriticalError,
|
|
@@ -23,7 +23,7 @@ export type SSRStatus = {
|
|
|
23
23
|
};
|
|
24
24
|
export declare const getErrorTraceContext: (error: MediaFilePreviewError) => MediaTraceContext | undefined;
|
|
25
25
|
export declare const getRenderErrorFailReason: (error: MediaFilePreviewError) => FailedErrorFailReason;
|
|
26
|
-
export declare const getRenderErrorErrorReason: (error: MediaFilePreviewError) => MediaClientErrorReason |
|
|
26
|
+
export declare const getRenderErrorErrorReason: (error: MediaFilePreviewError) => MediaClientErrorReason | "nativeError";
|
|
27
27
|
export declare const getRenderErrorErrorDetail: (error: MediaFilePreviewError) => string;
|
|
28
28
|
export declare const extractErrorInfo: (error: MediaFilePreviewError, metadataTraceContext?: MediaTraceContext) => MediaFilePreviewErrorInfo;
|
|
29
29
|
export declare const createFailedSSRObject: (preview: MediaFilePreview, metadataTraceContext?: MediaTraceContext) => SSRStatusFail;
|
|
@@ -8,4 +8,4 @@ export declare const isSSRClientPreview: (preview: MediaFilePreview) => boolean;
|
|
|
8
8
|
export declare const isSSRDataPreview: (preview: MediaFilePreview) => boolean;
|
|
9
9
|
export declare const isSSRPreview: (preview: MediaFilePreview) => boolean;
|
|
10
10
|
export declare const getAndCacheRemotePreview: (mediaClient: MediaClient, id: string, dimensions: MediaFilePreviewDimensions, params: MediaStoreGetFileImageParams, mediaBlobUrlAttrs?: MediaBlobUrlAttrs, traceContext?: MediaTraceContext) => Promise<MediaFilePreview>;
|
|
11
|
-
export declare const getAndCacheLocalPreview: (id: string, filePreview: FilePreview | Promise<FilePreview>, dimensions: MediaFilePreviewDimensions, mode: MediaStoreGetFileImageParams[
|
|
11
|
+
export declare const getAndCacheLocalPreview: (id: string, filePreview: FilePreview | Promise<FilePreview>, dimensions: MediaFilePreviewDimensions, mode: MediaStoreGetFileImageParams["mode"], mediaBlobUrlAttrs?: MediaBlobUrlAttrs) => Promise<MediaFilePreview>;
|
|
@@ -5,6 +5,6 @@ import { type MediaFilePreview } from '../types';
|
|
|
5
5
|
* This method tells the support for the media
|
|
6
6
|
* types covered in getCardPreviewFromFilePreview
|
|
7
7
|
*/
|
|
8
|
-
export declare const isSupportedLocalPreview: (mediaType?: MediaType) =>
|
|
8
|
+
export declare const isSupportedLocalPreview: (mediaType?: MediaType) => mediaType is "video" | "image";
|
|
9
9
|
export declare const getLocalPreview: (filePreview: FilePreview | Promise<FilePreview>) => Promise<MediaFilePreview>;
|
|
10
10
|
export declare const getRemotePreview: (mediaClient: MediaClient, id: string, params: MediaStoreGetFileImageParams, traceContext?: MediaTraceContext) => Promise<MediaFilePreview>;
|
|
@@ -8,8 +8,12 @@ export declare const GLOBAL_MEDIA_NAMESPACE = "__MEDIA_INTERNAL";
|
|
|
8
8
|
export type MediaGlobalScope = {
|
|
9
9
|
[GLOBAL_MEDIA_CARD_SSR]?: MediaCardSsr;
|
|
10
10
|
};
|
|
11
|
+
type MediaFeatureFlags = {
|
|
12
|
+
'media-perf-uplift-mutation-fix'?: boolean;
|
|
13
|
+
};
|
|
11
14
|
export declare function getMediaGlobalScope(globalScope?: any): MediaGlobalScope;
|
|
12
15
|
export declare function getMediaCardSSR(globalScope?: any): MediaCardSsr;
|
|
13
16
|
export declare const getKey: ({ id, collectionName, occurrenceKey }: FileIdentifier) => string;
|
|
14
|
-
export declare const storeDataURI: (key: string,
|
|
15
|
-
export declare const generateScriptProps: (identifier: FileIdentifier, dataURI?: string, dimensions?: Partial<NumericalCardDimensions>, error?: MediaFilePreviewErrorInfo) => React.ScriptHTMLAttributes<HTMLScriptElement>;
|
|
17
|
+
export declare const storeDataURI: (key: string, paramDataURI?: string, paramSrcSet?: string, dimensions?: Partial<NumericalCardDimensions>, error?: MediaFilePreviewErrorInfo, globalScope?: any, featureFlags?: MediaFeatureFlags) => void;
|
|
18
|
+
export declare const generateScriptProps: (identifier: FileIdentifier, dataURI?: string, srcSet?: string, dimensions?: Partial<NumericalCardDimensions>, error?: MediaFilePreviewErrorInfo, featureFlags?: MediaFeatureFlags) => React.ScriptHTMLAttributes<HTMLScriptElement>;
|
|
19
|
+
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const printFunctionCall: <T extends any
|
|
1
|
+
export declare const printFunctionCall: <T extends Array<any>>(fn: (...args: T) => void, ...args: T) => string;
|
|
2
2
|
export declare const printScript: (statements: string[]) => string;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
1
|
import { type FileIdentifier, type MediaBlobUrlAttrs, type MediaStoreGetFileImageParams } from '@atlaskit/media-client';
|
|
3
2
|
import { type MediaTraceContext, type SSR } from '@atlaskit/media-common';
|
|
4
3
|
import { type SSRStatus } from './analytics';
|
|
@@ -38,5 +37,5 @@ export declare const useFilePreview: ({ resizeMode, identifier, ssr, dimensions,
|
|
|
38
37
|
onImageError: (failedPreview?: MediaFilePreview) => void;
|
|
39
38
|
onImageLoad: (newPreview?: MediaFilePreview) => void;
|
|
40
39
|
getSsrScriptProps: (() => import("react").ScriptHTMLAttributes<HTMLScriptElement>) | undefined;
|
|
41
|
-
copyNodeRef: (instance:
|
|
40
|
+
copyNodeRef: (instance: HTMLDivElement | HTMLImageElement | null) => void;
|
|
42
41
|
};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
1
|
import { type FileIdentifier, type MediaBlobUrlAttrs, type MediaStoreGetFileImageParams } from '@atlaskit/media-client';
|
|
3
2
|
import { type MediaTraceContext, type SSR } from '@atlaskit/media-common';
|
|
4
3
|
import { type MediaFilePreviewDimensions } from './types';
|
|
@@ -23,7 +23,7 @@ export type SSRStatus = {
|
|
|
23
23
|
};
|
|
24
24
|
export declare const getErrorTraceContext: (error: MediaFilePreviewError) => MediaTraceContext | undefined;
|
|
25
25
|
export declare const getRenderErrorFailReason: (error: MediaFilePreviewError) => FailedErrorFailReason;
|
|
26
|
-
export declare const getRenderErrorErrorReason: (error: MediaFilePreviewError) => MediaClientErrorReason |
|
|
26
|
+
export declare const getRenderErrorErrorReason: (error: MediaFilePreviewError) => MediaClientErrorReason | "nativeError";
|
|
27
27
|
export declare const getRenderErrorErrorDetail: (error: MediaFilePreviewError) => string;
|
|
28
28
|
export declare const extractErrorInfo: (error: MediaFilePreviewError, metadataTraceContext?: MediaTraceContext) => MediaFilePreviewErrorInfo;
|
|
29
29
|
export declare const createFailedSSRObject: (preview: MediaFilePreview, metadataTraceContext?: MediaTraceContext) => SSRStatusFail;
|
|
@@ -8,4 +8,4 @@ export declare const isSSRClientPreview: (preview: MediaFilePreview) => boolean;
|
|
|
8
8
|
export declare const isSSRDataPreview: (preview: MediaFilePreview) => boolean;
|
|
9
9
|
export declare const isSSRPreview: (preview: MediaFilePreview) => boolean;
|
|
10
10
|
export declare const getAndCacheRemotePreview: (mediaClient: MediaClient, id: string, dimensions: MediaFilePreviewDimensions, params: MediaStoreGetFileImageParams, mediaBlobUrlAttrs?: MediaBlobUrlAttrs, traceContext?: MediaTraceContext) => Promise<MediaFilePreview>;
|
|
11
|
-
export declare const getAndCacheLocalPreview: (id: string, filePreview: FilePreview | Promise<FilePreview>, dimensions: MediaFilePreviewDimensions, mode: MediaStoreGetFileImageParams[
|
|
11
|
+
export declare const getAndCacheLocalPreview: (id: string, filePreview: FilePreview | Promise<FilePreview>, dimensions: MediaFilePreviewDimensions, mode: MediaStoreGetFileImageParams["mode"], mediaBlobUrlAttrs?: MediaBlobUrlAttrs) => Promise<MediaFilePreview>;
|
|
@@ -5,6 +5,6 @@ import { type MediaFilePreview } from '../types';
|
|
|
5
5
|
* This method tells the support for the media
|
|
6
6
|
* types covered in getCardPreviewFromFilePreview
|
|
7
7
|
*/
|
|
8
|
-
export declare const isSupportedLocalPreview: (mediaType?: MediaType) =>
|
|
8
|
+
export declare const isSupportedLocalPreview: (mediaType?: MediaType) => mediaType is "video" | "image";
|
|
9
9
|
export declare const getLocalPreview: (filePreview: FilePreview | Promise<FilePreview>) => Promise<MediaFilePreview>;
|
|
10
10
|
export declare const getRemotePreview: (mediaClient: MediaClient, id: string, params: MediaStoreGetFileImageParams, traceContext?: MediaTraceContext) => Promise<MediaFilePreview>;
|
|
@@ -8,8 +8,12 @@ export declare const GLOBAL_MEDIA_NAMESPACE = "__MEDIA_INTERNAL";
|
|
|
8
8
|
export type MediaGlobalScope = {
|
|
9
9
|
[GLOBAL_MEDIA_CARD_SSR]?: MediaCardSsr;
|
|
10
10
|
};
|
|
11
|
+
type MediaFeatureFlags = {
|
|
12
|
+
'media-perf-uplift-mutation-fix'?: boolean;
|
|
13
|
+
};
|
|
11
14
|
export declare function getMediaGlobalScope(globalScope?: any): MediaGlobalScope;
|
|
12
15
|
export declare function getMediaCardSSR(globalScope?: any): MediaCardSsr;
|
|
13
16
|
export declare const getKey: ({ id, collectionName, occurrenceKey }: FileIdentifier) => string;
|
|
14
|
-
export declare const storeDataURI: (key: string,
|
|
15
|
-
export declare const generateScriptProps: (identifier: FileIdentifier, dataURI?: string, dimensions?: Partial<NumericalCardDimensions>, error?: MediaFilePreviewErrorInfo) => React.ScriptHTMLAttributes<HTMLScriptElement>;
|
|
17
|
+
export declare const storeDataURI: (key: string, paramDataURI?: string, paramSrcSet?: string, dimensions?: Partial<NumericalCardDimensions>, error?: MediaFilePreviewErrorInfo, globalScope?: any, featureFlags?: MediaFeatureFlags) => void;
|
|
18
|
+
export declare const generateScriptProps: (identifier: FileIdentifier, dataURI?: string, srcSet?: string, dimensions?: Partial<NumericalCardDimensions>, error?: MediaFilePreviewErrorInfo, featureFlags?: MediaFeatureFlags) => React.ScriptHTMLAttributes<HTMLScriptElement>;
|
|
19
|
+
export {};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const printFunctionCall: <T extends any
|
|
1
|
+
export declare const printFunctionCall: <T extends Array<any>>(fn: (...args: T) => void, ...args: T) => string;
|
|
2
2
|
export declare const printScript: (statements: string[]) => string;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
1
|
import { type FileIdentifier, type MediaBlobUrlAttrs, type MediaStoreGetFileImageParams } from '@atlaskit/media-client';
|
|
3
2
|
import { type MediaTraceContext, type SSR } from '@atlaskit/media-common';
|
|
4
3
|
import { type SSRStatus } from './analytics';
|
|
@@ -38,5 +37,5 @@ export declare const useFilePreview: ({ resizeMode, identifier, ssr, dimensions,
|
|
|
38
37
|
onImageError: (failedPreview?: MediaFilePreview) => void;
|
|
39
38
|
onImageLoad: (newPreview?: MediaFilePreview) => void;
|
|
40
39
|
getSsrScriptProps: (() => import("react").ScriptHTMLAttributes<HTMLScriptElement>) | undefined;
|
|
41
|
-
copyNodeRef: (instance:
|
|
40
|
+
copyNodeRef: (instance: HTMLDivElement | HTMLImageElement | null) => void;
|
|
42
41
|
};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
1
|
import { type FileIdentifier, type MediaBlobUrlAttrs, type MediaStoreGetFileImageParams } from '@atlaskit/media-client';
|
|
3
2
|
import { type MediaTraceContext, type SSR } from '@atlaskit/media-common';
|
|
4
3
|
import { type MediaFilePreviewDimensions } from './types';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/media-file-preview",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.8",
|
|
4
4
|
"description": "A React Hook to fetch and render file previews. It's overloaded with fancy features like SSR, lazy loading, memory cache and local preview.",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -29,16 +29,13 @@
|
|
|
29
29
|
},
|
|
30
30
|
"sideEffects": false,
|
|
31
31
|
"atlaskit:src": "src/index.ts",
|
|
32
|
-
"af:exports": {
|
|
33
|
-
".": "./src/index.ts"
|
|
34
|
-
},
|
|
35
32
|
"dependencies": {
|
|
36
|
-
"@atlaskit/media-client": "^35.
|
|
33
|
+
"@atlaskit/media-client": "^35.5.0",
|
|
37
34
|
"@atlaskit/media-client-react": "^4.1.0",
|
|
38
35
|
"@atlaskit/media-common": "^12.3.0",
|
|
39
|
-
"@atlaskit/media-ui": "^28.
|
|
36
|
+
"@atlaskit/media-ui": "^28.7.0",
|
|
40
37
|
"@atlaskit/platform-feature-flags": "^1.1.0",
|
|
41
|
-
"@atlaskit/react-ufo": "^4.
|
|
38
|
+
"@atlaskit/react-ufo": "^4.12.0",
|
|
42
39
|
"@babel/runtime": "^7.0.0",
|
|
43
40
|
"eventemitter2": "^4.1.0",
|
|
44
41
|
"lru_map": "^0.4.1"
|
|
@@ -52,13 +49,11 @@
|
|
|
52
49
|
"@af/visual-regression": "workspace:^",
|
|
53
50
|
"@atlaskit/media-state": "^1.8.0",
|
|
54
51
|
"@atlaskit/media-test-data": "^3.2.0",
|
|
55
|
-
"@atlaskit/section-message": "^8.
|
|
52
|
+
"@atlaskit/section-message": "^8.7.0",
|
|
56
53
|
"@atlaskit/ssr": "workspace:^",
|
|
57
|
-
"@atlaskit/visual-regression": "workspace:^",
|
|
58
54
|
"@testing-library/react": "^13.4.0",
|
|
59
55
|
"@testing-library/react-hooks": "^8.0.1",
|
|
60
56
|
"react-dom": "^18.2.0",
|
|
61
|
-
"typescript": "~5.4.2",
|
|
62
57
|
"wait-for-expect": "^1.2.0"
|
|
63
58
|
},
|
|
64
59
|
"techstack": {
|
|
@@ -99,6 +94,9 @@
|
|
|
99
94
|
"platform-feature-flags": {
|
|
100
95
|
"platform_close_image_blindspot_2": {
|
|
101
96
|
"type": "boolean"
|
|
97
|
+
},
|
|
98
|
+
"media-perf-uplift-mutation-fix": {
|
|
99
|
+
"type": "boolean"
|
|
102
100
|
}
|
|
103
101
|
}
|
|
104
102
|
}
|