From 692d806fff879acaa36ea1bc3d4873b434a39085 Mon Sep 17 00:00:00 2001 From: Daryl Koopersmith Date: Thu, 27 Sep 2012 04:09:43 +0000 Subject: [PATCH] BUTTON. Add a "Beta Media" button to the post editor. Currently, it is only capable of inserting images. Other attachment types and galleries need not apply... yet. * Added `wp.media.string.image( attachment, props )` for generating an image as a string from an attachment and relevant attachment display properties. * Properly localized the gallery workflow. * Added `Workflow.update()`, which closes the modal, triggers an `update` event, and resets the selection. * Added `wp.mce.media` to manage the various media workflows for editors. see #21813, #21814, #21390. git-svn-id: https://develop.svn.wordpress.org/trunk@22036 602fd350-edb4-49c9-b593-d223f7449a82 --- wp-admin/includes/media.php | 2 + wp-admin/js/media-upload.js | 63 ++++++++++++++++++++++++ wp-includes/css/editor.css | 14 +++--- wp-includes/js/mce-view.js | 91 ++++++++++++++++++++++------------- wp-includes/js/media-views.js | 24 +++++---- wp-includes/script-loader.php | 22 ++++++--- 6 files changed, 160 insertions(+), 56 deletions(-) diff --git a/wp-admin/includes/media.php b/wp-admin/includes/media.php index b5aa42b221..fce66f7e25 100644 --- a/wp-admin/includes/media.php +++ b/wp-admin/includes/media.php @@ -381,6 +381,8 @@ function media_buttons($editor_id = 'content') { $img = ''; + echo '' . sprintf( __('%s Beta Media'), $img ) . ''; + echo '' . sprintf( $context, $img ) . ''; } add_action( 'media_buttons', 'media_buttons' ); diff --git a/wp-admin/js/media-upload.js b/wp-admin/js/media-upload.js index 9b998ff2a3..16f0a6e26e 100644 --- a/wp-admin/js/media-upload.js +++ b/wp-admin/js/media-upload.js @@ -86,3 +86,66 @@ var tb_position; }); })(jQuery); + +// WordPress, TinyMCE, and Media +// ----------------------------- +(function($){ + // Stores the editors' `wp.media.controller.Workflow` instaces. + var workflows = {}; + + wp.mce.media = { + insert: send_to_editor, + + add: function( id, options ) { + var workflow = this.get( id ); + + if ( workflow ) + return workflow; + + workflow = workflows[ id ] = wp.media( _.defaults( options || {}, { + multiple: true + } ) ); + + workflow.on( 'update', function( selection ) { + this.insert( '\n' + selection.map( function( attachment ) { + return wp.media.string.image( attachment ); + }).join('\n\n') + '\n' ); + }, this ); + + return workflow; + }, + + get: function( id ) { + return workflows[ id ]; + }, + + remove: function( id ) { + delete workflows[ id ]; + }, + + init: function() { + $('.insert-media').on( 'click', function( event ) { + var editor = $(this).data('editor'), + workflow; + + event.preventDefault(); + + if ( ! editor ) + return; + + workflow = wp.mce.media.get( editor ); + + // If the workflow exists, just open it. + if ( workflow ) { + workflow.open(); + return; + } + + // Initialize the editor's workflow if we haven't yet. + wp.mce.media.add( editor ); + }); + } + }; + + $( wp.mce.media.init ) +}(jQuery)); \ No newline at end of file diff --git a/wp-includes/css/editor.css b/wp-includes/css/editor.css index c53d7fdce4..a00cdee8b8 100644 --- a/wp-includes/css/editor.css +++ b/wp-includes/css/editor.css @@ -1008,7 +1008,7 @@ .wp-editor-tools { height: 30px; - padding: 0 10px; + padding: 0 10px 0 0; } .wp-editor-container { @@ -1079,16 +1079,18 @@ html[dir="rtl"] .wp-switch-editor { color: #555; } -.wp-media-buttons { - line-height: 1; - padding: 9px 0 0; +.wp-media-buttons .button { + margin-right: 5px; +} + +.wp-media-buttons .insert-media { + padding-left: 0.4em; } .wp-media-buttons a { text-decoration: none; - color: #333; + color: #464646; font-size: 12px; - vertical-align: bottom; } .wp-media-buttons img { diff --git a/wp-includes/js/mce-view.js b/wp-includes/js/mce-view.js index d2c9e55d50..d16fe1601e 100644 --- a/wp-includes/js/mce-view.js +++ b/wp-includes/js/mce-view.js @@ -359,45 +359,68 @@ if ( typeof wp === 'undefined' ) // Default TinyMCE Views // --------------------- (function($){ - var mceview = wp.mce.view, - mceFreeAttrs; + var mceview = wp.mce.view; + + wp.media.string = {}; + wp.media.string.image = function( attachment, props ) { + var classes, img, options, size; + + attachment = attachment.toJSON(); + + props = _.defaults( props || {}, { + img: {}, + align: getUserSetting( 'align', 'none' ), + size: getUserSetting( 'imgsize', 'medium' ), + link: getUserSetting( 'urlbutton', 'post' ) + }); + + img = _.clone( props.img ); + classes = img['class'] ? img['class'].split(/\s+/) : []; + size = attachment.sizes ? attachment.sizes[ props.size ] : {}; + + if ( ! size ) + delete props.size; + + img.width = size.width || attachment.width; + img.height = size.height || attachment.height; + img.src = size.url || attachment.url; + + // Update `img` classes. + if ( props.align ) + classes.push( 'align' + props.align ); + + if ( props.size ) + classes.push( 'size-' + props.size ); + + classes.push( 'wp-image-' + attachment.id ); + + img['class'] = _.compact( classes ).join(' '); + + // Generate `img` tag options. + options = { + tag: 'img', + attrs: img, + single: true + }; + + // Generate the `a` element options, if they exist. + if ( props.anchor ) { + options = { + tag: 'a', + attrs: props.anchor, + content: options + }; + } + + return wp.html.string( options ); + }; mceview.add( 'attachment', { pattern: new RegExp( '(?:]*)>)?]*class=(?:"[^"]*|\'[^\']*)\\bwp-image-(\\d+)[^>]*)>(?:)?' ), text: function( instance ) { - var img = _.clone( instance.img ), - classes = img['class'].split(/\s+/), - options; - - // Update `img` classes. - if ( instance.align ) - classes.push( 'align' + instance.align ); - - if ( instance.size ) - classes.push( 'size-' + instance.size ); - - classes.push( 'wp-image-' + instance.model.id ); - - img['class'] = _.compact( classes ).join(' '); - - // Generate `img` tag options. - options = { - tag: 'img', - attrs: img, - single: true - }; - - // Generate the `a` element options, if they exist. - if ( instance.anchor ) { - options = { - tag: 'a', - attrs: instance.anchor, - content: options - }; - } - - return wp.html.string( options ); + var props = _.pick( instance, 'align', 'size', 'link', 'img', 'anchor' ); + return wp.media.string.image( instance.model, props ); }, view: { diff --git a/wp-includes/js/media-views.js b/wp-includes/js/media-views.js index f3bec0cdb2..4d30d594b6 100644 --- a/wp-includes/js/media-views.js +++ b/wp-includes/js/media-views.js @@ -116,6 +116,12 @@ return this; }, + update: function() { + this.close(); + this.trigger( 'update', this.selection ); + this.selection.clear(); + }, + createSelection: function() { var controller = this; @@ -479,7 +485,8 @@ 'insert-into-post': { text: l10n.insertIntoPost, - priority: 30 + priority: 30, + click: _.bind( controller.update, controller ) }, 'add-to-gallery': { @@ -528,24 +535,23 @@ this.toolbarView = new media.view.Toolbar({ items: { 'return-to-library': { - text: 'Return to media library', + text: l10n.returnToLibrary, priority: -40, + click: function() { controller.render('library'); } }, 'insert-gallery-into-post': { - style: 'primary', - text: 'Insert gallery into post', + style: 'primary', + text: l10n.insertGalleryIntoPost, priority: 40, - click: function() { - controller.close(); - } + click: _.bind( controller.update, controller ) }, - 'add-images': { - text: 'Add images from media library', + 'add-images-from-library': { + text: l10n.addImagesFromLibrary, priority: 30 } } diff --git a/wp-includes/script-loader.php b/wp-includes/script-loader.php index f002abd2b4..451ea2cb34 100644 --- a/wp-includes/script-loader.php +++ b/wp-includes/script-loader.php @@ -297,7 +297,7 @@ function wp_default_scripts( &$scripts ) { 'type' => 'characters' == _x( 'words', 'word count: words or characters?' ) ? 'c' : 'w', ) ); - $scripts->add( 'media-upload', "/wp-admin/js/media-upload$suffix.js", array( 'thickbox' ), false, 1 ); + $scripts->add( 'media-upload', "/wp-admin/js/media-upload$suffix.js", array( 'thickbox', 'mce-view' ), false, 1 ); $scripts->add( 'hoverIntent', "/wp-includes/js/hoverIntent$suffix.js", array('jquery'), 'r6', 1 ); @@ -317,12 +317,20 @@ function wp_default_scripts( &$scripts ) { $scripts->add( 'media-models', "/wp-includes/js/media-models$suffix.js", array( 'backbone', 'jquery' ), false, 1 ); $scripts->add( 'media-views', "/wp-includes/js/media-views$suffix.js", array( 'media-models', 'wp-plupload' ), false, 1 ); did_action( 'init' ) && $scripts->localize( 'media-views', '_wpMediaViewsL10n', array( - 'insertMedia' => __( 'Insert Media' ), - 'selectMediaSingular' => __( 'Select a media file:' ), - 'selectMediaMultiple' => __( 'Select one or more media files:' ), - 'createNewGallery' => __( 'Create a new gallery' ), - 'insertIntoPost' => __( 'Insert into post' ), - 'addToGallery' => __( 'Add to gallery' ), + // Generic + 'insertMedia' => __( 'Insert Media' ), + 'selectMediaSingular' => __( 'Select a media file:' ), + 'selectMediaMultiple' => __( 'Select one or more media files:' ), + + // Library + 'createNewGallery' => __( 'Create a new gallery' ), + 'insertIntoPost' => __( 'Insert into post' ), + 'addToGallery' => __( 'Add to gallery' ), + + // Gallery + 'returnToLibrary' => __( 'Return to media library' ), + 'insertGalleryIntoPost' => __( 'Insert gallery into post' ), + 'addImagesFromLibrary' => __( 'Add images from media library' ), ) ); $scripts->add( 'shortcode', "/wp-includes/js/shortcode$suffix.js", array( 'underscore' ), false, 1 );