WordPress.org

Make WordPress Core

Ticket #32417: 32417.7.diff

File 32417.7.diff, 19.3 KB (added by gonom9, 9 months ago)
  • src/wp-includes/css/wp-media-widget.css

    diff --git a/src/wp-includes/css/wp-media-widget.css b/src/wp-includes/css/wp-media-widget.css
    index e69de29..ea6c75a 100644
    a b  
     1.media-widget-preview .button { 
     2        text-align: center 
     3} 
     4 
     5.media-widget-preview .aligncenter { 
     6        display: block; 
     7        margin: 0 auto; 
     8        text-align: center 
     9} 
     10 
     11.media-widget-preview .image { 
     12        height: auto; 
     13        max-width: 100%; 
     14        cursor: pointer; 
     15} 
  • src/wp-includes/default-widgets.php

    diff --git a/src/wp-includes/default-widgets.php b/src/wp-includes/default-widgets.php
    index 0cf5fc3..e803135 100644
    a b require_once( ABSPATH . WPINC . '/widgets/class-wp-widget-tag-cloud.php' ); 
    4545 
    4646/** WP_Nav_Menu_Widget class */ 
    4747require_once( ABSPATH . WPINC . '/widgets/class-wp-nav-menu-widget.php' ); 
     48 
     49/** WP_Widget_Media class */ 
     50require_once( ABSPATH . WPINC . '/widgets/class-wp-widget-media.php' ); 
  • src/wp-includes/js/wp-media-widget.js

    diff --git a/src/wp-includes/js/wp-media-widget.js b/src/wp-includes/js/wp-media-widget.js
    index e69de29..faf2263 100644
    a b  
     1/** 
     2 * @since 4.4.0 
     3 * 
     4 * @package WP_Media_Widget 
     5 */ 
     6(function ( $ ) { 
     7        var frame, widgetFrame; 
     8 
     9        frame = { 
     10                buttonId: '.media-widget-preview .button', 
     11 
     12                defaultProps: { 
     13                        'id' : '', 
     14                        'align' : '', 
     15                        'size' : '', 
     16                        'link' : '' 
     17                }, 
     18 
     19                init: function() { 
     20                        $( frame.buttonId ) 
     21                                .off( 'click.mediaWidget' ) 
     22                                .on( 'click.mediaWidget', frame.openMediaManager ); 
     23 
     24                        frame.bindImageClick(); 
     25 
     26                        wp.mediaelement.initialize(); 
     27                }, 
     28 
     29                bindImageClick: function(){ 
     30                        $('.media-widget-preview .image') 
     31                                .off( 'click.mediaWidget' ) 
     32                                .on( 'click.mediaWidget', frame.openMediaManager ); 
     33                }, 
     34 
     35                openMediaManager: function( event ) { 
     36                        event.preventDefault(); 
     37                        var widget_id = $( event.target ).data( 'id' ); 
     38 
     39                        // Create the media frame. 
     40                        widgetFrame = wp.media({ 
     41                                button: { 
     42                                        text: 'Add to widget' // Text of the submit button. 
     43                                }, 
     44 
     45                                states: new wp.media.controller.Library({ 
     46                                        library:   wp.media.query(), 
     47                                        title: 'Select Media', // Media frame title 
     48                                        multiple:  false, 
     49                                        priority:  20, 
     50                                        display: true // attachment display setting 
     51                                }) 
     52                        }); 
     53 
     54                        // Populate previously selected media when the media frame is opened. 
     55                        widgetFrame.on( 'open', function() { 
     56                                var selection = widgetFrame.state().get('selection'), 
     57                                        ids = $( '#widget-' + widget_id + '-id' ).val().split(','); 
     58 
     59                                if ( ids[0] > 0 ) { 
     60                                        ids.forEach( function( id ) { 
     61                                                var attachment = wp.media.attachment( id ); 
     62                                                attachment.fetch(); 
     63                                                selection.add( attachment ? [ attachment ] : [] ); 
     64                                        }); 
     65                                } 
     66                        }); 
     67 
     68                        // Render the attachment details. 
     69                        widgetFrame.on( 'select', function() { 
     70                                var props, attachment; 
     71 
     72                                // Only try to render the attachment details if a selection was made. 
     73                                if ( widgetFrame.state().get('selection').length > 0 ) { 
     74                                        props = widgetFrame.content.get('.attachments-browser') 
     75                                                .sidebar.get('display').model.toJSON(); 
     76 
     77                                        attachment = widgetFrame.state().get('selection').first().toJSON(); 
     78 
     79                                        frame.renderFormView( widget_id, props, attachment ); 
     80                                } 
     81                        }); 
     82 
     83                        widgetFrame.open( widget_id ); 
     84                }, 
     85 
     86                /** 
     87                 * Renders the attachment details from the media modal into the widget. 
     88                 * 
     89                 * @param {String} widget_id Attachment Display Settings (align, link, size, etc). 
     90                 * @param {Object} props Attachment Display Settings (align, link, size, etc). 
     91                 * @param {Object} attachment Attachment Details (title, description, caption, url, sizes, etc). 
     92                 */ 
     93                renderFormView: function( widget_id, props, attachment ) { 
     94                        // Start with container elements for the widgets page, customizer controls, and customizer preview. 
     95                        var mediaEl, 
     96                                html, 
     97                                extras, 
     98                                template, 
     99                                formView = $( '.' + widget_id + ', #customize-control-widget_' + widget_id + ', #' + widget_id ); 
     100 
     101                        // The widget title bar doesn't update automatically on the Appearance > Widgets page. This fixes that problem. 
     102                        formView.closest( '.widget' ).find( '.in-widget-title' ).html( ': ' + attachment.title ); 
     103 
     104                        formView.find( '.attachment-description' ) 
     105                                [ attachment.description ? 'removeClass' : 'addClass' ]('hidden') 
     106                                .html( attachment.description ); 
     107 
     108                        extras = formView.find( '.extras' ); 
     109                        // Display a preview of the image in the widgets page and customizer controls. 
     110                        extras.removeClass( 'hidden' ); 
     111 
     112                        attachment.link = props.link; 
     113                        attachment.size = props.size; 
     114 
     115                        if ( 'image' === attachment.type ) { 
     116 
     117                                if ( mediaEl && ! mediaEl.length ) { 
     118                                        extras.before( '<div class="media-widget-admin-preview"><img class="image" /></div>' ); 
     119                                        mediaEl = formView.find( '.image' ); // @todo Variable is not used. 
     120                                } 
     121 
     122                                html = $( '<img />' ).attr({ 
     123                                        'data-id': widget_id, 
     124                                        'src':     attachment.sizes[ props.size ].url, 
     125                                        'class':   'image align' + props.align, 
     126                                        'title':   attachment.title, 
     127                                        'alt':     attachment.alt, 
     128                                        'width':   attachment.sizes[ props.size ].width, 
     129                                        'height':  attachment.sizes[ props.size ].height 
     130                                }).wrap('<div />').parent().html(); 
     131 
     132                        } else if ( 'audio' === attachment.type ) { 
     133 
     134                                if( 'embed' === props.link ) { 
     135                                        template = wp.media.template( 'wp-media-widget-audio' ); 
     136                                        html = template( { 
     137                                                model: { 
     138                                                        src: attachment.url 
     139                                                } 
     140                                        } ); 
     141                                } else { 
     142                                        html = '<a href="#">' + attachment.title + '</a>'; 
     143                                } 
     144 
     145                        } else if ( 'video' === attachment.type ) { 
     146 
     147                                if( 'embed' === props.link ) { 
     148                                        template = wp.media.template( 'wp-media-widget-video' ); 
     149                                        html = template( { 
     150                                                model: { 
     151                                                        src: attachment.url, 
     152                                                        width: attachment.width, 
     153                                                        height: attachment.height 
     154                                                } 
     155                                        } ); 
     156                                } else { 
     157                                        html = '<a href="#">' + attachment.title + '</a>'; 
     158                                } 
     159 
     160                        } 
     161 
     162                        mediaEl = formView.find( '.media-widget-admin-preview' ); 
     163                        if ( mediaEl.length ) { 
     164                                if ( html ) { 
     165                                        mediaEl.html( html ); 
     166                                } else { 
     167                                        mediaEl.remove(); 
     168                                } 
     169                        } else if ( html ) { 
     170                                extras.before( '<div class="media-widget-admin-preview">' +  html + '</div>' ); 
     171                        } 
     172 
     173                        if ( -1 < $.inArray( attachment.type, [ 'audio', 'video' ] ) ) { 
     174                                wp.mediaelement.initialize(); 
     175                        } else if ( 'image' === attachment.type ) { 
     176                                frame.bindImageClick(); 
     177                        } 
     178 
     179                        // Populate form fields with selection data from the media frame. 
     180                        _.each( _.keys( frame.defaultProps ), function ( key ) { 
     181                                formView.find( '#widget-' + widget_id + '-' + key ).val( attachment[ key ] ).trigger( 'change' ); 
     182                        } ); 
     183 
     184                        // Trigger a sync to update the widget in the customizer preview. 
     185                        formView.find( '#widget-' + widget_id + '-url' ).trigger( 'change' ); 
     186 
     187                        // Change button text 
     188                        formView.find( frame.buttonId ).text( ( window._mediaWidgetl10n && _mediaWidgetl10n['change-media'] ) || 'Change Media' ); 
     189                } 
     190        }; 
     191 
     192        $( document ) 
     193                .ready( frame.init ) 
     194                .on( 'widget-added widget-updated', frame.init ); 
     195 
     196        window.wp = window.wp || {}; 
     197        window.wp.MediaWidget = frame; 
     198})( jQuery ); 
  • src/wp-includes/widgets.php

    diff --git a/src/wp-includes/widgets.php b/src/wp-includes/widgets.php
    index 1abadfb..f046f2d 100644
    a b function wp_widgets_init() { 
    14661466 
    14671467        register_widget('WP_Nav_Menu_Widget'); 
    14681468 
     1469        register_widget('WP_Media_Widget'); 
     1470 
    14691471        /** 
    14701472         * Fires after all default WordPress widgets have been registered. 
    14711473         * 
  • src/wp-includes/widgets/class-wp-widget-media.php

    diff --git a/src/wp-includes/widgets/class-wp-widget-media.php b/src/wp-includes/widgets/class-wp-widget-media.php
    index e69de29..6a73aca 100644
    a b  
     1<?php 
     2/** 
     3 * Widget API: WP_Media_Widget class 
     4 * 
     5 * @package WordPress 
     6 * @subpackage Widgets 
     7 * @since 4.4.0 
     8 */ 
     9 
     10/** 
     11 * Core class that implements a media widget. 
     12 * 
     13 * @since 4.4.0 
     14 * 
     15 * @see WP_Widget 
     16 */ 
     17class WP_Media_Widget extends WP_Widget { 
     18        /** 
     19         * Constructor. 
     20         * 
     21         * @since 4.4.0 
     22         * @access public 
     23         * 
     24         * @param string $id_base         Optional Base ID for the widget, lowercase and unique. If left empty, 
     25         *                                a portion of the widget's class name will be used Has to be unique. 
     26         * @param string $name            Optional. Name for the widget displayed on the configuration page. 
     27         *                                Default empty. 
     28         * @param array  $widget_options  Optional. Widget options. See wp_register_sidebar_widget() for 
     29         *                                information on accepted arguments. Default empty array. 
     30         * @param array  $control_options Optional. Widget control options. See wp_register_widget_control() 
     31         *                                for information on accepted arguments. Default empty array. 
     32         */ 
     33        public function __construct( $id_base = '', $name = '', $widget_options = array(), $control_options = array() ) { 
     34                $widget_opts = wp_parse_args( $widget_options, array( 
     35                        'classname' => 'widget_media', 
     36                        'description' => __( 'Display media such as images, video, or audio in your sidebar.' ), 
     37                        'customize_selective_refresh' => true, 
     38                ) ); 
     39 
     40                $control_opts = wp_parse_args( $control_options, array() ); 
     41 
     42                parent::__construct( 
     43                        $id_base ? $id_base : 'wp-media-widget', 
     44                        $name ? $name : __( 'Media' ), 
     45                        $widget_opts, 
     46                        $control_opts 
     47                ); 
     48 
     49                add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_styles' ) ); 
     50                add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) ); 
     51        } 
     52 
     53        /** 
     54         * Displays the widget on the front-end. 
     55         * 
     56         * @since 4.4.0 
     57         * @access public 
     58         * 
     59         * @see WP_Widget::widget() 
     60         * 
     61         * @param array $args     Display arguments including before_title, after_title, before_widget, and after_widget. 
     62         * @param array $instance Saved setting from the database. 
     63         */ 
     64        public function widget( $args, $instance ) { 
     65                extract( $instance ); 
     66 
     67                echo $args['before_widget']; 
     68                if ( ! empty( $instance['title'] ) ) { 
     69                        echo $args['before_title'] . $instance['title'] . $args['after_title']; 
     70                } 
     71                if ( ! empty( $instance['description'] ) ) { 
     72                        echo '<p class="attachment-description align' . $instance['align'] . '">' . $instance['description'] . '</p>'; 
     73                } 
     74                if ( ! empty( $instance['link'] ) ) { 
     75                        if ( 'file' == $instance['link'] ) { 
     76                                $url = wp_get_attachment_url( $instance['id'] ); 
     77                                $selectedLink = $url; 
     78                        } else if ( 'post' == $instance['link'] ) { 
     79                                $url = get_attachment_link( $instance['id'] ); 
     80                                $selectedLink = $url; 
     81                        } else { 
     82                                $selectedLink = ''; 
     83                        } 
     84                } 
     85 
     86                // Build the media output. 
     87                $media_output = ''; 
     88                if ( ! empty( $selectedLink ) ) { 
     89                        $media_output .= '<a href="' . $selectedLink . '">'; 
     90                } 
     91 
     92                if ( ! empty( $instance['id'] ) ) { 
     93                        if ( $attachment = get_post( $instance['id'] ) ) { 
     94                                $attrs = array(); 
     95 
     96                                if ( ! empty( $instance['title'] ) ) { 
     97                                        $attrs['title'] = $instance['title']; 
     98                                } 
     99 
     100                                // Image. 
     101                                if ( wp_attachment_is_image( $attachment ) ) { 
     102 
     103                                        $media_output .= wp_get_attachment_image( $instance['id'], $instance['size'], false, array( 
     104                                                'data-id' => esc_attr( $args['widget_id'] ), 
     105                                                'class' => 'image align' . $instance['align'], 
     106                                                'title' => $instance['title'], 
     107                                        ) ); 
     108 
     109                                // Audio. 
     110                                } elseif ( wp_attachment_is( 'audio', $attachment ) ) { 
     111                                        if ( ! empty( $selectedLink ) ) { 
     112                                                $media_output .= $attachment->post_title; 
     113                                        } else { 
     114                                                $media_output .= $this->get_attachment_audio( $attachment->ID, array() ); 
     115                                        } 
     116 
     117                                // Video. 
     118                                } elseif( wp_attachment_is( 'video', $attachment ) ) { 
     119                                        if ( ! empty( $selectedLink ) ) { 
     120                                                $media_output .= $attachment->post_title; 
     121                                        } else { 
     122                                                $media_output .= $this->get_attachment_video( $attachment->ID, array() ); 
     123                                        } 
     124                                } 
     125                        } 
     126                } 
     127 
     128                if ( ! empty( $selectedLink ) ) { 
     129                        $media_output .= '</a>'; 
     130                } 
     131 
     132                echo $media_output; 
     133                echo $args['after_widget']; 
     134        } 
     135 
     136        /** 
     137         * Sanitizes the widget form values as they are saved. 
     138         * 
     139         * @since 4.4.0 
     140         * @access public 
     141         * 
     142         * @see WP_Widget::update() 
     143         * 
     144         * @param array $new_instance Values just sent to be saved. 
     145         * @param array $old_instance Previously saved values from database. 
     146         * @return array Updated safe values to be saved. 
     147         */ 
     148        function update( $new_instance, $old_instance ) { 
     149                $instance = $old_instance; 
     150 
     151                // ID, title 
     152                $instance['id'] = (int) $new_instance['id']; 
     153                $instance['title'] = sanitize_text_field( $new_instance['title'] ); 
     154 
     155                // Everything else. 
     156                $instance['align'] = sanitize_text_field( $new_instance['align'] ); 
     157                $instance['size'] = sanitize_text_field( $new_instance['size'] ); 
     158                $instance['link'] = sanitize_text_field( $new_instance['link'] ); 
     159                return $instance; 
     160        } 
     161 
     162        /** 
     163         * Renders an image attachment preview. 
     164         * 
     165         * @since 4.4.0 
     166         * @access public 
     167         * 
     168         * @param WP_Post $attachment Attachment object. 
     169         * @param string  $widget_id  Widget ID. 
     170         * @param array   $instance   Current widget instance arguments. 
     171         */ 
     172        public function render_image( $attachment, $widget_id, $instance ) { 
     173                // If an image id is saved for this widget, display the image using `wp_get_attachment_image()`. 
     174                echo '<div class="media-widget-admin-preview">', 
     175                        wp_get_attachment_image( $attachment->ID, $instance['size'], false, array( 
     176                                'data-id' => esc_attr( $widget_id ), 
     177                                'class'   => 'image align' . esc_attr( $instance['align'] ), 
     178                                'title'   => esc_attr( $attachment->post_title ), 
     179                        ) ), 
     180                '</div>'; 
     181        } 
     182 
     183        /** 
     184         * Renders an audio attachment preview. 
     185         * 
     186         * @since 4.4.0 
     187         * @access public 
     188         * 
     189         * @param WP_Post $attachment Attachment object. 
     190         * @param string  $widget_id  Widget ID. 
     191         * @param array   $instance   Current widget instance arguments. 
     192         */ 
     193        public function render_audio( $attachment, $widget_id, $instance ) { 
     194                echo '<div class="media-widget-admin-preview">'; 
     195                if( $instance['link'] == 'embed' ){ 
     196                        echo $this->get_attachment_audio( $attachment->ID ); 
     197                } else { 
     198                        echo '<a href="#">' . $attachment->post_title .'</a>'; 
     199                } 
     200                echo '</p>'; 
     201        } 
     202 
     203        /** 
     204         * Get a audio elmeent reprensenting a video attachment 
     205         * 
     206         * @since 4.4.0 
     207         * @access private 
     208         * 
     209         * @param int   $attachment_id Audio attachment ID. 
     210         * @param array Attributes for the audio markup. 
     211         */ 
     212        private function get_attachment_audio( $attachment_id, $attrs = array() ) { 
     213                $output = wp_audio_shortcode( array( 
     214                        'src' => wp_get_attachment_url( $attachment_id ) 
     215                ) ); 
     216 
     217                return $output; 
     218        } 
     219 
     220        /** 
     221         * Renders a video attachment preview. 
     222         * 
     223         * @since 4.4.0 
     224         * @access public 
     225         * 
     226         * @param WP_Post $attachment Attachment object. 
     227         * @param string  $widget_id  Widget ID. 
     228         * @param array   $instance   Current widget instance arguments. 
     229         */ 
     230        public function render_video( $attachment, $widget_id, $instance ) { 
     231                echo '<div class="media-widget-admin-preview">'; 
     232                if( 'embed' === $instance['link'] ){ 
     233                        echo $this->get_attachment_video( $attachment->ID ); 
     234                } else { 
     235                        echo '<a href="#">' . $attachment->post_title .'</a>'; 
     236                } 
     237                echo '</div>'; 
     238        } 
     239 
     240        /** 
     241         * Get a video elmeent reprensenting a video attachment 
     242         * 
     243         * @since 4.4.0 
     244         * @access private 
     245         * 
     246         * @param int   $attachment_id Video attachment ID. 
     247         * @param array Attributes for the video markup. 
     248         */ 
     249        private function get_attachment_video( $attachment_id, $attrs = array() ) { 
     250                $output = wp_video_shortcode( array( 
     251                        'src' => wp_get_attachment_url( $attachment_id ) 
     252                ) ); 
     253 
     254                return $output; 
     255        } 
     256 
     257        /** 
     258         * Outputs the settings update form. 
     259         * 
     260         * @since 4.4.0 
     261         * @access public 
     262         * 
     263         * @param array $saved_instance Current settings. 
     264         * @return string Default return is 'noform'. 
     265         */ 
     266        public function form( $saved_instance ) { 
     267                $defaults = array( 
     268                        'title'  => '', 
     269                        // Attachment props. 
     270                        'id'     => '', 
     271                        'align'  => '', 
     272                        'size'   => '', 
     273                        'link'   => '', 
     274                ); 
     275                $instance   = wp_parse_args( (array) $saved_instance, $defaults ); 
     276                $attachment = empty( $instance['id'] ) ? null: get_post( $instance['id'] ); 
     277                $widget_id  = $this->id; 
     278                ?> 
     279                <div class="<?php echo esc_attr( $widget_id ); ?> media-widget-preview"> 
     280                        <p> 
     281                                <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php esc_html_e( 'Title:' ); ?></label> 
     282                                <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $instance['title'] ); ?>" /> 
     283                        </p> 
     284 
     285                        <p> 
     286                                <?php _e( 'Add an image, video, or audio to your sidebar.' ); ?> 
     287                        </p> 
     288 
     289                        <?php 
     290                                if ( $attachment ) { 
     291                                        if ( wp_attachment_is_image( $attachment ) ) { 
     292                                                $this->render_image( $attachment, $widget_id, $instance ); 
     293                                        } elseif ( wp_attachment_is( 'audio', $attachment ) ) { 
     294                                                $this->render_audio( $attachment, $widget_id, $instance ); 
     295                                        } elseif ( wp_attachment_is( 'video', $attachment ) ) { 
     296                                                $this->render_video( $attachment, $widget_id, $instance ); 
     297                                        } 
     298                                } 
     299                        ?> 
     300 
     301                        <p class="extras"> 
     302                        </p> 
     303 
     304                        <p> 
     305                                <a data-id="<?php echo esc_attr( $widget_id ); ?>" class="button select-media widefat"><?php 
     306                                        esc_html_e( $attachment ? 'Change Media' : 'Select Media' ); 
     307                                ?></a> 
     308                        </p> 
     309 
     310                        <fieldset class="media-widget-hidden-fields"> 
     311                                <?php 
     312                                // Use hidden form fields to capture the attachment details from the media manager. 
     313                                unset( $instance['title'] ); 
     314                                ?> 
     315 
     316                                <?php foreach ( array_keys( $instance ) as $i ) : ?> 
     317                                        <input type="hidden" id="<?php echo esc_attr( $this->get_field_id( $i ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( $i ) ); ?>" value="<?php echo esc_attr( $instance[ $i ] ); ?>" /> 
     318                                <?php endforeach; ?> 
     319                        </fieldset> 
     320                </div> 
     321                <?php 
     322        } 
     323 
     324        /** 
     325         * Registers the stylesheet for handling the widget in the back-end. 
     326         * 
     327         * @since 4.4.0 
     328         * @access public 
     329         */ 
     330        public function enqueue_admin_styles() { 
     331                wp_enqueue_style( 'wp-media-widget-styles', includes_url( 'css/wp-media-widget.css' ), array( 'media-views' ) ); 
     332        } 
     333 
     334        /** 
     335         * Registers the scripts for handling the widget in the back-end. 
     336         * 
     337         * @since 4.4.0 
     338         * @access public 
     339         */ 
     340        public function enqueue_admin_scripts() { 
     341                global $pagenow; 
     342 
     343                // Bail if we are not in the widgets or customize screens. 
     344                if ( ! ( 'widgets.php' == $pagenow || 'customize.php' == $pagenow ) ) { 
     345                        return; 
     346                } 
     347 
     348                // Load the required media files for the media manager. 
     349                wp_enqueue_media(); 
     350 
     351                // Register, localize and enqueue custom JS. 
     352                wp_enqueue_script( 
     353                        'wp-media-widget', 
     354                        includes_url( 'js/wp-media-widget.js' ), 
     355                        array( 'jquery', 'media-models', 'media-views', 'wp-mediaelement' ), 
     356                        '', 
     357                        true 
     358                ); 
     359 
     360                wp_localize_script( 'wp-media-widget', '_mediaWidgetl10n', 
     361                        array( 
     362                                'title'  => __( 'Select an Image' ), 
     363                                'button' => __( 'Insert Image' ), 
     364                                'select-media' => __( 'Select Media' ), 
     365                                'change-media' => __( 'Change Media' ), 
     366                        ) 
     367                ); 
     368 
     369                add_action( 'admin_print_footer_scripts', array( $this, 'admin_print_footer_scripts' ) ); 
     370        } 
     371 
     372        /** 
     373         * Prints footer scripts. 
     374         * 
     375         * @since 4.4.0 
     376         * @access public 
     377         */ 
     378        public function admin_print_footer_scripts() { 
     379                ?> 
     380                <script type="text/html" id="tmpl-wp-media-widget-audio"> 
     381                <?php wp_underscore_audio_template() ?> 
     382                </script> 
     383 
     384                <script type="text/html" id="tmpl-wp-media-widget-video"> 
     385                <?php wp_underscore_video_template() ?> 
     386                </script> 
     387 
     388                <?php 
     389        } 
     390}