Page MenuHomePhabricator

[Spike] Research responsive table solution
Closed, ResolvedPublic3 Estimated Story Points

Description

Background

  • Currently we use JS to wrap tables to make them responsive in Vector under a feature flag. This solution cant be permanent, as it causes a reflow. This ticket is for researching a long term solution to this to figure out:

What feedback to editors do we need to upstream this fix to their wikitext or should update default parser markup for tables (talk to content transform team)

User story

  • As a wiki reader, I want large tables to not mess up the UI and be usable on all resolutions without causing a reflow

Requirements

  • talk to content transform team about responsive table markup <div class="noresize"><table class="wikitable">
  • After this spike, create an implementation task to transition from the JS solution to a permanent one
  • identify any changes we want to give to editors to make
    • We'd then need some way for editors to remove the noresize class - this might be by adding a class to table, and us hoisting it. e.g {| class="wikitable aside" might result in <div><table class="wikitable"> or it might be by adding a parameter. <div class="noresize">{| class="wikitable" fullscreen="false" results in <div><table class="wikitable"> (e.g. noresize class is dropped)
  • current list of requirements in JS logic

Details

Event Timeline

It would be helpful for the Content Transform Team to know what your desired HTML looks like, and how that compares to the present HTML output. You should think through the behavior you want for Visual Editor as well, which uses Parsoid's markup.

Proposal is wrapper div and class:

<div class="something"><table>....</table></div>

restricted to tables which are not nested, not floated, are subclass of wikitable.

See https://github.com/wikimedia/mediawiki-skins-Vector/blob/d11e77a5ecafcb46ff7407e1e160eb05c2935729/resources/skins.vector.js/tables.js#L4

From @Jdlrobson :

I think we'd want to change the table parser function to output a div wrapping the table which defaults to have the class noresize. e.g. <div class="noresize"><table class="wikitable">
We'd then need some way for editors to remove the noresize class - this might be by adding a class to table, and us hoisting it. e.g {| class="wikitable aside" might result in <div><table class="wikitable"> or it might be by adding a parameter.

We also need to recognize when there is already a noresize wrapper and not double-wrap.

A thought or two from me since I've been musing on it.

  • Yes, a wrapper marked with noresize or equivalent seems like the right answer.
    • I have a suggestion that this be a new class, and that noresize be relegated to use strictly for editors.
  • Unfortunately, a wrapper dis-enables another often requested use case: floating table headers.
    • Of course, some CSS via TemplateStyles or a gadget can take care of turning off the overflow wrapper.... which they might do wrong per next bullet.
    • I'm not sure how to deal with that use case anyway at disparate resolutions since you're going to need noresizeish type thing at small resolution regardless.
      • Maybe someone should file bugs upstream with the browsers or W3C because of the shitty interaction between position: sticky and overflow-x: auto/scroll........
  • In case it's not obvious, I would wrap only {| and |}. Wrapping wikitext </?table> probably doesn't need to happen as that should appear exclusively in templates which can/should take care of themselves.

restricted to tables which are not nested

I don't think this is worth supporting or even being concerned with (and I'm totally sure why it's done in the JS version, but that's an aside). Tables shouldn't be nested in this day and age (despite that many wikis probably have nested tables, including en.wp - but we're working on it). And I think this fails gracefully anyway? I guess there's a concern of double scrollbars being potentially confusing? But I guess this is something that can be done solely in CSS: you can still output the wrapper and then add a .mw-table-wrapper .mw-table-wrapper { reset } block.

not floated

Right now the JS uses the relevant API. Is that doable in Parsoid?

(NB I'm not sure ignoring floating content is totally scalable down to small resolutions, and Parsoid can't support the low resolution [like Javascript can]. Maybe that could use some additional thought/care.)

are subclass of wikitable.

I guess 'subclass' means 'class'? This seems like a reasonable restriction, again if Parsoid can do it.

See https://github.com/wikimedia/mediawiki-skins-Vector/blob/d11e77a5ecafcb46ff7407e1e160eb05c2935729/resources/skins.vector.js/tables.js#L4

This is the Vector implementation. There is an implementation in Timeless that has something not totally different, though a bit older.

We also need to recognize when there is already a noresize wrapper and not double-wrap.

This can be done in CSS also, similar to above? .noresize .mw-table-wrapper { reset }.

  • Subbu: needs a sense of a timeline, can do an experiment but this needs to be a longer convo.
  • C scott: would feel more comfortable if this was an extension, or something editors opt-in to this for newly authored tables. More difficult to change HTML with so many different cases and logic.
  • C scott: nervous about doing for both mobile and desktop, more aggressive with transforms on mobile with the understanding that there's always desktop as a backup. Makes sense to deploy to mobile first, with a config for gradual change. Not good as a core parser behavior vs MF, cuz its hard to spec and its wiki specific.
  • C scott: getComputedStyle is very difficult. if the tables are generated by templates, then another option is to opt in via templates.
  • Subbu, 2 options, are we looking to change the input to the wikitext (longer time frame, more involved). Or are we changing only the output and how it render on desktop and mobile. For both, we need to write a simple spec that doesnt depend on computed styles/hardcoded classes, that editors can understand.
  • C scott: hybrid approach, automatic rule that doesnt get every case, but gets a useful subset, and combine it with optin/optout, maybe have a lint rule. Anticipating needing multiple solutions, but need to plan out step by step.

Change #1076038 had a related patch set uploaded (by Bernard Wang; author: Bernard Wang):

[mediawiki/skins/Vector@master] Add logging to table wrapping experiment

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

Change #1076038 merged by jenkins-bot:

[mediawiki/skins/Vector@master] Add logging to table wrapping experiment

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