PluginProbe
Gutenberg / 23.0.1
Gutenberg v23.0.1
23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 7.4.0 All 402 releases
gutenberg / build / scripts / upload-media / index.js

index.js in Gutenberg 23.0.1, at build/scripts/upload-media/index.js

1,942 lines 58.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 "use strict";
2 var wp;
3 (wp ||= {}).uploadMedia = (() => {
4 var __create = Object.create;
5 var __defProp = Object.defineProperty;
6 var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
7 var __getOwnPropNames = Object.getOwnPropertyNames;
8 var __getProtoOf = Object.getPrototypeOf;
9 var __hasOwnProp = Object.prototype.hasOwnProperty;
10 var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
11 get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
12 }) : x)(function(x) {
13 if (typeof require !== "undefined") return require.apply(this, arguments);
14 throw Error('Dynamic require of "' + x + '" is not supported');
15 });
16 var __commonJS = (cb, mod) => function __require2() {
17 return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
18 };
19 var __export = (target, all) => {
20 for (var name in all)
21 __defProp(target, name, { get: all[name], enumerable: true });
22 };
23 var __copyProps = (to, from, except, desc) => {
24 if (from && typeof from === "object" || typeof from === "function") {
25 for (let key of __getOwnPropNames(from))
26 if (!__hasOwnProp.call(to, key) && key !== except)
27 __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
28 }
29 return to;
30 };
31 var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
32 // If the importer is in node compatibility mode or this is not an ESM
33 // file that has been converted to a CommonJS file using a Babel-
34 // compatible transform (i.e. "__esModule" has not been set), then set
35 // "default" to the CommonJS "module.exports" for node compatibility.
36 isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
37 mod
38 ));
39 var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
40
41 // package-external:@wordpress/data
42 var require_data = __commonJS({
43 "package-external:@wordpress/data"(exports, module) {
44 module.exports = window.wp.data;
45 }
46 });
47
48 // package-external:@wordpress/url
49 var require_url = __commonJS({
50 "package-external:@wordpress/url"(exports, module) {
51 module.exports = window.wp.url;
52 }
53 });
54
55 // package-external:@wordpress/i18n
56 var require_i18n = __commonJS({
57 "package-external:@wordpress/i18n"(exports, module) {
58 module.exports = window.wp.i18n;
59 }
60 });
61
62 // package-external:@wordpress/blob
63 var require_blob = __commonJS({
64 "package-external:@wordpress/blob"(exports, module) {
65 module.exports = window.wp.blob;
66 }
67 });
68
69 // package-external:@wordpress/private-apis
70 var require_private_apis = __commonJS({
71 "package-external:@wordpress/private-apis"(exports, module) {
72 module.exports = window.wp.privateApis;
73 }
74 });
75
76 // package-external:@wordpress/element
77 var require_element = __commonJS({
78 "package-external:@wordpress/element"(exports, module) {
79 module.exports = window.wp.element;
80 }
81 });
82
83 // package-external:@wordpress/compose
84 var require_compose = __commonJS({
85 "package-external:@wordpress/compose"(exports, module) {
86 module.exports = window.wp.compose;
87 }
88 });
89
90 // vendor-external:react/jsx-runtime
91 var require_jsx_runtime = __commonJS({
92 "vendor-external:react/jsx-runtime"(exports, module) {
93 module.exports = window.ReactJSXRuntime;
94 }
95 });
96
97 // packages/upload-media/build-module/index.mjs
98 var index_exports = {};
99 __export(index_exports, {
100 MediaUploadProvider: () => provider_default,
101 UploadError: () => UploadError,
102 clearFeatureDetectionCache: () => clearFeatureDetectionCache,
103 detectClientSideMediaSupport: () => detectClientSideMediaSupport,
104 isClientSideMediaSupported: () => isClientSideMediaSupported,
105 store: () => store
106 });
107
108 // packages/upload-media/build-module/store/index.mjs
109 var import_data = __toESM(require_data(), 1);
110
111 // packages/upload-media/build-module/store/types.mjs
112 var Type = /* @__PURE__ */ ((Type2) => {
113 Type2["Unknown"] = "REDUX_UNKNOWN";
114 Type2["Add"] = "ADD_ITEM";
115 Type2["Prepare"] = "PREPARE_ITEM";
116 Type2["Cancel"] = "CANCEL_ITEM";
117 Type2["Remove"] = "REMOVE_ITEM";
118 Type2["RetryItem"] = "RETRY_ITEM";
119 Type2["PauseItem"] = "PAUSE_ITEM";
120 Type2["ResumeItem"] = "RESUME_ITEM";
121 Type2["PauseQueue"] = "PAUSE_QUEUE";
122 Type2["ResumeQueue"] = "RESUME_QUEUE";
123 Type2["OperationStart"] = "OPERATION_START";
124 Type2["OperationFinish"] = "OPERATION_FINISH";
125 Type2["AddOperations"] = "ADD_OPERATIONS";
126 Type2["CacheBlobUrl"] = "CACHE_BLOB_URL";
127 Type2["RevokeBlobUrls"] = "REVOKE_BLOB_URLS";
128 Type2["UpdateProgress"] = "UPDATE_PROGRESS";
129 Type2["UpdateSettings"] = "UPDATE_SETTINGS";
130 return Type2;
131 })(Type || {});
132 var ItemStatus = /* @__PURE__ */ ((ItemStatus2) => {
133 ItemStatus2["Queued"] = "QUEUED";
134 ItemStatus2["Processing"] = "PROCESSING";
135 ItemStatus2["Paused"] = "PAUSED";
136 ItemStatus2["Uploaded"] = "UPLOADED";
137 ItemStatus2["Error"] = "ERROR";
138 return ItemStatus2;
139 })(ItemStatus || {});
140 var OperationType = /* @__PURE__ */ ((OperationType2) => {
141 OperationType2["Prepare"] = "PREPARE";
142 OperationType2["Upload"] = "UPLOAD";
143 OperationType2["ResizeCrop"] = "RESIZE_CROP";
144 OperationType2["Rotate"] = "ROTATE";
145 OperationType2["TranscodeImage"] = "TRANSCODE_IMAGE";
146 OperationType2["ThumbnailGeneration"] = "THUMBNAIL_GENERATION";
147 OperationType2["Finalize"] = "FINALIZE";
148 return OperationType2;
149 })(OperationType || {});
150
151 // packages/upload-media/build-module/store/constants.mjs
152 var STORE_NAME = "core/upload-media";
153 var DEFAULT_MAX_CONCURRENT_UPLOADS = 5;
154 var DEFAULT_MAX_CONCURRENT_IMAGE_PROCESSING = 2;
155 var CLIENT_SIDE_SUPPORTED_MIME_TYPES = [
156 "image/jpeg",
157 "image/png",
158 "image/gif",
159 "image/webp",
160 "image/avif"
161 ];
162
163 // packages/upload-media/build-module/store/reducer.mjs
164 var noop = () => {
165 };
166 var DEFAULT_STATE = {
167 queue: [],
168 queueStatus: "active",
169 blobUrls: {},
170 settings: {
171 mediaUpload: noop,
172 maxConcurrentUploads: DEFAULT_MAX_CONCURRENT_UPLOADS,
173 maxConcurrentImageProcessing: DEFAULT_MAX_CONCURRENT_IMAGE_PROCESSING
174 }
175 };
176 function reducer(state = DEFAULT_STATE, action = { type: Type.Unknown }) {
177 switch (action.type) {
178 case Type.PauseQueue: {
179 return {
180 ...state,
181 queueStatus: "paused"
182 };
183 }
184 case Type.ResumeQueue: {
185 return {
186 ...state,
187 queueStatus: "active"
188 };
189 }
190 case Type.PauseItem:
191 return {
192 ...state,
193 queue: state.queue.map(
194 (item) => item.id === action.id ? {
195 ...item,
196 status: ItemStatus.Paused
197 } : item
198 )
199 };
200 case Type.ResumeItem:
201 return {
202 ...state,
203 queue: state.queue.map(
204 (item) => item.id === action.id ? {
205 ...item,
206 status: ItemStatus.Processing
207 } : item
208 )
209 };
210 case Type.Add:
211 return {
212 ...state,
213 queue: [...state.queue, action.item]
214 };
215 case Type.Cancel:
216 return {
217 ...state,
218 queue: state.queue.map(
219 (item) => item.id === action.id ? {
220 ...item,
221 error: action.error
222 } : item
223 )
224 };
225 case Type.RetryItem:
226 return {
227 ...state,
228 queue: state.queue.map(
229 (item) => item.id === action.id ? {
230 ...item,
231 status: ItemStatus.Processing,
232 error: void 0,
233 retryCount: (item.retryCount ?? 0) + 1
234 } : item
235 )
236 };
237 case Type.Remove:
238 return {
239 ...state,
240 queue: state.queue.filter((item) => item.id !== action.id)
241 };
242 case Type.OperationStart: {
243 return {
244 ...state,
245 queue: state.queue.map(
246 (item) => item.id === action.id ? {
247 ...item,
248 currentOperation: action.operation
249 } : item
250 )
251 };
252 }
253 case Type.AddOperations:
254 return {
255 ...state,
256 queue: state.queue.map((item) => {
257 if (item.id !== action.id) {
258 return item;
259 }
260 return {
261 ...item,
262 operations: [
263 ...item.operations || [],
264 ...action.operations
265 ]
266 };
267 })
268 };
269 case Type.OperationFinish:
270 return {
271 ...state,
272 queue: state.queue.map((item) => {
273 if (item.id !== action.id) {
274 return item;
275 }
276 const operations = item.operations ? item.operations.slice(1) : [];
277 const attachment = item.attachment || action.item.attachment ? {
278 ...item.attachment,
279 ...action.item.attachment
280 } : void 0;
281 return {
282 ...item,
283 currentOperation: void 0,
284 operations,
285 ...action.item,
286 attachment,
287 additionalData: {
288 ...item.additionalData,
289 ...action.item.additionalData
290 }
291 };
292 })
293 };
294 case Type.CacheBlobUrl: {
295 const blobUrls = state.blobUrls[action.id] || [];
296 return {
297 ...state,
298 blobUrls: {
299 ...state.blobUrls,
300 [action.id]: [...blobUrls, action.blobUrl]
301 }
302 };
303 }
304 case Type.RevokeBlobUrls: {
305 const newBlobUrls = { ...state.blobUrls };
306 delete newBlobUrls[action.id];
307 return {
308 ...state,
309 blobUrls: newBlobUrls
310 };
311 }
312 case Type.UpdateProgress:
313 return {
314 ...state,
315 queue: state.queue.map(
316 (item) => item.id === action.id ? {
317 ...item,
318 progress: action.progress
319 } : item
320 )
321 };
322 case Type.UpdateSettings: {
323 return {
324 ...state,
325 settings: {
326 ...state.settings,
327 ...action.settings
328 }
329 };
330 }
331 }
332 return state;
333 }
334 var reducer_default = reducer;
335
336 // packages/upload-media/build-module/store/selectors.mjs
337 var selectors_exports = {};
338 __export(selectors_exports, {
339 getItems: () => getItems,
340 getSettings: () => getSettings,
341 isUploading: () => isUploading,
342 isUploadingById: () => isUploadingById,
343 isUploadingByUrl: () => isUploadingByUrl
344 });
345 function getItems(state) {
346 return state.queue;
347 }
348 function isUploading(state) {
349 return state.queue.length >= 1;
350 }
351 function isUploadingByUrl(state, url) {
352 return state.queue.some(
353 (item) => item.attachment?.url === url || item.sourceUrl === url
354 );
355 }
356 function isUploadingById(state, attachmentId) {
357 return state.queue.some(
358 (item) => item.attachment?.id === attachmentId || item.sourceAttachmentId === attachmentId
359 );
360 }
361 function getSettings(state) {
362 return state.settings;
363 }
364
365 // packages/upload-media/build-module/store/private-selectors.mjs
366 var private_selectors_exports = {};
367 __export(private_selectors_exports, {
368 getActiveImageProcessingCount: () => getActiveImageProcessingCount,
369 getActiveUploadCount: () => getActiveUploadCount,
370 getAllItems: () => getAllItems,
371 getBlobUrls: () => getBlobUrls,
372 getFailedItems: () => getFailedItems,
373 getItem: () => getItem,
374 getItemProgress: () => getItemProgress,
375 getPausedUploadForPost: () => getPausedUploadForPost,
376 getPendingImageProcessing: () => getPendingImageProcessing,
377 getPendingUploads: () => getPendingUploads,
378 hasPendingItemsByParentId: () => hasPendingItemsByParentId,
379 isBatchUploaded: () => isBatchUploaded,
380 isPaused: () => isPaused,
381 isUploadingToPost: () => isUploadingToPost
382 });
383 function getAllItems(state) {
384 return state.queue;
385 }
386 function getItem(state, id) {
387 return state.queue.find((item) => item.id === id);
388 }
389 function isBatchUploaded(state, batchId) {
390 const batchItems = state.queue.filter(
391 (item) => batchId === item.batchId
392 );
393 return batchItems.length === 0;
394 }
395 function isUploadingToPost(state, postOrAttachmentId) {
396 return state.queue.some(
397 (item) => item.currentOperation === OperationType.Upload && item.additionalData.post === postOrAttachmentId
398 );
399 }
400 function getPausedUploadForPost(state, postOrAttachmentId) {
401 return state.queue.find(
402 (item) => item.status === ItemStatus.Paused && item.additionalData.post === postOrAttachmentId
403 );
404 }
405 function isPaused(state) {
406 return state.queueStatus === "paused";
407 }
408 function getBlobUrls(state, id) {
409 return state.blobUrls[id] || [];
410 }
411 function getActiveUploadCount(state) {
412 return state.queue.filter(
413 (item) => item.currentOperation === OperationType.Upload
414 ).length;
415 }
416 function getPendingUploads(state) {
417 return state.queue.filter((item) => {
418 const nextOperation = Array.isArray(item.operations?.[0]) ? item.operations[0][0] : item.operations?.[0];
419 return nextOperation === OperationType.Upload && item.currentOperation !== OperationType.Upload;
420 });
421 }
422 function getActiveImageProcessingCount(state) {
423 return state.queue.filter(
424 (item) => item.currentOperation === OperationType.ResizeCrop || item.currentOperation === OperationType.Rotate
425 ).length;
426 }
427 function getPendingImageProcessing(state) {
428 return state.queue.filter((item) => {
429 const nextOperation = Array.isArray(item.operations?.[0]) ? item.operations[0][0] : item.operations?.[0];
430 return (nextOperation === OperationType.ResizeCrop || nextOperation === OperationType.Rotate) && item.currentOperation !== OperationType.ResizeCrop && item.currentOperation !== OperationType.Rotate;
431 });
432 }
433 function getFailedItems(state) {
434 return state.queue.filter((item) => item.error !== void 0);
435 }
436 function hasPendingItemsByParentId(state, parentId) {
437 return state.queue.some((item) => item.parentId === parentId);
438 }
439 function getItemProgress(state, id) {
440 const item = state.queue.find((i) => i.id === id);
441 return item?.progress;
442 }
443
444 // packages/upload-media/build-module/store/actions.mjs
445 var actions_exports = {};
446 __export(actions_exports, {
447 addItems: () => addItems,
448 cancelItem: () => cancelItem,
449 retryItem: () => retryItem
450 });
451
452 // node_modules/uuid/dist/esm-browser/rng.js
453 var getRandomValues;
454 var rnds8 = new Uint8Array(16);
455 function rng() {
456 if (!getRandomValues) {
457 getRandomValues = typeof crypto !== "undefined" && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);
458 if (!getRandomValues) {
459 throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");
460 }
461 }
462 return getRandomValues(rnds8);
463 }
464
465 // node_modules/uuid/dist/esm-browser/stringify.js
466 var byteToHex = [];
467 for (let i = 0; i < 256; ++i) {
468 byteToHex.push((i + 256).toString(16).slice(1));
469 }
470 function unsafeStringify(arr, offset = 0) {
471 return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];
472 }
473
474 // node_modules/uuid/dist/esm-browser/native.js
475 var randomUUID = typeof crypto !== "undefined" && crypto.randomUUID && crypto.randomUUID.bind(crypto);
476 var native_default = {
477 randomUUID
478 };
479
480 // node_modules/uuid/dist/esm-browser/v4.js
481 function v4(options, buf, offset) {
482 if (native_default.randomUUID && !buf && !options) {
483 return native_default.randomUUID();
484 }
485 options = options || {};
486 const rnds = options.random || (options.rng || rng)();
487 rnds[6] = rnds[6] & 15 | 64;
488 rnds[8] = rnds[8] & 63 | 128;
489 if (buf) {
490 offset = offset || 0;
491 for (let i = 0; i < 16; ++i) {
492 buf[offset + i] = rnds[i];
493 }
494 return buf;
495 }
496 return unsafeStringify(rnds);
497 }
498 var v4_default = v4;
499
500 // packages/upload-media/build-module/image-file.mjs
501 var ImageFile = class extends File {
502 width = 0;
503 height = 0;
504 originalWidth = 0;
505 originalHeight = 0;
506 get wasResized() {
507 return (this.originalWidth || 0) > this.width || (this.originalHeight || 0) > this.height;
508 }
509 constructor(file, width, height, originalWidth, originalHeight) {
510 super([file], file.name, {
511 type: file.type,
512 lastModified: file.lastModified
513 });
514 this.width = width;
515 this.height = height;
516 this.originalWidth = originalWidth;
517 this.originalHeight = originalHeight;
518 }
519 };
520
521 // packages/upload-media/build-module/utils.mjs
522 var import_url = __toESM(require_url(), 1);
523 var import_i18n = __toESM(require_i18n(), 1);
524 function convertBlobToFile(fileOrBlob) {
525 if (fileOrBlob instanceof File) {
526 return fileOrBlob;
527 }
528 if ("name" in fileOrBlob && typeof fileOrBlob.name === "string") {
529 return new File([fileOrBlob], fileOrBlob.name, {
530 type: fileOrBlob.type,
531 lastModified: fileOrBlob.lastModified
532 });
533 }
534 const ext = fileOrBlob.type.split("/")[1];
535 const mediaType = "application/pdf" === fileOrBlob.type ? "document" : fileOrBlob.type.split("/")[0];
536 return new File([fileOrBlob], `${mediaType}.${ext}`, {
537 type: fileOrBlob.type
538 });
539 }
540 function renameFile(file, name) {
541 return new File([file], name, {
542 type: file.type,
543 lastModified: file.lastModified
544 });
545 }
546 function cloneFile(file) {
547 return renameFile(file, file.name);
548 }
549 function getFileBasename(name) {
550 return name.includes(".") ? name.split(".").slice(0, -1).join(".") : name;
551 }
552
553 // packages/upload-media/build-module/store/utils/index.mjs
554 var vipsModulePromise;
555 var vipsModule;
556 function loadVipsModule() {
557 if (!vipsModulePromise) {
558 vipsModulePromise = import("@wordpress/vips/worker").then(
559 (mod) => {
560 vipsModule = mod;
561 return mod;
562 }
563 );
564 }
565 return vipsModulePromise;
566 }
567 async function vipsConvertImageFormat(id, file, type, quality, interlaced) {
568 const { vipsConvertImageFormat: convertImageFormat } = await loadVipsModule();
569 const buffer = await convertImageFormat(
570 id,
571 await file.arrayBuffer(),
572 file.type,
573 type,
574 quality,
575 interlaced
576 );
577 const ext = type.split("/")[1];
578 const fileName = `${getFileBasename(file.name)}.${ext}`;
579 return new File([new Blob([buffer])], fileName, {
580 type
581 });
582 }
583 async function vipsHasTransparency(url) {
584 const { vipsHasTransparency: hasTransparency } = await loadVipsModule();
585 const response = await fetch(url);
586 if (!response.ok) {
587 throw new Error(`Failed to fetch image: ${response.status}`);
588 }
589 return hasTransparency(await response.arrayBuffer());
590 }
591 async function vipsResizeImage(id, file, resize, smartCrop, addSuffix, signal, scaledSuffix, quality) {
592 if (signal?.aborted) {
593 throw new Error("Operation aborted");
594 }
595 const { vipsResizeImage: resizeImage } = await loadVipsModule();
596 const { buffer, width, height, originalWidth, originalHeight } = await resizeImage(
597 id,
598 await file.arrayBuffer(),
599 file.type,
600 resize,
601 smartCrop,
602 quality
603 );
604 let fileName = file.name;
605 const wasResized = originalWidth > width || originalHeight > height;
606 if (wasResized) {
607 const basename = getFileBasename(file.name);
608 if (scaledSuffix) {
609 fileName = file.name.replace(basename, `${basename}-scaled`);
610 } else if (addSuffix) {
611 fileName = file.name.replace(
612 basename,
613 `${basename}-${width}x${height}`
614 );
615 }
616 }
617 const resultFile = new ImageFile(
618 new File(
619 [new Blob([buffer], { type: file.type })],
620 fileName,
621 {
622 type: file.type
623 }
624 ),
625 width,
626 height,
627 originalWidth,
628 originalHeight
629 );
630 return resultFile;
631 }
632 async function vipsBatchResizeImage(id, file, outputType, configs, smartCrop = false) {
633 const { vipsBatchResizeImage: batchResize } = await loadVipsModule();
634 const resizes = configs.map((c) => ({
635 resize: { ...c.resize },
636 quality: c.quality
637 }));
638 const results = await batchResize(
639 id,
640 await file.arrayBuffer(),
641 file.type,
642 outputType,
643 resizes,
644 smartCrop
645 );
646 const ext = outputType.split("/")[1];
647 const sourceBasename = getFileBasename(file.name);
648 return results.map((result, i) => {
649 const config = configs[i];
650 const { width, height, originalWidth, originalHeight } = result;
651 const wasResized = originalWidth > width || originalHeight > height;
652 let fileName = `${sourceBasename}.${ext}`;
653 if (wasResized) {
654 if (config.scaledSuffix) {
655 fileName = `${sourceBasename}-scaled.${ext}`;
656 } else {
657 fileName = `${sourceBasename}-${width}x${height}.${ext}`;
658 }
659 }
660 return {
661 name: config.name,
662 file: new ImageFile(
663 new File(
664 [
665 new Blob([result.buffer], {
666 type: outputType
667 })
668 ],
669 fileName,
670 { type: outputType }
671 ),
672 width,
673 height,
674 originalWidth,
675 originalHeight
676 )
677 };
678 });
679 }
680 async function vipsRotateImage(id, file, orientation, signal) {
681 if (signal?.aborted) {
682 throw new Error("Operation aborted");
683 }
684 if (orientation === 1) {
685 return file;
686 }
687 const { vipsRotateImage: rotateImage } = await loadVipsModule();
688 const { buffer, width, height } = await rotateImage(
689 id,
690 await file.arrayBuffer(),
691 file.type,
692 orientation
693 );
694 const basename = getFileBasename(file.name);
695 const fileName = file.name.replace(basename, `${basename}-rotated`);
696 const resultFile = new ImageFile(
697 new File(
698 [new Blob([buffer], { type: file.type })],
699 fileName,
700 {
701 type: file.type
702 }
703 ),
704 width,
705 height
706 );
707 return resultFile;
708 }
709 async function vipsCancelOperations(id) {
710 if (!vipsModule) {
711 return false;
712 }
713 return vipsModule.vipsCancelOperations(id);
714 }
715 function terminateVipsWorker() {
716 if (vipsModule) {
717 vipsModule.terminateVipsWorker();
718 }
719 }
720
721 // packages/upload-media/build-module/validate-mime-type.mjs
722 var import_i18n2 = __toESM(require_i18n(), 1);
723
724 // packages/upload-media/build-module/upload-error.mjs
725 var UploadError = class extends Error {
726 code;
727 file;
728 constructor({ code, message, file, cause }) {
729 super(message, { cause });
730 Object.setPrototypeOf(this, new.target.prototype);
731 this.code = code;
732 this.file = file;
733 }
734 };
735
736 // packages/upload-media/build-module/validate-mime-type.mjs
737 function validateMimeType(file, allowedTypes) {
738 if (!allowedTypes) {
739 return;
740 }
741 const isAllowedType = allowedTypes.some((allowedType) => {
742 if (allowedType.includes("/")) {
743 return allowedType === file.type;
744 }
745 return file.type.startsWith(`${allowedType}/`);
746 });
747 if (file.type && !isAllowedType) {
748 throw new UploadError({
749 code: "MIME_TYPE_NOT_SUPPORTED",
750 message: (0, import_i18n2.sprintf)(
751 // translators: %s: file name.
752 (0, import_i18n2.__)("%s: Sorry, this file type is not supported here."),
753 file.name
754 ),
755 file
756 });
757 }
758 }
759
760 // packages/upload-media/build-module/validate-mime-type-for-user.mjs
761 var import_i18n3 = __toESM(require_i18n(), 1);
762
763 // packages/upload-media/build-module/get-mime-types-array.mjs
764 function getMimeTypesArray(wpMimeTypesObject) {
765 if (!wpMimeTypesObject) {
766 return null;
767 }
768 return Object.entries(wpMimeTypesObject).flatMap(
769 ([extensionsString, mime]) => {
770 const [type] = mime.split("/");
771 const extensions = extensionsString.split("|");
772 return [
773 mime,
774 ...extensions.map(
775 (extension) => `${type}/${extension}`
776 )
777 ];
778 }
779 );
780 }
781
782 // packages/upload-media/build-module/validate-mime-type-for-user.mjs
783 function validateMimeTypeForUser(file, wpAllowedMimeTypes) {
784 const allowedMimeTypesForUser = getMimeTypesArray(wpAllowedMimeTypes);
785 if (!allowedMimeTypesForUser) {
786 return;
787 }
788 const isAllowedMimeTypeForUser = allowedMimeTypesForUser.includes(
789 file.type
790 );
791 if (file.type && !isAllowedMimeTypeForUser) {
792 throw new UploadError({
793 code: "MIME_TYPE_NOT_ALLOWED_FOR_USER",
794 message: (0, import_i18n3.sprintf)(
795 // translators: %s: file name.
796 (0, import_i18n3.__)(
797 "%s: Sorry, you are not allowed to upload this file type."
798 ),
799 file.name
800 ),
801 file
802 });
803 }
804 }
805
806 // packages/upload-media/build-module/validate-file-size.mjs
807 var import_i18n4 = __toESM(require_i18n(), 1);
808 function validateFileSize(file, maxUploadFileSize) {
809 if (file.size <= 0) {
810 throw new UploadError({
811 code: "EMPTY_FILE",
812 message: (0, import_i18n4.sprintf)(
813 // translators: %s: file name.
814 (0, import_i18n4.__)("%s: This file is empty."),
815 file.name
816 ),
817 file
818 });
819 }
820 if (maxUploadFileSize && file.size > maxUploadFileSize) {
821 throw new UploadError({
822 code: "SIZE_ABOVE_LIMIT",
823 message: (0, import_i18n4.sprintf)(
824 // translators: %s: file name.
825 (0, import_i18n4.__)(
826 "%s: This file exceeds the maximum upload size for this site."
827 ),
828 file.name
829 ),
830 file
831 });
832 }
833 }
834
835 // packages/upload-media/build-module/store/actions.mjs
836 function addItems({
837 files,
838 onChange,
839 onSuccess,
840 onError,
841 onBatchSuccess,
842 additionalData,
843 allowedTypes
844 }) {
845 return async ({ select: select2, dispatch }) => {
846 const batchId = v4_default();
847 for (const file of files) {
848 try {
849 validateMimeType(file, allowedTypes);
850 validateMimeTypeForUser(
851 file,
852 select2.getSettings().allowedMimeTypes
853 );
854 } catch (error) {
855 onError?.(error);
856 continue;
857 }
858 try {
859 validateFileSize(
860 file,
861 select2.getSettings().maxUploadFileSize
862 );
863 } catch (error) {
864 onError?.(error);
865 continue;
866 }
867 dispatch.addItem({
868 file,
869 batchId,
870 onChange,
871 onSuccess,
872 onBatchSuccess,
873 onError,
874 additionalData
875 });
876 }
877 };
878 }
879 function cancelItem(id, error, silent = false) {
880 return async ({ select: select2, dispatch }) => {
881 const item = select2.getItem(id);
882 if (!item) {
883 return;
884 }
885 item.abortController?.abort();
886 await vipsCancelOperations(id);
887 if (!silent) {
888 const { onError } = item;
889 onError?.(error ?? new Error("Upload cancelled"));
890 if (!onError && error) {
891 console.error("Upload cancelled", error);
892 }
893 }
894 dispatch({
895 type: Type.Cancel,
896 id,
897 error
898 });
899 dispatch.removeItem(id);
900 dispatch.revokeBlobUrls(id);
901 if (item.batchId && select2.isBatchUploaded(item.batchId)) {
902 item.onBatchSuccess?.();
903 }
904 };
905 }
906 function retryItem(id) {
907 return async ({ select: select2, dispatch }) => {
908 const item = select2.getItem(id);
909 if (!item) {
910 return;
911 }
912 if (!item.error) {
913 return;
914 }
915 dispatch({
916 type: Type.RetryItem,
917 id
918 });
919 dispatch.processItem(id);
920 };
921 }
922
923 // packages/upload-media/build-module/store/private-actions.mjs
924 var private_actions_exports = {};
925 __export(private_actions_exports, {
926 addItem: () => addItem,
927 addSideloadItem: () => addSideloadItem,
928 finalizeItem: () => finalizeItem,
929 finishOperation: () => finishOperation,
930 generateThumbnails: () => generateThumbnails,
931 getTranscodeImageOperation: () => getTranscodeImageOperation,
932 pauseItem: () => pauseItem,
933 pauseQueue: () => pauseQueue,
934 prepareItem: () => prepareItem,
935 processItem: () => processItem,
936 removeItem: () => removeItem,
937 resizeCropItem: () => resizeCropItem,
938 resumeItemByPostId: () => resumeItemByPostId,
939 resumeQueue: () => resumeQueue,
940 revokeBlobUrls: () => revokeBlobUrls,
941 rotateItem: () => rotateItem,
942 sideloadItem: () => sideloadItem,
943 transcodeImageItem: () => transcodeImageItem,
944 updateItemProgress: () => updateItemProgress,
945 updateSettings: () => updateSettings,
946 uploadItem: () => uploadItem
947 });
948 var import_blob = __toESM(require_blob(), 1);
949
950 // packages/upload-media/build-module/stub-file.mjs
951 var StubFile = class extends File {
952 constructor(fileName = "stub-file") {
953 super([], fileName);
954 }
955 };
956
957 // packages/upload-media/build-module/store/private-actions.mjs
958 var DEFAULT_OUTPUT_QUALITY = 0.82;
959 function shouldPauseForSideload(item, operation, select2) {
960 if (operation !== OperationType.Upload || !item.parentId || !item.additionalData.post) {
961 return false;
962 }
963 return select2.isUploadingToPost(item.additionalData.post);
964 }
965 function addItem({
966 file: fileOrBlob,
967 batchId,
968 onChange,
969 onSuccess,
970 onBatchSuccess,
971 onError,
972 additionalData = {},
973 sourceUrl,
974 sourceAttachmentId,
975 abortController,
976 operations
977 }) {
978 return async ({ dispatch }) => {
979 const itemId = v4_default();
980 const file = convertBlobToFile(fileOrBlob);
981 let blobUrl;
982 if (!(file instanceof StubFile)) {
983 blobUrl = (0, import_blob.createBlobURL)(file);
984 dispatch({
985 type: Type.CacheBlobUrl,
986 id: itemId,
987 blobUrl
988 });
989 }
990 dispatch({
991 type: Type.Add,
992 item: {
993 id: itemId,
994 batchId,
995 status: ItemStatus.Processing,
996 sourceFile: cloneFile(file),
997 file,
998 attachment: {
999 url: blobUrl
1000 },
1001 additionalData: {
1002 convert_format: false,
1003 generate_sub_sizes: false,
1004 ...additionalData
1005 },
1006 onChange,
1007 onSuccess,
1008 onBatchSuccess,
1009 onError,
1010 sourceUrl,
1011 sourceAttachmentId,
1012 abortController: abortController || new AbortController(),
1013 operations: Array.isArray(operations) ? operations : [OperationType.Prepare]
1014 }
1015 });
1016 dispatch.processItem(itemId);
1017 };
1018 }
1019 function addSideloadItem({
1020 file,
1021 onChange,
1022 additionalData,
1023 operations,
1024 batchId,
1025 parentId
1026 }) {
1027 return ({ dispatch }) => {
1028 const itemId = v4_default();
1029 dispatch({
1030 type: Type.Add,
1031 item: {
1032 id: itemId,
1033 batchId,
1034 status: ItemStatus.Processing,
1035 sourceFile: cloneFile(file),
1036 file,
1037 onChange,
1038 additionalData: {
1039 ...additionalData
1040 },
1041 parentId,
1042 operations: Array.isArray(operations) ? operations : [OperationType.Prepare],
1043 abortController: new AbortController()
1044 }
1045 });
1046 dispatch.processItem(itemId);
1047 };
1048 }
1049 function processItem(id) {
1050 return async ({ select: select2, dispatch }) => {
1051 if (select2.isPaused()) {
1052 return;
1053 }
1054 const item = select2.getItem(id);
1055 if (!item) {
1056 return;
1057 }
1058 const {
1059 attachment,
1060 onChange,
1061 onSuccess,
1062 onBatchSuccess,
1063 batchId,
1064 parentId
1065 } = item;
1066 const operation = Array.isArray(item.operations?.[0]) ? item.operations[0][0] : item.operations?.[0];
1067 const operationArgs = Array.isArray(item.operations?.[0]) ? item.operations[0][1] : void 0;
1068 if (shouldPauseForSideload(item, operation, select2)) {
1069 dispatch({
1070 type: Type.PauseItem,
1071 id
1072 });
1073 return;
1074 }
1075 if (operation === OperationType.Upload) {
1076 const settings = select2.getSettings();
1077 const activeCount = select2.getActiveUploadCount();
1078 if (activeCount >= settings.maxConcurrentUploads) {
1079 return;
1080 }
1081 }
1082 if (operation === OperationType.ResizeCrop || operation === OperationType.Rotate) {
1083 const settings = select2.getSettings();
1084 const activeCount = select2.getActiveImageProcessingCount();
1085 if (activeCount >= settings.maxConcurrentImageProcessing) {
1086 return;
1087 }
1088 }
1089 if (attachment) {
1090 onChange?.([attachment]);
1091 }
1092 if (!operation) {
1093 if (parentId || !parentId && !select2.hasPendingItemsByParentId(id)) {
1094 if (attachment) {
1095 onSuccess?.([attachment]);
1096 }
1097 dispatch.removeItem(id);
1098 dispatch.revokeBlobUrls(id);
1099 if (batchId && select2.isBatchUploaded(batchId)) {
1100 onBatchSuccess?.();
1101 }
1102 }
1103 if (parentId && batchId && select2.isBatchUploaded(batchId)) {
1104 const parentItem = select2.getItem(parentId);
1105 if (!parentItem) {
1106 return;
1107 }
1108 if (parentItem.operations && parentItem.operations.length > 0) {
1109 dispatch.processItem(parentId);
1110 return;
1111 }
1112 if (attachment) {
1113 parentItem.onSuccess?.([attachment]);
1114 }
1115 dispatch.removeItem(parentId);
1116 dispatch.revokeBlobUrls(parentId);
1117 if (parentItem.batchId && select2.isBatchUploaded(parentItem.batchId)) {
1118 parentItem.onBatchSuccess?.();
1119 }
1120 }
1121 return;
1122 }
1123 if (operation === OperationType.Finalize && select2.hasPendingItemsByParentId(id)) {
1124 return;
1125 }
1126 dispatch({
1127 type: Type.OperationStart,
1128 id,
1129 operation
1130 });
1131 switch (operation) {
1132 case OperationType.Prepare:
1133 dispatch.prepareItem(item.id);
1134 break;
1135 case OperationType.ResizeCrop:
1136 dispatch.resizeCropItem(
1137 item.id,
1138 operationArgs
1139 );
1140 break;
1141 case OperationType.Rotate:
1142 dispatch.rotateItem(
1143 item.id,
1144 operationArgs
1145 );
1146 break;
1147 case OperationType.TranscodeImage:
1148 dispatch.transcodeImageItem(
1149 item.id,
1150 operationArgs
1151 );
1152 break;
1153 case OperationType.Upload:
1154 if (item.parentId) {
1155 dispatch.sideloadItem(id);
1156 } else {
1157 dispatch.uploadItem(id);
1158 }
1159 break;
1160 case OperationType.ThumbnailGeneration:
1161 dispatch.generateThumbnails(id);
1162 break;
1163 case OperationType.Finalize:
1164 dispatch.finalizeItem(id);
1165 break;
1166 }
1167 };
1168 }
1169 function pauseQueue() {
1170 return {
1171 type: Type.PauseQueue
1172 };
1173 }
1174 function resumeQueue() {
1175 return async ({ select: select2, dispatch }) => {
1176 dispatch({
1177 type: Type.ResumeQueue
1178 });
1179 for (const item of select2.getAllItems()) {
1180 dispatch.processItem(item.id);
1181 }
1182 };
1183 }
1184 function pauseItem(id) {
1185 return async ({ dispatch }) => {
1186 dispatch({
1187 type: Type.PauseItem,
1188 id
1189 });
1190 };
1191 }
1192 function resumeItemByPostId(postOrAttachmentId) {
1193 return async ({ select: select2, dispatch }) => {
1194 const item = select2.getPausedUploadForPost(postOrAttachmentId);
1195 if (item) {
1196 dispatch({
1197 type: Type.ResumeItem,
1198 id: item.id
1199 });
1200 dispatch.processItem(item.id);
1201 }
1202 };
1203 }
1204 function removeItem(id) {
1205 return async ({ select: select2, dispatch }) => {
1206 const item = select2.getItem(id);
1207 if (!item) {
1208 return;
1209 }
1210 dispatch({
1211 type: Type.Remove,
1212 id
1213 });
1214 if (select2.getAllItems().length === 0) {
1215 terminateVipsWorker();
1216 }
1217 };
1218 }
1219 function finishOperation(id, updates) {
1220 return async ({ select: select2, dispatch }) => {
1221 const item = select2.getItem(id);
1222 const previousOperation = item?.currentOperation;
1223 dispatch({
1224 type: Type.OperationFinish,
1225 id,
1226 item: updates
1227 });
1228 dispatch.processItem(id);
1229 if (previousOperation === OperationType.Upload) {
1230 const pendingUploads = select2.getPendingUploads();
1231 for (const pendingItem of pendingUploads) {
1232 dispatch.processItem(pendingItem.id);
1233 }
1234 }
1235 if (previousOperation === OperationType.ResizeCrop || previousOperation === OperationType.Rotate) {
1236 const pendingItems = select2.getPendingImageProcessing();
1237 for (const pendingItem of pendingItems) {
1238 dispatch.processItem(pendingItem.id);
1239 }
1240 }
1241 };
1242 }
1243 var VALID_IMAGE_FORMATS = ["jpeg", "webp", "avif", "png", "gif"];
1244 function isValidImageFormat(format) {
1245 return VALID_IMAGE_FORMATS.includes(format);
1246 }
1247 function getInterlacedSetting(outputMimeType, settings) {
1248 switch (outputMimeType) {
1249 case "image/jpeg":
1250 return settings.jpegInterlaced ?? false;
1251 case "image/png":
1252 return settings.pngInterlaced ?? false;
1253 case "image/gif":
1254 return settings.gifInterlaced ?? false;
1255 default:
1256 return false;
1257 }
1258 }
1259 async function getTranscodeImageOperation(file, outputMimeType, settings) {
1260 if (file.type === "image/png" && outputMimeType === "image/jpeg") {
1261 const blobUrl = (0, import_blob.createBlobURL)(file);
1262 try {
1263 const hasAlpha = await vipsHasTransparency(blobUrl);
1264 if (hasAlpha) {
1265 return null;
1266 }
1267 } catch {
1268 return null;
1269 } finally {
1270 (0, import_blob.revokeBlobURL)(blobUrl);
1271 }
1272 }
1273 const formatPart = outputMimeType.split("/")[1];
1274 if (!isValidImageFormat(formatPart)) {
1275 return null;
1276 }
1277 return [
1278 OperationType.TranscodeImage,
1279 {
1280 outputFormat: formatPart,
1281 outputQuality: DEFAULT_OUTPUT_QUALITY,
1282 interlaced: getInterlacedSetting(outputMimeType, settings)
1283 }
1284 ];
1285 }
1286 function prepareItem(id) {
1287 return async ({ select: select2, dispatch }) => {
1288 const item = select2.getItem(id);
1289 if (!item) {
1290 return;
1291 }
1292 const { file } = item;
1293 const operations = [];
1294 const settings = select2.getSettings();
1295 const isImage = file.type.startsWith("image/");
1296 const isVipsSupported = CLIENT_SIDE_SUPPORTED_MIME_TYPES.includes(
1297 file.type
1298 );
1299 if (isImage && isVipsSupported) {
1300 const { imageOutputFormats } = settings;
1301 const outputMimeType = imageOutputFormats?.[file.type];
1302 if (outputMimeType && outputMimeType !== file.type) {
1303 const transcodeOperation = await getTranscodeImageOperation(
1304 file,
1305 outputMimeType,
1306 settings
1307 );
1308 if (transcodeOperation) {
1309 operations.push(transcodeOperation);
1310 }
1311 }
1312 operations.push(
1313 OperationType.Upload,
1314 OperationType.ThumbnailGeneration,
1315 OperationType.Finalize
1316 );
1317 } else {
1318 operations.push(OperationType.Upload);
1319 }
1320 dispatch({
1321 type: Type.AddOperations,
1322 id,
1323 operations
1324 });
1325 const updates = !isVipsSupported || !isImage ? {
1326 additionalData: {
1327 ...item.additionalData,
1328 generate_sub_sizes: true,
1329 convert_format: true
1330 }
1331 } : {};
1332 dispatch.finishOperation(id, updates);
1333 };
1334 }
1335 function uploadItem(id) {
1336 return async ({ select: select2, dispatch }) => {
1337 const item = select2.getItem(id);
1338 if (!item) {
1339 return;
1340 }
1341 select2.getSettings().mediaUpload({
1342 filesList: [item.file],
1343 additionalData: item.additionalData,
1344 signal: item.abortController?.signal,
1345 onFileChange: ([attachment]) => {
1346 if (attachment && !(0, import_blob.isBlobURL)(attachment.url)) {
1347 dispatch.finishOperation(id, {
1348 attachment
1349 });
1350 }
1351 },
1352 onSuccess: ([attachment]) => {
1353 dispatch.finishOperation(id, {
1354 attachment
1355 });
1356 },
1357 onError: (error) => {
1358 dispatch.cancelItem(id, error);
1359 }
1360 });
1361 };
1362 }
1363 function sideloadItem(id) {
1364 return async ({ select: select2, dispatch }) => {
1365 const item = select2.getItem(id);
1366 if (!item) {
1367 return;
1368 }
1369 const { post, ...additionalData } = item.additionalData;
1370 const mediaSideload = select2.getSettings().mediaSideload;
1371 if (!mediaSideload) {
1372 dispatch.finishOperation(id, {});
1373 return;
1374 }
1375 mediaSideload({
1376 file: item.file,
1377 attachmentId: post,
1378 additionalData,
1379 signal: item.abortController?.signal,
1380 onFileChange: ([attachment]) => {
1381 dispatch.finishOperation(id, { attachment });
1382 dispatch.resumeItemByPostId(post);
1383 },
1384 onError: (error) => {
1385 dispatch.cancelItem(id, error);
1386 dispatch.resumeItemByPostId(post);
1387 }
1388 });
1389 };
1390 }
1391 function resizeCropItem(id, args) {
1392 return async ({ select: select2, dispatch }) => {
1393 const item = select2.getItem(id);
1394 if (!item) {
1395 return;
1396 }
1397 if (!args?.resize) {
1398 dispatch.finishOperation(id, {
1399 file: item.file
1400 });
1401 return;
1402 }
1403 const addSuffix = Boolean(item.parentId);
1404 const scaledSuffix = Boolean(args.isThresholdResize);
1405 try {
1406 const file = await vipsResizeImage(
1407 item.id,
1408 item.file,
1409 args.resize,
1410 false,
1411 // smartCrop
1412 addSuffix,
1413 item.abortController?.signal,
1414 scaledSuffix
1415 );
1416 const blobUrl = (0, import_blob.createBlobURL)(file);
1417 dispatch({
1418 type: Type.CacheBlobUrl,
1419 id,
1420 blobUrl
1421 });
1422 dispatch.finishOperation(id, {
1423 file,
1424 attachment: {
1425 url: blobUrl
1426 }
1427 });
1428 } catch (error) {
1429 dispatch.cancelItem(
1430 id,
1431 new UploadError({
1432 code: "IMAGE_TRANSCODING_ERROR",
1433 message: "File could not be uploaded",
1434 file: item.file,
1435 cause: error instanceof Error ? error : void 0
1436 })
1437 );
1438 }
1439 };
1440 }
1441 function rotateItem(id, args) {
1442 return async ({ select: select2, dispatch }) => {
1443 const item = select2.getItem(id);
1444 if (!item) {
1445 return;
1446 }
1447 if (!args?.orientation || args.orientation === 1) {
1448 dispatch.finishOperation(id, {
1449 file: item.file
1450 });
1451 return;
1452 }
1453 try {
1454 const file = await vipsRotateImage(
1455 item.id,
1456 item.file,
1457 args.orientation,
1458 item.abortController?.signal
1459 );
1460 const blobUrl = (0, import_blob.createBlobURL)(file);
1461 dispatch({
1462 type: Type.CacheBlobUrl,
1463 id,
1464 blobUrl
1465 });
1466 dispatch.finishOperation(id, {
1467 file,
1468 attachment: {
1469 url: blobUrl
1470 }
1471 });
1472 } catch (error) {
1473 dispatch.cancelItem(
1474 id,
1475 new UploadError({
1476 code: "IMAGE_ROTATION_ERROR",
1477 message: "Image could not be rotated",
1478 file: item.file,
1479 cause: error instanceof Error ? error : void 0
1480 })
1481 );
1482 }
1483 };
1484 }
1485 function transcodeImageItem(id, args) {
1486 return async ({ select: select2, dispatch }) => {
1487 const item = select2.getItem(id);
1488 if (!item) {
1489 return;
1490 }
1491 if (!args?.outputFormat) {
1492 dispatch.finishOperation(id, {
1493 file: item.file
1494 });
1495 return;
1496 }
1497 const outputMimeType = `image/${args.outputFormat}`;
1498 const quality = args.outputQuality ?? DEFAULT_OUTPUT_QUALITY;
1499 const interlaced = args.interlaced ?? false;
1500 try {
1501 const file = await vipsConvertImageFormat(
1502 item.id,
1503 item.file,
1504 outputMimeType,
1505 quality,
1506 interlaced
1507 );
1508 const blobUrl = (0, import_blob.createBlobURL)(file);
1509 dispatch({
1510 type: Type.CacheBlobUrl,
1511 id,
1512 blobUrl
1513 });
1514 dispatch.finishOperation(id, {
1515 file,
1516 attachment: {
1517 url: blobUrl
1518 }
1519 });
1520 } catch (error) {
1521 dispatch.cancelItem(
1522 id,
1523 new UploadError({
1524 code: "MEDIA_TRANSCODING_ERROR",
1525 message: "Image could not be transcoded to the target format",
1526 file: item.file,
1527 cause: error instanceof Error ? error : void 0
1528 })
1529 );
1530 }
1531 };
1532 }
1533 function generateThumbnails(id) {
1534 return async ({ select: select2, dispatch }) => {
1535 const item = select2.getItem(id);
1536 if (!item) {
1537 return;
1538 }
1539 if (!item.attachment) {
1540 dispatch.finishOperation(id, {});
1541 return;
1542 }
1543 const attachment = item.attachment;
1544 const needsRotation = attachment.exif_orientation && attachment.exif_orientation !== 1 && !item.file.name.includes("-scaled");
1545 if (needsRotation && attachment.id) {
1546 try {
1547 const rotatedFile = await vipsRotateImage(
1548 item.id,
1549 item.sourceFile,
1550 attachment.exif_orientation,
1551 item.abortController?.signal
1552 );
1553 dispatch.addSideloadItem({
1554 file: rotatedFile,
1555 batchId: v4_default(),
1556 parentId: item.id,
1557 additionalData: {
1558 post: attachment.id,
1559 image_size: "original",
1560 convert_format: false
1561 },
1562 operations: [OperationType.Upload]
1563 });
1564 } catch {
1565 console.warn(
1566 "Failed to rotate image, continuing with thumbnails"
1567 );
1568 }
1569 }
1570 if (!item.parentId && attachment.missing_image_sizes && attachment.missing_image_sizes.length > 0) {
1571 const settings = select2.getSettings();
1572 const allImageSizes = settings.allImageSizes || {};
1573 const sizesToGenerate = attachment.missing_image_sizes;
1574 const file = attachment.filename ? renameFile(item.sourceFile, attachment.filename) : item.sourceFile;
1575 const batchId = v4_default();
1576 const { imageOutputFormats } = settings;
1577 const sourceType = item.sourceFile.type;
1578 const outputMimeType = imageOutputFormats?.[sourceType];
1579 let thumbnailTranscodeOperation = null;
1580 if (outputMimeType && outputMimeType !== sourceType) {
1581 thumbnailTranscodeOperation = await getTranscodeImageOperation(
1582 item.sourceFile,
1583 outputMimeType,
1584 settings
1585 );
1586 }
1587 const thumbnailOutputType = thumbnailTranscodeOperation ? `image/${thumbnailTranscodeOperation[1].outputFormat}` : sourceType;
1588 const quality = thumbnailTranscodeOperation ? thumbnailTranscodeOperation[1].outputQuality ?? DEFAULT_OUTPUT_QUALITY : DEFAULT_OUTPUT_QUALITY;
1589 const batchConfigs = [];
1590 for (const name of sizesToGenerate) {
1591 const imageSize = allImageSizes[name];
1592 if (!imageSize) {
1593 console.warn(
1594 `Image size "${name}" not found in configuration`
1595 );
1596 continue;
1597 }
1598 batchConfigs.push({
1599 name,
1600 resize: imageSize,
1601 quality
1602 });
1603 }
1604 const { bigImageSizeThreshold } = settings;
1605 let needsScaling = false;
1606 if (bigImageSizeThreshold && attachment.id) {
1607 const bitmap = await createImageBitmap(item.sourceFile);
1608 needsScaling = bitmap.width > bigImageSizeThreshold || bitmap.height > bigImageSizeThreshold;
1609 bitmap.close();
1610 if (needsScaling) {
1611 batchConfigs.push({
1612 name: "scaled",
1613 resize: {
1614 width: bigImageSizeThreshold,
1615 height: bigImageSizeThreshold
1616 },
1617 quality,
1618 scaledSuffix: true
1619 });
1620 }
1621 }
1622 let batchResults = null;
1623 if (batchConfigs.length > 0) {
1624 try {
1625 batchResults = await vipsBatchResizeImage(
1626 item.id,
1627 file,
1628 thumbnailOutputType,
1629 batchConfigs,
1630 false
1631 );
1632 } catch {
1633 console.warn(
1634 "Batch resize failed, falling back to per-thumbnail processing"
1635 );
1636 }
1637 }
1638 if (batchResults) {
1639 for (const result of batchResults) {
1640 dispatch.addSideloadItem({
1641 file: result.file,
1642 onChange: ([updatedAttachment]) => {
1643 if ((0, import_blob.isBlobURL)(updatedAttachment.url)) {
1644 return;
1645 }
1646 item.onChange?.([updatedAttachment]);
1647 },
1648 batchId,
1649 parentId: item.id,
1650 additionalData: {
1651 post: attachment.id,
1652 image_size: result.name,
1653 convert_format: false
1654 },
1655 operations: [OperationType.Upload]
1656 });
1657 }
1658 } else {
1659 for (const name of sizesToGenerate) {
1660 const imageSize = allImageSizes[name];
1661 if (!imageSize) {
1662 continue;
1663 }
1664 const thumbnailOperations = [
1665 [OperationType.ResizeCrop, { resize: imageSize }]
1666 ];
1667 if (thumbnailTranscodeOperation) {
1668 thumbnailOperations.push(thumbnailTranscodeOperation);
1669 }
1670 thumbnailOperations.push(OperationType.Upload);
1671 dispatch.addSideloadItem({
1672 file,
1673 onChange: ([updatedAttachment]) => {
1674 if ((0, import_blob.isBlobURL)(updatedAttachment.url)) {
1675 return;
1676 }
1677 item.onChange?.([updatedAttachment]);
1678 },
1679 batchId,
1680 parentId: item.id,
1681 additionalData: {
1682 post: attachment.id,
1683 image_size: name,
1684 convert_format: false
1685 },
1686 operations: thumbnailOperations
1687 });
1688 }
1689 if (needsScaling && bigImageSizeThreshold && attachment.id) {
1690 const scaledOperations = [
1691 [
1692 OperationType.ResizeCrop,
1693 {
1694 resize: {
1695 width: bigImageSizeThreshold,
1696 height: bigImageSizeThreshold
1697 },
1698 isThresholdResize: true
1699 }
1700 ]
1701 ];
1702 if (thumbnailTranscodeOperation) {
1703 scaledOperations.push(thumbnailTranscodeOperation);
1704 }
1705 scaledOperations.push(OperationType.Upload);
1706 dispatch.addSideloadItem({
1707 file,
1708 onChange: ([updatedAttachment]) => {
1709 if ((0, import_blob.isBlobURL)(updatedAttachment.url)) {
1710 return;
1711 }
1712 item.onChange?.([updatedAttachment]);
1713 },
1714 batchId,
1715 parentId: item.id,
1716 additionalData: {
1717 post: attachment.id,
1718 image_size: "scaled",
1719 convert_format: false
1720 },
1721 operations: scaledOperations
1722 });
1723 }
1724 }
1725 }
1726 dispatch.finishOperation(id, {});
1727 };
1728 }
1729 function finalizeItem(id) {
1730 return async ({ select: select2, dispatch }) => {
1731 const item = select2.getItem(id);
1732 if (!item) {
1733 return;
1734 }
1735 const attachment = item.attachment;
1736 const { mediaFinalize } = select2.getSettings();
1737 if (attachment?.id && mediaFinalize) {
1738 try {
1739 await mediaFinalize(attachment.id);
1740 } catch (error) {
1741 console.warn("Media finalization failed:", error);
1742 }
1743 }
1744 dispatch.finishOperation(id, {});
1745 };
1746 }
1747 function revokeBlobUrls(id) {
1748 return async ({ select: select2, dispatch }) => {
1749 const blobUrls = select2.getBlobUrls(id);
1750 for (const blobUrl of blobUrls) {
1751 (0, import_blob.revokeBlobURL)(blobUrl);
1752 }
1753 dispatch({
1754 type: Type.RevokeBlobUrls,
1755 id
1756 });
1757 };
1758 }
1759 function updateItemProgress(id, progress) {
1760 return async ({ dispatch }) => {
1761 dispatch({
1762 type: Type.UpdateProgress,
1763 id,
1764 progress
1765 });
1766 };
1767 }
1768 function updateSettings(settings) {
1769 return {
1770 type: Type.UpdateSettings,
1771 settings
1772 };
1773 }
1774
1775 // packages/upload-media/build-module/lock-unlock.mjs
1776 var import_private_apis = __toESM(require_private_apis(), 1);
1777 var { lock, unlock } = (0, import_private_apis.__dangerousOptInToUnstableAPIsOnlyForCoreModules)(
1778 "I acknowledge private features are not for use in themes or plugins and doing so will break in the next version of WordPress.",
1779 "@wordpress/upload-media"
1780 );
1781
1782 // packages/upload-media/build-module/store/index.mjs
1783 var storeConfig = {
1784 reducer: reducer_default,
1785 selectors: selectors_exports,
1786 actions: actions_exports
1787 };
1788 var store = (0, import_data.createReduxStore)(STORE_NAME, {
1789 reducer: reducer_default,
1790 selectors: selectors_exports,
1791 actions: actions_exports
1792 });
1793 if (!(0, import_data.select)(store)) {
1794 (0, import_data.register)(store);
1795 }
1796 unlock(store).registerPrivateActions(private_actions_exports);
1797 unlock(store).registerPrivateSelectors(private_selectors_exports);
1798
1799 // packages/upload-media/build-module/components/provider/index.mjs
1800 var import_element2 = __toESM(require_element(), 1);
1801 var import_data3 = __toESM(require_data(), 1);
1802
1803 // packages/upload-media/build-module/components/provider/with-registry-provider.mjs
1804 var import_element = __toESM(require_element(), 1);
1805 var import_data2 = __toESM(require_data(), 1);
1806 var import_compose = __toESM(require_compose(), 1);
1807 var import_jsx_runtime = __toESM(require_jsx_runtime(), 1);
1808 function getSubRegistry(subRegistries, registry, useSubRegistry) {
1809 if (!useSubRegistry) {
1810 return registry;
1811 }
1812 let subRegistry = subRegistries.get(registry);
1813 if (!subRegistry) {
1814 subRegistry = (0, import_data2.createRegistry)({}, registry);
1815 subRegistry.registerStore(STORE_NAME, storeConfig);
1816 subRegistries.set(registry, subRegistry);
1817 }
1818 return subRegistry;
1819 }
1820 var withRegistryProvider = (0, import_compose.createHigherOrderComponent)(
1821 (WrappedComponent) => ({ useSubRegistry = true, ...props }) => {
1822 const registry = (0, import_data2.useRegistry)();
1823 const [subRegistries] = (0, import_element.useState)(() => /* @__PURE__ */ new WeakMap());
1824 const subRegistry = getSubRegistry(
1825 subRegistries,
1826 registry,
1827 useSubRegistry
1828 );
1829 if (subRegistry === registry) {
1830 return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(WrappedComponent, { registry, ...props });
1831 }
1832 return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_data2.RegistryProvider, { value: subRegistry, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(WrappedComponent, { registry: subRegistry, ...props }) });
1833 },
1834 "withRegistryProvider"
1835 );
1836 var with_registry_provider_default = withRegistryProvider;
1837
1838 // packages/upload-media/build-module/components/provider/index.mjs
1839 var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
1840 var MediaUploadProvider = with_registry_provider_default((props) => {
1841 const { children, settings } = props;
1842 const { updateSettings: updateSettings2 } = unlock((0, import_data3.useDispatch)(store));
1843 (0, import_element2.useEffect)(() => {
1844 updateSettings2(settings);
1845 }, [settings, updateSettings2]);
1846 return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children });
1847 });
1848 var provider_default = MediaUploadProvider;
1849
1850 // packages/upload-media/build-module/feature-detection.mjs
1851 var cachedResult = null;
1852 function detectClientSideMediaSupport() {
1853 if (cachedResult !== null) {
1854 return cachedResult;
1855 }
1856 if (typeof WebAssembly === "undefined") {
1857 cachedResult = {
1858 supported: false,
1859 reason: "WebAssembly is not supported in this browser."
1860 };
1861 return cachedResult;
1862 }
1863 if (typeof SharedArrayBuffer === "undefined") {
1864 cachedResult = {
1865 supported: false,
1866 reason: "SharedArrayBuffer is not available. This may be due to missing cross-origin isolation headers."
1867 };
1868 return cachedResult;
1869 }
1870 if (typeof Worker === "undefined") {
1871 cachedResult = {
1872 supported: false,
1873 reason: "Web Workers are not supported in this browser."
1874 };
1875 return cachedResult;
1876 }
1877 if (typeof navigator !== "undefined" && "deviceMemory" in navigator && navigator.deviceMemory <= 2) {
1878 cachedResult = {
1879 supported: false,
1880 reason: "Device has insufficient memory for client-side media processing."
1881 };
1882 return cachedResult;
1883 }
1884 if (typeof navigator !== "undefined" && "hardwareConcurrency" in navigator && navigator.hardwareConcurrency < 2) {
1885 cachedResult = {
1886 supported: false,
1887 reason: "Device has insufficient CPU cores for client-side media processing."
1888 };
1889 return cachedResult;
1890 }
1891 if (typeof navigator !== "undefined") {
1892 const connection = navigator.connection;
1893 if (connection) {
1894 if (connection.saveData) {
1895 cachedResult = {
1896 supported: false,
1897 reason: "Data saver mode is enabled."
1898 };
1899 return cachedResult;
1900 }
1901 if (connection.effectiveType === "slow-2g" || connection.effectiveType === "2g") {
1902 cachedResult = {
1903 supported: false,
1904 reason: "Network connection is too slow for client-side media processing."
1905 };
1906 return cachedResult;
1907 }
1908 }
1909 }
1910 if (typeof window !== "undefined") {
1911 try {
1912 const testBlob = new Blob([""], {
1913 type: "application/javascript"
1914 });
1915 const testUrl = URL.createObjectURL(testBlob);
1916 try {
1917 const testWorker = new Worker(testUrl);
1918 testWorker.terminate();
1919 } finally {
1920 URL.revokeObjectURL(testUrl);
1921 }
1922 } catch {
1923 cachedResult = {
1924 supported: false,
1925 reason: "The site's Content Security Policy (CSP) does not allow blob: workers. The worker-src directive must include blob: to enable client-side media processing."
1926 };
1927 return cachedResult;
1928 }
1929 }
1930 cachedResult = { supported: true };
1931 return cachedResult;
1932 }
1933 function isClientSideMediaSupported() {
1934 return detectClientSideMediaSupport().supported;
1935 }
1936 function clearFeatureDetectionCache() {
1937 cachedResult = null;
1938 }
1939 return __toCommonJS(index_exports);
1940 })();
1941 //# sourceMappingURL=index.js.map
1942