I noticed a spike in client-errors in Logstash that seem to be connected to our just-launched Mobile Page Previews experiment.
I was seeing thousands of JS errors with the following message:
SyntaxError: Failed to execute 'closest' on 'Element': '#mw-content-text a[href][title]:not(.extiw, .mw-selflink, .image, .new, .internal, .external, .mw-cite-backlink a, .oo-ui-buttonElement-button, .ve-ce-surface a, .ext-discussiontools-init-timestamplink, .cancelLink a, .mw-selflink-fragment, [href^="#"])' is not a valid selector.
In the instrumentation.js code for Mobile Page Previews, we have the following code:
// Track link clicks
// This mimics the logic in App.vue for which links to actually handle;
// other links (e.g. external) will not be tracked.
const selector = `#mw-content-text a[href][title]:not(${ excludedLinksSelector })`;Then we do:
const link = event.target.closest( selector );
WMF staff can see the Logstash results here: https://logstash.wikimedia.org/app/dashboards#/view/AXDBY8Qhh3Uj6x1zCF56?_g=h@218e8f9&_a=h@9d755b9
Working theory
I believe that we are seeing these errors in browsers that don't support CSS selectors level 4 (2020-era browsers may lack this for example). See https://caniuse.com/css-not-sel-list
The problem is that we are calling :not() with a comma-separated list of selectors; older browsers can only accept a single (simple) selector here.
This matches what I'm seeing in the logs (Chrome v80 or below on older Android devices).
Proposed fix
We need to pass in a selectors-level-3-safe string that still implements all the desired behavior of the earlier L4 :not list.