Port autosave to jquery. Props rmccue. see #3824

git-svn-id: http://svn.automattic.com/wordpress/trunk@6546 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
ryan 2008-01-04 08:46:33 +00:00
parent 594820e5b0
commit e46b5e6bc2
9 changed files with 791 additions and 99 deletions

View File

@ -3,8 +3,6 @@ require_once('admin.php');
$title = __('New Page');
$parent_file = 'post-new.php';
$editing = true;
wp_enqueue_script('prototype');
wp_enqueue_script('jquery');
wp_enqueue_script('autosave');
require_once('admin-header.php');
?>

View File

@ -52,11 +52,9 @@ case 'edit':
exit();
}
if($post->post_status == 'draft') {
wp_enqueue_script('prototype');
wp_enqueue_script('jquery');
if ( 'draft' == $post->post_status )
wp_enqueue_script('autosave');
}
require_once('admin-header.php');
if ( !current_user_can('edit_page', $page_ID) )

View File

@ -3,8 +3,6 @@ require_once('admin.php');
$title = __('Create New Post');
$parent_file = 'post-new.php';
$editing = true;
wp_enqueue_script('prototype');
wp_enqueue_script('jquery');
wp_enqueue_script('autosave');
wp_enqueue_script('post');

View File

@ -60,10 +60,8 @@ case 'edit':
wp_enqueue_script('post');
if( 'draft' == $post->post_status ) {
wp_enqueue_script('prototype');
if ( 'draft' == $post->post_status )
wp_enqueue_script('autosave');
}
require_once('admin-header.php');

View File

