PluginProbe
Gutenberg / 19.6.0
Gutenberg v19.6.0
24.0.0 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 All 403 releases
gutenberg / build / media-utils / index.js

index.js in Gutenberg 19.6.0, at build/media-utils/index.js

865 lines 25.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /******/ (() => { // webpackBootstrap
2 /******/ "use strict";
3 /******/ // The require scope
4 /******/ var __webpack_require__ = {};
5 /******/
6 /************************************************************************/
7 /******/ /* webpack/runtime/compat get default export */
8 /******/ (() => {
9 /******/ // getDefaultExport function for compatibility with non-harmony modules
10 /******/ __webpack_require__.n = (module) => {
11 /******/ var getter = module && module.__esModule ?
12 /******/ () => (module['default']) :
13 /******/ () => (module);
14 /******/ __webpack_require__.d(getter, { a: getter });
15 /******/ return getter;
16 /******/ };
17 /******/ })();
18 /******/
19 /******/ /* webpack/runtime/define property getters */
20 /******/ (() => {
21 /******/ // define getter functions for harmony exports
22 /******/ __webpack_require__.d = (exports, definition) => {
23 /******/ for(var key in definition) {
24 /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
25 /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
26 /******/ }
27 /******/ }
28 /******/ };
29 /******/ })();
30 /******/
31 /******/ /* webpack/runtime/hasOwnProperty shorthand */
32 /******/ (() => {
33 /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
34 /******/ })();
35 /******/
36 /******/ /* webpack/runtime/make namespace object */
37 /******/ (() => {
38 /******/ // define __esModule on exports
39 /******/ __webpack_require__.r = (exports) => {
40 /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
41 /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
42 /******/ }
43 /******/ Object.defineProperty(exports, '__esModule', { value: true });
44 /******/ };
45 /******/ })();
46 /******/
47 /************************************************************************/
48 var __webpack_exports__ = {};
49 // ESM COMPAT FLAG
50 __webpack_require__.r(__webpack_exports__);
51
52 // EXPORTS
53 __webpack_require__.d(__webpack_exports__, {
54 MediaUpload: () => (/* reexport */ media_upload),
55 transformAttachment: () => (/* reexport */ transformAttachment),
56 uploadMedia: () => (/* reexport */ uploadMedia),
57 validateFileSize: () => (/* reexport */ validateFileSize),
58 validateMimeType: () => (/* reexport */ validateMimeType),
59 validateMimeTypeForUser: () => (/* reexport */ validateMimeTypeForUser)
60 });
61
62 ;// external ["wp","element"]
63 const external_wp_element_namespaceObject = window["wp"]["element"];
64 ;// external ["wp","i18n"]
65 const external_wp_i18n_namespaceObject = window["wp"]["i18n"];
66 ;// ./packages/media-utils/build-module/components/media-upload/index.js
67 /**
68 * WordPress dependencies
69 */
70
71
72 const DEFAULT_EMPTY_GALLERY = [];
73
74 /**
75 * Prepares the Featured Image toolbars and frames.
76 *
77 * @return {window.wp.media.view.MediaFrame.Select} The default media workflow.
78 */
79 const getFeaturedImageMediaFrame = () => {
80 const {
81 wp
82 } = window;
83 return wp.media.view.MediaFrame.Select.extend({
84 /**
85 * Enables the Set Featured Image Button.
86 *
87 * @param {Object} toolbar toolbar for featured image state
88 * @return {void}
89 */
90 featuredImageToolbar(toolbar) {
91 this.createSelectToolbar(toolbar, {
92 text: wp.media.view.l10n.setFeaturedImage,
93 state: this.options.state
94 });
95 },
96 /**
97 * Handle the edit state requirements of selected media item.
98 *
99 * @return {void}
100 */
101 editState() {
102 const selection = this.state('featured-image').get('selection');
103 const view = new wp.media.view.EditImage({
104 model: selection.single(),
105 controller: this
106 }).render();
107
108 // Set the view to the EditImage frame using the selected image.
109 this.content.set(view);
110
111 // After bringing in the frame, load the actual editor via an ajax call.
112 view.loadEditor();
113 },
114 /**
115 * Create the default states.
116 *
117 * @return {void}
118 */
119 createStates: function createStates() {
120 this.on('toolbar:create:featured-image', this.featuredImageToolbar, this);
121 this.on('content:render:edit-image', this.editState, this);
122 this.states.add([new wp.media.controller.FeaturedImage(), new wp.media.controller.EditImage({
123 model: this.options.editImage
124 })]);
125 }
126 });
127 };
128
129 /**
130 * Prepares the Gallery toolbars and frames.
131 *
132 * @return {window.wp.media.view.MediaFrame.Post} The default media workflow.
133 */
134 const getGalleryDetailsMediaFrame = () => {
135 const {
136 wp
137 } = window;
138 /**
139 * Custom gallery details frame.
140 *
141 * @see https://github.com/xwp/wp-core-media-widgets/blob/905edbccfc2a623b73a93dac803c5335519d7837/wp-admin/js/widgets/media-gallery-widget.js
142 * @class GalleryDetailsMediaFrame
143 * @class
144 */
145 return wp.media.view.MediaFrame.Post.extend({
146 /**
147 * Set up gallery toolbar.
148 *
149 * @return {void}
150 */
151 galleryToolbar() {
152 const editing = this.state().get('editing');
153 this.toolbar.set(new wp.media.view.Toolbar({
154 controller: this,
155 items: {
156 insert: {
157 style: 'primary',
158 text: editing ? wp.media.view.l10n.updateGallery : wp.media.view.l10n.insertGallery,
159 priority: 80,
160 requires: {
161 library: true
162 },
163 /**
164 * @fires wp.media.controller.State#update
165 */
166 click() {
167 const controller = this.controller,
168 state = controller.state();
169 controller.close();
170 state.trigger('update', state.get('library'));
171
172 // Restore and reset the default state.
173 controller.setState(controller.options.state);
174 controller.reset();
175 }
176 }
177 }
178 }));
179 },
180 /**
181 * Handle the edit state requirements of selected media item.
182 *
183 * @return {void}
184 */
185 editState() {
186 const selection = this.state('gallery').get('selection');
187 const view = new wp.media.view.EditImage({
188 model: selection.single(),
189 controller: this
190 }).render();
191
192 // Set the view to the EditImage frame using the selected image.
193 this.content.set(view);
194
195 // After bringing in the frame, load the actual editor via an ajax call.
196 view.loadEditor();
197 },
198 /**
199 * Create the default states.
200 *
201 * @return {void}
202 */
203 createStates: function createStates() {
204 this.on('toolbar:create:main-gallery', this.galleryToolbar, this);
205 this.on('content:render:edit-image', this.editState, this);
206 this.states.add([new wp.media.controller.Library({
207 id: 'gallery',
208 title: wp.media.view.l10n.createGalleryTitle,
209 priority: 40,
210 toolbar: 'main-gallery',
211 filterable: 'uploaded',
212 multiple: 'add',
213 editable: false,
214 library: wp.media.query({
215 type: 'image',
216 ...this.options.library
217 })
218 }), new wp.media.controller.EditImage({
219 model: this.options.editImage
220 }), new wp.media.controller.GalleryEdit({
221 library: this.options.selection,
222 editing: this.options.editing,
223 menu: 'gallery',
224 displaySettings: false,
225 multiple: true
226 }), new wp.media.controller.GalleryAdd()]);
227 }
228 });
229 };
230
231 // The media library image object contains numerous attributes
232 // we only need this set to display the image in the library.
233 const slimImageObject = img => {
234 const attrSet = ['sizes', 'mime', 'type', 'subtype', 'id', 'url', 'alt', 'link', 'caption'];
235 return attrSet.reduce((result, key) => {
236 if (img?.hasOwnProperty(key)) {
237 result[key] = img[key];
238 }
239 return result;
240 }, {});
241 };
242 const getAttachmentsCollection = ids => {
243 const {
244 wp
245 } = window;
246 return wp.media.query({
247 order: 'ASC',
248 orderby: 'post__in',
249 post__in: ids,
250 posts_per_page: -1,
251 query: true,
252 type: 'image'
253 });
254 };
255 class MediaUpload extends external_wp_element_namespaceObject.Component {
256 constructor() {
257 super(...arguments);
258 this.openModal = this.openModal.bind(this);
259 this.onOpen = this.onOpen.bind(this);
260 this.onSelect = this.onSelect.bind(this);
261 this.onUpdate = this.onUpdate.bind(this);
262 this.onClose = this.onClose.bind(this);
263 }
264 initializeListeners() {
265 // When an image is selected in the media frame...
266 this.frame.on('select', this.onSelect);
267 this.frame.on('update', this.onUpdate);
268 this.frame.on('open', this.onOpen);
269 this.frame.on('close', this.onClose);
270 }
271
272 /**
273 * Sets the Gallery frame and initializes listeners.
274 *
275 * @return {void}
276 */
277 buildAndSetGalleryFrame() {
278 const {
279 addToGallery = false,
280 allowedTypes,
281 multiple = false,
282 value = DEFAULT_EMPTY_GALLERY
283 } = this.props;
284
285 // If the value did not changed there is no need to rebuild the frame,
286 // we can continue to use the existing one.
287 if (value === this.lastGalleryValue) {
288 return;
289 }
290 const {
291 wp
292 } = window;
293 this.lastGalleryValue = value;
294
295 // If a frame already existed remove it.
296 if (this.frame) {
297 this.frame.remove();
298 }
299 let currentState;
300 if (addToGallery) {
301 currentState = 'gallery-library';
302 } else {
303 currentState = value && value.length ? 'gallery-edit' : 'gallery';
304 }
305 if (!this.GalleryDetailsMediaFrame) {
306 this.GalleryDetailsMediaFrame = getGalleryDetailsMediaFrame();
307 }
308 const attachments = getAttachmentsCollection(value);
309 const selection = new wp.media.model.Selection(attachments.models, {
310 props: attachments.props.toJSON(),
311 multiple
312 });
313 this.frame = new this.GalleryDetailsMediaFrame({
314 mimeType: allowedTypes,
315 state: currentState,
316 multiple,
317 selection,
318 editing: value && value.length ? true : false
319 });
320 wp.media.frame = this.frame;
321 this.initializeListeners();
322 }
323
324 /**
325 * Initializes the Media Library requirements for the featured image flow.
326 *
327 * @return {void}
328 */
329 buildAndSetFeatureImageFrame() {
330 const {
331 wp
332 } = window;
333 const {
334 value: featuredImageId,
335 multiple,
336 allowedTypes
337 } = this.props;
338 const featuredImageFrame = getFeaturedImageMediaFrame();
339 const attachments = getAttachmentsCollection(featuredImageId);
340 const selection = new wp.media.model.Selection(attachments.models, {
341 props: attachments.props.toJSON()
342 });
343 this.frame = new featuredImageFrame({
344 mimeType: allowedTypes,
345 state: 'featured-image',
346 multiple,
347 selection,
348 editing: featuredImageId
349 });
350 wp.media.frame = this.frame;
351 // In order to select the current featured image when opening
352 // the media library we have to set the appropriate settings.
353 // Currently they are set in php for the post editor, but
354 // not for site editor.
355 wp.media.view.settings.post = {
356 ...wp.media.view.settings.post,
357 featuredImageId: featuredImageId || -1
358 };
359 }
360 componentWillUnmount() {
361 this.frame?.remove();
362 }
363 onUpdate(selections) {
364 const {
365 onSelect,
366 multiple = false
367 } = this.props;
368 const state = this.frame.state();
369 const selectedImages = selections || state.get('selection');
370 if (!selectedImages || !selectedImages.models.length) {
371 return;
372 }
373 if (multiple) {
374 onSelect(selectedImages.models.map(model => slimImageObject(model.toJSON())));
375 } else {
376 onSelect(slimImageObject(selectedImages.models[0].toJSON()));
377 }
378 }
379 onSelect() {
380 const {
381 onSelect,
382 multiple = false
383 } = this.props;
384 // Get media attachment details from the frame state.
385 const attachment = this.frame.state().get('selection').toJSON();
386 onSelect(multiple ? attachment : attachment[0]);
387 }
388 onOpen() {
389 const {
390 wp
391 } = window;
392 const {
393 value
394 } = this.props;
395 this.updateCollection();
396
397 //Handle active tab in media model on model open.
398 if (this.props.mode) {
399 this.frame.content.mode(this.props.mode);
400 }
401
402 // Handle both this.props.value being either (number[]) multiple ids
403 // (for galleries) or a (number) singular id (e.g. image block).
404 const hasMedia = Array.isArray(value) ? !!value?.length : !!value;
405 if (!hasMedia) {
406 return;
407 }
408 const isGallery = this.props.gallery;
409 const selection = this.frame.state().get('selection');
410 const valueArray = Array.isArray(value) ? value : [value];
411 if (!isGallery) {
412 valueArray.forEach(id => {
413 selection.add(wp.media.attachment(id));
414 });
415 }
416
417 // Load the images so they are available in the media modal.
418 const attachments = getAttachmentsCollection(valueArray);
419
420 // Once attachments are loaded, set the current selection.
421 attachments.more().done(function () {
422 if (isGallery && attachments?.models?.length) {
423 selection.add(attachments.models);
424 }
425 });
426 }
427 onClose() {
428 const {
429 onClose
430 } = this.props;
431 if (onClose) {
432 onClose();
433 }
434 this.frame.detach();
435 }
436 updateCollection() {
437 const frameContent = this.frame.content.get();
438 if (frameContent && frameContent.collection) {
439 const collection = frameContent.collection;
440
441 // Clean all attachments we have in memory.
442 collection.toArray().forEach(model => model.trigger('destroy', model));
443
444 // Reset has more flag, if library had small amount of items all items may have been loaded before.
445 collection.mirroring._hasMore = true;
446
447 // Request items.
448 collection.more();
449 }
450 }
451 openModal() {
452 const {
453 allowedTypes,
454 gallery = false,
455 unstableFeaturedImageFlow = false,
456 modalClass,
457 multiple = false,
458 title = (0,external_wp_i18n_namespaceObject.__)('Select or Upload Media')
459 } = this.props;
460 const {
461 wp
462 } = window;
463 if (gallery) {
464 this.buildAndSetGalleryFrame();
465 } else {
466 const frameConfig = {
467 title,
468 multiple
469 };
470 if (!!allowedTypes) {
471 frameConfig.library = {
472 type: allowedTypes
473 };
474 }
475 this.frame = wp.media(frameConfig);
476 }
477 if (modalClass) {
478 this.frame.$el.addClass(modalClass);
479 }
480 if (unstableFeaturedImageFlow) {
481 this.buildAndSetFeatureImageFrame();
482 }
483 this.initializeListeners();
484 this.frame.open();
485 }
486 render() {
487 return this.props.render({
488 open: this.openModal
489 });
490 }
491 }
492 /* harmony default export */ const media_upload = (MediaUpload);
493
494 ;// ./packages/media-utils/build-module/components/index.js
495
496
497 ;// external ["wp","blob"]
498 const external_wp_blob_namespaceObject = window["wp"]["blob"];
499 ;// external ["wp","apiFetch"]
500 const external_wp_apiFetch_namespaceObject = window["wp"]["apiFetch"];
501 var external_wp_apiFetch_default = /*#__PURE__*/__webpack_require__.n(external_wp_apiFetch_namespaceObject);
502 ;// ./packages/media-utils/build-module/utils/flatten-form-data.js
503 /**
504 * Determines whether the passed argument appears to be a plain object.
505 *
506 * @param data The object to inspect.
507 */
508 function isPlainObject(data) {
509 return data !== null && typeof data === 'object' && Object.getPrototypeOf(data) === Object.prototype;
510 }
511
512 /**
513 * Recursively flatten data passed to form data, to allow using multi-level objects.
514 *
515 * @param {FormData} formData Form data object.
516 * @param {string} key Key to amend to form data object
517 * @param {string|Object} data Data to be amended to form data.
518 */
519 function flattenFormData(formData, key, data) {
520 if (isPlainObject(data)) {
521 for (const [name, value] of Object.entries(data)) {
522 flattenFormData(formData, `${key}[${name}]`, value);
523 }
524 } else if (data !== undefined) {
525 formData.append(key, String(data));
526 }
527 }
528
529 ;// ./packages/media-utils/build-module/utils/transform-attachment.js
530 /**
531 * Internal dependencies
532 */
533
534 /**
535 * Transforms an attachment object from the REST API shape into the shape expected by the block editor and other consumers.
536 *
537 * @param attachment REST API attachment object.
538 */
539 function transformAttachment(attachment) {
540 var _attachment$caption$r;
541 // eslint-disable-next-line camelcase
542 const {
543 alt_text,
544 source_url,
545 ...savedMediaProps
546 } = attachment;
547 return {
548 ...savedMediaProps,
549 alt: attachment.alt_text,
550 caption: (_attachment$caption$r = attachment.caption?.raw) !== null && _attachment$caption$r !== void 0 ? _attachment$caption$r : '',
551 title: attachment.title.raw,
552 url: attachment.source_url,
553 poster: attachment._embedded?.['wp:featuredmedia']?.[0]?.source_url || undefined
554 };
555 }
556
557 ;// ./packages/media-utils/build-module/utils/upload-to-server.js
558 /**
559 * WordPress dependencies
560 */
561
562
563 /**
564 * Internal dependencies
565 */
566
567
568 async function uploadToServer(file, additionalData = {}, signal) {
569 // Create upload payload.
570 const data = new FormData();
571 data.append('file', file, file.name || file.type.replace('/', '.'));
572 for (const [key, value] of Object.entries(additionalData)) {
573 flattenFormData(data, key, value);
574 }
575 return transformAttachment(await external_wp_apiFetch_default()({
576 // This allows the video block to directly get a video's poster image.
577 path: '/wp/v2/media?_embed=wp:featuredmedia',
578 body: data,
579 method: 'POST',
580 signal
581 }));
582 }
583
584 ;// ./packages/media-utils/build-module/utils/upload-error.js
585 /**
586 * MediaError class.
587 *
588 * Small wrapper around the `Error` class
589 * to hold an error code and a reference to a file object.
590 */
591 class UploadError extends Error {
592 constructor({
593 code,
594 message,
595 file,
596 cause
597 }) {
598 super(message, {
599 cause
600 });
601 Object.setPrototypeOf(this, new.target.prototype);
602 this.code = code;
603 this.file = file;
604 }
605 }
606
607 ;// ./packages/media-utils/build-module/utils/validate-mime-type.js
608 /**
609 * WordPress dependencies
610 */
611
612
613 /**
614 * Internal dependencies
615 */
616
617
618 /**
619 * Verifies if the caller (e.g. a block) supports this mime type.
620 *
621 * @param file File object.
622 * @param allowedTypes List of allowed mime types.
623 */
624 function validateMimeType(file, allowedTypes) {
625 if (!allowedTypes) {
626 return;
627 }
628
629 // Allowed type specified by consumer.
630 const isAllowedType = allowedTypes.some(allowedType => {
631 // If a complete mimetype is specified verify if it matches exactly the mime type of the file.
632 if (allowedType.includes('/')) {
633 return allowedType === file.type;
634 }
635 // Otherwise a general mime type is used, and we should verify if the file mimetype starts with it.
636 return file.type.startsWith(`${allowedType}/`);
637 });
638 if (file.type && !isAllowedType) {
639 throw new UploadError({
640 code: 'MIME_TYPE_NOT_SUPPORTED',
641 message: (0,external_wp_i18n_namespaceObject.sprintf)(
642 // translators: %s: file name.
643 (0,external_wp_i18n_namespaceObject.__)('%s: Sorry, this file type is not supported here.'), file.name),
644 file
645 });
646 }
647 }
648
649 ;// ./packages/media-utils/build-module/utils/get-mime-types-array.js
650 /**
651 * Browsers may use unexpected mime types, and they differ from browser to browser.
652 * This function computes a flexible array of mime types from the mime type structured provided by the server.
653 * Converts { jpg|jpeg|jpe: "image/jpeg" } into [ "image/jpeg", "image/jpg", "image/jpeg", "image/jpe" ]
654 *
655 * @param {?Object} wpMimeTypesObject Mime type object received from the server.
656 * Extensions are keys separated by '|' and values are mime types associated with an extension.
657 *
658 * @return An array of mime types or null
659 */
660 function getMimeTypesArray(wpMimeTypesObject) {
661 if (!wpMimeTypesObject) {
662 return null;
663 }
664 return Object.entries(wpMimeTypesObject).flatMap(([extensionsString, mime]) => {
665 const [type] = mime.split('/');
666 const extensions = extensionsString.split('|');
667 return [mime, ...extensions.map(extension => `${type}/${extension}`)];
668 });
669 }
670
671 ;// ./packages/media-utils/build-module/utils/validate-mime-type-for-user.js
672 /**
673 * WordPress dependencies
674 */
675
676
677 /**
678 * Internal dependencies
679 */
680
681
682
683 /**
684 * Verifies if the user is allowed to upload this mime type.
685 *
686 * @param file File object.
687 * @param wpAllowedMimeTypes List of allowed mime types and file extensions.
688 */
689 function validateMimeTypeForUser(file, wpAllowedMimeTypes) {
690 // Allowed types for the current WP_User.
691 const allowedMimeTypesForUser = getMimeTypesArray(wpAllowedMimeTypes);
692 if (!allowedMimeTypesForUser) {
693 return;
694 }
695 const isAllowedMimeTypeForUser = allowedMimeTypesForUser.includes(file.type);
696 if (file.type && !isAllowedMimeTypeForUser) {
697 throw new UploadError({
698 code: 'MIME_TYPE_NOT_ALLOWED_FOR_USER',
699 message: (0,external_wp_i18n_namespaceObject.sprintf)(
700 // translators: %s: file name.
701 (0,external_wp_i18n_namespaceObject.__)('%s: Sorry, you are not allowed to upload this file type.'), file.name),
702 file
703 });
704 }
705 }
706
707 ;// ./packages/media-utils/build-module/utils/validate-file-size.js
708 /**
709 * WordPress dependencies
710 */
711
712
713 /**
714 * Internal dependencies
715 */
716
717
718 /**
719 * Verifies whether the file is within the file upload size limits for the site.
720 *
721 * @param file File object.
722 * @param maxUploadFileSize Maximum upload size in bytes allowed for the site.
723 */
724 function validateFileSize(file, maxUploadFileSize) {
725 // Don't allow empty files to be uploaded.
726 if (file.size <= 0) {
727 throw new UploadError({
728 code: 'EMPTY_FILE',
729 message: (0,external_wp_i18n_namespaceObject.sprintf)(
730 // translators: %s: file name.
731 (0,external_wp_i18n_namespaceObject.__)('%s: This file is empty.'), file.name),
732 file
733 });
734 }
735 if (maxUploadFileSize && file.size > maxUploadFileSize) {
736 throw new UploadError({
737 code: 'SIZE_ABOVE_LIMIT',
738 message: (0,external_wp_i18n_namespaceObject.sprintf)(
739 // translators: %s: file name.
740 (0,external_wp_i18n_namespaceObject.__)('%s: This file exceeds the maximum upload size for this site.'), file.name),
741 file
742 });
743 }
744 }
745
746 ;// ./packages/media-utils/build-module/utils/upload-media.js
747 /**
748 * WordPress dependencies
749 */
750
751
752
753 /**
754 * Internal dependencies
755 */
756
757
758
759
760
761
762 /**
763 * Upload a media file when the file upload button is activated
764 * or when adding a file to the editor via drag & drop.
765 *
766 * @param $0 Parameters object passed to the function.
767 * @param $0.allowedTypes Array with the types of media that can be uploaded, if unset all types are allowed.
768 * @param $0.additionalData Additional data to include in the request.
769 * @param $0.filesList List of files.
770 * @param $0.maxUploadFileSize Maximum upload size in bytes allowed for the site.
771 * @param $0.onError Function called when an error happens.
772 * @param $0.onFileChange Function called each time a file or a temporary representation of the file is available.
773 * @param $0.wpAllowedMimeTypes List of allowed mime types and file extensions.
774 * @param $0.signal Abort signal.
775 */
776 function uploadMedia({
777 wpAllowedMimeTypes,
778 allowedTypes,
779 additionalData = {},
780 filesList,
781 maxUploadFileSize,
782 onError,
783 onFileChange,
784 signal
785 }) {
786 const validFiles = [];
787 const filesSet = [];
788 const setAndUpdateFiles = (index, value) => {
789 if (filesSet[index]?.url) {
790 (0,external_wp_blob_namespaceObject.revokeBlobURL)(filesSet[index].url);
791 }
792 filesSet[index] = value;
793 onFileChange?.(filesSet.filter(attachment => attachment !== null));
794 };
795 for (const mediaFile of filesList) {
796 // Verify if user is allowed to upload this mime type.
797 // Defer to the server when type not detected.
798 try {
799 validateMimeTypeForUser(mediaFile, wpAllowedMimeTypes);
800 } catch (error) {
801 onError?.(error);
802 continue;
803 }
804
805 // Check if the caller (e.g. a block) supports this mime type.
806 // Defer to the server when type not detected.
807 try {
808 validateMimeType(mediaFile, allowedTypes);
809 } catch (error) {
810 onError?.(error);
811 continue;
812 }
813
814 // Verify if file is greater than the maximum file upload size allowed for the site.
815 try {
816 validateFileSize(mediaFile, maxUploadFileSize);
817 } catch (error) {
818 onError?.(error);
819 continue;
820 }
821 validFiles.push(mediaFile);
822
823 // Set temporary URL to create placeholder media file, this is replaced
824 // with final file from media gallery when upload is `done` below.
825 filesSet.push({
826 url: (0,external_wp_blob_namespaceObject.createBlobURL)(mediaFile)
827 });
828 onFileChange?.(filesSet);
829 }
830 validFiles.map(async (file, index) => {
831 try {
832 const attachment = await uploadToServer(file, additionalData, signal);
833 setAndUpdateFiles(index, attachment);
834 } catch (error) {
835 // Reset to empty on failure.
836 setAndUpdateFiles(index, null);
837 let message;
838 if (error instanceof Error) {
839 message = error.message;
840 } else {
841 message = (0,external_wp_i18n_namespaceObject.sprintf)(
842 // translators: %s: file name
843 (0,external_wp_i18n_namespaceObject.__)('Error while uploading file %s to the media library.'), file.name);
844 }
845 onError?.(new UploadError({
846 code: 'GENERAL',
847 message,
848 file,
849 cause: error instanceof Error ? error : undefined
850 }));
851 }
852 });
853 }
854
855 ;// ./packages/media-utils/build-module/index.js
856
857
858
859
860
861
862
863 (window.wp = window.wp || {}).mediaUtils = __webpack_exports__;
864 /******/ })()
865 ;