Jump to content

User:Unready/ui.refresh.js

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Unready (talk | contribs) at 14:50, 28 April 2015 (Version 1.1.1: Faster selector ?). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
/*
 * Description:
 * Refresh page content periodically
 *
 * Version 1.0: 27 April 2015
 *   Original version for Wikipedia use
 * Version 1.1: 28 April 2015
 *   Use jQuery
 *
 * License: CC-BY-SA
 *   http://creativecommons.org/licenses/by-sa/3.0/
 */

(( window.user = window.user || {} ).ui = window.user.ui || {} ).refresh =
( function ( $ )
{
  'use strict';

  // Based on Special:RecentChanges & Special:Watchlist
  //   div#mw-content-text
  //   div.mw-changeslist
  // #mw-content-text seems to be a universally usable option
  // div.mw-changeslist only works on changes pages
  var g_Selector = '#mw-content-text > .mw-changeslist';

  var g_self,
      g_jqContent, g_jqInput, g_jqImg,
      g_interval = 120, // default refresh interval (seconds)
      g_idTimeout = -1; // cannot run = -1; okay to run = 0; running > 0

  // init g_self before document.ready
  //   in case document.ready executes immediately
  g_self =
  {
    message : 'Initializing',
    version : 'Version 1.1.1: 28 April 2015'
  };

  // process checkbox events
  function onCheck()
  {
    if ( g_jqInput.prop( 'checked' ))
    {
      if ( g_idTimeout === 0 )
      { // start refreshing
        g_idTimeout = window.setTimeout( onTick, g_interval * 1000 );
        g_self.message = 'OK';
      }
    }
    else
    {
      if ( g_idTimeout > 0 )
      { // try to stop the next tick, although it may already be too late
        window.clearTimeout( g_idTimeout );
        g_idTimeout = 0;
        g_self.message = 'Stopped';
      }
    }
  }

  // process Ajax done event
  function onDone( htmlString )
  {
    var jqNewContent,
        i;

    // strip off body tags
    // use search, because match could be too big for replace
    i = htmlString.search( /<\s*body[^>]*>/i );
    if ( i === -1 )
    {
      g_self.message = 'onDone :: unable to find html body';
      return;
    }
    htmlString = htmlString.substr( i )
      .replace( /^<\s*body[^>]*>\s*/i, '' )
      .replace( /\s*<\s*\/html[^>]*>\s*$/i, '' )
      .replace( /\s*<\s*\/body[^>]*>\s*$/i, '' );
    // force it to parse
    jqNewContent = $( htmlString ).find( g_Selector );
    if ( jqNewContent.length !== 1 )
    {
      g_self.message = 'onDone :: ' + jqNewContent.length +
        ' elements found for ( ' + g_Selector + ' )';
      return;
    }
    // refresh content
    g_jqContent.replaceWith( jqNewContent );
    g_jqContent = jqNewContent;
    // go back to sleep
    g_jqImg.hide();
    g_idTimeout = window.setTimeout( onTick, g_interval * 1000 );
  }

  // process Ajax fail event
  function onFail( jqDummy, textStatus, errorThrown )
  {
    g_self.message = 'onFail :: ' + textStatus + ' ' + errorThrown;
  }

  // handle timer events, 
  function onTick()
  { // ignore the event if the box isn't checked
    if ( g_jqInput.prop( 'checked' ))
    {
      g_jqImg.show();
      // ajax defaults to window.location.href
      $.ajax({ dataType: 'html' })
        .done( onDone )
        .fail( onFail );
    }
  }

  $( function main()
  {
    var jqSpan,
        uriData =
        [
          'data:image/gif;base64,',
          'R0lGODlhKwALAMIAAP///wAAAIKCggAAAP///////////////yH/C05FVFNDQVBF',
          'Mi4wAwEAAAAh+QQFCgADACwAAAAAKwALAAADNDiyzPNQtRbhpHfWTCP/mgduYEl+',
          'Z8mlGauG1ii+7bzadBejeL64sIfvAtQJR7yioHJsJQAAIfkEBQoAAgAsAAAAAAsA',
          'CwAAAw0os8zaMMpJq70YPykSACH5BAUKAAEALAAAAAAbAAsAAAMtGLLM8TCMSalq',
          'WERZ+8jY5nVgI45U6URoqmps+71n+8KQPKs1evejC2jzaAUSACH5BAEKAAEALBAA',
          'AAAbAAsAAAMtGLLM8TCMSalqWERZ+8jY5nVgI45U6URoqmps+71n+8KQPKs1evej',
          'C2jzaAUSADs='
        ].join( '' ),
        htmlString =
        [
          '<span style="font-size: 40%; margin: 5px; vertical-align: middle;">',
          '<label for="ui-refresh-input" title="Enable auto-refresh"',
          ' style="border-bottom: 1px dotted;">Auto-refresh:</label>',
          '<input id="ui-refresh-input" type="checkbox"',
          ' style="vertical-align: middle;">',
          '<img src="' + uriData + '" alt="Refreshing page">',
          '</span>'
        ].join( '' );

    g_jqContent = $( g_Selector ); // div
    if ( g_jqContent.length !== 1 )
    {
      g_self.message = 'main :: ' + g_jqContent.length +
        ' elements found for ( ' + g_Selector + ' )';
      return;
    }
    // span with all the new DOM elements
    jqSpan = $( htmlString );
    // checkbox checked, with handler
    g_jqInput = jqSpan.find( 'input' )
      .prop( 'checked', true )
      .click( onCheck );
    // throbber, initially hidden
    g_jqImg = jqSpan.find( 'img' )
      .hide();
    // add span to h1
    $( '#firstHeading' ).append( jqSpan );
    // done with DOM
    g_idTimeout = window.setTimeout( onTick, g_interval * 1000 );
    g_self.message = 'OK';
  });

  return g_self;
}( jQuery ));