WordPress.org

Make WordPress Core

Changeset 7103


Ignore:
Timestamp:
02/29/2008 09:51:36 AM (13 years ago)
Author:
ryan
Message:

Post Edit Collision Detection from mdawaffe. fixes #6043

Location:
trunk
Files:
1 added
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-admin/admin-ajax.php

    r7098 r7103  
    471471case 'autosave' : // The name of this action is hardcoded in edit_post()
    472472    check_ajax_referer( 'autosave', 'autosavenonce' );
     473    global $current_user;
     474
    473475    $_POST['post_content'] = $_POST['content'];
    474476    $_POST['post_excerpt'] = $_POST['excerpt'];
     
    479481        unset($_POST['post_category']);
    480482
     483    $do_autosave = (bool) $_POST['autosave'];
     484    $do_lock = true;
     485
     486    $data = '<div class="updated"><p>' . sprintf( __('Saved at %s.'), date( __('g:i:s a'), current_time( 'timestamp', true ) ) ) . '</p></div>';
     487
     488    $supplemental = array();
     489
     490    $id = 0;
    481491    if($_POST['post_ID'] < 0) {
    482492        $_POST['temp_ID'] = $_POST['post_ID'];
    483         $id = wp_write_post();
    484         if( is_wp_error($id) )
    485             die($id->get_error_message());
    486         else
    487             die("$id");
     493        if ( $do_autosave )
     494            $id = wp_write_post();
    488495    } else {
    489496        $post_ID = (int) $_POST['post_ID'];
    490497        $_POST['ID'] = $post_ID;
    491498        $post = get_post($post_ID);
     499
     500        if ( $last = wp_check_post_lock( $post->ID ) ) {
     501            $do_autosave = $do_lock = false;
     502
     503            $last_user = get_userdata( $last );
     504            $last_user_name = $last_user ? $last_user->display_name : __( 'Someone' );
     505            $data = new WP_Error( 'locked', sprintf(
     506                $_POST['post_type'] == 'page' ? __( 'Autosave disabled: %s is currently editing this page.' ) : __( 'Autosave disabled: %s is currently editing this post.' ),
     507                wp_specialchars( $last_user_name )
     508            ) );
     509
     510            $supplemental['disable_autosave'] = 'disable';
     511        }
     512
    492513        if ( 'page' == $post->post_type ) {
    493514            if ( !current_user_can('edit_page', $post_ID) )
     
    497518                die(__('You are not allowed to edit this post.'));
    498519        }
    499         wp_update_post($_POST);
    500     }
    501     die('0');
    502 break;
     520        if ( $do_autosave )
     521            $id = wp_update_post($_POST);
     522        else
     523            $id = $post->ID;
     524    }
     525
     526    if ( $do_lock && $id && is_numeric($id) )
     527        wp_set_post_lock( $id );
     528
     529    $x = new WP_Ajax_Response( array(
     530        'what' => 'autosave',
     531        'id' => $id,
     532        'data' => $id ? $data : '',
     533        'supplemental' => $supplemental
     534    ) );
     535    $x->send();
     536    break;
    503537case 'autosave-generate-nonces' :
    504538    check_ajax_referer( 'autosave', 'autosavenonce' );
  • trunk/wp-admin/edit-form-advanced.php

    r7101 r7103  
    5656<input type="hidden" name="post_author" value="<?php echo attribute_escape( $post->post_author ); ?>" />
    5757<input type="hidden" id="post_type" name="post_type" value="<?php echo $post->post_type ?>" />
     58<input type="hidden" id="original_post_status" name="original_post_status" value="<?php echo $post->post_status ?>" />
     59<input name="referredby" type="hidden" id="referredby" value="<?php
     60if ( !empty($_REQUEST['popupurl']) )
     61    echo clean_url(stripslashes($_REQUEST['popupurl']));
     62else if ( url_to_postid(wp_get_referer()) == $post_ID )
     63    echo 'redo';
     64else
     65    echo clean_url(stripslashes(wp_get_referer()));
     66?>" />
    5867
    5968<?php echo $form_extra ?>
     
    190199<?php echo $form_prevstatus ?>
    191200
    192 <p class="submit">
    193 
    194 <span id="autosave"></span>
    195 
    196 
    197 <input name="referredby" type="hidden" id="referredby" value="<?php
    198 if ( !empty($_REQUEST['popupurl']) )
    199     echo clean_url(stripslashes($_REQUEST['popupurl']));
    200 else if ( url_to_postid(wp_get_referer()) == $post_ID )
    201     echo 'redo';
    202 else
    203     echo clean_url(stripslashes(wp_get_referer()));
    204 ?>" /></p>
     201<div id="autosave"></div>
    205202
    206203<div id="tagsdiv" class="postbox <?php echo postbox_classes('tagsdiv', 'post'); ?>">
  • trunk/wp-admin/edit-page-form.php

    r7101 r7103  
    3737<?php echo $form_extra ?>
    3838<input type="hidden" id="post_type" name="post_type" value="<?php echo $post->post_type ?>" />
     39<input type="hidden" id="original_post_status" name="original_post_status" value="<?php echo $post->post_status ?>" />
    3940<input name="referredby" type="hidden" id="referredby" value="<?php
    4041if ( url_to_postid(wp_get_referer()) == $post_ID )
     
    170171</div>
    171172
    172 <p class="submit">
    173 
    174 <span id="autosave"></span>
    175 
    176 </p>
     173<div id="autosave"></div>
    177174
    178175<?php do_meta_boxes('page', 'normal', $post); ?>
  • trunk/wp-admin/includes/post.php

    r6983 r7103  
    1919        $now = time();
    2020        $then = strtotime($post->post_date_gmt . ' +0000');
    21         // Keep autosave_interval in sync with autosave-js.php.
    22         $delta = apply_filters( 'autosave_interval', 120 ) / 2;
     21        $delta = get_option( 'autosave_interval' ) / 2;
    2322        if ( ($now - $then) < $delta )
    2423            return $post_ID;
     
    620619}
    621620
     621// false: not locked or locked by current user
     622// int: user ID of user with lock
     623function wp_check_post_lock( $post_id ) {
     624    global $current_user;
     625
     626    if ( !$post = get_post( $post_id ) )
     627        return false;
     628
     629    $lock = get_post_meta( $post->ID, '_edit_lock', true );
     630    $last = get_post_meta( $post->ID, '_edit_last', true );
     631
     632    $time_window = apply_filters( 'wp_check_post_lock_window', get_option( 'autosave_interval' ) * 2 );
     633
     634    if ( $lock && $lock > time() - $time_window && $last != $current_user->ID )
     635        return $last;
     636    return false;
     637}
     638
     639function wp_set_post_lock( $post_id ) {
     640    global $current_user;
     641    if ( !$post = get_post( $post_id ) )
     642        return false;
     643    if ( !$current_user || !$current_user->ID )
     644        return false;
     645   
     646    $now = time();
     647
     648    if ( !add_post_meta( $post->ID, '_edit_lock', $now, true ) )
     649        update_post_meta( $post->ID, '_edit_lock', $now );
     650    if ( !add_post_meta( $post->ID, '_edit_last', $current_user->ID, true ) )
     651        update_post_meta( $post->ID, '_edit_last', $current_user->ID );
     652}
     653
    622654?>
  • trunk/wp-admin/includes/upgrade.php

    r6705 r7103  
    199199        upgrade_230_old_tables();
    200200
    201     if ( $wp_current_db_version < 6689 )
     201    if ( $wp_current_db_version < 7098 )
    202202        upgrade_250();
    203203
     
    726726        populate_roles_250();
    727727    }
     728
     729    add_option('autosave_interval', 60);
    728730}
    729731
  • trunk/wp-admin/page.php

    r7047 r7103  
    5858    wp_enqueue_script('thickbox');
    5959    wp_enqueue_script('media-upload');
    60 
    61     if ( 'draft' == $post->post_status )
     60    if ( $last = wp_check_post_lock( $post->ID ) ) {
     61        $last_user = get_userdata( $last );
     62        $last_user_name = $last_user ? $last_user->display_name : __('Somebody');
     63        $message = sprintf( __( '%s is currently editing this page' ), wp_specialchars( $last_user_name ) );
     64        $message = str_replace( "'", "\'", "<div class='error'><p>$message</p></div>" );
     65        add_action('admin_notices', create_function( '', "echo '$message';" ) );
     66    } else {
     67        wp_set_post_lock( $post->ID );
    6268        wp_enqueue_script('autosave');
     69    }
    6370
    6471    require_once('admin-header.php');
  • trunk/wp-admin/post.php

    r7084 r7103  
    6767    wp_enqueue_script('thickbox');
    6868    wp_enqueue_script('media-upload');
    69 
    70     if ( 'draft' == $post->post_status )
     69    if ( $last = wp_check_post_lock( $post->ID ) ) {
     70        $last_user = get_userdata( $last );
     71        $last_user_name = $last_user ? $last_user->display_name : __('Somebody');
     72        $message = sprintf( __( '%s is currently editing this post' ), wp_specialchars( $last_user_name ) );
     73        $message = str_replace( "'", "\'", "<div class='error'><p>$message</p></div>" );
     74        add_action('admin_notices', create_function( '', "echo '$message';" ) );
     75    } else {
     76        wp_set_post_lock( $post->ID );
    7177        wp_enqueue_script('autosave');
     78    }
    7279
    7380    require_once('admin-header.php');
  • trunk/wp-admin/wp-admin.css

    r7101 r7103  
    10321032    margin-bottom: 10px;
    10331033    margin-right: 8px;
     1034}
     1035
     1036#poststuff #autosave {
     1037    margin: 0;
     1038    padding: 0;
     1039}
     1040
     1041#poststuff #autosave div.updated, #poststuff #autosave div.error {
     1042    margin: 0 8px 10px 20px;
    10341043}
    10351044
  • trunk/wp-includes/classes.php

    r7081 r7103  
    778778
    779779        $s = '';
    780         if ( (array) $supplemental )
     780        if ( (array) $supplemental ) {
    781781            foreach ( $supplemental as $k => $v )
    782782                $s .= "<$k><![CDATA[$v]]></$k>";
     783            $s = "<supplemental>$s</supplemental>";
     784        }
    783785
    784786        if ( false === $action )
  • trunk/wp-includes/js/autosave.js

    r6955 r7103  
    22var autosavePeriodical;
    33
    4 function autosave_start_timer() {
    5     autosaveLast = jQuery('#post #title').val()+jQuery('#post #content').val();
    6     // Keep autosave_interval in sync with edit_post().
    7     autosavePeriodical = jQuery.schedule({time: autosaveL10n.autosaveInterval * 1000, func: autosave, repeat: true, protect: true});
     4jQuery(function($) {
     5    autosaveLast = $('#post #title').val()+$('#post #content').val();
     6    autosavePeriodical = $.schedule({time: autosaveL10n.autosaveInterval * 1000, func: function() { autosave(); }, repeat: true, protect: true});
    87
    98    //Disable autosave after the form has been submitted
    10     jQuery("#post #submit").submit(function() { jQuery.cancel(autosavePeriodical); });
    11     jQuery("#post #save").click(function() { jQuery.cancel(autosavePeriodical); });
    12     jQuery("#post #submit").click(function() { jQuery.cancel(autosavePeriodical); });
    13     jQuery("#post #publish").click(function() { jQuery.cancel(autosavePeriodical); });
    14     jQuery("#post #deletepost").click(function() { jQuery.cancel(autosavePeriodical); });
     9    $("#post").submit(function() { $.cancel(autosavePeriodical); });
    1510
    16     // Autosave early on for a new post
    17     jQuery("#content").keypress(function() {
    18         if ( 1 === ( jQuery(this).val().length % 15 ) && 1 > parseInt(jQuery("#post_ID").val(),10) )
     11    // Autosave early on for a new post.  Why?  Should this only be run once?
     12    $("#content").keypress(function() {
     13        if ( 1 === ( $(this).val().length % 15 ) && 1 > parseInt($("#post_ID").val(),10) )
    1914            setTimeout(autosave, 5000);
    2015    });
    21 }
    22 addLoadEvent(autosave_start_timer)
     16});
    2317
    24 function autosave_cur_time() {
    25     var now = new Date();
    26     return "" + ((now.getHours() >12) ? now.getHours() -12 : now.getHours()) +
    27     ((now.getMinutes() < 10) ? ":0" : ":") + now.getMinutes() +
    28     ((now.getSeconds() < 10) ? ":0" : ":") + now.getSeconds();
     18// called when autosaving pre-existing post
     19function autosave_saved(response) {
     20    var res = wpAjax.parseAjaxResponse(response, 'autosave'); // parse the ajax response
     21    var message = '';
     22
     23    if ( res && res.responses.length ) {
     24        message = res.responses[0].data; // The saved message or error.
     25        // someone else is editing: disable autosave, set errors
     26        if ( res.responses[0].supplemental && 'disable' == res.responses[0].supplemental['disable_autosave'] ) {
     27            autosave = function() {};
     28            res = { errors: true };
     29        }
     30
     31        // if no errors: add preview link and slug UI
     32        if ( !res.errors ) {
     33            var postID = parseInt( res.responses[0].id );
     34            if ( !isNaN(postID) && postID > 0 ) {
     35                autosave_update_preview_link(postID);
     36                autosave_update_slug(postID);
     37            }
     38        }
     39    }
     40    if ( message ) { jQuery('#autosave').html(message); } // update autosave message
     41    autosave_enable_buttons(); // re-enable disabled form buttons
     42    return res;
    2943}
    3044
     45// called when autosaving new post
    3146function autosave_update_post_ID(response) {
    32     var res = parseInt(response);
    33     var message;
     47    var res = autosave_saved(response); // parse the ajax response do the above
    3448
    35     if(isNaN(res)) {
    36         message = autosaveL10n.errorText.replace(/%response%/g, response);
    37     } else if( res > 0 ) {
    38         message = autosaveL10n.saveText.replace(/%time%/g, autosave_cur_time());
    39         jQuery('#post_ID').attr({name: "post_ID"});
    40         jQuery('#post_ID').val(res);
    41         // We need new nonces
    42         jQuery.post(autosaveL10n.requestFile, {
    43             action: "autosave-generate-nonces",
    44             post_ID: res,
    45             autosavenonce: jQuery('#autosavenonce').val(),
    46             post_type: jQuery('#post_type').val()
    47         }, function(html) {
    48             jQuery('#_wpnonce').val(html);
    49         });
    50         jQuery('#hiddenaction').val('editpost');
    51     } else {
    52         message = autosaveL10n.failText;
     49    // if no errors: update post_ID from the temporary value, grab new save-nonce for that new ID
     50    if ( res && res.responses.length && !res.errors ) {
     51        var postID = parseInt( res.responses[0].id );
     52        if ( !isNaN(postID) && postID > 0 ) {
     53            if ( postID == parseInt(jQuery('#post_ID').val()) ) { return; } // no need to do this more than once
     54            jQuery('#post_ID').attr({name: "post_ID"});
     55            jQuery('#post_ID').val(postID);
     56            // We need new nonces
     57            jQuery.post(autosaveL10n.requestFile, {
     58                action: "autosave-generate-nonces",
     59                post_ID: postID,
     60                autosavenonce: jQuery('#autosavenonce').val(),
     61                post_type: jQuery('#post_type').val()
     62            }, function(html) {
     63                jQuery('#_wpnonce').val(html);
     64            });
     65            jQuery('#hiddenaction').val('editpost');
     66        }
    5367    }
    54     jQuery('#autosave').html(message);
    55     autosave_update_preview_link(res);
    56     autosave_update_slug(res);
    57     autosave_enable_buttons();
    5868}
    5969
    6070function autosave_update_preview_link(post_id) {
    6171    // Add preview button if not already there
    62     if ( ! jQuery('#previewview > *').get()[0] ) {
     72    if ( !jQuery('#previewview > *').size() ) {
    6373        var post_type = jQuery('#post_type').val();
    6474        var previewText = 'page' == post_type ? autosaveL10n.previewPageText : autosaveL10n.previewPostText;
     
    7585function autosave_update_slug(post_id) {
    7686    // create slug area only if not already there
    77     if ( 'undefined' != typeof make_slugedit_clickable && ! jQuery('#edit-slug-box > *').get()[0] ) {
    78         jQuery.post(slugL10n.requestFile, {
    79             action: 'sample-permalink',
    80             post_id: post_id,
    81             samplepermalinknonce: jQuery('#samplepermalinknonce').val()}, function(data) {
     87    if ( jQuery.isFunction(make_slugedit_clickable) && !jQuery('#edit-slug-box > *').size() ) {
     88        jQuery.post(
     89            slugL10n.requestFile,
     90            {
     91                action: 'sample-permalink',
     92                post_id: post_id,
     93                samplepermalinknonce: jQuery('#samplepermalinknonce').val()
     94            },
     95            function(data) {
    8296                jQuery('#edit-slug-box').html(data);
    8397                make_slugedit_clickable();
    84             });
     98            }
     99        );
    85100    }
    86101}
    87102
    88103function autosave_loading() {
    89     jQuery('#autosave').html(autosaveL10n.savingText);
     104    jQuery('#autosave').html('<div class="updated"><p>' + autosaveL10n.savingText + '</p></div>');
    90105}
    91106
    92 function autosave_saved(response) {
    93     var res = parseInt(response);
    94     var message;
    95 
    96     if(isNaN(res)) {
    97         message = autosaveL10n.errorText.replace(/%response%/g, response);
    98     } else {
    99         message = autosaveL10n.saveText.replace(/%time%/g, autosave_cur_time());
    100     }
    101     jQuery('#autosave').html(message);
    102     autosave_update_preview_link(res);
    103     autosave_update_slug(res);
    104     autosave_enable_buttons();
     107function autosave_enable_buttons() {
     108    jQuery("#submitpost :button:disabled, #submitpost :submit:disabled").attr('disabled', '');
    105109}
    106110
    107111function autosave_disable_buttons() {
    108     jQuery("#post #save:enabled").attr('disabled', 'disabled');
    109     jQuery("#post #submit:enabled").attr('disabled', 'disabled');
    110     jQuery("#post #publish:enabled").attr('disabled', 'disabled');
    111     jQuery("#post #deletepost:enabled").attr('disabled', 'disabled');
    112     setTimeout('autosave_enable_buttons();', 1000); // Re-enable 1 sec later.  Just gives autosave a head start to avoid collisions.
     112    jQuery("#submitpost :button:enabled, #submitpost :submit:enabled").attr('disabled', 'disabled');
     113    setTimeout(autosave_enable_buttons, 1000); // Re-enable 1 sec later.  Just gives autosave a head start to avoid collisions.
    113114}
    114115
    115 function autosave_enable_buttons() {
    116     jQuery("#post #save:disabled").attr('disabled', '');
    117     jQuery("#post #submit:disabled").attr('disabled', '');
    118     jQuery("#post #publish:disabled").attr('disabled', '');
    119     jQuery("#post #deletepost:disabled").attr('disabled', '');
    120 }
     116var autosave = function() {
     117    // (bool) is rich editor enabled and active
     118    var rich = (typeof tinyMCE != "undefined") && tinyMCE.activeEditor && !tinyMCE.activeEditor.isHidden();
     119    var post_data = {
     120        action: "autosave",
     121        post_ID:  jQuery("#post_ID").val() || 0,
     122        post_title: jQuery("#title").val() || "",
     123        autosavenonce: jQuery('#autosavenonce').val(),
     124        tags_input: jQuery("#tags-input").val() || "",
     125        post_type: jQuery('#post_type').val() || "",
     126        autosave: 1
     127    };
    121128
    122 function autosave() {
    123     var rich = ( (typeof tinyMCE != "undefined") && tinyMCE.activeEditor && ! tinyMCE.activeEditor.isHidden() ) ? true : false;
    124     var post_data = {
    125             action: "autosave",
    126             post_ID:  jQuery("#post_ID").val() || 0,
    127             post_title: jQuery("#title").val() || "",
    128             autosavenonce: jQuery('#autosavenonce').val(),
    129             tags_input: jQuery("#tags-input").val() || "",
    130             post_type: jQuery('#post_type').val() || ""
    131         };
     129    // We always send the ajax request in order to keep the post lock fresh.
     130    // This (bool) tells whether or not to write the post to the DB during the ajax request.
     131    var doAutoSave = true;
    132132
    133133    /* Gotta do this up here so we can check the length when tinyMCE is in use */
    134     if ( rich ) {
    135         // Don't run while the TinyMCE spellcheck is on.
    136         if ( tinyMCE.activeEditor.plugins.spellchecker && tinyMCE.activeEditor.plugins.spellchecker.active ) return;
    137         tinyMCE.triggerSave();
    138     }
     134    if ( rich ) { tinyMCE.triggerSave(); }
    139135   
    140136    post_data["content"] = jQuery("#content").val();
     
    142138        post_data["post_name"] = jQuery('#post_name').val();
    143139
     140    // Nothing to save or no change.
    144141    if(post_data["post_title"].length==0 || post_data["content"].length==0 || post_data["post_title"] + post_data["content"] == autosaveLast) {
    145         return;
     142        doAutoSave = false
    146143    }
    147144
    148145    autosave_disable_buttons();
     146
     147    var origStatus = jQuery('#original_post_status').val();
     148    if ( 'draft' != origStatus ) // autosave currently only turned on for drafts
     149        doAutoSave = false;
    149150
    150151    autosaveLast = jQuery("#title").val()+jQuery("#content").val();
     
    162163        post_data["excerpt"] = jQuery("#excerpt").val();
    163164
    164     if ( rich )
    165         tinyMCE.triggerSave();
    166    
    167     post_data["content"] = jQuery("#content").val();
     165    // Don't run while the TinyMCE spellcheck is on.  Why?  Who knows.
     166    if ( rich && tinyMCE.activeEditor.plugins.spellchecker && tinyMCE.activeEditor.plugins.spellchecker.active ) {
     167        doAutoSave = false;
     168    }
    168169
    169170    if(parseInt(post_data["post_ID"]) < 1) {
    170171        post_data["temp_ID"] = post_data["post_ID"];
    171         jQuery.ajaxSetup({
    172             success: function(html) { autosave_update_post_ID(html); }
    173         });
     172        var successCallback = autosave_update_post_ID; // new post
    174173    } else {
    175         jQuery.ajaxSetup({
    176             success: function(html) { autosave_saved(html); }
    177         });
     174        var successCallback = autosave_saved; // pre-existing post
    178175    }
     176
     177    if ( !doAutoSave ) {
     178        post_data['autosave'] = 0;
     179    }
     180
    179181    jQuery.ajax({
    180182        data: post_data,
    181         beforeSend: function() { autosave_loading() },
     183        beforeSend: doAutoSave ? autosave_loading : null,
    182184        type: "POST",
    183         url: autosaveL10n.requestFile
     185        url: autosaveL10n.requestFile,
     186        success: successCallback
    184187    });
    185188}
  • trunk/wp-includes/js/wp-lists.js

    r7094 r7103  
    22var currentFormEl = false;
    33var fs = {add:'ajaxAdd',del:'ajaxDel',dim:'ajaxDim',process:'process',recolor:'recolor'};
    4 
    5 wpAjax = {
    6     unserialize: function( s ) {
    7         var r = {}; if ( !s ) { return r; }
    8         var q = s.split('?'); if ( q[1] ) { s = q[1]; }
    9         var pp = s.split('&');
    10         for ( var i in pp ) {
    11             if ( $.isFunction(pp.hasOwnProperty) && !pp.hasOwnProperty(i) ) { continue; }
    12             var p = pp[i].split('=');
    13             r[p[0]] = p[1];
    14         }
    15         return r;
    16     },
    17     parseAjaxResponse: function( x, r, e ) { // 1 = good, 0 = strange (bad data?), -1 = you lack permission
    18         var re = $('#' + r).html('');
    19         if ( x && typeof x == 'object' && x.getElementsByTagName('wp_ajax') ) {
    20             var errs = $('wp_error', x);
    21             if ( errs.size() ) {
    22                 var err = '';
    23                 errs.each( function() {
    24                     var code = $(this).attr('code');
    25                     if ( formField = $('wp_error_data[code="' + code + '"] form-field', x).text() )
    26                         code = formField;
    27                     wpAjax.invalidateForm( $('#' + e + ' :input[name="' + code + '"]' ).parents('.form-field:first') );
    28                     err += '<p>' + this.firstChild.nodeValue + '</p>';
    29                 } );
    30                 return !re.html( '<div class="error">' + err + '</div>' );
    31             }
    32             return true;
    33         }
    34         if ( isNaN(x) ) { return !re.html('<div class="error"><p>' + x + '</p></div>'); }
    35         x = parseInt(x,10);
    36         if ( -1 == x ) { return !re.html('<div class="error"><p>You do not have permission to do that.</p></div>'); }
    37         else if ( 0 === x ) { return !re.html('<div class="error"><p>AJAX is teh b0rked.</p></div>'); }
    38         return true;
    39     },
    40     invalidateForm: function( jQ ) {
    41         jQ.addClass( 'form-invalid' ).change( function() { $(this).removeClass( 'form-invalid' ); } );
    42     }
    43 };
    444
    455var wpList = {
     
    12888
    12989        s.success = function(r) {
    130             if ( !wpAjax.parseAjaxResponse(r, s.response, s.element) ) { return false; }
    131 
    132             $(s.what + ' response_data', r).each( function() {
    133                 var t = $(this);
    134                 wpList.add.call( list, t.text(), $.extend( {}, s, { // this.firstChild.nodevalue
    135                     pos: t.parent().attr( 'position' ) || 0,
    136                     id: t.parent().attr( 'id' ) || 0,
    137                     oldId: t.parent().attr( 'old_id' ) || null
     90            var res = wpAjax.parseAjaxResponse(r, s.response, s.element);
     91            if ( !res || res.errors ) { return false; }
     92
     93            jQuery.each( res.responses, function() {
     94                wpList.add.call( list, this.data, $.extend( {}, s, { // this.firstChild.nodevalue
     95                    pos: this.position || 0,
     96                    id: this.id || 0,
     97                    oldId: this.oldId || null
    13898                } ) );
    13999            } );
     
    142102                var o = this.complete;
    143103                this.complete = function(x,st) {
    144                     var _s = $.extend( { xml: x, status: st }, s );
     104                    var _s = $.extend( { xml: x, status: st, parsed: res }, s );
    145105                    s.addAfter( r, _s );
    146106                    if ( $.isFunction(o) ) { o(x,st); }
     
    195155
    196156        s.success = function(r) {
    197             if ( !wpAjax.parseAjaxResponse(r, s.response, s.element) ) {
     157            var res = wpAjax.parseAjaxResponse(r, s.response, s.element);
     158            if ( !res || res.errors ) {
    198159                element.stop().css( 'backgroundColor', '#FF3333' ).show().queue( function() { list.wpList.recolor(); $(this).dequeue(); } );
    199160                return false;
     
    203164                this.complete = function(x,st) {
    204165                    element.queue( function() {
    205                         var _s = $.extend( { xml: x, status: st }, s );
     166                        var _s = $.extend( { xml: x, status: st, parsed: res }, s );
    206167                        s.delAfter( r, _s );
    207168                        if ( $.isFunction(o) ) { o(x,st); }
     
    257218
    258219        s.success = function(r) {
    259             if ( !wpAjax.parseAjaxResponse(r, s.response, s.element) ) {
     220            var res = wpAjax.parseAjaxResponse(r, s.response, s.element);
     221            if ( !res || res.errors ) {
    260222                element.stop().css( 'backgroundColor', '#FF3333' )[isClass?'removeClass':'addClass'](s.dimClass).show().queue( function() { list.wpList.recolor(); $(this).dequeue(); } );
    261223                return false;
     
    265227                this.complete = function(x,st) {
    266228                    element.queue( function() {
    267                         var _s = $.extend( { xml: x, status: st }, s );
     229                        var _s = $.extend( { xml: x, status: st, parsed: res }, s );
    268230                        s.dimAfter( r, _s );
    269231                        if ( $.isFunction(o) ) { o(x,st); }
  • trunk/wp-includes/script-loader.php

    r7100 r7103  
    4242        $this->add( 'prototype', '/wp-includes/js/prototype.js', false, '1.6');
    4343
    44         $this->add( 'autosave', '/wp-includes/js/autosave.js', array('jquery', 'schedule'), '20080221');
     44        $this->add( 'wp-ajax-response', '/wp-includes/js/wp-ajax-response.js', array('jquery'), '20080229' . mt_rand() );
     45        $this->localize( 'wp-ajax-response', 'wpAjax', array(
     46            'noPerm' => 'You do not have permission to do that.',
     47            'broken' => 'AJAX is teh b0rked.'
     48        ) );
     49
     50        $this->add( 'autosave', '/wp-includes/js/autosave.js', array('schedule', 'wp-ajax-response'), '20080221' . mt_rand());
    4551        $this->localize( 'autosave', 'autosaveL10n', array(
    46             'autosaveInterval' => apply_filters('autosave_interval', '60'),
    47             'errorText' => __('Error: %response%'),
    48             'failText' => __('Error: Autosave Failed.'),
    49             'previewPageText' => __('Preview this Page'),
    50             'previewPostText' => __('Preview this Post'),
    51             'saveText' => __('Saved at %time%.'),
     52            'autosaveInterval' => get_option( 'autosave_interval' ),
     53            'previewPageText' => __('View this Page'),
     54            'previewPostText' => __('View this Post'),
    5255            'requestFile' => get_option( 'siteurl' ) . '/wp-admin/admin-ajax.php',
    53             'savingText' => __('Saving Draft...')
     56            'savingText' => __('Saving&#8230;')
    5457        ) );
    5558
     
    6265        ) );
    6366
    64         $this->add( 'wp-lists', '/wp-includes/js/wp-lists.js', array('jquery'), '20080228' );
     67        $this->add( 'wp-lists', '/wp-includes/js/wp-lists.js', array('wp-ajax-response'), '20080228' . mt_rand());
    6568        $this->localize( 'wp-lists', 'wpListL10n', array(
    6669            'url' => get_option( 'siteurl' ) . '/wp-admin/admin-ajax.php'
  • trunk/wp-includes/version.php

    r6957 r7103  
    1717 * @global int $wp_db_version
    1818 */
    19 $wp_db_version = 6846;
     19$wp_db_version = 7098;
    2020
    2121?>
Note: See TracChangeset for help on using the changeset viewer.