Edit Image modal:

- Bring back some of the advanced settings.
- Make the layout two-column for wider screens, remove the sidebar, and shrink the modal a bit.
- The image reflects the size as inserted in the post as long as it doesn't overflow the column and is not too tall. Changing the size to another intermediate will also update the image "preview."
- Rename "Edit Image" to "Edit Original" to try and better communicate that editing the image will modify the media library item not just the image inserted into the post that is being edited.
(updates two PNGs from precommit)
Props gcorne, see #27366
Built from https://develop.svn.wordpress.org/trunk@27797


git-svn-id: http://core.svn.wordpress.org/trunk@27632 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Andrew Ozz 2014-03-27 22:41:14 +00:00
parent 703f6fcc49
commit 60435c4143
12 changed files with 430 additions and 150 deletions

View File

@ -1462,6 +1462,10 @@
padding: 16px;
}
.media-frame .imgedit-wrap table {
width: 100%;
}
.media-frame .imgedit-wrap table td {
vertical-align: top;
padding-top: 0;
@ -1513,10 +1517,49 @@
overflow: auto;
}
.image-details .media-modal {
right: 140px;
left: 140px;
}
.image-details .media-frame-menu {
display: none;
}
.image-details .media-frame-title,
.image-details .media-frame-content,
.image-details .media-frame-router {
right: 0;
}
.image-details .embed-media-settings {
top: 0;
overflow: visible;
}
.image-details .column-settings {
width: 44%;
float: right;
margin-left: 20px;
}
.image-details .column-image {
width: 53%;
float: right;
}
.image-details .column-image:after {
content: '';
display: table;
clear: both;
}
.image-details .image img {
max-width: 100%;
max-height: 500px;
}
.media-embed .thumbnail {
max-width: 100%;
max-height: 200px;
@ -1529,10 +1572,6 @@
display: block;
}
.media-embed .edit-attachment {
margin-right: 10px;
}
.media-embed .thumbnail:after {
content: '';
display: block;
@ -1548,13 +1587,34 @@
.media-embed .setting {
width: 100%;
margin-top: 10px;
margin: 10px 0;
float: right;
display: block;
clear: both;
}
.media-embed .setting .hidden {
.image-details .setting {
float: none;
}
.image-details .actions {
margin: 10px 0;
}
.media-embed .setting input[type="text"],
.media-embed .setting textarea {
display: block;
width: 100%;
max-width: 400px;
margin: 1px 0;
}
.image-details .setting input[type="text"],
.image-details .setting textarea {
max-width: inherit;
}
.media-embed .setting input.hidden {
display: none;
}
@ -1570,12 +1630,19 @@
margin: 2px 0;
}
.media-embed .setting input[type="text"],
.media-embed .setting textarea {
display: block;
width: 100%;
max-width: 400px;
margin: 1px 0;
.media-embed-sidebar {
position: absolute;
top: 0;
right: 440px;
}
.advanced,
.link-settings {
margin-top: 10px;
}
.advanced .hidden {
display: none;
}
/* Drag & drop on the editor upload */
@ -1781,6 +1848,11 @@
top: 40%;
}
.image-details .media-modal {
right: 30px;
left: 30px;
}
.media-selection {
min-width: 120px;
}
@ -1849,6 +1921,12 @@
display: none;
}
.image-details .media-frame-title {
display: block;
top: 0;
font-size: 14px;
}
.media-frame-toolbar {
position: absolute;
bottom: 0px;
@ -1905,6 +1983,10 @@
top: 118px;
}
.image-details .media-frame.hide-router .media-frame-content {
top: 40px;
}
.media-frame .attachments-browser {
padding-bottom: 300px;
}
@ -1939,7 +2021,8 @@
}
/* Full-bleed modal */
.media-modal {
.media-modal,
.image-details .media-modal {
position: fixed;
top: 0;
right: 0;
@ -1975,6 +2058,12 @@
padding-bottom: 52px;
}
.image-details .column-settings,
.image-details .column-image {
float: none;
width: 100%;
}
/* Gallery */
.media-frame.hide-router .media-frame-content {
top: 73px;

File diff suppressed because one or more lines are too long

View File

@ -1462,6 +1462,10 @@
padding: 16px;
}
.media-frame .imgedit-wrap table {
width: 100%;
}
.media-frame .imgedit-wrap table td {
vertical-align: top;
padding-top: 0;
@ -1513,10 +1517,49 @@
overflow: auto;
}
.image-details .media-modal {
left: 140px;
right: 140px;
}
.image-details .media-frame-menu {
display: none;
}
.image-details .media-frame-title,
.image-details .media-frame-content,
.image-details .media-frame-router {
left: 0;
}
.image-details .embed-media-settings {
top: 0;
overflow: visible;
}
.image-details .column-settings {
width: 44%;
float: left;
margin-right: 20px;
}
.image-details .column-image {
width: 53%;
float: left;
}
.image-details .column-image:after {
content: '';
display: table;
clear: both;
}
.image-details .image img {
max-width: 100%;
max-height: 500px;
}
.media-embed .thumbnail {
max-width: 100%;
max-height: 200px;
@ -1529,10 +1572,6 @@
display: block;
}
.media-embed .edit-attachment {
margin-left: 10px;
}
.media-embed .thumbnail:after {
content: '';
display: block;
@ -1548,13 +1587,34 @@
.media-embed .setting {
width: 100%;
margin-top: 10px;
margin: 10px 0;
float: left;
display: block;
clear: both;
}
.media-embed .setting .hidden {
.image-details .setting {
float: none;
}
.image-details .actions {
margin: 10px 0;
}
.media-embed .setting input[type="text"],
.media-embed .setting textarea {
display: block;
width: 100%;
max-width: 400px;
margin: 1px 0;
}
.image-details .setting input[type="text"],
.image-details .setting textarea {
max-width: inherit;
}
.media-embed .setting input.hidden {
display: none;
}
@ -1570,12 +1630,19 @@
margin: 2px 0;
}
.media-embed .setting input[type="text"],
.media-embed .setting textarea {
display: block;
width: 100%;
max-width: 400px;
margin: 1px 0;
.media-embed-sidebar {
position: absolute;
top: 0;
left: 440px;
}
.advanced,
.link-settings {
margin-top: 10px;
}
.advanced .hidden {
display: none;
}
/* Drag & drop on the editor upload */
@ -1781,6 +1848,11 @@
top: 40%;
}
.image-details .media-modal {
left: 30px;
right: 30px;
}
.media-selection {
min-width: 120px;
}
@ -1849,6 +1921,12 @@
display: none;
}
.image-details .media-frame-title {
display: block;
top: 0;
font-size: 14px;
}
.media-frame-toolbar {
position: absolute;
bottom: 0px;
@ -1905,6 +1983,10 @@
top: 118px;
}
.image-details .media-frame.hide-router .media-frame-content {
top: 40px;
}
.media-frame .attachments-browser {
padding-bottom: 300px;
}
@ -1939,7 +2021,8 @@
}
/* Full-bleed modal */
.media-modal {
.media-modal,
.image-details .media-modal {
position: fixed;
top: 0;
left: 0;
@ -1975,6 +2058,12 @@
padding-bottom: 52px;
}
.image-details .column-settings,
.image-details .column-image {
float: none;
width: 100%;
}
/* Gallery */
.media-frame.hide-router .media-frame-content {
top: 73px;

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 584 B

After

Width:  |  Height:  |  Size: 417 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 583 B

After

Width:  |  Height:  |  Size: 382 B

View File

@ -761,6 +761,10 @@
initialize: function( options ) {
this.image = options.image;
media.controller.State.prototype.initialize.apply( this, arguments );
},
activate: function() {
this.frame.modal.$el.addClass('image-details');
}
});
@ -2622,7 +2626,6 @@
},
renderMenu: function( view ) {
var lastState = this.lastState(),
previous = lastState && lastState.id,
@ -2677,9 +2680,25 @@
},
renderReplaceImageToolbar: function() {
var frame = this,
lastState = frame.lastState(),
previous = lastState && lastState.id;
this.toolbar.set( new media.view.Toolbar({
controller: this,
items: {
back: {
text: l10n.back,
priority: 20,
click: function() {
if ( previous ) {
frame.setState( previous );
} else {
frame.close();
}
}
},
replace: {
style: 'primary',
text: l10n.replace,
@ -5970,13 +5989,16 @@
className: 'image-details',
template: media.template('image-details'),
events: _.defaults( media.view.Settings.AttachmentDisplay.prototype.events, {
'click .edit-attachment': 'editAttachment'
'click .edit-attachment': 'editAttachment',
'click .replace-attachment': 'replaceAttachment',
'click .show-advanced': 'showAdvanced'
} ),
initialize: function() {
// used in AttachmentDisplay.prototype.updateLinkTo
this.options.attachment = this.model.attachment;
if ( this.model.attachment ) {
this.listenTo( this.model.attachment, 'change:url', this.updateUrl );
this.listenTo( this.model, 'change:url', this.updateUrl );
this.listenTo( this.model, 'change:link', this.toggleLinkSettings );
}
media.view.Settings.AttachmentDisplay.prototype.initialize.apply( this, arguments );
},
@ -6001,29 +6023,47 @@
this.model.dfd.done( function() {
media.view.Settings.AttachmentDisplay.prototype.render.apply( self, args );
self.resetFocus();
self.toggleLinkSettings();
} ).fail( function() {
self.model.attachment = false;
media.view.Settings.AttachmentDisplay.prototype.render.apply( self, args );
self.resetFocus();
self.toggleLinkSettings();
} );
} else {
media.view.Settings.AttachmentDisplay.prototype.render.apply( this, arguments );
setTimeout( function() { self.resetFocus(); }, 10 );
self.toggleLinkSettings();
}
return this;
},
resetFocus: function() {
this.$( '.caption textarea' ).focus();
this.$( '.embed-image-settings' ).scrollTop( 0 );
this.$( '.link-to-custom' ).blur();
this.$( '.embed-media-settings' ).scrollTop( 0 );
},
updateUrl: function() {
this.$( '.thumbnail img' ).attr( 'src', this.model.get('url' ) );
this.$( '.image img' ).attr( 'src', this.model.get('url' ) );
this.$( '.url' ).val( this.model.get('url' ) );
},
toggleLinkSettings: function() {
if ( this.model.get( 'link' ) === 'none' ) {
this.$( '.link-settings' ).addClass('hidden');
} else {
this.$( '.link-settings' ).removeClass('hidden');
}
},
showAdvanced: function( event ) {
event.preventDefault();
$( event.target ).closest('.advanced')
.find( '.hidden' ).removeClass( 'hidden' );
$( event.target ).remove();
},
editAttachment: function( event ) {
var editState = this.controller.states.get( 'edit-image' );
@ -6032,6 +6072,11 @@
editState.set( 'image', this.model.attachment );
this.controller.setState( 'edit-image' );
}
},
replaceAttachment: function( event ) {
event.preventDefault();
this.controller.setState( 'replace-image' );
}
});

File diff suppressed because one or more lines are too long

View File

@ -114,7 +114,7 @@ tinymce.PluginManager.add( 'wpeditimage', function( editor ) {
}
function extractImageData( imageNode ) {
var classes, metadata, captionBlock, caption,
var classes, metadata, captionBlock, caption, link,
dom = editor.dom;
// default attributes
@ -123,25 +123,27 @@ tinymce.PluginManager.add( 'wpeditimage', function( editor ) {
url: false,
height: '',
width: '',
size: 'none',
size: false,
caption: '',
alt: '',
align: 'none',
link: false,
linkUrl: ''
linkUrl: '',
linkClassName: '',
linkTargetBlank: false,
linkRel: '',
title: '',
className: ''
};
metadata.url = dom.getAttrib( imageNode, 'src' );
metadata.alt = dom.getAttrib( imageNode, 'alt' );
metadata.title = dom.getAttrib( imageNode, 'title' );
metadata.width = parseInt( dom.getAttrib( imageNode, 'width' ), 10 );
metadata.height = parseInt( dom.getAttrib( imageNode, 'height' ), 10 );
metadata.className = imageNode.className;
//TODO: probably should capture attributes on both the <img /> and the <a /> so that they can be restored
// when the image and/or caption are updated
// maybe use getAttribs()
// extract meta data from classes (candidate for turning into a method)
classes = imageNode.className.split( ' ' );
classes = metadata.className.split( ' ' );
tinymce.each( classes, function( name ) {
if ( /^wp-image/.test( name ) ) {
@ -157,7 +159,7 @@ tinymce.PluginManager.add( 'wpeditimage', function( editor ) {
}
} );
// extract caption
// Extract caption
captionBlock = dom.getParents( imageNode, '.wp-caption' );
if ( captionBlock.length ) {
@ -173,15 +175,19 @@ tinymce.PluginManager.add( 'wpeditimage', function( editor ) {
caption = dom.select( 'dd.wp-caption-dd', captionBlock );
if ( caption.length ) {
caption = caption[0];
// need to do some more thinking about this
metadata.caption = editor.serializer.serialize( caption )
.replace( /<br[^>]*>/g, '$&\n' ).replace( /^<p>/, '' ).replace( /<\/p>$/, '' );
}
}
// extract linkTo
// Extract linkTo
if ( imageNode.parentNode && imageNode.parentNode.nodeName === 'A' ) {
metadata.linkUrl = dom.getAttrib( imageNode.parentNode, 'href' );
link = imageNode.parentNode;
metadata.linkUrl = dom.getAttrib( link, 'href' );
metadata.linkTargetBlank = dom.getAttrib( link, 'target' ) === '_blank' ? true : false;
metadata.linkRel = dom.getAttrib( link, 'rel' );
metadata.linkClassName = link.className;
}
return metadata;
@ -223,7 +229,7 @@ tinymce.PluginManager.add( 'wpeditimage', function( editor ) {
nodeToReplace = imageNode.parentNode;
}
}
// uniqueId isn't super exciting, so maybe we want to use something else
uid = editor.dom.uniqueId( 'wp_' );
editor.dom.setAttrib( node, 'data-wp-replace-id', uid );
editor.dom.replace( node, nodeToReplace );
@ -246,7 +252,7 @@ tinymce.PluginManager.add( 'wpeditimage', function( editor ) {
function createImageAndLink( imageData, mode ) {
var classes = [],
props;
attrs, linkAttrs;
mode = mode ? mode : 'node';
@ -261,27 +267,46 @@ tinymce.PluginManager.add( 'wpeditimage', function( editor ) {
}
}
props = {
attrs = {
src: imageData.url,
width: imageData.width,
height: imageData.height,
alt: imageData.alt
alt: imageData.alt,
title: imageData.title || null
};
if ( classes.length ) {
props['class'] = classes.join( ' ' );
attrs['class'] = classes.join( ' ' );
}
if ( imageData.linkUrl ) {
if ( mode === 'node' ) {
return editor.dom.create( 'a', { href: imageData.linkUrl }, editor.dom.createHTML( 'img', props ) );
} else if ( mode === 'html' ) {
return editor.dom.createHTML( 'a', { href: imageData.linkUrl }, editor.dom.createHTML( 'img', props ) );
linkAttrs = {
href: imageData.linkUrl
};
if ( imageData.linkRel ) {
linkAttrs.rel = imageData.linkRel;
}
if ( imageData.linkTargetBlank ) {
linkAttrs.target = '_blank';
}
if ( imageData.linkClassName ) {
linkAttrs['class'] = imageData.linkClassName;
}
if ( mode === 'node' ) {
return editor.dom.create( 'a', linkAttrs, editor.dom.createHTML( 'img', attrs ) );
} else if ( mode === 'html' ) {
return editor.dom.createHTML( 'a', linkAttrs, editor.dom.createHTML( 'img', attrs ) );
}
} else if ( mode === 'node' ) {
return editor.dom.create( 'img', props );
return editor.dom.create( 'img', attrs );
} else if ( mode === 'html' ) {
return editor.dom.createHTML( 'img', props );
return editor.dom.createHTML( 'img', attrs );
}
}

File diff suppressed because one or more lines are too long

View File

@ -638,101 +638,133 @@ function wp_print_media_templates() {
</script>
<script type="text/html" id="tmpl-image-details">
<?php // reusing .media-embed to pick up the styles for now ?>
<div class="media-embed">
<div class="embed-media-settings">
<div class="thumbnail">
<img src="{{ data.model.url }}" draggable="false" />
</div>
<# if ( data.attachment && window.imageEdit ) { #>
<input type="button" class="edit-attachment button" value="<?php esc_attr_e( 'Edit Image' ); ?>" />
<# } #>
<div class="column-settings">
<?php
/** This filter is documented in wp-admin/includes/media.php */
if ( ! apply_filters( 'disable_captions', '' ) ) : ?>
<label class="setting caption">
<span><?php _e('Caption'); ?></span>
<textarea data-setting="caption">{{ data.model.caption }}</textarea>
</label>
<?php endif; ?>
<div class="setting url">
<?php // might want to make the url editable if it isn't an attachment ?>
<input type="text" disabled="disabled" value="{{ data.model.url }}" />
</div>
<?php
/** This filter is documented in wp-admin/includes/media.php */
if ( ! apply_filters( 'disable_captions', '' ) ) : ?>
<label class="setting caption">
<span><?php _e('Caption'); ?></span>
<textarea data-setting="caption">{{ data.model.caption }}</textarea>
<label class="setting alt-text">
<span><?php _e('Alternative Text'); ?></span>
<input type="text" data-setting="alt" value="{{ data.model.alt }}" />
</label>
<?php endif; ?>
<label class="setting alt-text">
<span><?php _e('Alt Text'); ?></span>
<input type="text" data-setting="alt" value="{{ data.model.alt }}" />
</label>
<div class="setting align">
<span><?php _e('Align'); ?></span>
<div class="button-group button-large" data-setting="align">
<button class="button" value="left">
<?php esc_attr_e('Left'); ?>
</button>
<button class="button" value="center">
<?php esc_attr_e('Center'); ?>
</button>
<button class="button" value="right">
<?php esc_attr_e('Right'); ?>
</button>
<button class="button active" value="none">
<?php esc_attr_e('None'); ?>
</button>
</div>
</div>
<div class="setting link-to">
<span><?php _e('Link To'); ?></span>
<div class="button-group button-large" data-setting="link">
<# if ( data.attachment ) { #>
<button class="button" value="file">
<?php esc_attr_e('Media File'); ?>
</button>
<button class="button" value="post">
<?php esc_attr_e('Attachment Page'); ?>
</button>
<# } else { #>
<button class="button" value="file">
<?php esc_attr_e('Image URL'); ?>
</button>
<# } #>
<button class="button" value="custom">
<?php esc_attr_e('Custom URL'); ?>
</button>
<button class="button active" value="none">
<?php esc_attr_e('None'); ?>
</button>
</div>
<input type="text" class="link-to-custom" data-setting="linkUrl" />
</div>
<# if ( data.attachment ) { #>
<div class="setting size">
<span><?php _e('Size'); ?></span>
<div class="button-group button-large" data-setting="size">
<?php
/** This filter is documented in wp-admin/includes/media.php */
$sizes = apply_filters( 'image_size_names_choose', array(
'thumbnail' => __('Thumbnail'),
'medium' => __('Medium'),
'large' => __('Large'),
'full' => __('Full Size'),
) );
foreach ( $sizes as $value => $name ) : ?>
<# var size = data.attachment.sizes['<?php echo esc_js( $value ); ?>'];
if ( size ) { #>
<button class="button" value="<?php echo esc_attr( $value ); ?>">
<?php echo esc_html( $name ); ?>
</button>
<# } #>
<?php endforeach; ?>
<div class="setting advanced">
<a class="show-advanced" href="#"><?php _e('show advanced'); ?></a>
<div class="hidden">
<label class="setting title-text">
<span><?php _e('Title Attribute'); ?></span>
<input type="text" data-setting="title" value="{{ data.model.title }}" />
</label>
</div>
</div>
<# } #>
<div class="setting align">
<span><?php _e('Align'); ?></span>
<div class="button-group button-large" data-setting="align">
<button class="button" value="left">
<?php esc_attr_e('Left'); ?>
</button>
<button class="button" value="center">
<?php esc_attr_e('Center'); ?>
</button>
<button class="button" value="right">
<?php esc_attr_e('Right'); ?>
</button>
<button class="button active" value="none">
<?php esc_attr_e('None'); ?>
</button>
</div>
</div>
<# if ( data.attachment ) { #>
<div class="setting size">
<span><?php _e('Size'); ?></span>
<div class="button-group button-large" data-setting="size">
<?php
/** This filter is documented in wp-admin/includes/media.php */
$sizes = apply_filters( 'image_size_names_choose', array(
'thumbnail' => __('Thumbnail'),
'medium' => __('Medium'),
'large' => __('Large'),
'full' => __('Full Size'),
) );
foreach ( $sizes as $value => $name ) : ?>
<# var size = data.attachment.sizes['<?php echo esc_js( $value ); ?>'];
if ( size ) { #>
<button class="button" value="<?php echo esc_attr( $value ); ?>">
<?php echo esc_html( $name ); ?>
</button>
<# } #>
<?php endforeach; ?>
</div>
</div>
<# } #>
<div class="setting link-to">
<span><?php _e('Link To'); ?></span>
<div class="button-group button-large" data-setting="link">
<# if ( data.attachment ) { #>
<button class="button" value="file">
<?php esc_attr_e('Media File'); ?>
</button>
<button class="button" value="post">
<?php esc_attr_e('Attachment Page'); ?>
</button>
<# } else { #>
<button class="button" value="file">
<?php esc_attr_e('Image URL'); ?>
</button>
<# } #>
<button class="button" value="custom">
<?php esc_attr_e('Custom URL'); ?>
</button>
<button class="button active" value="none">
<?php esc_attr_e('None'); ?>
</button>
</div>
<input type="text" class="link-to-custom" data-setting="linkUrl" />
</div>
<div class="setting link-settings">
<div class="setting link-target">
<label><input type="checkbox" data-setting="linkTargetBlank" value="_blank" <# if ( data.model.linkTargetBlank ) { #>checked="checked"<# } #>><?php _e( 'Open link in a new window/tab' ); ?></label>
</div>
<div class="advanced">
<a class="show-advanced" href="#"><?php _e('show advanced'); ?></a>
<div class="hidden">
<label class="setting link-rel">
<span><?php _e('Link Rel'); ?></span>
<input type="text" data-setting="linkRel" value="{{ data.model.linkClassName }}" />
</label>
<label class="setting link-class-name">
<span><?php _e('CSS Class'); ?></span>
<input type="text" data-setting="linkClassName" value="{{ data.model.linkClassName }}" />
</label>
</div>
</div>
</div>
</div>
<div class="column-image">
<div class="image">
<img src="{{ data.model.url }}" draggable="false" />
</div>
<# if ( data.attachment && window.imageEdit ) { #>
<div class="actions">
<input type="button" class="edit-attachment button" value="<?php esc_attr_e( 'Edit Original' ); ?>" />
<input type="button" class="replace-attachment button" value="<?php esc_attr_e( 'Replace' ); ?>" />
</div>
<# } #>
</div>
</div>
</div>
</script>