WordPress.org

Make WordPress Core

Ticket #3824: autosave.js.7.diff

File autosave.js.7.diff, 22.3 KB (added by rmccue, 6 years ago)

Should be final patch. Includes speed improvements and setting temp_ID

  • wp-admin/page-new.php

     
    33$title = __('New Page'); 
    44$parent_file = 'post-new.php'; 
    55$editing = true; 
    6 wp_enqueue_script('prototype'); 
    7 wp_enqueue_script('jquery'); 
    86wp_enqueue_script('autosave'); 
    97require_once('admin-header.php'); 
    108?> 
  • wp-admin/page.php

     
    5252                exit(); 
    5353        } 
    5454 
    55         if($post->post_status == 'draft') { 
    56                 wp_enqueue_script('prototype'); 
    57                 wp_enqueue_script('jquery'); 
     55        if ( 'draft' == $post->post_status ) 
    5856                wp_enqueue_script('autosave'); 
    59         } 
     57 
    6058        require_once('admin-header.php'); 
    6159 
    6260        if ( !current_user_can('edit_page', $page_ID) ) 
  • wp-admin/post-new.php

     
    33$title = __('Create New Post'); 
    44$parent_file = 'post-new.php'; 
    55$editing = true; 
    6 wp_enqueue_script('prototype'); 
    7 wp_enqueue_script('jquery'); 
    86wp_enqueue_script('autosave'); 
    97wp_enqueue_script('post'); 
    108 
  • wp-admin/post.php

     
    6060 
    6161        wp_enqueue_script('post'); 
    6262 
    63         if( 'draft' == $post->post_status ) { 
    64                 wp_enqueue_script('prototype'); 
     63        if ( 'draft' == $post->post_status ) 
    6564                wp_enqueue_script('autosave'); 
    66         } 
    6765 
    6866        require_once('admin-header.php'); 
    6967 
  • wp-includes/functions.php

     
    968968 
    969969function wp_nonce_field( $action = -1, $name = "_wpnonce", $referer = true ) { 
    970970        $name = attribute_escape( $name ); 
    971         echo '<input type="hidden" name="' . $name . '" value="' . wp_create_nonce( $action ) . '" />'; 
     971        echo '<input type="hidden" id="' . $name . '" name="' . $name . '" value="' . wp_create_nonce( $action ) . '" />'; 
    972972        if ( $referer ) 
    973973                wp_referer_field(); 
    974974} 
  • wp-includes/js/autosave.js

     
    22var autosavePeriodical; 
    33 
    44function autosave_start_timer() { 
    5         var form = $('post'); 
    6         autosaveLast = form.post_title.value+form.content.value; 
     5        autosaveLast = jQuery('#post #title').val()+jQuery('#post #content').val(); 
    76        // Keep autosave_interval in sync with edit_post(). 
    8         autosavePeriodical = new PeriodicalExecuter(autosave, autosaveL10n.autosaveInterval); 
     7        autosavePeriodical = jQuery.schedule({time: autosaveL10n.autosaveInterval, func: autosave, repeat: true, protect: true}); 
     8 
    99        //Disable autosave after the form has been submitted 
    10         if(form.addEventListener) { 
    11                 form.addEventListener("submit", function () { autosavePeriodical.currentlyExecuting = true; }, false); 
    12         } 
    13         if(form.attachEvent) { 
    14                 form.save ? form.save.attachEvent("onclick", function () { autosavePeriodical.currentlyExecuting = true; }) : null; 
    15                 form.submit ? form.submit.attachEvent("onclick", function () { autosavePeriodical.currentlyExecuting = true; }) : null; 
    16                 form.publish ? form.publish.attachEvent("onclick", function () { autosavePeriodical.currentlyExecuting = true; }) : null; 
    17                 form.deletepost ? form.deletepost.attachEvent("onclick", function () { autosavePeriodical.currentlyExecuting = true; }) : null; 
    18         } 
     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); }); 
    1915} 
    2016addLoadEvent(autosave_start_timer) 
    2117 
     
    2622        ((now.getSeconds() < 10) ? ":0" : ":") + now.getSeconds(); 
    2723} 
    2824 
    29 function autosave_update_nonce() { 
    30         var response = nonceAjax.response; 
    31         document.getElementsByName('_wpnonce')[0].value = response; 
    32 } 
    33  
    34 function autosave_update_post_ID() { 
    35         var response = autosaveAjax.response; 
     25function autosave_update_post_ID(response) { 
    3626        var res = parseInt(response); 
    3727        var message; 
    3828 
     
    4030                message = autosaveL10n.errorText.replace(/%response%/g, response); 
    4131        } else { 
    4232                message = autosaveL10n.saveText.replace(/%time%/g, autosave_cur_time()); 
    43                 $('post_ID').name = "post_ID"; 
    44                 $('post_ID').value = res; 
     33                jQuery('#post_ID').attr({name: "post_ID"}); 
     34                jQuery('#post_ID').val(res); 
    4535                // We need new nonces 
    46                 nonceAjax = new sack(); 
    47                 nonceAjax.element = null; 
    48                 nonceAjax.setVar("action", "autosave-generate-nonces"); 
    49                 nonceAjax.setVar("post_ID", res); 
    50                 nonceAjax.setVar("cookie", document.cookie); 
    51                 nonceAjax.setVar("post_type", $('post_type').value); 
    52                 nonceAjax.requestFile = autosaveL10n.requestFile; 
    53                 nonceAjax.onCompletion = autosave_update_nonce; 
    54                 nonceAjax.method = "POST"; 
    55                 nonceAjax.runAJAX(); 
    56                 $('hiddenaction').value = 'editpost'; 
     36                jQuery.post(autosaveL10n.requestFile, { 
     37                        action: "autosave-generate-nonces", 
     38                        post_ID: res, 
     39                        cookie: document.cookie, 
     40                        post_type: jQuery('#post_type').val() 
     41                }, function(html) { 
     42                        jQuery('#_wpnonce').val(html); 
     43                }); 
     44                jQuery('#hiddenaction').val('editpost'); 
    5745        } 
    58         $('autosave').innerHTML = message; 
     46        jQuery('#autosave').html(message); 
    5947        autosave_enable_buttons(); 
    6048} 
    6149 
    6250function autosave_loading() { 
    63         $('autosave').innerHTML = autosaveL10n.savingText; 
     51        jQuery('#autosave').html(autosaveL10n.savingText); 
    6452} 
    6553 
    66 function autosave_saved() { 
    67         var response = autosaveAjax.response; 
     54function autosave_saved(response) { 
    6855        var res = parseInt(response); 
    6956        var message; 
    7057 
     
    7360        } else { 
    7461                message = autosaveL10n.saveText.replace(/%time%/g, autosave_cur_time()); 
    7562        } 
    76         $('autosave').innerHTML = message; 
     63        jQuery('#autosave').html(message); 
    7764        autosave_enable_buttons(); 
    7865} 
    7966 
    8067function autosave_disable_buttons() { 
    81         var form = $('post'); 
    82         form.save ? form.save.disabled = 'disabled' : null; 
    83         form.submit ? form.submit.disabled = 'disabled' : null; 
    84         form.publish ? form.publish.disabled = 'disabled' : null; 
    85         form.deletepost ? form.deletepost.disabled = 'disabled' : null; 
     68        jQuery("#post #save:enabled").attr('disabled', 'disabled'); 
     69        jQuery("#post #submit:enabled").attr('disabled', 'disabled'); 
     70        jQuery("#post #publish:enabled").attr('disabled', 'disabled'); 
     71        jQuery("#post #deletepost:enabled").attr('disabled', 'disabled'); 
    8672        setTimeout('autosave_enable_buttons();', 1000); // Re-enable 1 sec later.  Just gives autosave a head start to avoid collisions. 
    8773} 
    8874 
    8975function autosave_enable_buttons() { 
    90         var form = $('post'); 
    91         form.save ? form.save.disabled = '' : null; 
    92         form.submit ? form.submit.disabled = '' : null; 
    93         form.publish ? form.publish.disabled = '' : null; 
    94         form.deletepost ? form.deletepost.disabled = '' : null; 
     76        jQuery("#post #save:disabled").attr('disabled', ''); 
     77        jQuery("#post #submit:disabled").attr('disabled', ''); 
     78        jQuery("#post #publish:disabled").attr('disabled', ''); 
     79        jQuery("#post #deletepost:disabled").attr('disabled', ''); 
    9580} 
    9681 
    9782function autosave() { 
    98         var form = $('post'); 
    9983        var rich = ((typeof tinyMCE != "undefined") && tinyMCE.getInstanceById('content')) ? true : false; 
     84        var post_data = { 
     85                        action: "autosave", 
     86                        post_ID:  jQuery("#post_ID").val() || 0, 
     87                        post_title: jQuery("#title").val() || "", 
     88                        cookie: document.cookie, 
     89                        tags_input: jQuery("#tags-input").val() || "", 
     90                        post_type: jQuery('#post_type').val() || "" 
     91                }; 
    10092 
    101         autosaveAjax = new sack(); 
    102  
    10393        /* Gotta do this up here so we can check the length when tinyMCE is in use */ 
    10494        if ( typeof tinyMCE == "undefined" || tinyMCE.configs.length < 1 || rich == false ) { 
    105                 autosaveAjax.setVar("content", form.content.value); 
     95                post_data["content"] = jQuery("#content").val(); 
    10696        } else { 
    10797                // Don't run while the TinyMCE spellcheck is on. 
    10898                if(tinyMCE.selectedInstance.spellcheckerOn) return; 
    10999                tinyMCE.wpTriggerSave(); 
    110                 autosaveAjax.setVar("content", form.content.value); 
     100                post_data["content"] = jQuery("#content").val(); 
    111101        } 
    112102 
    113         if(form.post_title.value.length==0 || form.content.value.length==0 || form.post_title.value+form.content.value == autosaveLast) 
     103        if(post_data["post_title"].length==0 || post_data["content"].length==0 || post_data["post_title"] + post_data["content"] == autosaveLast) { 
    114104                return; 
     105        } 
    115106 
    116107        autosave_disable_buttons(); 
    117108 
    118         autosaveLast = form.post_title.value+form.content.value; 
    119  
    120         cats = document.getElementsByName("post_category[]"); 
     109        autosaveLast = jQuery("#title").val()+jQuery("#content").val(); 
    121110        goodcats = ([]); 
    122         for(i=0;i<cats.length;i++) { 
    123                 if(cats[i].checked) 
    124                         goodcats.push(cats[i].value); 
    125         } 
    126         catslist = goodcats.join(","); 
     111        jQuery("[@name='post_category[]']:checked").each( function(i) { 
     112                goodcats.push(this.value); 
     113        } ); 
     114        post_data["catslist"] = goodcats.join(","); 
    127115 
    128         autosaveAjax.setVar("action", "autosave"); 
    129         autosaveAjax.setVar("cookie", document.cookie); 
    130         autosaveAjax.setVar("catslist", catslist); 
    131         autosaveAjax.setVar("post_ID", $("post_ID").value); 
    132         autosaveAjax.setVar("post_title", form.post_title.value); 
    133         autosaveAjax.setVar("post_type", form.post_type.value); 
    134         autosaveAjax.setVar("tags_input", form.tags_input.value); 
    135         if ( form.comment_status.checked ) 
    136                 autosaveAjax.setVar("comment_status", 'open'); 
    137         if ( form.ping_status.checked ) 
    138                 autosaveAjax.setVar("ping_status", 'open'); 
    139         if(form.excerpt) 
    140                 autosaveAjax.setVar("excerpt", form.excerpt.value); 
     116        if ( jQuery("#comment_status").attr("checked") ) 
     117                post_data["comment_status"] = 'open'; 
     118        if ( jQuery("#ping_status").attr("checked") ) 
     119                post_data["ping_status"] = 'open'; 
     120        if( jQuery("#excerpt")) 
     121                post_data["excerpt"] = jQuery("#excerpt").val(); 
    141122 
    142123        if ( typeof tinyMCE == "undefined" || tinyMCE.configs.length < 1 || rich == false ) { 
    143                 autosaveAjax.setVar("content", form.content.value); 
     124                post_data["content"] = jQuery("#content").val(); 
    144125        } else { 
    145126                tinyMCE.wpTriggerSave(); 
    146                 autosaveAjax.setVar("content", form.content.value); 
     127                post_data["content"] = jQuery("#content").val(); 
    147128        } 
    148129 
    149         autosaveAjax.requestFile = autosaveL10n.requestFile; 
    150         autosaveAjax.method = "POST"; 
    151         autosaveAjax.element = null; 
    152         autosaveAjax.onLoading = autosave_loading; 
    153         autosaveAjax.onInteractive = autosave_loading; 
    154         if(parseInt($("post_ID").value) < 1) 
    155                 autosaveAjax.onCompletion = autosave_update_post_ID; 
    156         else 
    157                 autosaveAjax.onCompletion = autosave_saved; 
    158         autosaveAjax.runAJAX(); 
     130        if(parseInt(post_data["post_ID"]) < 1) { 
     131                post_data["temp_ID"] = post_data["post_ID"]; 
     132                jQuery.ajaxSetup({ 
     133                        success: function(html) { autosave_update_post_ID(html); } 
     134                }); 
     135        } else { 
     136                jQuery.ajaxSetup({ 
     137                        success: function(html) { autosave_saved(html); } 
     138                }); 
     139        } 
     140        jQuery.ajax({ 
     141                data: post_data, 
     142                beforeSend: function() { autosave_loading() }, 
     143                type: "POST", 
     144                url: autosaveL10n.requestFile 
     145        }); 
    159146} 
  • wp-includes/js/jquery/jquery.schedule.js

     
     1/* 
     2**  jquery.schedule.js -- jQuery plugin for scheduled/deferred actions 
     3**  Copyright (c) 2007 Ralf S. Engelschall <rse@engelschall.com>  
     4**  Licensed under GPL <http://www.gnu.org/licenses/gpl.txt> 
     5** 
     6**  $LastChangedDate$ 
     7**  $LastChangedRevision$ 
     8*/ 
     9 
     10/* 
     11 *  <div id="button">TEST BUTTON</div> 
     12 *  <div id="test"></div> 
     13 * 
     14 *  <script type="text/javascript"> 
     15 *     $(document).ready( 
     16 *     function(){ 
     17 *         $('#button').click(function () { 
     18 *             $(this).css("color", "blue").schedule(2000, function (x) { 
     19 *                 $(this).css("color", "red"); 
     20 *                 $("#test").html("test: x = " + x); 
     21 *             }, 42); 
     22 *         }); 
     23 *     }); 
     24 *  </script> 
     25 */ 
     26 
     27(function($) { 
     28 
     29    /*  object constructor  */ 
     30    $.scheduler = function () { 
     31        this.bucket = {}; 
     32        return; 
     33    }; 
     34 
     35    /*  object methods  */ 
     36    $.scheduler.prototype = { 
     37        /*  schedule a task  */ 
     38        schedule: function () { 
     39            /*  schedule context with default parameters */ 
     40            var ctx = { 
     41                "id":         null,         /* unique identifier of high-level schedule */ 
     42                "time":       1000,         /* time in milliseconds after which the task is run */ 
     43                "repeat":     false,        /* whether schedule should be automatically repeated */ 
     44                "protect":    false,        /* whether schedule should be protected from double scheduling */ 
     45                "obj":        null,         /* function context object ("this") */ 
     46                "func":       function(){}, /* function to call */ 
     47                "args":       []            /* function arguments to pass */ 
     48            }; 
     49 
     50            /*  helper function: portable checking whether something is a function  */ 
     51            function _isfn (fn) { 
     52                return ( 
     53                       !!fn 
     54                    && typeof fn != "string" 
     55                    && typeof fn[0] == "undefined" 
     56                    && RegExp("function", "i").test(fn + "") 
     57                ); 
     58            }; 
     59             
     60            /*  parse arguments into context parameters (part 1/4): 
     61                detect an override object (special case to support jQuery method) */ 
     62            var i = 0; 
     63            var override = false; 
     64            if (typeof arguments[i] == "object" && arguments.length > 1) { 
     65                override = true; 
     66                i++; 
     67            } 
     68 
     69            /*  parse arguments into context parameters (part 2/4): 
     70                support the flexible way of an associated array */ 
     71            if (typeof arguments[i] == "object") { 
     72                for (var option in arguments[i]) 
     73                    if (typeof ctx[option] != "undefined") 
     74                        ctx[option] = arguments[i][option]; 
     75                i++; 
     76            } 
     77 
     78            /*  parse arguments into context parameters (part 3/4): 
     79                support: schedule([time [, repeat], ]{{obj, methodname} | func}[, arg, ...]); */ 
     80            if (   typeof arguments[i] == "number" 
     81                || (   typeof arguments[i] == "string"  
     82                    && arguments[i].match(RegExp("^[0-9]+[smhdw]$")))) 
     83                ctx["time"] = arguments[i++]; 
     84            if (typeof arguments[i] == "boolean") 
     85                ctx["repeat"] = arguments[i++]; 
     86            if (typeof arguments[i] == "boolean") 
     87                ctx["protect"] = arguments[i++]; 
     88            if (   typeof arguments[i] == "object" 
     89                && typeof arguments[i+1] == "string" 
     90                && _isfn(arguments[i][arguments[i+1]])) { 
     91                ctx["obj"] = arguments[i++]; 
     92                ctx["func"] = arguments[i++]; 
     93            } 
     94            else if (   typeof arguments[i] != "undefined" 
     95                     && (   _isfn(arguments[i])  
     96                         || typeof arguments[i] == "string")) 
     97                ctx["func"] = arguments[i++]; 
     98            while (typeof arguments[i] != "undefined") 
     99                ctx["args"].push(arguments[i++]); 
     100 
     101            /*  parse arguments into context parameters (part 4/4): 
     102                apply parameters from override object */ 
     103            if (override) { 
     104                if (typeof arguments[1] == "object") { 
     105                    for (var option in arguments[0]) 
     106                        if (   typeof ctx[option] != "undefined" 
     107                            && typeof arguments[1][option] == "undefined") 
     108                            ctx[option] = arguments[0][option]; 
     109                } 
     110                else { 
     111                    for (var option in arguments[0]) 
     112                        if (typeof ctx[option] != "undefined") 
     113                            ctx[option] = arguments[0][option]; 
     114                } 
     115                i++; 
     116            } 
     117 
     118            /*  annotate context with internals */ 
     119            ctx["_scheduler"] = this; /* internal: back-reference to scheduler object */ 
     120            ctx["_handle"]    = null; /* internal: unique handle of low-level task */ 
     121 
     122            /*  determine time value in milliseconds */ 
     123            var match = String(ctx["time"]).match(RegExp("^([0-9]+)([smhdw])$")); 
     124            if (match && match[0] != "undefined" && match[1] != "undefined") 
     125                ctx["time"] = String(parseInt(match[1]) * 
     126                    { s: 1000, m: 1000*60, h: 1000*60*60, 
     127                      d: 1000*60*60*24, w: 1000*60*60*24*7 }[match[2]]); 
     128 
     129            /*  determine unique identifier of task  */ 
     130            if (ctx["id"] == null) 
     131                ctx["id"] = (  String(ctx["repeat"])  + ":" 
     132                             + String(ctx["protect"]) + ":" 
     133                             + String(ctx["time"])    + ":" 
     134                             + String(ctx["obj"])     + ":" 
     135                             + String(ctx["func"])    + ":" 
     136                             + String(ctx["args"])         ); 
     137 
     138            /*  optionally protect from duplicate calls  */ 
     139            if (ctx["protect"]) 
     140                if (typeof this.bucket[ctx["id"]] != "undefined") 
     141                    return this.bucket[ctx["id"]]; 
     142 
     143            /*  support execution of methods by name and arbitrary scripts  */ 
     144            if (!_isfn(ctx["func"])) { 
     145                if (   ctx["obj"] != null 
     146                    && typeof ctx["obj"] == "object" 
     147                    && typeof ctx["func"] == "string" 
     148                    && _isfn(ctx["obj"][ctx["func"]])) 
     149                    /*  method by name  */ 
     150                    ctx["func"] = ctx["obj"][ctx["func"]]; 
     151                else 
     152                    /*  arbitrary script  */ 
     153                    ctx["func"] = eval("function () { " + ctx["func"] + " }"); 
     154            } 
     155 
     156            /*  pass-through to internal scheduling operation  */ 
     157            ctx["_handle"] = this._schedule(ctx); 
     158 
     159            /*  store context into bucket of scheduler object  */ 
     160            this.bucket[ctx["id"]] = ctx; 
     161 
     162            /*  return context  */ 
     163            return ctx; 
     164        }, 
     165 
     166        /*  re-schedule a task  */ 
     167        reschedule: function (ctx) { 
     168            if (typeof ctx == "string") 
     169                ctx = this.bucket[ctx]; 
     170 
     171            /*  pass-through to internal scheduling operation  */ 
     172            ctx["_handle"] = this._schedule(ctx); 
     173 
     174            /*  return context  */ 
     175            return ctx; 
     176        }, 
     177 
     178        /*  internal scheduling operation  */ 
     179        _schedule: function (ctx) { 
     180            /*  closure to act as the call trampoline function  */ 
     181            var trampoline = function () { 
     182                /*  jump into function  */ 
     183                var obj = (ctx["obj"] != null ? ctx["obj"] : ctx); 
     184                (ctx["func"]).apply(obj, ctx["args"]); 
     185 
     186                /*  either repeat scheduling and keep in bucket or 
     187                    just stop scheduling and delete from scheduler bucket  */ 
     188                if (   /* not cancelled from inside... */ 
     189                       typeof (ctx["_scheduler"]).bucket[ctx["id"]] != "undefined" 
     190                    && /* ...and repeating requested */ 
     191                       ctx["repeat"]) 
     192                    (ctx["_scheduler"])._schedule(ctx); 
     193                else 
     194                    delete (ctx["_scheduler"]).bucket[ctx["id"]]; 
     195            }; 
     196 
     197            /*  schedule task and return handle  */ 
     198            return setTimeout(trampoline, ctx["time"]); 
     199        }, 
     200 
     201        /*  cancel a scheduled task  */ 
     202        cancel: function (ctx) { 
     203            if (typeof ctx == "string") 
     204                ctx = this.bucket[ctx]; 
     205 
     206            /*  cancel scheduled task  */ 
     207            if (typeof ctx == "object") { 
     208                clearTimeout(ctx["_handle"]); 
     209                delete this.bucket[ctx["id"]]; 
     210            } 
     211        } 
     212    }; 
     213 
     214    /* integrate a global instance of the scheduler into the global jQuery object */ 
     215    $.extend({ 
     216        scheduler$: new $.scheduler(), 
     217        schedule:   function () { return $.scheduler$.schedule.apply  ($.scheduler$, arguments) }, 
     218        reschedule: function () { return $.scheduler$.reschedule.apply($.scheduler$, arguments) }, 
     219        cancel:     function () { return $.scheduler$.cancel.apply    ($.scheduler$, arguments) } 
     220    }); 
     221 
     222    /* integrate scheduling convinience method into all jQuery objects */ 
     223    $.fn.extend({ 
     224        schedule: function () { 
     225            var a = [ {} ]; 
     226            for (var i = 0; i < arguments.length; i++) 
     227                a.push(arguments[i]); 
     228            return this.each(function () { 
     229                a[0] = { "id": this, "obj": this }; 
     230                return $.schedule.apply($, a); 
     231            }); 
     232        } 
     233    }); 
     234 
     235})(jQuery); 
     236 
  • wp-includes/script-loader.php

     
    3636 
    3737                $this->add( 'prototype', '/wp-includes/js/prototype.js', false, '1.6'); 
    3838 
    39                 $this->add( 'autosave', '/wp-includes/js/autosave.js', array('prototype', 'sack'), '20070306'); 
     39                $this->add( 'autosave', '/wp-includes/js/autosave.js', array('jquery', 'schedule'), '20080104'); 
    4040                $this->localize( 'autosave', 'autosaveL10n', array( 
    41                         'autosaveInterval' => apply_filters('autosave_interval', '120'), 
     41                        'autosaveInterval' => apply_filters('autosave_interval', '2m'), 
    4242                        'errorText' => __('Error: %response%'), 
    4343                        'saveText' => __('Saved at %time%.'), 
    4444                        'requestFile' => get_option( 'siteurl' ) . '/wp-admin/admin-ajax.php', 
     
    8080                $this->add( 'interface', '/wp-includes/js/jquery/interface.js', array('jquery'), '1.2'); 
    8181                $this->add( 'dimensions', '/wp-includes/js/jquery/jquery.dimensions.min.js', array('jquery'), '1.1.2'); 
    8282                $this->add( 'suggest', '/wp-includes/js/jquery/suggest.js', array('dimensions'), '1.1'); 
     83                $this->add( 'schedule', '/wp-includes/js/jquery/jquery.schedule.js', array('jquery'), '20'); 
    8384 
    8485                if ( is_admin() ) { 
    8586                        global $pagenow;