Changeset 23683
- Timestamp:
- 03/13/2013 10:08:16 AM (12 years ago)
- Location:
- trunk
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/wp-admin/edit-form-advanced.php
r23631 r23683 302 302 ?></h2> 303 303 <?php if ( $notice ) : ?> 304 <div id="notice" class="error"><p ><?php echo $notice ?></p></div>304 <div id="notice" class="error"><p id="has-newer-autosave"><?php echo $notice ?></p></div> 305 305 <?php endif; ?> 306 306 <?php if ( $message ) : ?> -
trunk/wp-admin/includes/ajax-actions.php
r23663 r23683 1051 1051 $id = $revision_id = 0; 1052 1052 1053 $post_ ID = (int) $_POST['post_ID'];1054 $_POST['ID'] = $ post_ID;1055 $post = get_post($post_ ID);1053 $post_id = (int) $_POST['post_id']; 1054 $_POST['ID'] = $_POST['post_ID'] = $post_id; 1055 $post = get_post($post_id); 1056 1056 if ( 'auto-draft' == $post->post_status ) 1057 1057 $_POST['post_status'] = 'draft'; … … 1069 1069 1070 1070 if ( 'page' == $post->post_type ) { 1071 if ( !current_user_can('edit_page', $post _ID) )1071 if ( !current_user_can('edit_page', $post->ID) ) 1072 1072 wp_die( __( 'You are not allowed to edit this page.' ) ); 1073 1073 } else { 1074 if ( !current_user_can('edit_post', $post _ID) )1074 if ( !current_user_can('edit_post', $post->ID) ) 1075 1075 wp_die( __( 'You are not allowed to edit this post.' ) ); 1076 1076 } -
trunk/wp-admin/includes/misc.php
r23681 r23683 633 633 } 634 634 add_filter( 'heartbeat_received', 'wp_refresh_post_lock', 10, 3 ); 635 636 /** 637 * Output the HTML for restoring the post data from DOM storage 638 * 639 * @since 3.6 640 * @access private 641 */ 642 function _local_storage_notice() { 643 $screen = get_current_screen(); 644 if ( ! $screen || 'post' != $screen->id ) 645 return; 646 647 ?> 648 <div id="local-storage-notice" class="hidden"> 649 <p class="local-restore"> 650 <?php _e('The backup of this post in your browser is different from the version below.'); ?> 651 <a class="restore-backup" href="#"><?php _e('Restore the backup.'); ?></a> 652 </p> 653 <p class="undo-restore hidden"> 654 <?php _e('Post restored successfully.'); ?> 655 <a class="undo-restore-backup" href="#"><?php _e('Undo.'); ?></a> 656 </p> 657 </div> 658 <?php 659 } 660 add_action( 'admin_footer', '_local_storage_notice' ); -
trunk/wp-includes/js/admin-bar.js
r23518 r23683 133 133 } 134 134 }); 135 136 // Empty sessionStorage on logging out 137 if ( 'sessionStorage' in window ) { 138 $('#wp-admin-bar-logout a').click( function() { 139 try { 140 for ( var key in sessionStorage ) { 141 if ( key.indexOf('wp-autosave-') != -1 ) 142 sessionStorage.removeItem(key); 143 } 144 } catch(e) {} 145 }); 146 } 135 147 }); 136 148 } else { … … 311 323 scrollToTop( e.target || e.srcElement ); 312 324 }); 325 326 addEvent( document.getElementById('wp-admin-bar-logout'), 'click', function() { 327 if ( 'sessionStorage' in window ) { 328 try { 329 for ( var key in sessionStorage ) { 330 if ( key.indexOf('wp-autosave-') != -1 ) 331 sessionStorage.removeItem(key); 332 } 333 } catch(e) {} 334 } 335 }); 313 336 } 314 337 -
trunk/wp-includes/js/autosave.js
r23518 r23683 188 188 blockSave = false; 189 189 var res = autosave_parse_response(response), postID; 190 190 191 if ( res && res.responses.length && !res.errors ) { 191 192 // An ID is sent only for real auto-saves, not for autosave=0 "keepalive" saves … … 258 259 autosave_disable_buttons(); 259 260 260 post_data = { 261 action: "autosave", 262 post_ID: jQuery("#post_ID").val() || 0, 263 autosavenonce: jQuery('#autosavenonce').val(), 264 post_type: jQuery('#post_type').val() || "", 265 autosave: 1 266 }; 267 268 jQuery('.tags-input').each( function() { 269 post_data[this.name] = this.value; 270 } ); 261 post_data = wp.autosave.getPostData(); 271 262 272 263 // We always send the ajax request in order to keep the post lock fresh. 273 264 // This (bool) tells whether or not to write the post to the DB during the ajax request. 274 doAutoSave = true;265 doAutoSave = post_data.autosave; 275 266 276 267 // No autosave while thickbox is open (media buttons) … … 278 269 doAutoSave = false; 279 270 280 /* Gotta do this up here so we can check the length when tinymce is in use */281 if ( rich && doAutoSave ) {282 ed = tinymce.activeEditor;283 // Don't run while the tinymce spellcheck is on. It resets all found words.284 if ( ed.plugins.spellchecker && ed.plugins.spellchecker.active ) {285 doAutoSave = false;286 } else {287 if ( 'mce_fullscreen' == ed.id || 'wp_mce_fullscreen' == ed.id )288 tinymce.get('content').setContent(ed.getContent({format : 'raw'}), {format : 'raw'});289 tinymce.triggerSave();290 }291 }292 293 if ( fullscreen && fullscreen.settings.visible ) {294 post_data["post_title"] = jQuery('#wp-fullscreen-title').val() || '';295 post_data["content"] = jQuery("#wp_mce_fullscreen").val() || '';296 } else {297 post_data["post_title"] = jQuery("#title").val() || '';298 post_data["content"] = jQuery("#content").val() || '';299 }300 301 if ( jQuery('#post_name').val() )302 post_data["post_name"] = jQuery('#post_name').val();303 304 271 // Nothing to save or no change. 305 272 if ( ( post_data["post_title"].length == 0 && post_data["content"].length == 0 ) || post_data["post_title"] + post_data["content"] == autosaveLast ) { 306 273 doAutoSave = false; 307 274 } 308 309 origStatus = jQuery('#original_post_status').val();310 311 goodcats = ([]);312 jQuery("[name='post_category[]']:checked").each( function(i) {313 goodcats.push(this.value);314 } );315 post_data["catslist"] = goodcats.join(",");316 317 if ( jQuery("#comment_status").prop("checked") )318 post_data["comment_status"] = 'open';319 if ( jQuery("#ping_status").prop("checked") )320 post_data["ping_status"] = 'open';321 if ( jQuery("#excerpt").size() )322 post_data["excerpt"] = jQuery("#excerpt").val();323 if ( jQuery("#post_author").size() )324 post_data["post_author"] = jQuery("#post_author").val();325 if ( jQuery("#parent_id").val() )326 post_data["parent_id"] = jQuery("#parent_id").val();327 post_data["user_ID"] = jQuery("#user-id").val();328 if ( jQuery('#auto_draft').val() == '1' )329 post_data["auto_draft"] = '1';330 275 331 276 if ( doAutoSave ) { … … 351 296 }); 352 297 } 298 299 // Autosave in localStorage 300 // set as simple object/mixin for now 301 window.wp = window.wp || {}; 302 wp.autosave = wp.autosave || {}; 303 304 (function($){ 305 // Returns the data for saving in both localStorage and autosaves to the server 306 wp.autosave.getPostData = function() { 307 var ed = typeof tinymce != 'undefined' ? tinymce.activeEditor : null, post_name, parent_id, cats = [], 308 data = { 309 action: 'autosave', 310 autosave: true, 311 post_id: $('#post_ID').val() || 0, 312 autosavenonce: $('#autosavenonce').val() || '', 313 post_type: $('#post_type').val() || '', 314 post_author: $('#post_author').val() || '', 315 excerpt: $('#excerpt').val() || '' 316 }; 317 318 if ( ed && !ed.isHidden() ) { 319 // Don't run while the tinymce spellcheck is on. It resets all found words. 320 if ( ed.plugins.spellchecker && ed.plugins.spellchecker.active ) { 321 data.autosave = false; 322 return data; 323 } else { 324 if ( 'mce_fullscreen' == ed.id ) 325 tinymce.get('content').setContent(ed.getContent({format : 'raw'}), {format : 'raw'}); 326 327 tinymce.triggerSave(); 328 } 329 } 330 331 if ( typeof fullscreen != 'undefined' && fullscreen.settings.visible ) { 332 data['post_title'] = $('#wp-fullscreen-title').val() || ''; 333 data['content'] = $('#wp_mce_fullscreen').val() || ''; 334 } else { 335 data['post_title'] = $('#title').val() || ''; 336 data['content'] = $('#content').val() || ''; 337 } 338 339 /* 340 // We haven't been saving tags with autosave since 2.8... Start again? 341 $('.the-tags').each( function() { 342 data[this.name] = this.value; 343 }); 344 */ 345 346 $('input[id^="in-category-"]:checked').each( function() { 347 cats.push(this.value); 348 }); 349 data['catslist'] = cats.join(','); 350 351 if ( post_name = $('#post_name').val() ) 352 data['post_name'] = post_name; 353 354 if ( parent_id = $('#parent_id').val() ) 355 data['parent_id'] = parent_id; 356 357 if ( $('#comment_status').prop('checked') ) 358 data['comment_status'] = 'open'; 359 360 if ( $('#ping_status').prop('checked') ) 361 data['ping_status'] = 'open'; 362 363 if ( $('#auto_draft').val() == '1' ) 364 data['auto_draft'] = '1'; 365 366 return data; 367 } 368 369 wp.autosave.local = { 370 371 lastsaveddata: '', 372 blog_id: 0, 373 ajaxurl: window.ajaxurl || 'wp-admin/admin-ajax.php', 374 hasStorage: false, 375 376 // Check if the browser supports sessionStorage and it's not disabled 377 checkStorage: function() { 378 var test = Math.random(), result = false; 379 380 try { 381 sessionStorage.setItem('wp-test', test); 382 result = sessionStorage.getItem('wp-test') == test; 383 sessionStorage.removeItem('wp-test'); 384 } catch(e) {} 385 386 this.hasStorage = result; 387 return result; 388 }, 389 390 /** 391 * Initialize the local storage 392 * 393 * @return mixed False if no sessionStorage in the browser or an Object containing all post_data for this blog 394 */ 395 getStorage: function() { 396 var stored_obj = false; 397 // Separate local storage containers for each blog_id 398 if ( this.hasStorage && this.blog_id ) { 399 stored_obj = sessionStorage.getItem( 'wp-autosave-' + this.blog_id ); 400 401 if ( stored_obj ) 402 stored_obj = JSON.parse( stored_obj ); 403 else 404 stored_obj = {}; 405 } 406 407 return stored_obj; 408 }, 409 410 /** 411 * Set the storage for this blog 412 * 413 * Confirms that the data was saved successfully. 414 * 415 * @return bool 416 */ 417 setStorage: function( stored_obj ) { 418 var key; 419 420 if ( this.hasStorage && this.blog_id ) { 421 key = 'wp-autosave-' + this.blog_id; 422 sessionStorage.setItem( key, JSON.stringify( stored_obj ) ); 423 return sessionStorage.getItem( key ) !== null; 424 } 425 426 return false; 427 }, 428 429 /** 430 * Get the saved post data for the current post 431 * 432 * @return mixed False if no storage or no data or the post_data as an Object 433 */ 434 getData: function() { 435 var stored = this.getStorage(), post_id = $('#post_ID').val(); 436 437 if ( !stored || !post_id ) 438 return false; 439 440 return stored[ 'post_' + post_id ] || false; 441 }, 442 443 /** 444 * Set (save) post data in the storage 445 * 446 * @return bool 447 */ 448 setData: function( stored_data ) { 449 var stored = this.getStorage(), post_id = $('#post_ID').val(); 450 451 if ( !stored || !post_id ) 452 return false; 453 454 stored[ 'post_' + post_id ] = stored_data; 455 456 return this.setStorage(stored); 457 }, 458 459 /** 460 * Save post data for the current post 461 * 462 * Runs on a 15 sec. schedule, saves when there are differences in the post title or content. 463 * When the optional data is provided, updates the last saved post data. 464 * 465 * $param data optional Object The post data for saving, minimum 'post_title' and 'content' 466 * @return bool 467 */ 468 save: function( data ) { 469 var result = false; 470 471 if ( ! data ) { 472 post_data = wp.autosave.getPostData(); 473 } else { 474 post_data = this.getData() || {}; 475 $.extend( post_data, data ); 476 } 477 478 // If the content and title are empty or did not change since the last save, don't save again 479 if ( post_data.post_title + ': ' + post_data.content == this.lastsaveddata ) 480 return false; 481 482 // Cannot get the post data at the moment 483 if ( !post_data.autosave ) 484 return false; 485 486 post_data['save_time'] = (new Date()).getTime(); 487 post_data['status'] = $('#post_status').val() || ''; 488 result = this.setData( post_data ); 489 490 if ( result ) 491 this.lastsaveddata = post_data.post_title + ': ' + post_data.content; 492 493 return result; 494 }, 495 496 // Initialize and run checkPost() on loading the script (before TinyMCE init) 497 init: function( settings ) { 498 var self = this; 499 500 // Run only on the Add/Edit Post screens and in browsers that have sessionStorage 501 if ( 'post' != window.pagenow || ! this.checkStorage() ) 502 return; 503 // editor.js has to be loaded before autosave.js 504 if ( typeof switchEditors == 'undefined' ) 505 return; 506 507 if ( settings ) 508 $.extend( this, settings ); 509 510 if ( !this.blog_id ) 511 this.blog_id = typeof window.autosaveL10n != 'undefined' ? window.autosaveL10n.blog_id : 0; 512 513 this.checkPost(); 514 $(document).ready( self.run ); 515 }, 516 517 // Run on DOM ready 518 run: function() { 519 var self = this, post_data; 520 521 // Set the comparison string 522 if ( !this.lastsaveddata ) { 523 post_data = wp.autosave.getPostData(); 524 525 if ( post_data.content && $('#wp-content-wrap').hasClass('tmce-active') ) 526 this.lastsaveddata = post_data.post_title + ': ' + switchEditors.pre_wpautop( post_data.content ); 527 else 528 this.lastsaveddata = post_data.post_title + ': ' + post_data.content; 529 } 530 531 // Set the schedule 532 this.schedule = $.schedule({ 533 time: 15 * 1000, 534 func: function() { wp.autosave.local.save(); }, 535 repeat: true, 536 protect: true 537 }); 538 539 $('form#post').on('submit.autosave-local', function() { 540 var editor = typeof tinymce != 'undefined' && tinymce.get('content'); 541 542 if ( editor && ! editor.isHidden() ) { 543 // Last onSubmit event in the editor, needs to run after the content has been moved to the textarea. 544 editor.onSubmit.add( function() { 545 wp.autosave.local.save({ 546 post_title: $('#title').val() || '', 547 content: $('#content').val() || '', 548 excerpt: $('#excerpt').val() || '' 549 }); 550 }); 551 } else { 552 self.save({ 553 post_title: $('#title').val() || '', 554 content: $('#content').val() || '', 555 excerpt: $('#excerpt').val() || '' 556 }); 557 } 558 }); 559 }, 560 561 // Strip whitespace and compare two strings 562 compare: function( str1, str2, strip_tags ) { 563 function remove( string, strip_tags ) { 564 string = string.toString(); 565 566 if ( strip_tags ) 567 string = string.replace(/<[^<>]+>/g, ''); 568 569 return string.replace(/[\x20\t\r\n\f]+/g, ''); 570 } 571 572 return ( remove( str1 || '', strip_tags ) == remove( str2 || '', strip_tags ) ); 573 }, 574 575 /** 576 * Check if the saved data for the current post (if any) is different than the loaded post data on the screen 577 * 578 * Shows a standard message letting the user restore the post data if different. 579 * 580 * @return void 581 */ 582 checkPost: function() { 583 var self = this, post_data = this.getData(), content, check_data, strip_tags = false, notice; 584 585 if ( ! post_data ) 586 return; 587 588 // There is a newer autosave. Don't show two "restore" notices at the same time. 589 if ( $('#has-newer-autosave').length ) 590 return; 591 592 content = $('#content').val(); 593 check_data = $.extend( {}, post_data ); 594 595 if ( $('#wp-content-wrap').hasClass('tmce-active') ) 596 content = switchEditors.pre_wpautop( content ); 597 598 // The post has just been published, only compare text 599 if ( $('#post_status').val() == 'publish' && check_data.status != 'publish' ) 600 strip_tags = true; 601 602 if ( this.compare( content, check_data.content, strip_tags ) && this.compare( $('#title').val(), check_data.post_title, strip_tags ) && this.compare( $('#excerpt').val(), check_data.excerpt, strip_tags ) ) 603 return; 604 605 // We have three choices here: 606 // - Do an autosave and then show the standard notice "There is an autosave newer than...". 607 // - Offer to load/restore the backed up post data. 608 // - Restore the post_data without asking, then show a notice with an Undo link/button. 609 // Doing an autosave will take few seconds and may take up to 30 and fail if network connectivity is bad 610 // Restoring the post will leave the user with the proper content, but it won't be saved to the server until the next autosave. 611 612 this.restore_post_data = post_data; 613 this.undo_post_data = wp.autosave.getPostData(); 614 615 /* 616 if ( $('#post_status').val() == 'publish' ) { 617 // Different message when a post is published? 618 // Comparing the current and saved post data may fail (false positive) when the post is published 619 // as in some cases there are changes to post_content on publishing and updating before saving to the DB. 620 } 621 */ 622 623 notice = $('#local-storage-notice'); 624 $('form#post').before( notice.addClass('updated').show() ); 625 626 notice.on( 'click', function(e) { 627 var target = $( e.target ); 628 629 if ( target.hasClass('restore-backup') ) { 630 self.restorePost( self.restore_post_data ); 631 target.parent().hide(); 632 $(this).find('p.undo-restore').show(); 633 } else if ( target.hasClass('undo-restore-backup') ) { 634 self.restorePost( self.undo_post_data ); 635 target.parent().hide(); 636 $(this).find('p.local-restore').show(); 637 } 638 639 e.preventDefault(); 640 }); 641 }, 642 643 // Restore the current title, content and excerpt from post_data. 644 restorePost: function( post_data ) { 645 var editor; 646 647 if ( post_data ) { 648 // Set the last saved data 649 this.lastsaveddata = post_data.post_title + ': ' + post_data.content; 650 651 if ( $('#title').val() != post_data.post_title ) 652 $('#title').focus().val( post_data.post_title || '' ); 653 654 $('#excerpt').val( post_data.excerpt || '' ); 655 editor = typeof tinymce != 'undefined' && tinymce.get('content'); 656 657 if ( editor && ! editor.isHidden() ) { 658 // Make sure there's an undo level in the editor 659 editor.undoManager.add(); 660 editor.setContent( post_data.content ? switchEditors.wpautop( post_data.content ) : '' ); 661 } else { 662 // Make sure the Text editor is selected 663 $('#content-html').click(); 664 $('#content').val( post_data.content ); 665 } 666 667 return true; 668 } 669 670 return false; 671 } 672 } 673 674 wp.autosave.local.init(); 675 676 }(jQuery)); -
trunk/wp-includes/script-loader.php
r23681 r23683 107 107 ) ); 108 108 109 $scripts->add( 'autosave', "/wp-includes/js/autosave$suffix.js", array('schedule', 'wp-ajax-response' ), false, 1 );109 $scripts->add( 'autosave', "/wp-includes/js/autosave$suffix.js", array('schedule', 'wp-ajax-response', 'editor'), false, 1 ); 110 110 111 111 $scripts->add( 'heartbeat', "/wp-includes/js/heartbeat$suffix.js", array('jquery'), false, 1 ); … … 586 586 'autosaveInterval' => AUTOSAVE_INTERVAL, 587 587 'savingText' => __('Saving Draft…'), 588 'saveAlert' => __('The changes you made will be lost if you navigate away from this page.') 588 'saveAlert' => __('The changes you made will be lost if you navigate away from this page.'), 589 'blog_id' => get_current_blog_id(), 589 590 ) ); 590 591 -
trunk/wp-login.php
r23625 r23683 67 67 if ( wp_is_mobile() ) { ?> 68 68 <meta name="viewport" content="width=320; initial-scale=0.9; maximum-scale=1.0; user-scalable=0;" /><?php 69 } 70 71 // Remove all stored post data on logging out. 72 // This could be added by add_action('login_head'...) like wp_shake_js() 73 // but maybe better if it's not removable by plugins 74 if ( 'loggedout' == $wp_error->get_error_code() ) { 75 ?> 76 <script>if("sessionStorage" in window){try{for(var key in sessionStorage){if(key.indexOf("wp-autosave-")!=-1){sessionStorage.removeItem(key)}}}catch(e){}};</script> 77 <?php 69 78 } 70 79
Note: See TracChangeset
for help on using the changeset viewer.