Page MenuHomePhabricator

Provide a standard addPortlet function
Closed, ResolvedPublic

Description

Some userscripts add their own new portals to the sidebar. With collapsible sidebars enabled, the bodies of these elements are always hidden (unless you change the script to add "expanded" to the portal div, and "display:block" to the body.

A function is needed to setup a portal with the "collapsible" routines.

Example: http://en.wikipedia.org/wiki/User:TheJosh/Scripts/NewPagePatrol.js

Note how user attempted to prepare his script for Vector, but was still broken due to the new collapsibility.


Version: unspecified
Severity: enhancement

Details

Reference
bz23515

Event Timeline

bzimport raised the priority of this task from to Low.Nov 21 2014, 11:01 PM
bzimport set Reference to bz23515.
bzimport added a subscriber: Unknown Object (MLST).

This appears to be an execution order issue. Portals added by code that runs before the jQuery ready handler from http://bits.wikimedia.org/w/extensions/UsabilityInitiative/Vector/Vector.combined.min.js that sets up the collapsing function (like [[commons:MediaWiki:InterProject.js]]) will be processed just fine, but those added later won't get the necessary post-processing.

A possible solution could be to expose an addPortlet() function via wikibits.js, similar to the existing addPortletLink(), which would take care of all the necessary tweaks. Such a function could also be made compatible with all the major portlet-using skins (Vector, MonoBook, Modern, etc.) without callers having to add custom tweaks to account for random differences in IDs and class names.

Ps. The readable version of the collapsing code, for any interested script writers, is at http://svn.wikimedia.org/viewvc/mediawiki/trunk/extensions/UsabilityInitiative/Vector/Vector.combined.js -- however, please note the comment at the top of the file.

A global function named toggle(), seems asking for problems with double definitions of that name btw.

(In reply to comment #3)

A global function named toggle(), seems asking for problems with double
definitions of that name btw.

That's not a global function, it's inside a $(document).ready(function() { ... });

This seems to be essentially a duplicate of bug 25726, fixed in r75793. However, I'm not closing this bug yet since there still remains the issue of setting the initial state of the portal. DieBuche does suggest a workaround at [[commons:MediaWiki_talk:InterProject.js]]:

if ($.cookie('vector-nav-' + id) == 'true') $('#' + id).mousedown();

That's rather ugly, and makes assumptions about the internal implementation of the collapsing portals, but it ought to work once r75793 is deployed.

(In reply to comment #1)

A possible solution could be to expose an addPortlet() function via
wikibits.js, similar to the existing addPortletLink(), which would take care of
all the necessary tweaks. Such a function could also be made compatible with
all the major portlet-using skins (Vector, MonoBook, Modern, etc.) without
callers having to add custom tweaks to account for random differences in IDs
and class names.

I was just going to create a bug for requesting some utility function addPortlet(), but since it was mentioned here: should I create another bug for that?

The function seems to be needed in various wikis, so it would be good to have a common implementation ready for all.

Another option would be to change the code of the current addPortletLink() where we have this

	if ( !root ) {
		return null;
	}

so that instead of returning, the function could create the new portlet if it doesn't already exists.

Should I create a new bug for any of theses suggestions?

PS:
(In reply to comment #2)

Ps. The readable version of the collapsing code, for any interested script
writers, is at
http://svn.wikimedia.org/viewvc/mediawiki/trunk/extensions/UsabilityInitiative/Vector/Vector.combined.js

  • however, please note the comment at the top of the file.

The link is broken.

I'll check this out next week.

In order to do this nicely and in a future proof I believe we need a change in the Skin landscape.

Perhaps one of the following:

A) Skins have to provide a way to know what the IDs of elements are

For example:

  • By giving them a class that all skins have to abide (ie. class="mw-articlecontent")
  • By setting a javascript variable
  • wgSkinElements.articleContent='div#bodyContent';
  • which all skins would set somehow

B) Move these things out of each individual skin and centralize them instead ( ->getPortlets(), getFooter(), wrapArticleContent() which would output the entire package (including the wrapping element), and no longer allow skins to use different IDs.

C) Something else that works without having needing to have switch() statement inside utlility functions such as addPorlet() in JavaScript. Because that is ugly, hard to maintain and not extendable by other skins.

This method of passing the info to js (A) wouldn't just be used for element ids, it could also be used to share HTML templates (ie. the HTML structure of a portlet).

Ofcourse the issue of knowing the IDs and the structure could be avoided all together with option B. But that would make it no longer backwards compatible.

In my opinion the ideal solution would be that skins would utilize centralized funtionality without having to construct the HTML themselfs (convinience) and at the same time avoiding this problem of stupid differences.

So what when a skin wants a different structure for a portlet ? Well, then it would no longer be a portlet :D

(In reply to comment #7)

Here are some other places where I found similar scripts for such portlets:

For the record: there is one more example on function twAddPortlet from
https://en.wikipedia.org/wiki/MediaWiki:Gadget-Twinkle.js

Krinkle claimed this task.

Closing per T42813. The current format is pretty minimal. As far as I'm concerned, it can be treated as a standard.