Opened 10 years ago

Closed 10 years ago

#9816 closed defect (fixed)

XD Loader can't handle requireLocalization if the bundle is already loaded - bundleMap

Reported by: Jared Jurkiewicz Owned by: James Burke
Priority: high Milestone: 1.4
Component: Loader Version: 1.3.2
Keywords: Cc:
Blocked By: Blocking:

Description

Reported from a co-worker of mine:


The crux of this issue is a simple coding error in loader_xd.js dojo.xdRequireLocalization function, the variable bundleMap is referenced before it is defined.

This bug has been around a long time and intermittently opened and closed as invalid, since it's not a typical code path that hits it.

In our usage of Dojo in our product we have a scenario where we are in fact hitting this code path and thus the bug is blocking us.

In addition to fixing the simple coding error, I feel the implementation of the bundleMap and the dojo._xdBundleMap should be reviewed to ensure it is working as intended.

test.html is attached with a simple test case to see the bug block the loader and parser.

Detailed notes of how we are getting into this scenario:

We are using a custom layer [bhc].

That layer has widgets which depend on or inherit from core dijit or dojox widgets. [dojo.require("dijit.....")].

We use the dojo build process to compile a cross domain build of our layer.

During the compile or build process lots of magic happens [interning strings, flattening bundles etc].

We include our layer directly in our document head via a script tag. This is done so we have access to our bhc.reldate helper which we use in document.write statements. If we waited to use the dojo loader the helper would not be immediately available.

As soon as the bhc layer is loaded in the <head> it calls preloadLocalizations to load the appropriate bhc bundle for the current locale.

We subsequently include random dijit widgets which have requireLocalization calls to some of the bundles which were already loaded through the aforementioned bhc layer.

This is where we hit the simple/silly bug in loader_xd.js

var bundleResource = dojo.getObject([moduleName, "nls", bundleName].join("."));

if(bundleResource && bundleResource[fixedBestLocale]){

bundleMap[jsLoc.replace('-', '_')] = bundleResource[fixedBestLocale];

}else{

...

Because the bundle is loaded so bundleResource returns the object.

It's not clear to me what the bundleMap and dojo._xdBundleMap are trying to accomplish. I think this should be revisited.

I understand that we had to work hard to put ourselves into this situation [not a typical use case], but nonetheless the dojo bug should be fixed.

Note a few different TRYME notes in the attached test case

  1. As is don't include dijit-all directly, bundleMap is undefined. This is similar to what we are seeing
  2. Include dijit-all before the bundle is included, this works
  3. Include dijit-all after the bundle is included, this doesn't work and fails in a new silent manner.

James, what do you think?

Attachments (1)

test.2.html (1.5 KB) - added by Jared Jurkiewicz 10 years ago.
Updated testcase.

Download all attachments as: .zip

Change History (7)

comment:1 Changed 10 years ago by Jared Jurkiewicz

Component: GeneralPackageSystem
Owner: changed from anonymous to James Burke

Changed 10 years ago by Jared Jurkiewicz

Attachment: test.2.html added

Updated testcase.

comment:2 Changed 10 years ago by Adam Peller

dup of #9751

comment:3 Changed 10 years ago by James Burke

Resolution: invalid
Status: newclosed

I do not see an error with the bundleMap with this test case. In fact, the way it is constructed, by doing script tag calls for the specific resources instead of using dojo.require(), the xd loader code that makes sure code is evaluated in the right order is not executed.

I put up a test page here to confirm: http://jburke.dojotoolkit.org/temp/9816/9816.html

(warning that URL will not work after a few months)

I modified the dojo.xd.js.uncompressed.js to console.log if the dojo.xdRequireLocalization() function was called, the one with the bad bundlemap reference, but it does not get called.

Since dojo.require() is not called, the dojo._inFlight count is not incremented. So when our DOMContentLoaded detection fires, it looks to see if anything is in flight (via a non-zero dojo._inFlight count), but gets a 0 for that, so it triggers the onload handlers.

However, the code in the dijit and dijit-all layers is just sitting in the xd-wrapped functions waiting to be called, so that is why there are no errors. Basically, the layer contents have not been evaluated into existence.

So closing this as invalid, since the proper way to do this sort of thing is via dojo.require calls anyway, but feel free to reopen with a test case that triggers the dojo.xdRequireLocalization() function and the bad bundleMap reference.

I tried a quick test by replacing the script tags:

dojo.require("dijit.dijit");
dojo.require("dijit.nls.dijit-all_es");
dojo.require("dijit.dijit-all");

but that worked.

comment:4 Changed 10 years ago by Jared Jurkiewicz

Resolution: invalid
Status: closedreopened

Comment from my co-worker, who was able to reproduce it with James' example (with a slight tweak to it):

Ok I see the issue.

The test page james put up here http://jburke.dojotoolkit.org/temp/9816/9816.html should not have dijit-all.xd.js uncommented.

See the note in the last TRYME comment, which is demonstrating what I believe is a separate issue.

The way to trigger the behavior we are seeing is to comment out the dijit-all.xd.js script tag.

So reopening for James' input.

comment:5 Changed 10 years ago by James Burke

Milestone: tbd1.4

Thanks, that change seems to trigger the error. This is very bizarre loading, but at least it allowed reproduction of the issue and I was able to make a fix and verify it. Thanks!

comment:6 Changed 10 years ago by James Burke

Resolution: fixed
Status: reopenedclosed

(In [20030]) Fixes #9816, bad code in i18n handling in xd loader. Only triggered by bizarre code loading sequence.

Note: See TracTickets for help on using tickets.