MediaWiki talk:Gadget-popups.js/Archive 3

Page contents not supported in other languages.
From Wikipedia, the free encyclopedia
Archive 1 Archive 2 Archive 3

Issue if there is a DOM element with id attribute "pg"

Hello,

An user reported on the French wiki that this script is not executed if there is an element with id attribute "pg" in the page.

Indeed, there is an old JavaScript behaviour that exposes the elements with an id to properties of the window object. For instance see this article: DOM: element IDs are global variables, the comments are also worth reading. This behaviour is considered very quirky and kept only for backward compatibility, though it's barely used and its use is discouraged. So, the gadget Popups also uses a window.pg property and looks for it to avoid multiple executions, but as it encounters the one from the legacy JavaScript, the early return is triggered.

A fix would be:

/* Bail if the gadget/script is being loaded twice */
/* An element with id "pg" would add a window.pg property, ignore such property */
if (window.pg && !(window.pg instanceof HTMLElement)) {
	return;
}
/* Export to global context */
window.pg = pg;

Note we are overwriting the legacy window.pg property, but I don't think it would cause trouble, and I suppose globally renaming the Popup's window.pg property would be a much more difficult task.

Regards, Od1n (talk) 13:34, 13 October 2021 (UTC)

This makes sense, can safely be deployed. —TheDJ (talkcontribs) 18:40, 13 October 2021 (UTC)
 Donexaosflux Talk 19:14, 28 October 2021 (UTC)

Question about possible recently deployed changes to Navigation Popups gadget

Historically, as in prior to this fall, the user group names that were displayed were the user group names as defined in the MediaWiki database tables (i.e., sysop, autopatrolled, etc.). More recently, though, the group names display, presumably, from the displayed text at MediaWiki:Group-sysop-member, as in that example. I'm wondering if there has been a recent change to the gadget that made this change and, if so, which change was it? Ordinarily, this would not be a big deal, but we many users use this very helpful gadget on non-Wikimedia projects (notably, Miraheze). As a result, if there was a recently deployed gadget change that caused this, since many Miraheze-hosted wikis use custom groups, they will not necessarily have a [[MediaWiki:Group-groupname-member]] interface message created, resulting in the displayed text in the popup displaying as {Group-member-member} in the navigation popup. Miraheze does use the MirahezeMagic extension that effectively provide for the ability to deploy global interface messages, which is generally done for the standard/default groups, but for the custom group names some wikis will create, it results in an undesirable display.

Assuming there was a recent change to this gadget, I'm wondering if it would, therefore, be possible to have the gadget display the actual groupname rather than the displayed wikitext from the interface message page? Dmehus (talk) 00:47, 14 November 2021 (UTC)

It looks like this was requested in this change. I'm wondering how married to the idea users are with using the displayed text version of the group names rather than the technical group names (as was done previously)? The other changes requested in that request all seem reasonable; it's just that one that I'm wondering if we could possibly revert? Dmehus (talk) 00:54, 14 November 2021 (UTC)
I just had another idea. Perhaps, if not wanting to revert to the technical group names, could we add an if/else statement to the gadget's code whereby if no interface message is defined, it uses the technical group name and, if there is an interface message defined, it uses the displayed text version of the group name? Dmehus (talk) 01:00, 14 November 2021 (UTC)
I liked the tech names better myself actually. As far as foreign projects not liking our local config - they can feel free to fork it to whatever they want. — xaosflux Talk 02:12, 14 November 2021 (UTC)
Thanks for the quick reply! I assume you meant you liked the localised group names better than the tech group names? As to forking the gadget, yeah, I was trying to avoid having to fork the gadget, so as to maintain and update only one codebase. What about the alternate solution, of having the gadget perform a check to see if a local interface message for the group name exists and, if no, then it uses the tech group name rather than the localised group name? Dmehus (talk) 17:04, 14 November 2021 (UTC)
No, for example I prefer "sysop" to {{int:Group-sysop-member}} - but I think I'm in the minority. — xaosflux Talk 17:13, 14 November 2021 (UTC)
It would probably make it even slower, but feel free to mock up, test, and propose a code update if you would like. — xaosflux Talk 17:13, 14 November 2021 (UTC)
I don’t think there’s a considerable time penalty in using mw.Message.exists() as it runs entirely on the client side. I think the following change could work (although I haven’t tested it):
@@ -4221,4236 +4221,4234 @@
 		if( user.groups ) {
 			user.groups.forEach( function ( groupName ) {
 				if( ["*", "user", "autoconfirmed", "extendedconfirmed"].indexOf( groupName ) === -1 ) {
-					ret.push( pg.escapeQuotesHTML(
-						mw.message( 'group-' + groupName + '-member', user.gender ).text()
-					) );
+					var msg = mw.message( 'group-' + groupName + '-member', user.gender );
+					ret.push( pg.escapeQuotesHTML( msg.exists() ? msg.text() : groupName ) );
 				}
 			} );
 		}
 		if( globaluserinfo && globaluserinfo.groups ) {
 			globaluserinfo.groups.forEach( function ( groupName ) {
-				ret.push( '<i>'+pg.escapeQuotesHTML(
-					mw.message( 'group-' + groupName + '-member', user.gender ).text()
-				)+'</i>' );
+				var msg = mw.message( 'group-' + groupName + '-member', user.gender );
+				ret.push( '<i>' + pg.escapeQuotesHTML( msg.exists() ? msg.text() : groupName ) + '</i>' );
 			} );
 		}
