Slate: Changing Block.types by Text/Input is hard.

Created on 6 Mar 2017  路  3Comments  路  Source: ianstormtaylor/slate

I would love to make this possible:

markdown
A slate markdown plugin that works like (gif) StackEdit.
(Yes I know the auto-markdown example It is not what I want.)

I think the perfekt way to would look like that:

  1. onDocumentChange
  2. get blocks part of the selection
  3. Try some regExs on block.text
  4. Set block type.
  5. Schema, Nodes, Render a h1, h2 or p....
  • I like to keep # in the text
  • Any manipulation of the text should be able to update its block.type. For example: delete one of the #
  • The headline is just an example, there are more similar markdown types

What I have tried

Schema, validate & normalize

Would be grate but there are two problems.

1. The validation runs not on Typing.
If you add a # Charakter, nothing would happen.
Validation runs only if you delete something or hit enter.
Try it: https://jsfiddle.net/bunterWolf/4gLsretr/1/

2. Validation checks the whole document.
There will be some regExs, which have to check every line, all the time.
The validation function gets only the document as a Parameter, therefore it is not possible to check the selection for the active block.

onKeyDown

A lot of control! But the state is not updated jet. That means the block.text is without the action the user is doing right now. To merge that on my own (Input/Delete + Selection) is to insane :)

onChange, onBeforeInput, onDocumentChange:

Could be nice, if there wouldn't be #402 (Which is not marked as bug, isn't it one?)
You can see what happens here: https://jsfiddle.net/bunterWolf/ze6nd2sb/7/
if I change the block.type in onChange, onBeforeInput, or onDocumentChange.

Thats it, for now.

Maybe I get there with marks (Not tried jet), but I would like to use the block.type and keep the marks separate for markdown inline stuff.

I would love to get some ideas or comments?:)

question

Most helpful comment

thanks a lot @ianstormtaylor for your help!
While looking into your approach, I came up with the idea of triggering a "unNative" event handling by a decorator (not sure if that would work). This leaded me the second time to the code highlighting example
I found there this time a tiny bug, which bought me away from this solution the last time.
Now I came to the insight that prism.js and slate decorators are really great and a quite good solution for me.
Try the result here: https://jsfiddle.net/bunterWolf/uuyshtvs/3/

This fiddle merges the prism tokens deeper than the code highlighting example does.
If your are interested I would try to create a pull request for a more powerful version of the code highlighting example.

To close this issue: just use decorators and marks, that works quite well! Thanks! ;)

All 3 comments

Hey @bunterWolf, good question.

I think the best way to do this might be to use the schema and a custom onBeforeInput.

Like you mention the schema isn't validated for all typing changes. This is because in the core plugin's onBeforeInput it tries to avoid the "slow" way of changing the content, and prefer native DOM insertion if possible (in the case of simply typing).

But you could opt out of this, and handle the insertion manually in your own onBeforeInput that is modeled off of the core plugin's. You'd need to check to see if the character is # or whatever else, and then insert it with a regular transform.

I'd also be down to accept a PR that makes the core plugin's onBeforeInput check if e.defaultPrevented and abort early if it already has been, such that it would be easy to then just define your own onBeforeInput that prevented the default behavior, without having to write it's own custom logic to insert too.

Hope that gives you some more things to try!

thanks a lot @ianstormtaylor for your help!
While looking into your approach, I came up with the idea of triggering a "unNative" event handling by a decorator (not sure if that would work). This leaded me the second time to the code highlighting example
I found there this time a tiny bug, which bought me away from this solution the last time.
Now I came to the insight that prism.js and slate decorators are really great and a quite good solution for me.
Try the result here: https://jsfiddle.net/bunterWolf/uuyshtvs/3/

This fiddle merges the prism tokens deeper than the code highlighting example does.
If your are interested I would try to create a pull request for a more powerful version of the code highlighting example.

To close this issue: just use decorators and marks, that works quite well! Thanks! ;)

Wow, @bunterWolf that is amazing!!! Really nice work! I didn't even realize that was possible haha 馃槃

I would love a pull request for that as an example if you're up for it. I think we should rename the auto-markdown example to markdown-shortcuts and maybe make your new one called markdown-decorations.

Sweet!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

chrpeter picture chrpeter  路  3Comments

ianstormtaylor picture ianstormtaylor  路  3Comments

ianstormtaylor picture ianstormtaylor  路  3Comments

bengotow picture bengotow  路  3Comments

adrianclay picture adrianclay  路  3Comments