Image editing (first run). Includes code by stephanreiter, see #10528

git-svn-id: http://svn.automattic.com/wordpress/trunk@11911 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
azaozz 2009-09-10 22:07:33 +00:00
parent 8772775a15
commit 1c161c23c2
28 changed files with 2335 additions and 42 deletions

View File

@ -111,6 +111,19 @@ case 'wp-compression-test' :
die('0'); die('0');
break; break;
case 'load-preview-image' :
$post_id = intval($_GET['postid']);
if ( empty($post_id) || !current_user_can('edit_post', $post_id) )
die('-1');
check_ajax_referer( "image_editor-$post_id" );
include_once( ABSPATH . 'wp-admin/includes/image-edit.php' );
if ( !stream_preview_image($post_id) )
die('-1');
die();
break;
default : default :
do_action( 'wp_ajax_' . $_GET['action'] ); do_action( 'wp_ajax_' . $_GET['action'] );
die('0'); die('0');
@ -1333,6 +1346,31 @@ case 'save-widget' :
if ( $form = $wp_registered_widget_controls[$widget_id] ) if ( $form = $wp_registered_widget_controls[$widget_id] )
call_user_func_array( $form['callback'], $form['params'] ); call_user_func_array( $form['callback'], $form['params'] );
die();
break;
case 'image-edit-save':
// $post_id is the attachment ID
$post_id = intval($_POST['postid']);
if ( empty($post_id) || !current_user_can('edit_post', $post_id) )
die('-1');
check_ajax_referer( "image_editor-$post_id" );
include_once( ABSPATH . 'wp-admin/includes/image-edit.php' );
$msg = wp_save_image($post_id);
die($msg);
break;
case 'open-image-editor' :
$post_id = intval($_POST['postid']);
if ( empty($post_id) || !current_user_can('edit_post', $post_id) )
die('-1');
check_ajax_referer( "image_editor-$post_id" );
include_once( ABSPATH . 'wp-admin/includes/image-edit.php' );
wp_image_editor($post_id);
die(); die();
break; break;
default : default :

File diff suppressed because one or more lines are too long

View File

@ -1660,3 +1660,21 @@ div.widgets-sortables,
.deleting .widget-title * { .deleting .widget-title * {
color: #aaa; color: #aaa;
} }
.imgedit-menu div {
border-color: #d5d5d5;
background-color: #f1f1f1;
}
.imgedit-menu div:hover {
border-color: #b1b1b1;
background-color: #e3e3e3;
}
.imgedit-menu div.disabled {
border-color: #b3b3b3;
background-color: #cacaca;
filter: alpha(opacity=40);
opacity: 0.4;
}

File diff suppressed because one or more lines are too long

View File

@ -1649,3 +1649,21 @@ div.widgets-sortables,
.deleting .widget-title * { .deleting .widget-title * {
color: #aaa; color: #aaa;
} }
.imgedit-menu div {
border-color: #d5d5d5;
background-color: #f1f1f1;
}
.imgedit-menu div:hover {
border-color: #b1b1b1;
background-color: #e3e3e3;
}
.imgedit-menu div.disabled {
border-color: #b3b3b3;
background-color: #cacaca;
filter: alpha(opacity=40);
opacity: 0.4;
}

BIN
wp-admin/images/imgedit.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View File

@ -0,0 +1,415 @@
<?php
/**
* WordPress Image Editor
*
* @package WordPress
* @subpackage Administration
*/
function wp_image_editor($post_id) {
$nonce = wp_create_nonce("image_editor-$post_id");
$image_size_opt = "<option value='all'>" . __('all image sizes') . "</option>\n";
$image_size_opt .= "<option value='full'>" . __('original image') . "</option>\n";
$meta = wp_get_attachment_metadata($post_id);
if ( is_array($meta) && is_array($meta['sizes']) ) {
$sizes = apply_filters('intermediate_image_sizes', array('thumbnail', 'medium', 'large'));
$size_names = array(
'thumbnail' => __('thumbnail'),
'medium' => __('medium'),
'large' => __('large')
);
foreach ( $sizes as $size ) {
if ( array_key_exists($size, $meta['sizes']) ) {
$size_name = isset($size_names[$size]) ? $size_names[$size] : $size;
$image_size_opt .= "<option value='$size'>$size_name</option>\n";
}
}
} ?>
<div class="imgedit-wrap">
<div id="imgedit-panel-<?php echo $post_id; ?>">
<div class="imgedit-menu">
<div onclick="imageEdit.crop(<?php echo "$post_id, '$nonce'"; ?>)" class="imgedit-crop" title="<?php echo esc_attr__( 'Crop' ); ?>"></div><?php
if ( function_exists('imagerotate') ) { ?>
<div onclick="imageEdit.rotate(90, <?php echo "$post_id, '$nonce'"; ?>)" class="imgedit-rleft" title="<?php echo esc_attr__( 'Rotate couter-clockwise' ); ?>"></div>
<div onclick="imageEdit.rotate(-90, <?php echo "$post_id, '$nonce'"; ?>)" class="imgedit-rright" title="<?php echo esc_attr__( 'Rotate clockwise' ); ?>"></div><?php
} ?>
<div onclick="imageEdit.flip(1, <?php echo "$post_id, '$nonce'"; ?>)" class="imgedit-fliph" title="<?php echo esc_attr__( 'Flip horizontally' ); ?>"></div>
<div onclick="imageEdit.flip(2, <?php echo "$post_id, '$nonce'"; ?>)" class="imgedit-flipv" title="<?php echo esc_attr__( 'Flip vertically' ); ?>"></div>
<div id="image-undo-<?php echo $post_id; ?>" onclick="imageEdit.undo(<?php echo "$post_id, '$nonce'"; ?>)" class="imgedit-undo disabled" title="<?php echo esc_attr__( 'Undo' ); ?>"></div>
<div id="image-redo-<?php echo $post_id; ?>" onclick="imageEdit.redo(<?php echo "$post_id, '$nonce'"; ?>)" class="imgedit-redo disabled" title="<?php echo esc_attr__( 'Redo' ); ?>"></div>
<br class="clear" />
</div>
<p>
<span id="imgedit-scale-<?php echo $post_id; ?>">
<input type="checkbox" onchange="imageEdit.scaleSwitched(<?php echo $post_id; ?>)" id="imgedit-scale-switch-<?php echo $post_id; ?>" /><label for="imgedit-scale-switch-<?php echo $post_id; ?>">Scale full size image:</label>
<span id="imgedit-scale-values-<?php echo $post_id; ?>">
<input type="text" id="imgedit-scale-width-<?php echo $post_id; ?>" onkeyup="imageEdit.scaleWidthChanged(<?php echo $post_id; ?>)" style="width:4em;" />
&times;
<input type="text" id="imgedit-scale-height-<?php echo $post_id; ?>" onkeyup="imageEdit.scaleHeightChanged(<?php echo $post_id; ?>)" style="width:4em;" />
</span>
</span>
</p>
<input type="hidden" id="imgedit-history-<?php echo $post_id; ?>" value="" />
<input type="hidden" id="imgedit-undone-<?php echo $post_id; ?>" value="0" />
<input type="hidden" id="imgedit-selection-<?php echo $post_id; ?>" value="" />
<input type="hidden" id="imgedit-aspect-x-<?php echo $post_id; ?>" value="" />
<input type="hidden" id="imgedit-aspect-y-<?php echo $post_id; ?>" value="" />
<h4><?php _e('Preview Image:'); ?></h4>
<div id="imgedit-crop-<?php echo $post_id; ?>" style="position:relative;">
<img src="<?php echo admin_url('admin-ajax.php') . "?action=load-preview-image&amp;_ajax_nonce={$nonce}&amp;postid={$post_id}&amp;ver=" . rand(1, 99999); ?>" id="image-preview-<?php echo $post_id; ?>" />
</div>
<p>
<?php _e('Apply to:'); ?>
<select id="imgedit-save-target-<?php echo $post_id; ?>" onchange="imageEdit.targetChanged(<?php echo $post_id; ?>)">
<?php echo $image_size_opt; ?>
</select>
</p>
<p>
<input type="button" onclick="imageEdit.close(<?php echo "$post_id, '$nonce'"; ?>)" class="button" value="<?php echo esc_attr__( 'Close' ); ?>" />
<input type="button" onclick="imageEdit.save(<?php echo "$post_id, '$nonce'"; ?>)" class="button-primary" value="<?php echo esc_attr__( 'Save' ); ?>" />
</p>
<script type="text/javascript">imageEdit.targetChanged(<?php echo $post_id; ?>);</script>
</div>
<div class="imgedit-wait" id="imgedit-wait-<?php echo $post_id; ?>"></div>
</div>
<?php
}
function load_image_to_edit($post, $size = 'full') {
$filename = get_attached_file($post->ID);
if ( 'full' != $size && ( $data = image_get_intermediate_size($post->ID, $size) ) )
$filename = path_join( dirname($filename), $data['file'] );
switch ( $post->post_mime_type ) {
case 'image/jpeg':
$image = imagecreatefromjpeg($filename);
break;
case 'image/png':
$image = imagecreatefrompng($filename);
break;
case 'image/gif':
$image = imagecreatefromgif($filename);
break;
default:
$image = false;
break;
}
if ( is_resource($image) ) {
$image = apply_filters('load_image_to_edit', $image, $post->ID); // allows plugins to remove a watermark
if ( function_exists('imagealphablending') && function_exists('imagesavealpha') ) {
imagealphablending($image, false);
imagesavealpha($image, true);
}
}
return $image;
}
function wp_stream_image($image, $mime_type, $post_id = 0, $intermediate_size = '') {
$image = apply_filters('image_save_pre', $image, $post->ID, $intermediate_size);
switch ( $mime_type ) {
case 'image/jpeg':
header('Content-Type: image/jpeg');
return imagejpeg($image, null, 90);
case 'image/png':
header('Content-Type: image/png');
return imagepng($image);
case 'image/gif':
header('Content-Type: image/gif');
return imagegif($image);
default:
return false;
}
}
function wp_save_image_file($filename, $image, $mime_type, $post_id = 0, $intermediate_size = '') {
$image = apply_filters('image_save_pre', $image, $post->ID, $intermediate_size);
switch ( $mime_type ) {
case 'image/jpeg':
return imagejpeg( $image, $filename, apply_filters( 'jpeg_quality', 90, 'edit_image' ) );
case 'image/png':
return imagepng($image, $filename);
case 'image/gif':
return imagegif($image, $filename);
default:
return false;
}
}
function _image_get_preview_ratio($w, $h) {
$max = max($w, $h);
return $max > 400 ? (400 / $max) : 1;
}
function _rotate_image_resource($img, $angle) {
if ( function_exists('imagerotate') ) {
$rotated = imagerotate($img, $angle, 0);
if ( is_resource($rotated) ) {
imagedestroy($img);
$img = $rotated;
}
}
return $img;
}
function _flip_image_resource($img, $horz, $vert) {
$w = imagesx($img);
$h = imagesy($img);
$dst = wp_imagecreatetruecolor($w, $h);
if ( is_resource($dst) ) {
$sx = $vert ? ($w - 1) : 0;
$sy = $horz ? ($h - 1) : 0;
$sw = $vert ? -$w : $w;
$sh = $horz ? -$h : $h;
if ( imagecopyresampled($dst, $img, 0, 0, $sx, $sy, $w, $h, $sw, $sh) ) {
imagedestroy($img);
$img = $dst;
}
}
return $img;
}
function _crop_image_resource($img, $x, $y, $w, $h) {
$dst = wp_imagecreatetruecolor($w, $h);
if ( is_resource($dst) ) {
if ( imagecopy($dst, $img, 0, 0, $x, $y, $w, $h) ) {
imagedestroy($img);
$img = $dst;
}
}
return $img;
}
function image_edit_apply_changes($img, $changes) {
if ( !is_array($changes) )
return $img;
// expand change operations
foreach ( $changes as $key => $obj ) {
if ( isset($obj->r) ) {
$obj->type = 'rotate';
$obj->angle = $obj->r;
unset($obj->r);
} elseif ( isset($obj->f) ) {
$obj->type = 'flip';
$obj->axis = $obj->f;
unset($obj->f);
} elseif ( isset($obj->c) ) {
$obj->type = 'crop';
$obj->sel = $obj->c;
unset($obj->c);
}
$changes[$key] = $obj;
}
// combine operations
if ( count($changes) > 1 ) {
$filtered = array($changes[0]);
for ( $i = 0, $j = 1; $j < count($changes); $j++ ) {
$combined = false;
if ( $filtered[$i]->type == $changes[$j]->type ) {
switch ( $filtered[$i]->type ) {
case 'rotate':
$filtered[$i]->angle += $changes[$j]->angle;
$combined = true;
break;
case 'flip':
$filtered[$i]->axis ^= $changes[$j]->axis;
$combined = true;
break;
}
}
if ( !$combined )
$filtered[++$i] = $changes[$j];
}
$changes = $filtered;
unset($filtered);
}
// image resource before applying the changes
$img = apply_filters('image_edit_before_change', $img, $changes);
foreach ( $changes as $operation ) {
switch ( $operation->type ) {
case 'rotate':
if ( $operation->angle != 0 )
$img = _rotate_image_resource($img, $operation->angle);
break;
case 'flip':
if ( $operation->axis != 0 )
$img = _flip_image_resource($img, ($operation->axis & 1) != 0, ($operation->axis & 2) != 0);
break;
case 'crop':
$sel = $operation->sel;
$scale = 1 / _image_get_preview_ratio( imagesx($img), imagesy($img) ); // discard preview scaling
$img = _crop_image_resource($img, $sel->x * $scale, $sel->y * $scale, $sel->w * $scale, $sel->h * $scale);
break;
}
}
return $img;
}
function stream_preview_image($post_id) {
$post = get_post($post_id);
@ini_set('memory_limit', '256M');
$img = load_image_to_edit( $post, array(400, 400) );
if ( !is_resource($img) )
return false;
$changes = !empty($_REQUEST['history']) ? json_decode( stripslashes($_REQUEST['history']) ) : null;
if ( $changes )
$img = image_edit_apply_changes($img, $changes);
// scale the image
$w = imagesx($img);
$h = imagesy($img);
$ratio = _image_get_preview_ratio($w, $h);
$w2 = $w * $ratio;
$h2 = $h * $ratio;
$preview = wp_imagecreatetruecolor($w2, $h2);
imagecopyresampled( $preview, $img, 0, 0, 0, 0, $w2, $h2, $w, $h );
wp_stream_image($preview, $post->post_mime_type, $post_id);
imagedestroy($preview);
imagedestroy($img);
return true;
}
function wp_save_image($post_id) {
$msg = '';
$success = $delete = $full_resized = false;
$post = get_post($post_id);
@ini_set('memory_limit', '256M');
$img = load_image_to_edit($post);
if ( !is_resource($img) )
return 'error=' . __('Unable to create new image.');
$fwidth = !empty($_REQUEST['fwidth']) ? intval($_REQUEST['fwidth']) : 0;
$fheight = !empty($_REQUEST['fheight']) ? intval($_REQUEST['fheight']) : 0;
$target = !empty($_REQUEST['target']) ? preg_replace('/[^a-z0-9_-]+/i', '', $_REQUEST['target']) : '';
if ( !empty($_REQUEST['history']) ) {
$changes = json_decode( stripslashes($_REQUEST['history']) );
if ( $changes )
$img = image_edit_apply_changes($img, $changes);
}
if ( $fwidth > 0 && $fheight > 0 ) {
// scale the full size image
$dst = wp_imagecreatetruecolor($fwidth, $fheight);
if ( imagecopyresampled( $dst, $img, 0, 0, 0, 0, $fwidth, $fheight, imagesx($img), imagesy($img) ) ) {
imagedestroy($img);
$img = $dst;
$full_resized = true;
}
}
if ( !$changes && !$full_resized )
return 'error=' . __('Nothing to save, the image is not changed.');
$meta = wp_get_attachment_metadata($post_id, false, false);
if ( !is_array($meta) )
$meta = array();
if ( !isset($meta['sizes']) || !is_array($meta['sizes']) )
$meta['sizes'] = array();
// generate new filename
$path = get_attached_file($post_id);
$path_parts = pathinfo52( $path );
$filename = $path_parts['filename'];
$suffix = time() . rand(100, 999);
while( true ) {
$filename = preg_replace( '/-e([0-9]+)$/', '', $filename );
$filename .= "-e{$suffix}";
$new_filename = "{$filename}.{$path_parts['extension']}";
$new_path = "{$path_parts['dirname']}/$new_filename";
if ( file_exists($new_path) )
$suffix++;
else
break;
}
// save the full-size file, also needed to create sub-sizes
if ( !wp_save_image_file($new_path, $img, $post->post_mime_type, $post_id) )
return 'error=' . __('Unable to save the image.');
if ( 'full' == $target || 'all' == $target || $full_resized ) {
$meta['sizes']["backup-{$suffix}-full"] = array('width' => $meta['width'], 'height' => $meta['height'], 'file' => $path_parts['basename']);
$success = update_attached_file($post_id, $new_path);
$meta['file'] = get_attached_file($post_id, true); // get the path unfiltered
$meta['width'] = imagesx($img);
$meta['height'] = imagesy($img);
list ( $uwidth, $uheight ) = wp_shrink_dimensions($meta['width'], $meta['height']);
$meta['hwstring_small'] = "height='$uheight' width='$uwidth'";
if ( $success && $target == 'all' )
$sizes = apply_filters( 'intermediate_image_sizes', array('large', 'medium', 'thumbnail') );
$msg .= "full={$meta['width']}x{$meta['height']}!";
} elseif ( array_key_exists($target, $meta['sizes']) ) {
$sizes = array( $target );
$success = $delete = true;
}
if ( isset($sizes) ) {
foreach ( $sizes as $size ) {
if ( isset($meta['sizes'][$size]) )
$meta['sizes']["backup-{$suffix}-$size"] = $meta['sizes'][$size];
$resized = image_make_intermediate_size($new_path, get_option("{$size}_size_w"), get_option("{$size}_size_h"), get_option("{$size}_crop") );
if ( $resized )
$meta['sizes'][$size] = $resized;
else
unset($meta['sizes'][$size]);
}
}
if ( $success ) {
wp_update_attachment_metadata($post_id, $meta);
if ( $target == 'thumbnail' || $target == 'all' || ( $target == 'full' && !array_key_exists('thumbnail', $meta['sizes']) ) ) {
if ( $thumb_url = get_attachment_icon_src($post_id) )
$msg .= "thumbnail={$thumb_url[0]}";
}
} else {
$delete = true;
}
if ( $delete ) {
$delpath = apply_filters('wp_delete_file', $new_path);
@unlink($delpath);
}
imagedestroy($img);
return $msg;
}

