MediaWiki:Gadget-morebits.js: Difference between revisions
Content deleted Content added
Amorymeltzer (talk | contribs) Repo at b60c1b8: Convert Morebits.wiki.page methods to json, not xml; Require matching level markers; Add YYYYMMDDHHmmss to morebits.date constructor; Fixes for internal templates/parser functions; Consolidate largely duplicated code; Fixes for unnamed parameters |
Amorymeltzer (talk | contribs) Repo at f050fa9: Fix ancient bug where multiple occurences were not being processed; Force loading of a page if a watchlist expiry is provided; Fix missing letter in fnLookupNonRedirectCreator; use blue colour for "Redirected from" message; Apply; bugfix: Exactly match templates and files; improve formatReasonText; Get watched status of page, only apply watchlist expiry if unwatched; userspaceLogger: return a promise; page: allow binding to existing statusElement |
||
Line 1,222:
* templates that are going to be substituted, (e.g. PROD, XFD, RPP).
* Handles `|` outside a nowiki tag.
* Optionally, also adds a signature if not present already.
*
* @param {string} str
* @param {boolean} [addSig]
* @returns {string}
*/
formatReasonText: function(str, addSig) {
var
var unbinder = new Morebits.unbinder(
unbinder.unbind('<no' + 'wiki>', '</no' + 'wiki>');
unbinder.content = unbinder.content.replace(/\|/g, '{{subst:!}}');
if (addSig) {
var sig = '~~~~', sigIndex = reason.lastIndexOf(sig);
if (sigIndex === -1 || sigIndex !== reason.length - sig.length) {
reason += ' ' + sig;
}
}
return reason.trim();
},
Line 1,761 ⟶ 1,770:
var h12 = h24 % 12 || 12, amOrPm = h24 >= 12 ? 'PM' : 'AM';
var replacementMap = {
};
Line 2,284 ⟶ 2,293:
* @param {string} pageName - The name of the page, prefixed by the namespace (if any).
* For the current page, use `mw.config.get('wgPageName')`.
* @param {string|Morebits.status} [
* or a Morebits.status object
*/
Morebits.wiki.page = function(pageName,
if (!
}
Line 2,308 ⟶ 2,318:
testActions: null, // array if any valid actions
callbackParameters: null,
statusElement: status instanceof Morebits.status ? status : new Morebits.status(
// - edit
Line 2,360 ⟶ 2,370:
revertCurID: null,
revertUser: null,
watched: false,
fullyProtected: false,
suppressProtectWarning: false,
Line 2,426 ⟶ 2,437:
action: 'query',
prop: 'info|revisions',
inprop: 'watched',
intestactions: 'edit', // can be expanded
curtimestamp: '',
Line 2,450 ⟶ 2,462:
}
if (Morebits.userIsSysop) {
ctx.loadQuery.inprop += '|protection';
}
Line 2,520 ⟶ 2,532:
}
if (ctx.watchlistExpiry && !ctx.watched) {
query.watchlistexpiry = ctx.watchlistExpiry;
}
Line 2,598 ⟶ 2,610:
/**
* Adds the text provided via `setAppendText()` to the end of the
* page. Does not require calling `load()` first
* expiry is used.
*
* @param {Function} [onSuccess] - Callback function which is called when the method has succeeded.
Line 2,617 ⟶ 2,630:
/**
* Adds the text provided via `setPrependText()` to the start of the
* page. Does not require calling `load()` first
* expiry is used.
*
* @param {Function} [onSuccess] - Callback function which is called when the method has succeeded.
Line 2,640 ⟶ 2,654:
* If `editSummary` is provided, that will be used instead of the
* autogenerated "->Title (new section" edit summary.
* Does not require calling `load()` first
* is used.
*
* @param {Function} [onSuccess] - Callback function which is called when the method has succeeded.
Line 2,964 ⟶ 2,979:
this.getCallbackParameters = function() {
return ctx.callbackParameters;
};
/**
* @param {Morebits.status} statusElement
*/
this.setStatusElement = function(statusElement) {
ctx.statusElement = statusElement;
};
Line 3,005 ⟶ 3,027:
this.getContentModel = function() {
return ctx.contentModel;
};
/** @returns {boolean} - Watched status of the page. */
this.getWatched = function () {
return ctx.watched;
};
Line 3,051 ⟶ 3,078:
var query = {
};
Line 3,332 ⟶ 3,359:
/**
* Determines whether we can save an API call by using the csrf token
* sent with the page HTML, or whether we need to ask the server for
* more info (e.g. protection or watchlist expiry). *
* Currently used for `append`, `prepend`, `newSection`, `move`,
* `stabilize`, `deletePage`, and `undeletePage`.
* `protect` since it always needs to request protection status.
*
Line 3,345 ⟶ 3,373:
var fnCanUseMwUserToken = function(action) {
action = typeof action !== 'undefined' ? action : 'edit'; // IE doesn't support default parameters
// If a watchlist expiry is set, always load protection status to avoid
// overwriting indefinite protection; see [[phab:T270057]] and [[phab:T268834]]
if (ctx.watchlistExpiry) {
return false;
}
// API-based redirect resolution only works for action=query and
Line 3,377 ⟶ 3,411:
* When functions can't use {@link
* Morebits.wiki.page~fnCanUseMwUserToken|fnCanUseMwUserToken} or
* require checking protection or watched status, maintain the query
* in one place. Used for {@link Morebits.wiki.page#deletePage|delete},
* {@link Morebits.wiki.page#undeletePage|undelete},
* {@link* Morebits.wiki.page#protect|protect},
* {@link Morebits.wiki.page#stabilize|stabilize},
* and {@link Morebits.wiki.page#move|move}
* (basically, just not {@link Morebits.wiki.page#load|load}).
*
* @param {string} action - The action being undertaken, e.g. "edit" or
* "delete".
* @returns {object} Appropriate
*/
var fnNeedTokenInfoQuery = function(action) {
Line 3,395 ⟶ 3,429:
type: 'csrf',
titles: ctx.pageName,
prop: 'info',
inprop: 'watched',
format: 'json'
};
// Protection not checked for flagged-revs or non-sysop moves
if (action !== 'stabilize' && (action !== 'move' || Morebits.userIsSysop)) {
query.
}
if (ctx.followRedirect && action !== 'undelete') {
Line 3,446 ⟶ 3,481:
ctx.contentModel = page.contentmodel;
ctx.watched = page.watched;
// extract protection info, to alert admins when they are about to edit a protected page
Line 3,526 ⟶ 3,562:
// only notify user for redirects, not normalization
new Morebits.status
}
Line 3,690 ⟶ 3,726:
var fnLookupNonRedirectCreator = function() {
var response = ctx.
var revs = response.pages[0].revisions;
Line 3,811 ⟶ 3,847:
token = response.tokens.csrftoken;
pageTitle = response.pages[0].title;
ctx.watched = response.pages[0].watched;
}
var query = {
};
if (ctx.changeTags) {
Line 3,826 ⟶ 3,863:
}
if (ctx.watchlistExpiry && !ctx.watched) {
query.watchlistexpiry = ctx.watchlistExpiry;
}
Line 3,956 ⟶ 3,993:
token = response.tokens.csrftoken;
pageTitle = response.pages[0].title;
ctx.watched = response.pages[0].watched;
}
var query = {
};
if (ctx.changeTags) {
Line 3,970 ⟶ 4,008:
}
if (ctx.watchlistExpiry && !ctx.watched) {
query.watchlistexpiry = ctx.watchlistExpiry;
}
Line 4,019 ⟶ 4,057:
token = response.tokens.csrftoken;
pageTitle = response.pages[0].title;
ctx.watched = response.pages[0].watched;
}
var query = {
};
if (ctx.changeTags) {
Line 4,033 ⟶ 4,072:
}
if (ctx.watchlistExpiry && !ctx.watched) {
query.watchlistexpiry = ctx.watchlistExpiry;
}
Line 4,082 ⟶ 4,121:
var token = response.tokens.csrftoken;
var pageTitle = response.pages[0].title;
ctx.watched = response.pages[0].watched;
// Fetch existing protection levels
Line 4,166 ⟶ 4,206:
}
if (ctx.watchlistExpiry && !ctx.watched) {
query.watchlistexpiry = ctx.watchlistExpiry;
}
Line 4,194 ⟶ 4,234:
token = response.tokens.csrftoken;
pageTitle = response.pages[0].title;
// ctx.watched = response.pages[0].watched; // Doesn't support watchlist expiry [[phab:T263336]]
}
Line 4,204 ⟶ 4,245:
// tags: ctx.changeTags, // flaggedrevs tag support: [[phab:T247721]]
reason: ctx.editSummary,
watchlist: ctx.watchlistOption,
format: 'json'
};
/* Doesn't support watchlist expiry [[phab:T263336]]
if (ctx.watchlistExpiry && !ctx.watched) {
query.watchlistexpiry = ctx.watchlistExpiry;
}
*/
ctx.stabilizeProcessApi = new Morebits.wiki.api('configuring stabilization settings...', query, ctx.onStabilizeSuccess, ctx.statusElement, ctx.onStabilizeFailure);
Line 4,470 ⟶ 4,517:
// Check for normal image links, i.e. [[File:Foobar.png|...]]
// Will eat the whole link
var links_re = new RegExp('\\[\\[(?:[Ii]mage|[Ff]ile):\\s*' + image_re_string + '\\s*[\\|(?:\\]\\])]');
var allLinks =
for (var i = 0; i < allLinks.length; ++i) {
if (links_re.test(allLinks[i])) {
var replacement = '<!-- ' + reason + allLinks[i] + ' -->';
unbinder.content = unbinder.content.replace(allLinks[i], replacement
}
}
Line 4,484 ⟶ 4,531:
// eventually preceded with some space, and must include File: prefix
// Will eat the whole line.
var gallery_image_re = new RegExp('(^\\s*(?:[Ii]mage|[Ff]ile):\\s*' + image_re_string + '\\s*(?:\\|.*?$|$))', 'mg');
unbinder.content = unbinder.content.replace(gallery_image_re, '<!-- ' + reason + '$1 -->');
Line 4,514 ⟶ 4,561:
}
var image_re_string = '(?:[Ii]mage|[Ff]ile):\\s*' + first_char_regex + Morebits.string.escapeRegExp(image.substr(1));
var links_re = new RegExp('\\[\\[' + image_re_string + '\\s*[\\|(?:\\]\\])]');
var allLinks =
for (var i = 0; i < allLinks.length; ++i) {
if (links_re.test(allLinks[i])) {
Line 4,521 ⟶ 4,568:
// just put it at the end?
replacement = replacement.replace(/\]\]$/, '|' + data + ']]');
this.text = this.text.replace(allLinks[i], replacement
}
}
Line 4,531 ⟶ 4,578:
/**
*
*
* @param {string} template - Page name whose transclusions are to be removed,
Line 4,541 ⟶ 4,588:
var first_char = template.substr(0, 1);
var template_re_string = '(?:[Tt]emplate:)?\\s*[' + first_char.toUpperCase() + first_char.toLowerCase() + ']' + Morebits.string.escapeRegExp(template.substr(1));
var links_re = new RegExp('\\{\\{' + template_re_string + '\\s*[\\|(?:\\}\\})]');
var allTemplates =
for (var i = 0; i < allTemplates.length; ++i) {
if (links_re.test(allTemplates[i])) {
this.text = this.text.replace(allTemplates[i], '
}
}
Line 4,660 ⟶ 4,707:
* @param {string} logText - Doesn't include leading `#` or `*`.
* @param {string} summaryText - Edit summary.
* @returns {JQuery.Promise}
*/
this.log = function(logText, summaryText) {
var def = $.Deferred();
if (!logText) {
return def.reject();
}
var page = new Morebits.wiki.page('User:' + mw.config.get('wgUserName') + '/' + logPageName,
'Adding entry to userspace log'); // make this '... to ' + logPageName ?
// add blurb if log page doesn't exist or is blank
var text = pageobj.getPageText() || this.initialText;
Line 4,681 ⟶ 4,730:
pageobj.setChangeTags(this.changeTags);
pageobj.setCreateOption('recreate');
pageobj.save(def.resolve, def.reject);
}.bind(this));
return def;
};
};
|