14

I'm currently getting an error within Facebook's FacePile code, and I'm baffled by the cause.

facepile.php loads a script which, among other things, has these lines (when pretty-printed):

...
o = document.createElement('script');
o.src = l[n];
o.async = true;
o.onload = h;
o.onreadystatechange = function() {
  if (o.readyState in c) {
    h();
    o.onreadystatechange = null;
  }
};
d++;
a.appendChild(o);
...

(a == document.body, d++ is irrelevant here)

This code loads a script with src = http://static.ak.fbcdn.net/rsrc.php/v1/yW/r/pmR8u_Z_9_0.js or something equally cryptic (the filename changes occasionally).

In that script, there are these lines at the very top (also when pretty-printed):

 /*1331654128,176820664*/

if (window.CavalryLogger) {
  CavalryLogger.start_js(["\/8f24"]);
}

window.__DEV__ = window.__DEV__ || 0;
if (!window.skipDomainLower && document.domain.toLowerCase().match(/(^|\.)facebook\..*/))
  document.domain = window.location.hostname.replace(/^.*(facebook\..*)$/i, '$1');
function bagofholding() {
}
function bagof(a) {
  return function() {
    return a;
  };
}
if (!Date.now)
  Date.now = function now() {
    return new Date().getTime();
  };
if (!Array.isArray)
  Array.isArray = function(a) {
    return Object.prototype.toString.call(a) == '[object Array]';
  };
...

And I'm getting an error which says "SCRIPT5009: 'Date' is undefined", right at the if (!Date.now) portion. Debugging near that point reveals that Date, Array, Object, Function, etc are all undefined.

Er... how? window exists, as does document (though document.body is null) and a handful of others, but plenty of pre-defined objects aren't. Earlier versions of IE don't seem to have this problem, nor do any other browsers, but multiple machines running IE9 (including a clean VM) all have the same issue.

I doubt I can do anything about it, but I'm very curious how this is happening / what the underlying problem is. Does anyone know, or can they point me to something that might help?

-- edit:

Prior to posting this question, I had found this site: http://www.guypo.com/technical/ies-premature-execution-problem/

While it seemed (and still does) like it might be the source of the problem, I can't replicate it under any smaller circumstances. All combinations I've tried still have Date, etc defined ; which isn't too surprising, as otherwise I'm sure others would be seeing many more problems with IE.

Groxx
  • 2,489
  • 1
  • 25
  • 32
  • Built–in objects like Date, Array, etc. should always available in the global context. How can a function execute if there is no Function constructor? Strange issue indeed. – RobG Mar 14 '12 at 02:41
  • try without "o.async = true;" – M. Dave Auayan Mar 14 '12 at 21:32
  • I can't - this is in Facebook's code, and I haven't been able to reproduce it with any of my own (though I haven't tried mirroring the whole thing. I may do that later). Unless IE9 has some way to edit the javascript that's currently running? – Groxx Mar 14 '12 at 21:48
  • @Groxx you can use fiddler to replace external javascript files with local javascript file ( modified copy of facebook's js file ). http://stackoverflow.com/questions/4821224/intercept-and-use-local-files-in-http-requests – N30 Jul 02 '12 at 01:18
  • Do you have an sample page you can show? It would be very interesting to see what is happening. You should try out IE9's debug tools. – Brian Nickel Jul 05 '12 at 17:04
  • 3
    I bet on: 1. typo, 2. Date is redefined in this context (event though it looks like global), 3. some code overwritten Date. For 2. try `window.Date` – kirilloid Jul 06 '12 at 09:36
  • As an example of redefining things in this context: ```with ({Date: undefined, Array: undefined, Object: undefined, Function: undefined}) {console.log(Date)}``` will log ```undefined``` – kybernetikos Jul 11 '12 at 07:32
  • 1
    The referred article ies-premature-execution-problem is not accessible anymore at the given link. Presumably this is the same article at a new location: http://www.guypo.com/technical/ies-premature-execution-problem/ – Paul Gobée Jul 10 '13 at 00:21
  • Thanks @PaulGobée, that's the same article :) Thankfully archive.org also has a copy of the original. I'll update the question for later browsers. – Groxx Oct 02 '13 at 01:23

2 Answers2

1

If you step through with a javascript debugger at the first point any JS gets run. At the same time add a watch for Date/Array etc. and note when it goes to null. Might be slow and laborious but I can't see why it wouldn't work.

Lee Taylor
  • 7,761
  • 16
  • 33
  • 49
  • They're undefined before the first line is executed, and only in the loaded script (not the other scripts in the page). – Groxx Jul 12 '12 at 23:29
  • If that is guaranteed then it sounds like a javascript parsing error or some kind of typo. How do you know that know js has run? – Lee Taylor Jul 12 '12 at 23:32
  • It hits the breakpoint. It's very likely a browser bug of some kind, it's just weird that I've only seen it on that file. – Groxx Jul 12 '12 at 23:52
1

You may want to try adding the script in a document.ready function. In other words, insure that the FB script is processed only after the DOM is ready. But, based on the link you give to Guy's Pod (great article, by the way), it seems you're right in the assertion that IE is downloading and executing the script pre-maturely (hence my suggestion to add a wrapper so that it only executes after the DOM ready event). IE9 is probably sandboxing the executing script (outside the document/window scope).

Joe Johnson
  • 1,814
  • 16
  • 20