Page MenuHomePhabricator

Create a button to expand all collapsible elements on a page
Closed, ResolvedPublic

Description

From https://meta.wikimedia.org/wiki/Community_Wishlist_Survey_2023/Reading/Create_a_button_to_expand_all_collapsible_elements_on_a_page
Problem
Some pages have many collapsible elements, for example Bulgaria women's national football team results, and it can be very tedious clicking "show" for each of those elements.

Proposed solution
Add a button to "Tools" that will expand all the collapsible elements with one click.

Who would benefit
Anyone who wants to see a page fully expanded; also editors who need to compare a preview of their edits to a page with the original page with all collapsed elements shown.

Event Timeline

jsn.sherman changed the task status from Open to In Progress.Sep 27 2023, 3:17 PM

My first step was to investigate how collapsible elements work.

I spent some time looking at all of the collapsible element examples at:
https://www.mediawiki.org/wiki/Manual:Collapsible_elements/Demo/Advanced

the standard collapsible elements have predictable class changes based on state, but that isn't necessarily true of custom toggles. So, I came up with selectors that identify toggles based on class and identify expand/collapse state based on aria-expanded.

The remote collapsible example is problematic though, as it does not correctly handle the aria-expanded attribute: one of the toggles has aria-expanded=true even if the content is collapsed, and the other toggle doesn't use aria-expanded at all.
https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-expanded

I believe that's a bug that might need to be resolved separately

I also looked at the makeCollapsible module:
https://gerrit.wikimedia.org/r/plugins/gitiles/mediawiki/core/+/refs/heads/master/resources/src/jquery/jquery.makeCollapsible.js

I've come up with the following example code that expands/collapses elements toolbar links. It can be pasted directly into the browser javascript console. It has some limitations:

  • it doesn't work on the aforementioned problematic example
  • it currently fires the click event on collapsible elements, which is probably a nightmare for analytics. I need to figure out how to run the handler in makeCollapsible
  • because I need to provide an anchor for portlet links, it currently brings the viewport back up to the top of the page on click.
  • no i18n at the moment, since I've just hardcoded the label
const expandCollapsibleToolbarLinkId = 't-expand-all',
	collapseCollapsibleToolbarLinkId = 't-collapse-all';

function toggleCollapsible( expanded ) {
	$( `.mw-collapsible-toggle[aria-expanded="${expanded}"], .mw-customtoggle[aria-expanded="${expanded}"], [class^="mw-customtoggle-"][aria-expanded="${expanded}"]` ).each(
		function () {
		$( this ).trigger( 'click' );
		} );
}

mw.util.addPortletLink(
	'p-tb',
	'#',
	'expand all',
	expandCollapsibleToolbarLinkId
);

$( `#${expandCollapsibleToolbarLinkId}` ).on( 'click', function () {
	$( this ).hide();
	$( `#${collapseCollapsibleToolbarLinkId}` ).show();
	toggleCollapsible( false );
} );
mw.util.addPortletLink(
	'p-tb',
	'#',
	'collapse all',
	collapseCollapsibleToolbarLinkId
);

$( `#${collapseCollapsibleToolbarLinkId}` )
	.hide()
	.on( 'click', function () {
		$( this ).hide();
		$( `#${expandCollapsibleToolbarLinkId}` ).show();
		toggleCollapsible( true );
} );

My next step will be to see how I can avoid triggering click, as that's really just a hacky shortcut, IMO.

Change 961789 had a related patch set uploaded (by Jsn.sherman; author: Jsn.sherman):

[mediawiki/core@master] Add toolbox link to expand all collapsible elements on a page

https://gerrit.wikimedia.org/r/961789

Test wiki created on Patch demo by JSherman (WMF) using patch(es) linked to this task:
https://patchdemo.wmflabs.org/wikis/366e29eac4/w

Test wiki on Patch demo by JSherman (WMF) using patch(es) linked to this task was deleted:

https://patchdemo.wmflabs.org/wikis/366e29eac4/w/

Test wiki created on Patch demo by JSherman (WMF) using patch(es) linked to this task:
https://patchdemo.wmflabs.org/wikis/d3edbcabb6/w

Test wiki on Patch demo by JSherman (WMF) using patch(es) linked to this task was deleted:

https://patchdemo.wmflabs.org/wikis/0dbf2d63a1/w/

Change 961789 merged by jenkins-bot:

[mediawiki/core@master] add portlet to toggle all collapsible elements

https://gerrit.wikimedia.org/r/961789

Test wiki on Patch demo by JSherman (WMF) using patch(es) linked to this task was deleted:

https://patchdemo.wmflabs.org/wikis/d3edbcabb6/w/

Change 1002613 had a related patch set uploaded (by Krinkle; author: Krinkle):

[mediawiki/core@master] mediawiki.page.ready: Move toggleAllCollapsibles.js file to this module

https://gerrit.wikimedia.org/r/1002613

Change 1002613 merged by jenkins-bot:

[mediawiki/core@master] mediawiki.page.ready: Move toggleAllCollapsibles.js file to this module

https://gerrit.wikimedia.org/r/1002613

I attempted to implement code within the frwiki Common.js to ensure that custom collapsible elements on frwiki expand and collapse in sync with the standard mw-collapsible elements when the toggle button is clicked. ( https://fr.wikipedia.org/wiki/Spécial:Lien_permanent/219936991#L-733).

Because of the common case of pages with custom frwiki collapsible elements without standard mw-collapsible elements, the toggle button often needs to be added manunally. The problem is that the test to see if the button is here may be done too early, so I often end with two toggle buttons : the one from toggleAllCollapsibles.js and the one from frwiki Common.js. See my sandbox here to see the duplicate buttons: https://fr.wikipedia.org/wiki/Utilisateur:Escargot_test/Brouillon .

Is there a way to be sure that this toggle button has been added if it needed to be added ? I tried with mw.loader.using( 'mediawiki.page.ready' ), but it does not work.

In addition to the "using mediawiki.page.ready" (code search, main code), we might add a mw.hook('wikipage.content').add() (with necessary checks to avoid adding the portlet several times, e.g. in live previews), so that it is executed after the hook from toggleAllCollapsibles.

mw.loader.using( 'mediawiki.page.ready', function () {

    // Hook from toggleAllCollapsibles has been registered.

    // Our hook is registered, thus executed, after.
    mw.hook( 'wikipage.content' ).add( function () {
        // Phase 3: Profit
    } );
} );

Though:

  • That's the kind of code I'm not a big fan of: it's already a hell of spaghetti right from the creation, and it can be a nightmare to maintain…
  • That being said, this link exists natively, so it makes sense to augment it so that it achieves it purpose on the wiki.
  • I'm also not a big fan of the "jump" in the toolbox caused by this dynamic link addition…

Also, I'm not sure it is advisable to manually load "mediawiki.page.ready".