'username' and 'password' in inline Javascript event handler in Chrome/Firefox

firefox, google-chrome, html, javascript

Solution

This is actually defined as part of the HTML5 standard. The `<a>` element is specified to have the following DOM interface:

interface HTMLAnchorElement : HTMLElement {
           attribute DOMString target;
           attribute DOMString download;

           attribute DOMString rel;
  readonly attribute DOMTokenList relList;
           attribute DOMString hreflang;
           attribute DOMString type;

           attribute DOMString text;
};
HTMLAnchorElement implements URLUtils;

`URLUtils` is actually taken from the URL standard, where its behaviour is defined. This is where these properties are actually coming from:

[NoInterfaceObject]
interface URLUtils {
  stringifier attribute [EnsureUTF16] DOMString href;
  readonly attribute DOMString origin;

           attribute [EnsureUTF16] DOMString protocol;
           attribute [EnsureUTF16] DOMString username;
           attribute [EnsureUTF16] DOMString password;
           attribute [EnsureUTF16] DOMString host;
           attribute [EnsureUTF16] DOMString hostname;
           attribute [EnsureUTF16] DOMString port;
           attribute [EnsureUTF16] DOMString pathname;
           attribute [EnsureUTF16] DOMString search;
           attribute URLSearchParams? searchParams;
           attribute [EnsureUTF16] DOMString hash;
};

These DOM attributes are defined as getters and setters which parse and return the relevant values (on getting) and changes the `href` value upon setting a valid value. For example, `protocol` is simply defined as:

The protocol attribute must run these steps:

- If url is null, return "`:`".

- Return scheme and "`:`" concatenated.

The parts (such as "scheme") are taken from the `href` value, which is parsed as a valid URL.

Note that the way that the interface is described is known as Web IDL, which could be considered as a form of pseudocode, though it is actually well specified under its own specification.

Because it is a new standard, it has only been implemented very recently (which might explain why this issue was not relevant earlier) -- this was only implemented by Firefox in version 26.

Problem

The variables `username` and `password` do not retain their original value (as defined in the script tag) or are not accessible from the onclick event, however making a function call that outputs the variables does. It seems as though the variables are being redefined inside that scope because they are not undefined even if I don't define them. It appears to be due to the variables being named `username` and `password`, as shown in the code sample below (`usr` and `passwd` work as expected.) There is reason to believe this behaviour has been introduced into recent versions of the browser as older Firefox doesn't exhibit it. Here is a reproducible code sample (tested in Google Chrome 32 / Firefox 26 - however some users are reporting that it does not work for them): ``` <html> <head> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <script> var username = "Administrator"; var password = "AdminPass"; var usr = "Jordan"; var passwd = "JordanPass"; function printCredentials() { $("#out").append("username is: " + username + "<br/>"); $("#out").append("password is: " + password + "<br/>"); $("#out").append("usr is: " + usr + "<br/>"); $("#out").append("passwd is: " + passwd + "<br/>"); } </script> </head> <body> <a href="#" onclick="printCredentials()">This works</a><br/> <a href="#" onclick="$('#out').append('username is: ' + username + '<br/>'); $('#out').append('password is: ' + password + '<br/>'); $('#out').append('usr is: ' + usr + '<br/>'); $('#out').append('passwd is: ' + passwd + '<br/>');">But this doesn't (properly)</a><br/> <div id="out" style="background: yellow"></div> </body> </html> ``` JSFiddle demo Using jQuery is optional, the same happens with regular JS. Clicking the second link prints out `usr` and `passwd` as expected but `username` and `password` are blank. Curiously, it works as expected (all fields printed) in Internet Explorer. What is going on here?

Original source