Skip to content

Commit

Permalink
Support batch requested moves (#1888)
Browse files Browse the repository at this point in the history
* Update morebits.js

* Update morebits.js

* Update twinklexfd.js

* Update twinklexfd.js

* Update twinklexfd.js

* Update twinklexfd.js

* Update morebits.js

* Update twinklexfd.js

* always default to the non talk page

---------

Co-authored-by: NovemLinguae <[email protected]>
  • Loading branch information
nardog and NovemLinguae authored Nov 19, 2024
1 parent 9b2ecba commit e0e1b75
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 44 deletions.
46 changes: 34 additions & 12 deletions modules/twinklexfd.js
Original file line number Diff line number Diff line change
Expand Up @@ -671,7 +671,7 @@ Twinkle.xfd.callback.change_category = function twinklexfdCallbackChangeCategory
old_area.parentNode.replaceChild(work_area, old_area);
break;

case 'rm':
case 'rm': {
work_area = new Morebits.quickForm.element({
type: 'field',
label: 'Requested moves',
Expand All @@ -687,7 +687,8 @@ Twinkle.xfd.callback.change_category = function twinklexfdCallbackChangeCategory
tooltip: 'Use this option when you are unable to perform this uncontroversial move yourself because of a technical reason (e.g. a page already exists at the new title, or the page is protected)',
checked: false,
event: function() {
form.newname.required = this.checked;
$('input[name="newname"]', form).prop('required', this.checked);
$('input[type="button"][value="more"]', form)[0].sublist.inputs[1].required = this.checked;
},
subgroup: {
type: 'checkbox',
Expand All @@ -705,16 +706,32 @@ Twinkle.xfd.callback.change_category = function twinklexfdCallbackChangeCategory
]
});
work_area.append({
type: 'input',
name: 'newname',
label: 'New title:',
tooltip: 'Required for technical requests. Otherwise, if unsure of the appropriate title, you may leave it blank.'
type: 'dyninput',
inputs: [
{
label: 'From:',
name: 'currentname',
required: true
},
{
label: 'To:',
name: 'newname',
tooltip: 'Required for technical requests. Otherwise, if unsure of the appropriate title, you may leave it blank.'
}
],
min: 1
});

appendReasonBox();
work_area = work_area.render();
old_area.parentNode.replaceChild(work_area, old_area);

const currentNonTalkPage = Morebits.pageNameNorm
.replace(/^Talk:/, '')
.replace(/^([A-Za-z]*) talk:/, '$1:');
form.currentname.value = currentNonTalkPage;
break;
}

default:
work_area = new Morebits.quickForm.element({
Expand Down Expand Up @@ -766,12 +783,17 @@ Twinkle.xfd.callbacks = {
// U+00A0 NO-BREAK SPACE; U+2013 EN RULE
}
if (venue === 'rm') {
// even if invoked from talk page, propose the subject page for move
var pageName = new mw.Title(Morebits.pageNameNorm).getSubjectPage().toText();
var rmtrDiscuss = params['rmtr-discuss'] ? '|discuss=no' : '';
var rmtr = '{{subst:RMassist|1=' + pageName + '|2=' + params.newname + rmtrDiscuss + '|reason=' + params.reason + '}}';
var requestedMove = '{{subst:Requested move|current1=' + pageName + '|new1=' + params.newname + '|reason=' + params.reason + '}}';
return params.rmtr ? rmtr : requestedMove;
if (params.rmtr) {
var rmtrDiscuss = params['rmtr-discuss'] ? '|discuss=no' : '';
return params.currentname
.map((currentname, i) => `{{subst:RMassist|1=${currentname}|2=${params.newname[i]}${rmtrDiscuss}|reason=${params.reason}}}`)
.join('\n');
}
return `{{subst:Requested move${
params.currentname
.map((currentname, i) => `|current${i + 1}=${currentname}|new${i + 1}=${params.newname[i]}`)
.join('')
}|reason=${params.reason}}}`;
}

var text = '{{subst:' + venue + '2';
Expand Down
89 changes: 57 additions & 32 deletions morebits.js
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ Morebits.quickForm.prototype.append = function QuickFormAppend(data) {
* - `number`: A number input box.
* - Attributes: Everything the text `input` has, as well as: min, max, step, list
* - `dyninput`: A set of text boxes with "Remove" buttons and an "Add" button.
* - Attributes: name, label, min, max, sublabel, value, size, maxlength, event
* - Attributes: name, label, min, max, inputs, sublabel, value, size, maxlength, event
* - `hidden`: An invisible form field.
* - Attributes: name, value
* - `header`: A level 5 header.
Expand All @@ -371,7 +371,7 @@ Morebits.quickForm.prototype.append = function QuickFormAppend(data) {
* There is some difference on how types handle the `label` attribute:
* - `div`, `select`, `field`, `checkbox`/`radio`, `input`, `textarea`, `header`, and `dyninput` can accept an array of items,
* and the label item(s) can be `Element`s.
* - `option`, `optgroup`, `_dyninput_element`, `submit`, and `button` accept only a single string.
* - `option`, `optgroup`, `_dyninput_cell`, `submit`, and `button` accept only a single string.
*
* @memberof Morebits.quickForm
* @class
Expand Down Expand Up @@ -731,14 +731,17 @@ Morebits.quickForm.element.prototype.compute = function QuickFormElementCompute(
var moreButton = more[1];

var sublist = {
type: '_dyninput_element',
label: data.sublabel || data.label,
name: data.name,
value: data.value,
size: data.size,
type: '_dyninput_row',
remove: false,
maxlength: data.maxlength,
event: data.event
event: data.event,
inputs: data.inputs || [{
// compatibility
label: data.sublabel || data.label,
name: data.name,
value: data.value,
size: data.size
}]
};

for (i = 0; i < min; ++i) {
Expand All @@ -754,31 +757,13 @@ Morebits.quickForm.element.prototype.compute = function QuickFormElementCompute(
moreButton.max = max - min;
moreButton.counter = 0;
break;
case '_dyninput_element': // Private, similar to normal input
case '_dyninput_row': // Private
node = document.createElement('div');

if (data.label) {
label = node.appendChild(document.createElement('label'));
label.appendChild(document.createTextNode(data.label));
label.setAttribute('for', id);
label.style.marginRight = '3px';
}

subnode = node.appendChild(document.createElement('input'));
if (data.value) {
subnode.setAttribute('value', data.value);
}
subnode.setAttribute('name', data.name);
subnode.setAttribute('type', 'text');
if (data.size) {
subnode.setAttribute('size', data.size);
}
if (data.maxlength) {
subnode.setAttribute('maxlength', data.maxlength);
}
if (data.event) {
subnode.addEventListener('keyup', data.event, false);
}
data.inputs.forEach(function(subdata) {
var cell = new Morebits.quickForm.element($.extend(subdata, { type: '_dyninput_cell' }));
node.appendChild(cell.render());
});
if (data.remove) {
var remove = this.compute({
type: 'button',
Expand All @@ -801,6 +786,41 @@ Morebits.quickForm.element.prototype.compute = function QuickFormElementCompute(
removeButton.morebutton = data.morebutton;
}
break;
case '_dyninput_cell': // Private, similar to normal input
node = document.createElement('span');

if (data.label) {
label = node.appendChild(document.createElement('label'));
label.appendChild(document.createTextNode(data.label));
label.setAttribute('for', id + '_input');
label.style.marginRight = '3px';
}

subnode = node.appendChild(document.createElement('input'));
subnode.setAttribute('id', id + '_input');
if (data.value) {
subnode.setAttribute('value', data.value);
}
subnode.setAttribute('name', data.name);
subnode.setAttribute('type', 'text');
subnode.setAttribute('data-dyninput', 'data-dyninput');
if (data.size) {
subnode.setAttribute('size', data.size);
}
if (data.maxlength) {
subnode.setAttribute('maxlength', data.maxlength);
}
if (data.required) {
subnode.setAttribute('required', 'required');
}
if (data.disabled) {
subnode.setAttribute('required', 'disabled');
}
if (data.event) {
subnode.addEventListener('keyup', data.event, false);
}
node.style.marginRight = '3px';
break;
case 'hidden':
node = document.createElement('input');
node.setAttribute('type', 'hidden');
Expand Down Expand Up @@ -980,7 +1000,12 @@ Morebits.quickForm.getInputData = function(form) {
break;
case 'text': // falls through
case 'textarea':
result[fieldNameNorm] = field.value.trim();
if (field.dataset.dyninput) {
result[fieldNameNorm] = result[fieldNameNorm] || [];
result[fieldNameNorm].push(field.value.trim());
} else {
result[fieldNameNorm] = field.value.trim();
}
break;
default: // could be select-one, date, number, email, etc
if (field.value) {
Expand Down

0 comments on commit e0e1b75

Please sign in to comment.