2

This question is specifically about a problem that I am having with our site's attempt to compensate for Chrome's insistence on performing autofill when it should not.

Please note: this question is not specifically about the autofill issue, which is well-documented over the course of several years. For example, here are some useful pages that cover that issue:

Over the years we have used several solutions similar to the ones documented in the above articles, especially the first article.

As developers have developed workarounds, the Chrome team works to disable the workarounds. At present I don't know of any workaround that is effective any more. The Chromium team apparently believes that any form with a password field is a login form, and it does not want to easily allow the ability to edit passwords, while retaining the automatic obfuscation feature.

In any case, I re-iterate that I am not specifically focusing on the autofill problem, but rather some issues I am having countering it.

We have successfully countered the issue on some of our edit pages, but don't have a complete solution, due to the following issue, which is the heart of this question.

The issue is that because the fields in question are email adddress (username) and password, there is other javascript on the page, which is fairly complex. The purpose of that javascript is to help the user with such functions as the following:

  1. Make sure that the entry meets certain basic validations.
  2. Make sure that an email address is not already used in our database.
  3. Make sure that the entry does not violate certain other policies, such as using first name, last name, etc. as a password.

Quite a ways back one of our measures that was in part to counter browser autofill was to make the email address and password fields hidden, and only displayed after the user clicks a button with a label like "Change Email Address". This had some beneficial user impact that I will not detail, but also stopped Chrome from autofilling.

Recently however, Chrome has started autofilling even the hidden fields. So when the button was clicked and the fields revealed, there was data populated into the email address. However, the data populated was the userid rather than an email address, because we allow logging using either userid or email address, and with certain Chrome settings, the userid was saved.

The next step in dealing with this "feature" was to add a line of jquery to clear the contents of that field when the button is clicked, and if the button is not clicked, to have the update routine ignore the bogus autofill.

The actual problem that is happening is that somehow, it appears that Chrome is inserting the value back into the DOM. Other works seems to show that Chrome will perversely and continually attempt to perform the autofill every time the DOM changes.

So here is the sequence of apparent events that I have not yet solved:

  1. User visits his profile page.
  2. Chrome autofills the hidden username.
  3. User clicks "Change Email Address"
  4. jquery uses val('') to clear the contents of the field.
  5. There is an onblur validation on the email address field that should not be triggered yet, because the field is not blurred. In fact, the cursor is not yet even placed into the field--the user has to do that. The reason we know the validation occurs is because immediately we get an error message about the invalid email address because it is a userid format rather than an email address format.

There are two "impossible" things going on here.

  1. A validation is occurring that seems there is no way it could be triggered.
  2. We have cleared the field using jquery. But the the validation (which should not be happening) is still seeing the original autofilled and invalid content.

A theory that might explain this is that when the field is displayed, the focus quickly goes into that field before the javascript has had time to actually clear the DOM, and that the focus leaves the field before the eye can see that it went into the field, thus triggering the validation, again before the jquery has had its effect.

So the theory might be that the sequence of events is gain focus, lose focus, trigger the onblur validation, clear the field. This would produce the observed effect.

So the question specifics are the following:

  1. What is causing the focus to be gained and lost?
  2. Why is this happening before the clearing of the field, which happens when the fields are made visible?

Yet a further theory might be "javascript handles events not in the order that it appears, but rather some other predetermined order". I have seen some information about that, but I don't know how to control this to solve the problem.

Here are some code snippets. You will note that a number of the previously-working autofill blocking tactics are still in place:

onblur=ValidFirstField()

<input type="password" autocomplete="new-password" name="password1" id="password1" size="20" maxlength="$MAX_PASSWORD_LEN" onkeydown="clearMessage('pw_message'); displayMessage('pw_strength');" onkeyup="chkPass(this.value);" onblur="ValidFirstField(this, 'Password', $MIN_PASSWORD_LEN, $MAX_PASSWORD_LEN, ValidPasswordSafety, ['$companyname', '$fname', '$lname', '$email1', '$email2'], 'pw_message', ' not allowed; please choose another.', 1, 'password2' );" >

validation Please note: the line of code with fieldname + ' must be between ' is the validation that is triggered out of sequence:

function ValidFirstField(field1, fieldname, minlen, maxlen, cfunc, aProhibited, msg_field, bad_msg, common_msg, mark_field)
{
    if (!field1.value.length)
    {
        return;
    }
    var login_prompt = document.getElementById('login-prompt');
    if (login_prompt)
    {
        login_prompt.style.display = STYLE_NONE;    /* clear in case set via ajax */
    }
    var msg = document.getElementById(msg_field);
    msg.innerHTML = '';
    var allowSubmit = true;
    if (field1.value.length < minlen || field1.value.length > maxlen)
    {
        msg.innerHTML = fieldname + ' must be between ' + minlen + ' and ' + maxlen + ' characters: ' + field1.value.length;
        allowSubmit = false;
        field1.focus();     // TODO temporarily suppress to prevent focus/onblur race in IE
    }
...

jquery that displays the fields and clears the content

$('#show-email').click(function()
{
    chg_email_clicked = true;
    $('#chg-email-clicked').val(1);
    // alert('chg=' + chg_email_clicked);
    $(this).hide();
    // from https://stackoverflow.com/questions/15738259/disabling-chrome-autofill mike nelson
    var $chrome_fake = $('.chrome-fake');
    $chrome_fake.show();
    window.setTimeout(function ()
    {
        $chrome_fake.hide();
    },1);
    $('#email1').val('');
    // var testemail1   = document.getElementById('email1').value;
    // alert(testemail1);
    $('.hide-email').show();
});
Jeffrey Simon
  • 702
  • 2
  • 9
  • 19

0 Answers0