media-image-widget.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /**
  2. * @output wp-admin/js/widgets/media-image-widget.js
  3. */
  4. /* eslint consistent-this: [ "error", "control" ] */
  5. (function( component, $ ) {
  6. 'use strict';
  7. var ImageWidgetModel, ImageWidgetControl;
  8. /**
  9. * Image widget model.
  10. *
  11. * See WP_Widget_Media_Image::enqueue_admin_scripts() for amending prototype from PHP exports.
  12. *
  13. * @class wp.mediaWidgets.modelConstructors.media_image
  14. * @augments wp.mediaWidgets.MediaWidgetModel
  15. */
  16. ImageWidgetModel = component.MediaWidgetModel.extend({});
  17. /**
  18. * Image widget control.
  19. *
  20. * See WP_Widget_Media_Image::enqueue_admin_scripts() for amending prototype from PHP exports.
  21. *
  22. * @class wp.mediaWidgets.controlConstructors.media_audio
  23. * @augments wp.mediaWidgets.MediaWidgetControl
  24. */
  25. ImageWidgetControl = component.MediaWidgetControl.extend(/** @lends wp.mediaWidgets.controlConstructors.media_image.prototype */{
  26. /**
  27. * View events.
  28. *
  29. * @type {object}
  30. */
  31. events: _.extend( {}, component.MediaWidgetControl.prototype.events, {
  32. 'click .media-widget-preview.populated': 'editMedia'
  33. } ),
  34. /**
  35. * Render preview.
  36. *
  37. * @return {void}
  38. */
  39. renderPreview: function renderPreview() {
  40. var control = this, previewContainer, previewTemplate, fieldsContainer, fieldsTemplate, linkInput;
  41. if ( ! control.model.get( 'attachment_id' ) && ! control.model.get( 'url' ) ) {
  42. return;
  43. }
  44. previewContainer = control.$el.find( '.media-widget-preview' );
  45. previewTemplate = wp.template( 'wp-media-widget-image-preview' );
  46. previewContainer.html( previewTemplate( control.previewTemplateProps.toJSON() ) );
  47. previewContainer.addClass( 'populated' );
  48. linkInput = control.$el.find( '.link' );
  49. if ( ! linkInput.is( document.activeElement ) ) {
  50. fieldsContainer = control.$el.find( '.media-widget-fields' );
  51. fieldsTemplate = wp.template( 'wp-media-widget-image-fields' );
  52. fieldsContainer.html( fieldsTemplate( control.previewTemplateProps.toJSON() ) );
  53. }
  54. },
  55. /**
  56. * Open the media image-edit frame to modify the selected item.
  57. *
  58. * @return {void}
  59. */
  60. editMedia: function editMedia() {
  61. var control = this, mediaFrame, updateCallback, defaultSync, metadata;
  62. metadata = control.mapModelToMediaFrameProps( control.model.toJSON() );
  63. // Needed or else none will not be selected if linkUrl is not also empty.
  64. if ( 'none' === metadata.link ) {
  65. metadata.linkUrl = '';
  66. }
  67. // Set up the media frame.
  68. mediaFrame = wp.media({
  69. frame: 'image',
  70. state: 'image-details',
  71. metadata: metadata
  72. });
  73. mediaFrame.$el.addClass( 'media-widget' );
  74. updateCallback = function() {
  75. var mediaProps, linkType;
  76. // Update cached attachment object to avoid having to re-fetch. This also triggers re-rendering of preview.
  77. mediaProps = mediaFrame.state().attributes.image.toJSON();
  78. linkType = mediaProps.link;
  79. mediaProps.link = mediaProps.linkUrl;
  80. control.selectedAttachment.set( mediaProps );
  81. control.displaySettings.set( 'link', linkType );
  82. control.model.set( _.extend(
  83. control.mapMediaToModelProps( mediaProps ),
  84. { error: false }
  85. ) );
  86. };
  87. mediaFrame.state( 'image-details' ).on( 'update', updateCallback );
  88. mediaFrame.state( 'replace-image' ).on( 'replace', updateCallback );
  89. // Disable syncing of attachment changes back to server. See <https://core.trac.wordpress.org/ticket/40403>.
  90. defaultSync = wp.media.model.Attachment.prototype.sync;
  91. wp.media.model.Attachment.prototype.sync = function rejectedSync() {
  92. return $.Deferred().rejectWith( this ).promise();
  93. };
  94. mediaFrame.on( 'close', function onClose() {
  95. mediaFrame.detach();
  96. wp.media.model.Attachment.prototype.sync = defaultSync;
  97. });
  98. mediaFrame.open();
  99. },
  100. /**
  101. * Get props which are merged on top of the model when an embed is chosen (as opposed to an attachment).
  102. *
  103. * @return {Object} Reset/override props.
  104. */
  105. getEmbedResetProps: function getEmbedResetProps() {
  106. return _.extend(
  107. component.MediaWidgetControl.prototype.getEmbedResetProps.call( this ),
  108. {
  109. size: 'full',
  110. width: 0,
  111. height: 0
  112. }
  113. );
  114. },
  115. /**
  116. * Get the instance props from the media selection frame.
  117. *
  118. * Prevent the image_title attribute from being initially set when adding an image from the media library.
  119. *
  120. * @param {wp.media.view.MediaFrame.Select} mediaFrame - Select frame.
  121. * @return {Object} Props.
  122. */
  123. getModelPropsFromMediaFrame: function getModelPropsFromMediaFrame( mediaFrame ) {
  124. var control = this;
  125. return _.omit(
  126. component.MediaWidgetControl.prototype.getModelPropsFromMediaFrame.call( control, mediaFrame ),
  127. 'image_title'
  128. );
  129. },
  130. /**
  131. * Map model props to preview template props.
  132. *
  133. * @return {Object} Preview template props.
  134. */
  135. mapModelToPreviewTemplateProps: function mapModelToPreviewTemplateProps() {
  136. var control = this, previewTemplateProps, url;
  137. url = control.model.get( 'url' );
  138. previewTemplateProps = component.MediaWidgetControl.prototype.mapModelToPreviewTemplateProps.call( control );
  139. previewTemplateProps.currentFilename = url ? url.replace( /\?.*$/, '' ).replace( /^.+\//, '' ) : '';
  140. previewTemplateProps.link_url = control.model.get( 'link_url' );
  141. return previewTemplateProps;
  142. }
  143. });
  144. // Exports.
  145. component.controlConstructors.media_image = ImageWidgetControl;
  146. component.modelConstructors.media_image = ImageWidgetModel;
  147. })( wp.mediaWidgets, jQuery );