Page MenuHomePhabricator

DiscussionTools's <div class="mw-heading"> wrapper (and future core wrapper) makes it difficult to style headings in wikitext
Closed, ResolvedPublic

Assigned To
Authored By
matmarex
Dec 15 2023, 12:32 AM

Description

(originally reported at T13555#9407882 and discussed at https://de.wikipedia.org/wiki/Wikipedia:Technik/Skin/MediaWiki/Änderungen#Geänderte_Überschriftenstruktur)

Context

DiscussionTools adds wrapper elements that look like <div class="mw-heading"> to wikitext headings. Specifically, the following wikitext:

<h2>Hello</h2>

…which would ordinarily turn into the following HTML:

<h2><span class="mw-headline" id="Hello">Hello</span></h2>

…turns into the following instead:

<div class="mw-heading mw-heading2 ext-discussiontools-init-section"><h2><span class="mw-headline" id="Hello" data-mw-thread-id="h-Hello"><span data-mw-comment-start="" id="h-Hello"></span>Hello<span data-mw-comment-end="h-Hello"></span></span></h2></div>

This happens on all talk pages and pages in $wgExtraSignatureNamespaces, which includes Wikipedia: and Help: on most Wikimedia wikis, even if those pages do not contain discussions and don't look any different.

Problem

We added those wrappers a year ago in T314714, and for the most part they did not cause problems (although there were some: T331474), but last week, after we added some forward-compatibility styles for T13555, more problems appeared. The new styles cause the <h2> to become an inline element, and change the value against which relative font sizes are computed, which means that many styles (and TemplateStyles) applied to it no longer have the desired effect.

For example, given the following wikitext:

<h2 style="border: 1px solid green; background: lightgreen; padding: 5px; font-size: 1.5em;">Hello!</h2>

…these pages demonstrate the problem:

While it is possible to update the styles, it is tricky (since you can't add classes or styles on the wrapper, and since you need to style the headings differently depending on whether the wrapper is present). In practice the easiest solution in wikitext is just not using headings, which is bad for accessibility. Other solutions may require adding extra wrappers outside the heading, which would interfere with the mobile site and Parsoid's section wrapping.

We were planning to use the same HTML structure for headings on all pages in T13555 (not just in DiscussionTools), and this problem would affect that as well.

Solution?

I think there's a chance we could resolve all of these issues by moving the style and class attributes (or maybe all attributes) defined on the <h2> in the input wikitext to the wrapper <div class="mw-heading"> in the output HTML. That would restore the previous structure (although with different tags), and it seems to fix the problems on the pages where I tried it. There might be some cases where it wouldn't help, though, and it might be confusing to the editors writing the wikitext. And there might be problems with that that I didn't think of yet.

Solution?

If we could distinguish whether the heading was originally written using == or <h2> in wikitext, we could use that information to decide not to add wrappers (and discussion metadata) to the <h2> headings. It's probably very rare for them to be used in discussions.

Event Timeline

I wonder whether you apply this if it is not an editable section with == but a deliberately non-editable section with <h2> in wikitext.

  • I do understand that you separated the [editsection] business from the headline element to improve accessibility.
  • However, if wikitext is containing <h2> there is nothing to be changed, no accessibility touched, no separate [editsection] element. There is nothing to be discussed, and nothing to subscribe or unsubscribe.
  • Therfore, if either __NOEDITSECTION__ or <h2> is present in wikitext, just produce the traditional element without wrapper.
  • Iff it is == then create that wrapper and [editsection] but that is almost everywhere regular article text or talk page without any special styling.

I am not deep in the most recent CSS but I think it is feasible to distinguish a wrapper containing a <h2> and turn that into inline, but keep block if there is no wrapper present.

@PerfektesChaos I do worry that folks might be using an <h2> instead of a === just to provide styling opportunities, and they don't *necessarily* want the section to be omitted from the TOC, section edit links, etc. The syntax limitations are discussed a bit here and in T230658.

Perhaps a solution for both is to add a new {{#h|<num>|contents|attrib=value|attrib=value}} built-in parser function which will generate the same heading markup as ==contents== but with the added attributes applied -- perhaps on the outer <div> as @matmarex suggests. Then plain <h2> gets no special treatment, as you suggest, but if you *did* want to create a heading element which matched the default tag structure, there's a way to do that as well.

I am always open to new {{#...}} parser functions.

  • However, I am worried since dewiki is using <h*> within some 1,500 wikitext source pages, and perhaps 1,000 of them may be broken by the recent and not announced change. Even our main page crashed, which got a hotfix.
  • In the long run I do prefer {{#...}} parser functions since they have explicit opening and closing syntax, compared to some : or ''' or * somewhere, and they are not misusing [[...]] links for {{#category:...}} purpose.

@ worry that folks might be using an <h2> instead of a === just to provide styling opportunities

  • For dewiki I am quite sure that probably no project nor help page nor template is using styled headlines for editable sections.
  • We use rare TemplateStyles, we are cutting down Common.css as much as possible, we have a limited number of community gadgets and we KISS (keep it simple and stupid, not much styling opportunities provided if not really needed).
  • Some user pages might desire styling, but they cannot achieve project wide CSS, and there is no amount of user TemplateStyles pages.

However, I do not understand this argument.

  • If there is <h2> instead of == then this is deliberately no editable section; it does not need any button or link for editing nor subscribing nor unsubscribing.
  • In all known cases of specific styling these are pages like Help:? which provide semantic <h2> for the sake of accessibility (even if no wiki TOC is present, A11Y should offer a collection of all headlines in sequence found in DOM).
  • In wikisyntax, <h2> instead of == is suppressing all edit links etc. since 2008-02-22.

I wonder whether you apply this if it is not an editable section with == but a deliberately non-editable section with <h2> in wikitext.

  • I do understand that you separated the [editsection] business from the headline element to improve accessibility.
  • However, if wikitext is containing <h2> there is nothing to be changed, no accessibility touched, no separate [editsection] element. There is nothing to be discussed, and nothing to subscribe or unsubscribe.
  • Therfore, if either __NOEDITSECTION__ or <h2> is present in wikitext, just produce the traditional element without wrapper.
  • Iff it is == then create that wrapper and [editsection] but that is almost everywhere regular article text or talk page without any special styling.

I am not deep in the most recent CSS but I think it is feasible to distinguish a wrapper containing a <h2> and turn that into inline, but keep block if there is no wrapper present.

That is actually a good question. I tried to find out why DiscussionTools processes <h2> headings, and as far as I can tell, it's just because we can't actually distinguish headings using == from those using <h2> – that information is lost earlier during wikitext parsing than when DiscussionTools runs. But if we could distinguish them (I found a task about allowing it: T68637), it would probably be a pretty reliable way to decide whether we should add formatting to that heading.

Sadly we can't just check for the presence of the [edit] link – they are commonly hidden in archives (and we probably want to add the "discussion statistics" to the headings there too), and there are some discussion pages where headings are generated by templates in such a way that they end up without the [edit] links, for example https://pt.wikipedia.org/wiki/Wikipédia:Esplanada/geral and https://en.wikipedia.org/wiki/Wikipedia_talk:Wikipedia_Signpost/2023-12-04/News_and_notes (even though in both cases the templates use ==).

(We could actually assume that any heading with unusual attributes must have been written as <h2 …> in wikitext.)

Yeah, obviously parsing needs to be revised. I would expect:

  1. encountering =+ and in __NOEDITSECTION__ mode then
    1. create <h.> instead
    2. send back into stream
  2. encountering =+ and not in __NOEDITSECTION__ mode then
    1. create wrapper business, be prepared for addition of edit/subscribe elements
    2. insert <h.> into wrapper
    3. send back into stream
  3. encountering <h.> then append content to TOC etc.
    1. processing both native elements in wikitext and those created from =+

or any switch or fork or sub-process to handle <h.> elements for TOC purpose.

CSS will add display:inline for <h.> which is child of wrapper. Then native <h.> are treated as always since 2008.

I have a personal tool that I think is also breaking from this (and which might point to other potential gadget/userscript breakages?). I use this userJS via the browser-extension violentmonkey to add mouseover anchor links for each heading (until T18691: RFC: Section header "share" link gets resolved -- and see that task for related gadgets/scripts). I wonder if it's easy to either change the default output so that it works again for my existing code (and potentially the other scripts), or if someone could tell me what to change to fix my code? (Low-urgency if it just affects me though!). Thanks, and hope that helps!

Change 983490 had a related patch set uploaded (by Bartosz Dziewoński; author: Bartosz Dziewoński):

[mediawiki/extensions/DiscussionTools@master] [WIP] CommentFormatter: Move heading attributes to the wrapper

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

Change 983492 had a related patch set uploaded (by Bartosz Dziewoński; author: Bartosz Dziewoński):

[mediawiki/extensions/DiscussionTools@master] [WIP] CommentFormatter: Do not add wrapper if the heading has attributes

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

@Quiddity Your script works for me. If you clarify what's wrong, I can try to help :)

@matmarex Aha! After comparing my prefs between 2 accounts, this was a "Use Parsoid by default" preference issue. Please can you pass that along to the appropriate folks, if needed? (And sorry for the noise in this task!)

Hey. As I haven’t seen this before and I was sort of pushing for T314714 to be a thing: the only styling that is made difficult is inline-only CSS styling, the headings can still be styled with TemplateStyles, which is what we should aim for as the best way forward for compatibility reasons (with dark mode, different skins, etc.). All of the uses of ‘wikitext-based inline styling’ are covered by extremely simple fixes: 1) wrapper elements around headings that do the same styling, 2) TemplateStyles that do the same styling, 3) maybe something else. The easiest solution is to migrate those limited uses of this syntax, and not try to guesstimate what the inline styles mean in these cases.

We've had a chat today with @cscott @DLynch @Esanders @matmarex, and we like the idea of simply not adding the wrappers to headings that have additional attributes – thanks for suggesting that @PerfektesChaos. It's much easier to document and understand than my original idea, and it's compatible with the future plans we had for T13555, since those headings wouldn't have section edit links anyway, and probably shouldn't have DiscussionTools features.

I'm planning to finish and deploy that change this week.

The currently proposed patch will still wrap headings written using <h2> with no attributes, since it's difficult to distinguish them from == (see T68637). This may or may not change in the future, depending on whether this version turns out to work well. We definitely don't want to rush bigger changes to allow distinguishing them before the holidays.

@stjn While the problem isn't too complicated to fix in wikitext, the solutions are still more complex than a simple inline 'style' attribute, and we don't want to break existing pages if that's possible. (Also, wrapper elements around headings complicate the code for adding <section> wrappers around sections in Parsoid, sometimes leading to weird effects like the table of contents displaying in the wrong place, so I wouldn't want to recommend that.)

Change 983490 abandoned by Bartosz Dziewoński:

[mediawiki/extensions/DiscussionTools@master] [WIP] CommentFormatter: Move heading attributes to the wrapper

Reason:

We prefer the other approach.

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

(Also, wrapper elements around headings complicate the code for adding <section> wrappers around sections in Parsoid, sometimes leading to weird effects like the table of contents displaying in the wrong place, so I wouldn't want to recommend that.)

You may want to chat with Language-Team folks about this, because this is exactly what Translate does when the translation of a heading is outdated (e.g. https://test.wikipedia.org/wiki/Wikipedia:Requests/Tools/hi). It doesn’t look broken with Parsoid, though.

Change 983492 merged by jenkins-bot:

[mediawiki/extensions/DiscussionTools@master] CommentFormatter: Do not add wrapper if the heading has attributes

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

Change 984495 had a related patch set uploaded (by Bartosz Dziewoński; author: Bartosz Dziewoński):

[mediawiki/extensions/DiscussionTools@wmf/1.42.0-wmf.9] CommentFormatter: Do not add wrapper if the heading has attributes

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

Change 984496 had a related patch set uploaded (by Bartosz Dziewoński; author: Bartosz Dziewoński):

[mediawiki/extensions/DiscussionTools@wmf/1.42.0-wmf.10] CommentFormatter: Do not add wrapper if the heading has attributes

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

An unrelated outage today foiled my plans to get this deployed, so I scheduled it for tomorrow morning instead. https://wikitech.wikimedia.org/wiki/Deployments#deploycal-item-20231221T0800

Change 984495 merged by jenkins-bot:

[mediawiki/extensions/DiscussionTools@wmf/1.42.0-wmf.9] CommentFormatter: Do not add wrapper if the heading has attributes

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

Mentioned in SAL (#wikimedia-operations) [2023-12-21T08:14:23Z] <ariel@deploy2002> Started scap: Backport for [[gerrit:984495|CommentFormatter: Do not add wrapper if the heading has attributes (T353489)]]

Mentioned in SAL (#wikimedia-operations) [2023-12-21T08:16:07Z] <ariel@deploy2002> matmarex and ariel: Backport for [[gerrit:984495|CommentFormatter: Do not add wrapper if the heading has attributes (T353489)]] synced to the testservers (https://wikitech.wikimedia.org/wiki/Mwdebug)

Mentioned in SAL (#wikimedia-operations) [2023-12-21T08:25:30Z] <ariel@deploy2002> Finished scap: Backport for [[gerrit:984495|CommentFormatter: Do not add wrapper if the heading has attributes (T353489)]] (duration: 11m 07s)

Change 984496 merged by jenkins-bot:

[mediawiki/extensions/DiscussionTools@wmf/1.42.0-wmf.10] CommentFormatter: Do not add wrapper if the heading has attributes

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

Mentioned in SAL (#wikimedia-operations) [2023-12-21T08:37:32Z] <ariel@deploy2002> Started scap: Backport for [[gerrit:984496|CommentFormatter: Do not add wrapper if the heading has attributes (T353489)]]

Mentioned in SAL (#wikimedia-operations) [2023-12-21T08:39:02Z] <ariel@deploy2002> ariel and matmarex: Backport for [[gerrit:984496|CommentFormatter: Do not add wrapper if the heading has attributes (T353489)]] synced to the testservers (https://wikitech.wikimedia.org/wiki/Mwdebug)

Mentioned in SAL (#wikimedia-operations) [2023-12-21T08:50:12Z] <ariel@deploy2002> Finished scap: Backport for [[gerrit:984496|CommentFormatter: Do not add wrapper if the heading has attributes (T353489)]] (duration: 12m 39s)

matmarex claimed this task.
matmarex removed a project: Patch-For-Review.

Okay, this should be resolved now.

For future reference, I took a couple of before-and-after screenshots of affected pages:

https://de.wikipedia.org/wiki/Wikipedia:Wiki_Loves_Monuments_2011

Screenshot 2023-12-21 at 09-17-15 Wikipedia Wiki Loves Monuments 2011 – Wikipedia.png (2×3 px, 698 KB)
Screenshot 2023-12-21 at 09-17-21 Wikipedia Wiki Loves Monuments 2011 – Wikipedia.png (2×3 px, 710 KB)

https://en.wikipedia.org/wiki/Wikipedia:Wikipedia_Signpost/2023-12-04/In_the_media

Screenshot 2023-12-21 at 09-19-45 Wikipedia Wikipedia Signpost_2023-12-04_In the media - Wikipedia.png (2×3 px, 1 MB)
Screenshot 2023-12-21 at 09-19-49 Wikipedia Wikipedia Signpost_2023-12-04_In the media - Wikipedia.png (2×3 px, 1 MB)
Screenshot 2023-12-21 at 09-20-51 Wikipedia Wikipedia Signpost_2023-12-04_In the media - Wikipedia.png (2×3 px, 591 KB)
Screenshot 2023-12-21 at 09-20-46 Wikipedia Wikipedia Signpost_2023-12-04_In the media - Wikipedia.png (2×3 px, 584 KB)

Thanks a lot @matmarex and everyone else involved!

@PerfektesChaos I do worry that folks might be using an <h2> instead of a === just to provide styling opportunities, and they don't *necessarily* want the section to be omitted from the TOC, section edit links, etc. The syntax limitations are discussed a bit here and in T230658.

Perhaps a solution for both is to add a new {{#h|<num>|contents|attrib=value|attrib=value}} built-in parser function which will generate the same heading markup as ==contents== but with the added attributes applied -- perhaps on the outer <div> as @matmarex suggests. Then plain <h2> gets no special treatment, as you suggest, but if you *did* want to create a heading element which matched the default tag structure, there's a way to do that as well.

I think the {{#h}} parser function could still be potentially useful? I proposed some other syntax options elsewhere (also T230658) and those didn't seem as popular.