Ticket #3824: autosave.js.7.diff
File autosave.js.7.diff, 22.3 KB (added by , 17 years ago) |
---|
-
wp-admin/page-new.php
3 3 $title = __('New Page'); 4 4 $parent_file = 'post-new.php'; 5 5 $editing = true; 6 wp_enqueue_script('prototype');7 wp_enqueue_script('jquery');8 6 wp_enqueue_script('autosave'); 9 7 require_once('admin-header.php'); 10 8 ?> -
wp-admin/page.php
52 52 exit(); 53 53 } 54 54 55 if($post->post_status == 'draft') { 56 wp_enqueue_script('prototype'); 57 wp_enqueue_script('jquery'); 55 if ( 'draft' == $post->post_status ) 58 56 wp_enqueue_script('autosave'); 59 } 57 60 58 require_once('admin-header.php'); 61 59 62 60 if ( !current_user_can('edit_page', $page_ID) ) -
wp-admin/post-new.php
3 3 $title = __('Create New Post'); 4 4 $parent_file = 'post-new.php'; 5 5 $editing = true; 6 wp_enqueue_script('prototype');7 wp_enqueue_script('jquery');8 6 wp_enqueue_script('autosave'); 9 7 wp_enqueue_script('post'); 10 8 -
wp-admin/post.php
60 60 61 61 wp_enqueue_script('post'); 62 62 63 if( 'draft' == $post->post_status ) { 64 wp_enqueue_script('prototype'); 63 if ( 'draft' == $post->post_status ) 65 64 wp_enqueue_script('autosave'); 66 }67 65 68 66 require_once('admin-header.php'); 69 67 -
wp-includes/functions.php
968 968 969 969 function wp_nonce_field( $action = -1, $name = "_wpnonce", $referer = true ) { 970 970 $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 ) . '" />'; 972 972 if ( $referer ) 973 973 wp_referer_field(); 974 974 } -
wp-includes/js/autosave.js
2 2 var autosavePeriodical; 3 3 4 4 function 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(); 7 6 // 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 9 9 //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); }); 19 15 } 20 16 addLoadEvent(autosave_start_timer) 21 17 … … 26 22 ((now.getSeconds() < 10) ? ":0" : ":") + now.getSeconds(); 27 23 } 28 24 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; 25 function autosave_update_post_ID(response) { 36 26 var res = parseInt(response); 37 27 var message; 38 28 … … 40 30 message = autosaveL10n.errorText.replace(/%response%/g, response); 41 31 } else { 42 32 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); 45 35 // 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'); 57 45 } 58 $('autosave').innerHTML = message;46 jQuery('#autosave').html(message); 59 47 autosave_enable_buttons(); 60 48 } 61 49 62 50 function autosave_loading() { 63 $('autosave').innerHTML = autosaveL10n.savingText;51 jQuery('#autosave').html(autosaveL10n.savingText); 64 52 } 65 53 66 function autosave_saved() { 67 var response = autosaveAjax.response; 54 function autosave_saved(response) { 68 55 var res = parseInt(response); 69 56 var message; 70 57 … … 73 60 } else { 74 61 message = autosaveL10n.saveText.replace(/%time%/g, autosave_cur_time()); 75 62 } 76 $('autosave').innerHTML = message;63 jQuery('#autosave').html(message); 77 64 autosave_enable_buttons(); 78 65 } 79 66 80 67 function 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'); 86 72 setTimeout('autosave_enable_buttons();', 1000); // Re-enable 1 sec later. Just gives autosave a head start to avoid collisions. 87 73 } 88 74 89 75 function 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', ''); 95 80 } 96 81 97 82 function autosave() { 98 var form = $('post');99 83 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 }; 100 92 101 autosaveAjax = new sack();102 103 93 /* Gotta do this up here so we can check the length when tinyMCE is in use */ 104 94 if ( typeof tinyMCE == "undefined" || tinyMCE.configs.length < 1 || rich == false ) { 105 autosaveAjax.setVar("content", form.content.value);95 post_data["content"] = jQuery("#content").val(); 106 96 } else { 107 97 // Don't run while the TinyMCE spellcheck is on. 108 98 if(tinyMCE.selectedInstance.spellcheckerOn) return; 109 99 tinyMCE.wpTriggerSave(); 110 autosaveAjax.setVar("content", form.content.value);100 post_data["content"] = jQuery("#content").val(); 111 101 } 112 102 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) { 114 104 return; 105 } 115 106 116 107 autosave_disable_buttons(); 117 108 118 autosaveLast = form.post_title.value+form.content.value; 119 120 cats = document.getElementsByName("post_category[]"); 109 autosaveLast = jQuery("#title").val()+jQuery("#content").val(); 121 110 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(","); 127 115 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(); 141 122 142 123 if ( typeof tinyMCE == "undefined" || tinyMCE.configs.length < 1 || rich == false ) { 143 autosaveAjax.setVar("content", form.content.value);124 post_data["content"] = jQuery("#content").val(); 144 125 } else { 145 126 tinyMCE.wpTriggerSave(); 146 autosaveAjax.setVar("content", form.content.value);127 post_data["content"] = jQuery("#content").val(); 147 128 } 148 129 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 }); 159 146 } -
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
36 36 37 37 $this->add( 'prototype', '/wp-includes/js/prototype.js', false, '1.6'); 38 38 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'); 40 40 $this->localize( 'autosave', 'autosaveL10n', array( 41 'autosaveInterval' => apply_filters('autosave_interval', ' 120'),41 'autosaveInterval' => apply_filters('autosave_interval', '2m'), 42 42 'errorText' => __('Error: %response%'), 43 43 'saveText' => __('Saved at %time%.'), 44 44 'requestFile' => get_option( 'siteurl' ) . '/wp-admin/admin-ajax.php', … … 80 80 $this->add( 'interface', '/wp-includes/js/jquery/interface.js', array('jquery'), '1.2'); 81 81 $this->add( 'dimensions', '/wp-includes/js/jquery/jquery.dimensions.min.js', array('jquery'), '1.1.2'); 82 82 $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'); 83 84 84 85 if ( is_admin() ) { 85 86 global $pagenow;