Skip to content

Commit

Permalink
Merge branch 'master' into rusty
Browse files Browse the repository at this point in the history
  • Loading branch information
RustyCat-1 authored Oct 16, 2024
2 parents 533633c + 3425932 commit 4e3d91a
Show file tree
Hide file tree
Showing 11 changed files with 88 additions and 61 deletions.
6 changes: 0 additions & 6 deletions .github/dependabot.yml

This file was deleted.

6 changes: 3 additions & 3 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
Expand All @@ -45,7 +45,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
uses: github/codeql-action/autobuild@v3

# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
Expand All @@ -59,4 +59,4 @@ jobs:
# make release

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
uses: github/codeql-action/analyze@v3
5 changes: 3 additions & 2 deletions DEVELOPER.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,12 @@ Every time:

### Dependencies

All the dependencies that Twinkle uses are JavaScript **dev** dependencies. They are not used at all on-wiki and are just used during development. Here's what they are and what they do. This may help with evaluating dependabot patches (dependabot is a GitHub bot that helps keep libraries up to date by submitting pull requests).
All the dependencies that Twinkle uses are JavaScript **dev** dependencies. They are not used at all on-wiki and are just used during development. Here's what they are and what they do.

- eslint - Used by continuous integration for enforcing code linting rules.
- jest - Used by continuous integration for unit testing.
- jest-environment-jsdom - Needed for Jest to work.
- mock-mediawiki - Used by continuous integration for unit testing.
- mwn - Used when you run `npm start`. `npm start` is what enables localhost testing.
- Everything else - Dependabot will not usually try to update these unless one of the 5 above dependencies gets out of date. It is probably best to update the above dependencies instead.

When updating dependencies, CI should take care of testing most of that. Manually testing `npm start` should be the only additional check needed.
14 changes: 8 additions & 6 deletions modules/friendlytag.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
*/

