wp-auth-check.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /**
  2. * Interim login dialog.
  3. *
  4. * @output wp-includes/js/wp-auth-check.js
  5. */
  6. /* global adminpage */
  7. (function($){
  8. var wrap, next;
  9. /**
  10. * Shows the authentication form popup.
  11. *
  12. * @since 3.6.0
  13. * @private
  14. */
  15. function show() {
  16. var parent = $('#wp-auth-check'),
  17. form = $('#wp-auth-check-form'),
  18. noframe = wrap.find('.wp-auth-fallback-expired'),
  19. frame, loaded = false;
  20. if ( form.length ) {
  21. // Add unload confirmation to counter (frame-busting) JS redirects.
  22. $(window).on( 'beforeunload.wp-auth-check', function(e) {
  23. e.originalEvent.returnValue = window.authcheckL10n.beforeunload;
  24. });
  25. frame = $('<iframe id="wp-auth-check-frame" frameborder="0">').attr( 'title', noframe.text() );
  26. frame.on( 'load', function() {
  27. var height, body;
  28. loaded = true;
  29. // Remove the spinner to avoid unnecessary CPU/GPU usage.
  30. form.removeClass( 'loading' );
  31. try {
  32. body = $(this).contents().find('body');
  33. height = body.height();
  34. } catch(e) {
  35. wrap.addClass('fallback');
  36. parent.css( 'max-height', '' );
  37. form.remove();
  38. noframe.focus();
  39. return;
  40. }
  41. if ( height ) {
  42. if ( body && body.hasClass('interim-login-success') )
  43. hide();
  44. else
  45. parent.css( 'max-height', height + 40 + 'px' );
  46. } else if ( ! body || ! body.length ) {
  47. // Catch "silent" iframe origin exceptions in WebKit after another page is
  48. // loaded in the iframe.
  49. wrap.addClass('fallback');
  50. parent.css( 'max-height', '' );
  51. form.remove();
  52. noframe.focus();
  53. }
  54. }).attr( 'src', form.data('src') );
  55. form.append( frame );
  56. }
  57. $( 'body' ).addClass( 'modal-open' );
  58. wrap.removeClass('hidden');
  59. if ( frame ) {
  60. frame.focus();
  61. // WebKit doesn't throw an error if the iframe fails to load because of
  62. // "X-Frame-Options: DENY" header.
  63. // Wait for 10 sec. and switch to the fallback text.
  64. setTimeout( function() {
  65. if ( ! loaded ) {
  66. wrap.addClass('fallback');
  67. form.remove();
  68. noframe.focus();
  69. }
  70. }, 10000 );
  71. } else {
  72. noframe.focus();
  73. }
  74. }
  75. /**
  76. * Hides the authentication form popup.
  77. *
  78. * @since 3.6.0
  79. * @private
  80. */
  81. function hide() {
  82. $(window).off( 'beforeunload.wp-auth-check' );
  83. // When on the Edit Post screen, speed up heartbeat after the user logs in to
  84. // quickly refresh nonces.
  85. if ( typeof adminpage !== 'undefined' && ( adminpage === 'post-php' || adminpage === 'post-new-php' ) &&
  86. typeof wp !== 'undefined' && wp.heartbeat ) {
  87. $(document).off( 'heartbeat-tick.wp-auth-check' );
  88. wp.heartbeat.connectNow();
  89. }
  90. wrap.fadeOut( 200, function() {
  91. wrap.addClass('hidden').css('display', '');
  92. $('#wp-auth-check-frame').remove();
  93. $( 'body' ).removeClass( 'modal-open' );
  94. });
  95. }
  96. /**
  97. * Schedules when the next time the authentication check will be done.
  98. *
  99. * @since 3.6.0
  100. * @private
  101. */
  102. function schedule() {
  103. // In seconds, default 3 min.
  104. var interval = parseInt( window.authcheckL10n.interval, 10 ) || 180;
  105. next = ( new Date() ).getTime() + ( interval * 1000 );
  106. }
  107. /**
  108. * Binds to the Heartbeat Tick event.
  109. *
  110. * - Shows the authentication form popup if user is not logged in.
  111. * - Hides the authentication form popup if it is already visible and user is
  112. * logged in.
  113. *
  114. * @ignore
  115. *
  116. * @since 3.6.0
  117. *
  118. * @param {Object} e The heartbeat-tick event that has been triggered.
  119. * @param {Object} data Response data.
  120. */
  121. $( document ).on( 'heartbeat-tick.wp-auth-check', function( e, data ) {
  122. if ( 'wp-auth-check' in data ) {
  123. schedule();
  124. if ( ! data['wp-auth-check'] && wrap.hasClass('hidden') ) {
  125. show();
  126. } else if ( data['wp-auth-check'] && ! wrap.hasClass('hidden') ) {
  127. hide();
  128. }
  129. }
  130. /**
  131. * Binds to the Heartbeat Send event.
  132. *
  133. * @ignore
  134. *
  135. * @since 3.6.0
  136. *
  137. * @param {Object} e The heartbeat-send event that has been triggered.
  138. * @param {Object} data Response data.
  139. */
  140. }).on( 'heartbeat-send.wp-auth-check', function( e, data ) {
  141. if ( ( new Date() ).getTime() > next ) {
  142. data['wp-auth-check'] = true;
  143. }
  144. }).ready( function() {
  145. schedule();
  146. /**
  147. * Hides the authentication form popup when the close icon is clicked.
  148. *
  149. * @ignore
  150. *
  151. * @since 3.6.0
  152. */
  153. wrap = $('#wp-auth-check-wrap');
  154. wrap.find('.wp-auth-check-close').on( 'click', function() {
  155. hide();
  156. });
  157. });
  158. }(jQuery));