MediaWiki:Dialog/receive

/* This script provides functions to receive parameters passed via {{Dialog/button}}, and to register page dependencies. Any javascript page importing this page should also contain a commented link to it, for Special:WhatLinksHere/MediaWiki:Dialog/receive.

For instructions, see the talk page. */

if (! window.wikidialog) window.wikidialog = {}; if (! window.wikidialog.receiveAnonymous) (function () {

   //
   // version
   //
   function receiveVersion() { return '0.42 (2019-11-05)'; }
   //
   window.wikidialog.safeHtml = function (s) {
       return s.replace(/\</g,'<').replace(/\>/g,'>');
   };
   function getWikidialogID() {
       var s = location.search.match(/[\?&]wikidialogid=(\d+)/);
       if (s && s.length && (s.length > 1)) {
           var thisID = Number(s[1])
           if (sessionStorage) {
               var nextID = 0;
               if (sessionStorage.wikidialogNextID) { nextID = Number(sessionStorage.wikidialogNextID); }
               if (nextID <= thisID) { sessionStorage.wikidialogNextID = (thisID + 1); }
           }
           return thisID;
       }
       if (sessionStorage) {
           if (! sessionStorage.wikidialogNextID) sessionStorage.wikidialogNextID = '1';
           return (Number(sessionStorage.wikidialogNextID) - 1);
       }
       return 0;
   }
   function getData() {
       var id = getWikidialogID();
       var data = {};
       var params = sessionStorage['wikidialog:' + id + ':params'];
       if (params) {
           params = params.split(',');
           for (var k = 0; k < params.length; k++) if (params[k]) data[params[k]] = sessionStorage['wikidialog:' + id + ':in:' + params[k]];
       }
       return data;
   }
   function anchorEncode(s) {
       return encodeURIComponent( s.replace( / /g, '_' ) )
           .replace( /!/g, '%21' ).replace( /'/g, '%27' )
           .replace( /\(/g, '%28' ).replace( /\)/g, '%29' )
           .replace( /\*/g, '%2A' ).replace( /~/g, '%7E' )
           .replace( /%3A/g, ':' ).replace( /%/g, '.' );
   }
   function saveGeometries(id, tag, carry) {
       var areas = $('input.wikidialog-text, textarea.wikidialog-textarea').map(function () {
           var t = $(this);
           if (t.css('display') == 'none') return;
           return t;
       });
       if ((typeof carry) == "object") {
           areas = areas.map(function () {
               var t = $(this);
               var tid = t.attr('id');
               for (var k = 0; k < carry.length; k++)
                   if ((tid == ('wikidialog-' + carry[k])) ||
                       (tid == ('wikidialog-' + anchorEncode(carry[k])))
                      )
                       return t;
               return;
           });
       }
       areas.each(function () {
           var t = $(this);
           var name = t.attr('id').substring(11);
           sessionStorage['wikidialog:' + id + ':' + tag + ':' + name + ':scroll-top' ] = t.scrollTop();
           sessionStorage['wikidialog:' + id + ':' + tag + ':' + name + ':scroll-left'] = t.scrollLeft();
           sessionStorage['wikidialog:' + id + ':' + tag + ':' + name + ':height'     ] = t.height();
           sessionStorage['wikidialog:' + id + ':' + tag + ':' + name + ':width'      ] = t.width();
       });
   }
   function collectGeometry(id, tag, name) {
       sessionStorage.removeItem('wikidialog:' + id + ':' + tag + ':' + name + ':scroll-top');
       sessionStorage.removeItem('wikidialog:' + id + ':' + tag + ':' + name + ':scroll-left');
       sessionStorage.removeItem('wikidialog:' + id + ':' + tag + ':' + name + ':height');
       sessionStorage.removeItem('wikidialog:' + id + ':' + tag + ':' + name + ':width');
   }
   function restoreGeometries(id, tag) {
       $('input.wikidialog-text, textarea.wikidialog-textarea').each(function () {
           var t = $(this);
           if (t.css('display') == 'none') return;
           var name = t.attr('id').substring(11);
           var st = sessionStorage['wikidialog:' + id + ':' + tag + ':' + name + ':scroll-top' ];
           var sl = sessionStorage['wikidialog:' + id + ':' + tag + ':' + name + ':scroll-left'];
           var ht = sessionStorage['wikidialog:' + id + ':' + tag + ':' + name + ':height'     ];
           var wd = sessionStorage['wikidialog:' + id + ':' + tag + ':' + name + ':width'      ];
           if (st) t.scrollTop( st);
           if (sl) t.scrollLeft(sl);
           if (ht) t.height(    ht);
           if (wd) t.width(     wd);
           collectGeometry(id, tag, name);
       });
   }
   function addNote(s) {
       var id = getWikidialogID();
       var note = sessionStorage['wikidialog:' + id + ':notes'];
       s = 'Dialog note: ' + window.wikidialog.safeHtml(s) + '
'; sessionStorage['wikidialog:' + id + ':notes'] = (note ? (note + s) : s); } function clearNotes() { var id = getWikidialogID(); sessionStorage.removeItem('wikidialog:' + id + ':notes'); sessionStorage.removeItem('wikidialog:' + id + ':keep-notes'); } function getNotes() { return sessionStorage['wikidialog:' + getWikidialogID() + ':notes']; } function releaseSavedFieldValues(sfx, id) { if (! sfx) sfx = ; // precaution if (! id) id = getWikidialogID(); // default var ls = sessionStorage['wikidialog:' + id + ':saves' + sfx]; if (! ls) ls = ; // precaution ls = ls.split(','); var k; for (k = ls.length - 1; k>=0; k--) { sessionStorage.removeItem('wikidialog:' + id + ':sv' + sfx + ':' + ls[k]); collectGeometry(id, ('sv' + sfx), ls[k]); } sessionStorage.removeItem('wikidialog:' + id + ':saves' + sfx); } function activateSavedFieldValues(sfx, id) { if (! sfx) return; if (! id) id = getWikidialogID(); // default releaseSavedFieldValues(, id); var ls = sessionStorage['wikidialog:' + id + ':saves' + sfx]; if (! ls) ls = ; // precaution ls = ls.split(','); for (var k = ls.length - 1; k>=0; k--) { sessionStorage[ 'wikidialog:' + id + ':sv:' + ls[k]] = sessionStorage[ 'wikidialog:' + id + ':sv' + sfx + ':' + ls[k]]; sessionStorage[ 'wikidialog:' + id + ':sv:' + ls[k].substring(11) + ':scroll-top'] = sessionStorage[ 'wikidialog:' + id + ':sv' + sfx + ':' + ls[k].substring(11) + ':scroll-top']; sessionStorage[ 'wikidialog:' + id + ':sv:' + ls[k].substring(11) + ':scroll-left'] = sessionStorage[ 'wikidialog:' + id + ':sv' + sfx + ':' + ls[k].substring(11) + ':scroll-left']; sessionStorage[ 'wikidialog:' + id + ':sv:' + ls[k].substring(11) + ':height'] = sessionStorage[ 'wikidialog:' + id + ':sv' + sfx + ':' + ls[k].substring(11) + ':height']; sessionStorage[ 'wikidialog:' + id + ':sv:' + ls[k].substring(11) + ':width'] = sessionStorage[ 'wikidialog:' + id + ':sv' + sfx + ':' + ls[k].substring(11) + ':width']; // don't remove yet; hopefully no field is listed more than once, // but if it is we don't want that to cause misbehavior here } for (var k = ls.length - 1; k>=0; k--) { sessionStorage.removeItem('wikidialog:' + id + ':sv' + sfx + ':' + ls[k]); collectGeometry(id, ('sv' + sfx), ls[k]); } sessionStorage['wikidialog:' + id + ':saves'] = sessionStorage['wikidialog:' + id + ':saves' + sfx]; sessionStorage.removeItem('wikidialog:' + id + ':saves' + sfx); } function saveFieldValues(id, sfx) { if (! sfx) sfx = ; // precaution var s = ; var n = 64; // SINGLE POINT TO ADJUST max number of fields to save $('input.wikidialog-text, textarea.wikidialog-textarea, select.wikidialog-select').each(function () { var t = $(this); if (t.css('display') == 'none') return; n--; if (n <= 0) return; var tname = t.attr('id'); var tvalue = t.val(); sessionStorage['wikidialog:' + id + ':sv' + sfx + ':' + tname] = tvalue; if (s) s += ','; s += tname; }); saveGeometries(id, ('sv' + sfx)); $('input.wikidialog-checkbox').each(function () { n--; if (n <= 0) return; var t = $(this); var tname = t.attr('id'); var tchecked = (t[0].checked ? 'yes' : ); sessionStorage['wikidialog:' + id + ':sv' + sfx + ':' + tname] = tchecked; if (s) s += ','; s += tname; }); sessionStorage['wikidialog:' + id + ':saves' + sfx] = s; } function restoreSavedFieldValues() { var id = getWikidialogID(); var ls = sessionStorage['wikidialog:' + id + ':saves']; if (! ls) ls = ; // precaution; ls = ls.split(','); $('input.wikidialog-text, textarea.wikidialog-textarea').each(function () { var n = $(this); var ni = n.attr('id'); var k; for (k = ls.length - 1; k>=0; k--) if (ls[k] == ni) { var sv = sessionStorage['wikidialog:' + id + ':sv:' + ni]; if (! sv) sv = ; // precaution n.val(sv); break; } }); restoreGeometries(id, 'sv'); $('input.wikidialog-checkbox').each(function () { var n = $(this); var ni = n.attr('id'); var k; for (k = ls.length - 1; k>=0; k--) if (ls[k] == ni) { var sv = sessionStorage['wikidialog:' + id + ':sv:' + ni]; if (sv) n.attr('checked','yes'); else n.removeAttr('checked'); break; } }); $('select.wikidialog-select').each(function () { var n = $(this); var ni = n.attr('id'); for (k = ls.length - 1; k>=0; k--) if (ls[k] == ni) { var sv = sessionStorage['wikidialog:' + id + ':sv:' + ni]; var k; for (var j=0; j<this.length; j++) if (this[j].value == sv) { this.selectedIndex = j; break; } break; } }); } function clearRollbackDelegating() { var id = getWikidialogID(); if (sessionStorage['wikidialog:' + id + ':rb-available']) { sessionStorage.removeItem('wikidialog:' + id + ':rb-available'); // sessionStorage.removeItem('wikidialog:' + id + ':rb-incoming'); sessionStorage.removeItem('wikidialog:' + id + ':rb-unauth'); sessionStorage.removeItem('wikidialog:' + id + ':rb-origin'); sessionStorage.removeItem('wikidialog:' + id + ':rb-proxy'); // sessionStorage.removeItem('wikidialog:' + id + ':rb-added'); // ls = sessionStorage['wikidialog:' + id + ':rb-changed']; if (! ls) ls = ; // precaution; ls = ls.split(','); for (k = ls.length - 1; k>=0; k--) sessionStorage.removeItem('wikidialog:' + id + ':rb-in:' + ls[k]); sessionStorage.removeItem('wikidialog:' + id + ':rb-changed'); // releaseSavedFieldValues('-rb', id); } } function clearRollbackSimple() { var id = getWikidialogID(); if (sessionStorage['wikidialog:' + id + ':prevurl']) { sessionStorage.removeItem('wikidialog:' + id + ':prevurl'); clearRollbackDelegating(); } } function getStableUrl(unforced) { var currentUrl = (location.pathname + location.search); if (unforced) { return currentUrl; } else { var newUrl = mw.util.getUrl(mw.config.get('wgPageName')) + '?wikidialogid=' + getWikidialogID(); if (newUrl == currentUrl) { newUrl += '&x=x'; } return newUrl; } } function stashUnstableUrl() { // // if we're here, and there's no id in the url, by definition it's unstable // var s = location.search.match(/[\?&]wikidialogid=(\d+)/); if (s && s.length && (s.length > 1)) { sessionStorage.removeItem('wikidialogUnstableUrl'); } else { sessionStorage.wikidialogUnstableUrl = location.href; } } function delegateVerified(data, metaproc, shortcut, shortcutParam) { var olddata = getData(); var id = getWikidialogID(); if (data) for (var p in data) { sessionStorage['wikidialog:' + id + ':in:' + p] = data[p]; var params = sessionStorage['wikidialog:' + id + ':params']; if (! params) params = ; // robust against undefined, which may arise during query-url conversion if (! (p in olddata)) sessionStorage['wikidialog:' + id + ':params'] = params + ',' + p + ','; } var carry = ; if (metaproc) { var metadata = metaproc({ unauth: sessionStorage['wikidialog:' + id + ':unauth'], origin: sessionStorage['wikidialog:' + id + ':origin'], proxy: sessionStorage['wikidialog:' + id + ':proxy'] }); sessionStorage['wikidialog:' + id + ':unauth'] = ((('unauth' in metadata) && metadata.unauth) ? metadata.unauth : ); sessionStorage['wikidialog:' + id + ':origin'] = ((('origin' in metadata) && metadata.origin) ? metadata.origin : ); sessionStorage['wikidialog:' + id + ':proxy' ] = ((('proxy' in metadata) && metadata.proxy ) ? metadata.proxy  : ); carry = ((('carry' in metadata) && metadata.carry ) ? metadata.carry  : ); } sessionStorage['wikidialog:' + id + ':incoming'] = getStableUrl(shortcut); if (sessionStorage['wikidialog:' + id + ':keep-notes']) { sessionStorage.removeItem('wikidialog:' + id + ':keep-notes'); } else { clearNotes(); } saveGeometries(id, 'in', carry); if (shortcut) shortcut(shortcutParam); else location = getStableUrl(shortcut); } function authenticIncoming() { var id = getWikidialogID(); var origin = sessionStorage['wikidialog:' + id + ':origin']; if (! origin) origin = ; // precaution else origin = mw.util.getUrl(origin); var proxy = sessionStorage['wikidialog:' + id + ':proxy']; if (! proxy) proxy = ; // precaution else proxy = mw.util.getUrl(proxy); var someFound = false; var noneFailed = true; $('span.wikidialog-origin').each(function () { // Template:Dialog/require origin someFound = true; var s = $(this).text(); s = s.split('&'); if (s.length == 1) return; // Template:Dialog/null requirement if (origin) { if (s[1]) s[1] = mw.util.getUrl(s[1]); for (var k = 2; (k < s.length); k++) s[k] = mw.util.getUrl(s[k]); if (s[1] == proxy) for (var k = 2; (k < s.length); k++) if (s[k] == origin) return; } noneFailed = false; return false; }); if (! someFound) { addNote('No outgoing authentication because no requirement clause was found.'); } else if (! noneFailed) { addNote('No outgoing authentication because a requirement clause failed.'); } return (someFound && noneFailed); } function registerAuthentication(origin, callback) { var proxy = ; if (! origin) origin = mw.config.get('wgPageName'); else if ((typeof origin) == 'function') { callback = origin; origin = mw.config.get('wgPageName'); } else proxy = mw.config.get('wgPageName'); $('span.wikidialog-button, input.wikidialog-button, button.wikidialog-button').each(function () { var button = $(this); var wikidialogButtonData = button.data(); if ('wikidialogButtonData' in wikidialogButtonData) wikidialogButtonData = wikidialogButtonData.wikidialogButtonData; else wikidialogButtonData = {}; wikidialogButtonData.origin = origin; if (proxy) wikidialogButtonData.proxy = proxy; button.data('wikidialogButtonData',wikidialogButtonData); }); if (callback) callback(); } function registerUnauthenticated(requesting) { $('span.wikidialog-button, input.wikidialog-button, button.wikidialog-button').each(function () { var button = $(this); var wikidialogButtonData = button.data(); if ('wikidialogButtonData' in wikidialogButtonData) wikidialogButtonData = wikidialogButtonData.wikidialogButtonData; else wikidialogButtonData = {}; wikidialogButtonData.unauth = requesting; button.data('wikidialogButtonData',wikidialogButtonData); }); } function maybeCollect(activeList, stack) { function isActive(id) { for (var k = activeList.length - 1; k>=0; k-- ) if (activeList[k] == id) return true; for (var k = stack.length - 2; k>=0; k -= 2) if (stack[k] == id) return true; return false; } for (var id = Number(sessionStorage.wikidialogNextID) - 1; id>=0; id--) if (! isActive(id)) { sessionStorage.removeItem('wikidialog:' + id + ':incoming'); sessionStorage.removeItem('wikidialog:' + id + ':unauth'); sessionStorage.removeItem('wikidialog:' + id + ':origin'); sessionStorage.removeItem('wikidialog:' + id + ':proxy'); sessionStorage.removeItem('wikidialog:' + id + ':newparams'); var ls = sessionStorage['wikidialog:' + id + ':params']; if (! ls) ls = ; // precaution; ls = ls.split(','); for (var k = ls.length - 1; k>=0; k--) { sessionStorage.removeItem('wikidialog:' + id + ':in:' + ls[k]); collectGeometry(id,'in',ls[k]); } sessionStorage.removeItem('wikidialog:' + id + ':params'); } } var maxIDsKept = 4; // SINGLE POINT TO ADJUST number of active IDs kept function updateActiveList() { var id = getWikidialogID(); var a = sessionStorage.wikidialogActiveList; if (! a) { // rather than use specialized code here, drop into the general case a = ( + id); } a = a.split(','); var s = sessionStorage.wikidialogStack; if (! s) s = ; // precaution s = s.split('&'); var k; for (k=0; k<a.length; k++) if (a[k] == id) { for (; k>0; k--) a[k] = a[k - 1]; a[0] = id; sessionStorage.wikidialogActiveList = a.join(','); maybeCollect(a, s); return; } if (a.length < maxIDsKept) { sessionStorage.wikidialogActiveList = id + ',' + a.join(','); a[a.length] = id; maybeCollect(a, s); return; } for (k = a.length - 1; k>0; k--) a[k] = a[k-1]; a[0] = id; sessionStorage.wikidialogActiveList = a.join(','); maybeCollect(a, s); } function canRollbackSimple() { var prevurl = sessionStorage['wikidialog:' + getWikidialogID() + ':prevurl']; if (! prevurl) return false; clearRollbackDelegating(); var s = prevurl.match(/[\?&]wikidialogid=(\d+)/); if (s && s.length && (s.length > 0)) { // safe because contains an id return true; } s = prevurl.match(/[\?&]wikidialogrolledback=/); if (s && s.length && (s.length > 0)) { // hopefully safe because active predecessor, if any, is warned return true; } // no grounds to claim safety (this shouldn't happen) return false; } function canRollbackDelegating() { var id = getWikidialogID(); if (sessionStorage['wikidialog:' + id + ':prevurl']) { clearRollbackDelegating(); return false; } else if (sessionStorage['wikidialog:' + id + ':rb-available']) { return true; } else { return false; } } window.wikidialog.addNote = addNote; window.wikidialog.clearNotes = clearNotes; window.wikidialog.getNotes = getNotes; window.wikidialog.keepNotes = function () { // impending non-manual delegation sessionStorage['wikidialog:' + getWikidialogID() + ':keep-notes'] = 'x'; } window.wikidialog.canRollback = function () { return (canRollbackSimple() || canRollbackDelegating()); } window.wikidialog.rollback = function (shortcut, shortcutParam) { window.wikidialog.noSequence(); // if we get here at all, don't sequence var id = getWikidialogID(); var prevurl = sessionStorage['wikidialog:' + id + ':prevurl']; if (prevurl) { clearRollbackDelegating(); clearRollbackSimple(); delete window.wikidialog; // precautionary rescript location = prevurl; return true; } if (! sessionStorage['wikidialog:' + id + ':rb-available']) { return false; // not delegating-rollback either } // // incoming; last chance to bail // var d = sessionStorage['wikidialog:' + id + ':rb-incoming']; if (! d) { // bailing; something's very wrong clearRollbackDelegating(); return false; } sessionStorage['wikidialog:' + id + ':incoming'] = d; // // unauth // d = sessionStorage['wikidialog:' + id + ':rb-unauth']; if (! d) { sessionStorage.removeItem('wikidialog:' + id + ':unauth'); } else { sessionStorage[ 'wikidialog:' + id + ':unauth'] = d; } // // origin // d = sessionStorage['wikidialog:' + id + ':rb-origin']; if (! d) { sessionStorage.removeItem('wikidialog:' + id + ':origin'); } else { sessionStorage[ 'wikidialog:' + id + ':origin'] = d; } // // proxy // d = sessionStorage['wikidialog:' + id + ':rb-proxy']; if (! d) { sessionStorage.removeItem('wikidialog:' + id + ':proxy'); } else { sessionStorage[ 'wikidialog:' + id + ':proxy'] = d; } // // added // var ls = sessionStorage['wikidialog:' + id + ':rb-added']; if (! ls) ls = ; // precaution ls = ls.split(','); d = getData(); var k; for (k = ls.length - 1; k>=0; k--) { sessionStorage.removeItem('wikidialog:' + id + ':in:' + ls[k]); delete d[ls[k]]; } var s = ; for (var p in d) { if (s) { s += ','; } s += p; } sessionStorage['wikidialog:' + id + ':params'] = s; // // changed // var ls = sessionStorage['wikidialog:' + id + ':rb-changed']; if (! ls) ls = ; // precaution ls = ls.split(','); var k; for (k = ls.length - 1; k>=0; k--) sessionStorage['wikidialog:' + id + ':in:' + ls[k]] = sessionStorage['wikidialog:' + id + ':rb-in:' + ls[k]]; // // saved // activateSavedFieldValues('-rb', id); // // one use only // clearRollbackDelegating(); // // nothing is new anymore // sessionStorage['wikidialog:' + id + ':newparams'] = '&'; // // let it fly // if (shortcut) { // check not removed, though shortcut now considered required shortcut(shortcutParam); } else { $(window).unbind('unload.wikidialog'); // would erase activated sessionStorage['wikidialog:' + id + ':incoming'] = getStableUrl(); delete window.wikidialog; // precautionary rescript location = getStableUrl(); } return true; } window.wikidialog.pushPrevious = function () { // // is there a prevurl? // var id = getWikidialogID(); var prevurl = sessionStorage['wikidialog:' + id + ':prevurl']; if (! prevurl) { return 'no previous url to push'; } clearRollbackDelegating(); // // is prevurl missing an id? // var previd = prevurl.match(/[\?&]wikidialogid=(\d+)/); if (previd && previd.length && (previd.length > 1)) { previd = previd[1]; } else { return 'no id in previous url'; } // // is the stack already full? // var stack = sessionStorage.wikidialogStack; stack = (stack ? stack.split('&') : []); if (stack.length >= maxIDsKept) { return 'stack already full'; } // // add to the stack // stack[stack.length] = previd; stack[stack.length] = prevurl; stack = stack.join('&'); sessionStorage.wikidialogStack = stack; } window.wikidialog.popUrl = function () { var stack = sessionStorage.wikidialogStack; stack = (stack ? stack.split('&') : []); if (stack.length <= 0) return false; window.wikidialog.noSequence(); // wary diving into unknown situation var prevurl = stack.pop(); stack.pop(); if (stack.length == 0) { sessionStorage.removeItem('wikidialogStack'); } else { sessionStorage.wikidialogStack = stack.join('&'); } clearRollbackDelegating(); clearRollbackSimple(); location = prevurl; return true; } window.wikidialog.validIncoming = function() { if (! sessionStorage) return false; var incoming = sessionStorage['wikidialog:' + getWikidialogID() + ':incoming']; if (! incoming) return false; if (incoming == (location.pathname + location.search)) return true; sessionStorage.wikidialogNextID++; return false; } window.wikidialog.receiveAnonymous = function (callback) { if (! window.wikidialog.validIncoming()) return; var id = getWikidialogID(); var args = [{origin: sessionStorage['wikidialog:' + id + ':origin'], proxy: sessionStorage['wikidialog:' + id + ':proxy']}]; for (var k = 1; k < arguments.length; k++) args.push(arguments[k]); callback.apply(getData(), args); } window.wikidialog.pageQuery = function (pageName, fields, callback) { // // fetch subject page info // at need: error // on request: exists, name, content, timestamp, // protected, flagged, categories // var data = { format: 'json', action: 'query', prop: 'revisions', rvprop: 'timestamp', rvlimit: 1, titles: pageName }; if ('flagged' in fields) data.prop += '|flagged'; if ('categories' in fields) data.prop += '|categories'; if ('content' in fields) data.rvprop += '|content'; if ('protected' in fields) { data.prop += '|info'; data.inprop = 'protection'; } $.getJSON( mw.util.wikiScript('api'), data ).done(function(data) { if (! (data.query && data.query.pages)) fields.error = 'page query misfired'; else for (var p in data.query.pages) { if ('invalid' in data.query.pages[p]){ fields.error = 'page name invalid'; } else if ('missing' in data.query.pages[p]) { if ('exists' in fields) fields.exists = false; else fields.error = 'page not found'; } else { if ('exists' in fields) fields.exists = true; if ('name' in fields) { if (data.query.pages[p].title) fields.name = data.query.pages[p].title; // normalize else fields.error = 'page query misfired'; } if ('content' in fields) { if (data.query.pages[p].revisions && data.query.pages[p].revisions[0] && data.query.pages[p].revisions[0]['*'] ) fields.content = data.query.pages[p].revisions[0]['*']; else fields.error = 'page query misfired'; } if ('timestamp' in fields) { if (data.query.pages[p].revisions && data.query.pages[p].revisions[0] && data.query.pages[p].revisions[0].timestamp ) fields.timestamp = data.query.pages[p].revisions[0].timestamp; else fields.error = 'page query misfired'; } if ('protected' in fields) { if ('protection' in data.query.pages[p]) { if (data.query.pages[p].protection[0] && data.query.pages[p].protection[1]) { if (('level' in data.query.pages[p].protection[0]) && ('level' in data.query.pages[p].protection[1]) ) fields.protected = ((data.query.pages[p].protection[0].level == 'sysop') && (data.query.pages[p].protection[1].level == 'sysop')); else fields.error = 'page query misfired'; } else fields.protected = false; } else fields.error = 'page query misfired'; } if ('flagged' in fields) { if ('flagged' in data.query.pages[p]) { if ('pending_since' in data.query.pages[p].flagged) fields.flagged = 'pending'; else fields.flagged = 'current'; } else fields.flagged = 'never'; } if ('categories' in fields) { fields.categories = ; if (data.query.pages[p].categories) for (var j = (data.query.pages[p].categories.length - 1); j >= 0; j--) if (data.query.pages[p].categories[j].title) fields.categories += '"' + data.query.pages[p].categories[j].title + '" '; else fields.error = 'page query misfired'; } } } callback(fields); }).fail(function () { fields.error = 'page query misfired'; callback(fields); }); } window.wikidialog.checkProtected = function (remotePageName, callbackDone, callbackFail) { window.wikidialog.pageQuery(remotePageName, { protected: }, function (data) { if ('error' in data) callbackFail(data.error + ': ' + window.wikidialog.safeHtml(remotePageName)); else if (data.protected) callbackDone(); else callbackFail('page unsecured: ' + window.wikidialog.safeHtml(remotePageName)); }); } window.wikidialog.pageHistory = function (pageName, fields, callback) { // // fetch subject page info // revid, timestamp, user, minor, size, comment // var data = { format: 'json', action: 'query', prop: 'revisions', rvprop: 'ids|timestamp|user|flags|size|comment', rvlimit: 50, titles: pageName }; if (('continue' in fields) && fields['continue']) { data.rvcontinue = fields.continue; delete fields.continue; } if ('direction' in fields) { data.rvdir = fields.direction; delete fields.direction; } $.getJSON( mw.util.wikiScript('api'), data ).done(function(data) { if (! (data.query && data.query.pages)) fields.error = 'page query misfired'; else for (var p in data.query.pages) { if ('invalid' in data.query.pages[p]){ fields.error = 'page name invalid'; } else if ('missing' in data.query.pages[p]) { fields.error = 'page not found'; } else if (data.query.pages[p].revisions && data.query.pages[p].revisions[0]) { if (('continue' in data) && ('rvcontinue' in data.continue)) { fields.continue = data.continue.rvcontinue; } fields['revid'] = ; fields['timestamp'] = ; fields['user'] = ; fields['minor'] = ; fields['size'] = ; fields['comment'] = ; for (var k=(data.query.pages[p].revisions.length - 1); k >= 0; k--) { if (! data.query.pages[p].revisions[k]) continue; if (fields['revid']) { fields['revid'] = '&' + fields['revid']; fields['timestamp'] = '&' + fields['timestamp']; fields['user'] = '&' + fields['user']; fields['minor'] = '&' + fields['minor']; fields['size'] = '&' + fields['size']; fields['comment'] = '&' + fields['comment']; } else { fields['revid'] = ; fields['timestamp'] = ; fields['user'] = ; fields['minor'] = ; fields['size'] = ; fields['comment'] = ; } if ( 'revid' in data.query.pages[p].revisions[k]) { fields['revid'] = data.query.pages[p].revisions[k].revid + fields['revid']; } if ( 'timestamp' in data.query.pages[p].revisions[k]) { fields['timestamp'] = data.query.pages[p].revisions[k].timestamp + fields['timestamp']; } if ( 'user' in data.query.pages[p].revisions[k]) { fields['user'] = data.query.pages[p].revisions[k].user + fields['user']; } if ( 'minor' in data.query.pages[p].revisions[k]) { fields['minor'] = 'm' + fields['minor']; } if ( 'size' in data.query.pages[p].revisions[k]) { fields['size'] = data.query.pages[p].revisions[k].size + fields['size']; } if ( 'comment' in data.query.pages[p].revisions[k]) { fields['comment'] = data.query.pages[p].revisions[k].comment + fields['comment']; } } } else { fields.error = 'page query misfired'; } } callback(fields); }).fail(function () { fields.error = 'page query misfired'; callback(fields); }); } window.wikidialog.categoryMembers = function (pageName, fields, callback) { // // fetch category members info // title, type, timestamp // var data = { format: 'json', action: 'query', list: 'categorymembers', cmtitle: pageName, cmprop: 'title|type|timestamp', cmlimit: 50, }; if (('continue' in fields) && fields['continue']) { data.cmcontinue = fields.continue; delete fields.continue; } if ('direction' in fields) { data.cmdir = fields.direction; delete fields.direction; } if ('type' in fields) { data.cmtype = fields.type; delete fields.type; } if ('sort' in fields) { data.cmsort = fields.sort; delete fields.sort; } $.getJSON( mw.util.wikiScript('api'), data ).done(function(data) { if (data.error && data.error.code) { if (data.error.code == 'cminvalidcategory') fields.error = 'invalid category title'; else if (data.error.code == 'cmbadcontinue') fields.error = 'invalid category-members continue value'; else fields.error = 'category members query misfired'; addNote('Category members query result error code: ' + data.error.code); } else if (! (data.query && data.query.categorymembers)) { fields.error = 'category members query misfired'; addNote('Category members query result has no categorymembers element.'); } else { if (('continue' in data) && ('cmcontinue' in data.continue)) { fields.continue = data.continue.cmcontinue; } fields['title'] = ; fields['type'] = ; fields['timestamp'] = ; for (var k=(data.query.categorymembers.length - 1); k >= 0; k--) { if (! data.query.categorymembers[k]) continue; if (fields['title']) { fields['title'] = '&' + fields['title']; fields['type'] = '&' + fields['type']; fields['timestamp'] = '&' + fields['timestamp']; } else { fields['title'] = ; fields['type'] = ; fields['timestamp'] = ; } if ( 'title' in data.query.categorymembers[k]) { fields['title'] = data.query.categorymembers[k].title + fields['title']; } if ( 'type' in data.query.categorymembers[k]) { fields['type'] = data.query.categorymembers[k].type + fields['type']; } if ( 'timestamp' in data.query.categorymembers[k]) { fields['timestamp'] = data.query.categorymembers[k].timestamp + fields['timestamp']; } } } callback(fields); }).fail(function () { fields.error = 'category members query misfired'; addNote('Category members query API call failed.'); callback(fields); }); } window.wikidialog.commit = function () { clearRollbackSimple(); clearRollbackDelegating(); } window.wikidialog.proxy = function (remotePageName, remoteProtected, callbackDone, callbackFail) { stashUnstableUrl(); if ((typeof remoteProtected) != "boolean") { callbackFail = callbackDone; callbackDone = remoteProtected; remoteProtected = false; } if (! authenticIncoming()) { registerUnauthenticated(remotePageName); if (callbackFail) callbackFail('incoming action-request not authenticated'); return false; } if (remoteProtected) { registerAuthentication(remotePageName, callbackDone); } else { registerUnauthenticated(remotePageName); addNote('No outgoing authentication because remote page is not protected.'); if (callbackFail) callbackFail('remote page not authenticated\n ' + window.wikidialog.safeHtml(remotePageName)); } } window.wikidialog.purelySelfContained = function (callbackDone, callbackFail) { stashUnstableUrl(); if (! authenticIncoming()) { if (callbackFail) callbackFail('incoming action-request not authenticated'); return false; } registerAuthentication(callbackDone); } window.wikidialog.recover = function () { // // reinstate carried-over field geometries // restoreGeometries(getWikidialogID(), 'in'); // // reinstate saved field values // restoreSavedFieldValues(); releaseSavedFieldValues(); // // cache expiry // updateActiveList(); // // register event handler for unload // var id = getWikidialogID(); function handleUnload() { // // expect to leave this id and maybe come back later // (not suitable for use on forced-reload delegating-rollback) // saveFieldValues(id); if (sessionStorage.wikidialogNextID) { var s = location.search.match(/[\?&]wikidialogid=(\d+)/); if (s && s.length && (s.length > 1)) {} else sessionStorage.wikidialogNextID++; // avoid accidental revisit } else { sessionStorage.wikidialogNextID = (getWikidialogID() + 2); } } $(window).unbind('unload.wikidialog'); $(window).one('unload.wikidialog', handleUnload); } function delegateToInternal(withRollback, params, metaproc, shortcut, shortcutParam) { $('input.wikidialog-button, button.wikidialog-button').attr('disabled',true); if (withRollback) { window.wikidialog.commit(); // disable any pre-existing rollback // set up rollback-delegating data var id = getWikidialogID(); sessionStorage['wikidialog:' + id + ':rb-available'] = 'x'; sessionStorage['wikidialog:' + id + ':rb-incoming'] = sessionStorage['wikidialog:' + id + ':incoming']; if (sessionStorage['wikidialog:' + id + ':unauth']) { sessionStorage['wikidialog:' + id + ':rb-unauth'] = sessionStorage['wikidialog:' + id + ':unauth']; } if (sessionStorage['wikidialog:' + id + ':origin']) { sessionStorage['wikidialog:' + id + ':rb-origin'] = sessionStorage['wikidialog:' + id + ':origin']; } if (sessionStorage['wikidialog:' + id + ':proxy']) { sessionStorage['wikidialog:' + id + ':rb-proxy'] = sessionStorage['wikidialog:' + id + ':proxy']; } saveFieldValues(id, '-rb'); var storedParams = sessionStorage['wikidialog:' + id + ':params']; storedParams = (storedParams ? storedParams.split(',') : []); var added = ; // parameters that didn't exist previously var changed = ; // parameters that did exist previously var k; for (var p in params) { for (k=0; true; k++) { if (k >= storedParams.length) { added += (added ? (',' + p) : p); break; } else if (p == storedParams[k]) { changed += (changed ? (',' + p) : p); sessionStorage[ 'wikidialog:' + id + ':rb-in:' + p] = sessionStorage['wikidialog:' + id + ':in:' + p]; break; } } } sessionStorage['wikidialog:' + id + ':rb-added' ] = added; sessionStorage['wikidialog:' + id + ':rb-changed'] = changed; } else if (canRollbackSimple()) { clearRollbackSimple(); // delegating rollback already cleared } else if (canRollbackDelegating()) { // augment rollback data var id = getWikidialogID(); var storedParams = sessionStorage['wikidialog:' + id + ':params']; storedParams = (storedParams ? storedParams.split(',') : []); var added = sessionStorage['wikidialog:' + id + ':rb-added']; var changed = sessionStorage['wikidialog:' + id + ':rb-changed']; changed = changed.split(','); var k, j; for (var p in params) { for (k=0; true; k++) { if (k >= storedParams.length) { added += (added ? (',' + p) : p); break; } else if (p == storedParams[k]) { for (j=0; true; j++) { if (j >= changed.length) { changed[changed.length] = p; sessionStorage[ 'wikidialog:' + id + ':rb-in:' + p] = sessionStorage['wikidialog:' + id + ':in:' + p]; break; } else if (p == changed[j]) { // value for rollback already stored break; } } break; } } } sessionStorage['wikidialog:' + id + ':rb-added'] = added; sessionStorage['wikidialog:' + id + ':rb-changed'] = changed.join(','); } delegateVerified(params, metaproc, shortcut, shortcutParam); } window.wikidialog.delegateTo = function (shortcut, params, metaproc, shortcutParam) { // clear newparams sessionStorage['wikidialog:' + getWikidialogID() + ':newparams'] = '&'; delegateToInternal(false, params, metaproc, shortcut, shortcutParam); } window.wikidialog.delegateToPreservingNewparams = function (shortcut, params, metaproc, shortcutParam) { // leave newparams alone delegateToInternal(false, params, metaproc, shortcut, shortcutParam); } window.wikidialog.delegateToSettingNewparams = function (shortcut, params, metaproc, shortcutParam) { var id = getWikidialogID(); var x = '&'; for (var p in params) { x += p + '&'; } sessionStorage['wikidialog:' + id + ':newparams'] = x; delegateToInternal(false, params, metaproc, shortcut, shortcutParam); } window.wikidialog.delegateToWithRollback = function (shortcut, params, metaproc, shortcutParam) { var id = getWikidialogID(); var x = '&'; for (var p in params) { x += p + '&'; } sessionStorage['wikidialog:' + id + ':newparams'] = x; delegateToInternal(true, params, metaproc, shortcut, shortcutParam); } window.wikidialog.startSequence = function () { sessionStorage.wikidialogSequenceBound = 10; // POINT TO ADJUST max action-sequence length // also occurs in gadget sessionStorage.removeItem('wikidialogSequenceOngoing'); // precaution, should be unnecessary } window.wikidialog.stepSequence = function () { if (sessionStorage.wikidialogSequenceBound) { var n = Number(sessionStorage.wikidialogSequenceBound); if (n > 0) { sessionStorage.wikidialogSequenceBound = (n - 1); } if (n > 1) { sessionStorage.wikidialogSequenceOngoing = 'x'; } else { sessionStorage.removeItem('wikidialogSequenceOngoing'); } } } window.wikidialog.noSequence = function (o) { sessionStorage.removeItem('wikidialogSequenceBound'); sessionStorage.removeItem('wikidialogSequenceOngoing'); if (o && (typeof(o) == 'object')) { delete o['ACTION-SEQUENCE-BOUND']; } } window.wikidialog.ongoingSequence = function () { return (sessionStorage.wikidialogSequenceOngoing ? true : false); } window.wikidialog.transclude = function (s) { function disassemble(s) { // break string into array of substrings // even elements are text other than inclusion directives // odd elements are inclusion directive labels, sans angle brackets // split keeps the parenthesized part of the delimiter; (?: ... ) is merely grouping return s.split(/<(noinclude|includeonly|onlyinclude|\/noinclude|\/includeonly|\/onlyinclude)(?:\s+[^<>]*)?>/); } function includeonly(s) { for (var k=1; k<s.length; k+=2) if ((s[k] == 'includeonly') || (s[k] == '/includeonly')) s[k] = ; return s; } function hasOnlyinclude(s) { for (var k=1; k<s.length; k+=2) if (s[k] == 'onlyinclude') return true; return false; } function onlyinclude(s) { var suppressFlag = true; s[0] = ; for (var k=1; k<s.length; k+=2) { if (suppressFlag) { if (s[k] == 'onlyinclude') suppressFlag = false; else s[k+1] = ; s[k] = ; } else if (s[k] == '/onlyinclude') { suppressFlag = true; s[k] = ; s[k+1] = ; } } return s; } function noinclude(s) { var suppressFlag = false; for (var k=1; k<s.length; k+=2) { if (suppressFlag) { if (s[k] == '/noinclude') suppressFlag = false; else s[k+1] = ; s[k] = ; } else if (s[k] == 'noinclude') { suppressFlag = true; s[k] = ; s[k+1] = ; } } return s; } function reassemble(s) { for (var k=2; k<s.length; k+=2) { if (s[k-1] != ) s[0] += '<' + s[k-1] + '>'; s[0] += s[k]; } return s[0]; } // s = includeonly(disassemble(s)); if (hasOnlyinclude(s)) s = onlyinclude(s); s = reassemble(noinclude(s)); return s; } function makeTparamRgx(name) { // the placement of parentheses here is dictated by substForTparams return new RegExp('(\\{\\{\\{)' + name + '(\\|[^\\|\\{\\}]*)?(\\}\\}\\})'); } window.wikidialog.substituteTemplateParameters = function (data, s) { // // substitute data for template parameters in raw wiki markup string s // safe to substitute arbitrarily because it's raw, provided we encode =[]<>{|} // function encodeMarkup(raw) { return raw.replace(/\||\=+|<+|>+|\[+|\]+|\{+|\}+/g, function (s) { function rpt(n, t) { var s = ; while (n > 16) { s += 'Template:' + t + ''; n -= 16; } s += '{{' + t; if (n > 1) s += ('|' + n); s += '}}'; return s; } switch (s[0]) { case '=': return rpt(s.length, '=='); // Template:== case '[': return rpt(s.length, '(-'); // Template:(- case ']': return rpt(s.length, '-)'); // Template:-) case '<': return rpt(s.length, '(\\'); // Template:(\ case '>': return rpt(s.length, '\\)'); // Template:\) case '{': return rpt(s.length, '(*'); // Template:(* case '|': return '|'; // Template:! case '}': return rpt(s.length, '*)'); // Template:*) } }); } var d = data; data = {}; for (var q in d) if ((typeof d[q]) != "string") data[q] = (d[q] ? d[q].toString() : ); else data[q] = d[q]; if (! s) return s; s = s.split(makeTparamRgx("([^\\{\\|\\}]*)")); for (var k = 0; (k < s.length); k++) if ((s[k] == '{{{') & (s[k+1] != '{{{')) { if (s[k+1] in data) { s[k] = ; s[k+1] = data[s[k+1]]; s[k+1] = encodeMarkup(s[k+1]); s[k+2] = ; s[k+3] = ; } k += 3; } return s.join(); } window.wikidialog.substituteParameters = function (pageName, actionParams, requests, content, callback) { // requests is optional if ((typeof requests) == "string") { callback = content; content = requests; requests = {}; } function makeInitRgx(name) { var maxBracesDepth = 32; // SINGLE POINT TO ADJUST max braces depth in dialog/init calls var rgx = "\\{[^\\{\\}]*\\}"; for (var j = 1; j <= maxBracesDepth; j++) rgx = "\\{[^\\{\\}]*(?:" + rgx + "[^\\{\\}]*)*\\}"; rgx = "\\{\\{\\s*[Dd]ialog/init\\s*\\|\\s*(" + name + "|\\(\\s*" + name + "(?:\\s+" + name + ")*\\s*\\))\\s*\\|([^\\{\\|\\}]*(?:" + rgx + "[^\\{\\|\\}]*)*)((?:\\|[^\\{\\|\\}\\=]*)?)\\}\\}"; return new RegExp(rgx); // three sets of parentheses here, for the three possible parameters to dialog/init } function reservedParam(s) { return ((s.search(/[A-Z]/) == 0) && (s.search(/[a-z]/) < 0)); } function localParam (s) { return (s.search(/local/) == 0); } function activeParams () { // // result is ampersand separated and delimited, // so each name on it is ampersand delimited // var id = getWikidialogID(); var result = sessionStorage['wikidialog:' + id + ':newparams']; if (! result) { result = sessionStorage['wikidialog:' + id + ':params']; if (! result) { result = '&'; } else { result = (',' + result + ',').replace(/,+/g, '&'); } } return result; } function paramIsActive(p) { return (activeParams().search('&' + p + '&') >= 0); } function paramIsTranscluded(p) { var rgx = makeTparamRgx(p); if (typeof content == "string") return (content.search(rgx) >= 0); for (var k = 0; (k < content.length); k++) if (content[k].search(rgx) >= 0) return true; return false; } function substForTparams(data) { if (typeof content == "string") content = window.wikidialog.substituteTemplateParameters(data, content); else for (var k = 0; (k < content.length); k++) content[k] = window.wikidialog.substituteTemplateParameters(data, content[k]); } function processInitCalls(pred, callback) { // // processes dialog/init calls // pred is optional; it's a critierion for possible deferral, so if provided, don't reassemble content when done // function assignment(definiend, value) { if (definiend.search(/\(/) < 0) { // simple definiend actionParams[definiend] = value; } else { // compound definiend definiend = definiend.replace(/\s*[\(\)]\s*/g,"").split(/\s+/); value = $.trim(value); var rgx1 = '"[^"]*(?:""[^"]*)*"'; // string var rgx2 = "\\(\\s*" + rgx1 + "(?:\\s+" + rgx1 + ")*\\s*\\)"; // list var vs = value.match(rgx2); if (! vs) { addNote('dialog/init compound definiend (' + definiend.join(' ') + ') value not well-formed.'); return; } value = vs[0]; vs = value.match(RegExp(rgx1, "g")); if (vs.length != definiend.length) { addNote('dialog/init compound definiend (' + definiend.join(' ') + ") value length doesn't match."); return; } for (var k=0; k<vs.length; k++) if (reservedParam(definiend[k])) { addNote('dialog/init prohibited from setting reserved parameter ' + definiend[k] + ' (in compound).'); } else { actionParams[definiend[k]] = vs[k].slice(1, (vs[k].length - 1)).replace(/""/g, '"'); } } } function f(n) { // process first n calls, from nth back to 1st if (n < 1) { callback(); return; } // // process nth remaining dialog/init call, then recurse // if (! content[4*n - 3]) { // already processed f(n - 1); return; } if (! pred(content[4*n - 2])) { // defer processing addNote('dialog/init parameter ' + content[4*n - 3] + ' deferred from early processing.'); f(n - 1); return; } if (reservedParam(content[4*n - 3])) { // simple reserved (reserved in compounds are detected elsewhere) addNote('dialog/init prohibited from setting reserved parameter ' + content[4*n - 3] + '.'); content[4*n - 3] = ; if (! content[4*n - 1]) content[4*n - 2] = ; // leave body for later expansion content[4*n - 1] = ; f(n - 1); return; } if (content[4*n - 2].search(/\{\{/) < 0) { // nothing to expand assignment(content[4*n - 3], content[4*n - 2]); content[4*n - 3] = ; if (! content[4*n - 1]) content[4*n - 2] = ; // leave body for later expansion content[4*n - 1] = ; f(n - 1); return; } $.ajax({ type: 'POST', url: mw.util.wikiScript('api'), data: { format: 'json', action: 'expandtemplates', text: content[4*n - 2], title: pageName, prop: 'wikitext' }, datatype: 'json' }).done(function(data) { if ((! data.expandtemplates) || (! data.expandtemplates.wikitext)) assignment(content[4*n - 3], ); else assignment(content[4*n - 3], data.expandtemplates.wikitext); content[4*n - 3] = ; if (! content[4*n - 1]) content[4*n - 2] = ; // leave body for later expansion content[4*n - 1] = ; f(n - 1); }).fail(function () { show('Error processing dialog/init call: expand-templates request failed.'); }); } function makeReassembler(callback) { return (function() { content = content.join(); callback(); }); } // // find the calls // if (typeof content == "string") content = content.split(makeInitRgx("[\\w\\-\\u0080-\\uFFFF]+")); var n = (content.length - 1) / 4; while (n > 8) { // SINGLE POINT TO ADJUST max number of dialog/init calls processed content[4*n - 3] = ; if (! content[4*n - 1]) content[4*n - 2] = ; content[4*n - 1] = ; n--; } if (! callback) { callback = makeReassembler(pred); pred = (function (s) { return true; }); } f(n); } function stepNine() { // // process remaining dialog/init calls, reassemble, and done // processInitCalls(function () { callback(content); }); } function stepEight() { // // fetch fileinfo if requested // if (! ( actionParams['file'] && paramIsTranscluded('FILE-INFO-[^\\{\\|\\}]*') && actionParams['local-file-info'])) { stepNine(); return; } addNote('Info requested for file "' + actionParams['file'] + '".'); $.ajax({ type: 'POST', url: mw.util.wikiScript('api'), data: { format: 'json', action: 'query', titles: actionParams['file'], prop: 'imageinfo', iiprop: ( paramIsTranscluded('FILE-INFO-META-[^\\{\\|\\}]*')  ? 'size|extmetadata'  : 'size') }, datatype: 'json' }).done(function(data) { if (data.query && data.query.pages) { var fields = {}; for (var p in data.query.pages) { var ii = data.query.pages[p].imageinfo; if (ii && ii[0]) { if (ii[0]['size' ]) fields['FILE-INFO-SIZE' ] = ii[0]['size' ]; if (ii[0]['width' ]) fields['FILE-INFO-WIDTH' ] = ii[0]['width' ]; if (ii[0]['height']) fields['FILE-INFO-HEIGHT'] = ii[0]['height']; var emd = ii[0]['extmetadata']; if (emd) for (var q in emd) { if (emd[q]['value']) fields['FILE-INFO-META-' + q.toUpperCase()] = emd[q]['value']; } } } substForTparams(fields); addNote('Info provided for file "' + actionParams['file'] + '".'); } else { addNote('Failed info retrieval for file "' + actionParams['file'] + '".'); } stepNine(); }).fail(function () { show('Error processing dialog request: imageinfo request failed.'); }); } function stepSeven() { // // fetch expanded text if requested // if (! ( paramIsTranscluded('EXPANDED-TEXT') && actionParams['local-text-to-expand'])) { stepEight(); return; } $.ajax({ type: 'POST', url: mw.util.wikiScript('api'), data: { format: 'json', action: 'expandtemplates', text: actionParams['local-text-to-expand'], title: pageName, prop: 'wikitext' }, datatype: 'json' }).done(function(data) { if ((data.expandtemplates) && (data.expandtemplates.wikitext)) substForTparams({ 'EXPANDED-TEXT': data.expandtemplates.wikitext }); stepEight(); }).fail(function () { show('Error processing dialog request: expand-templates request failed.'); }); } function stepSix() { // // fetch category members if requested // if (! ( actionParams['category'] && paramIsTranscluded('CATEGORY-MEMBERS-[^\\{\\|\\}]*') && actionParams['local-category-members'])) { stepSeven(); return; } var fields = {}; if (actionParams['local-category-members-continue' ]) fields.continue = actionParams['local-category-members-continue']; if (actionParams['local-category-members-direction']) fields.direction = actionParams['local-category-members-direction']; if (actionParams['local-category-members-type' ]) fields.type = actionParams['local-category-members-type']; if (actionParams['local-category-members-sort' ]) fields.sort = actionParams['local-category-members-sort']; window.wikidialog.categoryMembers(actionParams['category'], fields, function (result) { var data = {}; for (var p in result) { data ['CATEGORY-MEMBERS-' + p.toUpperCase()] = result[p]; actionParams['CATEGORY-MEMBERS-' + p.toUpperCase()] = result[p]; } substForTparams(data); stepSeven(); }); } function stepFive() { // // fetch page history if requested // if (! ( actionParams['subject'] && paramIsTranscluded('SUBJECT-HISTORY-[^\\{\\|\\}]*') && actionParams['local-subject-history'])) { stepSix(); return; } var fields = {}; if (actionParams['local-subject-history-continue' ]) fields.continue = actionParams['local-subject-history-continue']; if (actionParams['local-subject-history-direction']) fields.direction = actionParams['local-subject-history-direction']; window.wikidialog.pageHistory(actionParams['subject'], fields, function (result) { var data = {}; for (var p in result) { data ['SUBJECT-HISTORY-' + p.toUpperCase()] = result[p]; actionParams['SUBJECT-HISTORY-' + p.toUpperCase()] = result[p]; } substForTparams(data); stepSix(); }); } function stepFour() { // // process first round of dialog/init calls // processInitCalls((function (s) { return ( (s.search(makeTparamRgx('SUBJECT-HISTORY-[^\\{\\|\\}]*')) < 0) && (s.search(makeTparamRgx('CATEGORY-MEMBERS-[^\\{\\|\\}]*')) < 0) && (s.search(makeTparamRgx('EXPANDED-TEXT')) < 0)); }), stepFive); } function stepThree() { // // substitute for most template parameters, excluding complicated // query results controled by local parameter via dialog/init // substForTparams(actionParams) stepFour(); } function stepTwo() { // // fetch preload page if named and called for // if (! ('PRELOAD-PAGENAME' in actionParams)) { stepThree(); return; } if (! (paramIsTranscluded("PRELOAD-CONTENT"))) { stepThree(); return; } window.wikidialog.pageQuery( actionParams['PRELOAD-PAGENAME'], { content: }, function (fields) { if ('error' in fields) { stepThree(); return; } actionParams['PRELOAD-CONTENT'] = window.wikidialog.transclude(fields.content); stepThree(); }); } function stepOne() { // // remove reserved and local parameters // var subtractParams = {}; for (var p in actionParams) if (reservedParam(p) || localParam(p)) { subtractParams[p] = actionParams[p]; } for (var p in subtractParams) { delete actionParams[p]; } // // prep request/authentication parameters // var id = getWikidialogID(); var origin = sessionStorage['wikidialog:' + id + ':origin']; if (origin) { actionParams['INCOMING-AUTHENTICATED'] = origin; actionParams['REQUESTING-PAGE'] = origin; } else { var unauth = sessionStorage['wikidialog:' + id + ':unauth']; if (unauth) actionParams['REQUESTING-PAGE'] = unauth; } actionParams['ACTIVE-PARAMETERS'] = activeParams(); // // prep user name/groups parameters // var un = mw.config.get('wgUserName'); actionParams['USERNAME'] = (!un ? "" : un); var ug = mw.config.get('wgUserGroups'); actionParams['USER-GROUPS'] = (!ug ? "" : ug.join(" ")); // // prep version parameters // if (window.wikidialog.gadgetVersion) { actionParams['DIALOG-GADGET-VERSION'] = window.wikidialog.gadgetVersion(); } actionParams['DIALOG-RECEIVE-VERSION'] = receiveVersion(); // // prep stack-depth parameter // var stack = sessionStorage.wikidialogStack; if (stack) { actionParams['STACK-DEPTH'] = + (stack.split('&').length / 2); } // // prep action-dependent parameters // for (var p in requests) if (reservedParam(p)) { actionParams[p] = requests[p]; } // // prep sequence parameter // if (sessionStorage.wikidialogSequenceBound) { actionParams['ACTION-SEQUENCE-BOUND'] = sessionStorage.wikidialogSequenceBound; } // // fetch subject page info unless there's no subject // if (! ('subject' in actionParams)) { stepTwo(); return; } var fields = { name: , exists: }; for (var p in requests) fields[p] = ; if (paramIsTranscluded("SUBJECT-CONTENT")) fields.content = ; if (paramIsTranscluded("SUBJECT-TIMESTAMP")) fields.timestamp = ; if (paramIsTranscluded("SUBJECT-CATEGORIES")) fields.categories = ; if (paramIsTranscluded("SUBJECT-FLAGGED")) fields.flagged = ; window.wikidialog.pageQuery(actionParams.subject, fields, function (fields) { if ('error' in fields) { stepTwo(); return; } if (('exists' in fields) && (! fields.exists)) { actionParams['SUBJECT-EXISTS'] = 'false'; stepTwo(); return; } actionParams['SUBJECT-EXISTS'] = 'true'; actionParams.subject = fields.name; // normalize if ('content' in fields) actionParams['SUBJECT-CONTENT'] = fields.content; if ('timestamp' in fields) actionParams['SUBJECT-TIMESTAMP'] = fields.timestamp; if ('categories' in fields) actionParams['SUBJECT-CATEGORIES'] = fields.categories; if ('flagged' in fields) actionParams['SUBJECT-FLAGGED'] = fields.flagged; stepTwo(); }); } stepOne(); }

})();