Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS 11 Safari HTML - Disable "Smart Punctuation"?

Is there a good way to disable the "Smart Punctuation" the iOS 11 Apple Keyboard generates - in Safari on an HTML login form - username field in particular?

The problem is that we have users with apostrophes in their usernames. Typing their usernames on iOS 11 and not knowing the subtleties of unicode they are not able to sign in.

Ideally we could just instruct such users to disable smart quotes or type the proper character by holding down the apostrophe key - but I am working on educational software for small children and that is out of the question.

The problem is compounded by the fact that there are also a small selection of users with actual curly single quotes in their usernames, so a simple map of replacements won't work - and we can't canonicalize the usernames as they come from a number of external systems we don't control / can't have a lot of say over.

like image 756
donatJ Avatar asked Feb 08 '18 05:02

donatJ


People also ask

How do I turn off smart punctuation on my iPhone?

Disable smart quotes on iPad and iPhoneGo to Settings > General > Keyboard, and toggle off “Smart Punctuation.”

How do you do smart punctuation on iOS 11?

iOS 11 finally added a long-awaited feature for those of us who care about typographic details: smart punctuation. You can turn this on in Settings → General → Keyboards.

What is iPhone keyboard smart punctuation?

Last one to consider in the basic settings is the iPhone's "Smart Punctuation" abilities. This simply means your iPhone automatically corrects certain punctuation marks to be more visually pleasing.

How do I change the apostrophe on my iPhone keyboard?

I don't want the English curly quotes. Just the same upright apostrophes and quotes as on Windows. On an iPhone/iPad screen keyboard, tap the 123 button and then press and hold the keys that show quote marks. You should get a popup menu where you can choose the straight ones that you want.


2 Answers

Unfortunately according to this MDN page there is no known Webkit <input> or <textarea> attributes to disable smart-quotes, but you can patch it with a script I've written derived from this QA: How to disable smart quotes for textarea fields in the browser?

window.addEventListener('DOMContentLoaded', attachFilterToInputs );

function attachFilterToInputs() {

    var textInputs = document.querySelectorAll( 'input[type=text], input[type=password], input[type=email], input[type=search], input[type=url], textarea, *[contenteditable=true]' );
    for( var i = 0; i < textInputs.length; i++ ) {
        textInputs[i].addEventListener( 'keypress', preventPretentiousPunctuation );
    } 
}

var conversionMap = createConversionMap();

function createConversionMap() {

    var map = {};
    // Open-quotes: http://www.fileformat.info/info/unicode/category/Pi/list.htm
    map[ 0x2018 ] = '\'';
    map[ 0x201B ] = '\'';
    map[ 0x201C ] = '"';
    map[ 0x201F ] = '"';

    // Close-quotes: http://www.fileformat.info/info/unicode/category/Pf/list.htm
    map[ 0x2019 ] = '\'';
    map[ 0x201D ] = '\"';

    // Primes: http://www.fileformat.info/info/unicode/category/Po/list.htm
    map[ 0x2032 ] = '\'';
    map[ 0x2033 ] = '"';
    map[ 0x2035 ] = '\'';
    map[ 0x2036 ] = '"';

    map[ 0x2014 ] = '-'; // iOS 11 also replaces dashes with em-dash
    map[ 0x2013 ] = '-'; // and "--" with en-dash

    return map;
}

function preventPretentiousPunctuation( event ) {

    if( event.key.length != 1 ) return;

    var code = event.key.codePointAt(0);
    var replacement = conversionMap[ code ];
    if( replacement ) {

        event.preventDefault();
        document.execCommand( 'insertText', 0, replacement );
    }
} 
like image 189
Dai Avatar answered Sep 26 '22 06:09

Dai


Thanks to Dai for the outline of the answer. Unfortunately when we implemented their solution and tested on an iOS 11 device, we found that the keypress event listener wasn't firing at all. We reworked their solution using the input event and regex string replace and found this did work for us.

Here is our variation, using jQuery for the selector and a shorter replace list.

<script type="text/javascript">

    // Here are the reference to Unicode Characters in the Punctuation
    // Open-quotes: http://www.fileformat.info/info/unicode/category/Pi/list.htm    
    // Close-quotes: http://www.fileformat.info/info/unicode/category/Pf/list.htm    

    window.addEventListener('DOMContentLoaded', attachFilterToInputs);

    // Patch the iOS Smart Punctuation functionality on restricted field(s), 
    // so that the user types acceptable characters.
    function attachFilterToInputs() {
        try {
            $("[name$='MyProtectedFieldName']").on('input', preventPretentiousPunctuation);
        }
        catch (err) {
            // do nothing
        }
    }

    function preventPretentiousPunctuation(event) {
        try {
            var str = $(this).val();
            var replacedStr = "";
            replacedStr = str.replace(/[\u2018\u2019\u201C\u201D]/g, 
                (c) => '\'\'""'.substr('\u2018\u2019\u201C\u201D'.indexOf(c), 1));

            if (str !== replacedStr) {
                $(this).val(replacedStr);
            }            
        }
        catch (err) {
            // do nothing
        }        
    }
</script>

Adding as an answer since I don't have the rep to comment.

like image 43
spaced - out Avatar answered Sep 22 '22 06:09

spaced - out