[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-content/plugins/akismet/_inc/ -> akismet.js (source)

   1  jQuery( function ( $ ) {
   2      var mshotRemovalTimer = null;
   3      var mshotRetryTimer = null;
   4      var mshotTries = 0;
   5      var mshotRetryInterval = 1000;
   6      var mshotEnabledLinkSelector = 'a[id^="author_comment_url"], tr.pingback td.column-author a:first-of-type, td.comment p a';
   7  
   8      var preloadedMshotURLs = [];
   9  
  10      $('.akismet-status').each(function () {
  11          var thisId = $(this).attr('commentid');
  12          $(this).prependTo('#comment-' + thisId + ' .column-comment');
  13      });
  14      $('.akismet-user-comment-count').each(function () {
  15          var thisId = $(this).attr('commentid');
  16          $(this).insertAfter('#comment-' + thisId + ' .author strong:first').show();
  17      });
  18  
  19      akismet_enable_comment_author_url_removal();
  20      
  21      $( '#the-comment-list' ).on( 'click', '.akismet_remove_url', function () {
  22          var thisId = $(this).attr('commentid');
  23          var data = {
  24              action: 'comment_author_deurl',
  25              _wpnonce: WPAkismet.comment_author_url_nonce,
  26              id: thisId
  27          };
  28          $.ajax({
  29              url: ajaxurl,
  30              type: 'POST',
  31              data: data,
  32              beforeSend: function () {
  33                  // Removes "x" link
  34                  $("a[commentid='"+ thisId +"']").hide();
  35                  // Show temp status
  36                  $("#author_comment_url_"+ thisId).html( $( '<span/>' ).text( WPAkismet.strings['Removing...'] ) );
  37              },
  38              success: function (response) {
  39                  if (response) {
  40                      // Show status/undo link
  41                      $("#author_comment_url_"+ thisId)
  42                          .attr('cid', thisId)
  43                          .addClass('akismet_undo_link_removal')
  44                          .html(
  45                              $( '<span/>' ).text( WPAkismet.strings['URL removed'] )
  46                          )
  47                          .append( ' ' )
  48                          .append(
  49                              $( '<span/>' )
  50                                  .text( WPAkismet.strings['(undo)'] )
  51                                  .addClass( 'akismet-span-link' )
  52                          );
  53                  }
  54              }
  55          });
  56  
  57          return false;
  58      }).on( 'click', '.akismet_undo_link_removal', function () {
  59          var thisId = $(this).attr('cid');
  60          var thisUrl = $(this).attr('href');
  61          var data = {
  62              action: 'comment_author_reurl',
  63              _wpnonce: WPAkismet.comment_author_url_nonce,
  64              id: thisId,
  65              url: thisUrl
  66          };
  67          $.ajax({
  68              url: ajaxurl,
  69              type: 'POST',
  70              data: data,
  71              beforeSend: function () {
  72                  // Show temp status
  73                  $("#author_comment_url_"+ thisId).html( $( '<span/>' ).text( WPAkismet.strings['Re-adding...'] ) );
  74              },
  75              success: function (response) {
  76                  if (response) {
  77                      // Add "x" link
  78                      $("a[commentid='"+ thisId +"']").show();
  79                      // Show link. Core strips leading http://, so let's do that too.
  80                      $("#author_comment_url_"+ thisId).removeClass('akismet_undo_link_removal').text( thisUrl.replace( /^http:\/\/(www\.)?/ig, '' ) );
  81                  }
  82              }
  83          });
  84  
  85          return false;
  86      });
  87  
  88      // Show a preview image of the hovered URL. Applies to author URLs and URLs inside the comments.
  89      if ( "enable_mshots" in WPAkismet && WPAkismet.enable_mshots ) {
  90          $( '#the-comment-list' ).on( 'mouseover', mshotEnabledLinkSelector, function () {
  91              clearTimeout( mshotRemovalTimer );
  92  
  93              if ( $( '.akismet-mshot' ).length > 0 ) {
  94                  if ( $( '.akismet-mshot:first' ).data( 'link' ) == this ) {
  95                      // The preview is already showing for this link.
  96                      return;
  97                  }
  98                  else {
  99                      // A new link is being hovered, so remove the old preview.
 100                      $( '.akismet-mshot' ).remove();
 101                  }
 102              }
 103  
 104              clearTimeout( mshotRetryTimer );
 105  
 106              var linkUrl = $( this ).attr( 'href' );
 107  
 108              if ( preloadedMshotURLs.indexOf( linkUrl ) !== -1 ) {
 109                  // This preview image was already preloaded, so begin with a retry URL so the user doesn't see the placeholder image for the first second.
 110                  mshotTries = 2;
 111              }
 112              else {
 113                  mshotTries = 1;
 114              }
 115  
 116              var mShot = $( '<div class="akismet-mshot mshot-container"><div class="mshot-arrow"></div><img src="' + akismet_mshot_url( linkUrl, mshotTries ) + '" width="450" height="338" class="mshot-image" /></div>' );
 117              mShot.data( 'link', this );
 118              mShot.data( 'url', linkUrl );
 119  
 120              mShot.find( 'img' ).on( 'load', function () {
 121                  $( '.akismet-mshot' ).data( 'pending-request', false );
 122              } );
 123  
 124              var offset = $( this ).offset();
 125  
 126              mShot.offset( {
 127                  left : Math.min( $( window ).width() - 475, offset.left + $( this ).width() + 10 ), // Keep it on the screen if the link is near the edge of the window.
 128                  top: offset.top + ( $( this ).height() / 2 ) - 101 // 101 = top offset of the arrow plus the top border thickness
 129              } );
 130  
 131              $( 'body' ).append( mShot );
 132  
 133              mshotRetryTimer = setTimeout( retryMshotUntilLoaded, mshotRetryInterval );
 134          } ).on( 'mouseout', 'a[id^="author_comment_url"], tr.pingback td.column-author a:first-of-type, td.comment p a', function () {
 135              mshotRemovalTimer = setTimeout( function () {
 136                  clearTimeout( mshotRetryTimer );
 137  
 138                  $( '.akismet-mshot' ).remove();
 139              }, 200 );
 140          } );
 141  
 142          var preloadDelayTimer = null;
 143  
 144          $( window ).on( 'scroll resize', function () {
 145              clearTimeout( preloadDelayTimer );
 146  
 147              preloadDelayTimer = setTimeout( preloadMshotsInViewport, 500 );
 148          } );
 149  
 150          preloadMshotsInViewport();
 151      }
 152  
 153      /**
 154       * The way mShots works is if there was no screenshot already recently generated for the URL,
 155       * it returns a "loading..." image for the first request. Then, some subsequent request will
 156       * receive the actual screenshot, but it's unknown how long it will take. So, what we do here
 157       * is continually re-request the mShot, waiting a second after every response until we get the
 158       * actual screenshot.
 159       */
 160  	function retryMshotUntilLoaded() {
 161          clearTimeout( mshotRetryTimer );
 162  
 163          var imageWidth = $( '.akismet-mshot img' ).get(0).naturalWidth;
 164  
 165          if ( imageWidth == 0 ) {
 166              // It hasn't finished loading yet the first time. Check again shortly.
 167              setTimeout( retryMshotUntilLoaded, mshotRetryInterval );
 168          }
 169          else if ( imageWidth == 400 ) {
 170              // It loaded the preview image.
 171  
 172              if ( mshotTries == 20 ) {
 173                  // Give up if we've requested the mShot 20 times already.
 174                  return;
 175              }
 176  
 177              if ( ! $( '.akismet-mshot' ).data( 'pending-request' ) ) {
 178                  $( '.akismet-mshot' ).data( 'pending-request', true );
 179  
 180                  mshotTries++;
 181  
 182                  $( '.akismet-mshot .mshot-image' ).attr( 'src', akismet_mshot_url( $( '.akismet-mshot' ).data( 'url' ), mshotTries ) );
 183              }
 184  
 185              mshotRetryTimer = setTimeout( retryMshotUntilLoaded, mshotRetryInterval );
 186          }
 187          else {
 188              // All done.
 189          }
 190      }
 191      
 192  	function preloadMshotsInViewport() {
 193          var windowWidth = $( window ).width();
 194          var windowHeight = $( window ).height();
 195  
 196          $( '#the-comment-list' ).find( mshotEnabledLinkSelector ).each( function ( index, element ) {
 197              var linkUrl = $( this ).attr( 'href' );
 198  
 199              // Don't attempt to preload an mshot for a single link twice.
 200              if ( preloadedMshotURLs.indexOf( linkUrl ) !== -1 ) {
 201                  // The URL is already preloaded.
 202                  return true;
 203              }
 204  
 205              if ( typeof element.getBoundingClientRect !== 'function' ) {
 206                  // The browser is too old. Return false to stop this preloading entirely.
 207                  return false;
 208              }
 209  
 210              var rect = element.getBoundingClientRect();
 211  
 212              if ( rect.top >= 0 && rect.left >= 0 && rect.bottom <= windowHeight && rect.right <= windowWidth ) {
 213                  akismet_preload_mshot( linkUrl );
 214                  $( this ).data( 'akismet-mshot-preloaded', true );
 215              }
 216          } );
 217      }
 218  
 219      $( '.checkforspam.enable-on-load' ).on( 'click', function( e ) {
 220          if ( $( this ).hasClass( 'ajax-disabled' ) ) {
 221              // Akismet hasn't been configured yet. Allow the user to proceed to the button's link.
 222              return;
 223          }
 224  
 225          e.preventDefault();
 226  
 227          if ( $( this ).hasClass( 'button-disabled' ) ) {
 228              window.location.href = $( this ).data( 'success-url' ).replace( '__recheck_count__', 0 ).replace( '__spam_count__', 0 );
 229              return;
 230          }
 231  
 232          $('.checkforspam').addClass('button-disabled').addClass( 'checking' );
 233          $('.checkforspam-spinner').addClass( 'spinner' ).addClass( 'is-active' );
 234  
 235          akismet_check_for_spam(0, 100);
 236      }).removeClass( 'button-disabled' );
 237  
 238      var spam_count = 0;
 239      var recheck_count = 0;
 240  
 241  	function akismet_check_for_spam(offset, limit) {
 242          var check_for_spam_buttons = $( '.checkforspam' );
 243          
 244          var nonce = check_for_spam_buttons.data( 'nonce' );
 245          
 246          // We show the percentage complete down to one decimal point so even queues with 100k
 247          // pending comments will show some progress pretty quickly.
 248          var percentage_complete = Math.round( ( recheck_count / check_for_spam_buttons.data( 'pending-comment-count' ) ) * 1000 ) / 10;
 249          
 250          // Update the progress counter on the "Check for Spam" button.
 251          $( '.checkforspam' ).text( check_for_spam_buttons.data( 'progress-label' ).replace( '%1$s', percentage_complete ) );
 252  
 253          $.post(
 254              ajaxurl,
 255              {
 256                  'action': 'akismet_recheck_queue',
 257                  'offset': offset,
 258                  'limit': limit,
 259                  'nonce': nonce
 260              },
 261              function(result) {
 262                  if ( 'error' in result ) {
 263                      // An error is only returned in the case of a missing nonce, so we don't need the actual error message.
 264                      window.location.href = check_for_spam_buttons.data( 'failure-url' );
 265                      return;
 266                  }
 267                  
 268                  recheck_count += result.counts.processed;
 269                  spam_count += result.counts.spam;
 270                  
 271                  if (result.counts.processed < limit) {
 272                      window.location.href = check_for_spam_buttons.data( 'success-url' ).replace( '__recheck_count__', recheck_count ).replace( '__spam_count__', spam_count );
 273                  }
 274                  else {
 275                      // Account for comments that were caught as spam and moved out of the queue.
 276                      akismet_check_for_spam(offset + limit - result.counts.spam, limit);
 277                  }
 278              }
 279          );
 280      }
 281      
 282      if ( "start_recheck" in WPAkismet && WPAkismet.start_recheck ) {
 283          $( '.checkforspam' ).click();
 284      }
 285      
 286      if ( typeof MutationObserver !== 'undefined' ) {
 287          // Dynamically add the "X" next the the author URL links when a comment is quick-edited.
 288          var comment_list_container = document.getElementById( 'the-comment-list' );
 289  
 290          if ( comment_list_container ) {
 291              var observer = new MutationObserver( function ( mutations ) {
 292                  for ( var i = 0, _len = mutations.length; i < _len; i++ ) {
 293                      if ( mutations[i].addedNodes.length > 0 ) {
 294                          akismet_enable_comment_author_url_removal();
 295                          
 296                          // Once we know that we'll have to check for new author links, skip the rest of the mutations.
 297                          break;
 298                      }
 299                  }
 300              } );
 301              
 302              observer.observe( comment_list_container, { attributes: true, childList: true, characterData: true } );
 303          }
 304      }
 305  
 306  	function akismet_enable_comment_author_url_removal() {
 307          $( '#the-comment-list' )
 308              .find( 'tr.comment, tr[id ^= "comment-"]' )
 309              .find( '.column-author a[href^="http"]:first' ) // Ignore mailto: links, which would be the comment author's email.
 310              .each(function () {
 311                  if ( $( this ).parent().find( '.akismet_remove_url' ).length > 0 ) {
 312                      return;
 313                  }
 314              
 315              var linkHref = $(this).attr( 'href' );
 316          
 317              // Ignore any links to the current domain, which are diagnostic tools, like the IP address link
 318              // or any other links another plugin might add.
 319              var currentHostParts = document.location.href.split( '/' );
 320              var currentHost = currentHostParts[0] + '//' + currentHostParts[2] + '/';
 321          
 322              if ( linkHref.indexOf( currentHost ) != 0 ) {
 323                  var thisCommentId = $(this).parents('tr:first').attr('id').split("-");
 324  
 325                  $(this)
 326                      .attr("id", "author_comment_url_"+ thisCommentId[1])
 327                      .after(
 328                          $( '<a href="#" class="akismet_remove_url">x</a>' )
 329                              .attr( 'commentid', thisCommentId[1] )
 330                              .attr( 'title', WPAkismet.strings['Remove this URL'] )
 331                      );
 332              }
 333          });
 334      }
 335      
 336      /**
 337       * Generate an mShot URL if given a link URL.
 338       *
 339       * @param string linkUrl
 340       * @param int retry If retrying a request, the number of the retry.
 341       * @return string The mShot URL;
 342       */
 343  	function akismet_mshot_url( linkUrl, retry ) {
 344          var mshotUrl = '//s0.wp.com/mshots/v1/' + encodeURIComponent( linkUrl ) + '?w=900';
 345  
 346          if ( retry > 1 ) {
 347              mshotUrl += '&r=' + encodeURIComponent( retry );
 348          }
 349  
 350          mshotUrl += '&source=akismet';
 351  
 352          return mshotUrl;
 353      }
 354      
 355      /**
 356       * Begin loading an mShot preview of a link.
 357       *
 358       * @param string linkUrl
 359       */
 360  	function akismet_preload_mshot( linkUrl ) {
 361          var img = new Image();
 362          img.src = akismet_mshot_url( linkUrl );
 363          
 364          preloadedMshotURLs.push( linkUrl );
 365      }
 366  
 367      $( '.akismet-could-be-primary' ).each( function () {
 368          var form = $( this ).closest( 'form' );
 369  
 370          form.data( 'initial-state', form.serialize() );
 371  
 372          form.on( 'change keyup', function () {
 373              var self = $( this );
 374              var submit_button = self.find( '.akismet-could-be-primary' );
 375  
 376              if ( self.serialize() != self.data( 'initial-state' ) ) {
 377                  submit_button.addClass( 'akismet-is-primary' );
 378              }
 379              else {
 380                  submit_button.removeClass( 'akismet-is-primary' );
 381              }
 382          } );
 383      } );
 384  
 385      /**
 386       * Shows the Enter API key form
 387       */
 388      $( '.akismet-enter-api-key-box__reveal' ).on( 'click', function ( e ) {
 389          e.preventDefault();
 390  
 391          var div = $( '.akismet-enter-api-key-box__form-wrapper' );
 392          div.show( 500 );
 393          div.find( 'input[name=key]' ).focus();
 394  
 395          $( this ).hide();
 396      } );
 397  
 398      /**
 399       * Hides the Connect with Jetpack form | Shows the Activate Akismet Account form
 400       */
 401      $( 'a.toggle-ak-connect' ).on( 'click', function ( e ) {
 402          e.preventDefault();
 403  
 404          $( '.akismet-ak-connect' ).slideToggle('slow');
 405          $( 'a.toggle-ak-connect' ).hide();
 406          $( '.akismet-jp-connect' ).hide();
 407          $( 'a.toggle-jp-connect' ).show();
 408      } );
 409  
 410      /**
 411       * Shows the Connect with Jetpack form | Hides the Activate Akismet Account form
 412       */
 413      $( 'a.toggle-jp-connect' ).on( 'click', function ( e ) {
 414          e.preventDefault();
 415  
 416          $( '.akismet-jp-connect' ).slideToggle('slow');
 417          $( 'a.toggle-jp-connect' ).hide();
 418          $( '.akismet-ak-connect' ).hide();
 419          $( 'a.toggle-ak-connect' ).show();
 420      } );
 421  });


Generated : Tue Mar 19 08:20:01 2024 Cross-referenced by PHPXref