: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
/******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ({
var Selection = wp.media.model.Selection,
Library = wp.media.controller.Library,
* wp.media.controller.CollectionAdd
* A state for adding attachments to a collection (e.g. video playlist).
* @memberOf wp.media.controller
* @augments wp.media.controller.Library
* @augments wp.media.controller.State
* @augments Backbone.Model
* @param {object} [attributes] The attributes hash passed to the state.
* @param {string} [attributes.id=library] Unique identifier.
* @param {string} attributes.title Title for the state. Displays in the frame's title region.
* @param {boolean} [attributes.multiple=add] Whether multi-select is enabled. @todo 'add' doesn't seem do anything special, and gets used as a boolean.
* @param {wp.media.model.Attachments} [attributes.library] The attachments collection to browse.
* If one is not supplied, a collection of attachments of the specified type will be created.
* @param {boolean|string} [attributes.filterable=uploaded] Whether the library is filterable, and if so what filters should be shown.
* Accepts 'all', 'uploaded', or 'unattached'.
* @param {string} [attributes.menu=gallery] Initial mode for the menu region.
* @param {string} [attributes.content=upload] Initial mode for the content region.
* Overridden by persistent user setting if 'contentUserSetting' is true.
* @param {string} [attributes.router=browse] Initial mode for the router region.
* @param {string} [attributes.toolbar=gallery-add] Initial mode for the toolbar region.
* @param {boolean} [attributes.searchable=true] Whether the library is searchable.
* @param {boolean} [attributes.sortable=true] Whether the Attachments should be sortable. Depends on the orderby property being set to menuOrder on the attachments collection.
* @param {boolean} [attributes.autoSelect=true] Whether an uploaded attachment should be automatically added to the selection.
* @param {boolean} [attributes.contentUserSetting=true] Whether the content region's mode should be set and persisted per user.
* @param {int} [attributes.priority=100] The priority for the state link in the media menu.
* @param {boolean} [attributes.syncSelection=false] Whether the Attachments selection should be persisted from the last state.
* Defaults to false because for this state, because the library of the Edit Gallery state is the selection.
* @param {string} attributes.type The collection's media type. (e.g. 'video').
* @param {string} attributes.collectionType The collection type. (e.g. 'playlist').
CollectionAdd = Library.extend(/** @lends wp.media.controller.CollectionAdd.prototype */{
// Selection defaults. @see media.model.Selection
// Attachments browser defaults. @see media.view.AttachmentsBrowser
}, Library.prototype.defaults ),
var collectionType = this.get('collectionType');
if ( 'video' === this.get( 'type' ) ) {
collectionType = 'video-' + collectionType;
this.set( 'id', collectionType + '-library' );
this.set( 'toolbar', collectionType + '-add' );
this.set( 'menu', collectionType );
// If we haven't been provided a `library`, create a `Selection`.
if ( ! this.get('library') ) {
this.set( 'library', wp.media.query({ type: this.get('type') }) );
Library.prototype.initialize.apply( this, arguments );
var library = this.get('library'),
editLibrary = this.get('editLibrary'),
edit = this.frame.state( this.get('collectionType') + '-edit' ).get('library');
if ( editLibrary && editLibrary !== edit ) {
library.unobserve( editLibrary );
// Accepts attachments that exist in the original library and
// that do not exist in gallery's library.
library.validator = function( attachment ) {
return !! this.mirroring.get( attachment.cid ) && ! edit.get( attachment.cid ) && Selection.prototype.validator.apply( this, arguments );
* Reset the library to ensure that all attachments are re-added
* to the collection. Do so silently, as calling `observe` will
* trigger the `reset` event.
library.reset( library.mirroring.models, { silent: true });
this.set('editLibrary', edit);
Library.prototype.activate.apply( this, arguments );
module.exports = CollectionAdd;
var Library = wp.media.controller.Library,
l10n = wp.media.view.l10n,
* wp.media.controller.CollectionEdit
* A state for editing a collection, which is used by audio and video playlists,
* and can be used for other collections.
* @memberOf wp.media.controller
* @augments wp.media.controller.Library
* @augments wp.media.controller.State
* @augments Backbone.Model
* @param {object} [attributes] The attributes hash passed to the state.
* @param {string} attributes.title Title for the state. Displays in the media menu and the frame's title region.
* @param {wp.media.model.Attachments} [attributes.library] The attachments collection to edit.
* If one is not supplied, an empty media.model.Selection collection is created.
* @param {boolean} [attributes.multiple=false] Whether multi-select is enabled.
* @param {string} [attributes.content=browse] Initial mode for the content region.
* @param {string} attributes.menu Initial mode for the menu region. @todo this needs a better explanation.
* @param {boolean} [attributes.searchable=false] Whether the library is searchable.
* @param {boolean} [attributes.sortable=true] Whether the Attachments should be sortable. Depends on the orderby property being set to menuOrder on the attachments collection.
* @param {boolean} [attributes.date=true] Whether to show the date filter in the browser's toolbar.
* @param {boolean} [attributes.describe=true] Whether to offer UI to describe the attachments - e.g. captioning images in a gallery.
* @param {boolean} [attributes.dragInfo=true] Whether to show instructional text about the attachments being sortable.
* @param {boolean} [attributes.dragInfoText] Instructional text about the attachments being sortable.
* @param {int} [attributes.idealColumnWidth=170] The ideal column width in pixels for attachments.
* @param {boolean} [attributes.editing=false] Whether the gallery is being created, or editing an existing instance.
* @param {int} [attributes.priority=60] The priority for the state link in the media menu.
* @param {boolean} [attributes.syncSelection=false] Whether the Attachments selection should be persisted from the last state.
* Defaults to false for this state, because the library passed in *is* the selection.
* @param {view} [attributes.SettingsView] The view to edit the collection instance settings (e.g. Playlist settings with "Show tracklist" checkbox).
* @param {view} [attributes.AttachmentView] The single `Attachment` view to be used in the `Attachments`.
* If none supplied, defaults to wp.media.view.Attachment.EditLibrary.
* @param {string} attributes.type The collection's media type. (e.g. 'video').
* @param {string} attributes.collectionType The collection type. (e.g. 'playlist').
CollectionEdit = Library.extend(/** @lends wp.media.controller.CollectionEdit.prototype */{
var collectionType = this.get('collectionType');
if ( 'video' === this.get( 'type' ) ) {
collectionType = 'video-' + collectionType;
this.set( 'id', collectionType + '-edit' );
this.set( 'toolbar', collectionType + '-edit' );
// If we haven't been provided a `library`, create a `Selection`.
if ( ! this.get('library') ) {
this.set( 'library', new wp.media.model.Selection() );
// The single `Attachment` view to be used in the `Attachments` view.
if ( ! this.get('AttachmentView') ) {
this.set( 'AttachmentView', wp.media.view.Attachment.EditLibrary );
Library.prototype.initialize.apply( this, arguments );
var library = this.get('library');
// Limit the library to images only.
library.props.set( 'type', this.get( 'type' ) );
// Watch for uploaded attachments.
this.get('library').observe( wp.Uploader.queue );
this.frame.on( 'content:render:browse', this.renderSettings, this );
Library.prototype.activate.apply( this, arguments );
// Stop watching for uploaded attachments.
this.get('library').unobserve( wp.Uploader.queue );
this.frame.off( 'content:render:browse', this.renderSettings, this );
Library.prototype.deactivate.apply( this, arguments );
* Render the collection embed settings view in the browser sidebar.
* @todo This is against the pattern elsewhere in media. Typically the frame
* is responsible for adding region mode callbacks. Explain.
* @param {wp.media.view.attachmentsBrowser} The attachments browser view.
renderSettings: function( attachmentsBrowserView ) {
var library = this.get('library'),
collectionType = this.get('collectionType'),
dragInfoText = this.get('dragInfoText'),
SettingsView = this.get('SettingsView'),
if ( ! library || ! attachmentsBrowserView ) {
library[ collectionType ] = library[ collectionType ] || new Backbone.Model();
obj[ collectionType ] = new SettingsView({
model: library[ collectionType ],
attachmentsBrowserView.sidebar.set( obj );
attachmentsBrowserView.toolbar.set( 'dragInfo', new wp.media.View({
el: $( '<div class="instructions">' + dragInfoText + '</div>' )[0],
// Add the 'Reverse order' button to the toolbar.
attachmentsBrowserView.toolbar.set( 'reverse', {
library.reset( library.toArray().reverse() );
module.exports = CollectionEdit;
var l10n = wp.media.view.l10n,
* wp.media.controller.Cropper
* A class for cropping an image when called from the header media customization panel.
* @memberOf wp.media.controller
* @augments wp.media.controller.State
* @augments Backbone.Model
Cropper = wp.media.controller.State.extend(/** @lends wp.media.controller.Cropper.prototype */{
// Default doCrop Ajax arguments to allow the Customizer (for example) to inject state.
* Shows the crop image window when called from the Add new image button.
this.frame.on( 'content:create:crop', this.createCropContent, this );
this.frame.on( 'close', this.removeCropper, this );
this.set('selection', new Backbone.Collection(this.frame._selection.single));
* Changes the state of the toolbar window to browse mode.
this.frame.toolbar.mode('browse');
* Creates the crop image window.
* Initialized when clicking on the Select and Crop button.
createCropContent: function() {
this.cropperView = new wp.media.view.Cropper({
attachment: this.get('selection').first()
this.cropperView.on('image-loaded', this.createCropToolbar, this);
this.frame.content.set(this.cropperView);
* Removes the image selection and closes the cropping window.
removeCropper: function() {
this.imgSelect.cancelSelection();
this.imgSelect.setOptions({remove: true});
this.cropperView.remove();
* Checks if cropping can be skipped and creates crop toolbar accordingly.
createCropToolbar: function() {
var canSkipCrop, toolbarOptions;
canSkipCrop = this.get('canSkipCrop') || false;
requires: { library: false, selection: false },
var controller = this.controller,
selection = controller.state().get('selection').first();
selection.set({cropDetails: controller.state().imgSelect.getSelection()});
this.$el.text(l10n.cropping);
this.$el.attr('disabled', true);
controller.state().doCrop( selection ).done( function( croppedImage ) {
controller.trigger('cropped', croppedImage );
controller.trigger('content:error:crop');
_.extend( toolbarOptions.items, {
requires: { library: false, selection: false },
var selection = this.controller.state().get('selection').first();
this.controller.state().cropperView.remove();
this.controller.trigger('skippedcrop', selection);
this.frame.toolbar.set( new wp.media.view.Toolbar(toolbarOptions) );
* Creates an object with the image attachment and crop properties.
* @return {$.promise} A jQuery promise with the custom header crop details.
doCrop: function( attachment ) {
return wp.ajax.post( 'custom-header-crop', _.extend(
this.defaults.doCropArgs,
nonce: attachment.get( 'nonces' ).edit,
id: attachment.get( 'id' ),
cropDetails: attachment.get( 'cropDetails' )
module.exports = Cropper;
var Controller = wp.media.controller,
* A state for cropping an image in the customizer.
* @constructs wp.media.controller.CustomizeImageCropper
* @memberOf wp.media.controller
* @augments wp.media.controller.CustomizeImageCropper.Cropper
CustomizeImageCropper = Controller.Cropper.extend(/** @lends wp.media.controller.CustomizeImageCropper.prototype */{
* Posts the crop details to the admin.
* Uses crop measurements when flexible in both directions.
* Constrains flexible side based on image ratio and size of the fixed side.
* @param {Object} attachment The attachment to crop.
* @return {$.promise} A jQuery promise that represents the crop image request.
doCrop: function( attachment ) {
var cropDetails = attachment.get( 'cropDetails' ),
control = this.get( 'control' ),
ratio = cropDetails.width / cropDetails.height;
// Use crop measurements when flexible in both directions.
if ( control.params.flex_width && control.params.flex_height ) {
cropDetails.dst_width = cropDetails.width;
cropDetails.dst_height = cropDetails.height;
// Constrain flexible side based on image ratio and size of the fixed side.