#SmooshGate FAQ by Mathias Bynens

smoosh? ! What happened? !

A proposal called a JavaScript feature called Array.prototype.flatten proved incompatible with the Web. Publishing this feature in Firefox Nightly causes at least one popular web site to outage. Given that the code in question is part of the widely used MooTools library, it is likely that more sites will be affected. (Although MooTools wasn’t often used for new sites in 2018, it was very popular and still exists on many sites that are already running.)

The proposal author jokingly suggested renaming Flatten to Smoosh to avoid compatibility issues.

However, not everyone knew it was a joke, some people began to mistakenly believe that the new name had been decided, and things quickly escalated.

Array.prototype.flattenWhat is?

Array.prototype.flatten recursively flatten the Array to a specified depth, which defaults to 1.

// Flatten one level:
const array = [1[2[3]]];
array.flatten();
// → [1, 2, [3]]

// Flatten recursively until the array contains no more nested arrays:
array.flatten(Infinity);
// → [1, 2, 3]
Copy the code

The same proposal includes array.prototype. flatMap, which, like array.prototype. map, can pass a callback function inside the parameter.

[2.3.4].flatMap((x) = > [x, x * 2]);
// → [2, 4, 3, 6, 4, 8]
Copy the code

What problems are MooTools causing?

MooTools defines their own non-standard version of Array.prototype.flatten:

Array.prototype.flatten = /* non-standard implementation */;
Copy the code

MooTools’s flatten implementation differs from the recommended standard. But that’s not a problem! MooTools overrides native implementations when browsers provide native array.prototype. flatten. This ensures that mooTools-dependent code works as expected, whether native Flatten is available or not. So far so good!

Unfortunately, something else happened. MooTools copies all of its custom array methods to Elements. Prototype (Elements are MooTools-specific apis) :

for (var key in Array.prototype) {
  Elements.prototype[key] = Array.prototype[key];
}
Copy the code

For-in iterates through “enumerable” properties, which don’t include things like the native array.prototype. sort, but custom array.prototype. foo = whatever. But – and here we go – if you override a non-enumerable property, such as array.prototype. sort = whatever, then the property is still not enumerable.

At present, the Array. The prototype. Flatten = mooToolsFlattenImplementation create an enumeration flatten properties, so it will be copied to the Elements. However, if we publish the native version of Flatten, it will become unenumerable and will not be copied to Elements. Now, any using MooTools and depend on the Elements. The prototype. Flatten the code were destroyed.

Although making native array.prototype.flatten enumerable might solve the problem, it might cause more compatibility issues. Every web site that relies on a for-in traversal set (a bad practice, but one that is often used) suddenly gets a looping iteration of the Flatten property.

The bigger underlying problem here is modifying built-in objects. Now extending native prototypes is generally considered a bad idea because it doesn’t work well with other libraries and third-party code. Do not modify objects that do not belong to you!

Why don’t we keep the name and break the network?

In 1996, well before CSS became widespread, and long before “HTML5”, the Space Jam website was up and running. Today, the site has been running smoothly for 22 years.

How does this work? Has anyone maintained the site over the years, updating it every time browser vendors release new features?

It turns out that “Don’t break the Web” is the number one design principle widely used in HTML, CSS, JavaScript, and any standard on the Web. If releasing new browser features causes existing sites to stop working, that’s bad for everyone:

  • Visitors to the affected site suddenly get a broken user experience;

  • The site owner went from a perfect site to a nonfunctional site, and the site owner didn’t change anything;

  • Users switch browsers when they see “XXX browser only”, so browser vendors with new features lose market share.

  • Other browser vendors refused to implement this feature once they became aware of compatibility issues. Resulting in the specification of a feature not matching the actual implementation (” just a work of fiction “), which is detrimental to the standardization process.

Of course, in retrospect MooTools did one thing wrong – but breaking the network doesn’t punish them (MooTools), it penalizes users. These users don’t know what MooTools is.

Alternatively, we can find another solution and users can continue to use the network.

Does this mean that bad apis cannot be removed from the Web platform?

In rare cases, undesirable features can be removed from the network. Even just figuring out whether or not a feature can be removed is tricky work, requiring a lot of telemetry to quantify how many pages change their behavior. However, this can be done if the feature is sufficiently insecure, harmful to the user, or rarely used.


,
, and showModalDialog() are all examples of incorrect apis that were successfully removed from the Web platform.

Why not fix MooTools?

Tinkering with MooTools so that it no longer extends built-in objects is a good idea. But it does not solve the problem at hand. Even if MooTools releases a patched version, all existing sites using it will have to be updated for compatibility issues to disappear.

Is it possible to update only the copies of MooTools used on the site?

In an ideal world MooTools would release a patch, and every website using MooTools would magically update the next day. Problem solved, right? !

Unfortunately, this is unrealistic. Even if someone somehow identified the entire set of affected sites, they could manage to find contact information for each one, successfully contact all the site owners and convince them all to perform the update (which could mean refactoring their site’s entire codebase), a process that could take years at most.

Keep in mind that many of these sites are old and may not be maintainable. Even if the maintainers are still around, they may not be highly skilled Web developers like you. Because of network compatibility issues, we can’t expect everyone to change a site that they’ve been running for seven or eight years.

What is the workflow of TC39?

The JavaScript language is based on the ECMAScript standard, and TC39 is the committee responsible for the development of the JavaScript language

The “Smoosh gate” incident led some to mistakenly believe that “TC39 wants to rename Flatten as Smoosh”, but this was a joke that didn’t go over well. Big decisions like the renaming proposal are not taken lightly, not taken up by a single person, and definitely not done on GitHub comments.

TC39 has a clear grading process for functional proposals. The ECMAScript proposal and any significant changes (including methodological updates) are discussed during the TC39 session and require the approval of the full Committee before formal submission. In this case, the Array.prototype.Flatten proposal has gone through several stages of discussion, all the way up to Stage 3, indicating that the feature is ready to be implemented in a Web browser. Other specification problems are common during implementation. In this case, the most important feedback came after the attempt to release it: the feature breaks the Web in its current state. The TC39 process doesn’t end when browsers release new features because of these unpredictable issues.

TC39 operates by consensus, meaning the Committee must agree on any new changes. Even if Smoosh was a serious proposal, committee members seemed likely to oppose it, preferring instead more common names such as Compact or chain.

Renaming Flatten to Smoosh (even if it wasn’t a joke) was never discussed at the TC39 meeting. Therefore, the official TC39 position on this issue is currently unknown. No one can speak for all TC39 until consensus is reached at the next meeting.

TC39 conferences are typically attended by people with highly diverse backgrounds: some with years of programming language design experience, others working with browsers or JavaScript engines, and a growing community of JavaScript developers.

What happens next?

The next TC39 meeting is this week. One item on the agenda discusses Flatten and its network compatibility. Hopefully we’ll know more about the next steps after the meeting.