Itās almost Septemberween, which means itās that time of the year we gather āround our spinning MacBook fans and share website ghost stories:
The tale of the disappearing burger and lobster site content (i.e., webcompat bug 2760).
Chapter 1.
Once upon a time (that time being the present), there was this burger and lobster ārestaurantā called, um well, burger and lobster. In Firefox, as of today, the site content never renders ā you just end up with some fancy illustrations (none of which are burgers or lobsters).
Opening devtools, youāve got the following mysterious stacktrace:
Error: node is undefined
compositeLinkFn@http://www.burgerandlobster.../angular-1.2.25.js:6108:13
compositeLinkFn@http://www.burgerandlobster.../angular-1.2.25.js:6108:13
nodeLinkFn@http://www.burgerandlobster.../angular-1.2.25.js:6705:24
(...stack frames descend into hell...)
jQuery@http://www.burgerandlobster.../jquery-1.11.1.js:73:10
@http://www.burgerandlobster.../jquery-1.11.1.js:3557:1
@http://www.burgerandlobster.../jquery-1.11.1.js:34:3
@http://www.burgerandlobster.../jquery-1.11.1.js:15:2
Cool, time to debug AngularJS.
But it turns out that leads nowhere besides the abyss, AKA funtions that return functions that compose with other functions with dollar signs in themā¦ and the bug is elsewhere. Besides, Chrome has a similar error, and the page works there. Just a haunted node, maybe.
Dennis Schubert discovered that adding a <base href="/">
fixes the site, which happens to be required by Angular is later versions for $locationProvider.html5Mode
. But this bug has nothing to do with pushState
or history, or even SVG xlink:href
s, all of which the <base>
element can affect.
Another (dead) rabbit hole, another dead end (spooky).
At some point, all your debugging tricks and intuitions fail and itās time to just page a thousand lines of framework-specific JS into your brain and see where that leads. Two hours later, if youāre lucky, you notice something weird like so:
var illustArr = [
{
"url": "/Assets/images/illustrations/alert-man.png",
"x": "2508",
"y": "2028"
},
...
(bunch of similar objects objects, then...)
{
"url": "",
"x": "",
"y": ""
};
And you recall a method that dispatches a allImagesLoaded
event which tells the app itās OK to load the rest of the page content. It looks like this:
b.allImagesLoaded = function() {
d += 1,
d === a.imageArr.length && $("body").trigger("allImagesLoaded")
}
But it only does that once itās counted that all images have loaded (or fired an error event):
l.loadImage = function(a) {
var b = $(document.createElement("div"))
, c = $(document.createElement("img"));
[...]
c.attr("src", a.url),
[...]
c.bind("load error", function(e) {
$(this).addClass("illustration--show"),
h.allImagesLoaded()
})
}
So yeah, that looks fishy. And thatās why Firefox gets stuckāit doesnāt fire error
events when img.src
is set to the empty string, which is required per HTML. Hereās a small test case, which also demonstrates why the <base href="/">
fixed the pageāitāll fire an error
event when requesting an image from the site root (and eventually barf on the HTML, I guess).
Anyways, the Gecko bug for that is Bug 599975. That will probably get fixed soon.
Epilogue.
So whatās the moral of this ghost story? There is none. Septemberween is cruel that way.