Changeset 27733
- Timestamp:
- 03/26/2014 12:10:21 PM (12 years ago)
- Location:
- trunk/src/wp-includes
- Files:
-
- 5 edited
-
js/mce-view.js (modified) (1 diff)
-
js/media-audiovideo.js (modified) (3 diffs)
-
media-template.php (modified) (1 diff)
-
media.php (modified) (1 diff)
-
script-loader.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/js/mce-view.js
r27615 r27733 318 318 }; 319 319 wp.mce.views.register( 'gallery', wp.mce.gallery ); 320 321 /** 322 * Tiny MCE Views for Audio / Video 323 * 324 */ 325 326 /** 327 * These are base methods that are shared by each shortcode's MCE controller 328 * 329 * @mixin 330 */ 331 wp.mce.media = { 332 /** 333 * @global wp.shortcode 334 * 335 * @param {string} content 336 * @returns {Object} 337 */ 338 toView: function( content ) { 339 var match = wp.shortcode.next( this.shortcode, content ); 340 341 if ( ! match ) { 342 return; 343 } 344 345 return { 346 index: match.index, 347 content: match.content, 348 options: { 349 shortcode: match.shortcode 350 } 351 }; 352 }, 353 354 /** 355 * Called when a TinyMCE view is clicked for editing. 356 * - Parses the shortcode out of the element's data attribute 357 * - Calls the `edit` method on the shortcode model 358 * - Launches the model window 359 * - Bind's an `update` callback which updates the element's data attribute 360 * re-renders the view 361 * 362 * @param {HTMLElement} node 363 */ 364 edit: function( node ) { 365 var media = wp.media[ this.shortcode ], 366 self = this, 367 frame, data; 368 369 wp.media.mixin.pauseAllPlayers(); 370 371 data = window.decodeURIComponent( $( node ).attr('data-wpview-text') ); 372 frame = media.edit( data ); 373 frame.on( 'close', function() { 374 frame.detach(); 375 } ); 376 frame.state( self.state ).on( 'update', function( selection ) { 377 var shortcode = wp.media[ self.shortcode ].shortcode( selection ).string(); 378 $( node ).attr( 'data-wpview-text', window.encodeURIComponent( shortcode ) ); 379 wp.mce.views.refreshView( self, shortcode ); 380 frame.detach(); 381 } ); 382 frame.open(); 383 } 384 }; 385 386 /** 387 * Base View class for audio and video shortcodes 388 * 389 * @constructor 390 * @augments wp.mce.View 391 * @mixes wp.media.mixin 392 */ 393 wp.mce.media.View = wp.mce.View.extend({ 394 initialize: function( options ) { 395 this.shortcode = options.shortcode; 396 _.bindAll( this, 'setPlayer' ); 397 $(this).on( 'ready', this.setPlayer ); 398 }, 399 400 /** 401 * Creates the player instance for the current node 402 * 403 * @global MediaElementPlayer 404 * @global _wpmejsSettings 405 * 406 * @param {Event} e 407 * @param {HTMLElement} node 408 */ 409 setPlayer: function(e, node) { 410 // if the ready event fires on an empty node 411 if ( ! node ) { 412 return; 413 } 414 415 var self = this, 416 media, 417 firefox = this.ua.is( 'ff' ), 418 className = '.wp-' + this.shortcode.tag + '-shortcode'; 419 420 if ( this.player ) { 421 this.unsetPlayer(); 422 } 423 424 media = $( node ).find( className ); 425 426 if ( ! this.isCompatible( media ) ) { 427 media.closest( '.wpview-wrap' ).addClass( 'wont-play' ); 428 if ( ! media.parent().hasClass( 'wpview-wrap' ) ) { 429 media.parent().replaceWith( media ); 430 } 431 media.replaceWith( '<p>' + media.find( 'source' ).eq(0).prop( 'src' ) + '</p>' ); 432 return; 433 } else { 434 media.closest( '.wpview-wrap' ).removeClass( 'wont-play' ); 435 if ( firefox ) { 436 media.prop( 'preload', 'metadata' ); 437 } else { 438 media.prop( 'preload', 'none' ); 439 } 440 } 441 442 media = wp.media.view.MediaDetails.prepareSrc( media.get(0) ); 443 444 // Thanks, Firefox! 445 if ( firefox ) { 446 setTimeout( function() { 447 self.player = new MediaElementPlayer( media, this.mejsSettings ); 448 }, 50 ); 449 } else { 450 this.player = new MediaElementPlayer( media, this.mejsSettings ); 451 } 452 }, 453 454 /** 455 * Pass data to the View's Underscore template and return the compiled output 456 * 457 * @returns {string} 458 */ 459 getHtml: function() { 460 var attrs = _.defaults( 461 this.shortcode.attrs.named, 462 wp.media[ this.shortcode.tag ].defaults 463 ); 464 return this.template({ model: attrs }); 465 } 466 }); 467 _.extend( wp.mce.media.View.prototype, wp.media.mixin ); 468 469 /** 470 * TinyMCE handler for the video shortcode 471 * 472 * @mixes wp.mce.media 473 */ 474 wp.mce.video = _.extend( {}, wp.mce.media, { 475 shortcode: 'video', 476 state: 'video-details', 477 View: wp.mce.media.View.extend({ 478 className: 'editor-video', 479 template: media.template('editor-video') 480 }) 481 } ); 482 wp.mce.views.register( 'video', wp.mce.video ); 483 484 /** 485 * TinyMCE handler for the audio shortcode 486 * 487 * @mixes wp.mce.media 488 */ 489 wp.mce.audio = _.extend( {}, wp.mce.media, { 490 shortcode: 'audio', 491 state: 'audio-details', 492 View: wp.mce.media.View.extend({ 493 className: 'editor-audio', 494 template: media.template('editor-audio') 495 }) 496 } ); 497 wp.mce.views.register( 'audio', wp.mce.audio ); 498 499 /** 500 * Base View class for playlist shortcodes 501 * 502 * @constructor 503 * @augments wp.mce.View 504 * @mixes wp.media.mixin 505 */ 506 wp.mce.media.PlaylistView = wp.mce.View.extend({ 507 className: 'editor-playlist', 508 template: media.template('editor-playlist'), 509 510 initialize: function( options ) { 511 this.data = {}; 512 this.attachments = []; 513 this.shortcode = options.shortcode; 514 _.bindAll( this, 'setPlayer' ); 515 $(this).on('ready', this.setNode); 516 }, 517 518 /** 519 * Set the element context for the view, and then fetch the playlist's 520 * associated attachments. 521 * 522 * @param {Event} e 523 * @param {HTMLElement} node 524 */ 525 setNode: function(e, node) { 526 this.node = node; 527 this.fetch(); 528 }, 529 530 /** 531 * Asynchronously fetch the shortcode's attachments 532 */ 533 fetch: function() { 534 this.attachments = wp.media[ this.shortcode.tag ].attachments( this.shortcode ); 535 this.attachments.more().done( this.setPlayer ); 536 }, 537 538 /** 539 * Get the HTML for the view (which also set's the data), replace the 540 * current HTML, and then invoke the WPPlaylistView instance to render 541 * the playlist in the editor 542 * 543 * @global WPPlaylistView 544 * @global tinymce.editors 545 */ 546 setPlayer: function() { 547 var p, 548 html = this.getHtml(), 549 t = this.encodedText, 550 self = this; 551 552 this.unsetPlayer(); 553 554 _.each( tinymce.editors, function( editor ) { 555 var doc; 556 if ( editor.plugins.wpview ) { 557 doc = editor.getDoc(); 558 $( doc ).find( '[data-wpview-text="' + t + '"]' ).each(function(i, elem) { 559 var node = $( elem ); 560 node.html( html ); 561 self.node = elem; 562 }); 563 } 564 }, this ); 565 566 p = new WPPlaylistView({ 567 el: $( self.node ).find( '.wp-playlist' ).get(0), 568 metadata: this.data 569 }); 570 571 this.player = p._player; 572 }, 573 574 /** 575 * Set the data that will be used to compile the Underscore template, 576 * compile the template, and then return it. 577 * 578 * @returns {string} 579 */ 580 getHtml: function() { 581 var data = this.shortcode.attrs.named, 582 model = wp.media[ this.shortcode.tag ], 583 type = 'playlist' === this.shortcode.tag ? 'audio' : 'video', 584 options, 585 attachments, 586 tracks = []; 587 588 if ( ! this.attachments.length ) { 589 return; 590 } 591 592 _.each( model.defaults, function( value, key ) { 593 data[ key ] = model.coerce( data, key ); 594 }); 595 596 attachments = this.attachments.toJSON(); 597 598 options = { 599 type: type, 600 style: data.style, 601 tracklist: data.tracklist, 602 tracknumbers: data.tracknumbers, 603 images: data.images, 604 artists: data.artists 605 }; 606 607 _.each( attachments, function( attachment ) { 608 var size = {}, resize = {}, track = { 609 src : attachment.url, 610 type : attachment.mime, 611 title : attachment.title, 612 caption : attachment.caption, 613 description : attachment.description, 614 meta : attachment.meta 615 }; 616 617 if ( 'video' === type ) { 618 size.width = attachment.width; 619 size.height = attachment.height; 620 if ( media.view.settings.contentWidth ) { 621 resize.width = media.view.settings.contentWidth - 22; 622 resize.height = Math.ceil( ( size.height * resize.width ) / size.width ); 623 if ( ! options.width ) { 624 options.width = resize.width; 625 options.height = resize.height; 626 } 627 } else { 628 if ( ! options.width ) { 629 options.width = attachment.width; 630 options.height = attachment.height; 631 } 632 } 633 track.dimensions = { 634 original : size, 635 resized : _.isEmpty( resize ) ? size : resize 636 }; 637 } else { 638 options.width = 400; 639 } 640 641 track.image = attachment.image; 642 track.thumb = attachment.thumb; 643 644 tracks.push( track ); 645 } ); 646 647 options.tracks = tracks; 648 this.data = options; 649 650 return this.template( options ); 651 } 652 }); 653 _.extend( wp.mce.media.PlaylistView.prototype, wp.media.mixin ); 654 655 /** 656 * TinyMCE handler for the playlist shortcode 657 * 658 * @mixes wp.mce.media 659 */ 660 wp.mce.playlist = _.extend( {}, wp.mce.media, { 661 shortcode: 'playlist', 662 state: 'playlist-edit', 663 View: wp.mce.media.PlaylistView 664 } ); 665 wp.mce.views.register( 'playlist', wp.mce.playlist ); 666 667 /** 668 * TinyMCE handler for the video-playlist shortcode 669 * 670 * @mixes wp.mce.media 671 */ 672 wp.mce['video-playlist'] = _.extend( {}, wp.mce.media, { 673 shortcode: 'video-playlist', 674 state: 'video-playlist-edit', 675 View: wp.mce.media.PlaylistView 676 } ); 677 wp.mce.views.register( 'video-playlist', wp.mce['video-playlist'] ); 320 678 }(jQuery)); -
trunk/src/wp-includes/js/media-audiovideo.js
r27658 r27733 14 14 */ 15 15 wp.media.mixin = { 16 16 mejsSettings: baseSettings, 17 17 /** 18 18 * Pauses every instance of MediaElementPlayer … … 218 218 autoplay : false, 219 219 preload : 'none', 220 caption : '' 220 caption : '', 221 width : 400 221 222 }, 222 223 … … 1046 1047 1047 1048 /** 1048 * Tiny MCE Views1049 *1050 */1051 1052 /**1053 * These are base methods that are shared by each shortcode's MCE controller1054 *1055 * @mixin1056 */1057 wp.mce.media = {1058 /**1059 * @global wp.shortcode1060 *1061 * @param {string} content1062 * @returns {Object}1063 */1064 toView: function( content ) {1065 var match = wp.shortcode.next( this.shortcode, content );1066 1067 if ( ! match ) {1068 return;1069 }1070 1071 return {1072 index: match.index,1073 content: match.content,1074 options: {1075 shortcode: match.shortcode1076 }1077 };1078 },1079 1080 /**1081 * Called when a TinyMCE view is clicked for editing.1082 * - Parses the shortcode out of the element's data attribute1083 * - Calls the `edit` method on the shortcode model1084 * - Launches the model window1085 * - Bind's an `update` callback which updates the element's data attribute1086 * re-renders the view1087 *1088 * @param {HTMLElement} node1089 */1090 edit: function( node ) {1091 var media = wp.media[ this.shortcode ],1092 self = this,1093 frame, data;1094 1095 wp.media.mixin.pauseAllPlayers();1096 1097 data = window.decodeURIComponent( $( node ).attr('data-wpview-text') );1098 frame = media.edit( data );1099 frame.on( 'close', function() {1100 frame.detach();1101 } );1102 frame.state( self.state ).on( 'update', function( selection ) {1103 var shortcode = wp.media[ self.shortcode ].shortcode( selection ).string();1104 $( node ).attr( 'data-wpview-text', window.encodeURIComponent( shortcode ) );1105 wp.mce.views.refreshView( self, shortcode );1106 frame.detach();1107 } );1108 frame.open();1109 }1110 };1111 1112 /**1113 * Base View class for audio and video shortcodes1114 *1115 * @constructor1116 * @augments wp.mce.View1117 * @mixes wp.media.mixin1118 */1119 wp.mce.media.View = wp.mce.View.extend({1120 initialize: function( options ) {1121 this.shortcode = options.shortcode;1122 _.bindAll( this, 'setPlayer' );1123 $(this).on( 'ready', this.setPlayer );1124 },1125 1126 /**1127 * Creates the player instance for the current node1128 *1129 * @global MediaElementPlayer1130 * @global _wpmejsSettings1131 *1132 * @param {Event} e1133 * @param {HTMLElement} node1134 */1135 setPlayer: function(e, node) {1136 // if the ready event fires on an empty node1137 if ( ! node ) {1138 return;1139 }1140 1141 var self = this,1142 media,1143 firefox = this.ua.is( 'ff' ),1144 className = '.wp-' + this.shortcode.tag + '-shortcode';1145 1146 if ( this.player ) {1147 this.unsetPlayer();1148 }1149 1150 media = $( node ).find( className );1151 1152 if ( ! this.isCompatible( media ) ) {1153 media.closest( '.wpview-wrap' ).addClass( 'wont-play' );1154 if ( ! media.parent().hasClass( 'wpview-wrap' ) ) {1155 media.parent().replaceWith( media );1156 }1157 media.replaceWith( '<p>' + media.find( 'source' ).eq(0).prop( 'src' ) + '</p>' );1158 return;1159 } else {1160 media.closest( '.wpview-wrap' ).removeClass( 'wont-play' );1161 if ( firefox ) {1162 media.prop( 'preload', 'metadata' );1163 } else {1164 media.prop( 'preload', 'none' );1165 }1166 }1167 1168 media = wp.media.view.MediaDetails.prepareSrc( media.get(0) );1169 1170 // Thanks, Firefox!1171 if ( firefox ) {1172 setTimeout( function() {1173 self.player = new MediaElementPlayer( media, baseSettings );1174 }, 50 );1175 } else {1176 this.player = new MediaElementPlayer( media, baseSettings );1177 }1178 },1179 1180 /**1181 * Pass data to the View's Underscore template and return the compiled output1182 *1183 * @returns {string}1184 */1185 getHtml: function() {1186 var attrs = _.defaults(1187 this.shortcode.attrs.named,1188 wp.media[ this.shortcode.tag ].defaults1189 );1190 return this.template({ model: attrs });1191 }1192 });1193 _.extend( wp.mce.media.View.prototype, wp.media.mixin );1194 1195 /**1196 * TinyMCE handler for the video shortcode1197 *1198 * @mixes wp.mce.media1199 */1200 wp.mce.video = _.extend( {}, wp.mce.media, {1201 shortcode: 'video',1202 state: 'video-details',1203 View: wp.mce.media.View.extend({1204 className: 'editor-video',1205 template: media.template('editor-video')1206 })1207 } );1208 wp.mce.views.register( 'video', wp.mce.video );1209 1210 /**1211 * TinyMCE handler for the audio shortcode1212 *1213 * @mixes wp.mce.media1214 */1215 wp.mce.audio = _.extend( {}, wp.mce.media, {1216 shortcode: 'audio',1217 state: 'audio-details',1218 View: wp.mce.media.View.extend({1219 className: 'editor-audio',1220 template: media.template('editor-audio')1221 })1222 } );1223 wp.mce.views.register( 'audio', wp.mce.audio );1224 1225 /**1226 * Base View class for playlist shortcodes1227 *1228 * @constructor1229 * @augments wp.mce.View1230 * @mixes wp.media.mixin1231 */1232 wp.mce.media.PlaylistView = wp.mce.View.extend({1233 className: 'editor-playlist',1234 template: media.template('editor-playlist'),1235 1236 initialize: function( options ) {1237 this.data = {};1238 this.attachments = [];1239 this.shortcode = options.shortcode;1240 _.bindAll( this, 'setPlayer' );1241 $(this).on('ready', this.setNode);1242 },1243 1244 /**1245 * Set the element context for the view, and then fetch the playlist's1246 * associated attachments.1247 *1248 * @param {Event} e1249 * @param {HTMLElement} node1250 */1251 setNode: function(e, node) {1252 this.node = node;1253 this.fetch();1254 },1255 1256 /**1257 * Asynchronously fetch the shortcode's attachments1258 */1259 fetch: function() {1260 this.attachments = wp.media[ this.shortcode.tag ].attachments( this.shortcode );1261 this.attachments.more().done( this.setPlayer );1262 },1263 1264 /**1265 * Get the HTML for the view (which also set's the data), replace the1266 * current HTML, and then invoke the WPPlaylistView instance to render1267 * the playlist in the editor1268 *1269 * @global WPPlaylistView1270 * @global tinymce.editors1271 */1272 setPlayer: function() {1273 var p,1274 html = this.getHtml(),1275 t = this.encodedText,1276 self = this;1277 1278 this.unsetPlayer();1279 1280 _.each( tinymce.editors, function( editor ) {1281 var doc;1282 if ( editor.plugins.wpview ) {1283 doc = editor.getDoc();1284 $( doc ).find( '[data-wpview-text="' + t + '"]' ).each(function(i, elem) {1285 var node = $( elem );1286 node.html( html );1287 self.node = elem;1288 });1289 }1290 }, this );1291 1292 p = new WPPlaylistView({1293 el: $( self.node ).find( '.wp-playlist' ).get(0),1294 metadata: this.data1295 });1296 1297 this.player = p._player;1298 },1299 1300 /**1301 * Set the data that will be used to compile the Underscore template,1302 * compile the template, and then return it.1303 *1304 * @returns {string}1305 */1306 getHtml: function() {1307 var data = this.shortcode.attrs.named,1308 model = wp.media[ this.shortcode.tag ],1309 type = 'playlist' === this.shortcode.tag ? 'audio' : 'video',1310 options,1311 attachments,1312 tracks = [];1313 1314 if ( ! this.attachments.length ) {1315 return;1316 }1317 1318 _.each( model.defaults, function( value, key ) {1319 data[ key ] = model.coerce( data, key );1320 });1321 1322 attachments = this.attachments.toJSON();1323 1324 options = {1325 type: type,1326 style: data.style,1327 tracklist: data.tracklist,1328 tracknumbers: data.tracknumbers,1329 images: data.images,1330 artists: data.artists1331 };1332 1333 _.each( attachments, function( attachment ) {1334 var size = {}, resize = {}, track = {1335 src : attachment.url,1336 type : attachment.mime,1337 title : attachment.title,1338 caption : attachment.caption,1339 description : attachment.description,1340 meta : attachment.meta1341 };1342 1343 if ( 'video' === type ) {1344 size.width = attachment.width;1345 size.height = attachment.height;1346 if ( media.view.settings.contentWidth ) {1347 resize.width = media.view.settings.contentWidth - 22;1348 resize.height = Math.ceil( ( size.height * resize.width ) / size.width );1349 if ( ! options.width ) {1350 options.width = resize.width;1351 options.height = resize.height;1352 }1353 } else {1354 if ( ! options.width ) {1355 options.width = attachment.width;1356 options.height = attachment.height;1357 }1358 }1359 track.dimensions = {1360 original : size,1361 resized : _.isEmpty( resize ) ? size : resize1362 };1363 } else {1364 options.width = 400;1365 }1366 1367 track.image = attachment.image;1368 track.thumb = attachment.thumb;1369 1370 tracks.push( track );1371 } );1372 1373 options.tracks = tracks;1374 this.data = options;1375 1376 return this.template( options );1377 }1378 });1379 _.extend( wp.mce.media.PlaylistView.prototype, wp.media.mixin );1380 1381 /**1382 * TinyMCE handler for the playlist shortcode1383 *1384 * @mixes wp.mce.media1385 */1386 wp.mce.playlist = _.extend( {}, wp.mce.media, {1387 shortcode: 'playlist',1388 state: 'playlist-edit',1389 View: wp.mce.media.PlaylistView1390 } );1391 wp.mce.views.register( 'playlist', wp.mce.playlist );1392 1393 /**1394 * TinyMCE handler for the video-playlist shortcode1395 *1396 * @mixes wp.mce.media1397 */1398 wp.mce['video-playlist'] = _.extend( {}, wp.mce.media, {1399 shortcode: 'video-playlist',1400 state: 'video-playlist-edit',1401 View: wp.mce.media.PlaylistView1402 } );1403 wp.mce.views.register( 'video-playlist', wp.mce['video-playlist'] );1404 1405 /**1406 1049 * Event binding 1407 1050 */ -
trunk/src/wp-includes/media-template.php
r27695 r27733 19 19 <audio controls 20 20 class="wp-audio-shortcode" 21 width="{{ _.isUndefined( data.model.width ) ? 400 : data.model.width }}" 21 22 preload="{{ _.isUndefined( data.model.preload ) ? 'none' : data.model.preload }}" 22 23 <# -
trunk/src/wp-includes/media.php
r27726 r27733 2575 2575 wp_enqueue_style( 'media-views' ); 2576 2576 if ( is_admin() ) { 2577 wp_enqueue_script( 'mce-view' ); 2577 2578 wp_enqueue_script( 'image-edit' ); 2578 2579 } -
trunk/src/wp-includes/script-loader.php
r27732 r27733 413 413 $scripts->add( 'media-views', "/wp-includes/js/media-views$suffix.js", array( 'utils', 'media-models', 'wp-plupload', 'jquery-ui-sortable', 'wp-mediaelement' ), false, 1 ); 414 414 $scripts->add( 'media-editor', "/wp-includes/js/media-editor$suffix.js", array( 'shortcode', 'media-views' ), false, 1 ); 415 $scripts->add( 'media-audiovideo', "/wp-includes/js/media-audiovideo$suffix.js", array( 'media-editor' , 'mce-view', 'wp-playlist'), false, 1 );416 $scripts->add( 'mce-view', "/wp-includes/js/mce-view$suffix.js", array( 'shortcode', 'media-models' ), false, 1 );415 $scripts->add( 'media-audiovideo', "/wp-includes/js/media-audiovideo$suffix.js", array( 'media-editor' ), false, 1 ); 416 $scripts->add( 'mce-view', "/wp-includes/js/mce-view$suffix.js", array( 'shortcode', 'media-models', 'media-audiovideo', 'wp-playlist' ), false, 1 ); 417 417 418 418 if ( is_admin() ) {
Note: See TracChangeset
for help on using the changeset viewer.