diff options
Diffstat (limited to 'plugins/akismet/_inc/akismet.js')
-rw-r--r-- | plugins/akismet/_inc/akismet.js | 207 |
1 files changed, 137 insertions, 70 deletions
diff --git a/plugins/akismet/_inc/akismet.js b/plugins/akismet/_inc/akismet.js index 3445a094..7ebac1a5 100644 --- a/plugins/akismet/_inc/akismet.js +++ b/plugins/akismet/_inc/akismet.js @@ -1,10 +1,12 @@ jQuery( function ( $ ) { var mshotRemovalTimer = null; - var mshotSecondTryTimer = null - var mshotThirdTryTimer = null - + var mshotRetryTimer = null; + var mshotTries = 0; + var mshotRetryInterval = 1000; var mshotEnabledLinkSelector = 'a[id^="author_comment_url"], tr.pingback td.column-author a:first-of-type, td.comment p a'; - + + var preloadedMshotURLs = []; + $('.akismet-status').each(function () { var thisId = $(this).attr('commentid'); $(this).prependTo('#comment-' + thisId + ' .column-comment'); @@ -84,69 +86,142 @@ jQuery( function ( $ ) { }); // Show a preview image of the hovered URL. Applies to author URLs and URLs inside the comments. - $( '#the-comment-list' ).on( 'mouseover', mshotEnabledLinkSelector, function () { - clearTimeout( mshotRemovalTimer ); + if ( "enable_mshots" in WPAkismet && WPAkismet.enable_mshots ) { + $( '#the-comment-list' ).on( 'mouseover', mshotEnabledLinkSelector, function () { + clearTimeout( mshotRemovalTimer ); - if ( $( '.akismet-mshot' ).length > 0 ) { - if ( $( '.akismet-mshot:first' ).data( 'link' ) == this ) { - // The preview is already showing for this link. - return; + if ( $( '.akismet-mshot' ).length > 0 ) { + if ( $( '.akismet-mshot:first' ).data( 'link' ) == this ) { + // The preview is already showing for this link. + return; + } + else { + // A new link is being hovered, so remove the old preview. + $( '.akismet-mshot' ).remove(); + } + } + + clearTimeout( mshotRetryTimer ); + + var linkUrl = $( this ).attr( 'href' ); + + if ( preloadedMshotURLs.indexOf( linkUrl ) !== -1 ) { + // 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. + mshotTries = 2; } else { - // A new link is being hovered, so remove the old preview. - $( '.akismet-mshot' ).remove(); + mshotTries = 1; } - } - clearTimeout( mshotSecondTryTimer ); - clearTimeout( mshotThirdTryTimer ); + 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>' ); + mShot.data( 'link', this ); + mShot.data( 'url', linkUrl ); + + mShot.find( 'img' ).on( 'load', function () { + $( '.akismet-mshot' ).data( 'pending-request', false ); + } ); - var thisHref = $( this ).attr( 'href' ); + var offset = $( this ).offset(); - var mShot = $( '<div class="akismet-mshot mshot-container"><div class="mshot-arrow"></div><img src="' + akismet_mshot_url( thisHref ) + '" width="450" height="338" class="mshot-image" /></div>' ); - mShot.data( 'link', this ); + mShot.offset( { + 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. + top: offset.top + ( $( this ).height() / 2 ) - 101 // 101 = top offset of the arrow plus the top border thickness + } ); - var offset = $( this ).offset(); + $( 'body' ).append( mShot ); - mShot.offset( { - 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. - top: offset.top + ( $( this ).height() / 2 ) - 101 // 101 = top offset of the arrow plus the top border thickness + mshotRetryTimer = setTimeout( retryMshotUntilLoaded, mshotRetryInterval ); + } ).on( 'mouseout', 'a[id^="author_comment_url"], tr.pingback td.column-author a:first-of-type, td.comment p a', function () { + mshotRemovalTimer = setTimeout( function () { + clearTimeout( mshotRetryTimer ); + + $( '.akismet-mshot' ).remove(); + }, 200 ); } ); - // These retries appear to be superfluous if .mshot-image has already loaded, but it's because mShots - // can return a "Generating thumbnail..." image if it doesn't have a thumbnail ready, so we need - // to retry to see if we can get the newly generated thumbnail. - mshotSecondTryTimer = setTimeout( function () { - mShot.find( '.mshot-image' ).attr( 'src', akismet_mshot_url( thisHref, 2 ) ); - }, 6000 ); - - mshotThirdTryTimer = setTimeout( function () { - mShot.find( '.mshot-image' ).attr( 'src', akismet_mshot_url( thisHref, 3 ) ); - }, 12000 ); - - $( 'body' ).append( mShot ); - } ).on( 'mouseout', 'a[id^="author_comment_url"], tr.pingback td.column-author a:first-of-type, td.comment p a', function () { - mshotRemovalTimer = setTimeout( function () { - clearTimeout( mshotSecondTryTimer ); - clearTimeout( mshotThirdTryTimer ); - - $( '.akismet-mshot' ).remove(); - }, 200 ); - } ).on( 'mouseover', 'tr', function () { - // When the mouse hovers over a comment row, begin preloading mshots for any links in the comment or the comment author. - var linksToPreloadMshotsFor = $( this ).find( mshotEnabledLinkSelector ); - - linksToPreloadMshotsFor.each( function () { - // Don't attempt to preload an mshot for a single link twice. Browser caching should cover this, but in case of - // race conditions, save a flag locally when we've begun trying to preload one. - if ( ! $( this ).data( 'akismet-mshot-preloaded' ) ) { - akismet_preload_mshot( $( this ).attr( 'href' ) ); + var preloadDelayTimer = null; + + $( window ).on( 'scroll resize', function () { + clearTimeout( preloadDelayTimer ); + + preloadDelayTimer = setTimeout( preloadMshotsInViewport, 500 ); + } ); + + preloadMshotsInViewport(); + } + + /** + * The way mShots works is if there was no screenshot already recently generated for the URL, + * it returns a "loading..." image for the first request. Then, some subsequent request will + * receive the actual screenshot, but it's unknown how long it will take. So, what we do here + * is continually re-request the mShot, waiting a second after every response until we get the + * actual screenshot. + */ + function retryMshotUntilLoaded() { + clearTimeout( mshotRetryTimer ); + + var imageWidth = $( '.akismet-mshot img' ).get(0).naturalWidth; + + if ( imageWidth == 0 ) { + // It hasn't finished loading yet the first time. Check again shortly. + setTimeout( retryMshotUntilLoaded, mshotRetryInterval ); + } + else if ( imageWidth == 400 ) { + // It loaded the preview image. + + if ( mshotTries == 20 ) { + // Give up if we've requested the mShot 20 times already. + return; + } + + if ( ! $( '.akismet-mshot' ).data( 'pending-request' ) ) { + $( '.akismet-mshot' ).data( 'pending-request', true ); + + mshotTries++; + + $( '.akismet-mshot .mshot-image' ).attr( 'src', akismet_mshot_url( $( '.akismet-mshot' ).data( 'url' ), mshotTries ) ); + } + + mshotRetryTimer = setTimeout( retryMshotUntilLoaded, mshotRetryInterval ); + } + else { + // All done. + } + } + + function preloadMshotsInViewport() { + var windowWidth = $( window ).width(); + var windowHeight = $( window ).height(); + + $( '#the-comment-list' ).find( mshotEnabledLinkSelector ).each( function ( index, element ) { + var linkUrl = $( this ).attr( 'href' ); + + // Don't attempt to preload an mshot for a single link twice. + if ( preloadedMshotURLs.indexOf( linkUrl ) !== -1 ) { + // The URL is already preloaded. + return true; + } + + if ( typeof element.getBoundingClientRect !== 'function' ) { + // The browser is too old. Return false to stop this preloading entirely. + return false; + } + + var rect = element.getBoundingClientRect(); + + if ( rect.top >= 0 && rect.left >= 0 && rect.bottom <= windowHeight && rect.right <= windowWidth ) { + akismet_preload_mshot( linkUrl ); $( this ).data( 'akismet-mshot-preloaded', true ); } } ); - } ); + } + + $( '.checkforspam.enable-on-load' ).on( 'click', function( e ) { + if ( $( this ).hasClass( 'ajax-disabled' ) ) { + // Akismet hasn't been configured yet. Allow the user to proceed to the button's link. + return; + } - $( '.checkforspam' ).click( function( e ) { e.preventDefault(); if ( $( this ).hasClass( 'button-disabled' ) ) { @@ -157,11 +232,8 @@ jQuery( function ( $ ) { $('.checkforspam').addClass('button-disabled').addClass( 'checking' ); $('.checkforspam-spinner').addClass( 'spinner' ).addClass( 'is-active' ); - // Update the label on the "Check for Spam" button to use the active "Checking for Spam" language. - $( '.checkforspam .akismet-label' ).text( $( '.checkforspam' ).data( 'active-label' ) ); - akismet_check_for_spam(0, 100); - }); + }).removeClass( 'button-disabled' ); var spam_count = 0; var recheck_count = 0; @@ -176,7 +248,7 @@ jQuery( function ( $ ) { var percentage_complete = Math.round( ( recheck_count / check_for_spam_buttons.data( 'pending-comment-count' ) ) * 1000 ) / 10; // Update the progress counter on the "Check for Spam" button. - $( '.checkforspam-progress' ).text( check_for_spam_buttons.data( 'progress-label-format' ).replace( '%1$s', percentage_complete ) ); + $( '.checkforspam' ).text( check_for_spam_buttons.data( 'progress-label' ).replace( '%1$s', percentage_complete ) ); $.post( ajaxurl, @@ -269,12 +341,14 @@ jQuery( function ( $ ) { * @return string The mShot URL; */ function akismet_mshot_url( linkUrl, retry ) { - var mshotUrl = '//s0.wordpress.com/mshots/v1/' + encodeURIComponent( linkUrl ) + '?w=900'; - - if ( retry ) { + var mshotUrl = '//s0.wp.com/mshots/v1/' + encodeURIComponent( linkUrl ) + '?w=900'; + + if ( retry > 1 ) { mshotUrl += '&r=' + encodeURIComponent( retry ); } - + + mshotUrl += '&source=akismet'; + return mshotUrl; } @@ -286,17 +360,10 @@ jQuery( function ( $ ) { function akismet_preload_mshot( linkUrl ) { var img = new Image(); img.src = akismet_mshot_url( linkUrl ); + + preloadedMshotURLs.push( linkUrl ); } - /** - * Sets the comment form privacy notice display to hide when one clicks Core's dismiss button on the related admin notice. - */ - $( '#akismet-privacy-notice-admin-notice' ).on( 'click', '.notice-dismiss', function () { - $.ajax( { - url: './options-general.php?page=akismet-key-config&akismet_comment_form_privacy_notice=hide', - } ); - }); - $( '.akismet-could-be-primary' ).each( function () { var form = $( this ).closest( 'form' ); |