User:PerfektesChaos/js/versionControl/d.js

From Wikipedia, the free encyclopedia
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.
/// PerfektesChaos/js/versionControl/d.js
/// 2018-09-10 PerfektesChaos@de.wikipedia
//  Managing version identificaction by wiki revision identifier
/// Fingerprint: #0#0#
/// <nowiki>
// ResourceLoader:  compatible; dependencies: mediawiki.api
//                                            mediawiki.RegExp
//                                            mediawiki.user
//                                            mediawiki.util
/* global window:false                                                 */
/* jshint bitwise:true, curly:true, eqeqeq:true, latedef:true,
          laxbreak:true,
          nocomma:true, strict:true, undef:true, unused:true           */
( function ( mw ) {
   "use strict";
   var Signature = "versionControl",
       Version   = -5.1,
       VC        = { doc:  "[[w:en:User:PerfektesChaos/js/" + Signature
                                                                  + "]]",
                     sign: "user:PerfektesChaos/" + Signature,
                     type: Signature,
                     vsn:  Version };




   // Requires:
   //    MediaWiki 1.26wmf11
   //       mw.libs
   //       mw.loader.getState()
   //       mw.loader.state()
   //       mw.loader.using()
   //       mw.util.wikiUrlencode()
   //       mw.Api



   function fed( arrived, at, after ) {
      // Fetched JSON source after query
      // Precondition:
      //    arrived  -- result of ajax query for JSON source
      //    at       -- location of JSON source
      //                .site   domain
      //                .space  wide area
      //                .store  particular task
      //    after    -- callback function
      // Remark: May be used as event handler -- 'this' is not accessed
      // 2018-09-10 PerfektesChaos@de.wikipedia
      var page, parsed, rev, store;
      if ( typeof arrived  ===  "object"   &&
           typeof arrived.query  ===  "object" ) {
         store = arrived.query.pageids[ 0 ];
         page  = arrived.query.pages[ store ];
         rev   = page.revisions[ 0 ];
         if ( typeof rev  ===  "object"   &&
              typeof rev.slots  ===  "object"   &&
              typeof rev.slots.main  ===  "object" ) {
            try {
               parsed = JSON.parse( rev.slots.main[ "*" ] );
               if ( typeof parsed  ===  "object"
                    &&     parsed ) {
                  parsed.site  = at.site;
                  parsed.space = at.space;
                  parsed.store = at.store;
                  after( parsed );
               }
            } catch (e) {
            }
         }
      }
   }   // fed()



   function feed( at, after ) {
      // Retrieve JSON source from page
      // Precondition:
      //    at     -- object, with location of JSON source
      //              .site   domain
      //              .space  wide area
      //              .store  particular task
      //    after  -- callback function
      // Uses:
      //    >< .api
      //    >< .script
      //    mw.Api
      //    (.fed)
      // 2018-09-10 PerfektesChaos@de.wikipedia
      if ( typeof at  ===  "object"
           &&     at   &&
           typeof at.site  ===  "string"
           &&     at.site   &&
           typeof at.space  ===  "string"
           &&     at.space   &&
           typeof at.store  ===  "string"
           &&     at.store   &&
           typeof after  ===  "function" ) {
         if ( typeof VC.api  !==  "object" ) {
            VC.api = new mw.Api();
         }
         VC.api.get( { action:       "query",
                       "continue":   "",
                       indexpageids: true,
                       origin:       "https://"  +
                                       window.document.location.hostname,
                       prop:         "revisions",
                       rvprop:       "content",
                       rvslots:      "main",
                       titles:       at.space + "/" + at.store + ".json",
                       maxage:       0
                     },
                     { url:       "https://" + at.site + "/w/api.php",
                       dataType:  "json" } )
               .done( function ( arrived ) {   fed( arrived, at, after );
                                           } );
      }
   }   // feed()



   function filed () {
      // Called upon termination
      // Remark: May be used as event handler -- 'this' is not accessed
      // 2018-09-10 PerfektesChaos@de.wikipedia
   }   // .filed()



   function fill( assign, action ) {
      // Dump JSON source on page
      // Precondition:
      //    assign  -- object, with model
      //               .site       domain
      //               .space      wide area
      //               .store      particular task
      //               .revisions  Array, or not
      //    action  -- boolean, if do anything
      // Uses:
      //    >  .vsn
      //    >< .reEscape
      //    >< .api
      //    >< .token
      //    mw.Api
      //    mw.user.tokens()
      //    (.filed)
      // 2018-09-10 PerfektesChaos@de.wikipedia
      var d, e, i, n, s;
      if ( action ) {
         d = new Date();
         if ( typeof VC.reEscape  !==  "object" ) {
            VC.reEscape = new RegExp( "[\"\\|\n]+", "g" );
         }
         s =   '{ "stamp": "' + d.toISOString() + '",\n'
             + '  "site":  "'
             + assign.site.replace( VC.reEscape, "" ) + '",\n'
             + '  "space": "'
             + assign.space.replace( VC.reEscape, "" ) + '",\n'
             + '  "store": "'
             + assign.store.replace( VC.reEscape, "" ) + '"';
         if ( typeof assign.revisions  ===  "object" ) {
            s = s + ',\n  "revisions": [\n';
            n = assign.revisions.length;
            for ( i = 0;  i < n;  i++ ) {
               if ( i ) {
                  s = s + ',\n';
               }
               e = assign.revisions[ i ];
               if ( typeof e.id  !==  "number" ) {
                  e.id = 0;
               }
               if ( typeof e.stamp  !==  "string" ) {
                  e.stamp = "-";
               }
               s = s + '    { "src":   "'
                     + e.src.replace( VC.reEscape, "" ) + '",\n'
                     + '      "id":    ' + e.id + ',\n'
                     + '      "stamp": "'
                     + e.stamp.replace( VC.reEscape, "" ) + '" }';
            }   // for i
            s = s + '\n               ]';
         }
         s = s + '\n}';
         if ( typeof VC.api  !==  "object" ) {
            VC.api = new mw.Api();
         }
         if ( typeof VC.token  !==  "string" ) {
            VC.token = mw.user.tokens.get( "csrfToken" );
         }
         VC.api.post( { action:   "edit",
                        token:    VC.token,
                        title:    assign.space + "/"
                                                + assign.store + ".json",
                        text:     s,
                        summary:  "VersionControl " + VC.vsn,
                        nocreate: true },
                      { url: "https://" + assign.site + "/w/api.php" } )
               .done( filed );
      }
   }   // fill()



   function forward( arrived, assembly, after ) {
      // Page revision data arrived
      // Precondition:
      //    arrived   -- result of ajax query for
      //    assembly  -- object, with entire old information
      //    after     -- callback function
      // Uses:
      //    fill()
      // 2018-09-10 PerfektesChaos@de.wikipedia
      var e, i, j, k, l, n, p, query, s, v;
      if ( typeof arrived  ===  "object" ) {
         query = arrived.query;
      }
      if ( query ) {
         n = query.pageids.length;
         if ( n ) {
            k = assembly.start.length;
            v = assembly.revisions;
            for ( i = 0;  i < n;  i++ ) {
               s = query.pageids[ i ];
               if ( s.charCodeAt( 0 ) !== 45 ) {   // '-'
                  p = query.pages[ s ];
                  j = assembly.order[ p.title.substr( k ) ];
                  if ( typeof j  ===  "number" ) {
                     e = v[ j ];
                     if ( typeof e.id     !==  "number"   ||
                          typeof e.stamp  !==  "string"   ||
                          e.id    !== p.lastrevid   ||
                          e.stamp !== p.touched ) {
                        e.id    = p.lastrevid;
                        e.stamp = p.touched;
                        l = true;
                     }
                  }
               }
            }   // for i
            after( assembly, l );
         }
      }
   }   // forward()



   function found( assembly, after ) {
      // Retrieve single pages revision data
      // Precondition:
      //    assembly  -- object, with entire (old) information
      //    after     -- callback function
      // Uses:
      //    >< .api
      //    mw.util.wikiUrlencode()
      //    mw.Api
      //    (forward)
      // Remark: May be used as event handler -- 'this' is not accessed
      // 2018-09-10 PerfektesChaos@de.wikipedia
      var e, i, n, p, q, s, v;
      if ( typeof assembly.revisions  ===  "object"
           &&     assembly.revisions   &&
           typeof assembly.revisions.length  ===  "number" ) {
         v = assembly.revisions;
         n = v.length;
         if ( n > 1 ) {
            s = mw.util.wikiUrlencode( assembly.space ) + "/";
            assembly.start = s;
            assembly.order = { };
            for ( i = 0;  i < n;  i++ ) {
               e = v[ i ];
               if ( typeof e.src  ===  "string"
                    &&     e.src ) {
                  if ( q ) {
                     q = q + "|";
                  } else {
                     q = "";
                  }
                  p = mw.util.wikiUrlencode( e.src );
                  q = q + s + p;
                  assembly.order[ p ] = i;
               }
            }   // for i
            if ( q ) {
               if ( typeof VC.api  !==  "object" ) {
                  VC.api = new mw.Api();
               }
               VC.api.get( { prop:         "info",
                         //  inprop:       "lastrevid|touched",
                             titles:       q,
                             indexpageids: true },
                           { url: "https://" + assembly.site
                                                       + "/w/api.php" } )
                     .done( function( arrived ) {
                                     forward( arrived, assembly, after );
                                                } );
            }
         }   // entries
      }
   }   // found()



   function fresh( at ) {
      // Update page
      // Precondition:
      //    at  -- object, with location of JSON source
      //           .site   domain
      //           .space  wide area
      //           .store  particular task
      // Uses:
      //    (found)
      //    (fill)
      // Remark: May be used as event handler -- 'this' is not accessed
      // 2018-09-10 PerfektesChaos@de.wikipedia
      feed( at,
            function( assembly ) {   found( assembly, fill );   } );
   }   // fresh()



   function full() {
      // Complete initialization
      // Precondition:
      //    Modules ready
      // Uses:
      //    >  .sign
      //    >  .doc
      //    >  .type
      //    >  .vsn
      //    mw.loader.state()
      //    mw.hook()
      //    (feed)
      //    (found)
      //    (fresh)
      // Remark: May be used as event handler -- 'this' is not accessed
      // 2018-09-10 PerfektesChaos@de.wikipedia
      var rls = { };
      rls[ VC.sign ] = "ready";
      mw.loader.state( rls );
      mw.hook( VC.sign + ".ready" ).fire( { doc:  VC.doc,
                                            sign: VC.sign,
                                            type: VC.type,
                                            vsn:  VC.vsn } );
      mw.hook( VC.sign + ".retrieve" ).add( feed );
      mw.hook( VC.sign + ".revisions" ).add( found );
      mw.hook( VC.sign + ".update" ).add( fresh );
   }   // full()



   function furnish() {
      // Autorun on script load
      // Precondition:
      //    Current project is project of queries
      // Postcondition:
      //    Started analysis
      // Uses:
      //    >  .sign
      //    mw.loader.getState()
      //    mw.loader.state()
      //    mw.loader.using()
      //    (full)
      // 2018-09-10 PerfektesChaos@de.wikipedia
      var state = mw.loader.getState( VC.sign ),
          rls;
      if ( state !== "ready"  &&  state !== "loaded" ) {
         rls = { };
         rls[ VC.sign ] = "loaded";
         mw.loader.state( rls );
         mw.loader.using( [ "mediawiki.api",
                            "mediawiki.user",
                            "mediawiki.util" ],
                          full );
      }
   }   // furnish()



   furnish();
}( window.mediaWiki ) );



/// EOF </nowiki>    versionControl/d.js