highlight.js icon indicating copy to clipboard operation
highlight.js copied to clipboard

(javscript/typescript) improve JSX comment highlighting

Open brigand opened this issue 6 years ago • 6 comments

Live example on the npm website.

react-ck5 readme on npmjs.com

  state = { editorState: null }
  render() {
    return (
      <div>
        <ClassicBasic
          value={/* ... */}
          onChange={/* ... */}
          editorState={this.state.editorState}
          onStateChange={editorState => this.setState({ editorState })}
        />
        <button
          // prevent editor losing focus
          onMouseDown={e => e.preventDefault()}
          onClick={() => {
            this.setState(s => update(s, 'editorState.bold.value', value => !value));
          }}
        >
          Toggle bold
        </button>
      </div>
    );
  }

Expected behavior

Comments in jsx attribute positions should look like comments. The spec isn't explicit about it, but babel, acorn, typescript, and flow all support the syntax.


Thanks!

original issue

brigand avatar Nov 02 '17 21:11 brigand

I'm pretty sure this is illegal JSX syntax, the spec doesn't mention using // comments and this might be typo or something specific to your JSX transpiler, but I don't think it's standard.

Edit: Apparently it is legal but only between <>, not between ><.

nickmccurdy avatar Dec 02 '17 05:12 nickmccurdy

Edit: Apparently it is legal but only between <>, not between ><.

So in that case it acts like a Javascript style comment... that probably also pours a little rainstorm on the idea of trying to use "html/xml" as the internal parser for these blocks though.

Seeming more and more like we need a dedicated jsx grammar.

joshgoebel avatar Oct 07 '19 09:10 joshgoebel

Screen Shot 2020-10-01 at 2 25 57 AM

What I have working so far built on top of the new consolidated JS/TS stuff... wasn't that hard either.

joshgoebel avatar Oct 01 '20 06:10 joshgoebel

@allejo @egor-rogov

There is a weirdness here though... we're inside "tag" (which has it's own styling) and when we hit a {} pair then we have embedded JS... which should go back to the default "unhighlighted" color... not the tag color... so to do this we really need a new css class... reset or default or something that is pinned to whatever .hljs is... to allow content inside of a tag to do a "reset" to get back to the "parent" style...

Any thoughts on this or naming?

joshgoebel avatar Oct 01 '20 06:10 joshgoebel

Some dark magic:

            contains: [
              HTML_TAG,
              XML_ENTITIES,
              {
                begin: /[^<]+/, // eat everything up until the next <
                end: /./, // to avoid 0-width match error
                // always return, this rule is not intended to consume
                // anything, just bookend the JSX/HTML segment
                returnEnd: true,
                returnBegin: true,
                endsParent:true, // when we've paired all HTML tags, we endParent
                "on:begin": (_, resp) => {
                  if (nestedTagCount !== 0) resp.ignoreMatch();
                }
              }
            ]

It's likely we just need a response.endsParent() that could be called from HTML_TAG's on:end rule (to allow modes to conditionally end the parent)... but still it's cool this seems to work great. :-)

joshgoebel avatar Oct 01 '20 07:10 joshgoebel

@allejo @egor-rogov

There is a weirdness here though... we're inside "tag" (which has it's own styling) and when we hit a {} pair then we have embedded JS... which should go back to the default "unhighlighted" color... not the tag color... so to do this we really need a new css class... reset or default or something that is pinned to whatever .hljs is... to allow content inside of a tag to do a "reset" to get back to the "parent" style...

Any thoughts on this or naming?

What about hljs-unset following CSS's unset keyword?

allejo avatar Oct 21 '20 04:10 allejo