| 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 |
uploadMedia: () => (/* reexport */ uploadMedia) |
| 56 |
}); |
| 57 |
|
| 58 |
;// CONCATENATED MODULE: external ["wp","element"] |
| 59 |
const external_wp_element_namespaceObject = window["wp"]["element"]; |
| 60 |
;// CONCATENATED MODULE: external ["wp","i18n"] |
| 61 |
const external_wp_i18n_namespaceObject = window["wp"]["i18n"]; |
| 62 |
;// CONCATENATED MODULE: ./packages/media-utils/build-module/components/media-upload/index.js |
| 63 |
/** |
| 64 |
* WordPress dependencies |
| 65 |
*/ |
| 66 |
|
| 67 |
|
| 68 |
const DEFAULT_EMPTY_GALLERY = []; |
| 69 |
|
| 70 |
/** |
| 71 |
* Prepares the Featured Image toolbars and frames. |
| 72 |
* |
| 73 |
* @return {window.wp.media.view.MediaFrame.Select} The default media workflow. |
| 74 |
*/ |
| 75 |
const getFeaturedImageMediaFrame = () => { |
| 76 |
const { |
| 77 |
wp |
| 78 |
} = window; |
| 79 |
return wp.media.view.MediaFrame.Select.extend({ |
| 80 |
/** |
| 81 |
* Enables the Set Featured Image Button. |
| 82 |
* |
| 83 |
* @param {Object} toolbar toolbar for featured image state |
| 84 |
* @return {void} |
| 85 |
*/ |
| 86 |
featuredImageToolbar(toolbar) { |
| 87 |
this.createSelectToolbar(toolbar, { |
| 88 |
text: wp.media.view.l10n.setFeaturedImage, |
| 89 |
state: this.options.state |
| 90 |
}); |
| 91 |
}, |
| 92 |
/** |
| 93 |
* Handle the edit state requirements of selected media item. |
| 94 |
* |
| 95 |
* @return {void} |
| 96 |
*/ |
| 97 |
editState() { |
| 98 |
const selection = this.state('featured-image').get('selection'); |
| 99 |
const view = new wp.media.view.EditImage({ |
| 100 |
model: selection.single(), |
| 101 |
controller: this |
| 102 |
}).render(); |
| 103 |
|
| 104 |
// Set the view to the EditImage frame using the selected image. |
| 105 |
this.content.set(view); |
| 106 |
|
| 107 |
// After bringing in the frame, load the actual editor via an ajax call. |
| 108 |
view.loadEditor(); |
| 109 |
}, |
| 110 |
/** |
| 111 |
* Create the default states. |
| 112 |
* |
| 113 |
* @return {void} |
| 114 |
*/ |
| 115 |
createStates: function createStates() { |
| 116 |
this.on('toolbar:create:featured-image', this.featuredImageToolbar, this); |
| 117 |
this.on('content:render:edit-image', this.editState, this); |
| 118 |
this.states.add([new wp.media.controller.FeaturedImage(), new wp.media.controller.EditImage({ |
| 119 |
model: this.options.editImage |
| 120 |
})]); |
| 121 |
} |
| 122 |
}); |
| 123 |
}; |
| 124 |
|
| 125 |
/** |
| 126 |
* Prepares the Gallery toolbars and frames. |
| 127 |
* |
| 128 |
* @return {window.wp.media.view.MediaFrame.Post} The default media workflow. |
| 129 |
*/ |
| 130 |
const getGalleryDetailsMediaFrame = () => { |
| 131 |
const { |
| 132 |
wp |
| 133 |
} = window; |
| 134 |
/** |
| 135 |
* Custom gallery details frame. |
| 136 |
* |
| 137 |
* @see https://github.com/xwp/wp-core-media-widgets/blob/905edbccfc2a623b73a93dac803c5335519d7837/wp-admin/js/widgets/media-gallery-widget.js |
| 138 |
* @class GalleryDetailsMediaFrame |
| 139 |
* @class |
| 140 |
*/ |
| 141 |
return wp.media.view.MediaFrame.Post.extend({ |
| 142 |
/** |
| 143 |
* Set up gallery toolbar. |
| 144 |
* |
| 145 |
* @return {void} |
| 146 |
*/ |
| 147 |
galleryToolbar() { |
| 148 |
const editing = this.state().get('editing'); |
| 149 |
this.toolbar.set(new wp.media.view.Toolbar({ |
| 150 |
controller: this, |
| 151 |
items: { |
| 152 |
insert: { |
| 153 |
style: 'primary', |
| 154 |
text: editing ? wp.media.view.l10n.updateGallery : wp.media.view.l10n.insertGallery, |
| 155 |
priority: 80, |
| 156 |
requires: { |
| 157 |
library: true |
| 158 |
}, |
| 159 |
/** |
| 160 |
* @fires wp.media.controller.State#update |
| 161 |
*/ |
| 162 |
click() { |
| 163 |
const controller = this.controller, |
| 164 |
state = controller.state(); |
| 165 |
controller.close(); |
| 166 |
state.trigger('update', state.get('library')); |
| 167 |
|
| 168 |
// Restore and reset the default state. |
| 169 |
controller.setState(controller.options.state); |
| 170 |
controller.reset(); |
| 171 |
} |
| 172 |
} |
| 173 |
} |
| 174 |
})); |
| 175 |
}, |
| 176 |
/** |
| 177 |
* Handle the edit state requirements of selected media item. |
| 178 |
* |
| 179 |
* @return {void} |
| 180 |
*/ |
| 181 |
editState() { |
| 182 |
const selection = this.state('gallery').get('selection'); |
| 183 |
const view = new wp.media.view.EditImage({ |
| 184 |
model: selection.single(), |
| 185 |
controller: this |
| 186 |
}).render(); |
| 187 |
|
| 188 |
// Set the view to the EditImage frame using the selected image. |
| 189 |
this.content.set(view); |
| 190 |
|
| 191 |
// After bringing in the frame, load the actual editor via an ajax call. |
| 192 |
view.loadEditor(); |
| 193 |
}, |
| 194 |
/** |
| 195 |
* Create the default states. |
| 196 |
* |
| 197 |
* @return {void} |
| 198 |
*/ |
| 199 |
createStates: function createStates() { |
| 200 |
this.on('toolbar:create:main-gallery', this.galleryToolbar, this); |
| 201 |
this.on('content:render:edit-image', this.editState, this); |
| 202 |
this.states.add([new wp.media.controller.Library({ |
| 203 |
id: 'gallery', |
| 204 |
title: wp.media.view.l10n.createGalleryTitle, |
| 205 |
priority: 40, |
| 206 |
toolbar: 'main-gallery', |
| 207 |
filterable: 'uploaded', |
| 208 |
multiple: 'add', |
| 209 |
editable: false, |
| 210 |
library: wp.media.query({ |
| 211 |
type: 'image', |
| 212 |
...this.options.library |
| 213 |
}) |
| 214 |
}), new wp.media.controller.EditImage({ |
| 215 |
model: this.options.editImage |
| 216 |
}), new wp.media.controller.GalleryEdit({ |
| 217 |
library: this.options.selection, |
| 218 |
editing: this.options.editing, |
| 219 |
menu: 'gallery', |
| 220 |
displaySettings: false, |
| 221 |
multiple: true |
| 222 |
}), new wp.media.controller.GalleryAdd()]); |
| 223 |
} |
| 224 |
}); |
| 225 |
}; |
| 226 |
|
| 227 |
// The media library image object contains numerous attributes |
| 228 |
// we only need this set to display the image in the library. |
| 229 |
const slimImageObject = img => { |
| 230 |
const attrSet = ['sizes', 'mime', 'type', 'subtype', 'id', 'url', 'alt', 'link', 'caption']; |
| 231 |
return attrSet.reduce((result, key) => { |
| 232 |
if (img?.hasOwnProperty(key)) { |
| 233 |
result[key] = img[key]; |
| 234 |
} |
| 235 |
return result; |
| 236 |
}, {}); |
| 237 |
}; |
| 238 |
const getAttachmentsCollection = ids => { |
| 239 |
const { |
| 240 |
wp |
| 241 |
} = window; |
| 242 |
return wp.media.query({ |
| 243 |
order: 'ASC', |
| 244 |
orderby: 'post__in', |
| 245 |
post__in: ids, |
| 246 |
posts_per_page: -1, |
| 247 |
query: true, |
| 248 |
type: 'image' |
| 249 |
}); |
| 250 |
}; |
| 251 |
class MediaUpload extends external_wp_element_namespaceObject.Component { |
| 252 |
constructor() { |
| 253 |
super(...arguments); |
| 254 |
this.openModal = this.openModal.bind(this); |
| 255 |
this.onOpen = this.onOpen.bind(this); |
| 256 |
this.onSelect = this.onSelect.bind(this); |
| 257 |
this.onUpdate = this.onUpdate.bind(this); |
| 258 |
this.onClose = this.onClose.bind(this); |
| 259 |
} |
| 260 |
initializeListeners() { |
| 261 |
// When an image is selected in the media frame... |
| 262 |
this.frame.on('select', this.onSelect); |
| 263 |
this.frame.on('update', this.onUpdate); |
| 264 |
this.frame.on('open', this.onOpen); |
| 265 |
this.frame.on('close', this.onClose); |
| 266 |
} |
| 267 |
|
| 268 |
/** |
| 269 |
* Sets the Gallery frame and initializes listeners. |
| 270 |
* |
| 271 |
* @return {void} |
| 272 |
*/ |
| 273 |
buildAndSetGalleryFrame() { |
| 274 |
const { |
| 275 |
addToGallery = false, |
| 276 |
allowedTypes, |
| 277 |
multiple = false, |
| 278 |
value = DEFAULT_EMPTY_GALLERY |
| 279 |
} = this.props; |
| 280 |
|
| 281 |
// If the value did not changed there is no need to rebuild the frame, |
| 282 |
// we can continue to use the existing one. |
| 283 |
if (value === this.lastGalleryValue) { |
| 284 |
return; |
| 285 |
} |
| 286 |
const { |
| 287 |
wp |
| 288 |
} = window; |
| 289 |
this.lastGalleryValue = value; |
| 290 |
|
| 291 |
// If a frame already existed remove it. |
| 292 |
if (this.frame) { |
| 293 |
this.frame.remove(); |
| 294 |
} |
| 295 |
let currentState; |
| 296 |
if (addToGallery) { |
| 297 |
currentState = 'gallery-library'; |
| 298 |
} else { |
| 299 |
currentState = value && value.length ? 'gallery-edit' : 'gallery'; |
| 300 |
} |
| 301 |
if (!this.GalleryDetailsMediaFrame) { |
| 302 |
this.GalleryDetailsMediaFrame = getGalleryDetailsMediaFrame(); |
| 303 |
} |
| 304 |
const attachments = getAttachmentsCollection(value); |
| 305 |
const selection = new wp.media.model.Selection(attachments.models, { |
| 306 |
props: attachments.props.toJSON(), |
| 307 |
multiple |
| 308 |
}); |
| 309 |
this.frame = new this.GalleryDetailsMediaFrame({ |
| 310 |
mimeType: allowedTypes, |
| 311 |
state: currentState, |
| 312 |
multiple, |
| 313 |
selection, |
| 314 |
editing: value && value.length ? true : false |
| 315 |
}); |
| 316 |
wp.media.frame = this.frame; |
| 317 |
this.initializeListeners(); |
| 318 |
} |
| 319 |
|
| 320 |
/** |
| 321 |
* Initializes the Media Library requirements for the featured image flow. |
| 322 |
* |
| 323 |
* @return {void} |
| 324 |
*/ |
| 325 |
buildAndSetFeatureImageFrame() { |
| 326 |
const { |
| 327 |
wp |
| 328 |
} = window; |
| 329 |
const { |
| 330 |
value: featuredImageId, |
| 331 |
multiple, |
| 332 |
allowedTypes |
| 333 |
} = this.props; |
| 334 |
const featuredImageFrame = getFeaturedImageMediaFrame(); |
| 335 |
const attachments = getAttachmentsCollection(featuredImageId); |
| 336 |
const selection = new wp.media.model.Selection(attachments.models, { |
| 337 |
props: attachments.props.toJSON() |
| 338 |
}); |
| 339 |
this.frame = new featuredImageFrame({ |
| 340 |
mimeType: allowedTypes, |
| 341 |
state: 'featured-image', |
| 342 |
multiple, |
| 343 |
selection, |
| 344 |
editing: featuredImageId |
| 345 |
}); |
| 346 |
wp.media.frame = this.frame; |
| 347 |
// In order to select the current featured image when opening |
| 348 |
// the media library we have to set the appropriate settings. |
| 349 |
// Currently they are set in php for the post editor, but |
| 350 |
// not for site editor. |
| 351 |
wp.media.view.settings.post = { |
| 352 |
...wp.media.view.settings.post, |
| 353 |
featuredImageId: featuredImageId || -1 |
| 354 |
}; |
| 355 |
} |
| 356 |
componentWillUnmount() { |
| 357 |
this.frame?.remove(); |
| 358 |
} |
| 359 |
onUpdate(selections) { |
| 360 |
const { |
| 361 |
onSelect, |
| 362 |
multiple = false |
| 363 |
} = this.props; |
| 364 |
const state = this.frame.state(); |
| 365 |
const selectedImages = selections || state.get('selection'); |
| 366 |
if (!selectedImages || !selectedImages.models.length) { |
| 367 |
return; |
| 368 |
} |
| 369 |
if (multiple) { |
| 370 |
onSelect(selectedImages.models.map(model => slimImageObject(model.toJSON()))); |
| 371 |
} else { |
| 372 |
onSelect(slimImageObject(selectedImages.models[0].toJSON())); |
| 373 |
} |
| 374 |
} |
| 375 |
onSelect() { |
| 376 |
const { |
| 377 |
onSelect, |
| 378 |
multiple = false |
| 379 |
} = this.props; |
| 380 |
// Get media attachment details from the frame state. |
| 381 |
const attachment = this.frame.state().get('selection').toJSON(); |
| 382 |
onSelect(multiple ? attachment : attachment[0]); |
| 383 |
} |
| 384 |
onOpen() { |
| 385 |
const { |
| 386 |
wp |
| 387 |
} = window; |
| 388 |
const { |
| 389 |
value |
| 390 |
} = this.props; |
| 391 |
this.updateCollection(); |
| 392 |
|
| 393 |
//Handle active tab in media model on model open. |
| 394 |
if (this.props.mode) { |
| 395 |
this.frame.content.mode(this.props.mode); |
| 396 |
} |
| 397 |
|
| 398 |
// Handle both this.props.value being either (number[]) multiple ids |
| 399 |
// (for galleries) or a (number) singular id (e.g. image block). |
| 400 |
const hasMedia = Array.isArray(value) ? !!value?.length : !!value; |
| 401 |
if (!hasMedia) { |
| 402 |
return; |
| 403 |
} |
| 404 |
const isGallery = this.props.gallery; |
| 405 |
const selection = this.frame.state().get('selection'); |
| 406 |
const valueArray = Array.isArray(value) ? value : [value]; |
| 407 |
if (!isGallery) { |
| 408 |
valueArray.forEach(id => { |
| 409 |
selection.add(wp.media.attachment(id)); |
| 410 |
}); |
| 411 |
} |
| 412 |
|
| 413 |
// Load the images so they are available in the media modal. |
| 414 |
const attachments = getAttachmentsCollection(valueArray); |
| 415 |
|
| 416 |
// Once attachments are loaded, set the current selection. |
| 417 |
attachments.more().done(function () { |
| 418 |
if (isGallery && attachments?.models?.length) { |
| 419 |
selection.add(attachments.models); |
| 420 |
} |
| 421 |
}); |
| 422 |
} |
| 423 |
onClose() { |
| 424 |
const { |
| 425 |
onClose |
| 426 |
} = this.props; |
| 427 |
if (onClose) { |
| 428 |
onClose(); |
| 429 |
} |
| 430 |
this.frame.detach(); |
| 431 |
} |
| 432 |
updateCollection() { |
| 433 |
const frameContent = this.frame.content.get(); |
| 434 |
if (frameContent && frameContent.collection) { |
| 435 |
const collection = frameContent.collection; |
| 436 |
|
| 437 |
// Clean all attachments we have in memory. |
| 438 |
collection.toArray().forEach(model => model.trigger('destroy', model)); |
| 439 |
|
| 440 |
// Reset has more flag, if library had small amount of items all items may have been loaded before. |
| 441 |
collection.mirroring._hasMore = true; |
| 442 |
|
| 443 |
// Request items. |
| 444 |
collection.more(); |
| 445 |
} |
| 446 |
} |
| 447 |
openModal() { |
| 448 |
const { |
| 449 |
allowedTypes, |
| 450 |
gallery = false, |
| 451 |
unstableFeaturedImageFlow = false, |
| 452 |
modalClass, |
| 453 |
multiple = false, |
| 454 |
title = (0,external_wp_i18n_namespaceObject.__)('Select or Upload Media') |
| 455 |
} = this.props; |
| 456 |
const { |
| 457 |
wp |
| 458 |
} = window; |
| 459 |
if (gallery) { |
| 460 |
this.buildAndSetGalleryFrame(); |
| 461 |
} else { |
| 462 |
const frameConfig = { |
| 463 |
title, |
| 464 |
multiple |
| 465 |
}; |
| 466 |
if (!!allowedTypes) { |
| 467 |
frameConfig.library = { |
| 468 |
type: allowedTypes |
| 469 |
}; |
| 470 |
} |
| 471 |
this.frame = wp.media(frameConfig); |
| 472 |
} |
| 473 |
if (modalClass) { |
| 474 |
this.frame.$el.addClass(modalClass); |
| 475 |
} |
| 476 |
if (unstableFeaturedImageFlow) { |
| 477 |
this.buildAndSetFeatureImageFrame(); |
| 478 |
} |
| 479 |
this.initializeListeners(); |
| 480 |
this.frame.open(); |
| 481 |
} |
| 482 |
render() { |
| 483 |
return this.props.render({ |
| 484 |
open: this.openModal |
| 485 |
}); |
| 486 |
} |
| 487 |
} |
| 488 |
/* harmony default export */ const media_upload = (MediaUpload); |
| 489 |
|
| 490 |
;// CONCATENATED MODULE: ./packages/media-utils/build-module/components/index.js |
| 491 |
|
| 492 |
|
| 493 |
;// CONCATENATED MODULE: external ["wp","apiFetch"] |
| 494 |
const external_wp_apiFetch_namespaceObject = window["wp"]["apiFetch"]; |
| 495 |
var external_wp_apiFetch_default = /*#__PURE__*/__webpack_require__.n(external_wp_apiFetch_namespaceObject); |
| 496 |
;// CONCATENATED MODULE: external ["wp","blob"] |
| 497 |
const external_wp_blob_namespaceObject = window["wp"]["blob"]; |
| 498 |
;// CONCATENATED MODULE: ./packages/media-utils/build-module/utils/upload-media.js |
| 499 |
/** |
| 500 |
* WordPress dependencies |
| 501 |
*/ |
| 502 |
|
| 503 |
|
| 504 |
|
| 505 |
const noop = () => {}; |
| 506 |
|
| 507 |
/** |
| 508 |
* Browsers may use unexpected mime types, and they differ from browser to browser. |
| 509 |
* This function computes a flexible array of mime types from the mime type structured provided by the server. |
| 510 |
* Converts { jpg|jpeg|jpe: "image/jpeg" } into [ "image/jpeg", "image/jpg", "image/jpeg", "image/jpe" ] |
| 511 |
* The computation of this array instead of directly using the object, |
| 512 |
* solves the problem in chrome where mp3 files have audio/mp3 as mime type instead of audio/mpeg. |
| 513 |
* https://bugs.chromium.org/p/chromium/issues/detail?id=227004 |
| 514 |
* |
| 515 |
* @param {?Object} wpMimeTypesObject Mime type object received from the server. |
| 516 |
* Extensions are keys separated by '|' and values are mime types associated with an extension. |
| 517 |
* |
| 518 |
* @return {?Array} An array of mime types or the parameter passed if it was "falsy". |
| 519 |
*/ |
| 520 |
function getMimeTypesArray(wpMimeTypesObject) { |
| 521 |
if (!wpMimeTypesObject) { |
| 522 |
return wpMimeTypesObject; |
| 523 |
} |
| 524 |
return Object.entries(wpMimeTypesObject).map(([extensionsString, mime]) => { |
| 525 |
const [type] = mime.split('/'); |
| 526 |
const extensions = extensionsString.split('|'); |
| 527 |
return [mime, ...extensions.map(extension => `${type}/${extension}`)]; |
| 528 |
}).flat(); |
| 529 |
} |
| 530 |
|
| 531 |
/** |
| 532 |
* Media Upload is used by audio, image, gallery, video, and file blocks to |
| 533 |
* handle uploading a media file when a file upload button is activated. |
| 534 |
* |
| 535 |
* TODO: future enhancement to add an upload indicator. |
| 536 |
* |
| 537 |
* @param {Object} $0 Parameters object passed to the function. |
| 538 |
* @param {?Array} $0.allowedTypes Array with the types of media that can be uploaded, if unset all types are allowed. |
| 539 |
* @param {?Object} $0.additionalData Additional data to include in the request. |
| 540 |
* @param {Array} $0.filesList List of files. |
| 541 |
* @param {?number} $0.maxUploadFileSize Maximum upload size in bytes allowed for the site. |
| 542 |
* @param {Function} $0.onError Function called when an error happens. |
| 543 |
* @param {Function} $0.onFileChange Function called each time a file or a temporary representation of the file is available. |
| 544 |
* @param {?Object} $0.wpAllowedMimeTypes List of allowed mime types and file extensions. |
| 545 |
*/ |
| 546 |
async function uploadMedia({ |
| 547 |
allowedTypes, |
| 548 |
additionalData = {}, |
| 549 |
filesList, |
| 550 |
maxUploadFileSize, |
| 551 |
onError = noop, |
| 552 |
onFileChange, |
| 553 |
wpAllowedMimeTypes = null |
| 554 |
}) { |
| 555 |
// Cast filesList to array. |
| 556 |
const files = [...filesList]; |
| 557 |
const filesSet = []; |
| 558 |
const setAndUpdateFiles = (idx, value) => { |
| 559 |
(0,external_wp_blob_namespaceObject.revokeBlobURL)(filesSet[idx]?.url); |
| 560 |
filesSet[idx] = value; |
| 561 |
onFileChange(filesSet.filter(Boolean)); |
| 562 |
}; |
| 563 |
|
| 564 |
// Allowed type specified by consumer. |
| 565 |
const isAllowedType = fileType => { |
| 566 |
if (!allowedTypes) { |
| 567 |
return true; |
| 568 |
} |
| 569 |
return allowedTypes.some(allowedType => { |
| 570 |
// If a complete mimetype is specified verify if it matches exactly the mime type of the file. |
| 571 |
if (allowedType.includes('/')) { |
| 572 |
return allowedType === fileType; |
| 573 |
} |
| 574 |
// Otherwise a general mime type is used and we should verify if the file mimetype starts with it. |
| 575 |
return fileType.startsWith(`${allowedType}/`); |
| 576 |
}); |
| 577 |
}; |
| 578 |
|
| 579 |
// Allowed types for the current WP_User. |
| 580 |
const allowedMimeTypesForUser = getMimeTypesArray(wpAllowedMimeTypes); |
| 581 |
const isAllowedMimeTypeForUser = fileType => { |
| 582 |
return allowedMimeTypesForUser.includes(fileType); |
| 583 |
}; |
| 584 |
const validFiles = []; |
| 585 |
for (const mediaFile of files) { |
| 586 |
// Verify if user is allowed to upload this mime type. |
| 587 |
// Defer to the server when type not detected. |
| 588 |
if (allowedMimeTypesForUser && mediaFile.type && !isAllowedMimeTypeForUser(mediaFile.type)) { |
| 589 |
onError({ |
| 590 |
code: 'MIME_TYPE_NOT_ALLOWED_FOR_USER', |
| 591 |
message: (0,external_wp_i18n_namespaceObject.sprintf)( |
| 592 |
// translators: %s: file name. |
| 593 |
(0,external_wp_i18n_namespaceObject.__)('%s: Sorry, you are not allowed to upload this file type.'), mediaFile.name), |
| 594 |
file: mediaFile |
| 595 |
}); |
| 596 |
continue; |
| 597 |
} |
| 598 |
|
| 599 |
// Check if the block supports this mime type. |
| 600 |
// Defer to the server when type not detected. |
| 601 |
if (mediaFile.type && !isAllowedType(mediaFile.type)) { |
| 602 |
onError({ |
| 603 |
code: 'MIME_TYPE_NOT_SUPPORTED', |
| 604 |
message: (0,external_wp_i18n_namespaceObject.sprintf)( |
| 605 |
// translators: %s: file name. |
| 606 |
(0,external_wp_i18n_namespaceObject.__)('%s: Sorry, this file type is not supported here.'), mediaFile.name), |
| 607 |
file: mediaFile |
| 608 |
}); |
| 609 |
continue; |
| 610 |
} |
| 611 |
|
| 612 |
// Verify if file is greater than the maximum file upload size allowed for the site. |
| 613 |
if (maxUploadFileSize && mediaFile.size > maxUploadFileSize) { |
| 614 |
onError({ |
| 615 |
code: 'SIZE_ABOVE_LIMIT', |
| 616 |
message: (0,external_wp_i18n_namespaceObject.sprintf)( |
| 617 |
// translators: %s: file name. |
| 618 |
(0,external_wp_i18n_namespaceObject.__)('%s: This file exceeds the maximum upload size for this site.'), mediaFile.name), |
| 619 |
file: mediaFile |
| 620 |
}); |
| 621 |
continue; |
| 622 |
} |
| 623 |
|
| 624 |
// Don't allow empty files to be uploaded. |
| 625 |
if (mediaFile.size <= 0) { |
| 626 |
onError({ |
| 627 |
code: 'EMPTY_FILE', |
| 628 |
message: (0,external_wp_i18n_namespaceObject.sprintf)( |
| 629 |
// translators: %s: file name. |
| 630 |
(0,external_wp_i18n_namespaceObject.__)('%s: This file is empty.'), mediaFile.name), |
| 631 |
file: mediaFile |
| 632 |
}); |
| 633 |
continue; |
| 634 |
} |
| 635 |
validFiles.push(mediaFile); |
| 636 |
|
| 637 |
// Set temporary URL to create placeholder media file, this is replaced |
| 638 |
// with final file from media gallery when upload is `done` below. |
| 639 |
filesSet.push({ |
| 640 |
url: (0,external_wp_blob_namespaceObject.createBlobURL)(mediaFile) |
| 641 |
}); |
| 642 |
onFileChange(filesSet); |
| 643 |
} |
| 644 |
for (let idx = 0; idx < validFiles.length; ++idx) { |
| 645 |
const mediaFile = validFiles[idx]; |
| 646 |
try { |
| 647 |
var _savedMedia$caption$r; |
| 648 |
const savedMedia = await createMediaFromFile(mediaFile, additionalData); |
| 649 |
// eslint-disable-next-line camelcase |
| 650 |
const { |
| 651 |
alt_text, |
| 652 |
source_url, |
| 653 |
...savedMediaProps |
| 654 |
} = savedMedia; |
| 655 |
const mediaObject = { |
| 656 |
...savedMediaProps, |
| 657 |
alt: savedMedia.alt_text, |
| 658 |
caption: (_savedMedia$caption$r = savedMedia.caption?.raw) !== null && _savedMedia$caption$r !== void 0 ? _savedMedia$caption$r : '', |
| 659 |
title: savedMedia.title.raw, |
| 660 |
url: savedMedia.source_url |
| 661 |
}; |
| 662 |
setAndUpdateFiles(idx, mediaObject); |
| 663 |
} catch (error) { |
| 664 |
// Reset to empty on failure. |
| 665 |
setAndUpdateFiles(idx, null); |
| 666 |
let message; |
| 667 |
if (error.message) { |
| 668 |
message = error.message; |
| 669 |
} else { |
| 670 |
message = (0,external_wp_i18n_namespaceObject.sprintf)( |
| 671 |
// translators: %s: file name |
| 672 |
(0,external_wp_i18n_namespaceObject.__)('Error while uploading file %s to the media library.'), mediaFile.name); |
| 673 |
} |
| 674 |
onError({ |
| 675 |
code: 'GENERAL', |
| 676 |
message, |
| 677 |
file: mediaFile |
| 678 |
}); |
| 679 |
} |
| 680 |
} |
| 681 |
} |
| 682 |
|
| 683 |
/** |
| 684 |
* @param {File} file Media File to Save. |
| 685 |
* @param {?Object} additionalData Additional data to include in the request. |
| 686 |
* |
| 687 |
* @return {Promise} Media Object Promise. |
| 688 |
*/ |
| 689 |
function createMediaFromFile(file, additionalData) { |
| 690 |
// Create upload payload. |
| 691 |
const data = new window.FormData(); |
| 692 |
data.append('file', file, file.name || file.type.replace('/', '.')); |
| 693 |
if (additionalData) { |
| 694 |
Object.entries(additionalData).forEach(([key, value]) => data.append(key, value)); |
| 695 |
} |
| 696 |
return external_wp_apiFetch_default()({ |
| 697 |
path: '/wp/v2/media', |
| 698 |
body: data, |
| 699 |
method: 'POST' |
| 700 |
}); |
| 701 |
} |
| 702 |
|
| 703 |
;// CONCATENATED MODULE: ./packages/media-utils/build-module/utils/index.js |
| 704 |
|
| 705 |
|
| 706 |
;// CONCATENATED MODULE: ./packages/media-utils/build-module/index.js |
| 707 |
|
| 708 |
|
| 709 |
|
| 710 |
(window.wp = window.wp || {}).mediaUtils = __webpack_exports__; |
| 711 |
/******/ })() |
| 712 |
; |