Twinkle.tag = function friendlytag() {
// redirect tagging
if (Morebits.isPageRedirect()) {
// redirect tagging (exclude category redirects, which are all soft redirects and so shouldn't be tagged with rcats)
if (Morebits.isPageRedirect() && mw.config.get('wgNamespaceNumber') !== 14) {
Twinkle.tag.mode = 'redirect';
Twinkle.addPortletLink(Twinkle.tag.callback, 'Tag', 'friendly-tag', 'Tag redirect');
// file tagging
Expand Down Expand Up @@ -315,7 +315,7 @@ Twinkle.tag.callback = function friendlytagCallback() {

// break out on encountering the first heading, which means we are no
// longer in the lead section
if (e.tagName === 'H2') {
if (e.classList.contains('mw-heading')) {
return false;
}

Expand Down Expand Up @@ -837,6 +837,8 @@ Twinkle.tag.article.tagList = {
{ tag: 'BLP sources', description: 'BLP that needs additional references or sources for verification' },
{ tag: 'BLP unreferenced', description: 'BLP does not cite any sources at all (use BLP PROD instead for new articles)' },
{ tag: 'More citations needed', description: 'needs additional references or sources for verification' },
{ tag: 'No significant coverage', description: 'does not cite any sources containing significant coverage' },
{ tag: 'No significant coverage (sports)', description: 'sports biography that does not cite any sources containing significant coverage' },
{ tag: 'One source', description: 'relies largely or entirely on a single source' },
{ tag: 'Original research', description: 'contains original research' },
{ tag: 'Primary sources', description: 'relies too much on references to primary sources, and needs secondary sources' },
Expand Down Expand Up @@ -1444,13 +1446,13 @@ Twinkle.tag.callbacks = {

var text, summary;
if (params.tags.indexOf('Rough translation') !== -1) {
templateText = '{{subst:duflu|pg=' + Morebits.pageNameNorm + '|Language=' +
templateText = '{{subst:Dual fluency request|pg=' + Morebits.pageNameNorm + '|Language=' +
(lang || 'uncertain') + '|Comments=' + reason.trim() + '}} ~~~~';
// Place in section == Translated pages that could still use some cleanup ==
text = old_text + '\n\n' + templateText;
summary = 'Translation cleanup requested on ';
} else if (params.tags.indexOf('Not English') !== -1) {
templateText = '{{subst:needtrans|pg=' + Morebits.pageNameNorm + '|Language=' +
templateText = '{{subst:Translation request|pg=' + Morebits.pageNameNorm + '|Language=' +
(lang || 'uncertain') + '|Comments=' + reason.trim() + '}} ~~~~';
// Place in section == Pages for consideration ==
text = old_text.replace(/\n+(==\s?Translated pages that could still use some cleanup\s?==)/,
Expand Down Expand Up @@ -1548,7 +1550,7 @@ Twinkle.tag.callbacks = {
});
pages.forEach(function(page) {
var removed = false;
page.linkshere.forEach(function(el) {
page.linkshere.concat({title: page.title}).forEach(function(el) {
var tag = el.title.slice(9);
var tag_re = new RegExp('\\{\\{' + Morebits.pageNameRegex(tag) + '\\s*(\\|[^}]*)?\\}\\}\\n?');
if (tag_re.test(pageText)) {
Expand Down
61 changes: 41 additions & 20 deletions modules/friendlywelcome.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ Twinkle.welcome.callback = function friendlywelcomeCallback(uid) {
event: Twinkle.welcome.populateWelcomeList,
list: [
{ type: 'option', value: 'standard', label: 'Standard welcomes', selected: !mw.util.isIPAddress(mw.config.get('wgRelevantUserName')) },
{ type: 'option', value: 'anonymous', label: 'IP user welcomes', selected: mw.util.isIPAddress(mw.config.get('wgRelevantUserName')) },
{ type: 'option', value: 'unregistered', label: 'IP user welcomes', selected: mw.util.isIPAddress(mw.config.get('wgRelevantUserName')) },
{ type: 'option', value: 'wikiProject', label: 'WikiProject welcomes' },
{ type: 'option', value: 'nonEnglish', label: 'Non-English welcomes' }
]
Expand Down Expand Up @@ -183,7 +183,7 @@ Twinkle.welcome.populateWelcomeList = function(e) {

var container = new Morebits.quickForm.element({ type: 'fragment' });

if ((type === 'standard' || type === 'anonymous') && Twinkle.getPref('customWelcomeList').length) {
if ((type === 'standard' || type === 'unregistered') && Twinkle.getPref('customWelcomeList').length) {
container.append({ type: 'header', label: 'Custom welcome templates' });
container.append({
type: 'radio',
Expand Down Expand Up @@ -275,6 +275,10 @@ Twinkle.welcome.templates = {
'welcome non-latin': {
description: 'welcome for users with a username containing non-Latin characters',
syntax: '{{subst:welcome non-latin|$USERNAME$}} ~~~~'
},
'welcome mentor': {
description: 'welcome for mentor users to give to their mentees',
syntax: '{{subst:mentor welcome|$USERNAME$}} ~~~~'
}
},

Expand Down Expand Up @@ -341,37 +345,42 @@ Twinkle.welcome.templates = {
}
},

anonymous: {
'Anonymous user welcome templates': {
'welcome-anon': {
description: 'for anonymous users; encourages creating an account',
unregistered: {
'Unregistered user welcome templates': {
'welcome-unregistered': {
description: 'for unregistered users; encourages creating an account',
linkedArticle: true,
syntax: '{{subst:welcome-anon|art=$ARTICLE$}} ~~~~'
syntax: '{{subst:welcome-unregistered|art=$ARTICLE$}} ~~~~'
},
'thanks': {
description: 'for anonymous users; short; encourages creating an account',
description: 'for unregistered users; short; encourages creating an account',
linkedArticle: true,
syntax: '== Welcome! ==\n{{subst:thanks|page=$ARTICLE$}} ~~~~'
},
'welcome-anon-test': {
description: 'for anonymous users who have performed test edits',
'welcome-unregistered-test': {
description: 'for unregistered users who have performed test edits',
linkedArticle: true,
syntax: '{{subst:welcome-unregistered-test|$ARTICLE$|$USERNAME$}} ~~~~'
},
'welcome-unregistered-unconstructive': {
description: 'for unregistered users who have vandalized or made unhelpful edits',
linkedArticle: true,
syntax: '{{subst:welcome-anon-test|$ARTICLE$|$USERNAME$}} ~~~~'
syntax: '{{subst:welcome-unregistered-unconstructive|$ARTICLE$|$USERNAME$}}'
},
'welcome-anon-unconstructive': {
description: 'for anonymous users who have vandalized or made unhelpful edits',
'welcome-unregistered-constructive': {
description: 'for unregistered users who fight vandalism or edit constructively',
linkedArticle: true,
syntax: '{{subst:welcome-anon-unconstructive|$ARTICLE$|$USERNAME$}}'
syntax: '{{subst:welcome-unregistered-constructive|art=$ARTICLE$}}'
},
'welcome-anon-constructive': {
description: 'for anonymous users who fight vandalism or edit constructively',
'welcome-unregistered-delete': {
description: 'for unregistered users who have removed content from pages',
linkedArticle: true,
syntax: '{{subst:welcome-anon-constructive|art=$ARTICLE$}}'
syntax: '{{subst:welcome-unregistered-delete|$ARTICLE$|$USERNAME$}} ~~~~'
},
'welcome-anon-delete': {
description: 'for anonymous users who have removed content from pages',
'welcome-unregistered-unsourced': {
description: 'for anonymous users who have added unsourced content',
linkedArticle: true,
syntax: '{{subst:welcome-anon-delete|$ARTICLE$|$USERNAME$}} ~~~~'
syntax: '{{subst:welcome-unregistered-unsourced|$ARTICLE$|$USERNAME$}}'
}
}
},
Expand Down Expand Up @@ -534,6 +543,18 @@ Twinkle.welcome.templates = {
description: 'welcome for users whose first language appears to be Hebrew',
syntax: '{{subst:welcomeen-he}}'
},
'welcomeen-hi': {
description: 'welcome for users whose first language appears to be Hindi',
syntax: '{{subst:welcomeen-hi}}'
},
'welcomeen-id': {
description: 'welcome for users whose first language appears to be Indonesian',
syntax: '{{subst:welcomeen-id}}'
},
'welcomeen-it': {
description: 'welcome for users whose first language appears to be Italian',
syntax: '{{subst:welcomeen-it}}'
},
'welcomeen-ja': {
description: 'welcome for users whose first language appears to be Japanese',
syntax: '{{subst:welcomeen-ja}}'
Expand Down
3 changes: 2 additions & 1 deletion modules/twinklearv.js
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,7 @@ Twinkle.arv.callback.evaluate = function(e) {
// Report inappropriate username
case 'username':
types = form.getChecked('arvtype').map(Morebits.string.toLowerCaseFirstChar);
var censorUsername = types.includes('offensive'); // check if the username is marked offensive

// generate human-readable string, e.g. "misleading and promotional username"
if (types.length <= 2) {
Expand Down Expand Up @@ -640,7 +641,7 @@ Twinkle.arv.callback.evaluate = function(e) {
return;
}
uaaPage.getStatusElement().status('Adding new report...');
uaaPage.setEditSummary('Reporting [[Special:Contributions/' + uid + '|' + uid + ']].');
uaaPage.setEditSummary('Reporting ' + (censorUsername ? 'an offensive username.' : '[[Special:Contributions/' + uid + '|' + uid + ']].'));
uaaPage.setChangeTags(Twinkle.changeTags);

// Blank newline per [[Special:Permalink/996949310#Spacing]]; see also [[WP:LISTGAP]] and [[WP:INDENTGAP]]
Expand Down
34 changes: 17 additions & 17 deletions modules/twinkleblock.js
Original file line number Diff line number Diff line change
Expand Up @@ -815,13 +815,13 @@ Twinkle.block.callback.change_action = function twinkleblockCallbackChangeAction
* autoblock: <autoblock any IP addresses used (for registered users only)>
* disabletalk: <disable user from editing their own talk page while blocked>
* expiry: <string - expiry timestamp, can include relative times like "5 months", "2 weeks" etc>
* forAnonOnly: <show block option in the interface only if the relevant user is an IP>
* forUnregisteredOnly: <show block option in the interface only if the relevant user is an IP>
* forRegisteredOnly: <show block option in the interface only if the relevant user is registered>
* label: <string - label for the option of the dropdown in the interface (keep brief)>
* noemail: prevent the user from sending email through Special:Emailuser
* pageParam: <set if the associated block template accepts a page parameter>
* prependReason: <string - prepends the value of 'reason' to the end of the existing reason, namely for when revoking talk page access>
* nocreate: <block account creation from the user's IP (for anonymous users only)>
* nocreate: <block account creation from the user's IP (for unregistered users only)>
* nonstandard: <template does not conform to stewardship of WikiProject User Warnings and may not accept standard parameters>
* reason: <string - block rationale, as would appear in the block log,
* and the edit summary for when adding block template, unless 'summary' is set>
Expand All @@ -839,15 +839,15 @@ Twinkle.block.callback.change_action = function twinkleblockCallbackChangeAction
Twinkle.block.blockPresetsInfo = {
'anonblock': {
expiry: '31 hours',
forAnonOnly: true,
forUnregisteredOnly: true,
nocreate: true,
nonstandard: true,
reason: '{{anonblock}}',
sig: '~~~~'
},
'anonblock - school': {
expiry: '36 hours',
forAnonOnly: true,
forUnregisteredOnly: true,
nocreate: true,
nonstandard: true,
reason: '{{anonblock}} <!-- Likely a school based on behavioral evidence -->',
Expand All @@ -856,7 +856,7 @@ Twinkle.block.blockPresetsInfo = {
},
'blocked proxy': {
expiry: '1 year',
forAnonOnly: true,
forUnregisteredOnly: true,
nocreate: true,
nonstandard: true,
hardblock: true,
Expand All @@ -865,7 +865,7 @@ Twinkle.block.blockPresetsInfo = {
},
'CheckUser block': {
expiry: '1 week',
forAnonOnly: true,
forUnregisteredOnly: true,
nocreate: true,
nonstandard: true,
reason: '{{CheckUser block}}',
Expand All @@ -881,15 +881,15 @@ Twinkle.block.blockPresetsInfo = {
sig: '~~~~'
},
'checkuserblock-wide': {
forAnonOnly: true,
forUnregisteredOnly: true,
nocreate: true,
nonstandard: true,
reason: '{{checkuserblock-wide}}',
sig: '~~~~'
},
'colocationwebhost': {
expiry: '1 year',
forAnonOnly: true,
forUnregisteredOnly: true,
nonstandard: true,
reason: '{{colocationwebhost}}',
sig: null
Expand All @@ -903,14 +903,14 @@ Twinkle.block.blockPresetsInfo = {
sig: '~~~~'
},
'school block': {
forAnonOnly: true,
forUnregisteredOnly: true,
nocreate: true,
nonstandard: true,
reason: '{{school block}}',
sig: '~~~~'
},
'spamblacklistblock': {
forAnonOnly: true,
forUnregisteredOnly: true,
expiry: '1 month',
disabletalk: true,
nocreate: true,
Expand All @@ -920,19 +920,19 @@ Twinkle.block.blockPresetsInfo = {
reason: '{{rangeblock}}',
nocreate: true,
nonstandard: true,
forAnonOnly: true,
forUnregisteredOnly: true,
sig: '~~~~'
},
'tor': {
expiry: '1 year',
forAnonOnly: true,
forUnregisteredOnly: true,
nonstandard: true,
reason: '{{Tor}}',
sig: null
},
'webhostblock': {
expiry: '1 year',
forAnonOnly: true,
forUnregisteredOnly: true,
nonstandard: true,
reason: '{{webhostblock}}',
sig: null
Expand All @@ -949,7 +949,7 @@ Twinkle.block.blockPresetsInfo = {
'uw-ablock': {
autoblock: true,
expiry: '31 hours',
forAnonOnly: true,
forUnregisteredOnly: true,
nocreate: true,
pageParam: true,
reasonParam: true,
Expand Down Expand Up @@ -1082,7 +1082,7 @@ Twinkle.block.blockPresetsInfo = {
summary: 'You have been blocked from editing for attempting to [[WP:HARASS|harass]] other users'
},
'uw-ipevadeblock': {
forAnonOnly: true,
forUnregisteredOnly: true,
nocreate: true,
reason: '[[WP:Blocking policy#Evasion of blocks|Block evasion]]',
summary: 'Your IP address has been blocked from editing because it has been used to [[WP:EVADE|evade a previous block]]'
Expand Down Expand Up @@ -1255,7 +1255,7 @@ Twinkle.block.blockPresetsInfo = {
},
'zombie proxy': {
expiry: '1 month',
forAnonOnly: true,
forUnregisteredOnly: true,
nocreate: true,
nonstandard: true,
reason: '{{zombie proxy}}',
Expand Down Expand Up @@ -1485,7 +1485,7 @@ Twinkle.block.callback.filtered_block_groups = function twinkleblockCallbackFilt
var registrationRestrict;
if (blockSettings.forRegisteredOnly) {
registrationRestrict = Twinkle.block.isRegistered;
} else if (blockSettings.forAnonOnly) {
} else if (blockSettings.forUnregisteredOnly) {
registrationRestrict = !Twinkle.block.isRegistered;
} else {
registrationRestrict = true;
Expand Down
Loading

0 comments on commit 4e3d91a

Please sign in to comment.