Also,

As far as foreign projects not liking our local config - they can feel free to fork it to whatever they want.

Sorry, but this is the worst possible advice. Forks most likely won’t be updated not only with new features, but not even with fixes made necessary by changes in MediaWiki (or its extensions). This means that the forks will break sooner or later, causing bad user experience and log spam if client-side errors are logged (as is the case on Wikimedia wikis). A much better solution would be a configuration setting, which could be set on a site level with a much lower maintenance cost, and you could even easily set it for yourself to return to the technical names here on the English Wikipedia. —Tacsipacsi (talk) 20:42, 14 November 2021 (UTC)
Yeah, but we basically have no reason to care about non-WMF wikis, especially those hosted at another server farm which have their own support networks. That's besides the obvious security issues of pulling in JavaScript from a non-"local" network... Miraheze should be interested in blocking such pulls. Izno (talk) 23:49, 27 November 2021 (UTC)

XSS vulnerabilities fixed

Earlier on I fixed four separate XSS vulnerabilities in this gadget. The first three of them were due to the link text in the generalLink function not being escaped, which I fixed here, and the fourth is due to not removing user-supplied HTML before generating the box preview on the edit screen, which I fixed here. I also made a few edits escaping outputs that should be escaped, but weren't actually the cause of any vulnerabilities. If anyone notices any problems as a result of these edits, please let me know. All of the vulnerabilities required non-default options, so it is unlikely that many people were affected (especially as the options format seems to have changed, and the documentation doesn't seem to have been updated). Here are the details of each of them:

  1. phab:T297602: If an attacker saves a page with redirect syntax containing a payload like #REDIRECT [[<img src="x" onerror="alert(1)" />]], then when the victim views a popup of that page the attacker's code is run. This requires the popupAppendRedirNavLinks option to be false (the default is true). I fixed this by escaping the link text in generalLink. To avoid breaking existing HTML entities I decoded them before encoding the string again.
  2. (No Phabricator number) The attacker creates a page with a disambiguation template and a link containing an XSS payload, like [[<img/src="x"onerror="alert(1)"/>|Bar]]{{disambiguation}}. When the victim views a popup of this page, the attacker's code is run. This requires the popupFixDabs option to be true (default is false). The root cause is the same as #1 so I didn't file a Phabricator ticket for it.
  3. (No Phabricator number) For this one, all the attacker has to do is create a link to a disambiguation page with an XSS payload in the section link, like [[Foo (disambiguation)#<img/src='x'onerror='alert(1)'/>]]. When the victim hovers over the link, the attacker's code is run. This also requires the popupFixDabs option to be true, and also has the same root cause as #1.
  4. phab:T297560: The attacker saves a page containing a link followed by an XSS payload, like [[Foo]]<img src="x" onerror="alert(1)" />. If the victim edits that page, selects the link and the payload in the edit window, and hovers the mouse over the selection, the attacker's code is run. This requires the popupOnEditSelection option to be set to "boxpreview" (the default is "cursor"). I fixed this by using the same preview-generation code as used elsewhere in the gadget so that user-supplied HTML tags would be stripped.

These four vulnerabilities are the result of an exhaustive analysis of all the possible vulnerable code paths, which took me a couple of weeks on-and-off. If there are any XSS bugs still left in the gadget, then they are not obvious ones. (There are probably still issues with older IE versions, but those are not supported by Mediawiki any more.) In order to avoid issues like this in the future, this gadget could probably use a large-scale refactor to use safer coding idioms, but for now at least there should be no glaring security holes. — Mr. Stradivarius ♪ talk ♪ 15:06, 27 December 2021 (UTC)

Edit request for popupDabRegexp

The current regex does not catch markup like {{dab|geodis}}, as you can see by trying to dabfix this link with Popus: Anjou. The whole regex seems a bit too complicated as it is, so I propose a simpler one, which AFAICT will match all the same things as the current version, plus this false negative.

\{\{\s*(d(ab|isamb(ig(uation)?)?)|(((geo|hn|road?|school|number)dis)|[234][lc][acw]|(road|ship)index))\s*(\|[^}]*)?\}\}|is a .*disambiguation.*page

https://regex101.com/r/elip7e/1 to test.

Assuming there's no issues with this regex, then please change line 7112 to

newOption('popupDabRegexp', '\\{\\{\\s*(d(ab|isamb(ig(uation)?)?)|(((geo|hn|road?|school|number)dis)|[234][lc][acw]|(road|ship)index))\\s*(\\|[^}]*)?\\}\\}|is a .*disambiguation.*page');

-- Tamzin[cetacean needed] (she/they) 21:44, 12 December 2021 (UTC)

 DoneMr. Stradivarius ♪ talk ♪ 02:57, 28 December 2021 (UTC)
Thank you for the request - I've updated the gadget with your regex. Looking at Template:Disambiguation#Variant templates, there are a lot of disambiguation templates that are missed by this regex (and the old one), but this is definitely an improvement. Also, from JavaScript we should be able to use the API to check if the page is a disambiguation page or not without having to parse its wikitext, but that would require larger-scale changes to the code, so this is a good stop-gap solution. — Mr. Stradivarius ♪ talk ♪ 03:04, 28 December 2021 (UTC)
Using the API—this is exactly what I proposed in Wikipedia talk:Tools/Navigation popups#Dab page detection (why do we have two different talk pages for the same gadget?…). —Tacsipacsi (talk) 16:31, 28 December 2021 (UTC)

Prettify the code?

This file has a mix of styles for indentations and spacing, mostly being to avoid spaces and newlines as much as possible, which makes it really difficult to read through and make changes. To make it easier, I suggest we use a tool like prettier for a one-time reformatting to clean code. – SD0001 (talk) 07:03, 25 November 2021 (UTC)

SD0001, if you could send me a pastebin or a raw text file on Discord or by email with what you'd like, I'd be happy to swap it. I looked at the options and was generally bewildered. :) Izno (talk) 01:11, 4 January 2022 (UTC)
Do you just want to do something like this - adding 70000 bytes of whitespace to the source? I really don't want to start seeing white-space wars in javascript files - and especially don't want to hear tab-vs-spaces fights. — xaosflux Talk 02:06, 4 January 2022 (UTC)
If that's what it takes to get this module modernized, I'll take a one-off whitespace addition. Izno (talk) 02:13, 4 January 2022 (UTC)
You can configure Prettier to use tabs, so auto-formatting it wouldn't necessarily mean changing the indentation style. — Mr. Stradivarius ♪ talk ♪ 02:36, 4 January 2022 (UTC)
I would generally support using tabs, since that's the default in CodeEditor these days, but beyond that, I have no strong preference. (And I obviously don't work in JavaScript.) Izno (talk) 01:35, 5 January 2022 (UTC)
I support any changes to improve formatting; the existing poor formatting has certainly slowed me down while reading and changing the script. No preference on tabs vs spaces (and a million programmers howled in the distance). Enterprisey (talk!) 06:26, 5 January 2022 (UTC)
+1 for tabs. Also eliminate double quotes (maybe except where the string includes single)! Nardog (talk) 06:35, 5 January 2022 (UTC)
Note, I'm not opposed to a format update, but don't want to see some format warriors going through scripts that they don't actually maintain themselves to try to enforce their own layout style or start a local indentation holy war! So, that being said - if someone wants an udpate, fork this to your personal sandbox, update it - then drop us an ER :) — xaosflux Talk 14:40, 5 January 2022 (UTC)
I wouldn't mind spaces or double quotes, it just gotta be consistent. I suggest tabs and single only because they already are used in the majority of the code (as well as in MW code). Nardog (talk) 18:47, 5 January 2022 (UTC)
@Izno Here: User:SD0001/popups-prettified.js.
This was generated with npx prettier --use-tabs --single-quote --print-width 100 -w popups.jsSD0001 (talk) 14:54, 6 January 2022 (UTC)
Sanity testing can be done by disabling navpopups and popups, then running in console: importScript('User:SD0001/popups-prettified.js'); importStyleSheet('MediaWiki:Gadget-navpop.css')
Diff will of course be useless. But it can be verified that no functional changes are made by running
# nodejs and npm should be installed. (Easy way: go to play-with-docker.com and run `apk add nodejs npm`)
curl -s https://en.wikipedia.org/wiki/MediaWiki:Gadget-popups.js?action=raw > popups.js
curl -s https://en.wikipedia.org/wiki/User:SD0001/popups-prettified.js?action=raw > popups-prettified.js
npx prettier --use-tabs --single-quote --print-width 100 -w popups.js
diff popups.js popups-prettified.js
SD0001 (talk) 15:01, 6 January 2022 (UTC)
wikEdDiff eats the diff for breakfast. All I see are whitespace improvements and one or two 'normalized' regexes. Izno (talk) 17:47, 6 January 2022 (UTC)
Enqueued for ER, reviewing. — xaosflux Talk 15:02, 6 January 2022 (UTC)
Ran minify script on current and proposed versions, identical output. — xaosflux Talk 15:06, 6 January 2022 (UTC)
 On hold leaving this open for a day to see if there are any other comments, otherwise seems fine and will do. — xaosflux Talk 15:07, 6 January 2022 (UTC)
