facebook / jsx

The JSX specification is a XML-like syntax extension to ECMAScript.

Home Page:http://facebook.github.io/jsx/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Is scheme for JSXIdentifier correct?

igoradamenko opened this issue · comments

JSXIdentifier :
- IdentifierStart
- JSXIdentifier IdentifierPart
- JSXIdentifier NO WHITESPACE OR COMMENT `-`

Hey guys,

I'm looking at the scheme above and can't understand one thing. Is it possible according to this spec to create a JSXElement with a JSXElementName such as $-?

I'm asking because it looks pretty strange. It's impossible to create such function in JS, and also it's impossible to create such DOM element (I've tried to eval document.createElement('$-') and got an error). So, why is it possible to do such things in JSX?

I understand that:

This specification does not attempt to comply with any XML or HTML specification. JSX is designed as an ECMAScript feature and the similarity to XML is only for familiarity.

But according to usual application of JSX (rendering JS objects to HTML markup) a possibility of things like that is confusing.

(BTW, maybe this issue is related to #29)

Yes it does appear that way, I expect that is a mistake. I have a feeling that this is actually supposed to be something like:

  • JSXIdentifier NO WHITESPACE OR COMMENT - NO WHITESPACE OR COMMENT JSXIdentifier

To cover support for <custom-element>.

No, the current scheme covers things like <custom-element>, because you can ‘evaluate‘ JSXIdentifier as JSXIdentifier IdentifierPart, and then do it again, but with JSXIdentifier NO WHITESPACE OR COMMENT -, and you will get JSXIdentifier NO WHITESPACE OR COMMENT - IdentifierPart. Yeah, maybe there is no this warning about the absence of whitespace or comment after the dash, but I'm not sure that it's a big deal.

My point is, if the goal of this ‘dashed scheme’ is to describe valid custom HTML tags, then maybe it's better to use something instead of JSXIdentifier, because it can be equal IdentifierStart, that can be $ according to ECMA.

Right know, the latest part of the scheme describes not only things like [a-z]+-[a-z]+, but also a $-$. And this isn't valid anything, nor a JS object, neither a HTML tag.

For what it’s worth, Babel parses <$-$ /> just fine.

@j-f1, it does. But it make no sense later, because it's not a valid name for JS function, and it's not a valid name for HTML tag. So, React obviously can't find a function with this name, and when it tries to evaluate document.createElement it fails, because it isn't a valid HTML: https://codesandbox.io/s/937wrr6xny.

I'm not sure is it fine or not, and my question was exactly about it. It looks like it's possible in JSX, but it doesn't possible anywhere else, and for me scheme like this looks meaningless, but maybe I'm wrong.

Don't forget that JSX spec is not intended just for React, and other implementations might have other ways to transpile tag names, making any of these names valid.

@RReverser, yes. But JSX is intended for JS & HTML, isn't it?

I mean, yes, I understand that it's actually possible for example to transpile $-$ into something like __DOLLARSIGN__HYPHENSIGN__DOLLARSIGN__ and to hope that there won't be any conflicts with user's functions names in future. But I don't see any ways to transpile things like this into something compatible with JS and HTML at the same time and without any future conflicts.

So that was the reason why I created this issue. I think it's better to decrease possible variations of JSXIdentifier, to make spec compatible with JS and HTML right now and to prevent a possibility of things like $-$.

For example:

JSXElementName :
- IdentifierName
- JSXTagName
- JSXNamespacedName
- JSXMemberExpression

JSXTagName :
- UnicodeIDStart
- JSXTagName NO WHITESPACE OR COMMENT `-`

JSXNamespacedName :
- JSXIdentifier `:` JSXIdentifier

JSXMemberExpression :
- JSXIdentifier `.` JSXIdentifier
- JSXMemberExpression `.` JSXIdentifier

Here I removed JSXIdentifier NO WHITESPACE OR COMMENT - part from JSXIndentifier, which made it useless as entity, so I changed JSXIdentifier inside JSXElementName to IdentifierName. And I defined JSXTagName, which can be UnicodeIDStart (Unicode subset) or JSXTagName NO WHITESPACE OR COMMENT - (to support custom HTML tags).

Diff:

--- previous	2018-12-25 14:33:55.000000000 +0200
+++ next	2018-12-25 14:33:59.000000000 +0200
@@ -1,12 +1,12 @@
 JSXElementName :
-- JSXIdentifier
+- IdentifierName
+- JSXTagName
 - JSXNamespacedName
 - JSXMemberExpression

-JSXIdentifier :
-- IdentifierStart
-- JSXIdentifier IdentifierPart
-- JSXIdentifier NO WHITESPACE OR COMMENT `-`
+JSXTagName :
+- UnicodeIDStart
+- JSXTagName NO WHITESPACE OR COMMENT `-`

 JSXNamespacedName :
 - JSXIdentifier `:` JSXIdentifier

It is for JS but it doesn't need to translate to JS identifiers - it's common to transpile it to someFunc('elemName', ...).

Unless there is anything new, I think this has been desired. Closed.