MediaWiki:Gadget-twinkleblock.js: Difference between revisions

Content deleted Content added
Repo at 451b991: Don't add expiry to template if it's a date, not a duration
Repo at 4cba4ef: Align current/log displays; Append warning to an existing section, even if it's not the last; Favor current block information if present
Line 39:
Window.addFooterLink('Block templates', 'Template:Uw-block/doc/Block_templates');
Window.addFooterLink('Block policy', 'WP:BLOCK');
Window.addFooterLink('Block prefs', 'WP:TW/PREF#block');
Window.addFooterLink('Twinkle help', 'WP:TW/DOC#block');
 
Line 61 ⟶ 62:
value: 'partial',
tooltip: 'Enable partial blocks and partial block templates.',
checked: Twinkle.getPref('defaultToPartialBlocks') // Overridden if already blocked
},
{
Line 84 ⟶ 85:
 
Twinkle.block.fetchUserInfo(function() {
// Toggle initial partial state depending on prior block type,
// will override the defaultToPartialBlocks pref
if (Twinkle.block.currentBlockInfo) {
$(result).find('[name=actiontype][value=partial]').prop('checked', Twinkle.block.currentBlockInfo.partial === '');
}
 
// clean up preset data (defaults, etc.), done exactly once, must be before Twinkle.block.callback.change_action is called
Twinkle.block.transformBlockPresets();
Line 105 ⟶ 112:
lelimit: 1,
bkusers: mw.config.get('wgRelevantUserName'),
bkprop: 'expiry|reason|flags|restrictions',
ususers: mw.config.get('wgRelevantUserName'),
usprop: 'groupmemberships',
Line 163 ⟶ 171:
 
partial.prop('disabled', !blockBox && !templateBox);
 
// Add current block parameters as default preset
if (Twinkle.block.currentBlockInfo) {
Twinkle.block.blockPresetsInfo.prior = Twinkle.block.currentBlockInfo;
var prior = {
label: 'Prior block',
// value not a valid template selection, chosen below by setting templateName
list: [{ label: 'Prior block settings', value: 'prior', selected: true }]
};
// Arrays of objects are annoying to check
if (!blockGroup.some(function(bg) {
return bg.label === prior.label;
})) {
blockGroup.push(prior);
}
 
// Always ensure proper template exists/is selected when switching modes
if (partialBox) {
Twinkle.block.blockPresetsInfo.prior.templateName = Morebits.string.isInfinity(Twinkle.block.currentBlockInfo.expiry) ? 'uw-pblockindef' : 'uw-pblock';
} else {
if (!Twinkle.block.isRegistered) {
Twinkle.block.blockPresetsInfo.prior.templateName = 'uw-ablock';
} else {
Twinkle.block.blockPresetsInfo.prior.templateName = Morebits.string.isInfinity(Twinkle.block.currentBlockInfo.expiry) ? 'uw-blockindef' : 'uw-block';
}
}
}
 
// Can be in preset or template field, so the old one in the template
Line 183 ⟶ 218:
 
field_block_options = new Morebits.quickForm.element({ type: 'field', label: 'Block options', name: 'field_block_options' });
field_block_options.append({ type: 'div', name: 'hasblocklog', label: ' ' });
field_block_options.append({ type: 'div', name: 'currentblock', label: ' ' });
field_block_options.append({ type: 'div', name: 'hasblocklog', label: ' ' });
field_block_options.append({
type: 'select',
Line 546 ⟶ 581:
} else {
$form.find('fieldset[name="field_template_options"]').hide();
}
 
if (Twinkle.block.hasBlockLog) {
var $blockloglink = $('<a target="_blank" href="' + mw.util.getUrl('Special:Log', {action: 'view', page: mw.config.get('wgRelevantUserName'), type: 'block'}) + '">block log</a>)');
 
Morebits.status.init($('div[name="hasblocklog"] span').last()[0]);
Morebits.status.warn('This user has been blocked in the past', $blockloglink[0]);
}
 
if (Twinkle.block.currentBlockInfo) {
Morebits.status.init($('div[name="currentblock"] span').last()[0]);
// list=blocks without bkprops (as we do in fetchUerInfo)
// returns partial: '' if the user is partially blocked
var statusStr = relevantUserName + ' is ' + (Twinkle.block.currentBlockInfo.partial === '' ? 'partially blocked' : 'blocked sitewide');
if (Twinkle.block.currentBlockInfo.expiry === 'infinity') {
statusStr += ' (indefindefinite)';
} else if (new Morebits.date(Twinkle.block.currentBlockInfo.expiry).isValid()) {
statusStr += ' (expires ' + new Morebits.date(Twinkle.block.currentBlockInfo.expiry).calendar('utc') + ')';
Line 571 ⟶ 597:
infoStr += ', converting it to a sitewide block';
}
infoStr += '.';
Morebits.status.warn(statusStr, infoStr);
 
// Default to the current block conditions on intial form generation
Twinkle.block.callback.update_form(e, Twinkle.block.currentBlockInfo);
}
 
if (Twinkle.block.hasBlockLog) {
// make sure all the fields are correct based on defaults
var $blockloglink = $('<a target="_blank" href="' + mw.util.getUrl('Special:Log', {action: 'view', page: mw.config.get('wgRelevantUserName'), type: 'block'}) + '">block log</a>)');
 
Morebits.status.init($('div[name="hasblocklog"] span').last()[0]);
Morebits.status.warn(Twinkle.block.currentBlockInfo ? 'Previous blocks' : 'This user has been blocked in the past', $blockloglink[0]);
}
 
// Make sure all the fields are correct based on initial defaults
if (blockBox) {
Twinkle.block.callback.change_preset(e);
Line 1,494 ⟶ 1,530:
} else {
form.reason.value = data.reason || '';
}
 
// Clear and/or set any partial page or namespace restrictions
if (form.pagerestrictions) {
var $pageSelect = $(form).find('[name=pagerestrictions]');
var $namespaceSelect = $(form).find('[name=namespacerestrictions]');
 
// Respect useInitialOptions by clearing data when switching presets
// In practice, this will always clear, since no partial presets use it
if (!data.useInitialOptions) {
$pageSelect.val(null).trigger('change');
$namespaceSelect.val(null).trigger('change');
}
 
// Add any preset options; in practice, just used for prior block settings
if (data.restrictions) {
if (data.restrictions.pages && !$pageSelect.val().length) {
var pages = data.restrictions.pages.map(function(pr) {
return pr.title;
});
// since page restrictions use an ajax source, we
// short-circuit that and just add a new option
pages.forEach(function(page) {
if (!$pageSelect.find("option[value='" + $.escapeSelector(page) + "']").length) {
var newOption = new Option(page, page, true, true);
$pageSelect.append(newOption);
}
});
$pageSelect.val($pageSelect.val().concat(pages)).trigger('change');
}
if (data.restrictions.namespaces) {
$namespaceSelect.val($namespaceSelect.val().concat(data.restrictions.namespaces)).trigger('change');
}
}
}
};
Line 1,823 ⟶ 1,893:
 
Twinkle.block.callback.main = function twinkleblockcallbackMain(pageobj) {
var textparams = pageobj.getPageTextgetCallbackParameters(),
paramsdate = new Morebits.date(pageobj.getCallbackParametersgetLoadTime()),
messageData = params.messageData,
text;
date = new Morebits.date(pageobj.getLoadTime());
 
var dateHeaderRegex = date.monthHeaderRegex(), dateHeaderRegexLast, dateHeaderRegexResult;
while ((dateHeaderRegexLast = dateHeaderRegex.exec(text)) !== null) {
dateHeaderRegexResult = dateHeaderRegexLast;
}
// If dateHeaderRegexResult is null then lastHeaderIndex is never checked. If it is not null but
// \n== is not found, then the date header must be at the very start of the page. lastIndexOf
// returns -1 in this case, so lastHeaderIndex gets set to 0 as desired.
var lastHeaderIndex = text.lastIndexOf('\n==') + 1;
 
if (text.length > 0) {
text += '\n\n';
}
 
params.indefinite = Morebits.string.isInfinity(params.expiry);
Line 1,846 ⟶ 1,903:
Morebits.status.info('Info', 'Blanking talk page per preferences and creating a new level 2 heading for the date');
text = date.monthHeader() + '\n';
} else {
} else if (!dateHeaderRegexResult || dateHeaderRegexResult.index !== lastHeaderIndex) {
text = pageobj.getPageText();
Morebits.status.info('Info', 'Will create a new level 2 heading for the date, as none was found for this month');
 
text += date.monthHeader() + '\n';
var dateHeaderRegex = date.monthHeaderRegex(), dateHeaderRegexLast, dateHeaderRegexResult;
while ((dateHeaderRegexLast = dateHeaderRegex.exec(text)) !== null) {
dateHeaderRegexResult = dateHeaderRegexLast;
}
// If dateHeaderRegexResult is null then lastHeaderIndex is never checked. If it is not null but
// \n== is not found, then the date header must be at the very start of the page. lastIndexOf
// returns -1 in this case, so lastHeaderIndex gets set to 0 as desired.
var lastHeaderIndex = text.lastIndexOf('\n==') + 1;
 
if (text.length > 0) {
text += '\n\n';
}
 
if (!dateHeaderRegexResult || dateHeaderRegexResult.index !== lastHeaderIndex) {
Morebits.status.info('Info', 'Will create a new level 2 heading for the date, as none was found for this month');
text += date.monthHeader() + '\n';
}
}