Prettier is formatting the docstring comments a little awkwardly. For example, take lines 672-682:
	/**
   Creates a new Drag object. This is used to make various DOM elements draggable.
   @constructor
*/
	function Drag() {
		/**
	   Condition to determine whether or not to drag. This function should take one parameter, an Event.
	   To disable this, set it to <code>null</code>.
	   @type Function
	*/
		this.startCondition = null;
It looks like Prettier is trying to preserve the original indentation of the comments, so we get things like the text in the second comment (line 678) being prefixed with a tab and three spaces. This is the same as the original file (line 571) but we probably want to edit these so that they are lined up properly and use only tabs. I'll take a look at this. — Mr. Stradivarius ♪ talk ♪ 14:30, 7 January 2022 (UTC)
Yeah I saw that. The existing doc-comments were of a non-standard format, so it's a GIGO issue. Feel free to switch them over to the standard
    /**
     *
     *
     */
format which prettier purposefully won't do. – SD0001 (talk) 15:28, 7 January 2022 (UTC)
@SD0001: I've manually formatted the docstrings, added some newlines between functions, and split some of the remaining long lines into multiple lines. I formatted the result with Prettier using the options --use-tabs --single-quote --print-width 100 and added it to your sandbox. See the diff with the previous sandbox version and the diff with the live version. — Mr. Stradivarius ♪ talk ♪ 22:08, 7 January 2022 (UTC)
Ran minify on both proposed and usersandbox, identical outputs. — xaosflux Talk 22:22, 7 January 2022 (UTC)
 Done synced in from User:SD0001/popups-prettified.js. — xaosflux Talk 14:38, 10 January 2022 (UTC)

Interface-protected edit request on 29 January 2022

I've got the following error when trying to patrol a page (on Russian wiki):

load.php?modules=ext.gadget.Navigation_popups:133 Uncaught ReferenceError: api is not defined
   at HTMLAnchorElement.a.onclick (load.php?modules=ext.gadget.Navigation_popups:133:197)

I believe the error was introduced by this diff. The following change: [1] in my sandbox version fixed it. Could you push it? Alexei Kopylov (talk) 09:43, 29 January 2022 (UTC)

Confirmed, the suggested change is good and can be deployed. —TheDJ (talkcontribs) 11:04, 2 February 2022 (UTC)
 Donexaosflux Talk 11:32, 2 February 2022 (UTC)

Excluding "named"

I added "named" to the list of things we exclude, revert if this broke anything please! — xaosflux Talk 13:33, 5 May 2022 (UTC)

Display edits for user without registration date

Maybe it is not an issue on enwiki, but on some older sister projects (eg. metawiki, zhwiki), a lot of users registered before 2006 or something does not have the value for the user_registration field (an example), and since the popup gadget associates registration date with edits, their edits count just don't show up at all:

if (user.registration)
	ret.push(
		pg.escapeQuotesHTML(
			(user.editcount ? user.editcount : '0') +
				popupString(' edits since: ') +
				(user.registration ? formattedDate(new Date(user.registration)) : '')
		)
	);

As user.registration is not necessary for older users to have actual edits, I wonder if changing the conditionals, for example using user.editcount, or (either user.registration or user.editcount) as the condition, is possible to fix that? —— Eric LiuTalk 03:42, 17 May 2022 (UTC)

Display equivalent QID

Display and link the QID (in this case Q144), inside unlinked parentheses

I've only just discovered that this page exists.

I've been asking for some time for the popup to display the equivalent QID (i.e. the Wikidata identifier) when used on pages which have one. This will save me (and no doubt others) time and mouse clicks every single day. I've mocked up what I mean in the above image, and put more details on Phabricator, in T243820.

Can someone do that, please? Andy Mabbett (Pigsonthewing); Talk to Andy; Andy's edits 13:30, 3 July 2022 (UTC)

@Pigsonthewing not directly related, but if you do a lot of work with wikidata ID's, this userscript may help you in your workflow: User:Danski454/wikidata Qnum it puts (Qnnn) in plain text next to every article title. — xaosflux Talk 21:43, 6 August 2022 (UTC)
Thank you. I have a script that does that, but I need the functionality in pop-ups specifically. Andy Mabbett (Pigsonthewing); Talk to Andy; Andy's edits 21:53, 6 August 2022 (UTC)

ReferenceError: api is not defined

Hi, when I was debugging another script, I happened to face a ReferenceError at #L8367 in pg.fn.modifyWatchlist.

$.when(
    getMwApi().postWithToken('watch', reqData),
    mw.loader.using(['mediawiki.api', 'mediawiki.jqueryMsg']).then(function () {
        return api.loadMessagesIfMissing([messageName]);
    })
).done(function () {
    mw.notify(mw.message(messageName, title).parseDom());
});

This happened when I unwatched a page via the popup's interface. I didn't scrutinize the source code at all but probably there's no variable substitution for api in the function? Developers might want to check it out. --Dragoniez (talk) 11:52, 8 February 2023 (UTC)

Please replace from line 8366

    mw.loader.using(['mediawiki.api', 'mediawiki.jqueryMsg']).then(function () {
        return api.loadMessagesIfMissing([messageName]);
    })

with

    return getMwApi().loadMessagesIfMissing([messageName]);
This uses the api object fetcher, and removes the loader.using statement for mediawiki.api because that dependency is already enforced at line 7013. —TheDJ (talkcontribs) 14:24, 8 February 2023 (UTC)
TheDJ: Can we remove that loader.using statement entirely? It looks like mediawiki.jqueryMsg is also enforced at 7016. Writ Keeper  14:57, 8 February 2023 (UTC)
Good point. I'd missed that. done —TheDJ (talkcontribs) 15:02, 8 February 2023 (UTC)
Hmm, getting a parsing error complaining about a missing parenthetical that for some reason I can't find. Self-reverted for now. LMK if you can see what I missed. (Also, sidenote: I don't think we can include the "return" or semicolon, since this isn't a standalone line of code, but an argument to a when() function.) Writ Keeper  15:23, 8 February 2023 (UTC)
  • @TheDJ:, @Writ Keeper: Thank you both. I managed to find some time to look into this, and this issue (per se) can be resolved if we replace the whole API call lines as below:
$.when(
    getMwApi().postWithToken('watch', reqData),
    mw.loader.using(['mediawiki.api', 'mediawiki.jqueryMsg']).then(function () {
        return api.loadMessagesIfMissing([messageName]);
    })
).done(function () {
    mw.notify(mw.message(messageName, title).parseDom());
});

getMwApi().postWithToken('watch', reqData).done(function () {
    mw.notify(mw.message(messageName, title).parseDom());
});

But there's another problem, I looked through the code but loadMessagesIfMissing isn't defined anywhere in the script. This must be why Writ Keeper got a parsing error. But, this function is called in line 5110 too.

function fetchUserGroupNames(userinfoResponse) {
    var queryObj = getJsObj(userinfoResponse).query;
    var user = anyChild(queryObj.users);
    var messages = [];
    if (user.groups) {
        user.groups.forEach(function (groupName) {
            if (['*', 'user', 'autoconfirmed', 'extendedconfirmed', 'named'].indexOf(groupName) === -1) {
                messages.push('group-' + groupName + '-member');
            }
        });
    }
    if (queryObj.globaluserinfo && queryObj.globaluserinfo.groups) {
        queryObj.globaluserinfo.groups.forEach(function (groupName) {
            messages.push('group-' + groupName + '-member');
        });
    }
    return getMwApi().loadMessagesIfMissing(messages);
}

I'm pretty sure we'll need time if we try to fix this too, so could we just temporarily resolve the current issue and look into this one later? I currently don't even know what kind of error this one would spit. Thanks. --Dragoniez (talk) 15:41, 8 February 2023 (UTC)

No, loadMessagesIfMissing is a function of the mw.Api object, which is Mediawiki-defined and returned by the getMwApi() function. You can find its definition here: https://doc.wikimedia.org/mediawiki-core/master/js/#!/api/mw.Api.plugin.messages. I suspect the parsing issue I was seeing was just related to the above-mentioned problem with including the return ...; that was persisting unusually strongly through cache refreshes, since it seems to be working now. I'll reinstate the change shortly, if additional testing bears out. Writ Keeper  15:50, 8 February 2023 (UTC)
@Writ Keeper: Sorry I guess I looked at the code too quickly. Shoud've noticed that because getMwApi() initializes a mw.Api() instance. The following worked for me without any error in console:
var api = getMwApi();
$.when(
    api.postWithToken('watch', reqData),
    api.loadMessagesIfMissing([messageName])
).done(function () {
    mw.notify(mw.message(messageName, title).parseDom());
});
--Dragoniez (talk) 15:59, 8 February 2023 (UTC)
Flagging as answered; fix seems to work once return ...; has been removed. Writ Keeper  16:05, 8 February 2023 (UTC)
I noticed today that using popups to unwatch a page from my watchlist once again shows the brief notification pop-up. That hadn't happened for some considerable time, now it's fixed. Thank you. -- Michael Bednarek (talk) 00:56, 9 February 2023 (UTC)

Bug report (diff pages): TypeError: Cannot read properties of null (reading 'indexOf')

I'm seeing around 100 errors a day with the following stack trace on diff pages e.g.https://en.wikipedia.org/w/index.php?diff=1139175290&oldid=1139164047&title=Emily_Ratajkowski

:

at Title.namespaceId https://en.wikipedia.org/w/load.php?lang=en&modules=ext.gadget.Navigation_popups&skin=monobook&version=nxu22:49:957 at isInStrippableNamespace https://en.wikipedia.org/w/load.php?lang=en&modules=ext.gadget.Navigation_popups&skin=monobook&version=nxu22:53:921 at navlinkTag.getPrintFunction https://en.wikipedia.org/w/load.php?lang=en&modules=ext.gadget.Navigation_popups&skin=monobook&version=nxu22:127:213 at navlinkTag.html https://en.wikipedia.org/w/load.php?lang=en&modules=ext.gadget.Navigation_popups&skin=monobook&version=nxu22:123:239 at navlinkStringToHTML https://en.wikipedia.org/w/load.php?lang=en&modules=ext.gadget.Navigation_popups&skin=monobook&version=nxu22:123:111 at pg.structures.menus.popupTopLinks https://en.wikipedia.org/w/load.php?lang=en&modules=ext.gadget.Navigation_popups&skin=monobook&version=nxu22:23:605 at pg.structures.shortmenus.popupTopLinks https://en.wikipedia.org/w/load.php?lang=en&modules=ext.gadget.Navigation_popups&skin=monobook&version=nxu22:23:988 at fillEmptySpans https://en.wikipedia.org/w/load.php?lang=en&modules=ext.gadget.Navigation_popups&skin=monobook&version=nxu22:64:38 at simplePopupContent https://en.wikipedia.org/w/load.php?lang=en&modules=ext.gadget.Navigation_popups&skin=monobook&version=nxu22:6:915 at mouseOverWikiLink2 https://en.wikipedia.org/w/load.php?lang=en&modules=ext.gadget.Navigation_popups&skin=monobook&version=nxu22:6:90

Please let me know if you have any questions. Jon (WMF) (talk) 20:29, 14 February 2023 (UTC)

Interface-protected edit request on 21 February 2023

My request is to add the Yiddish redirect code to the redirLists. That is, after line 5679 in the source ("vi: [r, 'đổi'],"), please add the following line:

yi: [R, 'ווייטערפירן'],

אוהב חכמה (talk) 11:40, 21 February 2023 (UTC)

 Donexaosflux Talk 15:07, 23 February 2023 (UTC)

Refactored generateLink() to not use raw HTML manipulation

Per above the following changes are proposed. This allows for the removal of certain unsafe raw HTML manipulations from the generateLink() function. Sohom (talk) 11:15, 6 December 2023 (UTC)

For testing these changes,
mw.loader.using(['mediawiki.api', 'mediawiki.user', 'mediawiki.util', 'user.options', 'mediawiki.jqueryMsg']).then(function() {
	importScript('w:User:Sohom Datta/other-popups.js');
	importStylesheet('w:MediaWiki:Gadget-navpop.css');
});
should work :) Sohom (talk) 11:19, 6 December 2023 (UTC)
What modules should we be clicking to exercise this part of the code? –Novem Linguae (talk) 16:00, 7 December 2023 (UTC)
This should be a change to the way links are rendered so clicking on the actions and popups menu and making sure the individual entries behave the same should work. Sohom (talk) 20:24, 7 December 2023 (UTC)
  1. This patch has some minor linter errors, but I'll clean that up in my next linter autofixes patch. checkY
  2. {bool} should be {boolean}, I think. ☒N
  3. What does UNSAFE START and UNSAFE END mean? HTML sanitization related, I assume? Consider elaborating on the comment. ☒N
  4. What is the difference between link.text and link.title? Consider elaborating in the comment. ☒N
  5. Looks like this returns null sometimes? Should probably change to @returns {string|null} ☒N