View File

@ -49,7 +49,7 @@ function wp_crop_image( $src_file, $src_x, $src_y, $src_w, $src_h, $dst_w, $dst_
if ( !is_resource( $src )) if ( !is_resource( $src ))
return $src; return $src;
$dst = imagecreatetruecolor( $dst_w, $dst_h ); $dst = wp_imagecreatetruecolor( $dst_w, $dst_h );
if ( $src_abs ) { if ( $src_abs ) {
$src_w -= $src_x; $src_w -= $src_x;
@ -326,5 +326,3 @@ function file_is_displayable_image($path) {
return apply_filters('file_is_displayable_image', $result, $path); return apply_filters('file_is_displayable_image', $result, $path);
} }
?>

View File

@ -1151,22 +1151,35 @@ function get_media_item( $attachment_id, $args = null ) {
} }
} }
$media_dims = '';
$meta = wp_get_attachment_metadata($post->ID);
if ( is_array($meta) && array_key_exists('width', $meta) && array_key_exists('height', $meta) )
$media_dims .= "<span id='media-dims-{$post->ID}'>{$meta['width']}&nbsp;&times;&nbsp;{$meta['height']}</span> ";
$image_edit_button = '';
if ( gd_edit_image_support($post->post_mime_type) ) {
$nonce = wp_create_nonce("image_editor-$post->ID");
$image_edit_button = "<tr><td class='A1B1'><input type='button' id='imgedit-open-btn-{$post->ID}' onclick='imageEdit.open($post->ID, \"$nonce\")' class='button' value='" . esc_attr__( 'Edit image' ) . "' /> <img src='images/wpspin_light.gif' class='imgedit-wait-spin' alt='' /></td></tr>";
}
$item = " $item = "
$type $type
$toggle_links $toggle_links
$order $order
$display_title $display_title
<table class='slidetoggle describe $class'> <table class='slidetoggle describe $class'>
<thead class='media-item-info'> <thead class='media-item-info' id='media-head-$post->ID'>
<tr> <tr>
<td class='A1B1' rowspan='4'><img class='thumbnail' src='$thumb_url' alt='' /></td> <td class='A1B1' rowspan='5'><img class='thumbnail' src='$thumb_url' alt='' /></td>
<td>$filename</td> <td>$filename</td>
</tr> </tr>
<tr><td>$post->post_mime_type</td></tr> <tr><td>$post->post_mime_type</td></tr>
<tr><td>" . mysql2date($post->post_date, get_option('time_format')) . "</td></tr> <tr><td>" . mysql2date($post->post_date, get_option('time_format')) . "</td></tr>
<tr><td>" . apply_filters('media_meta', '', $post) . "</td></tr> <tr><td>" . apply_filters('media_meta', $media_dims, $post) . "</td></tr>
$image_edit_button
</thead> </thead>
<tbody>\n"; <tbody>
<tr><td style='display:none' colspan='2' id='image-editor-$post->ID'></td></tr>\n";
$defaults = array( $defaults = array(
'input' => 'text', 'input' => 'text',
@ -2130,4 +2143,3 @@ add_filter('media_upload_gallery', 'media_upload_gallery');
add_filter('media_upload_library', 'media_upload_library'); add_filter('media_upload_library', 'media_upload_library');
?>

View File

@ -3,10 +3,11 @@ jQuery(document).ready(function($) {
gallerySortableInit = function() { gallerySortableInit = function() {
gallerySortable = $('#media-items').sortable( { gallerySortable = $('#media-items').sortable( {
items: '.media-item', items: 'div.media-item',
placeholder: 'sorthelper', placeholder: 'sorthelper',
axis: 'y', axis: 'y',
distance: 2, distance: 2,
handle: 'div.filename',
stop: function(e, ui) { stop: function(e, ui) {
// When an update has occurred, adjust the order for each item // When an update has occurred, adjust the order for each item
var all = $('#media-items').sortable('toArray'), len = all.length; var all = $('#media-items').sortable('toArray'), len = all.length;

View File

@ -1 +1 @@
jQuery(document).ready(function(c){var b,e,a,d=false;e=function(){b=c("#media-items").sortable({items:".media-item",placeholder:"sorthelper",axis:"y",distance:2,stop:function(i,h){var g=c("#media-items").sortable("toArray"),f=g.length;c.each(g,function(k,l){var j=d?(f-k):(1+k);c("#"+l+" .menu_order input").val(j)})}})};sortIt=function(){var g=c(".menu_order_input"),f=g.length;g.each(function(j){var h=d?(f-j):(1+j);c(this).val(h)})};clearAll=function(f){f=f||0;c(".menu_order_input").each(function(){if(this.value=="0"||f){this.value=""}})};c("#asc").click(function(){d=false;sortIt();return false});c("#desc").click(function(){d=true;sortIt();return false});c("#clear").click(function(){clearAll(1);return false});c("#showall").click(function(){c("#sort-buttons span a").toggle();c("a.describe-toggle-on").hide();c("a.describe-toggle-off, table.slidetoggle").show();return false});c("#hideall").click(function(){c("#sort-buttons span a").toggle();c("a.describe-toggle-on").show();c("a.describe-toggle-off, table.slidetoggle").hide();return false});e();clearAll();if(c("#media-items>*").length>1){a=wpgallery.getWin();c("#save-all, #gallery-settings").show();if(typeof a.tinyMCE!="undefined"&&a.tinyMCE.activeEditor&&!a.tinyMCE.activeEditor.isHidden()){wpgallery.mcemode=true;wpgallery.init()}else{c("#insert-gallery").show()}}});jQuery(window).unload(function(){tinymce=tinyMCE=wpgallery=null});var tinymce=null,tinyMCE,wpgallery;wpgallery={mcemode:false,editor:{},dom:{},is_update:false,el:{},I:function(a){return document.getElementById(a)},init:function(){var d=this,a,f,c,e,b=d.getWin();if(!d.mcemode){return}a=(""+document.location.search).replace(/^\?/,"").split("&");f={};for(c=0;c<a.length;c++){e=a[c].split("=");f[unescape(e[0])]=unescape(e[1])}if(f.mce_rdomain){document.domain=f.mce_rdomain}tinymce=b.tinymce;tinyMCE=b.tinyMCE;d.editor=tinymce.EditorManager.activeEditor;d.setup()},getWin:function(){return window.dialogArguments||opener||parent||top},restoreSelection:function(){var a=this;if(tinymce.isIE){a.editor.selection.moveToBookmark(a.editor.windowManager.bookmark)}},setup:function(){var f=this,c,d=f.editor,i,e,h,b,j;if(!f.mcemode){return}f.restoreSelection();f.el=d.selection.getNode();if(f.el.nodeName!="IMG"||!d.dom.hasClass(f.el,"wpGallery")){if((i=d.dom.select("img.wpGallery"))&&i[0]){f.el=i[0]}else{if(getUserSetting("galfile")=="1"){f.I("linkto-file").checked="checked"}if(getUserSetting("galdesc")=="1"){f.I("order-desc").checked="checked"}if(getUserSetting("galcols")){f.I("columns").value=getUserSetting("galcols")}if(getUserSetting("galord")){f.I("orderby").value=getUserSetting("galord")}jQuery("#insert-gallery").show();return}}c=d.dom.getAttrib(f.el,"title");c=d.dom.decode(c);if(c){jQuery("#update-gallery").show();f.is_update=true;e=c.match(/columns=['"]([0-9]+)['"]/);h=c.match(/link=['"]([^'"]+)['"]/i);b=c.match(/order=['"]([^'"]+)['"]/i);j=c.match(/orderby=['"]([^'"]+)['"]/i);if(h&&h[1]){f.I("linkto-file").checked="checked"}if(b&&b[1]){f.I("order-desc").checked="checked"}if(e&&e[1]){f.I("columns").value=""+e[1]}if(j&&j[1]){f.I("orderby").value=j[1]}}else{jQuery("#insert-gallery").show()}},update:function(){var b=this,a=b.editor,d="",c;if(!b.mcemode||!b.is_update){c="[gallery"+b.getSettings()+"]";b.getWin().send_to_editor(c);return}if(b.el.nodeName!="IMG"){return}d=a.dom.decode(a.dom.getAttrib(b.el,"title"));d=d.replace(/\s*(order|link|columns|orderby)=['"]([^'"]+)['"]/gi,"");d+=b.getSettings();a.dom.setAttrib(b.el,"title",d);b.getWin().tb_remove()},getSettings:function(){var a=this.I,b="";if(a("linkto-file").checked){b+=' link="file"';setUserSetting("galfile","1")}if(a("order-desc").checked){b+=' order="DESC"';setUserSetting("galdesc","1")}if(a("columns").value!=3){b+=' columns="'+a("columns").value+'"';setUserSetting("galcols",a("columns").value)}if(a("orderby").value!="menu_order"){b+=' orderby="'+a("orderby").value+'"';setUserSetting("galord",a("orderby").value)}return b}}; jQuery(document).ready(function(c){var b,e,a,d=false;e=function(){b=c("#media-items").sortable({items:"div.media-item",placeholder:"sorthelper",axis:"y",distance:2,handle:"div.filename",stop:function(i,h){var g=c("#media-items").sortable("toArray"),f=g.length;c.each(g,function(k,l){var j=d?(f-k):(1+k);c("#"+l+" .menu_order input").val(j)})}})};sortIt=function(){var g=c(".menu_order_input"),f=g.length;g.each(function(j){var h=d?(f-j):(1+j);c(this).val(h)})};clearAll=function(f){f=f||0;c(".menu_order_input").each(function(){if(this.value=="0"||f){this.value=""}})};c("#asc").click(function(){d=false;sortIt();return false});c("#desc").click(function(){d=true;sortIt();return false});c("#clear").click(function(){clearAll(1);return false});c("#showall").click(function(){c("#sort-buttons span a").toggle();c("a.describe-toggle-on").hide();c("a.describe-toggle-off, table.slidetoggle").show();return false});c("#hideall").click(function(){c("#sort-buttons span a").toggle();c("a.describe-toggle-on").show();c("a.describe-toggle-off, table.slidetoggle").hide();return false});e();clearAll();if(c("#media-items>*").length>1){a=wpgallery.getWin();c("#save-all, #gallery-settings").show();if(typeof a.tinyMCE!="undefined"&&a.tinyMCE.activeEditor&&!a.tinyMCE.activeEditor.isHidden()){wpgallery.mcemode=true;wpgallery.init()}else{c("#insert-gallery").show()}}});jQuery(window).unload(function(){tinymce=tinyMCE=wpgallery=null});var tinymce=null,tinyMCE,wpgallery;wpgallery={mcemode:false,editor:{},dom:{},is_update:false,el:{},I:function(a){return document.getElementById(a)},init:function(){var d=this,a,f,c,e,b=d.getWin();if(!d.mcemode){return}a=(""+document.location.search).replace(/^\?/,"").split("&");f={};for(c=0;c<a.length;c++){e=a[c].split("=");f[unescape(e[0])]=unescape(e[1])}if(f.mce_rdomain){document.domain=f.mce_rdomain}tinymce=b.tinymce;tinyMCE=b.tinyMCE;d.editor=tinymce.EditorManager.activeEditor;d.setup()},getWin:function(){return window.dialogArguments||opener||parent||top},restoreSelection:function(){var a=this;if(tinymce.isIE){a.editor.selection.moveToBookmark(a.editor.windowManager.bookmark)}},setup:function(){var f=this,c,d=f.editor,i,e,h,b,j;if(!f.mcemode){return}f.restoreSelection();f.el=d.selection.getNode();if(f.el.nodeName!="IMG"||!d.dom.hasClass(f.el,"wpGallery")){if((i=d.dom.select("img.wpGallery"))&&i[0]){f.el=i[0]}else{if(getUserSetting("galfile")=="1"){f.I("linkto-file").checked="checked"}if(getUserSetting("galdesc")=="1"){f.I("order-desc").checked="checked"}if(getUserSetting("galcols")){f.I("columns").value=getUserSetting("galcols")}if(getUserSetting("galord")){f.I("orderby").value=getUserSetting("galord")}jQuery("#insert-gallery").show();return}}c=d.dom.getAttrib(f.el,"title");c=d.dom.decode(c);if(c){jQuery("#update-gallery").show();f.is_update=true;e=c.match(/columns=['"]([0-9]+)['"]/);h=c.match(/link=['"]([^'"]+)['"]/i);b=c.match(/order=['"]([^'"]+)['"]/i);j=c.match(/orderby=['"]([^'"]+)['"]/i);if(h&&h[1]){f.I("linkto-file").checked="checked"}if(b&&b[1]){f.I("order-desc").checked="checked"}if(e&&e[1]){f.I("columns").value=""+e[1]}if(j&&j[1]){f.I("orderby").value=j[1]}}else{jQuery("#insert-gallery").show()}},update:function(){var b=this,a=b.editor,d="",c;if(!b.mcemode||!b.is_update){c="[gallery"+b.getSettings()+"]";b.getWin().send_to_editor(c);return}if(b.el.nodeName!="IMG"){return}d=a.dom.decode(a.dom.getAttrib(b.el,"title"));d=d.replace(/\s*(order|link|columns|orderby)=['"]([^'"]+)['"]/gi,"");d+=b.getSettings();a.dom.setAttrib(b.el,"title",d);b.getWin().tb_remove()},getSettings:function(){var a=this.I,b="";if(a("linkto-file").checked){b+=' link="file"';setUserSetting("galfile","1")}if(a("order-desc").checked){b+=' order="DESC"';setUserSetting("galdesc","1")}if(a("columns").value!=3){b+=' columns="'+a("columns").value+'"';setUserSetting("galcols",a("columns").value)}if(a("orderby").value!="menu_order"){b+=' orderby="'+a("orderby").value+'"';setUserSetting("galord",a("orderby").value)}return b}};

View File

@ -0,0 +1,392 @@
var imageEdit;
(function($) {
imageEdit = {
iasapi : {},
intval : function(f) {
return f | 0;
},
setState : function(el, s) {
if ( s )
el.removeAttr('disabled');
else
el.attr('disabled', 'disabled');
},
setClass : function(el, c) {
if ( c )
el.removeClass('disabled');
else
el.addClass('disabled');
},
gcd : function(a, b) {
var r;
if ( a == 0 || b == 0 )
return 0;
else if ( a == b )
return a;
else {
do {
r = a % b;
a = b; b = r;
} while ( r != 0 );
return a;
}
},
toggleEditor : function(postid, toggle) {
var wait = $('#imgedit-wait-' + postid);
if ( toggle )
wait.height( $('#imgedit-panel-' + postid).height() ).fadeIn('fast');
else
wait.height(500).fadeOut('fast');
},
isChecked : function(chkbox) {
return ( !chkbox.attr('disabled') && chkbox[0].checked );
},
getAspect : function(postid) {
var enable = this.isChecked( $('#imgedit-scale-switch-' + postid) ), X, Y;
if ( enable ) {
X = this.intval( $('#imgedit-aspect-x-' + postid).val() );
Y = this.intval( $('#imgedit-aspect-y-' + postid).val() );
return X / Y;
} else {
return 0;
}
},
scaleWidthChanged : function(postid) {
var src = $('#imgedit-scale-width-' + postid), aspect;
if ( !src.attr('disabled') ) {
aspect = this.getAspect(postid);
if ( aspect != 0 )
$('#imgedit-scale-height-' + postid).val( (src.val() != '') ? this.intval( src.val() / aspect ) : '' );
}
},
scaleHeightChanged : function(postid) {
var src = $('#imgedit-scale-height-' + postid), aspect;
if ( !src.attr('disabled') ) {
aspect = this.getAspect(postid);
if ( aspect != 0 )
$('#imgedit-scale-width-' + postid).val( (src.val() != '') ? this.intval(src.val() * aspect) : '' );
}
},
setDefaultAspect : function(postid) {
var t = this, g, host = $('#image-preview-' + postid),
X = host.attr('width'), Y = host.attr('height');
while( (g = t.gcd(X, Y) ) > 1) {
X = t.intval( Math.ceil(X / g) );
Y = t.intval( Math.ceil(Y / g) );
}
if ( X > 10 && Y > 10 ) {
while ( X > 10 && Y > 10 ) {
X = t.intval( Math.ceil(X / 10) );
Y = t.intval( Math.ceil(Y / 10) );
}
while( ( g = t.gcd(X, Y) ) > 1) {
X = t.intval( Math.ceil(X / g) );
Y = t.intval( Math.ceil(Y / g) );
}
}
$('#imgedit-aspect-x-' + postid).val(X);
$('#imgedit-aspect-y-' + postid).val(Y);
},
filterHistory : function(postid) {
// apply undo state to history
var history = $('#imgedit-history-' + postid).val(), pop;
if ( history != '' ) {
pop = this.intval( $('#imgedit-undone-' + postid).val() );
if ( pop > 0 ) {
history = JSON.parse(history);
while ( pop > 0 ) {
history.pop();
pop--;
}
history = JSON.stringify(history);
}
}
return history;
},
refreshEditor : function(postid, nonce, callback) {
var t = this, data, host;
t.toggleEditor(postid, 1);
data = {
'action': 'load-preview-image',
'_ajax_nonce': nonce,
'postid': postid,
'history': t.filterHistory(postid),
'rand': t.intval(Math.random() * 1000000)
};
host = $('<img id="image-preview-' + postid + '" />');
host.load( function() {
var parent = $('#imgedit-crop-' + postid);
parent.empty().append(host);
t.initCrop(postid, host, parent);
$('#imgedit-panel-' + postid).show();
if ( (typeof callback != "unknown") && callback != null )
callback();
t.toggleEditor(postid, 0);
}).attr('src', ajaxurl + '?' + $.param(data));
},
save : function(postid, nonce) {
var t = this, fwidth = -1, fheight = -1, w, h, data,
scaled = t.isChecked( $('#imgedit-scale-switch-' + postid) ),
target = $('#imgedit-save-target-' + postid).val();
if ( scaled ) {
w = $('#imgedit-scale-width-' + postid);
h = $('#imgedit-scale-height-' + postid);
fwidth = t.intval(w.val());
fheight = t.intval(h.val());
if ( fwidth <= 0 ) {
w.focus();
return;
} else if ( fheight <= 0 ) {
h.focus();
return;
}
}
t.toggleEditor(postid, 1);
data = {
'action': 'image-edit-save',
'_ajax_nonce': nonce,
'postid': postid,
'history': t.filterHistory(postid),
'target': target,
'fwidth': fwidth,
'fheight': fheight
};
$.post(ajaxurl, data, function(r) {
var fields = r.split('!'), pair, res, fw, fh, i, thumbnail;
for ( i = 0; i < fields.length; i++ ) {
pair = fields[i].split('=');
if ( pair.length == 2 ) {
switch ( pair[0] ) {
case 'full':
// update full size dimensions
res = pair[1].split('x');
if ( res.length == 2 ) {
fw = res[0];
fh = res[1];
$('#image-dims-' + postid).html( fw + '&nbsp;&times;&nbsp;' + fh );
}
// clear undo history, it's no longer valid since we changed the original full size image
$('#imgedit-history-' + postid).val('');
$('#imgedit-undone-' + postid).val(0);
t.setClass($('#image-undo-' + postid), false);
t.setClass($('#image-redo-' + postid), false);
break;
case 'thumbnail':
// force a reload of the thumbnail ??
thumbnail = $('#media-item-' + postid);
if ( thumbnail.length == 0 ) {
// when the flash uploader is employed media items are named 'media-item-SWFUpload_n_n' with n >= 0
// we therefore try to locate a known element and navigate up to the image-item-info div object
thumbnail = $('#media-dims-' + postid).closest('.media-item-info');
}
thumbnail = thumbnail.find('.thumbnail');
thumbnail.attr('src', pair[1]);
break;
case 'error':
$('#imgedit-panel-' + postid).html(pair[1]);
}
}
}
t.toggleEditor(postid, 0);
});
},
open : function(postid, nonce) {
var t = this, data, elem = $('#image-editor-' + postid), head = $('#media-head-' + postid),
btn = $('#imgedit-open-btn-' + postid), spin = btn.siblings('img');
btn.attr('disabled', 'disabled');
spin.css('visibility', 'visible');
data = {
'action': 'open-image-editor',
'_ajax_nonce': nonce,
'postid': postid
};
elem.load(ajaxurl, data, function() {
elem.fadeIn('fast');
head.fadeOut('fast', function(){
btn.removeAttr('disabled');
spin.css('visibility', 'hidden');
});
t.toggleEditor(postid, 1);
$('#image-preview-' + postid).load(function(){
var t = imageEdit, parent = $('#imgedit-crop-' + postid);
t.initCrop(postid, this, parent);
t.setDefaultAspect(postid);
t.toggleEditor(postid, 0);
});
});
},
initCrop : function(postid, image, parent) {
var t = this;
t.iasapi = $(image).imgAreaSelect({
parent: parent,
instance: true,
handles: true,
keys: true,
minHeight: 5,
minWidth: 5,
onInit: function(img, c) {
parent.children().mousedown(function(e){
var sel, ratio = false, X = t.intval( $('#imgedit-aspect-x-' + postid).val() ),
Y = t.intval( $('#imgedit-aspect-y-' + postid).val() );
defRatio = ( X && Y ) ? X + ':' + Y : '1:1';
if ( e.shiftKey ) {
sel = t.iasapi.getSelection();
ratio = ( sel.width && sel.height ) ? sel.width + ':' + sel.height : defRatio;
}
t.iasapi.setOptions({
aspectRatio: ratio
});
});
},
onSelectEnd: function(img, c) {
var sel = { 'x': c.x1, 'y': c.y1, 'w': c.width, 'h': c.height };
$('#imgedit-selection-' + postid).val( JSON.stringify(sel) );
}
});
},
close : function(postid) {
$('#image-editor-' + postid).fadeOut('fast', function() {
$('#media-head-' + postid).fadeIn('fast');
});
},
addStep : function(op, postid, nonce) {
var t = this, elem = $('#imgedit-history-' + postid),
history = (elem.val() != '') ? JSON.parse(elem.val()) : new Array(),
undone = $('#imgedit-undone-' + postid),
pop = t.intval(undone.val());
while ( pop > 0 ) {
history.pop();
pop--;
}
undone.val(0); // reset
history.push(op);
elem.val( JSON.stringify(history) );
t.refreshEditor(postid, nonce, function() {
t.setClass($('#image-undo-' + postid), true);
t.setClass($('#image-redo-' + postid), false);
});
},
rotate : function(angle, postid, nonce) {
this.addStep({ 'r': angle }, postid, nonce);
},
flip : function (axis, postid, nonce) {
this.addStep({ 'f': axis }, postid, nonce);
},
crop : function (postid, nonce) {
var sel = $('#imgedit-selection-' + postid).val();
if ( sel != '' ) {
sel = JSON.parse(sel);
if ( sel.w > 0 && sel.h > 0 )
this.addStep({ 'c': sel }, postid, nonce);
}
},
undo : function (postid, nonce) {
var t = this, button = $('#image-undo-' + postid), elem = $('#imgedit-undone-' + postid),
pop = t.intval( elem.val() ) + 1;
if ( button.hasClass('disabled') )
return;
elem.val(pop);
t.refreshEditor(postid, nonce, function() {
var elem = $('#imgedit-history-' + postid),
history = (elem.val() != '') ? JSON.parse(elem.val()) : new Array();
t.setClass($('#image-redo-' + postid), true);
t.setClass(button, pop < history.length);
});
},
redo : function(postid, nonce) {
var t = this, button = $('#image-redo-' + postid), elem = $('#imgedit-undone-' + postid),
pop = t.intval( elem.val() ) - 1;
if ( button.hasClass('disabled') )
return;
elem.val(pop);
t.refreshEditor(postid, nonce, function() {
t.setClass($('#image-undo-' + postid), true);
t.setClass(button, pop > 0);
});
},
scaleSwitched : function(postid) {
var enable = this.isChecked( $('#imgedit-scale-switch-' + postid) );
this.setState($('#imgedit-scale-width-' + postid), enable);
this.setState($('#imgedit-scale-height-' + postid), enable);
// this.setClass($('#imgedit-scale-values-' + postid), !enable);
this.scaleWidthChanged(postid);
},
targetChanged : function(postid) {
var target = $('#imgedit-save-target-' + postid).val(),
enable = (target == 'full' || target == 'all');
this.setState($('#imgedit-scale-switch-' + postid), enable);
this.setClass($('#imgedit-scale-' + postid), !enable);
this.scaleSwitched(postid);
}
}
})(jQuery);

File diff suppressed because one or more lines are too long

View File

@ -17,6 +17,8 @@ if (!current_user_can('upload_files'))
wp_enqueue_script('swfupload-all'); wp_enqueue_script('swfupload-all');
wp_enqueue_script('swfupload-handlers'); wp_enqueue_script('swfupload-handlers');
wp_enqueue_script('image-edit');
wp_enqueue_style('imgareaselect');
@header('Content-Type: ' . get_option('html_type') . '; charset=' . get_option('blog_charset')); @header('Content-Type: ' . get_option('html_type') . '; charset=' . get_option('blog_charset'));

View File

@ -64,6 +64,8 @@ case 'edit' :
add_filter('attachment_fields_to_edit', 'media_single_attachment_fields_to_edit', 10, 2); add_filter('attachment_fields_to_edit', 'media_single_attachment_fields_to_edit', 10, 2);
wp_enqueue_script( 'wp-ajax-response' ); wp_enqueue_script( 'wp-ajax-response' );
wp_enqueue_script('image-edit');
wp_enqueue_style('imgareaselect');
require( 'admin-header.php' ); require( 'admin-header.php' );

File diff suppressed because one or more lines are too long

View File

@ -1299,7 +1299,7 @@ strong .post-com-count {
.form-table td, .form-table td,
#wpbody-content .describe td { #wpbody-content .describe td {
margin-bottom: 9px; margin-bottom: 9px;
padding: 4px 10px 12px; padding: 8px 10px;
line-height: 20px; line-height: 20px;
font-size: 11px; font-size: 11px;
} }
@ -2842,6 +2842,14 @@ table .inline-edit-row fieldset ul.cat-hover {
background-color: transparent; background-color: transparent;
} }
#wpbody-content .describe .media-item-info td {
padding: 4px 10px 0;
}
#wpbody-content .describe .media-item-info .A1B1 {
padding-bottom: 8px;
}
#wpbody-content .filename { #wpbody-content .filename {
padding: 0 10px; padding: 0 10px;
} }
@ -3338,3 +3346,82 @@ label,
position: relative; position: relative;
top: -3px; top: -3px;
} }
.imgedit-wrap {
position: relative;
min-height: 500px;
}
.imgedit-wait {
position: absolute;
top: 0;
background: #FFFFFF url(images/wpspin_light.gif) no-repeat scroll 200px 75px;
opacity: 0.7;
filter: alpha(opacity=70);
width: 100%;
height: 500px;
display: none;
}
.media-disabled {
color: grey;
}
.imgedit-wait-spin {
padding: 0 4px 4px;
vertical-align: bottom;
visibility: hidden;
}
.imgedit-menu {
margin: 5px 0;
}
.imgedit-menu div {
float: left;
width: 34px;
height: 34px;
-moz-border-radius: 4px;
-khtml-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
border-width: 1px;
border-style: solid;
}
.imgedit-crop {
background: transparent url(images/imgedit.gif) no-repeat scroll -62px 2px;
margin: 0 8px 0 0;
}
.imgedit-rleft {
background: transparent url(images/imgedit.gif) no-repeat scroll -31px 2px;
margin: 0 3px;
}
.imgedit-rright {
background: transparent url(images/imgedit.gif) no-repeat scroll 1px 2px;
margin: 0 8px 0 3px;
}
.imgedit-fliph {
background: transparent url(images/imgedit.gif) no-repeat scroll -127px 2px;
margin: 0 3px;
}
.imgedit-flipv {
background: transparent url(images/imgedit.gif) no-repeat scroll -95px 3px;
margin: 0 8px 0 3px;
}
.imgedit-undo {
background: transparent url(images/imgedit.gif) no-repeat scroll -161px 2px;
margin: 0 3px;
}
.imgedit-redo {
background: transparent url(images/imgedit.gif) no-repeat scroll -195px 2px;
margin: 0 8px 0 3px;
}

View File

@ -141,3 +141,14 @@ if ( !function_exists('json_decode') ) {
return $wp_json->decode( $string ); return $wp_json->decode( $string );
} }
} }
// pathinfo that fills 'filename' without extension like in PHP 5.2+
function pathinfo52($path) {
$parts = pathinfo($path);
if ( !isset($parts['filename']) ) {
$parts['filename'] = substr( $parts['basename'], 0, strrpos($parts['basename'], '.') );
if ( empty($parts['filename']) ) // there's no extension
$parts['filename'] = $parts['basename'];
}
return $parts;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 B

View File

@ -0,0 +1,41 @@
/*
* imgAreaSelect animated border style
*/
.imgareaselect-border1 {
background: url(border-anim-v.gif) repeat-y left top;
}
.imgareaselect-border2 {
background: url(border-anim-h.gif) repeat-x left top;
}
.imgareaselect-border3 {
background: url(border-anim-v.gif) repeat-y right top;
}
.imgareaselect-border4 {
background: url(border-anim-h.gif) repeat-x left bottom;
}
.imgareaselect-border1, .imgareaselect-border2,
.imgareaselect-border3, .imgareaselect-border4 {
opacity: 0.5;
filter: alpha(opacity=50);
}
.imgareaselect-handle {
background-color: #fff;
border: solid 1px #000;
opacity: 0.4;
filter: alpha(opacity=40);
}
.imgareaselect-outer {
background-color: #000;
opacity: 0.4;
filter: alpha(opacity=40);
}
.imgareaselect-selection {
}

View File

@ -0,0 +1,691 @@
/*
* imgAreaSelect jQuery plugin
* version 0.9.1
*
* Copyright (c) 2008-2009 Michal Wojciechowski (odyniec.net)
*
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
* http://odyniec.net/projects/imgareaselect/
*
*/
(function($) {
var abs = Math.abs,
max = Math.max,
min = Math.min,
round = Math.round;
function div() {
return $('<div/>');
}
$.imgAreaSelect = function (img, options) {
var
$img = $(img),
imgLoaded,
$box = div(),
$area = div(),
$border = div().add(div()).add(div()).add(div()),
$outer = div().add(div()).add(div()).add(div()),
$handles = $([]),
$areaOpera,
left, top,
imgOfs,
imgWidth, imgHeight,
$parent,
parOfs,
zIndex = 0,
position = 'absolute',
startX, startY,
scaleX, scaleY,
resizeMargin = 10,
resize,
aspectRatio,
shown,
x1, y1, x2, y2,
selection = { x1: 0, y1: 0, x2: 0, y2: 0, width: 0, height: 0 },
$p, d, i, o, w, h, adjusted;
function viewX(x) {
return x + imgOfs.left - parOfs.left;
}
function viewY(y) {
return y + imgOfs.top - parOfs.top;
}
function selX(x) {
return x - imgOfs.left + parOfs.left;
}
function selY(y) {
return y - imgOfs.top + parOfs.top;
}
function evX(event) {
return event.pageX - parOfs.left;
}
function evY(event) {
return event.pageY - parOfs.top;
}
function getSelection(noScale) {
var sx = noScale || scaleX, sy = noScale || scaleY;
return { x1: round(selection.x1 * sx),
y1: round(selection.y1 * sy),
x2: round(selection.x2 * sx),
y2: round(selection.y2 * sy),
width: round(selection.x2 * sx) - round(selection.x1 * sx),
height: round(selection.y2 * sy) - round(selection.y1 * sy) };
}
function setSelection(x1, y1, x2, y2, noScale) {
var sx = noScale || scaleX, sy = noScale || scaleY;
selection = {
x1: round(x1 / sx),
y1: round(y1 / sy),
x2: round(x2 / sx),
y2: round(y2 / sy)
};
selection.width = (x2 = viewX(selection.x2)) - (x1 = viewX(selection.x1));
selection.height = (y2 = viewX(selection.y2)) - (y1 = viewX(selection.y1));
}
function adjust() {
if (!$img.width())
return;
imgOfs = { left: round($img.offset().left), top: round($img.offset().top) };
imgWidth = $img.width();
imgHeight = $img.height();
if ($().jquery == '1.3.2' && $.browser.safari && position == 'fixed') {
imgOfs.top += max(document.documentElement.scrollTop, $('body').scrollTop());
imgOfs.left += max(document.documentElement.scrollLeft, $('body').scrollLeft());
}
parOfs = $.inArray($parent.css('position'), ['absolute', 'relative']) + 1 ?
{ left: round($parent.offset().left) - $parent.scrollLeft(),
top: round($parent.offset().top) - $parent.scrollTop() } :
position == 'fixed' ?
{ left: $(document).scrollLeft(), top: $(document).scrollTop() } :
{ left: 0, top: 0 };
left = viewX(0);
top = viewY(0);
}
function update(resetKeyPress) {
if (!shown) return;
$box.css({ left: viewX(selection.x1), top: viewY(selection.y1) })
.add($area).width(w = selection.width).height(h = selection.height);
$area.add($border).add($handles).css({ left: 0, top: 0 });
$border
.width(max(w - $border.outerWidth() + $border.innerWidth(), 0))
.height(max(h - $border.outerHeight() + $border.innerHeight(), 0));
$($outer[0]).css({ left: left, top: top,
width: selection.x1, height: imgHeight });
$($outer[1]).css({ left: left + selection.x1, top: top,
width: w, height: selection.y1 });
$($outer[2]).css({ left: left + selection.x2, top: top,
width: imgWidth - selection.x2, height: imgHeight });
$($outer[3]).css({ left: left + selection.x1, top: top + selection.y2,
width: w, height: imgHeight - selection.y2 });
w -= $handles.outerWidth();
h -= $handles.outerHeight();
switch ($handles.length) {
case 8:
$($handles[4]).css({ left: w / 2 });
$($handles[5]).css({ left: w, top: h / 2 });
$($handles[6]).css({ left: w / 2, top: h });
$($handles[7]).css({ top: h / 2 });
case 4:
$handles.slice(1,3).css({ left: w });
$handles.slice(2,4).css({ top: h });
}
if (resetKeyPress !== false) {
if ($.imgAreaSelect.keyPress != docKeyPress)
$(document).unbind($.imgAreaSelect.keyPress,
$.imgAreaSelect.onKeyPress);
if (options.keys)
$(document)[$.imgAreaSelect.keyPress](
$.imgAreaSelect.onKeyPress = docKeyPress);
}
if ($.browser.msie && $border.outerWidth() - $border.innerWidth() == 2) {
$border.css('margin', 0);
setTimeout(function () { $border.css('margin', 'auto'); }, 0);
}
}
function doUpdate(resetKeyPress) {
adjust();
update(resetKeyPress);
x1 = viewX(selection.x1); y1 = viewY(selection.y1);
x2 = viewX(selection.x2); y2 = viewY(selection.y2);
}
function hide($elem, fn) {
options.fadeSpeed ? $elem.fadeOut(options.fadeSpeed, fn) : $elem.hide();
}
function areaMouseMove(event) {
var x = selX(evX(event)) - selection.x1,
y = selY(evY(event)) - selection.y1;
if (!adjusted) {
adjust();
adjusted = true;
$box.one('mouseout', function () { adjusted = false; });
}
resize = '';
if (options.resizable) {
if (y <= resizeMargin)
resize = 'n';
else if (y >= selection.height - resizeMargin)
resize = 's';
if (x <= resizeMargin)
resize += 'w';
else if (x >= selection.width - resizeMargin)
resize += 'e';
}
$box.css('cursor', resize ? resize + '-resize' :
options.movable ? 'move' : '');
if ($areaOpera)
$areaOpera.toggle();
}
function docMouseUp(event) {
$('body').css('cursor', '');
if (options.autoHide || selection.width * selection.height == 0)
hide($box.add($outer), function () { $(this).hide(); });
options.onSelectEnd(img, getSelection());
$(document).unbind('mousemove', selectingMouseMove);
$box.mousemove(areaMouseMove);
}
function areaMouseDown(event) {
if (event.which != 1) return false;
adjust();
if (resize) {
$('body').css('cursor', resize + '-resize');
x1 = viewX(selection[/w/.test(resize) ? 'x2' : 'x1']);
y1 = viewY(selection[/n/.test(resize) ? 'y2' : 'y1']);
$(document).mousemove(selectingMouseMove)
.one('mouseup', docMouseUp);
$box.unbind('mousemove', areaMouseMove);
}
else if (options.movable) {
startX = left + selection.x1 - evX(event);
startY = top + selection.y1 - evY(event);
$box.unbind('mousemove', areaMouseMove);
$(document).mousemove(movingMouseMove)
.one('mouseup', function () {
options.onSelectEnd(img, getSelection());
$(document).unbind('mousemove', movingMouseMove);
$box.mousemove(areaMouseMove);
});
}
else
$img.mousedown(event);
return false;
}
function aspectRatioXY() {
x2 = max(left, min(left + imgWidth,
x1 + abs(y2 - y1) * aspectRatio * (x2 > x1 || -1)));
y2 = round(max(top, min(top + imgHeight,
y1 + abs(x2 - x1) / aspectRatio * (y2 > y1 || -1))));
x2 = round(x2);
}
function aspectRatioYX() {
y2 = max(top, min(top + imgHeight,
y1 + abs(x2 - x1) / aspectRatio * (y2 > y1 || -1)));
x2 = round(max(left, min(left + imgWidth,
x1 + abs(y2 - y1) * aspectRatio * (x2 > x1 || -1))));
y2 = round(y2);
}
function doResize() {
if (abs(x2 - x1) < options.minWidth) {
x2 = x1 - options.minWidth * (x2 < x1 || -1);
if (x2 < left)
x1 = left + options.minWidth;
else if (x2 > left + imgWidth)
x1 = left + imgWidth - options.minWidth;
}
if (abs(y2 - y1) < options.minHeight) {
y2 = y1 - options.minHeight * (y2 < y1 || -1);
if (y2 < top)
y1 = top + options.minHeight;
else if (y2 > top + imgHeight)
y1 = top + imgHeight - options.minHeight;
}
x2 = max(left, min(x2, left + imgWidth));
y2 = max(top, min(y2, top + imgHeight));
if (aspectRatio)
if (abs(x2 - x1) / aspectRatio > abs(y2 - y1))
aspectRatioYX();
else
aspectRatioXY();
if (abs(x2 - x1) > options.maxWidth) {
x2 = x1 - options.maxWidth * (x2 < x1 || -1);
if (aspectRatio) aspectRatioYX();
}
if (abs(y2 - y1) > options.maxHeight) {
y2 = y1 - options.maxHeight * (y2 < y1 || -1);
if (aspectRatio) aspectRatioXY();
}
selection = { x1: selX(min(x1, x2)), x2: selX(max(x1, x2)),
y1: selY(min(y1, y2)), y2: selY(max(y1, y2)),
width: abs(x2 - x1), height: abs(y2 - y1) };
update();
options.onSelectChange(img, getSelection());
}
function selectingMouseMove(event) {
x2 = resize == '' || /w|e/.test(resize) || aspectRatio ? evX(event) : viewX(selection.x2);
y2 = resize == '' || /n|s/.test(resize) || aspectRatio ? evY(event) : viewY(selection.y2);
doResize();
return false;
}
function doMove(newX1, newY1) {
x2 = (x1 = newX1) + selection.width;
y2 = (y1 = newY1) + selection.height;
selection = $.extend(selection, { x1: selX(x1), y1: selY(y1),
x2: selX(x2), y2: selY(y2) });
update();
options.onSelectChange(img, getSelection());
}
function movingMouseMove(event) {
x1 = max(left, min(startX + evX(event), left + imgWidth - selection.width));
y1 = max(top, min(startY + evY(event), top + imgHeight - selection.height));
doMove(x1, y1);
event.preventDefault();
return false;
}
function startSelection() {
adjust();
x2 = x1;
y2 = y1;
doResize();
resize = '';
if ($outer.is(':not(:visible)'))
$box.add($outer).hide().fadeIn(options.fadeSpeed||0);
shown = true;
$(document).unbind('mouseup', cancelSelection)
.mousemove(selectingMouseMove).one('mouseup', docMouseUp);
$box.unbind('mousemove', areaMouseMove);
options.onSelectStart(img, getSelection());
}
function cancelSelection() {
$(document).unbind('mousemove', startSelection);
hide($box.add($outer));
selection = { x1: selX(x1), y1: selY(y1), x2: selX(x1), y2: selY(y1),
width: 0, height: 0 };
options.onSelectChange(img, getSelection());
options.onSelectEnd(img, getSelection());
}
function imgMouseDown(event) {
if (event.which != 1 || $outer.is(':animated')) return false;
adjust();
startX = x1 = evX(event);
startY = y1 = evY(event);
$(document).one('mousemove', startSelection)
.one('mouseup', cancelSelection);
return false;
}
function parentScroll() {
doUpdate(false);
}
function imgLoad() {
imgLoaded = true;
setOptions(options = $.extend({
classPrefix: 'imgareaselect',
movable: true,
resizable: true,
parent: 'body',
onInit: function () {},
onSelectStart: function () {},
onSelectChange: function () {},
onSelectEnd: function () {}
}, options));
$box.add($outer).css({ visibility: '' });
if (options.show) {
shown = true;
adjust();
update();
$box.add($outer).hide().fadeIn(options.fadeSpeed||0);
}
setTimeout(function () { options.onInit(img, getSelection()); }, 0);
}
var docKeyPress = function(event) {
var k = options.keys, d, t, key = event.keyCode || event.which;
d = !isNaN(k.alt) && (event.altKey || event.originalEvent.altKey) ? k.alt :
!isNaN(k.ctrl) && event.ctrlKey ? k.ctrl :
!isNaN(k.shift) && event.shiftKey ? k.shift :
!isNaN(k.arrows) ? k.arrows : 10;
if (k.arrows == 'resize' || (k.shift == 'resize' && event.shiftKey) ||
(k.ctrl == 'resize' && event.ctrlKey) ||
(k.alt == 'resize' && (event.altKey || event.originalEvent.altKey)))
{
switch (key) {
case 37:
d = -d;
case 39:
t = max(x1, x2);
x1 = min(x1, x2);
x2 = max(t + d, x1);
if (aspectRatio) aspectRatioYX();
break;
case 38:
d = -d;
case 40:
t = max(y1, y2);
y1 = min(y1, y2);
y2 = max(t + d, y1);
if (aspectRatio) aspectRatioXY();
break;
default:
return;
}
doResize();
}
else {
x1 = min(x1, x2);
y1 = min(y1, y2);
switch (key) {
case 37:
doMove(max(x1 - d, left), y1);
break;
case 38:
doMove(x1, max(y1 - d, top));
break;
case 39:
doMove(x1 + min(d, imgWidth - selX(x2)), y1);
break;
case 40:
doMove(x1, y1 + min(d, imgHeight - selY(y2)));
break;
default:
return;
}
}
return false;
};
function styleOptions($elem, props) {
for (option in props)
if (options[option] !== undefined)
$elem.css(props[option], options[option]);
}
function setOptions(newOptions) {
if (newOptions.parent)
($parent = $(newOptions.parent)).append($box.add($outer));
options = $.extend(options, newOptions);
adjust();
if (newOptions.handles != null) {
$handles.remove();
$handles = $([]);
i = newOptions.handles ? newOptions.handles == 'corners' ? 4 : 8 : 0;
while (i--)
$handles = $handles.add(div());
$handles.addClass(options.classPrefix + '-handle').css({
position: 'absolute',
fontSize: 0,
zIndex: zIndex + 1 || 1
});
if (!parseInt($handles.css('width')))
$handles.width(5).height(5);
if (o = options.borderWidth)
$handles.css({ borderWidth: o, borderStyle: 'solid' });
styleOptions($handles, { borderColor1: 'border-color',
borderColor2: 'background-color',
borderOpacity: 'opacity' });
}
scaleX = options.imageWidth / imgWidth || 1;
scaleY = options.imageHeight / imgHeight || 1;
if (newOptions.x1 != null) {
setSelection(newOptions.x1, newOptions.y1, newOptions.x2,
newOptions.y2);
newOptions.show = !newOptions.hide;
}
if (newOptions.keys)
options.keys = $.extend({ shift: 1, ctrl: 'resize' },
newOptions.keys);
$outer.addClass(options.classPrefix + '-outer');
$area.addClass(options.classPrefix + '-selection');
for (i = 0; i++ < 4;)
$($border[i-1]).addClass(options.classPrefix + '-border' + i);
styleOptions($area, { selectionColor: 'background-color',
selectionOpacity: 'opacity' });
styleOptions($border, { borderOpacity: 'opacity',
borderWidth: 'border-width' });
styleOptions($outer, { outerColor: 'background-color',
outerOpacity: 'opacity' });
if (o = options.borderColor1)
$($border[0]).css({ borderStyle: 'solid', borderColor: o });
if (o = options.borderColor2)
$($border[1]).css({ borderStyle: 'dashed', borderColor: o });
$box.append($area.add($border).add($handles).add($areaOpera));
if ($.browser.msie) {
if (o = $outer.css('filter').match(/opacity=([0-9]+)/))
$outer.css('opacity', o[1]/100);
if (o = $border.css('filter').match(/opacity=([0-9]+)/))
$border.css('opacity', o[1]/100);
}
if (newOptions.hide)
hide($box.add($outer));
else if (newOptions.show && imgLoaded) {
shown = true;
$box.add($outer).fadeIn(options.fadeSpeed||0);
doUpdate();
}
aspectRatio = (d = (options.aspectRatio || '').split(/:/))[0] / d[1];
if (options.disable || options.enable === false) {
$box.unbind('mousemove', areaMouseMove).unbind('mousedown', areaMouseDown);
$img.add($outer).unbind('mousedown', imgMouseDown);
$(window).unbind('resize', parentScroll);
$img.add($img.parents()).unbind('scroll', parentScroll);
}
else if (options.enable || options.disable === false) {
if (options.resizable || options.movable)
$box.mousemove(areaMouseMove).mousedown(areaMouseDown);
if (!options.persistent)
$img.add($outer).mousedown(imgMouseDown);
$(window).resize(parentScroll);
$img.add($img.parents()).scroll(parentScroll);
}
options.enable = options.disable = undefined;
}
this.getOptions = function () { return options; };
this.setOptions = setOptions;
this.getSelection = getSelection;
this.setSelection = setSelection;
this.update = doUpdate;
$p = $img;
while ($p.length && !$p.is('body')) {
if (!isNaN($p.css('z-index')) && $p.css('z-index') > zIndex)
zIndex = $p.css('z-index');
if ($p.css('position') == 'fixed')
position = 'fixed';
$p = $p.parent();
}
if (!isNaN(options.zIndex))
zIndex = options.zIndex;
if ($.browser.msie)
$img.attr('unselectable', 'on');
$.imgAreaSelect.keyPress = $.browser.msie ||
$.browser.safari ? 'keydown' : 'keypress';
if ($.browser.opera)
$areaOpera = div().css({ width: '100%', height: '100%',
position: 'absolute', zIndex: zIndex + 2 || 2 });
$box.add($outer).css({ visibility: 'hidden', position: position,
overflow: 'hidden', zIndex: zIndex || '0' });
$box.css({ zIndex: zIndex + 2 || 2 });
$area.add($border).css({ position: 'absolute' });
img.complete || img.readyState == 'complete' || !$img.is('img') ?
imgLoad() : $img.one('load', imgLoad);
};
$.fn.imgAreaSelect = function (options) {
options = options || {};
this.each(function () {
if ($(this).data('imgAreaSelect'))
$(this).data('imgAreaSelect').setOptions(options);
else {
if (options.enable === undefined && options.disable === undefined)
options.enable = true;
$(this).data('imgAreaSelect', new $.imgAreaSelect(this, options));
}
});
if (options.instance)
return $(this).data('imgAreaSelect');
return this;
};
})(jQuery);

File diff suppressed because one or more lines are too long

481
wp-includes/js/json2.dev.js Normal file
View File

@ -0,0 +1,481 @@
/*
http://www.JSON.org/json2.js
2009-08-17
Public Domain.
NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
See http://www.JSON.org/js.html
This file creates a global JSON object containing two methods: stringify
and parse.
JSON.stringify(value, replacer, space)
value any JavaScript value, usually an object or array.
replacer an optional parameter that determines how object
values are stringified for objects. It can be a
function or an array of strings.
space an optional parameter that specifies the indentation
of nested structures. If it is omitted, the text will
be packed without extra whitespace. If it is a number,
it will specify the number of spaces to indent at each
level. If it is a string (such as '\t' or '&nbsp;'),
it contains the characters used to indent at each level.
This method produces a JSON text from a JavaScript value.
When an object value is found, if the object contains a toJSON
method, its toJSON method will be called and the result will be
stringified. A toJSON method does not serialize: it returns the
value represented by the name/value pair that should be serialized,
or undefined if nothing should be serialized. The toJSON method
will be passed the key associated with the value, and this will be
bound to the value
For example, this would serialize Dates as ISO strings.
Date.prototype.toJSON = function (key) {
function f(n) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
return this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z';
};
You can provide an optional replacer method. It will be passed the
key and value of each member, with this bound to the containing
object. The value that is returned from your method will be
serialized. If your method returns undefined, then the member will
be excluded from the serialization.
If the replacer parameter is an array of strings, then it will be
used to select the members to be serialized. It filters the results
such that only members with keys listed in the replacer array are
stringified.
Values that do not have JSON representations, such as undefined or
functions, will not be serialized. Such values in objects will be
dropped; in arrays they will be replaced with null. You can use
a replacer function to replace those with JSON values.
JSON.stringify(undefined) returns undefined.
The optional space parameter produces a stringification of the
value that is filled with line breaks and indentation to make it
easier to read.
If the space parameter is a non-empty string, then that string will
be used for indentation. If the space parameter is a number, then
the indentation will be that many spaces.
Example:
text = JSON.stringify(['e', {pluribus: 'unum'}]);
// text is '["e",{"pluribus":"unum"}]'
text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
// text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
text = JSON.stringify([new Date()], function (key, value) {
return this[key] instanceof Date ?
'Date(' + this[key] + ')' : value;
});
// text is '["Date(---current time---)"]'
JSON.parse(text, reviver)
This method parses a JSON text to produce an object or array.
It can throw a SyntaxError exception.
The optional reviver parameter is a function that can filter and
transform the results. It receives each of the keys and values,
and its return value is used instead of the original value.
If it returns what it received, then the structure is not modified.
If it returns undefined then the member is deleted.
Example:
// Parse the text. Values that look like ISO date strings will
// be converted to Date objects.
myData = JSON.parse(text, function (key, value) {
var a;
if (typeof value === 'string') {
a =
/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
if (a) {
return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+a[5], +a[6]));
}
}
return value;
});
myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
var d;
if (typeof value === 'string' &&
value.slice(0, 5) === 'Date(' &&
value.slice(-1) === ')') {
d = new Date(value.slice(5, -1));
if (d) {
return d;
}
}
return value;
});
This is a reference implementation. You are free to copy, modify, or
redistribute.
This code should be minified before deployment.
See http://javascript.crockford.com/jsmin.html
USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
NOT CONTROL.
*/
/*jslint evil: true */
/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
lastIndex, length, parse, prototype, push, replace, slice, stringify,
test, toJSON, toString, valueOf
*/
"use strict";
// Create a JSON object only if one does not already exist. We create the
// methods in a closure to avoid creating global variables.
if (!this.JSON) {
this.JSON = {};
}
(function () {
function f(n) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
if (typeof Date.prototype.toJSON !== 'function') {
Date.prototype.toJSON = function (key) {
return isFinite(this.valueOf()) ?
this.getUTCFullYear() + '-' +
f(this.getUTCMonth() + 1) + '-' +
f(this.getUTCDate()) + 'T' +
f(this.getUTCHours()) + ':' +
f(this.getUTCMinutes()) + ':' +
f(this.getUTCSeconds()) + 'Z' : null;
};
String.prototype.toJSON =
Number.prototype.toJSON =
Boolean.prototype.toJSON = function (key) {
return this.valueOf();
};
}
var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
gap,
indent,
meta = { // table of character substitutions
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'"' : '\\"',
'\\': '\\\\'
},
rep;
function quote(string) {
// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can safely slap some quotes around it.
// Otherwise we must also replace the offending characters with safe escape
// sequences.
escapable.lastIndex = 0;
return escapable.test(string) ?
'"' + string.replace(escapable, function (a) {
var c = meta[a];
return typeof c === 'string' ? c :
'\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
}) + '"' :
'"' + string + '"';
}
function str(key, holder) {
// Produce a string from holder[key].
var i, // The loop counter.
k, // The member key.
v, // The member value.
length,
mind = gap,
partial,
value = holder[key];
// If the value has a toJSON method, call it to obtain a replacement value.
if (value && typeof value === 'object' &&
typeof value.toJSON === 'function') {
value = value.toJSON(key);
}
// If we were called with a replacer function, then call the replacer to
// obtain a replacement value.
if (typeof rep === 'function') {
value = rep.call(holder, key, value);
}
// What happens next depends on the value's type.
switch (typeof value) {
case 'string':
return quote(value);
case 'number':
// JSON numbers must be finite. Encode non-finite numbers as null.
return isFinite(value) ? String(value) : 'null';
case 'boolean':
case 'null':
// If the value is a boolean or null, convert it to a string. Note:
// typeof null does not produce 'null'. The case is included here in
// the remote chance that this gets fixed someday.
return String(value);
// If the type is 'object', we might be dealing with an object or an array or
// null.
case 'object':
// Due to a specification blunder in ECMAScript, typeof null is 'object',
// so watch out for that case.
if (!value) {
return 'null';
}
// Make an array to hold the partial results of stringifying this object value.
gap += indent;
partial = [];
// Is the value an array?
if (Object.prototype.toString.apply(value) === '[object Array]') {
// The value is an array. Stringify every element. Use null as a placeholder
// for non-JSON values.
length = value.length;
for (i = 0; i < length; i += 1) {
partial[i] = str(i, value) || 'null';
}
// Join all of the elements together, separated with commas, and wrap them in
// brackets.
v = partial.length === 0 ? '[]' :
gap ? '[\n' + gap +
partial.join(',\n' + gap) + '\n' +
mind + ']' :
'[' + partial.join(',') + ']';
gap = mind;
return v;
}
// If the replacer is an array, use it to select the members to be stringified.
if (rep && typeof rep === 'object') {
length = rep.length;
for (i = 0; i < length; i += 1) {
k = rep[i];
if (typeof k === 'string') {
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
} else {
// Otherwise, iterate through all of the keys in the object.
for (k in value) {
if (Object.hasOwnProperty.call(value, k)) {
v = str(k, value);
if (v) {
partial.push(quote(k) + (gap ? ': ' : ':') + v);
}
}
}
}
// Join all of the member texts together, separated with commas,
// and wrap them in braces.
v = partial.length === 0 ? '{}' :
gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
mind + '}' : '{' + partial.join(',') + '}';
gap = mind;
return v;
}
}
// If the JSON object does not yet have a stringify method, give it one.
if (typeof JSON.stringify !== 'function') {
JSON.stringify = function (value, replacer, space) {
// The stringify method takes a value and an optional replacer, and an optional
// space parameter, and returns a JSON text. The replacer can be a function
// that can replace values, or an array of strings that will select the keys.
// A default replacer method can be provided. Use of the space parameter can
// produce text that is more easily readable.
var i;
gap = '';
indent = '';
// If the space parameter is a number, make an indent string containing that
// many spaces.
if (typeof space === 'number') {
for (i = 0; i < space; i += 1) {
indent += ' ';
}
// If the space parameter is a string, it will be used as the indent string.
} else if (typeof space === 'string') {
indent = space;
}
// If there is a replacer, it must be a function or an array.
// Otherwise, throw an error.
rep = replacer;
if (replacer && typeof replacer !== 'function' &&
(typeof replacer !== 'object' ||
typeof replacer.length !== 'number')) {
throw new Error('JSON.stringify');
}
// Make a fake root object containing our value under the key of ''.
// Return the result of stringifying the value.
return str('', {'': value});
};
}
// If the JSON object does not yet have a parse method, give it one.
if (typeof JSON.parse !== 'function') {
JSON.parse = function (text, reviver) {
// The parse method takes a text and an optional reviver function, and returns
// a JavaScript value if the text is a valid JSON text.
var j;
function walk(holder, key) {
// The walk method is used to recursively walk the resulting structure so
// that modifications can be made.
var k, v, value = holder[key];
if (value && typeof value === 'object') {
for (k in value) {
if (Object.hasOwnProperty.call(value, k)) {
v = walk(value, k);
if (v !== undefined) {
value[k] = v;
} else {
delete value[k];
}
}
}
}
return reviver.call(holder, key, value);
}
// Parsing happens in four stages. In the first stage, we replace certain
// Unicode characters with escape sequences. JavaScript handles many characters
// incorrectly, either silently deleting them, or treating them as line endings.
cx.lastIndex = 0;
if (cx.test(text)) {
text = text.replace(cx, function (a) {
return '\\u' +
('0000' + a.charCodeAt(0).toString(16)).slice(-4);
});
}
// In the second stage, we run the text against regular expressions that look
// for non-JSON patterns. We are especially concerned with '()' and 'new'
// because they can cause invocation, and '=' because it can cause mutation.
// But just to be safe, we want to reject all unexpected forms.
// We split the second stage into 4 regexp operations in order to work around
// crippling inefficiencies in IE's and Safari's regexp engines. First we
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
// replace all simple value tokens with ']' characters. Third, we delete all
// open brackets that follow a colon or comma or that begin the text. Finally,
// we look to see that the remaining characters are only whitespace or ']' or
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
if (/^[\],:{}\s]*$/.
test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
// In the third stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.
j = eval('(' + text + ')');
// In the optional fourth stage, we recursively walk the new structure, passing
// each name/value pair to a reviver function for possible transformation.
return typeof reviver === 'function' ?
walk({'': j}, '') : j;
}
// If the text is not JSON parseable, then a SyntaxError is thrown.
throw new SyntaxError('JSON.parse');
};
}
}());

11
wp-includes/js/json2.js Normal file
View File

@ -0,0 +1,11 @@
/*
http://www.JSON.org/json2.js
2009-08-17
Public Domain.
NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
See http://www.JSON.org/js.html
*/
if(!this.JSON){this.JSON={}}(function(){function f(n){return n<10?"0"+n:n}if(typeof Date.prototype.toJSON!=="function"){Date.prototype.toJSON=function(key){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(key){return this.valueOf()}}var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==="string"?c:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+string+'"'}function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==="object"&&typeof value.toJSON==="function"){value=value.toJSON(key)}if(typeof rep==="function"){value=rep.call(holder,key,value)}switch(typeof value){case"string":return quote(value);case"number":return isFinite(value)?String(value):"null";case"boolean":case"null":return String(value);case"object":if(!value){return"null"}gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==="[object Array]"){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||"null"}v=partial.length===0?"[]":gap?"[\n"+gap+partial.join(",\n"+gap)+"\n"+mind+"]":"["+partial.join(",")+"]";gap=mind;return v}if(rep&&typeof rep==="object"){length=rep.length;for(i=0;i<length;i+=1){k=rep[i];if(typeof k==="string"){v=str(k,value);if(v){partial.push(quote(k)+(gap?": ":":")+v)}}}}else{for(k in value){if(Object.hasOwnProperty.call(value,k)){v=str(k,value);if(v){partial.push(quote(k)+(gap?": ":":")+v)}}}}v=partial.length===0?"{}":gap?"{\n"+gap+partial.join(",\n"+gap)+"\n"+mind+"}":"{"+partial.join(",")+"}";gap=mind;return v}}if(typeof JSON.stringify!=="function"){JSON.stringify=function(value,replacer,space){var i;gap="";indent="";if(typeof space==="number"){for(i=0;i<space;i+=1){indent+=" "}}else{if(typeof space==="string"){indent=space}}rep=replacer;if(replacer&&typeof replacer!=="function"&&(typeof replacer!=="object"||typeof replacer.length!=="number")){throw new Error("JSON.stringify")}return str("",{"":value})}}if(typeof JSON.parse!=="function"){JSON.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==="object"){for(k in value){if(Object.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v}else{delete value[k]}}}}return reviver.call(holder,key,value)}cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})}if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,""))){j=eval("("+text+")");return typeof reviver==="function"?walk({"":j},""):j}throw new SyntaxError("JSON.parse")}}}());

