Web-bugs: www.burgerandlobster.com - layout is messed up

Created on 15 Jun 2016  ยท  16Comments  ยท  Source: webcompat/web-bugs

URL: http://www.burgerandlobster.com/home/
Browser / Version: Firefox 50.0
Operating System: Mac OS X 10.9
Problem type: Layout is messed up

Steps to Reproduce
1) Navigate to: http://www.burgerandlobster.com/home/

Expected Behavior:
-The website should be usable.

Actual Behavior:
-It seems like some of the content is not loading. I only see the background images and the zoom doesn't seem to happen.

_From webcompat.com with โค๏ธ_

browser-firefox

Most helpful comment

OK, here goes. After descending into the guts of AngularJS stack traces, it of course turns out to not be an Angular bug. ๐Ÿ’€

tl;dr we need this bug to get fixed https://bugzilla.mozilla.org/show_bug.cgi?id=599975. Seems like a not-too-difficult patch to resurrect.

The reason the content never loads in the non-isMobile case is because the allImagesLoaded event is never fired:

b.allImagesLoaded = function() {
        d += 1,
        d === a.imageArr.length && $("body").trigger("allImagesLoaded")
    }

The reason that isn't fired is because it keeps track of the images it knows it has and when the last one calls allImagesLoaded, it triggers the allimagesLoaded event on doc.body.

