javascriptios11

How to disable smart quotes for textarea fields in the browser?


I have a application that runs in the browser that compares strings. String compares with quotes fail using iOS11 because it is defaulting to smart quotes being on. can’t does not equal can't

I know smart quotes can be disabled under Setting for the whole device but I would like to handle it at the textarea level.

I thought I would be able to catch the smart quote on the keypress event, but iOS is making the switch later and under the covers.

textareaText is the text in my textarea field
39 is the character code for single quote
8216 is the character code for the left single smart quote
222 is the key code for the quote key
e is the event object passed to the keyboard event

keydown 
    e.keycode -> 222, e.key -> ', key.charCodeAt(0) -> 39 
    textareaText -> empty
keypress
    e.keycode -> 39, e.key -> ', key.charCodeAt(0) -> 39 
    textareaText -> empty
—> character is put in textarea here
keyup (iPad onscreen keyboard)
    e.keycode -> 222, e.key -> ', key.charCodeAt(0) -> 39 
    textareaText -> ’, textareaText.charCodeAt(0) -> 8216 
keyup (iPad external keyboard)
    e.keycode -> 0, e.key -> ', key.charCodeAt(0) -> 39 
    textareaText -> ’, textareaText.charCodeAt(0) -> 8216 

The keyup event thinks the character is the regular quote while the textarea contains the smart quote.

I tried:

textarea.innerHTML = textarea.innerHTML.replace(/’/,'\'')

but the cursor gets reset to the beginning of the string and I don't want to have to get and set the cursor position.

Is there any way to swap the smart quote before it is entered into the textarea? Or some way to disable smart quotes at the textarea level? Is any other solution to this problem?

My last resort is to replace the smart quotes in the string right before I compare it but I would prefer the browser to display the regular quotes to be consistent with what they entered, what they see, and what they are checked against.


Solution

  • The simplest way is to pass spellcheck="false" to the input element. This is based on how WebKit works: https://github.com/WebKit/WebKit/blob/596b3b01497f3bd3b3ea653ec79ffc69d6f68b30/Source/WebKit/UIProcess/ios/WKContentViewInteraction.mm#L6785