'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?