kellym / smartquotes.js

Smart quotes are smart typography, and now it’s just a ’script away.
https://smartquotes.js.org
MIT License
150 stars 30 forks source link

Addition of x characters causes final x characters in <p> tag to be removed #66

Open simonhrogers opened 5 months ago

simonhrogers commented 5 months ago

Hello!

I adore this package it is invaluable, thank you so much for your work.

I’ve got the following replacement in a project:

smartquotes.replacements.push([/([0-9])–([0-9])/g, '$1\u200a–\u200a$2'])

and it is causing the following string to be editing from this:

A solo exhibition by Ndaye Kouagou opening on 21 September 2023 at 6–8 pm.

to this:

A solo exhibition by Ndaye Kouagou opening on 21 September 2023 at 6 – 8 p

As you can see, the hair spaces are correctly inserted, but the final two characters of the p tag are inexplicably removed.

This happens whether I paste the hair space character or use the regex unicode. It happens with regular spaces too; the problem seems to be unique to the en-dash character. It happens at the end of the P tag, whether or not there are subsequent P tags.

simonhrogers commented 5 months ago

Whoops! Don’t think this repo is active but regardless for other people using in current projects: this seems to be a hydration error when used in an SSR context; in Vue 3’s case it was easily solved by wrapping in a setTimeout, as you might with Next/React too.

simonhrogers commented 4 months ago

hmm this doesn’t seem to be a hydration issue as I first thought... I’ve edited the title to describe it more broadly as it does appear to be any instance of the following: addition of x characters causes final x characters in

tag to be removed.

kellym commented 4 months ago

Thanks for filing a ticket for this issue. I'll take a look into it. I wonder if you or I can create a test to recreate the issue.

kellym commented 4 months ago

I see what's going on, but I don't have a fix for it yet. Essentially, we concatenate the values of all the text nodes together, perform the regex on it, and then go back through all the text nodes to replace the old text with the new text. We keep track of the current index on the string so the right content goes back into the right text nodes. I have an idea of how to solve this, though.