Novem Linguae (talk) 21:36, 7 December 2023 (UTC)
Addressed the issues with the code at User:Sohom Datta/other-popups.js :) Sohom (talk) 22:16, 7 December 2023 (UTC)
 Done. Tested on testwiki, didn't find any issues. Thanks for the patch! –Novem Linguae (talk) 22:50, 7 December 2023 (UTC)

Interface-protected edit request on 3 December 2023

It appears that the Show recent diff module was sending incorrect API params to the API, causing the diff display to fail, the changes below should allow it to be shown again :)

@@ -7869,9 +7869,7 @@ $(function () {
                                action: 'compare',
                                prop: 'ids|title',
                        };
-                       if (article.title) {
-                               params.fromtitle = article.title;
-                       }
+                       params.fromtitle = article.toString();
 
                        switch (diff) {
                                case 'cur':
@@ -7890,10 +7888,8 @@ $(function () {
                                        }
                                        break;
                                case 'prev':
-                                       if (oldid) {
+                                       if (oldid && oldid !== 'cur') {
                                                params.fromrev = oldid;
-                                       } else {
-                                               params.fromtitle;
                                        }
                                        params.torelative = 'prev';
                                        break;

Sohom (talk) 23:25, 3 December 2023 (UTC)

@Sohom Datta so you have a permalink that has the entire exact code you want to replace? — xaosflux Talk 00:08, 4 December 2023 (UTC)
@Xaosflux Special: PermanentLink/1188202247 should be it :) Sohom (talk) 00:13, 4 December 2023 (UTC)
I rebased this here, hopefully correctly :) Got a steps to reproduce if I want to test the before and after? –Novem Linguae (talk) 21:30, 4 December 2023 (UTC)
@Novem Linguae Hover over a link, and mousing over the actions link, and then mouse over to the "Show recent edit" link. If the patch is not applied, it will show the header of the page, if it applied it will show the diff of the most recent edit. Sohom (talk) 21:37, 4 December 2023 (UTC)
 Done Tested, works. Thanks for the patch! –Novem Linguae (talk) 21:49, 4 December 2023 (UTC)

@Sohom Datta I was porting this to plwiki and noticed `fromtitle` don't seem to support sections. Am I correct? If so would probably be good to skip an anchor:

        var fromtitle = article.toString(true);
        if (fromtitle) {
            params.fromtitle = fromtitle;
        }

@Novem Linguae Could you add JSDoc BTW:

/**
 * Load diff data.
 *
 * lets jump through hoops to find the rev ids we need to retrieve.
 *
 * @param {Title} article
 * @param {String} oldid
 * @param {String} diff
 * @param {Navpopup} navpop
 */
function loadDiff(article, oldid, diff, navpop) {

Thanks, Nux (talk) 23:07, 4 December 2023 (UTC)

@Nux Can you reproduce a case where this occurs ? I did test with URL fragments (anchors) but I wasn't able to reproduce any issue. My understanding is that the anchor gets removed globally on line 7453 (quoted below), so it doesn't really matter if we omit anchors or not.
:            // FIXME anchor handling should be done differently with Title object
:			this.article = this.article.removeAnchor();
:
Sohom (talk) 23:31, 4 December 2023 (UTC)
Yeah, no. I just looked at the `Title` class. I was even wondering if sections are at all possible in history. So maybe it doesn't matter. Nux (talk) 23:45, 4 December 2023 (UTC)
For applying the JSDoc comments mentioned by @Nux above. Sohom (talk) 13:58, 5 December 2023 (UTC)
/**
 * Load diff data.
 *
 * lets jump through hoops to find the rev ids we need to retrieve.
 *
 * @param {Title} article
 * @param {String} oldid
 * @param {String} diff
 * @param {Navpopup} navpop
 */
function loadDiff(article, oldid, diff, navpop) {
 Done. Already did a couple hours ago actually :) –Novem Linguae (talk) 19:18, 5 December 2023 (UTC)

ESLint #1

This code could use some linting. I plan to submit a series of edit requests that run a linter (ESLint) on this code. Let's start with this:

https://en.wikipedia.org/w/index.php?title=User%3ANovem_Linguae%2FScripts%2Fpopups.js&diff=1187778611&oldid=1187778525

This adds braces to every if/elseif/else/for/while/do/switch, and fixes tabs/spacing. I did not run any other ESLint rules yet.

The author's original style was to often omit braces and/or put them all on one line. I think most would agree that this decreases readability and can lead to errors. I ran ESLint's auto fix feature, which should be really low risk since it's automated. No opportunity for a human to make a typo. I've tested the changes using the below code in my common.js:

mw.loader.using(['mediawiki.api', 'mediawiki.user', 'mediawiki.util', 'user.options', 'mediawiki.jqueryMsg']).then(function() {
	importStylesheet('w:MediaWiki:Gadget-navpop.css');
	importScript('w:User:Novem Linguae/Scripts/popups.js');
});

The linted code loads without errors, and I tested the Actions -> Revert feature, which works. –Novem Linguae (talk) 10:08, 1 December 2023 (UTC)

I note you can make the change yourself as an iadmin - I have no objections to improving the formatting. Galobtter (talk) 15:14, 1 December 2023 (UTC)
I'm starting off slowly since I'm new to this repo. Now that I have your +1, will self merge in a day if no objections. –Novem Linguae (talk) 19:38, 1 December 2023 (UTC)
Someone giving this gadget some love is appreciated. Izno (talk) 22:49, 1 December 2023 (UTC)
Yes popups doesn't have anyone maintaining it so happy to support any improvements to make it more maintainable. Galobtter (talk) 04:49, 2 December 2023 (UTC)
 DoneNovem Linguae (talk) 18:22, 2 December 2023 (UTC)

Next round of linting

I'll give the above changes a few days to make sure they didn't break anything, then I plan on making the below changes. Please let me know if you have any feedback.

Novem Linguae (talk) 21:05, 2 December 2023 (UTC)

Seems fine imo :) Sohom (talk) 20:02, 3 December 2023 (UTC)
 DoneNovem Linguae (talk) 21:27, 4 December 2023 (UTC)

popupDabRegexp improvement

The popupDabRegexp as it currently stands doesn't capture some disambiguation templates, e.g. {{Place name disambiguation}} and presumably all templates ending in "disambiguation}}". This was raised at Wikipedia talk:Tools/Navigation popups#No dab links when using {{Place name disambiguation}}. After an analysis by User:Tacsipacsi, popupDabRegexp was identified as the culprit. I then added a term to that expression that will capture such category names. I used that modified expression in my popups configuration, and that successfully resolved the problem. I think it would be an improvement if this were the default as coded overleaf. Please change the string after newOption('popupDabRegexp', (line 9069), to

popupDabRegexp='disambiguation\\}\\}|\\{\\{\\s*(d(ab|isamb(ig(uation)?)?)|disambiguation\\}\\}|(((geo|hn|road?|school|number)dis)|[234][lc][acw]|(road|ship)index))\\s*(\\|[^}]*)?\\}\\}|is a .*disambiguation.*page';

The highlighted text is my modification. -- Michael Bednarek (talk) 04:37, 30 October 2023 (UTC)

 Done * Pppery * it has begun... 01:21, 2 November 2023 (UTC)
Thank you, Pppery. However, it seems to me the requested additional term was inserted twice, or am I misreading the diff? -- Michael Bednarek (talk) 02:20, 2 November 2023 (UTC)
Looking at my proposal again, it was me who inserted the term twice. Sigh. -- Michael Bednarek (talk) 02:23, 2 November 2023 (UTC)
It looks like you first added it in a place where it didn't work, then added it again where it did work. I've removed the non-functional copy. * Pppery * it has begun... 02:36, 2 November 2023 (UTC)
Thank you. Apologetically yours, Michael Bednarek (talk) 02:42, 2 November 2023 (UTC)

Docblock cleanup

Ad [2]

@Novem Linguae: Function and Array are object types and written capitalized. (Although the latter should rarely be used, as generally the element type should be indicated, producing string[], number[], any[] etc. instead of Array.) Only string, null, undefined, unknown, any and primitive types are written lower-case. —Tacsipacsi (talk) 22:00, 15 August 2023 (UTC)

 Fixed. Thanks for the code review. I am disappointed in my IDE's linters for allowing me to type that and not putting a little red squiggle under it. –Novem Linguae (talk) 23:52, 15 August 2023 (UTC)
FYI, let f = function() {}; typeof f; in Chrome DevTools console returns "function" not "Function". typeof ['test', 'test'] returns "object" (an "Array" I assume). –Novem Linguae (talk) 13:05, 7 September 2023 (UTC)

Add QID to info line

Please update the code with the version on User:Chlod/popups.js (compare). This is a requested change that's been requested since 2014 (phab:T243820), and a change as small as this deserves to be done quickly after all this time. Please also delete the userspace .js file when done. Thanks! (cc @Pigsonthewing) Chlod (say hi!) 08:45, 15 August 2023 (UTC)

 Done. Thanks for the patch! –Novem Linguae (talk) 11:05, 15 August 2023 (UTC)

Mouse safe zones for popup menus

Please add changes to CSS and JS to make menus in popups more stable (mouse out UX aka safe triangle technique).

Two changes:

  • Minor changes in JS JS diff (basically adds a CSS variable).
  • The extra CSS (CSS diff) creates a trapezoid that gives a safe path from the menu title to the list of links. There are also additional margins that will facilitate e.g. hitting the unfollow link.

CSS works without JS changes, but JS makes width of the trapezoid more stable (especially after i18n/l10n). It was my intention to do as much in CSS as possible. You can see the safe triangle technique in a Tweet.

Kind regards, Nux (talk) 00:11, 11 June 2023 (UTC)

Are you the sole maintainer for this gadget? If not, may want to add some more comments to this code so folks know what's going on. I don't think it's very easy to tell what's going on with that block of CSS just by reading the code. I think a good spot for a big comment that describes how this whole system works ("safe triangle technique") is at the top of the CSS code you're adding. Hope this helps. –Novem Linguae (talk) 04:58, 17 June 2023 (UTC)
@Novem Linguae well in practice nobody else is changing popups much... But I did add some comments see: pl:Gadget-Popups.css. As written there I'm using a trapezoid guide for the cursor, other CSS rules also got their comments. I haven't changed the old CSS (nor old JS) if that what you are referring to. Popups is generally not well documented (probably to save bytes, which used to matter ~10 years ago). Nux (talk) 09:03, 17 June 2023 (UTC)
Novem Linguae, Nux - Looking through the code, the JS change is essentially a variable name change with some small code optimization. The CSS looks like just a few small changes to the resulting function of the menus within the pop-up. I... don't see a reason to oppose the changes -  Done. ~Oshwah~(talk) (contribs) 02:41, 25 July 2023 (UTC)
Thanks. Seems to be working fine :) Nux (talk) 18:45, 25 July 2023 (UTC)

rvslots and edit counter fixes

I've prepped a new version with some minor updates

Thank you. —TheDJ (talkcontribs) 11:38, 12 April 2023 (UTC)

@TheDJ I only had a moment for a quick check, but I think there's an issue accessing a preview of "history" from within the action menu of a popup? I'll try to confirm later, but wanted to put it out there; I presume an issue parsing rvslots stuff. ~ Amory (utc) 12:50, 12 April 2023 (UTC)
@Amorymeltzer: Fixed. —TheDJ (talkcontribs) 13:56, 12 April 2023 (UTC)
 Done. Anyone holler if there're issues. ~ Amory (utc) 14:02, 16 April 2023 (UTC)

Minor formatting bug (with code to fix)

Before proposed change
After proposed change

The current implementation of the parser has a minor bug where if there are formatting marks within the code of a link, that code gets converted to html and then escaped, so that the html code is displayed as text. The text [[Law & Order franchise|''Law & Order'' franchise]] displays as <em>Law & Order</em> franchise instead of Law & Order franchise.

I fixed the issue by having the code parse wiki formatting after the html is escaped instead of before. This way, the formatting marks are converted to html after the html is escaped, rendering the preview as intended. I posted the code at User:Shardsofmetal/popups.js. This diff shows the changes I've made. I've posted screenshots of before and after the change, with a red box around the bug. Could somebody update the file with this change? Thank you, Shardsofmetal 00:32, 20 March 2022 (UTC)

No time to look at it yet, but that does seem like something that should be checked for XSS problems. —TheDJ (talkcontribs) 12:26, 21 March 2022 (UTC)
Example article link: Carolyn McCormick. — xaosflux Talk 22:14, 17 April 2022 (UTC)
 Not done: Please see TheDJ's comment. Izno (talk) 19:39, 3 June 2022 (UTC)
I'm reactivating my request. I've updated the page at User:Shardsofmetal/popups.js to make this change to the current version of the script (diff between my proposed code and the current code). The last time I made this request, I didn't realize how confusing the diff page was; it made it appear as if I had made many more modifications to the code than I actually had. This time, I've made sure the diff page clearly shows how few modifications I've actually made. I'll restate my proposal because I don't think I was clear enough and detailed enough last time.

Current behavior: The script converts wikitext formatting for italic and bold text (''italic'' and '''bold''') to html (<em>italic</em> and <strong>bold</strong>) before converting wikitext formatting for links into html. When the script converts wikitext formatting for links, it escapes or strips out any html from the article source (for safety reasons). Unfortunately, this means that it's also escaping the html code that the script itself just put there, resulting in the behavior described above and demonstrated in the sreenshot.

Intended behavior: The script escapes or strips html from the article source text (to prevent potential XSS attacks), but does not escape or strip html that the script itself created when parsing wikitext (e.g. converting italic markup to italicized text).

Confirmation that html is still escaped or stripped from links
My proposed change: Converts the wikitext formatting for italic and bold text after converting wikitext formatting for links and escaping or stripping html. This way, the <em></em> and <strong></strong> tags created by the script won't get escaped, while any html in the article source text is still escaped or stripped. (To demonstrate this, I created a test page at User:Shardsofmetal/popupsLinkTest. The page contains 2 links to the "Wikipedia" article with markup to italicize "Wikipedia". The first link uses wikitext and the second uses html. If you're running the version of popups with my proposed change and hover over the link to my test page, you can see that the html is still stripped out of the second link. I've attached a screenshot.)

This proposed change does not introduce any XSS vulnerabilities. None of the code related to escaping html has been modified.

Hopefully this explanation was clear and detailed. Please let me know if there are still any questions or concerns, or if there is anything else I can do get this implemented. Thank you — Shardsofmetal [talk] 00:20, 18 April 2023 (UTC)
This seems safe to me from an XSS perspective since the only HTML allowed is formatting generated by popups but will give this edit a bit for any comments otherwise. Galobtter (talk) 00:48, 18 April 2023 (UTC)
 Done Galobtter (talk) 06:02, 24 April 2023 (UTC)