When I discovered this weird "html" mode in addition to "htmlmixed", I wanted to allow a language to have multiple modes. But then mode validation didn't work anymore because "html" isn't really a mode. It just seemed to be a weird internal alias, and I thought there might be more of them.

But as it turns out, we invent this mode in TokenUtils ourselves. Where we normally would just report "xml" as the mode name, we make a distinction and instead return "html". A bunch of places rely on this madeup mode. I think we can get around this now, though.

For instance, when registering for code hints, the registration should be for a language, not a mode. Likewise, the CSSInlineEditor makes sure it only opens for HTML files - another decision that should be made based on the language, not the mode.

HTMLUtils also checks the the mode is "html", but why? Because it deals with tags, something that's works the same in XML.

So we could remove the XML distinction in TokenUtils, let it just return "xml", which is an actual mode, and map "xml" to HTML for our HTML language object - exactly how this was intended. That is, if it's safe to assume that XML inside HTML always actually is HTML. It is possible to embed XML in XHTML, but I doubt they make this distinction, and I certainly would still want this to be considered HTML.

As a result, the reported language would correctly be HTML, and if the CSSInlineEditor and the hint providers were to check for that instead of the mode, they are good. And HTMLUtils should be fine checking for the xml mode instead - getTagAttributes() and getTagInfo() don't sound HTML-specific at all.

Then we could get rid of mode aliases entirely, which is a huge relief indeed.

In the mean time, so we don't have to refactor CSSInlineEditor, etc., we could just change the returned mode to "htmlmixed" instead of "html" or hard-code this distinction into Languages.js for now. The latter sounds better, as it will avoid issues with extensions that register something for "html". Later we could actually treat this as a language ID rather than a mode name, so extensions wouldn't even have to change where mode names match language IDs.

Sound good?