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:
parent
8772775a15
commit
1c161c23c2
|
@ -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
|
@ -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
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
|
@ -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;" />
|
||||||
|
×
|
||||||
|
<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&_ajax_nonce={$nonce}&postid={$post_id}&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;
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
|
@ -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']} × {$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');
|
||||||
|
|
||||||
?>
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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}};
|
|
@ -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 + ' × ' + 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
|
@ -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'));
|
||||||
|
|
||||||
|
|
|
@ -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
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 |
|
@ -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 {
|
||||||
|
}
|
|
@ -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
|
@ -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 ' '),
|
||||||
|
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');
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}());
|
||||||
|
|
|
@ -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")}}}());
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
Loading…
Reference in New Issue