Page MenuHomePhabricator

Support mathematical formulae in Wikidata Query Service UI on all browsers
Open, Needs TriagePublic

Description

As a user of the Wikidata query service, I want to be able to see rendered formulae in order to read them more easily than the underlying markup.

Problem:
For mathematical formula values, Wikibase emits MathML to RDF, and in the Wikidata query service UI we just emit the same MathML into the results table and leave it to the browser to render it. However, Chrome does not support MathML, so users of Chrome and related browsers (now including Edge) will only see the underlying markup (it’s encoded inside the MathML as an annotation).

We should be able to fix this using the MathJax library.

Example:
Query for mathematical formula – results look nice in Firefox, not so much in Chrome

Acceptance criteria:

  • mathematical formula are shown in their rendered form in all browsers
  • native browser support is used where available

Details

Related Gerrit Patches:
wikidata/query/gui-deploy : productionMerging from d9f964b88c01748e278ca8c4b8929a8ef0ef0267:
wikidata/query/gui : masterRender MathML using MathJax

Event Timeline

Restricted Application added a subscriber: Aklapper. · View Herald TranscriptJan 30 2019, 6:41 PM
Physikerwelt added a subscriber: Physikerwelt.

The following patch is enough to support this in development mode:

diff --git a/embed.html b/embed.html
index 8c16801..b36d8da 100644
--- a/embed.html
+++ b/embed.html
@@ -458,6 +458,14 @@ body {
 	</div>
 
 		<!-- JS files -->
+	<script type="text/x-mathjax-config">
+		MathJax.Hub.Config( {
+			jax: [ "input/MathML", "output/CommonHTML" ],
+			extensions: [ "mml2jax.js","MathMenu.js","MathZoom.js", "AssistiveMML.js", "a11y/accessibility-menu.js" ],
+			messageStyle: "none"
+		} );
+	</script>
+	<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js" async></script>
 	<!-- build:js js/embed.vendor.min.js -->
 	<script src="node_modules/jquery/dist/jquery.js"></script>
 	<script src="node_modules/underscore/underscore.js"></script>
diff --git a/index.html b/index.html
index e74d5b5..c433a7a 100644
--- a/index.html
+++ b/index.html
@@ -430,6 +430,14 @@
 	</div>
 
 	<!-- JS files -->
+	<script type="text/x-mathjax-config">
+		MathJax.Hub.Config( {
+			jax: [ "input/MathML", "output/CommonHTML" ],
+			extensions: [ "mml2jax.js","MathMenu.js","MathZoom.js", "AssistiveMML.js", "a11y/accessibility-menu.js" ],
+			messageStyle: "none"
+		} );
+	</script>
+	<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js" async></script>
 	<!-- build:js js/vendor.min.js -->
 	<script src="node_modules/jquery/dist/jquery.js"></script>
 	<script src="node_modules/jquery-toast-plugin/src/jquery.toast.js"></script>
diff --git a/wikibase/queryService/ui/ResultView.js b/wikibase/queryService/ui/ResultView.js
index 1ff0bdd..3d6e3df 100644
--- a/wikibase/queryService/ui/ResultView.js
+++ b/wikibase/queryService/ui/ResultView.js
@@ -670,6 +670,7 @@ wikibase.queryService.ui.ResultView = ( function( $, download, window ) {
 			try {
 				$( '#query-result' ).show();
 				resultBrowser.draw( $( '#query-result' ) );
+				MathJax.Hub.Queue( [ "Typeset", MathJax.Hub, 'query-result' ] );
 				self._actionBar.hide();
 			} catch ( e ) {
 				self._drawErrorResult( resultBrowser );

Unfortunately, MathJax seems to insist on loading its own components dynamically, so I have no idea how we’re going to make this work with our build process. (The above patch loads MathJax from CDNJS, but I’m pretty sure that’s not acceptable in production.)

I am not sure whether it's ok to use cdnjs.cloudflare.com for privacy reasons. AFAIK, so far we have avoided directly including non-WMF resources.

Change 549457 had a related patch set uploaded (by Lucas Werkmeister (WMDE); owner: Lucas Werkmeister (WMDE)):
[wikidata/query/gui@master] Render MathML using MathJax

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

Change 549457 merged by jenkins-bot:
[wikidata/query/gui@master] Render MathML using MathJax

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

Change 549461 had a related patch set uploaded (by Lucas Werkmeister (WMDE); owner: Lucas Werkmeister (WMDE)):
[wikidata/query/gui-deploy@production] Merging from d9f964b88c01748e278ca8c4b8929a8ef0ef0267:

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

Change 549461 merged by Addshore:
[wikidata/query/gui-deploy@production] Merging from d9f964b88c01748e278ca8c4b8929a8ef0ef0267:

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

So to summarize T233213: XSS in Wikidata Query Service UI, DATATYPE_MATHML - CVE-2019-19329 (which is now public): The old implementation directly injected the markup from the MathML value into the page, which amounted to an XSS vulnerability if that markup was not pure MathML (e. g. if it contained a <script> element). To fix this without completely breaking math markup, I implemented MathML rendering using MathJax – v3 is thankfully easier to bundle than v2, so the problems I had in T214980#4918833 were no longer an issue – and we deployed this about a week ago. Besides fixing the XSS issue, this also has the pleasant effect of enabling MathML rendering in other browsers supported by MathJax, including Chrome. (It also produces different rendering in Firefox than the previous native rendering.) Strictly speaking, that resolves this task.

However, @Physikerwelt points out that this leaves us with two different ways to render math in the wiki world – Mathoid, which I believe uses MathJax 2 and is used on-wiki, and MathJax 3 in the query service. (Note that they don’t fulfill the same job, though: Mathoid renders TeX(-like?) input, whereas in the query service we need to render MathML, though in practice this MathML has usually been generated by Mathoid from TeX input on Wikidata.)

One way to resolve this would be to actually use Mathoid in the query service UI: enable its MathML input type (which is apparently supported but not currently enabled in RESTBase), then each time we want to render a formula, send it to Mathoid and add the resulting… image? HTML? to the page. But this would potentially require a lot of network requests – I believe queries with math results are fairly rare, but when they are made, they often include hundreds of results.

Another approach would be to bring Mathoid where the query service UI is today, in a sense, by migrating it to MathJax 3. I believe that’s the subject of T237516: Update to MathJax 3.

Did I miss anything?