View File

@ -346,13 +346,7 @@ function image_resize( $file, $max_w, $max_h, $crop = false, $suffix = null, $de
return $dims; return $dims;
list($dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) = $dims; list($dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h) = $dims;
$newimage = imagecreatetruecolor( $dst_w, $dst_h); $newimage = wp_imagecreatetruecolor( $dst_w, $dst_h );
// preserve PNG transparency
if ( IMAGETYPE_PNG == $orig_type && function_exists( 'imagealphablending' ) && function_exists( 'imagesavealpha' ) ) {
imagealphablending( $newimage, false);
imagesavealpha( $newimage, true);
}
imagecopyresampled( $newimage, $image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h); imagecopyresampled( $newimage, $image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
@ -816,3 +810,53 @@ function get_attachment_taxonomies($attachment) {
return array_unique($taxonomies); return array_unique($taxonomies);
} }
/**
* Check if the installed version of GD supports particular image type
*
* @since 2.9.0
*
* @param $mime_type string
* @return bool
*/
function gd_edit_image_support($mime_type) {
if ( function_exists('imagetypes') ) {
switch( $mime_type ) {
case 'image/jpeg':
return (imagetypes() & IMG_JPG) != 0;
case 'image/png':
return (imagetypes() & IMG_PNG) != 0;
case 'image/gif':
return (imagetypes() & IMG_GIF) != 0;
}
} else {
switch( $mime_type ) {
case 'image/jpeg':
return function_exists('imagecreatefromjpeg');
case 'image/png':
return function_exists('imagecreatefrompng');
case 'image/gif':
return function_exists('imagecreatefromgif');
}
}
return false;
}
/**
* Create new GD image resource with transparency support
*
* @since 2.9.0
*
* @param $width
* @param $height
* @return image resource
*/
function wp_imagecreatetruecolor($width, $height) {
$img = imagecreatetruecolor($width, $height);
if ( is_resource($img) && function_exists('imagealphablending') && function_exists('imagesavealpha') ) {
imagealphablending($img, false);
imagesavealpha($img, true);
}
return $img;
}

View File

@ -2658,53 +2658,63 @@ function wp_insert_attachment($object, $file = false, $parent = 0) {
* @param int $postid Attachment ID. * @param int $postid Attachment ID.
* @return mixed False on failure. Post data on success. * @return mixed False on failure. Post data on success.
*/ */
function wp_delete_attachment($postid) { function wp_delete_attachment($post_id) {
global $wpdb; global $wpdb;
if ( !$post = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->posts WHERE ID = %d", $postid)) ) if ( !$post = $wpdb->get_row( $wpdb->prepare("SELECT * FROM $wpdb->posts WHERE ID = %d", $post_id) ) )
return $post; return $post;
if ( 'attachment' != $post->post_type ) if ( 'attachment' != $post->post_type )
return false; return false;
if ( 'trash' != $post->post_status ) if ( 'trash' != $post->post_status )
return wp_trash_post($postid); return wp_trash_post($post_id);
delete_post_meta($post_id, '_wp_trash_meta_status'); delete_post_meta($post_id, '_wp_trash_meta_status');
delete_post_meta($post_id, '_wp_trash_meta_time'); delete_post_meta($post_id, '_wp_trash_meta_time');
$meta = wp_get_attachment_metadata( $post_id, false, false );
$file = get_attached_file( $post_id );
$meta = wp_get_attachment_metadata( $postid ); do_action('delete_attachment', $post_id);
$file = get_attached_file( $postid );
do_action('delete_attachment', $postid);
/** @todo Delete for pluggable post taxonomies too */ /** @todo Delete for pluggable post taxonomies too */
wp_delete_object_term_relationships($postid, array('category', 'post_tag')); wp_delete_object_term_relationships($post_id, array('category', 'post_tag'));
$wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->comments WHERE comment_post_ID = %d", $postid )); $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->comments WHERE comment_post_ID = %d", $post_id ));
$wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->postmeta WHERE post_id = %d ", $postid )); $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->postmeta WHERE post_id = %d ", $post_id ));
$wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->posts WHERE ID = %d", $postid )); $wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->posts WHERE ID = %d", $post_id ));
$uploadPath = wp_upload_dir(); $uploadpath = wp_upload_dir();
if ( ! empty($meta['thumb']) ) { if ( ! empty($meta['thumb']) ) {
// Don't delete the thumb if another attachment uses it // Don't delete the thumb if another attachment uses it
if (! $wpdb->get_row( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE meta_key = '_wp_attachment_metadata' AND meta_value LIKE %s AND post_id <> %d", '%'.$meta['thumb'].'%', $postid)) ) { if (! $wpdb->get_row( $wpdb->prepare( "SELECT meta_id FROM $wpdb->postmeta WHERE meta_key = '_wp_attachment_metadata' AND meta_value LIKE %s AND post_id <> %d", '%' . $meta['thumb'] . '%', $post_id)) ) {
$thumbfile = str_replace(basename($file), $meta['thumb'], $file); $thumbfile = str_replace(basename($file), $meta['thumb'], $file);
$thumbfile = apply_filters('wp_delete_file', $thumbfile); $thumbfile = apply_filters('wp_delete_file', $thumbfile);
@ unlink( path_join($uploadPath['basedir'], $thumbfile) ); @ unlink( path_join($uploadpath['basedir'], $thumbfile) );
} }
} }
// remove intermediate images if there are any // remove intermediate and backup images if there are any
$sizes = apply_filters('intermediate_image_sizes', array('thumbnail', 'medium', 'large')); $sizes = apply_filters('intermediate_image_sizes', array('thumbnail', 'medium', 'large'));
foreach ( $sizes as $size ) { foreach ( $sizes as $size ) {
if ( $intermediate = image_get_intermediate_size($postid, $size) ) { if ( $intermediate = image_get_intermediate_size($post_id, $size) ) {
$intermediate_file = apply_filters('wp_delete_file', $intermediate['path']); $intermediate_file = apply_filters('wp_delete_file', $intermediate['path']);
@ unlink( path_join($uploadPath['basedir'], $intermediate_file) ); @ unlink( path_join($uploadpath['basedir'], $intermediate_file) );
}
}
if ( isset($meta['sizes']) && is_array($meta['sizes']) ) {
foreach ( array_keys($meta['sizes']) as $size ) {
if ( preg_match('/backup-[0-9]+/', $size) ) { // make sure this is a backup
if ( $del = image_get_intermediate_size($post_id, $size) ) {
$del_file = apply_filters('wp_delete_file', $del['path']);
@ unlink( path_join($uploadpath['basedir'], $del_file) );
}
}
} }
} }
@ -2713,7 +2723,7 @@ function wp_delete_attachment($postid) {
if ( ! empty($file) ) if ( ! empty($file) )
@ unlink($file); @ unlink($file);
clean_post_cache($postid); clean_post_cache($post_id);
return $post; return $post;
} }
@ -2727,14 +2737,24 @@ function wp_delete_attachment($postid) {
* @param bool $unfiltered Optional, default is false. If true, filters are not run. * @param bool $unfiltered Optional, default is false. If true, filters are not run.
* @return string|bool Attachment meta field. False on failure. * @return string|bool Attachment meta field. False on failure.
*/ */
function wp_get_attachment_metadata( $post_id, $unfiltered = false ) { function wp_get_attachment_metadata( $post_id, $unfiltered = false, $remove_backups = true ) {
$post_id = (int) $post_id; $post_id = (int) $post_id;
if ( !$post =& get_post( $post_id ) ) if ( !$post =& get_post( $post_id ) )
return false; return false;
$data = get_post_meta( $post->ID, '_wp_attachment_metadata', true ); $data = get_post_meta( $post->ID, '_wp_attachment_metadata', true );
if ( $remove_backups && isset($data['sizes']) && is_array($data['sizes']) ) {
$sizes = apply_filters( 'intermediate_image_sizes', array('large', 'medium', 'thumbnail') );
foreach ( $data['sizes'] as $size => $val ) {
if ( !in_array( $size, $sizes, true ) )
unset($data['sizes'][$size]);
}
}
if ( $unfiltered ) if ( $unfiltered )
return $data; return $data;
return apply_filters( 'wp_get_attachment_metadata', $data, $post->ID ); return apply_filters( 'wp_get_attachment_metadata', $data, $post->ID );
} }

View File

@ -213,6 +213,11 @@ function wp_default_scripts( &$scripts ) {
$scripts->add( 'comment-reply', "/wp-includes/js/comment-reply$suffix.js", false, '20090102'); $scripts->add( 'comment-reply', "/wp-includes/js/comment-reply$suffix.js", false, '20090102');
$scripts->add( 'json2', "/wp-includes/js/json2$suffix.js", false, '20090817');
$scripts->add( 'imgareaselect', "/wp-includes/js/imgareaselect/jquery.imgareaselect$suffix.js", array('jquery'), '0.9.1' );
$scripts->add_data( 'imgareaselect', 'group', 1 );
if ( is_admin() ) { if ( is_admin() ) {
$scripts->add( 'ajaxcat', "/wp-admin/js/cat$suffix.js", array( 'wp-lists' ), '20090102' ); $scripts->add( 'ajaxcat', "/wp-admin/js/cat$suffix.js", array( 'wp-lists' ), '20090102' );
$scripts->add_data( 'ajaxcat', 'group', 1 ); $scripts->add_data( 'ajaxcat', 'group', 1 );
@ -399,6 +404,9 @@ function wp_default_scripts( &$scripts ) {
$scripts->add( 'codepress', '/wp-includes/js/codepress/codepress.js', false, '0.9.6' ); $scripts->add( 'codepress', '/wp-includes/js/codepress/codepress.js', false, '0.9.6' );
$scripts->add_data( 'codepress', 'group', 1 ); $scripts->add_data( 'codepress', 'group', 1 );
$scripts->add( 'image-edit', "/wp-admin/js/image-edit$suffix.js", array('jquery', 'json2', 'imgareaselect'), '20090831' );
$scripts->add_data( 'image-edit', 'group', 1 );
} }
} }
@ -464,6 +472,7 @@ function wp_default_styles( &$styles ) {
$styles->add( 'theme-install', "/wp-admin/css/theme-install$suffix.css", array(), '20090610' ); $styles->add( 'theme-install', "/wp-admin/css/theme-install$suffix.css", array(), '20090610' );
$styles->add( 'farbtastic', '/wp-admin/css/farbtastic.css', array(), '1.2' ); $styles->add( 'farbtastic', '/wp-admin/css/farbtastic.css', array(), '1.2' );
$styles->add( 'jcrop', '/wp-includes/js/jcrop/jquery.Jcrop.css', array(), '0.9.8' ); $styles->add( 'jcrop', '/wp-includes/js/jcrop/jquery.Jcrop.css', array(), '0.9.8' );
$styles->add( 'imgareaselect', '/wp-includes/js/imgareaselect/imgareaselect.css', array(), '0.9.1' );
foreach ( $rtl_styles as $rtl_style ) foreach ( $rtl_styles as $rtl_style )
$styles->add_data( $rtl_style, 'rtl', true ); $styles->add_data( $rtl_style, 'rtl', true );