MediaWiki:Gadget-importUtility/table.js

Hinweis: Leere nach dem Veröffentlichen den Browser-Cache, um die Änderungen sehen zu können.

  • Firefox/Safari: Umschalttaste drücken und gleichzeitig Aktualisieren anklicken oder entweder Strg+F5 oder Strg+R (⌘+R auf dem Mac) drücken
  • Google Chrome: Umschalttaste+Strg+R (⌘+Umschalttaste+R auf dem Mac) drücken
  • Edge: Strg+F5 drücken oder Strg drücken und gleichzeitig Aktualisieren anklicken
/// Gadget-importUtility/table.js
//  Maintain maintenance table
/// 2015-06-11 PerfektesChaos@de.wikipedia
//  ResourceLoader: compatible;
//    dependencies: mediawiki.user, mediawiki.util, mediawiki.api
//                  .batch. .cnf. .utl.
//  Namespaces:     4
//  Build:          .table
//  Documentation:  [[w:de:Wikipedia:Technik/Skin/Gadgets/importUtility]]
/// Fingerprint:    #0#0#
/// @license GPL [//www.mediawiki.org/w/COPYING] (+GFDL, LGPL, CC-BY-SA)
// <nowiki>
/*jshint bitwise:true, curly:true, eqeqeq:true, forin:false,
         latedef:true, laxbreak:true, strict:true, trailing:true,
         undef:true, unused:true, white:false                          */
/*global window:false                                                  */



