Edit Image modal:

- Move all advanced options under a single “Show advanced options” toggle that mirrors the behavior and look-and-feel of the wplink modal.
- Switch to using <select> for the Size and Link To.
- Bring back the field for CSS Class for the image, but don’t incorporate the internally managed WordPress classes (size-, wp-image-, etc…).
- On larger screen sizes, float labels to the left. When the width drops below 900px, stack the label above the fields.
- Keep image at top on screen sizes where the two columns are stacked into a single column.
- Don't replace the nodes in the editor DOM so we don't stomp on any custom attributes that the user may have added via the Text editor or some other mechanism.
Props gcorne, see #27366
Built from https://develop.svn.wordpress.org/trunk@27898


git-svn-id: http://core.svn.wordpress.org/trunk@27729 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Andrew Ozz 2014-04-02 01:54:15 +00:00
parent 2547ba21ae
commit 56ede0bad7
10 changed files with 399 additions and 226 deletions

View File

@ -270,7 +270,8 @@
width: 100%;
}
.media-sidebar h3 {
.media-sidebar h3,
.image-details h3 {
position: relative;
font-weight: bold;
text-transform: uppercase;
@ -1603,23 +1604,34 @@
.image-details .embed-media-settings {
top: 0;
overflow: visible;
padding: 0;
}
.image-details .column-settings {
width: 44%;
float: right;
margin-left: 20px;
background: #f3f3f3;
border-left: 1px solid #ddd;
min-height: 100%;
width: 52%;
position: absolute;
top: 0;
right: 0;
}
.image-details .column-settings h3 {
margin: 20px;
padding-top: 20px;
border-top: 1px solid #ddd;
}
.image-details .column-image {
width: 53%;
float: right;
width: 48%;
position: absolute;
right: 52%;
top: 0;
}
.image-details .column-image:after {
content: '';
display: table;
clear: both;
.image-details .image {
margin: 20px;
}
.image-details .image img {
@ -1627,6 +1639,29 @@
max-height: 500px;
}
.image-details .advanced-toggle {
font-style: italic;
color: #666;
text-decoration: none;
margin: 20px;
display: block;
}
.image-details .advanced-toggle::after {
font: normal 20px/1 'dashicons';
speak: none;
vertical-align: top;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
content: '\f140';
display: inline-block;
margin-top: -2px;
}
.image-details .advanced-visible .advanced-toggle::after {
content: '\f142';
margin-top: 0;
}
.media-embed .thumbnail {
max-width: 100%;
@ -1661,14 +1696,19 @@
clear: both;
}
.image-details .setting {
.image-details .embed-media-settings .setting {
float: none;
width: auto;
}
.image-details .actions {
margin: 10px 0;
}
.image-details .hidden {
display: none;
}
.media-embed .setting input[type="text"],
.media-embed .setting textarea {
display: block;
@ -1677,9 +1717,20 @@
margin: 1px 0;
}
.image-details .setting input[type="text"],
.image-details .setting textarea {
.image-details .embed-media-settings .setting input[type="text"],
.image-details .embed-media-settings .setting textarea {
max-width: inherit;
width: 70%;
}
.image-details .embed-media-settings .setting input.link-to-custom,
.image-details .embed-media-settings .link-target {
margin-right: 27%;
width: 70%;
}
.image-details .embed-media-settings .link-target {
margin-top: 24px;
}
.media-embed .setting input.hidden {
@ -1694,6 +1745,14 @@
color: #666;
}
.image-details .embed-media-settings .setting span {
float: right;
width: 25%;
text-align: left;
margin: 8px 1% 0 1%;
line-height: 1.1;
}
.media-embed .setting .button-group {
margin: 2px 0;
}
@ -1709,10 +1768,6 @@
margin-top: 10px;
}
.advanced .hidden {
display: none;
}
/* Drag & drop on the editor upload */
#wp-fullscreen-body .uploader-editor,
.wp-editor-wrap .uploader-editor {
@ -1930,6 +1985,28 @@
left: 30px;
}
.image-details .embed-media-settings .setting {
margin: 20px;
}
.image-details .embed-media-settings .setting span {
float: none;
text-align: right;
width: 100%;
margin-bottom: 4px;
}
.image-details .embed-media-settings .setting input.link-to-custom,
.image-details .embed-media-settings .setting input[type="text"],
.image-details .embed-media-settings .setting textarea {
width: 100%;
margin-right: 0;
}
.image-details .link-target {
width: 100%;
}
.media-selection {
min-width: 120px;
}
@ -2137,10 +2214,14 @@
.image-details .column-settings,
.image-details .column-image {
float: none;
position: relative;
padding: 10px 0 20px 0;
right: 0;
width: 100%;
min-height: inherit;
}
/* Gallery */
.media-frame.hide-router .media-frame-content {
top: 73px;

File diff suppressed because one or more lines are too long

View File

@ -270,7 +270,8 @@
width: 100%;
}
.media-sidebar h3 {
.media-sidebar h3,
.image-details h3 {
position: relative;
font-weight: bold;
text-transform: uppercase;
@ -1603,23 +1604,34 @@
.image-details .embed-media-settings {
top: 0;
overflow: visible;
padding: 0;
}
.image-details .column-settings {
width: 44%;
float: left;
margin-right: 20px;
background: #f3f3f3;
border-right: 1px solid #ddd;
min-height: 100%;
width: 52%;
position: absolute;
top: 0;
left: 0;
}
.image-details .column-settings h3 {
margin: 20px;
padding-top: 20px;
border-top: 1px solid #ddd;
}
.image-details .column-image {
width: 53%;
float: left;
width: 48%;
position: absolute;
left: 52%;
top: 0;
}
.image-details .column-image:after {
content: '';
display: table;
clear: both;
.image-details .image {
margin: 20px;
}
.image-details .image img {
@ -1627,6 +1639,29 @@
max-height: 500px;
}
.image-details .advanced-toggle {
font-style: italic;
color: #666;
text-decoration: none;
margin: 20px;
display: block;
}
.image-details .advanced-toggle::after {
font: normal 20px/1 'dashicons';
speak: none;
vertical-align: top;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
content: '\f140';
display: inline-block;
margin-top: -2px;
}
.image-details .advanced-visible .advanced-toggle::after {
content: '\f142';
margin-top: 0;
}
.media-embed .thumbnail {
max-width: 100%;
@ -1661,14 +1696,19 @@
clear: both;
}
.image-details .setting {
.image-details .embed-media-settings .setting {
float: none;
width: auto;
}
.image-details .actions {
margin: 10px 0;
}
.image-details .hidden {
display: none;
}
.media-embed .setting input[type="text"],
.media-embed .setting textarea {
display: block;
@ -1677,9 +1717,20 @@
margin: 1px 0;
}
.image-details .setting input[type="text"],
.image-details .setting textarea {
.image-details .embed-media-settings .setting input[type="text"],
.image-details .embed-media-settings .setting textarea {
max-width: inherit;
width: 70%;
}
.image-details .embed-media-settings .setting input.link-to-custom,
.image-details .embed-media-settings .link-target {
margin-left: 27%;
width: 70%;
}
.image-details .embed-media-settings .link-target {
margin-top: 24px;
}
.media-embed .setting input.hidden {
@ -1694,6 +1745,14 @@
color: #666;
}
.image-details .embed-media-settings .setting span {
float: left;
width: 25%;
text-align: right;
margin: 8px 1% 0 1%;
line-height: 1.1;
}
.media-embed .setting .button-group {
margin: 2px 0;
}
@ -1709,10 +1768,6 @@
margin-top: 10px;
}
.advanced .hidden {
display: none;
}
/* Drag & drop on the editor upload */
#wp-fullscreen-body .uploader-editor,
.wp-editor-wrap .uploader-editor {
@ -1930,6 +1985,28 @@
right: 30px;
}
.image-details .embed-media-settings .setting {
margin: 20px;
}
.image-details .embed-media-settings .setting span {
float: none;
text-align: left;
width: 100%;
margin-bottom: 4px;
}
.image-details .embed-media-settings .setting input.link-to-custom,
.image-details .embed-media-settings .setting input[type="text"],
.image-details .embed-media-settings .setting textarea {
width: 100%;
margin-left: 0;
}
.image-details .link-target {
width: 100%;
}
.media-selection {
min-width: 120px;
}
@ -2137,10 +2214,14 @@
.image-details .column-settings,
.image-details .column-image {
float: none;
position: relative;
padding: 10px 0 20px 0;
left: 0;
width: 100%;
min-height: inherit;
}
/* Gallery */
.media-frame.hide-router .media-frame-content {
top: 73px;

File diff suppressed because one or more lines are too long

View File

@ -6059,15 +6059,13 @@
events: _.defaults( media.view.Settings.AttachmentDisplay.prototype.events, {
'click .edit-attachment': 'editAttachment',
'click .replace-attachment': 'replaceAttachment',
'click .show-advanced': 'showAdvanced'
'click .advanced-toggle': 'toggleAdvanced'
} ),
initialize: function() {
// used in AttachmentDisplay.prototype.updateLinkTo
this.options.attachment = this.model.attachment;
if ( this.model.attachment ) {
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 );
},
@ -6125,11 +6123,16 @@
}
},
showAdvanced: function( event ) {
toggleAdvanced: function( event ) {
var $advanced = $( event.target ).closest( '.advanced' );
event.preventDefault();
$( event.target ).closest('.advanced')
.find( '.hidden' ).removeClass( 'hidden' );
$( event.target ).remove();
if ( $advanced.hasClass('advanced-visible') ) {
$advanced.removeClass('advanced-visible');
$advanced.find('div').addClass('hidden');
} else {
$advanced.addClass('advanced-visible');
$advanced.find('div').removeClass('hidden');
}
},
editAttachment: function( event ) {

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, link,
var classes, extraClasses, metadata, captionBlock, caption, link, width, height,
dom = editor.dom;
// default attributes
@ -127,38 +127,44 @@ tinymce.PluginManager.add( 'wpeditimage', function( editor ) {
caption: '',
alt: '',
align: 'none',
extraClasses: '',
link: false,
linkUrl: '',
linkClassName: '',
linkTargetBlank: false,
linkRel: '',
title: '',
className: ''
title: ''
};
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;
classes = metadata.className.split( ' ' );
width = dom.getAttrib( imageNode, 'width' ) || imageNode.width;
height = dom.getAttrib( imageNode, 'height' ) || imageNode.height;
metadata.width = parseInt( width, 10 );
metadata.height = parseInt( height, 10 );
classes = tinymce.explode( imageNode.className, ' ' );
extraClasses = [];
tinymce.each( classes, function( name ) {
if ( /^wp-image/.test( name ) ) {
metadata.attachment_id = parseInt( name.replace( 'wp-image-', '' ), 10 );
}
if ( /^align/.test( name ) ) {
} else if ( /^align/.test( name ) ) {
metadata.align = name.replace( 'align', '' );
} else if ( /^size/.test( name ) ) {
metadata.size = name.replace( 'size-', '' );
} else {
extraClasses.push( name );
}
if ( /^size/.test( name ) ) {
metadata.size = name.replace( 'size-', '' );
}
} );
metadata.extraClasses = extraClasses.join( ' ' );
// Extract caption
captionBlock = dom.getParents( imageNode, '.wp-caption' );
@ -194,68 +200,16 @@ tinymce.PluginManager.add( 'wpeditimage', function( editor ) {
}
function updateImage( imageNode, imageData ) {
var className, width, node, html, captionNode, nodeToReplace, uid, editedImg, id;
var classes, className, width, node, html, parent, wrap,
captionNode, dd, dl, id, attrs, linkAttrs,
dom = editor.dom;
if ( imageData.caption ) {
classes = tinymce.explode( imageData.extraClasses, ' ' );
html = createImageAndLink( imageData, 'html' );
width = parseInt( imageData.width, 10 );
if ( ! editor.getParam( 'wpeditimage_html5_captions' ) ) {
width += 10;
if ( ! classes ) {
classes = [];
}
className = 'align' + imageData.align;
id = imageData.attachment_id ? 'id="attachment_'+ imageData.attachment_id +'" ' : '';
// should create a new function for generating the caption markup
html = '<dl ' + id + 'class="wp-caption '+ className +'" style="width: '+ width +'px">' +
'<dt class="wp-caption-dt">'+ html + '</dt><dd class="wp-caption-dd">'+ imageData.caption +'</dd></dl>';
node = editor.dom.create( 'div', { 'class': 'mceTemp' }, html );
} else {
node = createImageAndLink( imageData, 'node' );
}
nodeToReplace = imageNode;
captionNode = editor.dom.getParent( imageNode, '.mceTemp' );
if ( captionNode ) {
nodeToReplace = captionNode;
} else {
if ( imageNode.parentNode.nodeName === 'A' ) {
nodeToReplace = imageNode.parentNode;
}
}
uid = editor.dom.uniqueId( 'wp_' );
editor.dom.setAttrib( node, 'data-wp-replace-id', uid );
editor.dom.replace( node, nodeToReplace );
// find the updated node
node = editor.dom.select( '[data-wp-replace-id="' + uid + '"]' )[0];
editor.dom.setAttrib( node, 'data-wp-replace-id', '' );
editor.nodeChanged();
editedImg = node.nodeName === 'IMG' ? node : editor.dom.select( 'img', node )[0];
if ( editedImg ) {
editor.selection.select( editedImg );
// refresh toolbar
addToolbar( editedImg );
}
}
function createImageAndLink( imageData, mode ) {
var classes = [],
attrs, linkAttrs;
mode = mode ? mode : 'node';
if ( ! imageData.caption ) {
classes.push( 'align' + imageData.align );
}
@ -269,45 +223,97 @@ tinymce.PluginManager.add( 'wpeditimage', function( editor ) {
attrs = {
src: imageData.url,
width: imageData.width,
height: imageData.height,
width: imageData.width || null,
height: imageData.height || null,
alt: imageData.alt,
title: imageData.title || null
title: imageData.title || null,
'class': classes.join( ' ' ) || null
};
if ( classes.length ) {
attrs['class'] = classes.join( ' ' );
}
if ( imageData.linkUrl ) {
dom.setAttribs( imageNode, attrs );
linkAttrs = {
href: imageData.linkUrl
href: imageData.linkUrl,
rel: imageData.linkRel || null,
target: imageData.linkTargetBlank ? '_blank': null,
'class': imageData.linkClassName || null
};
if ( imageData.linkRel ) {
linkAttrs.rel = imageData.linkRel;
if ( imageNode.parentNode.nodeName === 'A' ) {
if ( imageData.linkUrl ) {
dom.setAttribs( imageNode.parentNode, linkAttrs );
} else {
dom.remove( imageNode.parentNode, true );
}
} else if ( imageData.linkUrl ) {
html = dom.createHTML( 'a', linkAttrs, dom.getOuterHTML( imageNode ) );
dom.outerHTML( imageNode, html );
}
if ( imageData.linkTargetBlank ) {
linkAttrs.target = '_blank';
captionNode = editor.dom.getParent( imageNode, '.mceTemp' );
if ( imageNode.parentNode.nodeName === 'A' ) {
node = imageNode.parentNode;
} else {
node = imageNode;
}
if ( imageData.linkClassName ) {
linkAttrs['class'] = imageData.linkClassName;
if ( imageData.caption ) {
width = parseInt( imageData.width, 10 );
id = imageData.attachment_id ? 'attachment_' + imageData.attachment_id : null;
className = 'wp-caption align' + imageData.align;
if ( ! editor.getParam( 'wpeditimage_html5_captions' ) ) {
width += 10;
}
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 ) );
if ( captionNode ) {
dl = dom.select( 'dl.wp-caption', captionNode );
if ( dl.length ) {
dom.setAttribs( dl, {
id: id,
'class': className,
style: 'width: ' + width + 'px'
} );
}
} else if ( mode === 'node' ) {
return editor.dom.create( 'img', attrs );
} else if ( mode === 'html' ) {
return editor.dom.createHTML( 'img', attrs );
dd = dom.select( '.wp-caption-dd', captionNode );
if ( dd.length ) {
dom.setHTML( dd[0], imageData.caption );
}
} else {
id = id ? 'id="'+ id +'" ' : '';
// should create a new function for generating the caption markup
html = '<dl ' + id + 'class="' + className +'" style="width: '+ width +'px">' +
'<dt class="wp-caption-dt">' + dom.getOuterHTML( node ) + '</dt><dd class="wp-caption-dd">'+ imageData.caption +'</dd></dl>';
if ( parent = dom.getParent( node, 'p' ) ) {
wrap = dom.create( 'div', { 'class': 'mceTemp' }, html );
dom.insertAfter( wrap, parent );
dom.remove( node );
if ( dom.isEmpty( parent ) ) {
dom.remove( parent );
}
} else {
dom.setOuterHTML( node, '<div class="mceTemp">' + html + '</div>' );
}
}
} else if ( captionNode ) {
// Remove the caption wrapper and place the image in new paragraph
parent = dom.create( 'p' );
captionNode.parentNode.insertBefore( parent, captionNode );
parent.appendChild( node );
dom.remove( captionNode );
}
editor.nodeChanged();
// refresh the toolbar
addToolbar( imageNode );
}
function editImage( img ) {

File diff suppressed because one or more lines are too long

View File

@ -641,6 +641,18 @@ function wp_print_media_templates() {
<script type="text/html" id="tmpl-image-details">
<div class="media-embed">
<div class="embed-media-settings">
<div class="column-image">
<div class="image">
<img src="{{ data.model.url }}" draggable="false" />
<# 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 class="column-settings">
<?php
/** This filter is documented in wp-admin/includes/media.php */
@ -656,16 +668,7 @@ function wp_print_media_templates() {
<input type="text" data-setting="alt" value="{{ data.model.alt }}" />
</label>
<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>
<h3><?php _e( 'Display Settings' ); ?></h3>
<div class="setting align">
<span><?php _e('Align'); ?></span>
<div class="button-group button-large" data-setting="align">
@ -685,9 +688,14 @@ function wp_print_media_templates() {
</div>
<# if ( data.attachment ) { #>
<div class="setting size">
<# if ( 'undefined' !== typeof data.attachment.sizes ) { #>
<label class="setting">
<span><?php _e('Size'); ?></span>
<div class="button-group button-large" data-setting="size">
<select class="size" name="size"
data-setting="size"
<# if ( data.userSettings ) { #>
data-user-setting="imgsize"
<# } #>>
<?php
/** This filter is documented in wp-admin/includes/media.php */
$sizes = apply_filters( 'image_size_names_choose', array(
@ -698,74 +706,68 @@ function wp_print_media_templates() {
) );
foreach ( $sizes as $value => $name ) : ?>
<# var size = data.attachment.sizes['<?php echo esc_js( $value ); ?>'];
<#
var size = data.sizes['<?php echo esc_js( $value ); ?>'];
if ( size ) { #>
<button class="button" value="<?php echo esc_attr( $value ); ?>">
<?php echo esc_html( $name ); ?>
</button>
<option value="<?php echo esc_attr( $value ); ?>" <?php selected( $value, 'full' ); ?>>
<?php echo esc_html( $name ); ?> &ndash; {{ size.width }} &times; {{ size.height }}
</option>
<# } #>
<?php endforeach; ?>
</div>
</div>
</select>
</label>
<# } #>
<# } #>
<div class="setting link-to">
<span><?php _e('Link To'); ?></span>
<div class="button-group button-large" data-setting="link">
<select data-setting="link">
<# if ( data.attachment ) { #>
<button class="button" value="file">
<option value="file">
<?php esc_attr_e('Media File'); ?>
</button>
<button class="button" value="post">
</option>
<option value="post">
<?php esc_attr_e('Attachment Page'); ?>
</button>
</option>
<# } else { #>
<button class="button" value="file">
<option value="file">
<?php esc_attr_e('Image URL'); ?>
</button>
</option>
<# } #>
<button class="button" value="custom">
<option value="custom">
<?php esc_attr_e('Custom URL'); ?>
</button>
<button class="button active" value="none">
</option>
<option value="none">
<?php esc_attr_e('None'); ?>
</button>
</div>
</option>
</select>
<input type="text" class="link-to-custom" data-setting="linkUrl" />
</div>
<div class="setting link-settings">
<div class="advanced">
<a class="advanced-toggle" href="#"><?php _e('Show advanced options'); ?></a>
<div class="hidden">
<label class="setting title-text">
<span><?php _e('Image Title Attribute'); ?></span>
<input type="text" data-setting="title" value="{{ data.model.title }}" />
</label>
<label class="setting extra-classes">
<span><?php _e('Image CSS Class'); ?></span>
<input type="text" data-setting="extraClasses" value="{{ data.model.extraClasses }}" />
</label>
<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>
<span><?php _e('Link 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>