Page MenuHomePhabricator

ResourceLoader JavaScript parser should allow ES5 syntax features
Closed, DuplicatePublic

Description

If I create a user script with the following code, Resource Loader rejects it with the error message

Error: JavaScript parse error: Parse error: Unexpected token; token 3 expected in file 'User:He7d3r/global.js' on line 2

var foo = { 'true': 0.6 };
alert( foo.true );

However, this is valid JavaScript code according to jshint, and works in the console of latest Firefox and Chrome.


See also:

Related Objects

Event Timeline

He7d3r raised the priority of this task from to Needs Triage.
He7d3r updated the task description. (Show Details)
He7d3r subscribed.

@He7d3r ES3 does not allow keywords in dot notation. That restriction was removed in ES5 because it was stilly. Modern browsers ship JavaScript engines that are ES5 compliant.

However older browsers and JavaScript engines that implement ES3 all have this restriction. For example, in IE8 and other browsers this will fail.

Krinkle renamed this task from ResourceLoader JS validator rejects valid user scripts to ResourceLoader JavaScript parser should allow ES5 syntax features .Apr 22 2015, 8:01 PM
Krinkle set Security to None.
Krinkle updated the task description. (Show Details)
Krinkle triaged this task as Medium priority.Apr 28 2015, 7:12 PM
Krinkle moved this task from Inbox to Backlog on the MediaWiki-ResourceLoader board.

tedious/JShrink is a nice, well-maintained library that supports both ES5 and ES6 syntax, but it is slower than our current implementation. If we fixed cache thrashing for RL filters such that they only needed to be executed once per code change, the speed difference would not matter. So I'm marking this blocked by T102578.

Change 264767 had a related patch set uploaded (by Ricordisamoa):
JSMinPlus: allow keywords in dot notation as in ECMAScript 5

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

I want to empower our users to be able to use ES5 where they want to. They can decide for themselves their own scripts don't need to be ES3-compatible as they are most likely using an ES5-compatible browser (as most users are).

However until T128115, we can't allow ES3-invalid scripts to be served to all users.

Considering there will always be a next ES version on the horizon (T75714), and other experimental or proprietary syntax people want to use, I'd recommend we implement an option similar to /*@nomin*/ and use that to skip the validation stage for any modules that originate from individual users (ORIGIN_USER_INDIVIDUAL), such as user scripts and non-default gadgets.

I'm not sure about the idea of allowing it for non-default gadgets... Wouldn't that mean changing a gadget to be default could break it for everyone?

Change 264767 abandoned by Krinkle:
JSMinPlus: allow reserved words as property keys

Reason:
Closing due to inactivity.

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

Krinkle raised the priority of this task from Low to Medium.Apr 11 2017, 12:19 AM
Krinkle removed projects: Developer-notice, JavaScript.
Krinkle removed a subscriber: wikibugs-l-list.

This is now unblocked with the following two resolved:
T128115: Drop support for ES3 javascript browsers in MediaWiki
T102318: Convert startup blacklist to feature test

The path is now clear for (unconditionally) allowing ES5 syntax in any scripts (user-generated or not). The main difficulty to making this work is the JavaScriptMinifier library we use. It was built for ES3 syntax.

Switching is trivial from an interface perspective (we have very few directly callers to this library), however it's complicated because we have very high performance requirements. There aren't many performant JavaScript parsers/minifiers for PHP. And last time we checked we couldn't find any to the point that one of our volunteers (Paul Copperman) actually wrote a high-performance parser just for our use case.

It seems that in 2011, @brion patched the jsminplus library to support part of ES5 syntax: Unicode literals in identifiers.

rMW72ba305da444: * (bug 31187) Fix for user JavaScript validation to allow identifiers with…

The commit also added unit tests, except those were for JavaScriptMinifier, not jsminplus. Which is somewhat confusing to me, as those tests are passing. This would mean that JavaScriptMinifier already supported these literals before that patch. And, given that T166630 was filed, it seems the patch to jsminplus didn't work?

Background:
We currently use JavaScriptMinifier in production for all minificatin (not jsminplus, because it was too slow and sometimes produced invalid syntax). Parse validation is only enabled for user scripts and gadgets, and that process is still handled by jsminplus, due to it producing better error message (at least, I think that was the reason?).