Make WordPress Core

Changeset 40640


Ignore:
Timestamp:
05/11/2017 09:10:54 PM (9 years ago)
Author:
westonruter
Message:

Widgets: Introduce media widgets for images, audio, and video with extensible base for additional media widgets in the future.

The last time a new widget was introduced, Vuvuzelas were a thing, Angry Birds started taking over phones, and WordPress stopped shipping with Kubrick. Seven years and 17 releases without new widgets have been enough, time to spice up your sidebar!

Props westonruter, melchoyce, obenland, timmydcrawford, adamsilverstein, gonom9, wonderboymusic, Fab1en, DrewAPicture, sirbrillig, joen, matias, samikeijonen, afercia, celloexpressions, designsimply, michelleweber, ranh, kjellr, karmatosed.
Fixes #32417, #39993, #39994, #39995.

Location:
trunk
Files:
20 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/css/widgets.css

    r40480 r40640  
    5656}
    5757
     58/* Media Widgets */
     59.wp-core-ui .media-widget-control.selected .placeholder,
     60.wp-core-ui .media-widget-control.selected .not-selected,
     61.wp-core-ui .media-widget-control .selected {
     62        display: none;
     63}
     64
     65.media-widget-control.selected .selected {
     66        display: inline-block;
     67}
     68
     69.media-widget-buttons {
     70        text-align: left;
     71        margin-bottom: 10px;
     72}
     73
     74.media-widget-control .media-widget-buttons .button {
     75        margin-left: 8px;
     76        width: auto;
     77}
     78.media-widget-control:not(.selected) .media-widget-buttons .button,
     79.media-widget-buttons .button:first-child {
     80        margin-left: 0;
     81}
     82
     83.media-widget-control .placeholder {
     84        border: 1px dashed #b4b9be;
     85        -webkit-box-sizing: border-box;
     86        -moz-box-sizing: border-box;
     87        box-sizing: border-box;
     88        cursor: default;
     89        line-height: 20px;
     90        padding: 9px 0;
     91        position: relative;
     92        text-align: center;
     93        width: 100%;
     94}
     95
     96.media-widget-control .media-widget-preview {
     97        text-align: center;
     98}
     99.media-widget-control .media-widget-preview .notice {
     100        text-align: initial;
     101}
     102.media-frame .media-widget-embed-notice p code,
     103.media-widget-control .notice p code {
     104        padding: 0 3px 0 0;
     105}
     106.media-frame .media-widget-embed-notice {
     107        margin-top: 16px;
     108}
     109.media-widget-control .media-widget-preview img {
     110        max-width: 100%;
     111}
     112.media-widget-control .media-widget-preview .wp-video-shortcode {
     113        background: #000;
     114}
     115
     116.media-frame.media-widget .media-toolbar-secondary {
     117        min-width: 300px;
     118}
     119
     120.media-frame.media-widget .image-details .embed-media-settings .setting.align,
     121.media-frame.media-widget .attachment-display-settings .setting.align,
     122.media-frame.media-widget .embed-media-settings .setting.align,
     123.media-frame.media-widget .embed-link-settings .setting.link-text,
     124.media-frame.media-widget .replace-attachment,
     125.media-frame.media-widget .checkbox-setting.autoplay {
     126        display: none;
     127}
     128
     129.media-widget-video-preview {
     130        width: 100%;
     131}
     132
     133.media-widget-video-link {
     134        display: inline-block;
     135        min-height: 132px;
     136        width: 100%;
     137        background: black;
     138}
     139
     140.media-widget-video-link .dashicons {
     141        font: normal 60px/1 'dashicons';
     142        position: relative;
     143        width: 100%;
     144        top: -90px;
     145        color: white;
     146        text-decoration: none;
     147}
     148
     149.media-widget-video-link.no-poster .dashicons {
     150        top: 30px;
     151}
     152
     153.media-frame #embed-url-field.invalid {
     154        border: 1px solid #f00;
     155}
     156
     157.wp-customizer .mejs-controls a:focus > .mejs-offscreen,
     158.widgets-php .mejs-controls a:focus > .mejs-offscreen {
     159        z-index: 2;
     160}
     161
    58162/* Widget Dragging Helpers */
    59163.widget.ui-draggable-dragging {
  • trunk/src/wp-content/themes/twentyten/style.css

    r38171 r40640  
    842842        text-align: center;
    843843}
     844.widget-container .wp-caption {
     845        max-width: 100% !important;
     846}
    844847.wp-caption img {
    845848        margin: 5px 5px 0;
  • trunk/src/wp-includes/default-widgets.php

    r34408 r40640  
    1919/** WP_Widget_Archives class */
    2020require_once( ABSPATH . WPINC . '/widgets/class-wp-widget-archives.php' );
     21
     22/** WP_Widget_Media class */
     23require_once( ABSPATH . WPINC . '/widgets/class-wp-widget-media.php' );
     24
     25/** WP_Widget_Media_Audio class */
     26require_once( ABSPATH . WPINC . '/widgets/class-wp-widget-media-audio.php' );
     27
     28/** WP_Widget_Media_Image class */
     29require_once( ABSPATH . WPINC . '/widgets/class-wp-widget-media-image.php' );
     30
     31/** WP_Widget_Media_Video class */
     32require_once( ABSPATH . WPINC . '/widgets/class-wp-widget-media-video.php' );
     33
     34/** WP_Widget_Meta class */
     35require_once( ABSPATH . WPINC . '/widgets/class-wp-widget-meta.php' );
    2136
    2237/** WP_Widget_Meta class */
  • trunk/src/wp-includes/js/customize-selective-refresh.js

    r40055 r40640  
    469469                        // Prevent placement container from being being re-triggered as being rendered among nested partials.
    470470                        placement.container.data( 'customize-partial-content-rendered', true );
     471
     472                        /*
     473                         * Note that the 'wp_audio_shortcode_library' and 'wp_video_shortcode_library' filters
     474                         * will determine whether or not wp.mediaelement is loaded and whether it will
     475                         * initialize audio and video respectively. See also https://core.trac.wordpress.org/ticket/40144
     476                         */
     477                        if ( wp.mediaelement ) {
     478                                wp.mediaelement.initialize();
     479                        }
    471480
    472481                        /**
  • trunk/src/wp-includes/media-template.php

    r40573 r40640  
    609609
    610610                <# if ( 'image' === data.type ) { #>
    611                         <label class="setting">
     611                        <label class="setting align">
    612612                                <span><?php _e('Alignment'); ?></span>
    613613                                <select class="alignment"
     
    10881088                                </div>
    10891089
    1090                                 <label class="setting checkbox-setting">
     1090                                <label class="setting checkbox-setting autoplay">
    10911091                                        <input type="checkbox" data-setting="autoplay" />
    10921092                                        <span><?php _e( 'Autoplay' ); ?></span>
     
    11771177                                </div>
    11781178
    1179                                 <label class="setting checkbox-setting">
     1179                                <label class="setting checkbox-setting autoplay">
    11801180                                        <input type="checkbox" data-setting="autoplay" />
    11811181                                        <span><?php _e( 'Autoplay' ); ?></span>
  • trunk/src/wp-includes/script-loader.php

    r40631 r40640  
    603603
    604604                $scripts->add( 'admin-widgets', "/wp-admin/js/widgets$suffix.js", array( 'jquery-ui-sortable', 'jquery-ui-draggable', 'jquery-ui-droppable' ), false, 1 );
     605                $scripts->add( 'media-widgets', "/wp-admin/js/widgets/media-widgets$suffix.js", array( 'jquery', 'media-models', 'media-views' ) );
     606                $scripts->add_inline_script( 'media-widgets', 'wp.mediaWidgets.init();', 'after' );
     607
     608                $scripts->add( 'media-audio-widget', "/wp-admin/js/widgets/media-audio-widget$suffix.js", array( 'media-widgets', 'media-audiovideo' ) );
     609                $scripts->add( 'media-image-widget', "/wp-admin/js/widgets/media-image-widget$suffix.js", array( 'media-widgets' ) );
     610                $scripts->add( 'media-video-widget', "/wp-admin/js/widgets/media-video-widget$suffix.js", array( 'media-widgets', 'media-audiovideo' ) );
    605611                $scripts->add( 'text-widgets', "/wp-admin/js/widgets/text-widgets$suffix.js", array( 'jquery', 'backbone', 'editor', 'wp-util' ) );
    606612                $scripts->add_inline_script( 'text-widgets', 'wp.textWidgets.init();', 'after' );
  • trunk/src/wp-includes/widgets.php

    r40251 r40640  
    14371437 */
    14381438function wp_widgets_init() {
    1439         if ( !is_blog_installed() )
    1440                 return;
    1441 
    1442         register_widget('WP_Widget_Pages');
    1443 
    1444         register_widget('WP_Widget_Calendar');
    1445 
    1446         register_widget('WP_Widget_Archives');
    1447 
    1448         if ( get_option( 'link_manager_enabled' ) )
    1449                 register_widget('WP_Widget_Links');
    1450 
    1451         register_widget('WP_Widget_Meta');
    1452 
    1453         register_widget('WP_Widget_Search');
    1454 
    1455         register_widget('WP_Widget_Text');
    1456 
    1457         register_widget('WP_Widget_Categories');
    1458 
    1459         register_widget('WP_Widget_Recent_Posts');
    1460 
    1461         register_widget('WP_Widget_Recent_Comments');
    1462 
    1463         register_widget('WP_Widget_RSS');
    1464 
    1465         register_widget('WP_Widget_Tag_Cloud');
    1466 
    1467         register_widget('WP_Nav_Menu_Widget');
     1439        if ( ! is_blog_installed() ) {
     1440                return;
     1441        }
     1442
     1443        register_widget( 'WP_Widget_Pages' );
     1444
     1445        register_widget( 'WP_Widget_Calendar' );
     1446
     1447        register_widget( 'WP_Widget_Archives' );
     1448
     1449        if ( get_option( 'link_manager_enabled' ) ) {
     1450                register_widget( 'WP_Widget_Links' );
     1451        }
     1452
     1453        register_widget( 'WP_Widget_Media_Audio' );
     1454
     1455        register_widget( 'WP_Widget_Media_Image' );
     1456
     1457        register_widget( 'WP_Widget_Media_Video' );
     1458
     1459        register_widget( 'WP_Widget_Meta' );
     1460
     1461        register_widget( 'WP_Widget_Search' );
     1462
     1463        register_widget( 'WP_Widget_Text' );
     1464
     1465        register_widget( 'WP_Widget_Categories' );
     1466
     1467        register_widget( 'WP_Widget_Recent_Posts' );
     1468
     1469        register_widget( 'WP_Widget_Recent_Comments' );
     1470
     1471        register_widget( 'WP_Widget_RSS' );
     1472
     1473        register_widget( 'WP_Widget_Tag_Cloud' );
     1474
     1475        register_widget( 'WP_Nav_Menu_Widget' );
    14681476
    14691477        /**
  • trunk/tests/phpunit/tests/widgets/text-widget.php

    r40631 r40640  
    179179                $result = $widget->update( $instance, array() );
    180180                $this->assertEquals( $result, $expected );
    181 
    182181                remove_filter( 'map_meta_cap', array( $this, 'grant_unfiltered_html_cap' ) );
     182
    183183                add_filter( 'map_meta_cap', array( $this, 'revoke_unfiltered_html_cap' ), 10, 2 );
    184184                $this->assertFalse( current_user_can( 'unfiltered_html' ) );
     
    187187                $result = $widget->update( $instance, array() );
    188188                $this->assertEquals( $result, $expected );
    189                 remove_filter( 'map_meta_cap', array( $this, 'revoke_unfiltered_html_cap' ), 10, 2 );
     189                remove_filter( 'map_meta_cap', array( $this, 'revoke_unfiltered_html_cap' ), 10 );
    190190        }
    191191
  • trunk/tests/qunit/index.html

    r40584 r40640  
    2525                <script src="../../src/wp-includes/js/wp-util.js"></script>
    2626                <script src="../../src/wp-includes/js/wp-a11y.js"></script>
     27                <script>
     28                        window._wpMediaModelsL10n = {"settings":{"ajaxurl":"\/wp-admin\/admin-ajax.php","post":{"id":0}}};
     29                </script>
     30                <script src="../../src/wp-includes/js/media-models.js"></script>
     31                <script>
     32                        window.userSettings = {"url":"\/","uid":"0","time":"1493325477","secure":""};
     33                </script>
     34                <script src="../../src/wp-includes/js/utils.js"></script>
     35                <script src="../../src/wp-includes/js/plupload/plupload.full.min.js"></script>
     36                <script>
     37                        window.pluploadL10n = {"queue_limit_exceeded":"You have attempted to queue too many files.","file_exceeds_size_limit":"%s exceeds the maximum upload size for this site.","zero_byte_file":"This file is empty. Please try another.","invalid_filetype":"Sorry, this file type is not permitted for security reasons.","not_an_image":"This file is not an image. Please try another.","image_memory_exceeded":"Memory exceeded. Please try another smaller file.","image_dimensions_exceeded":"This is larger than the maximum size. Please try another.","default_error":"An error occurred in the upload. Please try again later.","missing_upload_url":"There was a configuration error. Please contact the server administrator.","upload_limit_exceeded":"You may only upload 1 file.","http_error":"HTTP error.","upload_failed":"Upload failed.","big_upload_failed":"Please try uploading this file with the %1$sbrowser uploader%2$s.","big_upload_queued":"%s exceeds the maximum upload size for the multi-file uploader when used in your browser.","io_error":"IO error.","security_error":"Security error.","file_cancelled":"File canceled.","upload_stopped":"Upload stopped.","dismiss":"Dismiss","crunching":"Crunching\u2026","deleted":"moved to the trash.","error_uploading":"\u201c%s\u201d has failed to upload."};
     38                        window._wpPluploadSettings = {"defaults":{"runtimes":"html5,flash,silverlight,html4","file_data_name":"async-upload","url":"\/wp-admin\/async-upload.php","flash_swf_url":"http:\/\/src.wordpress-develop.dev\/wp-includes\/js\/plupload\/plupload.flash.swf","silverlight_xap_url":"http:\/\/src.wordpress-develop.dev\/wp-includes\/js\/plupload\/plupload.silverlight.xap","filters":{"max_file_size":"2097152b","mime_types":[{"extensions":"jpg,jpeg,jpe,gif,png,bmp,tiff,tif,ico,asf,asx,wmv,wmx,wm,avi,divx,flv,mov,qt,mpeg,mpg,mpe,mp4,m4v,ogv,webm,mkv,3gp,3gpp,3g2,3gp2,txt,asc,c,cc,h,srt,csv,tsv,ics,rtx,css,vtt,dfxp,mp3,m4a,m4b,ra,ram,wav,ogg,oga,mid,midi,wma,wax,mka,rtf,js,pdf,class,tar,zip,gz,gzip,rar,7z,psd,xcf,doc,pot,pps,ppt,wri,xla,xls,xlt,xlw,mdb,mpp,docx,docm,dotx,dotm,xlsx,xlsm,xlsb,xltx,xltm,xlam,pptx,pptm,ppsx,ppsm,potx,potm,ppam,sldx,sldm,onetoc,onetoc2,onetmp,onepkg,oxps,xps,odt,odp,ods,odg,odc,odb,odf,wp,wpd,key,numbers,pages"}]},"multipart_params":{"action":"upload-attachment","_wpnonce":"87fa5740b8"}},"browser":{"mobile":false,"supported":true},"limitExceeded":false};
     39                </script>
     40                <script src="../../src/wp-includes/js/plupload/wp-plupload.js"></script>
     41                <script>
     42                        window.mejsL10n = {"language":"en-US","strings":{"Close":"Close","Fullscreen":"Fullscreen","Turn off Fullscreen":"Turn off Fullscreen","Go Fullscreen":"Go Fullscreen","Download File":"Download File","Download Video":"Download Video","Play":"Play","Pause":"Pause","Captions\/Subtitles":"Captions\/Subtitles","None":"None","Time Slider":"Time Slider","Skip back %1 seconds":"Skip back %1 seconds","Video Player":"Video Player","Audio Player":"Audio Player","Volume Slider":"Volume Slider","Mute Toggle":"Mute Toggle","Unmute":"Unmute","Mute":"Mute","Use Up\/Down Arrow keys to increase or decrease volume.":"Use Up\/Down Arrow keys to increase or decrease volume.","Use Left\/Right Arrow keys to advance one second, Up\/Down arrows to advance ten seconds.":"Use Left\/Right Arrow keys to advance one second, Up\/Down arrows to advance ten seconds."}};
     43                        window._wpmejsSettings = {"pluginPath":"\/wp-includes\/js\/mediaelement\/"};
     44                </script>
     45                <script src="../../src/wp-includes/js/mediaelement/mediaelement-and-player.min.js"></script>
     46                <script src="../../src/wp-includes/js/mediaelement/wp-mediaelement.js"></script>
     47                <script>
     48                        window._wpMediaViewsL10n = {"url":"URL","addMedia":"Add Media","search":"Search","select":"Select","cancel":"Cancel","update":"Update","replace":"Replace","remove":"Remove","back":"Back","selected":"%d selected","dragInfo":"Drag and drop to reorder media files.","uploadFilesTitle":"Upload Files","uploadImagesTitle":"Upload Images","mediaLibraryTitle":"Media Library","insertMediaTitle":"Insert Media","createNewGallery":"Create a new gallery","createNewPlaylist":"Create a new playlist","createNewVideoPlaylist":"Create a new video playlist","returnToLibrary":"\u2190 Return to library","allMediaItems":"All media items","allDates":"All dates","noItemsFound":"No items found.","insertIntoPost":"Insert into post","unattached":"Unattached","trash":"Trash","uploadedToThisPost":"Uploaded to this post","warnDelete":"You are about to permanently delete this item.\nThis will remove it from your site.\n 'Cancel' to stop, 'OK' to delete.","warnBulkDelete":"You are about to permanently delete these items.\nThis will remove them from your site.\n 'Cancel' to stop, 'OK' to delete.","warnBulkTrash":"You are about to trash these items.\n  'Cancel' to stop, 'OK' to delete.","bulkSelect":"Bulk Select","cancelSelection":"Cancel Selection","trashSelected":"Trash Selected","untrashSelected":"Untrash Selected","deleteSelected":"Delete Selected","deletePermanently":"Delete Permanently","apply":"Apply","filterByDate":"Filter by date","filterByType":"Filter by type","searchMediaLabel":"Search Media","searchMediaPlaceholder":"Search media items...","noMedia":"No media files found.","attachmentDetails":"Attachment Details","insertFromUrlTitle":"Insert from URL","setFeaturedImageTitle":"Featured Image","setFeaturedImage":"Set featured image","createGalleryTitle":"Create Gallery","editGalleryTitle":"Edit Gallery","cancelGalleryTitle":"\u2190 Cancel Gallery","insertGallery":"Insert gallery","updateGallery":"Update gallery","addToGallery":"Add to gallery","addToGalleryTitle":"Add to Gallery","reverseOrder":"Reverse order","imageDetailsTitle":"Image Details","imageReplaceTitle":"Replace Image","imageDetailsCancel":"Cancel Edit","editImage":"Edit Image","chooseImage":"Choose Image","selectAndCrop":"Select and Crop","skipCropping":"Skip Cropping","cropImage":"Crop Image","cropYourImage":"Crop your image","cropping":"Cropping\u2026","suggestedDimensions":"Suggested image dimensions:","cropError":"There has been an error cropping your image.","audioDetailsTitle":"Audio Details","audioReplaceTitle":"Replace Audio","audioAddSourceTitle":"Add Audio Source","audioDetailsCancel":"Cancel Edit","videoDetailsTitle":"Video Details","videoReplaceTitle":"Replace Video","videoAddSourceTitle":"Add Video Source","videoDetailsCancel":"Cancel Edit","videoSelectPosterImageTitle":"Select Poster Image","videoAddTrackTitle":"Add Subtitles","playlistDragInfo":"Drag and drop to reorder tracks.","createPlaylistTitle":"Create Audio Playlist","editPlaylistTitle":"Edit Audio Playlist","cancelPlaylistTitle":"\u2190 Cancel Audio Playlist","insertPlaylist":"Insert audio playlist","updatePlaylist":"Update audio playlist","addToPlaylist":"Add to audio playlist","addToPlaylistTitle":"Add to Audio Playlist","videoPlaylistDragInfo":"Drag and drop to reorder videos.","createVideoPlaylistTitle":"Create Video Playlist","editVideoPlaylistTitle":"Edit Video Playlist","cancelVideoPlaylistTitle":"\u2190 Cancel Video Playlist","insertVideoPlaylist":"Insert video playlist","updateVideoPlaylist":"Update video playlist","addToVideoPlaylist":"Add to video playlist","addToVideoPlaylistTitle":"Add to Video Playlist","settings":{"tabs":[],"tabUrl":"http:\/\/src.wordpress-develop.dev\/wp-admin\/media-upload.php?chromeless=1","mimeTypes":{"image":"Images","audio":"Audio","video":"Video"},"captions":true,"nonce":{"sendToEditor":"9585d11de6"},"post":{"id":0},"defaultProps":{"link":"none","align":"","size":""},"attachmentCounts":{"audio":1,"video":1},"embedExts":["mp3","ogg","wma","m4a","wav","mp4","m4v","webm","ogv","wmv","flv"],"embedMimes":{"mp3":"audio\/mpeg","ogg":"audio\/ogg","wma":"audio\/x-ms-wma","m4a":"audio\/mpeg","wav":"audio\/wav","mp4":"video\/mp4","m4v":"video\/mp4","webm":"video\/webm","ogv":"video\/ogg","wmv":"video\/x-ms-wmv","flv":"video\/x-flv"},"contentWidth":525,"months":[{"year":"2017","month":"4","text":"April 2017"}],"mediaTrash":0}};
     49                </script>
     50                <script src="../../src/wp-includes/js/media-views.js"></script>
     51                <script src="../../src/wp-includes/js/media-editor.js"></script>
     52                <script src="../../src/wp-includes/js/media-audiovideo.js"></script>
     53                <script src="../../src/wp-includes/js/mce-view.js"></script>
    2754
    2855                <!-- QUnit -->
     
    6592                <script src="../../src/wp-admin/js/word-count.js"></script>
    6693
     94                <script src="../../src/wp-admin/js/widgets/media-widgets.js"></script>
     95                <script>
     96                        wp.mediaWidgets.init();
     97                </script>
     98                <script src="../../src/wp-admin/js/widgets/media-image-widget.js"></script>
     99                <script>
     100                        wp.mediaWidgets.modelConstructors[ "media_image" ].prototype.schema = {"attachment_id":{"type":"integer","default":0,"minimum":0,"media_prop":"id"},"url":{"type":"string","default":"","format":"uri"},"title":{"type":"string","default":"","should_preview_update":false},"size":{"type":"string","default":"medium","enum":["thumbnail","medium","medium_large","large","twentyseventeen-featured-image","twentyseventeen-thumbnail-avatar","full","custom"]},"width":{"type":"integer","default":0,"minimum":0},"height":{"type":"integer","default":0,"minimum":0},"caption":{"type":"string","default":"","should_preview_update":false},"alt":{"type":"string","default":""},"link_type":{"type":"string","default":"none","enum":["none","file","post","custom"],"media_prop":"link","should_preview_update":false},"link_url":{"type":"string","default":"","format":"uri","media_prop":"linkUrl","should_preview_update":false},"image_classes":{"type":"string","default":"","media_prop":"extraClasses","should_preview_update":false},"link_classes":{"type":"string","default":"","media_prop":"linkClassName","should_preview_update":false},"link_rel":{"type":"string","default":"","media_prop":"linkRel","should_preview_update":false},"link_target_blank":{"type":"boolean","default":false,"media_prop":"linkTargetBlank","should_preview_update":false},"image_title":{"type":"string","default":"","media_prop":"title","should_preview_update":false}};
     101
     102                        wp.mediaWidgets.controlConstructors[ "media_image" ].prototype.mime_type = "image";
     103                        _.extend( wp.mediaWidgets.controlConstructors[ "media_image" ].prototype.l10n, {"no_media_selected":"No image selected","select_media":"Select Image","change_media":"Change Image","edit_media":"Edit Image","add_to_widget":"Add to Widget","missing_attachment":"We can&#8217;t find that image. Check your <a href=\"http:\/\/src.wordpress-develop.dev\/wp-admin\/upload.php\">media library<\/a> and make sure it wasn&#8217;t deleted.","media_library_state_multi":{"0":"Image Widget (%d)","1":"Image Widget (%d)","singular":"Image Widget (%d)","plural":"Image Widget (%d)","context":null,"domain":null},"media_library_state_single":"Image Widget"} );
     104                </script>
     105                <script src="../../src/wp-admin/js/widgets/media-video-widget.js"></script>
     106                <script>
     107                        wp.mediaWidgets.modelConstructors[ "media_video" ].prototype.schema = {"attachment_id":{"type":"integer","default":0,"minimum":0,"media_prop":"id"},"url":{"type":"string","default":"","format":"uri"},"title":{"type":"string","default":""},"preload":{"type":"string","default":"metadata","enum":["none","auto","metadata"]},"loop":{"type":"boolean","default":false},"content":{"type":"string","default":""},"mp4":{"type":"string","default":"","format":"uri"},"m4v":{"type":"string","default":"","format":"uri"},"webm":{"type":"string","default":"","format":"uri"},"ogv":{"type":"string","default":"","format":"uri"},"wmv":{"type":"string","default":"","format":"uri"},"flv":{"type":"string","default":"","format":"uri"}};
     108
     109                        wp.mediaWidgets.controlConstructors[ "media_video" ].prototype.mime_type = "video";
     110                        _.extend( wp.mediaWidgets.controlConstructors[ "media_video" ].prototype.l10n, {"no_media_selected":"No video selected","select_media":"Select Video","change_media":"Change Video","edit_media":"Edit Video","add_to_widget":"Add to Widget","missing_attachment":"We can&#8217;t find that video. Check your <a href=\"http:\/\/src.wordpress-develop.dev\/wp-admin\/upload.php\">media library<\/a> and make sure it wasn&#8217;t deleted.","media_library_state_multi":{"0":"Video Widget (%d)","1":"Video Widget (%d)","singular":"Video Widget (%d)","plural":"Video Widget (%d)","context":null,"domain":null},"media_library_state_single":"Video Widget"} );
     111                </script>
     112                <script src="../../src/wp-admin/js/widgets/media-audio-widget.js"></script>
     113                <script>
     114                        wp.mediaWidgets.modelConstructors[ "media_audio" ].prototype.schema = {"attachment_id":{"type":"integer","default":0,"minimum":0,"media_prop":"id"},"url":{"type":"string","default":"","format":"uri"},"title":{"type":"string","default":""},"preload":{"type":"string","default":"none","enum":["none","auto","metadata"]},"loop":{"type":"boolean","default":false},"mp3":{"type":"string","default":"","format":"uri"},"ogg":{"type":"string","default":"","format":"uri"},"wma":{"type":"string","default":"","format":"uri"},"m4a":{"type":"string","default":"","format":"uri"},"wav":{"type":"string","default":"","format":"uri"}};
     115
     116                        wp.mediaWidgets.controlConstructors[ "media_audio" ].prototype.mime_type = "audio";
     117                        _.extend( wp.mediaWidgets.controlConstructors[ "media_audio" ].prototype.l10n, {"no_media_selected":"No audio selected","select_media":"Select File","change_media":"Change Audio","edit_media":"Edit Audio","add_to_widget":"Add to Widget","missing_attachment":"We can&#8217;t find that audio file. Check your <a href=\"http:\/\/src.wordpress-develop.dev\/wp-admin\/upload.php\">media library<\/a> and make sure it wasn&#8217;t deleted.","media_library_state_multi":{"0":"Audio Widget (%d)","1":"Audio Widget (%d)","singular":"Audio Widget (%d)","plural":"Audio Widget (%d)","context":null,"domain":null},"media_library_state_single":"Audio Widget"} );
     118                </script>
     119
    67120                <!-- Unit tests -->
    68121                <script src="wp-admin/js/password-strength-meter.js"></script>
     
    77130                <script src="wp-admin/js/word-count.js"></script>
    78131                <script src="wp-admin/js/nav-menu.js"></script>
     132                <script src="wp-admin/js/widgets/test-media-widgets.js"></script>
     133                <script src="wp-admin/js/widgets/test-media-image-widget.js"></script>
     134                <script src="wp-admin/js/widgets/test-media-video-widget.js"></script>
    79135
    80136                <!-- Customizer templates for sections -->
     
    500556                                </div><!-- #available-widgets -->
    501557                        </div><!-- #widgets-left -->
     558                       
     559                        <script type="text/html" id="tmpl-widget-media-media_image-control">
     560                        <# var elementIdPrefix = 'el' + String( Math.random() ) + '_' #>
     561                        <p>
     562                                <label for="{{ elementIdPrefix }}title">Title:</label>
     563                                <input id="{{ elementIdPrefix }}title" type="text" class="widefat title">
     564                        </p>
     565                        <div class="media-widget-preview">
     566                                <div class="attachment-media-view">
     567                                        <div class="placeholder">No image selected</div>
     568                                </div>
     569                        </div>
     570                        <p class="media-widget-buttons">
     571                                <button type="button" class="button edit-media selected">
     572                                        Edit Image                              </button>
     573                                <button type="button" class="button change-media select-media selected">
     574                                        Replace Image                           </button>
     575                                <button type="button" class="button select-media not-selected">
     576                                        Add Image                               </button>
     577                        </p>
     578                </script>
     579                                <script type="text/html" id="tmpl-wp-media-widget-image-preview">
     580                        <#
     581                        var describedById = 'describedBy-' + String( Math.random() );
     582                        #>
     583                        <# if ( data.error && 'missing_attachment' === data.error ) { #>
     584                                <div class="notice notice-error notice-alt notice-missing-attachment">
     585                                        <p>We can&#8217;t find that image. Check your <a href="http://src.wordpress-develop.dev/wp-admin/upload.php">media library</a> and make sure it wasn&#8217;t deleted.</p>
     586                                </div>
     587                        <# } else if ( data.error ) { #>
     588                                <div class="notice notice-error notice-alt">
     589                                        <p>Unable to preview media due to an unknown error.</p>
     590                                </div>
     591                        <# } else if ( data.url ) { #>
     592                                <img class="attachment-thumb" src="{{ data.url }}" draggable="false" alt="{{ data.alt }}" <# if ( ! data.alt && data.currentFilename ) { #> aria-describedby="{{ describedById }}" <# } #> />
     593                                <# if ( ! data.alt && data.currentFilename ) { #>
     594                                        <p class="hidden" id="{{ describedById }}">Current image: {{ data.currentFilename }}</p>
     595                                <# } #>
     596                        <# } #>
     597                </script>
     598                                <script type="text/html" id="tmpl-widget-media-media_video-control">
     599                        <# var elementIdPrefix = 'el' + String( Math.random() ) + '_' #>
     600                        <p>
     601                                <label for="{{ elementIdPrefix }}title">Title:</label>
     602                                <input id="{{ elementIdPrefix }}title" type="text" class="widefat title">
     603                        </p>
     604                        <div class="media-widget-preview">
     605                                <div class="attachment-media-view">
     606                                        <div class="placeholder">No video selected</div>
     607                                </div>
     608                        </div>
     609                        <p class="media-widget-buttons">
     610                                <button type="button" class="button edit-media selected">
     611                                        Edit Video                              </button>
     612                                <button type="button" class="button change-media select-media selected">
     613                                        Replace Video                           </button>
     614                                <button type="button" class="button select-media not-selected">
     615                                        Add Video                               </button>
     616                        </p>
     617                </script>
     618                                <script type="text/html" id="tmpl-wp-media-widget-video-preview">
     619                        <# if ( data.error && 'missing_attachment' === data.error ) { #>
     620                                <div class="notice notice-error notice-alt notice-missing-attachment">
     621                                        <p>We can&#8217;t find that video. Check your <a href="http://src.wordpress-develop.dev/wp-admin/upload.php">media library</a> and make sure it wasn&#8217;t deleted.</p>
     622                                </div>
     623                        <# } else if ( data.error && 'unsupported_file_type' === data.error ) { #>
     624                                <div class="notice notice-error notice-alt notice-missing-attachment">
     625                                        <p>Sorry, we can&#8217;t display the video file type selected. Please select a supported video file (<code>.mp4</code>, <code>.m4v</code>, <code>.webm</code>, <code>.ogv</code>, <code>.wmv</code>, <code>.flv</code>) or stream (YouTube or Vimeo) instead.</p>
     626                                </div>
     627                        <# } else if ( data.error ) { #>
     628                                <div class="notice notice-error notice-alt">
     629                                        <p>Unable to preview media due to an unknown error.</p>
     630                                </div>
     631                        <# } else if ( data.is_hosted_embed && data.model.poster ) { #>
     632                                <a href="{{ data.model.src }}" target="_blank" class="media-widget-video-link">
     633                                        <img src="{{ data.model.poster }}" />
     634                                </a>
     635                        <# } else if ( data.is_hosted_embed ) { #>
     636                                <a href="{{ data.model.src }}" target="_blank" class="media-widget-video-link no-poster">
     637                                        <span class="dashicons dashicons-format-video"></span>
     638                                </a>
     639                        <# } else if ( data.model.src ) { #>
     640                                <#  var w_rule = '', classes = [],
     641                w, h, settings = wp.media.view.settings,
     642                isYouTube = isVimeo = false;
     643
     644        if ( ! _.isEmpty( data.model.src ) ) {
     645                isYouTube = data.model.src.match(/youtube|youtu\.be/);
     646                isVimeo = -1 !== data.model.src.indexOf('vimeo');
     647        }
     648
     649        if ( settings.contentWidth && data.model.width >= settings.contentWidth ) {
     650                w = settings.contentWidth;
     651        } else {
     652                w = data.model.width;
     653        }
     654
     655        if ( w !== data.model.width ) {
     656                h = Math.ceil( ( data.model.height * w ) / data.model.width );
     657        } else {
     658                h = data.model.height;
     659        }
     660
     661        if ( w ) {
     662                w_rule = 'width: ' + w + 'px; ';
     663        }
     664
     665        if ( isYouTube ) {
     666                classes.push( 'youtube-video' );
     667        }
     668
     669        if ( isVimeo ) {
     670                classes.push( 'vimeo-video' );
     671        }
     672
     673#>
     674<div style="{{ w_rule }}" class="wp-video">
     675<video controls
     676        class="wp-video-shortcode {{ classes.join( ' ' ) }}"
     677        <# if ( w ) { #>width="{{ w }}"<# } #>
     678        <# if ( h ) { #>height="{{ h }}"<# } #>
     679        <#
     680                if ( ! _.isUndefined( data.model.poster ) && data.model.poster ) {
     681                        #> poster="{{ data.model.poster }}"<#
     682                } #>
     683                preload="{{ _.isUndefined( data.model.preload ) ? 'metadata' : data.model.preload }}"<#
     684         if ( ! _.isUndefined( data.model.autoplay ) && data.model.autoplay ) {
     685                #> autoplay<#
     686        }
     687         if ( ! _.isUndefined( data.model.loop ) && data.model.loop ) {
     688                #> loop<#
     689        }
     690        #>
     691>
     692        <# if ( ! _.isEmpty( data.model.src ) ) {
     693                if ( isYouTube ) { #>
     694                <source src="{{ data.model.src }}" type="video/youtube" />
     695                <# } else if ( isVimeo ) { #>
     696                <source src="{{ data.model.src }}" type="video/vimeo" />
     697                <# } else { #>
     698                <source src="{{ data.model.src }}" type="{{ settings.embedMimes[ data.model.src.split('.').pop() ] }}" />
     699                <# }
     700        } #>
     701
     702        <# if ( data.model.mp4 ) { #>
     703        <source src="{{ data.model.mp4 }}" type="{{ settings.embedMimes[ 'mp4' ] }}" />
     704        <# } #>
     705        <# if ( data.model.m4v ) { #>
     706        <source src="{{ data.model.m4v }}" type="{{ settings.embedMimes[ 'm4v' ] }}" />
     707        <# } #>
     708        <# if ( data.model.webm ) { #>
     709        <source src="{{ data.model.webm }}" type="{{ settings.embedMimes[ 'webm' ] }}" />
     710        <# } #>
     711        <# if ( data.model.ogv ) { #>
     712        <source src="{{ data.model.ogv }}" type="{{ settings.embedMimes[ 'ogv' ] }}" />
     713        <# } #>
     714        <# if ( data.model.wmv ) { #>
     715        <source src="{{ data.model.wmv }}" type="{{ settings.embedMimes[ 'wmv' ] }}" />
     716        <# } #>
     717        <# if ( data.model.flv ) { #>
     718        <source src="{{ data.model.flv }}" type="{{ settings.embedMimes[ 'flv' ] }}" />
     719        <# } #>
     720                {{{ data.model.content }}}
     721</video>
     722</div>
     723                        <# } #>
     724                </script>
     725                        <script type="text/html" id="tmpl-widget-media-media_audio-control">
     726                                <# var elementIdPrefix = 'el' + String( Math.random() ) + '_' #>
     727                                <p>
     728                                        <label for="{{ elementIdPrefix }}title">Title:</label>
     729                                        <input id="{{ elementIdPrefix }}title" type="text" class="widefat title">
     730                                </p>
     731                                <div class="media-widget-preview">
     732                                        <div class="attachment-media-view">
     733                                                <div class="placeholder">No audio selected</div>
     734                                        </div>
     735                                </div>
     736                                <p class="media-widget-buttons">
     737                                        <button type="button" class="button edit-media selected">
     738                                                Edit Audio                              </button>
     739                                        <button type="button" class="button change-media select-media selected">
     740                                                Replace Audio                           </button>
     741                                        <button type="button" class="button select-media not-selected">
     742                                                Add File                                </button>
     743                                </p>
     744                        </script>
     745                        <script type="text/html" id="tmpl-wp-media-widget-audio-preview">
     746                                <# if ( data.error && 'missing_attachment' === data.error ) { #>
     747                                        <div class="notice notice-error notice-alt notice-missing-attachment">
     748                                                <p>We can&#8217;t find that audio file. Check your <a href="http://src.wordpress-develop.dev/wp-admin/upload.php">media library</a> and make sure it wasn&#8217;t deleted.</p>
     749                                        </div>
     750                                <# } else if ( data.error ) { #>
     751                                        <div class="notice notice-error notice-alt">
     752                                                <p>Unable to preview media due to an unknown error.</p>
     753                                        </div>
     754                                <# } else if ( data.model && data.model.src ) { #>
     755                                        <audio style="visibility: hidden"
     756                                                controls
     757                                                class="wp-audio-shortcode"
     758                                                width="{{ _.isUndefined( data.model.width ) ? 400 : data.model.width }}"
     759                                                preload="{{ _.isUndefined( data.model.preload ) ? 'none' : data.model.preload }}"
     760                                                <#
     761                                                if ( ! _.isUndefined( data.model.autoplay ) && data.model.autoplay ) {
     762                                                        #> autoplay<#
     763                                                }
     764                                                if ( ! _.isUndefined( data.model.loop ) && data.model.loop ) {
     765                                                        #> loop<#
     766                                                }
     767                                                #>
     768                                        >
     769                                        <# if ( ! _.isEmpty( data.model.src ) ) { #>
     770                                                <source src="{{ data.model.src }}" type="{{ wp.media.view.settings.embedMimes[ data.model.src.split('.').pop() ] }}" />
     771                                        <# } #>
     772
     773                                        <# if ( ! _.isEmpty( data.model.mp3 ) ) { #>
     774                                                <source src="{{ data.model.mp3 }}" type="{{ wp.media.view.settings.embedMimes[ 'mp3' ] }}" />
     775                                        <# } #>
     776                                        <# if ( ! _.isEmpty( data.model.ogg ) ) { #>
     777                                                <source src="{{ data.model.ogg }}" type="{{ wp.media.view.settings.embedMimes[ 'ogg' ] }}" />
     778                                        <# } #>
     779                                        <# if ( ! _.isEmpty( data.model.wma ) ) { #>
     780                                                <source src="{{ data.model.wma }}" type="{{ wp.media.view.settings.embedMimes[ 'wma' ] }}" />
     781                                        <# } #>
     782                                        <# if ( ! _.isEmpty( data.model.m4a ) ) { #>
     783                                                <source src="{{ data.model.m4a }}" type="{{ wp.media.view.settings.embedMimes[ 'm4a' ] }}" />
     784                                        <# } #>
     785                                        <# if ( ! _.isEmpty( data.model.wav ) ) { #>
     786                                                <source src="{{ data.model.wav }}" type="{{ wp.media.view.settings.embedMimes[ 'wav' ] }}" />
     787                                        <# } #>
     788                                        </audio>
     789                                <# } #>
     790                        </script>
     791                        <script type="text/html" id="tmpl-media-frame">
     792                <div class="media-frame-menu"></div>
     793                <div class="media-frame-title"></div>
     794                <div class="media-frame-router"></div>
     795                <div class="media-frame-content"></div>
     796                <div class="media-frame-toolbar"></div>
     797                <div class="media-frame-uploader"></div>
     798        </script>
     799
     800        <script type="text/html" id="tmpl-media-modal">
     801                <div class="media-modal wp-core-ui">
     802                        <button type="button" class="media-modal-close"><span class="media-modal-icon"><span class="screen-reader-text">Close media panel</span></span></button>
     803                        <div class="media-modal-content"></div>
     804                </div>
     805                <div class="media-modal-backdrop"></div>
     806        </script>
     807
     808        <script type="text/html" id="tmpl-uploader-window">
     809                <div class="uploader-window-content">
     810                        <h1>Drop files to upload</h1>
     811                </div>
     812        </script>
     813
     814        <script type="text/html" id="tmpl-uploader-editor">
     815                <div class="uploader-editor-content">
     816                        <div class="uploader-editor-title">Drop files to upload</div>
     817                </div>
     818        </script>
     819
     820        <script type="text/html" id="tmpl-uploader-inline">
     821                <# var messageClass = data.message ? 'has-upload-message' : 'no-upload-message'; #>
     822                <# if ( data.canClose ) { #>
     823                <button class="close dashicons dashicons-no"><span class="screen-reader-text">Close uploader</span></button>
     824                <# } #>
     825                <div class="uploader-inline-content {{ messageClass }}">
     826                <# if ( data.message ) { #>
     827                        <h2 class="upload-message">{{ data.message }}</h2>
     828                <# } #>
     829                                        <div class="upload-ui">
     830                                <h2 class="upload-instructions drop-instructions">Drop files anywhere to upload</h2>
     831                                <p class="upload-instructions drop-instructions">or</p>
     832                                <button type="button" class="browser button button-hero">Select Files</button>
     833                        </div>
     834
     835                        <div class="upload-inline-status"></div>
     836
     837                        <div class="post-upload-ui">
     838
     839                                <p class="max-upload-size">Maximum upload file size: 2 MB.</p>
     840
     841                                <# if ( data.suggestedWidth && data.suggestedHeight ) { #>
     842                                        <p class="suggested-dimensions">
     843                                                Suggested image dimensions: {{data.suggestedWidth}} &times; {{data.suggestedHeight}}
     844                                        </p>
     845                                <# } #>
     846
     847                                                        </div>
     848                                </div>
     849        </script>
     850
     851        <script type="text/html" id="tmpl-media-library-view-switcher">
     852                <a href="?mode=list" class="view-list">
     853                        <span class="screen-reader-text">List View</span>
     854                </a>
     855                <a href="?mode=grid" class="view-grid current">
     856                        <span class="screen-reader-text">Grid View</span>
     857                </a>
     858        </script>
     859
     860        <script type="text/html" id="tmpl-uploader-status">
     861                <h2>Uploading</h2>
     862                <button type="button" class="button-link upload-dismiss-errors"><span class="screen-reader-text">Dismiss Errors</span></button>
     863
     864                <div class="media-progress-bar"><div></div></div>
     865                <div class="upload-details">
     866                        <span class="upload-count">
     867                                <span class="upload-index"></span> / <span class="upload-total"></span>
     868                        </span>
     869                        <span class="upload-detail-separator">&ndash;</span>
     870                        <span class="upload-filename"></span>
     871                </div>
     872                <div class="upload-errors"></div>
     873        </script>
     874
     875        <script type="text/html" id="tmpl-uploader-status-error">
     876                <span class="upload-error-filename">{{{ data.filename }}}</span>
     877                <span class="upload-error-message">{{ data.message }}</span>
     878        </script>
     879
     880        <script type="text/html" id="tmpl-edit-attachment-frame">
     881                <div class="edit-media-header">
     882                        <button class="left dashicons <# if ( ! data.hasPrevious ) { #> disabled <# } #>"><span class="screen-reader-text">Edit previous media item</span></button>
     883                        <button class="right dashicons <# if ( ! data.hasNext ) { #> disabled <# } #>"><span class="screen-reader-text">Edit next media item</span></button>
     884                </div>
     885                <div class="media-frame-title"></div>
     886                <div class="media-frame-content"></div>
     887        </script>
     888
     889        <script type="text/html" id="tmpl-attachment-details-two-column">
     890                <div class="attachment-media-view {{ data.orientation }}">
     891                        <div class="thumbnail thumbnail-{{ data.type }}">
     892                                <# if ( data.uploading ) { #>
     893                                        <div class="media-progress-bar"><div></div></div>
     894                                <# } else if ( data.sizes && data.sizes.large ) { #>
     895                                        <img class="details-image" src="{{ data.sizes.large.url }}" draggable="false" alt="" />
     896                                <# } else if ( data.sizes && data.sizes.full ) { #>
     897                                        <img class="details-image" src="{{ data.sizes.full.url }}" draggable="false" alt="" />
     898                                <# } else if ( -1 === jQuery.inArray( data.type, [ 'audio', 'video' ] ) ) { #>
     899                                        <img class="details-image icon" src="{{ data.icon }}" draggable="false" alt="" />
     900                                <# } #>
     901
     902                                <# if ( 'audio' === data.type ) { #>
     903                                <div class="wp-media-wrapper">
     904                                        <audio style="visibility: hidden" controls class="wp-audio-shortcode" width="100%" preload="none">
     905                                                <source type="{{ data.mime }}" src="{{ data.url }}"/>
     906                                        </audio>
     907                                </div>
     908                                <# } else if ( 'video' === data.type ) {
     909                                        var w_rule = '';
     910                                        if ( data.width ) {
     911                                                w_rule = 'width: ' + data.width + 'px;';
     912                                        } else if ( wp.media.view.settings.contentWidth ) {
     913                                                w_rule = 'width: ' + wp.media.view.settings.contentWidth + 'px;';
     914                                        }
     915                                #>
     916                                <div style="{{ w_rule }}" class="wp-media-wrapper wp-video">
     917                                        <video controls="controls" class="wp-video-shortcode" preload="metadata"
     918                                                <# if ( data.width ) { #>width="{{ data.width }}"<# } #>
     919                                                <# if ( data.height ) { #>height="{{ data.height }}"<# } #>
     920                                                <# if ( data.image && data.image.src !== data.icon ) { #>poster="{{ data.image.src }}"<# } #>>
     921                                                <source type="{{ data.mime }}" src="{{ data.url }}"/>
     922                                        </video>
     923                                </div>
     924                                <# } #>
     925
     926                                <div class="attachment-actions">
     927                                        <# if ( 'image' === data.type && ! data.uploading && data.sizes && data.can.save ) { #>
     928                                        <button type="button" class="button edit-attachment">Edit Image</button>
     929                                        <# } else if ( 'pdf' === data.subtype && data.sizes ) { #>
     930                                        Document Preview                                        <# } #>
     931                                </div>
     932                        </div>
     933                </div>
     934                <div class="attachment-info">
     935                        <span class="settings-save-status">
     936                                <span class="spinner"></span>
     937                                <span class="saved">Saved.</span>
     938                        </span>
     939                        <div class="details">
     940                                <div class="filename"><strong>File name:</strong> {{ data.filename }}</div>
     941                                <div class="filename"><strong>File type:</strong> {{ data.mime }}</div>
     942                                <div class="uploaded"><strong>Uploaded on:</strong> {{ data.dateFormatted }}</div>
     943
     944                                <div class="file-size"><strong>File size:</strong> {{ data.filesizeHumanReadable }}</div>
     945                                <# if ( 'image' === data.type && ! data.uploading ) { #>
     946                                        <# if ( data.width && data.height ) { #>
     947                                                <div class="dimensions"><strong>Dimensions:</strong> {{ data.width }} &times; {{ data.height }}</div>
     948                                        <# } #>
     949                                <# } #>
     950
     951                                <# if ( data.fileLength ) { #>
     952                                        <div class="file-length"><strong>Length:</strong> {{ data.fileLength }}</div>
     953                                <# } #>
     954
     955                                <# if ( 'audio' === data.type && data.meta.bitrate ) { #>
     956                                        <div class="bitrate">
     957                                                <strong>Bitrate:</strong> {{ Math.round( data.meta.bitrate / 1000 ) }}kb/s
     958                                                <# if ( data.meta.bitrate_mode ) { #>
     959                                                {{ ' ' + data.meta.bitrate_mode.toUpperCase() }}
     960                                                <# } #>
     961                                        </div>
     962                                <# } #>
     963
     964                                <div class="compat-meta">
     965                                        <# if ( data.compat && data.compat.meta ) { #>
     966                                                {{{ data.compat.meta }}}
     967                                        <# } #>
     968                                </div>
     969                        </div>
     970
     971                        <div class="settings">
     972                                <label class="setting" data-setting="url">
     973                                        <span class="name">URL</span>
     974                                        <input type="text" value="{{ data.url }}" readonly />
     975                                </label>
     976                                <# var maybeReadOnly = data.can.save || data.allowLocalEdits ? '' : 'readonly'; #>
     977                                                                <label class="setting" data-setting="title">
     978                                        <span class="name">Title</span>
     979                                        <input type="text" value="{{ data.title }}" {{ maybeReadOnly }} />
     980                                </label>
     981                                                                <# if ( 'audio' === data.type ) { #>
     982                                                                <label class="setting" data-setting="artist">
     983                                        <span class="name">Artist</span>
     984                                        <input type="text" value="{{ data.artist || data.meta.artist || '' }}" />
     985                                </label>
     986                                                                <label class="setting" data-setting="album">
     987                                        <span class="name">Album</span>
     988                                        <input type="text" value="{{ data.album || data.meta.album || '' }}" />
     989                                </label>
     990                                                                <# } #>
     991                                <label class="setting" data-setting="caption">
     992                                        <span class="name">Caption</span>
     993                                        <textarea {{ maybeReadOnly }}>{{ data.caption }}</textarea>
     994                                </label>
     995                                <# if ( 'image' === data.type ) { #>
     996                                        <label class="setting" data-setting="alt">
     997                                                <span class="name">Alt Text</span>
     998                                                <input type="text" value="{{ data.alt }}" {{ maybeReadOnly }} />
     999                                        </label>
     1000                                <# } #>
     1001                                <label class="setting" data-setting="description">
     1002                                        <span class="name">Description</span>
     1003                                        <textarea {{ maybeReadOnly }}>{{ data.description }}</textarea>
     1004                                </label>
     1005                                <label class="setting">
     1006                                        <span class="name">Uploaded By</span>
     1007                                        <span class="value">{{ data.authorName }}</span>
     1008                                </label>
     1009                                <# if ( data.uploadedToTitle ) { #>
     1010                                        <label class="setting">
     1011                                                <span class="name">Uploaded To</span>
     1012                                                <# if ( data.uploadedToLink ) { #>
     1013                                                        <span class="value"><a href="{{ data.uploadedToLink }}">{{ data.uploadedToTitle }}</a></span>
     1014                                                <# } else { #>
     1015                                                        <span class="value">{{ data.uploadedToTitle }}</span>
     1016                                                <# } #>
     1017                                        </label>
     1018                                <# } #>
     1019                                <div class="attachment-compat"></div>
     1020                        </div>
     1021
     1022                        <div class="actions">
     1023                                <a class="view-attachment" href="{{ data.link }}">View attachment page</a>
     1024                                <# if ( data.can.save ) { #> |
     1025                                        <a href="post.php?post={{ data.id }}&action=edit">Edit more details</a>
     1026                                <# } #>
     1027                                <# if ( ! data.uploading && data.can.remove ) { #> |
     1028                                                                                        <button type="button" class="button-link delete-attachment">Delete Permanently</button>
     1029                                                                        <# } #>
     1030                        </div>
     1031
     1032                </div>
     1033        </script>
     1034
     1035        <script type="text/html" id="tmpl-attachment">
     1036                <div class="attachment-preview js--select-attachment type-{{ data.type }} subtype-{{ data.subtype }} {{ data.orientation }}">
     1037                        <div class="thumbnail">
     1038                                <# if ( data.uploading ) { #>
     1039                                        <div class="media-progress-bar"><div style="width: {{ data.percent }}%"></div></div>
     1040                                <# } else if ( 'image' === data.type && data.sizes ) { #>
     1041                                        <div class="centered">
     1042                                                <img src="{{ data.size.url }}" draggable="false" alt="" />
     1043                                        </div>
     1044                                <# } else { #>
     1045                                        <div class="centered">
     1046                                                <# if ( data.image && data.image.src && data.image.src !== data.icon ) { #>
     1047                                                        <img src="{{ data.image.src }}" class="thumbnail" draggable="false" alt="" />
     1048                                                <# } else if ( data.sizes && data.sizes.medium ) { #>
     1049                                                        <img src="{{ data.sizes.medium.url }}" class="thumbnail" draggable="false" alt="" />
     1050                                                <# } else { #>
     1051                                                        <img src="{{ data.icon }}" class="icon" draggable="false" alt="" />
     1052                                                <# } #>
     1053                                        </div>
     1054                                        <div class="filename">
     1055                                                <div>{{ data.filename }}</div>
     1056                                        </div>
     1057                                <# } #>
     1058                        </div>
     1059                        <# if ( data.buttons.close ) { #>
     1060                                <button type="button" class="button-link attachment-close media-modal-icon"><span class="screen-reader-text">Remove</span></button>
     1061                        <# } #>
     1062                </div>
     1063                <# if ( data.buttons.check ) { #>
     1064                        <button type="button" class="check" tabindex="-1"><span class="media-modal-icon"></span><span class="screen-reader-text">Deselect</span></button>
     1065                <# } #>
     1066                <#
     1067                var maybeReadOnly = data.can.save || data.allowLocalEdits ? '' : 'readonly';
     1068                if ( data.describe ) {
     1069                        if ( 'image' === data.type ) { #>
     1070                                <input type="text" value="{{ data.caption }}" class="describe" data-setting="caption"
     1071                                        placeholder="Caption this image&hellip;" {{ maybeReadOnly }} />
     1072                        <# } else { #>
     1073                                <input type="text" value="{{ data.title }}" class="describe" data-setting="title"
     1074                                        <# if ( 'video' === data.type ) { #>
     1075                                                placeholder="Describe this video&hellip;"
     1076                                        <# } else if ( 'audio' === data.type ) { #>
     1077                                                placeholder="Describe this audio file&hellip;"
     1078                                        <# } else { #>
     1079                                                placeholder="Describe this media file&hellip;"
     1080                                        <# } #> {{ maybeReadOnly }} />
     1081                        <# }
     1082                } #>
     1083        </script>
     1084
     1085        <script type="text/html" id="tmpl-attachment-details">
     1086                <h2>
     1087                        Attachment Details                      <span class="settings-save-status">
     1088                                <span class="spinner"></span>
     1089                                <span class="saved">Saved.</span>
     1090                        </span>
     1091                </h2>
     1092                <div class="attachment-info">
     1093                        <div class="thumbnail thumbnail-{{ data.type }}">
     1094                                <# if ( data.uploading ) { #>
     1095                                        <div class="media-progress-bar"><div></div></div>
     1096                                <# } else if ( 'image' === data.type && data.sizes ) { #>
     1097                                        <img src="{{ data.size.url }}" draggable="false" alt="" />
     1098                                <# } else { #>
     1099                                        <img src="{{ data.icon }}" class="icon" draggable="false" alt="" />
     1100                                <# } #>
     1101                        </div>
     1102                        <div class="details">
     1103                                <div class="filename">{{ data.filename }}</div>
     1104                                <div class="uploaded">{{ data.dateFormatted }}</div>
     1105
     1106                                <div class="file-size">{{ data.filesizeHumanReadable }}</div>
     1107                                <# if ( 'image' === data.type && ! data.uploading ) { #>
     1108                                        <# if ( data.width && data.height ) { #>
     1109                                                <div class="dimensions">{{ data.width }} &times; {{ data.height }}</div>
     1110                                        <# } #>
     1111
     1112                                        <# if ( data.can.save && data.sizes ) { #>
     1113                                                <a class="edit-attachment" href="{{ data.editLink }}&amp;image-editor" target="_blank">Edit Image</a>
     1114                                        <# } #>
     1115                                <# } #>
     1116
     1117                                <# if ( data.fileLength ) { #>
     1118                                        <div class="file-length">Length: {{ data.fileLength }}</div>
     1119                                <# } #>
     1120
     1121                                <# if ( ! data.uploading && data.can.remove ) { #>
     1122                                                                                        <button type="button" class="button-link delete-attachment">Delete Permanently</button>
     1123                                                                        <# } #>
     1124
     1125                                <div class="compat-meta">
     1126                                        <# if ( data.compat && data.compat.meta ) { #>
     1127                                                {{{ data.compat.meta }}}
     1128                                        <# } #>
     1129                                </div>
     1130                        </div>
     1131                </div>
     1132
     1133                <label class="setting" data-setting="url">
     1134                        <span class="name">URL</span>
     1135                        <input type="text" value="{{ data.url }}" readonly />
     1136                </label>
     1137                <# var maybeReadOnly = data.can.save || data.allowLocalEdits ? '' : 'readonly'; #>
     1138                                <label class="setting" data-setting="title">
     1139                        <span class="name">Title</span>
     1140                        <input type="text" value="{{ data.title }}" {{ maybeReadOnly }} />
     1141                </label>
     1142                                <# if ( 'audio' === data.type ) { #>
     1143                                <label class="setting" data-setting="artist">
     1144                        <span class="name">Artist</span>
     1145                        <input type="text" value="{{ data.artist || data.meta.artist || '' }}" />
     1146                </label>
     1147                                <label class="setting" data-setting="album">
     1148                        <span class="name">Album</span>
     1149                        <input type="text" value="{{ data.album || data.meta.album || '' }}" />
     1150                </label>
     1151                                <# } #>
     1152                <label class="setting" data-setting="caption">
     1153                        <span class="name">Caption</span>
     1154                        <textarea {{ maybeReadOnly }}>{{ data.caption }}</textarea>
     1155                </label>
     1156                <# if ( 'image' === data.type ) { #>
     1157                        <label class="setting" data-setting="alt">
     1158                                <span class="name">Alt Text</span>
     1159                                <input type="text" value="{{ data.alt }}" {{ maybeReadOnly }} />
     1160                        </label>
     1161                <# } #>
     1162                <label class="setting" data-setting="description">
     1163                        <span class="name">Description</span>
     1164                        <textarea {{ maybeReadOnly }}>{{ data.description }}</textarea>
     1165                </label>
     1166        </script>
     1167
     1168        <script type="text/html" id="tmpl-media-selection">
     1169                <div class="selection-info">
     1170                        <span class="count"></span>
     1171                        <# if ( data.editable ) { #>
     1172                                <button type="button" class="button-link edit-selection">Edit Selection</button>
     1173                        <# } #>
     1174                        <# if ( data.clearable ) { #>
     1175                                <button type="button" class="button-link clear-selection">Clear</button>
     1176                        <# } #>
     1177                </div>
     1178                <div class="selection-view"></div>
     1179        </script>
     1180
     1181        <script type="text/html" id="tmpl-attachment-display-settings">
     1182                <h2>Attachment Display Settings</h2>
     1183
     1184                <# if ( 'image' === data.type ) { #>
     1185                        <label class="setting">
     1186                                <span>Alignment</span>
     1187                                <select class="alignment"
     1188                                        data-setting="align"
     1189                                        <# if ( data.userSettings ) { #>
     1190                                                data-user-setting="align"
     1191                                        <# } #>>
     1192
     1193                                        <option value="left">
     1194                                                Left                                    </option>
     1195                                        <option value="center">
     1196                                                Center                                  </option>
     1197                                        <option value="right">
     1198                                                Right                                   </option>
     1199                                        <option value="none" selected>
     1200                                                None                                    </option>
     1201                                </select>
     1202                        </label>
     1203                <# } #>
     1204
     1205                <div class="setting">
     1206                        <label>
     1207                                <# if ( data.model.canEmbed ) { #>
     1208                                        <span>Embed or Link</span>
     1209                                <# } else { #>
     1210                                        <span>Link To</span>
     1211                                <# } #>
     1212
     1213                                <select class="link-to"
     1214                                        data-setting="link"
     1215                                        <# if ( data.userSettings && ! data.model.canEmbed ) { #>
     1216                                                data-user-setting="urlbutton"
     1217                                        <# } #>>
     1218
     1219                                <# if ( data.model.canEmbed ) { #>
     1220                                        <option value="embed" selected>
     1221                                                Embed Media Player                                      </option>
     1222                                        <option value="file">
     1223                                <# } else { #>
     1224                                        <option value="none" selected>
     1225                                                None                                    </option>
     1226                                        <option value="file">
     1227                                <# } #>
     1228                                        <# if ( data.model.canEmbed ) { #>
     1229                                                Link to Media File                                      <# } else { #>
     1230                                                Media File                                      <# } #>
     1231                                        </option>
     1232                                        <option value="post">
     1233                                        <# if ( data.model.canEmbed ) { #>
     1234                                                Link to Attachment Page                                 <# } else { #>
     1235                                                Attachment Page                                 <# } #>
     1236                                        </option>
     1237                                <# if ( 'image' === data.type ) { #>
     1238                                        <option value="custom">
     1239                                                Custom URL                                      </option>
     1240                                <# } #>
     1241                                </select>
     1242                        </label>
     1243                        <input type="text" class="link-to-custom" data-setting="linkUrl" />
     1244                </div>
     1245
     1246                <# if ( 'undefined' !== typeof data.sizes ) { #>
     1247                        <label class="setting">
     1248                                <span>Size</span>
     1249                                <select class="size" name="size"
     1250                                        data-setting="size"
     1251                                        <# if ( data.userSettings ) { #>
     1252                                                data-user-setting="imgsize"
     1253                                        <# } #>>
     1254                                                                                        <#
     1255                                                var size = data.sizes['thumbnail'];
     1256                                                if ( size ) { #>
     1257                                                        <option value="thumbnail" >
     1258                                                                Thumbnail &ndash; {{ size.width }} &times; {{ size.height }}
     1259                                                        </option>
     1260                                                <# } #>
     1261                                                                                        <#
     1262                                                var size = data.sizes['medium'];
     1263                                                if ( size ) { #>
     1264                                                        <option value="medium" >
     1265                                                                Medium &ndash; {{ size.width }} &times; {{ size.height }}
     1266                                                        </option>
     1267                                                <# } #>
     1268                                                                                        <#
     1269                                                var size = data.sizes['large'];
     1270                                                if ( size ) { #>
     1271                                                        <option value="large" >
     1272                                                                Large &ndash; {{ size.width }} &times; {{ size.height }}
     1273                                                        </option>
     1274                                                <# } #>
     1275                                                                                        <#
     1276                                                var size = data.sizes['full'];
     1277                                                if ( size ) { #>
     1278                                                        <option value="full"  selected='selected'>
     1279                                                                Full Size &ndash; {{ size.width }} &times; {{ size.height }}
     1280                                                        </option>
     1281                                                <# } #>
     1282                                                                        </select>
     1283                        </label>
     1284                <# } #>
     1285        </script>
     1286
     1287        <script type="text/html" id="tmpl-gallery-settings">
     1288                <h2>Gallery Settings</h2>
     1289
     1290                <label class="setting">
     1291                        <span>Link To</span>
     1292                        <select class="link-to"
     1293                                data-setting="link"
     1294                                <# if ( data.userSettings ) { #>
     1295                                        data-user-setting="urlbutton"
     1296                                <# } #>>
     1297
     1298                                <option value="post" <# if ( ! wp.media.galleryDefaults.link || 'post' == wp.media.galleryDefaults.link ) {
     1299                                        #>selected="selected"<# }
     1300                                #>>
     1301                                        Attachment Page                         </option>
     1302                                <option value="file" <# if ( 'file' == wp.media.galleryDefaults.link ) { #>selected="selected"<# } #>>
     1303                                        Media File                              </option>
     1304                                <option value="none" <# if ( 'none' == wp.media.galleryDefaults.link ) { #>selected="selected"<# } #>>
     1305                                        None                            </option>
     1306                        </select>
     1307                </label>
     1308
     1309                <label class="setting">
     1310                        <span>Columns</span>
     1311                        <select class="columns" name="columns"
     1312                                data-setting="columns">
     1313                                                                        <option value="1" <#
     1314                                                if ( 1 == wp.media.galleryDefaults.columns ) { #>selected="selected"<# }
     1315                                        #>>
     1316                                                1                                       </option>
     1317                                                                        <option value="2" <#
     1318                                                if ( 2 == wp.media.galleryDefaults.columns ) { #>selected="selected"<# }
     1319                                        #>>
     1320                                                2                                       </option>
     1321                                                                        <option value="3" <#
     1322                                                if ( 3 == wp.media.galleryDefaults.columns ) { #>selected="selected"<# }
     1323                                        #>>
     1324                                                3                                       </option>
     1325                                                                        <option value="4" <#
     1326                                                if ( 4 == wp.media.galleryDefaults.columns ) { #>selected="selected"<# }
     1327                                        #>>
     1328                                                4                                       </option>
     1329                                                                        <option value="5" <#
     1330                                                if ( 5 == wp.media.galleryDefaults.columns ) { #>selected="selected"<# }
     1331                                        #>>
     1332                                                5                                       </option>
     1333                                                                        <option value="6" <#
     1334                                                if ( 6 == wp.media.galleryDefaults.columns ) { #>selected="selected"<# }
     1335                                        #>>
     1336                                                6                                       </option>
     1337                                                                        <option value="7" <#
     1338                                                if ( 7 == wp.media.galleryDefaults.columns ) { #>selected="selected"<# }
     1339                                        #>>
     1340                                                7                                       </option>
     1341                                                                        <option value="8" <#
     1342                                                if ( 8 == wp.media.galleryDefaults.columns ) { #>selected="selected"<# }
     1343                                        #>>
     1344                                                8                                       </option>
     1345                                                                        <option value="9" <#
     1346                                                if ( 9 == wp.media.galleryDefaults.columns ) { #>selected="selected"<# }
     1347                                        #>>
     1348                                                9                                       </option>
     1349                                                        </select>
     1350                </label>
     1351
     1352                <label class="setting">
     1353                        <span>Random Order</span>
     1354                        <input type="checkbox" data-setting="_orderbyRandom" />
     1355                </label>
     1356
     1357                <label class="setting size">
     1358                        <span>Size</span>
     1359                        <select class="size" name="size"
     1360                                data-setting="size"
     1361                                <# if ( data.userSettings ) { #>
     1362                                        data-user-setting="imgsize"
     1363                                <# } #>
     1364                                >
     1365                                                                        <option value="thumbnail">
     1366                                                Thumbnail                                       </option>
     1367                                                                        <option value="medium">
     1368                                                Medium                                  </option>
     1369                                                                        <option value="large">
     1370                                                Large                                   </option>
     1371                                                                        <option value="full">
     1372                                                Full Size                                       </option>
     1373                                                        </select>
     1374                </label>
     1375        </script>
     1376
     1377        <script type="text/html" id="tmpl-playlist-settings">
     1378                <h2>Playlist Settings</h2>
     1379
     1380                <# var emptyModel = _.isEmpty( data.model ),
     1381                        isVideo = 'video' === data.controller.get('library').props.get('type'); #>
     1382
     1383                <label class="setting">
     1384                        <input type="checkbox" data-setting="tracklist" <# if ( emptyModel ) { #>
     1385                                checked="checked"
     1386                        <# } #> />
     1387                        <# if ( isVideo ) { #>
     1388                        <span>Show Video List</span>
     1389                        <# } else { #>
     1390                        <span>Show Tracklist</span>
     1391                        <# } #>
     1392                </label>
     1393
     1394                <# if ( ! isVideo ) { #>
     1395                <label class="setting">
     1396                        <input type="checkbox" data-setting="artists" <# if ( emptyModel ) { #>
     1397                                checked="checked"
     1398                        <# } #> />
     1399                        <span>Show Artist Name in Tracklist</span>
     1400                </label>
     1401                <# } #>
     1402
     1403                <label class="setting">
     1404                        <input type="checkbox" data-setting="images" <# if ( emptyModel ) { #>
     1405                                checked="checked"
     1406                        <# } #> />
     1407                        <span>Show Images</span>
     1408                </label>
     1409        </script>
     1410
     1411        <script type="text/html" id="tmpl-embed-link-settings">
     1412                <label class="setting link-text">
     1413                        <span>Link Text</span>
     1414                        <input type="text" class="alignment" data-setting="linkText" />
     1415                </label>
     1416                <div class="embed-container" style="display: none;">
     1417                        <div class="embed-preview"></div>
     1418                </div>
     1419        </script>
     1420
     1421        <script type="text/html" id="tmpl-embed-image-settings">
     1422                <div class="thumbnail">
     1423                        <img src="{{ data.model.url }}" draggable="false" alt="" />
     1424                </div>
     1425
     1426                                        <label class="setting caption">
     1427                                <span>Caption</span>
     1428                                <textarea data-setting="caption" />
     1429                        </label>
     1430
     1431                <label class="setting alt-text">
     1432                        <span>Alt Text</span>
     1433                        <input type="text" data-setting="alt" />
     1434                </label>
     1435
     1436                <div class="setting align">
     1437                        <span>Align</span>
     1438                        <div class="button-group button-large" data-setting="align">
     1439                                <button class="button" value="left">
     1440                                        Left                            </button>
     1441                                <button class="button" value="center">
     1442                                        Center                          </button>
     1443                                <button class="button" value="right">
     1444                                        Right                           </button>
     1445                                <button class="button active" value="none">
     1446                                        None                            </button>
     1447                        </div>
     1448                </div>
     1449
     1450                <div class="setting link-to">
     1451                        <span>Link To</span>
     1452                        <div class="button-group button-large" data-setting="link">
     1453                                <button class="button" value="file">
     1454                                        Image URL                               </button>
     1455                                <button class="button" value="custom">
     1456                                        Custom URL                              </button>
     1457                                <button class="button active" value="none">
     1458                                        None                            </button>
     1459                        </div>
     1460                        <input type="text" class="link-to-custom" data-setting="linkUrl" />
     1461                </div>
     1462        </script>
     1463
     1464        <script type="text/html" id="tmpl-image-details">
     1465                <div class="media-embed">
     1466                        <div class="embed-media-settings">
     1467                                <div class="column-image">
     1468                                        <div class="image">
     1469                                                <img src="{{ data.model.url }}" draggable="false" alt="" />
     1470
     1471                                                <# if ( data.attachment && window.imageEdit ) { #>
     1472                                                        <div class="actions">
     1473                                                                <input type="button" class="edit-attachment button" value="Edit Original" />
     1474                                                                <input type="button" class="replace-attachment button" value="Replace" />
     1475                                                        </div>
     1476                                                <# } #>
     1477                                        </div>
     1478                                </div>
     1479                                <div class="column-settings">
     1480                                                                                        <label class="setting caption">
     1481                                                        <span>Caption</span>
     1482                                                        <textarea data-setting="caption">{{ data.model.caption }}</textarea>
     1483                                                </label>
     1484
     1485                                        <label class="setting alt-text">
     1486                                                <span>Alternative Text</span>
     1487                                                <input type="text" data-setting="alt" value="{{ data.model.alt }}" />
     1488                                        </label>
     1489
     1490                                        <h2>Display Settings</h2>
     1491                                        <div class="setting align">
     1492                                                <span>Align</span>
     1493                                                <div class="button-group button-large" data-setting="align">
     1494                                                        <button class="button" value="left">
     1495                                                                Left                                                    </button>
     1496                                                        <button class="button" value="center">
     1497                                                                Center                                                  </button>
     1498                                                        <button class="button" value="right">
     1499                                                                Right                                                   </button>
     1500                                                        <button class="button active" value="none">
     1501                                                                None                                                    </button>
     1502                                                </div>
     1503                                        </div>
     1504
     1505                                        <# if ( data.attachment ) { #>
     1506                                                <# if ( 'undefined' !== typeof data.attachment.sizes ) { #>
     1507                                                        <label class="setting size">
     1508                                                                <span>Size</span>
     1509                                                                <select class="size" name="size"
     1510                                                                        data-setting="size"
     1511                                                                        <# if ( data.userSettings ) { #>
     1512                                                                                data-user-setting="imgsize"
     1513                                                                        <# } #>>
     1514                                                                                                                                                        <#
     1515                                                                                var size = data.sizes['thumbnail'];
     1516                                                                                if ( size ) { #>
     1517                                                                                        <option value="thumbnail">
     1518                                                                                                Thumbnail &ndash; {{ size.width }} &times; {{ size.height }}
     1519                                                                                        </option>
     1520                                                                                <# } #>
     1521                                                                                                                                                        <#
     1522                                                                                var size = data.sizes['medium'];
     1523                                                                                if ( size ) { #>
     1524                                                                                        <option value="medium">
     1525                                                                                                Medium &ndash; {{ size.width }} &times; {{ size.height }}
     1526                                                                                        </option>
     1527                                                                                <# } #>
     1528                                                                                                                                                        <#
     1529                                                                                var size = data.sizes['large'];
     1530                                                                                if ( size ) { #>
     1531                                                                                        <option value="large">
     1532                                                                                                Large &ndash; {{ size.width }} &times; {{ size.height }}
     1533                                                                                        </option>
     1534                                                                                <# } #>
     1535                                                                                                                                                        <#
     1536                                                                                var size = data.sizes['full'];
     1537                                                                                if ( size ) { #>
     1538                                                                                        <option value="full">
     1539                                                                                                Full Size &ndash; {{ size.width }} &times; {{ size.height }}
     1540                                                                                        </option>
     1541                                                                                <# } #>
     1542                                                                                                                                                <option value="custom">
     1543                                                                                Custom Size                                                                     </option>
     1544                                                                </select>
     1545                                                        </label>
     1546                                                <# } #>
     1547                                                        <div class="custom-size<# if ( data.model.size !== 'custom' ) { #> hidden<# } #>">
     1548                                                                <label><span>Width <small>(px)</small></span> <input data-setting="customWidth" type="number" step="1" value="{{ data.model.customWidth }}" /></label><span class="sep">&times;</span><label><span>Height <small>(px)</small></span><input data-setting="customHeight" type="number" step="1" value="{{ data.model.customHeight }}" /></label>
     1549                                                        </div>
     1550                                        <# } #>
     1551
     1552                                        <div class="setting link-to">
     1553                                                <span>Link To</span>
     1554                                                <select data-setting="link">
     1555                                                <# if ( data.attachment ) { #>
     1556                                                        <option value="file">
     1557                                                                Media File                                                      </option>
     1558                                                        <option value="post">
     1559                                                                Attachment Page                                                 </option>
     1560                                                <# } else { #>
     1561                                                        <option value="file">
     1562                                                                Image URL                                                       </option>
     1563                                                <# } #>
     1564                                                        <option value="custom">
     1565                                                                Custom URL                                                      </option>
     1566                                                        <option value="none">
     1567                                                                None                                                    </option>
     1568                                                </select>
     1569                                                <input type="text" class="link-to-custom" data-setting="linkUrl" />
     1570                                        </div>
     1571                                        <div class="advanced-section">
     1572                                                <h2><button type="button" class="button-link advanced-toggle">Advanced Options</button></h2>
     1573                                                <div class="advanced-settings hidden">
     1574                                                        <div class="advanced-image">
     1575                                                                <label class="setting title-text">
     1576                                                                        <span>Image Title Attribute</span>
     1577                                                                        <input type="text" data-setting="title" value="{{ data.model.title }}" />
     1578                                                                </label>
     1579                                                                <label class="setting extra-classes">
     1580                                                                        <span>Image CSS Class</span>
     1581                                                                        <input type="text" data-setting="extraClasses" value="{{ data.model.extraClasses }}" />
     1582                                                                </label>
     1583                                                        </div>
     1584                                                        <div class="advanced-link">
     1585                                                                <div class="setting link-target">
     1586                                                                        <label><input type="checkbox" data-setting="linkTargetBlank" value="_blank" <# if ( data.model.linkTargetBlank ) { #>checked="checked"<# } #>>Open link in a new tab</label>
     1587                                                                </div>
     1588                                                                <label class="setting link-rel">
     1589                                                                        <span>Link Rel</span>
     1590                                                                        <input type="text" data-setting="linkRel" value="{{ data.model.linkClassName }}" />
     1591                                                                </label>
     1592                                                                <label class="setting link-class-name">
     1593                                                                        <span>Link CSS Class</span>
     1594                                                                        <input type="text" data-setting="linkClassName" value="{{ data.model.linkClassName }}" />
     1595                                                                </label>
     1596                                                        </div>
     1597                                                </div>
     1598                                        </div>
     1599                                </div>
     1600                        </div>
     1601                </div>
     1602        </script>
     1603
     1604        <script type="text/html" id="tmpl-image-editor">
     1605                <div id="media-head-{{ data.id }}"></div>
     1606                <div id="image-editor-{{ data.id }}"></div>
     1607        </script>
     1608
     1609        <script type="text/html" id="tmpl-audio-details">
     1610                <# var ext, html5types = {
     1611                        mp3: wp.media.view.settings.embedMimes.mp3,
     1612                        ogg: wp.media.view.settings.embedMimes.ogg
     1613                }; #>
     1614
     1615                                <div class="media-embed media-embed-details">
     1616                        <div class="embed-media-settings embed-audio-settings">
     1617                                <audio style="visibility: hidden"
     1618        controls
     1619        class="wp-audio-shortcode"
     1620        width="{{ _.isUndefined( data.model.width ) ? 400 : data.model.width }}"
     1621        preload="{{ _.isUndefined( data.model.preload ) ? 'none' : data.model.preload }}"
     1622        <#
     1623        if ( ! _.isUndefined( data.model.autoplay ) && data.model.autoplay ) {
     1624                #> autoplay<#
     1625        }
     1626        if ( ! _.isUndefined( data.model.loop ) && data.model.loop ) {
     1627                #> loop<#
     1628        }
     1629        #>
     1630>
     1631        <# if ( ! _.isEmpty( data.model.src ) ) { #>
     1632        <source src="{{ data.model.src }}" type="{{ wp.media.view.settings.embedMimes[ data.model.src.split('.').pop() ] }}" />
     1633        <# } #>
     1634
     1635        <# if ( ! _.isEmpty( data.model.mp3 ) ) { #>
     1636        <source src="{{ data.model.mp3 }}" type="{{ wp.media.view.settings.embedMimes[ 'mp3' ] }}" />
     1637        <# } #>
     1638        <# if ( ! _.isEmpty( data.model.ogg ) ) { #>
     1639        <source src="{{ data.model.ogg }}" type="{{ wp.media.view.settings.embedMimes[ 'ogg' ] }}" />
     1640        <# } #>
     1641        <# if ( ! _.isEmpty( data.model.wma ) ) { #>
     1642        <source src="{{ data.model.wma }}" type="{{ wp.media.view.settings.embedMimes[ 'wma' ] }}" />
     1643        <# } #>
     1644        <# if ( ! _.isEmpty( data.model.m4a ) ) { #>
     1645        <source src="{{ data.model.m4a }}" type="{{ wp.media.view.settings.embedMimes[ 'm4a' ] }}" />
     1646        <# } #>
     1647        <# if ( ! _.isEmpty( data.model.wav ) ) { #>
     1648        <source src="{{ data.model.wav }}" type="{{ wp.media.view.settings.embedMimes[ 'wav' ] }}" />
     1649        <# } #>
     1650        </audio>
     1651
     1652                                <# if ( ! _.isEmpty( data.model.src ) ) {
     1653                                        ext = data.model.src.split('.').pop();
     1654                                        if ( html5types[ ext ] ) {
     1655                                                delete html5types[ ext ];
     1656                                        }
     1657                                #>
     1658                                <label class="setting">
     1659                                        <span>SRC</span>
     1660                                        <input type="text" disabled="disabled" data-setting="src" value="{{ data.model.src }}" />
     1661                                        <button type="button" class="button-link remove-setting">Remove audio source</button>
     1662                                </label>
     1663                                <# } #>
     1664                                <# if ( ! _.isEmpty( data.model.mp3 ) ) {
     1665                                        if ( ! _.isUndefined( html5types.mp3 ) ) {
     1666                                                delete html5types.mp3;
     1667                                        }
     1668                                #>
     1669                                <label class="setting">
     1670                                        <span>MP3</span>
     1671                                        <input type="text" disabled="disabled" data-setting="mp3" value="{{ data.model.mp3 }}" />
     1672                                        <button type="button" class="button-link remove-setting">Remove audio source</button>
     1673                                </label>
     1674                                <# } #>
     1675                                <# if ( ! _.isEmpty( data.model.ogg ) ) {
     1676                                        if ( ! _.isUndefined( html5types.ogg ) ) {
     1677                                                delete html5types.ogg;
     1678                                        }
     1679                                #>
     1680                                <label class="setting">
     1681                                        <span>OGG</span>
     1682                                        <input type="text" disabled="disabled" data-setting="ogg" value="{{ data.model.ogg }}" />
     1683                                        <button type="button" class="button-link remove-setting">Remove audio source</button>
     1684                                </label>
     1685                                <# } #>
     1686                                <# if ( ! _.isEmpty( data.model.wma ) ) {
     1687                                        if ( ! _.isUndefined( html5types.wma ) ) {
     1688                                                delete html5types.wma;
     1689                                        }
     1690                                #>
     1691                                <label class="setting">
     1692                                        <span>WMA</span>
     1693                                        <input type="text" disabled="disabled" data-setting="wma" value="{{ data.model.wma }}" />
     1694                                        <button type="button" class="button-link remove-setting">Remove audio source</button>
     1695                                </label>
     1696                                <# } #>
     1697                                <# if ( ! _.isEmpty( data.model.m4a ) ) {
     1698                                        if ( ! _.isUndefined( html5types.m4a ) ) {
     1699                                                delete html5types.m4a;
     1700                                        }
     1701                                #>
     1702                                <label class="setting">
     1703                                        <span>M4A</span>
     1704                                        <input type="text" disabled="disabled" data-setting="m4a" value="{{ data.model.m4a }}" />
     1705                                        <button type="button" class="button-link remove-setting">Remove audio source</button>
     1706                                </label>
     1707                                <# } #>
     1708                                <# if ( ! _.isEmpty( data.model.wav ) ) {
     1709                                        if ( ! _.isUndefined( html5types.wav ) ) {
     1710                                                delete html5types.wav;
     1711                                        }
     1712                                #>
     1713                                <label class="setting">
     1714                                        <span>WAV</span>
     1715                                        <input type="text" disabled="disabled" data-setting="wav" value="{{ data.model.wav }}" />
     1716                                        <button type="button" class="button-link remove-setting">Remove audio source</button>
     1717                                </label>
     1718                                <# } #>
     1719
     1720                                <# if ( ! _.isEmpty( html5types ) ) { #>
     1721                                <div class="setting">
     1722                                        <span>Add alternate sources for maximum HTML5 playback:</span>
     1723                                        <div class="button-large">
     1724                                        <# _.each( html5types, function (mime, type) { #>
     1725                                        <button class="button add-media-source" data-mime="{{ mime }}">{{ type }}</button>
     1726                                        <# } ) #>
     1727                                        </div>
     1728                                </div>
     1729                                <# } #>
     1730
     1731                                <div class="setting preload">
     1732                                        <span>Preload</span>
     1733                                        <div class="button-group button-large" data-setting="preload">
     1734                                                <button class="button" value="auto">Auto</button>
     1735                                                <button class="button" value="metadata">Metadata</button>
     1736                                                <button class="button active" value="none">None</button>
     1737                                        </div>
     1738                                </div>
     1739
     1740                                <label class="setting checkbox-setting">
     1741                                        <input type="checkbox" data-setting="autoplay" />
     1742                                        <span>Autoplay</span>
     1743                                </label>
     1744
     1745                                <label class="setting checkbox-setting">
     1746                                        <input type="checkbox" data-setting="loop" />
     1747                                        <span>Loop</span>
     1748                                </label>
     1749                        </div>
     1750                </div>
     1751        </script>
     1752
     1753        <script type="text/html" id="tmpl-video-details">
     1754                <# var ext, html5types = {
     1755                        mp4: wp.media.view.settings.embedMimes.mp4,
     1756                        ogv: wp.media.view.settings.embedMimes.ogv,
     1757                        webm: wp.media.view.settings.embedMimes.webm
     1758                }; #>
     1759
     1760                                <div class="media-embed media-embed-details">
     1761                        <div class="embed-media-settings embed-video-settings">
     1762                                <div class="wp-video-holder">
     1763                                <#
     1764                                var w = ! data.model.width || data.model.width > 640 ? 640 : data.model.width,
     1765                                        h = ! data.model.height ? 360 : data.model.height;
     1766
     1767                                if ( data.model.width && w !== data.model.width ) {
     1768                                        h = Math.ceil( ( h * w ) / data.model.width );
     1769                                }
     1770                                #>
     1771
     1772                                <#  var w_rule = '', classes = [],
     1773                w, h, settings = wp.media.view.settings,
     1774                isYouTube = isVimeo = false;
     1775
     1776        if ( ! _.isEmpty( data.model.src ) ) {
     1777                isYouTube = data.model.src.match(/youtube|youtu\.be/);
     1778                isVimeo = -1 !== data.model.src.indexOf('vimeo');
     1779        }
     1780
     1781        if ( settings.contentWidth && data.model.width >= settings.contentWidth ) {
     1782                w = settings.contentWidth;
     1783        } else {
     1784                w = data.model.width;
     1785        }
     1786
     1787        if ( w !== data.model.width ) {
     1788                h = Math.ceil( ( data.model.height * w ) / data.model.width );
     1789        } else {
     1790                h = data.model.height;
     1791        }
     1792
     1793        if ( w ) {
     1794                w_rule = 'width: ' + w + 'px; ';
     1795        }
     1796
     1797        if ( isYouTube ) {
     1798                classes.push( 'youtube-video' );
     1799        }
     1800
     1801        if ( isVimeo ) {
     1802                classes.push( 'vimeo-video' );
     1803        }
     1804
     1805#>
     1806<div style="{{ w_rule }}" class="wp-video">
     1807<video controls
     1808        class="wp-video-shortcode {{ classes.join( ' ' ) }}"
     1809        <# if ( w ) { #>width="{{ w }}"<# } #>
     1810        <# if ( h ) { #>height="{{ h }}"<# } #>
     1811        <#
     1812                if ( ! _.isUndefined( data.model.poster ) && data.model.poster ) {
     1813                        #> poster="{{ data.model.poster }}"<#
     1814                } #>
     1815                preload="{{ _.isUndefined( data.model.preload ) ? 'metadata' : data.model.preload }}"<#
     1816         if ( ! _.isUndefined( data.model.autoplay ) && data.model.autoplay ) {
     1817                #> autoplay<#
     1818        }
     1819         if ( ! _.isUndefined( data.model.loop ) && data.model.loop ) {
     1820                #> loop<#
     1821        }
     1822        #>
     1823>
     1824        <# if ( ! _.isEmpty( data.model.src ) ) {
     1825                if ( isYouTube ) { #>
     1826                <source src="{{ data.model.src }}" type="video/youtube" />
     1827                <# } else if ( isVimeo ) { #>
     1828                <source src="{{ data.model.src }}" type="video/vimeo" />
     1829                <# } else { #>
     1830                <source src="{{ data.model.src }}" type="{{ settings.embedMimes[ data.model.src.split('.').pop() ] }}" />
     1831                <# }
     1832        } #>
     1833
     1834        <# if ( data.model.mp4 ) { #>
     1835        <source src="{{ data.model.mp4 }}" type="{{ settings.embedMimes[ 'mp4' ] }}" />
     1836        <# } #>
     1837        <# if ( data.model.m4v ) { #>
     1838        <source src="{{ data.model.m4v }}" type="{{ settings.embedMimes[ 'm4v' ] }}" />
     1839        <# } #>
     1840        <# if ( data.model.webm ) { #>
     1841        <source src="{{ data.model.webm }}" type="{{ settings.embedMimes[ 'webm' ] }}" />
     1842        <# } #>
     1843        <# if ( data.model.ogv ) { #>
     1844        <source src="{{ data.model.ogv }}" type="{{ settings.embedMimes[ 'ogv' ] }}" />
     1845        <# } #>
     1846        <# if ( data.model.wmv ) { #>
     1847        <source src="{{ data.model.wmv }}" type="{{ settings.embedMimes[ 'wmv' ] }}" />
     1848        <# } #>
     1849        <# if ( data.model.flv ) { #>
     1850        <source src="{{ data.model.flv }}" type="{{ settings.embedMimes[ 'flv' ] }}" />
     1851        <# } #>
     1852                {{{ data.model.content }}}
     1853</video>
     1854</div>
     1855
     1856                                <# if ( ! _.isEmpty( data.model.src ) ) {
     1857                                        ext = data.model.src.split('.').pop();
     1858                                        if ( html5types[ ext ] ) {
     1859                                                delete html5types[ ext ];
     1860                                        }
     1861                                #>
     1862                                <label class="setting">
     1863                                        <span>SRC</span>
     1864                                        <input type="text" disabled="disabled" data-setting="src" value="{{ data.model.src }}" />
     1865                                        <button type="button" class="button-link remove-setting">Remove video source</button>
     1866                                </label>
     1867                                <# } #>
     1868                                <# if ( ! _.isEmpty( data.model.mp4 ) ) {
     1869                                        if ( ! _.isUndefined( html5types.mp4 ) ) {
     1870                                                delete html5types.mp4;
     1871                                        }
     1872                                #>
     1873                                <label class="setting">
     1874                                        <span>MP4</span>
     1875                                        <input type="text" disabled="disabled" data-setting="mp4" value="{{ data.model.mp4 }}" />
     1876                                        <button type="button" class="button-link remove-setting">Remove video source</button>
     1877                                </label>
     1878                                <# } #>
     1879                                <# if ( ! _.isEmpty( data.model.m4v ) ) {
     1880                                        if ( ! _.isUndefined( html5types.m4v ) ) {
     1881                                                delete html5types.m4v;
     1882                                        }
     1883                                #>
     1884                                <label class="setting">
     1885                                        <span>M4V</span>
     1886                                        <input type="text" disabled="disabled" data-setting="m4v" value="{{ data.model.m4v }}" />
     1887                                        <button type="button" class="button-link remove-setting">Remove video source</button>
     1888                                </label>
     1889                                <# } #>
     1890                                <# if ( ! _.isEmpty( data.model.webm ) ) {
     1891                                        if ( ! _.isUndefined( html5types.webm ) ) {
     1892                                                delete html5types.webm;
     1893                                        }
     1894                                #>
     1895                                <label class="setting">
     1896                                        <span>WEBM</span>
     1897                                        <input type="text" disabled="disabled" data-setting="webm" value="{{ data.model.webm }}" />
     1898                                        <button type="button" class="button-link remove-setting">Remove video source</button>
     1899                                </label>
     1900                                <# } #>
     1901                                <# if ( ! _.isEmpty( data.model.ogv ) ) {
     1902                                        if ( ! _.isUndefined( html5types.ogv ) ) {
     1903                                                delete html5types.ogv;
     1904                                        }
     1905                                #>
     1906                                <label class="setting">
     1907                                        <span>OGV</span>
     1908                                        <input type="text" disabled="disabled" data-setting="ogv" value="{{ data.model.ogv }}" />
     1909                                        <button type="button" class="button-link remove-setting">Remove video source</button>
     1910                                </label>
     1911                                <# } #>
     1912                                <# if ( ! _.isEmpty( data.model.wmv ) ) {
     1913                                        if ( ! _.isUndefined( html5types.wmv ) ) {
     1914                                                delete html5types.wmv;
     1915                                        }
     1916                                #>
     1917                                <label class="setting">
     1918                                        <span>WMV</span>
     1919                                        <input type="text" disabled="disabled" data-setting="wmv" value="{{ data.model.wmv }}" />
     1920                                        <button type="button" class="button-link remove-setting">Remove video source</button>
     1921                                </label>
     1922                                <# } #>
     1923                                <# if ( ! _.isEmpty( data.model.flv ) ) {
     1924                                        if ( ! _.isUndefined( html5types.flv ) ) {
     1925                                                delete html5types.flv;
     1926                                        }
     1927                                #>
     1928                                <label class="setting">
     1929                                        <span>FLV</span>
     1930                                        <input type="text" disabled="disabled" data-setting="flv" value="{{ data.model.flv }}" />
     1931                                        <button type="button" class="button-link remove-setting">Remove video source</button>
     1932                                </label>
     1933                                <# } #>
     1934                                                                </div>
     1935
     1936                                <# if ( ! _.isEmpty( html5types ) ) { #>
     1937                                <div class="setting">
     1938                                        <span>Add alternate sources for maximum HTML5 playback:</span>
     1939                                        <div class="button-large">
     1940                                        <# _.each( html5types, function (mime, type) { #>
     1941                                        <button class="button add-media-source" data-mime="{{ mime }}">{{ type }}</button>
     1942                                        <# } ) #>
     1943                                        </div>
     1944                                </div>
     1945                                <# } #>
     1946
     1947                                <# if ( ! _.isEmpty( data.model.poster ) ) { #>
     1948                                <label class="setting">
     1949                                        <span>Poster Image</span>
     1950                                        <input type="text" disabled="disabled" data-setting="poster" value="{{ data.model.poster }}" />
     1951                                        <button type="button" class="button-link remove-setting">Remove poster image</button>
     1952                                </label>
     1953                                <# } #>
     1954                                <div class="setting preload">
     1955                                        <span>Preload</span>
     1956                                        <div class="button-group button-large" data-setting="preload">
     1957                                                <button class="button" value="auto">Auto</button>
     1958                                                <button class="button" value="metadata">Metadata</button>
     1959                                                <button class="button active" value="none">None</button>
     1960                                        </div>
     1961                                </div>
     1962
     1963                                <label class="setting checkbox-setting">
     1964                                        <input type="checkbox" data-setting="autoplay" />
     1965                                        <span>Autoplay</span>
     1966                                </label>
     1967
     1968                                <label class="setting checkbox-setting">
     1969                                        <input type="checkbox" data-setting="loop" />
     1970                                        <span>Loop</span>
     1971                                </label>
     1972
     1973                                <label class="setting" data-setting="content">
     1974                                        <span>Tracks (subtitles, captions, descriptions, chapters, or metadata)</span>
     1975                                        <#
     1976                                        var content = '';
     1977                                        if ( ! _.isEmpty( data.model.content ) ) {
     1978                                                var tracks = jQuery( data.model.content ).filter( 'track' );
     1979                                                _.each( tracks.toArray(), function (track) {
     1980                                                        content += track.outerHTML; #>
     1981                                                <p>
     1982                                                        <input class="content-track" type="text" value="{{ track.outerHTML }}" />
     1983                                                        <button type="button" class="button-link remove-setting remove-track">Remove video track</button>
     1984                                                </p>
     1985                                                <# } ); #>
     1986                                        <# } else { #>
     1987                                        <em>There are no associated subtitles.</em>
     1988                                        <# } #>
     1989                                        <textarea class="hidden content-setting">{{ content }}</textarea>
     1990                                </label>
     1991                        </div>
     1992                </div>
     1993        </script>
     1994
     1995        <script type="text/html" id="tmpl-editor-gallery">
     1996                <# if ( data.attachments.length ) { #>
     1997                        <div class="gallery gallery-columns-{{ data.columns }}">
     1998                                <# _.each( data.attachments, function( attachment, index ) { #>
     1999                                        <dl class="gallery-item">
     2000                                                <dt class="gallery-icon">
     2001                                                        <# if ( attachment.thumbnail ) { #>
     2002                                                                <img src="{{ attachment.thumbnail.url }}" width="{{ attachment.thumbnail.width }}" height="{{ attachment.thumbnail.height }}" alt="" />
     2003                                                        <# } else { #>
     2004                                                                <img src="{{ attachment.url }}" alt="" />
     2005                                                        <# } #>
     2006                                                </dt>
     2007                                                <# if ( attachment.caption ) { #>
     2008                                                        <dd class="wp-caption-text gallery-caption">
     2009                                                                {{{ data.verifyHTML( attachment.caption ) }}}
     2010                                                        </dd>
     2011                                                <# } #>
     2012                                        </dl>
     2013                                        <# if ( index % data.columns === data.columns - 1 ) { #>
     2014                                                <br style="clear: both;">
     2015                                        <# } #>
     2016                                <# } ); #>
     2017                        </div>
     2018                <# } else { #>
     2019                        <div class="wpview-error">
     2020                                <div class="dashicons dashicons-format-gallery"></div><p>No items found.</p>
     2021                        </div>
     2022                <# } #>
     2023        </script>
     2024
     2025        <script type="text/html" id="tmpl-crop-content">
     2026                <img class="crop-image" src="{{ data.url }}" alt="Image crop area preview. Requires mouse interaction.">
     2027                <div class="upload-errors"></div>
     2028        </script>
     2029
     2030        <script type="text/html" id="tmpl-site-icon-preview">
     2031                <h2>Preview</h2>
     2032                <strong aria-hidden="true">As a browser icon</strong>
     2033                <div class="favicon-preview">
     2034                        <img src="http://src.wordpress-develop.dev/wp-admin/images/browser.png" class="browser-preview" width="182" height="" alt="" />
     2035
     2036                        <div class="favicon">
     2037                                <img id="preview-favicon" src="{{ data.url }}" alt="Preview as a browser icon"/>
     2038                        </div>
     2039                        <span class="browser-title" aria-hidden="true">WordPress Develop</span>
     2040                </div>
     2041
     2042                <strong aria-hidden="true">As an app icon</strong>
     2043                <div class="app-icon-preview">
     2044                        <img id="preview-app-icon" src="{{ data.url }}" alt="Preview as an app icon"/>
     2045                </div>
     2046        </script>
    5022047                </div><!-- end widget templates -->
    5032048                <script src="../../src/wp-includes/js/tinymce/tinymce.js"></script>
Note: See TracChangeset for help on using the changeset viewer.