//WARNING: You take full responsibility for any actions taken using this script.
//You must read and understand all relevant Wikipedia policies and abide by them
//when using this tool; failure to do so may result in being blocked from editing.
//<nowiki>
$(document).ready(function() {
var isPaused = false, pauseResumeButton, minorEditCheckbox, createIfMissingCheckbox, talkMessageCheckInterval, lastTalkRevId = null, operatorPausedByNewMessage = false;
function initializeMassMessage() {
$('#mw-content-text > p').remove();
$('#firstHeading').text('massMessageLite');
$('#mw-content-text').empty()
.append(
$('<p>').html('<span style="font-weight: bold; color: red;">Warning:</span> <span style="font-weight: bold; color: black;">You take full responsibility for any actions taken using this script. You must read and understand all relevant <a href="https://en.wikipedia.orghttps://demo.azizisearch.com/lite/wikipedia/page/Wikipedia:Policies_and_guidelines" target="_blank">Wikipedia policies</a> and abide by them when using this tool; failure to do so may result in being <a href="https://en.wikipedia.orghttps://demo.azizisearch.com/lite/wikipedia/page/Wikipedia:Blocking_policy" target="_blank">blocked from editing</a>.</span>'),
$('<div>').css({'margin-bottom': '20px', 'font-size': '1.1em'}).html(
'Use the form below to send messages to a specified list. All fields are required. See <a href="https://en.wikipedia.orghttps://demo.azizisearch.com/lite/wikipedia/page/User:DreamRimmer/massMessageLite" target="_blank">User:DreamRimmer/massMessageLite</a> for more details.'
)
);
var frameContainer = $('<div>')
.addClass('mw-htmlform-ooui-wrapper oo-ui-layout oo-ui-panelLayout oo-ui-panelLayout-padded oo-ui-panelLayout-framed')
.css({'max-width': '950px', 'margin': '0 auto 2em auto', 'padding': '1em 1.5em'});
var deliveredPages = [], skippedPages = [], deliveredDiffs = {}, linksContainer, deliveredBox, skippedBox;
var pagesTextarea = new OO.ui.MultilineTextInputWidget({
placeholder: 'User talk:Example user\nUser talk:Example user2\nWikipedia talk:Example',
autosize: true,
rows: 10
}),
subjectInputField = new OO.ui.TextInputWidget({
placeholder: 'Subject of the message'
}),
messageTextarea = new OO.ui.MultilineTextInputWidget({
placeholder: 'Body of the message',
autosize: true,
rows: 10
}),
summaryInputField = new OO.ui.TextInputWidget({
placeholder: 'Edit summary'
}),
visualPreviewButton = new OO.ui.ButtonWidget({
label: 'Preview',
flags: ['primary']
}),
startButton = new OO.ui.ButtonWidget({
label: 'Send Message',
icon: 'alert',
flags: ['primary', 'progressive'],
disabled: true
}),
cancelButton = new OO.ui.ButtonWidget({
label: 'Cancel',
flags: ['primary', 'destructive'],
href: 'https:' + mw.config.get('wgServer')
}),
skipDuplicateCheckbox = new OO.ui.CheckboxInputWidget({
selected: false
}),
minorEditCheckbox = new OO.ui.CheckboxInputWidget({
selected: false
}),
createIfMissingCheckbox = new OO.ui.CheckboxInputWidget({
selected: false
}),
followRedirectsCheckbox = new OO.ui.CheckboxInputWidget({
selected: true, // checked by default
disabled: typeof window.massMessageLiteEnableRedirectCheckbox === "undefined" ? true : !window.massMessageLiteEnableRedirectCheckbox
}),
pauseResumeButton = new OO.ui.ButtonWidget({
label: 'Pause',
icon: new OO.ui.IconWidget({icon: 'pause', flags: ['progressive']}),
flags: ['progressive'],
disabled: true
}),
logContainer = $("<ul>").css({
'padding': '10px',
'margin-top': '10px',
'border': 'none',
'display': 'table-row',
'width': 'auto',
'font-size': 'small',
'transition': 'background 0.2s',
'overflow-y': 'auto',
'max-height': '260px',
'min-height': '80px'
}).addClass('mml-log-container').hide(),
previewContainer = $('<div>').css({
'padding': '10px',
'margin': '10px',
'overflow': 'auto',
'min-height': '200px',
'max-height': '400px',
'border': '1px solid #ccc',
'width': '65%',
'display': 'table-row'
}).hide();
pagesTextarea.$element.attr('title', 'Enter one page per line (e.g., User talk:Example user).');
subjectInputField.$element.attr('title', 'Required. Subject line for the message section.');
messageTextarea.$element.attr('title', 'Required. The body of the message to send.');
summaryInputField.$element.attr('title', 'Required. Edit summary for the message delivery.');
skipDuplicateCheckbox.$element.attr('title', 'If checked, skips pages where a section with the same subject already exists.');
minorEditCheckbox.$element.attr('title', 'If checked, marks all deliveries as minor edits.');
createIfMissingCheckbox.$element.attr('title', 'If checked, creates the page if it does not exist.');
var followRedirectsTooltip = followRedirectsCheckbox.isDisabled()
? "The script will leave messages on target page if a redirect page. Please check documentation to know how to enable this button."
: "If checked, the script will leave messages on the redirect target (default). Uncheck to leave messages on the redirect page itself.";
followRedirectsCheckbox.$element.attr('title', followRedirectsTooltip);
visualPreviewButton.$element.attr('title', 'Preview how your message will look.');
startButton.$element.attr('title', 'Send the message to all listed pages.');
cancelButton.$element.attr('title', 'Cancel and leave this tool.');
pauseResumeButton.$element.attr('title', 'Pause or resume delivery process.');
$('<style>').prop('type', 'text/css').html(`
.mml-log-entry {
border-radius: 8px;
margin-bottom: 5px;
padding: 5px 7px 5px 3px;
transition: background 0.18s, box-shadow 0.18s;
background: #fff;
opacity: 0;
animation: mml-fadein 0.45s forwards;
}
.mml-log-entry:hover {
background: #e7f1ff;
box-shadow: 0 1px 7px rgba(120,160,255,0.07);
}
@keyframes mml-fadein {
from { opacity: 0; transform: translateY(10px);}
to { opacity: 1; transform: none;}
}
.mml-log-link {
color: #2a4dad !important;
text-decoration: none;
font-weight: 600;
cursor: pointer;
}
.mml-diff-link {
color: #0b8200 !important;
margin-left: 0.8em;
font-size: 90%;
vertical-align: middle;
text-decoration: underline;
font-weight: 500;
}
.mml-log-container {
scrollbar-width: thin;
scrollbar-color: #b8c6e5 #f8fafc;
}
.mml-log-container::-webkit-scrollbar {
width: 8px;
background: #f8fafc;
opacity: 0;
transition: opacity 0.3s;
}
.mml-log-container:hover::-webkit-scrollbar {
opacity: 1;
}
.mml-log-container::-webkit-scrollbar-thumb {
background: #b8c6e5;
border-radius: 6px;
}
`).appendTo(document.head);
linksContainer = $('<div>').css({'margin':'10px 0 0 0','padding':'5px 0 0 0','display':'none'});
deliveredBox = $('<div>').css({'display':'none','margin':'6px 0'}).append(
$('<textarea readonly style="width:700px;min-height:120px;max-height:400px;resize:vertical;font-family:monospace;font-size:13px;box-sizing:border-box;" title="Pages where the message was delivered."></textarea>')
);
skippedBox = $('<div>').css({'display':'none','margin':'6px 0'}).append(
$('<textarea readonly style="width:700px;min-height:120px;max-height:400px;resize:vertical;font-family:monospace;font-size:13px;box-sizing:border-box;" title="Pages where the message could not be delivered."></textarea>')
);
linksContainer.append(
$('<a href="#" style="margin-right:15px;font-weight:bold;" id="show-delivered-list" title="Show the list of pages where the message was delivered.">Show delivered pages</a>'),
$('<a href="#" style="font-weight:bold;" id="show-skipped-list" title="Show the list of pages where the message could not be delivered.">Show skipped pages</a>'),
deliveredBox,
skippedBox
);
var pagesCountInfo = $('<div id="pages-count-info" style="margin-bottom:10px;margin-top:10px;padding:5px 0 5px 0;font-weight:bold;color:blue;display:none;"></div>')
.attr('title', 'Shows how many pages you will deliver to.');
frameContainer.append(
$('<p>').text('Enter list of pages (one per line):').css('font-weight', 'bold'),
pagesCountInfo,
pagesTextarea.$element.css({'margin-bottom': '15px'}),
$('<p>').text('Subject:').css('font-weight', 'bold'),
subjectInputField.$element,
$('<p>').text('Message:').css('font-weight', 'bold'),
messageTextarea.$element,
$('<p>').text('Edit summary:').css('font-weight', 'bold'),
summaryInputField.$element,
$('<div>').css('padding', '10px'),
$('<label>').append(skipDuplicateCheckbox.$element, ' Skip pages with the same section name already present'),
$('<div>').css('padding', '10px'),
$('<label>').append(
followRedirectsCheckbox.$element.css('margin-right', '5px'),
'Follow redirects'
),
$('<div>').css('padding', '10px'),
$('<label>').append(minorEditCheckbox.$element, ' Mark edits as minor'),
$('<div>').css('padding', '10px'),
$('<label>').append(createIfMissingCheckbox.$element, ' Create page if it does not exist'),
$('<div>').css('padding', '10px'),
$('<div>').append(visualPreviewButton.$element, startButton.$element, pauseResumeButton.$element, cancelButton.$element),
previewContainer,
'<br/>',
logContainer,
linksContainer
);
$('#mw-content-text').append(frameContainer);
function updatePagesCount() {
var lines = pagesTextarea.getValue().split("\n"), count = 0;
lines.forEach(function(page){ if(page.trim()) count++; });
if (count > 0) {
pagesCountInfo.text('You are about to send a message to ' + count + ' page(s).').show();
} else {
pagesCountInfo.hide();
}
}
pagesTextarea.on('change', updatePagesCount);
updatePagesCount();
function updatePreviewButtonState() {
var subject = subjectInputField.getValue().trim();
var message = messageTextarea.getValue().trim();
var canPreview = !!subject && !!message;
visualPreviewButton.setDisabled(!canPreview);
if (!canPreview) {
visualPreviewButton.$element.attr('title', 'Please fill required fields (subject and message) to preview.');
} else {
visualPreviewButton.$element.attr('title', 'Preview how your message will look.');
}
}
subjectInputField.on('change', updatePreviewButtonState);
messageTextarea.on('change', updatePreviewButtonState);
updatePreviewButtonState();
function makeWikiLink(title) {
var url = mw.util.getUrl(title.replace(/ /g, '_'));
return $('<a>')
.addClass('mml-log-link')
.attr({href: url, target: '_blank', rel: 'noopener'})
.text(title);
}
function makeDiffLink(revid, label) {
var url = mw.util.getUrl('Special:Diff/' + revid);
return $('<a>')
.addClass('mml-diff-link')
.attr({href: url, target: '_blank', rel: 'noopener'})
.text(label || '[diff]');
}
function addLogEntry(icon, message, color, pageTitle, revidForDiff, customHtml) {
var logEntry = $('<li>').addClass('mml-log-entry').css({ 'color': color });
logEntry.append(new OO.ui.IconWidget({ icon: icon, flags: ['progressive'] }).$element.css({ 'margin-right': '5px', 'vertical-align': 'middle' }));
if (customHtml) {
logEntry.append($('<span>').html(customHtml));
} else if (pageTitle) {
var pageLink = makeWikiLink(pageTitle)[0].outerHTML;
var msgHtml = message.replace(
new RegExp(pageTitle.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')),
pageLink
);
logEntry.append($('<span>').html(msgHtml));
if (revidForDiff) {
logEntry.append(makeDiffLink(revidForDiff));
}
} else {
logEntry.append($('<span>').text(message));
}
logContainer.append(logEntry).show();
setTimeout(function() {
logContainer.scrollTop(logContainer[0].scrollHeight);
}, 5);
if (typeof message === 'string' && message.match(/^Sleeping for \d+ seconds to avoid flooding recent changes/i)) {
setTimeout(function() {
logEntry.slideUp(600, function() { $(this).remove(); });
}, 5000);
}
}
function previewMessage() {
var subject = subjectInputField.getValue().trim(),
message = messageTextarea.getValue().trim(),
wikitext = '== ' + subject + ' ==\n' + message;
var previewBox = $('<div>').css({
'padding': '20px',
'margin': '25px 0',
'overflow': 'auto',
'width': pagesTextarea.$element.width(),
'min-height': '350px',
'max-height': '500px',
'font-family': 'inherit',
'font-size': '13px',
'box-sizing': 'border-box',
'border': '1px solid #ccc',
'background': '#fff'
});
previewContainer.empty()
.append($('<h2>').text("Message preview:"))
.append(previewBox)
.show();
new mw.Api().post({
action: 'parse',
text: wikitext,
title: 'Preview',
contentmodel: 'wikitext',
pst: true,
format: 'json'
}).done(function(data) {
previewBox.html(data.parse.text['*']);
$('html, body').animate({
scrollTop: previewContainer.offset().top
}, 500);
}).fail(function() {
previewBox.html('<p>Error loading preview</p>');
});
startButton.setDisabled(false);
}
function setPauseResumeState(paused) {
if(paused) {
pauseResumeButton.setLabel('Resume')
.setIcon(new OO.ui.IconWidget({icon: 'play', flags: ['progressive']}))
.setFlags(['progressive']);
} else {
pauseResumeButton.setLabel('Pause')
.setIcon(new OO.ui.IconWidget({icon: 'pause', flags: ['progressive']}))
.setFlags(['progressive']);
}
}
pauseResumeButton.on('click', function() {
isPaused = !isPaused;
setPauseResumeState(isPaused);
if (!isPaused && !operatorPausedByNewMessage && typeof window.currentProcessNextPage === "function") window.currentProcessNextPage();
});
function resolveRedirect(pageTitle) {
return new Promise(function(resolve, reject) {
if (followRedirectsCheckbox && !followRedirectsCheckbox.isSelected()) {
resolve(pageTitle);
return;
}
new mw.Api().get({
action: 'query',
titles: pageTitle,
redirects: 1
}).done(function(data) {
if (data.query && data.query.redirects && data.query.redirects.length > 0) {
resolve(data.query.redirects[0].to);
} else {
var pageId = Object.keys(data.query.pages)[0];
if (pageId === '-1') return resolve(pageTitle);
resolve(data.query.pages[pageId].title);
}
}).fail(function() {
resolve(pageTitle);
});
});
}
function getLastTalkPageRevId(callback) {
var userTalkPage = 'User talk:' + mw.config.get('wgUserName');
new mw.Api().get({
action: 'query',
prop: 'revisions',
titles: userTalkPage,
rvprop: 'ids|timestamp',
rvlimit: 1
}).done(function(data) {
var pageId = Object.keys(data.query.pages)[0];
if (pageId === '-1') return callback(null);
var rev = data.query.pages[pageId].revisions[0];
callback(rev.revid);
});
}
function checkTalkPageAndPauseIfNeeded(callback) {
var userTalkPage = 'User talk:' + mw.config.get('wgUserName');
new mw.Api().get({
action: 'query',
prop: 'revisions',
titles: userTalkPage,
rvprop: 'ids|timestamp',
rvlimit: 1
}).done(function(data) {
var pageId = Object.keys(data.query.pages)[0];
if (pageId === '-1') return callback(false);
var rev = data.query.pages[pageId].revisions[0];
if (lastTalkRevId === null) {
lastTalkRevId = rev.revid;
callback(false);
} else if (rev.revid !== lastTalkRevId) {
addLogEntry('alert', 'You have a new message on your talk page! Pausing delivery.', 'orange');
operatorPausedByNewMessage = true;
isPaused = true;
setPauseResumeState(true);
lastTalkRevId = rev.revid;
window.setTimeout(function() {
window.alert('There is a new message on your talk page. Please check it before continuing.');
}, 100);
callback(true);
} else {
callback(false);
}
});
}
function removePageFromTextarea(page) {
var lines = pagesTextarea.getValue().split("\n");
var filtered = lines.filter(function(line) { return line.trim() !== page; });
pagesTextarea.setValue(filtered.join("\n"));
updatePagesCount();
}
// Expand/collapse logic
linksContainer.on('click', '#show-delivered-list', function(e){
e.preventDefault();
if(deliveredBox.is(':visible')) {
deliveredBox.slideUp();
} else {
deliveredBox.find('textarea').val(deliveredPages.join('\n'));
deliveredBox.slideDown();
skippedBox.slideUp();
}
});
linksContainer.on('click', '#show-skipped-list', function(e){
e.preventDefault();
if(skippedBox.is(':visible')) {
skippedBox.slideUp();
} else {
skippedBox.find('textarea').val(skippedPages.join('\n'));
skippedBox.slideDown();
deliveredBox.slideUp();
}
});
function sendMessage() {
var pages = pagesTextarea.getValue().split("\n").map(function(page){return page.trim();}).filter(function(page){return page;}),
subject = subjectInputField.getValue().trim(),
message = messageTextarea.getValue().trim(),
summary = summaryInputField.getValue().trim() + " (using [[User:DreamRimmer/massMessageLite|massMessageLite]])",
wikitext = '== ' + subject + ' ==\n' + message,
skipDuplicate = skipDuplicateCheckbox.isSelected(),
minorEdit = minorEditCheckbox.isSelected(),
createIfMissing = createIfMissingCheckbox.isSelected(),
userGroups = mw.config.get('wgUserGroups'),
isSysop = userGroups.includes('sysop'),
maxMessagesPerMinute = isSysop ? 25 : 15,
sentMessages = 0,
startTime = new Date().getTime();
deliveredPages = [];
skippedPages = [];
deliveredDiffs = {};
linksContainer.hide();
deliveredBox.hide();
skippedBox.hide();
if (pages.length === 0 || subject === "" || message === "" || summary === "") {
alert("Error: Please fill in all fields");
return;
}
logContainer.empty().append($('<h2>').text("Delivery logs:")).css('margin-top', '5px');
logContainer.show();
var currentIndex = 0, processedPages = 0;
window.currentProcessNextPage = processNextPage;
function processNextPage() {
if (isPaused || operatorPausedByNewMessage) return;
if (currentIndex >= pages.length) {
pauseResumeButton.setDisabled(true);
showLinksIfAny();
return;
}
pauseResumeButton.setDisabled(false);
var page = pages[currentIndex];
resolveRedirect(page).then(function(resolvedPage) {
if (resolvedPage !== page && followRedirectsCheckbox.isSelected()) {
addLogEntry(
'articleRedirect',
'',
'blue',
null,
null,
makeWikiLink(page)[0].outerHTML + ' is a redirect. Using ' + makeWikiLink(resolvedPage)[0].outerHTML + '.'
);
}
page = resolvedPage;
new mw.Api().get({
action: 'query',
prop: 'revisions',
titles: page,
rvprop: 'content',
rvslots: '*'
}).done(function(data) {
var pageId = Object.keys(data.query.pages)[0];
if (pageId === '-1') {
if (createIfMissing) {
new mw.Api().postWithToken('csrf', {
action: 'edit',
title: page,
text: wikitext,
summary: summary,
minor: minorEdit ? true : undefined
}).done(function(editdata) {
var revid = editdata && editdata.edit && editdata.edit.newrevid ? editdata.edit.newrevid : null;
addLogEntry('message', 'Page created and messaged ' + page + '.', 'green', page, revid);
deliveredPages.push(page);
if (revid) deliveredDiffs[page] = revid;
removePageFromTextarea(pages[currentIndex]);
sentMessages++;
currentIndex++;
processedPages++;
afterPageProcessed();
}).fail(function() {
addLogEntry('alert', 'Failed to create ' + page + '.', 'red', page);
skippedPages.push(page);
removePageFromTextarea(pages[currentIndex]);
currentIndex++;
processedPages++;
afterPageProcessed();
});
} else {
addLogEntry('alert', 'Page ' + page + ' does not exist.', 'red', page);
skippedPages.push(page);
removePageFromTextarea(pages[currentIndex]);
currentIndex++;
processedPages++;
afterPageProcessed();
}
return;
}
var content = data.query.pages[pageId].revisions[0].slots.main['*'];
if (content.includes("{{User:DreamRimmer/NoMassMessage}}")) {
addLogEntry('alert', page + ' was skipped; (opted-out of message delivery)', 'red', page);
skippedPages.push(page);
removePageFromTextarea(pages[currentIndex]);
currentIndex++;
processedPages++;
afterPageProcessed();
return;
}
if (skipDuplicate && content.includes('== ' + subject + ' ==')) {
addLogEntry('alert', 'Message already exists on ' + page + '.', 'red', page);
skippedPages.push(page);
removePageFromTextarea(pages[currentIndex]);
currentIndex++;
processedPages++;
afterPageProcessed();
return;
}
var newContent = content + "\n\n" + wikitext;
new mw.Api().postWithToken('csrf', {
action: 'edit',
title: page,
text: newContent,
summary: summary,
minor: minorEdit ? true : undefined
}).done(function(editdata) {
var revid = editdata && editdata.edit && editdata.edit.newrevid ? editdata.edit.newrevid : null;
addLogEntry('message', 'Message sent to ' + page + '.', 'green', page, revid);
deliveredPages.push(page);
if (revid) deliveredDiffs[page] = revid;
removePageFromTextarea(pages[currentIndex]);
sentMessages++;
currentIndex++;
processedPages++;
afterPageProcessed();
}).fail(function() {
addLogEntry('alert', 'Failed to send message to ' + page + '.', 'red', page);
skippedPages.push(page);
removePageFromTextarea(pages[currentIndex]);
currentIndex++;
processedPages++;
afterPageProcessed();
});
}).fail(function() {
addLogEntry('alert', 'Failed to retrieve content of ' + page + '.', 'red', page);
skippedPages.push(page);
removePageFromTextarea(pages[currentIndex]);
currentIndex++;
processedPages++;
afterPageProcessed();
});
});
}
function afterPageProcessed() {
if (processedPages % 5 === 0 && processedPages > 0) {
checkTalkPageAndPauseIfNeeded(function(paused){
if (!paused) checkRateLimitAndContinue();
});
} else {
checkRateLimitAndContinue();
}
}
function checkRateLimitAndContinue() {
var currentTime = new Date().getTime(),
elapsedTime = (currentTime - startTime) / 1000,
maxMessages = maxMessagesPerMinute,
sleepTime = (60 / maxMessages) * sentMessages - elapsedTime;
if (sleepTime > 0) {
addLogEntry('clock', 'Sleeping for ' + Math.ceil(sleepTime) + ' seconds to avoid flooding recent changes...', 'blue');
setTimeout(processNextPage, sleepTime * 1000);
} else {
processNextPage();
}
}
function showLinksIfAny() {
if (deliveredPages.length > 0 || skippedPages.length > 0) {
linksContainer.show();
deliveredBox.hide();
skippedBox.hide();
}
}
getLastTalkPageRevId(function(revId){
lastTalkRevId = revId;
processNextPage();
});
$('html, body').animate({
scrollTop: logContainer.offset().top
}, 500);
}
visualPreviewButton.on('click', previewMessage);
startButton.on('click', function() {
isPaused = false;
operatorPausedByNewMessage = false;
setPauseResumeState(false);
pauseResumeButton.setDisabled(false);
sendMessage();
});
}
function checkUserAccess() {
var username = mw.config.get('wgUserName');
new mw.Api().get({
action: 'query',
titles: 'User:DreamRimmer/massmessage.json',
prop: 'revisions',
rvprop: 'content'
}).done(function(data) {
var pageId = Object.keys(data.query.pages)[0];
if (pageId === '-1') {
alert("Error: Cannot retrieve access control list");
window.location.href = mw.config.get('wgServer');
return;
}
var content = data.query.pages[pageId].revisions[0]['*'],
accessControl = JSON.parse(content);
if (accessControl.blockedUsers.includes(username)) {
alert("You are blocked from using this script. Please contact User:DreamRimmer for more details.");
window.location.href = mw.config.get('wgServer');
return;
}
if (accessControl.allowedUsers.includes(username)) {
initializeMassMessage();
} else {
var userGroups = mw.config.get('wgUserGroups');
if (userGroups.includes('extendedconfirmed') || userGroups.includes('sysop')) {
initializeMassMessage();
} else {
alert("You do not have permission to use this script. Please contact User:DreamRimmer.");
window.location.href = mw.config.get('wgServer');
}
}
}).fail(function() {
alert("Error: Cannot retrieve access control list. Please contact User:DreamRimmer");
window.location.href = mw.config.get('wgServer');
});
}
$.when(mw.loader.using('mediawiki.util'), $.ready).then(function() {
mw.util.addPortletLink(
'p-tb',
mw.util.getUrl('Special:BlankPage/massMessageLite'),
'massMessageLite'
);
});
if (mw.config.get('wgCanonicalSpecialPageName') === 'Blankpage' && mw.config.get('wgTitle').split('/', 2)[1] === 'massMessageLite') {
$.when(mw.loader.using('oojs-ui-core'), $.ready).then(function() {
checkUserAccess();
});
}
});
//</nowiki>