( function ( mw, $ ) {
   "use strict";
   var Version    =  0.800,
       Self       =  "table",
       IUTIL      =  "importUtility",
       SIG        =  "ext.gadget." + IUTIL,
       SIGNATURE  =  SIG + "." + Self,
       TBL        =  { },
       factory, fault, feed, fetch, fiat, fill, fine, finish,
       flow, fold, folder, format, furnish;
   if ( typeof mw.libs[ IUTIL ]  !==  "object"   ||
        ! mw.libs[ IUTIL ] ) {
      mw.libs[ IUTIL ]  =  { };
   }
   mw.libs[ IUTIL ].type  =  IUTIL;
   IUTIL                  =  mw.libs[ IUTIL ];
   if ( typeof IUTIL.vsn  ===  "string" ) {
      IUTIL.vsn  =  IUTIL.vsn + " ";
   } else {
      IUTIL.vsn  =  "";
   }
   IUTIL.vsn  =  IUTIL.vsn + Self.substr( 0, 1 ) + "=" + Version;



//-----------------------------------------------------------------------



   if ( typeof IUTIL.table  !==  "object" ) {
      // Utilities for HTML form fields
      // Dependencies: mediawiki.util JSON
      IUTIL.table  =  { };



      factory  =  function ( assign, ahead ) {
         // Create marker comment
         // Precondition:
         //    assign  -- keyword
         //    ahead   -- true: "begin"   else "end"
         // Postcondition:
         //    Return comment
         // 2013-01-19 PerfektesChaos@de.wikipedia
         return  "<!--importUtility " + assign
                + ( ahead ? " begin" : " end" )
                + " -->";
      };   // factory()



      fault  =  function ( arrived ) {
         // Show API failure on maintenance page updating
         // Precondition:
         //    arrived  -- JSON info of ajax query, or false
         // Uses:
         //    .utl.fault()
         //    mw.log()
         // 2014-10-10 PerfektesChaos@de.wikipedia
         IUTIL.utl.fault( false );
         mw.log( {loud:true}, "IUTIL.table fault()", 2, arrived );
      };   // fault()



      feed  =  function ( arrived ) {
         // Retrieve one category member entry for this user
         // Precondition:
         //    arrived  -- JSON info of ajax query, or false, or null
         // Uses:
         //    >  TBL.$i
         //    >< TBL.item
         //    >< TBL.pages
         //    >< TBL.query
         //     < TBL.max
         //    jQuery().text()
         //    mw.Api()
         //    feed()
         //    fetch()
         //    (feed)
         //    (fault)
         // 2015-06-11 PerfektesChaos@de.wikipedia
         var i, p, q, s;
         if ( arrived ) {
            if ( arrived.limits ) {
               TBL.max            =  arrived.limits.revisions;
               TBL.query.rvlimit  =  TBL.max;
            }
            i  =  -1;
            p  =  TBL.pages[ TBL.item ];
            q  =  arrived.query;
            if ( q && p ) {
               if ( q.pageids ) {
                  i       =  q.pageids[ 0 ];
                  p[ 0 ]  =  i;
               }
               q  =  q.pages;
               if ( q  &&  i > 0 ) {
                  q  =  q[ i ];
                  if ( q ) {
                     q  =  q.revisions;
                     if ( q ) {
                        p[ 5 ]  =  q[ 0 ].timestamp.substr( 0, 10 );
                        i       =  q.length - 1;
                        if ( i ) {
                           p[ 4 ]  =  q[ i ].timestamp.substr( 0, 10 );
                        } else {
                           p[ 4 ]  =  "(1)";
                        }
                     } else {
                        p[ 5 ]  =  "-.-";
                     }
                  }
               }
            }
         } else if ( arrived === false ) {   // setup
            TBL.item   =  -1;
            TBL.max    =  "max";
            TBL.query  =  { action:       "query",
                            "continue":   "",
                            prop:         "revisions",
                            indexpageids: true,
                            rvlimit:      TBL.max,
                            rvprop:       "timestamp" };
         }
         TBL.item++;
         if ( TBL.item < TBL.pages.length ) {
            i  =  -9;
            TBL.$i.text( "#" + TBL.item );
            s  =  TBL.pages[ TBL.item ];
            if ( s ) {
               s  =  s.title;
               if ( s ) {
                  TBL.pages[ TBL.item ]  =
                                        [ false,   // [0] curid
                                          s,       // [1] user space path
                                          false,   // [2] log entry
                                          false,   // [3] title
                                          false,   // [4] first user edit
                                          false,   // [5] last user edit
                                          false ]; // [6] last edit
                  i                      =  s.lastIndexOf( "/" );
               }
            }
            if ( i > 0 ) {
               TBL.query.titles          =  s;
               TBL.pages[ TBL.item ][ 3 ]  =  s.substr( i + 1 );
               s                         =  s.substr( 0, i );
               i                         =  s.indexOf( ":" );
               if ( i > 0 ) {
                  TBL.query.rvuser  =  s.substr( i + 1 );
                  q                 =  new mw.Api();
                  q.get( TBL.query ).done( feed )
                                    .fail( fault );
               }
            } else {
               feed( null );
            }
         } else {
            fetch( false );
         }
      };   // feed()



      fetch  =  function ( arrived ) {
         // Retrieve logbook entries one by one
         // Precondition:
         //    arrived  -- JSON info of ajax query, or false
         // Uses:
         //    >  TBL.$n
         //    >  TBL.$i
         //    >< TBL.item
         //    >< TBL.pages
         //    >< TBL.query
         //    jQuery().text()
         //    mw.Api()
         //    fetch()
         //    flow()
         //    (fetch)
         //    (fault)
         // 2015-06-11 PerfektesChaos@de.wikipedia
         var q;
         if ( arrived ) {
            q  =  arrived.query;
            if ( q ) {
               q  =  q.logevents;
               if ( q ) {
                  if ( q.length ) {
                     TBL.pages[ TBL.item ][ 2 ]  =
                               q[ 0 ].timestamp.substr( 0, 10 )  +  "/*";
                  }
               }
            }
         } else if ( arrived === false ) {   // setup
            TBL.item   =  -1;
            TBL.query  =  { action:     "query",
                            "continue": "",
                            list:       "logevents",
                            letype:     "import",
                            lelimit:    1,
                            leprop:     "timestamp" };
            TBL.$n.text( "/" + TBL.pages.length );
         }
         TBL.item++;
         if ( TBL.item < TBL.pages.length ) {
            TBL.$i.text( "log " + TBL.item );
            q  =  TBL.pages[ TBL.item ];
            if ( q ) {
               TBL.query.letitle  =  q[ 1 ];
               q                  =  new mw.Api();
               q.get( TBL.query ).done( fetch )
                                 .fail( fault );
            } else {
               fetch( null );
            }
         } else {
            flow( false );
         }
      };   // fetch()



      fiat  =  function () {
         // Update table on maintenance page
         // Uses:
         //    >  .cnf.project.table.support
         //    >< .$msg
         //     < TBL.$i
         //     < TBL.$n
         //    mw.Api()
         //    .batch.fired()
         //    jQuery().append()
         //    jQuery().find()
         //    (fill)
         //    (fault)
         // 2015-06-11 PerfektesChaos@de.wikipedia
         var q  =  new mw.Api(),
             w  =  { action:       "query",
                     "continue":   "",
                     indexpageids: true,
                     prop:         "revisions",
                     rvlimit:      1,
                     rvprop:       "content",
                     titles:       "Project:"
                                   + IUTIL.cnf.project.table.support };
         IUTIL.batch.fired( false );
         q.get( w ).done( fill )
                   .fail( fault );
         IUTIL.$msg.append( "<span>&nbsp; &nbsp;</span>"
                            + "<span id='IUTIL-table-i' />"
                            + "<span id='IUTIL-table-n' />" );
         TBL.$i  =  IUTIL.$msg.find( "#IUTIL-table-i" );
         TBL.$n  =  IUTIL.$msg.find( "#IUTIL-table-n" );
      };   // fiat()



      fill  =  function ( arrived ) {
         // Retrieve content of maintenance page
         // Precondition:
         //    arrived  -- JSON info of ajax query
         // Uses:
         //     < TBL.story
         //    TBL.fresh()
         //    fault()
         // 2013-01-08 PerfektesChaos@de.wikipedia
         var i,
             q  =  arrived.query,
             w  =  q.pageids;
         TBL.story  =  false;
         if ( w ) {
            i  =  w[ 0 ];
         }
         if ( i ) {
            w  =  q.pages;
            if ( w ) {
               w  =  w[ i ];
               if ( w ) {
                  w  =  w.revisions;
                  if ( w ) {
                     w  =  w[ 0 ];
                     if ( w ) {
                        TBL.story  =  w[ "*" ];
                     }
                  }
               }
            }
         }
         if ( TBL.story ) {
            TBL.fresh();
         } else {
            fault();
         }
      };   // fill()



      fine  =  function () {
         // Show API success on table page updating
         // Precondition:
         //    arrived  -- JSON info of ajax query, or false
         // Uses:
         //    .batch.fine()
         // 2013-01-05 PerfektesChaos@de.wikipedia
         IUTIL.batch.fine( "PageUpdated" );
      };   // fine()



      finish  =  function ( arrived ) {
         // Retrieve last edit one by one
         // Precondition:
         //    arrived  -- JSON info of ajax query, or false
         // Uses:
         //    >  TBL.$i
         //    >< TBL.item
         //    >< TBL.pages
         //    >< TBL.query
         //    format()
         //    jQuery().text()
         //    mw.Api()
         //    (finish)
         //    (fault)
         // 2015-06-11 PerfektesChaos@de.wikipedia
         var q, s;
         if ( arrived ) {
            q  =  arrived.query;
            if ( q ) {
               q  =  q.pages;
               if ( q ) {
                  q  =  q[ TBL.pages[ TBL.item ][ 0 ] ];
                  if ( q ) {
                     q  =  q.revisions;
                     if ( q ) {
                        s  =  q[ 0 ].timestamp.substr( 0, 10 );
                        if ( s === TBL.pages[ TBL.item ][ 5 ] ) {
                           s  =  "===";
                        }
                        TBL.pages[ TBL.item ][ 6 ]  =  s;
                     }
                  }
               }
            }
         } else if ( arrived === false ) {   // setup
            TBL.item   =  -1;
            TBL.query  =  { action:     "query",
                            "continue": "",
                            prop:       "revisions",
                            rvlimit:    1,
                            rvprop:     "timestamp" };
         }
         TBL.item++;
         if ( TBL.item < TBL.pages.length ) {
            TBL.$i.text( "... " + TBL.item );
            TBL.query.pageids  =  TBL.pages[ TBL.item ][ 0 ];
            q                  =  new mw.Api();
            q.get( TBL.query ).done( finish )
                              .fail( fault );
         } else {
            format();
         }
      };   // finish()



      flow  =  function ( arrived ) {
         // Analyze revisions comments for missing log entry
         // Precondition:
         //    arrived  -- JSON info of ajax query, or false
         // Uses:
         //    >  TBL.max
         //    >  TBL.$i
         //    >< TBL.item
         //    >< TBL.reVsn
         //    >< TBL.pages
         //    >< TBL.query
         //    flow()
         //    jQuery().text()
         //    mw.Api()
         //    finish()
         //    (flow)
         //    (fault)
         // Remark: Used as event handler -- 'this' is not IUTIL.table
         // 2015-06-11 PerfektesChaos@de.wikipedia
         var e, i, j, k, n, p, q;
         if ( arrived ) {
            q  =  arrived.query;
            if ( q ) {
               q  =  q.pages;
               if ( q ) {
                  q  =  q[ TBL.pages[ TBL.item ][ 0 ] ];
                  if ( q ) {
                     q  =  q.revisions;
                     if ( q ) {
                        n  =  q.length;
                        if ( n ) {
                           e  =  q[ 0 ];
                           k  =  e.size;
                           for ( i = 1;  i < n;  i++ ) {
                              p  =  q[ i ];
                              j  =  p.size;
                              if ( k - j  ===  0 ) {
                                 if ( TBL.reVsn.test( e.comment ) ) {
                                    TBL.pages[ TBL.item ][ 2 ]  =
                                              e.timestamp.substr( 0, 10 )
                                                                 +  "/-";
                                    break;   // for i
                                 }
                              }
                              e  =  p;
                              k  =  j;
                           }   // for i
                        }
                     }
                  }
               }
            }
         } else if ( arrived === false ) {   // setup
            TBL.item       =  -1;
            TBL.query      =  { action:     "query",
                                "continue": "",
                                prop:       "revisions",
                                rvlimit:    TBL.max,
                                rvprop:     "size|comment|timestamp" };
            TBL.reVsn  =  new RegExp( "^[0-9]+ Versionen\\b" );
         }
         TBL.item++;
         if ( TBL.item < TBL.pages.length ) {
            if ( TBL.pages[ TBL.item ][ 2 ] ) {
               flow( null );
            } else {
               TBL.$i.text( "q " + TBL.item );
               TBL.query.titles  =  TBL.pages[ TBL.item ][ 1 ];
               q                 =  new mw.Api();
               q.get( TBL.query ).done( flow )
                                 .fail( fault );
            }
         } else {
            finish( false );
         }
      };   // flow()



      fold  =  function ( amount ) {
         // Integrate collected data into page
         // Precondition:
         //    amount  -- wikitable with all entries
         // Uses:
         //    this
         //    >  .type
         //    >  .vsn
         //    >  .cnf.project.table.support
         //    >  TBL.$n
         //    >  TBL.story
         //    mw.Api()
         //    folder()
         //    jQuery().text()
         //    mw.user.tokens.get()
         //    (fine)
         //    (fault)
         // 2013-01-19 PerfektesChaos@de.wikipedia
         var d  =  new Date(),
             i  =  0,
             q  =  new mw.Api(),
             w  =  { action:  "edit",
                     token:   mw.user.tokens.get( "editToken" ),
                     minor:   false,
                     summary: "Updated; " + IUTIL.type + " " + IUTIL.vsn,
                     title:   "Project:"
                              + IUTIL.cnf.project.table.support };
         folder( "TABLE", amount );
         folder( "TIMESTAMP", d.toLocaleString() );
         d  =  0;
         do {
            i  =  amount.indexOf( "\n|-",  i + 2 );
            d++;
         } while ( i > 0 );
         folder( "COUNT", d );
         TBL.$n.text( "UPDATING" );
         w.text  =  TBL.story;
         q.post( w ).done( fine )
                    .fail( fault );
      };   // fold()



      folder  =  function ( at, against ) {
         // Exchange
         // Precondition:
         //    at       --  wikitable with all entries
         //    against  --  wikitable with all entries
         // Uses:
         //    >< TBL.story
         //    factory()
         // 2013-01-19 PerfektesChaos@de.wikipedia
         var i, j, s,
             start  =  factory( at, true );
         i  =  TBL.story.indexOf( start );
         if ( i > 0 ) {
            i  +=  start.length;
            s   =  factory( at, false );
            j   =  TBL.story.indexOf( s, i );
            if ( j > 0 ) {
               TBL.story  =  TBL.story.substr( 0, i )
                             +  against
                             +  TBL.story.substr( j );
            }
         }
      };   // folder()



      format  =  function () {
         // Format collected data as wikitable
         // Precondition:
         //    arrived  -- JSON info of ajax query, or false
         // Uses:
         //    >  TBL.max
         //    >  TBL.pages
         //    >  TBL.$i
         //    >  TBL.$n
         //    jQuery().text()
         //    fold()
         // 2013-01-19 PerfektesChaos@de.wikipedia
         var d, e, i, j, u,
             p  =  TBL.pages,
             n  =  p.length,
             s  =  "";
         TBL.$i.text( "" );
         TBL.$n.text( "format" );
         for ( i = 0;  i < n;  i++ ) {
            e  =  p[ i ];
            s  =  s + "\n\n|-\n| <!--" + e[ 0 ] + "-->";   // [0] curid
            d  =  e[ 1 ];
            if ( d ) {   // [1] user space path
               j  =  d.indexOf( ":" );
               if ( j > 1 ) {
                  u  =  d.substr( j + 1 );
                  j  =  u.indexOf( "/" );
                  if ( j > 1 ) {
                     u  =  "'''"  +  u.substr( 0 , j )  +  "''' "
                           +  u.substr( j );
                  }
                  d  =  "[[" + d + "|" + u + "]]";
               }
            } else {
               d  =  "";
            }
            s  =  s + "\n" + d;
            d  =  e[ 2 ];   // [2] log entry
            s  =  s   +   "\n|"   +   ( d  ?  " " + d  :  "" );
            d  =  e[ 4 ];   // [4] first user edit
            if ( d ) {
               j  =  e[ 2 ];
               if ( j  &&  d.length === 10 ) {
                  if ( d  <  j.substr( 0, 10 ) ) {
                     d  =  "<s>" + d + "</s>";
                  }
               }
               d  =  " " + d;
            } else {
               d  =  "";
            }
            s  =  s + "\n|" + d;
            d  =  e[ 5 ];   // [5] last user edit
            s  =  s   +   "\n|"   +   ( d  ?  " " + d  :  "" );
            d  =  e[ 6 ];   // [6] last edit
            s  =  s   +   "\n|"   +   ( d  ?  " " + d  :  "" );
            d  =  e[ 3 ];
            if ( d ) {  // [3] title
               s  =  s + "\n| [[" + d + "]]";
            }
         }   // for i
         s  =  s + "\n\n|}\n";
         TBL.$n.text( "completed" );
         fold( s );
      };   // format()



      TBL.fresh  =  function ( arrived ) {
         // Retrieve list of category members
         // Precondition:
         //    arrived  -- JSON info of ajax query, or false
         // Uses:
         //    >  .cnf.project.table.source
         //    >  TBL.$n
         //    >< TBL.pages
         //    >< TBL.query
         //    >< TBL.api
         //     < TBL.pages
         //    mw.Api()
         //    jQuery().text()
         //    feed()
         //    (TBL.fresh)   -- self
         //    (fault)
         // Remark: Used as event handler -- 'this' is not TBL
         // 2015-06-11 PerfektesChaos@de.wikipedia
         if ( arrived ) {
            if ( typeof arrived.query  ===  "object" ) {
               TBL.pages  =
                       TBL.pages.concat( arrived.query.categorymembers );
               if ( typeof arrived[ "continue" ]  ===  "object" ) {
                  TBL.query[ "continue" ]  =  arrived[ "continue" ];
               } else {
                  TBL.query  =  false;
               }
            } else {
               TBL.query  =  false;
            }
         } else {   // setup
            TBL.api    =  new mw.Api();
            TBL.pages  =  [ ];
            TBL.query  =  { action:       "query",
                            "continue":   "",
                            list:         "categorymembers",
                            indexpageids: true,
                            cmlimit:      15,//      "max",
                            cmnamespace:  2,
                            cmprop:       "title|timestamp",
                            cmtitle:      "Category:"
                                           + IUTIL.cnf.projectable.source
                          };
         }
         if ( TBL.query ) {
            TBL.$n.text( "/" + TBL.pages.length );
            TBL.api.get( TBL.query ).done( TBL.fresh )
                                    .fail( fault );
         } else {
            feed( false );
         }
      };   // TBL.fresh()



      IUTIL.table.fiat  =  function () {
         // Update control has been triggered
         // Uses:
         //    mw.loader.using()
         //    (fiat)
         // 2014-10-10 PerfektesChaos@de.wikipedia
         mw.loader.using( [ "mediawiki.api",
                            "mediawiki.user",
                            "mediawiki.util" ],
                          fiat );
      };   // .table.fiat()



      furnish  =  function () {
         // Equip maintenance page with update control
         // Precondition:
         //    id="IUTIL-button-update" expected in maintenance page
         // Uses:
         //    >  mw.util.$content
         //    >  .type
         //    .utl.furnish()
         //    jQuery().find()
         //    jQuery().empty()
         //    jQuery()
         //    jQuery().attr()
         //    jQuery().text()
         //    jQuery().click()
         //    .cnf.feature()
         //    jQuery().append()
         //    (.table.fiat)
         // 2014-10-10 PerfektesChaos@de.wikipedia
         var $btn, $d;
         IUTIL.utl.furnish();
         $d  =  mw.util.$content.find( "#IUTIL-button-update" );
         if ( $d.length ) {
            $d.empty();
            $btn  =  $( "<button />" );
            $btn.attr( { id:   "IUTIL-button-update",
                         type: "button"
                       } );
            $btn.text( IUTIL.cnf.feature( "Update" ) );
            $btn.click( IUTIL.table.fiat );
            $d.append( $btn );
         }
      };   // furnish()



      IUTIL.table.fire  =  function () {
         // Initialize maintenance page
         // Precondition:
         //    Current page is maintenance page
         // Uses:
         //     < .start
         //    (furnish)
         // 2014-10-10 PerfektesChaos@de.wikipedia
         IUTIL.start  =  false;
         mw.hook( "wikipage.content" ).add( furnish );
      };   // .table.fire()
   }   // .table



//-----------------------------------------------------------------------



   function fire() {
      // Script unit has been loaded
      // Uses:
      //    >  SIGNATURE
      //    >  Self
      //    >  .start
      //    >  SIG
      //    mw.loader.state()
      //    mw.loader.getState()
      //    .utl.fire()
      // 2015-06-12 PerfektesChaos@de.wikipedia
      mw.loader.state( SIGNATURE, "ready" );
      if ( typeof IUTIL.start  ===  "string"
           &&  IUTIL.start  ===  Self
           &&  ( mw.loader.getState( SIG )  ===  "ready" )
           &&  typeof IUTIL.utl  ===  "object" ) {
         IUTIL.utl.fire();
         IUTIL[ Self ].fire();
      }
   }   // fire()



   fire();
}( window.mediaWiki, window.jQuery ) );



// Emacs
// Local Variables:
// End:

/// EOF   importUtility/table.js    </nowiki>