Opened 7 years ago

Closed 7 years ago

#15768 closed defect (duplicate)

async loader fails on dijit/form/nls/validate with lang="en" in html tag

Reported by: Nick Fenwick Owned by: Adam Peller
Priority: undecided Milestone: tbd
Component: Internationalization Version: 1.7.3
Keywords: Cc: Rawld Gill, bill
Blocked By: Blocking:

Description

I've done a fair bit of debugging but the loader remains fairly mysterious to me. This problem surfaced on our live site apparently out of nowhere, it's probably down to a quirk of the modules I include and the order I include them in the dependency chain.

The problem does not occur when running from the SDK .. only when running a built dojo.

The problem is that a page with a DateTextBox? being created by parseOnLoad: true is failing during parsing because the dijit/form/nls/validate.js file is loaded but not returned as a valid 'root' variable in the i18n.js loader code. It fails on the line:

var current= lang.clone(root.root)

Before going further, I'll mention that my page has "lang="en"" in the <html> tag. This is put in by my PHP framework and I'll look at taking it out .. however, I believe "en" should be valid. lang="en-gb" also fails. lang="en-us" works, the DateTextBox? instantiates properly, and all is well.

The failing line of code is inside the require callback in the doLoad function. The problem seems to be that the system decides validate.js is an AMD module and should therefore already be available in the 'modules' array, but it isn't, so somewhere some code does "return modules[mid]" expecting a value to be returned but undefined is returned instead.

i18n.js has a syncRequire function, that goes into a xhr.get({sync:true}) call, and correctly returns the dijit/form/nls/validate.js contents, gives it to the load() callback function, evalBundle correctly decides that it's an AMD module, and so a further require() call is done by the line:

require([mid], function(bundle){

That 'require' is actually the syncRequire function, and the callback function(bundle) is never invoked because an undefined value is hit inside the inner syncRequire.

This is all sufficiently arcane to make me seek help and check if this is technically a bug.

I provide a test case, which case be re-built simply:

  • extract .tgz to get a 'buildtest' folder
  • cd buildtest
  • extract a dojo-release-1.7.3-src to the current directory
  • cd dojo-release-1.7.3-src/util/buildscripts
  • ./build.sh -r -p ../../../buildtest
  • load buildtest/index.html in your browser

You should see the DateTextBox? fail to instantiate, and the debugger break on the line quoted above with a "Cannot read property 'root' of undefined" console error.

1.8.0rc1 also fails in the same way as far as I can tell.

Attachments (2)

15768_testcase.tgz (2.5 KB) - added by Nick Fenwick 7 years ago.
Simple build profile and test page.
main.inc.php (1.6 KB) - added by Slavon 5 years ago.
http://tostopby.tumblr.com/

Download all attachments as: .zip

Change History (9)

Changed 7 years ago by Nick Fenwick

Attachment: 15768_testcase.tgz added

Simple build profile and test page.

comment:1 Changed 7 years ago by Nick Fenwick

I should mention, I put "async" in this ticket title because, as you might guess, changing data-dojo-config to have "async: false" means the error doesn't happen. My preferred solution so far is to change the lang="en" to lang="en-us" in my header, as this avoids the problem one way.. the alternative of async:false isn't very appealing for reasons of performance.

By the way, is there something basically wrong I'm doing in my testcase, where I have a dependency on CommonDeps?, which includes DateTextBox?, and then a dependency on DateTextBox?? I thought duplicate dependencies would be handled gracefully, especially in a single require statement. However, in my Net panel for that test case, I see:

  • dojo.js
  • dojo_en-us.js
  • parser.js
  • url.js
  • validate.js

Surely the last three can be avoided?

comment:2 Changed 7 years ago by Adam Peller

Cc: Rawld Gill bill added

The way Dojo reads the lang off HTML LANG has been problematic. See also #14687. Typically it means you need to include the lang in your data-dojo-config I'm assuming that you're using a variant of 'en' as your default browser locale, so I don't see why this would be a problem for you (though it might be, say, for a user running in 'de' locale loading your page) Still, the build should be generating locale info for 'en' when it generates 'en-*'

comment:3 Changed 7 years ago by Nick Fenwick

Yes I agree, I shouldn't have had any trouble even if the locale was 'en'.

If I omit the HTML LANG entirely, my locale is set to "en-us" from the browser (all my LANG and LC_* environment variables seem to be set to en_US in my Fedora Linux system), and everything works fine.

Just to mention, I found that setting data-dojo-config="locale: 'en-us'" did not override the locale, or did var dojoConfig = { locale: 'en-us' }, when lang="en" is provided in the <html> tag. Whenever HTML LANG="en", the problem persists and the locale variable in the loader stack frame can be seen to be 'en', even if I have set locale "en" via data-dojo-config or dojoConfig.

I'd appreciate someone reproducing the error to verify it, as it looks like this stuff ought to work.

comment:4 Changed 7 years ago by Adam Peller

see also #15630

comment:5 Changed 7 years ago by Adam Peller

and #15324

comment:6 Changed 7 years ago by Nick Fenwick

Thank you peller.. looks like a dup of #15630, due to comment 7: "setting the lang attribute anywhere (on an HTML tag or on an individual ticket) without also setting the locale or extraLocale in data-dojo-config to match was not supported."

Setting <html lang="en"> (as dictated by the PHP framework I'm using) and var dojoConfig = { locale: 'en' } fixes the problem.

As hungerburg comments on that ticket, this isn't well documented to my knowledge, and may break a great number of sites. It seems crazy that these two must be kept in sync, surely, if dojo will fail in this way if the two are not properly configured, dojo should detect an incompatibility and gracefully degrade one or the other so that things will work? Or at least, issue an error. This has been a major stumbling block for me, over such a little thing.

comment:7 Changed 7 years ago by Adam Peller

Resolution: duplicate
Status: newclosed

Changed 5 years ago by Slavon

Attachment: main.inc.php added
Note: See TracTickets for help on using tickets.