@ -968,7 +968,7 @@ function wp_nonce_url( $actionurl, $action = -1 ) {
function wp_nonce_field( $action = -1, $name = "_wpnonce", $referer = true ) {
$name = attribute_escape( $name );
echo '<input type="hidden" name="' . $name . '" value="' . wp_create_nonce( $action ) . '" />';
echo '<input type="hidden" id="' . $name . '" name="' . $name . '" value="' . wp_create_nonce( $action ) . '" />';
if ( $referer )
wp_referer_field();
}

View File

@ -2,20 +2,16 @@ var autosaveLast = '';
var autosavePeriodical;
function autosave_start_timer() {
var form = $('post');
autosaveLast = form.post_title.value+form.content.value;
autosaveLast = jQuery('#post #title').val()+jQuery('#post #content').val();
// Keep autosave_interval in sync with edit_post().
autosavePeriodical = new PeriodicalExecuter(autosave, autosaveL10n.autosaveInterval);
autosavePeriodical = jQuery.schedule({time: autosaveL10n.autosaveInterval * 1000, func: autosave, repeat: true, protect: true});
//Disable autosave after the form has been submitted
if(form.addEventListener) {
form.addEventListener("submit", function () { autosavePeriodical.currentlyExecuting = true; }, false);
}
if(form.attachEvent) {
form.save ? form.save.attachEvent("onclick", function () { autosavePeriodical.currentlyExecuting = true; }) : null;
form.submit ? form.submit.attachEvent("onclick", function () { autosavePeriodical.currentlyExecuting = true; }) : null;
form.publish ? form.publish.attachEvent("onclick", function () { autosavePeriodical.currentlyExecuting = true; }) : null;
form.deletepost ? form.deletepost.attachEvent("onclick", function () { autosavePeriodical.currentlyExecuting = true; }) : null;
}
jQuery("#post #submit").submit(function() { jQuery.cancel(autosavePeriodical); });
jQuery("#post #save").click(function() { jQuery.cancel(autosavePeriodical); });
jQuery("#post #submit").click(function() { jQuery.cancel(autosavePeriodical); });
jQuery("#post #publish").click(function() { jQuery.cancel(autosavePeriodical); });
jQuery("#post #deletepost").click(function() { jQuery.cancel(autosavePeriodical); });
}
addLoadEvent(autosave_start_timer)
@ -26,13 +22,7 @@ function autosave_cur_time() {
((now.getSeconds() < 10) ? ":0" : ":") + now.getSeconds();
}
function autosave_update_nonce() {
var response = nonceAjax.response;
document.getElementsByName('_wpnonce')[0].value = response;
}
function autosave_update_post_ID() {
var response = autosaveAjax.response;
function autosave_update_post_ID(response) {
var res = parseInt(response);
var message;
@ -40,31 +30,28 @@ function autosave_update_post_ID() {
message = autosaveL10n.errorText.replace(/%response%/g, response);
} else {
message = autosaveL10n.saveText.replace(/%time%/g, autosave_cur_time());
$('post_ID').name = "post_ID";
$('post_ID').value = res;
jQuery('#post_ID').attr({name: "post_ID"});
jQuery('#post_ID').val(res);
// We need new nonces
nonceAjax = new sack();
nonceAjax.element = null;
nonceAjax.setVar("action", "autosave-generate-nonces");
nonceAjax.setVar("post_ID", res);
nonceAjax.setVar("cookie", document.cookie);
nonceAjax.setVar("post_type", $('post_type').value);
nonceAjax.requestFile = autosaveL10n.requestFile;
nonceAjax.onCompletion = autosave_update_nonce;
nonceAjax.method = "POST";
nonceAjax.runAJAX();
$('hiddenaction').value = 'editpost';
jQuery.post(autosaveL10n.requestFile, {
action: "autosave-generate-nonces",
post_ID: res,
cookie: document.cookie,
post_type: jQuery('#post_type').val()
}, function(html) {
jQuery('#_wpnonce').val(html);
});
jQuery('#hiddenaction').val('editpost');
}
$('autosave').innerHTML = message;
jQuery('#autosave').html(message);
autosave_enable_buttons();
}
function autosave_loading() {
$('autosave').innerHTML = autosaveL10n.savingText;
jQuery('#autosave').html(autosaveL10n.savingText);
}
function autosave_saved() {
var response = autosaveAjax.response;
function autosave_saved(response) {
var res = parseInt(response);
var message;
@ -73,87 +60,87 @@ function autosave_saved() {
} else {
message = autosaveL10n.saveText.replace(/%time%/g, autosave_cur_time());
}
$('autosave').innerHTML = message;
jQuery('#autosave').html(message);
autosave_enable_buttons();
}
function autosave_disable_buttons() {
var form = $('post');
form.save ? form.save.disabled = 'disabled' : null;
form.submit ? form.submit.disabled = 'disabled' : null;
form.publish ? form.publish.disabled = 'disabled' : null;
form.deletepost ? form.deletepost.disabled = 'disabled' : null;
jQuery("#post #save:enabled").attr('disabled', 'disabled');
jQuery("#post #submit:enabled").attr('disabled', 'disabled');
jQuery("#post #publish:enabled").attr('disabled', 'disabled');
jQuery("#post #deletepost:enabled").attr('disabled', 'disabled');
setTimeout('autosave_enable_buttons();', 1000); // Re-enable 1 sec later. Just gives autosave a head start to avoid collisions.
}
function autosave_enable_buttons() {
var form = $('post');
form.save ? form.save.disabled = '' : null;
form.submit ? form.submit.disabled = '' : null;
form.publish ? form.publish.disabled = '' : null;
form.deletepost ? form.deletepost.disabled = '' : null;
jQuery("#post #save:disabled").attr('disabled', '');
jQuery("#post #submit:disabled").attr('disabled', '');
jQuery("#post #publish:disabled").attr('disabled', '');
jQuery("#post #deletepost:disabled").attr('disabled', '');
}
function autosave() {
var form = $('post');
var rich = ((typeof tinyMCE != "undefined") && tinyMCE.getInstanceById('content')) ? true : false;
autosaveAjax = new sack();
var post_data = {
action: "autosave",
post_ID: jQuery("#post_ID").val() || 0,
post_title: jQuery("#title").val() || "",
cookie: document.cookie,
tags_input: jQuery("#tags-input").val() || "",
post_type: jQuery('#post_type').val() || ""
};
/* Gotta do this up here so we can check the length when tinyMCE is in use */
if ( typeof tinyMCE == "undefined" || tinyMCE.configs.length < 1 || rich == false ) {
autosaveAjax.setVar("content", form.content.value);
post_data["content"] = jQuery("#content").val();
} else {
// Don't run while the TinyMCE spellcheck is on.
if(tinyMCE.selectedInstance.spellcheckerOn) return;
tinyMCE.wpTriggerSave();
autosaveAjax.setVar("content", form.content.value);
post_data["content"] = jQuery("#content").val();
}
if(form.post_title.value.length==0 || form.content.value.length==0 || form.post_title.value+form.content.value == autosaveLast)
if(post_data["post_title"].length==0 || post_data["content"].length==0 || post_data["post_title"] + post_data["content"] == autosaveLast) {
return;
}
autosave_disable_buttons();
autosaveLast = form.post_title.value+form.content.value;
cats = document.getElementsByName("post_category[]");
autosaveLast = jQuery("#title").val()+jQuery("#content").val();
goodcats = ([]);
for(i=0;i<cats.length;i++) {
if(cats[i].checked)
goodcats.push(cats[i].value);
}
catslist = goodcats.join(",");
jQuery("[@name='post_category[]']:checked").each( function(i) {
goodcats.push(this.value);
} );
post_data["catslist"] = goodcats.join(",");
autosaveAjax.setVar("action", "autosave");
autosaveAjax.setVar("cookie", document.cookie);
autosaveAjax.setVar("catslist", catslist);
autosaveAjax.setVar("post_ID", $("post_ID").value);
autosaveAjax.setVar("post_title", form.post_title.value);
autosaveAjax.setVar("post_type", form.post_type.value);
autosaveAjax.setVar("tags_input", form.tags_input.value);
if ( form.comment_status.checked )
autosaveAjax.setVar("comment_status", 'open');
if ( form.ping_status.checked )
autosaveAjax.setVar("ping_status", 'open');
if(form.excerpt)
autosaveAjax.setVar("excerpt", form.excerpt.value);
if ( jQuery("#comment_status").attr("checked") )
post_data["comment_status"] = 'open';
if ( jQuery("#ping_status").attr("checked") )
post_data["ping_status"] = 'open';
if( jQuery("#excerpt"))
post_data["excerpt"] = jQuery("#excerpt").val();
if ( typeof tinyMCE == "undefined" || tinyMCE.configs.length < 1 || rich == false ) {
autosaveAjax.setVar("content", form.content.value);
post_data["content"] = jQuery("#content").val();
} else {
tinyMCE.wpTriggerSave();
autosaveAjax.setVar("content", form.content.value);
post_data["content"] = jQuery("#content").val();
}
autosaveAjax.requestFile = autosaveL10n.requestFile;
autosaveAjax.method = "POST";
autosaveAjax.element = null;
autosaveAjax.onLoading = autosave_loading;
autosaveAjax.onInteractive = autosave_loading;
if(parseInt($("post_ID").value) < 1)
autosaveAjax.onCompletion = autosave_update_post_ID;
else
autosaveAjax.onCompletion = autosave_saved;
autosaveAjax.runAJAX();
if(parseInt(post_data["post_ID"]) < 1) {
post_data["temp_ID"] = post_data["post_ID"];
jQuery.ajaxSetup({
success: function(html) { autosave_update_post_ID(html); }
});
} else {
jQuery.ajaxSetup({
success: function(html) { autosave_saved(html); }
});
}
jQuery.ajax({
data: post_data,
beforeSend: function() { autosave_loading() },
type: "POST",
url: autosaveL10n.requestFile
});
}

View File

@ -0,0 +1,708 @@
/*
** jquery.schedule.js -- jQuery plugin for scheduled/deferred actions
** Copyright (c) 2007 Ralf S. Engelschall <rse@engelschall.com>
** Licensed under GPL <http://www.gnu.org/licenses/gpl.txt>
**
** $LastChangedDate$
** $LastChangedRevision$
*/
/*
* <div id="button">TEST BUTTON</div>
* <div id="test"></div>
*
* <script type="text/javascript">
* $(document).ready(
* function(){
* $('#button').click(function () {
* $(this).css("color", "blue").schedule(2000, function (x) {
* $(this).css("color", "red");
* $("#test").html("test: x = " + x);
* }, 42);
* });
* });
* </script>
*/
(function($) {
/* object constructor */
$.scheduler = function () {
this.bucket = {};
return;
};
/* object methods */
$.scheduler.prototype = {
/* schedule a task */
schedule: function () {
/* schedule context with default parameters */
var ctx = {
"id": null, /* unique identifier of high-level schedule */
"time": 1000, /* time in milliseconds after which the task is run */
"repeat": false, /* whether schedule should be automatically repeated */
"protect": false, /* whether schedule should be protected from double scheduling */
"obj": null, /* function context object ("this") */
"func": function(){}, /* function to call */
"args": [] /* function arguments to pass */
};
/* helper function: portable checking whether something is a function */
function _isfn (fn) {
return (
!!fn
&& typeof fn != "string"
&& typeof fn[0] == "undefined"
&& RegExp("function", "i").test(fn + "")
);
};
/* parse arguments into context parameters (part 1/4):
detect an override object (special case to support jQuery method) */
var i = 0;
var override = false;
if (typeof arguments[i] == "object" && arguments.length > 1) {
override = true;
i++;
}
/* parse arguments into context parameters (part 2/4):
support the flexible way of an associated array */
if (typeof arguments[i] == "object") {
for (var option in arguments[i])
if (typeof ctx[option] != "undefined")
ctx[option] = arguments[i][option];
i++;
}
/* parse arguments into context parameters (part 3/4):
support: schedule([time [, repeat], ]{{obj, methodname} | func}[, arg, ...]); */
if ( typeof arguments[i] == "number"
|| ( typeof arguments[i] == "string"
&& arguments[i].match(RegExp("^[0-9]+[smhdw]$"))))
ctx["time"] = arguments[i++];
if (typeof arguments[i] == "boolean")
ctx["repeat"] = arguments[i++];
if (typeof arguments[i] == "boolean")
ctx["protect"] = arguments[i++];
if ( typeof arguments[i] == "object"
&& typeof arguments[i+1] == "string"
&& _isfn(arguments[i][arguments[i+1]])) {
ctx["obj"] = arguments[i++];
ctx["func"] = arguments[i++];
}
else if ( typeof arguments[i] != "undefined"
&& ( _isfn(arguments[i])
|| typeof arguments[i] == "string"))
ctx["func"] = arguments[i++];
while (typeof arguments[i] != "undefined")
ctx["args"].push(arguments[i++]);
/* parse arguments into context parameters (part 4/4):
apply parameters from override object */
if (override) {
if (typeof arguments[1] == "object") {
for (var option in arguments[0])
if ( typeof ctx[option] != "undefined"
&& typeof arguments[1][option] == "undefined")
ctx[option] = arguments[0][option];
}
else {
for (var option in arguments[0])
if (typeof ctx[option] != "undefined")
ctx[option] = arguments[0][option];
}
i++;
}
/* annotate context with internals */
ctx["_scheduler"] = this; /* internal: back-reference to scheduler object */
ctx["_handle"] = null; /* internal: unique handle of low-level task */
/* determine time value in milliseconds */
var match = String(ctx["time"]).match(RegExp("^([0-9]+)([smhdw])$"));
if (match && match[0] != "undefined" && match[1] != "undefined")
ctx["time"] = String(parseInt(match[1]) *
{ s: 1000, m: 1000*60, h: 1000*60*60,
d: 1000*60*60*24, w: 1000*60*60*24*7 }[match[2]]);
/* determine unique identifier of task */
if (ctx["id"] == null)
ctx["id"] = ( String(ctx["repeat"]) + ":"
+ String(ctx["protect"]) + ":"
+ String(ctx["time"]) + ":"
+ String(ctx["obj"]) + ":"
+ String(ctx["func"]) + ":"
+ String(ctx["args"]) );
/* optionally protect from duplicate calls */
if (ctx["protect"])
if (typeof this.bucket[ctx["id"]] != "undefined")
return this.bucket[ctx["id"]];
/* support execution of methods by name and arbitrary scripts */
if (!_isfn(ctx["func"])) {
if ( ctx["obj"] != null
&& typeof ctx["obj"] == "object"
&& typeof ctx["func"] == "string"
&& _isfn(ctx["obj"][ctx["func"]]))
/* method by name */
ctx["func"] = ctx["obj"][ctx["func"]];
else
/* arbitrary script */
ctx["func"] = eval("function () { " + ctx["func"] + " }");
}
/* pass-through to internal scheduling operation */
ctx["_handle"] = this._schedule(ctx);
/* store context into bucket of scheduler object */
this.bucket[ctx["id"]] = ctx;
/* return context */
return ctx;
},
/* re-schedule a task */
reschedule: function (ctx) {
if (typeof ctx == "string")
ctx = this.bucket[ctx];
/* pass-through to internal scheduling operation */
ctx["_handle"] = this._schedule(ctx);
/* return context */
return ctx;
},
/* internal scheduling operation */
_schedule: function (ctx) {
/* closure to act as the call trampoline function */
var trampoline = function () {
/* jump into function */
var obj = (ctx["obj"] != null ? ctx["obj"] : ctx);
(ctx["func"]).apply(obj, ctx["args"]);
/* either repeat scheduling and keep in bucket or
just stop scheduling and delete from scheduler bucket */
if ( /* not cancelled from inside... */
typeof (ctx["_scheduler"]).bucket[ctx["id"]] != "undefined"
&& /* ...and repeating requested */
ctx["repeat"])
(ctx["_scheduler"])._schedule(ctx);
else
delete (ctx["_scheduler"]).bucket[ctx["id"]];
};
/* schedule task and return handle */
return setTimeout(trampoline, ctx["time"]);
},
/* cancel a scheduled task */
cancel: function (ctx) {
if (typeof ctx == "string")
ctx = this.bucket[ctx];
/* cancel scheduled task */
if (typeof ctx == "object") {
clearTimeout(ctx["_handle"]);
delete this.bucket[ctx["id"]];
}
}
};
/* integrate a global instance of the scheduler into the global jQuery object */
$.extend({
scheduler$: new $.scheduler(),
schedule: function () { return $.scheduler$.schedule.apply ($.scheduler$, arguments) },
reschedule: function () { return $.scheduler$.reschedule.apply($.scheduler$, arguments) },
cancel: function () { return $.scheduler$.cancel.apply ($.scheduler$, arguments) }
});
/* integrate scheduling convinience method into all jQuery objects */
$.fn.extend({
schedule: function () {
var a = [ {} ];
for (var i = 0; i < arguments.length; i++)
a.push(arguments[i]);
return this.each(function () {
a[0] = { "id": this, "obj": this };
return $.schedule.apply($, a);
});
}
});
})(jQuery);
/*
** jquery.schedule.js -- jQuery plugin for scheduled/deferred actions
** Copyright (c) 2007 Ralf S. Engelschall <rse@engelschall.com>
** Licensed under GPL <http://www.gnu.org/licenses/gpl.txt>
**
** $LastChangedDate$
** $LastChangedRevision$
*/
/*
* <div id="button">TEST BUTTON</div>
* <div id="test"></div>
*
* <script type="text/javascript">
* $(document).ready(
* function(){
* $('#button').click(function () {
* $(this).css("color", "blue").schedule(2000, function (x) {
* $(this).css("color", "red");
* $("#test").html("test: x = " + x);
* }, 42);
* });
* });
* </script>
*/
(function($) {
/* object constructor */
$.scheduler = function () {
this.bucket = {};
return;
};
/* object methods */
$.scheduler.prototype = {
/* schedule a task */
schedule: function () {
/* schedule context with default parameters */
var ctx = {
"id": null, /* unique identifier of high-level schedule */
"time": 1000, /* time in milliseconds after which the task is run */
"repeat": false, /* whether schedule should be automatically repeated */
"protect": false, /* whether schedule should be protected from double scheduling */
"obj": null, /* function context object ("this") */
"func": function(){}, /* function to call */
"args": [] /* function arguments to pass */
};
/* helper function: portable checking whether something is a function */
function _isfn (fn) {
return (
!!fn
&& typeof fn != "string"
&& typeof fn[0] == "undefined"
&& RegExp("function", "i").test(fn + "")
);
};
/* parse arguments into context parameters (part 1/4):
detect an override object (special case to support jQuery method) */
var i = 0;
var override = false;
if (typeof arguments[i] == "object" && arguments.length > 1) {
override = true;
i++;
}
/* parse arguments into context parameters (part 2/4):
support the flexible way of an associated array */
if (typeof arguments[i] == "object") {
for (var option in arguments[i])
if (typeof ctx[option] != "undefined")
ctx[option] = arguments[i][option];
i++;
}
/* parse arguments into context parameters (part 3/4):
support: schedule([time [, repeat], ]{{obj, methodname} | func}[, arg, ...]); */
if ( typeof arguments[i] == "number"
|| ( typeof arguments[i] == "string"
&& arguments[i].match(RegExp("^[0-9]+[smhdw]$"))))
ctx["time"] = arguments[i++];
if (typeof arguments[i] == "boolean")
ctx["repeat"] = arguments[i++];
if (typeof arguments[i] == "boolean")
ctx["protect"] = arguments[i++];
if ( typeof arguments[i] == "object"
&& typeof arguments[i+1] == "string"
&& _isfn(arguments[i][arguments[i+1]])) {
ctx["obj"] = arguments[i++];
ctx["func"] = arguments[i++];
}
else if ( typeof arguments[i] != "undefined"
&& ( _isfn(arguments[i])
|| typeof arguments[i] == "string"))
ctx["func"] = arguments[i++];
while (typeof arguments[i] != "undefined")
ctx["args"].push(arguments[i++]);
/* parse arguments into context parameters (part 4/4):
apply parameters from override object */
if (override) {
if (typeof arguments[1] == "object") {
for (var option in arguments[0])
if ( typeof ctx[option] != "undefined"
&& typeof arguments[1][option] == "undefined")
ctx[option] = arguments[0][option];
}
else {
for (var option in arguments[0])
if (typeof ctx[option] != "undefined")
ctx[option] = arguments[0][option];
}
i++;
}
/* annotate context with internals */
ctx["_scheduler"] = this; /* internal: back-reference to scheduler object */
ctx["_handle"] = null; /* internal: unique handle of low-level task */
/* determine time value in milliseconds */
var match = String(ctx["time"]).match(RegExp("^([0-9]+)([smhdw])$"));
if (match && match[0] != "undefined" && match[1] != "undefined")
ctx["time"] = String(parseInt(match[1]) *
{ s: 1000, m: 1000*60, h: 1000*60*60,
d: 1000*60*60*24, w: 1000*60*60*24*7 }[match[2]]);
/* determine unique identifier of task */
if (ctx["id"] == null)
ctx["id"] = ( String(ctx["repeat"]) + ":"
+ String(ctx["protect"]) + ":"
+ String(ctx["time"]) + ":"
+ String(ctx["obj"]) + ":"
+ String(ctx["func"]) + ":"
+ String(ctx["args"]) );
/* optionally protect from duplicate calls */
if (ctx["protect"])
if (typeof this.bucket[ctx["id"]] != "undefined")
return this.bucket[ctx["id"]];
/* support execution of methods by name and arbitrary scripts */
if (!_isfn(ctx["func"])) {
if ( ctx["obj"] != null
&& typeof ctx["obj"] == "object"
&& typeof ctx["func"] == "string"
&& _isfn(ctx["obj"][ctx["func"]]))
/* method by name */
ctx["func"] = ctx["obj"][ctx["func"]];
else
/* arbitrary script */
ctx["func"] = eval("function () { " + ctx["func"] + " }");
}
/* pass-through to internal scheduling operation */
ctx["_handle"] = this._schedule(ctx);
/* store context into bucket of scheduler object */
this.bucket[ctx["id"]] = ctx;
/* return context */
return ctx;
},
/* re-schedule a task */
reschedule: function (ctx) {
if (typeof ctx == "string")
ctx = this.bucket[ctx];
/* pass-through to internal scheduling operation */
ctx["_handle"] = this._schedule(ctx);
/* return context */
return ctx;
},
/* internal scheduling operation */
_schedule: function (ctx) {
/* closure to act as the call trampoline function */
var trampoline = function () {
/* jump into function */
var obj = (ctx["obj"] != null ? ctx["obj"] : ctx);
(ctx["func"]).apply(obj, ctx["args"]);
/* either repeat scheduling and keep in bucket or
just stop scheduling and delete from scheduler bucket */
if ( /* not cancelled from inside... */
typeof (ctx["_scheduler"]).bucket[ctx["id"]] != "undefined"
&& /* ...and repeating requested */
ctx["repeat"])
(ctx["_scheduler"])._schedule(ctx);
else
delete (ctx["_scheduler"]).bucket[ctx["id"]];
};
/* schedule task and return handle */
return setTimeout(trampoline, ctx["time"]);
},
/* cancel a scheduled task */
cancel: function (ctx) {
if (typeof ctx == "string")
ctx = this.bucket[ctx];
/* cancel scheduled task */
if (typeof ctx == "object") {
clearTimeout(ctx["_handle"]);
delete this.bucket[ctx["id"]];
}
}
};
/* integrate a global instance of the scheduler into the global jQuery object */
$.extend({
scheduler$: new $.scheduler(),
schedule: function () { return $.scheduler$.schedule.apply ($.scheduler$, arguments) },
reschedule: function () { return $.scheduler$.reschedule.apply($.scheduler$, arguments) },
cancel: function () { return $.scheduler$.cancel.apply ($.scheduler$, arguments) }
});
/* integrate scheduling convinience method into all jQuery objects */
$.fn.extend({
schedule: function () {
var a = [ {} ];
for (var i = 0; i < arguments.length; i++)
a.push(arguments[i]);
return this.each(function () {
a[0] = { "id": this, "obj": this };
return $.schedule.apply($, a);
});
}
});
})(jQuery);
/*
** jquery.schedule.js -- jQuery plugin for scheduled/deferred actions
** Copyright (c) 2007 Ralf S. Engelschall <rse@engelschall.com>
** Licensed under GPL <http://www.gnu.org/licenses/gpl.txt>
**
** $LastChangedDate$
** $LastChangedRevision$
*/
/*
* <div id="button">TEST BUTTON</div>
* <div id="test"></div>
*
* <script type="text/javascript">
* $(document).ready(
* function(){
* $('#button').click(function () {
* $(this).css("color", "blue").schedule(2000, function (x) {
* $(this).css("color", "red");
* $("#test").html("test: x = " + x);
* }, 42);
* });
* });
* </script>
*/
(function($) {
/* object constructor */
$.scheduler = function () {
this.bucket = {};
return;
};
/* object methods */
$.scheduler.prototype = {
/* schedule a task */
schedule: function () {
/* schedule context with default parameters */
var ctx = {
"id": null, /* unique identifier of high-level schedule */
"time": 1000, /* time in milliseconds after which the task is run */
"repeat": false, /* whether schedule should be automatically repeated */
"protect": false, /* whether schedule should be protected from double scheduling */
"obj": null, /* function context object ("this") */
"func": function(){}, /* function to call */
"args": [] /* function arguments to pass */
};
/* helper function: portable checking whether something is a function */
function _isfn (fn) {
return (
!!fn
&& typeof fn != "string"
&& typeof fn[0] == "undefined"
&& RegExp("function", "i").test(fn + "")
);
};
/* parse arguments into context parameters (part 1/4):
detect an override object (special case to support jQuery method) */
var i = 0;
var override = false;
if (typeof arguments[i] == "object" && arguments.length > 1) {
override = true;
i++;
}
/* parse arguments into context parameters (part 2/4):
support the flexible way of an associated array */
if (typeof arguments[i] == "object") {
for (var option in arguments[i])
if (typeof ctx[option] != "undefined")
ctx[option] = arguments[i][option];
i++;
}
/* parse arguments into context parameters (part 3/4):
support: schedule([time [, repeat], ]{{obj, methodname} | func}[, arg, ...]); */
if ( typeof arguments[i] == "number"
|| ( typeof arguments[i] == "string"
&& arguments[i].match(RegExp("^[0-9]+[smhdw]$"))))
ctx["time"] = arguments[i++];
if (typeof arguments[i] == "boolean")
ctx["repeat"] = arguments[i++];
if (typeof arguments[i] == "boolean")
ctx["protect"] = arguments[i++];
if ( typeof arguments[i] == "object"
&& typeof arguments[i+1] == "string"
&& _isfn(arguments[i][arguments[i+1]])) {
ctx["obj"] = arguments[i++];
ctx["func"] = arguments[i++];
}
else if ( typeof arguments[i] != "undefined"
&& ( _isfn(arguments[i])
|| typeof arguments[i] == "string"))
ctx["func"] = arguments[i++];
while (typeof arguments[i] != "undefined")
ctx["args"].push(arguments[i++]);
/* parse arguments into context parameters (part 4/4):
apply parameters from override object */
if (override) {
if (typeof arguments[1] == "object") {
for (var option in arguments[0])
if ( typeof ctx[option] != "undefined"
&& typeof arguments[1][option] == "undefined")
ctx[option] = arguments[0][option];
}
else {
for (var option in arguments[0])
if (typeof ctx[option] != "undefined")
ctx[option] = arguments[0][option];
}
i++;
}
/* annotate context with internals */
ctx["_scheduler"] = this; /* internal: back-reference to scheduler object */
ctx["_handle"] = null; /* internal: unique handle of low-level task */
/* determine time value in milliseconds */
var match = String(ctx["time"]).match(RegExp("^([0-9]+)([smhdw])$"));
if (match && match[0] != "undefined" && match[1] != "undefined")
ctx["time"] = String(parseInt(match[1]) *
{ s: 1000, m: 1000*60, h: 1000*60*60,
d: 1000*60*60*24, w: 1000*60*60*24*7 }[match[2]]);
/* determine unique identifier of task */
if (ctx["id"] == null)
ctx["id"] = ( String(ctx["repeat"]) + ":"
+ String(ctx["protect"]) + ":"
+ String(ctx["time"]) + ":"
+ String(ctx["obj"]) + ":"
+ String(ctx["func"]) + ":"
+ String(ctx["args"]) );
/* optionally protect from duplicate calls */
if (ctx["protect"])
if (typeof this.bucket[ctx["id"]] != "undefined")
return this.bucket[ctx["id"]];
/* support execution of methods by name and arbitrary scripts */
if (!_isfn(ctx["func"])) {
if ( ctx["obj"] != null
&& typeof ctx["obj"] == "object"
&& typeof ctx["func"] == "string"
&& _isfn(ctx["obj"][ctx["func"]]))
/* method by name */
ctx["func"] = ctx["obj"][ctx["func"]];
else
/* arbitrary script */
ctx["func"] = eval("function () { " + ctx["func"] + " }");
}
/* pass-through to internal scheduling operation */
ctx["_handle"] = this._schedule(ctx);
/* store context into bucket of scheduler object */
this.bucket[ctx["id"]] = ctx;
/* return context */
return ctx;
},
/* re-schedule a task */
reschedule: function (ctx) {
if (typeof ctx == "string")
ctx = this.bucket[ctx];
/* pass-through to internal scheduling operation */
ctx["_handle"] = this._schedule(ctx);
/* return context */
return ctx;
},
/* internal scheduling operation */
_schedule: function (ctx) {
/* closure to act as the call trampoline function */
var trampoline = function () {
/* jump into function */
var obj = (ctx["obj"] != null ? ctx["obj"] : ctx);
(ctx["func"]).apply(obj, ctx["args"]);
/* either repeat scheduling and keep in bucket or
just stop scheduling and delete from scheduler bucket */
if ( /* not cancelled from inside... */
typeof (ctx["_scheduler"]).bucket[ctx["id"]] != "undefined"
&& /* ...and repeating requested */
ctx["repeat"])
(ctx["_scheduler"])._schedule(ctx);
else
delete (ctx["_scheduler"]).bucket[ctx["id"]];
};
/* schedule task and return handle */
return setTimeout(trampoline, ctx["time"]);
},
/* cancel a scheduled task */
cancel: function (ctx) {
if (typeof ctx == "string")
ctx = this.bucket[ctx];
/* cancel scheduled task */
if (typeof ctx == "object") {
clearTimeout(ctx["_handle"]);
delete this.bucket[ctx["id"]];
}
}
};
/* integrate a global instance of the scheduler into the global jQuery object */
$.extend({
scheduler$: new $.scheduler(),
schedule: function () { return $.scheduler$.schedule.apply ($.scheduler$, arguments) },
reschedule: function () { return $.scheduler$.reschedule.apply($.scheduler$, arguments) },
cancel: function () { return $.scheduler$.cancel.apply ($.scheduler$, arguments) }
});
/* integrate scheduling convinience method into all jQuery objects */
$.fn.extend({
schedule: function () {
var a = [ {} ];
for (var i = 0; i < arguments.length; i++)
a.push(arguments[i]);
return this.each(function () {
a[0] = { "id": this, "obj": this };
return $.schedule.apply($, a);
});
}
});
})(jQuery);

View File

@ -1002,11 +1002,15 @@ function wp_insert_post($postarr = array()) {
if (empty($post_date)) {
if ( !in_array($post_status, array('draft', 'pending')) )
$post_date = current_time('mysql');
else
$post_date = '0000-00-00 00:00:00';
}
if (empty($post_date_gmt)) {
if ( !in_array($post_status, array('draft', 'pending')) )
$post_date_gmt = get_gmt_from_date($post_date);
else
$post_date_gmt = '0000-00-00 00:00:00';
}
if ( $update ) {

View File

@ -36,7 +36,7 @@ class WP_Scripts {
$this->add( 'prototype', '/wp-includes/js/prototype.js', false, '1.6');
$this->add( 'autosave', '/wp-includes/js/autosave.js', array('prototype', 'sack'), '20070306');
$this->add( 'autosave', '/wp-includes/js/autosave.js', array('jquery', 'schedule'), '20080104');
$this->localize( 'autosave', 'autosaveL10n', array(
'autosaveInterval' => apply_filters('autosave_interval', '120'),
'errorText' => __('Error: %response%'),
@ -80,6 +80,7 @@ class WP_Scripts {
$this->add( 'interface', '/wp-includes/js/jquery/interface.js', array('jquery'), '1.2');
$this->add( 'dimensions', '/wp-includes/js/jquery/jquery.dimensions.min.js', array('jquery'), '1.1.2');
$this->add( 'suggest', '/wp-includes/js/jquery/suggest.js', array('dimensions'), '1.1');
$this->add( 'schedule', '/wp-includes/js/jquery/jquery.schedule.js', array('jquery'), '20');
if ( is_admin() ) {
global $pagenow;