Here's what the image array looks like (after a.imageArr = illustArr):

 var illustArr = [
  {
    "url": "/Assets/images/illustrations/alert-man.png",
    "x": "2508",
    "y": "2028"
  },
  {
    "url": "/Assets/images/illustrations/guru.png",
    "x": "290",
    "y": "1058"
  },
  {
    "url": "/Assets/images/illustrations/rendevous.png",
    "x": "160",
    "y": "1880"
  },
  {
    "url": "/Assets/images/illustrations/surfers.png",
    "x": "63",
    "y": "2500"
  },
  {
    "url": "/Assets/images/illustrations/top-dragon.png",
    "x": "1518",
    "y": "1072"
  },
  {
    "url": "/Assets/images/illustrations/dragon-bottom.png",
    "x": "2198",
    "y": "3491"
  },
  {
    "url": "/Assets/images/illustrations/woman.png",
    "x": "3555",
    "y": "3340"
  },
  {
    "url": "/Assets/images/illustrations/kraken.png",
    "x": "2724",
    "y": "327"
  },
  {
    "url": "/Assets/images/illustrations/fish.png",
    "x": "3138",
    "y": "2446"
  },
  {
    "url": "/Assets/images/illustrations/birds.png",
    "x": "3500",
    "y": "1354"
  },
  {
    "url": "",
    "x": "",
    "y": ""
  }

For whatever reason (mistake? no idea...) the last image has an empty url and x and y props.

The loadImage method that constructs the images looks like this:

l.loadImage = function(a) {
        var b = $(document.createElement("div"))
          , c = $(document.createElement("img"));
        c.addClass("illustration"),
        c.css({
            top: a.y + "px",
            left: a.x + "px"
        }),
        c.attr("src", a.url),
        b.addClass("loading"),
        $(".canvas-content").append(b),
        b.replaceWith(c),
        c.bind("load error", function(e) {
            $(this).addClass("illustration--show"),
            h.allImagesLoaded()
        })
    }

You can see that the created imgs are listening for load or error events before calling allImagesLoaded... and Firefox never fires that last error that Chrome does for the allImagesLoaded event to get called (that's when the sections get built up and the rest of the page is rendered).

That's also why adding a <base href="/"> fixes the issue -- with a base elm, an empty string on <img src=""> is really requesting an image source a the base URL... and will eventually fire an error event (if the server isn't set up for some kind of weird content negotiation...)

Check this out and click the buttons from top to bottom: https://miketaylr.com/bzla/burger-load.html

All 16 comments

I'm able to reproduce this issue, thanks for reporting @jrmuizel! In Firefox the page does not load and we get an Angular error in the console.

Error: node is undefined
compositeLinkFn@http://www.burgerandlobster.com/assets/scripts/libs/angular-1.2.25.js:6108:13
compositeLinkFn@http://www.burgerandlobster.com/assets/scripts/libs/angular-1.2.25.js:6108:13
nodeLinkFn@http://www.burgerandlobster.com/assets/scripts/libs/angular-1.2.25.js:6705:24
compositeLinkFn@http://www.burgerandlobster.com/assets/scripts/libs/angular-1.2.25.js:6105:13
compositeLinkFn@http://www.burgerandlobster.com/assets/scripts/libs/angular-1.2.25.js:6108:13
compositeLinkFn@http://www.burgerandlobster.com/assets/scripts/libs/angular-1.2.25.js:6108:13
compositeLinkFn@http://www.burgerandlobster.com/assets/scripts/libs/angular-1.2.25.js:6108:13
compositeLinkFn@http://www.burgerandlobster.com/assets/scripts/libs/angular-1.2.25.js:6108:13
publicLinkFn@http://www.burgerandlobster.com/assets/scripts/libs/angular-1.2.25.js:6001:30
bootstrap/doBootstrap/</<@http://www.burgerandlobster.com/assets/scripts/libs/angular-1.2.25.js:1449:11
$RootScopeProvider/this.$get</Scope.prototype.$eval@http://www.burgerandlobster.com/assets/scripts/libs/angular-1.2.25.js:12701:16
$RootScopeProvider/this.$get</Scope.prototype.$apply@http://www.burgerandlobster.com/assets/scripts/libs/angular-1.2.25.js:12799:18
bootstrap/doBootstrap/<@http://www.burgerandlobster.com/assets/scripts/libs/angular-1.2.25.js:1447:9
invoke@http://www.burgerandlobster.com/assets/scripts/libs/angular-1.2.25.js:3966:14
bootstrap/doBootstrap@http://www.burgerandlobster.com/assets/scripts/libs/angular-1.2.25.js:1445:5
bootstrap@http://www.burgerandlobster.com/assets/scripts/libs/angular-1.2.25.js:1459:12
angularInit@http://www.burgerandlobster.com/assets/scripts/libs/angular-1.2.25.js:1368:5
@http://www.burgerandlobster.com/assets/scripts/libs/angular-1.2.25.js:22019:5
jQuery.Callbacks/fire@http://www.burgerandlobster.com/assets/scripts/libs/jquery-1.11.1.js:3119:10
jQuery.Callbacks/self.fireWith@http://www.burgerandlobster.com/assets/scripts/libs/jquery-1.11.1.js:3231:7
.ready@http://www.burgerandlobster.com/assets/scripts/libs/jquery-1.11.1.js:3443:3
completed@http://www.burgerandlobster.com/assets/scripts/libs/jquery-1.11.1.js:3474:3
 angular-1.2.25.js:10071:18
consoleLog/<() angular-1.2.25.js:10071
$ExceptionHandlerProvider/this.$get</<() angular-1.2.25.js:7364
$RootScopeProvider/this.$get</Scope.prototype.$apply() angular-1.2.25.js:12801
bootstrap/doBootstrap/<() angular-1.2.25.js:1447
invoke() angular-1.2.25.js:3966
bootstrap/doBootstrap() angular-1.2.25.js:1445
bootstrap() angular-1.2.25.js:1459
angularInit() angular-1.2.25.js:1368
<anonymous> angular-1.2.25.js:22019
jQuery.Callbacks/fire() jquery-1.11.1.js:3119
jQuery.Callbacks/self.fireWith() jquery-1.11.1.js:3231
.ready() jquery-1.11.1.js:3443
completed() jquery-1.11.1.js:3474

In Chrome the website works as expected, though we also receive an Angular error message.

angular-1.2.25.js:7364 TypeError: Cannot read property 'childNodes' of undefined
    at compositeLinkFn (angular-1.2.25.js:6108)
    at compositeLinkFn (angular-1.2.25.js:6108)
    at nodeLinkFn (angular-1.2.25.js:6705)
    at compositeLinkFn (angular-1.2.25.js:6105)
    at compositeLinkFn (angular-1.2.25.js:6108)
    at compositeLinkFn (angular-1.2.25.js:6108)
    at compositeLinkFn (angular-1.2.25.js:6108)
    at compositeLinkFn (angular-1.2.25.js:6108)
    at publicLinkFn (angular-1.2.25.js:6001)
    at angular-1.2.25.js:1449

The website works in Edge and Safari as well.

Very interesting.

The site is broken on 48 as well, so this is not a recent regression. The JS error seems unrelated since it appears in all browsers and is fired in an event handler, so it should not affect the initial site loading.

I found the somewhat old-ish Angular version (namely 1.2.25, released in sep 2014) and wanted to check if the site works with newer Angular versions to maybe get a hint of what has been changed to point out the actual issue cause here. However, the new Angular version complained about the site missing a <base /> tag:

$location in HTML5 mode requires a <base /> tag to be present!

So, it turns out that Angular added this error in 1.3 with a very interesting note:

Before Angular 1.3 we didn't have this hard requirement and it was easy to write apps that worked when deployed in the root context but were broken when moved to a sub-context because in the sub-context all absolute urls would resolve to the root context of the app.

The site is indeed using the html5Mode and it is running inside a subdirectory:

bandl.config([
  '$routeProvider', 
  '$locationProvider',

  function ($routeProvider, $locationProvider, layoutHandler) {
    $locationProvider.html5Mode(true);

    $routeProvider.when('/home/', {controller: 'sectionsCtrl',resolve: {'getSection': function(layoutHandler) { layoutHandler.displayPage({url: "/home/",x: "-1839",y: "-2028"});}}})
      .when('/home/locations/', {controller: 'sectionsCtrl',resolve: {'getSection': function(layoutHandler) { layoutHandler.displayPage({url: "/home/locations/",x: "-2985",y: "-690"});}}});
    /* ... */
  }
]);

The site works in Firefox when I add <base href="/"> and since that's the only way one can do it in newer Angular versions, this could be a fix to suggest, although this does not give us any idea what Firefox does different here. I debugged a bit through Angular-Route, but didn't spot anything different so far, so more work needs to be done here.

I have ruled out the location parsing and controller calling. Basically, everything gets called as it should get called. The only notable difference is a call to$RouteProvider.$get and its first argument $rootScope. footer seems to be undefined in the case without a base tag, but it's set with the base tag. However, looking at the call stack, all the arguments are generated by a lot of magic and digging into that needs more time.

I'll probably be able to spend some time on that after next week, but if anyone is adventurous, feel free!

Oh, one thing I just noticed, this works as expected when the viewport is mobile-sized:

screen shot 2016-09-06 at 12 28 48 pm

(At least, it works in the same way that Chrome does in similar circumstances.)

in script.mins.js they define "mobile" like so:

a.isMobile = function () {
    return !a.viewPortWidthGreaterThan(768)
},

I think I have this one figured out... or at least, am close. And no, it has nothing to do with SVG, but does have something to do with image load events (!!111 ๐Ÿ˜–). Let me confirm locally and try to get a reduced test case before writing up a longer explanation.

OK, here goes. After descending into the guts of AngularJS stack traces, it of course turns out to not be an Angular bug. ๐Ÿ’€

tl;dr we need this bug to get fixed https://bugzilla.mozilla.org/show_bug.cgi?id=599975. Seems like a not-too-difficult patch to resurrect.

The reason the content never loads in the non-isMobile case is because the allImagesLoaded event is never fired:

b.allImagesLoaded = function() {
        d += 1,
        d === a.imageArr.length && $("body").trigger("allImagesLoaded")
    }

The reason that isn't fired is because it keeps track of the images it knows it has and when the last one calls allImagesLoaded, it triggers the allimagesLoaded event on doc.body.

Here's what the image array looks like (after a.imageArr = illustArr):

 var illustArr = [
  {
    "url": "/Assets/images/illustrations/alert-man.png",
    "x": "2508",
    "y": "2028"
  },
  {
    "url": "/Assets/images/illustrations/guru.png",
    "x": "290",
    "y": "1058"
  },
  {
    "url": "/Assets/images/illustrations/rendevous.png",
    "x": "160",
    "y": "1880"
  },
  {
    "url": "/Assets/images/illustrations/surfers.png",
    "x": "63",
    "y": "2500"
  },
  {
    "url": "/Assets/images/illustrations/top-dragon.png",
    "x": "1518",
    "y": "1072"
  },
  {
    "url": "/Assets/images/illustrations/dragon-bottom.png",
    "x": "2198",
    "y": "3491"
  },
  {
    "url": "/Assets/images/illustrations/woman.png",
    "x": "3555",
    "y": "3340"
  },
  {
    "url": "/Assets/images/illustrations/kraken.png",
    "x": "2724",
    "y": "327"
  },
  {
    "url": "/Assets/images/illustrations/fish.png",
    "x": "3138",
    "y": "2446"
  },
  {
    "url": "/Assets/images/illustrations/birds.png",
    "x": "3500",
    "y": "1354"
  },
  {
    "url": "",
    "x": "",
    "y": ""
  }

For whatever reason (mistake? no idea...) the last image has an empty url and x and y props.

The loadImage method that constructs the images looks like this:

l.loadImage = function(a) {
        var b = $(document.createElement("div"))
          , c = $(document.createElement("img"));
        c.addClass("illustration"),
        c.css({
            top: a.y + "px",
            left: a.x + "px"
        }),
        c.attr("src", a.url),
        b.addClass("loading"),
        $(".canvas-content").append(b),
        b.replaceWith(c),
        c.bind("load error", function(e) {
            $(this).addClass("illustration--show"),
            h.allImagesLoaded()
        })
    }

You can see that the created imgs are listening for load or error events before calling allImagesLoaded... and Firefox never fires that last error that Chrome does for the allImagesLoaded event to get called (that's when the sections get built up and the rest of the page is rendered).

That's also why adding a <base href="/"> fixes the issue -- with a base elm, an empty string on <img src=""> is really requesting an image source a the base URL... and will eventually fire an error event (if the server isn't set up for some kind of weird content negotiation...)

Check this out and click the buttons from top to bottom: https://miketaylr.com/bzla/burger-load.html

Even though this is a Gecko bug, we can move this into contact ready. If they remove that last object from the illustArr, the page loads just fine in Chrome and Firefox:

{
    "url": "",
    "x": "",
    "y": ""
  }

(And we'll work on getting the other bug fixed in Gecko).

Lovely bug!

@miketaylr you switched to contactready, but not sure who you meant to contact :)

For contacting burger and lobster
http://www.burgerandlobster.com/home/contact-us/

@miketaylr you switched to contactready, but not sure who you meant to contact :)

?

?
??

;) ok my question was not clear. I dived in the code and just realized that the allimagesLoaded is actually in http://www.burgerandlobster.com/assets/scripts/script.min.js (the source was not given)
which is a homemade script rather than Angular script.

And removing the last is also burger and lobster

{
    "url": "",
    "x": "",
    "y": ""
  }

ok so the needscontact was burger and lobster, the contact ready is my comment on https://github.com/webcompat/web-bugs/issues/2760#issuecomment-245179634

Thanks. Cleared.

Contacted.

A patch was landed in the autoland repo as well, so this should be fixed in NIghtly in the next day or so: https://bugzilla.mozilla.org/show_bug.cgi?id=599975

But it would be very cool if they could make the change so Firefox users don't have to wait a few months for the fix to land on stable.

??

????? โ“ ๐Ÿ˜†

(oops, sorry for not providing the source and picking the wrong label)

Nice work :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

IngrownMink4 picture IngrownMink4  ยท  3Comments

karlcow picture karlcow  ยท  5Comments

scheinercc picture scheinercc  ยท  6Comments

webcompat-bot picture webcompat-bot  ยท  5Comments

webcompat-bot picture webcompat-bot  ยท  4Comments